mirror of
https://github.com/getcompanion-ai/co-mono.git
synced 2026-04-18 21:00:41 +00:00
feat(coding-agent): add packages array with filtering support
- Add PackageSource type for npm/git sources with optional filtering - Migrate npm:/git: sources from extensions to packages array - Add getPackages(), setPackages(), setProjectPackages() methods - Update package-manager to resolve from packages array - Support selective loading: extensions, skills, prompts, themes per package - Update pi list to show packages - Add migration tests for settings closes #645
This commit is contained in:
parent
dd838d0fe0
commit
ef1fc3103e
8 changed files with 434 additions and 63 deletions
|
|
@ -38,6 +38,21 @@ export interface MarkdownSettings {
|
|||
codeBlockIndent?: string; // default: " "
|
||||
}
|
||||
|
||||
/**
|
||||
* Package source for npm/git packages.
|
||||
* - String form: load all resources from the package
|
||||
* - Object form: filter which resources to load
|
||||
*/
|
||||
export type PackageSource =
|
||||
| string
|
||||
| {
|
||||
source: string;
|
||||
extensions?: string[];
|
||||
skills?: string[];
|
||||
prompts?: string[];
|
||||
themes?: string[];
|
||||
};
|
||||
|
||||
export interface Settings {
|
||||
lastChangelogVersion?: string;
|
||||
defaultProvider?: string;
|
||||
|
|
@ -54,10 +69,11 @@ export interface Settings {
|
|||
quietStartup?: boolean;
|
||||
shellCommandPrefix?: string; // Prefix prepended to every bash command (e.g., "shopt -s expand_aliases" for alias support)
|
||||
collapseChangelog?: boolean; // Show condensed changelog after update (use /changelog for full)
|
||||
extensions?: string[]; // Array of extension file paths or directories
|
||||
skills?: string[]; // Array of skill file paths or directories
|
||||
prompts?: string[]; // Array of prompt template paths or directories
|
||||
themes?: string[]; // Array of theme file paths or directories
|
||||
packages?: PackageSource[]; // Array of npm/git package sources (string or object with filtering)
|
||||
extensions?: string[]; // Array of local extension file paths or directories
|
||||
skills?: string[]; // Array of local skill file paths or directories
|
||||
prompts?: string[]; // Array of local prompt template paths or directories
|
||||
themes?: string[]; // Array of local theme file paths or directories
|
||||
enableSkillCommands?: boolean; // default: true - register skills as /skill:name commands
|
||||
terminal?: TerminalSettings;
|
||||
images?: ImageSettings;
|
||||
|
|
@ -156,6 +172,7 @@ export class SettingsManager {
|
|||
delete settings.queueMode;
|
||||
}
|
||||
|
||||
// Migrate old skills object format to new array format
|
||||
if (
|
||||
"skills" in settings &&
|
||||
typeof settings.skills === "object" &&
|
||||
|
|
@ -176,9 +193,39 @@ export class SettingsManager {
|
|||
}
|
||||
}
|
||||
|
||||
// Migrate npm:/git: sources from extensions array to packages array
|
||||
if (Array.isArray(settings.extensions)) {
|
||||
const localExtensions: string[] = [];
|
||||
const packageSources: string[] = [];
|
||||
|
||||
for (const ext of settings.extensions) {
|
||||
if (typeof ext !== "string") continue;
|
||||
if (ext.startsWith("npm:") || ext.startsWith("git:") || SettingsManager.looksLikeGitUrl(ext)) {
|
||||
packageSources.push(ext);
|
||||
} else {
|
||||
localExtensions.push(ext);
|
||||
}
|
||||
}
|
||||
|
||||
if (packageSources.length > 0) {
|
||||
const existingPackages = Array.isArray(settings.packages) ? settings.packages : [];
|
||||
settings.packages = [...existingPackages, ...packageSources];
|
||||
settings.extensions = localExtensions.length > 0 ? localExtensions : undefined;
|
||||
if (settings.extensions === undefined) {
|
||||
delete settings.extensions;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return settings as Settings;
|
||||
}
|
||||
|
||||
private static looksLikeGitUrl(source: string): boolean {
|
||||
const gitHosts = ["github.com", "gitlab.com", "bitbucket.org", "codeberg.org"];
|
||||
const normalized = source.replace(/^https?:\/\//, "");
|
||||
return gitHosts.some((host) => normalized.startsWith(`${host}/`));
|
||||
}
|
||||
|
||||
private loadProjectSettings(): Settings {
|
||||
if (!this.projectSettingsPath || !existsSync(this.projectSettingsPath)) {
|
||||
return {};
|
||||
|
|
@ -416,6 +463,22 @@ export class SettingsManager {
|
|||
this.save();
|
||||
}
|
||||
|
||||
getPackages(): PackageSource[] {
|
||||
return [...(this.settings.packages ?? [])];
|
||||
}
|
||||
|
||||
setPackages(packages: PackageSource[]): void {
|
||||
this.globalSettings.packages = packages;
|
||||
this.save();
|
||||
}
|
||||
|
||||
setProjectPackages(packages: PackageSource[]): void {
|
||||
const projectSettings = this.loadProjectSettings();
|
||||
projectSettings.packages = packages;
|
||||
this.saveProjectSettings(projectSettings);
|
||||
this.settings = deepMergeSettings(this.globalSettings, projectSettings);
|
||||
}
|
||||
|
||||
getExtensionPaths(): string[] {
|
||||
return [...(this.settings.extensions ?? [])];
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue