@agimon-ai/doompi-plan 0.0.1-alpha.23 → 0.0.1-alpha.25

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 (88) hide show
  1. package/README.md +4 -3
  2. package/dist/adapters/pi/extension.cjs +1 -1
  3. package/dist/adapters/pi/extension.cjs.map +1 -1
  4. package/dist/adapters/pi/extension.d.cts +4 -3
  5. package/dist/adapters/pi/extension.d.cts.map +1 -1
  6. package/dist/adapters/pi/extension.d.mts +4 -3
  7. package/dist/adapters/pi/extension.d.mts.map +1 -1
  8. package/dist/adapters/pi/extension.mjs +1 -1
  9. package/dist/adapters/pi/extension.mjs.map +1 -1
  10. package/dist/extensions/pi.cjs +1 -2
  11. package/dist/extensions/pi.d.cts +2 -2
  12. package/dist/extensions/pi.d.mts +2 -2
  13. package/dist/extensions/pi.mjs +1 -2
  14. package/dist/fableFlow.cjs +1 -1
  15. package/dist/fableFlow.d.cts +1 -1
  16. package/dist/fableFlow.d.mts +1 -1
  17. package/dist/fableFlow.mjs +1 -1
  18. package/dist/index.cjs +1 -1
  19. package/dist/index.d.cts +3 -3
  20. package/dist/index.d.mts +3 -3
  21. package/dist/index.mjs +1 -1
  22. package/dist/planMode.cjs +1 -1
  23. package/dist/planMode.d.cts +2 -2
  24. package/dist/planMode.d.mts +2 -2
  25. package/dist/planMode.mjs +1 -1
  26. package/dist/prompts.cjs +1 -1
  27. package/dist/prompts.d.cts +1 -1
  28. package/dist/prompts.d.mts +1 -1
  29. package/dist/prompts.mjs +1 -1
  30. package/dist/schemas/plan/planConfig.cjs +1 -1
  31. package/dist/schemas/plan/planConfig.cjs.map +1 -1
  32. package/dist/schemas/plan/planConfig.d.cts +1 -1
  33. package/dist/schemas/plan/planConfig.d.cts.map +1 -1
  34. package/dist/schemas/plan/planConfig.d.mts +1 -1
  35. package/dist/schemas/plan/planConfig.d.mts.map +1 -1
  36. package/dist/schemas/plan/planConfig.mjs +1 -1
  37. package/dist/schemas/plan/planConfig.mjs.map +1 -1
  38. package/dist/services/fableFlow.cjs +3 -0
  39. package/dist/services/fableFlow.cjs.map +1 -0
  40. package/dist/services/{plan/fableFlow.d.cts → fableFlow.d.cts} +3 -1
  41. package/dist/services/fableFlow.d.cts.map +1 -0
  42. package/dist/services/{plan/fableFlow.d.mts → fableFlow.d.mts} +3 -1
  43. package/dist/services/fableFlow.d.mts.map +1 -0
  44. package/dist/services/fableFlow.mjs +3 -0
  45. package/dist/services/fableFlow.mjs.map +1 -0
  46. package/dist/services/planMode.cjs +7 -0
  47. package/dist/services/planMode.cjs.map +1 -0
  48. package/dist/services/{plan/planMode.d.cts → planMode.d.cts} +5 -4
  49. package/dist/services/planMode.d.cts.map +1 -0
  50. package/dist/services/{plan/planMode.d.mts → planMode.d.mts} +5 -4
  51. package/dist/services/planMode.d.mts.map +1 -0
  52. package/dist/services/planMode.mjs +7 -0
  53. package/dist/services/planMode.mjs.map +1 -0
  54. package/dist/services/prompts.cjs.map +1 -0
  55. package/dist/services/{plan/prompts.d.cts → prompts.d.cts} +1 -1
  56. package/dist/services/prompts.d.cts.map +1 -0
  57. package/dist/services/{plan/prompts.d.mts → prompts.d.mts} +1 -1
  58. package/dist/services/prompts.d.mts.map +1 -0
  59. package/dist/services/prompts.mjs.map +1 -0
  60. package/package.json +50 -16
  61. package/dist/extensions/doom.cjs +0 -2
  62. package/dist/extensions/doom.cjs.map +0 -1
  63. package/dist/extensions/doom.d.cts +0 -8
  64. package/dist/extensions/doom.d.cts.map +0 -1
  65. package/dist/extensions/doom.d.mts +0 -8
  66. package/dist/extensions/doom.d.mts.map +0 -1
  67. package/dist/extensions/doom.mjs +0 -2
  68. package/dist/extensions/doom.mjs.map +0 -1
  69. package/dist/extensions/pi.cjs.map +0 -1
  70. package/dist/extensions/pi.mjs.map +0 -1
  71. package/dist/services/plan/fableFlow.cjs +0 -3
  72. package/dist/services/plan/fableFlow.cjs.map +0 -1
  73. package/dist/services/plan/fableFlow.d.cts.map +0 -1
  74. package/dist/services/plan/fableFlow.d.mts.map +0 -1
  75. package/dist/services/plan/fableFlow.mjs +0 -3
  76. package/dist/services/plan/fableFlow.mjs.map +0 -1
  77. package/dist/services/plan/planMode.cjs +0 -6
  78. package/dist/services/plan/planMode.cjs.map +0 -1
  79. package/dist/services/plan/planMode.d.cts.map +0 -1
  80. package/dist/services/plan/planMode.d.mts.map +0 -1
  81. package/dist/services/plan/planMode.mjs +0 -6
  82. package/dist/services/plan/planMode.mjs.map +0 -1
  83. package/dist/services/plan/prompts.cjs.map +0 -1
  84. package/dist/services/plan/prompts.d.cts.map +0 -1
  85. package/dist/services/plan/prompts.d.mts.map +0 -1
  86. package/dist/services/plan/prompts.mjs.map +0 -1
  87. /package/dist/services/{plan/prompts.cjs → prompts.cjs} +0 -0
  88. /package/dist/services/{plan/prompts.mjs → prompts.mjs} +0 -0
package/README.md CHANGED
@@ -15,13 +15,14 @@ Plan mode removes `edit` and `write` from the active tool set and directs writes
15
15
 
16
16
  ## Install
17
17
 
18
- DoomPi includes Plan as an inactive core minor mode. For standalone Pi:
18
+ DoomPi includes Plan in every composition; Plan mode itself remains inactive until requested. For
19
+ standalone Pi:
19
20
 
20
21
  ```bash
21
22
  pi install npm:@agimon-ai/doompi-plan
22
23
  ```
23
24
 
24
- Use `/extensions/doom` for DoomPi integrations or `/extensions/pi` for the plain Pi adapter.
25
+ DoomPi and plain Pi use the same `@agimon-ai/doompi-plan/extensions/pi` factory.
25
26
 
26
27
  ## Start and exit
27
28
 
@@ -32,7 +33,7 @@ Use `/extensions/doom` for DoomPi integrations or `/extensions/pi` for the plain
32
33
  | `SPC p f` | Fable-assisted drafting followed by Pi verification |
33
34
  | `SPC p e` | Exit and restore the prior model, thinking, and tool state |
34
35
 
35
- Normal planning expects repository exploration and delegation where available. Debug planning separates verified evidence from hypotheses. Fable is optional: it requires the configured Fable/Team integration, treats returned text as untrusted, and requires Pi to verify and synthesize the final plan.
36
+ Normal planning expects repository exploration and delegation where available. Debug planning separates verified evidence from hypotheses. Fable is optional: Plan injects Team's `doom/fable-plan` service, treats returned text as untrusted, and requires Pi to verify and synthesize the final plan. Its child capability ceiling is contributed through `doom/subagent-policy` and retracts when either provider or Plan unloads.
36
37
 
37
38
  A model or tool restoration failure leaves the narrowed Plan state active and reports the failure rather than pretending the session was restored.
38
39
 
@@ -1,2 +1,2 @@
1
- const e=require(`../../services/plan/planMode.cjs`),t={recordError:async()=>void 0,recordWarning:async()=>void 0,recordEvent:async()=>void 0,flush:async()=>void 0,shutdown:async()=>void 0};function n(n){e.planModeExtension(n,()=>void 0,t,{doomIntegrations:!1})}exports.activateStandardPlanExtension=n;
1
+ require(`../../_virtual/_rolldown/runtime.cjs`);const e=require(`../../services/planMode.cjs`);let t=require(`@agimon-ai/doompi-extension-contracts/cordis-host`);function n(t,n){e.planModeExtension(t,n)}async function r(e){let n=await(0,t.connectDoomCordisHost)(e,`@agimon-ai/doompi-plan`),r=n.root.plugin(i,{pi:e});try{await r}catch(e){try{await r.dispose()}finally{await n.dispose()}throw e}let a;e.on(`session_shutdown`,()=>a??=(async()=>{try{await r.dispose()}finally{await n.dispose()}})())}function i(e,t){n(e,t.pi)}exports.default=r;
2
2
  //# sourceMappingURL=extension.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"extension.cjs","names":[],"sources":["../../../src/adapters/pi/extension.ts"],"sourcesContent":["import type { ExtensionAPI } from '@earendil-works/pi-coding-agent';\nimport { planModeExtension } from '../../services/plan/planMode.ts';\nimport type { PlanTelemetry } from '../telemetry/logSinkTelemetry.ts';\n\nconst standardTelemetry: PlanTelemetry = {\n recordError: async () => undefined,\n recordWarning: async () => undefined,\n recordEvent: async () => undefined,\n flush: async () => undefined,\n shutdown: async () => undefined,\n};\n\n/** Standard Pi composition using session APIs without Doom config or UI providers. */\nexport function activateStandardPlanExtension(pi: ExtensionAPI): void {\n planModeExtension(pi, () => undefined, standardTelemetry, { doomIntegrations: false });\n}\n"],"mappings":"oDAIM,EAAmC,CACvC,YAAa,SAAY,IAAA,GACzB,cAAe,SAAY,IAAA,GAC3B,YAAa,SAAY,IAAA,GACzB,MAAO,SAAY,IAAA,GACnB,SAAU,SAAY,IAAA,GACvB,CAGD,SAAgB,EAA8B,EAAwB,CACpE,EAAA,kBAAkB,MAAU,IAAA,GAAW,EAAmB,CAAE,iBAAkB,GAAO,CAAC"}
1
+ {"version":3,"file":"extension.cjs","names":[],"sources":["../../../src/adapters/pi/extension.ts"],"sourcesContent":["import { connectDoomCordisHost } from '@agimon-ai/doompi-extension-contracts/cordis-host';\nimport type { Context } from '@deepseek-ai/cordis';\nimport type { ExtensionAPI } from '@earendil-works/pi-coding-agent';\nimport { planModeExtension } from '../../services/planMode.ts';\n\nconst PACKAGE_SOURCE = '@agimon-ai/doompi-plan';\n\n/** Install Plan state and external resources into its host-owned Cordis plugin fiber. */\nexport function installPlanRuntime(cordis: Context, pi: ExtensionAPI): void {\n planModeExtension(cordis, pi);\n}\n\n/** The package's single standard Pi factory, including all optional typed Doom integrations. */\nexport async function activatePlanExtension(pi: ExtensionAPI): Promise<void> {\n const connection = await connectDoomCordisHost(pi, PACKAGE_SOURCE);\n const fiber = connection.root.plugin(planPlugin, { pi });\n try {\n await fiber;\n } catch (error) {\n try {\n await fiber.dispose();\n } finally {\n await connection.dispose();\n }\n throw error;\n }\n let disposal: Promise<void> | undefined;\n pi.on(\n 'session_shutdown',\n () =>\n (disposal ??= (async () => {\n try {\n await fiber.dispose();\n } finally {\n await connection.dispose();\n }\n })()),\n );\n}\n\ninterface PlanPluginConfig {\n readonly pi: ExtensionAPI;\n}\n\nfunction planPlugin(cordis: Context, config: PlanPluginConfig): void {\n installPlanRuntime(cordis, config.pi);\n}\n\nexport default activatePlanExtension;\n"],"mappings":"kKAQA,SAAgB,EAAmB,EAAiB,EAAwB,CAC1E,EAAA,kBAAkB,EAAQ,EAAG,CAI/B,eAAsB,EAAsB,EAAiC,CAC3E,IAAM,EAAa,MAAA,EAAA,EAAA,uBAA4B,EAAI,yBAAe,CAC5D,EAAQ,EAAW,KAAK,OAAO,EAAY,CAAE,KAAI,CAAC,CACxD,GAAI,CACF,MAAM,QACC,EAAO,CACd,GAAI,CACF,MAAM,EAAM,SAAS,QACb,CACR,MAAM,EAAW,SAAS,CAE5B,MAAM,EAER,IAAI,EACJ,EAAG,GACD,uBAEG,KAAc,SAAY,CACzB,GAAI,CACF,MAAM,EAAM,SAAS,QACb,CACR,MAAM,EAAW,SAAS,KAE1B,CACP,CAOH,SAAS,EAAW,EAAiB,EAAgC,CACnE,EAAmB,EAAQ,EAAO,GAAG"}
@@ -1,8 +1,9 @@
1
+ import { Context } from "@deepseek-ai/cordis";
1
2
  import { ExtensionAPI } from "@earendil-works/pi-coding-agent";
2
3
 
3
4
  //#region src/adapters/pi/extension.d.ts
4
- /** Standard Pi composition using session APIs without Doom config or UI providers. */
5
- declare function activateStandardPlanExtension(pi: ExtensionAPI): void;
5
+ /** The package's single standard Pi factory, including all optional typed Doom integrations. */
6
+ declare function activatePlanExtension(pi: ExtensionAPI): Promise<void>;
6
7
  //#endregion
7
- export { activateStandardPlanExtension };
8
+ export { activatePlanExtension };
8
9
  //# sourceMappingURL=extension.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"extension.d.cts","names":[],"sources":["../../../src/adapters/pi/extension.ts"],"mappings":";;;;iBAagB,6BAAA,CAA8B,EAAA,EAAI,YAAA"}
1
+ {"version":3,"file":"extension.d.cts","names":[],"sources":["../../../src/adapters/pi/extension.ts"],"mappings":";;;;AAaA;AAAA,iBAAsB,qBAAA,CAAsB,EAAA,EAAI,YAAA,GAAe,OAAA"}
@@ -1,8 +1,9 @@
1
+ import { Context } from "@deepseek-ai/cordis";
1
2
  import { ExtensionAPI } from "@earendil-works/pi-coding-agent";
2
3
 
3
4
  //#region src/adapters/pi/extension.d.ts
4
- /** Standard Pi composition using session APIs without Doom config or UI providers. */
5
- declare function activateStandardPlanExtension(pi: ExtensionAPI): void;
5
+ /** The package's single standard Pi factory, including all optional typed Doom integrations. */
6
+ declare function activatePlanExtension(pi: ExtensionAPI): Promise<void>;
6
7
  //#endregion
7
- export { activateStandardPlanExtension };
8
+ export { activatePlanExtension };
8
9
  //# sourceMappingURL=extension.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"extension.d.mts","names":[],"sources":["../../../src/adapters/pi/extension.ts"],"mappings":";;;;iBAagB,6BAAA,CAA8B,EAAA,EAAI,YAAA"}
1
+ {"version":3,"file":"extension.d.mts","names":[],"sources":["../../../src/adapters/pi/extension.ts"],"mappings":";;;;AAaA;AAAA,iBAAsB,qBAAA,CAAsB,EAAA,EAAI,YAAA,GAAe,OAAA"}
@@ -1,2 +1,2 @@
1
- import{planModeExtension as e}from"../../services/plan/planMode.mjs";const t={recordError:async()=>void 0,recordWarning:async()=>void 0,recordEvent:async()=>void 0,flush:async()=>void 0,shutdown:async()=>void 0};function n(n){e(n,()=>void 0,t,{doomIntegrations:!1})}export{n as activateStandardPlanExtension};
1
+ import{planModeExtension as e}from"../../services/planMode.mjs";import{connectDoomCordisHost as t}from"@agimon-ai/doompi-extension-contracts/cordis-host";function n(t,n){e(t,n)}async function r(e){let n=await t(e,`@agimon-ai/doompi-plan`),r=n.root.plugin(i,{pi:e});try{await r}catch(e){try{await r.dispose()}finally{await n.dispose()}throw e}let a;e.on(`session_shutdown`,()=>a??=(async()=>{try{await r.dispose()}finally{await n.dispose()}})())}function i(e,t){n(e,t.pi)}export{r as default};
2
2
  //# sourceMappingURL=extension.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"extension.mjs","names":[],"sources":["../../../src/adapters/pi/extension.ts"],"sourcesContent":["import type { ExtensionAPI } from '@earendil-works/pi-coding-agent';\nimport { planModeExtension } from '../../services/plan/planMode.ts';\nimport type { PlanTelemetry } from '../telemetry/logSinkTelemetry.ts';\n\nconst standardTelemetry: PlanTelemetry = {\n recordError: async () => undefined,\n recordWarning: async () => undefined,\n recordEvent: async () => undefined,\n flush: async () => undefined,\n shutdown: async () => undefined,\n};\n\n/** Standard Pi composition using session APIs without Doom config or UI providers. */\nexport function activateStandardPlanExtension(pi: ExtensionAPI): void {\n planModeExtension(pi, () => undefined, standardTelemetry, { doomIntegrations: false });\n}\n"],"mappings":"qEAIA,MAAM,EAAmC,CACvC,YAAa,SAAY,IAAA,GACzB,cAAe,SAAY,IAAA,GAC3B,YAAa,SAAY,IAAA,GACzB,MAAO,SAAY,IAAA,GACnB,SAAU,SAAY,IAAA,GACvB,CAGD,SAAgB,EAA8B,EAAwB,CACpE,EAAkB,MAAU,IAAA,GAAW,EAAmB,CAAE,iBAAkB,GAAO,CAAC"}
