@cortexkit/opencode-magic-context 0.33.0 → 0.34.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/config/agent-disable.d.ts +22 -0
- package/dist/config/agent-disable.d.ts.map +1 -1
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/project-security.d.ts +7 -0
- package/dist/config/project-security.d.ts.map +1 -1
- package/dist/config/schema/magic-context.d.ts +144 -24
- package/dist/config/schema/magic-context.d.ts.map +1 -1
- package/dist/config/transform-mode.d.ts +2 -0
- package/dist/config/transform-mode.d.ts.map +1 -1
- package/dist/{conflict-warning-hook-bwa99a04.js → conflict-warning-hook-fvpfvt0w.js} +1 -1
- package/dist/{derive-budgets-e9j09sjr.js → derive-budgets-9crp0cvd.js} +1 -1
- package/dist/features/builtin-commands/commands.d.ts +1 -1
- package/dist/features/builtin-commands/commands.d.ts.map +1 -1
- package/dist/features/magic-context/compaction-marker.d.ts +106 -0
- package/dist/features/magic-context/compaction-marker.d.ts.map +1 -1
- package/dist/features/magic-context/compartment-chunk-embedding.d.ts +0 -2
- package/dist/features/magic-context/compartment-chunk-embedding.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/classify.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/evaluate-smart-notes.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/map-memories.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/refresh-primers.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/task-executor.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/task-registry.d.ts +0 -1
- package/dist/features/magic-context/dreamer/task-registry.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/verify.d.ts.map +1 -1
- package/dist/features/magic-context/fail-closed-block.d.ts +10 -0
- package/dist/features/magic-context/fail-closed-block.d.ts.map +1 -1
- package/dist/features/magic-context/git-commits/index.d.ts +2 -2
- package/dist/features/magic-context/git-commits/index.d.ts.map +1 -1
- package/dist/features/magic-context/git-commits/storage-git-commit-embeddings.d.ts +0 -2
- package/dist/features/magic-context/git-commits/storage-git-commit-embeddings.d.ts.map +1 -1
- package/dist/features/magic-context/git-commits/storage-git-commits.d.ts +0 -13
- package/dist/features/magic-context/git-commits/storage-git-commits.d.ts.map +1 -1
- package/dist/features/magic-context/memory/embedding-identity.d.ts.map +1 -1
- package/dist/features/magic-context/memory/embedding-local.d.ts +7 -1
- package/dist/features/magic-context/memory/embedding-local.d.ts.map +1 -1
- package/dist/features/magic-context/memory/embedding.d.ts +1 -2
- package/dist/features/magic-context/memory/embedding.d.ts.map +1 -1
- package/dist/features/magic-context/memory/memory-migration.d.ts +0 -6
- package/dist/features/magic-context/memory/memory-migration.d.ts.map +1 -1
- package/dist/features/magic-context/memory/project-identity.d.ts +2 -6
- package/dist/features/magic-context/memory/project-identity.d.ts.map +1 -1
- package/dist/features/magic-context/memory/storage-memory-embeddings.d.ts +0 -1
- package/dist/features/magic-context/memory/storage-memory-embeddings.d.ts.map +1 -1
- package/dist/features/magic-context/memory/storage-memory.d.ts +1 -6
- package/dist/features/magic-context/memory/storage-memory.d.ts.map +1 -1
- package/dist/features/magic-context/memory/verification-paths.d.ts +0 -1
- package/dist/features/magic-context/memory/verification-paths.d.ts.map +1 -1
- package/dist/features/magic-context/migrations.d.ts.map +1 -1
- package/dist/features/magic-context/mural/compress-cues.d.ts.map +1 -1
- package/dist/features/magic-context/mural/render-mural.d.ts.map +1 -1
- package/dist/features/magic-context/mural/storage-mural.d.ts +0 -1
- package/dist/features/magic-context/mural/storage-mural.d.ts.map +1 -1
- package/dist/features/magic-context/overflow-detection.d.ts +8 -1
- package/dist/features/magic-context/overflow-detection.d.ts.map +1 -1
- package/dist/features/magic-context/project-embedding-registry.d.ts +16 -2
- package/dist/features/magic-context/project-embedding-registry.d.ts.map +1 -1
- package/dist/features/magic-context/scheduler.d.ts.map +1 -1
- package/dist/features/magic-context/schema-fence-probe.d.ts +28 -0
- package/dist/features/magic-context/schema-fence-probe.d.ts.map +1 -0
- package/dist/features/magic-context/sidekick/agent.d.ts.map +1 -1
- package/dist/features/magic-context/smart-notes/capabilities.d.ts +0 -2
- package/dist/features/magic-context/smart-notes/capabilities.d.ts.map +1 -1
- package/dist/features/magic-context/smart-notes/compiler.d.ts +0 -1
- package/dist/features/magic-context/smart-notes/compiler.d.ts.map +1 -1
- package/dist/features/magic-context/smart-notes/types.d.ts +0 -16
- package/dist/features/magic-context/smart-notes/types.d.ts.map +1 -1
- package/dist/features/magic-context/storage-db.d.ts +35 -1
- package/dist/features/magic-context/storage-db.d.ts.map +1 -1
- package/dist/features/magic-context/storage-meta-persisted.d.ts +38 -5
- package/dist/features/magic-context/storage-meta-persisted.d.ts.map +1 -1
- package/dist/features/magic-context/storage-meta.d.ts +1 -1
- package/dist/features/magic-context/storage-meta.d.ts.map +1 -1
- package/dist/features/magic-context/storage.d.ts +1 -1
- package/dist/features/magic-context/storage.d.ts.map +1 -1
- package/dist/features/magic-context/user-memory/review-user-memories.d.ts.map +1 -1
- package/dist/features/magic-context/user-memory/storage-user-memory.d.ts +0 -2
- package/dist/features/magic-context/user-memory/storage-user-memory.d.ts.map +1 -1
- package/dist/hooks/auto-update-checker/types.d.ts +0 -3
- package/dist/hooks/auto-update-checker/types.d.ts.map +1 -1
- package/dist/hooks/magic-context/boundary-execution.d.ts +1 -1
- package/dist/hooks/magic-context/boundary-execution.d.ts.map +1 -1
- package/dist/hooks/magic-context/cache-busting-signals.d.ts +1 -1
- package/dist/hooks/magic-context/cache-busting-signals.d.ts.map +1 -1
- package/dist/hooks/magic-context/channel2-delivery.d.ts.map +1 -1
- package/dist/hooks/magic-context/child-session-spawn.d.ts +26 -0
- package/dist/hooks/magic-context/child-session-spawn.d.ts.map +1 -0
- package/dist/hooks/magic-context/command-handler.d.ts +2 -0
- package/dist/hooks/magic-context/command-handler.d.ts.map +1 -1
- package/dist/hooks/magic-context/compaction-marker-manager.d.ts +49 -0
- package/dist/hooks/magic-context/compaction-marker-manager.d.ts.map +1 -1
- package/dist/hooks/magic-context/compaction-off-transition.d.ts +96 -0
- package/dist/hooks/magic-context/compaction-off-transition.d.ts.map +1 -0
- package/dist/hooks/magic-context/compartment-parser.d.ts +12 -0
- package/dist/hooks/magic-context/compartment-parser.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-runner-historian.d.ts +2 -0
- package/dist/hooks/magic-context/compartment-runner-historian.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-runner-incremental.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-runner-mapping.d.ts +0 -12
- package/dist/hooks/magic-context/compartment-runner-mapping.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-runner-partial-recomp.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-runner-recomp.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-trigger.d.ts +12 -5
- package/dist/hooks/magic-context/compartment-trigger.d.ts.map +1 -1
- package/dist/hooks/magic-context/ctx-reduce-availability.d.ts +47 -1
- package/dist/hooks/magic-context/ctx-reduce-availability.d.ts.map +1 -1
- package/dist/hooks/magic-context/emergency-drop.d.ts +2 -2
- package/dist/hooks/magic-context/event-handler.d.ts +7 -0
- package/dist/hooks/magic-context/event-handler.d.ts.map +1 -1
- package/dist/hooks/magic-context/event-resolvers.d.ts +13 -21
- package/dist/hooks/magic-context/event-resolvers.d.ts.map +1 -1
- package/dist/hooks/magic-context/final-wire-token-estimate.d.ts +2 -0
- package/dist/hooks/magic-context/final-wire-token-estimate.d.ts.map +1 -1
- package/dist/hooks/magic-context/heuristic-cleanup.d.ts +1 -1
- package/dist/hooks/magic-context/historian-prompt.generated.d.ts +1 -1
- package/dist/hooks/magic-context/historian-prompt.generated.d.ts.map +1 -1
- package/dist/hooks/magic-context/hook-handlers.d.ts +1 -0
- package/dist/hooks/magic-context/hook-handlers.d.ts.map +1 -1
- package/dist/hooks/magic-context/hook.d.ts +11 -1
- package/dist/hooks/magic-context/hook.d.ts.map +1 -1
- package/dist/hooks/magic-context/inject-compartments.d.ts +18 -0
- package/dist/hooks/magic-context/inject-compartments.d.ts.map +1 -1
- package/dist/hooks/magic-context/protected-tail-boundary.d.ts.map +1 -1
- package/dist/hooks/magic-context/read-session-db.d.ts.map +1 -1
- package/dist/hooks/magic-context/read-session-true-raw-tokens.d.ts.map +1 -1
- package/dist/hooks/magic-context/rust-mode-transform.d.ts +3 -0
- package/dist/hooks/magic-context/rust-mode-transform.d.ts.map +1 -1
- package/dist/hooks/magic-context/send-session-notification.d.ts +20 -1
- package/dist/hooks/magic-context/send-session-notification.d.ts.map +1 -1
- package/dist/hooks/magic-context/sentinel.d.ts +39 -0
- package/dist/hooks/magic-context/sentinel.d.ts.map +1 -1
- package/dist/hooks/magic-context/tag-messages.d.ts.map +1 -1
- package/dist/hooks/magic-context/tool-drop-target.d.ts +19 -0
- package/dist/hooks/magic-context/tool-drop-target.d.ts.map +1 -1
- package/dist/hooks/magic-context/transform-compartment-phase.d.ts +3 -0
- package/dist/hooks/magic-context/transform-compartment-phase.d.ts.map +1 -1
- package/dist/hooks/magic-context/transform-postprocess-phase.d.ts +30 -0
- package/dist/hooks/magic-context/transform-postprocess-phase.d.ts.map +1 -1
- package/dist/hooks/magic-context/transform.d.ts +27 -0
- package/dist/hooks/magic-context/transform.d.ts.map +1 -1
- package/dist/{index-kxz4tn6m.js → index-56yjaeb2.js} +56 -4
- package/dist/{index-bmkea2dq.js → index-b563sga5.js} +40 -287
- package/dist/{index-y1c9tcm3.js → index-cn960ffd.js} +101 -20
- package/dist/{index-k5y60ymm.js → index-dtas91s5.js} +27 -6
- package/dist/index-fcyvznch.js +279 -0
- package/dist/{index-63dq2g4d.js → index-ry8rh8cv.js} +138 -24
- package/dist/{index-h86twgsp.js → index-s0mdn690.js} +2113 -1067
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1356 -627
- package/dist/plugin/embedding-bootstrap.d.ts.map +1 -1
- package/dist/plugin/hooks/create-session-hooks.d.ts +19 -8
- package/dist/plugin/hooks/create-session-hooks.d.ts.map +1 -1
- package/dist/plugin/messages-transform.d.ts +10 -0
- package/dist/plugin/messages-transform.d.ts.map +1 -1
- package/dist/plugin/rpc-handlers.d.ts +3 -7
- package/dist/plugin/rpc-handlers.d.ts.map +1 -1
- package/dist/plugin/tool-registry.d.ts +8 -0
- package/dist/plugin/tool-registry.d.ts.map +1 -1
- package/dist/{recomp-orchestrator-yh7pepvx.js → recomp-orchestrator-8e82vmvb.js} +6 -5
- package/dist/send-session-notification-6njqewzk.js +20 -0
- package/dist/shared/conflict-detector.d.ts +38 -1
- package/dist/shared/conflict-detector.d.ts.map +1 -1
- package/dist/shared/conflict-fixer.d.ts +18 -1
- package/dist/shared/conflict-fixer.d.ts.map +1 -1
- package/dist/shared/context-limit-provenance.d.ts +3 -0
- package/dist/shared/context-limit-provenance.d.ts.map +1 -0
- package/dist/shared/escalation-bands.d.ts +9 -0
- package/dist/shared/escalation-bands.d.ts.map +1 -0
- package/dist/shared/format-threshold.d.ts +1 -1
- package/dist/shared/models-dev-cache.d.ts +29 -3
- package/dist/shared/models-dev-cache.d.ts.map +1 -1
- package/dist/shared/rpc-server.d.ts.map +1 -1
- package/dist/shared/rpc-types.d.ts +46 -1
- package/dist/shared/rpc-types.d.ts.map +1 -1
- package/dist/shared/sqlite.d.ts +9 -4
- package/dist/shared/sqlite.d.ts.map +1 -1
- package/dist/shared/storage-permissions.d.ts +5 -0
- package/dist/shared/storage-permissions.d.ts.map +1 -0
- package/dist/{storage-meta-session-1phy0b1z.js → storage-meta-session-xt41zbw4.js} +2 -1
- package/dist/{task-config-dn9k9szr.js → task-config-5nx3qfz8.js} +1 -2
- package/dist/tui/compaction-off.d.ts +13 -0
- package/dist/tui/compaction-off.d.ts.map +1 -0
- package/dist/tui/data/context-db.d.ts.map +1 -1
- package/dist/tui-compiled/compaction-off.d.ts +13 -0
- package/dist/tui-compiled/compaction-off.d.ts.map +1 -0
- package/dist/tui-compiled/data/context-db.d.ts.map +1 -1
- package/package.json +8 -3
- package/src/agents/dreamer.ts +68 -0
- package/src/agents/hidden-agent-registrations.ts +331 -0
- package/src/agents/historian.ts +3 -0
- package/src/agents/language-directive.test.ts +138 -0
- package/src/agents/language-directive.ts +121 -0
- package/src/agents/magic-context-prompt.language.test.ts +35 -0
- package/src/agents/magic-context-prompt.test.ts +292 -0
- package/src/agents/magic-context-prompt.ts +182 -0
- package/src/agents/permissions.test.ts +252 -0
- package/src/agents/permissions.ts +186 -0
- package/src/agents/sidekick.ts +1 -0
- package/src/agents/smart-note-compiler.ts +1 -0
- package/src/config/agent-disable.ts +106 -0
- package/src/config/compaction-accessor-guard.test.ts +82 -0
- package/src/config/compaction-backcompat.test.ts +52 -0
- package/src/config/index.test.ts +904 -0
- package/src/config/index.ts +601 -0
- package/src/config/migrate-config-location.test.ts +332 -0
- package/src/config/migrate-config-location.ts +635 -0
- package/src/config/migrate-dreamer-v2.test.ts +287 -0
- package/src/config/migrate-dreamer-v2.ts +336 -0
- package/src/config/migrate-experimental.ts +159 -0
- package/src/config/project-security.test.ts +366 -0
- package/src/config/project-security.ts +588 -0
- package/src/config/prune-config-leaf.test.ts +78 -0
- package/src/config/prune-config-leaf.ts +68 -0
- package/src/config/removed-config-keys.test.ts +116 -0
- package/src/config/schema/agent-overrides.ts +45 -0
- package/src/config/schema/magic-context.test.ts +358 -0
- package/src/config/schema/magic-context.ts +1002 -0
- package/src/config/transform-mode.test.ts +62 -0
- package/src/config/transform-mode.ts +34 -0
- package/src/config/variable.test.ts +323 -0
- package/src/config/variable.ts +192 -0
- package/src/features/magic-context/defaults.ts +1 -0
- package/src/features/magic-context/dreamer/cron.ts +243 -0
- package/src/features/magic-context/dreamer/task-registry.ts +104 -0
- package/src/shared/conflict-detector.test.ts +251 -1
- package/src/shared/conflict-detector.ts +84 -5
- package/src/shared/conflict-fixer.test.ts +309 -0
- package/src/shared/conflict-fixer.ts +82 -5
- package/src/shared/context-limit-provenance.ts +6 -0
- package/src/shared/escalation-bands.test.ts +23 -0
- package/src/shared/escalation-bands.ts +18 -0
- package/src/shared/format-threshold.ts +1 -1
- package/src/shared/models-dev-cache.test.ts +171 -0
- package/src/shared/models-dev-cache.ts +195 -38
- package/src/shared/rpc-server.ts +27 -18
- package/src/shared/rpc-types.ts +46 -1
- package/src/shared/sqlite.ts +13 -33
- package/src/shared/storage-permissions.ts +20 -0
- package/src/tui/compaction-off.test.ts +56 -0
- package/src/tui/compaction-off.ts +29 -0
- package/src/tui/data/context-db.ts +6 -0
- package/src/tui/index.tsx +113 -65
- package/src/tui/slots/sidebar-content.tsx +139 -83
- package/src/tui-compiled/compaction-off.ts +29 -0
- package/src/tui-compiled/data/context-db.ts +6 -0
- package/src/tui-compiled/index.tsx +558 -455
- package/src/tui-compiled/slots/sidebar-content.tsx +237 -161
- package/dist/config/schema.d.ts +0 -3
- package/dist/config/schema.d.ts.map +0 -1
- package/dist/features/magic-context/plugin-messages.d.ts +0 -75
- package/dist/features/magic-context/plugin-messages.d.ts.map +0 -1
- package/dist/hooks/magic-context/compartment-runner-state-xml.d.ts +0 -21
- package/dist/hooks/magic-context/compartment-runner-state-xml.d.ts.map +0 -1
- package/dist/index-anhrfygk.js +0 -57
- package/dist/send-session-notification-tghq9gnh.js +0 -11
- package/dist/shared/opencode-compaction-detector.d.ts +0 -2
- package/dist/shared/opencode-compaction-detector.d.ts.map +0 -1
- package/dist/shared/transcript-opencode.d.ts +0 -71
- package/dist/shared/transcript-opencode.d.ts.map +0 -1
- package/dist/tools/index.d.ts +0 -6
- package/dist/tools/index.d.ts.map +0 -1
- package/src/shared/opencode-compaction-detector.test.ts +0 -239
- package/src/shared/opencode-compaction-detector.ts +0 -81
- package/src/shared/transcript-opencode.ts +0 -302
- /package/dist/{index-v7fmc1s2.js → index-ygcng9t8.js} +0 -0
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { SidebarSnapshot } from "../shared/rpc-types";
|
|
2
|
+
export interface CompactionOffSidebarRow {
|
|
3
|
+
label: "Memories" | "Notes" | "Archived compartments";
|
|
4
|
+
value: string;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Formats context pressure from the current wire input and the model context
|
|
8
|
+
* limit. It deliberately does not use the stored Magic Context threshold
|
|
9
|
+
* percentage, because native compaction acts on the model window instead.
|
|
10
|
+
*/
|
|
11
|
+
export declare function nativeCompactionContextLabel(snapshot: SidebarSnapshot): string;
|
|
12
|
+
export declare function compactionOffSidebarRows(snapshot: SidebarSnapshot): CompactionOffSidebarRow[];
|
|
13
|
+
//# sourceMappingURL=compaction-off.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compaction-off.d.ts","sourceRoot":"","sources":["../../src/tui-compiled/compaction-off.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAE3D,MAAM,WAAW,uBAAuB;IACpC,KAAK,EAAE,UAAU,GAAG,OAAO,GAAG,uBAAuB,CAAC;IACtD,KAAK,EAAE,MAAM,CAAC;CACjB;AAED;;;;GAIG;AACH,wBAAgB,4BAA4B,CAAC,QAAQ,EAAE,eAAe,GAAG,MAAM,CAI9E;AAED,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,eAAe,GAAG,uBAAuB,EAAE,CAU7F"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context-db.d.ts","sourceRoot":"","sources":["../../../src/tui-compiled/data/context-db.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAEzF,YAAY,EAAE,WAAW,EAAE,eAAe,EAAE,YAAY,EAAE,CAAC;AAc3D,2DAA2D;AAC3D,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAOrD;AAED,wBAAgB,gBAAgB,IAAI,MAAM,CAEzC;AAED;sCACsC;AACtC,wBAAgB,YAAY,IAAI,qBAAqB,GAAG,IAAI,CAE3D;AAED,+BAA+B;AAC/B,wBAAgB,QAAQ,IAAI,IAAI,CAM/B;
|
|
1
|
+
{"version":3,"file":"context-db.d.ts","sourceRoot":"","sources":["../../../src/tui-compiled/data/context-db.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAEzF,YAAY,EAAE,WAAW,EAAE,eAAe,EAAE,YAAY,EAAE,CAAC;AAc3D,2DAA2D;AAC3D,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAOrD;AAED,wBAAgB,gBAAgB,IAAI,MAAM,CAEzC;AAED;sCACsC;AACtC,wBAAgB,YAAY,IAAI,qBAAqB,GAAG,IAAI,CAE3D;AAED,+BAA+B;AAC/B,wBAAgB,QAAQ,IAAI,IAAI,CAM/B;AAwFD,sDAAsD;AACtD,wBAAsB,mBAAmB,CACrC,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,GAClB,OAAO,CAAC,eAAe,CAAC,CA8B1B;AAED,wDAAwD;AACxD,wBAAsB,gBAAgB,CAClC,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,QAAQ,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,YAAY,CAAC,CA+CvB;AAYD,gEAAgE;AAChE,wBAAsB,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAchG;AAED,MAAM,MAAM,sBAAsB,GAAG;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAEhG,oFAAoF;AACpF,wBAAsB,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAe5F;AAED,6CAA6C;AAC7C,wBAAsB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAQvE;AAED;mFACmF;AACnF,wBAAsB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAQxE;AAED;;iDAEiD;AACjD,wBAAsB,sBAAsB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAUhF;AAED,gEAAgE;AAChE,wBAAsB,mBAAmB,IAAI,OAAO,CAAC,MAAM,CAAC,CAQ3D;AAED;;;;GAIG;AACH,MAAM,WAAW,oBAAoB;IACjC,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,wBAAsB,eAAe,IAAI,OAAO,CAAC,oBAAoB,CAAC,CAkBrE;AAED,wEAAwE;AACxE,wBAAsB,aAAa,IAAI,OAAO,CAAC,OAAO,CAAC,CAQtD"}
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cortexkit/opencode-magic-context",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.34.0",
|
|
4
4
|
"type": "module",
|
|
5
|
-
"description": "OpenCode plugin for Magic Context
|
|
5
|
+
"description": "OpenCode plugin for Magic Context \u2014 cross-session memory and context management",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"types": "dist/index.d.ts",
|
|
8
8
|
"author": "ualtinok",
|
|
@@ -27,10 +27,15 @@
|
|
|
27
27
|
"src/tui",
|
|
28
28
|
"src/tui-compiled",
|
|
29
29
|
"src/shared",
|
|
30
|
+
"src/config",
|
|
31
|
+
"src/agents",
|
|
32
|
+
"src/features/magic-context/defaults.ts",
|
|
33
|
+
"src/features/magic-context/dreamer/cron.ts",
|
|
34
|
+
"src/features/magic-context/dreamer/task-registry.ts",
|
|
30
35
|
"README.md"
|
|
31
36
|
],
|
|
32
37
|
"scripts": {
|
|
33
|
-
"build": "bun run build:tui && bun build src/index.ts --outdir dist --target node --format esm --splitting --external @opencode-ai/plugin --external @huggingface/transformers --external onnxruntime-web --external bun:sqlite --external node:sqlite && tsc --emitDeclarationOnly",
|
|
38
|
+
"build": "bun run build:tui && rm -f dist/index.js dist/*-*.js && bun build src/index.ts --outdir dist --target node --format esm --splitting --external @opencode-ai/plugin --external @huggingface/transformers --external onnxruntime-web --external bun:sqlite --external node:sqlite && tsc --emitDeclarationOnly",
|
|
34
39
|
"build:tui": "bun scripts/build-tui.ts",
|
|
35
40
|
"check:tui-compiled": "bun run build:tui && git diff --exit-code -- src/tui-compiled && test -z \"$(git status --porcelain -- src/tui-compiled)\"",
|
|
36
41
|
"typecheck": "tsc --noEmit && tsc -p tsconfig.scripts.json",
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
export const DREAMER_AGENT = "dreamer";
|
|
2
|
+
export const DREAMER_RETROSPECTIVE_AGENT = "dreamer-retrospective";
|
|
3
|
+
// Read-only code investigator for the refresh-primers task. Locked to
|
|
4
|
+
// navigation/read/search tools only — NO write/edit/bash/ctx_memory/ctx_note —
|
|
5
|
+
// because it runs an unsupervised, scheduled, weak-model agentic loop. A
|
|
6
|
+
// ctx_memory mutation here would bump the project memory epoch and bust m[0],
|
|
7
|
+
// violating the primers cache-neutral contract; write/bash could corrupt the
|
|
8
|
+
// user's source. Mirrors the dreamer-retrospective lockPermissions pattern.
|
|
9
|
+
export const DREAMER_PRIMER_INVESTIGATOR_AGENT = "dreamer-primer-investigator";
|
|
10
|
+
|
|
11
|
+
// Locked read-only code reader for the memory-maintenance tasks (map-memories,
|
|
12
|
+
// verify, verify-broad). Same source-safety + cache-neutrality lock as the
|
|
13
|
+
// primer investigator (NO write/edit/bash/ctx_memory), but deliberately WITHOUT
|
|
14
|
+
// ctx_search — these tasks check memories against the CURRENT local source, not
|
|
15
|
+
// cross-session recall. The host parses the agent's XML manifest and applies the
|
|
16
|
+
// DB writes itself, so the agent never needs a mutation tool.
|
|
17
|
+
export const DREAMER_MEMORY_MAPPER_AGENT = "dreamer-memory-mapper";
|
|
18
|
+
|
|
19
|
+
/** Read-only tool profile shared by the memory-maintenance reader agent.
|
|
20
|
+
* No ctx_search (local-source checks only), no write/bash/ctx_memory. */
|
|
21
|
+
export const DREAMER_MEMORY_MAPPER_ALLOWED_TOOLS = [
|
|
22
|
+
"read",
|
|
23
|
+
"grep",
|
|
24
|
+
"glob",
|
|
25
|
+
"aft_outline",
|
|
26
|
+
"aft_zoom",
|
|
27
|
+
"aft_search",
|
|
28
|
+
] as const;
|
|
29
|
+
|
|
30
|
+
// Pure-transform classifier for the classify-memories task: prompt in → ONE XML
|
|
31
|
+
// manifest out, ZERO tools. classify scores metadata from the memory text alone
|
|
32
|
+
// (no code inspection), and the host applies the column writes — so the agent
|
|
33
|
+
// needs no tools at all. Locked so a user override can't grant any.
|
|
34
|
+
export const DREAMER_CLASSIFIER_AGENT = "dreamer-classifier";
|
|
35
|
+
|
|
36
|
+
// Docs maintainer for the maintain-docs task: explores the codebase and writes
|
|
37
|
+
// ARCHITECTURE.md / STRUCTURE.md. Needs file read + write/edit + bash (git log,
|
|
38
|
+
// find) + aft navigation, but deliberately NO ctx_memory/ctx_search/ctx_note —
|
|
39
|
+
// it touches docs, never the memory store. Locked so a user override can't add
|
|
40
|
+
// the memory surface back.
|
|
41
|
+
export const DREAMER_DOCS_AGENT = "dreamer-docs";
|
|
42
|
+
|
|
43
|
+
/** Codebase-read + doc-write tool profile for the docs maintainer. No memory
|
|
44
|
+
* tools (it edits docs, not the memory store). */
|
|
45
|
+
export const DREAMER_DOCS_ALLOWED_TOOLS = [
|
|
46
|
+
"read",
|
|
47
|
+
"grep",
|
|
48
|
+
"glob",
|
|
49
|
+
"bash",
|
|
50
|
+
"write",
|
|
51
|
+
"edit",
|
|
52
|
+
"aft_outline",
|
|
53
|
+
"aft_zoom",
|
|
54
|
+
"aft_search",
|
|
55
|
+
] as const;
|
|
56
|
+
|
|
57
|
+
// Pure JSON reviewer for the review-user-memories task: reads the candidate
|
|
58
|
+
// observations the host renders and returns a JSON verdict the host applies. It
|
|
59
|
+
// calls NO tools (zero), so it gets the empty allow-list, locked.
|
|
60
|
+
export const DREAMER_REVIEWER_AGENT = "dreamer-reviewer";
|
|
61
|
+
|
|
62
|
+
/** Tool profile for the base `dreamer` agent, now CURATE-ONLY (memory-pool
|
|
63
|
+
* hygiene). Curate edits the memory store through ctx_memory and never reads
|
|
64
|
+
* code (a separate verify task owns memory-vs-code correctness), so it needs
|
|
65
|
+
* only ctx_memory — not the former bash/write/edit/read/aft/ctx_search/ctx_note
|
|
66
|
+
* kitchen sink. Kept on the `dreamer` id so the ctx_memory dreamer-action gate
|
|
67
|
+
* (toolContext.agent === DREAMER_AGENT) still recognizes it. */
|
|
68
|
+
export const DREAMER_CURATE_ALLOWED_TOOLS = ["ctx_memory"] as const;
|
|
@@ -0,0 +1,331 @@
|
|
|
1
|
+
import { applyDisallowedTools, buildAllowOnlyPermission } from "./permissions";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Hidden-agent registration builders.
|
|
5
|
+
*
|
|
6
|
+
* # Why this lives in its own module (NOT in the plugin entry `index.ts`)
|
|
7
|
+
*
|
|
8
|
+
* OpenCode loads a plugin module and, for the legacy plugin shape (a function
|
|
9
|
+
* `default` export rather than a `{ server, tui }` object), treats EVERY
|
|
10
|
+
* exported function in that module as a plugin factory and invokes it with the
|
|
11
|
+
* plugin input `{ client, directory, ... }` (see opencode
|
|
12
|
+
* `plugin/index.ts` → `getLegacyPlugins`). magic-context uses that legacy shape.
|
|
13
|
+
*
|
|
14
|
+
* If `buildHiddenAgentRegistrations` is exported from the entry module it gets
|
|
15
|
+
* called by the loader as `buildHiddenAgentRegistrations(pluginInput)` — with
|
|
16
|
+
* the wrong argument — so `args.historianDisallowed` is `undefined` and
|
|
17
|
+
* `applyDisallowedTools([...], undefined)` throws
|
|
18
|
+
* `undefined is not an object (evaluating 'disallowed.includes')`, which fails
|
|
19
|
+
* the WHOLE plugin load. Keeping these helpers out of the entry module means the
|
|
20
|
+
* entry module's only export is `default` (the real plugin factory); these
|
|
21
|
+
* builders are still bundled (inlined) into `dist/index.js`, just never treated
|
|
22
|
+
* as plugin factories.
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
// Clamp a user-provided step override to the hidden-agent's built-in cap (loop
|
|
26
|
+
// insurance — see buildHiddenAgentConfig). Caps live as inline literals in
|
|
27
|
+
// buildHiddenAgentRegistrations (historian/sidekick=40, dreamer=150): a handful
|
|
28
|
+
// of tool calls for the historian/sidekick, a real multi-step maintenance loop
|
|
29
|
+
// for the dreamer.
|
|
30
|
+
function clampHiddenAgentStepLimit(value: unknown, cap: number): number {
|
|
31
|
+
return typeof value === "number" && Number.isFinite(value) ? Math.min(value, cap) : cap;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Static registration data for one hidden agent. The id / allow-list / step cap
|
|
36
|
+
* are INLINE LITERALS in {@link buildHiddenAgentRegistrations} rather than
|
|
37
|
+
* cross-module `const` imports.
|
|
38
|
+
*
|
|
39
|
+
* # Why inline
|
|
40
|
+
*
|
|
41
|
+
* Belt-and-suspenders, not the load-bearing fix. The load failure was caused by
|
|
42
|
+
* exporting helpers from the entry module (see the module header) — that is what
|
|
43
|
+
* the entry-only-`default` rule fixes. Inlining the small id/tool/step values
|
|
44
|
+
* additionally removes any dependency on cross-module top-level `const` init
|
|
45
|
+
* timing, so this builder returns a complete, valid registration set the instant
|
|
46
|
+
* it is called regardless of module-evaluation order. Cheap insurance for a path
|
|
47
|
+
* that runs once per plugin-instance boot.
|
|
48
|
+
*
|
|
49
|
+
* The only value that cannot be inlined is the multi-KB generated system prompt;
|
|
50
|
+
* it stays a module `var` and is guarded at the call site (skip the agent + log
|
|
51
|
+
* if undefined, never register a broken/deny-all agent).
|
|
52
|
+
*
|
|
53
|
+
* `agent-registration-drift.test.ts` asserts the inline literals here stay
|
|
54
|
+
* byte-identical to the canonical exported constants so they can't silently
|
|
55
|
+
* diverge.
|
|
56
|
+
*/
|
|
57
|
+
export interface HiddenAgentRegistration {
|
|
58
|
+
id: string;
|
|
59
|
+
prompt: string | undefined;
|
|
60
|
+
allowedTools: readonly string[];
|
|
61
|
+
maxSteps: number;
|
|
62
|
+
overrides?: Record<string, unknown>;
|
|
63
|
+
/** Drop any user `permission` override (privacy-critical agents only). */
|
|
64
|
+
lockPermissions?: boolean;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Hoisted function declaration: returns the four hidden-agent registrations with
|
|
69
|
+
* INLINE id / allow-list / step-cap literals (see {@link HiddenAgentRegistration}
|
|
70
|
+
* for why these must not come from module-level `var` consts). Prompts and
|
|
71
|
+
* computed overrides are passed in by the caller; the historian disallow filter
|
|
72
|
+
* is applied here against an inline default allow-list.
|
|
73
|
+
*/
|
|
74
|
+
export function buildHiddenAgentRegistrations(args: {
|
|
75
|
+
dreamerPrompt: string | undefined;
|
|
76
|
+
smartNoteCompilerPrompt?: string | undefined;
|
|
77
|
+
historianPrompt: string | undefined;
|
|
78
|
+
historianRecompPrompt?: string | undefined;
|
|
79
|
+
historianEditorPrompt: string | undefined;
|
|
80
|
+
sidekickPrompt: string | undefined;
|
|
81
|
+
dreamerOverrides?: Record<string, unknown>;
|
|
82
|
+
historianOverrides?: Record<string, unknown>;
|
|
83
|
+
sidekickOverrides?: Record<string, unknown>;
|
|
84
|
+
historianDisallowed: readonly string[];
|
|
85
|
+
}): HiddenAgentRegistration[] {
|
|
86
|
+
const historianAllowedTools = applyDisallowedTools(
|
|
87
|
+
["read", "aft_outline", "aft_zoom", "aft_search"],
|
|
88
|
+
args.historianDisallowed,
|
|
89
|
+
);
|
|
90
|
+
return [
|
|
91
|
+
{
|
|
92
|
+
id: "dreamer",
|
|
93
|
+
prompt: args.dreamerPrompt,
|
|
94
|
+
// CURATE-ONLY now. Curate edits the memory store via ctx_memory and
|
|
95
|
+
// never reads code (a separate verify task owns memory-vs-code
|
|
96
|
+
// correctness), so it needs only ctx_memory — not the former
|
|
97
|
+
// bash/write/edit/read/aft/ctx_search/ctx_note surface. maintain-docs
|
|
98
|
+
// and review-user-memories moved to their own scoped agents below.
|
|
99
|
+
// (Inline literal — kept byte-identical to DREAMER_CURATE_ALLOWED_TOOLS
|
|
100
|
+
// by agent-registration-drift.test.ts; see the module header for why
|
|
101
|
+
// these are not const imports.)
|
|
102
|
+
allowedTools: ["ctx_memory"],
|
|
103
|
+
// Curate is a genuine multi-step whole-pool hygiene loop, so it keeps a
|
|
104
|
+
// high cap.
|
|
105
|
+
maxSteps: 150,
|
|
106
|
+
overrides: args.dreamerOverrides,
|
|
107
|
+
// Lock the curate tool surface: a user dreamer `tools`/`permission`
|
|
108
|
+
// override must not re-grant bash/write/edit to this unsupervised
|
|
109
|
+
// memory-hygiene agent. Model/temperature overrides still apply.
|
|
110
|
+
lockPermissions: true,
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
id: "dreamer-docs",
|
|
114
|
+
prompt: args.dreamerPrompt,
|
|
115
|
+
// maintain-docs: explore code + write/edit ARCHITECTURE.md/STRUCTURE.md
|
|
116
|
+
// + bash (git log, find). NO ctx_memory/ctx_search/ctx_note — it edits
|
|
117
|
+
// docs, never the memory store. (Inline literal — kept byte-identical to
|
|
118
|
+
// DREAMER_DOCS_ALLOWED_TOOLS by agent-registration-drift.test.ts.)
|
|
119
|
+
allowedTools: [
|
|
120
|
+
"read",
|
|
121
|
+
"grep",
|
|
122
|
+
"glob",
|
|
123
|
+
"bash",
|
|
124
|
+
"write",
|
|
125
|
+
"edit",
|
|
126
|
+
"aft_outline",
|
|
127
|
+
"aft_zoom",
|
|
128
|
+
"aft_search",
|
|
129
|
+
],
|
|
130
|
+
// Docs maintenance reads the tree and writes two files — a bounded loop,
|
|
131
|
+
// not the whole-pool 150.
|
|
132
|
+
maxSteps: 60,
|
|
133
|
+
overrides: args.dreamerOverrides,
|
|
134
|
+
// Lock so a user override can't add the memory surface back.
|
|
135
|
+
lockPermissions: true,
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
id: "dreamer-reviewer",
|
|
139
|
+
prompt: args.dreamerPrompt,
|
|
140
|
+
// review-user-memories: a pure JSON reviewer of behavioral observations.
|
|
141
|
+
// It calls NO tools — the host applies its verdict — so zero tools,
|
|
142
|
+
// locked (mirrors dreamer-classifier).
|
|
143
|
+
allowedTools: [],
|
|
144
|
+
maxSteps: 4,
|
|
145
|
+
overrides: args.dreamerOverrides,
|
|
146
|
+
lockPermissions: true,
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
id: "dreamer-retrospective",
|
|
150
|
+
prompt: args.dreamerPrompt,
|
|
151
|
+
allowedTools: ["ctx_search"],
|
|
152
|
+
maxSteps: 40,
|
|
153
|
+
overrides: args.dreamerOverrides,
|
|
154
|
+
// Privacy-critical: this child reads OTHER sessions' raw user text.
|
|
155
|
+
// Lock it to ctx_search-only — a user dreamer `permission` override
|
|
156
|
+
// must never broaden it.
|
|
157
|
+
lockPermissions: true,
|
|
158
|
+
},
|
|
159
|
+
{
|
|
160
|
+
id: "dreamer-primer-investigator",
|
|
161
|
+
prompt: args.dreamerPrompt,
|
|
162
|
+
// Read-only code investigation: read/navigate/search the CURRENT
|
|
163
|
+
// source to answer a primer. Deliberately NO write/edit/bash (could
|
|
164
|
+
// corrupt user source) and NO ctx_memory/ctx_note (ctx_memory
|
|
165
|
+
// update/archive/merge bumps the project memory epoch → busts m[0],
|
|
166
|
+
// violating the primers cache-neutral contract).
|
|
167
|
+
allowedTools: [
|
|
168
|
+
"read",
|
|
169
|
+
"grep",
|
|
170
|
+
"glob",
|
|
171
|
+
"aft_outline",
|
|
172
|
+
"aft_zoom",
|
|
173
|
+
"aft_search",
|
|
174
|
+
"ctx_search",
|
|
175
|
+
],
|
|
176
|
+
// Tight read-only-lookup budget — NOT the dreamer's 150. A single
|
|
177
|
+
// primer is a targeted investigation, not a whole-pool maintenance
|
|
178
|
+
// loop; it also bounds the per-primer cost of an unsupervised run.
|
|
179
|
+
maxSteps: 40,
|
|
180
|
+
overrides: args.dreamerOverrides,
|
|
181
|
+
// A user dreamer `permission`/`tools` override must never re-grant the
|
|
182
|
+
// denied write/bash/ctx_memory surface to this unsupervised agent.
|
|
183
|
+
lockPermissions: true,
|
|
184
|
+
},
|
|
185
|
+
{
|
|
186
|
+
id: "dreamer-memory-mapper",
|
|
187
|
+
prompt: args.dreamerPrompt,
|
|
188
|
+
// Read-only local-source reader for map-memories / verify: open and
|
|
189
|
+
// check the CURRENT source. NO write/edit/bash (could corrupt user
|
|
190
|
+
// source), NO ctx_memory (mutations bump the project memory epoch →
|
|
191
|
+
// bust m[0]; the host applies the manifest's DB writes itself), and NO
|
|
192
|
+
// ctx_search (these tasks check against local code, not cross-session
|
|
193
|
+
// recall).
|
|
194
|
+
allowedTools: ["read", "grep", "glob", "aft_outline", "aft_zoom", "aft_search"],
|
|
195
|
+
// Bounded read-only-lookup budget (mirrors the primer investigator) —
|
|
196
|
+
// NOT the dreamer's 150. A map/verify batch is a targeted file-lookup
|
|
197
|
+
// pass, and this bounds the per-batch cost of an unsupervised run.
|
|
198
|
+
maxSteps: 60,
|
|
199
|
+
overrides: args.dreamerOverrides,
|
|
200
|
+
// A user dreamer `permission`/`tools` override must never re-grant the
|
|
201
|
+
// denied write/bash/ctx_memory surface to this unsupervised agent.
|
|
202
|
+
lockPermissions: true,
|
|
203
|
+
},
|
|
204
|
+
{
|
|
205
|
+
id: "dreamer-classifier",
|
|
206
|
+
prompt: args.dreamerPrompt,
|
|
207
|
+
// ZERO tools: classify scores importance/scope/shareable from the
|
|
208
|
+
// memory text alone (no code inspection), emits ONE XML manifest, and
|
|
209
|
+
// the host applies the column writes. A pure transform — no tool can
|
|
210
|
+
// help it, and locking prevents a user override from granting one.
|
|
211
|
+
allowedTools: [],
|
|
212
|
+
maxSteps: 4,
|
|
213
|
+
overrides: args.dreamerOverrides,
|
|
214
|
+
lockPermissions: true,
|
|
215
|
+
},
|
|
216
|
+
{
|
|
217
|
+
id: "smart-note-compiler",
|
|
218
|
+
prompt: args.smartNoteCompilerPrompt,
|
|
219
|
+
allowedTools: [],
|
|
220
|
+
maxSteps: 8,
|
|
221
|
+
overrides: args.dreamerOverrides,
|
|
222
|
+
// Security-critical: condition text is untrusted prompt data; never
|
|
223
|
+
// let user dreamer overrides grant tools to the compiler.
|
|
224
|
+
lockPermissions: true,
|
|
225
|
+
},
|
|
226
|
+
{
|
|
227
|
+
id: "historian",
|
|
228
|
+
prompt: args.historianPrompt,
|
|
229
|
+
allowedTools: historianAllowedTools,
|
|
230
|
+
maxSteps: 40,
|
|
231
|
+
overrides: args.historianOverrides,
|
|
232
|
+
},
|
|
233
|
+
{
|
|
234
|
+
id: "historian-recomp",
|
|
235
|
+
prompt: args.historianRecompPrompt ?? args.historianPrompt,
|
|
236
|
+
allowedTools: historianAllowedTools,
|
|
237
|
+
maxSteps: 40,
|
|
238
|
+
overrides: args.historianOverrides,
|
|
239
|
+
},
|
|
240
|
+
{
|
|
241
|
+
id: "historian-editor",
|
|
242
|
+
prompt: args.historianEditorPrompt,
|
|
243
|
+
allowedTools: historianAllowedTools,
|
|
244
|
+
maxSteps: 40,
|
|
245
|
+
overrides: args.historianOverrides,
|
|
246
|
+
},
|
|
247
|
+
{
|
|
248
|
+
id: "sidekick",
|
|
249
|
+
prompt: args.sidekickPrompt,
|
|
250
|
+
allowedTools: ["ctx_search", "aft_outline", "aft_zoom"],
|
|
251
|
+
maxSteps: 40,
|
|
252
|
+
overrides: args.sidekickOverrides,
|
|
253
|
+
},
|
|
254
|
+
];
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
/**
|
|
258
|
+
* Build a hidden-agent config with a deny-everything-by-default permission
|
|
259
|
+
* baseline and a hard tool-iteration ceiling. User overrides may lower
|
|
260
|
+
* `steps`/`maxSteps`, but cannot raise either above the built-in cap.
|
|
261
|
+
*/
|
|
262
|
+
export function buildHiddenAgentConfig(
|
|
263
|
+
prompt: string,
|
|
264
|
+
allowedTools: readonly string[],
|
|
265
|
+
maxSteps: number,
|
|
266
|
+
overrides?: Record<string, unknown>,
|
|
267
|
+
agentLabel?: string,
|
|
268
|
+
lockPermissions = false,
|
|
269
|
+
) {
|
|
270
|
+
const {
|
|
271
|
+
permission: overridePermission,
|
|
272
|
+
tools: overrideTools,
|
|
273
|
+
// Pulled out so they can be conditionally re-added: under lockPermissions
|
|
274
|
+
// a user `prompt`/`system` override must NOT replace the hardened
|
|
275
|
+
// system prompt (see below). Spreading `...rest` below would otherwise
|
|
276
|
+
// clobber the positional `prompt` arg, since `...rest` lands after it.
|
|
277
|
+
prompt: overridePrompt,
|
|
278
|
+
system: overrideSystem,
|
|
279
|
+
...rest
|
|
280
|
+
} = (overrides ?? {}) as {
|
|
281
|
+
permission?: Record<string, unknown>;
|
|
282
|
+
tools?: Record<string, boolean>;
|
|
283
|
+
prompt?: unknown;
|
|
284
|
+
system?: unknown;
|
|
285
|
+
[key: string]: unknown;
|
|
286
|
+
};
|
|
287
|
+
// When locked (privacy-critical agents), the user `tools` enable/disable map
|
|
288
|
+
// AND the `prompt`/`system` text are ALL dropped — each is a
|
|
289
|
+
// privilege/behavior-escalation surface. A user `dreamer.tools: { bash: true }`
|
|
290
|
+
// would otherwise re-enable a denied tool; a user `dreamer.prompt`/`system`
|
|
291
|
+
// would otherwise replace the privacy-hardened prompt that, e.g., keeps the
|
|
292
|
+
// retrospective agent from transcribing raw user text. Unlocked agents keep
|
|
293
|
+
// their `tools`/`prompt`/`system` overrides.
|
|
294
|
+
const promptOverrides: Record<string, unknown> = lockPermissions
|
|
295
|
+
? {}
|
|
296
|
+
: {
|
|
297
|
+
...(overridePrompt !== undefined ? { prompt: overridePrompt } : {}),
|
|
298
|
+
...(overrideSystem !== undefined ? { system: overrideSystem } : {}),
|
|
299
|
+
};
|
|
300
|
+
const restOverrides: Record<string, unknown> = lockPermissions
|
|
301
|
+
? { ...rest, ...promptOverrides }
|
|
302
|
+
: {
|
|
303
|
+
...rest,
|
|
304
|
+
...promptOverrides,
|
|
305
|
+
...(overrideTools !== undefined ? { tools: overrideTools } : {}),
|
|
306
|
+
};
|
|
307
|
+
const basePermission = buildAllowOnlyPermission(allowedTools, agentLabel);
|
|
308
|
+
return {
|
|
309
|
+
prompt,
|
|
310
|
+
// No builtin fallback chain: the user's `fallback_models` (if any) flow
|
|
311
|
+
// through `restOverrides`. A hardcoded chain names providers the user may
|
|
312
|
+
// not have, producing `Model not found` retry storms.
|
|
313
|
+
...restOverrides,
|
|
314
|
+
steps: clampHiddenAgentStepLimit(restOverrides.steps, maxSteps),
|
|
315
|
+
maxSteps: clampHiddenAgentStepLimit(restOverrides.maxSteps, maxSteps),
|
|
316
|
+
// Permission baseline goes after `restOverrides` so that accidental
|
|
317
|
+
// `permission` keys in user overrides we DIDN'T explicitly destructure
|
|
318
|
+
// can't bypass the deny. The explicit override (destructured above) is
|
|
319
|
+
// then layered on top — UNLESS lockPermissions is set, in which case the
|
|
320
|
+
// user override is dropped entirely. lockPermissions is for
|
|
321
|
+
// privacy-critical agents (dreamer-retrospective reads other sessions'
|
|
322
|
+
// raw user text and MUST stay ctx_search-only; a user dreamer `permission`
|
|
323
|
+
// override must never grant it bash/edit/ctx_memory/etc).
|
|
324
|
+
permission: {
|
|
325
|
+
...basePermission,
|
|
326
|
+
...(lockPermissions ? {} : (overridePermission ?? {})),
|
|
327
|
+
},
|
|
328
|
+
mode: "subagent" as const,
|
|
329
|
+
hidden: true,
|
|
330
|
+
};
|
|
331
|
+
}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import { describe, expect, it } from "bun:test";
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
buildContentLanguageDirective,
|
|
5
|
+
buildMigrationLanguageDirective,
|
|
6
|
+
buildPrimaryLanguageDirective,
|
|
7
|
+
isValidLanguageCode,
|
|
8
|
+
resolveLanguageName,
|
|
9
|
+
withContentLanguageDirective,
|
|
10
|
+
withMigrationLanguageDirective,
|
|
11
|
+
} from "./language-directive";
|
|
12
|
+
|
|
13
|
+
const EXHAUSTIVE_STRUCTURAL_TOKENS = [
|
|
14
|
+
"summary",
|
|
15
|
+
"symptom",
|
|
16
|
+
"model_or_provider_involved",
|
|
17
|
+
"ord_span",
|
|
18
|
+
"provider_sdk",
|
|
19
|
+
"model_behavior",
|
|
20
|
+
"tool_protocol",
|
|
21
|
+
"host_integration",
|
|
22
|
+
"historian_pipeline",
|
|
23
|
+
"edit_pipeline",
|
|
24
|
+
"environment",
|
|
25
|
+
"undocumented_internal",
|
|
26
|
+
"other",
|
|
27
|
+
"fixed",
|
|
28
|
+
"workaround",
|
|
29
|
+
"external_blocker",
|
|
30
|
+
"contained_failure",
|
|
31
|
+
"deferred",
|
|
32
|
+
"unknown_but_bounded",
|
|
33
|
+
"user",
|
|
34
|
+
"test_result",
|
|
35
|
+
"tool_result",
|
|
36
|
+
"self_review",
|
|
37
|
+
"unprocessed_from",
|
|
38
|
+
"verified",
|
|
39
|
+
"update",
|
|
40
|
+
"archive",
|
|
41
|
+
"candidate_ids",
|
|
42
|
+
"update_existing",
|
|
43
|
+
"memory_id",
|
|
44
|
+
"dismiss_existing",
|
|
45
|
+
"consume_candidate_ids",
|
|
46
|
+
"migrated",
|
|
47
|
+
"user_observations",
|
|
48
|
+
"answer",
|
|
49
|
+
] as const;
|
|
50
|
+
|
|
51
|
+
describe("resolveLanguageName", () => {
|
|
52
|
+
it("maps a 2-letter ISO 639-1 code to 'English (Endonym)'", () => {
|
|
53
|
+
expect(resolveLanguageName("tr")).toBe("Turkish (Türkçe)");
|
|
54
|
+
expect(resolveLanguageName("es")).toBe("Spanish (Español)");
|
|
55
|
+
expect(resolveLanguageName("ja")).toBe("Japanese (日本語)");
|
|
56
|
+
});
|
|
57
|
+
it("normalizes case and surrounding whitespace", () => {
|
|
58
|
+
expect(resolveLanguageName(" TR ")).toBe("Turkish (Türkçe)");
|
|
59
|
+
});
|
|
60
|
+
it("returns the bare English name when the endonym matches it", () => {
|
|
61
|
+
expect(resolveLanguageName("en")).toBe("English");
|
|
62
|
+
});
|
|
63
|
+
it("returns '' for unset, blank, non-codes, and unknown codes", () => {
|
|
64
|
+
expect(resolveLanguageName()).toBe("");
|
|
65
|
+
expect(resolveLanguageName(" ")).toBe("");
|
|
66
|
+
expect(resolveLanguageName("Turkish")).toBe(""); // full name rejected
|
|
67
|
+
expect(resolveLanguageName("tur")).toBe(""); // 3-letter rejected
|
|
68
|
+
expect(resolveLanguageName("zz")).toBe(""); // not a real language
|
|
69
|
+
expect(resolveLanguageName("e1")).toBe("");
|
|
70
|
+
});
|
|
71
|
+
it("isValidLanguageCode mirrors resolveLanguageName", () => {
|
|
72
|
+
expect(isValidLanguageCode("tr")).toBe(true);
|
|
73
|
+
expect(isValidLanguageCode("zz")).toBe(false);
|
|
74
|
+
expect(isValidLanguageCode("Español")).toBe(false);
|
|
75
|
+
});
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
describe("language directives", () => {
|
|
79
|
+
it("emits the content directive with the resolved name and structural rule", () => {
|
|
80
|
+
const directive = buildContentLanguageDirective("tr");
|
|
81
|
+
expect(directive).toContain("Write human-readable prose you author in: Turkish (Türkçe).");
|
|
82
|
+
expect(directive).toContain("Copy required output schemas exactly");
|
|
83
|
+
expect(directive).toContain("No relevant memories found");
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
it("emits the preserve-user-quotes variant", () => {
|
|
87
|
+
const directive = buildContentLanguageDirective("es", {
|
|
88
|
+
preserveUserQuotes: true,
|
|
89
|
+
});
|
|
90
|
+
expect(directive).toContain(
|
|
91
|
+
"Preserve U: lines and directly quoted user text in their original source language; write the surrounding summary prose in Spanish (Español).",
|
|
92
|
+
);
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
it("emits the retrospective no-quote variant", () => {
|
|
96
|
+
const directive = buildContentLanguageDirective("tr", { retrospective: true });
|
|
97
|
+
expect(directive).toContain(
|
|
98
|
+
"Write the lesson text in Turkish (Türkçe); paraphrase source text and never quote the user.",
|
|
99
|
+
);
|
|
100
|
+
expect(directive).not.toContain("directly quoted user text");
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
it("emits the migration preserve-language variant", () => {
|
|
104
|
+
const directive = buildMigrationLanguageDirective("pt");
|
|
105
|
+
expect(directive).toContain("Preserve each migrated memory's existing language");
|
|
106
|
+
expect(directive).toContain(
|
|
107
|
+
"do NOT translate a memory just because an output language is set",
|
|
108
|
+
);
|
|
109
|
+
expect(directive).not.toContain("Write human-readable prose you author");
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
it("emits the primary one-liner with the resolved name", () => {
|
|
113
|
+
expect(buildPrimaryLanguageDirective("zh")).toBe(
|
|
114
|
+
"Use Chinese (中文) for your natural-language replies to the user unless the user explicitly asks for another language. Keep code, identifiers, file paths, commands, logs, and quoted text verbatim.",
|
|
115
|
+
);
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
it("returns empty or unchanged for blank or invalid language", () => {
|
|
119
|
+
expect(buildContentLanguageDirective()).toBe("");
|
|
120
|
+
expect(buildContentLanguageDirective(" ")).toBe("");
|
|
121
|
+
expect(buildContentLanguageDirective("Turkish")).toBe(""); // full name not a code
|
|
122
|
+
expect(buildMigrationLanguageDirective()).toBe("");
|
|
123
|
+
expect(buildPrimaryLanguageDirective()).toBe("");
|
|
124
|
+
expect(withContentLanguageDirective("base", "")).toBe("base");
|
|
125
|
+
expect(withMigrationLanguageDirective("base", " ")).toBe("base");
|
|
126
|
+
expect(withContentLanguageDirective("base", "zz")).toBe("base"); // unknown code
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
it("does not inline the exhaustive structural token inventory", () => {
|
|
130
|
+
const directive = buildContentLanguageDirective("tr");
|
|
131
|
+
for (const token of EXHAUSTIVE_STRUCTURAL_TOKENS) {
|
|
132
|
+
const escaped = token.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
133
|
+
expect(directive, token).not.toMatch(
|
|
134
|
+
new RegExp(`(^|[^A-Za-z0-9_])${escaped}([^A-Za-z0-9_]|$)`),
|
|
135
|
+
);
|
|
136
|
+
}
|
|
137
|
+
});
|
|
138
|
+
});
|