@cortexkit/opencode-magic-context 0.26.0 → 0.27.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/README.md +14 -12
- package/dist/agents/dreamer.d.ts +19 -0
- package/dist/agents/dreamer.d.ts.map +1 -1
- package/dist/agents/hidden-agent-registrations.d.ts +67 -0
- package/dist/agents/hidden-agent-registrations.d.ts.map +1 -0
- package/dist/agents/historian.d.ts +1 -0
- package/dist/agents/historian.d.ts.map +1 -1
- package/dist/agents/permissions.d.ts +15 -44
- package/dist/agents/permissions.d.ts.map +1 -1
- package/dist/agents/smart-note-compiler.d.ts +2 -0
- package/dist/agents/smart-note-compiler.d.ts.map +1 -0
- package/dist/config/index.d.ts +1 -1
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/migrate-config-location.d.ts +89 -0
- package/dist/config/migrate-config-location.d.ts.map +1 -0
- package/dist/config/migrate-dreamer-v2.d.ts +37 -0
- package/dist/config/migrate-dreamer-v2.d.ts.map +1 -0
- package/dist/config/migrate-experimental.d.ts.map +1 -1
- package/dist/config/project-security.d.ts +3 -0
- package/dist/config/project-security.d.ts.map +1 -1
- package/dist/config/prune-config-leaf.d.ts.map +1 -1
- package/dist/config/schema/magic-context.d.ts +584 -60
- package/dist/config/schema/magic-context.d.ts.map +1 -1
- package/dist/features/magic-context/compaction-marker.d.ts +9 -3
- package/dist/features/magic-context/compaction-marker.d.ts.map +1 -1
- package/dist/features/magic-context/compartment-chunk-embedding.d.ts +1 -1
- package/dist/features/magic-context/compartment-chunk-embedding.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/classify-prompt.d.ts +50 -0
- package/dist/features/magic-context/dreamer/classify-prompt.d.ts.map +1 -0
- package/dist/features/magic-context/dreamer/classify.d.ts +22 -0
- package/dist/features/magic-context/dreamer/classify.d.ts.map +1 -0
- package/dist/features/magic-context/dreamer/cron.d.ts +72 -0
- package/dist/features/magic-context/dreamer/cron.d.ts.map +1 -0
- package/dist/features/magic-context/dreamer/evaluate-smart-notes.d.ts +30 -0
- package/dist/features/magic-context/dreamer/evaluate-smart-notes.d.ts.map +1 -0
- package/dist/features/magic-context/dreamer/index.d.ts +1 -3
- package/dist/features/magic-context/dreamer/index.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/lease.d.ts +44 -6
- package/dist/features/magic-context/dreamer/lease.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/maintain-docs-protected-enforcement.d.ts +13 -0
- package/dist/features/magic-context/dreamer/maintain-docs-protected-enforcement.d.ts.map +1 -0
- package/dist/features/magic-context/dreamer/map-memories-prompt.d.ts +36 -0
- package/dist/features/magic-context/dreamer/map-memories-prompt.d.ts.map +1 -0
- package/dist/features/magic-context/dreamer/map-memories.d.ts +22 -0
- package/dist/features/magic-context/dreamer/map-memories.d.ts.map +1 -0
- package/dist/features/magic-context/dreamer/open-opencode-db.d.ts +7 -0
- package/dist/features/magic-context/dreamer/open-opencode-db.d.ts.map +1 -0
- package/dist/features/magic-context/dreamer/primer-seed.d.ts +25 -0
- package/dist/features/magic-context/dreamer/primer-seed.d.ts.map +1 -0
- package/dist/features/magic-context/dreamer/promote-primers.d.ts +21 -0
- package/dist/features/magic-context/dreamer/promote-primers.d.ts.map +1 -0
- package/dist/features/magic-context/dreamer/protected-regions.d.ts +19 -0
- package/dist/features/magic-context/dreamer/protected-regions.d.ts.map +1 -0
- package/dist/features/magic-context/dreamer/refresh-primers.d.ts +30 -0
- package/dist/features/magic-context/dreamer/refresh-primers.d.ts.map +1 -0
- package/dist/features/magic-context/dreamer/retrospective-learnings.d.ts +47 -0
- package/dist/features/magic-context/dreamer/retrospective-learnings.d.ts.map +1 -0
- package/dist/features/magic-context/dreamer/retrospective-orphan-sweep.d.ts +48 -0
- package/dist/features/magic-context/dreamer/retrospective-orphan-sweep.d.ts.map +1 -0
- package/dist/features/magic-context/dreamer/retrospective-raw-provider.d.ts +81 -0
- package/dist/features/magic-context/dreamer/retrospective-raw-provider.d.ts.map +1 -0
- package/dist/features/magic-context/dreamer/storage-dream-runs.d.ts +8 -0
- package/dist/features/magic-context/dreamer/storage-dream-runs.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/storage-task-schedule.d.ts +82 -0
- package/dist/features/magic-context/dreamer/storage-task-schedule.d.ts.map +1 -0
- package/dist/features/magic-context/dreamer/task-config.d.ts +28 -0
- package/dist/features/magic-context/dreamer/task-config.d.ts.map +1 -0
- package/dist/features/magic-context/dreamer/task-executor.d.ts +49 -0
- package/dist/features/magic-context/dreamer/task-executor.d.ts.map +1 -0
- package/dist/features/magic-context/dreamer/task-gates.d.ts +29 -0
- package/dist/features/magic-context/dreamer/task-gates.d.ts.map +1 -0
- package/dist/features/magic-context/dreamer/task-prompts.d.ts +37 -6
- package/dist/features/magic-context/dreamer/task-prompts.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/task-registry.d.ts +48 -0
- package/dist/features/magic-context/dreamer/task-registry.d.ts.map +1 -0
- package/dist/features/magic-context/dreamer/task-scheduler.d.ts +88 -0
- package/dist/features/magic-context/dreamer/task-scheduler.d.ts.map +1 -0
- package/dist/features/magic-context/dreamer/verify-gate.d.ts +43 -0
- package/dist/features/magic-context/dreamer/verify-gate.d.ts.map +1 -0
- package/dist/features/magic-context/dreamer/verify-prompt.d.ts +41 -0
- package/dist/features/magic-context/dreamer/verify-prompt.d.ts.map +1 -0
- package/dist/features/magic-context/dreamer/verify.d.ts +43 -0
- package/dist/features/magic-context/dreamer/verify.d.ts.map +1 -0
- package/dist/features/magic-context/git-commits/search-git-commits.d.ts +2 -0
- package/dist/features/magic-context/git-commits/search-git-commits.d.ts.map +1 -1
- package/dist/features/magic-context/git-commits/storage-git-commit-embeddings.d.ts +4 -4
- package/dist/features/magic-context/git-commits/storage-git-commit-embeddings.d.ts.map +1 -1
- package/dist/features/magic-context/index.d.ts +1 -0
- package/dist/features/magic-context/index.d.ts.map +1 -1
- package/dist/features/magic-context/memory/embedding-cache.d.ts +2 -2
- package/dist/features/magic-context/memory/embedding-cache.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.map +1 -1
- package/dist/features/magic-context/memory/embedding-openai.d.ts +12 -5
- package/dist/features/magic-context/memory/embedding-openai.d.ts.map +1 -1
- package/dist/features/magic-context/memory/embedding.d.ts +2 -2
- package/dist/features/magic-context/memory/embedding.d.ts.map +1 -1
- package/dist/features/magic-context/memory/index.d.ts +4 -1
- package/dist/features/magic-context/memory/index.d.ts.map +1 -1
- package/dist/features/magic-context/memory/memory-migration.d.ts +1 -0
- package/dist/features/magic-context/memory/memory-migration.d.ts.map +1 -1
- package/dist/features/magic-context/memory/promotion.d.ts +16 -4
- package/dist/features/magic-context/memory/promotion.d.ts.map +1 -1
- package/dist/features/magic-context/memory/storage-memory-embeddings.d.ts +2 -2
- package/dist/features/magic-context/memory/storage-memory-embeddings.d.ts.map +1 -1
- package/dist/features/magic-context/memory/storage-memory-verifications.d.ts +31 -0
- package/dist/features/magic-context/memory/storage-memory-verifications.d.ts.map +1 -0
- package/dist/features/magic-context/memory/storage-memory.d.ts +12 -1
- package/dist/features/magic-context/memory/storage-memory.d.ts.map +1 -1
- package/dist/features/magic-context/memory/types.d.ts +4 -0
- package/dist/features/magic-context/memory/types.d.ts.map +1 -1
- package/dist/features/magic-context/memory/verification-paths.d.ts +32 -0
- package/dist/features/magic-context/memory/verification-paths.d.ts.map +1 -0
- package/dist/features/magic-context/message-index.d.ts.map +1 -1
- package/dist/features/magic-context/migrations.d.ts.map +1 -1
- package/dist/features/magic-context/overflow-detection.d.ts.map +1 -1
- package/dist/features/magic-context/primer-clustering.d.ts +29 -0
- package/dist/features/magic-context/primer-clustering.d.ts.map +1 -0
- package/dist/features/magic-context/project-embedding-registry.d.ts +25 -1
- package/dist/features/magic-context/project-embedding-registry.d.ts.map +1 -1
- package/dist/features/magic-context/search.d.ts +12 -2
- package/dist/features/magic-context/search.d.ts.map +1 -1
- package/dist/features/magic-context/sidekick/agent.d.ts.map +1 -1
- package/dist/features/magic-context/smart-notes/capabilities.d.ts +31 -0
- package/dist/features/magic-context/smart-notes/capabilities.d.ts.map +1 -0
- package/dist/features/magic-context/smart-notes/compiler-prompt.d.ts +2 -0
- package/dist/features/magic-context/smart-notes/compiler-prompt.d.ts.map +1 -0
- package/dist/features/magic-context/smart-notes/compiler.d.ts +52 -0
- package/dist/features/magic-context/smart-notes/compiler.d.ts.map +1 -0
- package/dist/features/magic-context/smart-notes/index.d.ts +10 -0
- package/dist/features/magic-context/smart-notes/index.d.ts.map +1 -0
- package/dist/features/magic-context/smart-notes/runner.d.ts +18 -0
- package/dist/features/magic-context/smart-notes/runner.d.ts.map +1 -0
- package/dist/features/magic-context/smart-notes/sandbox-runner.d.ts +22 -0
- package/dist/features/magic-context/smart-notes/sandbox-runner.d.ts.map +1 -0
- package/dist/features/magic-context/smart-notes/schedule.d.ts +9 -0
- package/dist/features/magic-context/smart-notes/schedule.d.ts.map +1 -0
- package/dist/features/magic-context/smart-notes/ssrf-guard.d.ts +49 -0
- package/dist/features/magic-context/smart-notes/ssrf-guard.d.ts.map +1 -0
- package/dist/features/magic-context/smart-notes/storage.d.ts +27 -0
- package/dist/features/magic-context/smart-notes/storage.d.ts.map +1 -0
- package/dist/features/magic-context/smart-notes/types.d.ts +63 -0
- package/dist/features/magic-context/smart-notes/types.d.ts.map +1 -0
- package/dist/features/magic-context/storage-db.d.ts +5 -1
- package/dist/features/magic-context/storage-db.d.ts.map +1 -1
- package/dist/features/magic-context/storage-meta-persisted.d.ts +8 -4
- package/dist/features/magic-context/storage-meta-persisted.d.ts.map +1 -1
- package/dist/features/magic-context/storage-meta-session.d.ts.map +1 -1
- package/dist/features/magic-context/storage-meta-shared.d.ts +3 -1
- package/dist/features/magic-context/storage-meta-shared.d.ts.map +1 -1
- package/dist/features/magic-context/storage-notes.d.ts +15 -0
- package/dist/features/magic-context/storage-notes.d.ts.map +1 -1
- package/dist/features/magic-context/storage-primers.d.ts +85 -0
- package/dist/features/magic-context/storage-primers.d.ts.map +1 -0
- package/dist/features/magic-context/storage-tags.d.ts +20 -0
- package/dist/features/magic-context/storage-tags.d.ts.map +1 -1
- package/dist/features/magic-context/storage.d.ts +2 -1
- package/dist/features/magic-context/storage.d.ts.map +1 -1
- package/dist/features/magic-context/tagger.d.ts +6 -0
- package/dist/features/magic-context/tagger.d.ts.map +1 -1
- package/dist/features/magic-context/tool-owner-backfill.d.ts.map +1 -1
- package/dist/features/magic-context/transform-decision-log.d.ts +10 -0
- package/dist/features/magic-context/transform-decision-log.d.ts.map +1 -1
- package/dist/features/magic-context/types.d.ts +2 -0
- package/dist/features/magic-context/types.d.ts.map +1 -1
- package/dist/features/magic-context/user-memory/review-user-memories.d.ts +5 -0
- 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 +18 -0
- package/dist/features/magic-context/user-memory/storage-user-memory.d.ts.map +1 -1
- package/dist/features/magic-context/v22-deferred-backfill.d.ts.map +1 -1
- package/dist/hooks/auto-update-checker/semver.d.ts +9 -0
- package/dist/hooks/auto-update-checker/semver.d.ts.map +1 -1
- package/dist/hooks/magic-context/auto-search-hint.d.ts.map +1 -1
- package/dist/hooks/magic-context/command-handler.d.ts +8 -15
- package/dist/hooks/magic-context/command-handler.d.ts.map +1 -1
- package/dist/hooks/magic-context/compaction-marker-manager.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-parser.d.ts +9 -0
- package/dist/hooks/magic-context/compartment-parser.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-prompt.d.ts +4 -1
- package/dist/hooks/magic-context/compartment-prompt.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-runner-historian.d.ts +1 -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-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-runner-types.d.ts +8 -0
- package/dist/hooks/magic-context/compartment-runner-types.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-runner-validation.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-trigger.d.ts.map +1 -1
- package/dist/hooks/magic-context/ctx-reduce-nudge.d.ts.map +1 -1
- package/dist/hooks/magic-context/event-handler.d.ts.map +1 -1
- package/dist/hooks/magic-context/event-resolvers.d.ts.map +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/historian-state-file.d.ts.map +1 -1
- package/dist/hooks/magic-context/hook-handlers.d.ts +2 -1
- package/dist/hooks/magic-context/hook-handlers.d.ts.map +1 -1
- package/dist/hooks/magic-context/hook.d.ts +1 -0
- package/dist/hooks/magic-context/hook.d.ts.map +1 -1
- package/dist/hooks/magic-context/inject-compartments.d.ts +0 -3
- package/dist/hooks/magic-context/inject-compartments.d.ts.map +1 -1
- package/dist/hooks/magic-context/send-session-notification.d.ts +2 -0
- package/dist/hooks/magic-context/send-session-notification.d.ts.map +1 -1
- package/dist/hooks/magic-context/system-prompt-hash.d.ts +17 -0
- package/dist/hooks/magic-context/system-prompt-hash.d.ts.map +1 -1
- package/dist/hooks/magic-context/transform-postprocess-phase.d.ts +8 -5
- package/dist/hooks/magic-context/transform-postprocess-phase.d.ts.map +1 -1
- package/dist/hooks/magic-context/transform.d.ts +0 -2
- package/dist/hooks/magic-context/transform.d.ts.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +17028 -4059
- package/dist/plugin/dream-timer.d.ts +17 -9
- package/dist/plugin/dream-timer.d.ts.map +1 -1
- package/dist/plugin/embedding-bootstrap-helpers.d.ts +1 -1
- package/dist/plugin/embedding-bootstrap-helpers.d.ts.map +1 -1
- package/dist/plugin/embedding-bootstrap.d.ts.map +1 -1
- package/dist/plugin/hooks/create-session-hooks.d.ts +211 -0
- package/dist/plugin/hooks/create-session-hooks.d.ts.map +1 -1
- package/dist/plugin/instance-disposal.d.ts +2 -0
- package/dist/plugin/instance-disposal.d.ts.map +1 -0
- package/dist/plugin/rpc-handlers.d.ts.map +1 -1
- package/dist/shared/announcement.d.ts +1 -1
- package/dist/shared/announcement.d.ts.map +1 -1
- package/dist/shared/data-path.d.ts +26 -7
- package/dist/shared/data-path.d.ts.map +1 -1
- package/dist/shared/model-suggestion-retry.d.ts +48 -2
- package/dist/shared/model-suggestion-retry.d.ts.map +1 -1
- package/dist/shared/redaction.d.ts +7 -0
- package/dist/shared/redaction.d.ts.map +1 -0
- package/dist/shared/resolve-fallbacks.d.ts +12 -0
- package/dist/shared/resolve-fallbacks.d.ts.map +1 -1
- package/dist/shared/rpc-server.d.ts.map +1 -1
- package/dist/shared/rpc-types.d.ts +2 -0
- package/dist/shared/rpc-types.d.ts.map +1 -1
- package/dist/shared/subagent-runner.d.ts +12 -3
- package/dist/shared/subagent-runner.d.ts.map +1 -1
- package/dist/shared/tui-config.d.ts.map +1 -1
- package/dist/tools/ctx-memory/tools.d.ts.map +1 -1
- package/dist/tools/ctx-memory/types.d.ts.map +1 -1
- package/dist/tools/ctx-memory/verification-recording.d.ts +8 -0
- package/dist/tools/ctx-memory/verification-recording.d.ts.map +1 -0
- package/dist/tools/ctx-search/tools.d.ts.map +1 -1
- package/dist/tools/ctx-search/types.d.ts +1 -1
- package/dist/tools/ctx-search/types.d.ts.map +1 -1
- package/dist/tui/data/context-db.d.ts +2 -0
- package/dist/tui/data/context-db.d.ts.map +1 -1
- package/package.json +3 -1
- package/src/shared/announcement.test.ts +20 -0
- package/src/shared/announcement.ts +19 -7
- package/src/shared/data-path.test.ts +70 -6
- package/src/shared/data-path.ts +50 -8
- package/src/shared/model-suggestion-retry.test.ts +79 -2
- package/src/shared/model-suggestion-retry.ts +181 -3
- package/src/shared/redaction.test.ts +48 -0
- package/src/shared/redaction.ts +240 -0
- package/src/shared/resolve-fallbacks.ts +14 -0
- package/src/shared/rpc-server.ts +24 -0
- package/src/shared/rpc-types.ts +2 -0
- package/src/shared/subagent-runner.ts +12 -3
- package/src/shared/tui-config.test.ts +63 -0
- package/src/shared/tui-config.ts +67 -39
- package/src/tui/data/context-db.ts +12 -0
- package/src/tui/index.tsx +87 -17
- package/src/tui/slots/sidebar-content.tsx +4 -0
- package/dist/features/magic-context/dreamer/queue.d.ts +0 -55
- package/dist/features/magic-context/dreamer/queue.d.ts.map +0 -1
- package/dist/features/magic-context/dreamer/runner.d.ts +0 -92
- package/dist/features/magic-context/dreamer/runner.d.ts.map +0 -1
- package/dist/features/magic-context/dreamer/scheduler.d.ts +0 -29
- package/dist/features/magic-context/dreamer/scheduler.d.ts.map +0 -1
- package/dist/features/magic-context/key-files/aft-availability.d.ts +0 -11
- package/dist/features/magic-context/key-files/aft-availability.d.ts.map +0 -1
- package/dist/features/magic-context/key-files/identify-key-files.d.ts +0 -84
- package/dist/features/magic-context/key-files/identify-key-files.d.ts.map +0 -1
- package/dist/features/magic-context/key-files/project-key-files.d.ts +0 -42
- package/dist/features/magic-context/key-files/project-key-files.d.ts.map +0 -1
- package/dist/features/magic-context/key-files/read-history.d.ts +0 -26
- package/dist/features/magic-context/key-files/read-history.d.ts.map +0 -1
- package/dist/features/magic-context/key-files/read-stats.d.ts +0 -18
- package/dist/features/magic-context/key-files/read-stats.d.ts.map +0 -1
- package/dist/features/magic-context/key-files/storage-key-files.d.ts +0 -20
- package/dist/features/magic-context/key-files/storage-key-files.d.ts.map +0 -1
- package/dist/hooks/magic-context/key-files-block.d.ts +0 -27
- package/dist/hooks/magic-context/key-files-block.d.ts.map +0 -1
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Database } from "../../shared/sqlite";
|
|
2
|
+
/**
|
|
3
|
+
* Run `fn` inside a `BEGIN IMMEDIATE` transaction, committing on success and
|
|
4
|
+
* rolling back on throw. Used by the in-session ctx_memory mutation actions so
|
|
5
|
+
* a memory write + its mutation-log row commit atomically.
|
|
6
|
+
*/
|
|
7
|
+
export declare function runImmediateTransaction<T>(db: Database, fn: () => T): T;
|
|
8
|
+
//# sourceMappingURL=verification-recording.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verification-recording.d.ts","sourceRoot":"","sources":["../../../src/tools/ctx-memory/verification-recording.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAEpD;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,CAAC,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,CAUvE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../../../src/tools/ctx-search/tools.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,cAAc,EAAQ,MAAM,qBAAqB,CAAC;AAahE,OAAO,KAAK,EAAkC,iBAAiB,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../../../src/tools/ctx-search/tools.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,cAAc,EAAQ,MAAM,qBAAqB,CAAC;AAahE,OAAO,KAAK,EAAkC,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAqMjF,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,iBAAiB,GAAG,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAI5F"}
|
|
@@ -2,7 +2,7 @@ import type { Database } from "../../shared/sqlite";
|
|
|
2
2
|
/** Sources the agent can narrow ctx_search to. Facts are intentionally NOT a
|
|
3
3
|
* source — they're always rendered in <session-history> in message[0], so
|
|
4
4
|
* searching them returns content already visible in context. */
|
|
5
|
-
export type CtxSearchSource = "memory" | "message" | "git_commit";
|
|
5
|
+
export type CtxSearchSource = "memory" | "message" | "git_commit" | "primer";
|
|
6
6
|
export interface CtxSearchArgs {
|
|
7
7
|
query: string;
|
|
8
8
|
limit?: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/tools/ctx-search/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAEpD;;iEAEiE;AACjE,MAAM,MAAM,eAAe,GAAG,QAAQ,GAAG,SAAS,GAAG,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/tools/ctx-search/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAEpD;;iEAEiE;AACjE,MAAM,MAAM,eAAe,GAAG,QAAQ,GAAG,SAAS,GAAG,YAAY,GAAG,QAAQ,CAAC;AAE7E,MAAM,WAAW,aAAa;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,+DAA+D;IAC/D,OAAO,CAAC,EAAE,eAAe,EAAE,CAAC;CAC/B;AAED,MAAM,WAAW,iBAAiB;IAC9B,EAAE,EAAE,QAAQ,CAAC;IACb,uBAAuB,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,EAAE,QAAQ,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7E;;;;;OAKG;IACH,kBAAkB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,MAAM,CAAC;IAClD,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,0EAA0E;IAC1E,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,8EAA8E;IAC9E,YAAY,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,KAAK,CAAC;QACxC,OAAO,EAAE,MAAM,CAAC;QAChB,EAAE,EAAE,MAAM,CAAC;QACX,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,EAAE,OAAO,EAAE,CAAC;KACpB,CAAC,CAAC;CACN"}
|
|
@@ -22,6 +22,8 @@ export declare function requestUpgrade(sessionId: string): Promise<boolean>;
|
|
|
22
22
|
* choice), setting the durable stamp so the FRESH dialog won't re-show. Resume
|
|
23
23
|
* prompts are staging-driven and unaffected. */
|
|
24
24
|
export declare function dismissUpgradeReminder(sessionId: string): Promise<boolean>;
|
|
25
|
+
/** Resolve global toast duration from server config via RPC. */
|
|
26
|
+
export declare function loadToastDurationMs(): Promise<number>;
|
|
25
27
|
export interface TuiMessage {
|
|
26
28
|
id: number;
|
|
27
29
|
type: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context-db.d.ts","sourceRoot":"","sources":["../../../src/tui/data/context-db.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EACR,WAAW,EAEX,eAAe,EACf,YAAY,EACf,MAAM,wBAAwB,CAAC;AAEhC,YAAY,EAAE,WAAW,EAAE,eAAe,EAAE,YAAY,EAAE,CAAC;AAe3D,2DAA2D;AAC3D,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAOrD;AAED,wBAAgB,gBAAgB,IAAI,MAAM,CAEzC;AAED,+BAA+B;AAC/B,wBAAgB,QAAQ,IAAI,IAAI,CAO/B;AA4FD,sDAAsD;AACtD,wBAAsB,mBAAmB,CACrC,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,GAClB,OAAO,CAAC,eAAe,CAAC,CA4B1B;AAED,wDAAwD;AACxD,wBAAsB,gBAAgB,CAClC,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,QAAQ,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,YAAY,CAAC,
|
|
1
|
+
{"version":3,"file":"context-db.d.ts","sourceRoot":"","sources":["../../../src/tui/data/context-db.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EACR,WAAW,EAEX,eAAe,EACf,YAAY,EACf,MAAM,wBAAwB,CAAC;AAEhC,YAAY,EAAE,WAAW,EAAE,eAAe,EAAE,YAAY,EAAE,CAAC;AAe3D,2DAA2D;AAC3D,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAOrD;AAED,wBAAgB,gBAAgB,IAAI,MAAM,CAEzC;AAED,+BAA+B;AAC/B,wBAAgB,QAAQ,IAAI,IAAI,CAO/B;AA4FD,sDAAsD;AACtD,wBAAsB,mBAAmB,CACrC,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,GAClB,OAAO,CAAC,eAAe,CAAC,CA4B1B;AAED,wDAAwD;AACxD,wBAAsB,gBAAgB,CAClC,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,QAAQ,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,YAAY,CAAC,CA0CvB;AAYD,gEAAgE;AAChE,wBAAsB,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAchG;AAED,qCAAqC;AACrC,wBAAsB,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAQ5E;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,MAAM,WAAW,UAAU;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,SAAS,CAAC,EAAE,MAAM,CAAC;CACtB;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;AAED,yDAAyD;AACzD,wBAAsB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,CAyBjF;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,GAAG,IAAI,CAWtF"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cortexkit/opencode-magic-context",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.27.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "OpenCode plugin for Magic Context — cross-session memory and context management",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -41,10 +41,12 @@
|
|
|
41
41
|
},
|
|
42
42
|
"dependencies": {
|
|
43
43
|
"@huggingface/transformers": "^4.1.0",
|
|
44
|
+
"@jitl/quickjs-singlefile-cjs-release-asyncify": "0.32.0",
|
|
44
45
|
"@opencode-ai/plugin": "^1.15.13",
|
|
45
46
|
"@opencode-ai/sdk": "^1.15.13",
|
|
46
47
|
"ai-tokenizer": "^1.0.6",
|
|
47
48
|
"comment-json": "^4.2.5",
|
|
49
|
+
"quickjs-emscripten": "^0.32.0",
|
|
48
50
|
"zod": "^4.1.8"
|
|
49
51
|
},
|
|
50
52
|
"devDependencies": {
|
|
@@ -174,4 +174,24 @@ describe("shouldShowAnnouncement gating", () => {
|
|
|
174
174
|
markAnnouncementSeen("0.0.0-pre-historic");
|
|
175
175
|
expect(shouldShowAnnouncement()).toBe(true);
|
|
176
176
|
});
|
|
177
|
+
|
|
178
|
+
test("does NOT re-announce on a downgrade (stored version is newer)", async () => {
|
|
179
|
+
const mod = await import(`./announcement?t=${Date.now()}-downgrade`);
|
|
180
|
+
const {
|
|
181
|
+
ANNOUNCEMENT_VERSION,
|
|
182
|
+
ANNOUNCEMENT_FEATURES,
|
|
183
|
+
markAnnouncementSeen,
|
|
184
|
+
shouldShowAnnouncement,
|
|
185
|
+
} = mod;
|
|
186
|
+
|
|
187
|
+
if (!ANNOUNCEMENT_VERSION || ANNOUNCEMENT_FEATURES.length === 0) {
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
// Stored version is far newer than the running binary (user downgraded).
|
|
192
|
+
// A bare string-inequality gate would re-show the OLD announcement; the
|
|
193
|
+
// semver gate must stay quiet (current is NOT > stored).
|
|
194
|
+
markAnnouncementSeen("999.0.0");
|
|
195
|
+
expect(shouldShowAnnouncement()).toBe(false);
|
|
196
|
+
});
|
|
177
197
|
});
|
|
@@ -17,24 +17,25 @@
|
|
|
17
17
|
|
|
18
18
|
import * as fs from "node:fs";
|
|
19
19
|
import * as path from "node:path";
|
|
20
|
+
import { compareSemverCore } from "../hooks/auto-update-checker/semver";
|
|
20
21
|
import { getMagicContextStorageDir } from "./data-path";
|
|
21
22
|
|
|
22
23
|
/**
|
|
23
24
|
* Bump only when there are user-visible changes worth a startup dialog.
|
|
24
25
|
* Does NOT need to match the published package version.
|
|
25
26
|
*/
|
|
26
|
-
export const ANNOUNCEMENT_VERSION = "0.
|
|
27
|
+
export const ANNOUNCEMENT_VERSION = "0.27.0";
|
|
27
28
|
|
|
28
29
|
/**
|
|
29
30
|
* Short, user-facing bullet strings. Keep each line ~80 chars or shorter so the
|
|
30
31
|
* TUI dialog renders cleanly without horizontal scroll on a typical terminal.
|
|
31
32
|
*/
|
|
32
33
|
export const ANNOUNCEMENT_FEATURES: ReadonlyArray<string> = [
|
|
33
|
-
"
|
|
34
|
-
"
|
|
35
|
-
"
|
|
36
|
-
"
|
|
37
|
-
"
|
|
34
|
+
"Dreamer V2: each maintenance task now runs on its own schedule (cron), with its own model. Configure them in setup, the dashboard, or magic-context.jsonc.",
|
|
35
|
+
"New 'classify' task scores each memory's importance so the most relevant stay in context as your work shifts; new 'retrospective' learns from moments you had to correct or re-explain. Both cache-safe, on by default, off anytime.",
|
|
36
|
+
"New Primers: durable answers to the questions that keep coming up about your project, kept current by the dreamer investigating the actual code.",
|
|
37
|
+
"Embedding storage no longer wipes your vectors when you change model or endpoint. Different models now coexist, so switching providers keeps your existing vectors.",
|
|
38
|
+
"Config moved to a shared CortexKit location (~/.config/cortexkit/ and <project>/.cortexkit/). This happens automatically on first run; your old file is preserved.",
|
|
38
39
|
];
|
|
39
40
|
|
|
40
41
|
/**
|
|
@@ -130,5 +131,16 @@ export function shouldShowAnnouncement(): boolean {
|
|
|
130
131
|
// Do not advance the version; a later successful boot can still show it.
|
|
131
132
|
return false;
|
|
132
133
|
}
|
|
133
|
-
|
|
134
|
+
// Show ONLY on a forward version change (current > stored). A bare string
|
|
135
|
+
// inequality re-announced on a DOWNGRADE (0.27.0 → 0.26.0) or when stored
|
|
136
|
+
// state held an unexpected value. compareSemverCore returns null for
|
|
137
|
+
// non-semver input → treat conservatively (don't announce).
|
|
138
|
+
const ordering = compareSemverCore(ANNOUNCEMENT_VERSION, state.version);
|
|
139
|
+
if (ordering === null) {
|
|
140
|
+
// Stored version isn't parseable as semver but differs from current: only
|
|
141
|
+
// announce when it's genuinely not the current string (avoids re-showing on
|
|
142
|
+
// every boot for a corrupt-but-present value).
|
|
143
|
+
return state.version !== ANNOUNCEMENT_VERSION;
|
|
144
|
+
}
|
|
145
|
+
return ordering > 0;
|
|
134
146
|
}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { afterEach, beforeEach, describe, expect, test } from "bun:test";
|
|
2
|
+
import { mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs";
|
|
2
3
|
import * as os from "node:os";
|
|
3
4
|
import * as path from "node:path";
|
|
4
5
|
import {
|
|
6
|
+
ensureCortexKitArtifactGitignore,
|
|
5
7
|
getCacheDir,
|
|
6
8
|
getDataDir,
|
|
7
9
|
getLegacyOpenCodeMagicContextStorageDir,
|
|
@@ -121,20 +123,20 @@ describe("data-path", () => {
|
|
|
121
123
|
expect(shared).toContain("cortexkit");
|
|
122
124
|
});
|
|
123
125
|
|
|
124
|
-
test("getProjectMagicContextDir composes <project>/.
|
|
126
|
+
test("getProjectMagicContextDir composes <project>/.cortexkit/magic-context", () => {
|
|
125
127
|
// Project-local artifacts (historian state file, failure dumps) live
|
|
126
128
|
// inside the project so OpenCode's external_directory permission system
|
|
127
129
|
// treats them as project-internal. Without this, historian's Read tool
|
|
128
130
|
// would trigger a permission prompt on every run when artifacts lived
|
|
129
|
-
// under os.tmpdir().
|
|
131
|
+
// under os.tmpdir(). Moved from .opencode/ to the shared .cortexkit/.
|
|
130
132
|
expect(getProjectMagicContextDir("/Users/me/Work/proj")).toBe(
|
|
131
|
-
path.join("/Users/me/Work/proj", ".
|
|
133
|
+
path.join("/Users/me/Work/proj", ".cortexkit", "magic-context"),
|
|
132
134
|
);
|
|
133
135
|
});
|
|
134
136
|
|
|
135
137
|
test("getProjectMagicContextHistorianDir appends historian/", () => {
|
|
136
138
|
expect(getProjectMagicContextHistorianDir("/Users/me/Work/proj")).toBe(
|
|
137
|
-
path.join("/Users/me/Work/proj", ".
|
|
139
|
+
path.join("/Users/me/Work/proj", ".cortexkit", "magic-context", "historian"),
|
|
138
140
|
);
|
|
139
141
|
});
|
|
140
142
|
|
|
@@ -145,7 +147,7 @@ describe("data-path", () => {
|
|
|
145
147
|
// project-local historian dir.
|
|
146
148
|
process.env.XDG_DATA_HOME = "/tmp/custom-data";
|
|
147
149
|
expect(getProjectMagicContextDir("/some/project")).toBe(
|
|
148
|
-
path.join("/some/project", ".
|
|
150
|
+
path.join("/some/project", ".cortexkit", "magic-context"),
|
|
149
151
|
);
|
|
150
152
|
});
|
|
151
153
|
|
|
@@ -153,7 +155,69 @@ describe("data-path", () => {
|
|
|
153
155
|
// path.join normalizes redundant separators so callers don't need to
|
|
154
156
|
// worry about how the project directory was constructed.
|
|
155
157
|
expect(getProjectMagicContextDir("/some/project/")).toBe(
|
|
156
|
-
path.join("/some/project/", ".
|
|
158
|
+
path.join("/some/project/", ".cortexkit", "magic-context"),
|
|
157
159
|
);
|
|
158
160
|
});
|
|
159
161
|
});
|
|
162
|
+
|
|
163
|
+
describe("ensureCortexKitArtifactGitignore", () => {
|
|
164
|
+
test("creates .cortexkit/.gitignore with a fenced magic-context block", () => {
|
|
165
|
+
const dir = mkdtempSync(path.join(os.tmpdir(), "mc-gi-"));
|
|
166
|
+
try {
|
|
167
|
+
ensureCortexKitArtifactGitignore(dir);
|
|
168
|
+
const gi = readFileSync(path.join(dir, ".cortexkit", ".gitignore"), "utf8");
|
|
169
|
+
expect(gi).toContain("# >>> cortexkit:magic-context");
|
|
170
|
+
expect(gi).toContain("magic-context/");
|
|
171
|
+
expect(gi).toContain("# <<< cortexkit:magic-context");
|
|
172
|
+
} finally {
|
|
173
|
+
rmSync(dir, { recursive: true, force: true });
|
|
174
|
+
}
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
test("is idempotent — a second call does not duplicate the block", () => {
|
|
178
|
+
const dir = mkdtempSync(path.join(os.tmpdir(), "mc-gi-"));
|
|
179
|
+
try {
|
|
180
|
+
ensureCortexKitArtifactGitignore(dir);
|
|
181
|
+
ensureCortexKitArtifactGitignore(dir);
|
|
182
|
+
const gi = readFileSync(path.join(dir, ".cortexkit", ".gitignore"), "utf8");
|
|
183
|
+
const occurrences = gi.split("# >>> cortexkit:magic-context").length - 1;
|
|
184
|
+
expect(occurrences).toBe(1);
|
|
185
|
+
} finally {
|
|
186
|
+
rmSync(dir, { recursive: true, force: true });
|
|
187
|
+
}
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
test("preserves a sibling module's existing entries (appends, never clobbers)", () => {
|
|
191
|
+
const dir = mkdtempSync(path.join(os.tmpdir(), "mc-gi-"));
|
|
192
|
+
try {
|
|
193
|
+
const ckDir = path.join(dir, ".cortexkit");
|
|
194
|
+
mkdirSync(ckDir, { recursive: true });
|
|
195
|
+
// Simulate a sibling (e.g. AFT) already owning a fenced block.
|
|
196
|
+
writeFileSync(
|
|
197
|
+
path.join(ckDir, ".gitignore"),
|
|
198
|
+
"# >>> cortexkit:aft\naft/scratch/\n# <<< cortexkit:aft\n",
|
|
199
|
+
);
|
|
200
|
+
ensureCortexKitArtifactGitignore(dir);
|
|
201
|
+
const gi = readFileSync(path.join(ckDir, ".gitignore"), "utf8");
|
|
202
|
+
expect(gi).toContain("# >>> cortexkit:aft");
|
|
203
|
+
expect(gi).toContain("aft/scratch/");
|
|
204
|
+
expect(gi).toContain("# >>> cortexkit:magic-context");
|
|
205
|
+
expect(gi).toContain("magic-context/");
|
|
206
|
+
} finally {
|
|
207
|
+
rmSync(dir, { recursive: true, force: true });
|
|
208
|
+
}
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
test("does not ignore the project config — only the artifact dir", () => {
|
|
212
|
+
const dir = mkdtempSync(path.join(os.tmpdir(), "mc-gi-"));
|
|
213
|
+
try {
|
|
214
|
+
ensureCortexKitArtifactGitignore(dir);
|
|
215
|
+
const gi = readFileSync(path.join(dir, ".cortexkit", ".gitignore"), "utf8");
|
|
216
|
+
// The config file stays tracked: it must NOT appear as an ignore.
|
|
217
|
+
expect(gi).not.toContain("magic-context.jsonc");
|
|
218
|
+
expect(gi).not.toContain("*.jsonc");
|
|
219
|
+
} finally {
|
|
220
|
+
rmSync(dir, { recursive: true, force: true });
|
|
221
|
+
}
|
|
222
|
+
});
|
|
223
|
+
});
|
package/src/shared/data-path.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
1
2
|
import * as os from "node:os";
|
|
2
3
|
import * as path from "node:path";
|
|
3
4
|
import { getHarness, type HarnessId } from "./harness";
|
|
@@ -62,28 +63,69 @@ export function getMagicContextHistorianDir(harness: HarnessId = getHarness()):
|
|
|
62
63
|
/**
|
|
63
64
|
* Project-local magic-context artifact directory.
|
|
64
65
|
*
|
|
65
|
-
* Layout: `<project-directory>/.
|
|
66
|
+
* Layout: `<project-directory>/.cortexkit/magic-context/`
|
|
66
67
|
*
|
|
67
68
|
* Used for artifacts that the historian/recomp pipeline writes during a run
|
|
68
69
|
* and that the model is asked to read via its native Read tool. OpenCode's
|
|
69
70
|
* `external_directory` permission system asks the user before reading any
|
|
70
71
|
* file outside the project directory or its worktree, which interrupts every
|
|
71
72
|
* historian run when artifacts live under `os.tmpdir()`. Writing under the
|
|
72
|
-
* project's own `.
|
|
73
|
+
* project's own `.cortexkit/` subtree falls inside the project boundary and
|
|
73
74
|
* never triggers a permission prompt.
|
|
74
75
|
*
|
|
75
|
-
*
|
|
76
|
-
*
|
|
77
|
-
*
|
|
78
|
-
*
|
|
79
|
-
*
|
|
76
|
+
* `.cortexkit/` is the shared CortexKit per-project dir (also holds the
|
|
77
|
+
* project config `magic-context.jsonc`). Because these artifacts are transient
|
|
78
|
+
* debug dumps that shouldn't dirty the user's repo, the first write also drops
|
|
79
|
+
* a fenced-block `.gitignore` entry ignoring this subdir (see
|
|
80
|
+
* ensureCortexKitArtifactGitignore) while leaving `*.jsonc` config tracked.
|
|
81
|
+
*
|
|
82
|
+
* Migration note: artifacts used to live under `.opencode/magic-context/`. We
|
|
83
|
+
* cut the write path forward only — old transient dumps are git-ignored and
|
|
84
|
+
* regenerated, so they are intentionally NOT migrated (left to be cleaned).
|
|
80
85
|
*
|
|
81
86
|
* Logger does NOT use this — log files stay in the per-harness tmp subtree
|
|
82
87
|
* because they are written by the plugin process itself (no model-side Read
|
|
83
88
|
* tool call, no permission prompt) and span sessions/projects.
|
|
84
89
|
*/
|
|
85
90
|
export function getProjectMagicContextDir(directory: string): string {
|
|
86
|
-
return path.join(directory, ".
|
|
91
|
+
return path.join(directory, ".cortexkit", "magic-context");
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
const GITIGNORE_GUARD_OPEN = "# >>> cortexkit:magic-context";
|
|
95
|
+
const GITIGNORE_GUARD_CLOSE = "# <<< cortexkit:magic-context";
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Ensure `<project>/.cortexkit/.gitignore` ignores Magic Context's transient
|
|
99
|
+
* artifact subdir (`magic-context/`) without touching anything else in the
|
|
100
|
+
* shared `.cortexkit/` dir — the project config `magic-context.jsonc` stays
|
|
101
|
+
* tracked, and any sibling module's (e.g. AFT's) entries are preserved.
|
|
102
|
+
*
|
|
103
|
+
* Uses the shared CortexKit fenced-block convention: each module owns exactly
|
|
104
|
+
* its `# >>> cortexkit:<module>` … `# <<< cortexkit:<module>` block and appends
|
|
105
|
+
* it idempotently (no-op when its own guard line is already present). This lets
|
|
106
|
+
* multiple cortexkit modules coexist in one `.gitignore` without clobbering.
|
|
107
|
+
*
|
|
108
|
+
* Best-effort: a write failure never blocks an artifact write (the caller
|
|
109
|
+
* already degrades gracefully on its own write failures).
|
|
110
|
+
*/
|
|
111
|
+
export function ensureCortexKitArtifactGitignore(directory: string): void {
|
|
112
|
+
try {
|
|
113
|
+
const cortexKitDir = path.join(directory, ".cortexkit");
|
|
114
|
+
const gitignorePath = path.join(cortexKitDir, ".gitignore");
|
|
115
|
+
let existing = "";
|
|
116
|
+
if (existsSync(gitignorePath)) {
|
|
117
|
+
existing = readFileSync(gitignorePath, "utf8");
|
|
118
|
+
// Already fenced by us — nothing to do.
|
|
119
|
+
if (existing.includes(GITIGNORE_GUARD_OPEN)) return;
|
|
120
|
+
}
|
|
121
|
+
const block = `${GITIGNORE_GUARD_OPEN}\nmagic-context/\n${GITIGNORE_GUARD_CLOSE}\n`;
|
|
122
|
+
const needsLeadingNewline = existing.length > 0 && !existing.endsWith("\n");
|
|
123
|
+
const next = existing + (needsLeadingNewline ? "\n" : "") + block;
|
|
124
|
+
mkdirSync(cortexKitDir, { recursive: true });
|
|
125
|
+
writeFileSync(gitignorePath, next, "utf8");
|
|
126
|
+
} catch {
|
|
127
|
+
// best-effort — never block an artifact write on the gitignore.
|
|
128
|
+
}
|
|
87
129
|
}
|
|
88
130
|
|
|
89
131
|
/**
|
|
@@ -1,17 +1,25 @@
|
|
|
1
1
|
import { describe, expect, mock, test } from "bun:test";
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
promptSyncWithModelSuggestionRetry,
|
|
5
|
+
promptSyncWithValidatedOutputRetry,
|
|
6
|
+
} from "./model-suggestion-retry";
|
|
4
7
|
|
|
5
8
|
type PromptCall = {
|
|
6
9
|
body: { model?: { providerID: string; modelID: string } };
|
|
7
10
|
signal?: AbortSignal;
|
|
8
11
|
};
|
|
9
12
|
|
|
10
|
-
function createClient(
|
|
13
|
+
function createClient(
|
|
14
|
+
prompt: ReturnType<typeof mock>,
|
|
15
|
+
abort?: ReturnType<typeof mock>,
|
|
16
|
+
messages?: ReturnType<typeof mock>,
|
|
17
|
+
) {
|
|
11
18
|
return {
|
|
12
19
|
session: {
|
|
13
20
|
prompt,
|
|
14
21
|
abort: abort ?? mock(async () => ({})),
|
|
22
|
+
messages: messages ?? mock(async () => []),
|
|
15
23
|
},
|
|
16
24
|
} as never;
|
|
17
25
|
}
|
|
@@ -309,3 +317,72 @@ describe("promptSyncWithModelSuggestionRetry", () => {
|
|
|
309
317
|
expect(prompt).toHaveBeenCalledTimes(1);
|
|
310
318
|
});
|
|
311
319
|
});
|
|
320
|
+
|
|
321
|
+
describe("promptSyncWithValidatedOutputRetry", () => {
|
|
322
|
+
test("valid first model returns without trying fallbacks", async () => {
|
|
323
|
+
const prompt = mock(async () => ({}));
|
|
324
|
+
const messages = mock(async () => "primary-output");
|
|
325
|
+
const client = createClient(prompt, undefined, messages);
|
|
326
|
+
|
|
327
|
+
const result = await promptSyncWithValidatedOutputRetry(client, createArgs(), {
|
|
328
|
+
fallbackModels: ["anthropic/claude-sonnet-4-6"],
|
|
329
|
+
fetchOutput: async () => messages(),
|
|
330
|
+
validateOutput: (output: string) => {
|
|
331
|
+
if (output.trim().length === 0) throw new Error("empty output");
|
|
332
|
+
return output.trim();
|
|
333
|
+
},
|
|
334
|
+
});
|
|
335
|
+
|
|
336
|
+
expect(result.validated).toBe("primary-output");
|
|
337
|
+
expect(prompt).toHaveBeenCalledTimes(1);
|
|
338
|
+
expect(messages).toHaveBeenCalledTimes(1);
|
|
339
|
+
});
|
|
340
|
+
|
|
341
|
+
test("empty first model tries the next fallback", async () => {
|
|
342
|
+
const prompt = mock(async () => ({}));
|
|
343
|
+
const messages = mock(async () =>
|
|
344
|
+
messages.mock.calls.length === 1 ? "" : "fallback-output",
|
|
345
|
+
);
|
|
346
|
+
const client = createClient(prompt, undefined, messages);
|
|
347
|
+
|
|
348
|
+
const result = await promptSyncWithValidatedOutputRetry(client, createArgs(), {
|
|
349
|
+
fallbackModels: ["anthropic/claude-sonnet-4-6"],
|
|
350
|
+
fetchOutput: async () => messages(),
|
|
351
|
+
validateOutput: (output: string, attempt) => {
|
|
352
|
+
if (output.trim().length === 0)
|
|
353
|
+
throw new Error(`empty output from ${attempt.label}`);
|
|
354
|
+
return output.trim();
|
|
355
|
+
},
|
|
356
|
+
});
|
|
357
|
+
|
|
358
|
+
expect(result.validated).toBe("fallback-output");
|
|
359
|
+
expect(prompt).toHaveBeenCalledTimes(2);
|
|
360
|
+
expect(messages).toHaveBeenCalledTimes(2);
|
|
361
|
+
expect((prompt.mock.calls[1]?.[0] as PromptCall).body.model).toEqual({
|
|
362
|
+
providerID: "anthropic",
|
|
363
|
+
modelID: "claude-sonnet-4-6",
|
|
364
|
+
});
|
|
365
|
+
});
|
|
366
|
+
|
|
367
|
+
test("all empty outputs surface the original validation failure", async () => {
|
|
368
|
+
const prompt = mock(async () => ({}));
|
|
369
|
+
const messages = mock(async () => "");
|
|
370
|
+
const client = createClient(prompt, undefined, messages);
|
|
371
|
+
|
|
372
|
+
await expect(
|
|
373
|
+
promptSyncWithValidatedOutputRetry(client, createArgs(), {
|
|
374
|
+
fallbackModels: ["anthropic/claude-sonnet-4-6"],
|
|
375
|
+
fetchOutput: async () => messages(),
|
|
376
|
+
validateOutput: (output: string, attempt) => {
|
|
377
|
+
if (output.trim().length === 0) {
|
|
378
|
+
throw new Error(`empty output from ${attempt.label}`);
|
|
379
|
+
}
|
|
380
|
+
return output.trim();
|
|
381
|
+
},
|
|
382
|
+
}),
|
|
383
|
+
).rejects.toThrow("empty output from primary");
|
|
384
|
+
|
|
385
|
+
expect(prompt).toHaveBeenCalledTimes(2);
|
|
386
|
+
expect(messages).toHaveBeenCalledTimes(2);
|
|
387
|
+
});
|
|
388
|
+
});
|