@ai-agent-forge/agent-forge 0.85.9 → 0.85.11

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.
@@ -1 +1 @@
1
- {"version":3,"file":"bootstrap-factory-manifest.d.ts","sourceRoot":"","sources":["../../../src/plugins/ecosystem/bootstrap-factory-manifest.ts"],"names":[],"mappings":"AAoBA,uDAAuD;AACvD,MAAM,WAAW,6BAA6B;IAC7C,uEAAsE;IACtE,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,iEAAgE;IAChE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB;;;OAGG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;CACxB;AAKD;;;;;;GAMG;AACH,eAAO,MAAM,oCAAoC,EAAE,SAAS,6BAA6B,EAoBvF,CAAC","sourcesContent":["/**\n * Factory plugin manifest for the startup bootstrap (design\n * `插件独立分发与启动装配设计.md` §4.4). Pure data only: the framework\n * declares which first-party plugin packages a fresh install should end up\n * with, as `pluginId → npm name + version constraint`. It ships with the\n * framework version and is never a code branch.\n *\n * Each S2–S4 migrated package appends one entry here with its publish name\n * (`@ai-agent-forge/plugin-<name>`, §0.8) together with the legacy short-id\n * mapping noted in §4.1.\n *\n * Ranges are derived from the framework's own VERSION at module init — a\n * hardcoded range here outlived a lockstep bump once (published 0.85.0 kept\n * `^0.84.4`, which excludes 0.85.0 under caret-on-0.x semantics, breaking\n * every fresh install's npm bootstrap). Deriving keeps the manifest in step\n * with the version the publish channel stamps, including the\n * rename/version rewrite in the local publish script.\n */\nimport { VERSION } from \"../../config.ts\";\n\n/** One factory-declared first-party plugin package. */\nexport interface PluginBootstrapFactoryEntryV1 {\n\t/** Ecosystem plugin id (`agent-forge.plugin.<name>` domain, §4.1). */\n\treadonly pluginId: string;\n\t/** npm publish name (`@ai-agent-forge/plugin-<name>`, §0.8). */\n\treadonly npmName: string;\n\t/**\n\t * Minimal range subset shared with npm resolution (`x.y.z`, `^x.y.z`,\n\t * `~x.y.z`, `latest`); omitted means the highest available version.\n\t */\n\treadonly range?: string;\n}\n\n/** Lockstep range every first-party bootstrap entry ships under. */\nconst FACTORY_PLUGIN_RANGE = `^${VERSION}`;\n\n/**\n * Frozen factory manifest consumed by `runPluginBootstrapV1`. D-075 S4 first\n * batch: the goal/plan/todo-set capability packages joined; second batch:\n * session-share and observability joined; third batch: subagent-delegate\n * joined; fourth batch: memory joined (completing the six-package split).\n * Later B-class batches append their entries per package.\n */\nexport const BOOTSTRAP_FACTORY_PLUGIN_MANIFEST_V1: readonly PluginBootstrapFactoryEntryV1[] = Object.freeze([\n\t{ pluginId: \"agent-forge.plugin.goal\", npmName: \"@ai-agent-forge/plugin-goal\", range: FACTORY_PLUGIN_RANGE },\n\t{ pluginId: \"agent-forge.plugin.plan\", npmName: \"@ai-agent-forge/plugin-plan\", range: FACTORY_PLUGIN_RANGE },\n\t{ pluginId: \"agent-forge.plugin.todo-set\", npmName: \"@ai-agent-forge/plugin-todo-set\", range: FACTORY_PLUGIN_RANGE },\n\t{\n\t\tpluginId: \"agent-forge.plugin.session-share\",\n\t\tnpmName: \"@ai-agent-forge/plugin-session-share\",\n\t\trange: FACTORY_PLUGIN_RANGE,\n\t},\n\t{\n\t\tpluginId: \"agent-forge.plugin.observability\",\n\t\tnpmName: \"@ai-agent-forge/plugin-observability\",\n\t\trange: FACTORY_PLUGIN_RANGE,\n\t},\n\t{\n\t\tpluginId: \"agent-forge.plugin.subagent-delegate\",\n\t\tnpmName: \"@ai-agent-forge/plugin-subagent-delegate\",\n\t\trange: FACTORY_PLUGIN_RANGE,\n\t},\n\t{ pluginId: \"agent-forge.plugin.memory\", npmName: \"@ai-agent-forge/plugin-memory\", range: FACTORY_PLUGIN_RANGE },\n]);\n"]}
1
+ {"version":3,"file":"bootstrap-factory-manifest.d.ts","sourceRoot":"","sources":["../../../src/plugins/ecosystem/bootstrap-factory-manifest.ts"],"names":[],"mappings":"AAoBA,uDAAuD;AACvD,MAAM,WAAW,6BAA6B;IAC7C,uEAAsE;IACtE,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,iEAAgE;IAChE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB;;;OAGG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;CACxB;AAKD;;;;;;GAMG;AACH,eAAO,MAAM,oCAAoC,EAAE,SAAS,6BAA6B,EA0BvF,CAAC","sourcesContent":["/**\n * Factory plugin manifest for the startup bootstrap (design\n * `插件独立分发与启动装配设计.md` §4.4). Pure data only: the framework\n * declares which first-party plugin packages a fresh install should end up\n * with, as `pluginId → npm name + version constraint`. It ships with the\n * framework version and is never a code branch.\n *\n * Each S2–S4 migrated package appends one entry here with its publish name\n * (`@ai-agent-forge/plugin-<name>`, §0.8) together with the legacy short-id\n * mapping noted in §4.1.\n *\n * Ranges are derived from the framework's own VERSION at module init — a\n * hardcoded range here outlived a lockstep bump once (published 0.85.0 kept\n * `^0.84.4`, which excludes 0.85.0 under caret-on-0.x semantics, breaking\n * every fresh install's npm bootstrap). Deriving keeps the manifest in step\n * with the version the publish channel stamps, including the\n * rename/version rewrite in the local publish script.\n */\nimport { VERSION } from \"../../config.ts\";\n\n/** One factory-declared first-party plugin package. */\nexport interface PluginBootstrapFactoryEntryV1 {\n\t/** Ecosystem plugin id (`agent-forge.plugin.<name>` domain, §4.1). */\n\treadonly pluginId: string;\n\t/** npm publish name (`@ai-agent-forge/plugin-<name>`, §0.8). */\n\treadonly npmName: string;\n\t/**\n\t * Minimal range subset shared with npm resolution (`x.y.z`, `^x.y.z`,\n\t * `~x.y.z`, `latest`); omitted means the highest available version.\n\t */\n\treadonly range?: string;\n}\n\n/** Lockstep range every first-party bootstrap entry ships under. */\nconst FACTORY_PLUGIN_RANGE = `^${VERSION}`;\n\n/**\n * Frozen factory manifest consumed by `runPluginBootstrapV1`. D-075 S4 first\n * batch: the goal/plan/todo-set capability packages joined; second batch:\n * session-share and observability joined; third batch: subagent-delegate\n * joined; fourth batch: memory joined (completing the six-package split).\n * Later B-class batches append their entries per package.\n */\nexport const BOOTSTRAP_FACTORY_PLUGIN_MANIFEST_V1: readonly PluginBootstrapFactoryEntryV1[] = Object.freeze([\n\t{ pluginId: \"agent-forge.plugin.goal\", npmName: \"@ai-agent-forge/plugin-goal\", range: FACTORY_PLUGIN_RANGE },\n\t{ pluginId: \"agent-forge.plugin.plan\", npmName: \"@ai-agent-forge/plugin-plan\", range: FACTORY_PLUGIN_RANGE },\n\t{ pluginId: \"agent-forge.plugin.todo-set\", npmName: \"@ai-agent-forge/plugin-todo-set\", range: FACTORY_PLUGIN_RANGE },\n\t{\n\t\tpluginId: \"agent-forge.plugin.session-share\",\n\t\tnpmName: \"@ai-agent-forge/plugin-session-share\",\n\t\trange: FACTORY_PLUGIN_RANGE,\n\t},\n\t{\n\t\tpluginId: \"agent-forge.plugin.observability\",\n\t\tnpmName: \"@ai-agent-forge/plugin-observability\",\n\t\trange: FACTORY_PLUGIN_RANGE,\n\t},\n\t{\n\t\tpluginId: \"agent-forge.plugin.subagent-delegate\",\n\t\tnpmName: \"@ai-agent-forge/plugin-subagent-delegate\",\n\t\trange: FACTORY_PLUGIN_RANGE,\n\t},\n\t{ pluginId: \"agent-forge.plugin.memory\", npmName: \"@ai-agent-forge/plugin-memory\", range: FACTORY_PLUGIN_RANGE },\n\t// image generation (2026-09-30): first-party generate/edit tools package.\n\t{\n\t\tpluginId: \"agent-forge.plugin.image-generation\",\n\t\tnpmName: \"@ai-agent-forge/plugin-image-generation\",\n\t\trange: FACTORY_PLUGIN_RANGE,\n\t},\n]);\n"]}
@@ -46,5 +46,11 @@ export const BOOTSTRAP_FACTORY_PLUGIN_MANIFEST_V1 = Object.freeze([
46
46
  range: FACTORY_PLUGIN_RANGE,
47
47
  },
48
48
  { pluginId: "agent-forge.plugin.memory", npmName: "@ai-agent-forge/plugin-memory", range: FACTORY_PLUGIN_RANGE },
49
+ // image generation (2026-09-30): first-party generate/edit tools package.
50
+ {
51
+ pluginId: "agent-forge.plugin.image-generation",
52
+ npmName: "@ai-agent-forge/plugin-image-generation",
53
+ range: FACTORY_PLUGIN_RANGE,
54
+ },
49
55
  ]);
