@wrongstack/core 0.282.0 → 0.282.1

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 (84) hide show
  1. package/README.md +1 -1
  2. package/dist/{agent-subagent-runner-Dksf0QVU.d.ts → agent-subagent-runner-DCczSoQj.d.ts} +6 -6
  3. package/dist/{config-BCAEJicb.d.ts → config-DkCbA3Bw.d.ts} +22 -0
  4. package/dist/coordination/index.d.ts +15 -15
  5. package/dist/coordination/index.js +802 -139
  6. package/dist/coordination/index.js.map +1 -1
  7. package/dist/{default-config-azFprTB3.d.ts → default-config-Buho8yge.d.ts} +1 -0
  8. package/dist/defaults/index.d.ts +18 -18
  9. package/dist/defaults/index.js +811 -119
  10. package/dist/defaults/index.js.map +1 -1
  11. package/dist/{events-CovDylaH.d.ts → events-BOv8h6I1.d.ts} +1 -1
  12. package/dist/execution/index.d.ts +9 -9
  13. package/dist/execution/index.js +8 -1
  14. package/dist/execution/index.js.map +1 -1
  15. package/dist/extension/index.d.ts +4 -4
  16. package/dist/{global-mailbox-CNfgvRw3.d.ts → global-mailbox-MDDFhLYh.d.ts} +1 -1
  17. package/dist/{goal-store-CBd749M4.d.ts → goal-store-BEmDmSKF.d.ts} +1 -1
  18. package/dist/hq/index.d.ts +4 -4
  19. package/dist/{index-D5HB7WkV.d.ts → index-Dd-PJJ8A.d.ts} +3 -3
  20. package/dist/index.d.ts +209 -30
  21. package/dist/index.js +29562 -28136
  22. package/dist/index.js.map +1 -1
  23. package/dist/infrastructure/index.d.ts +3 -3
  24. package/dist/infrastructure/index.js +8 -0
  25. package/dist/infrastructure/index.js.map +1 -1
  26. package/dist/kernel/index.d.ts +7 -7
  27. package/dist/kernel/index.js.map +1 -1
  28. package/dist/{mcp-servers-DJYwZXyH.d.ts → mcp-servers-BUx9A_AQ.d.ts} +1 -1
  29. package/dist/models/index.d.ts +4 -4
  30. package/dist/models/index.js +18 -20
  31. package/dist/models/index.js.map +1 -1
  32. package/dist/{multi-agent-coordinator-4DC31QWu.d.ts → multi-agent-coordinator-BRqtpn-a.d.ts} +1 -1
  33. package/dist/{null-fleet-bus-DuvA8PIR.d.ts → null-fleet-bus-BkptvIVo.d.ts} +7 -6
  34. package/dist/observability/index.d.ts +1 -1
  35. package/dist/{parallel-eternal-engine-BwcA0bAt.d.ts → parallel-eternal-engine-BXECuOVG.d.ts} +4 -4
  36. package/dist/{pipeline-DM-CPTUs.d.ts → pipeline-ixSFe5jg.d.ts} +2 -2
  37. package/dist/{provider-model-resolve-hNUbewMd.d.ts → provider-model-resolve-DIxKL_T-.d.ts} +1 -1
  38. package/dist/{provider-runner-Bz4GyUqo.d.ts → provider-runner-CJtCs1Rw.d.ts} +1 -1
  39. package/dist/sdd/index.d.ts +7 -7
  40. package/dist/sdd/index.js.map +1 -1
  41. package/dist/security/index.js +6 -0
  42. package/dist/security/index.js.map +1 -1
  43. package/dist/storage/index.d.ts +9 -9
  44. package/dist/storage/index.js +10 -1
  45. package/dist/storage/index.js.map +1 -1
  46. package/dist/{task-format-vGOIftmK.d.ts → task-format-GX0B1mMC.d.ts} +1 -1
  47. package/dist/{task-graph-u1q9Jkyk.d.ts → task-graph-CH3acNQ7.d.ts} +10 -1
  48. package/dist/{todos-checkpoint-addCdQ9f.d.ts → todos-checkpoint-Bw83WMh9.d.ts} +2 -2
  49. package/dist/{tool-executor-B3spV_Q6.d.ts → tool-executor-4mWN2vHW.d.ts} +7 -7
  50. package/dist/tools/index.d.ts +1 -1
  51. package/dist/tools/index.js +8 -0
  52. package/dist/tools/index.js.map +1 -1
  53. package/dist/types/index.d.ts +12 -12
  54. package/dist/types/index.js +22 -1
  55. package/dist/types/index.js.map +1 -1
  56. package/dist/utils/index.d.ts +5 -5
  57. package/dist/utils/index.js.map +1 -1
  58. package/dist/{worktree-manager-BBXdJq-Y.d.ts → worktree-manager-BrtjUFYk.d.ts} +1 -1
  59. package/instructions/leader-after-task.md +4 -4
  60. package/instructions/system.md +11 -0
  61. package/package.json +1 -1
  62. package/skills/api-design/SKILL.md +1 -1
  63. package/skills/audit-log/SKILL.md +3 -3
  64. package/skills/bug-hunter/SKILL.md +3 -3
  65. package/skills/chimera/SKILL.md +3 -3
  66. package/skills/docker-deploy/SKILL.md +1 -1
  67. package/skills/git-flow/SKILL.md +3 -3
  68. package/skills/mailbox-bridge/SKILL.md +1 -1
  69. package/skills/multi-agent/SKILL.md +3 -3
  70. package/skills/node-modern/SKILL.md +1 -1
  71. package/skills/observability/SKILL.md +1 -1
  72. package/skills/output-standards/SKILL.md +31 -30
  73. package/skills/output-standards/SKILL.save.md +5 -5
  74. package/skills/plugin-author/SKILL.md +1 -1
  75. package/skills/prompt-engineering/SKILL.md +1 -1
  76. package/skills/react-modern/SKILL.md +1 -1
  77. package/skills/refactor-planner/SKILL.md +3 -3
  78. package/skills/research-web/SKILL.md +1 -1
  79. package/skills/sdd/SKILL.md +1 -1
  80. package/skills/security-scanner/SKILL.md +3 -3
  81. package/skills/skill-creator/SKILL.md +1 -1
  82. package/skills/tech-stack/SKILL.md +3 -3
  83. package/skills/testing/SKILL.md +1 -1
  84. package/skills/typescript-strict/SKILL.md +1 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/types/blocks.ts","../../src/types/tool.ts","../../src/types/tool-markers.ts","../../src/utils/error.ts","../../src/utils/expect-defined.ts","../../src/utils/regex-guard.ts","../../src/utils/session-scoped-path.ts","../../src/utils/string.ts","../../src/types/errors.ts","../../src/types/provider.ts","../../src/types/config.ts","../../src/types/default-config.ts","../../src/types/memory.ts","../../src/types/prompt.ts","../../src/types/prompt-registry.ts","../../src/types/design-kit.ts","../../src/types/mode-prompts.ts","../../src/types/mode.ts","../../src/types/context-window.ts","../../src/types/spec.ts","../../src/types/task-graph.ts","../../src/storage/session-reader.ts"],"names":["ToolErrorCategory","path","stat"],"mappings":";;;;;;AA2EO,SAAS,YAAY,CAAA,EAAiC;AAC3D,EAAA,OAAO,EAAE,IAAA,KAAS,MAAA;AACpB;AACO,SAAS,eAAe,CAAA,EAAoC;AACjE,EAAA,OAAO,EAAE,IAAA,KAAS,UAAA;AACpB;AACO,SAAS,kBAAkB,CAAA,EAAuC;AACvE,EAAA,OAAO,EAAE,IAAA,KAAS,aAAA;AACpB;AACO,SAAS,aAAa,CAAA,EAAkC;AAC7D,EAAA,OAAO,EAAE,IAAA,KAAS,OAAA;AACpB;;;ACsKO,IAAK,iBAAA,qBAAAA,kBAAAA,KAAL;AACL,EAAAA,mBAAA,WAAA,CAAA,GAAY,WAAA;AACZ,EAAAA,mBAAA,WAAA,CAAA,GAAY,WAAA;AACZ,EAAAA,mBAAA,YAAA,CAAA,GAAa,YAAA;AACb,EAAAA,mBAAA,YAAA,CAAA,GAAa,YAAA;AACb,EAAAA,mBAAA,OAAA,CAAA,GAAQ,OAAA;AALE,EAAA,OAAAA,kBAAAA;AAAA,CAAA,EAAA,iBAAA,IAAA,EAAA;;;ACvOL,IAAM,qBAAA,GAAwB,CAAC,OAAA,EAAS,iBAAA,EAAmB,MAAM;;;ACjBjE,SAAS,eAAe,GAAA,EAAsB;AACnD,EAAA,OAAO,GAAA,YAAe,KAAA,GAAQ,GAAA,CAAI,OAAA,GAAU,OAAO,GAAG,CAAA;AACxD;;;ACFO,SAAS,aAAA,CAAiB,OAA6B,KAAA,EAAmB;AAC/E,EAAA,IAAI,KAAA,KAAU,IAAA,IAAQ,KAAA,KAAU,MAAA,EAAW;AACzC,IAAA,MAAM,MAAM,IAAI,KAAA,CAAkD,8BAA8B,CAAA;AAChG,IAAA,GAAA,CAAI,IAAA,GAAO,oBAAA;AACX,IAAA,MAAM,GAAA;AAAA,EACR;AACA,EAAA,OAAO,KAAA;AACT;;;ACCA,IAAM,eAAA,GAAkB,GAAA;AAGxB,IAAM,kBAAA,GAA4C;AAAA,EAChD,0BAAA;AAAA;AAAA,EACA;AAAA;AACF,CAAA;AAYO,SAAS,gBAAA,CAAiB,SAAiB,KAAA,EAA4C;AAC5F,EAAA,IAAI,OAAO,YAAY,QAAA,EAAU;AAC/B,IAAA,OAAO,EAAE,EAAA,EAAI,KAAA,EAAO,MAAA,EAAQ,0BAAA,EAA2B;AAAA,EACzD;AACA,EAAA,IAAI,OAAA,CAAQ,WAAW,CAAA,EAAG;AACxB,IAAA,OAAO,EAAE,EAAA,EAAI,KAAA,EAAO,MAAA,EAAQ,kBAAA,EAAmB;AAAA,EACjD;AACA,EAAA,IAAI,OAAA,CAAQ,SAAS,eAAA,EAAiB;AACpC,IAAA,OAAO,EAAE,EAAA,EAAI,KAAA,EAAO,MAAA,EAAQ,CAAA,gBAAA,EAAmB,eAAe,CAAA,WAAA,CAAA,EAAc;AAAA,EAC9E;AACA,EAAA,KAAA,MAAW,MAAM,kBAAA,EAAoB;AACnC,IAAA,IAAI,EAAA,CAAG,IAAA,CAAK,OAAO,CAAA,EAAG;AACpB,MAAA,OAAO;AAAA,QACL,EAAA,EAAI,KAAA;AAAA,QACJ,MAAA,EACE;AAAA,OACJ;AAAA,IACF;AAAA,EACF;AACA,EAAA,IAAI;AACF,IAAA,OAAO,EAAE,IAAI,IAAA,EAAM,KAAA,EAAO,IAAI,MAAA,CAAO,OAAA,EAAS,KAAK,CAAA,EAAE;AAAA,EACvD,SAAS,GAAA,EAAK;AACZ,IAAA,OAAO;AAAA,MACL,EAAA,EAAI,KAAA;AAAA,MACJ,MAAA,EAAQ,GAAA,YAAe,KAAA,GAAQ,GAAA,CAAI,OAAA,GAAU;AAAA,KAC/C;AAAA,EACF;AACF;AC3CO,SAAS,iBAAA,CAAkB,GAAA,EAAa,SAAA,EAAmB,MAAA,EAAwB;AACxF,EAAA,IAAI,CAAC,aAAa,SAAA,CAAU,QAAA,CAAS,IAAI,CAAA,IAAK,SAAA,CAAU,QAAA,CAAS,IAAI,CAAA,EAAG;AACtE,IAAA,MAAM,QAAQ,SAAS,CAAA;AAAA,EACzB;AACA,EAAA,MAAM,WAAgBC,KAAA,CAAA,OAAA,CAAQ,GAAA,EAAK,GAAG,SAAS,CAAA,EAAG,MAAM,CAAA,CAAE,CAAA;AAC1D,EAAA,MAAM,GAAA,GAAWA,KAAA,CAAA,QAAA,CAAcA,KAAA,CAAA,OAAA,CAAQ,GAAG,GAAG,QAAQ,CAAA;AACrD,EAAA,IAAI,IAAI,UAAA,CAAW,IAAI,CAAA,IAAUA,KAAA,CAAA,UAAA,CAAW,GAAG,CAAA,EAAG;AAChD,IAAA,MAAM,QAAQ,SAAS,CAAA;AAAA,EACzB;AACA,EAAA,OAAO,QAAA;AACT;AAEA,SAAS,QAAQ,SAAA,EAA4B;AAC3C,EAAA,OAAO,IAAI,OAAA,CAAQ;AAAA,IACjB,OAAA,EAAS,sBAAsB,SAAS,CAAA,CAAA;AAAA,IACxC,MAAM,WAAA,CAAY,gBAAA;AAAA,IAClB,IAAA,EAAM,SAAA;AAAA,IACN,OAAA,EAAS,EAAE,MAAA,EAAQ,gBAAA;AAAiB,GACrC,CAAA;AACH;;;ACzBO,SAAS,QAAA,CAAS,GAAW,GAAA,EAAqB;AACvD,EAAA,OAAO,CAAA,CAAE,MAAA,IAAU,GAAA,GAAM,CAAA,GAAI,CAAA,EAAG,EAAE,KAAA,CAAM,CAAA,EAAG,GAAA,GAAM,CAAC,CAAC,CAAA,MAAA,CAAA;AACrD;;;ACcO,IAAM,WAAA,GAAc;AAAA;AAAA,EAEzB,qBAAA,EAAuB,uBAAA;AAAA,EACvB,oBAAA,EAAsB,sBAAA;AAAA,EACtB,mBAAA,EAAqB,qBAAA;AAAA,EACrB,wBAAA,EAA0B,0BAAA;AAAA,EAC1B,qBAAA,EAAuB,uBAAA;AAAA,EACvB,sBAAA,EAAwB,wBAAA;AAAA,EACxB,yBAAA,EAA2B,2BAAA;AAAA;AAAA,EAE3B,cAAA,EAAgB,gBAAA;AAAA,EAChB,sBAAA,EAAwB,wBAAA;AAAA,EACxB,qBAAA,EAAuB,uBAAA;AAAA,EACvB,YAAA,EAAc,cAAA;AAAA,EACd,kBAAA,EAAoB,oBAAA;AAAA;AAAA,EAEpB,cAAA,EAAgB,gBAAA;AAAA,EAChB,gBAAA,EAAkB,kBAAA;AAAA,EAClB,mBAAA,EAAqB,qBAAA;AAAA,EACrB,uBAAA,EAAyB,yBAAA;AAAA;AAAA,EAEzB,kBAAA,EAAoB,oBAAA;AAAA,EACpB,mBAAA,EAAqB,qBAAA;AAAA,EACrB,yBAAA,EAA2B,2BAAA;AAAA;AAAA,EAE3B,qBAAA,EAAuB,uBAAA;AAAA,EACvB,sBAAA,EAAwB,wBAAA;AAAA,EACxB,aAAA,EAAe,eAAA;AAAA,EACf,gBAAA,EAAkB,kBAAA;AAAA;AAAA,EAElB,iBAAA,EAAmB,mBAAA;AAAA,EACnB,iBAAA,EAAmB,mBAAA;AAAA,EACnB,oBAAA,EAAsB,sBAAA;AAAA;AAAA,EAEtB,6BAAA,EAA+B,+BAAA;AAAA,EAC/B,yBAAA,EAA2B,2BAAA;AAAA,EAC3B,6BAAA,EAA+B,+BAAA;AAAA,EAC/B,kBAAA,EAAoB,oBAAA;AAAA,EACpB,kBAAA,EAAoB,oBAAA;AAAA,EACpB,gBAAA,EAAkB,kBAAA;AAAA;AAAA,EAElB,cAAA,EAAgB,gBAAA;AAAA,EAChB,eAAA,EAAiB,iBAAA;AAAA,EACjB,eAAA,EAAiB,iBAAA;AAAA,EACjB,gBAAA,EAAkB,kBAAA;AAAA,EAClB,sBAAA,EAAwB,wBAAA;AAAA;AAAA,EAExB,qBAAA,EAAuB,uBAAA;AAAA,EACvB,gBAAA,EAAkB,kBAAA;AAAA,EAClB,iBAAA,EAAmB,mBAAA;AAAA,EACnB,aAAA,EAAe,eAAA;AAAA;AAAA,EAEf,gBAAA,EAAkB,kBAAA;AAAA,EAClB,YAAA,EAAc,cAAA;AAAA,EACd,OAAA,EAAS;AACX;AAwBO,IAAM,eAAA,GAAN,cAA8B,KAAA,CAAM;AAAA,EAChC,IAAA;AAAA,EACA,SAAA;AAAA,EACA,QAAA;AAAA,EACA,WAAA;AAAA,EACA,OAAA;AAAA,EAET,YAAY,IAAA,EAQT;AACD,IAAA,KAAA,CAAM,KAAK,OAAA,EAAS,EAAE,KAAA,EAAO,IAAA,CAAK,OAAO,CAAA;AACzC,IAAA,IAAA,CAAK,IAAA,GAAO,iBAAA;AACZ,IAAA,IAAA,CAAK,OAAO,IAAA,CAAK,IAAA;AACjB,IAAA,IAAA,CAAK,YAAY,IAAA,CAAK,SAAA;AACtB,IAAA,IAAA,CAAK,QAAA,GAAW,KAAK,QAAA,IAAY,OAAA;AACjC,IAAA,IAAA,CAAK,WAAA,GAAc,KAAK,WAAA,IAAe,KAAA;AACvC,IAAA,IAAA,CAAK,UAAU,IAAA,CAAK,OAAA;AAAA,EACtB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,QAAA,GAAmB;AACjB,IAAA,MAAM,GAAA,GAAM,KAAK,OAAA,GAAU,CAAA,CAAA,EAAI,cAAc,IAAA,CAAK,OAAO,CAAC,CAAA,CAAA,GAAK,EAAA;AAC/D,IAAA,OAAO,GAAG,IAAA,CAAK,IAAI,KAAK,IAAA,CAAK,OAAO,GAAG,GAAG,CAAA,CAAA;AAAA,EAC5C;AACF;AAEA,SAAS,cAAc,GAAA,EAAsC;AAC3D,EAAA,MAAM,KAAA,GAAQ,MAAA,CAAO,OAAA,CAAQ,GAAG,CAAA,CAC7B,MAAA,CAAO,CAAC,GAAG,CAAC,CAAA,KAAM,CAAA,KAAM,MAAS,CAAA,CACjC,KAAA,CAAM,CAAA,EAAG,CAAC,CAAA,CACV,GAAA,CAAI,CAAC,CAAC,CAAA,EAAG,CAAC,CAAA,KAAM,CAAA,EAAG,CAAC,CAAA,CAAA,EAAI,MAAA,CAAO,CAAC,CAAC,CAAA,CAAE,CAAA;AACtC,EAAA,OAAO,KAAA,CAAM,SAAS,CAAA,GAAI,CAAA,CAAA,EAAI,MAAM,IAAA,CAAK,GAAG,CAAC,CAAA,CAAA,CAAA,GAAM,EAAA;AACrD;AAOO,IAAM,SAAA,GAAN,cAAwB,eAAA,CAAgB;AAAA,EACpC,QAAA;AAAA,EAET,YAAY,IAAA,EAcT;AACD,IAAA,KAAA,CAAM;AAAA,MACJ,SAAS,IAAA,CAAK,OAAA;AAAA,MACd,MAAM,IAAA,CAAK,IAAA;AAAA,MACX,SAAA,EAAW,MAAA;AAAA,MACX,aAAa,IAAA,CAAK,WAAA;AAAA,MAClB,SAAS,EAAE,IAAA,EAAM,KAAK,QAAA,EAAU,GAAG,KAAK,OAAA,EAAQ;AAAA,MAChD,OAAO,IAAA,CAAK;AAAA,KACb,CAAA;AACD,IAAA,IAAA,CAAK,IAAA,GAAO,WAAA;AACZ,IAAA,IAAA,CAAK,WAAW,IAAA,CAAK,QAAA;AAAA,EACvB;AACF;AAKO,IAAM,WAAA,GAAN,cAA0B,eAAA,CAAgB;AAAA,EAC/C,YAAY,IAAA,EAQT;AACD,IAAA,KAAA,CAAM;AAAA,MACJ,SAAS,IAAA,CAAK,OAAA;AAAA,MACd,MAAM,IAAA,CAAK,IAAA;AAAA,MACX,SAAA,EAAW,QAAA;AAAA,MACX,QAAA,EAAU,OAAA;AAAA,MACV,WAAA,EAAa,KAAA;AAAA,MACb,SAAS,IAAA,CAAK,OAAA;AAAA,MACd,OAAO,IAAA,CAAK;AAAA,KACb,CAAA;AACD,IAAA,IAAA,CAAK,IAAA,GAAO,aAAA;AAAA,EACd;AACF;AAKO,IAAM,WAAA,GAAN,cAA0B,eAAA,CAAgB;AAAA,EACtC,UAAA;AAAA,EAET,YAAY,IAAA,EAST;AACD,IAAA,KAAA,CAAM;AAAA,MACJ,SAAS,IAAA,CAAK,OAAA;AAAA,MACd,MAAM,IAAA,CAAK,IAAA;AAAA,MACX,SAAA,EAAW,QAAA;AAAA,MACX,QAAA,EAAU,OAAA;AAAA,MACV,WAAA,EAAa,IAAA,CAAK,IAAA,KAAS,WAAA,CAAY,yBAAA;AAAA,MACvC,SAAS,EAAE,MAAA,EAAQ,KAAK,UAAA,EAAY,GAAG,KAAK,OAAA,EAAQ;AAAA,MACpD,OAAO,IAAA,CAAK;AAAA,KACb,CAAA;AACD,IAAA,IAAA,CAAK,IAAA,GAAO,aAAA;AACZ,IAAA,IAAA,CAAK,aAAa,IAAA,CAAK,UAAA;AAAA,EACzB;AACF;AAMO,IAAM,UAAA,GAAN,cAAyB,eAAA,CAAgB;AAAA,EAC9C,YAAY,IAAA,EAST;AACD,IAAA,KAAA,CAAM;AAAA,MACJ,SAAS,IAAA,CAAK,OAAA;AAAA,MACd,MAAM,IAAA,CAAK,IAAA;AAAA,MACX,SAAA,EAAW,OAAA;AAAA,MACX,QAAA,EAAU,IAAA,CAAK,IAAA,KAAS,WAAA,CAAY,gBAAgB,SAAA,GAAY,OAAA;AAAA,MAChE,WAAA,EAAa,IAAA,CAAK,WAAA,IAAe,IAAA,CAAK,SAAS,WAAA,CAAY,qBAAA;AAAA,MAC3D,SAAS,IAAA,CAAK,OAAA;AAAA,MACd,OAAO,IAAA,CAAK;AAAA,KACb,CAAA;AACD,IAAA,IAAA,CAAK,IAAA,GAAO,YAAA;AAAA,EACd;AACF;AAQO,SAAS,iBAAA,CACd,GAAA,EACA,IAAA,GAA6E,WAAA,CAAY,gBAAA,EACxE;AACjB,EAAA,IAAI,GAAA,YAAe,iBAAiB,OAAO,GAAA;AAC3C,EAAA,MAAM,OAAA,GAAU,eAAe,GAAG,CAAA;AAClC,EAAA,OAAO,IAAI,UAAA,CAAW;AAAA,IACpB,OAAA;AAAA,IACA,IAAA,EAAM,IAAA,KAAS,SAAA,GAAY,WAAA,CAAY,gBAAA,GAAmB,IAAA;AAAA,IAC1D,KAAA,EAAO;AAAA,GACR,CAAA;AACH;AAKO,IAAM,YAAA,GAAN,cAA2B,eAAA,CAAgB;AAAA,EACvC,SAAA;AAAA,EAET,YAAY,IAAA,EAMT;AACD,IAAA,KAAA,CAAM;AAAA,MACJ,SAAS,IAAA,CAAK,OAAA;AAAA,MACd,MAAM,IAAA,CAAK,IAAA;AAAA,MACX,SAAA,EAAW,SAAA;AAAA,MACX,QAAA,EAAU,IAAA,CAAK,IAAA,KAAS,WAAA,CAAY,uBAAuB,OAAA,GAAU,SAAA;AAAA,MACrE,WAAA,EAAa,IAAA,CAAK,IAAA,KAAS,WAAA,CAAY,iBAAA;AAAA,MACvC,SAAS,EAAE,SAAA,EAAW,KAAK,SAAA,EAAW,GAAG,KAAK,OAAA,EAAQ;AAAA,MACtD,OAAO,IAAA,CAAK;AAAA,KACb,CAAA;AACD,IAAA,IAAA,CAAK,IAAA,GAAO,cAAA;AACZ,IAAA,IAAA,CAAK,YAAY,IAAA,CAAK,SAAA;AAAA,EACxB;AACF;AAMO,IAAM,QAAA,GAAN,cAAuB,eAAA,CAAgB;AAAA,EAC5C,YAAY,IAAA,EAQT;AACD,IAAA,KAAA,CAAM;AAAA,MACJ,SAAS,IAAA,CAAK,OAAA;AAAA,MACd,MAAM,IAAA,CAAK,IAAA;AAAA,MACX,SAAA,EAAW,KAAA;AAAA,MACX,QAAA,EAAU,IAAA,CAAK,IAAA,KAAS,WAAA,CAAY,mBAAmB,SAAA,GAAY,OAAA;AAAA,MACnE,WAAA,EAAa,IAAA,CAAK,IAAA,KAAS,WAAA,CAAY,aAAA;AAAA,MACvC,SAAS,IAAA,CAAK,OAAA;AAAA,MACd,OAAO,IAAA,CAAK;AAAA,KACb,CAAA;AACD,IAAA,IAAA,CAAK,IAAA,GAAO,UAAA;AAAA,EACd;AACF;AAKO,IAAM,OAAA,GAAN,cAAsB,eAAA,CAAgB;AAAA,EAClC,IAAA;AAAA,EAET,YAAY,IAAA,EAST;AACD,IAAA,KAAA,CAAM;AAAA,MACJ,SAAS,IAAA,CAAK,OAAA;AAAA,MACd,MAAM,IAAA,CAAK,IAAA;AAAA,MACX,SAAA,EAAW,IAAA;AAAA,MACX,QAAA,EAAU,OAAA;AAAA,MACV,WAAA,EAAa,IAAA,CAAK,IAAA,KAAS,WAAA,CAAY,cAAA;AAAA,MACvC,SAAS,EAAE,IAAA,EAAM,KAAK,IAAA,EAAM,GAAG,KAAK,OAAA,EAAQ;AAAA,MAC5C,OAAO,IAAA,CAAK;AAAA,KACb,CAAA;AACD,IAAA,IAAA,CAAK,IAAA,GAAO,SAAA;AACZ,IAAA,IAAA,CAAK,OAAO,IAAA,CAAK,IAAA;AAAA,EACnB;AACF;AAgBO,IAAM,UAAA,GAAN,cAAyB,eAAA,CAAgB;AAAA,EACrC,MAAA;AAAA,EAET,YAAY,IAAA,EAKT;AACD,IAAA,KAAA,CAAM;AAAA,MACJ,SAAS,IAAA,CAAK,OAAA;AAAA,MACd,MAAM,WAAA,CAAY,gBAAA;AAAA,MAClB,SAAA,EAAW,SAAA;AAAA,MACX,QAAA,EAAU,OAAA;AAAA,MACV,WAAA,EAAa,IAAA,CAAK,MAAA,KAAW,GAAA,IAAO,KAAK,MAAA,IAAU,GAAA;AAAA,MACnD,SAAS,EAAE,MAAA,EAAQ,KAAK,MAAA,EAAQ,GAAG,KAAK,OAAA,EAAQ;AAAA,MAChD,OAAO,IAAA,CAAK;AAAA,KACb,CAAA;AACD,IAAA,IAAA,CAAK,IAAA,GAAO,YAAA;AACZ,IAAA,IAAA,CAAK,SAAS,IAAA,CAAK,MAAA;AAAA,EACrB;AACF;AAiBO,IAAM,mBAAA,GAAN,cAAkC,eAAA,CAAgB;AAAA,EACvD,YAAY,IAAA,EAMT;AACD,IAAA,KAAA,CAAM;AAAA,MACJ,SAAS,IAAA,CAAK,OAAA;AAAA,MACd,MAAM,WAAA,CAAY,gBAAA;AAAA,MAClB,SAAA,EAAW,SAAA;AAAA,MACX,QAAA,EAAU,OAAA;AAAA,MACV,WAAA,EAAa,KAAA;AAAA,MACb,SAAS,EAAE,KAAA,EAAO,KAAK,KAAA,EAAO,GAAG,KAAK,OAAA,EAAQ;AAAA,MAC9C,OAAO,IAAA,CAAK;AAAA,KACb,CAAA;AACD,IAAA,IAAA,CAAK,IAAA,GAAO,qBAAA;AAAA,EACd;AACF;AAgBO,IAAM,UAAA,GAAN,cAAyB,eAAA,CAAgB;AAAA,EACrC,MAAA;AAAA,EAET,YAAY,IAAA,EAUT;AACD,IAAA,KAAA,CAAM;AAAA,MACJ,SAAS,IAAA,CAAK,OAAA;AAAA,MACd,MAAM,WAAA,CAAY,YAAA;AAAA,MAClB,SAAA,EAAW,SAAA;AAAA,MACX,QAAA,EAAU,OAAA;AAAA,MACV,WAAA,EAAa,KAAA;AAAA,MACb,SAAS,EAAE,MAAA,EAAQ,KAAK,MAAA,EAAQ,GAAG,KAAK,OAAA,EAAQ;AAAA,MAChD,OAAO,IAAA,CAAK;AAAA,KACb,CAAA;AACD,IAAA,IAAA,CAAK,IAAA,GAAO,YAAA;AACZ,IAAA,IAAA,CAAK,SAAS,IAAA,CAAK,MAAA;AAAA,EACrB;AACF;AAIO,SAAS,kBAAkB,GAAA,EAAsC;AACtE,EAAA,OAAO,GAAA,YAAe,eAAA;AACxB;AAEO,SAAS,YAAY,GAAA,EAAgC;AAC1D,EAAA,OAAO,GAAA,YAAe,SAAA;AACxB;AAEO,SAAS,cAAc,GAAA,EAAkC;AAC9D,EAAA,OAAO,GAAA,YAAe,WAAA;AACxB;AAEO,SAAS,cAAc,GAAA,EAAkC;AAC9D,EAAA,OAAO,GAAA,YAAe,WAAA;AACxB;AAEO,SAAS,eAAe,GAAA,EAAmC;AAChE,EAAA,OAAO,GAAA,YAAe,YAAA;AACxB;AAEO,SAAS,aAAa,GAAA,EAAiC;AAC5D,EAAA,OAAO,GAAA,YAAe,UAAA;AACxB;AAEO,SAAS,UAAU,GAAA,EAA8B;AACtD,EAAA,OAAO,GAAA,YAAe,OAAA;AACxB;AAEO,SAAS,sBAAsB,GAAA,EAA0C;AAC9E,EAAA,OAAO,GAAA,YAAe,mBAAA;AACxB;AAEO,SAAS,aAAa,GAAA,EAAiC;AAC5D,EAAA,OAAO,GAAA,YAAe,UAAA;AACxB;AAEO,SAAS,aAAa,GAAA,EAAiC;AAC5D,EAAA,OAAO,GAAA,YAAe,UAAA;AACxB;AAEO,SAAS,WAAW,GAAA,EAA+B;AACxD,EAAA,OAAO,GAAA,YAAe,QAAA;AACxB;;;AC5PO,IAAM,aAAA,GAAN,cAA4B,eAAA,CAAgB;AAAA,EACjC,MAAA;AAAA,EACA,SAAA;AAAA,EACA,UAAA;AAAA,EACA,IAAA;AAAA,EAEhB,YACE,OAAA,EACA,MAAA,EACA,WACA,UAAA,EACA,IAAA,GAA8E,EAAC,EAC/E;AACA,IAAA,KAAA,CAAM;AAAA,MACJ,OAAA;AAAA,MACA,IAAA,EAAM,oBAAA,CAAqB,MAAA,EAAQ,IAAA,CAAK,MAAM,IAAI,CAAA;AAAA,MAClD,SAAA,EAAW,UAAA;AAAA,MACX,QAAA,EAAU,MAAA,IAAU,GAAA,GAAM,OAAA,GAAU,SAAA;AAAA,MACpC,WAAA,EAAa,SAAA;AAAA,MACb,OAAA,EAAS,EAAE,UAAA,EAAY,MAAA,EAAO;AAAA,MAC9B,OAAO,IAAA,CAAK;AAAA,KACb,CAAA;AACD,IAAA,IAAA,CAAK,IAAA,GAAO,eAAA;AACZ,IAAA,IAAA,CAAK,MAAA,GAAS,MAAA;AACd,IAAA,IAAA,CAAK,SAAA,GAAY,SAAA;AACjB,IAAA,IAAA,CAAK,UAAA,GAAa,UAAA;AAClB,IAAA,IAAA,CAAK,OAAO,IAAA,CAAK,IAAA;AAAA,EACnB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcS,QAAA,GAAmB;AAC1B,IAAA,MAAM,OAAO,cAAA,CAAe,IAAA,CAAK,MAAA,EAAQ,IAAA,CAAK,MAAM,IAAI,CAAA;AACxD,IAAA,MAAM,IAAA,GAAO,CAAA,EAAG,IAAA,CAAK,UAAU,IAAI,IAAI,CAAA,CAAA;AACvC,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,IAAA,EAAM,OAAA,EAAS,IAAA,EAAK;AACxC,IAAA,MAAM,KAAA,GAAQ,KAAK,IAAA,EAAM,SAAA,GACrB,SAAS,IAAA,CAAK,IAAA,CAAK,UAAU,KAAA,CAAM,CAAA,EAAG,EAAE,CAAC,CAAA,EAAG,KAAK,IAAA,CAAK,SAAA,CAAU,SAAS,EAAA,GAAK,QAAA,GAAM,EAAE,CAAA,CAAA,CAAA,GACtF,EAAA;AACJ,IAAA,IAAI,MAAA,IAAU,MAAA,CAAO,MAAA,GAAS,CAAA,EAAG;AAC/B,MAAA,OAAO,CAAA,EAAG,IAAI,CAAA,EAAA,EAAK,QAAA,CAAS,QAAQ,GAAG,CAAC,GAAG,KAAK,CAAA,CAAA;AAAA,IAClD;AACA,IAAA,OAAO,CAAA,EAAG,IAAI,CAAA,EAAG,KAAK,CAAA,CAAA;AAAA,EACxB;AACF;AAEA,SAAS,cAAA,CAAe,QAAgB,IAAA,EAAuB;AAC7D,EAAA,IAAI,MAAA,KAAW,GAAG,OAAO,eAAA;AACzB,EAAA,IAAI,SAAS,kBAAA,IAAsB,MAAA,KAAW,GAAA,EAAK,OAAO,eAAe,MAAM,CAAA,CAAA,CAAA;AAC/E,EAAA,IAAI,SAAS,kBAAA,IAAsB,MAAA,KAAW,GAAA,EAAK,OAAO,iBAAiB,MAAM,CAAA,CAAA,CAAA;AACjF,EAAA,IAAI,SAAS,sBAAA,IAA0B,MAAA,KAAW,GAAA,EAAK,OAAO,gBAAgB,MAAM,CAAA,CAAA,CAAA;AACpF,EAAA,IAAI,SAAS,kBAAA,IAAsB,MAAA,KAAW,GAAA,EAAK,OAAO,cAAc,MAAM,CAAA,CAAA,CAAA;AAC9E,EAAA,IAAI,SAAS,iBAAA,IAAqB,MAAA,KAAW,GAAA,EAAK,OAAO,cAAc,MAAM,CAAA,CAAA,CAAA;AAC7E,EAAA,IAAI,SAAS,uBAAA,IAA2B,MAAA,KAAW,GAAA,EAAK,OAAO,oBAAoB,MAAM,CAAA,CAAA,CAAA;AACzF,EAAA,IAAI,MAAA,KAAW,GAAA,EAAK,OAAO,CAAA,SAAA,EAAY,MAAM,CAAA,CAAA,CAAA;AAC7C,EAAA,IAAI,UAAU,GAAA,IAAO,MAAA,GAAS,GAAA,EAAK,OAAO,QAAQ,MAAM,CAAA,eAAA,CAAA;AACxD,EAAA,IAAI,IAAA,EAAM,OAAO,CAAA,EAAG,IAAI,KAAK,MAAM,CAAA,CAAA,CAAA;AACnC,EAAA,OAAO,QAAQ,MAAM,CAAA,CAAA;AACvB;AAYO,IAAM,eAAA,GAAN,cAA8B,aAAA,CAAc;AAAA;AAAA,EAEjC,cAAA;AAAA;AAAA,EAEA,SAAA;AAAA;AAAA,EAEA,aAAA;AAAA;AAAA,EAEA,aAAA;AAAA;AAAA,EAEA,SAAA;AAAA,EAEhB,YAAY,IAAA,EAOT;AACD,IAAA,KAAA;AAAA,MACE,CAAA,aAAA,EAAgB,IAAA,CAAK,UAAU,CAAA,CAAA,EAAI,KAAK,KAAK,CAAA,oBAAA,EAAkB,IAAA,CAAK,aAAa,CAAA,SAAA,EAAY,IAAA,CAAK,aAAa,CAAA,QAAA,EAAW,KAAK,SAAS,CAAA,WAAA,CAAA;AAAA,MACxI,GAAA;AAAA,MACA,IAAA;AAAA;AAAA,MACA,IAAA,CAAK,UAAA;AAAA,MACL;AAAA,QACE,IAAA,EAAM;AAAA,UACJ,SAAS,CAAA,qBAAA,EAAwB,IAAA,CAAK,SAAS,CAAA,IAAA,EAAO,KAAK,aAAa,CAAA,eAAA;AAAA,SAC1E;AAAA,QACA,OAAO,IAAA,CAAK;AAAA;AACd,KACF;AACA,IAAA,IAAA,CAAK,IAAA,GAAO,iBAAA;AACZ,IAAA,IAAA,CAAK,iBAAiB,IAAA,CAAK,UAAA;AAC3B,IAAA,IAAA,CAAK,YAAY,IAAA,CAAK,KAAA;AACtB,IAAA,IAAA,CAAK,gBAAgB,IAAA,CAAK,aAAA;AAC1B,IAAA,IAAA,CAAK,gBAAgB,IAAA,CAAK,aAAA;AAC1B,IAAA,IAAA,CAAK,YAAY,IAAA,CAAK,SAAA;AAAA,EACxB;AACF;AAEA,SAAS,oBAAA,CAAqB,QAAgB,IAAA,EAA0B;AACtE,EAAA,IAAI,MAAA,KAAW,CAAA,EAAG,OAAO,WAAA,CAAY,sBAAA;AACrC,EAAA,IAAI,IAAA,KAAS,kBAAA,IAAsB,MAAA,KAAW,GAAA,SAAY,WAAA,CAAY,qBAAA;AACtE,EAAA,IAAI,IAAA,KAAS,sBAAA,IAA0B,MAAA,KAAW,GAAA,SAAY,WAAA,CAAY,oBAAA;AAC1E,EAAA,IAAI,IAAA,KAAS,kBAAA,IAAsB,MAAA,KAAW,GAAA,SAAY,WAAA,CAAY,mBAAA;AACtE,EAAA,IAAI,IAAA,KAAS,uBAAA,IAA2B,MAAA,KAAW,GAAA,SAAY,WAAA,CAAY,wBAAA;AAC3E,EAAA,IAAI,MAAA,KAAW,GAAA,EAAK,OAAO,WAAA,CAAY,sBAAA;AACvC,EAAA,IAAI,MAAA,IAAU,GAAA,EAAK,OAAO,WAAA,CAAY,qBAAA;AACtC,EAAA,OAAO,WAAA,CAAY,wBAAA;AACrB;;;ACtSO,SAAS,yBAAyB,GAAA,EAAkD;AACzF,EAAA,IAAI,GAAA,KAAQ,QAAW,OAAO,KAAA;AAC9B,EAAA,IAAI,OAAO,GAAA,KAAQ,SAAA,EAAW,OAAO,MAAM,QAAA,GAAW,KAAA;AACtD,EAAA,MAAM,UAAA,uBAAiB,GAAA,CAAqB,CAAC,OAAO,SAAA,EAAW,OAAA,EAAS,QAAA,EAAU,YAAY,CAAC,CAAA;AAC/F,EAAA,OAAO,UAAA,CAAW,GAAA,CAAI,GAAG,CAAA,GAAI,GAAA,GAAM,KAAA;AACrC;AAEO,IAAM,yBAAA,GAA4B;AAClC,IAAM,4BAAA,GAA+B;AAMrC,SAAS,yBAAyB,KAAA,EAAwB;AAC/D,EAAA,IAAI,OAAO,KAAA,KAAU,QAAA,EAAU,OAAO,yBAAA;AACtC,EAAA,MAAM,IAAA,GAAO,MAAM,IAAA,EAAK;AACxB,EAAA,IAAI,IAAA,CAAK,MAAA,KAAW,CAAA,IAAK,IAAA,CAAK,SAAS,4BAAA,EAA8B;AACnE,IAAA,OAAO,yBAAA;AAAA,EACT;AACA,EAAA,IAAI,CAAC,oBAAA,CAAqB,IAAA,CAAK,IAAI,GAAG,OAAO,yBAAA;AAC7C,EAAA,OAAO,IAAA;AACT;;;AC/HO,IAAM,oBAAA,GAAuB,OAAO,MAAA,CAAO;AAAA,EAChD,wBAAA,EAA0B,OAAA;AAAA,EAC1B,aAAA,EAAe,GAAA;AAAA,EACf,kBAAA,EAAoB,GAAA;AAAA,EACpB,gBAAA,EAAkB,IAAA;AAAA,EAClB,0BAAA,EAA4B,GAAA;AAAA,EAC5B,eAAA,EAAiB,MAAA,CAAO,MAAA,CAAO,EAAE,CAAA;AAAA,EACjC,aAAA,EAAe,MAAA,CAAO,MAAA,CAAO,EAAE,CAAA;AAAA,EAC/B,eAAA,EAAiB,IAAA;AAAA,EACjB,qBAAA,EAAuB;AACzB,CAAC;AAGM,IAAM,sBAAA,GAAyB,OAAO,MAAA,CAAO;AAAA,EAClD,SAAA,EAAW,EAAA;AAAA,EACX,cAAA,EAAgB;AAClB,CAAC;AAGM,IAAM,uBAAA,GAA0B,OAAO,MAAA,CAAO;AAAA,EACnD,kBAAA,EAAoB;AACtB,CAAC;AAOM,IAAM,8BAAA,GAAiC,OAAO,MAAA,CAAO;AAAA,EAC1D,OAAA,EAAS,KAAA;AAAA,EACT,eAAA,EAAiB;AACnB,CAAC;AAGM,IAAM,8BAAA,GAAiC,OAAO,MAAA,CAAO;AAAA,EAC1D,UAAA,EAAY,UAAA;AAAA,EACZ,QAAA,EAAU;AAAA,IACR,YAAA,EAAc;AAAA,MACZ,UAAA,EAAY;AAAA;AACd;AAEJ,CAAC;AAGM,IAAM,0BAAA,GAA6B;;;AC5CnC,IAAM,kBAAA,GAAiD;AAAA,EAC5D,IAAA,EAAM,MAAA;AAAA,EACN,QAAA,EAAU,UAAA;AAAA,EACV,UAAA,EAAY,YAAA;AAAA,EACZ,UAAA,EAAY,YAAA;AAAA,EACZ,SAAA,EAAW,WAAA;AAAA,EACX,YAAA,EAAc;AAChB;;;ACGO,IAAM,yBAAA,GAA4B;AAAA,EACvC,QAAA;AAAA,EACA,WAAA;AAAA,EACA,aAAA;AAAA,EACA,SAAA;AAAA,EACA,aAAA;AAAA,EACA,cAAA;AAAA,EACA,QAAA;AAAA,EACA,eAAA;AAAA,EACA,eAAA;AAAA,EACA,SAAA;AAAA,EACA,UAAA;AAAA,EACA,SAAA;AAAA,EACA,mBAAA;AAAA,EACA,gBAAA;AAAA,EACA;AACF;AAOO,IAAM,sBAAA,GAAgE;AAAA,EAC3E,MAAA,EAAQ,QAAA;AAAA,EACR,SAAA,EAAW,WAAA;AAAA,EACX,WAAA,EAAa,aAAA;AAAA,EACb,OAAA,EAAS,SAAA;AAAA,EACT,aAAA,EAAe,aAAA;AAAA,EACf,YAAA,EAAc,cAAA;AAAA,EACd,MAAA,EAAQ,QAAA;AAAA,EACR,aAAA,EAAe,eAAA;AAAA,EACf,eAAA,EAAiB,eAAA;AAAA,EACjB,OAAA,EAAS,SAAA;AAAA,EACT,QAAA,EAAU,UAAA;AAAA,EACV,OAAA,EAAS,SAAA;AAAA,EACT,mBAAA,EAAqB,mBAAA;AAAA,EACrB,gBAAA,EAAkB,gBAAA;AAAA,EAClB,aAAA,EAAe;AACjB;AASO,SAAS,kBAAkB,KAAA,EAA+C;AAC/E,EAAA,OAAQ,yBAAA,CAAgD,SAAS,KAAK,CAAA;AACxE;;;ACPA,IAAM,OAAA,GAAU,4BAAA;AAChB,IAAM,WAAA,GAAc,gBAAA;AACpB,IAAM,OAAA,GAAU,IAAA;AAQT,SAAS,yBAAyB,GAAA,EAAkC;AACzE,EAAA,MAAM,SAAmB,EAAC;AAC1B,EAAA,IAAI,CAAC,GAAA,IAAO,OAAO,GAAA,KAAQ,QAAA,EAAU,OAAO,EAAE,EAAA,EAAI,KAAA,EAAO,MAAA,EAAQ,CAAC,2BAA2B,CAAA,EAAE;AAC/F,EAAA,MAAM,CAAA,GAAI,GAAA;AAEV,EAAA,IAAI,EAAE,iBAAiB,CAAA,KAAM,CAAA,EAAG,MAAA,CAAO,KAAK,2BAA2B,CAAA;AACvE,EAAA,IAAI,OAAO,CAAA,CAAE,QAAQ,MAAM,QAAA,IAAY,CAAC,EAAE,QAAQ,CAAA;AAChD,IAAA,MAAA,CAAO,KAAK,mCAAmC,CAAA;AACjD,EAAA,IAAI,OAAO,CAAA,CAAE,aAAa,MAAM,QAAA,EAAU,MAAA,CAAO,KAAK,8BAA8B,CAAA;AACpF,EAAA,IAAI,CAAC,KAAA,CAAM,OAAA,CAAQ,CAAA,CAAE,SAAS,CAAC,CAAA,EAAG;AAChC,IAAA,MAAA,CAAO,KAAK,0BAA0B,CAAA;AACtC,IAAA,OAAO,EAAE,EAAA,EAAI,KAAA,EAAO,MAAA,EAAO;AAAA,EAC7B;AAEA,EAAA,MAAM,IAAA,uBAAW,GAAA,EAAY;AAC7B,EAAA,MAAM,OAA4B,EAAC;AACnC,EAAC,EAAE,SAAS,CAAA,CAAgB,OAAA,CAAQ,CAAC,GAAG,CAAA,KAAM;AAC5C,IAAA,IAAI,CAAC,CAAA,IAAK,OAAO,CAAA,KAAM,QAAA,EAAU;AAC/B,MAAA,MAAA,CAAO,IAAA,CAAK,CAAA,QAAA,EAAW,CAAC,CAAA,kBAAA,CAAoB,CAAA;AAC5C,MAAA;AAAA,IACF;AACA,IAAA,MAAM,CAAA,GAAI,CAAA;AACV,IAAA,MAAM,IAAA,GAAO,EAAE,MAAM,CAAA;AACrB,IAAA,IAAI,OAAO,IAAA,KAAS,QAAA,IAAY,CAAC,OAAA,CAAQ,IAAA,CAAK,IAAI,CAAA,EAAG;AACnD,MAAA,MAAA,CAAO,IAAA,CAAK,CAAA,QAAA,EAAW,CAAC,CAAA,mCAAA,CAAqC,CAAA;AAC7D,MAAA;AAAA,IACF;AACA,IAAA,IAAI,IAAA,CAAK,GAAA,CAAI,IAAI,CAAA,EAAG;AAClB,MAAA,MAAA,CAAO,IAAA,CAAK,CAAA,QAAA,EAAW,CAAC,CAAA,QAAA,EAAW,IAAI,CAAA,YAAA,CAAc,CAAA;AACrD,MAAA;AAAA,IACF;AACA,IAAA,IAAA,CAAK,IAAI,IAAI,CAAA;AACb,IAAA,IAAI,OAAO,CAAA,CAAE,UAAU,CAAA,KAAM,QAAA,IAAY,CAAC,WAAA,CAAY,IAAA,CAAK,CAAA,CAAE,UAAU,CAAC,CAAA,EAAG;AACzE,MAAA,MAAA,CAAO,IAAA,CAAK,CAAA,QAAA,EAAW,CAAC,CAAA,uCAAA,CAAyC,CAAA;AACjE,MAAA;AAAA,IACF;AACA,IAAA,KAAA,MAAW,SAAS,CAAC,IAAA,EAAM,OAAA,EAAS,aAAA,EAAe,UAAU,CAAA,EAAY;AACvE,MAAA,MAAM,CAAA,GAAI,EAAE,KAAK,CAAA;AACjB,MAAA,IAAI,OAAO,MAAM,QAAA,IAAY,CAAA,CAAE,WAAW,CAAA,IAAK,CAAA,CAAE,SAAS,OAAA,EAAS;AACjE,QAAA,MAAA,CAAO,KAAK,CAAA,QAAA,EAAW,CAAC,KAAK,KAAK,CAAA,kCAAA,EAAqC,OAAO,CAAA,MAAA,CAAQ,CAAA;AACtF,QAAA;AAAA,MACF;AAAA,IACF;AACA,IAAA,MAAM,OAAO,KAAA,CAAM,OAAA,CAAQ,CAAA,CAAE,MAAM,CAAC,CAAA,GAC/B,CAAA,CAAE,MAAM,CAAA,CAAE,OAAO,CAAC,CAAA,KAAM,OAAO,CAAA,KAAM,QAAQ,IAC9C,EAAC;AACL,IAAA,IAAA,CAAK,IAAA,CAAK;AAAA,MACR,EAAA,EAAI,EAAE,IAAI,CAAA;AAAA,MACV,IAAA;AAAA,MACA,KAAA,EAAO,EAAE,OAAO,CAAA;AAAA,MAChB,WAAA,EAAa,EAAE,aAAa,CAAA;AAAA,MAC5B,QAAA,EAAU,EAAE,UAAU,CAAA;AAAA,MACtB,IAAA;AAAA,MACA,QAAA,EAAU,EAAE,UAAU,CAAA;AAAA,MACtB,OAAA,EAAS,OAAO,CAAA,CAAE,SAAS,MAAM,QAAA,GAAW,CAAA,CAAE,SAAS,CAAA,GAAI,MAAA;AAAA,MAC3D,OAAA,EAAS,OAAO,CAAA,CAAE,SAAS,MAAM,QAAA,GAAW,CAAA,CAAE,SAAS,CAAA,GAAI,MAAA;AAAA,MAC3D,GAAA,EAAK,OAAO,CAAA,CAAE,KAAK,MAAM,QAAA,GAAW,CAAA,CAAE,KAAK,CAAA,GAAI;AAAA,KAChD,CAAA;AAAA,EACH,CAAC,CAAA;AAED,EAAA,IAAI,OAAO,MAAA,GAAS,CAAA,SAAU,EAAE,EAAA,EAAI,OAAO,MAAA,EAAO;AAClD,EAAA,OAAO;AAAA,IACL,EAAA,EAAI,IAAA;AAAA,IACJ,QAAA,EAAU;AAAA,MACR,eAAA,EAAiB,CAAA;AAAA,MACjB,MAAA,EAAQ,EAAE,QAAQ,CAAA;AAAA,MAClB,WAAA,EAAa,EAAE,aAAa,CAAA;AAAA,MAC5B,OAAA,EAAS;AAAA;AACX,GACF;AACF;AAeO,SAAS,YAAA,CACd,OACA,QAAA,EACc;AACd,EAAA,MAAM,WAAA,GAAc,IAAI,GAAA,CAAI,KAAA,CAAM,GAAA,CAAI,CAAC,CAAA,KAAM,CAAC,CAAA,CAAE,IAAA,EAAM,CAAA,CAAE,QAAQ,CAAC,CAAC,CAAA;AAClE,EAAA,MAAM,IAAA,GAAqB,EAAE,KAAA,EAAO,EAAC,EAAG,SAAS,EAAC,EAAG,SAAA,EAAW,EAAC,EAAE;AACnE,EAAA,KAAA,MAAW,GAAA,IAAO,SAAS,OAAA,EAAS;AAClC,IAAA,IAAI,CAAC,YAAY,GAAA,CAAI,GAAA,CAAI,IAAI,CAAA,EAAG,IAAA,CAAK,KAAA,CAAM,IAAA,CAAK,GAAG,CAAA;AAAA,SAAA,IAC1C,WAAA,CAAY,GAAA,CAAI,GAAA,CAAI,IAAI,CAAA,KAAM,IAAI,QAAA,EAAU,IAAA,CAAK,OAAA,CAAQ,IAAA,CAAK,GAAG,CAAA;AAAA,SACrE,IAAA,CAAK,SAAA,CAAU,IAAA,CAAK,GAAG,CAAA;AAAA,EAC9B;AACA,EAAA,OAAO,IAAA;AACT;;;ACxJO,IAAM,gBAAgB,CAAC,KAAA,EAAO,cAAA,EAAgB,SAAA,EAAW,WAAW,SAAS;AAI7E,SAAS,cAAc,CAAA,EAA6B;AACzD,EAAA,OAAQ,aAAA,CAAoC,SAAS,CAAC,CAAA;AACxD;AChBO,SAAS,WAAW,EAAA,EAAoB;AAC7C,EAAA,KAAA,MAAW,GAAA,IAAO,yBAAwB,EAAG;AAC3C,IAAA,IAAI;AACF,MAAA,OAAO,YAAA,CAAkB,WAAK,GAAA,EAAK,CAAA,EAAG,EAAE,CAAA,GAAA,CAAK,CAAA,EAAG,MAAM,CAAA,CAAE,OAAA,EAAQ;AAAA,IAClE,CAAA,CAAA,MAAQ;AAAA,IAER;AAAA,EACF;AACA,EAAA,OAAO,EAAA;AACT;AAEA,SAAS,uBAAA,GAAoC;AAC3C,EAAA,MAAM,IAAA,GAAY,KAAA,CAAA,OAAA,CAAQ,aAAA,CAAc,MAAA,CAAA,IAAA,CAAY,GAAG,CAAC,CAAA;AACxD,EAAA,MAAM,UAAA,GAAa;AAAA,IACZ,KAAA,CAAA,OAAA,CAAQ,MAAM,0BAA0B,CAAA;AAAA,IACxC,KAAA,CAAA,OAAA,CAAQ,MAAM,uBAAuB,CAAA;AAAA,IACrC,KAAA,CAAA,OAAA,CAAQ,MAAM,oBAAoB;AAAA,GACzC;AACA,EAAA,OAAO,WAAW,IAAA,CAAK,CAAC,CAAA,EAAG,CAAA,KAAM,OAAO,CAAC,WAAA,CAAY,CAAC,CAAC,IAAI,MAAA,CAAO,CAAC,WAAA,CAAY,CAAC,CAAC,CAAC,CAAA;AACpF;AAEA,SAAS,YAAY,SAAA,EAA4B;AAC/C,EAAA,IAAI;AACF,IAAA,OAAO,QAAA,CAAS,SAAS,CAAA,CAAE,WAAA,EAAY;AAAA,EACzC,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,KAAA;AAAA,EACT;AACF;;;ACKO,IAAM,aAAA,GAAwB;AAAA,EACnC;AAAA,IACE,EAAA,EAAI,SAAA;AAAA,IACJ,IAAA,EAAM,SAAA;AAAA,IACN,WAAA,EAAa,kCAAA;AAAA,IACb,MAAA,EAAQ,EAAA;AAAA,IACR,IAAA,EAAM,CAAC,SAAS;AAAA,GAClB;AAAA,EACA;AAAA,IACE,EAAA,EAAI,eAAA;AAAA,IACJ,IAAA,EAAM,eAAA;AAAA,IACN,WAAA,EAAa,2DAAA;AAAA,IACb,MAAA,EAAQ,WAAW,eAAe,CAAA;AAAA,IAClC,IAAA,EAAM,CAAC,QAAA,EAAU,SAAA,EAAW,UAAU,CAAA;AAAA,IACtC,iBAAiB,CAAC,MAAA,EAAQ,MAAA,EAAQ,KAAA,EAAO,QAAQ,MAAM,CAAA;AAAA,IACvD,eAAA,EAAiB,CAAC,YAAA,EAAc,kBAAA,EAAoB,qBAAqB,SAAS;AAAA,GACpF;AAAA,EACA;AAAA,IACE,EAAA,EAAI,cAAA;AAAA,IACJ,IAAA,EAAM,cAAA;AAAA,IACN,WAAA,EAAa,gCAAA;AAAA,IACb,MAAA,EAAQ,WAAW,cAAc,CAAA;AAAA,IACjC,IAAA,EAAM,CAAC,UAAA,EAAY,OAAA,EAAS,YAAY,CAAA;AAAA,IACxC,eAAA,EAAiB,CAAC,MAAA,EAAQ,MAAA,EAAQ,SAAS,MAAM,CAAA;AAAA,IACjD,eAAA,EAAiB,CAAC,kBAAA,EAAoB,YAAA,EAAc,WAAW;AAAA,GACjE;AAAA,EACA;AAAA,IACE,EAAA,EAAI,WAAA;AAAA,IACJ,IAAA,EAAM,oBAAA;AAAA,IACN,WAAA,EAAa,iDAAA;AAAA,IACb,MAAA,EAAQ,WAAW,WAAW,CAAA;AAAA,IAC9B,IAAA,EAAM,CAAC,cAAA,EAAgB,QAAA,EAAU,aAAa,CAAA;AAAA,IAC9C,eAAA,EAAiB,CAAC,MAAA,EAAQ,MAAA,EAAQ,QAAQ,MAAM,CAAA;AAAA,IAChD,eAAA,EAAiB,CAAC,YAAA,EAAc,kBAAA,EAAoB,eAAe,eAAe;AAAA,GACpF;AAAA,EACA;AAAA,IACE,EAAA,EAAI,UAAA;AAAA,IACJ,IAAA,EAAM,UAAA;AAAA,IACN,WAAA,EAAa,6CAAA;AAAA,IACb,MAAA,EAAQ,WAAW,UAAU,CAAA;AAAA,IAC7B,IAAA,EAAM,CAAC,OAAA,EAAS,eAAA,EAAiB,kBAAkB,CAAA;AAAA,IACnD,iBAAiB,CAAC,MAAA,EAAQ,MAAA,EAAQ,MAAA,EAAQ,QAAQ,MAAM,CAAA;AAAA,IACxD,eAAA,EAAiB,CAAC,YAAA,EAAc,WAAA,EAAa,eAAe;AAAA,GAC9D;AAAA,EACA;AAAA,IACE,EAAA,EAAI,QAAA;AAAA,IACJ,IAAA,EAAM,aAAA;AAAA,IACN,WAAA,EAAa,kDAAA;AAAA,IACb,MAAA,EAAQ,WAAW,QAAQ,CAAA;AAAA,IAC3B,IAAA,EAAM,CAAC,SAAA,EAAW,IAAA,EAAM,SAAS,CAAA;AAAA,IACjC,eAAA,EAAiB,CAAC,MAAA,EAAQ,MAAA,EAAQ,QAAQ,MAAM,CAAA;AAAA,IAChD,eAAA,EAAiB,CAAC,SAAA,EAAW,YAAA,EAAc,mBAAmB;AAAA,GAChE;AAAA,EACA;AAAA,IACE,EAAA,EAAI,QAAA;AAAA,IACJ,IAAA,EAAM,iBAAA;AAAA,IACN,WAAA,EAAa,4CAAA;AAAA,IACb,MAAA,EAAQ,WAAW,QAAQ,CAAA;AAAA,IAC3B,IAAA,EAAM,CAAC,QAAA,EAAU,gBAAA,EAAkB,YAAY,CAAA;AAAA,IAC/C,iBAAiB,CAAC,MAAA,EAAQ,MAAA,EAAQ,MAAA,EAAQ,QAAQ,KAAK,CAAA;AAAA,IACvD,eAAA,EAAiB,CAAC,eAAA,EAAiB,eAAA,EAAiB,kBAAkB;AAAA,GACxE;AAAA,EACA;AAAA,IACE,EAAA,EAAI,YAAA;AAAA,IACJ,IAAA,EAAM,YAAA;AAAA,IACN,WAAA,EAAa,oCAAA;AAAA,IACb,MAAA,EAAQ,WAAW,YAAY,CAAA;AAAA,IAC/B,IAAA,EAAM,CAAC,UAAA,EAAY,eAAA,EAAiB,aAAa,CAAA;AAAA,IACjD,iBAAiB,CAAC,MAAA,EAAQ,MAAA,EAAQ,MAAA,EAAQ,OAAO,MAAM,CAAA;AAAA,IACvD,eAAA,EAAiB,CAAC,kBAAA,EAAoB,mBAAA,EAAqB,eAAe,SAAS;AAAA,GACrF;AAAA,EACA;AAAA,IACE,EAAA,EAAI,WAAA;AAAA,IACJ,IAAA,EAAM,WAAA;AAAA,IACN,WAAA,EAAa,wDAAA;AAAA,IACb,MAAA,EAAQ,WAAW,WAAW,CAAA;AAAA,IAC9B,IAAA,EAAM,CAAC,IAAA,EAAM,UAAA,EAAY,UAAU,QAAQ,CAAA;AAAA,IAC3C,iBAAiB,CAAC,QAAA,EAAU,OAAA,EAAS,MAAA,EAAQ,QAAQ,UAAU,CAAA;AAAA,IAC/D,eAAA,EAAiB,CAAC,cAAc;AAAA,GAClC;AAAA,EACA;AAAA,IACE,EAAA,EAAI,OAAA;AAAA,IACJ,IAAA,EAAM,OAAA;AAAA,IACN,WAAA,EAAa,2CAAA;AAAA,IACb,MAAA,EAAQ,WAAW,OAAO,CAAA;AAAA,IAC1B,IAAA,EAAM,CAAC,MAAA,EAAQ,SAAA,EAAW,QAAQ,CAAA;AAAA,IAClC,eAAA,EAAiB,CAAC,MAAA,EAAQ,MAAA,EAAQ,MAAM,CAAA;AAAA,IACxC,iBAAiB;AAAC,GACpB;AAAA,EACA;AAAA,IACE,EAAA,EAAI,OAAA;AAAA,IACJ,IAAA,EAAM,OAAA;AAAA,IACN,WAAA,EAAa,gDAAA;AAAA,IACb,MAAA,EAAQ,WAAW,OAAO,CAAA;AAAA,IAC1B,IAAA,EAAM,CAAC,UAAA,EAAY,QAAA,EAAU,UAAU,CAAA;AAAA,IACvC,eAAA,EAAiB,CAAC,MAAA,EAAQ,MAAA,EAAQ,SAAS,CAAA;AAAA,IAC3C,eAAA,EAAiB,CAAC,oBAAA,EAAsB,eAAA,EAAiB,eAAe,mBAAmB;AAAA,GAC7F;AAAA,EACA;AAAA,IACE,EAAA,EAAI,cAAA;AAAA,IACJ,IAAA,EAAM,cAAA;AAAA,IACN,WAAA,EAAa,+EAAA;AAAA,IACb,MAAA,EAAQ,WAAW,cAAc,CAAA;AAAA,IACjC,IAAA,EAAM,CAAC,UAAA,EAAY,KAAA,EAAO,gBAAgB,YAAY,CAAA;AAAA,IACtD,iBAAiB,CAAC,cAAA,EAAgB,cAAA,EAAgB,QAAA,EAAU,SAAS,iBAAiB,CAAA;AAAA,IACtF,iBAAiB,CAAC,cAAA,EAAgB,YAAA,EAAc,aAAA,EAAe,oBAAoB,cAAc;AAAA;AAErG;;;AC9GO,IAAM,8BAAA,GAAsD;AAE5D,IAAM,oBAAA,GAAqD,OAAO,MAAA,CAAO;AAAA,EAC9E;AAAA,IACE,EAAA,EAAI,UAAA;AAAA,IACJ,IAAA,EAAM,UAAA;AAAA,IACN,WAAA,EAAa,qFAAA;AAAA,IACb,YAAY,EAAE,IAAA,EAAM,KAAK,IAAA,EAAM,IAAA,EAAM,MAAM,GAAA,EAAI;AAAA,IAC/C,YAAA,EAAc,MAAA;AAAA,IACd,SAAA,EAAW,EAAA;AAAA,IACX,cAAA,EAAgB,GAAA;AAAA,IAChB,UAAA,EAAY;AAAA,GACd;AAAA,EACA;AAAA,IACE,EAAA,EAAI,QAAA;AAAA,IACJ,IAAA,EAAM,QAAA;AAAA,IACN,WAAA,EAAa,qEAAA;AAAA,IACb,YAAY,EAAE,IAAA,EAAM,MAAM,IAAA,EAAM,GAAA,EAAK,MAAM,IAAA,EAAK;AAAA,IAChD,YAAA,EAAc,MAAA;AAAA,IACd,SAAA,EAAW,CAAA;AAAA,IACX,cAAA,EAAgB,GAAA;AAAA,IAChB,UAAA,EAAY;AAAA,GACd;AAAA,EACA;AAAA,IACE,EAAA,EAAI,MAAA;AAAA,IACJ,IAAA,EAAM,MAAA;AAAA,IACN,WAAA,EAAa,4EAAA;AAAA,IACb,YAAY,EAAE,IAAA,EAAM,MAAM,IAAA,EAAM,IAAA,EAAM,MAAM,IAAA,EAAK;AAAA,IACjD,YAAA,EAAc,MAAA;AAAA,IACd,SAAA,EAAW,EAAA;AAAA,IACX,cAAA,EAAgB,GAAA;AAAA,IAChB,UAAA,EAAY;AAAA,GACd;AAAA,EACA;AAAA,IACE,EAAA,EAAI,UAAA;AAAA,IACJ,IAAA,EAAM,UAAA;AAAA,IACN,WAAA,EAAa,gFAAA;AAAA,IACb,YAAY,EAAE,IAAA,EAAM,MAAM,IAAA,EAAM,GAAA,EAAK,MAAM,IAAA,EAAK;AAAA,IAChD,YAAA,EAAc,MAAA;AAAA,IACd,SAAA,EAAW,CAAA;AAAA,IACX,cAAA,EAAgB,IAAA;AAAA,IAChB,UAAA,EAAY;AAAA;AAEhB,CAAC;AAEM,SAAS,sBAAA,GAA8C;AAC5D,EAAA,OAAO,oBAAA,CAAqB,GAAA,CAAI,CAAC,CAAA,MAAO,EAAE,GAAG,CAAA,EAAG,UAAA,EAAY,EAAE,GAAG,CAAA,CAAE,UAAA,IAAa,CAAE,CAAA;AACpF;AAEO,SAAS,qBAAqB,EAAA,EAAyD;AAC5F,EAAA,IAAI,CAAC,IAAI,OAAO,IAAA;AAChB,EAAA,MAAM,OAAO,oBAAA,CAAqB,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,OAAO,EAAE,CAAA;AACzD,EAAA,OAAO,IAAA,GAAO,EAAE,GAAG,IAAA,EAAM,UAAA,EAAY,EAAE,GAAG,IAAA,CAAK,UAAA,EAAW,EAAE,GAAI,IAAA;AAClE;AAEO,SAAS,sBAAsB,EAAA,EAAuC;AAC3E,EAAA,OAAO,qBAAqB,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,OAAO,EAAE,CAAA;AACrD;AAEO,SAAS,0BAAA,CACd,MAAA,GAAkC,EAAC,EACnC,YAAA,EACqB;AACrB,EAAA,MAAM,SAAA,GAAY,YAAA,IAAgB,MAAA,CAAO,IAAA,IAAQ,8BAAA;AACjD,EAAA,MAAM,OAAO,oBAAA,CAAqB,SAAS,KAAK,aAAA,CAAc,oBAAA,CAAqB,8BAA8B,CAAC,CAAA;AAElH,EAAA,IAAI,IAAA,CAAK,OAAO,8BAAA,EAAgC;AAC9C,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,OAAO;AAAA,IACL,GAAG,IAAA;AAAA,IACH,UAAA,EAAY;AAAA,MACV,IAAA,EAAM,MAAA,CAAO,aAAA,IAAiB,IAAA,CAAK,UAAA,CAAW,IAAA;AAAA,MAC9C,IAAA,EAAM,MAAA,CAAO,aAAA,IAAiB,IAAA,CAAK,UAAA,CAAW,IAAA;AAAA,MAC9C,IAAA,EAAM,MAAA,CAAO,aAAA,IAAiB,IAAA,CAAK,UAAA,CAAW;AAAA,KAChD;AAAA,IACA,SAAA,EAAW,MAAA,CAAO,SAAA,IAAa,IAAA,CAAK,SAAA;AAAA,IACpC,cAAA,EAAgB,MAAA,CAAO,cAAA,IAAkB,IAAA,CAAK;AAAA,GAChD;AACF;AAEO,SAAS,4BAA4B,QAAA,EAAkC;AAC5E,EAAA,OAAO,oBAAA,CAAqB,GAAA,CAAI,CAAC,CAAA,KAAM;AACrC,IAAA,MAAM,MAAA,GAAS,CAAA,CAAE,EAAA,KAAO,QAAA,GAAW,GAAA,GAAM,GAAA;AACzC,IAAA,OAAO,CAAA,EAAG,MAAM,CAAA,CAAA,EAAI,CAAA,CAAE,EAAA,CAAG,MAAA,CAAO,CAAC,CAAC,CAAA,CAAA,EAAI,CAAA,CAAE,IAAI,CAAA,GAAA,EAAM,EAAE,WAAW,CAAA,CAAA;AAAA,EACjE,CAAC,CAAA,CAAE,IAAA,CAAK,IAAI,CAAA;AACd;;;ACxCO,IAAM,qBAAA,GAAsC;AAAA,EACjD,EAAA,EAAI,SAAA;AAAA,EACJ,IAAA,EAAM,sBAAA;AAAA,EACN,WAAA,EAAa,8CAAA;AAAA,EACb,QAAA,EAAU;AAAA,IACR,EAAE,IAAA,EAAM,UAAA,EAAY,KAAA,EAAO,UAAA,EAAY,OAAO,CAAA,EAAE;AAAA,IAChD,EAAE,IAAA,EAAM,cAAA,EAAgB,KAAA,EAAO,cAAA,EAAgB,OAAO,CAAA,EAAE;AAAA,IACxD,EAAE,IAAA,EAAM,cAAA,EAAgB,KAAA,EAAO,cAAA,EAAgB,OAAO,CAAA,EAAE;AAAA,IACxD,EAAE,IAAA,EAAM,KAAA,EAAO,KAAA,EAAO,YAAA,EAAc,OAAO,CAAA,EAAE;AAAA,IAC7C,EAAE,IAAA,EAAM,MAAA,EAAQ,KAAA,EAAO,YAAA,EAAc,OAAO,CAAA,EAAE;AAAA,IAC9C,EAAE,IAAA,EAAM,UAAA,EAAY,KAAA,EAAO,UAAA,EAAY,OAAO,CAAA,EAAE;AAAA,IAChD,EAAE,IAAA,EAAM,YAAA,EAAc,KAAA,EAAO,qBAAA,EAAuB,OAAO,CAAA;AAAE,GAC/D;AAAA,EACA,mBAAA,EAAqB;AAAA,IACnB,EAAE,IAAA,EAAM,YAAA,EAAc,QAAA,EAAU,MAAA,EAAQ,kBAAA,EAAoB,EAAC,EAAG,SAAA,EAAW,EAAC,EAAG,UAAA,EAAY,EAAC,EAAE;AAAA,IAC9F;AAAA,MACE,IAAA,EAAM,gBAAA;AAAA,MACN,QAAA,EAAU,QAAA;AAAA,MACV,oBAAoB,EAAC;AAAA,MACrB,WAAW,EAAC;AAAA,MACZ,YAAY;AAAC;AACf;AAEJ;;;ACdO,SAAS,oBAAoB,KAAA,EAAgC;AAClE,EAAA,IAAI,SAAA,GAAY,CAAA;AAChB,EAAA,IAAI,OAAA,GAAU,CAAA;AACd,EAAA,IAAI,UAAA,GAAa,CAAA;AACjB,EAAA,IAAI,OAAA,GAAU,CAAA;AACd,EAAA,IAAI,MAAA,GAAS,CAAA;AACb,EAAA,IAAI,MAAA,GAAS,CAAA;AACb,EAAA,IAAI,cAAA,GAAiB,CAAA;AACrB,EAAA,IAAI,WAAA,GAAc,CAAA;AAClB,EAAA,KAAA,MAAW,CAAA,IAAK,KAAA,CAAM,KAAA,CAAM,MAAA,EAAO,EAAG;AACpC,IAAA,QAAQ,EAAE,MAAA;AAAQ,MAChB,KAAK,WAAA;AACH,QAAA,SAAA,EAAA;AACA,QAAA;AAAA,MACF,KAAK,SAAA;AACH,QAAA,OAAA,EAAA;AACA,QAAA;AAAA,MACF,KAAK,aAAA;AACH,QAAA,UAAA,EAAA;AACA,QAAA;AAAA,MACF,KAAK,SAAA;AACH,QAAA,OAAA,EAAA;AACA,QAAA;AAAA,MACF,KAAK,QAAA;AACH,QAAA,MAAA,EAAA;AACA,QAAA;AAAA,MACF,KAAK,QAAA;AACH,QAAA,MAAA,EAAA;AACA,QAAA;AAAA;AAEJ,IAAA,cAAA,IAAkB,EAAE,aAAA,IAAiB,CAAA;AACrC,IAAA,WAAA,IAAe,EAAE,WAAA,IAAe,CAAA;AAAA,EAClC;AACA,EAAA,MAAM,KAAA,GAAQ,MAAM,KAAA,CAAM,IAAA;AAE1B,EAAA,OAAO;AAAA,IACL,KAAA;AAAA,IACA,OAAA;AAAA,IACA,UAAA;AAAA,IACA,OAAA;AAAA,IACA,MAAA;AAAA,IACA,MAAA;AAAA,IACA,SAAA;AAAA,IACA,eAAA,EAAiB,QAAQ,CAAA,GAAI,IAAA,CAAK,MAAO,SAAA,GAAY,KAAA,GAAS,GAAG,CAAA,GAAI,CAAA;AAAA,IACrE,cAAA;AAAA,IACA;AAAA,GACF;AACF;AAEO,SAAS,iBAAiB,KAAA,EAAsC;AACrE,EAAA,MAAM,QAAQ,KAAA,CAAM,IAAA,CAAK,KAAA,CAAM,KAAA,CAAM,QAAQ,CAAA;AAC7C,EAAA,MAAM,gBAAgB,KAAA,CAAM,MAAA,CAAO,CAAC,CAAA,KAAM,CAAA,CAAE,aAAa,UAAU,CAAA;AACnE,EAAA,MAAM,eAAA,GAAkB,cACrB,MAAA,CAAO,CAAC,MAAM,KAAA,CAAM,KAAA,CAAM,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,OAAO,CAAA,CAAE,EAAA,IAAM,CAAA,CAAE,IAAA,KAAS,YAAY,CAAC,EAC/E,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,CAAE,EAAE,CAAA;AAElB,EAAA,MAAM,kBAAA,GAAqB,aAAA,CAAc,MAAA,CAAO,CAAC,GAAA,EAAK,MAAM,GAAA,IAAO,CAAA,CAAE,aAAA,IAAiB,CAAA,CAAA,EAAI,CAAC,CAAA;AAE3F,EAAA,OAAO;AAAA,IACL,SAAS,aAAA,CAAc,GAAA,CAAI,CAAC,CAAA,KAAM,EAAE,EAAE,CAAA;AAAA,IACtC,kBAAA;AAAA,IACA;AAAA,GACF;AACF;AAEO,SAAS,gBAAgB,KAAA,EAA4B;AAC1D,EAAA,MAAM,OAAA,uBAAc,GAAA,EAAY;AAChC,EAAA,MAAM,OAAA,uBAAc,GAAA,EAAY;AAChC,EAAA,MAAM,SAAmB,EAAC;AAE1B,EAAA,SAAS,MAAM,EAAA,EAAkB;AAE/B,IAAA,IAAI,OAAA,CAAQ,GAAA,CAAI,EAAE,CAAA,EAAG;AACrB,IAAA,IAAI,OAAA,CAAQ,GAAA,CAAI,EAAE,CAAA,EAAG;AACrB,IAAA,IAAI,CAAC,KAAA,CAAM,KAAA,CAAM,GAAA,CAAI,EAAE,CAAA,EAAG;AAE1B,IAAA,OAAA,CAAQ,IAAI,EAAE,CAAA;AACd,IAAA,OAAA,CAAQ,IAAI,EAAE,CAAA;AAEd,IAAA,KAAA,MAAW,IAAA,IAAQ,MAAM,KAAA,EAAO;AAC9B,MAAA,IAAI,IAAA,CAAK,IAAA,KAAS,EAAA,EAAI,KAAA,CAAM,KAAK,EAAE,CAAA;AAAA,IACrC;AAEA,IAAA,OAAA,CAAQ,OAAO,EAAE,CAAA;AACjB,IAAA,MAAA,CAAO,KAAK,EAAE,CAAA;AAAA,EAChB;AAEA,EAAA,KAAA,MAAW,MAAA,IAAU,MAAM,SAAA,EAAW;AACpC,IAAA,KAAA,CAAM,MAAM,CAAA;AAAA,EACd;AAEA,EAAA,OAAO,MAAA;AACT;AChKO,IAAM,oBAAA,GAAN,MAAM,qBAAA,CAA8C;AAAA,EACxC,KAAA;AAAA,EACA,UAAA,uBAAiB,GAAA,EAAyB;AAAA,EAC1C,gBAAA,uBAAuB,GAAA,EAAoB;AAAA,EAC5D,OAAwB,uBAAA,GAA0B,EAAA;AAAA,EAElD,YAAY,IAAA,EAAmC;AAC7C,IAAA,IAAA,CAAK,QAAQ,IAAA,CAAK,KAAA;AAAA,EACpB;AAAA,EAEA,MAAc,sBAAsB,SAAA,EAAyC;AAC3E,IAAA,MAAM,gBAAgB,IAAA,CAAK,KAAA;AAI3B,IAAA,MAAM,UAAU,aAAA,CAAc,GAAA;AAC9B,IAAA,IAAI,CAAC,OAAA,EAAS;AACZ,MAAA,OAAO,MAAM,IAAA,CAAK,KAAA,CAAM,IAAA,CAAK,SAAS,CAAA;AAAA,IACxC;AACA,IAAA,MAAM,WAAA,GAAc,iBAAA,CAAkB,OAAA,EAAS,SAAA,EAAW,QAAQ,CAAA;AAClE,IAAA,IAAI,OAAA,GAAyB,IAAA;AAC7B,IAAA,IAAI;AACF,MAAA,MAAMC,KAAAA,GAAO,MAAS,EAAA,CAAA,IAAA,CAAK,WAAW,CAAA;AACtC,MAAA,OAAA,GAAUA,KAAAA,CAAK,OAAA;AAAA,IACjB,CAAA,CAAA,MAAQ;AACN,MAAA,IAAA,CAAK,UAAA,CAAW,OAAO,SAAS,CAAA;AAChC,MAAA,IAAA,CAAK,gBAAA,CAAiB,OAAO,SAAS,CAAA;AACtC,MAAA,OAAO,MAAM,IAAA,CAAK,KAAA,CAAM,IAAA,CAAK,SAAS,CAAA;AAAA,IACxC;AAEA,IAAA,MAAM,WAAA,GAAc,IAAA,CAAK,gBAAA,CAAiB,GAAA,CAAI,SAAS,CAAA;AACvD,IAAA,MAAM,UAAA,GAAa,IAAA,CAAK,UAAA,CAAW,GAAA,CAAI,SAAS,CAAA;AAChD,IAAA,IAAI,UAAA,IAAc,gBAAgB,OAAA,EAAS;AACzC,MAAA,IAAA,CAAK,UAAA,CAAW,OAAO,SAAS,CAAA;AAChC,MAAA,IAAA,CAAK,gBAAA,CAAiB,OAAO,SAAS,CAAA;AACtC,MAAA,IAAA,CAAK,UAAA,CAAW,GAAA,CAAI,SAAA,EAAW,UAAU,CAAA;AACzC,MAAA,IAAA,CAAK,gBAAA,CAAiB,GAAA,CAAI,SAAA,EAAW,OAAO,CAAA;AAC5C,MAAA,OAAO,UAAA;AAAA,IACT;AAEA,IAAA,MAAM,IAAA,GAAO,MAAM,IAAA,CAAK,KAAA,CAAM,KAAK,SAAS,CAAA;AAC5C,IAAA,IAAA,CAAK,UAAA,CAAW,OAAO,SAAS,CAAA;AAChC,IAAA,IAAA,CAAK,gBAAA,CAAiB,OAAO,SAAS,CAAA;AACtC,IAAA,IAAA,CAAK,UAAA,CAAW,GAAA,CAAI,SAAA,EAAW,IAAI,CAAA;AACnC,IAAA,IAAA,CAAK,gBAAA,CAAiB,GAAA,CAAI,SAAA,EAAW,OAAO,CAAA;AAC5C,IAAA,OAAO,IAAA,CAAK,UAAA,CAAW,IAAA,GAAO,qBAAA,CAAqB,uBAAA,EAAyB;AAC1E,MAAA,MAAM,SAAS,IAAA,CAAK,UAAA,CAAW,IAAA,EAAK,CAAE,MAAK,CAAE,KAAA;AAC7C,MAAA,IAAI,WAAW,MAAA,EAAW;AAC1B,MAAA,IAAA,CAAK,UAAA,CAAW,OAAO,MAAM,CAAA;AAC7B,MAAA,IAAA,CAAK,gBAAA,CAAiB,OAAO,MAAM,CAAA;AAAA,IACrC;AAEA,IAAA,IAAI,IAAA,CAAK,SAAS,OAAA,EAAS;AACzB,MAAA,aAAA,CAAc,iBAAiB,SAAS,CAAA;AAAA,IAC1C;AAEA,IAAA,OAAO,IAAA;AAAA,EACT;AAAA,EAEA,MAAM,KAAA,CAAM,CAAA,GAAkB,EAAC,EAAkC;AAG/D,IAAA,MAAM,kBAAkB,IAAA,CAAK,KAAA;AAW7B,IAAA,IAAI,GAAA;AACJ,IAAA,IAAI,OAAO,eAAA,CAAgB,YAAA,KAAiB,UAAA,EAAY;AACtD,MAAA,GAAA,GAAM,MAAM,gBAAgB,YAAA,CAAa;AAAA,QACvC,OAAO,CAAA,CAAE,KAAA;AAAA,QACT,OAAO,CAAA,CAAE,KAAA;AAAA,QACT,UAAU,CAAA,CAAE,QAAA;AAAA,QACZ,OAAO,CAAA,CAAE,KAAA;AAAA,QACT,WAAW,CAAA,CAAE,SAAA;AAAA,QACb,eAAe,CAAA,CAAE,aAAA;AAAA,QACjB,OAAO,CAAA,CAAE;AAAA,OACV,CAAA;AAAA,IACH,CAAA,MAAO;AACL,MAAA,MAAM,OAAA,GAAU,MAAM,IAAA,CAAK,KAAA,CAAM,IAAA,CAAK,CAAA,CAAE,KAAA,GAAQ,IAAA,CAAK,GAAA,CAAI,CAAA,CAAE,KAAA,EAAO,GAAG,IAAI,GAAI,CAAA;AAC7E,MAAA,MAAM,WAAA,GAAc,CAAA,CAAE,aAAA,EAAe,WAAA,EAAY;AACjD,MAAA,GAAA,GAAM,OAAA,CAAQ,MAAA,CAAO,CAAC,CAAA,KAAM;AAC1B,QAAA,IAAI,EAAE,KAAA,IAAS,CAAA,CAAE,SAAA,GAAY,CAAA,CAAE,OAAO,OAAO,KAAA;AAC7C,QAAA,IAAI,EAAE,KAAA,IAAS,CAAA,CAAE,SAAA,GAAY,CAAA,CAAE,OAAO,OAAO,KAAA;AAC7C,QAAA,IAAI,EAAE,QAAA,IAAY,CAAA,CAAE,QAAA,KAAa,CAAA,CAAE,UAAU,OAAO,KAAA;AACpD,QAAA,IAAI,EAAE,KAAA,IAAS,CAAA,CAAE,KAAA,KAAU,CAAA,CAAE,OAAO,OAAO,KAAA;AAC3C,QAAA,IAAI,EAAE,SAAA,KAAc,MAAA,IAAa,EAAE,UAAA,GAAa,CAAA,CAAE,WAAW,OAAO,KAAA;AACpE,QAAA,IAAI,WAAA,IAAe,CAAC,CAAA,CAAE,KAAA,CAAM,aAAY,CAAE,QAAA,CAAS,WAAW,CAAA,EAAG,OAAO,KAAA;AACxE,QAAA,OAAO,IAAA;AAAA,MACT,CAAC,CAAA;AAAA,IACH;AACA,IAAA,MAAM,GAAA,GAA4B,GAAA,CAAI,GAAA,CAAI,CAAC,CAAA,MAAO;AAAA,MAChD,IAAI,CAAA,CAAE,EAAA;AAAA,MACN,OAAO,CAAA,CAAE,KAAA;AAAA,MACT,WAAW,CAAA,CAAE,SAAA;AAAA,MACb,UAAU,CAAA,CAAE,QAAA;AAAA,MACZ,OAAO,CAAA,CAAE,KAAA;AAAA,MACT,YAAY,CAAA,CAAE;AAAA,KAChB,CAAE,CAAA;AACF,IAAA,OAAO,EAAE,KAAA,GAAQ,GAAA,CAAI,MAAM,CAAA,EAAG,CAAA,CAAE,KAAK,CAAA,GAAI,GAAA;AAAA,EAC3C;AAAA,EAEA,OAAO,OAAO,SAAA,EAAgD;AAC5D,IAAA,MAAM,IAAA,GAAO,MAAM,IAAA,CAAK,qBAAA,CAAsB,SAAS,CAAA;AACvD,IAAA,KAAA,MAAW,CAAA,IAAK,IAAA,CAAK,MAAA,EAAQ,MAAM,CAAA;AAAA,EACrC;AAAA,EAEA,MAAM,MAAA,CAAO,CAAA,EAAuB,SAAA,EAAgC,YAAA,EAA0D;AAC5H,IAAA,MAAM,KAAA,GAAQ,EAAE,KAAA,IAAS,GAAA;AACzB,IAAA,MAAM,OAAA,GAAU,aAAa,CAAC,CAAA;AAC9B,IAAA,MAAM,eAAe,CAAA,CAAE,KAAA,GAAQ,IAAI,GAAA,CAAI,CAAA,CAAE,KAAK,CAAA,GAAI,IAAA;AAIlD,IAAA,IAAI,GAAA;AACJ,IAAA,IAAI,SAAA,EAAW;AACb,MAAA,GAAA,GAAM,CAAC,SAAS,CAAA;AAAA,IAClB,CAAA,MAAO;AAGL,MAAA,MAAM,kBAAkB,IAAA,CAAK,KAAA;AAW7B,MAAA,IAAI,QAAA;AACJ,MAAA,IAAI,OAAO,eAAA,CAAgB,YAAA,KAAiB,UAAA,EAAY;AACtD,QAAA,QAAA,GAAW,MAAM,gBAAgB,YAAA,CAAa;AAAA,UAC5C,OAAO,YAAA,EAAc,KAAA;AAAA,UACrB,OAAO,YAAA,EAAc,KAAA;AAAA,UACrB,UAAU,YAAA,EAAc,QAAA;AAAA,UACxB,OAAO,YAAA,EAAc,KAAA;AAAA,UACrB,WAAW,YAAA,EAAc,SAAA;AAAA,UACzB,eAAe,YAAA,EAAc,aAAA;AAAA,UAC7B,KAAA,EAAO;AAAA,SACR,CAAA;AAAA,MACH,CAAA,MAAO;AACL,QAAA,QAAA,GAAW,MAAM,IAAA,CAAK,KAAA,CAAM,IAAA,CAAK,GAAI,CAAA;AACrC,QAAA,MAAM,WAAA,GAAc,YAAA,EAAc,aAAA,EAAe,WAAA,EAAY;AAC7D,QAAA,QAAA,GAAW,QAAA,CAAS,MAAA,CAAO,CAAC,CAAA,KAAM;AAChC,UAAA,IAAI,cAAc,KAAA,IAAS,CAAA,CAAE,SAAA,GAAY,YAAA,CAAa,OAAO,OAAO,KAAA;AACpE,UAAA,IAAI,cAAc,KAAA,IAAS,CAAA,CAAE,SAAA,GAAY,YAAA,CAAa,OAAO,OAAO,KAAA;AACpE,UAAA,IAAI,cAAc,QAAA,IAAY,CAAA,CAAE,QAAA,KAAa,YAAA,CAAa,UAAU,OAAO,KAAA;AAC3E,UAAA,IAAI,cAAc,KAAA,IAAS,CAAA,CAAE,KAAA,KAAU,YAAA,CAAa,OAAO,OAAO,KAAA;AAClE,UAAA,IAAI,cAAc,SAAA,KAAc,MAAA,IAAa,EAAE,UAAA,GAAa,YAAA,CAAa,WAAW,OAAO,KAAA;AAC3F,UAAA,IAAI,WAAA,IAAe,CAAC,CAAA,CAAE,KAAA,CAAM,aAAY,CAAE,QAAA,CAAS,WAAW,CAAA,EAAG,OAAO,KAAA;AACxE,UAAA,OAAO,IAAA;AAAA,QACT,CAAC,CAAA;AAAA,MACH;AACA,MAAA,GAAA,GAAM,QAAA,CAAS,GAAA,CAAI,CAAC,CAAA,KAAM,EAAE,EAAE,CAAA;AAAA,IAChC;AAEA,IAAA,MAAM,OAA2B,EAAC;AAOlC,IAAA,MAAM,YAAY,IAAA,CAAK,KAAA,CAAM,YAAA,EAAc,IAAA,CAAK,KAAK,KAAK,CAAA;AAC1D,IAAA,IAAI,SAAA,EAAW;AACb,MAAA,KAAA,MAAW,MAAM,GAAA,EAAK;AACpB,QAAA,MAAM,UAAU,MAAM,SAAA;AAAA,UACpB,EAAA;AAAA,UACA,CAAC,EAAA,KAAO;AACN,YAAA,IAAI,gBAAgB,CAAC,YAAA,CAAa,IAAI,EAAA,CAAG,IAAI,GAAG,OAAO,KAAA;AACvD,YAAA,MAAM,IAAA,GAAO,UAAU,EAAE,CAAA;AACzB,YAAA,IAAI,IAAA,KAAS,MAAM,OAAO,KAAA;AAC1B,YAAA,OAAO,OAAA,CAAQ,IAAI,CAAA,KAAM,IAAA;AAAA,UAC3B,CAAA;AAAA,UACA,EAAE,KAAA,EAAO,KAAA,GAAQ,IAAA,CAAK,MAAA;AAAO,SAC/B;AACA,QAAA,KAAA,MAAW,KAAK,OAAA,EAAS;AACvB,UAAA,MAAM,IAAA,GAAO,aAAA,CAAc,SAAA,CAAU,CAAA,CAAE,KAAK,CAAC,CAAA;AAC7C,UAAA,MAAM,GAAA,GAAM,aAAA,CAAc,OAAA,CAAQ,IAAI,CAAC,CAAA;AACvC,UAAA,IAAA,CAAK,IAAA,CAAK;AAAA,YACR,SAAA,EAAW,EAAA;AAAA,YACX,YAAY,CAAA,CAAE,UAAA;AAAA,YACd,IAAI,CAAA,CAAE,EAAA;AAAA,YACN,IAAA,EAAM,EAAE,KAAA,CAAM,IAAA;AAAA,YACd,SAAS,SAAA,CAAU,IAAA,EAAM,GAAA,CAAI,KAAA,EAAO,IAAI,GAAG;AAAA,WAC5C,CAAA;AACD,UAAA,IAAI,IAAA,CAAK,MAAA,IAAU,KAAA,EAAO,OAAO,IAAA;AAAA,QACnC;AAAA,MACF;AACA,MAAA,OAAO,IAAA;AAAA,IACT;AAKA,IAAA,KAAA,MAAW,MAAM,GAAA,EAAK;AACpB,MAAA,IAAI,IAAA;AACJ,MAAA,IAAI;AACF,QAAA,IAAA,GAAO,MAAM,IAAA,CAAK,qBAAA,CAAsB,EAAE,CAAA;AAAA,MAC5C,CAAA,CAAA,MAAQ;AACN,QAAA;AAAA,MACF;AACA,MAAA,KAAA,IAAS,IAAI,CAAA,EAAG,CAAA,GAAI,IAAA,CAAK,MAAA,CAAO,QAAQ,CAAA,EAAA,EAAK;AAC3C,QAAA,MAAM,EAAA,GAAK,aAAA,CAAc,IAAA,CAAK,MAAA,CAAO,CAAC,CAAC,CAAA;AACvC,QAAA,IAAI,gBAAgB,CAAC,YAAA,CAAa,GAAA,CAAI,EAAA,CAAG,IAAI,CAAA,EAAG;AAChD,QAAA,MAAM,IAAA,GAAO,UAAU,EAAE,CAAA;AACzB,QAAA,IAAI,SAAS,IAAA,EAAM;AACnB,QAAA,MAAM,GAAA,GAAM,QAAQ,IAAI,CAAA;AACxB,QAAA,IAAI,CAAC,GAAA,EAAK;AACV,QAAA,IAAA,CAAK,IAAA,CAAK;AAAA,UACR,SAAA,EAAW,EAAA;AAAA,UACX,UAAA,EAAY,CAAA;AAAA,UACZ,IAAI,EAAA,CAAG,EAAA;AAAA,UACP,MAAM,EAAA,CAAG,IAAA;AAAA,UACT,SAAS,SAAA,CAAU,IAAA,EAAM,GAAA,CAAI,KAAA,EAAO,IAAI,GAAG;AAAA,SAC5C,CAAA;AACD,QAAA,IAAI,IAAA,CAAK,MAAA,IAAU,KAAA,EAAO,OAAO,IAAA;AAAA,MACnC;AAAA,IACF;AACA,IAAA,OAAO,IAAA;AAAA,EACT;AAAA,EAEA,MAAM,MAAA,CAAO,SAAA,EAAmB,IAAA,EAA6C;AAC3E,IAAA,MAAM,IAAA,GAAO,MAAM,IAAA,CAAK,qBAAA,CAAsB,SAAS,CAAA;AACvD,IAAA,MAAM,YAAA,GAAe,KAAK,YAAA,IAAgB,IAAA;AAC1C,IAAA,MAAM,kBAAA,GAAqB,KAAK,kBAAA,IAAsB,IAAA;AAEtD,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,MAAA,CAAO,MAAA,CAAO,CAAC,CAAA,KAAM;AACzC,MAAA,IACE,CAAC,YAAA,KACA,CAAA,CAAE,IAAA,KAAS,UAAA,IACV,CAAA,CAAE,IAAA,KAAS,aAAA,IACX,CAAA,CAAE,IAAA,KAAS,iBAAA,IACX,CAAA,CAAE,SAAS,eAAA,CAAA,EACb;AACA,QAAA,OAAO,KAAA;AAAA,MACT;AACA,MAAA,IACE,CAAC,kBAAA,KACA,CAAA,CAAE,IAAA,KAAS,OAAA,IAAW,EAAE,IAAA,KAAS,YAAA,IAAgB,CAAA,CAAE,IAAA,KAAS,mBAAA,CAAA,EAC7D;AACA,QAAA,OAAO,KAAA;AAAA,MACT;AACA,MAAA,OAAO,IAAA;AAAA,IACT,CAAC,CAAA;AAED,IAAA,IAAI,IAAA,CAAK,WAAW,MAAA,EAAQ;AAC1B,MAAA,OAAO,IAAA,CAAK,SAAA,CAAU,EAAE,QAAA,EAAU,IAAA,CAAK,UAAU,MAAA,EAAQ,QAAA,EAAS,EAAG,IAAA,EAAM,CAAC,CAAA;AAAA,IAC9E;AACA,IAAA,IAAI,IAAA,CAAK,WAAW,MAAA,EAAQ;AAC1B,MAAA,OAAO,eAAA,CAAgB,IAAA,CAAK,QAAA,EAAU,QAAQ,CAAA;AAAA,IAChD;AACA,IAAA,OAAO,cAAA,CAAe,IAAA,CAAK,QAAA,EAAU,QAAQ,CAAA;AAAA,EAC/C;AAAA,EAEA,MAAM,SAAS,SAAA,EAA6C;AAC1D,IAAA,MAAM,IAAA,GAAO,MAAM,IAAA,CAAK,qBAAA,CAAsB,SAAS,CAAA;AACvD,IAAA,OAAO,IAAA,CAAK,QAAA;AAAA,EACd;AACF;AAEA,SAAS,aACP,CAAA,EACyD;AACzD,EAAA,MAAM,EAAA,GAAK,EAAE,eAAA,IAAmB,IAAA;AAChC,EAAA,IAAI,EAAE,KAAA,EAAO;AACX,IAAA,MAAM,KAAA,GAAQ,KAAK,GAAA,GAAM,EAAA;AACzB,IAAA,MAAM,QAAA,GAAW,gBAAA,CAAiB,CAAA,CAAE,KAAA,EAAO,KAAK,CAAA;AAChD,IAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,MAAA,MAAM,IAAI,MAAM,CAAA,sBAAA,EAAyB,CAAA,CAAE,KAAK,CAAA,GAAA,EAAM,QAAA,CAAS,MAAM,CAAA,CAAE,CAAA;AAAA,IACzE;AACA,IAAA,MAAM,KAAK,QAAA,CAAS,KAAA;AACpB,IAAA,OAAO,CAAC,IAAA,KAAS;AACf,MAAA,MAAM,CAAA,GAAI,EAAA,CAAG,IAAA,CAAK,IAAI,CAAA;AACtB,MAAA,OAAO,CAAA,GAAI,EAAE,KAAA,EAAO,CAAA,CAAE,KAAA,EAAO,GAAA,EAAK,CAAA,CAAE,KAAA,GAAQ,CAAA,CAAE,CAAC,CAAA,CAAE,MAAA,EAAO,GAAI,IAAA;AAAA,IAC9D,CAAA;AAAA,EACF;AACA,EAAA,MAAM,SAAS,EAAA,GAAK,CAAA,CAAE,KAAA,CAAM,WAAA,KAAgB,CAAA,CAAE,KAAA;AAC9C,EAAA,OAAO,CAAC,IAAA,KAAS;AACf,IAAA,MAAM,GAAA,GAAM,EAAA,GAAK,IAAA,CAAK,WAAA,EAAY,GAAI,IAAA;AACtC,IAAA,MAAM,GAAA,GAAM,GAAA,CAAI,OAAA,CAAQ,MAAM,CAAA;AAC9B,IAAA,OAAO,GAAA,KAAQ,KAAK,IAAA,GAAO,EAAE,OAAO,GAAA,EAAK,GAAA,EAAK,GAAA,GAAM,MAAA,CAAO,MAAA,EAAO;AAAA,EACpE,CAAA;AACF;AAEA,SAAS,UAAU,CAAA,EAAgC;AACjD,EAAA,QAAQ,EAAE,IAAA;AAAM,IACd,KAAK,YAAA;AACH,MAAA,OAAO,eAAA,CAAgB,EAAE,OAAO,CAAA;AAAA,IAClC,KAAK,cAAA;AACH,MAAA,OAAO,eAAA,CAAgB,EAAE,OAAO,CAAA;AAAA,IAClC,KAAK,UAAA;AACH,MAAA,OAAO,CAAA,EAAG,EAAE,IAAI,CAAA,CAAA,EAAI,KAAK,SAAA,CAAU,CAAA,CAAE,KAAK,CAAC,CAAA,CAAA;AAAA,IAC7C,KAAK,aAAA;AACH,MAAA,OAAO,OAAO,EAAE,OAAA,KAAY,QAAA,GAAW,EAAE,OAAA,GAAU,IAAA,CAAK,SAAA,CAAU,CAAA,CAAE,OAAO,CAAA;AAAA,IAC7E,KAAK,OAAA;AACH,MAAA,OAAO,CAAA,EAAG,CAAA,CAAE,KAAK,CAAA,EAAA,EAAK,EAAE,OAAO,CAAA,CAAA;AAAA,IACjC,KAAK,eAAA;AAAA,IACL,KAAK,iBAAA;AACH,MAAA,OAAO,CAAA,EAAG,CAAA,CAAE,KAAK,CAAA,CAAA,EAAI,EAAE,QAAQ,CAAA,CAAA;AAAA,IACjC,KAAK,cAAA;AAAA,IACL,KAAK,gBAAA;AACH,MAAA,OAAO,CAAA,CAAE,KAAA;AAAA,IACX,KAAK,aAAA;AACH,MAAA,OAAO,CAAA,EAAG,CAAA,CAAE,KAAK,CAAA,EAAA,EAAK,EAAE,KAAK,CAAA,CAAA;AAAA,IAC/B,KAAK,iBAAA;AAAA,IACL,KAAK,mBAAA;AACH,MAAA,OAAO,CAAA,CAAE,SAAA;AAAA,IACX;AACE,MAAA,OAAO,IAAA;AAAA;AAEb;AAEA,SAAS,gBAAgB,OAAA,EAA0C;AACjE,EAAA,IAAI,OAAO,OAAA,KAAY,QAAA,EAAU,OAAO,OAAA;AACxC,EAAA,OAAO,OAAA,CACJ,GAAA,CAAI,CAAC,CAAA,KAAM;AACV,IAAA,QAAQ,EAAE,IAAA;AAAM,MACd,KAAK,MAAA;AACH,QAAA,OAAO,CAAA,CAAE,IAAA;AAAA,MACX,KAAK,UAAA;AACH,QAAA,OAAO,CAAA,UAAA,EAAa,EAAE,IAAI,CAAA,CAAA,EAAI,KAAK,SAAA,CAAU,CAAA,CAAE,KAAK,CAAC,CAAA,CAAA,CAAA;AAAA,MACvD,KAAK,aAAA;AACH,QAAA,OAAO,OAAO,EAAE,OAAA,KAAY,QAAA,GAAW,EAAE,OAAA,GAAU,IAAA,CAAK,SAAA,CAAU,CAAA,CAAE,OAAO,CAAA;AAAA,MAC7E;AACE,QAAA,OAAO,EAAA;AAAA;AACX,EACF,CAAC,CAAA,CACA,IAAA,CAAK,IAAI,CAAA;AACd;AAEA,IAAM,cAAA,GAAiB,EAAA;AAEvB,SAAS,SAAA,CAAU,IAAA,EAAc,KAAA,EAAe,GAAA,EAAqB;AACnE,EAAA,MAAM,IAAA,GAAO,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,QAAQ,cAAc,CAAA;AAC/C,EAAA,MAAM,KAAK,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,MAAA,EAAQ,MAAM,cAAc,CAAA;AACrD,EAAA,MAAM,MAAA,GAAS,IAAA,GAAO,CAAA,GAAI,QAAA,GAAM,EAAA;AAChC,EAAA,MAAM,MAAA,GAAS,EAAA,GAAK,IAAA,CAAK,MAAA,GAAS,QAAA,GAAM,EAAA;AACxC,EAAA,OAAO,MAAA,GAAS,IAAA,CAAK,KAAA,CAAM,IAAA,EAAM,EAAE,CAAA,CAAE,OAAA,CAAQ,MAAA,EAAQ,GAAG,CAAA,CAAE,IAAA,EAAK,GAAI,MAAA;AACrE;AAEA,SAAS,cAAA,CAAe,MAAuB,MAAA,EAAgC;AAC7E,EAAA,MAAM,QAAkB,EAAC;AACzB,EAAA,KAAA,CAAM,IAAA,CAAK,CAAA,UAAA,EAAa,IAAA,CAAK,EAAE,CAAA,CAAE,CAAA;AACjC,EAAA,KAAA,CAAM,KAAK,EAAE,CAAA;AACb,EAAA,IAAI,IAAA,CAAK,KAAA,IAAS,IAAA,CAAK,QAAA,EAAU;AAC/B,IAAA,KAAA,CAAM,IAAA,CAAK,gBAAgB,IAAA,CAAK,QAAA,IAAY,GAAG,CAAA,CAAA,EAAI,IAAA,CAAK,KAAA,IAAS,GAAG,CAAA,CAAE,CAAA;AAAA,EACxE;AACA,EAAA,KAAA,CAAM,IAAA,CAAK,CAAA,eAAA,EAAkB,IAAA,CAAK,SAAS,CAAA,CAAE,CAAA;AAC7C,EAAA,IAAI,KAAK,OAAA,EAAS,KAAA,CAAM,KAAK,CAAA,aAAA,EAAgB,IAAA,CAAK,OAAO,CAAA,CAAE,CAAA;AAC3D,EAAA,KAAA,CAAM,KAAK,EAAE,CAAA;AACb,EAAA,KAAA,CAAM,KAAK,KAAK,CAAA;AAChB,EAAA,KAAA,CAAM,KAAK,EAAE,CAAA;AACb,EAAA,KAAA,MAAW,KAAK,MAAA,EAAQ;AACtB,IAAA,QAAQ,EAAE,IAAA;AAAM,MACd,KAAK,YAAA,EAAc;AACjB,QAAA,KAAA,CAAM,IAAA,CAAK,CAAA,eAAA,EAAa,CAAA,CAAE,EAAE,CAAA,CAAE,CAAA;AAC9B,QAAA,KAAA,CAAM,KAAK,EAAE,CAAA;AACb,QAAA,KAAA,CAAM,IAAA,CAAK,eAAA,CAAgB,CAAA,CAAE,OAAO,CAAC,CAAA;AACrC,QAAA,KAAA,CAAM,KAAK,EAAE,CAAA;AACb,QAAA;AAAA,MACF;AAAA,MACA,KAAK,cAAA,EAAgB;AACnB,QAAA,KAAA,CAAM,IAAA,CAAK,CAAA,oBAAA,EAAkB,CAAA,CAAE,EAAE,CAAA,CAAE,CAAA;AACnC,QAAA,KAAA,CAAM,KAAK,EAAE,CAAA;AACb,QAAA,KAAA,CAAM,IAAA,CAAK,eAAA,CAAgB,CAAA,CAAE,OAAO,CAAC,CAAA;AACrC,QAAA,IAAI,CAAA,CAAE,UAAA,IAAc,CAAA,CAAE,UAAA,KAAe,UAAA,EAAY;AAC/C,UAAA,KAAA,CAAM,KAAK,EAAE,CAAA;AACb,UAAA,KAAA,CAAM,IAAA,CAAK,CAAA,OAAA,EAAU,CAAA,CAAE,UAAU,CAAA,CAAA,CAAG,CAAA;AAAA,QACtC;AACA,QAAA,KAAA,CAAM,KAAK,EAAE,CAAA;AACb,QAAA;AAAA,MACF;AAAA,MACA,KAAK,UAAA,EAAY;AACf,QAAA,KAAA,CAAM,IAAA,CAAK,CAAA,iBAAA,EAAoB,CAAA,CAAE,IAAI,CAAA,EAAA,CAAI,CAAA;AACzC,QAAA,KAAA,CAAM,KAAK,EAAE,CAAA;AACb,QAAA,KAAA,CAAM,KAAK,SAAS,CAAA;AACpB,QAAA,KAAA,CAAM,KAAK,IAAA,CAAK,SAAA,CAAU,EAAE,KAAA,EAAO,IAAA,EAAM,CAAC,CAAC,CAAA;AAC3C,QAAA,KAAA,CAAM,KAAK,KAAK,CAAA;AAChB,QAAA,KAAA,CAAM,KAAK,EAAE,CAAA;AACb,QAAA;AAAA,MACF;AAAA,MACA,KAAK,aAAA,EAAe;AAClB,QAAA,MAAM,IAAA,GAAO,OAAO,CAAA,CAAE,OAAA,KAAY,QAAA,GAAW,CAAA,CAAE,OAAA,GAAU,IAAA,CAAK,SAAA,CAAU,CAAA,CAAE,OAAA,EAAS,IAAA,EAAM,CAAC,CAAA;AAC1F,QAAA,KAAA,CAAM,KAAK,CAAA,eAAA,EAAkB,CAAA,CAAE,OAAA,GAAU,UAAA,GAAa,EAAE,CAAA,CAAE,CAAA;AAC1D,QAAA,KAAA,CAAM,KAAK,EAAE,CAAA;AACb,QAAA,KAAA,CAAM,KAAK,KAAK,CAAA;AAChB,QAAA,KAAA,CAAM,KAAK,IAAI,CAAA;AACf,QAAA,KAAA,CAAM,KAAK,KAAK,CAAA;AAChB,QAAA,KAAA,CAAM,KAAK,EAAE,CAAA;AACb,QAAA;AAAA,MACF;AAAA,MACA,KAAK,OAAA,EAAS;AACZ,QAAA,KAAA,CAAM,KAAK,CAAA,aAAA,EAAgB,CAAA,CAAE,KAAK,CAAA,GAAA,EAAM,CAAA,CAAE,OAAO,CAAA,CAAE,CAAA;AACnD,QAAA,KAAA,CAAM,KAAK,EAAE,CAAA;AACb,QAAA;AAAA,MACF;AAAA,MACA,KAAK,YAAA,EAAc;AACjB,QAAA,KAAA,CAAM,KAAK,CAAA,kBAAA,EAAqB,CAAA,CAAE,MAAM,CAAA,QAAA,EAAM,CAAA,CAAE,KAAK,CAAA,OAAA,CAAS,CAAA;AAC9D,QAAA,KAAA,CAAM,KAAK,EAAE,CAAA;AACb,QAAA;AAAA,MACF;AAEE;AACJ,EACF;AACA,EAAA,OAAO,KAAA,CAAM,KAAK,IAAI,CAAA;AACxB;AAEA,SAAS,eAAA,CAAgB,MAAuB,MAAA,EAAgC;AAC9E,EAAA,MAAM,QAAkB,EAAC;AACzB,EAAA,KAAA,CAAM,IAAA;AAAA,IACJ,CAAA,QAAA,EAAW,IAAA,CAAK,EAAE,CAAA,QAAA,EAAM,IAAA,CAAK,QAAA,IAAY,GAAG,CAAA,CAAA,EAAI,IAAA,CAAK,KAAA,IAAS,GAAG,CAAA,gBAAA,EAAc,KAAK,SAAS,CAAA;AAAA,GAC/F;AACA,EAAA,KAAA,CAAM,IAAA,CAAK,EAAA,CAAG,MAAA,CAAO,EAAA,EAAI,GAAG,CAAC,CAAA;AAC7B,EAAA,KAAA,MAAW,KAAK,MAAA,EAAQ;AACtB,IAAA,QAAQ,EAAE,IAAA;AAAM,MACd,KAAK,YAAA;AACH,QAAA,KAAA,CAAM,IAAA,CAAK,CAAA,CAAA,EAAI,CAAA,CAAE,EAAE,CAAA,MAAA,CAAQ,CAAA;AAC3B,QAAA,KAAA,CAAM,IAAA,CAAK,eAAA,CAAgB,CAAA,CAAE,OAAO,CAAC,CAAA;AACrC,QAAA,KAAA,CAAM,KAAK,EAAE,CAAA;AACb,QAAA;AAAA,MACF,KAAK,cAAA;AACH,QAAA,KAAA,CAAM,IAAA,CAAK,CAAA,CAAA,EAAI,CAAA,CAAE,EAAE,CAAA,WAAA,CAAa,CAAA;AAChC,QAAA,KAAA,CAAM,IAAA,CAAK,eAAA,CAAgB,CAAA,CAAE,OAAO,CAAC,CAAA;AACrC,QAAA,KAAA,CAAM,KAAK,EAAE,CAAA;AACb,QAAA;AAAA,MACF,KAAK,UAAA;AACH,QAAA,KAAA,CAAM,IAAA,CAAK,CAAA,CAAA,EAAI,CAAA,CAAE,EAAE,CAAA,WAAA,EAAc,CAAA,CAAE,IAAI,CAAA,CAAA,EAAI,IAAA,CAAK,SAAA,CAAU,CAAA,CAAE,KAAK,CAAC,CAAA,CAAE,CAAA;AACpE,QAAA;AAAA,MACF,KAAK,aAAA;AACH,QAAA,KAAA,CAAM,IAAA;AAAA,UACJ,IAAI,CAAA,CAAE,EAAE,gBAAgB,CAAA,CAAE,OAAA,GAAU,aAAa,EAAE,CAAA,CAAA,EACjD,OAAO,CAAA,CAAE,OAAA,KAAY,WAAW,CAAA,CAAE,OAAA,GAAU,KAAK,SAAA,CAAU,CAAA,CAAE,OAAO,CACtE,CAAA;AAAA,SACF;AACA,QAAA;AAAA,MACF,KAAK,OAAA;AACH,QAAA,KAAA,CAAM,IAAA,CAAK,CAAA,CAAA,EAAI,CAAA,CAAE,EAAE,CAAA,SAAA,EAAY,EAAE,KAAK,CAAA,GAAA,EAAM,CAAA,CAAE,OAAO,CAAA,CAAE,CAAA;AACvD,QAAA;AAEA;AACJ,EACF;AACA,EAAA,OAAO,KAAA,CAAM,KAAK,IAAI,CAAA;AACxB","file":"index.js","sourcesContent":["export interface TextBlock {\n type: 'text';\n text: string;\n cache_control?: { type: 'ephemeral' | undefined };\n}\n\nexport interface ToolUseBlock {\n type: 'tool_use';\n id: string;\n name: string;\n input: Record<string, unknown>;\n /**\n * Provider-specific opaque metadata captured from the wire response.\n * Echoed back verbatim in the next request so providers that bind\n * extra state to function calls keep working. Example: Gemini's\n * `thoughtSignature` — required for tool-use turns with thinking\n * models, otherwise the next request fails with 400 \"Function call\n * is missing a thought_signature in functionCall parts\".\n *\n * Keys are namespaced by intent so multiple wires can coexist:\n * - `google.thoughtSignature` — Gemini signed-thought blob\n * Other providers can add their own keys without colliding.\n */\n providerMeta?: Record<string, unknown>;\n}\n\nexport interface ToolResultBlock {\n type: 'tool_result';\n tool_use_id: string;\n /**\n * The original tool name. Useful for providers like Google Gemini that\n * need the tool name in `functionResponse.name` — the tool_use_id is\n * only a session-local identifier and is not stable across replays.\n * Always set by ToolExecutor; may be absent on manually-constructed blocks.\n */\n name?: string | undefined;\n content: string;\n is_error?: boolean | undefined;\n}\n\nexport interface ImageBlock {\n type: 'image';\n source: {\n type: 'base64' | 'url';\n media_type?: string | undefined;\n data?: string | undefined;\n url?: string | undefined;\n };\n}\n\n/**\n * Chain-of-thought / extended-thinking content emitted by the model.\n *\n * Both Anthropic extended thinking (`{type:'thinking', thinking, signature}`)\n * and DeepSeek reasoning mode (top-level `reasoning_content` on the assistant\n * message) require this content to be echoed back verbatim on the next\n * request, otherwise the provider returns 400:\n * - Anthropic: \"The `content[].thinking` in the thinking mode must be passed back\"\n * - DeepSeek: \"The `reasoning_content` in the thinking mode must be passed back\"\n *\n * `signature` is Anthropic-specific (an opaque integrity blob). DeepSeek\n * doesn't issue a signature — the field is absent for that provider.\n *\n * Per Anthropic, thinking blocks MUST appear before any text/tool_use blocks\n * in an assistant message. Stream builders preserve that order.\n */\nexport interface ThinkingBlock {\n type: 'thinking';\n thinking: string;\n signature?: string | undefined;\n providerMeta?: Record<string, unknown>;\n}\n\nexport type ContentBlock = TextBlock | ToolUseBlock | ToolResultBlock | ImageBlock | ThinkingBlock;\n\nexport function isTextBlock(b: ContentBlock): b is TextBlock {\n return b.type === 'text';\n}\nexport function isToolUseBlock(b: ContentBlock): b is ToolUseBlock {\n return b.type === 'tool_use';\n}\nexport function isToolResultBlock(b: ContentBlock): b is ToolResultBlock {\n return b.type === 'tool_result';\n}\nexport function isImageBlock(b: ContentBlock): b is ImageBlock {\n return b.type === 'image';\n}\n","import type { Context } from '../core/context.js';\n\nexport type Permission = 'auto' | 'confirm' | 'deny';\n\n/**\n * Risk tier for tools in YOLO mode. YOLO auto-approves normal project work,\n * while clearly destructive calls still require confirmation.\n *\n * - `safe` — read-only, no side effects (read, glob, grep, etc.)\n * - `standard` — non-destructive writes and mutations (write, edit, safe shell commands)\n * - `destructive` — irreversible or broadside effects (recursive deletes, db drops, etc.)\n */\nexport type RiskTier = 'safe' | 'standard' | 'destructive';\n\n/**\n * Icon identifiers for tools — each UI (WebUI/TUI/REPL) maps these to its own icon library.\n * Add the icon directly on each Tool so all UIs consume the same canonical value.\n */\nexport type ToolIconId =\n | 'file' // read, write — document operations\n | 'edit' // edit, patch — modifying files\n | 'search' // grep, search — searching content\n | 'folder' // glob — file discovery\n | 'terminal' // bash, exec — shell commands\n | 'web' // fetch — HTTP requests\n | 'git' // git — version control\n | 'tree' // tree — directory structure\n | 'code' // lint, format, typecheck — code quality\n | 'test' // test — testing\n | 'package' // install, audit, outdated — package management\n | 'document' // document — documentation\n | 'scaffold' // scaffold — project generation\n | 'todo' // todo — task tracking\n | 'plan' // plan — planning\n | 'task' // task — structured work items\n | 'meta' // tool-use, batch-tool-use, tool-search, tool-help — meta tools\n | 'index' // codebase-index, codebase-search, codebase-stats — code indexing\n | 'json' // json — JSON operations\n | 'diff' // diff — comparing changes\n | 'logs' // logs — log viewing\n | 'settings' // set-working-dir — configuration\n | 'fallback'; // unknown tool — fallback icon\n\nexport interface JSONSchema {\n type?: string | undefined;\n properties?: Record<string, JSONSchema>;\n required?: string[] | undefined;\n items?: JSONSchema | undefined;\n enum?: unknown[] | undefined;\n description?: string | undefined;\n [k: string]: unknown;\n}\n\n/**\n * Tool progress event — yielded by `Tool.executeStream` to give the UI\n * something to render while a long-running tool works. The executor\n * publishes each event via EventBus as `tool.progress` so the TUI, logger,\n * and observability layer can consume them uniformly.\n *\n * Keep events small. They are buffered through the EventBus synchronously\n * and rendered on the main thread.\n */\nexport interface ToolProgressEvent {\n /**\n * - `log` — verbose informational message (e.g. \"scanning…\")\n * - `warning` — non-fatal issue (e.g. \"skipped X due to ENOENT\")\n * - `metric` — numeric data (e.g. files scanned so far)\n * - `file_changed` — a tool that mutates the workspace announces a write\n * - `partial_output` — stream of textual output (bash stdout, fetch body)\n */\n type: 'log' | 'warning' | 'metric' | 'file_changed' | 'partial_output';\n text?: string | undefined;\n data?: Record<string, unknown>;\n}\n\n/**\n * Terminal event for `executeStream`. The output must match the tool's\n * declared output type — the executor unwraps `output` and treats it like\n * a normal `execute` return value.\n */\nexport interface ToolFinalEvent<O> {\n type: 'final';\n output: O;\n}\n\nexport type ToolStreamEvent<O = unknown> = ToolProgressEvent | ToolFinalEvent<O>;\n\nexport interface Tool<I = unknown, O = unknown> {\n name: string;\n description: string;\n /**\n * Pre-computed token estimate for this tool's definition (name +\n * description + JSON-serialized inputSchema). Set by ToolRegistry on\n * registration; consumed by estimateToolDefTokens / estimateRequestTokens\n * to skip redundant JSON.stringify on every context-pressure check.\n */\n _estDefTokens?: number | undefined;\n usageHint?: string | undefined;\n /** Optional category for grouping in help lists and system prompts. */\n category?: string | undefined;\n inputSchema: JSONSchema;\n permission: Permission;\n mutating: boolean;\n /**\n * Risk tier for selective YOLO gating. When YOLO is active, clearly\n * destructive calls still emit `confirm`. Defaults to `standard` when\n * omitted — callers should always check `riskTier` after the basic\n * permission decision.\n */\n riskTier?: RiskTier | undefined;\n /**\n * Input-field name that the permission policy should match trust rules\n * against. Without this, the policy falls back to a heuristic\n * (`command` / `path` / `url` / `name`) that can collide across tools —\n * e.g. an HTTP tool whose `path` means \"request path\" would be checked\n * against filesystem-path trust rules. Set explicitly to avoid the\n * cross-tool subject collision.\n *\n * The named field's value must be a string at runtime; non-string values\n * fall back to the heuristic.\n */\n subjectKey?: string | undefined;\n maxOutputBytes?: number | undefined;\n timeoutMs?: number | undefined;\n /**\n * Hint for the TUI spinner — does NOT affect actual timeout enforcement.\n * Use `timeoutMs` for hard limits. Leave undefined when duration varies\n * unpredictably.\n */\n estimatedDurationMs?: number | undefined;\n\n /**\n * Declarative security capabilities granted by this tool.\n *\n * Examples: \"shell.arbitrary\", \"fs.write\", \"fs.write.outside-project\",\n * \"net.outbound\", \"mcp.proxy\", \"subagent.spawn\", \"config.mutate\".\n *\n * These are used by permission policies (especially subagent guards) and\n * future capability-based allowlists. Prefer well-known values over ad-hoc strings.\n *\n * This field is optional for backward compatibility. Tools without it are\n * treated conservatively by guards.\n */\n capabilities?: readonly string[] | undefined;\n /**\n * Icon identifier for this tool — consumed by all UIs (WebUI/TUI/REPL) to\n * render a tool-specific icon instead of a generic fallback.\n * Each UI maps this id to its own icon library.\n */\n icon?: ToolIconId | undefined;\n execute(input: I, ctx: Context, opts: { signal: AbortSignal }): Promise<O>;\n /**\n * Optional cross-field validation hook. Called by the executor AFTER\n * JSON Schema validation passes and AFTER PreToolUse hooks may have\n * rewritten the input, but BEFORE permission checks and execution.\n *\n * Use this for invariants the JSON Schema cannot express — e.g.\n * `old_string !== new_string` in edit, or `end > start` in a range tool.\n * Return an array of validation errors (empty = valid). The executor\n * surfaces them to the model just like schema validation errors, so the\n * model can self-correct without the tool's `execute()` running.\n *\n * P3 #16 (before-release.md): tools that implement cross-field checks\n * inside `execute()` can migrate them here for earlier rejection and\n * consistent error formatting.\n */\n validate?(input: I): string[];\n /**\n * Optional streaming variant. When defined, the executor prefers this\n * over `execute` — yielded events become `tool.progress` EventBus events\n * and the terminal `final` event provides the output. Tools that don't\n * have intermediate state shouldn't implement this; the default `execute`\n * path is more efficient.\n */\n executeStream?(\n input: I,\n ctx: Context,\n opts: { signal: AbortSignal },\n ): AsyncIterable<ToolStreamEvent<O>>;\n /**\n * Optional teardown hook fired by the executor when the tool's run is\n * aborted (signal triggered). Errors thrown here are swallowed so they\n * never mask the originating failure.\n *\n * **When to use `cleanup` vs `ctx.registerAbortHook`:**\n *\n * - Use `cleanup` for resources **owned by the tool author** that are\n * established at execute-time: child processes spawned by the tool,\n * file handles opened by the tool, network connections initiated by\n * the tool. The lifecycle is co-located with the tool definition, so\n * readers see the resource and its teardown in one place.\n *\n * ```ts\n * async execute(input, ctx, opts) {\n * const child = spawn(...);\n * // … tool work …\n * },\n * async cleanup(_input, _ctx) {\n * // best-effort kill of any child still running\n * }\n * ```\n *\n * - Use `ctx.registerAbortHook` for **context-scoped teardown** registered\n * dynamically inside `execute`: when the tool delegates to a library\n * that needs cancellation, or when the resource is created lazily\n * somewhere down the call stack and the natural cleanup point isn't\n * at the tool boundary. The hook fires when the **agent run** ends,\n * not when this specific tool call aborts.\n *\n * ```ts\n * async execute(input, ctx, opts) {\n * const handle = openHelper();\n * ctx.registerAbortHook(() => handle.dispose());\n * // … work …\n * }\n * ```\n *\n * If both are registered for the same resource, `cleanup` fires first\n * (on tool abort) and the abort-hook fires after on the wider run abort.\n * Avoid double-free by gating one on the other's effect, or pick a single\n * teardown channel per resource.\n */\n cleanup?(input: I, ctx: Context): Promise<void>;\n /**\n * Optional custom output serializer. When present, the executor's output\n * serializer calls this INSTEAD of the central `renderToolObject()` switch\n * — the tool owns its own pretty-printing.\n *\n * Return a string representation of the output that the model will see in\n * its tool_result block. The serializer applies the iteration output cap\n * AFTER this runs, so don't worry about truncation.\n *\n * P3 #21 (before-release.md): `renderToolObject()` is a god function with\n * 30+ per-tool branches, far from each tool's definition. New tools that\n * want custom output no longer need to add a branch there — they implement\n * this method instead. Existing branches stay until migrated incrementally.\n */\n serialize?(output: O, input: I): string;\n}\n\nexport interface ToolCallContext {\n tool: Tool;\n input: unknown;\n callId: string;\n ctx: Context;\n signal: AbortSignal;\n}\n\n/**\n * Error categories for tool execution failures.\n * Used by the executor to classify errors and determine retry strategy.\n */\nexport enum ToolErrorCategory {\n TRANSIENT = \"transient\", // ETIMEDOUT, ECONNRESET, network timeout, HTTP 429/503\n NOT_FOUND = \"not_found\", // ENOENT, ENOTDIR, HTTP 404\n PERMISSION = \"permission\", // EACCES, EPERM, HTTP 401/403\n VALIDATION = \"validation\", // schema validation error, HTTP 400\n FATAL = \"fatal\", // unhandled exception, crash, invariant violation\n}\n\n/**\n * Structured tool error information for the LLM and retry logic.\n */\nexport interface ToolErrorInfo {\n readonly category: ToolErrorCategory;\n /** Whether the operation can be retried automatically. */\n readonly retryable: boolean;\n /** User-facing message describing the error. */\n readonly userMessage: string;\n /** Optional technical detail for debugging. */\n readonly detail?: string;\n}\n","/**\n * Sentinel keys provider adapters use to wrap tool-call arguments that could\n * not be parsed into a proper JSON object. Single source of truth — the core\n * tool executor (which DETECTS these markers to surface a friendly error)\n * defines them here, and the providers package (which PRODUCES them when\n * wrapping) imports from `@wrongstack/core`.\n *\n * P3 #14 (before-release.md): the list was duplicated in tool-executor.ts with\n * a \"Keep this list in sync\" comment — a manual rule that will eventually be\n * forgotten. Centralizing it removes the sync burden.\n *\n * Layering note: this lives in core (not providers) because the dependency\n * direction is providers → core, not the reverse. Putting it in providers\n * would force core into a forbidden upward dependency.\n *\n * Current markers:\n * - `__raw` — produced by `parseToolInput` (Anthropic / shared)\n * - `__raw_arguments` — produced by `contentFromOpenAI` (OpenAI / compatible)\n * - `_raw` — produced by the streaming response builder's\n * `safeJsonOrRaw` (legacy fallback)\n */\nexport const MALFORMED_ARG_MARKERS = ['__raw', '__raw_arguments', '_raw'] as const;\n","/**\n * Converts an unknown error value to a human-readable string.\n * Used in 40+ files across the codebase to normalize error messaging.\n */\nexport function toErrorMessage(err: unknown): string {\n return err instanceof Error ? err.message : String(err);\n}\n","/** Assert a value is neither null nor undefined. Throws if it is.\n * Useful after optional chaining and indexed access when the\n * control flow guarantees the value exists but TypeScript can't\n * prove it (e.g. after a check on a related field). */\nexport function expectDefined<T>(value: T | null | undefined, label?: string): T {\n if (value === null || value === undefined) {\n const err = new Error(label ? `Expected ${label} to be defined` : 'Expected value to be defined');\n err.name = 'ExpectDefinedError';\n throw err;\n }\n return value;\n}\n","/**\n * Compile a user-supplied regex with conservative bounds against ReDoS.\n *\n * Duplicated from @wrongstack/tools/_regex.ts to avoid a circular\n * dependency (tools depends on core, not vice versa). Keep both copies\n * in sync if the heuristics change.\n *\n * V8's regex engine is backtracking-based and cannot interrupt a\n * synchronous match — a pattern like `(a+)+$` against a sufficiently\n * long line will pin a worker for seconds.\n */\n\nconst MAX_PATTERN_LEN = 512;\n\n// Heuristics for catastrophic-backtracking constructs.\nconst DANGEROUS_PATTERNS: ReadonlyArray<RegExp> = [\n /(\\([^)]*[+*][^)]*\\))[+*]/, // (a+)+, (.*)+, etc\n /(\\(\\?:[^)]*[+*][^)]*\\))[+*]/, // same, with non-capturing group\n];\n\nexport interface CompileResult {\n ok: true;\n regex: RegExp;\n}\n\nexport interface CompileFail {\n ok: false;\n reason: string;\n}\n\nexport function compileUserRegex(pattern: string, flags: string): CompileResult | CompileFail {\n if (typeof pattern !== 'string') {\n return { ok: false, reason: 'pattern must be a string' };\n }\n if (pattern.length === 0) {\n return { ok: false, reason: 'pattern is empty' };\n }\n if (pattern.length > MAX_PATTERN_LEN) {\n return { ok: false, reason: `pattern exceeds ${MAX_PATTERN_LEN} characters` };\n }\n for (const rx of DANGEROUS_PATTERNS) {\n if (rx.test(pattern)) {\n return {\n ok: false,\n reason:\n 'pattern looks vulnerable to catastrophic backtracking — rewrite without nested quantifiers',\n };\n }\n }\n try {\n return { ok: true, regex: new RegExp(pattern, flags) };\n } catch (err) {\n return {\n ok: false,\n reason: err instanceof Error ? err.message : 'invalid regex',\n };\n }\n}\n","import * as path from 'node:path';\nimport { ERROR_CODES, FsError } from '../types/errors.js';\n\n/**\n * Resolve `<dir>/<sessionId><suffix>` for per-session sidecar files\n * (annotations, audit chain, replay log, the session JSONL itself).\n *\n * Modern session ids are date-sharded (\"2026-06-11/sess_<ULID>\"),\n * so a forward slash is a legitimate shard separator — NOT traversal.\n * Escape attempts are blocked two ways: an explicit ban on `..` and\n * backslashes, plus a resolved-path containment check that rejects any\n * id whose resolved target leaves `dir`. Character bans alone are how\n * several stores ended up throwing on every modern session id.\n */\nexport function sessionScopedPath(dir: string, sessionId: string, suffix: string): string {\n if (!sessionId || sessionId.includes('\\\\') || sessionId.includes('..')) {\n throw invalid(sessionId);\n }\n const resolved = path.resolve(dir, `${sessionId}${suffix}`);\n const rel = path.relative(path.resolve(dir), resolved);\n if (rel.startsWith('..') || path.isAbsolute(rel)) {\n throw invalid(sessionId);\n }\n return resolved;\n}\n\nfunction invalid(sessionId: string): FsError {\n return new FsError({\n message: `Invalid sessionId: ${sessionId}`,\n code: ERROR_CODES.FS_DELETE_FAILED,\n path: sessionId,\n context: { reason: 'path_traversal' },\n });\n}\n","/**\n * String utilities shared across the WrongStack codebase.\n */\n\n/**\n * Truncate a string to at most `max` characters, appending an ellipsis if it\n * was longer. Returns the original string unchanged when it fits.\n */\nexport function truncate(s: string, max: number): string {\n return s.length <= max ? s : `${s.slice(0, max - 1)}…`;\n}\n","import { toErrorMessage } from '../utils/index.js';\n\n/**\n * WrongStack error hierarchy.\n *\n * Every error thrown by the framework is a `WrongStackError` with a\n * machine-readable `code`, a `subsystem` tag, and a `severity` level.\n * This lets consumers (CLI, TUI, plugins, tests) branch on structured\n * data instead of parsing error messages.\n */\n\n// ── Error codes ──────────────────────────────────────────────────────\n\n/**\n * Machine-readable error codes as frozen constants.\n *\n * Use `ERROR_CODES.X` instead of raw string literals for:\n * - IDE autocomplete and compile-time validation\n * - Safe refactoring (rename updates all usages)\n * - Plugin extensibility (extend the object to add custom codes)\n *\n * The `ErrorCode` type is derived from this object, so adding a new\n * code here automatically updates the type without extra changes.\n */\nexport const ERROR_CODES = {\n // Provider\n PROVIDER_RATE_LIMITED: 'PROVIDER_RATE_LIMITED',\n PROVIDER_AUTH_FAILED: 'PROVIDER_AUTH_FAILED',\n PROVIDER_OVERLOADED: 'PROVIDER_OVERLOADED',\n PROVIDER_INVALID_REQUEST: 'PROVIDER_INVALID_REQUEST',\n PROVIDER_SERVER_ERROR: 'PROVIDER_SERVER_ERROR',\n PROVIDER_NETWORK_ERROR: 'PROVIDER_NETWORK_ERROR',\n PROVIDER_CONTEXT_OVERFLOW: 'PROVIDER_CONTEXT_OVERFLOW',\n // Tool\n TOOL_NOT_FOUND: 'TOOL_NOT_FOUND',\n TOOL_PERMISSION_DENIED: 'TOOL_PERMISSION_DENIED',\n TOOL_EXECUTION_FAILED: 'TOOL_EXECUTION_FAILED',\n TOOL_TIMEOUT: 'TOOL_TIMEOUT',\n TOOL_INPUT_INVALID: 'TOOL_INPUT_INVALID',\n // Config\n CONFIG_INVALID: 'CONFIG_INVALID',\n CONFIG_NOT_FOUND: 'CONFIG_NOT_FOUND',\n CONFIG_PARSE_FAILED: 'CONFIG_PARSE_FAILED',\n CONFIG_MIGRATION_NEEDED: 'CONFIG_MIGRATION_NEEDED',\n // Plugin\n PLUGIN_LOAD_FAILED: 'PLUGIN_LOAD_FAILED',\n PLUGIN_API_MISMATCH: 'PLUGIN_API_MISMATCH',\n PLUGIN_MISSING_DEPENDENCY: 'PLUGIN_MISSING_DEPENDENCY',\n // Agent\n AGENT_ITERATION_LIMIT: 'AGENT_ITERATION_LIMIT',\n AGENT_CONTEXT_OVERFLOW: 'AGENT_CONTEXT_OVERFLOW',\n AGENT_ABORTED: 'AGENT_ABORTED',\n AGENT_RUN_FAILED: 'AGENT_RUN_FAILED',\n // Session\n SESSION_NOT_FOUND: 'SESSION_NOT_FOUND',\n SESSION_CORRUPTED: 'SESSION_CORRUPTED',\n SESSION_WRITE_FAILED: 'SESSION_WRITE_FAILED',\n // Container / Registry\n CONTAINER_TOKEN_ALREADY_BOUND: 'CONTAINER_TOKEN_ALREADY_BOUND',\n CONTAINER_TOKEN_NOT_BOUND: 'CONTAINER_TOKEN_NOT_BOUND',\n CONTAINER_CIRCULAR_DEPENDENCY: 'CONTAINER_CIRCULAR_DEPENDENCY',\n REGISTRY_DUPLICATE: 'REGISTRY_DUPLICATE',\n REGISTRY_NOT_FOUND: 'REGISTRY_NOT_FOUND',\n REGISTRY_INVALID: 'REGISTRY_INVALID',\n // File system\n FS_READ_FAILED: 'FS_READ_FAILED',\n FS_WRITE_FAILED: 'FS_WRITE_FAILED',\n FS_MKDIR_FAILED: 'FS_MKDIR_FAILED',\n FS_DELETE_FAILED: 'FS_DELETE_FAILED',\n FS_ATOMIC_WRITE_FAILED: 'FS_ATOMIC_WRITE_FAILED',\n // SDD (Spec-Driven Development)\n SDD_VALIDATION_FAILED: 'SDD_VALIDATION_FAILED',\n SDD_PARSE_FAILED: 'SDD_PARSE_FAILED',\n SDD_INVALID_STATE: 'SDD_INVALID_STATE',\n SDD_NOT_READY: 'SDD_NOT_READY',\n // General\n VALIDATION_ERROR: 'VALIDATION_ERROR',\n PARSE_FAILED: 'PARSE_FAILED',\n UNKNOWN: 'UNKNOWN',\n} as const;\n\n/**\n * Union type derived from `ERROR_CODES`. Using `typeof ERROR_CODES[keyof typeof ERROR_CODES]`\n * instead of a string literal union means TypeScript auto-updates the type whenever\n * a new code is added to `ERROR_CODES` — no need to keep two lists in sync.\n */\nexport type ErrorCode = (typeof ERROR_CODES)[keyof typeof ERROR_CODES];\n\nexport type ErrorSubsystem =\n | 'provider'\n | 'tool'\n | 'config'\n | 'plugin'\n | 'agent'\n | 'session'\n | 'sdd'\n | 'container'\n | 'fs'\n | 'general';\nexport type ErrorSeverity = 'fatal' | 'error' | 'warning';\n\n// ── Base error class ─────────────────────────────────────────────────\n\nexport class WrongStackError extends Error {\n readonly code: ErrorCode;\n readonly subsystem: ErrorSubsystem;\n readonly severity: ErrorSeverity;\n readonly recoverable: boolean;\n readonly context?: Record<string, unknown> | undefined;\n\n constructor(opts: {\n message: string;\n code: ErrorCode;\n subsystem: ErrorSubsystem;\n severity?: ErrorSeverity | undefined;\n recoverable?: boolean | undefined;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super(opts.message, { cause: opts.cause });\n this.name = 'WrongStackError';\n this.code = opts.code;\n this.subsystem = opts.subsystem;\n this.severity = opts.severity ?? 'error';\n this.recoverable = opts.recoverable ?? false;\n this.context = opts.context;\n }\n\n /**\n * Render a one-line user-facing description.\n * Subclasses should override for domain-specific formatting.\n */\n describe(): string {\n const ctx = this.context ? ` ${formatContext(this.context)}` : '';\n return `${this.code}: ${this.message}${ctx}`;\n }\n}\n\nfunction formatContext(ctx: Record<string, unknown>): string {\n const parts = Object.entries(ctx)\n .filter(([, v]) => v !== undefined)\n .slice(0, 3)\n .map(([k, v]) => `${k}=${String(v)}`);\n return parts.length > 0 ? `[${parts.join(' ')}]` : '';\n}\n\n// ── Specific error classes ───────────────────────────────────────────\n\n/**\n * Tool execution errors — thrown by ToolExecutor and individual tools.\n */\nexport class ToolError extends WrongStackError {\n readonly toolName: string;\n\n constructor(opts: {\n message: string;\n code: Extract<\n ErrorCode,\n | 'TOOL_NOT_FOUND'\n | 'TOOL_PERMISSION_DENIED'\n | 'TOOL_EXECUTION_FAILED'\n | 'TOOL_TIMEOUT'\n | 'TOOL_INPUT_INVALID'\n >;\n toolName: string;\n recoverable?: boolean | undefined;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'tool',\n recoverable: opts.recoverable,\n context: { tool: opts.toolName, ...opts.context },\n cause: opts.cause,\n });\n this.name = 'ToolError';\n this.toolName = opts.toolName;\n }\n}\n\n/**\n * Config loading / validation errors.\n */\nexport class ConfigError extends WrongStackError {\n constructor(opts: {\n message: string;\n code: Extract<\n ErrorCode,\n 'CONFIG_INVALID' | 'CONFIG_NOT_FOUND' | 'CONFIG_PARSE_FAILED' | 'CONFIG_MIGRATION_NEEDED'\n >;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'config',\n severity: 'fatal',\n recoverable: false,\n context: opts.context,\n cause: opts.cause,\n });\n this.name = 'ConfigError';\n }\n}\n\n/**\n * Plugin loading / lifecycle errors.\n */\nexport class PluginError extends WrongStackError {\n readonly pluginName: string;\n\n constructor(opts: {\n message: string;\n code: Extract<\n ErrorCode,\n 'PLUGIN_LOAD_FAILED' | 'PLUGIN_API_MISMATCH' | 'PLUGIN_MISSING_DEPENDENCY'\n >;\n pluginName: string;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'plugin',\n severity: 'error',\n recoverable: opts.code === ERROR_CODES.PLUGIN_MISSING_DEPENDENCY,\n context: { plugin: opts.pluginName, ...opts.context },\n cause: opts.cause,\n });\n this.name = 'PluginError';\n this.pluginName = opts.pluginName;\n }\n}\n\n/**\n * Agent runtime errors — thrown by Agent.run when a non-WrongStackError\n * escapes the inner loop, so callers always see a structured error.\n */\nexport class AgentError extends WrongStackError {\n constructor(opts: {\n message: string;\n code: Extract<\n ErrorCode,\n 'AGENT_ITERATION_LIMIT' | 'AGENT_CONTEXT_OVERFLOW' | 'AGENT_ABORTED' | 'AGENT_RUN_FAILED'\n >;\n recoverable?: boolean | undefined;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'agent',\n severity: opts.code === ERROR_CODES.AGENT_ABORTED ? 'warning' : 'error',\n recoverable: opts.recoverable ?? opts.code === ERROR_CODES.AGENT_ITERATION_LIMIT,\n context: opts.context,\n cause: opts.cause,\n });\n this.name = 'AgentError';\n }\n}\n\n/**\n * Wrap an arbitrary thrown value into a `WrongStackError` so the caller\n * always gets a structured error. Pass-throughs WrongStackError instances\n * unchanged; raw `Error`s and primitives get an `AGENT_RUN_FAILED` wrapper\n * with the original preserved as `cause`.\n */\nexport function toWrongStackError(\n err: unknown,\n code: Extract<ErrorCode, 'AGENT_RUN_FAILED' | 'AGENT_ABORTED' | 'UNKNOWN'> = ERROR_CODES.AGENT_RUN_FAILED,\n): WrongStackError {\n if (err instanceof WrongStackError) return err;\n const message = toErrorMessage(err);\n return new AgentError({\n message,\n code: code === 'UNKNOWN' ? ERROR_CODES.AGENT_RUN_FAILED : code,\n cause: err,\n });\n}\n\n/**\n * Session storage errors.\n */\nexport class SessionError extends WrongStackError {\n readonly sessionId?: string | undefined;\n\n constructor(opts: {\n message: string;\n code: Extract<ErrorCode, 'SESSION_NOT_FOUND' | 'SESSION_CORRUPTED' | 'SESSION_WRITE_FAILED'>;\n sessionId?: string | undefined;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'session',\n severity: opts.code === ERROR_CODES.SESSION_WRITE_FAILED ? 'error' : 'warning',\n recoverable: opts.code !== ERROR_CODES.SESSION_CORRUPTED,\n context: { sessionId: opts.sessionId, ...opts.context },\n cause: opts.cause,\n });\n this.name = 'SessionError';\n this.sessionId = opts.sessionId;\n }\n}\n\n/**\n * SDD (Spec-Driven Development) errors — spec validation, parsing, and\n * state machine violations in the AISpecBuilder, TaskFlow, and TaskTracker.\n */\nexport class SddError extends WrongStackError {\n constructor(opts: {\n message: string;\n code: Extract<\n ErrorCode,\n 'SDD_VALIDATION_FAILED' | 'SDD_PARSE_FAILED' | 'SDD_INVALID_STATE' | 'SDD_NOT_READY'\n >;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'sdd',\n severity: opts.code === ERROR_CODES.SDD_PARSE_FAILED ? 'warning' : 'error',\n recoverable: opts.code === ERROR_CODES.SDD_NOT_READY,\n context: opts.context,\n cause: opts.cause,\n });\n this.name = 'SddError';\n }\n}\n\n/**\n * File system operation errors.\n */\nexport class FsError extends WrongStackError {\n readonly path?: string | undefined;\n\n constructor(opts: {\n message: string;\n code: Extract<\n ErrorCode,\n 'FS_READ_FAILED' | 'FS_WRITE_FAILED' | 'FS_MKDIR_FAILED' | 'FS_DELETE_FAILED' | 'FS_ATOMIC_WRITE_FAILED'\n >;\n path?: string | undefined;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'fs',\n severity: 'error',\n recoverable: opts.code !== ERROR_CODES.FS_READ_FAILED,\n context: { path: opts.path, ...opts.context },\n cause: opts.cause,\n });\n this.name = 'FsError';\n this.path = opts.path;\n }\n}\n\n/**\n * HTTP fetch error — thrown when a network request returns a non-OK status.\n * Carries the response status so {@link classifyToolError} can branch on it\n * (429 → transient, 404 → not_found, 401 → permission) without duck-typing\n * the error via `'response' in err`.\n *\n * P3 #18 (before-release.md): the previous `'response' in err` check caught\n * any Error with a `response` property, including custom errors, proxy\n * objects, or mocked errors in tests. `instanceof FetchError` is reliable.\n *\n * Tools and providers that make HTTP requests and need the executor to\n * classify their failures should throw `new FetchError({ status, message })`\n * instead of a bare `Error` with an ad-hoc `response` field.\n */\nexport class FetchError extends WrongStackError {\n readonly status: number;\n\n constructor(opts: {\n message: string;\n status: number;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: ERROR_CODES.VALIDATION_ERROR,\n subsystem: 'general',\n severity: 'error',\n recoverable: opts.status === 429 || opts.status >= 500,\n context: { status: opts.status, ...opts.context },\n cause: opts.cause,\n });\n this.name = 'FetchError';\n this.status = opts.status;\n }\n}\n\n/**\n * Tool input validation error — thrown when a tool's input fails a validation\n * check that the JSON Schema cannot express (e.g. `old_string === new_string`\n * in edit, or a cross-field invariant). Use this instead of a bare\n * `throw new Error('...validation...')` so {@link classifyToolError} can\n * match on `instanceof` rather than a locale-dependent message substring.\n *\n * P2 #6 (before-release.md): the previous `err.message.includes('validation')`\n * check misclassified any error whose message happened to contain \"validation\"\n * (e.g. a third-party \"input validation timeout\") as a VALIDATION error.\n *\n * Named `ToolValidationError` (not `ValidationError`) to avoid colliding with\n * the existing `ValidationError` interface exported by json-schema-validate.ts\n * (a validation-result shape, not an Error subclass).\n */\nexport class ToolValidationError extends WrongStackError {\n constructor(opts: {\n message: string;\n /** Field path or tool name that failed validation, for diagnostics. */\n field?: string | undefined;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: ERROR_CODES.VALIDATION_ERROR,\n subsystem: 'general',\n severity: 'error',\n recoverable: false,\n context: { field: opts.field, ...opts.context },\n cause: opts.cause,\n });\n this.name = 'ToolValidationError';\n }\n}\n\n/**\n * Response / payload parse error — thrown when an upstream HTTP response,\n * file, or data structure is well-formed at the transport layer (HTTP 200,\n * valid JSON) but is missing required fields or has an unexpected shape.\n *\n * Distinct from `ConfigError(CONFIG_PARSE_FAILED)` (which is specifically\n * for config-file parsing) and `FetchError` (which covers HTTP non-OK\n * responses). `ParseError` fills the gap: the request succeeded but the\n * response body couldn't be interpreted.\n *\n * Common sites: OAuth token responses missing `access_token`, device-code\n * responses missing `device_code`, registry responses with unexpected\n * schemas.\n */\nexport class ParseError extends WrongStackError {\n readonly source?: string | undefined;\n\n constructor(opts: {\n message: string;\n /**\n * What was being parsed — e.g. `'oauth-token-response'`,\n * `'device-code-response'`. Lets consumers distinguish parse failures\n * from different upstream APIs without parsing the message.\n */\n source?: string | undefined;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: ERROR_CODES.PARSE_FAILED,\n subsystem: 'general',\n severity: 'error',\n recoverable: false,\n context: { source: opts.source, ...opts.context },\n cause: opts.cause,\n });\n this.name = 'ParseError';\n this.source = opts.source;\n }\n}\n\n// ── Type guards ──────────────────────────────────────────────────────\n\nexport function isWrongStackError(err: unknown): err is WrongStackError {\n return err instanceof WrongStackError;\n}\n\nexport function isToolError(err: unknown): err is ToolError {\n return err instanceof ToolError;\n}\n\nexport function isConfigError(err: unknown): err is ConfigError {\n return err instanceof ConfigError;\n}\n\nexport function isPluginError(err: unknown): err is PluginError {\n return err instanceof PluginError;\n}\n\nexport function isSessionError(err: unknown): err is SessionError {\n return err instanceof SessionError;\n}\n\nexport function isAgentError(err: unknown): err is AgentError {\n return err instanceof AgentError;\n}\n\nexport function isFsError(err: unknown): err is FsError {\n return err instanceof FsError;\n}\n\nexport function isToolValidationError(err: unknown): err is ToolValidationError {\n return err instanceof ToolValidationError;\n}\n\nexport function isFetchError(err: unknown): err is FetchError {\n return err instanceof FetchError;\n}\n\nexport function isParseError(err: unknown): err is ParseError {\n return err instanceof ParseError;\n}\n\nexport function isSddError(err: unknown): err is SddError {\n return err instanceof SddError;\n}\n","import type { ContentBlock, TextBlock } from './blocks.js';\nimport type { ErrorCode } from './errors.js';\nimport { WrongStackError, ERROR_CODES } from './errors.js';\nimport type { Message } from './messages.js';\nimport type { Tool } from './tool.js';\nimport { truncate } from '../utils/string.js';\n\n/**\n * Token usage for a single provider call, normalized across providers.\n *\n * Disjoint semantics: the four fields never overlap. `input` is the count\n * of FRESH input tokens (billed at the full input rate); `cacheRead` and\n * `cacheWrite` are separate cached subsets each priced at their own rate.\n * The total context the model loaded for this turn is\n * `input + (cacheRead ?? 0) + (cacheWrite ?? 0)`.\n *\n * Provider quirks normalized at the adapter layer:\n * - Anthropic: returns `input_tokens` already disjoint from cache fields.\n * - OpenAI / OpenAI-compatible: `prompt_tokens` is the TOTAL including\n * cached portion; the adapter subtracts `cached_tokens` to stay disjoint.\n * - Google: `promptTokenCount` likewise includes cache; adapter subtracts\n * `cachedContentTokenCount`.\n *\n * Cost math and the context-fullness chip both depend on the disjoint\n * invariant — a TOTAL `input` plus a separate `cacheRead` count would bill\n * cached tokens twice and skew cache-hit-ratio reporting.\n */\nexport type ReasoningEffort = 'none' | 'minimal' | 'low' | 'medium' | 'high' | 'xhigh' | 'max';\nexport type CacheTtl = '5m' | '1h';\n\n/**\n * Provider-agnostic response-format directive.\n *\n * - `{ type: 'text' }` — free-form text (default).\n * - `{ type: 'json_object' }` — valid JSON without a schema constraint.\n * - `{ type: 'json_schema', jsonSchema: { name, schema, strict? } }` — JSON\n * constrained to the supplied JSON Schema. The `strict` flag is\n * OpenAI-specific; Gemini ignores it in favour of `responseMimeType`.\n *\n * Each provider adapter maps this into its own wire format:\n * OpenAI → `response_format`\n * Gemini → `responseMimeType` + `responseSchema`\n * Anthropic → (not yet supported; uses tools for structured output)\n */\nexport interface JsonSchemaSpec {\n name: string;\n /** OpenAI-specific: enable strict schema adherence. */\n strict?: boolean | undefined;\n /** The JSON Schema object describing the expected shape. */\n schema: Record<string, unknown>;\n /** Optional human-readable description (OpenAI). */\n description?: string | undefined;\n}\n\nexport type ResponseFormat =\n | { type: 'text' }\n | { type: 'json_object' }\n | { type: 'json_schema'; jsonSchema: JsonSchemaSpec };\n\n/**\n * Safety category threshold pair used by Google Gemini's `safetySettings`.\n *\n * Categories: `HARM_CATEGORY_HARASSMENT`, `HARM_CATEGORY_HATE_SPEECH`,\n * `HARM_CATEGORY_SEXUALLY_EXPLICIT`, `HARM_CATEGORY_DANGEROUS_CONTENT`.\n *\n * Thresholds: `BLOCK_NONE`, `BLOCK_ONLY_HIGH`, `BLOCK_MEDIUM_AND_ABOVE`,\n * `BLOCK_LOW_AND_ABOVE`.\n */\nexport interface SafetySetting {\n category: string;\n threshold: string;\n}\n\nexport interface Usage {\n input: number;\n output: number;\n cacheRead?: number | undefined;\n /** Back-compat aggregate of all cache-write tokens. Prefer TTL-specific fields when present. */\n cacheWrite?: number | undefined;\n cacheWrite5m?: number | undefined;\n cacheWrite1h?: number | undefined;\n}\n\nexport interface ReasoningRequest {\n enabled?: boolean | undefined;\n effort?: ReasoningEffort | undefined;\n preserve?: boolean | undefined;\n display?: 'summarized' | 'omitted' | undefined;\n}\n\nexport interface RequestCacheControl {\n ttl?: CacheTtl | undefined;\n}\n\nexport interface ReasoningConfig {\n default: 'enabled' | 'disabled' | 'adaptive' | 'always_on';\n disableSupported: boolean;\n effortSupported: boolean;\n effortLevels: ReasoningEffort[];\n preserveThinking: 'unsupported' | 'optional' | 'always_on';\n}\n\nexport interface Capabilities {\n tools: boolean;\n parallelTools: boolean;\n vision: boolean;\n streaming: boolean;\n promptCache: boolean;\n systemPrompt: boolean;\n jsonMode: boolean;\n reasoning: boolean;\n maxContext: number;\n /**\n * Maximum output tokens the model can produce in a single response.\n * Used as the default for `Request.maxTokens` when the caller doesn't\n * supply an explicit value — letting subagents run up to the model's\n * native ceiling instead of a fixed 8192 cap. Omit (undefined) to fall\n * back to a conservative default; populate per family in\n * `family-capabilities.ts` once you know the spec.\n */\n maxOutput?: number | undefined;\n cacheControl: 'native' | 'auto' | 'none';\n\n // ── Extended parameter support (optional; family defaults in CAPABILITIES_BY_FAMILY) ──\n\n /** Model accepts `top_k` / `topK` sampling parameter. */\n topK?: boolean | undefined;\n /** Model accepts `frequency_penalty` / `frequencyPenalty` parameter. */\n frequencyPenalty?: boolean | undefined;\n /** Model accepts `presence_penalty` / `presencePenalty` parameter. */\n presencePenalty?: boolean | undefined;\n /** Model accepts `seed` parameter for deterministic generation. */\n seed?: boolean | undefined;\n /**\n * Model accepts JSON Schema / structured-output constraints\n * (OpenAI `response_format.json_schema`, Gemini `responseMimeType`+`responseSchema`).\n * Distinct from `jsonMode` (which is just a system-prompt hint).\n */\n structuredOutput?: boolean | undefined;\n /** Model supports log-probability output (`logprobs`, `top_logprobs`). */\n logprobs?: boolean | undefined;\n /** Model supports audio input/output modality. */\n audio?: boolean | undefined;\n /** Model supports the `n` parameter for multiple completions. */\n multipleCompletions?: boolean | undefined;\n}\n\nexport interface Request {\n model: string;\n system?: TextBlock[] | undefined;\n messages: Message[];\n tools?: Tool[] | undefined;\n /**\n * Cap on output tokens for this single response. Optional — when\n * omitted, the provider adapter falls back to its own\n * `capabilities.maxOutput` (which the catalog populates from\n * `ModelsDevModel.limit.output`). If neither is available, the\n * adapter applies a conservative 8192 safety net. Letting this stay\n * undefined at the call site means callers like Chimera can hand the\n * model its native output ceiling without hard-coding a number.\n */\n maxTokens?: number | undefined;\n temperature?: number | undefined;\n topP?: number | undefined;\n topK?: number | undefined;\n frequencyPenalty?: number | undefined;\n presencePenalty?: number | undefined;\n seed?: number | undefined;\n /**\n * End-user identifier for abuse monitoring and per-user rate limiting.\n * - Anthropic → `metadata.user_id`\n * - OpenAI → `user`\n * - Gemini → (not supported)\n */\n user?: string | undefined;\n /**\n * Number of response candidates to generate. Google Gemini supports\n * this via `generationConfig.candidateCount`. OpenAI does not have\n * an equivalent (`n` is conceptually similar but distinct).\n */\n candidateCount?: number | undefined;\n /**\n * Whether to return log probabilities for output tokens.\n * - OpenAI → `logprobs: boolean` (+ `topLogprobs: number`)\n * - Gemini → `generationConfig.logprobs: number` (how many top candidates)\n * Default undefined = no logprobs requested.\n */\n logprobs?: boolean | undefined;\n /**\n * Number of most probable tokens to return log probabilities for\n * (OpenAI `top_logprobs`). Only meaningful when `logprobs` is true.\n * Range: 0-20. Gemini ignores this (uses `logprobs` as the count).\n */\n topLogprobs?: number | undefined;\n stopSequences?: string[] | undefined;\n toolChoice?: 'auto' | 'required' | 'none' | { type: 'tool' | undefined; name: string };\n reasoning?: ReasoningRequest | undefined;\n cache?: RequestCacheControl | undefined;\n /**\n * Structured-output / response-format directive.\n * When set, the provider adapter maps this to its native response-format\n * parameter (OpenAI `response_format`, Gemini `responseMimeType`, etc.).\n * The model must advertise `capabilities.structuredOutput` for this to be\n * honoured; unsupported models will likely 400 or ignore it.\n */\n responseFormat?: ResponseFormat | undefined;\n /**\n * Safety category thresholds for filtering harmful content.\n * - Gemini → top-level `safetySettings` array with `{ category, threshold }`\n * - OpenAI → not supported (uses server-side moderation)\n * - Anthropic → not supported\n */\n safetySettings?: SafetySetting[] | undefined;\n}\n\nexport type StopReason = 'end_turn' | 'tool_use' | 'max_tokens' | 'stop_sequence' | 'refusal';\n\nexport interface Response {\n content: ContentBlock[];\n stopReason: StopReason;\n usage: Usage;\n model: string;\n}\n\nexport type StreamEvent =\n | { type: 'message_start'; model: string }\n | {\n type: 'content_block_start';\n kind: 'text' | 'tool_use' | 'thinking';\n id?: string | undefined;\n name?: string | undefined;\n }\n | { type: 'content_block_stop'; index: number }\n | { type: 'text_delta'; text: string }\n | { type: 'tool_use_start'; id: string; name: string }\n | { type: 'tool_use_input_delta'; id: string; partial: string }\n | { type: 'tool_use_stop'; id: string; input: unknown; providerMeta?: Record<string, unknown> }\n | { type: 'thinking_start'; providerMeta?: Record<string, unknown> }\n | { type: 'thinking_delta'; text: string }\n | { type: 'thinking_signature'; signature: string }\n | { type: 'thinking_stop' }\n | { type: 'message_stop'; stopReason: StopReason; usage: Usage };\n\nexport interface Provider {\n readonly id: string;\n readonly capabilities: Capabilities;\n /** Canonical streaming entry point. `complete()` defaults to a wrapper that\n * aggregates this stream — providers may override for non-streaming wires. */\n stream(req: Request, opts: { signal: AbortSignal }): AsyncIterable<StreamEvent>;\n complete(req: Request, opts: { signal: AbortSignal }): Promise<Response>;\n}\n\n/**\n * Structured body parsed from a provider's HTTP error response. Populated\n * best-effort: providers return JSON shaped differently (Anthropic uses\n * `{error: {type, message}}`, OpenAI uses `{error: {message, code}}`,\n * Google uses `{error: {status, message}}`), so the fields here are the\n * intersection that's usable for rendering and routing.\n */\nexport interface ProviderErrorBody {\n /** Provider-specific kind, e.g. \"overloaded_error\", \"rate_limit_error\", \"invalid_request_error\". */\n type?: string | undefined;\n /** Human-readable explanation from the provider. */\n message?: string | undefined;\n /** Provider request id, when present in the body or headers. */\n requestId?: string | undefined;\n /** Parsed Retry-After header (or equivalent body hint) in milliseconds. */\n retryAfterMs?: number | undefined;\n /** The raw response body (truncated to ~2 KB), kept for debugging. */\n raw?: string | undefined;\n /** True when `raw` was truncated; check `rawLength` for the original size. */\n truncated?: boolean | undefined;\n /** Original length of the response body in bytes, when `truncated` is true. */\n rawLength?: number | undefined;\n}\n\nexport class ProviderError extends WrongStackError {\n public readonly status: number;\n public readonly retryable: boolean;\n public readonly providerId: string;\n public readonly body?: ProviderErrorBody | undefined;\n\n constructor(\n message: string,\n status: number,\n retryable: boolean,\n providerId: string,\n opts: { body?: ProviderErrorBody | undefined; cause?: unknown | undefined } = {},\n ) {\n super({\n message,\n code: providerStatusToCode(status, opts.body?.type),\n subsystem: 'provider',\n severity: status >= 500 ? 'error' : 'warning',\n recoverable: retryable,\n context: { providerId, status },\n cause: opts.cause,\n });\n this.name = 'ProviderError';\n this.status = status;\n this.retryable = retryable;\n this.providerId = providerId;\n this.body = opts.body;\n }\n\n /**\n * Render a one-line, user-facing description. Designed for the CLI/TUI\n * status line and the agent's retry warning. Avoids dumping raw JSON\n * (which is what users see today when a 529 lands and the log message\n * includes the full `{\"type\":\"error\",...}` body).\n *\n * Examples:\n * \"minimax-coding-plan overloaded (529): High traffic detected. Upgrade for highspeed model. [req 06534785201de9c0…]\"\n * \"openai rate limited (429): Retry after 12s\"\n * \"anthropic invalid request (400): messages.0.role must be one of 'user'|'assistant'\"\n * \"groq HTTP 500 (server error)\"\n */\n override describe(): string {\n const kind = describeStatus(this.status, this.body?.type);\n const head = `${this.providerId} ${kind}`;\n const detail = this.body?.message?.trim();\n const reqId = this.body?.requestId\n ? ` [req ${this.body.requestId.slice(0, 16)}${this.body.requestId.length > 16 ? '…' : ''}]`\n : '';\n if (detail && detail.length > 0) {\n return `${head}: ${truncate(detail, 240)}${reqId}`;\n }\n return `${head}${reqId}`;\n }\n}\n\nfunction describeStatus(status: number, type?: string): string {\n if (status === 0) return 'network error';\n if (type === 'overloaded_error' || status === 529) return `overloaded (${status})`;\n if (type === 'rate_limit_error' || status === 429) return `rate limited (${status})`;\n if (type === 'authentication_error' || status === 401) return `auth failed (${status})`;\n if (type === 'permission_error' || status === 403) return `forbidden (${status})`;\n if (type === 'not_found_error' || status === 404) return `not found (${status})`;\n if (type === 'invalid_request_error' || status === 400) return `invalid request (${status})`;\n if (status === 408) return `timeout (${status})`;\n if (status >= 500 && status < 600) return `HTTP ${status} (server error)`;\n if (type) return `${type} (${status})`;\n return `HTTP ${status}`;\n}\n\n/**\n * Thrown when the provider stream stops delivering data mid-response.\n * This is distinct from a network error (TCP reset, DNS failure) — the\n * connection is established and the response started, but chunks stopped\n * arriving before the stream completed.\n *\n * Status 599 is used as a sentinel to distinguish stream hangs from\n * regular HTTP errors while still flowing through ProviderError-based\n * retry and fallback infrastructure.\n */\nexport class StreamHangError extends ProviderError {\n /** Name of the provider that hung, e.g. \"zai\", \"anthropic\". */\n public readonly hungProviderId: string;\n /** Model that was being called when the hang occurred. */\n public readonly hungModel: string;\n /** How long (ms) we waited for the next chunk before declaring a hang. */\n public readonly hangTimeoutMs: number;\n /** How many bytes were received before the hang. */\n public readonly bytesReceived: number;\n /** Elapsed time (ms) from the start of the stream until the hang. */\n public readonly elapsedMs: number;\n\n constructor(opts: {\n providerId: string;\n model: string;\n hangTimeoutMs: number;\n bytesReceived: number;\n elapsedMs: number;\n cause?: unknown | undefined;\n }) {\n super(\n `Stream hang: ${opts.providerId}/${opts.model} — no data for ${opts.hangTimeoutMs}ms after ${opts.bytesReceived} bytes (${opts.elapsedMs}ms elapsed)`,\n 599,\n true, // always retryable\n opts.providerId,\n {\n body: {\n message: `Stream stalled after ${opts.elapsedMs}ms, ${opts.bytesReceived} bytes received`,\n },\n cause: opts.cause,\n },\n );\n this.name = 'StreamHangError';\n this.hungProviderId = opts.providerId;\n this.hungModel = opts.model;\n this.hangTimeoutMs = opts.hangTimeoutMs;\n this.bytesReceived = opts.bytesReceived;\n this.elapsedMs = opts.elapsedMs;\n }\n}\n\nfunction providerStatusToCode(status: number, type?: string): ErrorCode {\n if (status === 0) return ERROR_CODES.PROVIDER_NETWORK_ERROR;\n if (type === 'rate_limit_error' || status === 429) return ERROR_CODES.PROVIDER_RATE_LIMITED;\n if (type === 'authentication_error' || status === 401) return ERROR_CODES.PROVIDER_AUTH_FAILED;\n if (type === 'overloaded_error' || status === 529) return ERROR_CODES.PROVIDER_OVERLOADED;\n if (type === 'invalid_request_error' || status === 400) return ERROR_CODES.PROVIDER_INVALID_REQUEST;\n if (status === 408) return ERROR_CODES.PROVIDER_NETWORK_ERROR;\n if (status >= 500) return ERROR_CODES.PROVIDER_SERVER_ERROR;\n return ERROR_CODES.PROVIDER_INVALID_REQUEST;\n}\n","import type { ContextWindowModeId } from './context-window.js';\nimport type { HookEvent, ShellHook } from './hooks.js';\nimport type { WireFamily } from './models-registry.js';\nimport type { CacheTtl, Capabilities, ReasoningEffort } from './provider.js';\nimport type { Permission } from './tool.js';\n\n/**\n * Runtime reasoning controls the user can set per-session/project. Mapped into\n * the provider `Request.reasoning` field by the model-runtime request\n * middleware, gated by the active model's `reasoningConfig` capabilities so\n * unsupported values are omitted (and warned) instead of triggering provider\n * 400s. See `resolveReasoningForRequest()` in packages/core.\n */\nexport interface ModelRuntimeReasoningConfig {\n /**\n * Whether to send explicit reasoning enable/disable.\n * - 'auto' → do not send explicit fields; provider/model default wins\n * - 'on' → send `reasoning.enabled = true`\n * - 'off' → send `reasoning.enabled = false` only when the model supports disable\n */\n mode?: 'auto' | 'on' | 'off' | undefined;\n /** Reasoning effort. Only sent when the model advertises `effortSupported`. */\n effort?: ReasoningEffort | undefined;\n /** Preserve thinking across turns. Only sent when `preserveThinking !== 'unsupported'`. */\n preserve?: boolean | undefined;\n}\n\n/**\n * Runtime prompt-cache controls mapped into `Request.cache`. Currently only the\n * Anthropic TTL toggle (5m vs 1h) is exposed; other providers ignore it.\n */\nexport interface ModelRuntimeCacheConfig {\n ttl?: CacheTtl | undefined;\n}\n\n/**\n * Shared runtime controls applied to every provider request, regardless of host\n * (REPL / TUI / WebUI). The CLI installs a single request-pipeline middleware\n * that reads these and mutates the outgoing `Request`.\n */\nexport interface ModelRuntimeConfig {\n reasoning?: ModelRuntimeReasoningConfig | undefined;\n cache?: ModelRuntimeCacheConfig | undefined;\n /**\n * Generic generation parameters mapped directly onto `Request` fields.\n * Only sent when the active model's `Capabilities` advertise support.\n */\n parameters?: ModelRuntimeParametersConfig | undefined;\n}\n\n/**\n * Generic generation parameters the user can set per-session / per-project.\n * Each field maps to a `Request` field of the same name and is gated by the\n * corresponding `Capabilities` flag so unsupported models don't receive\n * parameters they'd reject.\n */\nexport interface ModelRuntimeParametersConfig {\n /** Top-K sampling (Anthropic, Gemini). Gated by `capabilities.topK`. */\n topK?: number | undefined;\n /** Frequency penalty (OpenAI, Gemini). Gated by `capabilities.frequencyPenalty`. */\n frequencyPenalty?: number | undefined;\n /** Presence penalty (OpenAI, Gemini). Gated by `capabilities.presencePenalty`. */\n presencePenalty?: number | undefined;\n /** Random seed (OpenAI, Gemini). Gated by `capabilities.seed`. */\n seed?: number | undefined;\n /** End-user identifier for abuse monitoring. */\n user?: string | undefined;\n /** Log probabilities (OpenAI, Gemini). Gated by `capabilities.logprobs`. */\n logprobs?: boolean | undefined;\n /** Number of top logprobs to return (OpenAI). Only when `logprobs` is true. */\n topLogprobs?: number | undefined;\n}\n\n/**\n * HQ client connection settings. Same-machine clients can auto-discover the\n * local HQ auth file; remote clients use this config-backed URL/token pair.\n */\nexport interface HqClientConfig {\n /** Enable HQ publishing. Env WRONGSTACK_HQ_ENABLED still overrides at runtime. */\n enabled?: boolean | undefined;\n /** HQ HTTP base URL, e.g. http://host:3499. */\n url?: string | undefined;\n /** Client token for /ws/client. Stored encrypted by SecretVault when persisted. */\n token?: string | undefined;\n /** Optional HQ data dir for same-machine auth.json discovery. */\n dataDir?: string | undefined;\n /** Send raw content previews to HQ instead of redacted previews. */\n rawContent?: boolean | undefined;\n /** Override project display name in HQ. */\n projectAlias?: string | undefined;\n}\n\n/**\n * Token-saving mode tier levels. Controls how aggressively the system prompt\n * is compacted to reduce per-request token consumption.\n *\n * - 'off' — Full prompt, all tools, complete guidance (no reduction)\n * - 'minimal' — TIER1 tools only (~10), stripped guidance (~3-4k tokens saved)\n * - 'light' — Core + memory tools (~14), common patterns, minimal guidance\n * - 'medium' — Most development tools (~24), some guidance (default when `true`)\n * - 'aggressive' — Maximum savings before tools become unusable (~4-5k tokens saved)\n */\nexport type TokenSavingTier = 'off' | 'minimal' | 'light' | 'medium' | 'aggressive';\n\n/**\n * Normalize a TokenSavingTier value, handling backward-compatible boolean inputs.\n * - `true` → 'medium' (existing behavior)\n * - `false` → 'off'\n * - string values are returned as-is after validation\n * - `undefined` → 'off'\n */\nexport function normalizeTokenSavingTier(val?: TokenSavingTier | boolean): TokenSavingTier {\n if (val === undefined) return 'off';\n if (typeof val === 'boolean') return val ? 'medium' : 'off';\n const validTiers = new Set<TokenSavingTier>(['off', 'minimal', 'light', 'medium', 'aggressive']);\n return validTiers.has(val) ? val : 'off';\n}\n\nexport const DEFAULT_TUI_THINKING_WORD = 'thinking';\nexport const MAX_TUI_THINKING_WORD_LENGTH = 16;\n\n/**\n * Normalize the configurable statusline word shown while the TUI is working.\n * The value must be a single short word; invalid values fall back to the default.\n */\nexport function normalizeTuiThinkingWord(value: unknown): string {\n if (typeof value !== 'string') return DEFAULT_TUI_THINKING_WORD;\n const word = value.trim();\n if (word.length === 0 || word.length > MAX_TUI_THINKING_WORD_LENGTH) {\n return DEFAULT_TUI_THINKING_WORD;\n }\n if (!/^[\\p{L}\\p{N}_-]+$/u.test(word)) return DEFAULT_TUI_THINKING_WORD;\n return word;\n}\n\nexport interface ContextConfig {\n /** Context-window policy mode. Controls compaction thresholds and preservation depth. */\n mode?: ContextWindowModeId | undefined;\n warnThreshold: number;\n softThreshold: number;\n hardThreshold: number;\n /** Enable automatic compaction when thresholds are crossed (default: true). */\n autoCompact?: boolean | undefined;\n /**\n * Model used for LLM-assisted summarization in IntelligentCompactor.\n * Falls back to the main model when omitted.\n */\n summarizerModel?: string | undefined;\n /**\n * Override the effective context window size (in tokens). Use this when\n * you want the compactor to trigger earlier than the provider's actual\n * maxContext. Defaults to the provider's reported maxContext.\n */\n effectiveMaxContext?: number | undefined;\n maxSessionTokens?: number | undefined;\n maxDailyTokens?: number | undefined;\n preserveK: number;\n eliseThreshold: number;\n /** Compactor strategy: 'hybrid' (default, fast rules), 'intelligent' (LLM summarization), 'selective' (LLM-driven selection). */\n strategy?: 'hybrid' | 'intelligent' | 'selective' | undefined;\n /** Enable LLM-driven selective compaction (default: false for backward compat). */\n llmSelector?: boolean | undefined;\n}\n\n/**\n * Runtime configuration for the process circuit breaker (the one owned by the\n * ProcessRegistry that gates `bash`/`exec`). Toggle via `/settings breaker`.\n *\n * The breaker itself is a low-level primitive (`packages/tools/.../circuit-breaker.ts`)\n * that is on by default; this section controls whether the registry actually\n * participates in it and how it auto-recovers.\n */\nexport interface CircuitBreakerRuntimeConfig {\n /**\n * Enable circuit-breaker protection. When false (the default), the breaker\n * is bypassed — `bash`/`exec` calls always proceed regardless of failure\n * history. When true, the breaker trips on repeated failures / slow calls /\n * bursts and blocks further calls until it recovers.\n */\n enabled?: boolean | undefined;\n /**\n * When the breaker trips, automatically kill all tracked processes AND\n * reset the breaker to closed after this delay (ms). 0 = disabled (manual\n * recovery only via `/kill reset`). Only effective when `enabled` is true.\n * While armed, the statusline shows a live countdown to the kill/reset.\n */\n autoKillResetMs?: number | undefined;\n}\n\n/**\n * Adaptive concurrency controller configuration. When enabled, the controller\n * automatically adjusts `maxConcurrent` based on rate-limit (429) errors:\n * - On 429: halves `maxConcurrent` (floor at 1)\n * - On sustained success (no 429 for `recoveryIntervalMs`): increases `maxConcurrent` by 1\n */\nexport interface AdaptiveConcurrencyConfig {\n /** Enable adaptive concurrency. Default: false (disabled). */\n enabled?: boolean | undefined;\n /**\n * Minimum concurrency floor. The controller never drops below this.\n * Default: 1.\n */\n minConcurrent?: number | undefined;\n /**\n * Maximum concurrency ceiling. The controller never exceeds this.\n * Default: 16 (matches MultiAgentCoordinator default).\n */\n maxConcurrent?: number | undefined;\n /**\n * Multiplicative decrease factor when a 429 is hit.\n * `newConcurrency = floor(currentConcurrency * decreaseFactor)`.\n * Default: 0.5 (halves concurrency).\n */\n decreaseFactor?: number | undefined;\n /**\n * Number of consecutive successful requests before increasing concurrency by 1.\n * Default: 10.\n */\n successThreshold?: number | undefined;\n /**\n * How often (ms) to check for recovery and bump concurrency.\n * Default: 30_000 (30 seconds).\n */\n recoveryIntervalMs?: number | undefined;\n}\n\nexport interface ToolsConfig {\n defaultExecutionStrategy: 'parallel' | 'sequential' | 'smart';\n maxIterations: number;\n iterationTimeoutMs: number;\n sessionTimeoutMs: number;\n perIterationOutputCapBytes: number;\n /**\n * Per-tool prose budget for the tool's top-level description and usage hint.\n * Missing entries default to \"extend\".\n */\n descriptionMode?: ToolDescriptionModeConfig | undefined;\n /**\n * Per-tool on-screen result rendering mode (terminal / WebUI / TUI).\n * Missing entries default to \"extend\". Independent of `descriptionMode`:\n * `/tool <name> result simple` toggles this without touching the\n * LLM-side description length.\n */\n resultRenderMode?: ToolResultRenderModeConfig | undefined;\n /**\n * Tool names to disable. Disabled tools are excluded from the tool registry\n * (`ToolRegistry.list()` / `get()`), so they do NOT appear in the system\n * prompt's \"## Tool usage\" block — reducing per-request token consumption.\n * Override per-session with `/tool enable <name>` or re-enable all via\n * `/tool enable-all`.\n */\n disabledTools?: string[] | undefined;\n /**\n * When true (default), the agent automatically extends its iteration\n * limit by 100 when hit. Set to false to require user confirmation.\n */\n autoExtendLimit?: boolean | undefined;\n /**\n * When true, file tools (read/write/edit/grep/glob/install) are confined to\n * the project root and `set_working_dir` may not leave it. Default: false —\n * tools may access paths outside the project root, still subject to each\n * tool's permission tier (writes/edits prompt for confirmation). Toggle via\n * `/settings` (\"Filesystem access\").\n */\n restrictToProjectRoot?: boolean | undefined;\n /**\n * Per-command policy for the `exec` tool's allowlist. The tool ships a\n * curated default allowlist of dev/build commands; this extends or trims it.\n *\n * SECURITY: `allow` EXPANDS what the agent may execute, so it is honored only\n * from TRUSTED config (`~/.wrongstack/config.json`) — the config loader\n * strips `tools.exec.allow` from the untrusted, repo-committed\n * `<project>/.wrongstack/config.json`. `deny` only ever REMOVES commands, so\n * it is honored from any source.\n */\n exec?: ExecToolConfig | undefined;\n}\n\n/** Allow/deny extension of the `exec` tool's built-in command allowlist. */\nexport interface ExecToolConfig {\n /**\n * Extra command names to add to the allowlist (e.g. `[\"make\", \"dotnet\"]`).\n * Trusted sources only — stripped from in-project repo config.\n */\n allow?: string[] | undefined;\n /**\n * Command names to remove from the allowlist. Honored from any source —\n * removing a command can only narrow what runs, so it is always safe.\n */\n deny?: string[] | undefined;\n /**\n * Per-rule bypass for the heuristic danger detector. Each entry is a\n * stable `matchedRule` id (e.g. `rm-recursive`, `git-push-force`); a\n * matched rule whose id is in this list is suppressed.\n *\n * Use case: a project that legitimately runs `rm -rf ./build` on every\n * CI run can add `\"rm-recursive\"` to bypass so the detector stops\n * emitting banners for that one rule — without disabling it for every\n * other `rm -rf` invocation.\n *\n * **Trusted sources only.** Bypassing a danger rule means the user\n * agreed to a specific destructive pattern; in-project repo config\n * could otherwise be used to silently opt everyone in. The boot path\n * strips this field from `<project>/.wrongstack/config.json` the\n * same way it strips `allow`.\n */\n danger?: ExecDangerConfig | undefined;\n}\n\nexport interface ExecDangerConfig {\n /**\n * List of danger rule ids to skip. Each id corresponds to a rule in\n * `@wrongstack/tools/src/_danger-detect.ts` (e.g. `rm-recursive`,\n * `git-push-force`, `inline-eval`, `sudo`). Unknown ids are ignored\n * (forward-compat: a rule added in a future version can be referenced\n * before the user upgrades).\n */\n bypass?: string[] | undefined;\n}\n\nexport type ToolDescriptionMode = 'extend' | 'simple';\nexport type ToolDescriptionModeConfig = Record<string, ToolDescriptionMode | undefined>;\n\n/**\n * Per-tool on-screen result rendering mode. Independent of\n * {@link ToolDescriptionMode}: `descriptionMode` controls the prose the\n * model sees in the system prompt, `resultRenderMode` controls how the\n * tool's RESULT is printed to the user (terminal / WebUI / TUI).\n *\n * - `simple` — meta only (filename, line count, exit code). Body is hidden\n * by default; the user can still expand on demand where the renderer\n * supports it.\n * - `extend` — full preview, up to 10 lines for read-like tools.\n *\n * The two modes are toggled independently via `/tool <name> desc simple`\n * and `/tool <name> result simple`. The legacy `/tool <name> simple`\n * command sets BOTH at once for backward compatibility.\n */\nexport type ToolResultRenderMode = 'extend' | 'simple';\nexport type ToolResultRenderModeConfig = Record<string, ToolResultRenderMode | undefined>;\n\nexport interface ProviderApiKey {\n /** Short human-readable label (e.g. \"personal\", \"work\", \"rate-limit-backup\"). */\n label: string;\n /**\n * The key itself. The field name contains `apiKey` so the secret-vault\n * walker will encrypt it on write and decrypt it on read.\n */\n apiKey: string;\n /** ISO-8601 timestamp the key was added. */\n createdAt: string;\n /**\n * How this credential was obtained.\n * - `api_key` — manually pasted API key (default)\n * - `oauth` — OAuth 2.0 device-code / authorization-code flow\n * - `session_token` — extracted from browser session (ChatGPT web, etc.)\n */\n authMethod?: 'api_key' | 'oauth' | 'session_token' | undefined;\n /** ISO-8601 expiry. When set, the token manager will refresh before this time. */\n expiresAt?: string | undefined;\n /**\n * OAuth refresh token. Stored encrypted by the secret-vault walker because\n * the field name contains `Token` (case-insensitive match by vault).\n */\n refreshToken?: string | undefined;\n /** Token type as returned by the OAuth endpoint (e.g. \"bearer\"). */\n tokenType?: string | undefined;\n /** OAuth scope string (e.g. \"openai.models.read openai.models.use\"). */\n scope?: string | undefined;\n /**\n * ChatGPT account id, extracted from the OAuth access-token JWT\n * (`https://api.openai.com/auth`.chatgpt_account_id). Sent as the\n * `chatgpt-account-id` header by the `openai-codex` wire family. Cached\n * here for display/diagnostics; the provider re-derives it from the live\n * token at request time so it can never go stale after a refresh.\n */\n accountId?: string | undefined;\n}\n\nexport interface ProviderConfig {\n type: string;\n /**\n * Legacy single-key field. Still honored as a read fallback when `apiKeys`\n * is empty (for configs not yet migrated to multi-key format). After key\n * management operations (`writeKeysBack`), this field is **cleared** to\n * prevent accidental serialization of the plaintext key. Consumers that\n * need the active API key should use `resolveActiveApiKey()` (cli) or\n * resolve from `apiKeys[]` directly — never read `cfg.apiKey` in new code.\n */\n apiKey?: string | undefined;\n /** Multiple keys for the same provider — pick one with `activeKey`. */\n apiKeys?: ProviderApiKey[] | undefined;\n /** Label of the entry in `apiKeys` to use. Defaults to the first one. */\n activeKey?: string | undefined;\n baseUrl?: string | undefined;\n headers?: Record<string, string>;\n model?: string | undefined;\n quirks?: Record<string, unknown>;\n capabilities?: Record<string, unknown>;\n /**\n * Optional wire-family override. When present, the provider can be\n * constructed without consulting the models.dev catalog — useful for\n * self-hosted endpoints, internal proxies, or for working offline.\n */\n family?: WireFamily | undefined;\n /** Custom env var names to probe when `apiKey` is missing. */\n envVars?: string[] | undefined;\n /** Optional list of models the user wants visible for this provider. */\n models?: string[] | undefined;\n /**\n * Fetch this provider's model list + per-model capabilities from its\n * `{baseUrl}/models` endpoint at startup and inject them into the catalog.\n * For openai-compatible gateways/proxies (omniroute, LiteLLM, vLLM, …) that\n * expose rich metadata there. Defaults on for presets that set it (omniroute).\n * Discovery is best-effort: a down server or missing key is a no-op.\n */\n autoDiscoverModels?: boolean | undefined;\n /**\n * Provider-relative custom model definitions (maps modelId → definition).\n * Each entry adds/overrides a model for this provider with optional\n * capability overrides. The model id is the key, not a fully qualified id.\n */\n customModels?: Record<string, CustomModelDefinition>;\n /**\n * Per-provider OAuth configuration. When present, `wstack auth login <id>`\n * uses this instead of prompting for a raw API key. Set by the catalog or\n * by the user via `/settings`.\n */\n oauthConfig?:\n | {\n /** OAuth client id registered with the provider. */\n clientId?: string | undefined;\n /** Device authorization endpoint (RFC 8628). */\n deviceCodeEndpoint?: string | undefined;\n /** Token endpoint for code exchange and refresh. */\n tokenEndpoint?: string | undefined;\n /** Authorization server URL shown to the user for opening in browser. */\n authorizationEndpoint?: string | undefined;\n /** Default OAuth scopes to request. */\n scopes?: string[] | undefined;\n }\n | undefined;\n}\n\n/**\n * One entry in the per-task model matrix. Pins a catalog role, a phase, or\n * the `*` default to a specific model (and, optionally, a specific provider).\n * Resolved at subagent-spawn time so e.g. `security-scanner` can run a\n * different model than `documentation` while the leader stays on its own.\n */\nexport interface ModelMatrixEntry {\n /** Provider registry id (e.g. \"anthropic\", \"minimax\", \"zai\"). When omitted,\n * the leader's provider is used with this entry's model. */\n provider?: string | undefined;\n /** Model id to run for the matched role/phase/default. */\n model?: string | undefined;\n /**\n * Runtime request overrides for subagents matched by this entry. This is\n * intentionally scoped to subagents: leader requests keep using top-level\n * `Config.modelRuntime`, while a role/phase can opt into its own reasoning\n * effort, cache TTL, or gated generation parameters.\n */\n modelRuntime?: ModelRuntimeConfig | undefined;\n /**\n * Named fallback profile to use for the matched role/phase/default. When\n * `model` is omitted, the first model in the profile becomes the primary and\n * the remaining entries become that subagent's fallback chain.\n */\n fallbackProfile?: string | undefined;\n}\n\nexport interface MCPServerConfig {\n /** Human-readable description shown in `wstack mcp list`. */\n description?: string | undefined;\n name: string;\n transport: 'stdio' | 'sse' | 'streamable-http';\n command?: string | undefined;\n args?: string[] | undefined;\n env?: Record<string, string>;\n url?: string | undefined;\n headers?: Record<string, string>;\n enabled?: boolean | undefined;\n allowedTools?: string[] | undefined;\n permission?: Permission | undefined;\n startupTimeoutMs?: number | undefined;\n requestTimeoutMs?: number | undefined;\n /**\n * Lazy connect: when true, the server process is NOT spawned at boot. Its\n * tools are registered from a cached manifest (discovered on the first ever\n * connect) and the server only spawns when one of its tools is actually\n * called, then auto-sleeps after an idle period. Default (false/undefined) =\n * eager connect at boot.\n */\n lazy?: boolean | undefined;\n}\n\nexport interface LogConfig {\n level: 'error' | 'warn' | 'info' | 'debug' | 'trace';\n file?: string | undefined;\n}\n\nexport interface PluginConfig {\n name: string;\n enabled?: boolean | undefined;\n options?: Record<string, unknown>;\n}\n\n/**\n * Optional subsystems that the CLI can boot without. The core flow\n * (provider + agent loop + bundled tools + session) always works; these\n * just add capabilities. `--no-features` flips all of these off, which\n * is the minimum viable WrongStack: a single provider, a fixed config,\n * no network calls at startup.\n */\nexport interface FeaturesConfig {\n /** Load MCP servers declared in `mcpServers`. */\n mcp: boolean;\n /** Load + initialise npm plugins declared in `plugins`. */\n plugins: boolean;\n /** Register `remember` / `forget` tools backed by memory store. */\n memory: boolean;\n /**\n * Automatically consolidate session learnings into long-term memory\n * after each completed run. The agent extracts key facts, conventions,\n * and decisions via a lightweight LLM call and persists them.\n * Enabled by default when `memory` is on; set to false to opt out.\n */\n memoryConsolidation?: boolean | undefined;\n /** Fetch the models.dev catalog at startup. When false, the provider\n * must declare its `family` explicitly in `providers[<id>]`. */\n modelsRegistry: boolean;\n /** Discover + load skills from disk. */\n skills: boolean;\n /**\n * Enable the prompt library (`/prompt`, `/prompts`, `/prompt-gen`, the WebUI\n * modal and the bundled 168-prompt dataset). Defaults to on; set to false to\n * disable the subsystem entirely (the loader is withheld so every surface\n * reports it unavailable).\n */\n prompts?: boolean | undefined;\n /**\n * Token-saving mode tier. Controls how aggressively the system prompt\n * is compacted to reduce per-request token consumption.\n *\n * - 'off' — Full prompt, all tools, complete guidance\n * - 'minimal' — TIER1 tools only, stripped guidance (~3-4k tokens saved)\n * - 'light' — Core + memory tools, common patterns, minimal guidance\n * - 'medium' — Most development tools, some guidance\n * - 'aggressive' — Maximum savings before tools become unusable (~4-5k tokens)\n *\n * Boolean values are accepted for backward compatibility:\n * - `true` → 'medium'\n * - `false` → 'off'\n *\n * Enable via CLI: `--token-saving-tier <level>` or `--token-saving-mode` (maps to 'medium').\n * Configure via: `features.tokenSavingMode: \"minimal\"` in config.\n */\n tokenSavingMode?: TokenSavingTier | boolean | undefined;\n /**\n * Enable the autonomous-coordination toolkit (AutonomousCoordinator +\n * KnowledgeGraph + ConsensusProtocol + TaskAuctioneer + ChangeManager +\n * TaskDAG). When true (the default), the TUI boot wires the coordinator\n * lazily on the first Director spawn. When false, the coordinator is\n * never constructed and the `/coordinator` slash command reports it\n * unavailable — reducing the coordination domain's runtime surface for\n * users who only use the simpler Director/Fleet path.\n */\n autonomousCoordination?: boolean | undefined;\n /**\n * Allow tools to read/write paths outside the project root directory.\n * When true (default), tools can access any path on the filesystem.\n * When false, tools are restricted to the project root directory.\n */\n allowOutsideProjectRoot?: boolean | undefined;\n /**\n * Auto-bootstrap the mailbox HTTP bridge from any WrongStack surface\n * (REPL/TUI/WebUI/eternal). When 'auto' (the default), the first\n * surface to come up for a given project joins or spawns the bridge\n * so external agents can connect without the user running\n * `wstack mailbox serve` themselves. 'off' disables this — operators\n * must start the bridge explicitly (e.g. via the `/mailbox-serve`\n * slash command or the standalone `wstack mailbox serve` subcommand).\n * The per-project lock + token-persistence model means a second\n * surface on the same project joins the first's bridge rather than\n * spawning a duplicate.\n */\n mailboxBridge?: 'auto' | 'off' | undefined;\n}\n\nexport interface AutonomyConfig {\n /** Default autonomy mode at startup. Default: \"off\". */\n defaultMode?: 'off' | 'suggest' | 'auto' | undefined;\n /** ms to wait before auto-proceeding in 'auto' mode. Default: 45000. */\n autoProceedDelayMs?: number | undefined;\n /** Maximum consecutive auto-proceed turns before pausing. 0 = unlimited. Default: 50. */\n autoProceedMaxIterations?: number | undefined;\n /** Template used for YOLO+auto suggestions. Must include {{suggestion}}. */\n autonomyNextPrompt?: string | undefined;\n /** Animate the terminal/window title while the agent is active. Default: true. */\n terminalTitleAnimation?: boolean | undefined;\n /** Persisted YOLO preference mirrored into top-level config.yolo at runtime. Default: false. */\n yolo?: boolean | undefined;\n /** Stream fleet/subagent output into the main TUI chat. Default: true. */\n streamFleet?: boolean | undefined;\n /** Ring terminal bell when an agent run completes. Default: false. */\n chime?: boolean | undefined;\n /** Ask for confirmation before interrupt/exit. Default: true. */\n confirmExit?: boolean | undefined;\n /** Terminal mouse tracking preference. Default: false. */\n mouseMode?: boolean | undefined;\n /** Enable prompt refinement before sending. Default: true. */\n enhance?: boolean | undefined;\n /** Prompt-refinement preview countdown in ms. Default: 60000. */\n enhanceDelayMs?: number | undefined;\n /** Prompt-refinement language mode. Default: \"original\". */\n enhanceLanguage?: 'original' | 'english' | undefined;\n /** TUI statusline density. Default: \"detailed\". */\n statuslineMode?: 'minimum' | 'detailed' | undefined;\n /** Single short word shown in the TUI rainbow working-state chip. Default: \"thinking\". */\n thinkingWord?: string | undefined;\n /**\n * Persist the TUI prompt input history to disk per project so Up/Down\n * navigation recalls prompts across sessions. Secrets are scrubbed before\n * they reach disk. Default: enabled, 100 entries.\n */\n inputHistory?: InputHistoryConfig | undefined;\n}\n\n/**\n * Per-project TUI input history persistence options. Lives under\n * `config.autonomy.inputHistory` because the TUI-specific knobs on Config\n * are grouped there.\n */\nexport interface InputHistoryConfig {\n /** Persist history to ~/.wrongstack/projects/<slug>/input-history.json. Default: true. */\n enabled?: boolean | undefined;\n /** Max entries kept on disk (and in memory). Default: 100. */\n maxEntries?: number | undefined;\n}\n\n/**\n * Automatic codebase symbol-index maintenance. Keeps the `codebase-search`\n * index (SQLite, `~/.wrongstack/projects/<hash>/codebase-index/index.db`) fresh\n * without the user having to call `codebase-index` by hand.\n */\nexport interface IndexingConfig {\n /** Run a blocking incremental index at session start (with a visible summary). Default: true. */\n onSessionStart: boolean;\n /** Reindex files the agent writes/edits via tools, in the background. Default: true. */\n onEdit: boolean;\n /** Watch the project root for external editor changes and reindex them. Default: true. */\n watchExternal: boolean;\n /** Debounce window (ms) coalescing rapid edits to the same file. Default: 400. */\n debounceMs: number;\n /**\n * Watchdog timeout (ms) for a full index run. A run exceeding this is\n * aborted (so it can never wedge the indexing mutex or freeze the terminal)\n * and counts toward the indexing circuit breaker. Default: 120000.\n */\n indexTimeoutMs?: number | undefined;\n}\n\n/**\n * Saved launch preferences — restored on next boot so the pre-launch prompt\n * can offer a one-line \"Continue with last settings? [Y/n]\" instead of\n * re-asking every question from scratch.\n */\nexport interface LaunchConfig {\n /** Interactive mode: 'tui' (Ink TUI) or 'repl' (readline REPL). */\n mode?: 'tui' | 'repl' | undefined;\n /** Start with Director mode on (fleet manifest + multi-agent orchestration). */\n director?: boolean | undefined;\n /**\n * Launch-time autonomy mode (binary choice from pre-launch prompt).\n * 'off' = stops after each turn; 'auto' = self-driving.\n * Distinct from `AutonomyConfig.defaultMode` which also supports 'suggest'.\n */\n autonomy?: 'off' | 'auto' | undefined;\n}\n\n/**\n * Controls how much detail is persisted to the per-session JSONL log\n * (`~/.wrongstack/projects/<hash>/sessions/<date>/sess_<ULID>.jsonl`).\n */\nexport interface SessionLoggingConfig {\n /**\n * How much detail to write to the persistent session log.\n *\n * - \"minimal\" → Only events required for resume/rewind/recovery\n * - \"standard\" → (default) + high-value lightweight audit events\n * (compaction, tool timing, retries, errors, etc.)\n * - \"full\" → Also persist full request payloads (very large).\n * Consider enabling a separate replay log instead.\n */\n auditLevel?: 'minimal' | 'standard' | 'full' | undefined;\n\n /**\n * Sampling configuration for high-volume events (especially relevant at\n * `auditLevel: \"full\"`).\n */\n sampling?: {\n /** Controls sampling of `tool_progress` events. */\n toolProgress?: {\n /**\n * Sample rate for noisy progress events (`log`, `partial_output`).\n * - 1 = no sampling (every message is logged)\n * - 8 = default (first message + every 8th)\n */\n sampleRate?: number | undefined;\n };\n };\n}\n\nexport type SyncCategory = 'settings' | 'skills' | 'prompts' | 'memory' | 'history';\n\nexport interface SyncConfig {\n enabled: boolean;\n repo: string;\n /** GitHub token (fine-grained PAT). Encrypted at rest via SecretVault. */\n githubToken: string;\n categories: SyncCategory[];\n lastSyncedAt?: string | undefined;\n}\n\n/**\n * Per-model capability overrides the user can define in their config.\n * Used to add models not in the models.dev catalog, or override catalog\n * facts when the real backend differs (e.g. local Ollama models, proxies).\n */\nexport interface CustomModelDefinition {\n /** Provider this model belongs to. Defaults to the owning ProviderConfig. */\n provider?: string | undefined;\n /** Optional display name. */\n name?: string | undefined;\n /** Capability overrides — only specified fields are overlaid. */\n capabilities?: Partial<Capabilities> | undefined;\n /**\n * Max output tokens. If not specified, the provider family default\n * or catalog entry is used.\n */\n maxOutput?: number | undefined;\n}\n\n/**\n * Skill subsystem configuration. All fields optional; the subsystem itself is\n * gated by `features.skills`. Honored from the user's `~/.wrongstack/config.json`;\n * in the repo-committed in-project config the `extraDirs` field is stripped\n * (arbitrary directories are a prompt-injection vector) — only `readClaudeSkills`\n * and `mode` survive there.\n */\nexport interface SkillsConfig {\n /**\n * Read skills from foreign coding-agent directories (`<project>/.claude/skills`\n * and `~/.claude/skills`). Default `true`. Lets Claude Code / Codex / Gemini /\n * `asm` / `gh skill` skills be used without copying them.\n */\n readClaudeSkills?: boolean | undefined;\n /**\n * Scan OTHER coding agents' skill directories (`~/.codex/skills`,\n * `~/.cursor/skills`, `~/.agents/skills`, `~/.qwen/skills`,\n * `~/.trae/skills`, … + their `<project>/.<tool>/…` equivalents). Default\n * `true` (all known tools); pass a tool-id list to restrict, or `false` to\n * disable. Non-existent dirs are skipped. Unknown ids in the list (likely\n * typos) are dropped and surfaced via a config warning.\n */\n foreignSources?: boolean | string[] | undefined;\n /**\n * How skill bodies reach the system prompt.\n * - `'eager'` (default): inject every discovered skill body into the prompt.\n * - `'progressive'`: inject only the metadata manifest; the agent loads a\n * skill body on demand via the `skill` tool (the agentskills.io model).\n */\n mode?: 'eager' | 'progressive' | undefined;\n /**\n * Extra skill directories to scan (lowest priority, after the `.claude`\n * layers). Honored only from the user config; stripped from in-project config.\n */\n extraDirs?: string[] | undefined;\n /**\n * In eager mode, the maximum total chars of skill bodies injected into the\n * prompt (highest-priority skills first; the rest are listed as a manifest the\n * agent loads via the `skill` tool). Bounds prompt cost when many skills are\n * discovered. Default 24000 (~6k tokens). Set very high to disable. Ignored in\n * progressive mode (which injects only the manifest anyway).\n */\n eagerMaxChars?: number | undefined;\n /**\n * Base URL of the skill registry used by `/skill-search` and\n * `/skill-install <registry>:<id>`. Default `https://skills.sh` (the open\n * marketplace backed by mastra-ai/skills-api). Honored only from the user\n * config; stripped from in-project config (a repo-committed override would be\n * an SSRF / prompt-injection vector — the registry response is parsed into the\n * prompt). Set to a self-hosted skills-api instance to use a private catalog.\n */\n registryUrl?: string | undefined;\n}\n\n/**\n * Fleet peer-awareness + supervision settings. All sub-features are\n * enabled-by-default with conservative throttles; each has its own kill\n * switch. See `FleetSupervisor` (coordination/fleet-supervisor.ts) for the\n * supervisor semantics.\n */\nexport interface FleetConfig {\n /** Periodic \"[FLEET PULSE]\" peer-status digest folded into each agent's context. */\n pulse?:\n | {\n /** Default true. */\n enabled?: boolean | undefined;\n /** Inject at most every N agent iterations. Default 5. */\n everyNIterations?: number | undefined;\n /** Hard cap on digest characters. Default 900. */\n maxChars?: number | undefined;\n /** Max peers listed per digest. Default 15. */\n maxAgents?: number | undefined;\n }\n | undefined;\n /** Broadcast `type:'status'` mails on meaningful subagent transitions. */\n statusBroadcasts?:\n | {\n /** Default true. */\n enabled?: boolean | undefined;\n /** Min interval between broadcasts about the same subagent. Default 15000. */\n minIntervalMsPerAgent?: number | undefined;\n /** Global cap on broadcasts per minute (excess dropped + counted). Default 20. */\n globalPerMinuteCap?: number | undefined;\n }\n | undefined;\n /**\n * Per-subagent git-worktree isolation for Director fleets. The default is\n * `auto`: mutating/build-capable subagents run in isolated checkouts and are\n * squash-merged back on success; read-only review agents usually stay on the\n * shared checkout. Set `enabled:false` or `mode:'off'` when a workflow cannot\n * use worktrees.\n */\n worktrees?:\n | {\n /** Kill switch. Default true. */\n enabled?: boolean | undefined;\n /**\n * `auto` (default): isolate only side-effectful subagents.\n * `required`: side-effectful subagents must get a worktree or fail.\n * `off`: never allocate worktrees.\n */\n mode?: 'auto' | 'required' | 'off' | undefined;\n /**\n * Merge successful task branches back into the base checkout. Default\n * true. When false, successful worktrees are committed and kept for\n * manual `/worktree merge`.\n */\n autoMerge?: boolean | undefined;\n /** Keep failed/timeout worktrees when they contain changes. Default true. */\n keepFailed?: boolean | undefined;\n }\n | undefined;\n /** Brain-gated fleet supervisor (rebalance/steer/spawn-helper). */\n supervisor?: FleetSupervisorConfig | undefined;\n}\n\n/** Config surface for the brain-gated FleetSupervisor. */\nexport interface FleetSupervisorConfig {\n /** Kill switch. Default true (active whenever a Director is running). */\n enabled?: boolean | undefined;\n /** Evaluation tick. Default 20000. */\n intervalMs?: number | undefined;\n /** Per-(signal,subject) re-engagement cooldown. Default 120000. */\n cooldownMs?: number | undefined;\n /** Hard cap on interventions touching one subagent per run. Default 3. */\n maxInterventionsPerSubagent?: number | undefined;\n /** Pending task pinned to a busy worker longer than this → starvation signal. Default 60000. */\n pinnedWaitMs?: number | undefined;\n /** ≥ this many pending tasks pinned to one worker (with an idle sibling) → overload signal. Default 2. */\n overloadPinnedThreshold?: number | undefined;\n /** pending > backlogFactor × live workers (sustained) → spawn-helper signal. Default 2. */\n backlogFactor?: number | undefined;\n /** Running subagent with no tool activity for this long → stuck signal. Default 180000. */\n stuckMs?: number | undefined;\n /** Consecutive failed/timeout results from one subagent → failure-streak signal. Default 2. */\n failureStreak?: number | undefined;\n /** Allow the supervisor to spawn helper subagents. Default true. */\n allowSpawn?: boolean | undefined;\n /** Allow the supervisor to terminate subagents (highest risk). Default false. */\n allowTerminate?: boolean | undefined;\n}\n\nexport interface Config {\n version: 1;\n provider: string;\n model: string;\n apiKey?: string | undefined;\n baseUrl?: string | undefined;\n /**\n * Maximum number of subagent tasks the fleet coordinator dispatches\n * simultaneously. Extra tasks queue until a slot frees. Default: 4.\n * Overridden by WRONGSTACK_MAX_CONCURRENT env var and --max-concurrent\n * CLI flag. Change at runtime with /fleet concurrency <n>.\n */\n maxConcurrent?: number | undefined;\n /**\n * Display language for the UI chrome (WebUI + desktop shell). A BCP-47-ish\n * code from SUPPORTED_LOCALES (en/tr/de/fr/it/es/pt-BR). Persisted here so a\n * change in one surface propagates to all others via the shared machine\n * config; each surface may keep a local cache for instant reactivity. When\n * unset, surfaces fall back to their own browser/system detection.\n */\n uiLocale?: string | undefined;\n providers?: Record<string, ProviderConfig>;\n /**\n * Top-level custom models (maps modelId → definition). Merged with\n * per-provider `customModels` at resolution time. The key is the\n * model id — not a fully qualified name. When the same model id\n * appears in both places, the top-level one wins.\n */\n models?: Record<string, CustomModelDefinition>;\n /**\n * Per-task model matrix. Keys are catalog roles (e.g. \"security-scanner\"),\n * phase names (e.g. \"review\"), or the `*` default. Resolution precedence at\n * subagent spawn: exact role → the role's phase → `*` → leader model. Set via\n * the `/setmodel` slash command; persisted to ~/.wrongstack/config.json.\n */\n modelMatrix?: Record<string, ModelMatrixEntry>;\n /**\n * User-curated model references shown/prioritized by model commands and used\n * by smart fallback derivation. Entries are `model`, `provider/model`, or\n * `provider model`.\n */\n favoriteModels?: string[] | undefined;\n /**\n * When true, auto-derived fallback chains are restricted to `favoriteModels`.\n * Explicit fallback profiles/chains are always honored as written.\n */\n favoriteModelsOnly?: boolean | undefined;\n context: ContextConfig;\n tools: ToolsConfig;\n mcpServers?: Record<string, MCPServerConfig>;\n /**\n * Per-agent ACP invocation overrides, keyed by catalog agent id\n * (`claude-code`, `codex-cli`, `gemini-cli`, …). Lets a user correct an\n * agent's ACP entry command — e.g. point `claude-code` at the right\n * adapter — without a code change. Consumed by `/acp`, `/ensemble`, and\n * `wstack acp`. SECURITY: this is an arbitrary-command exec surface, so it\n * is in the in-project config DENY list — only honoured from the user's\n * `~/.wrongstack/config.json`, never from a repo-committed config.\n */\n acp?: {\n agents?: Record<string, { command: string; args?: string[]; env?: Record<string, string> }>;\n };\n /**\n * Ordered list of fallback model references tried, in order, when the\n * primary model is overloaded (HTTP 429/529/5xx) and its own retries are\n * exhausted. Each entry is a model reference: a bare model id (same\n * provider), `provider/model`, or `provider model`. After a fallback hop,\n * the primary is retried only after its cooldown expires. See\n * `createFallbackModelExtension`.\n */\n fallbackModels?: string[] | undefined;\n /**\n * Named fallback chains. A profile's first entry can be used as a primary\n * model by `/setmodel`, while the whole ordered list is used for failover.\n */\n fallbackProfiles?: Record<string, string[]> | undefined;\n /**\n * When `true` (the default) and `fallbackModels` is empty, a fallback chain\n * is derived automatically from the other keyed providers/models so 429s\n * recover out of the box. Set `false` to disable the smart default and only\n * use an explicit `fallbackModels` list. Toggle via `/fallback auto on|off`.\n */\n fallbackAuto?: boolean | undefined;\n /**\n * Lifecycle shell hooks, keyed by event. Each command receives the hook\n * `HookInput` JSON on stdin; a JSON `HookOutcome` on stdout (and exit code 2\n * = block) steers the agent. In-process hooks are registered separately via\n * the plugin API. Disabled entirely under `--bare` / `--no-hooks`.\n */\n hooks?: Partial<Record<HookEvent, ShellHook[]>>;\n plugins?: (string | PluginConfig)[] | undefined;\n log: LogConfig;\n features: FeaturesConfig;\n /** Skill subsystem options (readClaudeSkills / mode / extraDirs). */\n skills?: SkillsConfig | undefined;\n yolo?: boolean | undefined;\n /** When true, show lightweight LLM-predicted next steps after each turn (/next). */\n nextPrediction?: boolean | undefined;\n cwd?: string | undefined;\n /** Autonomy mode configuration (auto-proceed delay, etc.). */\n autonomy?: AutonomyConfig | undefined;\n /** Show rotating launch hints on startup. Default: true. Set to false to suppress. */\n hints?: boolean | undefined;\n /** Raw SSE stream debugging — hex-dump every byte received from providers to stderr. */\n debugStream?: boolean | undefined;\n /**\n * Where settings are persisted. 'global' → ~/.wrongstack/config.json\n * (default). 'project' → <project>/.wrongstack/config.json.\n * When 'project', safe settings are saved per-project.\n */\n configScope?: 'global' | 'project' | undefined;\n /** Automatic codebase symbol-index maintenance (session-start + live updates). */\n indexing?: IndexingConfig | undefined;\n /**\n * Process circuit-breaker protection (gates `bash`/`exec` on repeated\n * failures). Default off — toggle with `/settings breaker on|off`.\n */\n circuitBreaker?: CircuitBreakerRuntimeConfig | undefined;\n /**\n * Adaptive concurrency controller — automatically adjusts `maxConcurrent` based on\n * rate-limit (429) errors. On 429: decreases concurrency. On sustained success:\n * gradually increases concurrency back up. Default off.\n */\n adaptiveConcurrency?: AdaptiveConcurrencyConfig | undefined;\n /** Saved launch preferences — restored on next boot for one-line confirmation. */\n launch?: LaunchConfig | undefined;\n\n /**\n * Session logging & audit configuration.\n * Controls what gets written to the persistent JSONL transcript.\n */\n session?: SessionLoggingConfig | undefined;\n /**\n * Runtime reasoning / cache controls applied to every provider request\n * (REPL/TUI/WebUI). Mapped into `Request.reasoning` and `Request.cache` by a\n * single request-pipeline middleware, gated by the active model's\n * capabilities. See `ModelRuntimeConfig`.\n */\n modelRuntime?: ModelRuntimeConfig | undefined;\n /** HQ client publishing settings, used by CLI/REPL/TUI/WebUI consistently. */\n hq?: HqClientConfig | undefined;\n /**\n * Fleet awareness + supervision settings (peer-status pulse digests,\n * status-broadcast mails, and the brain-gated FleetSupervisor). SECURITY:\n * in the in-project config DENY list — a repo-committed config must not be\n * able to enable autonomous spawning/steering or mailbox traffic. Only\n * honoured from the user's `~/.wrongstack/config.json`.\n */\n fleet?: FleetConfig | undefined;\n /**\n * Cloud sync configuration. Stored separately in sync.json to avoid\n * accidentally committing the GitHub token to project configs.\n */\n sync?: SyncConfig | undefined;\n /**\n * Per-plugin namespaced config sections. Each plugin reads its own\n * subtree via `ConfigStore.getExtension(pluginName)`. Plugins should\n * declare a `configSchema` so the loader validates this section\n * automatically before `setup()` runs.\n *\n * Example:\n * extensions: {\n * 'wstack-auth': { tokenUrl: 'https://...', refreshBefore: 300 },\n * 'wstack-metrics': { sink: 'prometheus', port: 9090 },\n * }\n */\n extensions?: Record<string, Record<string, unknown>>;\n}\n\nexport interface ConfigLoader {\n load(opts?: {\n cliFlags?: Partial<Config> | undefined;\n cwd?: string | undefined;\n }): Promise<Config>;\n /** Load and decrypt the sync config from ~/.wrongstack/sync.json. */\n loadSyncConfig(): Promise<SyncConfig | null>;\n /** Persist sync config to ~/.wrongstack/sync.json with encrypted token. */\n persistSyncConfig(cfg: SyncConfig): Promise<void>;\n}\n\n/**\n * Subscribable view over Config. Plugins and CLI subsystems use this instead\n * of holding a frozen Config reference, so they can react to runtime updates\n * (e.g. `/model` switching the active provider, secrets rotation, dynamic\n * extension reload).\n *\n * The store enforces immutability — `get()` always returns a frozen object.\n * Updates happen through `update(partial)`, which produces a new Config\n * (structurally cloned, then frozen) and notifies watchers.\n */\nexport interface ConfigStore {\n get(): Readonly<Config>;\n /**\n * Get a typed top-level section. Convenience for consumers that only\n * care about one slice (e.g. `tools` or `context`).\n */\n getSection<K extends keyof Config>(key: K): Readonly<Config[K]>;\n /**\n * Return the extension namespace for `pluginName`, or an empty record\n * when none is configured. The returned object is frozen.\n */\n getExtension(pluginName: string): Readonly<Record<string, unknown>>;\n /**\n * Apply a partial update. Returns the new Config. Watchers are notified\n * synchronously after the update completes. Throws if the result fails\n * any registered invariants (currently: version must stay 1).\n */\n update(partial: Partial<Config>): Readonly<Config>;\n /** Subscribe to changes. Returns an unsubscribe function. */\n watch(cb: (next: Readonly<Config>, prev: Readonly<Config>) => void): () => void;\n}\n","/**\n * Shared configuration constants used across execution, storage, CLI, and WebUI.\n * Centralized here to avoid cross-domain import cycles.\n */\n\n/** Default tools config — mirrors values baked into BEHAVIOR_DEFAULTS. */\nexport const DEFAULT_TOOLS_CONFIG = Object.freeze({\n defaultExecutionStrategy: 'smart',\n maxIterations: 100,\n iterationTimeoutMs: 300_000,\n sessionTimeoutMs: 1_800_000,\n perIterationOutputCapBytes: 100_000,\n descriptionMode: Object.freeze({}) as Record<string, 'extend' | 'simple' | undefined>,\n disabledTools: Object.freeze([]) as readonly string[],\n autoExtendLimit: true,\n restrictToProjectRoot: false,\n});\n\n/** Default context config — mirrors BEHAVIOR_DEFAULTS.context. */\nexport const DEFAULT_CONTEXT_CONFIG = Object.freeze({\n preserveK: 10,\n eliseThreshold: 2000,\n});\n\n/** Default autonomy config — auto-proceed delay etc. */\nexport const DEFAULT_AUTONOMY_CONFIG = Object.freeze({\n autoProceedDelayMs: 45_000,\n});\n\n/**\n * Default process circuit-breaker config. Protection is OFF by default — the\n * breaker only gates `bash`/`exec` once the user opts in via `/settings breaker on`.\n * The auto kill/reset delay is only consulted when protection is enabled.\n */\nexport const DEFAULT_CIRCUIT_BREAKER_CONFIG = Object.freeze({\n enabled: false,\n autoKillResetMs: 60_000,\n});\n\n/** Default session logging / audit configuration. */\nexport const DEFAULT_SESSION_LOGGING_CONFIG = Object.freeze({\n auditLevel: 'standard' as const,\n sampling: {\n toolProgress: {\n sampleRate: 8,\n },\n },\n});\n\n/** Default retention window for local session pruning. */\nexport const DEFAULT_SESSION_PRUNE_DAYS = 30;\n","export type MemoryScope = 'project-agents' | 'project-memory' | 'user-memory';\n\n// ── Memory categories ──────────────────────────────────────────────────\n\nexport type MemoryType = 'fact' | 'decision' | 'convention' | 'preference' | 'reference' | 'anti_pattern';\n\nexport const MEMORY_TYPE_LABELS: Record<MemoryType, string> = {\n fact: 'Fact',\n decision: 'Decision',\n convention: 'Convention',\n preference: 'Preference',\n reference: 'Reference',\n anti_pattern: 'Anti-pattern',\n};\n\nexport type MemoryPriority = 'critical' | 'high' | 'medium' | 'low';\n\nexport interface MemoryEntry {\n scope: MemoryScope;\n text: string;\n ts: string;\n /** Category — helps the agent decide whether to inject or ignore. */\n type?: MemoryType | undefined;\n /** Free-form tags for grouping (e.g. [\"build\", \"pnpm\", \"typescript\"]). */\n tags?: string[] | undefined;\n /** Priority — critical entries are always injected; low may be skipped. */\n priority?: MemoryPriority | undefined;\n /** Session or agent that created this entry. */\n source?: string | undefined;\n /** 0.0–1.0 confidence. Low-confidence entries are injected less often. */\n confidence?: number | undefined;\n /** ISO timestamp of last access (read or injection into context). */\n lastAccessed?: string | undefined;\n}\n\n// ── Memory events — emitted by DefaultMemoryStore so plugins can react ──\n\nexport interface MemoryRememberedPayload {\n scope: MemoryScope;\n text: string;\n ts: string;\n type?: MemoryType | undefined;\n tags?: string[] | undefined;\n priority?: MemoryPriority | undefined;\n}\n\nexport interface MemoryForgottenPayload {\n scope: MemoryScope;\n query: string;\n removed: number;\n}\n\nexport interface MemoryClearedPayload {\n /** Scope that was cleared, or undefined when all scopes were cleared. */\n scope?: MemoryScope | undefined;\n}\n\nexport interface MemoryConsolidatedPayload {\n scope: MemoryScope;\n /** Entries removed by deduplication. */\n removed: number;\n}\n\n// ── Relevance scoring ──────────────────────────────────────────────────\n\n/**\n * Context used to score memory relevance for context injection.\n * Passed by the system prompt builder.\n */\nexport interface MemoryRelevanceContext {\n /** Current user message or task description. */\n currentTask: string;\n /** Active skills in this session (e.g. [\"typescript-strict\", \"git-flow\"]). */\n activeSkills?: string[] | undefined;\n /** Active mode (e.g. \"Teach\", \"Brief\", \"Code Reviewer\"). */\n activeMode?: string | undefined;\n /** Available tools — memories referencing relevant tools score higher. */\n toolNames?: string[] | undefined;\n}\n\nexport interface ScoredEntry extends MemoryEntry {\n score: number;\n matchReason: string;\n}\n\n// ── Store interface ────────────────────────────────────────────────────\n\nexport interface MemoryStore {\n readAll(): Promise<string>;\n read(scope: MemoryScope): Promise<string>;\n remember(text: string, scope?: MemoryScope, metadata?: Omit<Partial<MemoryEntry>, 'scope' | 'text' | 'ts'>): Promise<void>;\n forget(query: string, scope?: MemoryScope): Promise<number>;\n consolidate(scope: MemoryScope): Promise<void>;\n clear(scope?: MemoryScope): Promise<void>;\n /** List entries, newest first. */\n list(scope?: MemoryScope, limit?: number): Promise<MemoryEntry[]>;\n /** Search by content (substring or semantic). */\n search(query: string, scope?: MemoryScope, limit?: number): Promise<MemoryEntry[]>;\n /** Access the backend for advanced queries. */\n getBackend?(): unknown;\n /** Graph-based related memory traversal. */\n findRelated?(text: string, scope?: MemoryScope, limit?: number): Promise<MemoryEntry[]>;\n /**\n * Score and rank memories by relevance to the current context.\n * Returns only entries that meet a relevance threshold.\n */\n scoreRelevant?(ctx: MemoryRelevanceContext, scope?: MemoryScope, limit?: number): Promise<ScoredEntry[]>;\n /**\n * Attach a trace ID to this store so that all subsequent `storage.*`\n * events include it for observability correlation. Mutates the store\n * in place and returns the same instance (convenience chaining).\n */\n withTraceId(traceId: string): MemoryStore;\n}\n","/**\n * Prompt library types — the canonical home for the prompt data model and the\n * loader/registry contracts. Has no internal dependencies so both `storage/`\n * (the writable store) and `execution/` (the layered loader) can import it\n * without creating a cycle.\n */\n\n/** Provenance of a prompt — which layer it came from. */\nexport type PromptSource = 'builtin' | 'user' | 'project' | 'synced';\n\n/**\n * The fourteen first-party categories shipped with the builtin dataset, plus\n * the `uncategorized` sentinel used when migrating legacy v1 entries. Builtin\n * prompts MUST use one of these (enforced by the dataset schema test); user and\n * project prompts may use any free-form string.\n */\nexport const BUILTIN_PROMPT_CATEGORIES = [\n 'coding',\n 'debugging',\n 'refactoring',\n 'testing',\n 'code-review',\n 'architecture',\n 'devops',\n 'documentation',\n 'data-analysis',\n 'writing',\n 'research',\n 'product',\n 'agentic-workflows',\n 'meta-prompting',\n 'uncategorized',\n] as const;\n\nexport type BuiltinPromptCategory = (typeof BUILTIN_PROMPT_CATEGORIES)[number];\n\n/**\n * Human-readable labels for the builtin categories (for UI chips / pickers).\n */\nexport const PROMPT_CATEGORY_LABELS: Record<BuiltinPromptCategory, string> = {\n coding: 'Coding',\n debugging: 'Debugging',\n refactoring: 'Refactoring',\n testing: 'Testing',\n 'code-review': 'Code Review',\n architecture: 'Architecture',\n devops: 'DevOps',\n documentation: 'Documentation',\n 'data-analysis': 'Data Analysis',\n writing: 'Writing',\n research: 'Research',\n product: 'Product',\n 'agentic-workflows': 'Agentic Workflows',\n 'meta-prompting': 'Meta-Prompting',\n uncategorized: 'Uncategorized',\n};\n\n/**\n * A prompt's category. Typed as a free-form string because user/project prompts\n * may invent their own; the builtin dataset is constrained to\n * {@link BUILTIN_PROMPT_CATEGORIES} by its schema.\n */\nexport type PromptCategory = BuiltinPromptCategory | (string & {});\n\nexport function isBuiltinCategory(value: string): value is BuiltinPromptCategory {\n return (BUILTIN_PROMPT_CATEGORIES as readonly string[]).includes(value);\n}\n\n/** A `{{name}}` placeholder declared by a prompt. */\nexport interface PromptVariable {\n /** Placeholder name as it appears between `{{ }}` (case-sensitive). */\n name: string;\n description?: string | undefined;\n default?: string | undefined;\n required?: boolean | undefined;\n /**\n * Closed set of allowed values. When present, surfaces render a dropdown\n * instead of a free text field and a supplied value outside the set is\n * reported as invalid by {@link renderPrompt}.\n */\n enum?: string[] | undefined;\n /**\n * UI hint: the value is expected to span multiple lines (pasted code, a\n * diff, a long passage). Surfaces render a textarea instead of a one-line\n * input. Has no effect on rendering — purely presentational.\n */\n multiline?: boolean | undefined;\n}\n\n/**\n * A reusable prompt. v2 schema. Legacy v1 entries (only `id/title/content/tags/\n * createdAt/updatedAt`) are upgraded lazily on read by `migratePromptEntry`.\n */\nexport interface PromptEntry {\n /** Stable unique handle (ULID for new entries; legacy short hex tolerated). */\n id: string;\n /** kebab-case stable key — the dedup key across layers and registry key. */\n slug: string;\n title: string;\n /** One-line summary shown in lists/pickers. */\n description: string;\n content: string;\n category: PromptCategory;\n /** Secondary facets (free-form). */\n tags: string[];\n source: PromptSource;\n favorite: boolean;\n /** `{{placeholder}}` variables this prompt expects, if any. */\n variables?: PromptVariable[] | undefined;\n author?: string | undefined;\n version?: string | undefined;\n license?: string | undefined;\n /** sha256 of `content` — set for builtin/synced entries for integrity. */\n checksum?: string | undefined;\n /** When a builtin was copy-on-written into the user layer, its origin slug. */\n forkedFrom?: string | undefined;\n createdAt: string;\n updatedAt: string;\n}\n\n/** One category with its prompt count, for picker chips. */\nexport interface PromptCategoryCount {\n id: PromptCategory;\n label: string;\n count: number;\n}\n\nexport interface PromptSearchOptions {\n category?: PromptCategory | undefined;\n /** Max results (default: unbounded). */\n limit?: number | undefined;\n}\n\n/**\n * Read-side contract over the three prompt layers (project > user > builtin),\n * merged and de-duplicated by slug. Mirrors `SkillLoader` in shape.\n */\nexport interface PromptLoader {\n /** All prompts across layers, project/user shadowing builtin by slug. */\n list(): Promise<PromptEntry[]>;\n /** Resolve by slug first, then by id. */\n find(slugOrId: string): Promise<PromptEntry | undefined>;\n /** Ranked search over title/description/content/tags, optional category filter. */\n search(query: string, opts?: PromptSearchOptions): Promise<PromptEntry[]>;\n /** Category counts across all layers, for UI chips. */\n categories(): Promise<PromptCategoryCount[]>;\n /**\n * Persist into the writable (user, or project when `scope:'project'`) layer.\n * Throws if the resolved target is the read-only builtin layer.\n */\n save(entry: PromptEntry, opts?: { scope?: 'user' | 'project' }): Promise<void>;\n /** Delete from a writable layer. Returns false if not found / builtin. */\n delete(slugOrId: string): Promise<boolean>;\n /**\n * Mark/unmark a prompt as favorite. Favoriting a builtin copies it down into\n * the user layer (copy-on-write, `source:'user'`, `forkedFrom:<slug>`).\n */\n setFavorite(slugOrId: string, favorite: boolean): Promise<PromptEntry | undefined>;\n /** Clear the internal cache so the next read re-scans disk. */\n invalidateCache(): void;\n}\n\n/**\n * The packed builtin index (also the shape a remote registry manifest mirrors\n * — see `types/prompt-registry.ts`).\n */\nexport interface PromptManifest {\n datasetVersion: number;\n generatedAt: string;\n count: number;\n categories: PromptCategoryCount[];\n prompts: PromptManifestRef[];\n}\n\nexport interface PromptManifestRef {\n id: string;\n slug: string;\n title: string;\n description: string;\n category: PromptCategory;\n tags: string[];\n checksum: string;\n /** Relative path of the per-prompt file within the dataset. */\n file: string;\n}\n","/**\n * Prompt registry / sync types — the contract for a remote prompt hub\n * (e.g. prompts.wrongstack.com) and the local installed-prompts manifest.\n *\n * The manifest shape intentionally mirrors the bundled dataset's\n * `data/prompts/index.json` (see `PromptManifest` in `types/prompt.ts`): the\n * builtin dataset IS a local registry, so builtin and synced prompts can flow\n * through one validation + diff path. This file defines the format and the\n * structural validator; the actual fetch/download is a deliberately small stub\n * (see `prompts/prompt-installer.ts`) — \"groundwork now, sync later\".\n */\nimport type { PromptCategory } from './prompt.js';\n\nexport interface PromptRegistryRef {\n id: string;\n slug: string;\n title: string;\n description: string;\n category: PromptCategory;\n tags: string[];\n /** sha256 of the prompt content — drives the update diff. */\n checksum: string;\n version?: string | undefined;\n license?: string | undefined;\n /** Optional direct URL to the full prompt JSON. */\n url?: string | undefined;\n}\n\nexport interface PromptRegistryManifest {\n registryVersion: 1;\n /** Where this manifest came from (hub URL or `owner/repo`). */\n source: string;\n generatedAt: string;\n prompts: PromptRegistryRef[];\n}\n\n/** One entry recorded in `~/.wrongstack/installed-prompts.json`. */\nexport interface InstalledPromptEntry {\n slug: string;\n /** The registry/source this prompt was pulled from. */\n source: string;\n /** The ref pinned at install (tag/branch/commit or manifest version). */\n ref: string;\n checksum: string;\n /** True once the prompt body has actually been written locally. */\n synced: boolean;\n installedAt: string;\n}\n\nexport interface PromptManifestData {\n version: 1;\n entries: InstalledPromptEntry[];\n}\n\n/** Result of validating an untrusted manifest. */\nexport type ManifestValidation =\n | { ok: true; manifest: PromptRegistryManifest }\n | { ok: false; errors: string[] };\n\nconst SLUG_RE = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;\nconst CHECKSUM_RE = /^[a-f0-9]{64}$/;\nconst MAX_STR = 4096;\n\n/**\n * Structurally validate an untrusted registry manifest. Treats the manifest as\n * DATA, not instructions: enforces slug charset, checksum format, and field\n * lengths so a malicious hub can't smuggle oversized or malformed entries into\n * the local store. Does NOT fetch prompt bodies.\n */\nexport function validateRegistryManifest(raw: unknown): ManifestValidation {\n const errors: string[] = [];\n if (!raw || typeof raw !== 'object') return { ok: false, errors: ['manifest is not an object'] };\n const m = raw as Record<string, unknown>;\n\n if (m['registryVersion'] !== 1) errors.push('registryVersion must be 1');\n if (typeof m['source'] !== 'string' || !m['source'])\n errors.push('source must be a non-empty string');\n if (typeof m['generatedAt'] !== 'string') errors.push('generatedAt must be a string');\n if (!Array.isArray(m['prompts'])) {\n errors.push('prompts must be an array');\n return { ok: false, errors };\n }\n\n const seen = new Set<string>();\n const refs: PromptRegistryRef[] = [];\n (m['prompts'] as unknown[]).forEach((p, i) => {\n if (!p || typeof p !== 'object') {\n errors.push(`prompts[${i}] is not an object`);\n return;\n }\n const r = p as Record<string, unknown>;\n const slug = r['slug'];\n if (typeof slug !== 'string' || !SLUG_RE.test(slug)) {\n errors.push(`prompts[${i}].slug invalid (must be kebab-case)`);\n return;\n }\n if (seen.has(slug)) {\n errors.push(`prompts[${i}].slug \"${slug}\" duplicated`);\n return;\n }\n seen.add(slug);\n if (typeof r['checksum'] !== 'string' || !CHECKSUM_RE.test(r['checksum'])) {\n errors.push(`prompts[${i}].checksum must be a 64-char sha256 hex`);\n return;\n }\n for (const field of ['id', 'title', 'description', 'category'] as const) {\n const v = r[field];\n if (typeof v !== 'string' || v.length === 0 || v.length > MAX_STR) {\n errors.push(`prompts[${i}].${field} must be a non-empty string under ${MAX_STR} chars`);\n return;\n }\n }\n const tags = Array.isArray(r['tags'])\n ? (r['tags'].filter((t) => typeof t === 'string') as string[])\n : [];\n refs.push({\n id: r['id'] as string,\n slug,\n title: r['title'] as string,\n description: r['description'] as string,\n category: r['category'] as string,\n tags,\n checksum: r['checksum'] as string,\n version: typeof r['version'] === 'string' ? r['version'] : undefined,\n license: typeof r['license'] === 'string' ? r['license'] : undefined,\n url: typeof r['url'] === 'string' ? r['url'] : undefined,\n });\n });\n\n if (errors.length > 0) return { ok: false, errors };\n return {\n ok: true,\n manifest: {\n registryVersion: 1,\n source: m['source'] as string,\n generatedAt: m['generatedAt'] as string,\n prompts: refs,\n },\n };\n}\n\nexport interface RegistryDiff {\n /** Slugs present in the manifest but not locally. */\n added: PromptRegistryRef[];\n /** Slugs present locally but whose checksum differs in the manifest. */\n updated: PromptRegistryRef[];\n /** Slugs present locally and identical in the manifest. */\n unchanged: PromptRegistryRef[];\n}\n\n/**\n * Compute what a pull WOULD change, by slug+checksum, against the prompts the\n * caller already has. Pure — no I/O, no writes.\n */\nexport function diffRegistry(\n local: { slug: string; checksum?: string | undefined }[],\n manifest: PromptRegistryManifest,\n): RegistryDiff {\n const localBySlug = new Map(local.map((e) => [e.slug, e.checksum]));\n const diff: RegistryDiff = { added: [], updated: [], unchanged: [] };\n for (const ref of manifest.prompts) {\n if (!localBySlug.has(ref.slug)) diff.added.push(ref);\n else if (localBySlug.get(ref.slug) !== ref.checksum) diff.updated.push(ref);\n else diff.unchanged.push(ref);\n }\n return diff;\n}\n","/**\n * Design Studio — curated frontend/mobile UI design kits.\n *\n * A \"design kit\" is a self-contained, selectable design direction (an aesthetic\n * + concrete design tokens + per-stack implementation guidance) that the model\n * commits to BEFORE writing UI code. Kits are surfaced progressively: a compact\n * menu is injected when frontend work is detected, and the heavy kit body is\n * only loaded once the model (or user) picks one — keeping per-turn tokens low.\n *\n * This mirrors the skills subsystem (`types/skill.ts` + `execution/skill-loader.ts`)\n * but adds the per-stack body selection and a token snapshot for visual pickers.\n */\n\n/** Target implementation stacks a kit can speak to. */\nexport const DESIGN_STACKS = ['web', 'react-native', 'flutter', 'swiftui', 'compose'] as const;\n\nexport type DesignStack = (typeof DESIGN_STACKS)[number];\n\nexport function isDesignStack(v: string): v is DesignStack {\n return (DESIGN_STACKS as readonly string[]).includes(v);\n}\n\nexport interface DesignKitManifest {\n id: string;\n name: string;\n /** One-line vibe shown in the menu, e.g. \"Restrained, Linear-style minimalism\". */\n aesthetic: string;\n /** Free-form tags for filtering. */\n tags: string[];\n /** Stacks this kit provides guidance for. */\n stacks: DesignStack[];\n /** Whether the kit ships light + dark themes (almost always true). */\n themes: string[];\n /** \"Best for…\" one-liner used in menu + pickers. */\n bestFor: string;\n version?: string | undefined;\n path: string;\n source: 'project' | 'user' | 'bundled';\n}\n\n/** A single theme's concrete token values (OKLCH strings, font names, etc.). */\nexport interface DesignTokenSet {\n [token: string]: string;\n}\n\n/** Parsed `tokens.json` — light + dark token snapshots used by visual pickers. */\nexport interface DesignKitTokens {\n light?: DesignTokenSet | undefined;\n dark?: DesignTokenSet | undefined;\n}\n\n/** Compact menu entry rendered into the request when frontend work is detected. */\nexport interface DesignKitEntry {\n id: string;\n name: string;\n aesthetic: string;\n bestFor: string;\n stacks: DesignStack[];\n source: DesignKitManifest['source'];\n}\n\n/**\n * Live Design Studio state stashed on `ctx.meta.designStudio`. Set by the\n * detection middleware (user intent + frontend file writes); read by the\n * request middleware that injects the menu / active-kit reminder.\n */\nexport interface DesignStudioState {\n /** True once frontend/UI work has been detected this session. */\n active: boolean;\n /** Detected target stack, if any. */\n stack?: DesignStack | undefined;\n /** What triggered activation (for transparency / debugging). */\n signals: string[];\n /** Kit id the model/user committed to, if any. */\n activeKit?: string | undefined;\n /**\n * User color/token overrides applied over the active kit's tokens. Keys are\n * token names (`primary`) applied to both themes, or theme-scoped\n * (`light.bg`/`dark.bg`). See `applyTokenOverrides`.\n */\n overrides?: Record<string, string> | undefined;\n}\n\nexport interface DesignKitLoader {\n list(): Promise<DesignKitManifest[]>;\n /** Structured entries for the compact menu. */\n listEntries(): Promise<DesignKitEntry[]>;\n find(id: string): Promise<DesignKitManifest | undefined>;\n /** Compact, model-facing menu of every available kit. */\n menuText(): Promise<string>;\n /**\n * Full kit body for a given stack. Strips frontmatter and, when `stack` is\n * provided, narrows stack-specific sections to that stack.\n */\n readBody(id: string, stack?: DesignStack | undefined): Promise<string>;\n /** Parsed `tokens.json` for a kit (light/dark snapshots), if present. */\n readTokens(id: string): Promise<DesignKitTokens | undefined>;\n /** The mandatory cross-cutting baseline (responsive / a11y / theming / motion). */\n foundationsText(stack?: DesignStack | undefined): Promise<string>;\n invalidateCache(): void;\n}\n","import { readFileSync, statSync } from 'node:fs';\nimport * as path from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nexport function modePrompt(id: string): string {\n for (const dir of modePromptDirCandidates()) {\n try {\n return readFileSync(path.join(dir, `${id}.md`), 'utf8').trimEnd();\n } catch {\n // try next candidate\n }\n }\n return '';\n}\n\nfunction modePromptDirCandidates(): string[] {\n const here = path.dirname(fileURLToPath(import.meta.url));\n const candidates = [\n path.resolve(here, '../../instructions/modes'),\n path.resolve(here, '../instructions/modes'),\n path.resolve(here, 'instructions/modes'),\n ];\n return candidates.sort((a, b) => Number(!isDirectory(a)) - Number(!isDirectory(b)));\n}\n\nfunction isDirectory(candidate: string): boolean {\n try {\n return statSync(candidate).isDirectory();\n } catch {\n return false;\n }\n}\n","import { modePrompt } from './mode-prompts.js';\nexport interface Mode {\n id: string;\n name: string;\n description: string;\n /** Additional prompt text injected into system prompt when mode is active */\n prompt: string;\n /** Tags for tool_search filtering */\n tags?: string[] | undefined;\n /** Tools that should be prioritized/highlighted when this mode is active */\n toolPreferences?: string[] | undefined;\n /**\n * Skill names that are particularly relevant to this mode. The system\n * prompt builder appends a \"Suggested skills\" note so the model knows\n * which domain knowledge to leverage first. Skill must exist in the\n * loaded skill set to appear.\n */\n suggestedSkills?: string[] | undefined;\n}\n\nexport interface ModeManifest {\n modes: Mode[];\n defaultMode?: string | undefined;\n}\n\nexport interface ModeStore {\n getActiveMode(): Promise<Mode | null>;\n setActiveMode(modeId: string | null): Promise<void>;\n listModes(): Promise<Mode[]>;\n getMode(modeId: string): Promise<Mode | null>;\n}\n\nexport interface ModeConfig {\n directory: string;\n}\n\nexport const DEFAULT_MODES: Mode[] = [\n {\n id: 'default',\n name: 'Default',\n description: 'General-purpose coding assistant',\n prompt: '',\n tags: ['general'],\n },\n {\n id: 'code-reviewer',\n name: 'Code Reviewer',\n description: 'Focus on code quality, best practices, and potential bugs',\n prompt: modePrompt('code-reviewer'),\n tags: ['review', 'quality', 'security'],\n toolPreferences: ['read', 'grep', 'git', 'diff', 'test'],\n suggestedSkills: ['bug-hunter', 'security-scanner', 'typescript-strict', 'testing'],\n },\n {\n id: 'code-auditor',\n name: 'Code Auditor',\n description: 'Security-focused code analysis',\n prompt: modePrompt('code-auditor'),\n tags: ['security', 'audit', 'compliance'],\n toolPreferences: ['grep', 'read', 'audit', 'bash'],\n suggestedSkills: ['security-scanner', 'bug-hunter', 'audit-log'],\n },\n {\n id: 'architect',\n name: 'Software Architect',\n description: 'Design patterns, scalability, and system design',\n prompt: modePrompt('architect'),\n tags: ['architecture', 'design', 'scalability'],\n toolPreferences: ['read', 'glob', 'tree', 'diff'],\n suggestedSkills: ['api-design', 'refactor-planner', 'node-modern', 'docker-deploy'],\n },\n {\n id: 'debugger',\n name: 'Debugger',\n description: 'Root cause analysis and error investigation',\n prompt: modePrompt('debugger'),\n tags: ['debug', 'investigation', 'error-resolution'],\n toolPreferences: ['read', 'grep', 'bash', 'logs', 'test'],\n suggestedSkills: ['bug-hunter', 'audit-log', 'observability'],\n },\n {\n id: 'tester',\n name: 'QA Engineer',\n description: 'Test coverage, edge cases, and quality assurance',\n prompt: modePrompt('tester'),\n tags: ['testing', 'qa', 'quality'],\n toolPreferences: ['read', 'grep', 'test', 'bash'],\n suggestedSkills: ['testing', 'bug-hunter', 'typescript-strict'],\n },\n {\n id: 'devops',\n name: 'DevOps Engineer',\n description: 'Infrastructure, deployment, and operations',\n prompt: modePrompt('devops'),\n tags: ['devops', 'infrastructure', 'operations'],\n toolPreferences: ['read', 'bash', 'grep', 'logs', 'git'],\n suggestedSkills: ['docker-deploy', 'observability', 'security-scanner'],\n },\n {\n id: 'refactorer',\n name: 'Refactorer',\n description: 'Code improvement and modernization',\n prompt: modePrompt('refactorer'),\n tags: ['refactor', 'modernization', 'improvement'],\n toolPreferences: ['read', 'edit', 'test', 'git', 'grep'],\n suggestedSkills: ['refactor-planner', 'typescript-strict', 'node-modern', 'testing'],\n },\n {\n id: 'ui-design',\n name: 'UI Design',\n description: 'Design-first frontend & mobile UI work (Design Studio)',\n prompt: modePrompt('ui-design'),\n tags: ['ui', 'frontend', 'mobile', 'design'],\n toolPreferences: ['design', 'write', 'edit', 'read', 'scaffold'],\n suggestedSkills: ['react-modern'],\n },\n {\n id: 'brief',\n name: 'Brief',\n description: 'Fast, no-nonsense — get to the point',\n prompt: modePrompt('brief'),\n tags: ['fast', 'concise', 'direct'],\n toolPreferences: ['read', 'edit', 'bash'],\n suggestedSkills: [],\n },\n {\n id: 'teach',\n name: 'Teach',\n description: 'Mentor mode — explains why, not just what',\n prompt: modePrompt('teach'),\n tags: ['teaching', 'mentor', 'learning'],\n toolPreferences: ['read', 'edit', 'explain'],\n suggestedSkills: ['prompt-engineering', 'skill-creator', 'node-modern', 'typescript-strict'],\n },\n {\n id: 'research-web',\n name: 'Research Web',\n description: 'Current-data research — search web, verify, inject findings into context',\n prompt: modePrompt('research-web'),\n tags: ['research', 'web', 'current-data', 'up-to-date'],\n toolPreferences: ['search/fetch', 'search/fetch', 'search', 'fetch', 'context_manager'],\n suggestedSkills: ['research-web', 'tech-stack', 'node-modern', 'security-scanner', 'react-modern'],\n },\n];\n","import { expectDefined } from '../utils/expect-defined.js';\nexport type ContextWindowModeId = 'balanced' | 'frugal' | 'deep' | 'archival';\n\nexport type ContextWindowAggressiveOn = 'hard' | 'soft' | 'warn';\n\nexport interface ContextWindowThresholds {\n warn: number;\n soft: number;\n hard: number;\n}\n\nexport interface ContextWindowMode {\n id: ContextWindowModeId;\n name: string;\n description: string;\n thresholds: ContextWindowThresholds;\n aggressiveOn: ContextWindowAggressiveOn;\n preserveK: number;\n eliseThreshold: number;\n targetLoad: number;\n}\n\nexport interface ContextWindowPolicy extends ContextWindowMode {}\n\nexport interface ContextWindowConfigLike {\n mode?: ContextWindowModeId | string | undefined;\n warnThreshold?: number | undefined;\n softThreshold?: number | undefined;\n hardThreshold?: number | undefined;\n preserveK?: number | undefined;\n eliseThreshold?: number | undefined;\n}\n\nexport const DEFAULT_CONTEXT_WINDOW_MODE_ID: ContextWindowModeId = 'balanced';\n\nexport const CONTEXT_WINDOW_MODES: readonly ContextWindowMode[] = Object.freeze([\n {\n id: 'balanced',\n name: 'Balanced',\n description: 'Default rolling compaction: recent work stays verbatim, old tool output is trimmed.',\n thresholds: { warn: 0.6, soft: 0.75, hard: 0.9 },\n aggressiveOn: 'soft',\n preserveK: 10,\n eliseThreshold: 2000,\n targetLoad: 0.65,\n },\n {\n id: 'frugal',\n name: 'Frugal',\n description: 'Token-saver mode: compacts early and keeps a tighter verbatim tail.',\n thresholds: { warn: 0.45, soft: 0.6, hard: 0.75 },\n aggressiveOn: 'warn',\n preserveK: 6,\n eliseThreshold: 700,\n targetLoad: 0.5,\n },\n {\n id: 'deep',\n name: 'Deep',\n description: 'Long-reasoning mode: delays compaction and keeps more recent turns intact.',\n thresholds: { warn: 0.72, soft: 0.86, hard: 0.96 },\n aggressiveOn: 'hard',\n preserveK: 18,\n eliseThreshold: 5000,\n targetLoad: 0.78,\n },\n {\n id: 'archival',\n name: 'Archival',\n description: 'Decision-preserving mode: compacts steadily while keeping summaries prominent.',\n thresholds: { warn: 0.55, soft: 0.7, hard: 0.84 },\n aggressiveOn: 'soft',\n preserveK: 8,\n eliseThreshold: 1200,\n targetLoad: 0.58,\n },\n]);\n\nexport function listContextWindowModes(): ContextWindowMode[] {\n return CONTEXT_WINDOW_MODES.map((m) => ({ ...m, thresholds: { ...m.thresholds } }));\n}\n\nexport function getContextWindowMode(id: string | null | undefined): ContextWindowMode | null {\n if (!id) return null;\n const mode = CONTEXT_WINDOW_MODES.find((m) => m.id === id);\n return mode ? { ...mode, thresholds: { ...mode.thresholds } } : null;\n}\n\nexport function isContextWindowModeId(id: string): id is ContextWindowModeId {\n return CONTEXT_WINDOW_MODES.some((m) => m.id === id);\n}\n\nexport function resolveContextWindowPolicy(\n config: ContextWindowConfigLike = {},\n overrideMode?: string | null | undefined,\n): ContextWindowPolicy {\n const requested = overrideMode ?? config.mode ?? DEFAULT_CONTEXT_WINDOW_MODE_ID;\n const mode = getContextWindowMode(requested) ?? expectDefined(getContextWindowMode(DEFAULT_CONTEXT_WINDOW_MODE_ID));\n\n if (mode.id !== DEFAULT_CONTEXT_WINDOW_MODE_ID) {\n return mode;\n }\n\n return {\n ...mode,\n thresholds: {\n warn: config.warnThreshold ?? mode.thresholds.warn,\n soft: config.softThreshold ?? mode.thresholds.soft,\n hard: config.hardThreshold ?? mode.thresholds.hard,\n },\n preserveK: config.preserveK ?? mode.preserveK,\n eliseThreshold: config.eliseThreshold ?? mode.eliseThreshold,\n };\n}\n\nexport function formatContextWindowModeList(activeId?: string | null): string {\n return CONTEXT_WINDOW_MODES.map((m) => {\n const marker = m.id === activeId ? '*' : ' ';\n return `${marker} ${m.id.padEnd(9)} ${m.name} - ${m.description}`;\n }).join('\\n');\n}\n","export type SpecStatus = 'draft' | 'review' | 'approved' | 'implemented' | 'deprecated';\nexport type SpecSectionType =\n | 'overview'\n | 'requirements'\n | 'architecture'\n | 'api'\n | 'data'\n | 'security'\n | 'acceptance';\n\nexport interface SpecSection {\n type: SpecSectionType;\n title: string;\n content: string;\n level: number;\n children?: SpecSection[] | undefined;\n}\n\nexport interface SpecRequirement {\n id: string;\n type: 'functional' | 'non-functional' | 'security' | 'performance' | 'ux';\n priority: 'critical' | 'high' | 'medium' | 'low';\n description: string;\n acceptanceCriteria: string[];\n blockedBy?: string[] | undefined;\n implements?: string[] | undefined;\n}\n\nexport interface SpecApiEndpoint {\n method: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';\n path: string;\n description: string;\n request?: Record<string, unknown>;\n response?: Record<string, unknown>;\n auth?: boolean | undefined;\n}\n\nexport interface Specification {\n id: string;\n title: string;\n version: string;\n status: SpecStatus;\n overview: string;\n sections: SpecSection[];\n requirements: SpecRequirement[];\n apiEndpoints?: SpecApiEndpoint[] | undefined;\n dependencies?: string[] | undefined;\n createdAt: number;\n updatedAt: number;\n metadata?: Record<string, unknown>;\n}\n\nexport interface SpecAnalysis {\n specId: string;\n completeness: number; // 0-100\n coverage: {\n requirements: number;\n apiEndpoints: number;\n edgeCases: number;\n errorHandling: number;\n };\n gaps: string[];\n risks: { requirement: string; risk: string; severity: 'high' | 'medium' | 'low' }[];\n suggestions: string[];\n}\n\nexport interface SpecValidationResult {\n valid: boolean;\n errors: { path: string; message: string }[];\n warnings: { path: string; message: string }[];\n}\n\nexport interface SpecTemplate {\n id: string;\n name: string;\n description: string;\n sections: Omit<SpecSection, 'content'>[];\n defaultRequirements: Omit<SpecRequirement, 'id' | 'description'>[];\n}\n\nexport const DEFAULT_SPEC_TEMPLATE: SpecTemplate = {\n id: 'default',\n name: 'Default Feature Spec',\n description: 'Standard template for feature specifications',\n sections: [\n { type: 'overview', title: 'Overview', level: 1 },\n { type: 'requirements', title: 'Requirements', level: 1 },\n { type: 'architecture', title: 'Architecture', level: 1 },\n { type: 'api', title: 'API Design', level: 1 },\n { type: 'data', title: 'Data Model', level: 1 },\n { type: 'security', title: 'Security', level: 1 },\n { type: 'acceptance', title: 'Acceptance Criteria', level: 1 },\n ],\n defaultRequirements: [\n { type: 'functional', priority: 'high', acceptanceCriteria: [], blockedBy: [], implements: [] },\n {\n type: 'non-functional',\n priority: 'medium',\n acceptanceCriteria: [],\n blockedBy: [],\n implements: [],\n },\n ],\n};\n","export type TaskStatus = 'pending' | 'in_progress' | 'blocked' | 'failed' | 'review' | 'completed';\nexport type TaskPriority = 'critical' | 'high' | 'medium' | 'low';\nexport type TaskType = 'feature' | 'bugfix' | 'refactor' | 'docs' | 'test' | 'chore';\n\nexport interface TaskNode {\n id: string;\n title: string;\n description: string;\n type: TaskType;\n priority: TaskPriority;\n status: TaskStatus;\n assignee?: string | undefined;\n estimateHours?: number | undefined;\n actualHours?: number | undefined;\n tags?: string[] | undefined;\n specRequirementId?: string | undefined;\n parentId?: string | undefined;\n children?: string[] | undefined;\n createdAt: number;\n updatedAt: number;\n startedAt?: number | undefined; // set when status → in_progress\n completedAt?: number | undefined;\n metadata?: Record<string, unknown>;\n}\n\nexport interface TaskEdge {\n id: string;\n from: string;\n to: string;\n type: 'blocks' | 'depends_on' | 'relates_to' | 'implements';\n weight?: number | undefined;\n}\n\nexport interface TaskGraph {\n id: string;\n specId: string;\n title: string;\n nodes: Map<string, TaskNode>;\n edges: TaskEdge[];\n rootNodes: string[];\n createdAt: number;\n updatedAt: number;\n}\n\nexport interface TaskDependency {\n taskId: string;\n blockedBy: string[];\n blocking: string[];\n}\n\nexport interface TaskAssignment {\n taskId: string;\n assignee: string;\n assignedAt: number;\n}\n\nexport interface TaskProgress {\n total: number;\n pending: number;\n inProgress: number;\n blocked: number;\n failed: number;\n review: number;\n completed: number;\n percentComplete: number;\n estimatedHours: number;\n actualHours: number;\n}\n\nexport interface TaskFilter {\n status?: TaskStatus[] | undefined;\n priority?: TaskPriority[] | undefined;\n type?: TaskType[] | undefined;\n assignee?: string[] | undefined;\n tags?: string[] | undefined;\n specRequirementId?: string | undefined;\n}\n\nexport interface TaskSort {\n field: 'priority' | 'createdAt' | 'updatedAt' | 'status';\n direction: 'asc' | 'desc';\n}\n\nexport interface CriticalPathResult {\n taskIds: string[];\n totalEstimateHours: number;\n bottleneckTasks: string[];\n}\n\nexport function computeTaskProgress(graph: TaskGraph): TaskProgress {\n let completed = 0;\n let pending = 0;\n let inProgress = 0;\n let blocked = 0;\n let failed = 0;\n let review = 0;\n let estimatedHours = 0;\n let actualHours = 0;\n for (const n of graph.nodes.values()) {\n switch (n.status) {\n case 'completed':\n completed++;\n break;\n case 'pending':\n pending++;\n break;\n case 'in_progress':\n inProgress++;\n break;\n case 'blocked':\n blocked++;\n break;\n case 'failed':\n failed++;\n break;\n case 'review':\n review++;\n break;\n }\n estimatedHours += n.estimateHours ?? 0;\n actualHours += n.actualHours ?? 0;\n }\n const total = graph.nodes.size;\n\n return {\n total,\n pending,\n inProgress,\n blocked,\n failed,\n review,\n completed,\n percentComplete: total > 0 ? Math.round((completed / total) * 100) : 0,\n estimatedHours,\n actualHours,\n };\n}\n\nexport function findCriticalPath(graph: TaskGraph): CriticalPathResult {\n const nodes = Array.from(graph.nodes.values());\n const criticalNodes = nodes.filter((n) => n.priority === 'critical');\n const bottleneckTasks = criticalNodes\n .filter((n) => graph.edges.some((e) => e.to === n.id && e.type === 'depends_on'))\n .map((n) => n.id);\n\n const totalEstimateHours = criticalNodes.reduce((sum, n) => sum + (n.estimateHours ?? 0), 0);\n\n return {\n taskIds: criticalNodes.map((n) => n.id),\n totalEstimateHours,\n bottleneckTasks,\n };\n}\n\nexport function topologicalSort(graph: TaskGraph): string[] {\n const visited = new Set<string>();\n const inStack = new Set<string>();\n const result: string[] = [];\n\n function visit(id: string): void {\n // Cycle: callers must detect cycles up-front if they care; we just stop recursing.\n if (inStack.has(id)) return;\n if (visited.has(id)) return;\n if (!graph.nodes.has(id)) return;\n\n visited.add(id);\n inStack.add(id);\n\n for (const edge of graph.edges) {\n if (edge.from === id) visit(edge.to);\n }\n\n inStack.delete(id);\n result.push(id);\n }\n\n for (const rootId of graph.rootNodes) {\n visit(rootId);\n }\n\n return result;\n}\n","import * as fs from 'node:fs/promises';\nimport { expectDefined } from '../utils/expect-defined.js';\nimport type { ContentBlock } from '../types/blocks.js';\nimport type {\n DefaultSessionReaderOptions,\n SessionExportOptions,\n SessionQuery,\n SessionReader,\n SessionSearchHit,\n SessionSearchQuery,\n SessionSummaryLite,\n} from '../types/session-reader.js';\nimport { compileUserRegex } from '../utils/regex-guard.js';\nimport { sessionScopedPath } from '../utils/session-scoped-path.js';\nimport type { SessionData, SessionEvent, SessionMetadata, SessionStore } from '../types/session.js';\n\n/**\n * L2-A: read-only view over a `SessionStore` with query, replay, search,\n * and export helpers. Implemented on top of the public `SessionStore`\n * surface so any concrete store can be inspected without re-implementation.\n */\nexport class DefaultSessionReader implements SessionReader {\n private readonly store: SessionStore;\n private readonly eventCache = new Map<string, SessionData>();\n private readonly eventCacheMtimes = new Map<string, number>();\n private static readonly EVENT_CACHE_MAX_ENTRIES = 32;\n\n constructor(opts: DefaultSessionReaderOptions) {\n this.store = opts.store;\n }\n\n private async loadCachedSessionData(sessionId: string): Promise<SessionData> {\n const storeWithPath = this.store as SessionStore & {\n dir?: string | undefined;\n clearLoadCache?: ((sessionId?: string | undefined) => void) | undefined;\n };\n const rootDir = storeWithPath.dir;\n if (!rootDir) {\n return await this.store.load(sessionId);\n }\n const sessionPath = sessionScopedPath(rootDir, sessionId, '.jsonl');\n let mtimeMs: number | null = null;\n try {\n const stat = await fs.stat(sessionPath);\n mtimeMs = stat.mtimeMs;\n } catch {\n this.eventCache.delete(sessionId);\n this.eventCacheMtimes.delete(sessionId);\n return await this.store.load(sessionId);\n }\n\n const cachedMtime = this.eventCacheMtimes.get(sessionId);\n const cachedData = this.eventCache.get(sessionId);\n if (cachedData && cachedMtime === mtimeMs) {\n this.eventCache.delete(sessionId);\n this.eventCacheMtimes.delete(sessionId);\n this.eventCache.set(sessionId, cachedData);\n this.eventCacheMtimes.set(sessionId, mtimeMs);\n return cachedData;\n }\n\n const data = await this.store.load(sessionId);\n this.eventCache.delete(sessionId);\n this.eventCacheMtimes.delete(sessionId);\n this.eventCache.set(sessionId, data);\n this.eventCacheMtimes.set(sessionId, mtimeMs);\n while (this.eventCache.size > DefaultSessionReader.EVENT_CACHE_MAX_ENTRIES) {\n const oldest = this.eventCache.keys().next().value;\n if (oldest === undefined) break;\n this.eventCache.delete(oldest);\n this.eventCacheMtimes.delete(oldest);\n }\n\n if (data.metadata.endedAt) {\n storeWithPath.clearLoadCache?.(sessionId);\n }\n\n return data;\n }\n\n async query(q: SessionQuery = {}): Promise<SessionSummaryLite[]> {\n // Prefer the store's filtered list when available — it pushes the\n // filter into the cached index instead of fetching 1000 + linear scan.\n const storeWithFilter = this.store as SessionStore & {\n listFiltered?: ((criteria: {\n since?: string | undefined;\n until?: string | undefined;\n provider?: string | undefined;\n model?: string | undefined;\n minTokens?: number | undefined;\n titleContains?: string | undefined;\n limit?: number | undefined;\n }) => Promise<import('../types/session.js').SessionSummary[]>) | undefined;\n };\n let raw: import('../types/session.js').SessionSummary[];\n if (typeof storeWithFilter.listFiltered === 'function') {\n raw = await storeWithFilter.listFiltered({\n since: q.since,\n until: q.until,\n provider: q.provider,\n model: q.model,\n minTokens: q.minTokens,\n titleContains: q.titleContains,\n limit: q.limit,\n });\n } else {\n const fetched = await this.store.list(q.limit ? Math.max(q.limit, 100) : 1000);\n const titleNeedle = q.titleContains?.toLowerCase();\n raw = fetched.filter((s) => {\n if (q.since && s.startedAt < q.since) return false;\n if (q.until && s.startedAt > q.until) return false;\n if (q.provider && s.provider !== q.provider) return false;\n if (q.model && s.model !== q.model) return false;\n if (q.minTokens !== undefined && s.tokenTotal < q.minTokens) return false;\n if (titleNeedle && !s.title.toLowerCase().includes(titleNeedle)) return false;\n return true;\n });\n }\n const out: SessionSummaryLite[] = raw.map((s) => ({\n id: s.id,\n title: s.title,\n startedAt: s.startedAt,\n provider: s.provider,\n model: s.model,\n tokenTotal: s.tokenTotal,\n }));\n return q.limit ? out.slice(0, q.limit) : out;\n }\n\n async *replay(sessionId: string): AsyncIterable<SessionEvent> {\n const data = await this.loadCachedSessionData(sessionId);\n for (const e of data.events) yield e;\n }\n\n async search(q: SessionSearchQuery, sessionId?: string | undefined, sessionQuery?: SessionQuery): Promise<SessionSearchHit[]> {\n const limit = q.limit ?? 100;\n const matcher = buildMatcher(q);\n const allowedTypes = q.types ? new Set(q.types) : null;\n\n // Filter sessions BEFORE scanning events — avoids touching the JSONL\n // for sessions that don't match the time/provider/model criteria.\n let ids: string[];\n if (sessionId) {\n ids = [sessionId];\n } else {\n // Prefer the store's filtered list when available — avoids fetching\n // 1000 sessions and linear-filtering in-process.\n const storeWithFilter = this.store as SessionStore & {\n listFiltered?: ((criteria: {\n since?: string | undefined;\n until?: string | undefined;\n provider?: string | undefined;\n model?: string | undefined;\n minTokens?: number | undefined;\n titleContains?: string | undefined;\n limit?: number | undefined;\n }) => Promise<import('../types/session.js').SessionSummary[]>) | undefined;\n };\n let sessions: import('../types/session.js').SessionSummary[];\n if (typeof storeWithFilter.listFiltered === 'function') {\n sessions = await storeWithFilter.listFiltered({\n since: sessionQuery?.since,\n until: sessionQuery?.until,\n provider: sessionQuery?.provider,\n model: sessionQuery?.model,\n minTokens: sessionQuery?.minTokens,\n titleContains: sessionQuery?.titleContains,\n limit: 1000,\n });\n } else {\n sessions = await this.store.list(1000);\n const titleNeedle = sessionQuery?.titleContains?.toLowerCase();\n sessions = sessions.filter((s) => {\n if (sessionQuery?.since && s.startedAt < sessionQuery.since) return false;\n if (sessionQuery?.until && s.startedAt > sessionQuery.until) return false;\n if (sessionQuery?.provider && s.provider !== sessionQuery.provider) return false;\n if (sessionQuery?.model && s.model !== sessionQuery.model) return false;\n if (sessionQuery?.minTokens !== undefined && s.tokenTotal < sessionQuery.minTokens) return false;\n if (titleNeedle && !s.title.toLowerCase().includes(titleNeedle)) return false;\n return true;\n });\n }\n ids = sessions.map((s) => s.id);\n }\n\n const hits: SessionSearchHit[] = [];\n\n // Fast path: when the underlying store supports streaming search,\n // walk each session's JSONL line-by-line and bail out the moment we\n // hit `limit`. This avoids reading + parsing the entire file (which\n // `load()` does) and never reuses `_loadCache`, so concurrent\n // analytics queries don't churn the writer-side cache.\n const streaming = this.store.searchEvents?.bind(this.store);\n if (streaming) {\n for (const id of ids) {\n const matched = await streaming(\n id,\n (ev) => {\n if (allowedTypes && !allowedTypes.has(ev.type)) return false;\n const text = eventText(ev);\n if (text === null) return false;\n return matcher(text) !== null;\n },\n { limit: limit - hits.length },\n );\n for (const m of matched) {\n const text = expectDefined(eventText(m.event));\n const hit = expectDefined(matcher(text));\n hits.push({\n sessionId: id,\n eventIndex: m.eventIndex,\n ts: m.ts,\n type: m.event.type,\n snippet: snippetOf(text, hit.start, hit.end),\n });\n if (hits.length >= limit) return hits;\n }\n }\n return hits;\n }\n\n // Fallback: stores that don't implement streaming. Loads the full\n // event stream per session — necessary for in-memory or non-file\n // stores that don't expose a streaming surface.\n for (const id of ids) {\n let data;\n try {\n data = await this.loadCachedSessionData(id);\n } catch {\n continue;\n }\n for (let i = 0; i < data.events.length; i++) {\n const ev = expectDefined(data.events[i]);\n if (allowedTypes && !allowedTypes.has(ev.type)) continue;\n const text = eventText(ev);\n if (text === null) continue;\n const hit = matcher(text);\n if (!hit) continue;\n hits.push({\n sessionId: id,\n eventIndex: i,\n ts: ev.ts,\n type: ev.type,\n snippet: snippetOf(text, hit.start, hit.end),\n });\n if (hits.length >= limit) return hits;\n }\n }\n return hits;\n }\n\n async export(sessionId: string, opts: SessionExportOptions): Promise<string> {\n const data = await this.loadCachedSessionData(sessionId);\n const includeTools = opts.includeTools ?? true;\n const includeDiagnostics = opts.includeDiagnostics ?? true;\n\n const filtered = data.events.filter((e) => {\n if (\n !includeTools &&\n (e.type === 'tool_use' ||\n e.type === 'tool_result' ||\n e.type === 'tool_call_start' ||\n e.type === 'tool_call_end')\n ) {\n return false;\n }\n if (\n !includeDiagnostics &&\n (e.type === 'error' || e.type === 'compaction' || e.type === 'message_truncated')\n ) {\n return false;\n }\n return true;\n });\n\n if (opts.format === 'json') {\n return JSON.stringify({ metadata: data.metadata, events: filtered }, null, 2);\n }\n if (opts.format === 'text') {\n return renderPlainText(data.metadata, filtered);\n }\n return renderMarkdown(data.metadata, filtered);\n }\n\n async metadata(sessionId: string): Promise<SessionMetadata> {\n const data = await this.loadCachedSessionData(sessionId);\n return data.metadata;\n }\n}\n\nfunction buildMatcher(\n q: SessionSearchQuery,\n): (text: string) => { start: number; end: number } | null {\n const ci = q.caseInsensitive ?? true;\n if (q.regex) {\n const flags = ci ? 'i' : '';\n const compiled = compileUserRegex(q.query, flags);\n if (!compiled.ok) {\n throw new Error(`Invalid search regex \"${q.query}\": ${compiled.reason}`);\n }\n const re = compiled.regex;\n return (text) => {\n const m = re.exec(text);\n return m ? { start: m.index, end: m.index + m[0].length } : null;\n };\n }\n const needle = ci ? q.query.toLowerCase() : q.query;\n return (text) => {\n const hay = ci ? text.toLowerCase() : text;\n const idx = hay.indexOf(needle);\n return idx === -1 ? null : { start: idx, end: idx + needle.length };\n };\n}\n\nfunction eventText(e: SessionEvent): string | null {\n switch (e.type) {\n case 'user_input':\n return contentToString(e.content);\n case 'llm_response':\n return contentToString(e.content);\n case 'tool_use':\n return `${e.name} ${JSON.stringify(e.input)}`;\n case 'tool_result':\n return typeof e.content === 'string' ? e.content : JSON.stringify(e.content);\n case 'error':\n return `${e.phase}: ${e.message}`;\n case 'session_start':\n case 'session_resumed':\n return `${e.model}/${e.provider}`;\n case 'task_created':\n case 'task_completed':\n return e.title;\n case 'task_failed':\n return `${e.title}: ${e.error}`;\n case 'skill_activated':\n case 'skill_deactivated':\n return e.skillName;\n default:\n return null;\n }\n}\n\nfunction contentToString(content: string | ContentBlock[]): string {\n if (typeof content === 'string') return content;\n return content\n .map((b) => {\n switch (b.type) {\n case 'text':\n return b.text;\n case 'tool_use':\n return `[tool_use:${b.name} ${JSON.stringify(b.input)}]`;\n case 'tool_result':\n return typeof b.content === 'string' ? b.content : JSON.stringify(b.content);\n default:\n return '';\n }\n })\n .join('\\n');\n}\n\nconst SNIPPET_RADIUS = 60;\n\nfunction snippetOf(text: string, start: number, end: number): string {\n const from = Math.max(0, start - SNIPPET_RADIUS);\n const to = Math.min(text.length, end + SNIPPET_RADIUS);\n const prefix = from > 0 ? '…' : '';\n const suffix = to < text.length ? '…' : '';\n return prefix + text.slice(from, to).replace(/\\s+/g, ' ').trim() + suffix;\n}\n\nfunction renderMarkdown(meta: SessionMetadata, events: SessionEvent[]): string {\n const lines: string[] = [];\n lines.push(`# Session ${meta.id}`);\n lines.push('');\n if (meta.model || meta.provider) {\n lines.push(`- **Model:** ${meta.provider ?? '?'}/${meta.model ?? '?'}`);\n }\n lines.push(`- **Started:** ${meta.startedAt}`);\n if (meta.endedAt) lines.push(`- **Ended:** ${meta.endedAt}`);\n lines.push('');\n lines.push('---');\n lines.push('');\n for (const e of events) {\n switch (e.type) {\n case 'user_input': {\n lines.push(`## User — ${e.ts}`);\n lines.push('');\n lines.push(contentToString(e.content));\n lines.push('');\n break;\n }\n case 'llm_response': {\n lines.push(`## Assistant — ${e.ts}`);\n lines.push('');\n lines.push(contentToString(e.content));\n if (e.stopReason && e.stopReason !== 'end_turn') {\n lines.push('');\n lines.push(`*stop: ${e.stopReason}*`);\n }\n lines.push('');\n break;\n }\n case 'tool_use': {\n lines.push(`### Tool call: \\`${e.name}\\``);\n lines.push('');\n lines.push('```json');\n lines.push(JSON.stringify(e.input, null, 2));\n lines.push('```');\n lines.push('');\n break;\n }\n case 'tool_result': {\n const body = typeof e.content === 'string' ? e.content : JSON.stringify(e.content, null, 2);\n lines.push(`### Tool result${e.isError ? ' (error)' : ''}`);\n lines.push('');\n lines.push('```');\n lines.push(body);\n lines.push('```');\n lines.push('');\n break;\n }\n case 'error': {\n lines.push(`> **Error** (${e.phase}): ${e.message}`);\n lines.push('');\n break;\n }\n case 'compaction': {\n lines.push(`> **Compaction**: ${e.before} → ${e.after} tokens`);\n lines.push('');\n break;\n }\n default:\n break;\n }\n }\n return lines.join('\\n');\n}\n\nfunction renderPlainText(meta: SessionMetadata, events: SessionEvent[]): string {\n const lines: string[] = [];\n lines.push(\n `Session ${meta.id} — ${meta.provider ?? '?'}/${meta.model ?? '?'} — started ${meta.startedAt}`,\n );\n lines.push(''.padEnd(72, '-'));\n for (const e of events) {\n switch (e.type) {\n case 'user_input':\n lines.push(`[${e.ts}] USER`);\n lines.push(contentToString(e.content));\n lines.push('');\n break;\n case 'llm_response':\n lines.push(`[${e.ts}] ASSISTANT`);\n lines.push(contentToString(e.content));\n lines.push('');\n break;\n case 'tool_use':\n lines.push(`[${e.ts}] TOOL_USE ${e.name} ${JSON.stringify(e.input)}`);\n break;\n case 'tool_result':\n lines.push(\n `[${e.ts}] TOOL_RESULT${e.isError ? ' (error)' : ''} ${\n typeof e.content === 'string' ? e.content : JSON.stringify(e.content)\n }`,\n );\n break;\n case 'error':\n lines.push(`[${e.ts}] ERROR (${e.phase}): ${e.message}`);\n break;\n default:\n break;\n }\n }\n return lines.join('\\n');\n}\n"]}
1
+ {"version":3,"sources":["../../src/types/blocks.ts","../../src/types/tool.ts","../../src/types/tool-markers.ts","../../src/utils/error.ts","../../src/utils/expect-defined.ts","../../src/utils/regex-guard.ts","../../src/utils/session-scoped-path.ts","../../src/utils/string.ts","../../src/types/errors.ts","../../src/types/provider.ts","../../src/types/config.ts","../../src/types/default-config.ts","../../src/types/memory.ts","../../src/types/prompt.ts","../../src/types/prompt-registry.ts","../../src/types/design-kit.ts","../../src/types/mode-prompts.ts","../../src/types/mode.ts","../../src/types/context-window.ts","../../src/types/spec.ts","../../src/types/task-graph.ts","../../src/storage/session-reader.ts"],"names":["ToolErrorCategory","path","stat"],"mappings":"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","file":"index.js","sourcesContent":["export interface TextBlock {\n type: 'text';\n text: string;\n cache_control?: { type: 'ephemeral' | undefined };\n}\n\nexport interface ToolUseBlock {\n type: 'tool_use';\n id: string;\n name: string;\n input: Record<string, unknown>;\n /**\n * Provider-specific opaque metadata captured from the wire response.\n * Echoed back verbatim in the next request so providers that bind\n * extra state to function calls keep working. Example: Gemini's\n * `thoughtSignature` — required for tool-use turns with thinking\n * models, otherwise the next request fails with 400 \"Function call\n * is missing a thought_signature in functionCall parts\".\n *\n * Keys are namespaced by intent so multiple wires can coexist:\n * - `google.thoughtSignature` — Gemini signed-thought blob\n * Other providers can add their own keys without colliding.\n */\n providerMeta?: Record<string, unknown>;\n}\n\nexport interface ToolResultBlock {\n type: 'tool_result';\n tool_use_id: string;\n /**\n * The original tool name. Useful for providers like Google Gemini that\n * need the tool name in `functionResponse.name` — the tool_use_id is\n * only a session-local identifier and is not stable across replays.\n * Always set by ToolExecutor; may be absent on manually-constructed blocks.\n */\n name?: string | undefined;\n content: string;\n is_error?: boolean | undefined;\n}\n\nexport interface ImageBlock {\n type: 'image';\n source: {\n type: 'base64' | 'url';\n media_type?: string | undefined;\n data?: string | undefined;\n url?: string | undefined;\n };\n}\n\n/**\n * Chain-of-thought / extended-thinking content emitted by the model.\n *\n * Both Anthropic extended thinking (`{type:'thinking', thinking, signature}`)\n * and DeepSeek reasoning mode (top-level `reasoning_content` on the assistant\n * message) require this content to be echoed back verbatim on the next\n * request, otherwise the provider returns 400:\n * - Anthropic: \"The `content[].thinking` in the thinking mode must be passed back\"\n * - DeepSeek: \"The `reasoning_content` in the thinking mode must be passed back\"\n *\n * `signature` is Anthropic-specific (an opaque integrity blob). DeepSeek\n * doesn't issue a signature — the field is absent for that provider.\n *\n * Per Anthropic, thinking blocks MUST appear before any text/tool_use blocks\n * in an assistant message. Stream builders preserve that order.\n */\nexport interface ThinkingBlock {\n type: 'thinking';\n thinking: string;\n signature?: string | undefined;\n providerMeta?: Record<string, unknown>;\n}\n\nexport type ContentBlock = TextBlock | ToolUseBlock | ToolResultBlock | ImageBlock | ThinkingBlock;\n\nexport function isTextBlock(b: ContentBlock): b is TextBlock {\n return b.type === 'text';\n}\nexport function isToolUseBlock(b: ContentBlock): b is ToolUseBlock {\n return b.type === 'tool_use';\n}\nexport function isToolResultBlock(b: ContentBlock): b is ToolResultBlock {\n return b.type === 'tool_result';\n}\nexport function isImageBlock(b: ContentBlock): b is ImageBlock {\n return b.type === 'image';\n}\n","import type { Context } from '../core/context.js';\n\nexport type Permission = 'auto' | 'confirm' | 'deny';\n\n/**\n * Risk tier for tools in YOLO mode. YOLO auto-approves normal project work,\n * while clearly destructive calls still require confirmation.\n *\n * - `safe` — read-only, no side effects (read, glob, grep, etc.)\n * - `standard` — non-destructive writes and mutations (write, edit, safe shell commands)\n * - `destructive` — irreversible or broadside effects (recursive deletes, db drops, etc.)\n */\nexport type RiskTier = 'safe' | 'standard' | 'destructive';\n\n/**\n * Icon identifiers for tools — each UI (WebUI/TUI/REPL) maps these to its own icon library.\n * Add the icon directly on each Tool so all UIs consume the same canonical value.\n */\nexport type ToolIconId =\n | 'file' // read, write — document operations\n | 'edit' // edit, patch — modifying files\n | 'search' // grep, search — searching content\n | 'folder' // glob — file discovery\n | 'terminal' // bash, exec — shell commands\n | 'web' // fetch — HTTP requests\n | 'git' // git — version control\n | 'tree' // tree — directory structure\n | 'code' // lint, format, typecheck — code quality\n | 'test' // test — testing\n | 'package' // install, audit, outdated — package management\n | 'document' // document — documentation\n | 'scaffold' // scaffold — project generation\n | 'todo' // todo — task tracking\n | 'plan' // plan — planning\n | 'task' // task — structured work items\n | 'meta' // tool-use, batch-tool-use, tool-search, tool-help — meta tools\n | 'index' // codebase-index, codebase-search, codebase-stats — code indexing\n | 'json' // json — JSON operations\n | 'diff' // diff — comparing changes\n | 'logs' // logs — log viewing\n | 'settings' // set-working-dir — configuration\n | 'fallback'; // unknown tool — fallback icon\n\nexport interface JSONSchema {\n type?: string | undefined;\n properties?: Record<string, JSONSchema>;\n required?: string[] | undefined;\n items?: JSONSchema | undefined;\n enum?: unknown[] | undefined;\n description?: string | undefined;\n [k: string]: unknown;\n}\n\n/**\n * Tool progress event — yielded by `Tool.executeStream` to give the UI\n * something to render while a long-running tool works. The executor\n * publishes each event via EventBus as `tool.progress` so the TUI, logger,\n * and observability layer can consume them uniformly.\n *\n * Keep events small. They are buffered through the EventBus synchronously\n * and rendered on the main thread.\n */\nexport interface ToolProgressEvent {\n /**\n * - `log` — verbose informational message (e.g. \"scanning…\")\n * - `warning` — non-fatal issue (e.g. \"skipped X due to ENOENT\")\n * - `metric` — numeric data (e.g. files scanned so far)\n * - `file_changed` — a tool that mutates the workspace announces a write\n * - `partial_output` — stream of textual output (bash stdout, fetch body)\n */\n type: 'log' | 'warning' | 'metric' | 'file_changed' | 'partial_output';\n text?: string | undefined;\n data?: Record<string, unknown>;\n}\n\n/**\n * Terminal event for `executeStream`. The output must match the tool's\n * declared output type — the executor unwraps `output` and treats it like\n * a normal `execute` return value.\n */\nexport interface ToolFinalEvent<O> {\n type: 'final';\n output: O;\n}\n\nexport type ToolStreamEvent<O = unknown> = ToolProgressEvent | ToolFinalEvent<O>;\n\nexport interface Tool<I = unknown, O = unknown> {\n name: string;\n description: string;\n /**\n * Pre-computed token estimate for this tool's definition (name +\n * description + JSON-serialized inputSchema). Set by ToolRegistry on\n * registration; consumed by estimateToolDefTokens / estimateRequestTokens\n * to skip redundant JSON.stringify on every context-pressure check.\n */\n _estDefTokens?: number | undefined;\n usageHint?: string | undefined;\n /** Optional category for grouping in help lists and system prompts. */\n category?: string | undefined;\n inputSchema: JSONSchema;\n permission: Permission;\n mutating: boolean;\n /**\n * Risk tier for selective YOLO gating. When YOLO is active, clearly\n * destructive calls still emit `confirm`. Defaults to `standard` when\n * omitted — callers should always check `riskTier` after the basic\n * permission decision.\n */\n riskTier?: RiskTier | undefined;\n /**\n * Input-field name that the permission policy should match trust rules\n * against. Without this, the policy falls back to a heuristic\n * (`command` / `path` / `url` / `name`) that can collide across tools —\n * e.g. an HTTP tool whose `path` means \"request path\" would be checked\n * against filesystem-path trust rules. Set explicitly to avoid the\n * cross-tool subject collision.\n *\n * The named field's value must be a string at runtime; non-string values\n * fall back to the heuristic.\n */\n subjectKey?: string | undefined;\n maxOutputBytes?: number | undefined;\n timeoutMs?: number | undefined;\n /**\n * Hint for the TUI spinner — does NOT affect actual timeout enforcement.\n * Use `timeoutMs` for hard limits. Leave undefined when duration varies\n * unpredictably.\n */\n estimatedDurationMs?: number | undefined;\n\n /**\n * Declarative security capabilities granted by this tool.\n *\n * Examples: \"shell.arbitrary\", \"fs.write\", \"fs.write.outside-project\",\n * \"net.outbound\", \"mcp.proxy\", \"subagent.spawn\", \"config.mutate\".\n *\n * These are used by permission policies (especially subagent guards) and\n * future capability-based allowlists. Prefer well-known values over ad-hoc strings.\n *\n * This field is optional for backward compatibility. Tools without it are\n * treated conservatively by guards.\n */\n capabilities?: readonly string[] | undefined;\n /**\n * Icon identifier for this tool — consumed by all UIs (WebUI/TUI/REPL) to\n * render a tool-specific icon instead of a generic fallback.\n * Each UI maps this id to its own icon library.\n */\n icon?: ToolIconId | undefined;\n execute(input: I, ctx: Context, opts: { signal: AbortSignal }): Promise<O>;\n /**\n * Optional cross-field validation hook. Called by the executor AFTER\n * JSON Schema validation passes and AFTER PreToolUse hooks may have\n * rewritten the input, but BEFORE permission checks and execution.\n *\n * Use this for invariants the JSON Schema cannot express — e.g.\n * `old_string !== new_string` in edit, or `end > start` in a range tool.\n * Return an array of validation errors (empty = valid). The executor\n * surfaces them to the model just like schema validation errors, so the\n * model can self-correct without the tool's `execute()` running.\n *\n * P3 #16 (before-release.md): tools that implement cross-field checks\n * inside `execute()` can migrate them here for earlier rejection and\n * consistent error formatting.\n */\n validate?(input: I): string[];\n /**\n * Optional streaming variant. When defined, the executor prefers this\n * over `execute` — yielded events become `tool.progress` EventBus events\n * and the terminal `final` event provides the output. Tools that don't\n * have intermediate state shouldn't implement this; the default `execute`\n * path is more efficient.\n */\n executeStream?(\n input: I,\n ctx: Context,\n opts: { signal: AbortSignal },\n ): AsyncIterable<ToolStreamEvent<O>>;\n /**\n * Optional teardown hook fired by the executor when the tool's run is\n * aborted (signal triggered). Errors thrown here are swallowed so they\n * never mask the originating failure.\n *\n * **When to use `cleanup` vs `ctx.registerAbortHook`:**\n *\n * - Use `cleanup` for resources **owned by the tool author** that are\n * established at execute-time: child processes spawned by the tool,\n * file handles opened by the tool, network connections initiated by\n * the tool. The lifecycle is co-located with the tool definition, so\n * readers see the resource and its teardown in one place.\n *\n * ```ts\n * async execute(input, ctx, opts) {\n * const child = spawn(...);\n * // … tool work …\n * },\n * async cleanup(_input, _ctx) {\n * // best-effort kill of any child still running\n * }\n * ```\n *\n * - Use `ctx.registerAbortHook` for **context-scoped teardown** registered\n * dynamically inside `execute`: when the tool delegates to a library\n * that needs cancellation, or when the resource is created lazily\n * somewhere down the call stack and the natural cleanup point isn't\n * at the tool boundary. The hook fires when the **agent run** ends,\n * not when this specific tool call aborts.\n *\n * ```ts\n * async execute(input, ctx, opts) {\n * const handle = openHelper();\n * ctx.registerAbortHook(() => handle.dispose());\n * // … work …\n * }\n * ```\n *\n * If both are registered for the same resource, `cleanup` fires first\n * (on tool abort) and the abort-hook fires after on the wider run abort.\n * Avoid double-free by gating one on the other's effect, or pick a single\n * teardown channel per resource.\n */\n cleanup?(input: I, ctx: Context): Promise<void>;\n /**\n * Optional custom output serializer. When present, the executor's output\n * serializer calls this INSTEAD of the central `renderToolObject()` switch\n * — the tool owns its own pretty-printing.\n *\n * Return a string representation of the output that the model will see in\n * its tool_result block. The serializer applies the iteration output cap\n * AFTER this runs, so don't worry about truncation.\n *\n * P3 #21 (before-release.md): `renderToolObject()` is a god function with\n * 30+ per-tool branches, far from each tool's definition. New tools that\n * want custom output no longer need to add a branch there — they implement\n * this method instead. Existing branches stay until migrated incrementally.\n */\n serialize?(output: O, input: I): string;\n}\n\nexport interface ToolCallContext {\n tool: Tool;\n input: unknown;\n callId: string;\n ctx: Context;\n signal: AbortSignal;\n}\n\n/**\n * Error categories for tool execution failures.\n * Used by the executor to classify errors and determine retry strategy.\n */\nexport enum ToolErrorCategory {\n TRANSIENT = \"transient\", // ETIMEDOUT, ECONNRESET, network timeout, HTTP 429/503\n NOT_FOUND = \"not_found\", // ENOENT, ENOTDIR, HTTP 404\n PERMISSION = \"permission\", // EACCES, EPERM, HTTP 401/403\n VALIDATION = \"validation\", // schema validation error, HTTP 400\n FATAL = \"fatal\", // unhandled exception, crash, invariant violation\n}\n\n/**\n * Structured tool error information for the LLM and retry logic.\n */\nexport interface ToolErrorInfo {\n readonly category: ToolErrorCategory;\n /** Whether the operation can be retried automatically. */\n readonly retryable: boolean;\n /** User-facing message describing the error. */\n readonly userMessage: string;\n /** Optional technical detail for debugging. */\n readonly detail?: string;\n}\n","/**\n * Sentinel keys provider adapters use to wrap tool-call arguments that could\n * not be parsed into a proper JSON object. Single source of truth — the core\n * tool executor (which DETECTS these markers to surface a friendly error)\n * defines them here, and the providers package (which PRODUCES them when\n * wrapping) imports from `@wrongstack/core`.\n *\n * P3 #14 (before-release.md): the list was duplicated in tool-executor.ts with\n * a \"Keep this list in sync\" comment — a manual rule that will eventually be\n * forgotten. Centralizing it removes the sync burden.\n *\n * Layering note: this lives in core (not providers) because the dependency\n * direction is providers → core, not the reverse. Putting it in providers\n * would force core into a forbidden upward dependency.\n *\n * Current markers:\n * - `__raw` — produced by `parseToolInput` (Anthropic / shared)\n * - `__raw_arguments` — produced by `contentFromOpenAI` (OpenAI / compatible)\n * - `_raw` — produced by the streaming response builder's\n * `safeJsonOrRaw` (legacy fallback)\n */\nexport const MALFORMED_ARG_MARKERS = ['__raw', '__raw_arguments', '_raw'] as const;\n","/**\n * Converts an unknown error value to a human-readable string.\n * Used in 40+ files across the codebase to normalize error messaging.\n */\nexport function toErrorMessage(err: unknown): string {\n return err instanceof Error ? err.message : String(err);\n}\n","/** Assert a value is neither null nor undefined. Throws if it is.\n * Useful after optional chaining and indexed access when the\n * control flow guarantees the value exists but TypeScript can't\n * prove it (e.g. after a check on a related field). */\nexport function expectDefined<T>(value: T | null | undefined, label?: string): T {\n if (value === null || value === undefined) {\n const err = new Error(label ? `Expected ${label} to be defined` : 'Expected value to be defined');\n err.name = 'ExpectDefinedError';\n throw err;\n }\n return value;\n}\n","/**\n * Compile a user-supplied regex with conservative bounds against ReDoS.\n *\n * Duplicated from @wrongstack/tools/_regex.ts to avoid a circular\n * dependency (tools depends on core, not vice versa). Keep both copies\n * in sync if the heuristics change.\n *\n * V8's regex engine is backtracking-based and cannot interrupt a\n * synchronous match — a pattern like `(a+)+$` against a sufficiently\n * long line will pin a worker for seconds.\n */\n\nconst MAX_PATTERN_LEN = 512;\n\n// Heuristics for catastrophic-backtracking constructs.\nconst DANGEROUS_PATTERNS: ReadonlyArray<RegExp> = [\n /(\\([^)]*[+*][^)]*\\))[+*]/, // (a+)+, (.*)+, etc\n /(\\(\\?:[^)]*[+*][^)]*\\))[+*]/, // same, with non-capturing group\n];\n\nexport interface CompileResult {\n ok: true;\n regex: RegExp;\n}\n\nexport interface CompileFail {\n ok: false;\n reason: string;\n}\n\nexport function compileUserRegex(pattern: string, flags: string): CompileResult | CompileFail {\n if (typeof pattern !== 'string') {\n return { ok: false, reason: 'pattern must be a string' };\n }\n if (pattern.length === 0) {\n return { ok: false, reason: 'pattern is empty' };\n }\n if (pattern.length > MAX_PATTERN_LEN) {\n return { ok: false, reason: `pattern exceeds ${MAX_PATTERN_LEN} characters` };\n }\n for (const rx of DANGEROUS_PATTERNS) {\n if (rx.test(pattern)) {\n return {\n ok: false,\n reason:\n 'pattern looks vulnerable to catastrophic backtracking — rewrite without nested quantifiers',\n };\n }\n }\n try {\n return { ok: true, regex: new RegExp(pattern, flags) };\n } catch (err) {\n return {\n ok: false,\n reason: err instanceof Error ? err.message : 'invalid regex',\n };\n }\n}\n","import * as path from 'node:path';\nimport { ERROR_CODES, FsError } from '../types/errors.js';\n\n/**\n * Resolve `<dir>/<sessionId><suffix>` for per-session sidecar files\n * (annotations, audit chain, replay log, the session JSONL itself).\n *\n * Modern session ids are date-sharded (\"2026-06-11/sess_<ULID>\"),\n * so a forward slash is a legitimate shard separator — NOT traversal.\n * Escape attempts are blocked two ways: an explicit ban on `..` and\n * backslashes, plus a resolved-path containment check that rejects any\n * id whose resolved target leaves `dir`. Character bans alone are how\n * several stores ended up throwing on every modern session id.\n */\nexport function sessionScopedPath(dir: string, sessionId: string, suffix: string): string {\n if (!sessionId || sessionId.includes('\\\\') || sessionId.includes('..')) {\n throw invalid(sessionId);\n }\n const resolved = path.resolve(dir, `${sessionId}${suffix}`);\n const rel = path.relative(path.resolve(dir), resolved);\n if (rel.startsWith('..') || path.isAbsolute(rel)) {\n throw invalid(sessionId);\n }\n return resolved;\n}\n\nfunction invalid(sessionId: string): FsError {\n return new FsError({\n message: `Invalid sessionId: ${sessionId}`,\n code: ERROR_CODES.FS_DELETE_FAILED,\n path: sessionId,\n context: { reason: 'path_traversal' },\n });\n}\n","/**\n * String utilities shared across the WrongStack codebase.\n */\n\n/**\n * Truncate a string to at most `max` characters, appending an ellipsis if it\n * was longer. Returns the original string unchanged when it fits.\n */\nexport function truncate(s: string, max: number): string {\n return s.length <= max ? s : `${s.slice(0, max - 1)}…`;\n}\n","import { toErrorMessage } from '../utils/index.js';\n\n/**\n * WrongStack error hierarchy.\n *\n * Every error thrown by the framework is a `WrongStackError` with a\n * machine-readable `code`, a `subsystem` tag, and a `severity` level.\n * This lets consumers (CLI, TUI, plugins, tests) branch on structured\n * data instead of parsing error messages.\n */\n\n// ── Error codes ──────────────────────────────────────────────────────\n\n/**\n * Machine-readable error codes as frozen constants.\n *\n * Use `ERROR_CODES.X` instead of raw string literals for:\n * - IDE autocomplete and compile-time validation\n * - Safe refactoring (rename updates all usages)\n * - Plugin extensibility (extend the object to add custom codes)\n *\n * The `ErrorCode` type is derived from this object, so adding a new\n * code here automatically updates the type without extra changes.\n */\nexport const ERROR_CODES = {\n // Provider\n PROVIDER_RATE_LIMITED: 'PROVIDER_RATE_LIMITED',\n PROVIDER_AUTH_FAILED: 'PROVIDER_AUTH_FAILED',\n PROVIDER_OVERLOADED: 'PROVIDER_OVERLOADED',\n PROVIDER_INVALID_REQUEST: 'PROVIDER_INVALID_REQUEST',\n PROVIDER_SERVER_ERROR: 'PROVIDER_SERVER_ERROR',\n PROVIDER_NETWORK_ERROR: 'PROVIDER_NETWORK_ERROR',\n PROVIDER_CONTEXT_OVERFLOW: 'PROVIDER_CONTEXT_OVERFLOW',\n // Tool\n TOOL_NOT_FOUND: 'TOOL_NOT_FOUND',\n TOOL_PERMISSION_DENIED: 'TOOL_PERMISSION_DENIED',\n TOOL_EXECUTION_FAILED: 'TOOL_EXECUTION_FAILED',\n TOOL_TIMEOUT: 'TOOL_TIMEOUT',\n TOOL_INPUT_INVALID: 'TOOL_INPUT_INVALID',\n // Config\n CONFIG_INVALID: 'CONFIG_INVALID',\n CONFIG_NOT_FOUND: 'CONFIG_NOT_FOUND',\n CONFIG_PARSE_FAILED: 'CONFIG_PARSE_FAILED',\n CONFIG_MIGRATION_NEEDED: 'CONFIG_MIGRATION_NEEDED',\n // Plugin\n PLUGIN_LOAD_FAILED: 'PLUGIN_LOAD_FAILED',\n PLUGIN_API_MISMATCH: 'PLUGIN_API_MISMATCH',\n PLUGIN_MISSING_DEPENDENCY: 'PLUGIN_MISSING_DEPENDENCY',\n // Agent\n AGENT_ITERATION_LIMIT: 'AGENT_ITERATION_LIMIT',\n AGENT_CONTEXT_OVERFLOW: 'AGENT_CONTEXT_OVERFLOW',\n AGENT_ABORTED: 'AGENT_ABORTED',\n AGENT_RUN_FAILED: 'AGENT_RUN_FAILED',\n // Session\n SESSION_NOT_FOUND: 'SESSION_NOT_FOUND',\n SESSION_CORRUPTED: 'SESSION_CORRUPTED',\n SESSION_WRITE_FAILED: 'SESSION_WRITE_FAILED',\n // Container / Registry\n CONTAINER_TOKEN_ALREADY_BOUND: 'CONTAINER_TOKEN_ALREADY_BOUND',\n CONTAINER_TOKEN_NOT_BOUND: 'CONTAINER_TOKEN_NOT_BOUND',\n CONTAINER_CIRCULAR_DEPENDENCY: 'CONTAINER_CIRCULAR_DEPENDENCY',\n REGISTRY_DUPLICATE: 'REGISTRY_DUPLICATE',\n REGISTRY_NOT_FOUND: 'REGISTRY_NOT_FOUND',\n REGISTRY_INVALID: 'REGISTRY_INVALID',\n // File system\n FS_READ_FAILED: 'FS_READ_FAILED',\n FS_WRITE_FAILED: 'FS_WRITE_FAILED',\n FS_MKDIR_FAILED: 'FS_MKDIR_FAILED',\n FS_DELETE_FAILED: 'FS_DELETE_FAILED',\n FS_ATOMIC_WRITE_FAILED: 'FS_ATOMIC_WRITE_FAILED',\n // SDD (Spec-Driven Development)\n SDD_VALIDATION_FAILED: 'SDD_VALIDATION_FAILED',\n SDD_PARSE_FAILED: 'SDD_PARSE_FAILED',\n SDD_INVALID_STATE: 'SDD_INVALID_STATE',\n SDD_NOT_READY: 'SDD_NOT_READY',\n // General\n VALIDATION_ERROR: 'VALIDATION_ERROR',\n PARSE_FAILED: 'PARSE_FAILED',\n UNKNOWN: 'UNKNOWN',\n} as const;\n\n/**\n * Union type derived from `ERROR_CODES`. Using `typeof ERROR_CODES[keyof typeof ERROR_CODES]`\n * instead of a string literal union means TypeScript auto-updates the type whenever\n * a new code is added to `ERROR_CODES` — no need to keep two lists in sync.\n */\nexport type ErrorCode = (typeof ERROR_CODES)[keyof typeof ERROR_CODES];\n\nexport type ErrorSubsystem =\n | 'provider'\n | 'tool'\n | 'config'\n | 'plugin'\n | 'agent'\n | 'session'\n | 'sdd'\n | 'container'\n | 'fs'\n | 'general';\nexport type ErrorSeverity = 'fatal' | 'error' | 'warning';\n\n// ── Base error class ─────────────────────────────────────────────────\n\nexport class WrongStackError extends Error {\n readonly code: ErrorCode;\n readonly subsystem: ErrorSubsystem;\n readonly severity: ErrorSeverity;\n readonly recoverable: boolean;\n readonly context?: Record<string, unknown> | undefined;\n\n constructor(opts: {\n message: string;\n code: ErrorCode;\n subsystem: ErrorSubsystem;\n severity?: ErrorSeverity | undefined;\n recoverable?: boolean | undefined;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super(opts.message, { cause: opts.cause });\n this.name = 'WrongStackError';\n this.code = opts.code;\n this.subsystem = opts.subsystem;\n this.severity = opts.severity ?? 'error';\n this.recoverable = opts.recoverable ?? false;\n this.context = opts.context;\n }\n\n /**\n * Render a one-line user-facing description.\n * Subclasses should override for domain-specific formatting.\n */\n describe(): string {\n const ctx = this.context ? ` ${formatContext(this.context)}` : '';\n return `${this.code}: ${this.message}${ctx}`;\n }\n}\n\nfunction formatContext(ctx: Record<string, unknown>): string {\n const parts = Object.entries(ctx)\n .filter(([, v]) => v !== undefined)\n .slice(0, 3)\n .map(([k, v]) => `${k}=${String(v)}`);\n return parts.length > 0 ? `[${parts.join(' ')}]` : '';\n}\n\n// ── Specific error classes ───────────────────────────────────────────\n\n/**\n * Tool execution errors — thrown by ToolExecutor and individual tools.\n */\nexport class ToolError extends WrongStackError {\n readonly toolName: string;\n\n constructor(opts: {\n message: string;\n code: Extract<\n ErrorCode,\n | 'TOOL_NOT_FOUND'\n | 'TOOL_PERMISSION_DENIED'\n | 'TOOL_EXECUTION_FAILED'\n | 'TOOL_TIMEOUT'\n | 'TOOL_INPUT_INVALID'\n >;\n toolName: string;\n recoverable?: boolean | undefined;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'tool',\n recoverable: opts.recoverable,\n context: { tool: opts.toolName, ...opts.context },\n cause: opts.cause,\n });\n this.name = 'ToolError';\n this.toolName = opts.toolName;\n }\n}\n\n/**\n * Config loading / validation errors.\n */\nexport class ConfigError extends WrongStackError {\n constructor(opts: {\n message: string;\n code: Extract<\n ErrorCode,\n 'CONFIG_INVALID' | 'CONFIG_NOT_FOUND' | 'CONFIG_PARSE_FAILED' | 'CONFIG_MIGRATION_NEEDED'\n >;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'config',\n severity: 'fatal',\n recoverable: false,\n context: opts.context,\n cause: opts.cause,\n });\n this.name = 'ConfigError';\n }\n}\n\n/**\n * Plugin loading / lifecycle errors.\n */\nexport class PluginError extends WrongStackError {\n readonly pluginName: string;\n\n constructor(opts: {\n message: string;\n code: Extract<\n ErrorCode,\n 'PLUGIN_LOAD_FAILED' | 'PLUGIN_API_MISMATCH' | 'PLUGIN_MISSING_DEPENDENCY'\n >;\n pluginName: string;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'plugin',\n severity: 'error',\n recoverable: opts.code === ERROR_CODES.PLUGIN_MISSING_DEPENDENCY,\n context: { plugin: opts.pluginName, ...opts.context },\n cause: opts.cause,\n });\n this.name = 'PluginError';\n this.pluginName = opts.pluginName;\n }\n}\n\n/**\n * Agent runtime errors — thrown by Agent.run when a non-WrongStackError\n * escapes the inner loop, so callers always see a structured error.\n */\nexport class AgentError extends WrongStackError {\n constructor(opts: {\n message: string;\n code: Extract<\n ErrorCode,\n 'AGENT_ITERATION_LIMIT' | 'AGENT_CONTEXT_OVERFLOW' | 'AGENT_ABORTED' | 'AGENT_RUN_FAILED'\n >;\n recoverable?: boolean | undefined;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'agent',\n severity: opts.code === ERROR_CODES.AGENT_ABORTED ? 'warning' : 'error',\n recoverable: opts.recoverable ?? opts.code === ERROR_CODES.AGENT_ITERATION_LIMIT,\n context: opts.context,\n cause: opts.cause,\n });\n this.name = 'AgentError';\n }\n}\n\n/**\n * Wrap an arbitrary thrown value into a `WrongStackError` so the caller\n * always gets a structured error. Pass-throughs WrongStackError instances\n * unchanged; raw `Error`s and primitives get an `AGENT_RUN_FAILED` wrapper\n * with the original preserved as `cause`.\n */\nexport function toWrongStackError(\n err: unknown,\n code: Extract<ErrorCode, 'AGENT_RUN_FAILED' | 'AGENT_ABORTED' | 'UNKNOWN'> = ERROR_CODES.AGENT_RUN_FAILED,\n): WrongStackError {\n if (err instanceof WrongStackError) return err;\n const message = toErrorMessage(err);\n return new AgentError({\n message,\n code: code === 'UNKNOWN' ? ERROR_CODES.AGENT_RUN_FAILED : code,\n cause: err,\n });\n}\n\n/**\n * Session storage errors.\n */\nexport class SessionError extends WrongStackError {\n readonly sessionId?: string | undefined;\n\n constructor(opts: {\n message: string;\n code: Extract<ErrorCode, 'SESSION_NOT_FOUND' | 'SESSION_CORRUPTED' | 'SESSION_WRITE_FAILED'>;\n sessionId?: string | undefined;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'session',\n severity: opts.code === ERROR_CODES.SESSION_WRITE_FAILED ? 'error' : 'warning',\n recoverable: opts.code !== ERROR_CODES.SESSION_CORRUPTED,\n context: { sessionId: opts.sessionId, ...opts.context },\n cause: opts.cause,\n });\n this.name = 'SessionError';\n this.sessionId = opts.sessionId;\n }\n}\n\n/**\n * SDD (Spec-Driven Development) errors — spec validation, parsing, and\n * state machine violations in the AISpecBuilder, TaskFlow, and TaskTracker.\n */\nexport class SddError extends WrongStackError {\n constructor(opts: {\n message: string;\n code: Extract<\n ErrorCode,\n 'SDD_VALIDATION_FAILED' | 'SDD_PARSE_FAILED' | 'SDD_INVALID_STATE' | 'SDD_NOT_READY'\n >;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'sdd',\n severity: opts.code === ERROR_CODES.SDD_PARSE_FAILED ? 'warning' : 'error',\n recoverable: opts.code === ERROR_CODES.SDD_NOT_READY,\n context: opts.context,\n cause: opts.cause,\n });\n this.name = 'SddError';\n }\n}\n\n/**\n * File system operation errors.\n */\nexport class FsError extends WrongStackError {\n readonly path?: string | undefined;\n\n constructor(opts: {\n message: string;\n code: Extract<\n ErrorCode,\n 'FS_READ_FAILED' | 'FS_WRITE_FAILED' | 'FS_MKDIR_FAILED' | 'FS_DELETE_FAILED' | 'FS_ATOMIC_WRITE_FAILED'\n >;\n path?: string | undefined;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'fs',\n severity: 'error',\n recoverable: opts.code !== ERROR_CODES.FS_READ_FAILED,\n context: { path: opts.path, ...opts.context },\n cause: opts.cause,\n });\n this.name = 'FsError';\n this.path = opts.path;\n }\n}\n\n/**\n * HTTP fetch error — thrown when a network request returns a non-OK status.\n * Carries the response status so {@link classifyToolError} can branch on it\n * (429 → transient, 404 → not_found, 401 → permission) without duck-typing\n * the error via `'response' in err`.\n *\n * P3 #18 (before-release.md): the previous `'response' in err` check caught\n * any Error with a `response` property, including custom errors, proxy\n * objects, or mocked errors in tests. `instanceof FetchError` is reliable.\n *\n * Tools and providers that make HTTP requests and need the executor to\n * classify their failures should throw `new FetchError({ status, message })`\n * instead of a bare `Error` with an ad-hoc `response` field.\n */\nexport class FetchError extends WrongStackError {\n readonly status: number;\n\n constructor(opts: {\n message: string;\n status: number;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: ERROR_CODES.VALIDATION_ERROR,\n subsystem: 'general',\n severity: 'error',\n recoverable: opts.status === 429 || opts.status >= 500,\n context: { status: opts.status, ...opts.context },\n cause: opts.cause,\n });\n this.name = 'FetchError';\n this.status = opts.status;\n }\n}\n\n/**\n * Tool input validation error — thrown when a tool's input fails a validation\n * check that the JSON Schema cannot express (e.g. `old_string === new_string`\n * in edit, or a cross-field invariant). Use this instead of a bare\n * `throw new Error('...validation...')` so {@link classifyToolError} can\n * match on `instanceof` rather than a locale-dependent message substring.\n *\n * P2 #6 (before-release.md): the previous `err.message.includes('validation')`\n * check misclassified any error whose message happened to contain \"validation\"\n * (e.g. a third-party \"input validation timeout\") as a VALIDATION error.\n *\n * Named `ToolValidationError` (not `ValidationError`) to avoid colliding with\n * the existing `ValidationError` interface exported by json-schema-validate.ts\n * (a validation-result shape, not an Error subclass).\n */\nexport class ToolValidationError extends WrongStackError {\n constructor(opts: {\n message: string;\n /** Field path or tool name that failed validation, for diagnostics. */\n field?: string | undefined;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: ERROR_CODES.VALIDATION_ERROR,\n subsystem: 'general',\n severity: 'error',\n recoverable: false,\n context: { field: opts.field, ...opts.context },\n cause: opts.cause,\n });\n this.name = 'ToolValidationError';\n }\n}\n\n/**\n * Response / payload parse error — thrown when an upstream HTTP response,\n * file, or data structure is well-formed at the transport layer (HTTP 200,\n * valid JSON) but is missing required fields or has an unexpected shape.\n *\n * Distinct from `ConfigError(CONFIG_PARSE_FAILED)` (which is specifically\n * for config-file parsing) and `FetchError` (which covers HTTP non-OK\n * responses). `ParseError` fills the gap: the request succeeded but the\n * response body couldn't be interpreted.\n *\n * Common sites: OAuth token responses missing `access_token`, device-code\n * responses missing `device_code`, registry responses with unexpected\n * schemas.\n */\nexport class ParseError extends WrongStackError {\n readonly source?: string | undefined;\n\n constructor(opts: {\n message: string;\n /**\n * What was being parsed — e.g. `'oauth-token-response'`,\n * `'device-code-response'`. Lets consumers distinguish parse failures\n * from different upstream APIs without parsing the message.\n */\n source?: string | undefined;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: ERROR_CODES.PARSE_FAILED,\n subsystem: 'general',\n severity: 'error',\n recoverable: false,\n context: { source: opts.source, ...opts.context },\n cause: opts.cause,\n });\n this.name = 'ParseError';\n this.source = opts.source;\n }\n}\n\n// ── Type guards ──────────────────────────────────────────────────────\n\nexport function isWrongStackError(err: unknown): err is WrongStackError {\n return err instanceof WrongStackError;\n}\n\nexport function isToolError(err: unknown): err is ToolError {\n return err instanceof ToolError;\n}\n\nexport function isConfigError(err: unknown): err is ConfigError {\n return err instanceof ConfigError;\n}\n\nexport function isPluginError(err: unknown): err is PluginError {\n return err instanceof PluginError;\n}\n\nexport function isSessionError(err: unknown): err is SessionError {\n return err instanceof SessionError;\n}\n\nexport function isAgentError(err: unknown): err is AgentError {\n return err instanceof AgentError;\n}\n\nexport function isFsError(err: unknown): err is FsError {\n return err instanceof FsError;\n}\n\nexport function isToolValidationError(err: unknown): err is ToolValidationError {\n return err instanceof ToolValidationError;\n}\n\nexport function isFetchError(err: unknown): err is FetchError {\n return err instanceof FetchError;\n}\n\nexport function isParseError(err: unknown): err is ParseError {\n return err instanceof ParseError;\n}\n\nexport function isSddError(err: unknown): err is SddError {\n return err instanceof SddError;\n}\n","import type { ContentBlock, TextBlock } from './blocks.js';\nimport type { ErrorCode } from './errors.js';\nimport { WrongStackError, ERROR_CODES } from './errors.js';\nimport type { Message } from './messages.js';\nimport type { Tool } from './tool.js';\nimport { truncate } from '../utils/string.js';\n\n/**\n * Token usage for a single provider call, normalized across providers.\n *\n * Disjoint semantics: the four fields never overlap. `input` is the count\n * of FRESH input tokens (billed at the full input rate); `cacheRead` and\n * `cacheWrite` are separate cached subsets each priced at their own rate.\n * The total context the model loaded for this turn is\n * `input + (cacheRead ?? 0) + (cacheWrite ?? 0)`.\n *\n * Provider quirks normalized at the adapter layer:\n * - Anthropic: returns `input_tokens` already disjoint from cache fields.\n * - OpenAI / OpenAI-compatible: `prompt_tokens` is the TOTAL including\n * cached portion; the adapter subtracts `cached_tokens` to stay disjoint.\n * - Google: `promptTokenCount` likewise includes cache; adapter subtracts\n * `cachedContentTokenCount`.\n *\n * Cost math and the context-fullness chip both depend on the disjoint\n * invariant — a TOTAL `input` plus a separate `cacheRead` count would bill\n * cached tokens twice and skew cache-hit-ratio reporting.\n */\nexport type ReasoningEffort = 'none' | 'minimal' | 'low' | 'medium' | 'high' | 'xhigh' | 'max';\nexport type CacheTtl = '5m' | '1h';\n\n/**\n * Provider-agnostic response-format directive.\n *\n * - `{ type: 'text' }` — free-form text (default).\n * - `{ type: 'json_object' }` — valid JSON without a schema constraint.\n * - `{ type: 'json_schema', jsonSchema: { name, schema, strict? } }` — JSON\n * constrained to the supplied JSON Schema. The `strict` flag is\n * OpenAI-specific; Gemini ignores it in favour of `responseMimeType`.\n *\n * Each provider adapter maps this into its own wire format:\n * OpenAI → `response_format`\n * Gemini → `responseMimeType` + `responseSchema`\n * Anthropic → (not yet supported; uses tools for structured output)\n */\nexport interface JsonSchemaSpec {\n name: string;\n /** OpenAI-specific: enable strict schema adherence. */\n strict?: boolean | undefined;\n /** The JSON Schema object describing the expected shape. */\n schema: Record<string, unknown>;\n /** Optional human-readable description (OpenAI). */\n description?: string | undefined;\n}\n\nexport type ResponseFormat =\n | { type: 'text' }\n | { type: 'json_object' }\n | { type: 'json_schema'; jsonSchema: JsonSchemaSpec };\n\n/**\n * Safety category threshold pair used by Google Gemini's `safetySettings`.\n *\n * Categories: `HARM_CATEGORY_HARASSMENT`, `HARM_CATEGORY_HATE_SPEECH`,\n * `HARM_CATEGORY_SEXUALLY_EXPLICIT`, `HARM_CATEGORY_DANGEROUS_CONTENT`.\n *\n * Thresholds: `BLOCK_NONE`, `BLOCK_ONLY_HIGH`, `BLOCK_MEDIUM_AND_ABOVE`,\n * `BLOCK_LOW_AND_ABOVE`.\n */\nexport interface SafetySetting {\n category: string;\n threshold: string;\n}\n\nexport interface Usage {\n input: number;\n output: number;\n cacheRead?: number | undefined;\n /** Back-compat aggregate of all cache-write tokens. Prefer TTL-specific fields when present. */\n cacheWrite?: number | undefined;\n cacheWrite5m?: number | undefined;\n cacheWrite1h?: number | undefined;\n}\n\nexport interface ReasoningRequest {\n enabled?: boolean | undefined;\n effort?: ReasoningEffort | undefined;\n preserve?: boolean | undefined;\n display?: 'summarized' | 'omitted' | undefined;\n}\n\nexport interface RequestCacheControl {\n ttl?: CacheTtl | undefined;\n}\n\nexport interface ReasoningConfig {\n default: 'enabled' | 'disabled' | 'adaptive' | 'always_on';\n disableSupported: boolean;\n effortSupported: boolean;\n effortLevels: ReasoningEffort[];\n preserveThinking: 'unsupported' | 'optional' | 'always_on';\n}\n\nexport interface Capabilities {\n tools: boolean;\n parallelTools: boolean;\n vision: boolean;\n streaming: boolean;\n promptCache: boolean;\n systemPrompt: boolean;\n jsonMode: boolean;\n reasoning: boolean;\n maxContext: number;\n /**\n * Maximum output tokens the model can produce in a single response.\n * Used as the default for `Request.maxTokens` when the caller doesn't\n * supply an explicit value — letting subagents run up to the model's\n * native ceiling instead of a fixed 8192 cap. Omit (undefined) to fall\n * back to a conservative default; populate per family in\n * `family-capabilities.ts` once you know the spec.\n */\n maxOutput?: number | undefined;\n cacheControl: 'native' | 'auto' | 'none';\n\n // ── Extended parameter support (optional; family defaults in CAPABILITIES_BY_FAMILY) ──\n\n /** Model accepts `top_k` / `topK` sampling parameter. */\n topK?: boolean | undefined;\n /** Model accepts `frequency_penalty` / `frequencyPenalty` parameter. */\n frequencyPenalty?: boolean | undefined;\n /** Model accepts `presence_penalty` / `presencePenalty` parameter. */\n presencePenalty?: boolean | undefined;\n /** Model accepts `seed` parameter for deterministic generation. */\n seed?: boolean | undefined;\n /**\n * Model accepts JSON Schema / structured-output constraints\n * (OpenAI `response_format.json_schema`, Gemini `responseMimeType`+`responseSchema`).\n * Distinct from `jsonMode` (which is just a system-prompt hint).\n */\n structuredOutput?: boolean | undefined;\n /** Model supports log-probability output (`logprobs`, `top_logprobs`). */\n logprobs?: boolean | undefined;\n /** Model supports audio input/output modality. */\n audio?: boolean | undefined;\n /** Model supports the `n` parameter for multiple completions. */\n multipleCompletions?: boolean | undefined;\n}\n\nexport interface Request {\n model: string;\n system?: TextBlock[] | undefined;\n messages: Message[];\n tools?: Tool[] | undefined;\n /**\n * Cap on output tokens for this single response. Optional — when\n * omitted, the provider adapter falls back to its own\n * `capabilities.maxOutput` (which the catalog populates from\n * `ModelsDevModel.limit.output`). If neither is available, the\n * adapter applies a conservative 8192 safety net. Letting this stay\n * undefined at the call site means callers like Chimera can hand the\n * model its native output ceiling without hard-coding a number.\n */\n maxTokens?: number | undefined;\n temperature?: number | undefined;\n topP?: number | undefined;\n topK?: number | undefined;\n frequencyPenalty?: number | undefined;\n presencePenalty?: number | undefined;\n seed?: number | undefined;\n /**\n * End-user identifier for abuse monitoring and per-user rate limiting.\n * - Anthropic → `metadata.user_id`\n * - OpenAI → `user`\n * - Gemini → (not supported)\n */\n user?: string | undefined;\n /**\n * Number of response candidates to generate. Google Gemini supports\n * this via `generationConfig.candidateCount`. OpenAI does not have\n * an equivalent (`n` is conceptually similar but distinct).\n */\n candidateCount?: number | undefined;\n /**\n * Whether to return log probabilities for output tokens.\n * - OpenAI → `logprobs: boolean` (+ `topLogprobs: number`)\n * - Gemini → `generationConfig.logprobs: number` (how many top candidates)\n * Default undefined = no logprobs requested.\n */\n logprobs?: boolean | undefined;\n /**\n * Number of most probable tokens to return log probabilities for\n * (OpenAI `top_logprobs`). Only meaningful when `logprobs` is true.\n * Range: 0-20. Gemini ignores this (uses `logprobs` as the count).\n */\n topLogprobs?: number | undefined;\n stopSequences?: string[] | undefined;\n toolChoice?: 'auto' | 'required' | 'none' | { type: 'tool' | undefined; name: string };\n reasoning?: ReasoningRequest | undefined;\n cache?: RequestCacheControl | undefined;\n /**\n * Structured-output / response-format directive.\n * When set, the provider adapter maps this to its native response-format\n * parameter (OpenAI `response_format`, Gemini `responseMimeType`, etc.).\n * The model must advertise `capabilities.structuredOutput` for this to be\n * honoured; unsupported models will likely 400 or ignore it.\n */\n responseFormat?: ResponseFormat | undefined;\n /**\n * Safety category thresholds for filtering harmful content.\n * - Gemini → top-level `safetySettings` array with `{ category, threshold }`\n * - OpenAI → not supported (uses server-side moderation)\n * - Anthropic → not supported\n */\n safetySettings?: SafetySetting[] | undefined;\n}\n\nexport type StopReason = 'end_turn' | 'tool_use' | 'max_tokens' | 'stop_sequence' | 'refusal';\n\nexport interface Response {\n content: ContentBlock[];\n stopReason: StopReason;\n usage: Usage;\n model: string;\n}\n\nexport type StreamEvent =\n | { type: 'message_start'; model: string }\n | {\n type: 'content_block_start';\n kind: 'text' | 'tool_use' | 'thinking';\n id?: string | undefined;\n name?: string | undefined;\n }\n | { type: 'content_block_stop'; index: number }\n | { type: 'text_delta'; text: string }\n | { type: 'tool_use_start'; id: string; name: string }\n | { type: 'tool_use_input_delta'; id: string; partial: string }\n | { type: 'tool_use_stop'; id: string; input: unknown; providerMeta?: Record<string, unknown> }\n | { type: 'thinking_start'; providerMeta?: Record<string, unknown> }\n | { type: 'thinking_delta'; text: string }\n | { type: 'thinking_signature'; signature: string }\n | { type: 'thinking_stop' }\n | { type: 'message_stop'; stopReason: StopReason; usage: Usage };\n\nexport interface Provider {\n readonly id: string;\n readonly capabilities: Capabilities;\n /** Canonical streaming entry point. `complete()` defaults to a wrapper that\n * aggregates this stream — providers may override for non-streaming wires. */\n stream(req: Request, opts: { signal: AbortSignal }): AsyncIterable<StreamEvent>;\n complete(req: Request, opts: { signal: AbortSignal }): Promise<Response>;\n}\n\n/**\n * Structured body parsed from a provider's HTTP error response. Populated\n * best-effort: providers return JSON shaped differently (Anthropic uses\n * `{error: {type, message}}`, OpenAI uses `{error: {message, code}}`,\n * Google uses `{error: {status, message}}`), so the fields here are the\n * intersection that's usable for rendering and routing.\n */\nexport interface ProviderErrorBody {\n /** Provider-specific kind, e.g. \"overloaded_error\", \"rate_limit_error\", \"invalid_request_error\". */\n type?: string | undefined;\n /** Human-readable explanation from the provider. */\n message?: string | undefined;\n /** Provider request id, when present in the body or headers. */\n requestId?: string | undefined;\n /** Parsed Retry-After header (or equivalent body hint) in milliseconds. */\n retryAfterMs?: number | undefined;\n /** The raw response body (truncated to ~2 KB), kept for debugging. */\n raw?: string | undefined;\n /** True when `raw` was truncated; check `rawLength` for the original size. */\n truncated?: boolean | undefined;\n /** Original length of the response body in bytes, when `truncated` is true. */\n rawLength?: number | undefined;\n}\n\nexport class ProviderError extends WrongStackError {\n public readonly status: number;\n public readonly retryable: boolean;\n public readonly providerId: string;\n public readonly body?: ProviderErrorBody | undefined;\n\n constructor(\n message: string,\n status: number,\n retryable: boolean,\n providerId: string,\n opts: { body?: ProviderErrorBody | undefined; cause?: unknown | undefined } = {},\n ) {\n super({\n message,\n code: providerStatusToCode(status, opts.body?.type),\n subsystem: 'provider',\n severity: status >= 500 ? 'error' : 'warning',\n recoverable: retryable,\n context: { providerId, status },\n cause: opts.cause,\n });\n this.name = 'ProviderError';\n this.status = status;\n this.retryable = retryable;\n this.providerId = providerId;\n this.body = opts.body;\n }\n\n /**\n * Render a one-line, user-facing description. Designed for the CLI/TUI\n * status line and the agent's retry warning. Avoids dumping raw JSON\n * (which is what users see today when a 529 lands and the log message\n * includes the full `{\"type\":\"error\",...}` body).\n *\n * Examples:\n * \"minimax-coding-plan overloaded (529): High traffic detected. Upgrade for highspeed model. [req 06534785201de9c0…]\"\n * \"openai rate limited (429): Retry after 12s\"\n * \"anthropic invalid request (400): messages.0.role must be one of 'user'|'assistant'\"\n * \"groq HTTP 500 (server error)\"\n */\n override describe(): string {\n const kind = describeStatus(this.status, this.body?.type);\n const head = `${this.providerId} ${kind}`;\n const detail = this.body?.message?.trim();\n const reqId = this.body?.requestId\n ? ` [req ${this.body.requestId.slice(0, 16)}${this.body.requestId.length > 16 ? '…' : ''}]`\n : '';\n if (detail && detail.length > 0) {\n return `${head}: ${truncate(detail, 240)}${reqId}`;\n }\n return `${head}${reqId}`;\n }\n}\n\nfunction describeStatus(status: number, type?: string): string {\n if (status === 0) return 'network error';\n if (type === 'overloaded_error' || status === 529) return `overloaded (${status})`;\n if (type === 'rate_limit_error' || status === 429) return `rate limited (${status})`;\n if (type === 'authentication_error' || status === 401) return `auth failed (${status})`;\n if (type === 'permission_error' || status === 403) return `forbidden (${status})`;\n if (type === 'not_found_error' || status === 404) return `not found (${status})`;\n if (type === 'invalid_request_error' || status === 400) return `invalid request (${status})`;\n if (status === 408) return `timeout (${status})`;\n if (status >= 500 && status < 600) return `HTTP ${status} (server error)`;\n if (type) return `${type} (${status})`;\n return `HTTP ${status}`;\n}\n\n/**\n * Thrown when the provider stream stops delivering data mid-response.\n * This is distinct from a network error (TCP reset, DNS failure) — the\n * connection is established and the response started, but chunks stopped\n * arriving before the stream completed.\n *\n * Status 599 is used as a sentinel to distinguish stream hangs from\n * regular HTTP errors while still flowing through ProviderError-based\n * retry and fallback infrastructure.\n */\nexport class StreamHangError extends ProviderError {\n /** Name of the provider that hung, e.g. \"zai\", \"anthropic\". */\n public readonly hungProviderId: string;\n /** Model that was being called when the hang occurred. */\n public readonly hungModel: string;\n /** How long (ms) we waited for the next chunk before declaring a hang. */\n public readonly hangTimeoutMs: number;\n /** How many bytes were received before the hang. */\n public readonly bytesReceived: number;\n /** Elapsed time (ms) from the start of the stream until the hang. */\n public readonly elapsedMs: number;\n\n constructor(opts: {\n providerId: string;\n model: string;\n hangTimeoutMs: number;\n bytesReceived: number;\n elapsedMs: number;\n cause?: unknown | undefined;\n }) {\n super(\n `Stream hang: ${opts.providerId}/${opts.model} — no data for ${opts.hangTimeoutMs}ms after ${opts.bytesReceived} bytes (${opts.elapsedMs}ms elapsed)`,\n 599,\n true, // always retryable\n opts.providerId,\n {\n body: {\n message: `Stream stalled after ${opts.elapsedMs}ms, ${opts.bytesReceived} bytes received`,\n },\n cause: opts.cause,\n },\n );\n this.name = 'StreamHangError';\n this.hungProviderId = opts.providerId;\n this.hungModel = opts.model;\n this.hangTimeoutMs = opts.hangTimeoutMs;\n this.bytesReceived = opts.bytesReceived;\n this.elapsedMs = opts.elapsedMs;\n }\n}\n\nfunction providerStatusToCode(status: number, type?: string): ErrorCode {\n if (status === 0) return ERROR_CODES.PROVIDER_NETWORK_ERROR;\n if (type === 'rate_limit_error' || status === 429) return ERROR_CODES.PROVIDER_RATE_LIMITED;\n if (type === 'authentication_error' || status === 401) return ERROR_CODES.PROVIDER_AUTH_FAILED;\n if (type === 'overloaded_error' || status === 529) return ERROR_CODES.PROVIDER_OVERLOADED;\n if (type === 'invalid_request_error' || status === 400) return ERROR_CODES.PROVIDER_INVALID_REQUEST;\n if (status === 408) return ERROR_CODES.PROVIDER_NETWORK_ERROR;\n if (status >= 500) return ERROR_CODES.PROVIDER_SERVER_ERROR;\n return ERROR_CODES.PROVIDER_INVALID_REQUEST;\n}\n","import type { ContextWindowModeId } from './context-window.js';\nimport type { HookEvent, ShellHook } from './hooks.js';\nimport type { WireFamily } from './models-registry.js';\nimport type { CacheTtl, Capabilities, ReasoningEffort } from './provider.js';\nimport type { Permission } from './tool.js';\n\n/**\n * Runtime reasoning controls the user can set per-session/project. Mapped into\n * the provider `Request.reasoning` field by the model-runtime request\n * middleware, gated by the active model's `reasoningConfig` capabilities so\n * unsupported values are omitted (and warned) instead of triggering provider\n * 400s. See `resolveReasoningForRequest()` in packages/core.\n */\nexport interface ModelRuntimeReasoningConfig {\n /**\n * Whether to send explicit reasoning enable/disable.\n * - 'auto' → do not send explicit fields; provider/model default wins\n * - 'on' → send `reasoning.enabled = true`\n * - 'off' → send `reasoning.enabled = false` only when the model supports disable\n */\n mode?: 'auto' | 'on' | 'off' | undefined;\n /** Reasoning effort. Only sent when the model advertises `effortSupported`. */\n effort?: ReasoningEffort | undefined;\n /** Preserve thinking across turns. Only sent when `preserveThinking !== 'unsupported'`. */\n preserve?: boolean | undefined;\n}\n\n/**\n * Runtime prompt-cache controls mapped into `Request.cache`. Currently only the\n * Anthropic TTL toggle (5m vs 1h) is exposed; other providers ignore it.\n */\nexport interface ModelRuntimeCacheConfig {\n ttl?: CacheTtl | undefined;\n}\n\n/**\n * Shared runtime controls applied to every provider request, regardless of host\n * (REPL / TUI / WebUI). The CLI installs a single request-pipeline middleware\n * that reads these and mutates the outgoing `Request`.\n */\nexport interface ModelRuntimeConfig {\n reasoning?: ModelRuntimeReasoningConfig | undefined;\n cache?: ModelRuntimeCacheConfig | undefined;\n /**\n * Generic generation parameters mapped directly onto `Request` fields.\n * Only sent when the active model's `Capabilities` advertise support.\n */\n parameters?: ModelRuntimeParametersConfig | undefined;\n}\n\n/**\n * Generic generation parameters the user can set per-session / per-project.\n * Each field maps to a `Request` field of the same name and is gated by the\n * corresponding `Capabilities` flag so unsupported models don't receive\n * parameters they'd reject.\n */\nexport interface ModelRuntimeParametersConfig {\n /** Top-K sampling (Anthropic, Gemini). Gated by `capabilities.topK`. */\n topK?: number | undefined;\n /** Frequency penalty (OpenAI, Gemini). Gated by `capabilities.frequencyPenalty`. */\n frequencyPenalty?: number | undefined;\n /** Presence penalty (OpenAI, Gemini). Gated by `capabilities.presencePenalty`. */\n presencePenalty?: number | undefined;\n /** Random seed (OpenAI, Gemini). Gated by `capabilities.seed`. */\n seed?: number | undefined;\n /** End-user identifier for abuse monitoring. */\n user?: string | undefined;\n /** Log probabilities (OpenAI, Gemini). Gated by `capabilities.logprobs`. */\n logprobs?: boolean | undefined;\n /** Number of top logprobs to return (OpenAI). Only when `logprobs` is true. */\n topLogprobs?: number | undefined;\n}\n\n/**\n * HQ client connection settings. Same-machine clients can auto-discover the\n * local HQ auth file; remote clients use this config-backed URL/token pair.\n */\nexport interface HqClientConfig {\n /** Enable HQ publishing. Env WRONGSTACK_HQ_ENABLED still overrides at runtime. */\n enabled?: boolean | undefined;\n /** HQ HTTP base URL, e.g. http://host:3499. */\n url?: string | undefined;\n /** Client token for /ws/client. Stored encrypted by SecretVault when persisted. */\n token?: string | undefined;\n /** Optional HQ data dir for same-machine auth.json discovery. */\n dataDir?: string | undefined;\n /** Send raw content previews to HQ instead of redacted previews. */\n rawContent?: boolean | undefined;\n /** Override project display name in HQ. */\n projectAlias?: string | undefined;\n}\n\n/**\n * Token-saving mode tier levels. Controls how aggressively the system prompt\n * is compacted to reduce per-request token consumption.\n *\n * - 'off' — Full prompt, all tools, complete guidance (no reduction)\n * - 'minimal' — TIER1 tools only (~10), stripped guidance (~3-4k tokens saved)\n * - 'light' — Core + memory tools (~14), common patterns, minimal guidance\n * - 'medium' — Most development tools (~24), some guidance (default when `true`)\n * - 'aggressive' — Maximum savings before tools become unusable (~4-5k tokens saved)\n */\nexport type TokenSavingTier = 'off' | 'minimal' | 'light' | 'medium' | 'aggressive';\n\n/**\n * Normalize a TokenSavingTier value, handling backward-compatible boolean inputs.\n * - `true` → 'medium' (existing behavior)\n * - `false` → 'off'\n * - string values are returned as-is after validation\n * - `undefined` → 'off'\n */\nexport function normalizeTokenSavingTier(val?: TokenSavingTier | boolean): TokenSavingTier {\n if (val === undefined) return 'off';\n if (typeof val === 'boolean') return val ? 'medium' : 'off';\n const validTiers = new Set<TokenSavingTier>(['off', 'minimal', 'light', 'medium', 'aggressive']);\n return validTiers.has(val) ? val : 'off';\n}\n\nexport const DEFAULT_TUI_THINKING_WORD = 'thinking';\nexport const MAX_TUI_THINKING_WORD_LENGTH = 16;\n\n/**\n * Normalize the configurable statusline word shown while the TUI is working.\n * The value must be a single short word; invalid values fall back to the default.\n */\nexport function normalizeTuiThinkingWord(value: unknown): string {\n if (typeof value !== 'string') return DEFAULT_TUI_THINKING_WORD;\n const word = value.trim();\n if (word.length === 0 || word.length > MAX_TUI_THINKING_WORD_LENGTH) {\n return DEFAULT_TUI_THINKING_WORD;\n }\n if (!/^[\\p{L}\\p{N}_-]+$/u.test(word)) return DEFAULT_TUI_THINKING_WORD;\n return word;\n}\n\nexport interface ContextConfig {\n /** Context-window policy mode. Controls compaction thresholds and preservation depth. */\n mode?: ContextWindowModeId | undefined;\n warnThreshold: number;\n softThreshold: number;\n hardThreshold: number;\n /** Enable automatic compaction when thresholds are crossed (default: true). */\n autoCompact?: boolean | undefined;\n /**\n * Model used for LLM-assisted summarization in IntelligentCompactor.\n * Falls back to the main model when omitted.\n */\n summarizerModel?: string | undefined;\n /**\n * Override the effective context window size (in tokens). Use this when\n * you want the compactor to trigger earlier than the provider's actual\n * maxContext. Defaults to the provider's reported maxContext.\n */\n effectiveMaxContext?: number | undefined;\n maxSessionTokens?: number | undefined;\n maxDailyTokens?: number | undefined;\n preserveK: number;\n eliseThreshold: number;\n /** Compactor strategy: 'hybrid' (default, fast rules), 'intelligent' (LLM summarization), 'selective' (LLM-driven selection). */\n strategy?: 'hybrid' | 'intelligent' | 'selective' | undefined;\n /** Enable LLM-driven selective compaction (default: false for backward compat). */\n llmSelector?: boolean | undefined;\n}\n\n/**\n * Runtime configuration for the process circuit breaker (the one owned by the\n * ProcessRegistry that gates `bash`/`exec`). Toggle via `/settings breaker`.\n *\n * The breaker itself is a low-level primitive (`packages/tools/.../circuit-breaker.ts`)\n * that is on by default; this section controls whether the registry actually\n * participates in it and how it auto-recovers.\n */\nexport interface CircuitBreakerRuntimeConfig {\n /**\n * Enable circuit-breaker protection. When false (the default), the breaker\n * is bypassed — `bash`/`exec` calls always proceed regardless of failure\n * history. When true, the breaker trips on repeated failures / slow calls /\n * bursts and blocks further calls until it recovers.\n */\n enabled?: boolean | undefined;\n /**\n * When the breaker trips, automatically kill all tracked processes AND\n * reset the breaker to closed after this delay (ms). 0 = disabled (manual\n * recovery only via `/kill reset`). Only effective when `enabled` is true.\n * While armed, the statusline shows a live countdown to the kill/reset.\n */\n autoKillResetMs?: number | undefined;\n}\n\n/**\n * Adaptive concurrency controller configuration. When enabled, the controller\n * automatically adjusts `maxConcurrent` based on rate-limit (429) errors:\n * - On 429: halves `maxConcurrent` (floor at 1)\n * - On sustained success (no 429 for `recoveryIntervalMs`): increases `maxConcurrent` by 1\n */\nexport interface AdaptiveConcurrencyConfig {\n /** Enable adaptive concurrency. Default: false (disabled). */\n enabled?: boolean | undefined;\n /**\n * Minimum concurrency floor. The controller never drops below this.\n * Default: 1.\n */\n minConcurrent?: number | undefined;\n /**\n * Maximum concurrency ceiling. The controller never exceeds this.\n * Default: 16 (matches MultiAgentCoordinator default).\n */\n maxConcurrent?: number | undefined;\n /**\n * Multiplicative decrease factor when a 429 is hit.\n * `newConcurrency = floor(currentConcurrency * decreaseFactor)`.\n * Default: 0.5 (halves concurrency).\n */\n decreaseFactor?: number | undefined;\n /**\n * Number of consecutive successful requests before increasing concurrency by 1.\n * Default: 10.\n */\n successThreshold?: number | undefined;\n /**\n * How often (ms) to check for recovery and bump concurrency.\n * Default: 30_000 (30 seconds).\n */\n recoveryIntervalMs?: number | undefined;\n}\n\nexport interface ToolsConfig {\n defaultExecutionStrategy: 'parallel' | 'sequential' | 'smart';\n maxIterations: number;\n iterationTimeoutMs: number;\n /** Hard upper bound for a single tool call timeout. Defaults to 5 minutes. */\n maxToolTimeoutMs?: number | undefined;\n sessionTimeoutMs: number;\n perIterationOutputCapBytes: number;\n /**\n * Per-tool prose budget for the tool's top-level description and usage hint.\n * Missing entries default to \"extend\".\n */\n descriptionMode?: ToolDescriptionModeConfig | undefined;\n /**\n * Per-tool on-screen result rendering mode (terminal / WebUI / TUI).\n * Missing entries default to \"extend\". Independent of `descriptionMode`:\n * `/tool <name> result simple` toggles this without touching the\n * LLM-side description length.\n */\n resultRenderMode?: ToolResultRenderModeConfig | undefined;\n /**\n * Tool names to disable. Disabled tools are excluded from the tool registry\n * (`ToolRegistry.list()` / `get()`), so they do NOT appear in the system\n * prompt's \"## Tool usage\" block — reducing per-request token consumption.\n * Override per-session with `/tool enable <name>` or re-enable all via\n * `/tool enable-all`.\n */\n disabledTools?: string[] | undefined;\n /**\n * When true (default), the agent automatically extends its iteration\n * limit by 100 when hit. Set to false to require user confirmation.\n */\n autoExtendLimit?: boolean | undefined;\n /**\n * When true, file tools (read/write/edit/grep/glob/install) are confined to\n * the project root and `set_working_dir` may not leave it. Default: false —\n * tools may access paths outside the project root, still subject to each\n * tool's permission tier (writes/edits prompt for confirmation). Toggle via\n * `/settings` (\"Filesystem access\").\n */\n restrictToProjectRoot?: boolean | undefined;\n /**\n * Per-command policy for the `exec` tool's allowlist. The tool ships a\n * curated default allowlist of dev/build commands; this extends or trims it.\n *\n * SECURITY: `allow` EXPANDS what the agent may execute, so it is honored only\n * from TRUSTED config (`~/.wrongstack/config.json`) — the config loader\n * strips `tools.exec.allow` from the untrusted, repo-committed\n * `<project>/.wrongstack/config.json`. `deny` only ever REMOVES commands, so\n * it is honored from any source.\n */\n exec?: ExecToolConfig | undefined;\n}\n\n/** Allow/deny extension of the `exec` tool's built-in command allowlist. */\nexport interface ExecToolConfig {\n /**\n * Extra command names to add to the allowlist (e.g. `[\"make\", \"dotnet\"]`).\n * Trusted sources only — stripped from in-project repo config.\n */\n allow?: string[] | undefined;\n /**\n * Command names to remove from the allowlist. Honored from any source —\n * removing a command can only narrow what runs, so it is always safe.\n */\n deny?: string[] | undefined;\n /**\n * Per-rule bypass for the heuristic danger detector. Each entry is a\n * stable `matchedRule` id (e.g. `rm-recursive`, `git-push-force`); a\n * matched rule whose id is in this list is suppressed.\n *\n * Use case: a project that legitimately runs `rm -rf ./build` on every\n * CI run can add `\"rm-recursive\"` to bypass so the detector stops\n * emitting banners for that one rule — without disabling it for every\n * other `rm -rf` invocation.\n *\n * **Trusted sources only.** Bypassing a danger rule means the user\n * agreed to a specific destructive pattern; in-project repo config\n * could otherwise be used to silently opt everyone in. The boot path\n * strips this field from `<project>/.wrongstack/config.json` the\n * same way it strips `allow`.\n */\n danger?: ExecDangerConfig | undefined;\n}\n\nexport interface ExecDangerConfig {\n /**\n * List of danger rule ids to skip. Each id corresponds to a rule in\n * `@wrongstack/tools/src/_danger-detect.ts` (e.g. `rm-recursive`,\n * `git-push-force`, `inline-eval`, `sudo`). Unknown ids are ignored\n * (forward-compat: a rule added in a future version can be referenced\n * before the user upgrades).\n */\n bypass?: string[] | undefined;\n}\n\nexport type ToolDescriptionMode = 'extend' | 'simple';\nexport type ToolDescriptionModeConfig = Record<string, ToolDescriptionMode | undefined>;\n\n/**\n * Per-tool on-screen result rendering mode. Independent of\n * {@link ToolDescriptionMode}: `descriptionMode` controls the prose the\n * model sees in the system prompt, `resultRenderMode` controls how the\n * tool's RESULT is printed to the user (terminal / WebUI / TUI).\n *\n * - `simple` — meta only (filename, line count, exit code). Body is hidden\n * by default; the user can still expand on demand where the renderer\n * supports it.\n * - `extend` — full preview, up to 10 lines for read-like tools.\n *\n * The two modes are toggled independently via `/tool <name> desc simple`\n * and `/tool <name> result simple`. The legacy `/tool <name> simple`\n * command sets BOTH at once for backward compatibility.\n */\nexport type ToolResultRenderMode = 'extend' | 'simple';\nexport type ToolResultRenderModeConfig = Record<string, ToolResultRenderMode | undefined>;\n\nexport interface ProviderApiKey {\n /** Short human-readable label (e.g. \"personal\", \"work\", \"rate-limit-backup\"). */\n label: string;\n /**\n * The key itself. The field name contains `apiKey` so the secret-vault\n * walker will encrypt it on write and decrypt it on read.\n */\n apiKey: string;\n /** ISO-8601 timestamp the key was added. */\n createdAt: string;\n /**\n * How this credential was obtained.\n * - `api_key` — manually pasted API key (default)\n * - `oauth` — OAuth 2.0 device-code / authorization-code flow\n * - `session_token` — extracted from browser session (ChatGPT web, etc.)\n */\n authMethod?: 'api_key' | 'oauth' | 'session_token' | undefined;\n /** ISO-8601 expiry. When set, the token manager will refresh before this time. */\n expiresAt?: string | undefined;\n /**\n * OAuth refresh token. Stored encrypted by the secret-vault walker because\n * the field name contains `Token` (case-insensitive match by vault).\n */\n refreshToken?: string | undefined;\n /** Token type as returned by the OAuth endpoint (e.g. \"bearer\"). */\n tokenType?: string | undefined;\n /** OAuth scope string (e.g. \"openai.models.read openai.models.use\"). */\n scope?: string | undefined;\n /**\n * ChatGPT account id, extracted from the OAuth access-token JWT\n * (`https://api.openai.com/auth`.chatgpt_account_id). Sent as the\n * `chatgpt-account-id` header by the `openai-codex` wire family. Cached\n * here for display/diagnostics; the provider re-derives it from the live\n * token at request time so it can never go stale after a refresh.\n */\n accountId?: string | undefined;\n}\n\nexport interface ProviderConfig {\n type: string;\n /**\n * Legacy single-key field. Still honored as a read fallback when `apiKeys`\n * is empty (for configs not yet migrated to multi-key format). After key\n * management operations (`writeKeysBack`), this field is **cleared** to\n * prevent accidental serialization of the plaintext key. Consumers that\n * need the active API key should use `resolveActiveApiKey()` (cli) or\n * resolve from `apiKeys[]` directly — never read `cfg.apiKey` in new code.\n */\n apiKey?: string | undefined;\n /** Multiple keys for the same provider — pick one with `activeKey`. */\n apiKeys?: ProviderApiKey[] | undefined;\n /** Label of the entry in `apiKeys` to use. Defaults to the first one. */\n activeKey?: string | undefined;\n baseUrl?: string | undefined;\n headers?: Record<string, string>;\n model?: string | undefined;\n quirks?: Record<string, unknown>;\n capabilities?: Record<string, unknown>;\n /**\n * Optional wire-family override. When present, the provider can be\n * constructed without consulting the models.dev catalog — useful for\n * self-hosted endpoints, internal proxies, or for working offline.\n */\n family?: WireFamily | undefined;\n /** Custom env var names to probe when `apiKey` is missing. */\n envVars?: string[] | undefined;\n /** Optional list of models the user wants visible for this provider. */\n models?: string[] | undefined;\n /**\n * Fetch this provider's model list + per-model capabilities from its\n * `{baseUrl}/models` endpoint at startup and inject them into the catalog.\n * For openai-compatible gateways/proxies (omniroute, LiteLLM, vLLM, …) that\n * expose rich metadata there. Defaults on for presets that set it (omniroute).\n * Discovery is best-effort: a down server or missing key is a no-op.\n */\n autoDiscoverModels?: boolean | undefined;\n /**\n * Provider-relative custom model definitions (maps modelId → definition).\n * Each entry adds/overrides a model for this provider with optional\n * capability overrides. The model id is the key, not a fully qualified id.\n */\n customModels?: Record<string, CustomModelDefinition>;\n /**\n * Per-provider OAuth configuration. When present, `wstack auth login <id>`\n * uses this instead of prompting for a raw API key. Set by the catalog or\n * by the user via `/settings`.\n */\n oauthConfig?:\n | {\n /** OAuth client id registered with the provider. */\n clientId?: string | undefined;\n /** Device authorization endpoint (RFC 8628). */\n deviceCodeEndpoint?: string | undefined;\n /** Token endpoint for code exchange and refresh. */\n tokenEndpoint?: string | undefined;\n /** Authorization server URL shown to the user for opening in browser. */\n authorizationEndpoint?: string | undefined;\n /** Default OAuth scopes to request. */\n scopes?: string[] | undefined;\n }\n | undefined;\n}\n\n/**\n * One entry in the per-task model matrix. Pins a catalog role, a phase, or\n * the `*` default to a specific model (and, optionally, a specific provider).\n * Resolved at subagent-spawn time so e.g. `security-scanner` can run a\n * different model than `documentation` while the leader stays on its own.\n */\nexport interface ModelMatrixEntry {\n /** Provider registry id (e.g. \"anthropic\", \"minimax\", \"zai\"). When omitted,\n * the leader's provider is used with this entry's model. */\n provider?: string | undefined;\n /** Model id to run for the matched role/phase/default. */\n model?: string | undefined;\n /**\n * Runtime request overrides for subagents matched by this entry. This is\n * intentionally scoped to subagents: leader requests keep using top-level\n * `Config.modelRuntime`, while a role/phase can opt into its own reasoning\n * effort, cache TTL, or gated generation parameters.\n */\n modelRuntime?: ModelRuntimeConfig | undefined;\n /**\n * Named fallback profile to use for the matched role/phase/default. When\n * `model` is omitted, the first model in the profile becomes the primary and\n * the remaining entries become that subagent's fallback chain.\n */\n fallbackProfile?: string | undefined;\n}\n\nexport interface MCPServerConfig {\n /** Human-readable description shown in `wstack mcp list`. */\n description?: string | undefined;\n name: string;\n transport: 'stdio' | 'sse' | 'streamable-http';\n command?: string | undefined;\n args?: string[] | undefined;\n env?: Record<string, string>;\n url?: string | undefined;\n headers?: Record<string, string>;\n enabled?: boolean | undefined;\n allowedTools?: string[] | undefined;\n permission?: Permission | undefined;\n startupTimeoutMs?: number | undefined;\n requestTimeoutMs?: number | undefined;\n /**\n * Lazy connect: when true, the server process is NOT spawned at boot. Its\n * tools are registered from a cached manifest (discovered on the first ever\n * connect) and the server only spawns when one of its tools is actually\n * called, then auto-sleeps after an idle period. Default (false/undefined) =\n * eager connect at boot.\n */\n lazy?: boolean | undefined;\n /**\n * Allowlist of environment variable names to forward from the parent process\n * to this MCP server's child process. The values are resolved from\n * `process.env` at spawn time, NOT stored in the config file.\n *\n * Why this exists: WrongStack's `buildChildEnv()` security filter scrubs\n * env vars whose names look like secrets (TOKEN, SECRET, AUTH, KEY, ...)\n * from all child processes — this prevents a compromised MCP server from\n * exfiltrating provider API keys. But most MCP servers (GitHub, Slack,\n * Brave Search, ...) need their own API tokens from the environment.\n * `passthroughEnv` is the explicit bypass: only vars listed here survive\n * the filter, and they go through the `extra` path (unfiltered merge).\n *\n * Built-in presets declare their required env vars here so they work\n * out of the box when the user has the corresponding env vars exported\n * in their shell. Users can also add entries for custom servers.\n *\n * Example: passthroughEnv: ['GITHUB_PERSONAL_ACCESS_TOKEN', 'GITHUB_TOKEN']\n */\n passthroughEnv?: string[] | undefined;\n}\n\nexport interface LogConfig {\n level: 'error' | 'warn' | 'info' | 'debug' | 'trace';\n file?: string | undefined;\n}\n\nexport interface PluginConfig {\n name: string;\n enabled?: boolean | undefined;\n options?: Record<string, unknown>;\n}\n\n/**\n * Optional subsystems that the CLI can boot without. The core flow\n * (provider + agent loop + bundled tools + session) always works; these\n * just add capabilities. `--no-features` flips all of these off, which\n * is the minimum viable WrongStack: a single provider, a fixed config,\n * no network calls at startup.\n */\nexport interface FeaturesConfig {\n /** Load MCP servers declared in `mcpServers`. */\n mcp: boolean;\n /** Load + initialise npm plugins declared in `plugins`. */\n plugins: boolean;\n /** Register `remember` / `forget` tools backed by memory store. */\n memory: boolean;\n /**\n * Automatically consolidate session learnings into long-term memory\n * after each completed run. The agent extracts key facts, conventions,\n * and decisions via a lightweight LLM call and persists them.\n * Enabled by default when `memory` is on; set to false to opt out.\n */\n memoryConsolidation?: boolean | undefined;\n /** Fetch the models.dev catalog at startup. When false, the provider\n * must declare its `family` explicitly in `providers[<id>]`. */\n modelsRegistry: boolean;\n /** Discover + load skills from disk. */\n skills: boolean;\n /**\n * Enable the prompt library (`/prompt`, `/prompts`, `/prompt-gen`, the WebUI\n * modal and the bundled 168-prompt dataset). Defaults to on; set to false to\n * disable the subsystem entirely (the loader is withheld so every surface\n * reports it unavailable).\n */\n prompts?: boolean | undefined;\n /**\n * Token-saving mode tier. Controls how aggressively the system prompt\n * is compacted to reduce per-request token consumption.\n *\n * - 'off' — Full prompt, all tools, complete guidance\n * - 'minimal' — TIER1 tools only, stripped guidance (~3-4k tokens saved)\n * - 'light' — Core + memory tools, common patterns, minimal guidance\n * - 'medium' — Most development tools, some guidance\n * - 'aggressive' — Maximum savings before tools become unusable (~4-5k tokens)\n *\n * Boolean values are accepted for backward compatibility:\n * - `true` → 'medium'\n * - `false` → 'off'\n *\n * Enable via CLI: `--token-saving-tier <level>` or `--token-saving-mode` (maps to 'medium').\n * Configure via: `features.tokenSavingMode: \"minimal\"` in config.\n */\n tokenSavingMode?: TokenSavingTier | boolean | undefined;\n /**\n * Enable the autonomous-coordination toolkit (AutonomousCoordinator +\n * KnowledgeGraph + ConsensusProtocol + TaskAuctioneer + ChangeManager +\n * TaskDAG). When true (the default), the TUI boot wires the coordinator\n * lazily on the first Director spawn. When false, the coordinator is\n * never constructed and the `/coordinator` slash command reports it\n * unavailable — reducing the coordination domain's runtime surface for\n * users who only use the simpler Director/Fleet path.\n */\n autonomousCoordination?: boolean | undefined;\n /**\n * Allow tools to read/write paths outside the project root directory.\n * When true (default), tools can access any path on the filesystem.\n * When false, tools are restricted to the project root directory.\n */\n allowOutsideProjectRoot?: boolean | undefined;\n /**\n * Auto-bootstrap the mailbox HTTP bridge from any WrongStack surface\n * (REPL/TUI/WebUI/eternal). When 'auto' (the default), the first\n * surface to come up for a given project joins or spawns the bridge\n * so external agents can connect without the user running\n * `wstack mailbox serve` themselves. 'off' disables this — operators\n * must start the bridge explicitly (e.g. via the `/mailbox-serve`\n * slash command or the standalone `wstack mailbox serve` subcommand).\n * The per-project lock + token-persistence model means a second\n * surface on the same project joins the first's bridge rather than\n * spawning a duplicate.\n */\n mailboxBridge?: 'auto' | 'off' | undefined;\n}\n\nexport interface AutonomyConfig {\n /** Default autonomy mode at startup. Default: \"off\". */\n defaultMode?: 'off' | 'suggest' | 'auto' | undefined;\n /** ms to wait before auto-proceeding in 'auto' mode. Default: 45000. */\n autoProceedDelayMs?: number | undefined;\n /** Maximum consecutive auto-proceed turns before pausing. 0 = unlimited. Default: 50. */\n autoProceedMaxIterations?: number | undefined;\n /** Template used for YOLO+auto suggestions. Must include {{suggestion}}. */\n autonomyNextPrompt?: string | undefined;\n /** Animate the terminal/window title while the agent is active. Default: true. */\n terminalTitleAnimation?: boolean | undefined;\n /** Persisted YOLO preference mirrored into top-level config.yolo at runtime. Default: false. */\n yolo?: boolean | undefined;\n /** Stream fleet/subagent output into the main TUI chat. Default: true. */\n streamFleet?: boolean | undefined;\n /** Ring terminal bell when an agent run completes. Default: false. */\n chime?: boolean | undefined;\n /** Ask for confirmation before interrupt/exit. Default: true. */\n confirmExit?: boolean | undefined;\n /** Terminal mouse tracking preference. Default: false. */\n mouseMode?: boolean | undefined;\n /** Enable prompt refinement before sending. Default: true. */\n enhance?: boolean | undefined;\n /** Prompt-refinement preview countdown in ms. Default: 60000. */\n enhanceDelayMs?: number | undefined;\n /** Prompt-refinement language mode. Default: \"original\". */\n enhanceLanguage?: 'original' | 'english' | undefined;\n /** TUI statusline density. Default: \"detailed\". */\n statuslineMode?: 'minimum' | 'detailed' | undefined;\n /** Single short word shown in the TUI rainbow working-state chip. Default: \"thinking\". */\n thinkingWord?: string | undefined;\n /**\n * Persist the TUI prompt input history to disk per project so Up/Down\n * navigation recalls prompts across sessions. Secrets are scrubbed before\n * they reach disk. Default: enabled, 100 entries.\n */\n inputHistory?: InputHistoryConfig | undefined;\n}\n\n/**\n * Per-project TUI input history persistence options. Lives under\n * `config.autonomy.inputHistory` because the TUI-specific knobs on Config\n * are grouped there.\n */\nexport interface InputHistoryConfig {\n /** Persist history to ~/.wrongstack/projects/<slug>/input-history.json. Default: true. */\n enabled?: boolean | undefined;\n /** Max entries kept on disk (and in memory). Default: 100. */\n maxEntries?: number | undefined;\n}\n\n/**\n * Automatic codebase symbol-index maintenance. Keeps the `codebase-search`\n * index (SQLite, `~/.wrongstack/projects/<hash>/codebase-index/index.db`) fresh\n * without the user having to call `codebase-index` by hand.\n */\nexport interface IndexingConfig {\n /** Run a blocking incremental index at session start (with a visible summary). Default: true. */\n onSessionStart: boolean;\n /** Reindex files the agent writes/edits via tools, in the background. Default: true. */\n onEdit: boolean;\n /** Watch the project root for external editor changes and reindex them. Default: true. */\n watchExternal: boolean;\n /** Debounce window (ms) coalescing rapid edits to the same file. Default: 400. */\n debounceMs: number;\n /**\n * Watchdog timeout (ms) for a full index run. A run exceeding this is\n * aborted (so it can never wedge the indexing mutex or freeze the terminal)\n * and counts toward the indexing circuit breaker. Default: 120000.\n */\n indexTimeoutMs?: number | undefined;\n}\n\n/**\n * Saved launch preferences — restored on next boot so the pre-launch prompt\n * can offer a one-line \"Continue with last settings? [Y/n]\" instead of\n * re-asking every question from scratch.\n */\nexport interface LaunchConfig {\n /** Interactive mode: 'tui' (Ink TUI) or 'repl' (readline REPL). */\n mode?: 'tui' | 'repl' | undefined;\n /** Start with Director mode on (fleet manifest + multi-agent orchestration). */\n director?: boolean | undefined;\n /**\n * Launch-time autonomy mode (binary choice from pre-launch prompt).\n * 'off' = stops after each turn; 'auto' = self-driving.\n * Distinct from `AutonomyConfig.defaultMode` which also supports 'suggest'.\n */\n autonomy?: 'off' | 'auto' | undefined;\n}\n\n/**\n * Controls how much detail is persisted to the per-session JSONL log\n * (`~/.wrongstack/projects/<hash>/sessions/<date>/sess_<ULID>.jsonl`).\n */\nexport interface SessionLoggingConfig {\n /**\n * How much detail to write to the persistent session log.\n *\n * - \"minimal\" → Only events required for resume/rewind/recovery\n * - \"standard\" → (default) + high-value lightweight audit events\n * (compaction, tool timing, retries, errors, etc.)\n * - \"full\" → Also persist full request payloads (very large).\n * Consider enabling a separate replay log instead.\n */\n auditLevel?: 'minimal' | 'standard' | 'full' | undefined;\n\n /**\n * Sampling configuration for high-volume events (especially relevant at\n * `auditLevel: \"full\"`).\n */\n sampling?: {\n /** Controls sampling of `tool_progress` events. */\n toolProgress?: {\n /**\n * Sample rate for noisy progress events (`log`, `partial_output`).\n * - 1 = no sampling (every message is logged)\n * - 8 = default (first message + every 8th)\n */\n sampleRate?: number | undefined;\n };\n };\n}\n\nexport type SyncCategory = 'settings' | 'skills' | 'prompts' | 'memory' | 'history';\n\nexport interface SyncConfig {\n enabled: boolean;\n repo: string;\n /** GitHub token (fine-grained PAT). Encrypted at rest via SecretVault. */\n githubToken: string;\n categories: SyncCategory[];\n lastSyncedAt?: string | undefined;\n}\n\n/**\n * Per-model capability overrides the user can define in their config.\n * Used to add models not in the models.dev catalog, or override catalog\n * facts when the real backend differs (e.g. local Ollama models, proxies).\n */\nexport interface CustomModelDefinition {\n /** Provider this model belongs to. Defaults to the owning ProviderConfig. */\n provider?: string | undefined;\n /** Optional display name. */\n name?: string | undefined;\n /** Capability overrides — only specified fields are overlaid. */\n capabilities?: Partial<Capabilities> | undefined;\n /**\n * Max output tokens. If not specified, the provider family default\n * or catalog entry is used.\n */\n maxOutput?: number | undefined;\n}\n\n/**\n * Skill subsystem configuration. All fields optional; the subsystem itself is\n * gated by `features.skills`. Honored from the user's `~/.wrongstack/config.json`;\n * in the repo-committed in-project config the `extraDirs` field is stripped\n * (arbitrary directories are a prompt-injection vector) — only `readClaudeSkills`\n * and `mode` survive there.\n */\nexport interface SkillsConfig {\n /**\n * Read skills from foreign coding-agent directories (`<project>/.claude/skills`\n * and `~/.claude/skills`). Default `true`. Lets Claude Code / Codex / Gemini /\n * `asm` / `gh skill` skills be used without copying them.\n */\n readClaudeSkills?: boolean | undefined;\n /**\n * Scan OTHER coding agents' skill directories (`~/.codex/skills`,\n * `~/.cursor/skills`, `~/.agents/skills`, `~/.qwen/skills`,\n * `~/.trae/skills`, … + their `<project>/.<tool>/…` equivalents). Default\n * `true` (all known tools); pass a tool-id list to restrict, or `false` to\n * disable. Non-existent dirs are skipped. Unknown ids in the list (likely\n * typos) are dropped and surfaced via a config warning.\n */\n foreignSources?: boolean | string[] | undefined;\n /**\n * How skill bodies reach the system prompt.\n * - `'eager'` (default): inject every discovered skill body into the prompt.\n * - `'progressive'`: inject only the metadata manifest; the agent loads a\n * skill body on demand via the `skill` tool (the agentskills.io model).\n */\n mode?: 'eager' | 'progressive' | undefined;\n /**\n * Extra skill directories to scan (lowest priority, after the `.claude`\n * layers). Honored only from the user config; stripped from in-project config.\n */\n extraDirs?: string[] | undefined;\n /**\n * In eager mode, the maximum total chars of skill bodies injected into the\n * prompt (highest-priority skills first; the rest are listed as a manifest the\n * agent loads via the `skill` tool). Bounds prompt cost when many skills are\n * discovered. Default 24000 (~6k tokens). Set very high to disable. Ignored in\n * progressive mode (which injects only the manifest anyway).\n */\n eagerMaxChars?: number | undefined;\n /**\n * Base URL of the skill registry used by `/skill-search` and\n * `/skill-install <registry>:<id>`. Default `https://skills.sh` (the open\n * marketplace backed by mastra-ai/skills-api). Honored only from the user\n * config; stripped from in-project config (a repo-committed override would be\n * an SSRF / prompt-injection vector — the registry response is parsed into the\n * prompt). Set to a self-hosted skills-api instance to use a private catalog.\n */\n registryUrl?: string | undefined;\n}\n\n/**\n * Fleet peer-awareness + supervision settings. All sub-features are\n * enabled-by-default with conservative throttles; each has its own kill\n * switch. See `FleetSupervisor` (coordination/fleet-supervisor.ts) for the\n * supervisor semantics.\n */\nexport interface FleetConfig {\n /** Periodic \"[FLEET PULSE]\" peer-status digest folded into each agent's context. */\n pulse?:\n | {\n /** Default true. */\n enabled?: boolean | undefined;\n /** Inject at most every N agent iterations. Default 5. */\n everyNIterations?: number | undefined;\n /** Hard cap on digest characters. Default 900. */\n maxChars?: number | undefined;\n /** Max peers listed per digest. Default 15. */\n maxAgents?: number | undefined;\n }\n | undefined;\n /** Broadcast `type:'status'` mails on meaningful subagent transitions. */\n statusBroadcasts?:\n | {\n /** Default true. */\n enabled?: boolean | undefined;\n /** Min interval between broadcasts about the same subagent. Default 15000. */\n minIntervalMsPerAgent?: number | undefined;\n /** Global cap on broadcasts per minute (excess dropped + counted). Default 20. */\n globalPerMinuteCap?: number | undefined;\n }\n | undefined;\n /**\n * Per-subagent git-worktree isolation for Director fleets. The default is\n * `auto`: mutating/build-capable subagents run in isolated checkouts and are\n * squash-merged back on success; read-only review agents usually stay on the\n * shared checkout. Set `enabled:false` or `mode:'off'` when a workflow cannot\n * use worktrees.\n */\n worktrees?:\n | {\n /** Kill switch. Default true. */\n enabled?: boolean | undefined;\n /**\n * `auto` (default): isolate only side-effectful subagents.\n * `required`: side-effectful subagents must get a worktree or fail.\n * `off`: never allocate worktrees.\n */\n mode?: 'auto' | 'required' | 'off' | undefined;\n /**\n * Merge successful task branches back into the base checkout. Default\n * true. When false, successful worktrees are committed and kept for\n * manual `/worktree merge`.\n */\n autoMerge?: boolean | undefined;\n /** Keep failed/timeout worktrees when they contain changes. Default true. */\n keepFailed?: boolean | undefined;\n }\n | undefined;\n /** Brain-gated fleet supervisor (rebalance/steer/spawn-helper). */\n supervisor?: FleetSupervisorConfig | undefined;\n}\n\n/** Config surface for the brain-gated FleetSupervisor. */\nexport interface FleetSupervisorConfig {\n /** Kill switch. Default true (active whenever a Director is running). */\n enabled?: boolean | undefined;\n /** Evaluation tick. Default 20000. */\n intervalMs?: number | undefined;\n /** Per-(signal,subject) re-engagement cooldown. Default 120000. */\n cooldownMs?: number | undefined;\n /** Hard cap on interventions touching one subagent per run. Default 3. */\n maxInterventionsPerSubagent?: number | undefined;\n /** Pending task pinned to a busy worker longer than this → starvation signal. Default 60000. */\n pinnedWaitMs?: number | undefined;\n /** ≥ this many pending tasks pinned to one worker (with an idle sibling) → overload signal. Default 2. */\n overloadPinnedThreshold?: number | undefined;\n /** pending > backlogFactor × live workers (sustained) → spawn-helper signal. Default 2. */\n backlogFactor?: number | undefined;\n /** Running subagent with no tool activity for this long → stuck signal. Default 180000. */\n stuckMs?: number | undefined;\n /** Consecutive failed/timeout results from one subagent → failure-streak signal. Default 2. */\n failureStreak?: number | undefined;\n /** Allow the supervisor to spawn helper subagents. Default true. */\n allowSpawn?: boolean | undefined;\n /** Allow the supervisor to terminate subagents (highest risk). Default false. */\n allowTerminate?: boolean | undefined;\n}\n\nexport interface Config {\n version: 1;\n provider: string;\n model: string;\n apiKey?: string | undefined;\n baseUrl?: string | undefined;\n /**\n * Maximum number of subagent tasks the fleet coordinator dispatches\n * simultaneously. Extra tasks queue until a slot frees. Default: 4.\n * Overridden by WRONGSTACK_MAX_CONCURRENT env var and --max-concurrent\n * CLI flag. Change at runtime with /fleet concurrency <n>.\n */\n maxConcurrent?: number | undefined;\n /**\n * Display language for the UI chrome (WebUI + desktop shell). A BCP-47-ish\n * code from SUPPORTED_LOCALES (en/tr/de/fr/it/es/pt-BR). Persisted here so a\n * change in one surface propagates to all others via the shared machine\n * config; each surface may keep a local cache for instant reactivity. When\n * unset, surfaces fall back to their own browser/system detection.\n */\n uiLocale?: string | undefined;\n providers?: Record<string, ProviderConfig>;\n /**\n * Top-level custom models (maps modelId → definition). Merged with\n * per-provider `customModels` at resolution time. The key is the\n * model id — not a fully qualified name. When the same model id\n * appears in both places, the top-level one wins.\n */\n models?: Record<string, CustomModelDefinition>;\n /**\n * Per-task model matrix. Keys are catalog roles (e.g. \"security-scanner\"),\n * phase names (e.g. \"review\"), or the `*` default. Resolution precedence at\n * subagent spawn: exact role → the role's phase → `*` → leader model. Set via\n * the `/setmodel` slash command; persisted to ~/.wrongstack/config.json.\n */\n modelMatrix?: Record<string, ModelMatrixEntry>;\n /**\n * User-curated model references shown/prioritized by model commands and used\n * by smart fallback derivation. Entries are `model`, `provider/model`, or\n * `provider model`.\n */\n favoriteModels?: string[] | undefined;\n /**\n * When true, auto-derived fallback chains are restricted to `favoriteModels`.\n * Explicit fallback profiles/chains are always honored as written.\n */\n favoriteModelsOnly?: boolean | undefined;\n context: ContextConfig;\n tools: ToolsConfig;\n mcpServers?: Record<string, MCPServerConfig>;\n /**\n * Per-agent ACP invocation overrides, keyed by catalog agent id\n * (`claude-code`, `codex-cli`, `gemini-cli`, …). Lets a user correct an\n * agent's ACP entry command — e.g. point `claude-code` at the right\n * adapter — without a code change. Consumed by `/acp`, `/ensemble`, and\n * `wstack acp`. SECURITY: this is an arbitrary-command exec surface, so it\n * is in the in-project config DENY list — only honoured from the user's\n * `~/.wrongstack/config.json`, never from a repo-committed config.\n */\n acp?: {\n agents?: Record<string, { command: string; args?: string[]; env?: Record<string, string> }>;\n };\n /**\n * Ordered list of fallback model references tried, in order, when the\n * primary model is overloaded (HTTP 429/529/5xx) and its own retries are\n * exhausted. Each entry is a model reference: a bare model id (same\n * provider), `provider/model`, or `provider model`. After a fallback hop,\n * the primary is retried only after its cooldown expires. See\n * `createFallbackModelExtension`.\n */\n fallbackModels?: string[] | undefined;\n /**\n * Named fallback chains. A profile's first entry can be used as a primary\n * model by `/setmodel`, while the whole ordered list is used for failover.\n */\n fallbackProfiles?: Record<string, string[]> | undefined;\n /**\n * When `true` (the default) and `fallbackModels` is empty, a fallback chain\n * is derived automatically from the other keyed providers/models so 429s\n * recover out of the box. Set `false` to disable the smart default and only\n * use an explicit `fallbackModels` list. Toggle via `/fallback auto on|off`.\n */\n fallbackAuto?: boolean | undefined;\n /**\n * Lifecycle shell hooks, keyed by event. Each command receives the hook\n * `HookInput` JSON on stdin; a JSON `HookOutcome` on stdout (and exit code 2\n * = block) steers the agent. In-process hooks are registered separately via\n * the plugin API. Disabled entirely under `--bare` / `--no-hooks`.\n */\n hooks?: Partial<Record<HookEvent, ShellHook[]>>;\n plugins?: (string | PluginConfig)[] | undefined;\n log: LogConfig;\n features: FeaturesConfig;\n /** Skill subsystem options (readClaudeSkills / mode / extraDirs). */\n skills?: SkillsConfig | undefined;\n yolo?: boolean | undefined;\n /** When true, show lightweight LLM-predicted next steps after each turn (/next). */\n nextPrediction?: boolean | undefined;\n cwd?: string | undefined;\n /** Autonomy mode configuration (auto-proceed delay, etc.). */\n autonomy?: AutonomyConfig | undefined;\n /** Show rotating launch hints on startup. Default: true. Set to false to suppress. */\n hints?: boolean | undefined;\n /** Raw SSE stream debugging — hex-dump every byte received from providers to stderr. */\n debugStream?: boolean | undefined;\n /**\n * Where settings are persisted. 'global' → ~/.wrongstack/config.json\n * (default). 'project' → <project>/.wrongstack/config.json.\n * When 'project', safe settings are saved per-project.\n */\n configScope?: 'global' | 'project' | undefined;\n /** Automatic codebase symbol-index maintenance (session-start + live updates). */\n indexing?: IndexingConfig | undefined;\n /**\n * Process circuit-breaker protection (gates `bash`/`exec` on repeated\n * failures). Default off — toggle with `/settings breaker on|off`.\n */\n circuitBreaker?: CircuitBreakerRuntimeConfig | undefined;\n /**\n * Adaptive concurrency controller — automatically adjusts `maxConcurrent` based on\n * rate-limit (429) errors. On 429: decreases concurrency. On sustained success:\n * gradually increases concurrency back up. Default off.\n */\n adaptiveConcurrency?: AdaptiveConcurrencyConfig | undefined;\n /** Saved launch preferences — restored on next boot for one-line confirmation. */\n launch?: LaunchConfig | undefined;\n\n /**\n * Session logging & audit configuration.\n * Controls what gets written to the persistent JSONL transcript.\n */\n session?: SessionLoggingConfig | undefined;\n /**\n * Runtime reasoning / cache controls applied to every provider request\n * (REPL/TUI/WebUI). Mapped into `Request.reasoning` and `Request.cache` by a\n * single request-pipeline middleware, gated by the active model's\n * capabilities. See `ModelRuntimeConfig`.\n */\n modelRuntime?: ModelRuntimeConfig | undefined;\n /** HQ client publishing settings, used by CLI/REPL/TUI/WebUI consistently. */\n hq?: HqClientConfig | undefined;\n /**\n * Fleet awareness + supervision settings (peer-status pulse digests,\n * status-broadcast mails, and the brain-gated FleetSupervisor). SECURITY:\n * in the in-project config DENY list — a repo-committed config must not be\n * able to enable autonomous spawning/steering or mailbox traffic. Only\n * honoured from the user's `~/.wrongstack/config.json`.\n */\n fleet?: FleetConfig | undefined;\n /**\n * Cloud sync configuration. Stored separately in sync.json to avoid\n * accidentally committing the GitHub token to project configs.\n */\n sync?: SyncConfig | undefined;\n /**\n * Per-plugin namespaced config sections. Each plugin reads its own\n * subtree via `ConfigStore.getExtension(pluginName)`. Plugins should\n * declare a `configSchema` so the loader validates this section\n * automatically before `setup()` runs.\n *\n * Example:\n * extensions: {\n * 'wstack-auth': { tokenUrl: 'https://...', refreshBefore: 300 },\n * 'wstack-metrics': { sink: 'prometheus', port: 9090 },\n * }\n */\n extensions?: Record<string, Record<string, unknown>>;\n}\n\nexport interface ConfigLoader {\n load(opts?: {\n cliFlags?: Partial<Config> | undefined;\n cwd?: string | undefined;\n }): Promise<Config>;\n /** Load and decrypt the sync config from ~/.wrongstack/sync.json. */\n loadSyncConfig(): Promise<SyncConfig | null>;\n /** Persist sync config to ~/.wrongstack/sync.json with encrypted token. */\n persistSyncConfig(cfg: SyncConfig): Promise<void>;\n}\n\n/**\n * Subscribable view over Config. Plugins and CLI subsystems use this instead\n * of holding a frozen Config reference, so they can react to runtime updates\n * (e.g. `/model` switching the active provider, secrets rotation, dynamic\n * extension reload).\n *\n * The store enforces immutability — `get()` always returns a frozen object.\n * Updates happen through `update(partial)`, which produces a new Config\n * (structurally cloned, then frozen) and notifies watchers.\n */\nexport interface ConfigStore {\n get(): Readonly<Config>;\n /**\n * Get a typed top-level section. Convenience for consumers that only\n * care about one slice (e.g. `tools` or `context`).\n */\n getSection<K extends keyof Config>(key: K): Readonly<Config[K]>;\n /**\n * Return the extension namespace for `pluginName`, or an empty record\n * when none is configured. The returned object is frozen.\n */\n getExtension(pluginName: string): Readonly<Record<string, unknown>>;\n /**\n * Apply a partial update. Returns the new Config. Watchers are notified\n * synchronously after the update completes. Throws if the result fails\n * any registered invariants (currently: version must stay 1).\n */\n update(partial: Partial<Config>): Readonly<Config>;\n /** Subscribe to changes. Returns an unsubscribe function. */\n watch(cb: (next: Readonly<Config>, prev: Readonly<Config>) => void): () => void;\n}\n","/**\n * Shared configuration constants used across execution, storage, CLI, and WebUI.\n * Centralized here to avoid cross-domain import cycles.\n */\n\n/** Default tools config — mirrors values baked into BEHAVIOR_DEFAULTS. */\nexport const DEFAULT_TOOLS_CONFIG = Object.freeze({\n defaultExecutionStrategy: 'smart',\n maxIterations: 100,\n iterationTimeoutMs: 300_000,\n maxToolTimeoutMs: 300_000,\n sessionTimeoutMs: 1_800_000,\n perIterationOutputCapBytes: 100_000,\n descriptionMode: Object.freeze({}) as Record<string, 'extend' | 'simple' | undefined>,\n disabledTools: Object.freeze([]) as readonly string[],\n autoExtendLimit: true,\n restrictToProjectRoot: false,\n});\n\n/** Default context config — mirrors BEHAVIOR_DEFAULTS.context. */\nexport const DEFAULT_CONTEXT_CONFIG = Object.freeze({\n preserveK: 10,\n eliseThreshold: 2000,\n});\n\n/** Default autonomy config — auto-proceed delay etc. */\nexport const DEFAULT_AUTONOMY_CONFIG = Object.freeze({\n autoProceedDelayMs: 45_000,\n});\n\n/**\n * Default process circuit-breaker config. Protection is OFF by default — the\n * breaker only gates `bash`/`exec` once the user opts in via `/settings breaker on`.\n * The auto kill/reset delay is only consulted when protection is enabled.\n */\nexport const DEFAULT_CIRCUIT_BREAKER_CONFIG = Object.freeze({\n enabled: false,\n autoKillResetMs: 60_000,\n});\n\n/** Default session logging / audit configuration. */\nexport const DEFAULT_SESSION_LOGGING_CONFIG = Object.freeze({\n auditLevel: 'standard' as const,\n sampling: {\n toolProgress: {\n sampleRate: 8,\n },\n },\n});\n\n/** Default retention window for local session pruning. */\nexport const DEFAULT_SESSION_PRUNE_DAYS = 30;\n","export type MemoryScope = 'project-agents' | 'project-memory' | 'user-memory';\n\n// ── Memory categories ──────────────────────────────────────────────────\n\nexport type MemoryType = 'fact' | 'decision' | 'convention' | 'preference' | 'reference' | 'anti_pattern';\n\nexport const MEMORY_TYPE_LABELS: Record<MemoryType, string> = {\n fact: 'Fact',\n decision: 'Decision',\n convention: 'Convention',\n preference: 'Preference',\n reference: 'Reference',\n anti_pattern: 'Anti-pattern',\n};\n\nexport type MemoryPriority = 'critical' | 'high' | 'medium' | 'low';\n\nexport interface MemoryEntry {\n scope: MemoryScope;\n text: string;\n ts: string;\n /** Category — helps the agent decide whether to inject or ignore. */\n type?: MemoryType | undefined;\n /** Free-form tags for grouping (e.g. [\"build\", \"pnpm\", \"typescript\"]). */\n tags?: string[] | undefined;\n /** Priority — critical entries are always injected; low may be skipped. */\n priority?: MemoryPriority | undefined;\n /** Session or agent that created this entry. */\n source?: string | undefined;\n /** 0.0–1.0 confidence. Low-confidence entries are injected less often. */\n confidence?: number | undefined;\n /** ISO timestamp of last access (read or injection into context). */\n lastAccessed?: string | undefined;\n}\n\n// ── Memory events — emitted by DefaultMemoryStore so plugins can react ──\n\nexport interface MemoryRememberedPayload {\n scope: MemoryScope;\n text: string;\n ts: string;\n type?: MemoryType | undefined;\n tags?: string[] | undefined;\n priority?: MemoryPriority | undefined;\n}\n\nexport interface MemoryForgottenPayload {\n scope: MemoryScope;\n query: string;\n removed: number;\n}\n\nexport interface MemoryClearedPayload {\n /** Scope that was cleared, or undefined when all scopes were cleared. */\n scope?: MemoryScope | undefined;\n}\n\nexport interface MemoryConsolidatedPayload {\n scope: MemoryScope;\n /** Entries removed by deduplication. */\n removed: number;\n}\n\n// ── Relevance scoring ──────────────────────────────────────────────────\n\n/**\n * Context used to score memory relevance for context injection.\n * Passed by the system prompt builder.\n */\nexport interface MemoryRelevanceContext {\n /** Current user message or task description. */\n currentTask: string;\n /** Active skills in this session (e.g. [\"typescript-strict\", \"git-flow\"]). */\n activeSkills?: string[] | undefined;\n /** Active mode (e.g. \"Teach\", \"Brief\", \"Code Reviewer\"). */\n activeMode?: string | undefined;\n /** Available tools — memories referencing relevant tools score higher. */\n toolNames?: string[] | undefined;\n}\n\nexport interface ScoredEntry extends MemoryEntry {\n score: number;\n matchReason: string;\n}\n\n// ── Store interface ────────────────────────────────────────────────────\n\nexport interface MemoryStore {\n readAll(): Promise<string>;\n read(scope: MemoryScope): Promise<string>;\n remember(text: string, scope?: MemoryScope, metadata?: Omit<Partial<MemoryEntry>, 'scope' | 'text' | 'ts'>): Promise<void>;\n forget(query: string, scope?: MemoryScope): Promise<number>;\n consolidate(scope: MemoryScope): Promise<void>;\n clear(scope?: MemoryScope): Promise<void>;\n /** List entries, newest first. */\n list(scope?: MemoryScope, limit?: number): Promise<MemoryEntry[]>;\n /** Search by content (substring or semantic). */\n search(query: string, scope?: MemoryScope, limit?: number): Promise<MemoryEntry[]>;\n /** Access the backend for advanced queries. */\n getBackend?(): unknown;\n /** Graph-based related memory traversal. */\n findRelated?(text: string, scope?: MemoryScope, limit?: number): Promise<MemoryEntry[]>;\n /**\n * Score and rank memories by relevance to the current context.\n * Returns only entries that meet a relevance threshold.\n */\n scoreRelevant?(ctx: MemoryRelevanceContext, scope?: MemoryScope, limit?: number): Promise<ScoredEntry[]>;\n /**\n * Attach a trace ID to this store so that all subsequent `storage.*`\n * events include it for observability correlation. Mutates the store\n * in place and returns the same instance (convenience chaining).\n */\n withTraceId(traceId: string): MemoryStore;\n}\n","/**\n * Prompt library types — the canonical home for the prompt data model and the\n * loader/registry contracts. Has no internal dependencies so both `storage/`\n * (the writable store) and `execution/` (the layered loader) can import it\n * without creating a cycle.\n */\n\n/** Provenance of a prompt — which layer it came from. */\nexport type PromptSource = 'builtin' | 'user' | 'project' | 'synced';\n\n/**\n * The fourteen first-party categories shipped with the builtin dataset, plus\n * the `uncategorized` sentinel used when migrating legacy v1 entries. Builtin\n * prompts MUST use one of these (enforced by the dataset schema test); user and\n * project prompts may use any free-form string.\n */\nexport const BUILTIN_PROMPT_CATEGORIES = [\n 'coding',\n 'debugging',\n 'refactoring',\n 'testing',\n 'code-review',\n 'architecture',\n 'devops',\n 'documentation',\n 'data-analysis',\n 'writing',\n 'research',\n 'product',\n 'agentic-workflows',\n 'meta-prompting',\n 'uncategorized',\n] as const;\n\nexport type BuiltinPromptCategory = (typeof BUILTIN_PROMPT_CATEGORIES)[number];\n\n/**\n * Human-readable labels for the builtin categories (for UI chips / pickers).\n */\nexport const PROMPT_CATEGORY_LABELS: Record<BuiltinPromptCategory, string> = {\n coding: 'Coding',\n debugging: 'Debugging',\n refactoring: 'Refactoring',\n testing: 'Testing',\n 'code-review': 'Code Review',\n architecture: 'Architecture',\n devops: 'DevOps',\n documentation: 'Documentation',\n 'data-analysis': 'Data Analysis',\n writing: 'Writing',\n research: 'Research',\n product: 'Product',\n 'agentic-workflows': 'Agentic Workflows',\n 'meta-prompting': 'Meta-Prompting',\n uncategorized: 'Uncategorized',\n};\n\n/**\n * A prompt's category. Typed as a free-form string because user/project prompts\n * may invent their own; the builtin dataset is constrained to\n * {@link BUILTIN_PROMPT_CATEGORIES} by its schema.\n */\nexport type PromptCategory = BuiltinPromptCategory | (string & {});\n\nexport function isBuiltinCategory(value: string): value is BuiltinPromptCategory {\n return (BUILTIN_PROMPT_CATEGORIES as readonly string[]).includes(value);\n}\n\n/** A `{{name}}` placeholder declared by a prompt. */\nexport interface PromptVariable {\n /** Placeholder name as it appears between `{{ }}` (case-sensitive). */\n name: string;\n description?: string | undefined;\n default?: string | undefined;\n required?: boolean | undefined;\n /**\n * Closed set of allowed values. When present, surfaces render a dropdown\n * instead of a free text field and a supplied value outside the set is\n * reported as invalid by {@link renderPrompt}.\n */\n enum?: string[] | undefined;\n /**\n * UI hint: the value is expected to span multiple lines (pasted code, a\n * diff, a long passage). Surfaces render a textarea instead of a one-line\n * input. Has no effect on rendering — purely presentational.\n */\n multiline?: boolean | undefined;\n}\n\n/**\n * A reusable prompt. v2 schema. Legacy v1 entries (only `id/title/content/tags/\n * createdAt/updatedAt`) are upgraded lazily on read by `migratePromptEntry`.\n */\nexport interface PromptEntry {\n /** Stable unique handle (ULID for new entries; legacy short hex tolerated). */\n id: string;\n /** kebab-case stable key — the dedup key across layers and registry key. */\n slug: string;\n title: string;\n /** One-line summary shown in lists/pickers. */\n description: string;\n content: string;\n category: PromptCategory;\n /** Secondary facets (free-form). */\n tags: string[];\n source: PromptSource;\n favorite: boolean;\n /** `{{placeholder}}` variables this prompt expects, if any. */\n variables?: PromptVariable[] | undefined;\n author?: string | undefined;\n version?: string | undefined;\n license?: string | undefined;\n /** sha256 of `content` — set for builtin/synced entries for integrity. */\n checksum?: string | undefined;\n /** When a builtin was copy-on-written into the user layer, its origin slug. */\n forkedFrom?: string | undefined;\n createdAt: string;\n updatedAt: string;\n}\n\n/** One category with its prompt count, for picker chips. */\nexport interface PromptCategoryCount {\n id: PromptCategory;\n label: string;\n count: number;\n}\n\nexport interface PromptSearchOptions {\n category?: PromptCategory | undefined;\n /** Max results (default: unbounded). */\n limit?: number | undefined;\n}\n\n/**\n * Read-side contract over the three prompt layers (project > user > builtin),\n * merged and de-duplicated by slug. Mirrors `SkillLoader` in shape.\n */\nexport interface PromptLoader {\n /** All prompts across layers, project/user shadowing builtin by slug. */\n list(): Promise<PromptEntry[]>;\n /** Resolve by slug first, then by id. */\n find(slugOrId: string): Promise<PromptEntry | undefined>;\n /** Ranked search over title/description/content/tags, optional category filter. */\n search(query: string, opts?: PromptSearchOptions): Promise<PromptEntry[]>;\n /** Category counts across all layers, for UI chips. */\n categories(): Promise<PromptCategoryCount[]>;\n /**\n * Persist into the writable (user, or project when `scope:'project'`) layer.\n * Throws if the resolved target is the read-only builtin layer.\n */\n save(entry: PromptEntry, opts?: { scope?: 'user' | 'project' }): Promise<void>;\n /** Delete from a writable layer. Returns false if not found / builtin. */\n delete(slugOrId: string): Promise<boolean>;\n /**\n * Mark/unmark a prompt as favorite. Favoriting a builtin copies it down into\n * the user layer (copy-on-write, `source:'user'`, `forkedFrom:<slug>`).\n */\n setFavorite(slugOrId: string, favorite: boolean): Promise<PromptEntry | undefined>;\n /** Clear the internal cache so the next read re-scans disk. */\n invalidateCache(): void;\n}\n\n/**\n * The packed builtin index (also the shape a remote registry manifest mirrors\n * — see `types/prompt-registry.ts`).\n */\nexport interface PromptManifest {\n datasetVersion: number;\n generatedAt: string;\n count: number;\n categories: PromptCategoryCount[];\n prompts: PromptManifestRef[];\n}\n\nexport interface PromptManifestRef {\n id: string;\n slug: string;\n title: string;\n description: string;\n category: PromptCategory;\n tags: string[];\n checksum: string;\n /** Relative path of the per-prompt file within the dataset. */\n file: string;\n}\n","/**\n * Prompt registry / sync types — the contract for a remote prompt hub\n * (e.g. prompts.wrongstack.com) and the local installed-prompts manifest.\n *\n * The manifest shape intentionally mirrors the bundled dataset's\n * `data/prompts/index.json` (see `PromptManifest` in `types/prompt.ts`): the\n * builtin dataset IS a local registry, so builtin and synced prompts can flow\n * through one validation + diff path. This file defines the format and the\n * structural validator; the actual fetch/download is a deliberately small stub\n * (see `prompts/prompt-installer.ts`) — \"groundwork now, sync later\".\n */\nimport type { PromptCategory } from './prompt.js';\n\nexport interface PromptRegistryRef {\n id: string;\n slug: string;\n title: string;\n description: string;\n category: PromptCategory;\n tags: string[];\n /** sha256 of the prompt content — drives the update diff. */\n checksum: string;\n version?: string | undefined;\n license?: string | undefined;\n /** Optional direct URL to the full prompt JSON. */\n url?: string | undefined;\n}\n\nexport interface PromptRegistryManifest {\n registryVersion: 1;\n /** Where this manifest came from (hub URL or `owner/repo`). */\n source: string;\n generatedAt: string;\n prompts: PromptRegistryRef[];\n}\n\n/** One entry recorded in `~/.wrongstack/installed-prompts.json`. */\nexport interface InstalledPromptEntry {\n slug: string;\n /** The registry/source this prompt was pulled from. */\n source: string;\n /** The ref pinned at install (tag/branch/commit or manifest version). */\n ref: string;\n checksum: string;\n /** True once the prompt body has actually been written locally. */\n synced: boolean;\n installedAt: string;\n}\n\nexport interface PromptManifestData {\n version: 1;\n entries: InstalledPromptEntry[];\n}\n\n/** Result of validating an untrusted manifest. */\nexport type ManifestValidation =\n | { ok: true; manifest: PromptRegistryManifest }\n | { ok: false; errors: string[] };\n\nconst SLUG_RE = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;\nconst CHECKSUM_RE = /^[a-f0-9]{64}$/;\nconst MAX_STR = 4096;\n\n/**\n * Structurally validate an untrusted registry manifest. Treats the manifest as\n * DATA, not instructions: enforces slug charset, checksum format, and field\n * lengths so a malicious hub can't smuggle oversized or malformed entries into\n * the local store. Does NOT fetch prompt bodies.\n */\nexport function validateRegistryManifest(raw: unknown): ManifestValidation {\n const errors: string[] = [];\n if (!raw || typeof raw !== 'object') return { ok: false, errors: ['manifest is not an object'] };\n const m = raw as Record<string, unknown>;\n\n if (m['registryVersion'] !== 1) errors.push('registryVersion must be 1');\n if (typeof m['source'] !== 'string' || !m['source'])\n errors.push('source must be a non-empty string');\n if (typeof m['generatedAt'] !== 'string') errors.push('generatedAt must be a string');\n if (!Array.isArray(m['prompts'])) {\n errors.push('prompts must be an array');\n return { ok: false, errors };\n }\n\n const seen = new Set<string>();\n const refs: PromptRegistryRef[] = [];\n (m['prompts'] as unknown[]).forEach((p, i) => {\n if (!p || typeof p !== 'object') {\n errors.push(`prompts[${i}] is not an object`);\n return;\n }\n const r = p as Record<string, unknown>;\n const slug = r['slug'];\n if (typeof slug !== 'string' || !SLUG_RE.test(slug)) {\n errors.push(`prompts[${i}].slug invalid (must be kebab-case)`);\n return;\n }\n if (seen.has(slug)) {\n errors.push(`prompts[${i}].slug \"${slug}\" duplicated`);\n return;\n }\n seen.add(slug);\n if (typeof r['checksum'] !== 'string' || !CHECKSUM_RE.test(r['checksum'])) {\n errors.push(`prompts[${i}].checksum must be a 64-char sha256 hex`);\n return;\n }\n for (const field of ['id', 'title', 'description', 'category'] as const) {\n const v = r[field];\n if (typeof v !== 'string' || v.length === 0 || v.length > MAX_STR) {\n errors.push(`prompts[${i}].${field} must be a non-empty string under ${MAX_STR} chars`);\n return;\n }\n }\n const tags = Array.isArray(r['tags'])\n ? (r['tags'].filter((t) => typeof t === 'string') as string[])\n : [];\n refs.push({\n id: r['id'] as string,\n slug,\n title: r['title'] as string,\n description: r['description'] as string,\n category: r['category'] as string,\n tags,\n checksum: r['checksum'] as string,\n version: typeof r['version'] === 'string' ? r['version'] : undefined,\n license: typeof r['license'] === 'string' ? r['license'] : undefined,\n url: typeof r['url'] === 'string' ? r['url'] : undefined,\n });\n });\n\n if (errors.length > 0) return { ok: false, errors };\n return {\n ok: true,\n manifest: {\n registryVersion: 1,\n source: m['source'] as string,\n generatedAt: m['generatedAt'] as string,\n prompts: refs,\n },\n };\n}\n\nexport interface RegistryDiff {\n /** Slugs present in the manifest but not locally. */\n added: PromptRegistryRef[];\n /** Slugs present locally but whose checksum differs in the manifest. */\n updated: PromptRegistryRef[];\n /** Slugs present locally and identical in the manifest. */\n unchanged: PromptRegistryRef[];\n}\n\n/**\n * Compute what a pull WOULD change, by slug+checksum, against the prompts the\n * caller already has. Pure — no I/O, no writes.\n */\nexport function diffRegistry(\n local: { slug: string; checksum?: string | undefined }[],\n manifest: PromptRegistryManifest,\n): RegistryDiff {\n const localBySlug = new Map(local.map((e) => [e.slug, e.checksum]));\n const diff: RegistryDiff = { added: [], updated: [], unchanged: [] };\n for (const ref of manifest.prompts) {\n if (!localBySlug.has(ref.slug)) diff.added.push(ref);\n else if (localBySlug.get(ref.slug) !== ref.checksum) diff.updated.push(ref);\n else diff.unchanged.push(ref);\n }\n return diff;\n}\n","/**\n * Design Studio — curated frontend/mobile UI design kits.\n *\n * A \"design kit\" is a self-contained, selectable design direction (an aesthetic\n * + concrete design tokens + per-stack implementation guidance) that the model\n * commits to BEFORE writing UI code. Kits are surfaced progressively: a compact\n * menu is injected when frontend work is detected, and the heavy kit body is\n * only loaded once the model (or user) picks one — keeping per-turn tokens low.\n *\n * This mirrors the skills subsystem (`types/skill.ts` + `execution/skill-loader.ts`)\n * but adds the per-stack body selection and a token snapshot for visual pickers.\n */\n\n/** Target implementation stacks a kit can speak to. */\nexport const DESIGN_STACKS = ['web', 'react-native', 'flutter', 'swiftui', 'compose'] as const;\n\nexport type DesignStack = (typeof DESIGN_STACKS)[number];\n\nexport function isDesignStack(v: string): v is DesignStack {\n return (DESIGN_STACKS as readonly string[]).includes(v);\n}\n\nexport interface DesignKitManifest {\n id: string;\n name: string;\n /** One-line vibe shown in the menu, e.g. \"Restrained, Linear-style minimalism\". */\n aesthetic: string;\n /** Free-form tags for filtering. */\n tags: string[];\n /** Stacks this kit provides guidance for. */\n stacks: DesignStack[];\n /** Whether the kit ships light + dark themes (almost always true). */\n themes: string[];\n /** \"Best for…\" one-liner used in menu + pickers. */\n bestFor: string;\n version?: string | undefined;\n path: string;\n source: 'project' | 'user' | 'bundled';\n}\n\n/** A single theme's concrete token values (OKLCH strings, font names, etc.). */\nexport interface DesignTokenSet {\n [token: string]: string;\n}\n\n/** Parsed `tokens.json` — light + dark token snapshots used by visual pickers. */\nexport interface DesignKitTokens {\n light?: DesignTokenSet | undefined;\n dark?: DesignTokenSet | undefined;\n}\n\n/** Compact menu entry rendered into the request when frontend work is detected. */\nexport interface DesignKitEntry {\n id: string;\n name: string;\n aesthetic: string;\n bestFor: string;\n stacks: DesignStack[];\n source: DesignKitManifest['source'];\n}\n\n/**\n * Live Design Studio state stashed on `ctx.meta.designStudio`. Set by the\n * detection middleware (user intent + frontend file writes); read by the\n * request middleware that injects the menu / active-kit reminder.\n */\nexport interface DesignStudioState {\n /** True once frontend/UI work has been detected this session. */\n active: boolean;\n /** Detected target stack, if any. */\n stack?: DesignStack | undefined;\n /** What triggered activation (for transparency / debugging). */\n signals: string[];\n /** Kit id the model/user committed to, if any. */\n activeKit?: string | undefined;\n /**\n * User color/token overrides applied over the active kit's tokens. Keys are\n * token names (`primary`) applied to both themes, or theme-scoped\n * (`light.bg`/`dark.bg`). See `applyTokenOverrides`.\n */\n overrides?: Record<string, string> | undefined;\n}\n\nexport interface DesignKitLoader {\n list(): Promise<DesignKitManifest[]>;\n /** Structured entries for the compact menu. */\n listEntries(): Promise<DesignKitEntry[]>;\n find(id: string): Promise<DesignKitManifest | undefined>;\n /** Compact, model-facing menu of every available kit. */\n menuText(): Promise<string>;\n /**\n * Full kit body for a given stack. Strips frontmatter and, when `stack` is\n * provided, narrows stack-specific sections to that stack.\n */\n readBody(id: string, stack?: DesignStack | undefined): Promise<string>;\n /** Parsed `tokens.json` for a kit (light/dark snapshots), if present. */\n readTokens(id: string): Promise<DesignKitTokens | undefined>;\n /** The mandatory cross-cutting baseline (responsive / a11y / theming / motion). */\n foundationsText(stack?: DesignStack | undefined): Promise<string>;\n invalidateCache(): void;\n}\n","import { readFileSync, statSync } from 'node:fs';\nimport * as path from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nexport function modePrompt(id: string): string {\n for (const dir of modePromptDirCandidates()) {\n try {\n return readFileSync(path.join(dir, `${id}.md`), 'utf8').trimEnd();\n } catch {\n // try next candidate\n }\n }\n return '';\n}\n\nfunction modePromptDirCandidates(): string[] {\n const here = path.dirname(fileURLToPath(import.meta.url));\n const candidates = [\n path.resolve(here, '../../instructions/modes'),\n path.resolve(here, '../instructions/modes'),\n path.resolve(here, 'instructions/modes'),\n ];\n return candidates.sort((a, b) => Number(!isDirectory(a)) - Number(!isDirectory(b)));\n}\n\nfunction isDirectory(candidate: string): boolean {\n try {\n return statSync(candidate).isDirectory();\n } catch {\n return false;\n }\n}\n","import { modePrompt } from './mode-prompts.js';\nexport interface Mode {\n id: string;\n name: string;\n description: string;\n /** Additional prompt text injected into system prompt when mode is active */\n prompt: string;\n /** Tags for tool_search filtering */\n tags?: string[] | undefined;\n /** Tools that should be prioritized/highlighted when this mode is active */\n toolPreferences?: string[] | undefined;\n /**\n * Skill names that are particularly relevant to this mode. The system\n * prompt builder appends a \"Suggested skills\" note so the model knows\n * which domain knowledge to leverage first. Skill must exist in the\n * loaded skill set to appear.\n */\n suggestedSkills?: string[] | undefined;\n}\n\nexport interface ModeManifest {\n modes: Mode[];\n defaultMode?: string | undefined;\n}\n\nexport interface ModeStore {\n getActiveMode(): Promise<Mode | null>;\n setActiveMode(modeId: string | null): Promise<void>;\n listModes(): Promise<Mode[]>;\n getMode(modeId: string): Promise<Mode | null>;\n}\n\nexport interface ModeConfig {\n directory: string;\n}\n\nexport const DEFAULT_MODES: Mode[] = [\n {\n id: 'default',\n name: 'Default',\n description: 'General-purpose coding assistant',\n prompt: '',\n tags: ['general'],\n },\n {\n id: 'code-reviewer',\n name: 'Code Reviewer',\n description: 'Focus on code quality, best practices, and potential bugs',\n prompt: modePrompt('code-reviewer'),\n tags: ['review', 'quality', 'security'],\n toolPreferences: ['read', 'grep', 'git', 'diff', 'test'],\n suggestedSkills: ['bug-hunter', 'security-scanner', 'typescript-strict', 'testing'],\n },\n {\n id: 'code-auditor',\n name: 'Code Auditor',\n description: 'Security-focused code analysis',\n prompt: modePrompt('code-auditor'),\n tags: ['security', 'audit', 'compliance'],\n toolPreferences: ['grep', 'read', 'audit', 'bash'],\n suggestedSkills: ['security-scanner', 'bug-hunter', 'audit-log'],\n },\n {\n id: 'architect',\n name: 'Software Architect',\n description: 'Design patterns, scalability, and system design',\n prompt: modePrompt('architect'),\n tags: ['architecture', 'design', 'scalability'],\n toolPreferences: ['read', 'glob', 'tree', 'diff'],\n suggestedSkills: ['api-design', 'refactor-planner', 'node-modern', 'docker-deploy'],\n },\n {\n id: 'debugger',\n name: 'Debugger',\n description: 'Root cause analysis and error investigation',\n prompt: modePrompt('debugger'),\n tags: ['debug', 'investigation', 'error-resolution'],\n toolPreferences: ['read', 'grep', 'bash', 'logs', 'test'],\n suggestedSkills: ['bug-hunter', 'audit-log', 'observability'],\n },\n {\n id: 'tester',\n name: 'QA Engineer',\n description: 'Test coverage, edge cases, and quality assurance',\n prompt: modePrompt('tester'),\n tags: ['testing', 'qa', 'quality'],\n toolPreferences: ['read', 'grep', 'test', 'bash'],\n suggestedSkills: ['testing', 'bug-hunter', 'typescript-strict'],\n },\n {\n id: 'devops',\n name: 'DevOps Engineer',\n description: 'Infrastructure, deployment, and operations',\n prompt: modePrompt('devops'),\n tags: ['devops', 'infrastructure', 'operations'],\n toolPreferences: ['read', 'bash', 'grep', 'logs', 'git'],\n suggestedSkills: ['docker-deploy', 'observability', 'security-scanner'],\n },\n {\n id: 'refactorer',\n name: 'Refactorer',\n description: 'Code improvement and modernization',\n prompt: modePrompt('refactorer'),\n tags: ['refactor', 'modernization', 'improvement'],\n toolPreferences: ['read', 'edit', 'test', 'git', 'grep'],\n suggestedSkills: ['refactor-planner', 'typescript-strict', 'node-modern', 'testing'],\n },\n {\n id: 'ui-design',\n name: 'UI Design',\n description: 'Design-first frontend & mobile UI work (Design Studio)',\n prompt: modePrompt('ui-design'),\n tags: ['ui', 'frontend', 'mobile', 'design'],\n toolPreferences: ['design', 'write', 'edit', 'read', 'scaffold'],\n suggestedSkills: ['react-modern'],\n },\n {\n id: 'brief',\n name: 'Brief',\n description: 'Fast, no-nonsense — get to the point',\n prompt: modePrompt('brief'),\n tags: ['fast', 'concise', 'direct'],\n toolPreferences: ['read', 'edit', 'bash'],\n suggestedSkills: [],\n },\n {\n id: 'teach',\n name: 'Teach',\n description: 'Mentor mode — explains why, not just what',\n prompt: modePrompt('teach'),\n tags: ['teaching', 'mentor', 'learning'],\n toolPreferences: ['read', 'edit', 'explain'],\n suggestedSkills: ['prompt-engineering', 'skill-creator', 'node-modern', 'typescript-strict'],\n },\n {\n id: 'research-web',\n name: 'Research Web',\n description: 'Current-data research — search web, verify, inject findings into context',\n prompt: modePrompt('research-web'),\n tags: ['research', 'web', 'current-data', 'up-to-date'],\n toolPreferences: ['search/fetch', 'search/fetch', 'search', 'fetch', 'context_manager'],\n suggestedSkills: ['research-web', 'tech-stack', 'node-modern', 'security-scanner', 'react-modern'],\n },\n];\n","import { expectDefined } from '../utils/expect-defined.js';\nexport type ContextWindowModeId = 'balanced' | 'frugal' | 'deep' | 'archival';\n\nexport type ContextWindowAggressiveOn = 'hard' | 'soft' | 'warn';\n\nexport interface ContextWindowThresholds {\n warn: number;\n soft: number;\n hard: number;\n}\n\nexport interface ContextWindowMode {\n id: ContextWindowModeId;\n name: string;\n description: string;\n thresholds: ContextWindowThresholds;\n aggressiveOn: ContextWindowAggressiveOn;\n preserveK: number;\n eliseThreshold: number;\n targetLoad: number;\n}\n\nexport interface ContextWindowPolicy extends ContextWindowMode {}\n\nexport interface ContextWindowConfigLike {\n mode?: ContextWindowModeId | string | undefined;\n warnThreshold?: number | undefined;\n softThreshold?: number | undefined;\n hardThreshold?: number | undefined;\n preserveK?: number | undefined;\n eliseThreshold?: number | undefined;\n}\n\nexport const DEFAULT_CONTEXT_WINDOW_MODE_ID: ContextWindowModeId = 'balanced';\n\nexport const CONTEXT_WINDOW_MODES: readonly ContextWindowMode[] = Object.freeze([\n {\n id: 'balanced',\n name: 'Balanced',\n description: 'Default rolling compaction: recent work stays verbatim, old tool output is trimmed.',\n thresholds: { warn: 0.6, soft: 0.75, hard: 0.9 },\n aggressiveOn: 'soft',\n preserveK: 10,\n eliseThreshold: 2000,\n targetLoad: 0.65,\n },\n {\n id: 'frugal',\n name: 'Frugal',\n description: 'Token-saver mode: compacts early and keeps a tighter verbatim tail.',\n thresholds: { warn: 0.45, soft: 0.6, hard: 0.75 },\n aggressiveOn: 'warn',\n preserveK: 6,\n eliseThreshold: 700,\n targetLoad: 0.5,\n },\n {\n id: 'deep',\n name: 'Deep',\n description: 'Long-reasoning mode: delays compaction and keeps more recent turns intact.',\n thresholds: { warn: 0.72, soft: 0.86, hard: 0.96 },\n aggressiveOn: 'hard',\n preserveK: 18,\n eliseThreshold: 5000,\n targetLoad: 0.78,\n },\n {\n id: 'archival',\n name: 'Archival',\n description: 'Decision-preserving mode: compacts steadily while keeping summaries prominent.',\n thresholds: { warn: 0.55, soft: 0.7, hard: 0.84 },\n aggressiveOn: 'soft',\n preserveK: 8,\n eliseThreshold: 1200,\n targetLoad: 0.58,\n },\n]);\n\nexport function listContextWindowModes(): ContextWindowMode[] {\n return CONTEXT_WINDOW_MODES.map((m) => ({ ...m, thresholds: { ...m.thresholds } }));\n}\n\nexport function getContextWindowMode(id: string | null | undefined): ContextWindowMode | null {\n if (!id) return null;\n const mode = CONTEXT_WINDOW_MODES.find((m) => m.id === id);\n return mode ? { ...mode, thresholds: { ...mode.thresholds } } : null;\n}\n\nexport function isContextWindowModeId(id: string): id is ContextWindowModeId {\n return CONTEXT_WINDOW_MODES.some((m) => m.id === id);\n}\n\nexport function resolveContextWindowPolicy(\n config: ContextWindowConfigLike = {},\n overrideMode?: string | null | undefined,\n): ContextWindowPolicy {\n const requested = overrideMode ?? config.mode ?? DEFAULT_CONTEXT_WINDOW_MODE_ID;\n const mode = getContextWindowMode(requested) ?? expectDefined(getContextWindowMode(DEFAULT_CONTEXT_WINDOW_MODE_ID));\n\n if (mode.id !== DEFAULT_CONTEXT_WINDOW_MODE_ID) {\n return mode;\n }\n\n return {\n ...mode,\n thresholds: {\n warn: config.warnThreshold ?? mode.thresholds.warn,\n soft: config.softThreshold ?? mode.thresholds.soft,\n hard: config.hardThreshold ?? mode.thresholds.hard,\n },\n preserveK: config.preserveK ?? mode.preserveK,\n eliseThreshold: config.eliseThreshold ?? mode.eliseThreshold,\n };\n}\n\nexport function formatContextWindowModeList(activeId?: string | null): string {\n return CONTEXT_WINDOW_MODES.map((m) => {\n const marker = m.id === activeId ? '*' : ' ';\n return `${marker} ${m.id.padEnd(9)} ${m.name} - ${m.description}`;\n }).join('\\n');\n}\n","export type SpecStatus = 'draft' | 'review' | 'approved' | 'implemented' | 'deprecated';\nexport type SpecSectionType =\n | 'overview'\n | 'requirements'\n | 'architecture'\n | 'api'\n | 'data'\n | 'security'\n | 'acceptance';\n\nexport interface SpecSection {\n type: SpecSectionType;\n title: string;\n content: string;\n level: number;\n children?: SpecSection[] | undefined;\n}\n\nexport interface SpecRequirement {\n id: string;\n type: 'functional' | 'non-functional' | 'security' | 'performance' | 'ux';\n priority: 'critical' | 'high' | 'medium' | 'low';\n description: string;\n acceptanceCriteria: string[];\n blockedBy?: string[] | undefined;\n implements?: string[] | undefined;\n}\n\nexport interface SpecApiEndpoint {\n method: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';\n path: string;\n description: string;\n request?: Record<string, unknown>;\n response?: Record<string, unknown>;\n auth?: boolean | undefined;\n}\n\nexport interface Specification {\n id: string;\n title: string;\n version: string;\n status: SpecStatus;\n overview: string;\n sections: SpecSection[];\n requirements: SpecRequirement[];\n apiEndpoints?: SpecApiEndpoint[] | undefined;\n dependencies?: string[] | undefined;\n createdAt: number;\n updatedAt: number;\n metadata?: Record<string, unknown>;\n}\n\nexport interface SpecAnalysis {\n specId: string;\n completeness: number; // 0-100\n coverage: {\n requirements: number;\n apiEndpoints: number;\n edgeCases: number;\n errorHandling: number;\n };\n gaps: string[];\n risks: { requirement: string; risk: string; severity: 'high' | 'medium' | 'low' }[];\n suggestions: string[];\n}\n\nexport interface SpecValidationResult {\n valid: boolean;\n errors: { path: string; message: string }[];\n warnings: { path: string; message: string }[];\n}\n\nexport interface SpecTemplate {\n id: string;\n name: string;\n description: string;\n sections: Omit<SpecSection, 'content'>[];\n defaultRequirements: Omit<SpecRequirement, 'id' | 'description'>[];\n}\n\nexport const DEFAULT_SPEC_TEMPLATE: SpecTemplate = {\n id: 'default',\n name: 'Default Feature Spec',\n description: 'Standard template for feature specifications',\n sections: [\n { type: 'overview', title: 'Overview', level: 1 },\n { type: 'requirements', title: 'Requirements', level: 1 },\n { type: 'architecture', title: 'Architecture', level: 1 },\n { type: 'api', title: 'API Design', level: 1 },\n { type: 'data', title: 'Data Model', level: 1 },\n { type: 'security', title: 'Security', level: 1 },\n { type: 'acceptance', title: 'Acceptance Criteria', level: 1 },\n ],\n defaultRequirements: [\n { type: 'functional', priority: 'high', acceptanceCriteria: [], blockedBy: [], implements: [] },\n {\n type: 'non-functional',\n priority: 'medium',\n acceptanceCriteria: [],\n blockedBy: [],\n implements: [],\n },\n ],\n};\n","export type TaskStatus = 'pending' | 'in_progress' | 'blocked' | 'failed' | 'review' | 'completed';\nexport type TaskPriority = 'critical' | 'high' | 'medium' | 'low';\nexport type TaskType = 'feature' | 'bugfix' | 'refactor' | 'docs' | 'test' | 'chore';\n\nexport interface TaskNode {\n id: string;\n title: string;\n description: string;\n type: TaskType;\n priority: TaskPriority;\n status: TaskStatus;\n assignee?: string | undefined;\n estimateHours?: number | undefined;\n actualHours?: number | undefined;\n tags?: string[] | undefined;\n specRequirementId?: string | undefined;\n parentId?: string | undefined;\n children?: string[] | undefined;\n createdAt: number;\n updatedAt: number;\n startedAt?: number | undefined; // set when status → in_progress\n completedAt?: number | undefined;\n metadata?: Record<string, unknown>;\n}\n\nexport interface TaskEdge {\n id: string;\n from: string;\n to: string;\n type: 'blocks' | 'depends_on' | 'relates_to' | 'implements';\n weight?: number | undefined;\n}\n\nexport interface TaskGraph {\n id: string;\n specId: string;\n title: string;\n nodes: Map<string, TaskNode>;\n edges: TaskEdge[];\n rootNodes: string[];\n createdAt: number;\n updatedAt: number;\n}\n\nexport interface TaskDependency {\n taskId: string;\n blockedBy: string[];\n blocking: string[];\n}\n\nexport interface TaskAssignment {\n taskId: string;\n assignee: string;\n assignedAt: number;\n}\n\nexport interface TaskProgress {\n total: number;\n pending: number;\n inProgress: number;\n blocked: number;\n failed: number;\n review: number;\n completed: number;\n percentComplete: number;\n estimatedHours: number;\n actualHours: number;\n}\n\nexport interface TaskFilter {\n status?: TaskStatus[] | undefined;\n priority?: TaskPriority[] | undefined;\n type?: TaskType[] | undefined;\n assignee?: string[] | undefined;\n tags?: string[] | undefined;\n specRequirementId?: string | undefined;\n}\n\nexport interface TaskSort {\n field: 'priority' | 'createdAt' | 'updatedAt' | 'status';\n direction: 'asc' | 'desc';\n}\n\nexport interface CriticalPathResult {\n taskIds: string[];\n totalEstimateHours: number;\n bottleneckTasks: string[];\n}\n\nexport function computeTaskProgress(graph: TaskGraph): TaskProgress {\n let completed = 0;\n let pending = 0;\n let inProgress = 0;\n let blocked = 0;\n let failed = 0;\n let review = 0;\n let estimatedHours = 0;\n let actualHours = 0;\n for (const n of graph.nodes.values()) {\n switch (n.status) {\n case 'completed':\n completed++;\n break;\n case 'pending':\n pending++;\n break;\n case 'in_progress':\n inProgress++;\n break;\n case 'blocked':\n blocked++;\n break;\n case 'failed':\n failed++;\n break;\n case 'review':\n review++;\n break;\n }\n estimatedHours += n.estimateHours ?? 0;\n actualHours += n.actualHours ?? 0;\n }\n const total = graph.nodes.size;\n\n return {\n total,\n pending,\n inProgress,\n blocked,\n failed,\n review,\n completed,\n percentComplete: total > 0 ? Math.round((completed / total) * 100) : 0,\n estimatedHours,\n actualHours,\n };\n}\n\nexport function findCriticalPath(graph: TaskGraph): CriticalPathResult {\n const nodes = Array.from(graph.nodes.values());\n const criticalNodes = nodes.filter((n) => n.priority === 'critical');\n const bottleneckTasks = criticalNodes\n .filter((n) => graph.edges.some((e) => e.to === n.id && e.type === 'depends_on'))\n .map((n) => n.id);\n\n const totalEstimateHours = criticalNodes.reduce((sum, n) => sum + (n.estimateHours ?? 0), 0);\n\n return {\n taskIds: criticalNodes.map((n) => n.id),\n totalEstimateHours,\n bottleneckTasks,\n };\n}\n\nexport function topologicalSort(graph: TaskGraph): string[] {\n const visited = new Set<string>();\n const inStack = new Set<string>();\n const result: string[] = [];\n\n function visit(id: string): void {\n // Cycle: callers must detect cycles up-front if they care; we just stop recursing.\n if (inStack.has(id)) return;\n if (visited.has(id)) return;\n if (!graph.nodes.has(id)) return;\n\n visited.add(id);\n inStack.add(id);\n\n for (const edge of graph.edges) {\n if (edge.from === id) visit(edge.to);\n }\n\n inStack.delete(id);\n result.push(id);\n }\n\n for (const rootId of graph.rootNodes) {\n visit(rootId);\n }\n\n return result;\n}\n\nexport type SerializableTaskGraphNodes =\n | TaskNode[]\n | Array<[string, TaskNode]>\n | Record<string, TaskNode>;\n\nexport type SerializableTaskGraph = Omit<TaskGraph, 'nodes'> & {\n nodes: SerializableTaskGraphNodes;\n};\n\nexport type SerializedTaskGraph = Omit<TaskGraph, 'nodes'> & {\n nodes: TaskNode[];\n};\n\nexport function serializeTaskGraph(graph: TaskGraph): SerializedTaskGraph {\n return {\n ...graph,\n nodes: Array.from(graph.nodes.values()),\n };\n}\n\nexport function deserializeTaskGraph(input: SerializableTaskGraph): TaskGraph {\n const nodes = new Map<string, TaskNode>();\n if (Array.isArray(input.nodes)) {\n for (const entry of input.nodes) {\n if (Array.isArray(entry)) nodes.set(entry[0], { ...entry[1], id: entry[1].id || entry[0] });\n else nodes.set(entry.id, entry);\n }\n } else {\n for (const [id, node] of Object.entries(input.nodes)) {\n nodes.set(id, { ...node, id: node.id || id });\n }\n }\n return { ...input, nodes };\n}\n","import * as fs from 'node:fs/promises';\nimport { expectDefined } from '../utils/expect-defined.js';\nimport type { ContentBlock } from '../types/blocks.js';\nimport type {\n DefaultSessionReaderOptions,\n SessionExportOptions,\n SessionQuery,\n SessionReader,\n SessionSearchHit,\n SessionSearchQuery,\n SessionSummaryLite,\n} from '../types/session-reader.js';\nimport { compileUserRegex } from '../utils/regex-guard.js';\nimport { sessionScopedPath } from '../utils/session-scoped-path.js';\nimport type { SessionData, SessionEvent, SessionMetadata, SessionStore } from '../types/session.js';\n\n/**\n * L2-A: read-only view over a `SessionStore` with query, replay, search,\n * and export helpers. Implemented on top of the public `SessionStore`\n * surface so any concrete store can be inspected without re-implementation.\n */\nexport class DefaultSessionReader implements SessionReader {\n private readonly store: SessionStore;\n private readonly eventCache = new Map<string, SessionData>();\n private readonly eventCacheMtimes = new Map<string, number>();\n private static readonly EVENT_CACHE_MAX_ENTRIES = 32;\n\n constructor(opts: DefaultSessionReaderOptions) {\n this.store = opts.store;\n }\n\n private async loadCachedSessionData(sessionId: string): Promise<SessionData> {\n const storeWithPath = this.store as SessionStore & {\n dir?: string | undefined;\n clearLoadCache?: ((sessionId?: string | undefined) => void) | undefined;\n };\n const rootDir = storeWithPath.dir;\n if (!rootDir) {\n return await this.store.load(sessionId);\n }\n const sessionPath = sessionScopedPath(rootDir, sessionId, '.jsonl');\n let mtimeMs: number | null = null;\n try {\n const stat = await fs.stat(sessionPath);\n mtimeMs = stat.mtimeMs;\n } catch {\n this.eventCache.delete(sessionId);\n this.eventCacheMtimes.delete(sessionId);\n return await this.store.load(sessionId);\n }\n\n const cachedMtime = this.eventCacheMtimes.get(sessionId);\n const cachedData = this.eventCache.get(sessionId);\n if (cachedData && cachedMtime === mtimeMs) {\n this.eventCache.delete(sessionId);\n this.eventCacheMtimes.delete(sessionId);\n this.eventCache.set(sessionId, cachedData);\n this.eventCacheMtimes.set(sessionId, mtimeMs);\n return cachedData;\n }\n\n const data = await this.store.load(sessionId);\n this.eventCache.delete(sessionId);\n this.eventCacheMtimes.delete(sessionId);\n this.eventCache.set(sessionId, data);\n this.eventCacheMtimes.set(sessionId, mtimeMs);\n while (this.eventCache.size > DefaultSessionReader.EVENT_CACHE_MAX_ENTRIES) {\n const oldest = this.eventCache.keys().next().value;\n if (oldest === undefined) break;\n this.eventCache.delete(oldest);\n this.eventCacheMtimes.delete(oldest);\n }\n\n if (data.metadata.endedAt) {\n storeWithPath.clearLoadCache?.(sessionId);\n }\n\n return data;\n }\n\n async query(q: SessionQuery = {}): Promise<SessionSummaryLite[]> {\n // Prefer the store's filtered list when available — it pushes the\n // filter into the cached index instead of fetching 1000 + linear scan.\n const storeWithFilter = this.store as SessionStore & {\n listFiltered?: ((criteria: {\n since?: string | undefined;\n until?: string | undefined;\n provider?: string | undefined;\n model?: string | undefined;\n minTokens?: number | undefined;\n titleContains?: string | undefined;\n limit?: number | undefined;\n }) => Promise<import('../types/session.js').SessionSummary[]>) | undefined;\n };\n let raw: import('../types/session.js').SessionSummary[];\n if (typeof storeWithFilter.listFiltered === 'function') {\n raw = await storeWithFilter.listFiltered({\n since: q.since,\n until: q.until,\n provider: q.provider,\n model: q.model,\n minTokens: q.minTokens,\n titleContains: q.titleContains,\n limit: q.limit,\n });\n } else {\n const fetched = await this.store.list(q.limit ? Math.max(q.limit, 100) : 1000);\n const titleNeedle = q.titleContains?.toLowerCase();\n raw = fetched.filter((s) => {\n if (q.since && s.startedAt < q.since) return false;\n if (q.until && s.startedAt > q.until) return false;\n if (q.provider && s.provider !== q.provider) return false;\n if (q.model && s.model !== q.model) return false;\n if (q.minTokens !== undefined && s.tokenTotal < q.minTokens) return false;\n if (titleNeedle && !s.title.toLowerCase().includes(titleNeedle)) return false;\n return true;\n });\n }\n const out: SessionSummaryLite[] = raw.map((s) => ({\n id: s.id,\n title: s.title,\n startedAt: s.startedAt,\n provider: s.provider,\n model: s.model,\n tokenTotal: s.tokenTotal,\n }));\n return q.limit ? out.slice(0, q.limit) : out;\n }\n\n async *replay(sessionId: string): AsyncIterable<SessionEvent> {\n const data = await this.loadCachedSessionData(sessionId);\n for (const e of data.events) yield e;\n }\n\n async search(q: SessionSearchQuery, sessionId?: string | undefined, sessionQuery?: SessionQuery): Promise<SessionSearchHit[]> {\n const limit = q.limit ?? 100;\n const matcher = buildMatcher(q);\n const allowedTypes = q.types ? new Set(q.types) : null;\n\n // Filter sessions BEFORE scanning events — avoids touching the JSONL\n // for sessions that don't match the time/provider/model criteria.\n let ids: string[];\n if (sessionId) {\n ids = [sessionId];\n } else {\n // Prefer the store's filtered list when available — avoids fetching\n // 1000 sessions and linear-filtering in-process.\n const storeWithFilter = this.store as SessionStore & {\n listFiltered?: ((criteria: {\n since?: string | undefined;\n until?: string | undefined;\n provider?: string | undefined;\n model?: string | undefined;\n minTokens?: number | undefined;\n titleContains?: string | undefined;\n limit?: number | undefined;\n }) => Promise<import('../types/session.js').SessionSummary[]>) | undefined;\n };\n let sessions: import('../types/session.js').SessionSummary[];\n if (typeof storeWithFilter.listFiltered === 'function') {\n sessions = await storeWithFilter.listFiltered({\n since: sessionQuery?.since,\n until: sessionQuery?.until,\n provider: sessionQuery?.provider,\n model: sessionQuery?.model,\n minTokens: sessionQuery?.minTokens,\n titleContains: sessionQuery?.titleContains,\n limit: 1000,\n });\n } else {\n sessions = await this.store.list(1000);\n const titleNeedle = sessionQuery?.titleContains?.toLowerCase();\n sessions = sessions.filter((s) => {\n if (sessionQuery?.since && s.startedAt < sessionQuery.since) return false;\n if (sessionQuery?.until && s.startedAt > sessionQuery.until) return false;\n if (sessionQuery?.provider && s.provider !== sessionQuery.provider) return false;\n if (sessionQuery?.model && s.model !== sessionQuery.model) return false;\n if (sessionQuery?.minTokens !== undefined && s.tokenTotal < sessionQuery.minTokens) return false;\n if (titleNeedle && !s.title.toLowerCase().includes(titleNeedle)) return false;\n return true;\n });\n }\n ids = sessions.map((s) => s.id);\n }\n\n const hits: SessionSearchHit[] = [];\n\n // Fast path: when the underlying store supports streaming search,\n // walk each session's JSONL line-by-line and bail out the moment we\n // hit `limit`. This avoids reading + parsing the entire file (which\n // `load()` does) and never reuses `_loadCache`, so concurrent\n // analytics queries don't churn the writer-side cache.\n const streaming = this.store.searchEvents?.bind(this.store);\n if (streaming) {\n for (const id of ids) {\n const matched = await streaming(\n id,\n (ev) => {\n if (allowedTypes && !allowedTypes.has(ev.type)) return false;\n const text = eventText(ev);\n if (text === null) return false;\n return matcher(text) !== null;\n },\n { limit: limit - hits.length },\n );\n for (const m of matched) {\n const text = expectDefined(eventText(m.event));\n const hit = expectDefined(matcher(text));\n hits.push({\n sessionId: id,\n eventIndex: m.eventIndex,\n ts: m.ts,\n type: m.event.type,\n snippet: snippetOf(text, hit.start, hit.end),\n });\n if (hits.length >= limit) return hits;\n }\n }\n return hits;\n }\n\n // Fallback: stores that don't implement streaming. Loads the full\n // event stream per session — necessary for in-memory or non-file\n // stores that don't expose a streaming surface.\n for (const id of ids) {\n let data;\n try {\n data = await this.loadCachedSessionData(id);\n } catch {\n continue;\n }\n for (let i = 0; i < data.events.length; i++) {\n const ev = expectDefined(data.events[i]);\n if (allowedTypes && !allowedTypes.has(ev.type)) continue;\n const text = eventText(ev);\n if (text === null) continue;\n const hit = matcher(text);\n if (!hit) continue;\n hits.push({\n sessionId: id,\n eventIndex: i,\n ts: ev.ts,\n type: ev.type,\n snippet: snippetOf(text, hit.start, hit.end),\n });\n if (hits.length >= limit) return hits;\n }\n }\n return hits;\n }\n\n async export(sessionId: string, opts: SessionExportOptions): Promise<string> {\n const data = await this.loadCachedSessionData(sessionId);\n const includeTools = opts.includeTools ?? true;\n const includeDiagnostics = opts.includeDiagnostics ?? true;\n\n const filtered = data.events.filter((e) => {\n if (\n !includeTools &&\n (e.type === 'tool_use' ||\n e.type === 'tool_result' ||\n e.type === 'tool_call_start' ||\n e.type === 'tool_call_end')\n ) {\n return false;\n }\n if (\n !includeDiagnostics &&\n (e.type === 'error' || e.type === 'compaction' || e.type === 'message_truncated')\n ) {\n return false;\n }\n return true;\n });\n\n if (opts.format === 'json') {\n return JSON.stringify({ metadata: data.metadata, events: filtered }, null, 2);\n }\n if (opts.format === 'text') {\n return renderPlainText(data.metadata, filtered);\n }\n return renderMarkdown(data.metadata, filtered);\n }\n\n async metadata(sessionId: string): Promise<SessionMetadata> {\n const data = await this.loadCachedSessionData(sessionId);\n return data.metadata;\n }\n}\n\nfunction buildMatcher(\n q: SessionSearchQuery,\n): (text: string) => { start: number; end: number } | null {\n const ci = q.caseInsensitive ?? true;\n if (q.regex) {\n const flags = ci ? 'i' : '';\n const compiled = compileUserRegex(q.query, flags);\n if (!compiled.ok) {\n throw new Error(`Invalid search regex \"${q.query}\": ${compiled.reason}`);\n }\n const re = compiled.regex;\n return (text) => {\n const m = re.exec(text);\n return m ? { start: m.index, end: m.index + m[0].length } : null;\n };\n }\n const needle = ci ? q.query.toLowerCase() : q.query;\n return (text) => {\n const hay = ci ? text.toLowerCase() : text;\n const idx = hay.indexOf(needle);\n return idx === -1 ? null : { start: idx, end: idx + needle.length };\n };\n}\n\nfunction eventText(e: SessionEvent): string | null {\n switch (e.type) {\n case 'user_input':\n return contentToString(e.content);\n case 'llm_response':\n return contentToString(e.content);\n case 'tool_use':\n return `${e.name} ${JSON.stringify(e.input)}`;\n case 'tool_result':\n return typeof e.content === 'string' ? e.content : JSON.stringify(e.content);\n case 'error':\n return `${e.phase}: ${e.message}`;\n case 'session_start':\n case 'session_resumed':\n return `${e.model}/${e.provider}`;\n case 'task_created':\n case 'task_completed':\n return e.title;\n case 'task_failed':\n return `${e.title}: ${e.error}`;\n case 'skill_activated':\n case 'skill_deactivated':\n return e.skillName;\n default:\n return null;\n }\n}\n\nfunction contentToString(content: string | ContentBlock[]): string {\n if (typeof content === 'string') return content;\n return content\n .map((b) => {\n switch (b.type) {\n case 'text':\n return b.text;\n case 'tool_use':\n return `[tool_use:${b.name} ${JSON.stringify(b.input)}]`;\n case 'tool_result':\n return typeof b.content === 'string' ? b.content : JSON.stringify(b.content);\n default:\n return '';\n }\n })\n .join('\\n');\n}\n\nconst SNIPPET_RADIUS = 60;\n\nfunction snippetOf(text: string, start: number, end: number): string {\n const from = Math.max(0, start - SNIPPET_RADIUS);\n const to = Math.min(text.length, end + SNIPPET_RADIUS);\n const prefix = from > 0 ? '…' : '';\n const suffix = to < text.length ? '…' : '';\n return prefix + text.slice(from, to).replace(/\\s+/g, ' ').trim() + suffix;\n}\n\nfunction renderMarkdown(meta: SessionMetadata, events: SessionEvent[]): string {\n const lines: string[] = [];\n lines.push(`# Session ${meta.id}`);\n lines.push('');\n if (meta.model || meta.provider) {\n lines.push(`- **Model:** ${meta.provider ?? '?'}/${meta.model ?? '?'}`);\n }\n lines.push(`- **Started:** ${meta.startedAt}`);\n if (meta.endedAt) lines.push(`- **Ended:** ${meta.endedAt}`);\n lines.push('');\n lines.push('---');\n lines.push('');\n for (const e of events) {\n switch (e.type) {\n case 'user_input': {\n lines.push(`## User — ${e.ts}`);\n lines.push('');\n lines.push(contentToString(e.content));\n lines.push('');\n break;\n }\n case 'llm_response': {\n lines.push(`## Assistant — ${e.ts}`);\n lines.push('');\n lines.push(contentToString(e.content));\n if (e.stopReason && e.stopReason !== 'end_turn') {\n lines.push('');\n lines.push(`*stop: ${e.stopReason}*`);\n }\n lines.push('');\n break;\n }\n case 'tool_use': {\n lines.push(`### Tool call: \\`${e.name}\\``);\n lines.push('');\n lines.push('```json');\n lines.push(JSON.stringify(e.input, null, 2));\n lines.push('```');\n lines.push('');\n break;\n }\n case 'tool_result': {\n const body = typeof e.content === 'string' ? e.content : JSON.stringify(e.content, null, 2);\n lines.push(`### Tool result${e.isError ? ' (error)' : ''}`);\n lines.push('');\n lines.push('```');\n lines.push(body);\n lines.push('```');\n lines.push('');\n break;\n }\n case 'error': {\n lines.push(`> **Error** (${e.phase}): ${e.message}`);\n lines.push('');\n break;\n }\n case 'compaction': {\n lines.push(`> **Compaction**: ${e.before} → ${e.after} tokens`);\n lines.push('');\n break;\n }\n default:\n break;\n }\n }\n return lines.join('\\n');\n}\n\nfunction renderPlainText(meta: SessionMetadata, events: SessionEvent[]): string {\n const lines: string[] = [];\n lines.push(\n `Session ${meta.id} — ${meta.provider ?? '?'}/${meta.model ?? '?'} — started ${meta.startedAt}`,\n );\n lines.push(''.padEnd(72, '-'));\n for (const e of events) {\n switch (e.type) {\n case 'user_input':\n lines.push(`[${e.ts}] USER`);\n lines.push(contentToString(e.content));\n lines.push('');\n break;\n case 'llm_response':\n lines.push(`[${e.ts}] ASSISTANT`);\n lines.push(contentToString(e.content));\n lines.push('');\n break;\n case 'tool_use':\n lines.push(`[${e.ts}] TOOL_USE ${e.name} ${JSON.stringify(e.input)}`);\n break;\n case 'tool_result':\n lines.push(\n `[${e.ts}] TOOL_RESULT${e.isError ? ' (error)' : ''} ${\n typeof e.content === 'string' ? e.content : JSON.stringify(e.content)\n }`,\n );\n break;\n case 'error':\n lines.push(`[${e.ts}] ERROR (${e.phase}): ${e.message}`);\n break;\n default:\n break;\n }\n }\n return lines.join('\\n');\n}\n"]}