1
+ {"version":3,"file":"extension.mjs","names":[],"sources":["../../../src/adapters/pi/extension.ts"],"sourcesContent":["import { connectDoomCordisHost } from '@agimon-ai/doompi-extension-contracts/cordis-host';\nimport type { Context } from '@deepseek-ai/cordis';\nimport type { ExtensionAPI } from '@earendil-works/pi-coding-agent';\nimport { planModeExtension } from '../../services/planMode.ts';\n\nconst PACKAGE_SOURCE = '@agimon-ai/doompi-plan';\n\n/** Install Plan state and external resources into its host-owned Cordis plugin fiber. */\nexport function installPlanRuntime(cordis: Context, pi: ExtensionAPI): void {\n planModeExtension(cordis, pi);\n}\n\n/** The package's single standard Pi factory, including all optional typed Doom integrations. */\nexport async function activatePlanExtension(pi: ExtensionAPI): Promise<void> {\n const connection = await connectDoomCordisHost(pi, PACKAGE_SOURCE);\n const fiber = connection.root.plugin(planPlugin, { pi });\n try {\n await fiber;\n } catch (error) {\n try {\n await fiber.dispose();\n } finally {\n await connection.dispose();\n }\n throw error;\n }\n let disposal: Promise<void> | undefined;\n pi.on(\n 'session_shutdown',\n () =>\n (disposal ??= (async () => {\n try {\n await fiber.dispose();\n } finally {\n await connection.dispose();\n }\n })()),\n );\n}\n\ninterface PlanPluginConfig {\n readonly pi: ExtensionAPI;\n}\n\nfunction planPlugin(cordis: Context, config: PlanPluginConfig): void {\n installPlanRuntime(cordis, config.pi);\n}\n\nexport default activatePlanExtension;\n"],"mappings":"0JAQA,SAAgB,EAAmB,EAAiB,EAAwB,CAC1E,EAAkB,EAAQ,EAAG,CAI/B,eAAsB,EAAsB,EAAiC,CAC3E,IAAM,EAAa,MAAM,EAAsB,EAAI,yBAAe,CAC5D,EAAQ,EAAW,KAAK,OAAO,EAAY,CAAE,KAAI,CAAC,CACxD,GAAI,CACF,MAAM,QACC,EAAO,CACd,GAAI,CACF,MAAM,EAAM,SAAS,QACb,CACR,MAAM,EAAW,SAAS,CAE5B,MAAM,EAER,IAAI,EACJ,EAAG,GACD,uBAEG,KAAc,SAAY,CACzB,GAAI,CACF,MAAM,EAAM,SAAS,QACb,CACR,MAAM,EAAW,SAAS,KAE1B,CACP,CAOH,SAAS,EAAW,EAAiB,EAAgC,CACnE,EAAmB,EAAQ,EAAO,GAAG"}
@@ -1,2 +1 @@
1
- var e=require(`../adapters/pi/extension.cjs`).activateStandardPlanExtension;module.exports=e;
2
- //# sourceMappingURL=pi.cjs.map
1
+ const e=require(`../adapters/pi/extension.cjs`);module.exports=e;
@@ -1,2 +1,2 @@
1
- import { activateStandardPlanExtension } from "../adapters/pi/extension.cjs";
2
- export = activateStandardPlanExtension;
1
+ import { activatePlanExtension } from "../adapters/pi/extension.cjs";
2
+ export = activatePlanExtension;
@@ -1,2 +1,2 @@
1
- import { activateStandardPlanExtension } from "../adapters/pi/extension.mjs";
2
- export { activateStandardPlanExtension as default };
1
+ import { activatePlanExtension } from "../adapters/pi/extension.mjs";
2
+ export { activatePlanExtension as default };
@@ -1,2 +1 @@
1
- import{activateStandardPlanExtension as e}from"../adapters/pi/extension.mjs";var t=e;export{t as default};
2
- //# sourceMappingURL=pi.mjs.map
1
+ import e from"../adapters/pi/extension.mjs";export{e as default};
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./services/plan/fableFlow.cjs`);exports.FABLE_PLAN_MODEL=e.FABLE_PLAN_MODEL,exports.FABLE_PLAN_PROFILE=e.FABLE_PLAN_PROFILE,exports.FABLE_PLAN_REQUESTER=e.FABLE_PLAN_REQUESTER,exports.FABLE_PLAN_RUNTIME=e.FABLE_PLAN_RUNTIME,exports.FABLE_PROVIDER_SOURCE=e.FABLE_PROVIDER_SOURCE,exports.MAX_FABLE_ARRAY_ITEMS=e.MAX_FABLE_ARRAY_ITEMS,exports.MAX_FABLE_PACKET_BYTES=e.MAX_FABLE_PACKET_BYTES,exports.MAX_FABLE_TEXT_BYTES=e.MAX_FABLE_TEXT_BYTES,exports.containsSuspectedCredential=e.containsSuspectedCredential,exports.createFablePlanFlow=e.createFablePlanFlow,exports.sanitizeFablePacket=e.sanitizeFablePacket;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./services/fableFlow.cjs`);exports.FABLE_PLAN_MODEL=e.FABLE_PLAN_MODEL,exports.FABLE_PLAN_PROFILE=e.FABLE_PLAN_PROFILE,exports.FABLE_PLAN_REQUESTER=e.FABLE_PLAN_REQUESTER,exports.FABLE_PLAN_RUNTIME=e.FABLE_PLAN_RUNTIME,exports.FABLE_PROVIDER_SOURCE=e.FABLE_PROVIDER_SOURCE,exports.MAX_FABLE_ARRAY_ITEMS=e.MAX_FABLE_ARRAY_ITEMS,exports.MAX_FABLE_PACKET_BYTES=e.MAX_FABLE_PACKET_BYTES,exports.MAX_FABLE_TEXT_BYTES=e.MAX_FABLE_TEXT_BYTES,exports.containsSuspectedCredential=e.containsSuspectedCredential,exports.createFablePlanFlow=e.createFablePlanFlow,exports.sanitizeFablePacket=e.sanitizeFablePacket;
@@ -1,2 +1,2 @@
1
- import { FABLE_PLAN_MODEL, FABLE_PLAN_PROFILE, FABLE_PLAN_REQUESTER, FABLE_PLAN_RUNTIME, FABLE_PROVIDER_SOURCE, FableFlowOptions, FablePlanBroker, FablePlanFinding, FablePlanFlow, FablePlanPacket, FablePlanRequest, FablePlanResult, FablePlanStage, FablePlanStatus, FableStage, MAX_FABLE_ARRAY_ITEMS, MAX_FABLE_PACKET_BYTES, MAX_FABLE_TEXT_BYTES, containsSuspectedCredential, createFablePlanFlow, sanitizeFablePacket } from "./services/plan/fableFlow.cjs";
1
+ import { FABLE_PLAN_MODEL, FABLE_PLAN_PROFILE, FABLE_PLAN_REQUESTER, FABLE_PLAN_RUNTIME, FABLE_PROVIDER_SOURCE, FableFlowOptions, FablePlanBroker, FablePlanFinding, FablePlanFlow, FablePlanPacket, FablePlanRequest, FablePlanResult, FablePlanStage, FablePlanStatus, FableStage, MAX_FABLE_ARRAY_ITEMS, MAX_FABLE_PACKET_BYTES, MAX_FABLE_TEXT_BYTES, containsSuspectedCredential, createFablePlanFlow, sanitizeFablePacket } from "./services/fableFlow.cjs";
2
2
  export { FABLE_PLAN_MODEL, FABLE_PLAN_PROFILE, FABLE_PLAN_REQUESTER, FABLE_PLAN_RUNTIME, FABLE_PROVIDER_SOURCE, FableFlowOptions, FablePlanBroker, FablePlanFinding, FablePlanFlow, FablePlanPacket, FablePlanRequest, FablePlanResult, FablePlanStage, FablePlanStatus, FableStage, MAX_FABLE_ARRAY_ITEMS, MAX_FABLE_PACKET_BYTES, MAX_FABLE_TEXT_BYTES, containsSuspectedCredential, createFablePlanFlow, sanitizeFablePacket };
@@ -1,2 +1,2 @@
1
- import { FABLE_PLAN_MODEL, FABLE_PLAN_PROFILE, FABLE_PLAN_REQUESTER, FABLE_PLAN_RUNTIME, FABLE_PROVIDER_SOURCE, FableFlowOptions, FablePlanBroker, FablePlanFinding, FablePlanFlow, FablePlanPacket, FablePlanRequest, FablePlanResult, FablePlanStage, FablePlanStatus, FableStage, MAX_FABLE_ARRAY_ITEMS, MAX_FABLE_PACKET_BYTES, MAX_FABLE_TEXT_BYTES, containsSuspectedCredential, createFablePlanFlow, sanitizeFablePacket } from "./services/plan/fableFlow.mjs";
1
+ import { FABLE_PLAN_MODEL, FABLE_PLAN_PROFILE, FABLE_PLAN_REQUESTER, FABLE_PLAN_RUNTIME, FABLE_PROVIDER_SOURCE, FableFlowOptions, FablePlanBroker, FablePlanFinding, FablePlanFlow, FablePlanPacket, FablePlanRequest, FablePlanResult, FablePlanStage, FablePlanStatus, FableStage, MAX_FABLE_ARRAY_ITEMS, MAX_FABLE_PACKET_BYTES, MAX_FABLE_TEXT_BYTES, containsSuspectedCredential, createFablePlanFlow, sanitizeFablePacket } from "./services/fableFlow.mjs";
2
2
  export { FABLE_PLAN_MODEL, FABLE_PLAN_PROFILE, FABLE_PLAN_REQUESTER, FABLE_PLAN_RUNTIME, FABLE_PROVIDER_SOURCE, FableFlowOptions, FablePlanBroker, FablePlanFinding, FablePlanFlow, FablePlanPacket, FablePlanRequest, FablePlanResult, FablePlanStage, FablePlanStatus, FableStage, MAX_FABLE_ARRAY_ITEMS, MAX_FABLE_PACKET_BYTES, MAX_FABLE_TEXT_BYTES, containsSuspectedCredential, createFablePlanFlow, sanitizeFablePacket };
@@ -1 +1 @@
1
- import{FABLE_PLAN_MODEL as e,FABLE_PLAN_PROFILE as t,FABLE_PLAN_REQUESTER as n,FABLE_PLAN_RUNTIME as r,FABLE_PROVIDER_SOURCE as i,MAX_FABLE_ARRAY_ITEMS as a,MAX_FABLE_PACKET_BYTES as o,MAX_FABLE_TEXT_BYTES as s,containsSuspectedCredential as c,createFablePlanFlow as l,sanitizeFablePacket as u}from"./services/plan/fableFlow.mjs";export{e as FABLE_PLAN_MODEL,t as FABLE_PLAN_PROFILE,n as FABLE_PLAN_REQUESTER,r as FABLE_PLAN_RUNTIME,i as FABLE_PROVIDER_SOURCE,a as MAX_FABLE_ARRAY_ITEMS,o as MAX_FABLE_PACKET_BYTES,s as MAX_FABLE_TEXT_BYTES,c as containsSuspectedCredential,l as createFablePlanFlow,u as sanitizeFablePacket};
1
+ import{FABLE_PLAN_MODEL as e,FABLE_PLAN_PROFILE as t,FABLE_PLAN_REQUESTER as n,FABLE_PLAN_RUNTIME as r,FABLE_PROVIDER_SOURCE as i,MAX_FABLE_ARRAY_ITEMS as a,MAX_FABLE_PACKET_BYTES as o,MAX_FABLE_TEXT_BYTES as s,containsSuspectedCredential as c,createFablePlanFlow as l,sanitizeFablePacket as u}from"./services/fableFlow.mjs";export{e as FABLE_PLAN_MODEL,t as FABLE_PLAN_PROFILE,n as FABLE_PLAN_REQUESTER,r as FABLE_PLAN_RUNTIME,i as FABLE_PROVIDER_SOURCE,a as MAX_FABLE_ARRAY_ITEMS,o as MAX_FABLE_PACKET_BYTES,s as MAX_FABLE_TEXT_BYTES,c as containsSuspectedCredential,l as createFablePlanFlow,u as sanitizeFablePacket};
package/dist/index.cjs CHANGED
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`./_virtual/_rolldown/runtime.cjs`);const e=require(`./schemas/plan/config.cjs`),t=require(`./services/plan/fableFlow.cjs`),n=require(`./services/plan/prompts.cjs`),r=require(`./services/plan/planMode.cjs`);let i=require(`@agimon-ai/doompi-config`);exports.FABLE_PLAN_MODEL=t.FABLE_PLAN_MODEL,exports.FABLE_PLAN_PROFILE=t.FABLE_PLAN_PROFILE,exports.FABLE_PLAN_REQUESTER=t.FABLE_PLAN_REQUESTER,exports.FABLE_PLAN_RUNTIME=t.FABLE_PLAN_RUNTIME,exports.FABLE_PROVIDER_SOURCE=t.FABLE_PROVIDER_SOURCE,exports.MAX_FABLE_ARRAY_ITEMS=t.MAX_FABLE_ARRAY_ITEMS,exports.MAX_FABLE_PACKET_BYTES=t.MAX_FABLE_PACKET_BYTES,exports.MAX_FABLE_TEXT_BYTES=t.MAX_FABLE_TEXT_BYTES,exports.WRITE_PLAN_TIMEOUT_MS=r.WRITE_PLAN_TIMEOUT_MS,exports.buildDebugPlanningPrompt=n.buildDebugPlanningPrompt,exports.buildFablePlanningPrompt=n.buildFablePlanningPrompt,exports.buildFlavorPlanningPrompt=n.buildFlavorPlanningPrompt,exports.buildNormalPlanningPrompt=n.buildNormalPlanningPrompt,exports.configurePlanningSubagentInput=r.configurePlanningSubagentInput,exports.configurePlanningTaskInput=r.configurePlanningTaskInput,exports.constrainSubagentInput=r.constrainSubagentInput,exports.containsSuspectedCredential=t.containsSuspectedCredential,exports.createFablePlanFlow=t.createFablePlanFlow,exports.createPlanIdentifier=r.createPlanIdentifier,exports.getHarnessState=i.getHarnessState,exports.globalDoomConfigPath=i.globalDoomConfigPath,exports.isBlockedSubagentManagementAction=r.isBlockedSubagentManagementAction,exports.loadDoomConfig=e.loadDoomConfig,exports.loadHarnessState=i.loadHarnessState,exports.loadPlanningModeConfig=r.loadPlanningModeConfig,exports.mergeDoomConfigs=e.mergeDoomConfigs,exports.parseDebugEvidencePacket=r.parseDebugEvidencePacket,exports.parseDoomConfig=e.parseDoomConfig,exports.parsePersistedPlanState=r.parsePersistedPlanState,exports.parsePlanningModeConfig=i.parsePlanningModeConfig,exports.planModeExtension=r.planModeExtension,exports.planModeTools=r.planModeTools,exports.planSessionIdentifier=r.planSessionIdentifier,exports.planTitleSlug=r.planTitleSlug,exports.planningSubagentModel=r.planningSubagentModel,exports.repositoryDoomConfigPath=i.repositoryDoomConfigPath,exports.resolvePlanningPlansDirectory=i.resolvePlanningPlansDirectory,exports.sanitizeFablePacket=t.sanitizeFablePacket,exports.visiblePlanForToolCall=r.visiblePlanForToolCall;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`./_virtual/_rolldown/runtime.cjs`);const e=require(`./schemas/plan/config.cjs`),t=require(`./services/fableFlow.cjs`),n=require(`./services/prompts.cjs`),r=require(`./services/planMode.cjs`);let i=require(`@agimon-ai/doompi-config`);exports.FABLE_PLAN_MODEL=t.FABLE_PLAN_MODEL,exports.FABLE_PLAN_PROFILE=t.FABLE_PLAN_PROFILE,exports.FABLE_PLAN_REQUESTER=t.FABLE_PLAN_REQUESTER,exports.FABLE_PLAN_RUNTIME=t.FABLE_PLAN_RUNTIME,exports.FABLE_PROVIDER_SOURCE=t.FABLE_PROVIDER_SOURCE,exports.MAX_FABLE_ARRAY_ITEMS=t.MAX_FABLE_ARRAY_ITEMS,exports.MAX_FABLE_PACKET_BYTES=t.MAX_FABLE_PACKET_BYTES,exports.MAX_FABLE_TEXT_BYTES=t.MAX_FABLE_TEXT_BYTES,exports.WRITE_PLAN_TIMEOUT_MS=r.WRITE_PLAN_TIMEOUT_MS,exports.buildDebugPlanningPrompt=n.buildDebugPlanningPrompt,exports.buildFablePlanningPrompt=n.buildFablePlanningPrompt,exports.buildFlavorPlanningPrompt=n.buildFlavorPlanningPrompt,exports.buildNormalPlanningPrompt=n.buildNormalPlanningPrompt,exports.configurePlanningSubagentInput=r.configurePlanningSubagentInput,exports.configurePlanningTaskInput=r.configurePlanningTaskInput,exports.constrainSubagentInput=r.constrainSubagentInput,exports.containsSuspectedCredential=t.containsSuspectedCredential,exports.createFablePlanFlow=t.createFablePlanFlow,exports.createPlanIdentifier=r.createPlanIdentifier,exports.getHarnessState=i.getHarnessState,exports.globalDoomConfigPath=i.globalDoomConfigPath,exports.isBlockedSubagentManagementAction=r.isBlockedSubagentManagementAction,exports.loadDoomConfig=e.loadDoomConfig,exports.loadHarnessState=i.loadHarnessState,exports.loadPlanningModeConfig=r.loadPlanningModeConfig,exports.mergeDoomConfigs=e.mergeDoomConfigs,exports.parseDebugEvidencePacket=r.parseDebugEvidencePacket,exports.parseDoomConfig=e.parseDoomConfig,exports.parsePersistedPlanState=r.parsePersistedPlanState,exports.parsePlanningModeConfig=i.parsePlanningModeConfig,exports.planModeExtension=r.planModeExtension,exports.planModeTools=r.planModeTools,exports.planSessionIdentifier=r.planSessionIdentifier,exports.planTitleSlug=r.planTitleSlug,exports.planningSubagentModel=r.planningSubagentModel,exports.repositoryDoomConfigPath=i.repositoryDoomConfigPath,exports.resolvePlanningPlansDirectory=i.resolvePlanningPlansDirectory,exports.sanitizeFablePacket=t.sanitizeFablePacket,exports.visiblePlanForToolCall=r.visiblePlanForToolCall;
package/dist/index.d.cts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { DoomConfig, PlanningAgentConfig, PlanningModeConfig, PlanningThinkingLevel, getHarnessState, globalDoomConfigPath, loadDoomConfig, loadHarnessState, mergeDoomConfigs, parseDoomConfig, parsePlanningModeConfig, repositoryDoomConfigPath, resolvePlanningPlansDirectory } from "./schemas/plan/config.cjs";
2
- import { FABLE_PLAN_MODEL, FABLE_PLAN_PROFILE, FABLE_PLAN_REQUESTER, FABLE_PLAN_RUNTIME, FABLE_PROVIDER_SOURCE, FableFlowOptions, FablePlanBroker, FablePlanFinding, FablePlanFlow, FablePlanPacket, FablePlanRequest, FablePlanResult, FablePlanStage, FablePlanStatus, FableStage, MAX_FABLE_ARRAY_ITEMS, MAX_FABLE_PACKET_BYTES, MAX_FABLE_TEXT_BYTES, containsSuspectedCredential, createFablePlanFlow, sanitizeFablePacket } from "./services/plan/fableFlow.cjs";
3
- import { DebugEvidencePacket, PlanningFlavor, buildDebugPlanningPrompt, buildFablePlanningPrompt, buildFlavorPlanningPrompt, buildNormalPlanningPrompt } from "./services/plan/prompts.cjs";
4
- import { ModelIdentity, PlanModeExtensionOptions, PlanSnapshot, PlanningConfigProvider, WRITE_PLAN_TIMEOUT_MS, configurePlanningSubagentInput, configurePlanningTaskInput, constrainSubagentInput, createPlanIdentifier, isBlockedSubagentManagementAction, loadPlanningModeConfig, parseDebugEvidencePacket, parsePersistedPlanState, planModeExtension, planModeTools, planSessionIdentifier, planTitleSlug, planningSubagentModel, visiblePlanForToolCall } from "./services/plan/planMode.cjs";
2
+ import { FABLE_PLAN_MODEL, FABLE_PLAN_PROFILE, FABLE_PLAN_REQUESTER, FABLE_PLAN_RUNTIME, FABLE_PROVIDER_SOURCE, FableFlowOptions, FablePlanBroker, FablePlanFinding, FablePlanFlow, FablePlanPacket, FablePlanRequest, FablePlanResult, FablePlanStage, FablePlanStatus, FableStage, MAX_FABLE_ARRAY_ITEMS, MAX_FABLE_PACKET_BYTES, MAX_FABLE_TEXT_BYTES, containsSuspectedCredential, createFablePlanFlow, sanitizeFablePacket } from "./services/fableFlow.cjs";
3
+ import { DebugEvidencePacket, PlanningFlavor, buildDebugPlanningPrompt, buildFablePlanningPrompt, buildFlavorPlanningPrompt, buildNormalPlanningPrompt } from "./services/prompts.cjs";
4
+ import { ModelIdentity, PlanModeExtensionOptions, PlanSnapshot, PlanningConfigProvider, WRITE_PLAN_TIMEOUT_MS, configurePlanningSubagentInput, configurePlanningTaskInput, constrainSubagentInput, createPlanIdentifier, isBlockedSubagentManagementAction, loadPlanningModeConfig, parseDebugEvidencePacket, parsePersistedPlanState, planModeExtension, planModeTools, planSessionIdentifier, planTitleSlug, planningSubagentModel, visiblePlanForToolCall } from "./services/planMode.cjs";
5
5
  export { DebugEvidencePacket, DoomConfig, FABLE_PLAN_MODEL, FABLE_PLAN_PROFILE, FABLE_PLAN_REQUESTER, FABLE_PLAN_RUNTIME, FABLE_PROVIDER_SOURCE, FableFlowOptions, FablePlanBroker, FablePlanFinding, FablePlanFlow, FablePlanPacket, FablePlanRequest, FablePlanResult, FablePlanStage, FablePlanStatus, FableStage, MAX_FABLE_ARRAY_ITEMS, MAX_FABLE_PACKET_BYTES, MAX_FABLE_TEXT_BYTES, ModelIdentity, PlanModeExtensionOptions, PlanSnapshot, PlanningAgentConfig, PlanningConfigProvider, PlanningFlavor, PlanningModeConfig, PlanningThinkingLevel, WRITE_PLAN_TIMEOUT_MS, buildDebugPlanningPrompt, buildFablePlanningPrompt, buildFlavorPlanningPrompt, buildNormalPlanningPrompt, configurePlanningSubagentInput, configurePlanningTaskInput, constrainSubagentInput, containsSuspectedCredential, createFablePlanFlow, createPlanIdentifier, getHarnessState, globalDoomConfigPath, isBlockedSubagentManagementAction, loadDoomConfig, loadHarnessState, loadPlanningModeConfig, mergeDoomConfigs, parseDebugEvidencePacket, parseDoomConfig, parsePersistedPlanState, parsePlanningModeConfig, planModeExtension, planModeTools, planSessionIdentifier, planTitleSlug, planningSubagentModel, repositoryDoomConfigPath, resolvePlanningPlansDirectory, sanitizeFablePacket, visiblePlanForToolCall };