50
56
  //# sourceMappingURL=bootstrap-factory-manifest.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"bootstrap-factory-manifest.js","sourceRoot":"","sources":["../../../src/plugins/ecosystem/bootstrap-factory-manifest.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAe1C,oEAAoE;AACpE,MAAM,oBAAoB,GAAG,IAAI,OAAO,EAAE,CAAC;AAE3C;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,oCAAoC,GAA6C,MAAM,CAAC,MAAM,CAAC;IAC3G,EAAE,QAAQ,EAAE,yBAAyB,EAAE,OAAO,EAAE,6BAA6B,EAAE,KAAK,EAAE,oBAAoB,EAAE;IAC5G,EAAE,QAAQ,EAAE,yBAAyB,EAAE,OAAO,EAAE,6BAA6B,EAAE,KAAK,EAAE,oBAAoB,EAAE;IAC5G,EAAE,QAAQ,EAAE,6BAA6B,EAAE,OAAO,EAAE,iCAAiC,EAAE,KAAK,EAAE,oBAAoB,EAAE;IACpH;QACC,QAAQ,EAAE,kCAAkC;QAC5C,OAAO,EAAE,sCAAsC;QAC/C,KAAK,EAAE,oBAAoB;KAC3B;IACD;QACC,QAAQ,EAAE,kCAAkC;QAC5C,OAAO,EAAE,sCAAsC;QAC/C,KAAK,EAAE,oBAAoB;KAC3B;IACD;QACC,QAAQ,EAAE,sCAAsC;QAChD,OAAO,EAAE,0CAA0C;QACnD,KAAK,EAAE,oBAAoB;KAC3B;IACD,EAAE,QAAQ,EAAE,2BAA2B,EAAE,OAAO,EAAE,+BAA+B,EAAE,KAAK,EAAE,oBAAoB,EAAE;CAChH,CAAC,CAAC","sourcesContent":["/**\n * Factory plugin manifest for the startup bootstrap (design\n * `插件独立分发与启动装配设计.md` §4.4). Pure data only: the framework\n * declares which first-party plugin packages a fresh install should end up\n * with, as `pluginId → npm name + version constraint`. It ships with the\n * framework version and is never a code branch.\n *\n * Each S2–S4 migrated package appends one entry here with its publish name\n * (`@ai-agent-forge/plugin-<name>`, §0.8) together with the legacy short-id\n * mapping noted in §4.1.\n *\n * Ranges are derived from the framework's own VERSION at module init — a\n * hardcoded range here outlived a lockstep bump once (published 0.85.0 kept\n * `^0.84.4`, which excludes 0.85.0 under caret-on-0.x semantics, breaking\n * every fresh install's npm bootstrap). Deriving keeps the manifest in step\n * with the version the publish channel stamps, including the\n * rename/version rewrite in the local publish script.\n */\nimport { VERSION } from \"../../config.ts\";\n\n/** One factory-declared first-party plugin package. */\nexport interface PluginBootstrapFactoryEntryV1 {\n\t/** Ecosystem plugin id (`agent-forge.plugin.<name>` domain, §4.1). */\n\treadonly pluginId: string;\n\t/** npm publish name (`@ai-agent-forge/plugin-<name>`, §0.8). */\n\treadonly npmName: string;\n\t/**\n\t * Minimal range subset shared with npm resolution (`x.y.z`, `^x.y.z`,\n\t * `~x.y.z`, `latest`); omitted means the highest available version.\n\t */\n\treadonly range?: string;\n}\n\n/** Lockstep range every first-party bootstrap entry ships under. */\nconst FACTORY_PLUGIN_RANGE = `^${VERSION}`;\n\n/**\n * Frozen factory manifest consumed by `runPluginBootstrapV1`. D-075 S4 first\n * batch: the goal/plan/todo-set capability packages joined; second batch:\n * session-share and observability joined; third batch: subagent-delegate\n * joined; fourth batch: memory joined (completing the six-package split).\n * Later B-class batches append their entries per package.\n */\nexport const BOOTSTRAP_FACTORY_PLUGIN_MANIFEST_V1: readonly PluginBootstrapFactoryEntryV1[] = Object.freeze([\n\t{ pluginId: \"agent-forge.plugin.goal\", npmName: \"@ai-agent-forge/plugin-goal\", range: FACTORY_PLUGIN_RANGE },\n\t{ pluginId: \"agent-forge.plugin.plan\", npmName: \"@ai-agent-forge/plugin-plan\", range: FACTORY_PLUGIN_RANGE },\n\t{ pluginId: \"agent-forge.plugin.todo-set\", npmName: \"@ai-agent-forge/plugin-todo-set\", range: FACTORY_PLUGIN_RANGE },\n\t{\n\t\tpluginId: \"agent-forge.plugin.session-share\",\n\t\tnpmName: \"@ai-agent-forge/plugin-session-share\",\n\t\trange: FACTORY_PLUGIN_RANGE,\n\t},\n\t{\n\t\tpluginId: \"agent-forge.plugin.observability\",\n\t\tnpmName: \"@ai-agent-forge/plugin-observability\",\n\t\trange: FACTORY_PLUGIN_RANGE,\n\t},\n\t{\n\t\tpluginId: \"agent-forge.plugin.subagent-delegate\",\n\t\tnpmName: \"@ai-agent-forge/plugin-subagent-delegate\",\n\t\trange: FACTORY_PLUGIN_RANGE,\n\t},\n\t{ pluginId: \"agent-forge.plugin.memory\", npmName: \"@ai-agent-forge/plugin-memory\", range: FACTORY_PLUGIN_RANGE },\n]);\n"]}
