ai-factory 2.0.0 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (91) hide show
  1. package/README.md +17 -4
  2. package/dist/cli/commands/extension.d.ts +4 -0
  3. package/dist/cli/commands/extension.d.ts.map +1 -0
  4. package/dist/cli/commands/extension.js +288 -0
  5. package/dist/cli/commands/extension.js.map +1 -0
  6. package/dist/cli/commands/init.d.ts.map +1 -1
  7. package/dist/cli/commands/init.js +31 -35
  8. package/dist/cli/commands/init.js.map +1 -1
  9. package/dist/cli/commands/update.d.ts.map +1 -1
  10. package/dist/cli/commands/update.js +86 -7
  11. package/dist/cli/commands/update.js.map +1 -1
  12. package/dist/cli/commands/upgrade.d.ts.map +1 -1
  13. package/dist/cli/commands/upgrade.js +44 -41
  14. package/dist/cli/commands/upgrade.js.map +1 -1
  15. package/dist/cli/index.js +48 -1
  16. package/dist/cli/index.js.map +1 -1
  17. package/dist/cli/wizard/prompts.d.ts +2 -1
  18. package/dist/cli/wizard/prompts.d.ts.map +1 -1
  19. package/dist/cli/wizard/prompts.js +13 -20
  20. package/dist/cli/wizard/prompts.js.map +1 -1
  21. package/dist/core/agents.d.ts.map +1 -1
  22. package/dist/core/agents.js +9 -0
  23. package/dist/core/agents.js.map +1 -1
  24. package/dist/core/config.d.ts +8 -2
  25. package/dist/core/config.d.ts.map +1 -1
  26. package/dist/core/config.js +5 -8
  27. package/dist/core/config.js.map +1 -1
  28. package/dist/core/extension-ops.d.ts +32 -0
  29. package/dist/core/extension-ops.d.ts.map +1 -0
  30. package/dist/core/extension-ops.js +83 -0
  31. package/dist/core/extension-ops.js.map +1 -0
  32. package/dist/core/extensions.d.ts +53 -0
  33. package/dist/core/extensions.d.ts.map +1 -0
  34. package/dist/core/extensions.js +141 -0
  35. package/dist/core/extensions.js.map +1 -0
  36. package/dist/core/injections.d.ts +10 -0
  37. package/dist/core/injections.d.ts.map +1 -0
  38. package/dist/core/injections.js +154 -0
  39. package/dist/core/injections.js.map +1 -0
  40. package/dist/core/installer.d.ts +7 -3
  41. package/dist/core/installer.d.ts.map +1 -1
  42. package/dist/core/installer.js +68 -26
  43. package/dist/core/installer.js.map +1 -1
  44. package/dist/core/mcp.d.ts +12 -0
  45. package/dist/core/mcp.d.ts.map +1 -1
  46. package/dist/core/mcp.js +112 -67
  47. package/dist/core/mcp.js.map +1 -1
  48. package/dist/core/transformer.d.ts +10 -1
  49. package/dist/core/transformer.d.ts.map +1 -1
  50. package/dist/core/transformer.js +19 -1
  51. package/dist/core/transformer.js.map +1 -1
  52. package/dist/core/transformers/antigravity.d.ts +1 -0
  53. package/dist/core/transformers/antigravity.d.ts.map +1 -1
  54. package/dist/core/transformers/antigravity.js +19 -4
  55. package/dist/core/transformers/antigravity.js.map +1 -1
  56. package/dist/core/transformers/codex.d.ts +7 -0
  57. package/dist/core/transformers/codex.d.ts.map +1 -0
  58. package/dist/core/transformers/codex.js +24 -0
  59. package/dist/core/transformers/codex.js.map +1 -0
  60. package/dist/core/transformers/default.d.ts +1 -0
  61. package/dist/core/transformers/default.d.ts.map +1 -1
  62. package/dist/core/transformers/default.js +6 -0
  63. package/dist/core/transformers/default.js.map +1 -1
  64. package/dist/core/transformers/kilocode.js +1 -1
  65. package/dist/core/transformers/kilocode.js.map +1 -1
  66. package/dist/core/transformers/qwen.d.ts +7 -0
  67. package/dist/core/transformers/qwen.d.ts.map +1 -0
  68. package/dist/core/transformers/qwen.js +25 -0
  69. package/dist/core/transformers/qwen.js.map +1 -0
  70. package/dist/utils/fs.d.ts +0 -2
  71. package/dist/utils/fs.d.ts.map +1 -1
  72. package/dist/utils/fs.js +1 -5
  73. package/dist/utils/fs.js.map +1 -1
  74. package/mcp/templates/playwright.json +4 -0
  75. package/package.json +16 -1
  76. package/skills/aif/SKILL.md +27 -52
  77. package/skills/aif-commit/SKILL.md +13 -1
  78. package/skills/aif-grounded/SKILL.md +90 -0
  79. package/skills/aif-implement/SKILL.md +39 -2
  80. package/skills/aif-implement/references/IMPLEMENTATION-GUIDE.md +16 -0
  81. package/skills/aif-loop/SKILL.md +2 -2
  82. package/dist/cli/wizard/detector.d.ts +0 -10
  83. package/dist/cli/wizard/detector.d.ts.map +0 -1
  84. package/dist/cli/wizard/detector.js +0 -231
  85. package/dist/cli/wizard/detector.js.map +0 -1
  86. package/skills/_templates/nextjs/nextjs-patterns/SKILL.md +0 -146
  87. package/skills/_templates/node-api/api-patterns/SKILL.md +0 -245
  88. package/skills/_templates/php/php-patterns/SKILL.md +0 -491
  89. package/skills/_templates/python/python-patterns/SKILL.md +0 -236
  90. package/skills/_templates/react/react-patterns/SKILL.md +0 -181
  91. package/skills/aif-deploy/SKILL.md +0 -138