package/dist/index.d.mts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { DoomConfig, PlanningAgentConfig, PlanningModeConfig, PlanningThinkingLevel, getHarnessState, globalDoomConfigPath, loadDoomConfig, loadHarnessState, mergeDoomConfigs, parseDoomConfig, parsePlanningModeConfig, repositoryDoomConfigPath, resolvePlanningPlansDirectory } from "./schemas/plan/config.mjs";
2
- import { FABLE_PLAN_MODEL, FABLE_PLAN_PROFILE, FABLE_PLAN_REQUESTER, FABLE_PLAN_RUNTIME, FABLE_PROVIDER_SOURCE, FableFlowOptions, FablePlanBroker, FablePlanFinding, FablePlanFlow, FablePlanPacket, FablePlanRequest, FablePlanResult, FablePlanStage, FablePlanStatus, FableStage, MAX_FABLE_ARRAY_ITEMS, MAX_FABLE_PACKET_BYTES, MAX_FABLE_TEXT_BYTES, containsSuspectedCredential, createFablePlanFlow, sanitizeFablePacket } from "./services/plan/fableFlow.mjs";
3
- import { DebugEvidencePacket, PlanningFlavor, buildDebugPlanningPrompt, buildFablePlanningPrompt, buildFlavorPlanningPrompt, buildNormalPlanningPrompt } from "./services/plan/prompts.mjs";
4
- import { ModelIdentity, PlanModeExtensionOptions, PlanSnapshot, PlanningConfigProvider, WRITE_PLAN_TIMEOUT_MS, configurePlanningSubagentInput, configurePlanningTaskInput, constrainSubagentInput, createPlanIdentifier, isBlockedSubagentManagementAction, loadPlanningModeConfig, parseDebugEvidencePacket, parsePersistedPlanState, planModeExtension, planModeTools, planSessionIdentifier, planTitleSlug, planningSubagentModel, visiblePlanForToolCall } from "./services/plan/planMode.mjs";
2
+ import { FABLE_PLAN_MODEL, FABLE_PLAN_PROFILE, FABLE_PLAN_REQUESTER, FABLE_PLAN_RUNTIME, FABLE_PROVIDER_SOURCE, FableFlowOptions, FablePlanBroker, FablePlanFinding, FablePlanFlow, FablePlanPacket, FablePlanRequest, FablePlanResult, FablePlanStage, FablePlanStatus, FableStage, MAX_FABLE_ARRAY_ITEMS, MAX_FABLE_PACKET_BYTES, MAX_FABLE_TEXT_BYTES, containsSuspectedCredential, createFablePlanFlow, sanitizeFablePacket } from "./services/fableFlow.mjs";
3
+ import { DebugEvidencePacket, PlanningFlavor, buildDebugPlanningPrompt, buildFablePlanningPrompt, buildFlavorPlanningPrompt, buildNormalPlanningPrompt } from "./services/prompts.mjs";
4
+ import { ModelIdentity, PlanModeExtensionOptions, PlanSnapshot, PlanningConfigProvider, WRITE_PLAN_TIMEOUT_MS, configurePlanningSubagentInput, configurePlanningTaskInput, constrainSubagentInput, createPlanIdentifier, isBlockedSubagentManagementAction, loadPlanningModeConfig, parseDebugEvidencePacket, parsePersistedPlanState, planModeExtension, planModeTools, planSessionIdentifier, planTitleSlug, planningSubagentModel, visiblePlanForToolCall } from "./services/planMode.mjs";
5
5
  export { DebugEvidencePacket, DoomConfig, FABLE_PLAN_MODEL, FABLE_PLAN_PROFILE, FABLE_PLAN_REQUESTER, FABLE_PLAN_RUNTIME, FABLE_PROVIDER_SOURCE, FableFlowOptions, FablePlanBroker, FablePlanFinding, FablePlanFlow, FablePlanPacket, FablePlanRequest, FablePlanResult, FablePlanStage, FablePlanStatus, FableStage, MAX_FABLE_ARRAY_ITEMS, MAX_FABLE_PACKET_BYTES, MAX_FABLE_TEXT_BYTES, ModelIdentity, PlanModeExtensionOptions, PlanSnapshot, PlanningAgentConfig, PlanningConfigProvider, PlanningFlavor, PlanningModeConfig, PlanningThinkingLevel, WRITE_PLAN_TIMEOUT_MS, buildDebugPlanningPrompt, buildFablePlanningPrompt, buildFlavorPlanningPrompt, buildNormalPlanningPrompt, configurePlanningSubagentInput, configurePlanningTaskInput, constrainSubagentInput, containsSuspectedCredential, createFablePlanFlow, createPlanIdentifier, getHarnessState, globalDoomConfigPath, isBlockedSubagentManagementAction, loadDoomConfig, loadHarnessState, loadPlanningModeConfig, mergeDoomConfigs, parseDebugEvidencePacket, parseDoomConfig, parsePersistedPlanState, parsePlanningModeConfig, planModeExtension, planModeTools, planSessionIdentifier, planTitleSlug, planningSubagentModel, repositoryDoomConfigPath, resolvePlanningPlansDirectory, sanitizeFablePacket, visiblePlanForToolCall };
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- import{getHarnessState as e,globalDoomConfigPath as t,loadDoomConfig as n,loadHarnessState as r,mergeDoomConfigs as i,parseDoomConfig as a,parsePlanningModeConfig as o,repositoryDoomConfigPath as s,resolvePlanningPlansDirectory as c}from"./schemas/plan/config.mjs";import{FABLE_PLAN_MODEL as l,FABLE_PLAN_PROFILE as u,FABLE_PLAN_REQUESTER as d,FABLE_PLAN_RUNTIME as f,FABLE_PROVIDER_SOURCE as p,MAX_FABLE_ARRAY_ITEMS as m,MAX_FABLE_PACKET_BYTES as h,MAX_FABLE_TEXT_BYTES as g,containsSuspectedCredential as _,createFablePlanFlow as v,sanitizeFablePacket as y}from"./services/plan/fableFlow.mjs";import{buildDebugPlanningPrompt as b,buildFablePlanningPrompt as x,buildFlavorPlanningPrompt as S,buildNormalPlanningPrompt as C}from"./services/plan/prompts.mjs";import{WRITE_PLAN_TIMEOUT_MS as w,configurePlanningSubagentInput as T,configurePlanningTaskInput as E,constrainSubagentInput as D,createPlanIdentifier as O,isBlockedSubagentManagementAction as k,loadPlanningModeConfig as A,parseDebugEvidencePacket as j,parsePersistedPlanState as M,planModeExtension as N,planModeTools as P,planSessionIdentifier as F,planTitleSlug as I,planningSubagentModel as L,visiblePlanForToolCall as R}from"./services/plan/planMode.mjs";export{l as FABLE_PLAN_MODEL,u as FABLE_PLAN_PROFILE,d as FABLE_PLAN_REQUESTER,f as FABLE_PLAN_RUNTIME,p as FABLE_PROVIDER_SOURCE,m as MAX_FABLE_ARRAY_ITEMS,h as MAX_FABLE_PACKET_BYTES,g as MAX_FABLE_TEXT_BYTES,w as WRITE_PLAN_TIMEOUT_MS,b as buildDebugPlanningPrompt,x as buildFablePlanningPrompt,S as buildFlavorPlanningPrompt,C as buildNormalPlanningPrompt,T as configurePlanningSubagentInput,E as configurePlanningTaskInput,D as constrainSubagentInput,_ as containsSuspectedCredential,v as createFablePlanFlow,O as createPlanIdentifier,e as getHarnessState,t as globalDoomConfigPath,k as isBlockedSubagentManagementAction,n as loadDoomConfig,r as loadHarnessState,A as loadPlanningModeConfig,i as mergeDoomConfigs,j as parseDebugEvidencePacket,a as parseDoomConfig,M as parsePersistedPlanState,o as parsePlanningModeConfig,N as planModeExtension,P as planModeTools,F as planSessionIdentifier,I as planTitleSlug,L as planningSubagentModel,s as repositoryDoomConfigPath,c as resolvePlanningPlansDirectory,y as sanitizeFablePacket,R as visiblePlanForToolCall};
1
+ import{getHarnessState as e,globalDoomConfigPath as t,loadDoomConfig as n,loadHarnessState as r,mergeDoomConfigs as i,parseDoomConfig as a,parsePlanningModeConfig as o,repositoryDoomConfigPath as s,resolvePlanningPlansDirectory as c}from"./schemas/plan/config.mjs";import{FABLE_PLAN_MODEL as l,FABLE_PLAN_PROFILE as u,FABLE_PLAN_REQUESTER as d,FABLE_PLAN_RUNTIME as f,FABLE_PROVIDER_SOURCE as p,MAX_FABLE_ARRAY_ITEMS as m,MAX_FABLE_PACKET_BYTES as h,MAX_FABLE_TEXT_BYTES as g,containsSuspectedCredential as _,createFablePlanFlow as v,sanitizeFablePacket as y}from"./services/fableFlow.mjs";import{buildDebugPlanningPrompt as b,buildFablePlanningPrompt as x,buildFlavorPlanningPrompt as S,buildNormalPlanningPrompt as C}from"./services/prompts.mjs";import{WRITE_PLAN_TIMEOUT_MS as w,configurePlanningSubagentInput as T,configurePlanningTaskInput as E,constrainSubagentInput as D,createPlanIdentifier as O,isBlockedSubagentManagementAction as k,loadPlanningModeConfig as A,parseDebugEvidencePacket as j,parsePersistedPlanState as M,planModeExtension as N,planModeTools as P,planSessionIdentifier as F,planTitleSlug as I,planningSubagentModel as L,visiblePlanForToolCall as R}from"./services/planMode.mjs";export{l as FABLE_PLAN_MODEL,u as FABLE_PLAN_PROFILE,d as FABLE_PLAN_REQUESTER,f as FABLE_PLAN_RUNTIME,p as FABLE_PROVIDER_SOURCE,m as MAX_FABLE_ARRAY_ITEMS,h as MAX_FABLE_PACKET_BYTES,g as MAX_FABLE_TEXT_BYTES,w as WRITE_PLAN_TIMEOUT_MS,b as buildDebugPlanningPrompt,x as buildFablePlanningPrompt,S as buildFlavorPlanningPrompt,C as buildNormalPlanningPrompt,T as configurePlanningSubagentInput,E as configurePlanningTaskInput,D as constrainSubagentInput,_ as containsSuspectedCredential,v as createFablePlanFlow,O as createPlanIdentifier,e as getHarnessState,t as globalDoomConfigPath,k as isBlockedSubagentManagementAction,n as loadDoomConfig,r as loadHarnessState,A as loadPlanningModeConfig,i as mergeDoomConfigs,j as parseDebugEvidencePacket,a as parseDoomConfig,M as parsePersistedPlanState,o as parsePlanningModeConfig,N as planModeExtension,P as planModeTools,F as planSessionIdentifier,I as planTitleSlug,L as planningSubagentModel,s as repositoryDoomConfigPath,c as resolvePlanningPlansDirectory,y as sanitizeFablePacket,R as visiblePlanForToolCall};
package/dist/planMode.cjs CHANGED
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./services/plan/planMode.cjs`);exports.WRITE_PLAN_TIMEOUT_MS=e.WRITE_PLAN_TIMEOUT_MS,exports.configurePlanningSubagentInput=e.configurePlanningSubagentInput,exports.configurePlanningTaskInput=e.configurePlanningTaskInput,exports.constrainSubagentInput=e.constrainSubagentInput,exports.createPlanIdentifier=e.createPlanIdentifier,exports.isBlockedSubagentManagementAction=e.isBlockedSubagentManagementAction,exports.loadPlanningModeConfig=e.loadPlanningModeConfig,exports.parseDebugEvidencePacket=e.parseDebugEvidencePacket,exports.parsePersistedPlanState=e.parsePersistedPlanState,exports.planModeExtension=e.planModeExtension,exports.planModeTools=e.planModeTools,exports.planSessionIdentifier=e.planSessionIdentifier,exports.planTitleSlug=e.planTitleSlug,exports.planningSubagentModel=e.planningSubagentModel,exports.visiblePlanForToolCall=e.visiblePlanForToolCall;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./services/planMode.cjs`);exports.WRITE_PLAN_TIMEOUT_MS=e.WRITE_PLAN_TIMEOUT_MS,exports.configurePlanningSubagentInput=e.configurePlanningSubagentInput,exports.configurePlanningTaskInput=e.configurePlanningTaskInput,exports.constrainSubagentInput=e.constrainSubagentInput,exports.createPlanIdentifier=e.createPlanIdentifier,exports.isBlockedSubagentManagementAction=e.isBlockedSubagentManagementAction,exports.loadPlanningModeConfig=e.loadPlanningModeConfig,exports.parseDebugEvidencePacket=e.parseDebugEvidencePacket,exports.parsePersistedPlanState=e.parsePersistedPlanState,exports.planModeExtension=e.planModeExtension,exports.planModeTools=e.planModeTools,exports.planSessionIdentifier=e.planSessionIdentifier,exports.planTitleSlug=e.planTitleSlug,exports.planningSubagentModel=e.planningSubagentModel,exports.visiblePlanForToolCall=e.visiblePlanForToolCall;
@@ -1,3 +1,3 @@
1
- import { PlanningFlavor } from "./services/plan/prompts.cjs";
2
- import { ModelIdentity, PlanModeExtensionOptions, PlanSnapshot, PlanningConfigProvider, WRITE_PLAN_TIMEOUT_MS, configurePlanningSubagentInput, configurePlanningTaskInput, constrainSubagentInput, createPlanIdentifier, isBlockedSubagentManagementAction, loadPlanningModeConfig, parseDebugEvidencePacket, parsePersistedPlanState, planModeExtension, planModeTools, planSessionIdentifier, planTitleSlug, planningSubagentModel, visiblePlanForToolCall } from "./services/plan/planMode.cjs";
1
+ import { PlanningFlavor } from "./services/prompts.cjs";
2
+ import { ModelIdentity, PlanModeExtensionOptions, PlanSnapshot, PlanningConfigProvider, WRITE_PLAN_TIMEOUT_MS, configurePlanningSubagentInput, configurePlanningTaskInput, constrainSubagentInput, createPlanIdentifier, isBlockedSubagentManagementAction, loadPlanningModeConfig, parseDebugEvidencePacket, parsePersistedPlanState, planModeExtension, planModeTools, planSessionIdentifier, planTitleSlug, planningSubagentModel, visiblePlanForToolCall } from "./services/planMode.cjs";
3
3
  export { ModelIdentity, PlanModeExtensionOptions, PlanSnapshot, PlanningConfigProvider, PlanningFlavor, WRITE_PLAN_TIMEOUT_MS, configurePlanningSubagentInput, configurePlanningTaskInput, constrainSubagentInput, createPlanIdentifier, isBlockedSubagentManagementAction, loadPlanningModeConfig, parseDebugEvidencePacket, parsePersistedPlanState, planModeExtension, planModeTools, planSessionIdentifier, planTitleSlug, planningSubagentModel, visiblePlanForToolCall };