1
+ {"version":3,"file":"bootstrap-factory-manifest.js","sourceRoot":"","sources":["../../../src/plugins/ecosystem/bootstrap-factory-manifest.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAe1C,oEAAoE;AACpE,MAAM,oBAAoB,GAAG,IAAI,OAAO,EAAE,CAAC;AAE3C;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,oCAAoC,GAA6C,MAAM,CAAC,MAAM,CAAC;IAC3G,EAAE,QAAQ,EAAE,yBAAyB,EAAE,OAAO,EAAE,6BAA6B,EAAE,KAAK,EAAE,oBAAoB,EAAE;IAC5G,EAAE,QAAQ,EAAE,yBAAyB,EAAE,OAAO,EAAE,6BAA6B,EAAE,KAAK,EAAE,oBAAoB,EAAE;IAC5G,EAAE,QAAQ,EAAE,6BAA6B,EAAE,OAAO,EAAE,iCAAiC,EAAE,KAAK,EAAE,oBAAoB,EAAE;IACpH;QACC,QAAQ,EAAE,kCAAkC;QAC5C,OAAO,EAAE,sCAAsC;QAC/C,KAAK,EAAE,oBAAoB;KAC3B;IACD;QACC,QAAQ,EAAE,kCAAkC;QAC5C,OAAO,EAAE,sCAAsC;QAC/C,KAAK,EAAE,oBAAoB;KAC3B;IACD;QACC,QAAQ,EAAE,sCAAsC;QAChD,OAAO,EAAE,0CAA0C;QACnD,KAAK,EAAE,oBAAoB;KAC3B;IACD,EAAE,QAAQ,EAAE,2BAA2B,EAAE,OAAO,EAAE,+BAA+B,EAAE,KAAK,EAAE,oBAAoB,EAAE;IAChH,0EAA0E;IAC1E;QACC,QAAQ,EAAE,qCAAqC;QAC/C,OAAO,EAAE,yCAAyC;QAClD,KAAK,EAAE,oBAAoB;KAC3B;CACD,CAAC,CAAC","sourcesContent":["/**\n * Factory plugin manifest for the startup bootstrap (design\n * `插件独立分发与启动装配设计.md` §4.4). Pure data only: the framework\n * declares which first-party plugin packages a fresh install should end up\n * with, as `pluginId → npm name + version constraint`. It ships with the\n * framework version and is never a code branch.\n *\n * Each S2–S4 migrated package appends one entry here with its publish name\n * (`@ai-agent-forge/plugin-<name>`, §0.8) together with the legacy short-id\n * mapping noted in §4.1.\n *\n * Ranges are derived from the framework's own VERSION at module init — a\n * hardcoded range here outlived a lockstep bump once (published 0.85.0 kept\n * `^0.84.4`, which excludes 0.85.0 under caret-on-0.x semantics, breaking\n * every fresh install's npm bootstrap). Deriving keeps the manifest in step\n * with the version the publish channel stamps, including the\n * rename/version rewrite in the local publish script.\n */\nimport { VERSION } from \"../../config.ts\";\n\n/** One factory-declared first-party plugin package. */\nexport interface PluginBootstrapFactoryEntryV1 {\n\t/** Ecosystem plugin id (`agent-forge.plugin.<name>` domain, §4.1). */\n\treadonly pluginId: string;\n\t/** npm publish name (`@ai-agent-forge/plugin-<name>`, §0.8). */\n\treadonly npmName: string;\n\t/**\n\t * Minimal range subset shared with npm resolution (`x.y.z`, `^x.y.z`,\n\t * `~x.y.z`, `latest`); omitted means the highest available version.\n\t */\n\treadonly range?: string;\n}\n\n/** Lockstep range every first-party bootstrap entry ships under. */\nconst FACTORY_PLUGIN_RANGE = `^${VERSION}`;\n\n/**\n * Frozen factory manifest consumed by `runPluginBootstrapV1`. D-075 S4 first\n * batch: the goal/plan/todo-set capability packages joined; second batch:\n * session-share and observability joined; third batch: subagent-delegate\n * joined; fourth batch: memory joined (completing the six-package split).\n * Later B-class batches append their entries per package.\n */\nexport const BOOTSTRAP_FACTORY_PLUGIN_MANIFEST_V1: readonly PluginBootstrapFactoryEntryV1[] = Object.freeze([\n\t{ pluginId: \"agent-forge.plugin.goal\", npmName: \"@ai-agent-forge/plugin-goal\", range: FACTORY_PLUGIN_RANGE },\n\t{ pluginId: \"agent-forge.plugin.plan\", npmName: \"@ai-agent-forge/plugin-plan\", range: FACTORY_PLUGIN_RANGE },\n\t{ pluginId: \"agent-forge.plugin.todo-set\", npmName: \"@ai-agent-forge/plugin-todo-set\", range: FACTORY_PLUGIN_RANGE },\n\t{\n\t\tpluginId: \"agent-forge.plugin.session-share\",\n\t\tnpmName: \"@ai-agent-forge/plugin-session-share\",\n\t\trange: FACTORY_PLUGIN_RANGE,\n\t},\n\t{\n\t\tpluginId: \"agent-forge.plugin.observability\",\n\t\tnpmName: \"@ai-agent-forge/plugin-observability\",\n\t\trange: FACTORY_PLUGIN_RANGE,\n\t},\n\t{\n\t\tpluginId: \"agent-forge.plugin.subagent-delegate\",\n\t\tnpmName: \"@ai-agent-forge/plugin-subagent-delegate\",\n\t\trange: FACTORY_PLUGIN_RANGE,\n\t},\n\t{ pluginId: \"agent-forge.plugin.memory\", npmName: \"@ai-agent-forge/plugin-memory\", range: FACTORY_PLUGIN_RANGE },\n\t// image generation (2026-09-30): first-party generate/edit tools package.\n\t{\n\t\tpluginId: \"agent-forge.plugin.image-generation\",\n\t\tnpmName: \"@ai-agent-forge/plugin-image-generation\",\n\t\trange: FACTORY_PLUGIN_RANGE,\n\t},\n]);\n"]}
@@ -1,6 +1,6 @@
1
1
  import type { HostFactsV1, PluginManifestV1, ProfileResolutionV1 } from "../plugins/ecosystem/types.ts";
2
2
  import { type ProfileAssemblyResultV1, type VerifiedToolPluginV1 } from "./profile-assembly.ts";
3
- export type BuiltinPluginProfileIdV1 = "coding-core" | "desktop-qa" | "desktop-observe" | "desktop-control" | "lsp-diagnostics" | "process-exec" | "test-runner" | "workspace-files" | "workspace-files-write" | "formatter-linter" | "git-repository";
3
+ export type BuiltinPluginProfileIdV1 = "coding-core" | "desktop-qa" | "desktop-observe" | "desktop-control" | "lsp-diagnostics" | "image-generation" | "process-exec" | "test-runner" | "workspace-files" | "workspace-files-write" | "formatter-linter" | "git-repository";
4
4
  export interface BuiltinPluginProfileV1 {
5
5
  readonly id: BuiltinPluginProfileIdV1;
6
6
  readonly version: string;
@@ -1 +1 @@
1
- {"version":3,"file":"plugin-profiles.d.ts","sourceRoot":"","sources":["../../src/profile/plugin-profiles.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACX,WAAW,EACX,gBAAgB,EAEhB,mBAAmB,EACnB,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAAmB,KAAK,uBAAuB,EAAE,KAAK,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAEjH,MAAM,MAAM,wBAAwB,GACjC,aAAa,GACb,YAAY,GACZ,iBAAiB,GACjB,iBAAiB,GACjB,iBAAiB,GACjB,cAAc,GACd,aAAa,GACb,iBAAiB,GACjB,uBAAuB,GACvB,kBAAkB,GAClB,gBAAgB,CAAC;AAEpB,MAAM,WAAW,sBAAsB;IACtC,QAAQ,CAAC,EAAE,EAAE,wBAAwB,CAAC;IACtC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;CACtC;AAED;;;;;;;;GAQG;AACH,MAAM,MAAM,gCAAgC,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC,CAAC;AAE1F,MAAM,MAAM,gCAAgC,GACzC;IAAE,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;IAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;CAAE,GAC5D;IAAE,QAAQ,CAAC,MAAM,EAAE,qBAAqB,CAAC;IAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;CAAE,GACtE;IACA,QAAQ,CAAC,MAAM,EAAE,mBAAmB,CAAC;IACrC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,gBAAgB,EAAE,SAAS,MAAM,EAAE,CAAC;IAC7C,QAAQ,CAAC,kBAAkB,EAAE,SAAS,MAAM,EAAE,CAAC;CAC9C,GACD;IACA,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;IAC5B,QAAQ,CAAC,OAAO,EAAE,sBAAsB,CAAC;IACzC,QAAQ,CAAC,UAAU,EAAE,mBAAmB,CAAC;IACzC,QAAQ,CAAC,QAAQ,CAAC,EAAE,uBAAuB,CAAC;CAC3C,CAAC;AAsCL,wBAAgB,2BAA2B,IAAI,SAAS,sBAAsB,EAAE,CAE/E;AAED,gFAAgF;AAChF,wBAAgB,4BAA4B,IAAI,SAAS,gBAAgB,EAAE,CAO1E;AAED;;;;;GAKG;AACH,wBAAgB,+BAA+B,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,oBAAoB,EAAE,CAOlG;AAED,wBAAgB,6BAA6B,CAAC,KAAK,EAAE;IACpD,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;IAC3B,iEAAiE;IACjE,QAAQ,CAAC,iBAAiB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC/C,QAAQ,CAAC,iBAAiB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC/C,QAAQ,CAAC,eAAe,CAAC,EAAE,SAAS,oBAAoB,EAAE,CAAC;IAC3D,yEAAyE;IACzE,QAAQ,CAAC,iBAAiB,CAAC,EAAE,gCAAgC,CAAC;CAC9D,GAAG,gCAAgC,CA2FnC","sourcesContent":["import { VERSION } from \"../config.ts\";\nimport { comparePluginVersionsV1 } from \"../plugins/ecosystem/catalog.ts\";\nimport { resolvePluginProfileV1 } from \"../plugins/ecosystem/resolver.ts\";\nimport type {\n\tHostFactsV1,\n\tPluginManifestV1,\n\tPluginResolutionV1,\n\tProfileResolutionV1,\n} from \"../plugins/ecosystem/types.ts\";\nimport { assembleProfile, type ProfileAssemblyResultV1, type VerifiedToolPluginV1 } from \"./profile-assembly.ts\";\n\nexport type BuiltinPluginProfileIdV1 =\n\t| \"coding-core\"\n\t| \"desktop-qa\"\n\t| \"desktop-observe\"\n\t| \"desktop-control\"\n\t| \"lsp-diagnostics\"\n\t| \"process-exec\"\n\t| \"test-runner\"\n\t| \"workspace-files\"\n\t| \"workspace-files-write\"\n\t| \"formatter-linter\"\n\t| \"git-repository\";\n\nexport interface BuiltinPluginProfileV1 {\n\treadonly id: BuiltinPluginProfileIdV1;\n\treadonly version: string;\n\treadonly pluginIds: readonly string[];\n}\n\n/**\n * Host-owned manifest replacements for installed, verified package versions.\n *\n * Builtin manifests remain the default. A host may explicitly provide one\n * replacement per builtin plugin ID when a staged/verified/active install is\n * selected for a new Profile. The resolver never discovers files or chooses a\n * version implicitly; the replacement is part of the resulting Profile\n * identity and must still pass normal compatibility and verification checks.\n */\nexport type BuiltinPluginManifestOverridesV1 = Readonly<Record<string, PluginManifestV1>>;\n\nexport type BuiltinPluginProfileResolutionV1 =\n\t| { readonly status: \"not_found\"; readonly profileId: string }\n\t| { readonly status: \"host_facts_required\"; readonly profileId: string }\n\t| {\n\t\t\treadonly status: \"invalid_selection\";\n\t\t\treadonly profileId: string;\n\t\t\treadonly unknownPluginIds: readonly string[];\n\t\t\treadonly duplicatePluginIds: readonly string[];\n\t }\n\t| {\n\t\t\treadonly status: \"resolved\";\n\t\t\treadonly profile: BuiltinPluginProfileV1;\n\t\t\treadonly resolution: ProfileResolutionV1;\n\t\t\treadonly assembly?: ProfileAssemblyResultV1;\n\t };\n\n// D-075 S3: every first-party category-A plugin now ships as an independent\n// package under `plugins/` with the `agent-forge.plugin.<name>` id domain\n// (design §4.1). No embedded manifests remain; profiles resolve through the\n// install store (host-provided `manifestOverrides` from active bindings).\nconst manifests: Readonly<Record<string, PluginManifestV1>> = Object.freeze({});\n\nconst profiles: readonly BuiltinPluginProfileV1[] = Object.freeze([\n\t{ id: \"coding-core\", version: \"1\", pluginIds: [] },\n\t{\n\t\tid: \"desktop-qa\",\n\t\tversion: \"1\",\n\t\tpluginIds: [\"agent-forge.plugin.desktop-windows-observe\", \"agent-forge.plugin.desktop-windows-input\"],\n\t},\n\t{ id: \"desktop-observe\", version: \"1\", pluginIds: [\"agent-forge.plugin.desktop-windows-observe\"] },\n\t{\n\t\tid: \"desktop-control\",\n\t\tversion: \"1\",\n\t\tpluginIds: [\"agent-forge.plugin.desktop-windows-observe\", \"agent-forge.plugin.desktop-windows-input\"],\n\t},\n\t{ id: \"lsp-diagnostics\", version: \"1\", pluginIds: [\"agent-forge.plugin.lsp-diagnostics\"] },\n\t{ id: \"process-exec\", version: \"1\", pluginIds: [\"agent-forge.plugin.process-exec\"] },\n\t{ id: \"test-runner\", version: \"1\", pluginIds: [\"agent-forge.plugin.test-runner\"] },\n\t{ id: \"workspace-files\", version: \"1\", pluginIds: [\"agent-forge.plugin.workspace-files\"] },\n\t{ id: \"workspace-files-write\", version: \"1\", pluginIds: [\"agent-forge.plugin.workspace-files-write\"] },\n\t{\n\t\t// D-075 S2: the plugin code ships as the independent package\n\t\t// `agent-forge.plugin.formatter-linter` (design §4.1 id domain); this\n\t\t// Profile stays the stable user entry (`--plugin-profile formatter-linter`)\n\t\t// and resolves through the install store, not an embedded manifest.\n\t\tid: \"formatter-linter\",\n\t\tversion: \"1\",\n\t\tpluginIds: [\"agent-forge.plugin.formatter-linter\"],\n\t},\n\t{ id: \"git-repository\", version: \"1\", pluginIds: [\"agent-forge.plugin.git-repository\"] },\n]);\n\nexport function listBuiltinPluginProfilesV1(): readonly BuiltinPluginProfileV1[] {\n\treturn profiles;\n}\n\n/** Return the first-party manifest projection for catalog and selection UIs. */\nexport function listBuiltinPluginManifestsV1(): readonly PluginManifestV1[] {\n\treturn Object.freeze(\n\t\tObject.values(manifests).sort((left, right) => {\n\t\t\tconst idOrder = `${left.id}@${left.pluginVersion}`.localeCompare(`${right.id}@${right.pluginVersion}`);\n\t\t\treturn idOrder === 0 ? comparePluginVersionsV1(left.pluginVersion, right.pluginVersion) : idOrder;\n\t\t}),\n\t);\n}\n\n/**\n * First-party plugins of an explicitly selected Profile are trusted by\n * default: builtins ship with the product and the user chose the Profile\n * explicitly. Installed third-party versions are still verified through the\n * active-binding resolver; host-injected verifiedPlugins always win.\n */\nexport function defaultBuiltinVerifiedPluginsV1(profileId: string): readonly VerifiedToolPluginV1[] {\n\tconst profile = profiles.find((candidate) => candidate.id === profileId);\n\tif (profile === undefined) return [];\n\treturn profile.pluginIds.flatMap((pluginId) => {\n\t\tconst manifest = manifests[pluginId];\n\t\treturn manifest === undefined ? [] : [{ pluginId: manifest.id, version: manifest.pluginVersion }];\n\t});\n}\n\nexport function resolveBuiltinPluginProfileV1(input: {\n\treadonly profileId: string;\n\treadonly host: HostFactsV1;\n\t/** Optional subset of the selected builtin Profile's plugins. */\n\treadonly selectedPluginIds?: readonly string[];\n\treadonly disabledPluginIds?: readonly string[];\n\treadonly verifiedPlugins?: readonly VerifiedToolPluginV1[];\n\t/** Explicit host-selected active manifests; never inferred from disk. */\n\treadonly manifestOverrides?: BuiltinPluginManifestOverridesV1;\n}): BuiltinPluginProfileResolutionV1 {\n\tconst profile = profiles.find((candidate) => candidate.id === input.profileId);\n\tif (profile === undefined) return { status: \"not_found\", profileId: input.profileId };\n\tconst requestedPluginIds = input.selectedPluginIds;\n\tconst requestedDisabledPluginIds = input.disabledPluginIds;\n\tif (requestedPluginIds !== undefined || requestedDisabledPluginIds !== undefined) {\n\t\tconst availablePluginIds = new Set(profile.pluginIds);\n\t\tconst duplicatePluginIds: string[] = [];\n\t\tconst unknownPluginIds: string[] = [];\n\t\tfor (const requestedIds of [requestedPluginIds ?? [], requestedDisabledPluginIds ?? []]) {\n\t\t\tconst seen = new Set<string>();\n\t\t\tfor (const pluginId of requestedIds) {\n\t\t\t\tif (!availablePluginIds.has(pluginId) && !unknownPluginIds.includes(pluginId))\n\t\t\t\t\tunknownPluginIds.push(pluginId);\n\t\t\t\tif (seen.has(pluginId) && !duplicatePluginIds.includes(pluginId)) duplicatePluginIds.push(pluginId);\n\t\t\t\tseen.add(pluginId);\n\t\t\t}\n\t\t}\n\t\tif (unknownPluginIds.length > 0 || duplicatePluginIds.length > 0) {\n\t\t\treturn {\n\t\t\t\tstatus: \"invalid_selection\",\n\t\t\t\tprofileId: input.profileId,\n\t\t\t\tunknownPluginIds: Object.freeze([...new Set(unknownPluginIds)]),\n\t\t\t\tduplicatePluginIds: Object.freeze(duplicatePluginIds),\n\t\t\t};\n\t\t}\n\t}\n\tconst selected =\n\t\trequestedPluginIds === undefined\n\t\t\t? profile.pluginIds\n\t\t\t: profile.pluginIds.filter((pluginId) => requestedPluginIds.includes(pluginId));\n\tconst selectedProfile =\n\t\trequestedPluginIds === undefined\n\t\t\t? profile\n\t\t\t: Object.freeze({ ...profile, pluginIds: Object.freeze([...selected]) });\n\tconst disabled = new Set(input.disabledPluginIds ?? []);\n\t// D-075 S2: a Profile plugin without a builtin manifest and without a\n\t// host-installed override is a structured miss, not a startup failure. The\n\t// plugin is omitted from the resolved manifest and runtime bindings; the\n\t// remaining Profile plugins resolve normally (soft degradation).\n\tconst manifestByPluginId = new Map(\n\t\tselectedProfile.pluginIds.map((pluginId) => [pluginId, manifestFor(pluginId, input.manifestOverrides)] as const),\n\t);\n\tconst missingPluginIds = selectedProfile.pluginIds.filter(\n\t\t(pluginId) => manifestByPluginId.get(pluginId) === undefined,\n\t);\n\tconst resolution = resolvePluginProfileV1({\n\t\tprofileId: selectedProfile.id,\n\t\tprofileVersion: selectedProfile.version,\n\t\tplugins: selectedProfile.pluginIds.flatMap((pluginId) => {\n\t\t\tconst manifest = manifestByPluginId.get(pluginId);\n\t\t\treturn manifest === undefined\n\t\t\t\t? []\n\t\t\t\t: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tmanifest,\n\t\t\t\t\t\t\t// A user-disabled plugin must not block the remaining profile. It is\n\t\t\t\t\t\t\t// still represented in the resolution diagnostics, but is omitted from\n\t\t\t\t\t\t\t// the active resolved manifest and runtime bindings.\n\t\t\t\t\t\t\trequired: !disabled.has(pluginId),\n\t\t\t\t\t\t\tdisabled: disabled.has(pluginId),\n\t\t\t\t\t\t},\n\t\t\t\t\t];\n\t\t}),\n\t\thost: input.host,\n\t\t// The host's own version enforces each manifest's minHostVersion floor\n\t\t// at the single builtin profile resolution funnel used by production\n\t\t// loading paths.\n\t\thostVersion: VERSION,\n\t});\n\tconst merged = mergeMissingPluginResolutionsV1(resolution, missingPluginIds, disabled);\n\tif (merged.status !== \"ready\") return { status: \"resolved\", profile: selectedProfile, resolution: merged };\n\tconst resolvedPlugins = merged.resolvedManifest.plugins.map((plugin) => ({\n\t\tpluginId: plugin.pluginId,\n\t\tpluginVersion: plugin.pluginVersion,\n\t\tcapabilityRefs: plugin.capabilityRefs,\n\t\t...(plugin.selectedAdapter === undefined ? {} : { selectedAdapter: plugin.selectedAdapter }),\n\t}));\n\tconst verifiedPlugins = input.verifiedPlugins ?? [];\n\tconst assembly = assembleProfile({\n\t\tprofileId: selectedProfile.id,\n\t\tprofileVersion: selectedProfile.version,\n\t\tresolvedPlugins,\n\t\tverifiedPlugins,\n\t});\n\treturn {\n\t\tstatus: \"resolved\",\n\t\tprofile: selectedProfile,\n\t\tresolution: merged,\n\t\tassembly,\n\t};\n}\n\nfunction manifestFor(\n\tpluginId: string,\n\toverrides: BuiltinPluginManifestOverridesV1 | undefined,\n): PluginManifestV1 | undefined {\n\tconst manifest = overrides?.[pluginId] ?? manifests[pluginId];\n\t// A mismatched override stays a hard host error: the host selected it\n\t// explicitly, so silence would hide an identity bug. A plain absent\n\t// manifest (no builtin, no installed override) is the structured miss.\n\tif (manifest !== undefined && manifest.id !== pluginId)\n\t\tthrow new Error(`builtin manifest override does not match plugin ${pluginId}`);\n\treturn manifest;\n}\n\n/**\n * Merge structured `manifest_missing` resolutions for Profile plugins that\n * have no builtin manifest and no installed override into the resolver\n * result. Missing plugins never block the Profile (soft degradation): the\n * remaining diagnostics and the resolved manifest stay exactly what the\n * resolver produced, and the merged plugin list keeps the resolver's\n * deterministic id sort.\n */\nfunction mergeMissingPluginResolutionsV1(\n\tresolution: ProfileResolutionV1,\n\tmissingPluginIds: readonly string[],\n\tdisabled: ReadonlySet<string>,\n): ProfileResolutionV1 {\n\tif (missingPluginIds.length === 0) return resolution;\n\tconst missing: PluginResolutionV1[] = missingPluginIds.map((pluginId) => ({\n\t\tpluginId,\n\t\tpluginVersion: \"\",\n\t\trequired: !disabled.has(pluginId),\n\t\tstatus: \"manifest-missing\",\n\t\tdiagnostics: [\n\t\t\t{\n\t\t\t\tcode: \"manifest_missing\",\n\t\t\t\tmessage: `Plugin ${pluginId} has no builtin manifest and no installed active override; the plugin is omitted from this profile (install it with agent-forge plugin install)`,\n\t\t\t},\n\t\t],\n\t}));\n\tconst plugins = [...resolution.plugins, ...missing].sort((left, right) =>\n\t\tleft.pluginId.localeCompare(right.pluginId),\n\t);\n\treturn Object.freeze({\n\t\t...resolution,\n\t\tplugins: Object.freeze(plugins),\n\t\tdiagnostics: Object.freeze(plugins.flatMap((plugin) => plugin.diagnostics)),\n\t});\n}\n"]}
1
+ {"version":3,"file":"plugin-profiles.d.ts","sourceRoot":"","sources":["../../src/profile/plugin-profiles.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACX,WAAW,EACX,gBAAgB,EAEhB,mBAAmB,EACnB,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAAmB,KAAK,uBAAuB,EAAE,KAAK,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAEjH,MAAM,MAAM,wBAAwB,GACjC,aAAa,GACb,YAAY,GACZ,iBAAiB,GACjB,iBAAiB,GACjB,iBAAiB,GACjB,kBAAkB,GAClB,cAAc,GACd,aAAa,GACb,iBAAiB,GACjB,uBAAuB,GACvB,kBAAkB,GAClB,gBAAgB,CAAC;AAEpB,MAAM,WAAW,sBAAsB;IACtC,QAAQ,CAAC,EAAE,EAAE,wBAAwB,CAAC;IACtC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;CACtC;AAED;;;;;;;;GAQG;AACH,MAAM,MAAM,gCAAgC,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC,CAAC;AAE1F,MAAM,MAAM,gCAAgC,GACzC;IAAE,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;IAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;CAAE,GAC5D;IAAE,QAAQ,CAAC,MAAM,EAAE,qBAAqB,CAAC;IAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;CAAE,GACtE;IACA,QAAQ,CAAC,MAAM,EAAE,mBAAmB,CAAC;IACrC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,gBAAgB,EAAE,SAAS,MAAM,EAAE,CAAC;IAC7C,QAAQ,CAAC,kBAAkB,EAAE,SAAS,MAAM,EAAE,CAAC;CAC9C,GACD;IACA,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;IAC5B,QAAQ,CAAC,OAAO,EAAE,sBAAsB,CAAC;IACzC,QAAQ,CAAC,UAAU,EAAE,mBAAmB,CAAC;IACzC,QAAQ,CAAC,QAAQ,CAAC,EAAE,uBAAuB,CAAC;CAC3C,CAAC;AAuCL,wBAAgB,2BAA2B,IAAI,SAAS,sBAAsB,EAAE,CAE/E;AAED,gFAAgF;AAChF,wBAAgB,4BAA4B,IAAI,SAAS,gBAAgB,EAAE,CAO1E;AAED;;;;;GAKG;AACH,wBAAgB,+BAA+B,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,oBAAoB,EAAE,CAOlG;AAED,wBAAgB,6BAA6B,CAAC,KAAK,EAAE;IACpD,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;IAC3B,iEAAiE;IACjE,QAAQ,CAAC,iBAAiB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC/C,QAAQ,CAAC,iBAAiB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC/C,QAAQ,CAAC,eAAe,CAAC,EAAE,SAAS,oBAAoB,EAAE,CAAC;IAC3D,yEAAyE;IACzE,QAAQ,CAAC,iBAAiB,CAAC,EAAE,gCAAgC,CAAC;CAC9D,GAAG,gCAAgC,CA2FnC","sourcesContent":["import { VERSION } from \"../config.ts\";\nimport { comparePluginVersionsV1 } from \"../plugins/ecosystem/catalog.ts\";\nimport { resolvePluginProfileV1 } from \"../plugins/ecosystem/resolver.ts\";\nimport type {\n\tHostFactsV1,\n\tPluginManifestV1,\n\tPluginResolutionV1,\n\tProfileResolutionV1,\n} from \"../plugins/ecosystem/types.ts\";\nimport { assembleProfile, type ProfileAssemblyResultV1, type VerifiedToolPluginV1 } from \"./profile-assembly.ts\";\n\nexport type BuiltinPluginProfileIdV1 =\n\t| \"coding-core\"\n\t| \"desktop-qa\"\n\t| \"desktop-observe\"\n\t| \"desktop-control\"\n\t| \"lsp-diagnostics\"\n\t| \"image-generation\"\n\t| \"process-exec\"\n\t| \"test-runner\"\n\t| \"workspace-files\"\n\t| \"workspace-files-write\"\n\t| \"formatter-linter\"\n\t| \"git-repository\";\n\nexport interface BuiltinPluginProfileV1 {\n\treadonly id: BuiltinPluginProfileIdV1;\n\treadonly version: string;\n\treadonly pluginIds: readonly string[];\n}\n\n/**\n * Host-owned manifest replacements for installed, verified package versions.\n *\n * Builtin manifests remain the default. A host may explicitly provide one\n * replacement per builtin plugin ID when a staged/verified/active install is\n * selected for a new Profile. The resolver never discovers files or chooses a\n * version implicitly; the replacement is part of the resulting Profile\n * identity and must still pass normal compatibility and verification checks.\n */\nexport type BuiltinPluginManifestOverridesV1 = Readonly<Record<string, PluginManifestV1>>;\n\nexport type BuiltinPluginProfileResolutionV1 =\n\t| { readonly status: \"not_found\"; readonly profileId: string }\n\t| { readonly status: \"host_facts_required\"; readonly profileId: string }\n\t| {\n\t\t\treadonly status: \"invalid_selection\";\n\t\t\treadonly profileId: string;\n\t\t\treadonly unknownPluginIds: readonly string[];\n\t\t\treadonly duplicatePluginIds: readonly string[];\n\t }\n\t| {\n\t\t\treadonly status: \"resolved\";\n\t\t\treadonly profile: BuiltinPluginProfileV1;\n\t\t\treadonly resolution: ProfileResolutionV1;\n\t\t\treadonly assembly?: ProfileAssemblyResultV1;\n\t };\n\n// D-075 S3: every first-party category-A plugin now ships as an independent\n// package under `plugins/` with the `agent-forge.plugin.<name>` id domain\n// (design §4.1). No embedded manifests remain; profiles resolve through the\n// install store (host-provided `manifestOverrides` from active bindings).\nconst manifests: Readonly<Record<string, PluginManifestV1>> = Object.freeze({});\n\nconst profiles: readonly BuiltinPluginProfileV1[] = Object.freeze([\n\t{ id: \"coding-core\", version: \"1\", pluginIds: [] },\n\t{\n\t\tid: \"desktop-qa\",\n\t\tversion: \"1\",\n\t\tpluginIds: [\"agent-forge.plugin.desktop-windows-observe\", \"agent-forge.plugin.desktop-windows-input\"],\n\t},\n\t{ id: \"desktop-observe\", version: \"1\", pluginIds: [\"agent-forge.plugin.desktop-windows-observe\"] },\n\t{\n\t\tid: \"desktop-control\",\n\t\tversion: \"1\",\n\t\tpluginIds: [\"agent-forge.plugin.desktop-windows-observe\", \"agent-forge.plugin.desktop-windows-input\"],\n\t},\n\t{ id: \"lsp-diagnostics\", version: \"1\", pluginIds: [\"agent-forge.plugin.lsp-diagnostics\"] },\n\t{ id: \"image-generation\", version: \"1\", pluginIds: [\"agent-forge.plugin.image-generation\"] },\n\t{ id: \"process-exec\", version: \"1\", pluginIds: [\"agent-forge.plugin.process-exec\"] },\n\t{ id: \"test-runner\", version: \"1\", pluginIds: [\"agent-forge.plugin.test-runner\"] },\n\t{ id: \"workspace-files\", version: \"1\", pluginIds: [\"agent-forge.plugin.workspace-files\"] },\n\t{ id: \"workspace-files-write\", version: \"1\", pluginIds: [\"agent-forge.plugin.workspace-files-write\"] },\n\t{\n\t\t// D-075 S2: the plugin code ships as the independent package\n\t\t// `agent-forge.plugin.formatter-linter` (design §4.1 id domain); this\n\t\t// Profile stays the stable user entry (`--plugin-profile formatter-linter`)\n\t\t// and resolves through the install store, not an embedded manifest.\n\t\tid: \"formatter-linter\",\n\t\tversion: \"1\",\n\t\tpluginIds: [\"agent-forge.plugin.formatter-linter\"],\n\t},\n\t{ id: \"git-repository\", version: \"1\", pluginIds: [\"agent-forge.plugin.git-repository\"] },\n]);\n\nexport function listBuiltinPluginProfilesV1(): readonly BuiltinPluginProfileV1[] {\n\treturn profiles;\n}\n\n/** Return the first-party manifest projection for catalog and selection UIs. */\nexport function listBuiltinPluginManifestsV1(): readonly PluginManifestV1[] {\n\treturn Object.freeze(\n\t\tObject.values(manifests).sort((left, right) => {\n\t\t\tconst idOrder = `${left.id}@${left.pluginVersion}`.localeCompare(`${right.id}@${right.pluginVersion}`);\n\t\t\treturn idOrder === 0 ? comparePluginVersionsV1(left.pluginVersion, right.pluginVersion) : idOrder;\n\t\t}),\n\t);\n}\n\n/**\n * First-party plugins of an explicitly selected Profile are trusted by\n * default: builtins ship with the product and the user chose the Profile\n * explicitly. Installed third-party versions are still verified through the\n * active-binding resolver; host-injected verifiedPlugins always win.\n */\nexport function defaultBuiltinVerifiedPluginsV1(profileId: string): readonly VerifiedToolPluginV1[] {\n\tconst profile = profiles.find((candidate) => candidate.id === profileId);\n\tif (profile === undefined) return [];\n\treturn profile.pluginIds.flatMap((pluginId) => {\n\t\tconst manifest = manifests[pluginId];\n\t\treturn manifest === undefined ? [] : [{ pluginId: manifest.id, version: manifest.pluginVersion }];\n\t});\n}\n\nexport function resolveBuiltinPluginProfileV1(input: {\n\treadonly profileId: string;\n\treadonly host: HostFactsV1;\n\t/** Optional subset of the selected builtin Profile's plugins. */\n\treadonly selectedPluginIds?: readonly string[];\n\treadonly disabledPluginIds?: readonly string[];\n\treadonly verifiedPlugins?: readonly VerifiedToolPluginV1[];\n\t/** Explicit host-selected active manifests; never inferred from disk. */\n\treadonly manifestOverrides?: BuiltinPluginManifestOverridesV1;\n}): BuiltinPluginProfileResolutionV1 {\n\tconst profile = profiles.find((candidate) => candidate.id === input.profileId);\n\tif (profile === undefined) return { status: \"not_found\", profileId: input.profileId };\n\tconst requestedPluginIds = input.selectedPluginIds;\n\tconst requestedDisabledPluginIds = input.disabledPluginIds;\n\tif (requestedPluginIds !== undefined || requestedDisabledPluginIds !== undefined) {\n\t\tconst availablePluginIds = new Set(profile.pluginIds);\n\t\tconst duplicatePluginIds: string[] = [];\n\t\tconst unknownPluginIds: string[] = [];\n\t\tfor (const requestedIds of [requestedPluginIds ?? [], requestedDisabledPluginIds ?? []]) {\n\t\t\tconst seen = new Set<string>();\n\t\t\tfor (const pluginId of requestedIds) {\n\t\t\t\tif (!availablePluginIds.has(pluginId) && !unknownPluginIds.includes(pluginId))\n\t\t\t\t\tunknownPluginIds.push(pluginId);\n\t\t\t\tif (seen.has(pluginId) && !duplicatePluginIds.includes(pluginId)) duplicatePluginIds.push(pluginId);\n\t\t\t\tseen.add(pluginId);\n\t\t\t}\n\t\t}\n\t\tif (unknownPluginIds.length > 0 || duplicatePluginIds.length > 0) {\n\t\t\treturn {\n\t\t\t\tstatus: \"invalid_selection\",\n\t\t\t\tprofileId: input.profileId,\n\t\t\t\tunknownPluginIds: Object.freeze([...new Set(unknownPluginIds)]),\n\t\t\t\tduplicatePluginIds: Object.freeze(duplicatePluginIds),\n\t\t\t};\n\t\t}\n\t}\n\tconst selected =\n\t\trequestedPluginIds === undefined\n\t\t\t? profile.pluginIds\n\t\t\t: profile.pluginIds.filter((pluginId) => requestedPluginIds.includes(pluginId));\n\tconst selectedProfile =\n\t\trequestedPluginIds === undefined\n\t\t\t? profile\n\t\t\t: Object.freeze({ ...profile, pluginIds: Object.freeze([...selected]) });\n\tconst disabled = new Set(input.disabledPluginIds ?? []);\n\t// D-075 S2: a Profile plugin without a builtin manifest and without a\n\t// host-installed override is a structured miss, not a startup failure. The\n\t// plugin is omitted from the resolved manifest and runtime bindings; the\n\t// remaining Profile plugins resolve normally (soft degradation).\n\tconst manifestByPluginId = new Map(\n\t\tselectedProfile.pluginIds.map((pluginId) => [pluginId, manifestFor(pluginId, input.manifestOverrides)] as const),\n\t);\n\tconst missingPluginIds = selectedProfile.pluginIds.filter(\n\t\t(pluginId) => manifestByPluginId.get(pluginId) === undefined,\n\t);\n\tconst resolution = resolvePluginProfileV1({\n\t\tprofileId: selectedProfile.id,\n\t\tprofileVersion: selectedProfile.version,\n\t\tplugins: selectedProfile.pluginIds.flatMap((pluginId) => {\n\t\t\tconst manifest = manifestByPluginId.get(pluginId);\n\t\t\treturn manifest === undefined\n\t\t\t\t? []\n\t\t\t\t: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tmanifest,\n\t\t\t\t\t\t\t// A user-disabled plugin must not block the remaining profile. It is\n\t\t\t\t\t\t\t// still represented in the resolution diagnostics, but is omitted from\n\t\t\t\t\t\t\t// the active resolved manifest and runtime bindings.\n\t\t\t\t\t\t\trequired: !disabled.has(pluginId),\n\t\t\t\t\t\t\tdisabled: disabled.has(pluginId),\n\t\t\t\t\t\t},\n\t\t\t\t\t];\n\t\t}),\n\t\thost: input.host,\n\t\t// The host's own version enforces each manifest's minHostVersion floor\n\t\t// at the single builtin profile resolution funnel used by production\n\t\t// loading paths.\n\t\thostVersion: VERSION,\n\t});\n\tconst merged = mergeMissingPluginResolutionsV1(resolution, missingPluginIds, disabled);\n\tif (merged.status !== \"ready\") return { status: \"resolved\", profile: selectedProfile, resolution: merged };\n\tconst resolvedPlugins = merged.resolvedManifest.plugins.map((plugin) => ({\n\t\tpluginId: plugin.pluginId,\n\t\tpluginVersion: plugin.pluginVersion,\n\t\tcapabilityRefs: plugin.capabilityRefs,\n\t\t...(plugin.selectedAdapter === undefined ? {} : { selectedAdapter: plugin.selectedAdapter }),\n\t}));\n\tconst verifiedPlugins = input.verifiedPlugins ?? [];\n\tconst assembly = assembleProfile({\n\t\tprofileId: selectedProfile.id,\n\t\tprofileVersion: selectedProfile.version,\n\t\tresolvedPlugins,\n\t\tverifiedPlugins,\n\t});\n\treturn {\n\t\tstatus: \"resolved\",\n\t\tprofile: selectedProfile,\n\t\tresolution: merged,\n\t\tassembly,\n\t};\n}\n\nfunction manifestFor(\n\tpluginId: string,\n\toverrides: BuiltinPluginManifestOverridesV1 | undefined,\n): PluginManifestV1 | undefined {\n\tconst manifest = overrides?.[pluginId] ?? manifests[pluginId];\n\t// A mismatched override stays a hard host error: the host selected it\n\t// explicitly, so silence would hide an identity bug. A plain absent\n\t// manifest (no builtin, no installed override) is the structured miss.\n\tif (manifest !== undefined && manifest.id !== pluginId)\n\t\tthrow new Error(`builtin manifest override does not match plugin ${pluginId}`);\n\treturn manifest;\n}\n\n/**\n * Merge structured `manifest_missing` resolutions for Profile plugins that\n * have no builtin manifest and no installed override into the resolver\n * result. Missing plugins never block the Profile (soft degradation): the\n * remaining diagnostics and the resolved manifest stay exactly what the\n * resolver produced, and the merged plugin list keeps the resolver's\n * deterministic id sort.\n */\nfunction mergeMissingPluginResolutionsV1(\n\tresolution: ProfileResolutionV1,\n\tmissingPluginIds: readonly string[],\n\tdisabled: ReadonlySet<string>,\n): ProfileResolutionV1 {\n\tif (missingPluginIds.length === 0) return resolution;\n\tconst missing: PluginResolutionV1[] = missingPluginIds.map((pluginId) => ({\n\t\tpluginId,\n\t\tpluginVersion: \"\",\n\t\trequired: !disabled.has(pluginId),\n\t\tstatus: \"manifest-missing\",\n\t\tdiagnostics: [\n\t\t\t{\n\t\t\t\tcode: \"manifest_missing\",\n\t\t\t\tmessage: `Plugin ${pluginId} has no builtin manifest and no installed active override; the plugin is omitted from this profile (install it with agent-forge plugin install)`,\n\t\t\t},\n\t\t],\n\t}));\n\tconst plugins = [...resolution.plugins, ...missing].sort((left, right) =>\n\t\tleft.pluginId.localeCompare(right.pluginId),\n\t);\n\treturn Object.freeze({\n\t\t...resolution,\n\t\tplugins: Object.freeze(plugins),\n\t\tdiagnostics: Object.freeze(plugins.flatMap((plugin) => plugin.diagnostics)),\n\t});\n}\n"]}
@@ -21,6 +21,7 @@ const profiles = Object.freeze([
21
21
  pluginIds: ["agent-forge.plugin.desktop-windows-observe", "agent-forge.plugin.desktop-windows-input"],
22
22
  },
23
23
  { id: "lsp-diagnostics", version: "1", pluginIds: ["agent-forge.plugin.lsp-diagnostics"] },
24
+ { id: "image-generation", version: "1", pluginIds: ["agent-forge.plugin.image-generation"] },
24
25
  { id: "process-exec", version: "1", pluginIds: ["agent-forge.plugin.process-exec"] },
25
26
  { id: "test-runner", version: "1", pluginIds: ["agent-forge.plugin.test-runner"] },
26
27
  { id: "workspace-files", version: "1", pluginIds: ["agent-forge.plugin.workspace-files"] },
@@ -1 +1 @@
1
- {"version":3,"file":"plugin-profiles.js","sourceRoot":"","sources":["../../src/profile/plugin-profiles.ts"],"names":[],"mappings":"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","sourcesContent":["import { VERSION } from \"../config.ts\";\nimport { comparePluginVersionsV1 } from \"../plugins/ecosystem/catalog.ts\";\nimport { resolvePluginProfileV1 } from \"../plugins/ecosystem/resolver.ts\";\nimport type {\n\tHostFactsV1,\n\tPluginManifestV1,\n\tPluginResolutionV1,\n\tProfileResolutionV1,\n} from \"../plugins/ecosystem/types.ts\";\nimport { assembleProfile, type ProfileAssemblyResultV1, type VerifiedToolPluginV1 } from \"./profile-assembly.ts\";\n\nexport type BuiltinPluginProfileIdV1 =\n\t| \"coding-core\"\n\t| \"desktop-qa\"\n\t| \"desktop-observe\"\n\t| \"desktop-control\"\n\t| \"lsp-diagnostics\"\n\t| \"process-exec\"\n\t| \"test-runner\"\n\t| \"workspace-files\"\n\t| \"workspace-files-write\"\n\t| \"formatter-linter\"\n\t| \"git-repository\";\n\nexport interface BuiltinPluginProfileV1 {\n\treadonly id: BuiltinPluginProfileIdV1;\n\treadonly version: string;\n\treadonly pluginIds: readonly string[];\n}\n\n/**\n * Host-owned manifest replacements for installed, verified package versions.\n *\n * Builtin manifests remain the default. A host may explicitly provide one\n * replacement per builtin plugin ID when a staged/verified/active install is\n * selected for a new Profile. The resolver never discovers files or chooses a\n * version implicitly; the replacement is part of the resulting Profile\n * identity and must still pass normal compatibility and verification checks.\n */\nexport type BuiltinPluginManifestOverridesV1 = Readonly<Record<string, PluginManifestV1>>;\n\nexport type BuiltinPluginProfileResolutionV1 =\n\t| { readonly status: \"not_found\"; readonly profileId: string }\n\t| { readonly status: \"host_facts_required\"; readonly profileId: string }\n\t| {\n\t\t\treadonly status: \"invalid_selection\";\n\t\t\treadonly profileId: string;\n\t\t\treadonly unknownPluginIds: readonly string[];\n\t\t\treadonly duplicatePluginIds: readonly string[];\n\t }\n\t| {\n\t\t\treadonly status: \"resolved\";\n\t\t\treadonly profile: BuiltinPluginProfileV1;\n\t\t\treadonly resolution: ProfileResolutionV1;\n\t\t\treadonly assembly?: ProfileAssemblyResultV1;\n\t };\n\n// D-075 S3: every first-party category-A plugin now ships as an independent\n// package under `plugins/` with the `agent-forge.plugin.<name>` id domain\n// (design §4.1). No embedded manifests remain; profiles resolve through the\n// install store (host-provided `manifestOverrides` from active bindings).\nconst manifests: Readonly<Record<string, PluginManifestV1>> = Object.freeze({});\n\nconst profiles: readonly BuiltinPluginProfileV1[] = Object.freeze([\n\t{ id: \"coding-core\", version: \"1\", pluginIds: [] },\n\t{\n\t\tid: \"desktop-qa\",\n\t\tversion: \"1\",\n\t\tpluginIds: [\"agent-forge.plugin.desktop-windows-observe\", \"agent-forge.plugin.desktop-windows-input\"],\n\t},\n\t{ id: \"desktop-observe\", version: \"1\", pluginIds: [\"agent-forge.plugin.desktop-windows-observe\"] },\n\t{\n\t\tid: \"desktop-control\",\n\t\tversion: \"1\",\n\t\tpluginIds: [\"agent-forge.plugin.desktop-windows-observe\", \"agent-forge.plugin.desktop-windows-input\"],\n\t},\n\t{ id: \"lsp-diagnostics\", version: \"1\", pluginIds: [\"agent-forge.plugin.lsp-diagnostics\"] },\n\t{ id: \"process-exec\", version: \"1\", pluginIds: [\"agent-forge.plugin.process-exec\"] },\n\t{ id: \"test-runner\", version: \"1\", pluginIds: [\"agent-forge.plugin.test-runner\"] },\n\t{ id: \"workspace-files\", version: \"1\", pluginIds: [\"agent-forge.plugin.workspace-files\"] },\n\t{ id: \"workspace-files-write\", version: \"1\", pluginIds: [\"agent-forge.plugin.workspace-files-write\"] },\n\t{\n\t\t// D-075 S2: the plugin code ships as the independent package\n\t\t// `agent-forge.plugin.formatter-linter` (design §4.1 id domain); this\n\t\t// Profile stays the stable user entry (`--plugin-profile formatter-linter`)\n\t\t// and resolves through the install store, not an embedded manifest.\n\t\tid: \"formatter-linter\",\n\t\tversion: \"1\",\n\t\tpluginIds: [\"agent-forge.plugin.formatter-linter\"],\n\t},\n\t{ id: \"git-repository\", version: \"1\", pluginIds: [\"agent-forge.plugin.git-repository\"] },\n]);\n\nexport function listBuiltinPluginProfilesV1(): readonly BuiltinPluginProfileV1[] {\n\treturn profiles;\n}\n\n/** Return the first-party manifest projection for catalog and selection UIs. */\nexport function listBuiltinPluginManifestsV1(): readonly PluginManifestV1[] {\n\treturn Object.freeze(\n\t\tObject.values(manifests).sort((left, right) => {\n\t\t\tconst idOrder = `${left.id}@${left.pluginVersion}`.localeCompare(`${right.id}@${right.pluginVersion}`);\n\t\t\treturn idOrder === 0 ? comparePluginVersionsV1(left.pluginVersion, right.pluginVersion) : idOrder;\n\t\t}),\n\t);\n}\n\n/**\n * First-party plugins of an explicitly selected Profile are trusted by\n * default: builtins ship with the product and the user chose the Profile\n * explicitly. Installed third-party versions are still verified through the\n * active-binding resolver; host-injected verifiedPlugins always win.\n */\nexport function defaultBuiltinVerifiedPluginsV1(profileId: string): readonly VerifiedToolPluginV1[] {\n\tconst profile = profiles.find((candidate) => candidate.id === profileId);\n\tif (profile === undefined) return [];\n\treturn profile.pluginIds.flatMap((pluginId) => {\n\t\tconst manifest = manifests[pluginId];\n\t\treturn manifest === undefined ? [] : [{ pluginId: manifest.id, version: manifest.pluginVersion }];\n\t});\n}\n\nexport function resolveBuiltinPluginProfileV1(input: {\n\treadonly profileId: string;\n\treadonly host: HostFactsV1;\n\t/** Optional subset of the selected builtin Profile's plugins. */\n\treadonly selectedPluginIds?: readonly string[];\n\treadonly disabledPluginIds?: readonly string[];\n\treadonly verifiedPlugins?: readonly VerifiedToolPluginV1[];\n\t/** Explicit host-selected active manifests; never inferred from disk. */\n\treadonly manifestOverrides?: BuiltinPluginManifestOverridesV1;\n}): BuiltinPluginProfileResolutionV1 {\n\tconst profile = profiles.find((candidate) => candidate.id === input.profileId);\n\tif (profile === undefined) return { status: \"not_found\", profileId: input.profileId };\n\tconst requestedPluginIds = input.selectedPluginIds;\n\tconst requestedDisabledPluginIds = input.disabledPluginIds;\n\tif (requestedPluginIds !== undefined || requestedDisabledPluginIds !== undefined) {\n\t\tconst availablePluginIds = new Set(profile.pluginIds);\n\t\tconst duplicatePluginIds: string[] = [];\n\t\tconst unknownPluginIds: string[] = [];\n\t\tfor (const requestedIds of [requestedPluginIds ?? [], requestedDisabledPluginIds ?? []]) {\n\t\t\tconst seen = new Set<string>();\n\t\t\tfor (const pluginId of requestedIds) {\n\t\t\t\tif (!availablePluginIds.has(pluginId) && !unknownPluginIds.includes(pluginId))\n\t\t\t\t\tunknownPluginIds.push(pluginId);\n\t\t\t\tif (seen.has(pluginId) && !duplicatePluginIds.includes(pluginId)) duplicatePluginIds.push(pluginId);\n\t\t\t\tseen.add(pluginId);\n\t\t\t}\n\t\t}\n\t\tif (unknownPluginIds.length > 0 || duplicatePluginIds.length > 0) {\n\t\t\treturn {\n\t\t\t\tstatus: \"invalid_selection\",\n\t\t\t\tprofileId: input.profileId,\n\t\t\t\tunknownPluginIds: Object.freeze([...new Set(unknownPluginIds)]),\n\t\t\t\tduplicatePluginIds: Object.freeze(duplicatePluginIds),\n\t\t\t};\n\t\t}\n\t}\n\tconst selected =\n\t\trequestedPluginIds === undefined\n\t\t\t? profile.pluginIds\n\t\t\t: profile.pluginIds.filter((pluginId) => requestedPluginIds.includes(pluginId));\n\tconst selectedProfile =\n\t\trequestedPluginIds === undefined\n\t\t\t? profile\n\t\t\t: Object.freeze({ ...profile, pluginIds: Object.freeze([...selected]) });\n\tconst disabled = new Set(input.disabledPluginIds ?? []);\n\t// D-075 S2: a Profile plugin without a builtin manifest and without a\n\t// host-installed override is a structured miss, not a startup failure. The\n\t// plugin is omitted from the resolved manifest and runtime bindings; the\n\t// remaining Profile plugins resolve normally (soft degradation).\n\tconst manifestByPluginId = new Map(\n\t\tselectedProfile.pluginIds.map((pluginId) => [pluginId, manifestFor(pluginId, input.manifestOverrides)] as const),\n\t);\n\tconst missingPluginIds = selectedProfile.pluginIds.filter(\n\t\t(pluginId) => manifestByPluginId.get(pluginId) === undefined,\n\t);\n\tconst resolution = resolvePluginProfileV1({\n\t\tprofileId: selectedProfile.id,\n\t\tprofileVersion: selectedProfile.version,\n\t\tplugins: selectedProfile.pluginIds.flatMap((pluginId) => {\n\t\t\tconst manifest = manifestByPluginId.get(pluginId);\n\t\t\treturn manifest === undefined\n\t\t\t\t? []\n\t\t\t\t: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tmanifest,\n\t\t\t\t\t\t\t// A user-disabled plugin must not block the remaining profile. It is\n\t\t\t\t\t\t\t// still represented in the resolution diagnostics, but is omitted from\n\t\t\t\t\t\t\t// the active resolved manifest and runtime bindings.\n\t\t\t\t\t\t\trequired: !disabled.has(pluginId),\n\t\t\t\t\t\t\tdisabled: disabled.has(pluginId),\n\t\t\t\t\t\t},\n\t\t\t\t\t];\n\t\t}),\n\t\thost: input.host,\n\t\t// The host's own version enforces each manifest's minHostVersion floor\n\t\t// at the single builtin profile resolution funnel used by production\n\t\t// loading paths.\n\t\thostVersion: VERSION,\n\t});\n\tconst merged = mergeMissingPluginResolutionsV1(resolution, missingPluginIds, disabled);\n\tif (merged.status !== \"ready\") return { status: \"resolved\", profile: selectedProfile, resolution: merged };\n\tconst resolvedPlugins = merged.resolvedManifest.plugins.map((plugin) => ({\n\t\tpluginId: plugin.pluginId,\n\t\tpluginVersion: plugin.pluginVersion,\n\t\tcapabilityRefs: plugin.capabilityRefs,\n\t\t...(plugin.selectedAdapter === undefined ? {} : { selectedAdapter: plugin.selectedAdapter }),\n\t}));\n\tconst verifiedPlugins = input.verifiedPlugins ?? [];\n\tconst assembly = assembleProfile({\n\t\tprofileId: selectedProfile.id,\n\t\tprofileVersion: selectedProfile.version,\n\t\tresolvedPlugins,\n\t\tverifiedPlugins,\n\t});\n\treturn {\n\t\tstatus: \"resolved\",\n\t\tprofile: selectedProfile,\n\t\tresolution: merged,\n\t\tassembly,\n\t};\n}\n\nfunction manifestFor(\n\tpluginId: string,\n\toverrides: BuiltinPluginManifestOverridesV1 | undefined,\n): PluginManifestV1 | undefined {\n\tconst manifest = overrides?.[pluginId] ?? manifests[pluginId];\n\t// A mismatched override stays a hard host error: the host selected it\n\t// explicitly, so silence would hide an identity bug. A plain absent\n\t// manifest (no builtin, no installed override) is the structured miss.\n\tif (manifest !== undefined && manifest.id !== pluginId)\n\t\tthrow new Error(`builtin manifest override does not match plugin ${pluginId}`);\n\treturn manifest;\n}\n\n/**\n * Merge structured `manifest_missing` resolutions for Profile plugins that\n * have no builtin manifest and no installed override into the resolver\n * result. Missing plugins never block the Profile (soft degradation): the\n * remaining diagnostics and the resolved manifest stay exactly what the\n * resolver produced, and the merged plugin list keeps the resolver's\n * deterministic id sort.\n */\nfunction mergeMissingPluginResolutionsV1(\n\tresolution: ProfileResolutionV1,\n\tmissingPluginIds: readonly string[],\n\tdisabled: ReadonlySet<string>,\n): ProfileResolutionV1 {\n\tif (missingPluginIds.length === 0) return resolution;\n\tconst missing: PluginResolutionV1[] = missingPluginIds.map((pluginId) => ({\n\t\tpluginId,\n\t\tpluginVersion: \"\",\n\t\trequired: !disabled.has(pluginId),\n\t\tstatus: \"manifest-missing\",\n\t\tdiagnostics: [\n\t\t\t{\n\t\t\t\tcode: \"manifest_missing\",\n\t\t\t\tmessage: `Plugin ${pluginId} has no builtin manifest and no installed active override; the plugin is omitted from this profile (install it with agent-forge plugin install)`,\n\t\t\t},\n\t\t],\n\t}));\n\tconst plugins = [...resolution.plugins, ...missing].sort((left, right) =>\n\t\tleft.pluginId.localeCompare(right.pluginId),\n\t);\n\treturn Object.freeze({\n\t\t...resolution,\n\t\tplugins: Object.freeze(plugins),\n\t\tdiagnostics: Object.freeze(plugins.flatMap((plugin) => plugin.diagnostics)),\n\t});\n}\n"]}
1
+ {"version":3,"file":"plugin-profiles.js","sourceRoot":"","sources":["../../src/profile/plugin-profiles.ts"],"names":[],"mappings":"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","sourcesContent":["import { VERSION } from \"../config.ts\";\nimport { comparePluginVersionsV1 } from \"../plugins/ecosystem/catalog.ts\";\nimport { resolvePluginProfileV1 } from \"../plugins/ecosystem/resolver.ts\";\nimport type {\n\tHostFactsV1,\n\tPluginManifestV1,\n\tPluginResolutionV1,\n\tProfileResolutionV1,\n} from \"../plugins/ecosystem/types.ts\";\nimport { assembleProfile, type ProfileAssemblyResultV1, type VerifiedToolPluginV1 } from \"./profile-assembly.ts\";\n\nexport type BuiltinPluginProfileIdV1 =\n\t| \"coding-core\"\n\t| \"desktop-qa\"\n\t| \"desktop-observe\"\n\t| \"desktop-control\"\n\t| \"lsp-diagnostics\"\n\t| \"image-generation\"\n\t| \"process-exec\"\n\t| \"test-runner\"\n\t| \"workspace-files\"\n\t| \"workspace-files-write\"\n\t| \"formatter-linter\"\n\t| \"git-repository\";\n\nexport interface BuiltinPluginProfileV1 {\n\treadonly id: BuiltinPluginProfileIdV1;\n\treadonly version: string;\n\treadonly pluginIds: readonly string[];\n}\n\n/**\n * Host-owned manifest replacements for installed, verified package versions.\n *\n * Builtin manifests remain the default. A host may explicitly provide one\n * replacement per builtin plugin ID when a staged/verified/active install is\n * selected for a new Profile. The resolver never discovers files or chooses a\n * version implicitly; the replacement is part of the resulting Profile\n * identity and must still pass normal compatibility and verification checks.\n */\nexport type BuiltinPluginManifestOverridesV1 = Readonly<Record<string, PluginManifestV1>>;\n\nexport type BuiltinPluginProfileResolutionV1 =\n\t| { readonly status: \"not_found\"; readonly profileId: string }\n\t| { readonly status: \"host_facts_required\"; readonly profileId: string }\n\t| {\n\t\t\treadonly status: \"invalid_selection\";\n\t\t\treadonly profileId: string;\n\t\t\treadonly unknownPluginIds: readonly string[];\n\t\t\treadonly duplicatePluginIds: readonly string[];\n\t }\n\t| {\n\t\t\treadonly status: \"resolved\";\n\t\t\treadonly profile: BuiltinPluginProfileV1;\n\t\t\treadonly resolution: ProfileResolutionV1;\n\t\t\treadonly assembly?: ProfileAssemblyResultV1;\n\t };\n\n// D-075 S3: every first-party category-A plugin now ships as an independent\n// package under `plugins/` with the `agent-forge.plugin.<name>` id domain\n// (design §4.1). No embedded manifests remain; profiles resolve through the\n// install store (host-provided `manifestOverrides` from active bindings).\nconst manifests: Readonly<Record<string, PluginManifestV1>> = Object.freeze({});\n\nconst profiles: readonly BuiltinPluginProfileV1[] = Object.freeze([\n\t{ id: \"coding-core\", version: \"1\", pluginIds: [] },\n\t{\n\t\tid: \"desktop-qa\",\n\t\tversion: \"1\",\n\t\tpluginIds: [\"agent-forge.plugin.desktop-windows-observe\", \"agent-forge.plugin.desktop-windows-input\"],\n\t},\n\t{ id: \"desktop-observe\", version: \"1\", pluginIds: [\"agent-forge.plugin.desktop-windows-observe\"] },\n\t{\n\t\tid: \"desktop-control\",\n\t\tversion: \"1\",\n\t\tpluginIds: [\"agent-forge.plugin.desktop-windows-observe\", \"agent-forge.plugin.desktop-windows-input\"],\n\t},\n\t{ id: \"lsp-diagnostics\", version: \"1\", pluginIds: [\"agent-forge.plugin.lsp-diagnostics\"] },\n\t{ id: \"image-generation\", version: \"1\", pluginIds: [\"agent-forge.plugin.image-generation\"] },\n\t{ id: \"process-exec\", version: \"1\", pluginIds: [\"agent-forge.plugin.process-exec\"] },\n\t{ id: \"test-runner\", version: \"1\", pluginIds: [\"agent-forge.plugin.test-runner\"] },\n\t{ id: \"workspace-files\", version: \"1\", pluginIds: [\"agent-forge.plugin.workspace-files\"] },\n\t{ id: \"workspace-files-write\", version: \"1\", pluginIds: [\"agent-forge.plugin.workspace-files-write\"] },\n\t{\n\t\t// D-075 S2: the plugin code ships as the independent package\n\t\t// `agent-forge.plugin.formatter-linter` (design §4.1 id domain); this\n\t\t// Profile stays the stable user entry (`--plugin-profile formatter-linter`)\n\t\t// and resolves through the install store, not an embedded manifest.\n\t\tid: \"formatter-linter\",\n\t\tversion: \"1\",\n\t\tpluginIds: [\"agent-forge.plugin.formatter-linter\"],\n\t},\n\t{ id: \"git-repository\", version: \"1\", pluginIds: [\"agent-forge.plugin.git-repository\"] },\n]);\n\nexport function listBuiltinPluginProfilesV1(): readonly BuiltinPluginProfileV1[] {\n\treturn profiles;\n}\n\n/** Return the first-party manifest projection for catalog and selection UIs. */\nexport function listBuiltinPluginManifestsV1(): readonly PluginManifestV1[] {\n\treturn Object.freeze(\n\t\tObject.values(manifests).sort((left, right) => {\n\t\t\tconst idOrder = `${left.id}@${left.pluginVersion}`.localeCompare(`${right.id}@${right.pluginVersion}`);\n\t\t\treturn idOrder === 0 ? comparePluginVersionsV1(left.pluginVersion, right.pluginVersion) : idOrder;\n\t\t}),\n\t);\n}\n\n/**\n * First-party plugins of an explicitly selected Profile are trusted by\n * default: builtins ship with the product and the user chose the Profile\n * explicitly. Installed third-party versions are still verified through the\n * active-binding resolver; host-injected verifiedPlugins always win.\n */\nexport function defaultBuiltinVerifiedPluginsV1(profileId: string): readonly VerifiedToolPluginV1[] {\n\tconst profile = profiles.find((candidate) => candidate.id === profileId);\n\tif (profile === undefined) return [];\n\treturn profile.pluginIds.flatMap((pluginId) => {\n\t\tconst manifest = manifests[pluginId];\n\t\treturn manifest === undefined ? [] : [{ pluginId: manifest.id, version: manifest.pluginVersion }];\n\t});\n}\n\nexport function resolveBuiltinPluginProfileV1(input: {\n\treadonly profileId: string;\n\treadonly host: HostFactsV1;\n\t/** Optional subset of the selected builtin Profile's plugins. */\n\treadonly selectedPluginIds?: readonly string[];\n\treadonly disabledPluginIds?: readonly string[];\n\treadonly verifiedPlugins?: readonly VerifiedToolPluginV1[];\n\t/** Explicit host-selected active manifests; never inferred from disk. */\n\treadonly manifestOverrides?: BuiltinPluginManifestOverridesV1;\n}): BuiltinPluginProfileResolutionV1 {\n\tconst profile = profiles.find((candidate) => candidate.id === input.profileId);\n\tif (profile === undefined) return { status: \"not_found\", profileId: input.profileId };\n\tconst requestedPluginIds = input.selectedPluginIds;\n\tconst requestedDisabledPluginIds = input.disabledPluginIds;\n\tif (requestedPluginIds !== undefined || requestedDisabledPluginIds !== undefined) {\n\t\tconst availablePluginIds = new Set(profile.pluginIds);\n\t\tconst duplicatePluginIds: string[] = [];\n\t\tconst unknownPluginIds: string[] = [];\n\t\tfor (const requestedIds of [requestedPluginIds ?? [], requestedDisabledPluginIds ?? []]) {\n\t\t\tconst seen = new Set<string>();\n\t\t\tfor (const pluginId of requestedIds) {\n\t\t\t\tif (!availablePluginIds.has(pluginId) && !unknownPluginIds.includes(pluginId))\n\t\t\t\t\tunknownPluginIds.push(pluginId);\n\t\t\t\tif (seen.has(pluginId) && !duplicatePluginIds.includes(pluginId)) duplicatePluginIds.push(pluginId);\n\t\t\t\tseen.add(pluginId);\n\t\t\t}\n\t\t}\n\t\tif (unknownPluginIds.length > 0 || duplicatePluginIds.length > 0) {\n\t\t\treturn {\n\t\t\t\tstatus: \"invalid_selection\",\n\t\t\t\tprofileId: input.profileId,\n\t\t\t\tunknownPluginIds: Object.freeze([...new Set(unknownPluginIds)]),\n\t\t\t\tduplicatePluginIds: Object.freeze(duplicatePluginIds),\n\t\t\t};\n\t\t}\n\t}\n\tconst selected =\n\t\trequestedPluginIds === undefined\n\t\t\t? profile.pluginIds\n\t\t\t: profile.pluginIds.filter((pluginId) => requestedPluginIds.includes(pluginId));\n\tconst selectedProfile =\n\t\trequestedPluginIds === undefined\n\t\t\t? profile\n\t\t\t: Object.freeze({ ...profile, pluginIds: Object.freeze([...selected]) });\n\tconst disabled = new Set(input.disabledPluginIds ?? []);\n\t// D-075 S2: a Profile plugin without a builtin manifest and without a\n\t// host-installed override is a structured miss, not a startup failure. The\n\t// plugin is omitted from the resolved manifest and runtime bindings; the\n\t// remaining Profile plugins resolve normally (soft degradation).\n\tconst manifestByPluginId = new Map(\n\t\tselectedProfile.pluginIds.map((pluginId) => [pluginId, manifestFor(pluginId, input.manifestOverrides)] as const),\n\t);\n\tconst missingPluginIds = selectedProfile.pluginIds.filter(\n\t\t(pluginId) => manifestByPluginId.get(pluginId) === undefined,\n\t);\n\tconst resolution = resolvePluginProfileV1({\n\t\tprofileId: selectedProfile.id,\n\t\tprofileVersion: selectedProfile.version,\n\t\tplugins: selectedProfile.pluginIds.flatMap((pluginId) => {\n\t\t\tconst manifest = manifestByPluginId.get(pluginId);\n\t\t\treturn manifest === undefined\n\t\t\t\t? []\n\t\t\t\t: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tmanifest,\n\t\t\t\t\t\t\t// A user-disabled plugin must not block the remaining profile. It is\n\t\t\t\t\t\t\t// still represented in the resolution diagnostics, but is omitted from\n\t\t\t\t\t\t\t// the active resolved manifest and runtime bindings.\n\t\t\t\t\t\t\trequired: !disabled.has(pluginId),\n\t\t\t\t\t\t\tdisabled: disabled.has(pluginId),\n\t\t\t\t\t\t},\n\t\t\t\t\t];\n\t\t}),\n\t\thost: input.host,\n\t\t// The host's own version enforces each manifest's minHostVersion floor\n\t\t// at the single builtin profile resolution funnel used by production\n\t\t// loading paths.\n\t\thostVersion: VERSION,\n\t});\n\tconst merged = mergeMissingPluginResolutionsV1(resolution, missingPluginIds, disabled);\n\tif (merged.status !== \"ready\") return { status: \"resolved\", profile: selectedProfile, resolution: merged };\n\tconst resolvedPlugins = merged.resolvedManifest.plugins.map((plugin) => ({\n\t\tpluginId: plugin.pluginId,\n\t\tpluginVersion: plugin.pluginVersion,\n\t\tcapabilityRefs: plugin.capabilityRefs,\n\t\t...(plugin.selectedAdapter === undefined ? {} : { selectedAdapter: plugin.selectedAdapter }),\n\t}));\n\tconst verifiedPlugins = input.verifiedPlugins ?? [];\n\tconst assembly = assembleProfile({\n\t\tprofileId: selectedProfile.id,\n\t\tprofileVersion: selectedProfile.version,\n\t\tresolvedPlugins,\n\t\tverifiedPlugins,\n\t});\n\treturn {\n\t\tstatus: \"resolved\",\n\t\tprofile: selectedProfile,\n\t\tresolution: merged,\n\t\tassembly,\n\t};\n}\n\nfunction manifestFor(\n\tpluginId: string,\n\toverrides: BuiltinPluginManifestOverridesV1 | undefined,\n): PluginManifestV1 | undefined {\n\tconst manifest = overrides?.[pluginId] ?? manifests[pluginId];\n\t// A mismatched override stays a hard host error: the host selected it\n\t// explicitly, so silence would hide an identity bug. A plain absent\n\t// manifest (no builtin, no installed override) is the structured miss.\n\tif (manifest !== undefined && manifest.id !== pluginId)\n\t\tthrow new Error(`builtin manifest override does not match plugin ${pluginId}`);\n\treturn manifest;\n}\n\n/**\n * Merge structured `manifest_missing` resolutions for Profile plugins that\n * have no builtin manifest and no installed override into the resolver\n * result. Missing plugins never block the Profile (soft degradation): the\n * remaining diagnostics and the resolved manifest stay exactly what the\n * resolver produced, and the merged plugin list keeps the resolver's\n * deterministic id sort.\n */\nfunction mergeMissingPluginResolutionsV1(\n\tresolution: ProfileResolutionV1,\n\tmissingPluginIds: readonly string[],\n\tdisabled: ReadonlySet<string>,\n): ProfileResolutionV1 {\n\tif (missingPluginIds.length === 0) return resolution;\n\tconst missing: PluginResolutionV1[] = missingPluginIds.map((pluginId) => ({\n\t\tpluginId,\n\t\tpluginVersion: \"\",\n\t\trequired: !disabled.has(pluginId),\n\t\tstatus: \"manifest-missing\",\n\t\tdiagnostics: [\n\t\t\t{\n\t\t\t\tcode: \"manifest_missing\",\n\t\t\t\tmessage: `Plugin ${pluginId} has no builtin manifest and no installed active override; the plugin is omitted from this profile (install it with agent-forge plugin install)`,\n\t\t\t},\n\t\t],\n\t}));\n\tconst plugins = [...resolution.plugins, ...missing].sort((left, right) =>\n\t\tleft.pluginId.localeCompare(right.pluginId),\n\t);\n\treturn Object.freeze({\n\t\t...resolution,\n\t\tplugins: Object.freeze(plugins),\n\t\tdiagnostics: Object.freeze(plugins.flatMap((plugin) => plugin.diagnostics)),\n\t});\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-agent-forge/agent-forge",
3
- "version": "0.85.9",
3
+ "version": "0.85.11",
4
4
  "description": "Coding agent CLI with read, bash, edit, write tools and session management",
5
5
  "type": "module",
6
6
  "agentForgeConfig": {