@@ -6,7 +6,7 @@ const require = createRequire(import.meta.url);
6
6
  const pkg = require('../../package.json');
7
7
  const CONFIG_FILENAME = '.ai-factory.json';
8
8
  const CURRENT_VERSION = pkg.version;
9
- export function getConfigPath(projectDir) {
9
+ function getConfigPath(projectDir) {
10
10
  return path.join(projectDir, CONFIG_FILENAME);
11
11
  }
12
12
  function normalizeMcp(mcp) {
@@ -15,6 +15,7 @@ function normalizeMcp(mcp) {
15
15
  filesystem: mcp?.filesystem ?? false,
16
16
  postgres: mcp?.postgres ?? false,
17
17
  chromeDevtools: mcp?.chromeDevtools ?? false,
18
+ playwright: mcp?.playwright ?? false,
18
19
  };
19
20
  }
20
21
  function createAgentInstallation(agentId, legacy) {
@@ -26,13 +27,6 @@ function createAgentInstallation(agentId, legacy) {
26
27
  mcp: normalizeMcp(legacy?.mcp),
27
28
  };
28
29
  }
29
- export function createDefaultConfig(agentIds = ['claude']) {
30
- const uniqueAgentIds = Array.from(new Set(agentIds));
31
- return {
32
- version: CURRENT_VERSION,
33
- agents: uniqueAgentIds.map(id => createAgentInstallation(id)),
34
- };
35
- }
36
30
  export async function loadConfig(projectDir) {
37
31
  const configPath = getConfigPath(projectDir);
38
32
  const raw = await readJsonFile(configPath);
@@ -52,17 +46,20 @@ export async function loadConfig(projectDir) {
52
46
  return {
53
47
  version: raw.version ?? CURRENT_VERSION,
54
48
  agents: normalizedAgents,
49
+ extensions: Array.isArray(raw.extensions) ? raw.extensions : [],
55
50
  };
56
51
  }
57
52
  if (raw.agent) {
58
53
  return {
59
54
  version: raw.version ?? CURRENT_VERSION,
60
55
  agents: [createAgentInstallation(raw.agent, raw)],
56
+ extensions: [],
61
57
  };
62
58
  }
63
59
  return {
64
60
  version: raw.version ?? CURRENT_VERSION,
65
61
  agents: [],
62
+ extensions: [],
66
63
  };
67
64
  }
68
65
  export async function saveConfig(projectDir, config) {
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/core/config.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/core/config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,32 @@
1
+ import type { AgentInstallation, ExtensionRecord } from './config.js';
2
+ import type { ExtensionManifest } from './extensions.js';
3
+ /**
4
+ * Install base skills on all agents.
5
+ */
6
+ export declare function installSkillsForAllAgents(projectDir: string, agents: AgentInstallation[], skills: string[]): Promise<void>;
7
+ /**
8
+ * Remove extension skills from all agents. Returns per-agent removed lists.
9
+ */
10
+ export declare function removeSkillsForAllAgents(projectDir: string, agents: AgentInstallation[], skillNames: string[]): Promise<Map<string, string[]>>;
11
+ /**
12
+ * Install extension skills on all agents. Returns per-agent installed lists.
13
+ */
14
+ export declare function installExtensionSkillsForAllAgents(projectDir: string, agents: AgentInstallation[], extensionDir: string, skillPaths: string[], nameOverrides?: Record<string, string>): Promise<Map<string, string[]>>;
15
+ /**
16
+ * Collect all replaced skills from extensions, optionally excluding one extension by name.
17
+ */
18
+ export declare function collectReplacedSkills(extensions: ExtensionRecord[], excludeName?: string): Set<string>;
19
+ /**
20
+ * Restore base skills that were previously replaced, filtering out skills still replaced by other extensions.
21
+ */
22
+ export declare function restoreBaseSkills(projectDir: string, agents: AgentInstallation[], skillNames: string[], excludeStillReplaced: Set<string>): Promise<string[]>;
23
+ /**
24
+ * Strip extension injections from all agents. Uses manifest if available, falls back to name-based scan.
25
+ */
26
+ export declare function stripInjectionsForAllAgents(projectDir: string, agents: AgentInstallation[], extensionName: string, manifest?: ExtensionManifest | null): Promise<void>;
27
+ /**
28
+ * Remove custom (non-replacement) skills from all agents based on the manifest.
29
+ * Returns the list of custom skill paths that were targeted for removal.
30
+ */
31
+ export declare function removeCustomSkillsForAllAgents(projectDir: string, agents: AgentInstallation[], manifest: ExtensionManifest): Promise<Map<string, string[]>>;
32
+ //# sourceMappingURL=extension-ops.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extension-ops.d.ts","sourceRoot":"","sources":["../../src/core/extension-ops.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACtE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAIzD;;GAEG;AACH,wBAAsB,yBAAyB,CAC7C,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,iBAAiB,EAAE,EAC3B,MAAM,EAAE,MAAM,EAAE,GACf,OAAO,CAAC,IAAI,CAAC,CAIf;AAED;;GAEG;AACH,wBAAsB,wBAAwB,CAC5C,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,iBAAiB,EAAE,EAC3B,UAAU,EAAE,MAAM,EAAE,GACnB,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC,CAOhC;AAED;;GAEG;AACH,wBAAsB,kCAAkC,CACtD,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,iBAAiB,EAAE,EAC3B,YAAY,EAAE,MAAM,EACpB,UAAU,EAAE,MAAM,EAAE,EACpB,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GACrC,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC,CAOhC;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,UAAU,EAAE,eAAe,EAAE,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,CAStG;AAED;;GAEG;AACH,wBAAsB,iBAAiB,CACrC,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,iBAAiB,EAAE,EAC3B,UAAU,EAAE,MAAM,EAAE,EACpB,oBAAoB,EAAE,GAAG,CAAC,MAAM,CAAC,GAChC,OAAO,CAAC,MAAM,EAAE,CAAC,CAOnB;AAED;;GAEG;AACH,wBAAsB,2BAA2B,CAC/C,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,iBAAiB,EAAE,EAC3B,aAAa,EAAE,MAAM,EACrB,QAAQ,CAAC,EAAE,iBAAiB,GAAG,IAAI,GAClC,OAAO,CAAC,IAAI,CAAC,CAQf;AAED;;;GAGG;AACH,wBAAsB,8BAA8B,CAClD,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,iBAAiB,EAAE,EAC3B,QAAQ,EAAE,iBAAiB,GAC1B,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC,CAKhC"}
@@ -0,0 +1,83 @@
1
+ import { installSkills, getAvailableSkills, installExtensionSkills, removeExtensionSkills } from './installer.js';
2
+ import { stripAllExtensionInjections, stripInjectionsByExtensionName } from './injections.js';
3
+ /**
4
+ * Install base skills on all agents.
5
+ */
6
+ export async function installSkillsForAllAgents(projectDir, agents, skills) {
7
+ for (const agent of agents) {
8
+ await installSkills({ projectDir, skillsDir: agent.skillsDir, skills, agentId: agent.id });
9
+ }
10
+ }
11
+ /**
12
+ * Remove extension skills from all agents. Returns per-agent removed lists.
13
+ */
14
+ export async function removeSkillsForAllAgents(projectDir, agents, skillNames) {
15
+ const results = new Map();
16
+ for (const agent of agents) {
17
+ const removed = await removeExtensionSkills(projectDir, agent, skillNames);
18
+ results.set(agent.id, removed);
19
+ }
20
+ return results;
21
+ }
22
+ /**
23
+ * Install extension skills on all agents. Returns per-agent installed lists.
24
+ */
25
+ export async function installExtensionSkillsForAllAgents(projectDir, agents, extensionDir, skillPaths, nameOverrides) {
26
+ const results = new Map();
27
+ for (const agent of agents) {
28
+ const installed = await installExtensionSkills(projectDir, agent, extensionDir, skillPaths, nameOverrides);
29
+ results.set(agent.id, installed);
30
+ }
31
+ return results;
32
+ }
33
+ /**
34
+ * Collect all replaced skills from extensions, optionally excluding one extension by name.
35
+ */
36
+ export function collectReplacedSkills(extensions, excludeName) {
37
+ const result = new Set();
38
+ for (const ext of extensions) {
39
+ if (excludeName && ext.name === excludeName)
40
+ continue;
41
+ if (ext.replacedSkills?.length) {
42
+ for (const s of ext.replacedSkills)
43
+ result.add(s);
44
+ }
45
+ }
46
+ return result;
47
+ }
48
+ /**
49
+ * Restore base skills that were previously replaced, filtering out skills still replaced by other extensions.
50
+ */
51
+ export async function restoreBaseSkills(projectDir, agents, skillNames, excludeStillReplaced) {
52
+ const available = await getAvailableSkills();
53
+ const toRestore = skillNames.filter(s => available.includes(s) && !excludeStillReplaced.has(s));
54
+ if (toRestore.length > 0) {
55
+ await installSkillsForAllAgents(projectDir, agents, toRestore);
56
+ }
57
+ return toRestore;
58
+ }
59
+ /**
60
+ * Strip extension injections from all agents. Uses manifest if available, falls back to name-based scan.
61
+ */
62
+ export async function stripInjectionsForAllAgents(projectDir, agents, extensionName, manifest) {
63
+ for (const agent of agents) {
64
+ if (manifest) {
65
+ await stripAllExtensionInjections(projectDir, agent, extensionName, manifest);
66
+ }
67
+ else {
68
+ await stripInjectionsByExtensionName(projectDir, agent, extensionName);
69
+ }
70
+ }
71
+ }
72
+ /**
73
+ * Remove custom (non-replacement) skills from all agents based on the manifest.
74
+ * Returns the list of custom skill paths that were targeted for removal.
75
+ */
76
+ export async function removeCustomSkillsForAllAgents(projectDir, agents, manifest) {
77
+ const replacesPaths = new Set(Object.keys(manifest.replaces ?? {}));
78
+ const customSkills = (manifest.skills ?? []).filter(s => !replacesPaths.has(s));
79
+ if (customSkills.length === 0)
80
+ return new Map();
81
+ return removeSkillsForAllAgents(projectDir, agents, customSkills);
82
+ }
83
+ //# sourceMappingURL=extension-ops.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extension-ops.js","sourceRoot":"","sources":["../../src/core/extension-ops.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,53 @@
1
+ export interface ExtensionInjection {
2
+ target: string;
3
+ position: 'append' | 'prepend';
4
+ file: string;
5
+ }
6
+ export interface ExtensionCommand {
7
+ name: string;
8
+ description: string;
9
+ module: string;
10
+ }
11
+ export interface ExtensionAgentDef {
12
+ id: string;
13
+ displayName: string;
14
+ configDir: string;
15
+ skillsDir: string;
16
+ settingsFile: string | null;
17
+ supportsMcp: boolean;
18
+ skillsCliAgent: string | null;
19
+ }
20
+ export interface ExtensionMcpServer {
21
+ key: string;
22
+ template: string;
23
+ instruction?: string;
24
+ }
25
+ export interface ExtensionManifest {
26
+ name: string;
27
+ version: string;
28
+ description?: string;
29
+ commands?: ExtensionCommand[];
30
+ agents?: ExtensionAgentDef[];
31
+ injections?: ExtensionInjection[];
32
+ skills?: string[];
33
+ replaces?: Record<string, string>;
34
+ mcpServers?: ExtensionMcpServer[];
35
+ }
36
+ export declare function validateExtensionName(name: string): void;
37
+ export declare function validateSkillName(name: string): void;
38
+ export declare function getExtensionsDir(projectDir: string): string;
39
+ export declare function loadExtensionManifest(extensionDir: string): Promise<ExtensionManifest | null>;
40
+ export declare function loadAllExtensions(projectDir: string, registeredNames: string[]): Promise<{
41
+ dir: string;
42
+ manifest: ExtensionManifest;
43
+ }[]>;
44
+ export interface ResolvedExtension {
45
+ manifest: ExtensionManifest;
46
+ sourceDir: string;
47
+ tempDir?: string;
48
+ cleanup: () => Promise<void>;
49
+ }
50
+ export declare function resolveExtension(projectDir: string, source: string): Promise<ResolvedExtension>;
51
+ export declare function commitExtensionInstall(projectDir: string, resolved: ResolvedExtension): Promise<void>;
52
+ export declare function removeExtensionFiles(projectDir: string, name: string): Promise<void>;
53
+ //# sourceMappingURL=extensions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extensions.d.ts","sourceRoot":"","sources":["../../src/core/extensions.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,QAAQ,GAAG,SAAS,CAAC;IAC/B,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,WAAW,EAAE,OAAO,CAAC;IACrB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;CAC/B;AAED,MAAM,WAAW,kBAAkB;IACjC,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,gBAAgB,EAAE,CAAC;IAC9B,MAAM,CAAC,EAAE,iBAAiB,EAAE,CAAC;IAC7B,UAAU,CAAC,EAAE,kBAAkB,EAAE,CAAC;IAClC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClC,UAAU,CAAC,EAAE,kBAAkB,EAAE,CAAC;CACnC;AAMD,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAIxD;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAIpD;AAED,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAE3D;AAED,wBAAsB,qBAAqB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC,CAanG;AAED,wBAAsB,iBAAiB,CACrC,UAAU,EAAE,MAAM,EAClB,eAAe,EAAE,MAAM,EAAE,GACxB,OAAO,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,iBAAiB,CAAA;CAAE,EAAE,CAAC,CAkBzD;AAiBD,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9B;AAyDD,wBAAsB,gBAAgB,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAQrG;AAED,wBAAsB,sBAAsB,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAc3G;AAED,wBAAsB,oBAAoB,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAS1F"}
@@ -0,0 +1,141 @@
1
+ import path from 'path';
2
+ import fs from 'fs-extra';
3
+ import { readJsonFile, removeDirectory, ensureDir } from '../utils/fs.js';
4
+ const EXTENSIONS_DIR = 'extensions';
5
+ const SAFE_NAME_PATTERN = /^[a-zA-Z0-9_@][\w.@/-]*$/;
6
+ const SAFE_SKILL_NAME_PATTERN = /^[a-zA-Z0-9][\w.-]*$/;
7
+ export function validateExtensionName(name) {
8
+ if (!SAFE_NAME_PATTERN.test(name) || name.includes('..') || path.isAbsolute(name)) {
9
+ throw new Error(`Invalid extension name: "${name}". Names must be alphanumeric (with -, _, @, /) and cannot contain ".." or absolute paths.`);
10
+ }
11
+ }
12
+ export function validateSkillName(name) {
13
+ if (!SAFE_SKILL_NAME_PATTERN.test(name) || name.includes('..') || name.includes('/') || name.includes('\\') || path.isAbsolute(name)) {
14
+ throw new Error(`Invalid skill name: "${name}". Skill names must be simple identifiers (letters, digits, -, _, .).`);
15
+ }
16
+ }
17
+ export function getExtensionsDir(projectDir) {
18
+ return path.join(projectDir, '.ai-factory', EXTENSIONS_DIR);
19
+ }
20
+ export async function loadExtensionManifest(extensionDir) {
21
+ const manifestPath = path.join(extensionDir, 'extension.json');
22
+ const manifest = await readJsonFile(manifestPath);
23
+ if (!manifest || !manifest.name || !manifest.version) {
24
+ return null;
25
+ }
26
+ validateExtensionName(manifest.name);
27
+ if (manifest.replaces) {
28
+ for (const baseSkillName of Object.values(manifest.replaces)) {
29
+ validateSkillName(baseSkillName);
30
+ }
31
+ }
32
+ return manifest;
33
+ }
34
+ export async function loadAllExtensions(projectDir, registeredNames) {
35
+ const extensionsDir = getExtensionsDir(projectDir);
36
+ const results = [];
37
+ for (const name of registeredNames) {
38
+ try {
39
+ validateExtensionName(name);
40
+ }
41
+ catch {
42
+ continue;
43
+ }
44
+ const extDir = path.join(extensionsDir, name);
45
+ const manifest = await loadExtensionManifest(extDir);
46
+ if (manifest) {
47
+ results.push({ dir: extDir, manifest });
48
+ }
49
+ }
50
+ return results;
51
+ }
52
+ function isGitUrl(source) {
53
+ return source.startsWith('git+') ||
54
+ source.startsWith('git://') ||
55
+ source.endsWith('.git') ||
56
+ source.includes('github.com/') ||
57
+ source.includes('gitlab.com/');
58
+ }
59
+ function isLocalPath(source) {
60
+ return source.startsWith('./') || source.startsWith('/') || source.startsWith('../') || path.isAbsolute(source);
61
+ }
62
+ async function resolveFromLocal(sourcePath) {
63
+ const resolvedSource = path.resolve(sourcePath);
64
+ const manifest = await loadExtensionManifest(resolvedSource);
65
+ if (!manifest) {
66
+ throw new Error(`Invalid extension: no valid extension.json found in ${resolvedSource}`);
67
+ }
68
+ return { manifest, sourceDir: resolvedSource, cleanup: async () => { } };
69
+ }
70
+ async function resolveFromNpm(projectDir, packageName) {
71
+ const { execFileSync } = await import('child_process');
72
+ const tmpDir = path.join(getExtensionsDir(projectDir), '.tmp-install');
73
+ await removeDirectory(tmpDir);
74
+ await ensureDir(tmpDir);
75
+ execFileSync('npm', ['pack', packageName, '--pack-destination', tmpDir], { stdio: 'pipe' });
76
+ const files = await fs.readdir(tmpDir);
77
+ const tgzFile = files.find(f => f.endsWith('.tgz'));
78
+ if (!tgzFile) {
79
+ await removeDirectory(tmpDir);
80
+ throw new Error('npm pack produced no output');
81
+ }
82
+ const extractDir = path.join(tmpDir, 'extracted');
83
+ await ensureDir(extractDir);
84
+ execFileSync('tar', ['-xzf', path.join(tmpDir, tgzFile), '-C', extractDir], { stdio: 'pipe' });
85
+ const packageDir = path.join(extractDir, 'package');
86
+ const manifest = await loadExtensionManifest(packageDir);
87
+ if (!manifest) {
88
+ await removeDirectory(tmpDir);
89
+ throw new Error(`Invalid extension: no valid extension.json in ${packageName}`);
90
+ }
91
+ return { manifest, sourceDir: packageDir, tempDir: tmpDir, cleanup: () => removeDirectory(tmpDir) };
92
+ }
93
+ async function resolveFromGit(projectDir, url) {
94
+ const { execFileSync } = await import('child_process');
95
+ const tmpDir = path.join(getExtensionsDir(projectDir), '.tmp-clone');
96
+ await removeDirectory(tmpDir);
97
+ const cleanUrl = url.replace(/^git\+/, '');
98
+ execFileSync('git', ['clone', '--depth', '1', cleanUrl, tmpDir], { stdio: 'pipe' });
99
+ const manifest = await loadExtensionManifest(tmpDir);
100
+ if (!manifest) {
101
+ await removeDirectory(tmpDir);
102
+ throw new Error(`Invalid extension: no valid extension.json in ${url}`);
103
+ }
104
+ return { manifest, sourceDir: tmpDir, tempDir: tmpDir, cleanup: () => removeDirectory(tmpDir) };
105
+ }
106
+ export async function resolveExtension(projectDir, source) {
107
+ if (isLocalPath(source)) {
108
+ return resolveFromLocal(source);
109
+ }
110
+ if (isGitUrl(source)) {
111
+ return resolveFromGit(projectDir, source);
112
+ }
113
+ return resolveFromNpm(projectDir, source);
114
+ }
115
+ export async function commitExtensionInstall(projectDir, resolved) {
116
+ const targetDir = path.join(getExtensionsDir(projectDir), resolved.manifest.name);
117
+ await ensureDir(targetDir);
118
+ if (resolved.sourceDir === resolved.tempDir && await fs.pathExists(path.join(resolved.sourceDir, '.git'))) {
119
+ // Git clone: copy everything except .git
120
+ const entries = await fs.readdir(resolved.sourceDir);
121
+ for (const entry of entries) {
122
+ if (entry === '.git')
123
+ continue;
124
+ await fs.copy(path.join(resolved.sourceDir, entry), path.join(targetDir, entry), { overwrite: true });
125
+ }
126
+ }
127
+ else {
128
+ await fs.copy(resolved.sourceDir, targetDir, { overwrite: true });
129
+ }
130
+ }
131
+ export async function removeExtensionFiles(projectDir, name) {
132
+ validateExtensionName(name);
133
+ const targetDir = path.join(getExtensionsDir(projectDir), name);
134
+ // Verify target stays within extensions dir
135
+ const extensionsDir = getExtensionsDir(projectDir);
136
+ if (!path.resolve(targetDir).startsWith(path.resolve(extensionsDir) + path.sep)) {
137
+ throw new Error(`Extension path escapes extensions directory: "${name}"`);
138
+ }
139
+ await removeDirectory(targetDir);
140
+ }
141
+ //# sourceMappingURL=extensions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extensions.js","sourceRoot":"","sources":["../../src/core/extensions.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import type { AgentInstallation } from './config.js';
2
+ import type { ExtensionRecord } from './config.js';
3
+ import { type ExtensionManifest } from './extensions.js';
4
+ export declare function stripInjection(content: string, extensionName: string, skillName: string, position: string): string;
5
+ export declare function applyInjection(skillContent: string, injectionContent: string, position: 'append' | 'prepend', extensionName: string, skillName: string): string;
6
+ export declare function applyExtensionInjections(projectDir: string, agent: AgentInstallation, registeredExtensions: ExtensionRecord[]): Promise<number>;
7
+ export declare function applySingleExtensionInjections(projectDir: string, agent: AgentInstallation, extensionDir: string, manifest: ExtensionManifest): Promise<number>;
8
+ export declare function stripAllExtensionInjections(projectDir: string, agent: AgentInstallation, extensionName: string, manifest: ExtensionManifest): Promise<void>;
9
+ export declare function stripInjectionsByExtensionName(projectDir: string, agent: AgentInstallation, extensionName: string): Promise<void>;
10
+ //# sourceMappingURL=injections.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"injections.d.ts","sourceRoot":"","sources":["../../src/core/injections.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AACrD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEnD,OAAO,EAAqB,KAAK,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAiB5E,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAElH;AAED,wBAAgB,cAAc,CAC5B,YAAY,EAAE,MAAM,EACpB,gBAAgB,EAAE,MAAM,EACxB,QAAQ,EAAE,QAAQ,GAAG,SAAS,EAC9B,aAAa,EAAE,MAAM,EACrB,SAAS,EAAE,MAAM,GAChB,MAAM,CAwBR;AAiBD,wBAAsB,wBAAwB,CAC5C,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,iBAAiB,EACxB,oBAAoB,EAAE,eAAe,EAAE,GACtC,OAAO,CAAC,MAAM,CAAC,CA+BjB;AAED,wBAAsB,8BAA8B,CAClD,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,iBAAiB,EACxB,YAAY,EAAE,MAAM,EACpB,QAAQ,EAAE,iBAAiB,GAC1B,OAAO,CAAC,MAAM,CAAC,CA0BjB;AAED,wBAAsB,2BAA2B,CAC/C,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,iBAAiB,EACxB,aAAa,EAAE,MAAM,EACrB,QAAQ,EAAE,iBAAiB,GAC1B,OAAO,CAAC,IAAI,CAAC,CAaf;AAkCD,wBAAsB,8BAA8B,CAClD,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,iBAAiB,EACxB,aAAa,EAAE,MAAM,GACpB,OAAO,CAAC,IAAI,CAAC,CAgBf"}
@@ -0,0 +1,154 @@
1
+ import path from 'path';
2
+ import fs from 'fs-extra';
3
+ import { readTextFile, writeTextFile } from '../utils/fs.js';
4
+ import { getAgentConfig } from './agents.js';
5
+ import { loadAllExtensions } from './extensions.js';
6
+ import { getTransformer } from './transformer.js';
7
+ function startMarker(extensionName, skillName, position) {
8
+ return `<!-- aif-ext:${extensionName}:${skillName}:${position}:start -->`;
9
+ }
10
+ function endMarker(extensionName, skillName, position) {
11
+ return `<!-- aif-ext:${extensionName}:${skillName}:${position}:end -->`;
12
+ }
13
+ function markerRegex(extensionName, skillName, position) {
14
+ const start = startMarker(extensionName, skillName, position).replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
15
+ const end = endMarker(extensionName, skillName, position).replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
16
+ return new RegExp(`\\n?${start}\\n[\\s\\S]*?\\n${end}\\n?`, 'g');
17
+ }
18
+ export function stripInjection(content, extensionName, skillName, position) {
19
+ return content.replace(markerRegex(extensionName, skillName, position), '');
20
+ }
21
+ export function applyInjection(skillContent, injectionContent, position, extensionName, skillName) {
22
+ // First strip existing injection for idempotency
23
+ let content = stripInjection(skillContent, extensionName, skillName, position);
24
+ const block = [
25
+ startMarker(extensionName, skillName, position),
26
+ injectionContent.trimEnd(),
27
+ endMarker(extensionName, skillName, position),
28
+ ].join('\n');
29
+ if (position === 'append') {
30
+ content = content.trimEnd() + '\n\n' + block + '\n';
31
+ }
32
+ else {
33
+ // prepend: after frontmatter if present
34
+ const fmMatch = content.match(/^---\n[\s\S]*?\n---\n/);
35
+ if (fmMatch) {
36
+ const afterFm = fmMatch[0].length;
37
+ content = content.slice(0, afterFm) + '\n' + block + '\n' + content.slice(afterFm);
38
+ }
39
+ else {
40
+ content = block + '\n\n' + content;
41
+ }
42
+ }
43
+ return content;
44
+ }
45
+ function getSkillFilePath(projectDir, agent, skillName) {
46
+ const transformer = getTransformer(agent.id);
47
+ const result = transformer.transform(skillName, '');
48
+ const agentConfig = getAgentConfig(agent.id);
49
+ if (result.flat) {
50
+ return path.join(projectDir, agentConfig.configDir, result.targetDir, result.targetName);
51
+ }
52
+ return path.join(projectDir, agent.skillsDir, result.targetDir, 'SKILL.md');
53
+ }
54
+ export async function applyExtensionInjections(projectDir, agent, registeredExtensions) {
55
+ const names = registeredExtensions.map(e => e.name);
56
+ const extensions = await loadAllExtensions(projectDir, names);
57
+ let count = 0;
58
+ for (const { dir, manifest } of extensions) {
59
+ if (!manifest.injections?.length)
60
+ continue;
61
+ for (const injection of manifest.injections) {
62
+ const skillFilePath = getSkillFilePath(projectDir, agent, injection.target);
63
+ const skillContent = await readTextFile(skillFilePath);
64
+ if (!skillContent)
65
+ continue;
66
+ const injectionFilePath = path.join(dir, injection.file);
67
+ const injectionContent = await readTextFile(injectionFilePath);
68
+ if (!injectionContent)
69
+ continue;
70
+ const updated = applyInjection(skillContent, injectionContent, injection.position, manifest.name, injection.target);
71
+ await writeTextFile(skillFilePath, updated);
72
+ count++;
73
+ }
74
+ }
75
+ return count;
76
+ }
77
+ export async function applySingleExtensionInjections(projectDir, agent, extensionDir, manifest) {
78
+ if (!manifest.injections?.length)
79
+ return 0;
80
+ let count = 0;
81
+ for (const injection of manifest.injections) {
82
+ const skillFilePath = getSkillFilePath(projectDir, agent, injection.target);
83
+ const skillContent = await readTextFile(skillFilePath);
84
+ if (!skillContent)
85
+ continue;
86
+ const injectionFilePath = path.join(extensionDir, injection.file);
87
+ const injectionContent = await readTextFile(injectionFilePath);
88
+ if (!injectionContent)
89
+ continue;
90
+ const updated = applyInjection(skillContent, injectionContent, injection.position, manifest.name, injection.target);
91
+ await writeTextFile(skillFilePath, updated);
92
+ count++;
93
+ }
94
+ return count;
95
+ }
96
+ export async function stripAllExtensionInjections(projectDir, agent, extensionName, manifest) {
97
+ if (!manifest.injections?.length)
98
+ return;
99
+ for (const injection of manifest.injections) {
100
+ const skillFilePath = getSkillFilePath(projectDir, agent, injection.target);
101
+ const skillContent = await readTextFile(skillFilePath);
102
+ if (!skillContent)
103
+ continue;
104
+ const updated = stripInjection(skillContent, extensionName, injection.target, injection.position);
105
+ if (updated !== skillContent) {
106
+ await writeTextFile(skillFilePath, updated);
107
+ }
108
+ }
109
+ }
110
+ function extensionMarkerRegex(extensionName) {
111
+ const escaped = extensionName.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
112
+ return new RegExp(`\\n?<!-- aif-ext:${escaped}:[^:]+:[^:]+:start -->\\n[\\s\\S]*?\\n<!-- aif-ext:${escaped}:[^:]+:[^:]+:end -->\\n?`, 'g');
113
+ }
114
+ function stripAllMarkersForExtension(content, extensionName) {
115
+ return content.replace(extensionMarkerRegex(extensionName), '');
116
+ }
117
+ async function findMarkdownFiles(dir) {
118
+ const results = [];
119
+ try {
120
+ const entries = await fs.readdir(dir, { withFileTypes: true });
121
+ for (const entry of entries) {
122
+ const fullPath = path.join(dir, entry.name);
123
+ if (entry.isDirectory()) {
124
+ // Recurse into subdirectories (covers skills/*/SKILL.md, workflows/*.md, rules/*.md)
125
+ const nested = await findMarkdownFiles(fullPath);
126
+ results.push(...nested);
127
+ }
128
+ else if (entry.isFile() && entry.name.endsWith('.md')) {
129
+ results.push(fullPath);
130
+ }
131
+ }
132
+ }
133
+ catch {
134
+ // dir doesn't exist
135
+ }
136
+ return results;
137
+ }
138
+ export async function stripInjectionsByExtensionName(projectDir, agent, extensionName) {
139
+ // Search agent configDir recursively — covers skills/*/SKILL.md,
140
+ // flat workflow files (e.g. .agent/workflows/*.md), and rules
141
+ const agentConfig = getAgentConfig(agent.id);
142
+ const configDir = path.join(projectDir, agentConfig.configDir);
143
+ const files = await findMarkdownFiles(configDir);
144
+ for (const filePath of files) {
145
+ const content = await readTextFile(filePath);
146
+ if (!content || !content.includes(`aif-ext:${extensionName}:`))
147
+ continue;
148
+ const updated = stripAllMarkersForExtension(content, extensionName);
149
+ if (updated !== content) {
150
+ await writeTextFile(filePath, updated);
151
+ }
152
+ }
153
+ }
154
+ //# sourceMappingURL=injections.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"injections.js","sourceRoot":"","sources":["../../src/core/injections.ts"],"names":[],"mappings":"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"}
@@ -3,11 +3,15 @@ export interface InstallOptions {
3
3
  projectDir: string;
4
4
  skillsDir: string;
5
5
  skills: string[];
6
- stack: string | null;
7
6
  agentId: string;
8
7
  }
9
8
  export declare function installSkills(options: InstallOptions): Promise<string[]>;
9
+ export declare function partitionSkills(skills: string[]): {
10
+ base: string[];
11
+ custom: string[];
12
+ };
10
13
  export declare function getAvailableSkills(): Promise<string[]>;
11
- export declare function getAvailableTemplates(): Promise<string[]>;
12
- export declare function updateSkills(agentInstallation: AgentInstallation, projectDir: string): Promise<string[]>;
14
+ export declare function installExtensionSkills(projectDir: string, agentInstallation: AgentInstallation, extensionDir: string, skillPaths: string[], nameOverrides?: Record<string, string>): Promise<string[]>;
15
+ export declare function removeExtensionSkills(projectDir: string, agentInstallation: AgentInstallation, skillPaths: string[]): Promise<string[]>;
16
+ export declare function updateSkills(agentInstallation: AgentInstallation, projectDir: string, excludeSkills?: string[]): Promise<string[]>;
13
17
  //# sourceMappingURL=installer.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"installer.d.ts","sourceRoot":"","sources":["../../src/core/installer.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAKrD,MAAM,WAAW,cAAc;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;CACjB;AAiCD,wBAAsB,aAAa,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CA0C9E;AAED,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,CAI5D;AAED,wBAAsB,qBAAqB,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,CAG/D;AAED,wBAAsB,YAAY,CAAC,iBAAiB,EAAE,iBAAiB,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAa9G"}
1
+ {"version":3,"file":"installer.d.ts","sourceRoot":"","sources":["../../src/core/installer.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAKrD,MAAM,WAAW,cAAc;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;CACjB;AAuCD,wBAAsB,aAAa,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CA2B9E;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG;IAAE,IAAI,EAAE,MAAM,EAAE,CAAC;IAAC,MAAM,EAAE,MAAM,EAAE,CAAA;CAAE,CAKtF;AAED,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,CAI5D;AAED,wBAAsB,sBAAsB,CAC1C,UAAU,EAAE,MAAM,EAClB,iBAAiB,EAAE,iBAAiB,EACpC,YAAY,EAAE,MAAM,EACpB,UAAU,EAAE,MAAM,EAAE,EACpB,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GACrC,OAAO,CAAC,MAAM,EAAE,CAAC,CAgBnB;AA8BD,wBAAsB,qBAAqB,CACzC,UAAU,EAAE,MAAM,EAClB,iBAAiB,EAAE,iBAAiB,EACpC,UAAU,EAAE,MAAM,EAAE,GACnB,OAAO,CAAC,MAAM,EAAE,CAAC,CAEnB;AAED,wBAAsB,YAAY,CAAC,iBAAiB,EAAE,iBAAiB,EAAE,UAAU,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAqBxI"}