@@ -1,3 +1,3 @@
1
- import { PlanningFlavor } from "./services/plan/prompts.mjs";
2
- import { ModelIdentity, PlanModeExtensionOptions, PlanSnapshot, PlanningConfigProvider, WRITE_PLAN_TIMEOUT_MS, configurePlanningSubagentInput, configurePlanningTaskInput, constrainSubagentInput, createPlanIdentifier, isBlockedSubagentManagementAction, loadPlanningModeConfig, parseDebugEvidencePacket, parsePersistedPlanState, planModeExtension, planModeTools, planSessionIdentifier, planTitleSlug, planningSubagentModel, visiblePlanForToolCall } from "./services/plan/planMode.mjs";
1
+ import { PlanningFlavor } from "./services/prompts.mjs";
2
+ import { ModelIdentity, PlanModeExtensionOptions, PlanSnapshot, PlanningConfigProvider, WRITE_PLAN_TIMEOUT_MS, configurePlanningSubagentInput, configurePlanningTaskInput, constrainSubagentInput, createPlanIdentifier, isBlockedSubagentManagementAction, loadPlanningModeConfig, parseDebugEvidencePacket, parsePersistedPlanState, planModeExtension, planModeTools, planSessionIdentifier, planTitleSlug, planningSubagentModel, visiblePlanForToolCall } from "./services/planMode.mjs";
3
3
  export { ModelIdentity, PlanModeExtensionOptions, PlanSnapshot, PlanningConfigProvider, PlanningFlavor, WRITE_PLAN_TIMEOUT_MS, configurePlanningSubagentInput, configurePlanningTaskInput, constrainSubagentInput, createPlanIdentifier, isBlockedSubagentManagementAction, loadPlanningModeConfig, parseDebugEvidencePacket, parsePersistedPlanState, planModeExtension, planModeTools, planSessionIdentifier, planTitleSlug, planningSubagentModel, visiblePlanForToolCall };
package/dist/planMode.mjs CHANGED
@@ -1 +1 @@
1
- import{WRITE_PLAN_TIMEOUT_MS as e,configurePlanningSubagentInput as t,configurePlanningTaskInput as n,constrainSubagentInput as r,createPlanIdentifier as i,isBlockedSubagentManagementAction as a,loadPlanningModeConfig as o,parseDebugEvidencePacket as s,parsePersistedPlanState as c,planModeExtension as l,planModeTools as u,planSessionIdentifier as d,planTitleSlug as f,planningSubagentModel as p,visiblePlanForToolCall as m}from"./services/plan/planMode.mjs";export{e as WRITE_PLAN_TIMEOUT_MS,t as configurePlanningSubagentInput,n as configurePlanningTaskInput,r as constrainSubagentInput,i as createPlanIdentifier,a as isBlockedSubagentManagementAction,o as loadPlanningModeConfig,s as parseDebugEvidencePacket,c as parsePersistedPlanState,l as planModeExtension,u as planModeTools,d as planSessionIdentifier,f as planTitleSlug,p as planningSubagentModel,m as visiblePlanForToolCall};
1
+ import{WRITE_PLAN_TIMEOUT_MS as e,configurePlanningSubagentInput as t,configurePlanningTaskInput as n,constrainSubagentInput as r,createPlanIdentifier as i,isBlockedSubagentManagementAction as a,loadPlanningModeConfig as o,parseDebugEvidencePacket as s,parsePersistedPlanState as c,planModeExtension as l,planModeTools as u,planSessionIdentifier as d,planTitleSlug as f,planningSubagentModel as p,visiblePlanForToolCall as m}from"./services/planMode.mjs";export{e as WRITE_PLAN_TIMEOUT_MS,t as configurePlanningSubagentInput,n as configurePlanningTaskInput,r as constrainSubagentInput,i as createPlanIdentifier,a as isBlockedSubagentManagementAction,o as loadPlanningModeConfig,s as parseDebugEvidencePacket,c as parsePersistedPlanState,l as planModeExtension,u as planModeTools,d as planSessionIdentifier,f as planTitleSlug,p as planningSubagentModel,m as visiblePlanForToolCall};
package/dist/prompts.cjs CHANGED
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./services/plan/prompts.cjs`);exports.buildDebugPlanningPrompt=e.buildDebugPlanningPrompt,exports.buildFablePlanningPrompt=e.buildFablePlanningPrompt,exports.buildFlavorPlanningPrompt=e.buildFlavorPlanningPrompt,exports.buildNormalPlanningPrompt=e.buildNormalPlanningPrompt;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./services/prompts.cjs`);exports.buildDebugPlanningPrompt=e.buildDebugPlanningPrompt,exports.buildFablePlanningPrompt=e.buildFablePlanningPrompt,exports.buildFlavorPlanningPrompt=e.buildFlavorPlanningPrompt,exports.buildNormalPlanningPrompt=e.buildNormalPlanningPrompt;
@@ -1,2 +1,2 @@
1
- import { DebugEvidencePacket, PlanningFlavor, buildDebugPlanningPrompt, buildFablePlanningPrompt, buildFlavorPlanningPrompt, buildNormalPlanningPrompt } from "./services/plan/prompts.cjs";
1
+ import { DebugEvidencePacket, PlanningFlavor, buildDebugPlanningPrompt, buildFablePlanningPrompt, buildFlavorPlanningPrompt, buildNormalPlanningPrompt } from "./services/prompts.cjs";
2
2
  export { DebugEvidencePacket, PlanningFlavor, buildDebugPlanningPrompt, buildFablePlanningPrompt, buildFlavorPlanningPrompt, buildNormalPlanningPrompt };
@@ -1,2 +1,2 @@
1
- import { DebugEvidencePacket, PlanningFlavor, buildDebugPlanningPrompt, buildFablePlanningPrompt, buildFlavorPlanningPrompt, buildNormalPlanningPrompt } from "./services/plan/prompts.mjs";
1
+ import { DebugEvidencePacket, PlanningFlavor, buildDebugPlanningPrompt, buildFablePlanningPrompt, buildFlavorPlanningPrompt, buildNormalPlanningPrompt } from "./services/prompts.mjs";
2
2
  export { DebugEvidencePacket, PlanningFlavor, buildDebugPlanningPrompt, buildFablePlanningPrompt, buildFlavorPlanningPrompt, buildNormalPlanningPrompt };
package/dist/prompts.mjs CHANGED
@@ -1 +1 @@
1
- import{buildDebugPlanningPrompt as e,buildFablePlanningPrompt as t,buildFlavorPlanningPrompt as n,buildNormalPlanningPrompt as r}from"./services/plan/prompts.mjs";export{e as buildDebugPlanningPrompt,t as buildFablePlanningPrompt,n as buildFlavorPlanningPrompt,r as buildNormalPlanningPrompt};
1
+ import{buildDebugPlanningPrompt as e,buildFablePlanningPrompt as t,buildFlavorPlanningPrompt as n,buildNormalPlanningPrompt as r}from"./services/prompts.mjs";export{e as buildDebugPlanningPrompt,t as buildFablePlanningPrompt,n as buildFlavorPlanningPrompt,r as buildNormalPlanningPrompt};
@@ -1,2 +1,2 @@
1
- require(`../../_virtual/_rolldown/runtime.cjs`);let e=require(`@agimon-ai/doompi-config`),t=require(`@agimon-ai/doompi-ui/config`);const n=`planning`,r=[`modes`,n],i=`main`,a=`subagents`,o=`inherit the session model`,s=`inherit`,c=[{id:`main.model`,label:`main model`,keyPath:[...r,i,`model`],placeholder:o,detail:`Model the main agent switches to while plan mode is on.`,read:e=>e?.main?.model},{id:`main.thinking`,label:`main thinking`,keyPath:[...r,i,`thinking`],placeholder:s,detail:`Thinking level appended to the main model while planning.`,options:e.DOOM_PLANNING_THINKING_LEVELS,read:e=>e?.main?.thinking},{id:`subagents.model`,label:`subagent model`,keyPath:[...r,a,`model`],placeholder:o,detail:`Model forced onto delegated planning subagents.`,read:e=>e?.subagents?.model},{id:`subagents.thinking`,label:`subagent thinking`,keyPath:[...r,a,`thinking`],placeholder:s,detail:`Thinking level appended to the subagent model.`,options:e.DOOM_PLANNING_THINKING_LEVELS,read:e=>e?.subagents?.thinking},{id:`plansdirectory`,label:`plans directory`,keyPath:[...r,`plansDirectory`],placeholder:`~/.pi/plans`,detail:`Absolute, repo-relative, or under ~. Written plans land here.`,read:e=>e?.plansDirectory}];function l(e){return c.find(t=>t.id===e)}function u(e){return e.options?.map(e=>({id:e,label:e,action:t.CONFIG_ACTION.set}))}function d(e,t){return[{id:n,title:`planning`,order:30,detail:`plan mode`,fields:c.map(t=>{let n=t.read(e),r=u(t);return{id:t.id,label:t.label,kind:r?`enum`:`text`,keyPath:t.keyPath.join(`.`),placeholder:t.placeholder,detail:t.detail,...n?{value:n}:{},...r?{choices:r}:{}}}),...t?{notice:t,noticeLevel:`error`}:{}}]}exports.PLAN_CONFIG_SECTION_ID=n,exports.PLAN_SETTINGS=c,exports.planConfigSections=d,exports.planSettingByFieldId=l;
1
+ require(`../../_virtual/_rolldown/runtime.cjs`);let e=require(`@agimon-ai/doompi-config`),t=require(`@agimon-ai/doompi-extension-contracts/config`);const n=`planning`,r=[`modes`,n],i=`main`,a=`subagents`,o=`inherit the session model`,s=`inherit`,c=[{id:`main.model`,label:`main model`,keyPath:[...r,i,`model`],placeholder:o,detail:`Model the main agent switches to while plan mode is on.`,read:e=>e?.main?.model},{id:`main.thinking`,label:`main thinking`,keyPath:[...r,i,`thinking`],placeholder:s,detail:`Thinking level appended to the main model while planning.`,options:e.DOOM_PLANNING_THINKING_LEVELS,read:e=>e?.main?.thinking},{id:`subagents.model`,label:`subagent model`,keyPath:[...r,a,`model`],placeholder:o,detail:`Model forced onto delegated planning subagents.`,read:e=>e?.subagents?.model},{id:`subagents.thinking`,label:`subagent thinking`,keyPath:[...r,a,`thinking`],placeholder:s,detail:`Thinking level appended to the subagent model.`,options:e.DOOM_PLANNING_THINKING_LEVELS,read:e=>e?.subagents?.thinking},{id:`plansdirectory`,label:`plans directory`,keyPath:[...r,`plansDirectory`],placeholder:`~/.pi/plans`,detail:`Absolute, repo-relative, or under ~. Written plans land here.`,read:e=>e?.plansDirectory}];function l(e){return c.find(t=>t.id===e)}function u(e){return e.options?.map(e=>({id:e,label:e,action:t.CONFIG_ACTION.set}))}function d(e,t){return[{id:n,title:`planning`,order:30,detail:`plan mode`,fields:c.map(t=>{let n=t.read(e),r=u(t);return{id:t.id,label:t.label,kind:r?`enum`:`text`,keyPath:t.keyPath.join(`.`),placeholder:t.placeholder,detail:t.detail,...n?{value:n}:{},...r?{choices:r}:{}}}),...t?{notice:t,noticeLevel:`error`}:{}}]}exports.PLAN_CONFIG_SECTION_ID=n,exports.PLAN_SETTINGS=c,exports.planConfigSections=d,exports.planSettingByFieldId=l;
2
2
  //# sourceMappingURL=planConfig.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"planConfig.cjs","names":["DOOM_PLANNING_THINKING_LEVELS","CONFIG_ACTION"],"sources":["../../../src/schemas/plan/planConfig.ts"],"sourcesContent":["/**\n * Plan mode's slice of the `SPC e c` config panel.\n *\n * Plan mode reads `modes.planning` from disk on every activation, so an edit\n * here lands on the next time the mode is turned on with no restart and nothing\n * to invalidate.\n *\n * The descriptor table is the whole design: the panel renders it and the write\n * handler looks the key path back up in it, so adding a setting means adding a\n * row rather than a case.\n */\n\nimport { DOOM_PLANNING_THINKING_LEVELS } from '@agimon-ai/doompi-config';\nimport type { ConfigChoice, ConfigField, ConfigSection } from '@agimon-ai/doompi-ui/config';\nimport { CONFIG_ACTION } from '@agimon-ai/doompi-ui/config';\nimport type { PlanningModeConfig } from './config.ts';\n\nexport const PLAN_CONFIG_SECTION_ID = 'planning';\nconst SECTION_ORDER = 30;\nconst PLANNING_PATH = ['modes', PLAN_CONFIG_SECTION_ID] as const;\nconst MAIN_KEY = 'main';\nconst SUBAGENTS_KEY = 'subagents';\n/** Both agents fall back to the session's own settings when left unset. */\nconst INHERIT_MODEL = 'inherit the session model';\nconst INHERIT_THINKING = 'inherit';\n\ninterface PlanSettingDescriptor {\n readonly id: string;\n readonly label: string;\n readonly keyPath: readonly string[];\n readonly placeholder: string;\n readonly detail: string;\n /** Present for a closed set; the panel offers these rather than free text. */\n readonly options?: readonly string[];\n readonly read: (config: PlanningModeConfig | undefined) => string | undefined;\n}\n\nexport const PLAN_SETTINGS: readonly PlanSettingDescriptor[] = [\n {\n id: 'main.model',\n label: 'main model',\n keyPath: [...PLANNING_PATH, MAIN_KEY, 'model'],\n placeholder: INHERIT_MODEL,\n detail: 'Model the main agent switches to while plan mode is on.',\n read: (config) => config?.main?.model,\n },\n {\n id: 'main.thinking',\n label: 'main thinking',\n keyPath: [...PLANNING_PATH, MAIN_KEY, 'thinking'],\n placeholder: INHERIT_THINKING,\n detail: 'Thinking level appended to the main model while planning.',\n options: DOOM_PLANNING_THINKING_LEVELS,\n read: (config) => config?.main?.thinking,\n },\n {\n id: 'subagents.model',\n label: 'subagent model',\n keyPath: [...PLANNING_PATH, SUBAGENTS_KEY, 'model'],\n placeholder: INHERIT_MODEL,\n detail: 'Model forced onto delegated planning subagents.',\n read: (config) => config?.subagents?.model,\n },\n {\n id: 'subagents.thinking',\n label: 'subagent thinking',\n keyPath: [...PLANNING_PATH, SUBAGENTS_KEY, 'thinking'],\n placeholder: INHERIT_THINKING,\n detail: 'Thinking level appended to the subagent model.',\n options: DOOM_PLANNING_THINKING_LEVELS,\n read: (config) => config?.subagents?.thinking,\n },\n {\n id: 'plansdirectory',\n label: 'plans directory',\n keyPath: [...PLANNING_PATH, 'plansDirectory'],\n placeholder: '~/.pi/plans',\n detail: 'Absolute, repo-relative, or under ~. Written plans land here.',\n read: (config) => config?.plansDirectory,\n },\n];\n\nexport function planSettingByFieldId(fieldId: string): PlanSettingDescriptor | undefined {\n return PLAN_SETTINGS.find((setting) => setting.id === fieldId);\n}\n\nfunction choicesFor(setting: PlanSettingDescriptor): ConfigChoice[] | undefined {\n // `set` rather than a bespoke action: choosing a level is the same write as\n // typing one, so it shares the handler.\n return setting.options?.map((option) => ({ id: option, label: option, action: CONFIG_ACTION.set }));\n}\n\nexport function planConfigSections(config: PlanningModeConfig | undefined, notice?: string): readonly ConfigSection[] {\n const fields: ConfigField[] = PLAN_SETTINGS.map((setting) => {\n const value = setting.read(config);\n const choices = choicesFor(setting);\n return {\n id: setting.id,\n label: setting.label,\n kind: choices ? ('enum' as const) : ('text' as const),\n keyPath: setting.keyPath.join('.'),\n placeholder: setting.placeholder,\n detail: setting.detail,\n ...(value ? { value } : {}),\n ...(choices ? { choices } : {}),\n };\n });\n return [\n {\n id: PLAN_CONFIG_SECTION_ID,\n title: 'planning',\n order: SECTION_ORDER,\n detail: 'plan mode',\n fields,\n ...(notice ? { notice, noticeLevel: 'error' as const } : {}),\n },\n ];\n}\n"],"mappings":"mIAiBA,MAAa,EAAyB,WAEhC,EAAgB,CAAC,QAAS,EAAuB,CACjD,EAAW,OACX,EAAgB,YAEhB,EAAgB,4BAChB,EAAmB,UAaZ,EAAkD,CAC7D,CACE,GAAI,aACJ,MAAO,aACP,QAAS,CAAC,GAAG,EAAe,EAAU,QAAQ,CAC9C,YAAa,EACb,OAAQ,0DACR,KAAO,GAAW,GAAQ,MAAM,MACjC,CACD,CACE,GAAI,gBACJ,MAAO,gBACP,QAAS,CAAC,GAAG,EAAe,EAAU,WAAW,CACjD,YAAa,EACb,OAAQ,4DACR,QAASA,EAAAA,8BACT,KAAO,GAAW,GAAQ,MAAM,SACjC,CACD,CACE,GAAI,kBACJ,MAAO,iBACP,QAAS,CAAC,GAAG,EAAe,EAAe,QAAQ,CACnD,YAAa,EACb,OAAQ,kDACR,KAAO,GAAW,GAAQ,WAAW,MACtC,CACD,CACE,GAAI,qBACJ,MAAO,oBACP,QAAS,CAAC,GAAG,EAAe,EAAe,WAAW,CACtD,YAAa,EACb,OAAQ,iDACR,QAASA,EAAAA,8BACT,KAAO,GAAW,GAAQ,WAAW,SACtC,CACD,CACE,GAAI,iBACJ,MAAO,kBACP,QAAS,CAAC,GAAG,EAAe,iBAAiB,CAC7C,YAAa,cACb,OAAQ,gEACR,KAAO,GAAW,GAAQ,eAC3B,CACF,CAED,SAAgB,EAAqB,EAAoD,CACvF,OAAO,EAAc,KAAM,GAAY,EAAQ,KAAO,EAAQ,CAGhE,SAAS,EAAW,EAA4D,CAG9E,OAAO,EAAQ,SAAS,IAAK,IAAY,CAAE,GAAI,EAAQ,MAAO,EAAQ,OAAQC,EAAAA,cAAc,IAAK,EAAE,CAGrG,SAAgB,EAAmB,EAAwC,EAA2C,CAepH,MAAO,CACL,CACE,GAAI,EACJ,MAAO,WACP,MAAO,GACP,OAAQ,YACR,OApB0B,EAAc,IAAK,GAAY,CAC3D,IAAM,EAAQ,EAAQ,KAAK,EAAO,CAC5B,EAAU,EAAW,EAAQ,CACnC,MAAO,CACL,GAAI,EAAQ,GACZ,MAAO,EAAQ,MACf,KAAM,EAAW,OAAoB,OACrC,QAAS,EAAQ,QAAQ,KAAK,IAAI,CAClC,YAAa,EAAQ,YACrB,OAAQ,EAAQ,OAChB,GAAI,EAAQ,CAAE,QAAO,CAAG,EAAE,CAC1B,GAAI,EAAU,CAAE,UAAS,CAAG,EAAE,CAC/B,EAQO,CACN,GAAI,EAAS,CAAE,SAAQ,YAAa,QAAkB,CAAG,EAAE,CAC5D,CACF"}
1
+ {"version":3,"file":"planConfig.cjs","names":["DOOM_PLANNING_THINKING_LEVELS","CONFIG_ACTION"],"sources":["../../../src/schemas/plan/planConfig.ts"],"sourcesContent":["/**\n * Plan mode's slice of the `SPC e c` config panel.\n *\n * Plan mode reads `modes.planning` from disk on every activation, so an edit\n * here lands on the next time the mode is turned on with no restart and nothing\n * to invalidate.\n *\n * The descriptor table is the whole design: the panel renders it and the write\n * handler looks the key path back up in it, so adding a setting means adding a\n * row rather than a case.\n */\n\nimport { DOOM_PLANNING_THINKING_LEVELS } from '@agimon-ai/doompi-config';\nimport {\n CONFIG_ACTION,\n type ConfigChoice,\n type ConfigField,\n type ConfigSection,\n} from '@agimon-ai/doompi-extension-contracts/config';\nimport type { PlanningModeConfig } from './config.ts';\n\nexport const PLAN_CONFIG_SECTION_ID = 'planning';\nconst SECTION_ORDER = 30;\nconst PLANNING_PATH = ['modes', PLAN_CONFIG_SECTION_ID] as const;\nconst MAIN_KEY = 'main';\nconst SUBAGENTS_KEY = 'subagents';\n/** Both agents fall back to the session's own settings when left unset. */\nconst INHERIT_MODEL = 'inherit the session model';\nconst INHERIT_THINKING = 'inherit';\n\ninterface PlanSettingDescriptor {\n readonly id: string;\n readonly label: string;\n readonly keyPath: readonly string[];\n readonly placeholder: string;\n readonly detail: string;\n /** Present for a closed set; the panel offers these rather than free text. */\n readonly options?: readonly string[];\n readonly read: (config: PlanningModeConfig | undefined) => string | undefined;\n}\n\nexport const PLAN_SETTINGS: readonly PlanSettingDescriptor[] = [\n {\n id: 'main.model',\n label: 'main model',\n keyPath: [...PLANNING_PATH, MAIN_KEY, 'model'],\n placeholder: INHERIT_MODEL,\n detail: 'Model the main agent switches to while plan mode is on.',\n read: (config) => config?.main?.model,\n },\n {\n id: 'main.thinking',\n label: 'main thinking',\n keyPath: [...PLANNING_PATH, MAIN_KEY, 'thinking'],\n placeholder: INHERIT_THINKING,\n detail: 'Thinking level appended to the main model while planning.',\n options: DOOM_PLANNING_THINKING_LEVELS,\n read: (config) => config?.main?.thinking,\n },\n {\n id: 'subagents.model',\n label: 'subagent model',\n keyPath: [...PLANNING_PATH, SUBAGENTS_KEY, 'model'],\n placeholder: INHERIT_MODEL,\n detail: 'Model forced onto delegated planning subagents.',\n read: (config) => config?.subagents?.model,\n },\n {\n id: 'subagents.thinking',\n label: 'subagent thinking',\n keyPath: [...PLANNING_PATH, SUBAGENTS_KEY, 'thinking'],\n placeholder: INHERIT_THINKING,\n detail: 'Thinking level appended to the subagent model.',\n options: DOOM_PLANNING_THINKING_LEVELS,\n read: (config) => config?.subagents?.thinking,\n },\n {\n id: 'plansdirectory',\n label: 'plans directory',\n keyPath: [...PLANNING_PATH, 'plansDirectory'],\n placeholder: '~/.pi/plans',\n detail: 'Absolute, repo-relative, or under ~. Written plans land here.',\n read: (config) => config?.plansDirectory,\n },\n];\n\nexport function planSettingByFieldId(fieldId: string): PlanSettingDescriptor | undefined {\n return PLAN_SETTINGS.find((setting) => setting.id === fieldId);\n}\n\nfunction choicesFor(setting: PlanSettingDescriptor): ConfigChoice[] | undefined {\n // `set` rather than a bespoke action: choosing a level is the same write as\n // typing one, so it shares the handler.\n return setting.options?.map((option) => ({ id: option, label: option, action: CONFIG_ACTION.set }));\n}\n\nexport function planConfigSections(config: PlanningModeConfig | undefined, notice?: string): readonly ConfigSection[] {\n const fields: ConfigField[] = PLAN_SETTINGS.map((setting) => {\n const value = setting.read(config);\n const choices = choicesFor(setting);\n return {\n id: setting.id,\n label: setting.label,\n kind: choices ? ('enum' as const) : ('text' as const),\n keyPath: setting.keyPath.join('.'),\n placeholder: setting.placeholder,\n detail: setting.detail,\n ...(value ? { value } : {}),\n ...(choices ? { choices } : {}),\n };\n });\n return [\n {\n id: PLAN_CONFIG_SECTION_ID,\n title: 'planning',\n order: SECTION_ORDER,\n detail: 'plan mode',\n fields,\n ...(notice ? { notice, noticeLevel: 'error' as const } : {}),\n },\n ];\n}\n"],"mappings":"oJAqBA,MAAa,EAAyB,WAEhC,EAAgB,CAAC,QAAS,EAAuB,CACjD,EAAW,OACX,EAAgB,YAEhB,EAAgB,4BAChB,EAAmB,UAaZ,EAAkD,CAC7D,CACE,GAAI,aACJ,MAAO,aACP,QAAS,CAAC,GAAG,EAAe,EAAU,QAAQ,CAC9C,YAAa,EACb,OAAQ,0DACR,KAAO,GAAW,GAAQ,MAAM,MACjC,CACD,CACE,GAAI,gBACJ,MAAO,gBACP,QAAS,CAAC,GAAG,EAAe,EAAU,WAAW,CACjD,YAAa,EACb,OAAQ,4DACR,QAASA,EAAAA,8BACT,KAAO,GAAW,GAAQ,MAAM,SACjC,CACD,CACE,GAAI,kBACJ,MAAO,iBACP,QAAS,CAAC,GAAG,EAAe,EAAe,QAAQ,CACnD,YAAa,EACb,OAAQ,kDACR,KAAO,GAAW,GAAQ,WAAW,MACtC,CACD,CACE,GAAI,qBACJ,MAAO,oBACP,QAAS,CAAC,GAAG,EAAe,EAAe,WAAW,CACtD,YAAa,EACb,OAAQ,iDACR,QAASA,EAAAA,8BACT,KAAO,GAAW,GAAQ,WAAW,SACtC,CACD,CACE,GAAI,iBACJ,MAAO,kBACP,QAAS,CAAC,GAAG,EAAe,iBAAiB,CAC7C,YAAa,cACb,OAAQ,gEACR,KAAO,GAAW,GAAQ,eAC3B,CACF,CAED,SAAgB,EAAqB,EAAoD,CACvF,OAAO,EAAc,KAAM,GAAY,EAAQ,KAAO,EAAQ,CAGhE,SAAS,EAAW,EAA4D,CAG9E,OAAO,EAAQ,SAAS,IAAK,IAAY,CAAE,GAAI,EAAQ,MAAO,EAAQ,OAAQC,EAAAA,cAAc,IAAK,EAAE,CAGrG,SAAgB,EAAmB,EAAwC,EAA2C,CAepH,MAAO,CACL,CACE,GAAI,EACJ,MAAO,WACP,MAAO,GACP,OAAQ,YACR,OApB0B,EAAc,IAAK,GAAY,CAC3D,IAAM,EAAQ,EAAQ,KAAK,EAAO,CAC5B,EAAU,EAAW,EAAQ,CACnC,MAAO,CACL,GAAI,EAAQ,GACZ,MAAO,EAAQ,MACf,KAAM,EAAW,OAAoB,OACrC,QAAS,EAAQ,QAAQ,KAAK,IAAI,CAClC,YAAa,EAAQ,YACrB,OAAQ,EAAQ,OAChB,GAAI,EAAQ,CAAE,QAAO,CAAG,EAAE,CAC1B,GAAI,EAAU,CAAE,UAAS,CAAG,EAAE,CAC/B,EAQO,CACN,GAAI,EAAS,CAAE,SAAQ,YAAa,QAAkB,CAAG,EAAE,CAC5D,CACF"}
@@ -1,5 +1,5 @@
1
1
  import { PlanningModeConfig } from "./config.cjs";
2
- import { ConfigSection } from "@agimon-ai/doompi-ui/config";
2
+ import { ConfigSection } from "@agimon-ai/doompi-extension-contracts/config";
3
3
 
4
4
  //#region src/schemas/plan/planConfig.d.ts
5
5
  declare const PLAN_CONFIG_SECTION_ID = "planning";
@@ -1 +1 @@
1
- {"version":3,"file":"planConfig.d.cts","names":[],"sources":["../../../src/schemas/plan/planConfig.ts"],"mappings":";;;;cAiBa,sBAAA;AAAA,UASH,qBAAA;EAAA,SACC,EAAA;EAAA,SACA,KAAA;EAAA,SACA,OAAA;EAAA,SACA,WAAA;EAAA,SACA,MAAA;EAGe;EAAA,SADf,OAAA;EAAA,SACA,IAAA,GAAO,MAAA,EAAQ,kBAAA;AAAA;AAAA,cAGb,aAAA,WAAwB,qBAAA;AAAA,iBA6CrB,oBAAA,CAAqB,OAAA,WAAkB,qBAAA;AAAA,iBAUvC,kBAAA,CAAmB,MAAA,EAAQ,kBAAA,cAAgC,MAAA,qBAA2B,aAAA"}
1
+ {"version":3,"file":"planConfig.d.cts","names":[],"sources":["../../../src/schemas/plan/planConfig.ts"],"mappings":";;;;cAqBa,sBAAA;AAAA,UASH,qBAAA;EAAA,SACC,EAAA;EAAA,SACA,KAAA;EAAA,SACA,OAAA;EAAA,SACA,WAAA;EAAA,SACA,MAAA;EAGe;EAAA,SADf,OAAA;EAAA,SACA,IAAA,GAAO,MAAA,EAAQ,kBAAA;AAAA;AAAA,cAGb,aAAA,WAAwB,qBAAA;AAAA,iBA6CrB,oBAAA,CAAqB,OAAA,WAAkB,qBAAA;AAAA,iBAUvC,kBAAA,CAAmB,MAAA,EAAQ,kBAAA,cAAgC,MAAA,qBAA2B,aAAA"}
@@ -1,5 +1,5 @@
1
1
  import { PlanningModeConfig } from "./config.mjs";
2
- import { ConfigSection } from "@agimon-ai/doompi-ui/config";
2
+ import { ConfigSection } from "@agimon-ai/doompi-extension-contracts/config";
3
3
 
4
4
  //#region src/schemas/plan/planConfig.d.ts
5
5
  declare const PLAN_CONFIG_SECTION_ID = "planning";
@@ -1 +1 @@
1
- {"version":3,"file":"planConfig.d.mts","names":[],"sources":["../../../src/schemas/plan/planConfig.ts"],"mappings":";;;;cAiBa,sBAAA;AAAA,UASH,qBAAA;EAAA,SACC,EAAA;EAAA,SACA,KAAA;EAAA,SACA,OAAA;EAAA,SACA,WAAA;EAAA,SACA,MAAA;EAGe;EAAA,SADf,OAAA;EAAA,SACA,IAAA,GAAO,MAAA,EAAQ,kBAAA;AAAA;AAAA,cAGb,aAAA,WAAwB,qBAAA;AAAA,iBA6CrB,oBAAA,CAAqB,OAAA,WAAkB,qBAAA;AAAA,iBAUvC,kBAAA,CAAmB,MAAA,EAAQ,kBAAA,cAAgC,MAAA,qBAA2B,aAAA"}
1
+ {"version":3,"file":"planConfig.d.mts","names":[],"sources":["../../../src/schemas/plan/planConfig.ts"],"mappings":";;;;cAqBa,sBAAA;AAAA,UASH,qBAAA;EAAA,SACC,EAAA;EAAA,SACA,KAAA;EAAA,SACA,OAAA;EAAA,SACA,WAAA;EAAA,SACA,MAAA;EAGe;EAAA,SADf,OAAA;EAAA,SACA,IAAA,GAAO,MAAA,EAAQ,kBAAA;AAAA;AAAA,cAGb,aAAA,WAAwB,qBAAA;AAAA,iBA6CrB,oBAAA,CAAqB,OAAA,WAAkB,qBAAA;AAAA,iBAUvC,kBAAA,CAAmB,MAAA,EAAQ,kBAAA,cAAgC,MAAA,qBAA2B,aAAA"}
@@ -1,2 +1,2 @@
1
- import{DOOM_PLANNING_THINKING_LEVELS as e}from"@agimon-ai/doompi-config";import{CONFIG_ACTION as t}from"@agimon-ai/doompi-ui/config";const n=`planning`,r=[`modes`,n],i=`main`,a=`subagents`,o=`inherit the session model`,s=`inherit`,c=[{id:`main.model`,label:`main model`,keyPath:[...r,i,`model`],placeholder:o,detail:`Model the main agent switches to while plan mode is on.`,read:e=>e?.main?.model},{id:`main.thinking`,label:`main thinking`,keyPath:[...r,i,`thinking`],placeholder:s,detail:`Thinking level appended to the main model while planning.`,options:e,read:e=>e?.main?.thinking},{id:`subagents.model`,label:`subagent model`,keyPath:[...r,a,`model`],placeholder:o,detail:`Model forced onto delegated planning subagents.`,read:e=>e?.subagents?.model},{id:`subagents.thinking`,label:`subagent thinking`,keyPath:[...r,a,`thinking`],placeholder:s,detail:`Thinking level appended to the subagent model.`,options:e,read:e=>e?.subagents?.thinking},{id:`plansdirectory`,label:`plans directory`,keyPath:[...r,`plansDirectory`],placeholder:`~/.pi/plans`,detail:`Absolute, repo-relative, or under ~. Written plans land here.`,read:e=>e?.plansDirectory}];function l(e){return c.find(t=>t.id===e)}function u(e){return e.options?.map(e=>({id:e,label:e,action:t.set}))}function d(e,t){return[{id:n,title:`planning`,order:30,detail:`plan mode`,fields:c.map(t=>{let n=t.read(e),r=u(t);return{id:t.id,label:t.label,kind:r?`enum`:`text`,keyPath:t.keyPath.join(`.`),placeholder:t.placeholder,detail:t.detail,...n?{value:n}:{},...r?{choices:r}:{}}}),...t?{notice:t,noticeLevel:`error`}:{}}]}export{n as PLAN_CONFIG_SECTION_ID,c as PLAN_SETTINGS,d as planConfigSections,l as planSettingByFieldId};
1
+ import{DOOM_PLANNING_THINKING_LEVELS as e}from"@agimon-ai/doompi-config";import{CONFIG_ACTION as t}from"@agimon-ai/doompi-extension-contracts/config";const n=`planning`,r=[`modes`,n],i=`main`,a=`subagents`,o=`inherit the session model`,s=`inherit`,c=[{id:`main.model`,label:`main model`,keyPath:[...r,i,`model`],placeholder:o,detail:`Model the main agent switches to while plan mode is on.`,read:e=>e?.main?.model},{id:`main.thinking`,label:`main thinking`,keyPath:[...r,i,`thinking`],placeholder:s,detail:`Thinking level appended to the main model while planning.`,options:e,read:e=>e?.main?.thinking},{id:`subagents.model`,label:`subagent model`,keyPath:[...r,a,`model`],placeholder:o,detail:`Model forced onto delegated planning subagents.`,read:e=>e?.subagents?.model},{id:`subagents.thinking`,label:`subagent thinking`,keyPath:[...r,a,`thinking`],placeholder:s,detail:`Thinking level appended to the subagent model.`,options:e,read:e=>e?.subagents?.thinking},{id:`plansdirectory`,label:`plans directory`,keyPath:[...r,`plansDirectory`],placeholder:`~/.pi/plans`,detail:`Absolute, repo-relative, or under ~. Written plans land here.`,read:e=>e?.plansDirectory}];function l(e){return c.find(t=>t.id===e)}function u(e){return e.options?.map(e=>({id:e,label:e,action:t.set}))}function d(e,t){return[{id:n,title:`planning`,order:30,detail:`plan mode`,fields:c.map(t=>{let n=t.read(e),r=u(t);return{id:t.id,label:t.label,kind:r?`enum`:`text`,keyPath:t.keyPath.join(`.`),placeholder:t.placeholder,detail:t.detail,...n?{value:n}:{},...r?{choices:r}:{}}}),...t?{notice:t,noticeLevel:`error`}:{}}]}export{n as PLAN_CONFIG_SECTION_ID,c as PLAN_SETTINGS,d as planConfigSections,l as planSettingByFieldId};
2
2
  //# sourceMappingURL=planConfig.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"planConfig.mjs","names":[],"sources":["../../../src/schemas/plan/planConfig.ts"],"sourcesContent":["/**\n * Plan mode's slice of the `SPC e c` config panel.\n *\n * Plan mode reads `modes.planning` from disk on every activation, so an edit\n * here lands on the next time the mode is turned on with no restart and nothing\n * to invalidate.\n *\n * The descriptor table is the whole design: the panel renders it and the write\n * handler looks the key path back up in it, so adding a setting means adding a\n * row rather than a case.\n */\n\nimport { DOOM_PLANNING_THINKING_LEVELS } from '@agimon-ai/doompi-config';\nimport type { ConfigChoice, ConfigField, ConfigSection } from '@agimon-ai/doompi-ui/config';\nimport { CONFIG_ACTION } from '@agimon-ai/doompi-ui/config';\nimport type { PlanningModeConfig } from './config.ts';\n\nexport const PLAN_CONFIG_SECTION_ID = 'planning';\nconst SECTION_ORDER = 30;\nconst PLANNING_PATH = ['modes', PLAN_CONFIG_SECTION_ID] as const;\nconst MAIN_KEY = 'main';\nconst SUBAGENTS_KEY = 'subagents';\n/** Both agents fall back to the session's own settings when left unset. */\nconst INHERIT_MODEL = 'inherit the session model';\nconst INHERIT_THINKING = 'inherit';\n\ninterface PlanSettingDescriptor {\n readonly id: string;\n readonly label: string;\n readonly keyPath: readonly string[];\n readonly placeholder: string;\n readonly detail: string;\n /** Present for a closed set; the panel offers these rather than free text. */\n readonly options?: readonly string[];\n readonly read: (config: PlanningModeConfig | undefined) => string | undefined;\n}\n\nexport const PLAN_SETTINGS: readonly PlanSettingDescriptor[] = [\n {\n id: 'main.model',\n label: 'main model',\n keyPath: [...PLANNING_PATH, MAIN_KEY, 'model'],\n placeholder: INHERIT_MODEL,\n detail: 'Model the main agent switches to while plan mode is on.',\n read: (config) => config?.main?.model,\n },\n {\n id: 'main.thinking',\n label: 'main thinking',\n keyPath: [...PLANNING_PATH, MAIN_KEY, 'thinking'],\n placeholder: INHERIT_THINKING,\n detail: 'Thinking level appended to the main model while planning.',\n options: DOOM_PLANNING_THINKING_LEVELS,\n read: (config) => config?.main?.thinking,\n },\n {\n id: 'subagents.model',\n label: 'subagent model',\n keyPath: [...PLANNING_PATH, SUBAGENTS_KEY, 'model'],\n placeholder: INHERIT_MODEL,\n detail: 'Model forced onto delegated planning subagents.',\n read: (config) => config?.subagents?.model,\n },\n {\n id: 'subagents.thinking',\n label: 'subagent thinking',\n keyPath: [...PLANNING_PATH, SUBAGENTS_KEY, 'thinking'],\n placeholder: INHERIT_THINKING,\n detail: 'Thinking level appended to the subagent model.',\n options: DOOM_PLANNING_THINKING_LEVELS,\n read: (config) => config?.subagents?.thinking,\n },\n {\n id: 'plansdirectory',\n label: 'plans directory',\n keyPath: [...PLANNING_PATH, 'plansDirectory'],\n placeholder: '~/.pi/plans',\n detail: 'Absolute, repo-relative, or under ~. Written plans land here.',\n read: (config) => config?.plansDirectory,\n },\n];\n\nexport function planSettingByFieldId(fieldId: string): PlanSettingDescriptor | undefined {\n return PLAN_SETTINGS.find((setting) => setting.id === fieldId);\n}\n\nfunction choicesFor(setting: PlanSettingDescriptor): ConfigChoice[] | undefined {\n // `set` rather than a bespoke action: choosing a level is the same write as\n // typing one, so it shares the handler.\n return setting.options?.map((option) => ({ id: option, label: option, action: CONFIG_ACTION.set }));\n}\n\nexport function planConfigSections(config: PlanningModeConfig | undefined, notice?: string): readonly ConfigSection[] {\n const fields: ConfigField[] = PLAN_SETTINGS.map((setting) => {\n const value = setting.read(config);\n const choices = choicesFor(setting);\n return {\n id: setting.id,\n label: setting.label,\n kind: choices ? ('enum' as const) : ('text' as const),\n keyPath: setting.keyPath.join('.'),\n placeholder: setting.placeholder,\n detail: setting.detail,\n ...(value ? { value } : {}),\n ...(choices ? { choices } : {}),\n };\n });\n return [\n {\n id: PLAN_CONFIG_SECTION_ID,\n title: 'planning',\n order: SECTION_ORDER,\n detail: 'plan mode',\n fields,\n ...(notice ? { notice, noticeLevel: 'error' as const } : {}),\n },\n ];\n}\n"],"mappings":"qIAiBA,MAAa,EAAyB,WAEhC,EAAgB,CAAC,QAAS,EAAuB,CACjD,EAAW,OACX,EAAgB,YAEhB,EAAgB,4BAChB,EAAmB,UAaZ,EAAkD,CAC7D,CACE,GAAI,aACJ,MAAO,aACP,QAAS,CAAC,GAAG,EAAe,EAAU,QAAQ,CAC9C,YAAa,EACb,OAAQ,0DACR,KAAO,GAAW,GAAQ,MAAM,MACjC,CACD,CACE,GAAI,gBACJ,MAAO,gBACP,QAAS,CAAC,GAAG,EAAe,EAAU,WAAW,CACjD,YAAa,EACb,OAAQ,4DACR,QAAS,EACT,KAAO,GAAW,GAAQ,MAAM,SACjC,CACD,CACE,GAAI,kBACJ,MAAO,iBACP,QAAS,CAAC,GAAG,EAAe,EAAe,QAAQ,CACnD,YAAa,EACb,OAAQ,kDACR,KAAO,GAAW,GAAQ,WAAW,MACtC,CACD,CACE,GAAI,qBACJ,MAAO,oBACP,QAAS,CAAC,GAAG,EAAe,EAAe,WAAW,CACtD,YAAa,EACb,OAAQ,iDACR,QAAS,EACT,KAAO,GAAW,GAAQ,WAAW,SACtC,CACD,CACE,GAAI,iBACJ,MAAO,kBACP,QAAS,CAAC,GAAG,EAAe,iBAAiB,CAC7C,YAAa,cACb,OAAQ,gEACR,KAAO,GAAW,GAAQ,eAC3B,CACF,CAED,SAAgB,EAAqB,EAAoD,CACvF,OAAO,EAAc,KAAM,GAAY,EAAQ,KAAO,EAAQ,CAGhE,SAAS,EAAW,EAA4D,CAG9E,OAAO,EAAQ,SAAS,IAAK,IAAY,CAAE,GAAI,EAAQ,MAAO,EAAQ,OAAQ,EAAc,IAAK,EAAE,CAGrG,SAAgB,EAAmB,EAAwC,EAA2C,CAepH,MAAO,CACL,CACE,GAAI,EACJ,MAAO,WACP,MAAO,GACP,OAAQ,YACR,OApB0B,EAAc,IAAK,GAAY,CAC3D,IAAM,EAAQ,EAAQ,KAAK,EAAO,CAC5B,EAAU,EAAW,EAAQ,CACnC,MAAO,CACL,GAAI,EAAQ,GACZ,MAAO,EAAQ,MACf,KAAM,EAAW,OAAoB,OACrC,QAAS,EAAQ,QAAQ,KAAK,IAAI,CAClC,YAAa,EAAQ,YACrB,OAAQ,EAAQ,OAChB,GAAI,EAAQ,CAAE,QAAO,CAAG,EAAE,CAC1B,GAAI,EAAU,CAAE,UAAS,CAAG,EAAE,CAC/B,EAQO,CACN,GAAI,EAAS,CAAE,SAAQ,YAAa,QAAkB,CAAG,EAAE,CAC5D,CACF"}
1
+ {"version":3,"file":"planConfig.mjs","names":[],"sources":["../../../src/schemas/plan/planConfig.ts"],"sourcesContent":["/**\n * Plan mode's slice of the `SPC e c` config panel.\n *\n * Plan mode reads `modes.planning` from disk on every activation, so an edit\n * here lands on the next time the mode is turned on with no restart and nothing\n * to invalidate.\n *\n * The descriptor table is the whole design: the panel renders it and the write\n * handler looks the key path back up in it, so adding a setting means adding a\n * row rather than a case.\n */\n\nimport { DOOM_PLANNING_THINKING_LEVELS } from '@agimon-ai/doompi-config';\nimport {\n CONFIG_ACTION,\n type ConfigChoice,\n type ConfigField,\n type ConfigSection,\n} from '@agimon-ai/doompi-extension-contracts/config';\nimport type { PlanningModeConfig } from './config.ts';\n\nexport const PLAN_CONFIG_SECTION_ID = 'planning';\nconst SECTION_ORDER = 30;\nconst PLANNING_PATH = ['modes', PLAN_CONFIG_SECTION_ID] as const;\nconst MAIN_KEY = 'main';\nconst SUBAGENTS_KEY = 'subagents';\n/** Both agents fall back to the session's own settings when left unset. */\nconst INHERIT_MODEL = 'inherit the session model';\nconst INHERIT_THINKING = 'inherit';\n\ninterface PlanSettingDescriptor {\n readonly id: string;\n readonly label: string;\n readonly keyPath: readonly string[];\n readonly placeholder: string;\n readonly detail: string;\n /** Present for a closed set; the panel offers these rather than free text. */\n readonly options?: readonly string[];\n readonly read: (config: PlanningModeConfig | undefined) => string | undefined;\n}\n\nexport const PLAN_SETTINGS: readonly PlanSettingDescriptor[] = [\n {\n id: 'main.model',\n label: 'main model',\n keyPath: [...PLANNING_PATH, MAIN_KEY, 'model'],\n placeholder: INHERIT_MODEL,\n detail: 'Model the main agent switches to while plan mode is on.',\n read: (config) => config?.main?.model,\n },\n {\n id: 'main.thinking',\n label: 'main thinking',\n keyPath: [...PLANNING_PATH, MAIN_KEY, 'thinking'],\n placeholder: INHERIT_THINKING,\n detail: 'Thinking level appended to the main model while planning.',\n options: DOOM_PLANNING_THINKING_LEVELS,\n read: (config) => config?.main?.thinking,\n },\n {\n id: 'subagents.model',\n label: 'subagent model',\n keyPath: [...PLANNING_PATH, SUBAGENTS_KEY, 'model'],\n placeholder: INHERIT_MODEL,\n detail: 'Model forced onto delegated planning subagents.',\n read: (config) => config?.subagents?.model,\n },\n {\n id: 'subagents.thinking',\n label: 'subagent thinking',\n keyPath: [...PLANNING_PATH, SUBAGENTS_KEY, 'thinking'],\n placeholder: INHERIT_THINKING,\n detail: 'Thinking level appended to the subagent model.',\n options: DOOM_PLANNING_THINKING_LEVELS,\n read: (config) => config?.subagents?.thinking,\n },\n {\n id: 'plansdirectory',\n label: 'plans directory',\n keyPath: [...PLANNING_PATH, 'plansDirectory'],\n placeholder: '~/.pi/plans',\n detail: 'Absolute, repo-relative, or under ~. Written plans land here.',\n read: (config) => config?.plansDirectory,\n },\n];\n\nexport function planSettingByFieldId(fieldId: string): PlanSettingDescriptor | undefined {\n return PLAN_SETTINGS.find((setting) => setting.id === fieldId);\n}\n\nfunction choicesFor(setting: PlanSettingDescriptor): ConfigChoice[] | undefined {\n // `set` rather than a bespoke action: choosing a level is the same write as\n // typing one, so it shares the handler.\n return setting.options?.map((option) => ({ id: option, label: option, action: CONFIG_ACTION.set }));\n}\n\nexport function planConfigSections(config: PlanningModeConfig | undefined, notice?: string): readonly ConfigSection[] {\n const fields: ConfigField[] = PLAN_SETTINGS.map((setting) => {\n const value = setting.read(config);\n const choices = choicesFor(setting);\n return {\n id: setting.id,\n label: setting.label,\n kind: choices ? ('enum' as const) : ('text' as const),\n keyPath: setting.keyPath.join('.'),\n placeholder: setting.placeholder,\n detail: setting.detail,\n ...(value ? { value } : {}),\n ...(choices ? { choices } : {}),\n };\n });\n return [\n {\n id: PLAN_CONFIG_SECTION_ID,\n title: 'planning',\n order: SECTION_ORDER,\n detail: 'plan mode',\n fields,\n ...(notice ? { notice, noticeLevel: 'error' as const } : {}),\n },\n ];\n}\n"],"mappings":"sJAqBA,MAAa,EAAyB,WAEhC,EAAgB,CAAC,QAAS,EAAuB,CACjD,EAAW,OACX,EAAgB,YAEhB,EAAgB,4BAChB,EAAmB,UAaZ,EAAkD,CAC7D,CACE,GAAI,aACJ,MAAO,aACP,QAAS,CAAC,GAAG,EAAe,EAAU,QAAQ,CAC9C,YAAa,EACb,OAAQ,0DACR,KAAO,GAAW,GAAQ,MAAM,MACjC,CACD,CACE,GAAI,gBACJ,MAAO,gBACP,QAAS,CAAC,GAAG,EAAe,EAAU,WAAW,CACjD,YAAa,EACb,OAAQ,4DACR,QAAS,EACT,KAAO,GAAW,GAAQ,MAAM,SACjC,CACD,CACE,GAAI,kBACJ,MAAO,iBACP,QAAS,CAAC,GAAG,EAAe,EAAe,QAAQ,CACnD,YAAa,EACb,OAAQ,kDACR,KAAO,GAAW,GAAQ,WAAW,MACtC,CACD,CACE,GAAI,qBACJ,MAAO,oBACP,QAAS,CAAC,GAAG,EAAe,EAAe,WAAW,CACtD,YAAa,EACb,OAAQ,iDACR,QAAS,EACT,KAAO,GAAW,GAAQ,WAAW,SACtC,CACD,CACE,GAAI,iBACJ,MAAO,kBACP,QAAS,CAAC,GAAG,EAAe,iBAAiB,CAC7C,YAAa,cACb,OAAQ,gEACR,KAAO,GAAW,GAAQ,eAC3B,CACF,CAED,SAAgB,EAAqB,EAAoD,CACvF,OAAO,EAAc,KAAM,GAAY,EAAQ,KAAO,EAAQ,CAGhE,SAAS,EAAW,EAA4D,CAG9E,OAAO,EAAQ,SAAS,IAAK,IAAY,CAAE,GAAI,EAAQ,MAAO,EAAQ,OAAQ,EAAc,IAAK,EAAE,CAGrG,SAAgB,EAAmB,EAAwC,EAA2C,CAepH,MAAO,CACL,CACE,GAAI,EACJ,MAAO,WACP,MAAO,GACP,OAAQ,YACR,OApB0B,EAAc,IAAK,GAAY,CAC3D,IAAM,EAAQ,EAAQ,KAAK,EAAO,CAC5B,EAAU,EAAW,EAAQ,CACnC,MAAO,CACL,GAAI,EAAQ,GACZ,MAAO,EAAQ,MACf,KAAM,EAAW,OAAoB,OACrC,QAAS,EAAQ,QAAQ,KAAK,IAAI,CAClC,YAAa,EAAQ,YACrB,OAAQ,EAAQ,OAChB,GAAI,EAAQ,CAAE,QAAO,CAAG,EAAE,CAC1B,GAAI,EAAU,CAAE,UAAS,CAAG,EAAE,CAC/B,EAQO,CACN,GAAI,EAAS,CAAE,SAAQ,YAAa,QAAkB,CAAG,EAAE,CAC5D,CACF"}
@@ -0,0 +1,3 @@
1
+ require(`../_virtual/_rolldown/runtime.cjs`);let e=require(`node:buffer`);const t=`@agimon-ai/doompi-plan`,n=`claude`,r=`fable`,i=`claude/fable-plan-v1`,a=[/(?:api[_-]?key|access[_-]?token|client[_-]?secret|password|private[_-]?key|authorization|bearer)\s*[:=]/iu,/-----BEGIN [A-Z ]*PRIVATE KEY-----/u,/\bsk-[A-Za-z0-9_-]{16,}\b/u,/\bgh[pousr]_[A-Za-z0-9_]{16,}\b/u];function o(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function s(e){for(let t of e){let e=t.codePointAt(0);if(e!==void 0&&(e<=31||e===127))return!0}return!1}function c(e){return a.some(t=>t.test(e))}function l(t,n,r=!0){if(typeof t!=`string`)throw Error(`${n} must be a string.`);let i=t.trim();if(!i&&r)throw Error(`${n} must not be empty.`);if(e.Buffer.byteLength(i,`utf8`)>4096||s(i))throw Error(`${n} exceeds the bounded Fable text limit or contains control characters.`);if(c(i))throw Error(`${n} appears to contain a credential.`);return i}function u(e,t,n=!0){if(!Array.isArray(e))throw Error(`${t} must be an array.`);if(e.length>24)throw Error(`${t} exceeds the bounded item limit.`);let r=e.map((e,n)=>l(e,`${t}[${n}]`));if(n&&r.length===0)throw Error(`${t} must contain at least one item.`);return r}function d(e,t){if(typeof e!=`string`)throw Error(`${t} must be a string.`);let n=e.trim();if(!n||n.length>512||s(n))throw Error(`${t} is not a safe source path.`);if(c(n))throw Error(`${t} appears to contain a credential.`);return n}function f(e){if(!Array.isArray(e))throw Error(`verifiedFindings must be an array.`);if(e.length>24)throw Error(`verifiedFindings exceeds the bounded item limit.`);return e.map((e,t)=>{if(!o(e))throw Error(`verifiedFindings[${t}] must be an object.`);if(Object.keys(e).some(e=>e!==`path`&&e!==`finding`))throw Error(`verifiedFindings[${t}] contains an unsupported field.`);return{path:d(e.path,`verifiedFindings[${t}].path`),finding:l(e.finding,`verifiedFindings[${t}].finding`)}})}function p(e,t,n){let r=new Set(t),i=Object.keys(e).find(e=>!r.has(e));if(i)throw Error(`${n} contains unsupported field '${i}'.`)}function m(t){if(!o(t))throw Error(`Fable packet must be an object.`);p(t,[`goal`,`constraints`,`decisions`,`verifiedFindings`,`inferredFindings`,`unresolvedQuestions`,`currentPlan`],`Fable packet`);let n={goal:u(t.goal,`goal`),constraints:u(t.constraints,`constraints`,!1),decisions:u(t.decisions,`decisions`,!1),verifiedFindings:f(t.verifiedFindings),inferredFindings:u(t.inferredFindings,`inferredFindings`,!1),unresolvedQuestions:u(t.unresolvedQuestions,`unresolvedQuestions`,!1),...t.currentPlan===void 0?{}:{currentPlan:l(t.currentPlan,`currentPlan`,!1)}};if(e.Buffer.byteLength(JSON.stringify(n),`utf8`)>32768)throw Error(`Fable packet exceeds the bounded packet size.`);return n}function h(e){return c([e.draft,e.review].filter(e=>e!==void 0).join(`
2
+ `))?{operationId:e.operationId,status:`failed`,stage:`failed`,durationMs:e.durationMs,errorCode:`unsafe_output`}:e}function g(e,t){return{operationId:e,status:`timed_out`,stage:`interrupted`,durationMs:Math.max(0,Date.now()-t),errorCode:`timeout`}}function _(e){let a=e.newOperationId??(()=>crypto.randomUUID()),o,s=(t=`Fable operation cancelled.`)=>{let n=o;if(n){if(!n.cancelSent){n.cancelSent=!0;try{e.broker?.cancel(n.operationId,t)}catch(t){e.onError?.(t)}}n.controller.abort(Error(t))}};return{run:async(c,l)=>{if(o)throw Error(`A Fable operation is already active for this session.`);if(!e.isAuthorized())throw Error(`The Fable capability profile is not authorized.`);let u=m(c),d=`fable-${a()}`,f=Date.now(),p=new AbortController;o={operationId:d,controller:p,cancelSent:!1},e.onStage?.(`draft`);let _=()=>p.abort(l?.reason);l&&(l.addEventListener(`abort`,_,{once:!0}),l.aborted&&_());let v={requester:t,operationId:d,runtime:n,model:r,profile:i,packet:u},y,b=!1;try{if(!e.broker)return g(d,f);let t=e.broker.start(v,p.signal),n=new Promise(e=>{p.signal.addEventListener(`abort`,()=>{b||e({operationId:d,status:`cancelled`,stage:`cancelled`,durationMs:Math.max(0,Date.now()-f),errorCode:`cancelled`})},{once:!0})}),r=e.timeoutMs===void 0?void 0:new Promise(t=>{y=setTimeout(()=>{b=!0,s(`Fable operation timed out.`),t(g(d,f))},e.timeoutMs)}),i=h(r===void 0?await Promise.race([t,n]):await Promise.race([t,r,n]));return e.onStage?.(i.status===`completed`?`completed`:i.status===`cancelled`?`cancelled`:i.stage),i}catch(t){e.onError?.(t);let n={operationId:d,status:`failed`,stage:`failed`,durationMs:Math.max(0,Date.now()-f),errorCode:`unavailable`};return e.onStage?.(`failed`),n}finally{y&&clearTimeout(y),l&&l.removeEventListener(`abort`,_),o=void 0}},cancel:s,isActive:()=>o!==void 0}}exports.FABLE_PLAN_MODEL=r,exports.FABLE_PLAN_PROFILE=i,exports.FABLE_PLAN_REQUESTER=t,exports.FABLE_PLAN_RUNTIME=n,exports.FABLE_PROVIDER_SOURCE=`@agimon-ai/doompi-team`,exports.MAX_FABLE_ARRAY_ITEMS=24,exports.MAX_FABLE_PACKET_BYTES=32768,exports.MAX_FABLE_TEXT_BYTES=4096,exports.containsSuspectedCredential=c,exports.createFablePlanFlow=_,exports.sanitizeFablePacket=m;
3
+ //# sourceMappingURL=fableFlow.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fableFlow.cjs","names":["Buffer"],"sources":["../../src/services/fableFlow.ts"],"sourcesContent":["import { Buffer } from 'node:buffer';\n\nexport const FABLE_PROVIDER_SOURCE = '@agimon-ai/doompi-team';\nexport const FABLE_PLAN_REQUESTER = '@agimon-ai/doompi-plan';\nexport const FABLE_PLAN_RUNTIME = 'claude';\nexport const FABLE_PLAN_MODEL = 'fable';\nexport const FABLE_PLAN_PROFILE = 'claude/fable-plan-v1';\nexport const MAX_FABLE_PACKET_BYTES = 32 * 1024;\nexport const MAX_FABLE_TEXT_BYTES = 4 * 1024;\nexport const MAX_FABLE_ARRAY_ITEMS = 24;\n\nconst SECRET_PATTERNS = [\n /(?:api[_-]?key|access[_-]?token|client[_-]?secret|password|private[_-]?key|authorization|bearer)\\s*[:=]/iu,\n /-----BEGIN [A-Z ]*PRIVATE KEY-----/u,\n /\\bsk-[A-Za-z0-9_-]{16,}\\b/u,\n /\\bgh[pousr]_[A-Za-z0-9_]{16,}\\b/u,\n];\nconst CONTROL_CHARACTER_MAX = 31;\nconst DELETE_CHARACTER = 127;\nconst MAX_SOURCE_PATH_LENGTH = 512;\n\nexport interface FablePlanFinding {\n path: string;\n finding: string;\n}\n\nexport interface FablePlanPacket {\n goal: string[];\n constraints: string[];\n decisions: string[];\n verifiedFindings: FablePlanFinding[];\n inferredFindings: string[];\n unresolvedQuestions: string[];\n currentPlan?: string;\n}\n\nexport type FablePlanStatus = 'completed' | 'failed' | 'timed_out' | 'cancelled' | 'interrupted';\nexport type FablePlanStage = 'draft' | 'review' | 'completed' | 'failed' | 'cancelled' | 'interrupted';\n\nexport interface FablePlanResult {\n operationId: string;\n status: FablePlanStatus;\n stage: FablePlanStage;\n draft?: string;\n review?: string;\n draftRunId?: string;\n reviewRunId?: string;\n durationMs: number;\n errorCode?: string;\n}\n\nexport interface FablePlanRequest {\n requester: typeof FABLE_PLAN_REQUESTER;\n operationId: string;\n runtime: typeof FABLE_PLAN_RUNTIME;\n model: typeof FABLE_PLAN_MODEL;\n profile: typeof FABLE_PLAN_PROFILE;\n packet: FablePlanPacket;\n}\n\nexport interface FablePlanBroker {\n start(request: FablePlanRequest, signal: AbortSignal): Promise<FablePlanResult>;\n cancel(operationId: string, reason: string): void;\n}\n\nexport interface FableFlowOptions {\n broker?: FablePlanBroker;\n isAuthorized: () => boolean;\n /** Supplies operation ids. Injected so a test can pin them. */\n newOperationId?: () => string;\n timeoutMs?: number;\n onStage?: (stage: FableStage) => void;\n onError?: (error: unknown) => void;\n}\n\nexport type FableStage = 'idle' | 'draft' | 'review' | 'completed' | 'failed' | 'cancelled' | 'interrupted';\n\nexport interface FablePlanFlow {\n run(value: unknown, signal?: AbortSignal): Promise<FablePlanResult>;\n cancel(reason?: string): void;\n isActive(): boolean;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction hasControlCharacter(value: string): boolean {\n for (const character of value) {\n const code = character.codePointAt(0);\n if (code !== undefined && (code <= CONTROL_CHARACTER_MAX || code === DELETE_CHARACTER)) return true;\n }\n return false;\n}\n\nexport function containsSuspectedCredential(value: string): boolean {\n return SECRET_PATTERNS.some((pattern) => pattern.test(value));\n}\n\nfunction boundedText(value: unknown, field: string, required = true): string {\n if (typeof value !== 'string') throw new Error(`${field} must be a string.`);\n const text = value.trim();\n if (!text && required) throw new Error(`${field} must not be empty.`);\n if (Buffer.byteLength(text, 'utf8') > MAX_FABLE_TEXT_BYTES || hasControlCharacter(text)) {\n throw new Error(`${field} exceeds the bounded Fable text limit or contains control characters.`);\n }\n if (containsSuspectedCredential(text)) throw new Error(`${field} appears to contain a credential.`);\n return text;\n}\n\nfunction boundedList(value: unknown, field: string, required = true): string[] {\n if (!Array.isArray(value)) throw new Error(`${field} must be an array.`);\n if (value.length > MAX_FABLE_ARRAY_ITEMS) throw new Error(`${field} exceeds the bounded item limit.`);\n const items = value.map((item, index) => boundedText(item, `${field}[${index}]`));\n if (required && items.length === 0) throw new Error(`${field} must contain at least one item.`);\n return items;\n}\n\nfunction boundedPath(value: unknown, field: string): string {\n if (typeof value !== 'string') throw new Error(`${field} must be a string.`);\n const sourcePath = value.trim();\n if (!sourcePath || sourcePath.length > MAX_SOURCE_PATH_LENGTH || hasControlCharacter(sourcePath)) {\n throw new Error(`${field} is not a safe source path.`);\n }\n if (containsSuspectedCredential(sourcePath)) throw new Error(`${field} appears to contain a credential.`);\n return sourcePath;\n}\n\nfunction boundedFindings(value: unknown): FablePlanFinding[] {\n if (!Array.isArray(value)) throw new Error('verifiedFindings must be an array.');\n if (value.length > MAX_FABLE_ARRAY_ITEMS) throw new Error('verifiedFindings exceeds the bounded item limit.');\n return value.map((item, index) => {\n if (!isRecord(item)) throw new Error(`verifiedFindings[${index}] must be an object.`);\n const keys = Object.keys(item);\n if (keys.some((key) => key !== 'path' && key !== 'finding')) {\n throw new Error(`verifiedFindings[${index}] contains an unsupported field.`);\n }\n return {\n path: boundedPath(item.path, `verifiedFindings[${index}].path`),\n finding: boundedText(item.finding, `verifiedFindings[${index}].finding`),\n };\n });\n}\n\nfunction assertAllowedKeys(value: Record<string, unknown>, keys: readonly string[], field: string): void {\n const allowed = new Set(keys);\n const unexpected = Object.keys(value).find((key) => !allowed.has(key));\n if (unexpected) throw new Error(`${field} contains unsupported field '${unexpected}'.`);\n}\n\nexport function sanitizeFablePacket(value: unknown): FablePlanPacket {\n if (!isRecord(value)) throw new Error('Fable packet must be an object.');\n assertAllowedKeys(\n value,\n ['goal', 'constraints', 'decisions', 'verifiedFindings', 'inferredFindings', 'unresolvedQuestions', 'currentPlan'],\n 'Fable packet',\n );\n const packet: FablePlanPacket = {\n goal: boundedList(value.goal, 'goal'),\n constraints: boundedList(value.constraints, 'constraints', false),\n decisions: boundedList(value.decisions, 'decisions', false),\n verifiedFindings: boundedFindings(value.verifiedFindings),\n inferredFindings: boundedList(value.inferredFindings, 'inferredFindings', false),\n unresolvedQuestions: boundedList(value.unresolvedQuestions, 'unresolvedQuestions', false),\n ...(value.currentPlan === undefined ? {} : { currentPlan: boundedText(value.currentPlan, 'currentPlan', false) }),\n };\n if (Buffer.byteLength(JSON.stringify(packet), 'utf8') > MAX_FABLE_PACKET_BYTES) {\n throw new Error('Fable packet exceeds the bounded packet size.');\n }\n return packet;\n}\n\nfunction safeResult(result: FablePlanResult): FablePlanResult {\n const output = [result.draft, result.review].filter((value): value is string => value !== undefined).join('\\n');\n if (containsSuspectedCredential(output)) {\n return {\n operationId: result.operationId,\n status: 'failed',\n stage: 'failed',\n durationMs: result.durationMs,\n errorCode: 'unsafe_output',\n };\n }\n return result;\n}\n\nfunction timedOutResult(operationId: string, startedAt: number): FablePlanResult {\n return {\n operationId,\n status: 'timed_out',\n stage: 'interrupted',\n durationMs: Math.max(0, Date.now() - startedAt),\n errorCode: 'timeout',\n };\n}\n\nexport function createFablePlanFlow(options: FableFlowOptions): FablePlanFlow {\n const newOperationId = options.newOperationId ?? (() => crypto.randomUUID());\n let active:\n | {\n operationId: string;\n controller: AbortController;\n cancelSent: boolean;\n }\n | undefined;\n\n const cancel = (reason = 'Fable operation cancelled.'): void => {\n const current = active;\n if (!current) return;\n if (!current.cancelSent) {\n current.cancelSent = true;\n try {\n options.broker?.cancel(current.operationId, reason);\n } catch (error) {\n options.onError?.(error);\n }\n }\n current.controller.abort(new Error(reason));\n };\n\n const run = async (value: unknown, signal?: AbortSignal): Promise<FablePlanResult> => {\n if (active) throw new Error('A Fable operation is already active for this session.');\n if (!options.isAuthorized()) throw new Error('The Fable capability profile is not authorized.');\n const packet = sanitizeFablePacket(value);\n const operationId = `fable-${newOperationId()}`;\n const startedAt = Date.now();\n const controller = new AbortController();\n active = { operationId, controller, cancelSent: false };\n options.onStage?.('draft');\n\n const parentAbort = (): void => controller.abort(signal?.reason);\n if (signal) {\n signal.addEventListener('abort', parentAbort, { once: true });\n if (signal.aborted) parentAbort();\n }\n\n const brokerRequest: FablePlanRequest = {\n requester: FABLE_PLAN_REQUESTER,\n operationId,\n runtime: FABLE_PLAN_RUNTIME,\n model: FABLE_PLAN_MODEL,\n profile: FABLE_PLAN_PROFILE,\n packet,\n };\n let timeout: ReturnType<typeof setTimeout> | undefined;\n let timeoutTriggered = false;\n try {\n if (!options.broker) return timedOutResult(operationId, startedAt);\n const brokerResult = options.broker.start(brokerRequest, controller.signal);\n const cancelledResult = new Promise<FablePlanResult>((resolve) => {\n const onAbort = (): void => {\n if (timeoutTriggered) return;\n resolve({\n operationId,\n status: 'cancelled',\n stage: 'cancelled',\n durationMs: Math.max(0, Date.now() - startedAt),\n errorCode: 'cancelled',\n });\n };\n controller.signal.addEventListener('abort', onAbort, { once: true });\n });\n const timeoutResult =\n options.timeoutMs === undefined\n ? undefined\n : new Promise<FablePlanResult>((resolve) => {\n timeout = setTimeout(() => {\n timeoutTriggered = true;\n cancel('Fable operation timed out.');\n resolve(timedOutResult(operationId, startedAt));\n }, options.timeoutMs);\n });\n const result =\n timeoutResult === undefined\n ? await Promise.race([brokerResult, cancelledResult])\n : await Promise.race([brokerResult, timeoutResult, cancelledResult]);\n const safe = safeResult(result);\n options.onStage?.(\n safe.status === 'completed' ? 'completed' : safe.status === 'cancelled' ? 'cancelled' : safe.stage,\n );\n return safe;\n } catch (error) {\n options.onError?.(error);\n const failure: FablePlanResult = {\n operationId,\n status: 'failed',\n stage: 'failed',\n durationMs: Math.max(0, Date.now() - startedAt),\n errorCode: 'unavailable',\n };\n options.onStage?.('failed');\n return failure;\n } finally {\n if (timeout) clearTimeout(timeout);\n if (signal) signal.removeEventListener('abort', parentAbort);\n active = undefined;\n }\n };\n\n return {\n run,\n cancel,\n isActive: () => active !== undefined,\n };\n}\n"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- //#region src/services/plan/fableFlow.d.ts
1
+ //#region src/services/fableFlow.d.ts
2
2
  declare const FABLE_PROVIDER_SOURCE = "@agimon-ai/doompi-team";
3
3
  declare const FABLE_PLAN_REQUESTER = "@agimon-ai/doompi-plan";
4
4
  declare const FABLE_PLAN_RUNTIME = "claude";
@@ -48,6 +48,8 @@ interface FablePlanBroker {
48
48
  interface FableFlowOptions {
49
49
  broker?: FablePlanBroker;
50
50
  isAuthorized: () => boolean;
51
+ /** Supplies operation ids. Injected so a test can pin them. */
52
+ newOperationId?: () => string;
51
53
  timeoutMs?: number;
52
54
  onStage?: (stage: FableStage) => void;
53
55
  onError?: (error: unknown) => void;
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fableFlow.d.cts","names":[],"sources":["../../src/services/fableFlow.ts"],"mappings":";cAEa,qBAAA;AAAA,cACA,oBAAA;AAAA,cACA,kBAAA;AAAA,cACA,gBAAA;AAAA,cACA,kBAAA;AAAA,cACA,sBAAA;AAAA,cACA,oBAAA;AAAA,cACA,qBAAA;AAAA,UAYI,gBAAA;EACf,IAAA;EACA,OAAA;AAAA;AAAA,UAGe,eAAA;EACf,IAAA;EACA,WAAA;EACA,SAAA;EACA,gBAAA,EAAkB,gBAAA;EAClB,gBAAA;EACA,mBAAA;EACA,WAAA;AAAA;AAAA,KAGU,eAAA;AAAA,KACA,cAAA;AAAA,UAEK,eAAA;EACf,WAAA;EACA,MAAA,EAAQ,eAAA;EACR,KAAA,EAAO,cAAA;EACP,KAAA;EACA,MAAA;EACA,UAAA;EACA,WAAA;EACA,UAAA;EACA,SAAA;AAAA;AAAA,UAGe,gBAAA;EACf,SAAA,SAAkB,oBAAA;EAClB,WAAA;EACA,OAAA,SAAgB,kBAAA;EAChB,KAAA,SAAc,gBAAA;EACd,OAAA,SAAgB,kBAAA;EAChB,MAAA,EAAQ,eAAA;AAAA;AAAA,UAGO,eAAA;EACf,KAAA,CAAM,OAAA,EAAS,gBAAA,EAAkB,MAAA,EAAQ,WAAA,GAAc,OAAA,CAAQ,eAAA;EAC/D,MAAA,CAAO,WAAA,UAAqB,MAAA;AAAA;AAAA,UAGb,gBAAA;EACf,MAAA,GAAS,eAAA;EACT,YAAA;EArCkC;EAuClC,cAAA;EACA,SAAA;EACA,OAAA,IAAW,KAAA,EAAO,UAAA;EAClB,OAAA,IAAW,KAAA;AAAA;AAAA,KAGD,UAAA;AAAA,UAEK,aAAA;EACf,GAAA,CAAI,KAAA,WAAgB,MAAA,GAAS,WAAA,GAAc,OAAA,CAAQ,eAAA;EACnD,MAAA,CAAO,MAAA;EACP,QAAA;AAAA;AAAA,iBAec,2BAAA,CAA4B,KAAA;AAAA,iBAuD5B,mBAAA,CAAoB,KAAA,YAAiB,eAAA;AAAA,iBA8CrC,mBAAA,CAAoB,OAAA,EAAS,gBAAA,GAAmB,aAAA"}
@@ -1,4 +1,4 @@
1
- //#region src/services/plan/fableFlow.d.ts
1
+ //#region src/services/fableFlow.d.ts
2
2
  declare const FABLE_PROVIDER_SOURCE = "@agimon-ai/doompi-team";
3
3
  declare const FABLE_PLAN_REQUESTER = "@agimon-ai/doompi-plan";
4
4
  declare const FABLE_PLAN_RUNTIME = "claude";
@@ -48,6 +48,8 @@ interface FablePlanBroker {
48
48
  interface FableFlowOptions {
49
49
  broker?: FablePlanBroker;
50
50
  isAuthorized: () => boolean;
51
+ /** Supplies operation ids. Injected so a test can pin them. */
52
+ newOperationId?: () => string;
51
53
  timeoutMs?: number;
52
54
  onStage?: (stage: FableStage) => void;
53
55
  onError?: (error: unknown) => void;
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fableFlow.d.mts","names":[],"sources":["../../src/services/fableFlow.ts"],"mappings":";cAEa,qBAAA;AAAA,cACA,oBAAA;AAAA,cACA,kBAAA;AAAA,cACA,gBAAA;AAAA,cACA,kBAAA;AAAA,cACA,sBAAA;AAAA,cACA,oBAAA;AAAA,cACA,qBAAA;AAAA,UAYI,gBAAA;EACf,IAAA;EACA,OAAA;AAAA;AAAA,UAGe,eAAA;EACf,IAAA;EACA,WAAA;EACA,SAAA;EACA,gBAAA,EAAkB,gBAAA;EAClB,gBAAA;EACA,mBAAA;EACA,WAAA;AAAA;AAAA,KAGU,eAAA;AAAA,KACA,cAAA;AAAA,UAEK,eAAA;EACf,WAAA;EACA,MAAA,EAAQ,eAAA;EACR,KAAA,EAAO,cAAA;EACP,KAAA;EACA,MAAA;EACA,UAAA;EACA,WAAA;EACA,UAAA;EACA,SAAA;AAAA;AAAA,UAGe,gBAAA;EACf,SAAA,SAAkB,oBAAA;EAClB,WAAA;EACA,OAAA,SAAgB,kBAAA;EAChB,KAAA,SAAc,gBAAA;EACd,OAAA,SAAgB,kBAAA;EAChB,MAAA,EAAQ,eAAA;AAAA;AAAA,UAGO,eAAA;EACf,KAAA,CAAM,OAAA,EAAS,gBAAA,EAAkB,MAAA,EAAQ,WAAA,GAAc,OAAA,CAAQ,eAAA;EAC/D,MAAA,CAAO,WAAA,UAAqB,MAAA;AAAA;AAAA,UAGb,gBAAA;EACf,MAAA,GAAS,eAAA;EACT,YAAA;EArCkC;EAuClC,cAAA;EACA,SAAA;EACA,OAAA,IAAW,KAAA,EAAO,UAAA;EAClB,OAAA,IAAW,KAAA;AAAA;AAAA,KAGD,UAAA;AAAA,UAEK,aAAA;EACf,GAAA,CAAI,KAAA,WAAgB,MAAA,GAAS,WAAA,GAAc,OAAA,CAAQ,eAAA;EACnD,MAAA,CAAO,MAAA;EACP,QAAA;AAAA;AAAA,iBAec,2BAAA,CAA4B,KAAA;AAAA,iBAuD5B,mBAAA,CAAoB,KAAA,YAAiB,eAAA;AAAA,iBA8CrC,mBAAA,CAAoB,OAAA,EAAS,gBAAA,GAAmB,aAAA"}
@@ -0,0 +1,3 @@
1
+ import{Buffer as e}from"node:buffer";const t=`@agimon-ai/doompi-team`,n=`@agimon-ai/doompi-plan`,r=`claude`,i=`fable`,a=`claude/fable-plan-v1`,o=32*1024,s=4*1024,c=24,l=[/(?:api[_-]?key|access[_-]?token|client[_-]?secret|password|private[_-]?key|authorization|bearer)\s*[:=]/iu,/-----BEGIN [A-Z ]*PRIVATE KEY-----/u,/\bsk-[A-Za-z0-9_-]{16,}\b/u,/\bgh[pousr]_[A-Za-z0-9_]{16,}\b/u];function u(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function d(e){for(let t of e){let e=t.codePointAt(0);if(e!==void 0&&(e<=31||e===127))return!0}return!1}function f(e){return l.some(t=>t.test(e))}function p(t,n,r=!0){if(typeof t!=`string`)throw Error(`${n} must be a string.`);let i=t.trim();if(!i&&r)throw Error(`${n} must not be empty.`);if(e.byteLength(i,`utf8`)>4096||d(i))throw Error(`${n} exceeds the bounded Fable text limit or contains control characters.`);if(f(i))throw Error(`${n} appears to contain a credential.`);return i}function m(e,t,n=!0){if(!Array.isArray(e))throw Error(`${t} must be an array.`);if(e.length>24)throw Error(`${t} exceeds the bounded item limit.`);let r=e.map((e,n)=>p(e,`${t}[${n}]`));if(n&&r.length===0)throw Error(`${t} must contain at least one item.`);return r}function h(e,t){if(typeof e!=`string`)throw Error(`${t} must be a string.`);let n=e.trim();if(!n||n.length>512||d(n))throw Error(`${t} is not a safe source path.`);if(f(n))throw Error(`${t} appears to contain a credential.`);return n}function g(e){if(!Array.isArray(e))throw Error(`verifiedFindings must be an array.`);if(e.length>24)throw Error(`verifiedFindings exceeds the bounded item limit.`);return e.map((e,t)=>{if(!u(e))throw Error(`verifiedFindings[${t}] must be an object.`);if(Object.keys(e).some(e=>e!==`path`&&e!==`finding`))throw Error(`verifiedFindings[${t}] contains an unsupported field.`);return{path:h(e.path,`verifiedFindings[${t}].path`),finding:p(e.finding,`verifiedFindings[${t}].finding`)}})}function _(e,t,n){let r=new Set(t),i=Object.keys(e).find(e=>!r.has(e));if(i)throw Error(`${n} contains unsupported field '${i}'.`)}function v(t){if(!u(t))throw Error(`Fable packet must be an object.`);_(t,[`goal`,`constraints`,`decisions`,`verifiedFindings`,`inferredFindings`,`unresolvedQuestions`,`currentPlan`],`Fable packet`);let n={goal:m(t.goal,`goal`),constraints:m(t.constraints,`constraints`,!1),decisions:m(t.decisions,`decisions`,!1),verifiedFindings:g(t.verifiedFindings),inferredFindings:m(t.inferredFindings,`inferredFindings`,!1),unresolvedQuestions:m(t.unresolvedQuestions,`unresolvedQuestions`,!1),...t.currentPlan===void 0?{}:{currentPlan:p(t.currentPlan,`currentPlan`,!1)}};if(e.byteLength(JSON.stringify(n),`utf8`)>32768)throw Error(`Fable packet exceeds the bounded packet size.`);return n}function y(e){return f([e.draft,e.review].filter(e=>e!==void 0).join(`
2
+ `))?{operationId:e.operationId,status:`failed`,stage:`failed`,durationMs:e.durationMs,errorCode:`unsafe_output`}:e}function b(e,t){return{operationId:e,status:`timed_out`,stage:`interrupted`,durationMs:Math.max(0,Date.now()-t),errorCode:`timeout`}}function x(e){let t=e.newOperationId??(()=>crypto.randomUUID()),o,s=(t=`Fable operation cancelled.`)=>{let n=o;if(n){if(!n.cancelSent){n.cancelSent=!0;try{e.broker?.cancel(n.operationId,t)}catch(t){e.onError?.(t)}}n.controller.abort(Error(t))}};return{run:async(c,l)=>{if(o)throw Error(`A Fable operation is already active for this session.`);if(!e.isAuthorized())throw Error(`The Fable capability profile is not authorized.`);let u=v(c),d=`fable-${t()}`,f=Date.now(),p=new AbortController;o={operationId:d,controller:p,cancelSent:!1},e.onStage?.(`draft`);let m=()=>p.abort(l?.reason);l&&(l.addEventListener(`abort`,m,{once:!0}),l.aborted&&m());let h={requester:n,operationId:d,runtime:r,model:i,profile:a,packet:u},g,_=!1;try{if(!e.broker)return b(d,f);let t=e.broker.start(h,p.signal),n=new Promise(e=>{p.signal.addEventListener(`abort`,()=>{_||e({operationId:d,status:`cancelled`,stage:`cancelled`,durationMs:Math.max(0,Date.now()-f),errorCode:`cancelled`})},{once:!0})}),r=e.timeoutMs===void 0?void 0:new Promise(t=>{g=setTimeout(()=>{_=!0,s(`Fable operation timed out.`),t(b(d,f))},e.timeoutMs)}),i=y(r===void 0?await Promise.race([t,n]):await Promise.race([t,r,n]));return e.onStage?.(i.status===`completed`?`completed`:i.status===`cancelled`?`cancelled`:i.stage),i}catch(t){e.onError?.(t);let n={operationId:d,status:`failed`,stage:`failed`,durationMs:Math.max(0,Date.now()-f),errorCode:`unavailable`};return e.onStage?.(`failed`),n}finally{g&&clearTimeout(g),l&&l.removeEventListener(`abort`,m),o=void 0}},cancel:s,isActive:()=>o!==void 0}}export{i as FABLE_PLAN_MODEL,a as FABLE_PLAN_PROFILE,n as FABLE_PLAN_REQUESTER,r as FABLE_PLAN_RUNTIME,t as FABLE_PROVIDER_SOURCE,c as MAX_FABLE_ARRAY_ITEMS,o as MAX_FABLE_PACKET_BYTES,s as MAX_FABLE_TEXT_BYTES,f as containsSuspectedCredential,x as createFablePlanFlow,v as sanitizeFablePacket};
3
+ //# sourceMappingURL=fableFlow.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fableFlow.mjs","names":[],"sources":["../../src/services/fableFlow.ts"],"sourcesContent":["import { Buffer } from 'node:buffer';\n\nexport const FABLE_PROVIDER_SOURCE = '@agimon-ai/doompi-team';\nexport const FABLE_PLAN_REQUESTER = '@agimon-ai/doompi-plan';\nexport const FABLE_PLAN_RUNTIME = 'claude';\nexport const FABLE_PLAN_MODEL = 'fable';\nexport const FABLE_PLAN_PROFILE = 'claude/fable-plan-v1';\nexport const MAX_FABLE_PACKET_BYTES = 32 * 1024;\nexport const MAX_FABLE_TEXT_BYTES = 4 * 1024;\nexport const MAX_FABLE_ARRAY_ITEMS = 24;\n\nconst SECRET_PATTERNS = [\n /(?:api[_-]?key|access[_-]?token|client[_-]?secret|password|private[_-]?key|authorization|bearer)\\s*[:=]/iu,\n /-----BEGIN [A-Z ]*PRIVATE KEY-----/u,\n /\\bsk-[A-Za-z0-9_-]{16,}\\b/u,\n /\\bgh[pousr]_[A-Za-z0-9_]{16,}\\b/u,\n];\nconst CONTROL_CHARACTER_MAX = 31;\nconst DELETE_CHARACTER = 127;\nconst MAX_SOURCE_PATH_LENGTH = 512;\n\nexport interface FablePlanFinding {\n path: string;\n finding: string;\n}\n\nexport interface FablePlanPacket {\n goal: string[];\n constraints: string[];\n decisions: string[];\n verifiedFindings: FablePlanFinding[];\n inferredFindings: string[];\n unresolvedQuestions: string[];\n currentPlan?: string;\n}\n\nexport type FablePlanStatus = 'completed' | 'failed' | 'timed_out' | 'cancelled' | 'interrupted';\nexport type FablePlanStage = 'draft' | 'review' | 'completed' | 'failed' | 'cancelled' | 'interrupted';\n\nexport interface FablePlanResult {\n operationId: string;\n status: FablePlanStatus;\n stage: FablePlanStage;\n draft?: string;\n review?: string;\n draftRunId?: string;\n reviewRunId?: string;\n durationMs: number;\n errorCode?: string;\n}\n\nexport interface FablePlanRequest {\n requester: typeof FABLE_PLAN_REQUESTER;\n operationId: string;\n runtime: typeof FABLE_PLAN_RUNTIME;\n model: typeof FABLE_PLAN_MODEL;\n profile: typeof FABLE_PLAN_PROFILE;\n packet: FablePlanPacket;\n}\n\nexport interface FablePlanBroker {\n start(request: FablePlanRequest, signal: AbortSignal): Promise<FablePlanResult>;\n cancel(operationId: string, reason: string): void;\n}\n\nexport interface FableFlowOptions {\n broker?: FablePlanBroker;\n isAuthorized: () => boolean;\n /** Supplies operation ids. Injected so a test can pin them. */\n newOperationId?: () => string;\n timeoutMs?: number;\n onStage?: (stage: FableStage) => void;\n onError?: (error: unknown) => void;\n}\n\nexport type FableStage = 'idle' | 'draft' | 'review' | 'completed' | 'failed' | 'cancelled' | 'interrupted';\n\nexport interface FablePlanFlow {\n run(value: unknown, signal?: AbortSignal): Promise<FablePlanResult>;\n cancel(reason?: string): void;\n isActive(): boolean;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction hasControlCharacter(value: string): boolean {\n for (const character of value) {\n const code = character.codePointAt(0);\n if (code !== undefined && (code <= CONTROL_CHARACTER_MAX || code === DELETE_CHARACTER)) return true;\n }\n return false;\n}\n\nexport function containsSuspectedCredential(value: string): boolean {\n return SECRET_PATTERNS.some((pattern) => pattern.test(value));\n}\n\nfunction boundedText(value: unknown, field: string, required = true): string {\n if (typeof value !== 'string') throw new Error(`${field} must be a string.`);\n const text = value.trim();\n if (!text && required) throw new Error(`${field} must not be empty.`);\n if (Buffer.byteLength(text, 'utf8') > MAX_FABLE_TEXT_BYTES || hasControlCharacter(text)) {\n throw new Error(`${field} exceeds the bounded Fable text limit or contains control characters.`);\n }\n if (containsSuspectedCredential(text)) throw new Error(`${field} appears to contain a credential.`);\n return text;\n}\n\nfunction boundedList(value: unknown, field: string, required = true): string[] {\n if (!Array.isArray(value)) throw new Error(`${field} must be an array.`);\n if (value.length > MAX_FABLE_ARRAY_ITEMS) throw new Error(`${field} exceeds the bounded item limit.`);\n const items = value.map((item, index) => boundedText(item, `${field}[${index}]`));\n if (required && items.length === 0) throw new Error(`${field} must contain at least one item.`);\n return items;\n}\n\nfunction boundedPath(value: unknown, field: string): string {\n if (typeof value !== 'string') throw new Error(`${field} must be a string.`);\n const sourcePath = value.trim();\n if (!sourcePath || sourcePath.length > MAX_SOURCE_PATH_LENGTH || hasControlCharacter(sourcePath)) {\n throw new Error(`${field} is not a safe source path.`);\n }\n if (containsSuspectedCredential(sourcePath)) throw new Error(`${field} appears to contain a credential.`);\n return sourcePath;\n}\n\nfunction boundedFindings(value: unknown): FablePlanFinding[] {\n if (!Array.isArray(value)) throw new Error('verifiedFindings must be an array.');\n if (value.length > MAX_FABLE_ARRAY_ITEMS) throw new Error('verifiedFindings exceeds the bounded item limit.');\n return value.map((item, index) => {\n if (!isRecord(item)) throw new Error(`verifiedFindings[${index}] must be an object.`);\n const keys = Object.keys(item);\n if (keys.some((key) => key !== 'path' && key !== 'finding')) {\n throw new Error(`verifiedFindings[${index}] contains an unsupported field.`);\n }\n return {\n path: boundedPath(item.path, `verifiedFindings[${index}].path`),\n finding: boundedText(item.finding, `verifiedFindings[${index}].finding`),\n };\n });\n}\n\nfunction assertAllowedKeys(value: Record<string, unknown>, keys: readonly string[], field: string): void {\n const allowed = new Set(keys);\n const unexpected = Object.keys(value).find((key) => !allowed.has(key));\n if (unexpected) throw new Error(`${field} contains unsupported field '${unexpected}'.`);\n}\n\nexport function sanitizeFablePacket(value: unknown): FablePlanPacket {\n if (!isRecord(value)) throw new Error('Fable packet must be an object.');\n assertAllowedKeys(\n value,\n ['goal', 'constraints', 'decisions', 'verifiedFindings', 'inferredFindings', 'unresolvedQuestions', 'currentPlan'],\n 'Fable packet',\n );\n const packet: FablePlanPacket = {\n goal: boundedList(value.goal, 'goal'),\n constraints: boundedList(value.constraints, 'constraints', false),\n decisions: boundedList(value.decisions, 'decisions', false),\n verifiedFindings: boundedFindings(value.verifiedFindings),\n inferredFindings: boundedList(value.inferredFindings, 'inferredFindings', false),\n unresolvedQuestions: boundedList(value.unresolvedQuestions, 'unresolvedQuestions', false),\n ...(value.currentPlan === undefined ? {} : { currentPlan: boundedText(value.currentPlan, 'currentPlan', false) }),\n };\n if (Buffer.byteLength(JSON.stringify(packet), 'utf8') > MAX_FABLE_PACKET_BYTES) {\n throw new Error('Fable packet exceeds the bounded packet size.');\n }\n return packet;\n}\n\nfunction safeResult(result: FablePlanResult): FablePlanResult {\n const output = [result.draft, result.review].filter((value): value is string => value !== undefined).join('\\n');\n if (containsSuspectedCredential(output)) {\n return {\n operationId: result.operationId,\n status: 'failed',\n stage: 'failed',\n durationMs: result.durationMs,\n errorCode: 'unsafe_output',\n };\n }\n return result;\n}\n\nfunction timedOutResult(operationId: string, startedAt: number): FablePlanResult {\n return {\n operationId,\n status: 'timed_out',\n stage: 'interrupted',\n durationMs: Math.max(0, Date.now() - startedAt),\n errorCode: 'timeout',\n };\n}\n\nexport function createFablePlanFlow(options: FableFlowOptions): FablePlanFlow {\n const newOperationId = options.newOperationId ?? (() => crypto.randomUUID());\n let active:\n | {\n operationId: string;\n controller: AbortController;\n cancelSent: boolean;\n }\n | undefined;\n\n const cancel = (reason = 'Fable operation cancelled.'): void => {\n const current = active;\n if (!current) return;\n if (!current.cancelSent) {\n current.cancelSent = true;\n try {\n options.broker?.cancel(current.operationId, reason);\n } catch (error) {\n options.onError?.(error);\n }\n }\n current.controller.abort(new Error(reason));\n };\n\n const run = async (value: unknown, signal?: AbortSignal): Promise<FablePlanResult> => {\n if (active) throw new Error('A Fable operation is already active for this session.');\n if (!options.isAuthorized()) throw new Error('The Fable capability profile is not authorized.');\n const packet = sanitizeFablePacket(value);\n const operationId = `fable-${newOperationId()}`;\n const startedAt = Date.now();\n const controller = new AbortController();\n active = { operationId, controller, cancelSent: false };\n options.onStage?.('draft');\n\n const parentAbort = (): void => controller.abort(signal?.reason);\n if (signal) {\n signal.addEventListener('abort', parentAbort, { once: true });\n if (signal.aborted) parentAbort();\n }\n\n const brokerRequest: FablePlanRequest = {\n requester: FABLE_PLAN_REQUESTER,\n operationId,\n runtime: FABLE_PLAN_RUNTIME,\n model: FABLE_PLAN_MODEL,\n profile: FABLE_PLAN_PROFILE,\n packet,\n };\n let timeout: ReturnType<typeof setTimeout> | undefined;\n let timeoutTriggered = false;\n try {\n if (!options.broker) return timedOutResult(operationId, startedAt);\n const brokerResult = options.broker.start(brokerRequest, controller.signal);\n const cancelledResult = new Promise<FablePlanResult>((resolve) => {\n const onAbort = (): void => {\n if (timeoutTriggered) return;\n resolve({\n operationId,\n status: 'cancelled',\n stage: 'cancelled',\n durationMs: Math.max(0, Date.now() - startedAt),\n errorCode: 'cancelled',\n });\n };\n controller.signal.addEventListener('abort', onAbort, { once: true });\n });\n const timeoutResult =\n options.timeoutMs === undefined\n ? undefined\n : new Promise<FablePlanResult>((resolve) => {\n timeout = setTimeout(() => {\n timeoutTriggered = true;\n cancel('Fable operation timed out.');\n resolve(timedOutResult(operationId, startedAt));\n }, options.timeoutMs);\n });\n const result =\n timeoutResult === undefined\n ? await Promise.race([brokerResult, cancelledResult])\n : await Promise.race([brokerResult, timeoutResult, cancelledResult]);\n const safe = safeResult(result);\n options.onStage?.(\n safe.status === 'completed' ? 'completed' : safe.status === 'cancelled' ? 'cancelled' : safe.stage,\n );\n return safe;\n } catch (error) {\n options.onError?.(error);\n const failure: FablePlanResult = {\n operationId,\n status: 'failed',\n stage: 'failed',\n durationMs: Math.max(0, Date.now() - startedAt),\n errorCode: 'unavailable',\n };\n options.onStage?.('failed');\n return failure;\n } finally {\n if (timeout) clearTimeout(timeout);\n if (signal) signal.removeEventListener('abort', parentAbort);\n active = undefined;\n }\n };\n\n return {\n run,\n cancel,\n isActive: () => active !== undefined,\n };\n}\n"],"mappings":"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"}