@cortexkit/opencode-magic-context 0.47.0 → 0.49.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/agents/magic-context-prompt.d.ts +1 -1
- package/dist/agents/magic-context-prompt.d.ts.map +1 -1
- package/dist/{announcement-y35wzg2r.js → announcement-fp14dw0n.js} +3 -2
- package/dist/auto-search-worker.js +27 -30
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/mural-model-deprecation.d.ts +15 -0
- package/dist/config/mural-model-deprecation.d.ts.map +1 -0
- package/dist/config/project-security.d.ts +0 -3
- package/dist/config/project-security.d.ts.map +1 -1
- package/dist/config/schema/magic-context.d.ts +10 -6
- package/dist/config/schema/magic-context.d.ts.map +1 -1
- package/dist/{conflict-warning-hook-z44ynfz7.js → conflict-warning-hook-kzx4dmk1.js} +12 -10
- package/dist/{context-wq4ffwyb.js → context-nj5f293n.js} +2765 -1925
- package/dist/{derive-budgets-ke12jnnh.js → derive-budgets-qz5rrr08.js} +4 -3
- package/dist/embedding-activity-g1dhes6g.js +10 -0
- package/dist/embedding-backfill-aetxv1vt.js +21 -0
- package/dist/embedding-cache-mgyr73ef.js +16 -0
- package/dist/embedding-worker.js +11 -9
- package/dist/features/magic-context/compaction-marker.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/evaluate-smart-notes.d.ts +1 -0
- package/dist/features/magic-context/dreamer/evaluate-smart-notes.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/task-config.d.ts +3 -3
- package/dist/features/magic-context/dreamer/task-config.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/task-executor.d.ts +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 +1 -0
- 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/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/message-index-async.d.ts +16 -3
- package/dist/features/magic-context/message-index-async.d.ts.map +1 -1
- package/dist/features/magic-context/message-index-bounded.d.ts +17 -0
- package/dist/features/magic-context/message-index-bounded.d.ts.map +1 -0
- package/dist/features/magic-context/message-index.d.ts +7 -1
- package/dist/features/magic-context/message-index.d.ts.map +1 -1
- package/dist/features/magic-context/mural/render-trigger.d.ts +7 -4
- package/dist/features/magic-context/mural/render-trigger.d.ts.map +1 -1
- package/dist/features/magic-context/pi-content-decisions.d.ts +7 -1
- package/dist/features/magic-context/pi-content-decisions.d.ts.map +1 -1
- package/dist/features/magic-context/search-rerank.d.ts +35 -0
- package/dist/features/magic-context/search-rerank.d.ts.map +1 -0
- package/dist/features/magic-context/search.d.ts +40 -0
- package/dist/features/magic-context/search.d.ts.map +1 -1
- package/dist/features/magic-context/session-activity.d.ts.map +1 -1
- package/dist/features/magic-context/smart-notes/runner.d.ts +1 -0
- package/dist/features/magic-context/smart-notes/runner.d.ts.map +1 -1
- package/dist/features/magic-context/storage-db.d.ts.map +1 -1
- package/dist/features/magic-context/storage-meta-persisted.d.ts +13 -2
- package/dist/features/magic-context/storage-meta-persisted.d.ts.map +1 -1
- package/dist/features/magic-context/storage-meta-session.d.ts +7 -1
- package/dist/features/magic-context/storage-meta-session.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-session-tables.d.ts +2 -0
- package/dist/features/magic-context/storage-session-tables.d.ts.map +1 -1
- package/dist/features/magic-context/storage-tag-identity-revision.d.ts +50 -0
- package/dist/features/magic-context/storage-tag-identity-revision.d.ts.map +1 -0
- package/dist/features/magic-context/storage-tags.d.ts +153 -4
- package/dist/features/magic-context/storage-tags.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/subagent-token-capture.d.ts.map +1 -1
- package/dist/features/magic-context/tagger.d.ts +2 -0
- package/dist/features/magic-context/tagger.d.ts.map +1 -1
- package/dist/features/magic-context/transform-decision-log.d.ts +4 -1
- package/dist/features/magic-context/transform-decision-log.d.ts.map +1 -1
- package/dist/harness-e4avh192.js +10 -0
- package/dist/hooks/magic-context/active-anthropic-turn.d.ts +2 -0
- package/dist/hooks/magic-context/active-anthropic-turn.d.ts.map +1 -1
- package/dist/hooks/magic-context/auto-search-deadline.d.ts.map +1 -1
- package/dist/hooks/magic-context/auto-search-replay.fixture.d.ts +24 -0
- package/dist/hooks/magic-context/auto-search-replay.fixture.d.ts.map +1 -0
- package/dist/hooks/magic-context/auto-search-runner.d.ts +1 -1
- package/dist/hooks/magic-context/auto-search-runner.d.ts.map +1 -1
- package/dist/hooks/magic-context/auto-search-worker-client.d.ts +34 -3
- package/dist/hooks/magic-context/auto-search-worker-client.d.ts.map +1 -1
- package/dist/hooks/magic-context/command-handler.d.ts +3 -0
- package/dist/hooks/magic-context/command-handler.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-recomp.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-trigger.d.ts.map +1 -1
- package/dist/hooks/magic-context/emergency-fail-closed.d.ts +28 -0
- package/dist/hooks/magic-context/emergency-fail-closed.d.ts.map +1 -1
- package/dist/hooks/magic-context/event-handler.d.ts.map +1 -1
- package/dist/hooks/magic-context/historian-host-runner.d.ts +8 -0
- package/dist/hooks/magic-context/historian-host-runner.d.ts.map +1 -1
- package/dist/hooks/magic-context/hook.d.ts +3 -2
- package/dist/hooks/magic-context/hook.d.ts.map +1 -1
- package/dist/hooks/magic-context/inject-compartments.d.ts.map +1 -1
- package/dist/hooks/magic-context/latest-thinking-recovery.d.ts +7 -0
- package/dist/hooks/magic-context/latest-thinking-recovery.d.ts.map +1 -1
- package/dist/hooks/magic-context/lkg-persist.d.ts +4 -3
- package/dist/hooks/magic-context/lkg-persist.d.ts.map +1 -1
- package/dist/hooks/magic-context/lkg-replay.d.ts +13 -8
- package/dist/hooks/magic-context/lkg-replay.d.ts.map +1 -1
- package/dist/hooks/magic-context/lkg-slot.d.ts +139 -2
- package/dist/hooks/magic-context/lkg-slot.d.ts.map +1 -1
- package/dist/hooks/magic-context/message-search-accepting-silent-worker.fixture.d.ts +2 -0
- package/dist/hooks/magic-context/message-search-accepting-silent-worker.fixture.d.ts.map +1 -0
- package/dist/hooks/magic-context/oc-stall-r2-warmup-worker.fixture.d.ts +2 -0
- package/dist/hooks/magic-context/oc-stall-r2-warmup-worker.fixture.d.ts.map +1 -0
- package/dist/hooks/magic-context/oc-stall-search-review.fixture.d.ts +2 -0
- package/dist/hooks/magic-context/oc-stall-search-review.fixture.d.ts.map +1 -0
- package/dist/hooks/magic-context/opencode1-to-model-messages.fixture.d.ts +63 -0
- package/dist/hooks/magic-context/opencode1-to-model-messages.fixture.d.ts.map +1 -0
- package/dist/hooks/magic-context/pass-outcome.d.ts +1 -0
- package/dist/hooks/magic-context/pass-outcome.d.ts.map +1 -1
- package/dist/hooks/magic-context/provider-visible-parts.d.ts +45 -0
- package/dist/hooks/magic-context/provider-visible-parts.d.ts.map +1 -0
- package/dist/hooks/magic-context/raw-ordinal-warmup-silent-worker.fixture.d.ts +2 -0
- package/dist/hooks/magic-context/raw-ordinal-warmup-silent-worker.fixture.d.ts.map +1 -0
- package/dist/hooks/magic-context/raw-ordinal-warmup-worker.d.ts +2 -0
- package/dist/hooks/magic-context/raw-ordinal-warmup-worker.d.ts.map +1 -0
- package/dist/hooks/magic-context/raw-ordinal-warmup.d.ts +87 -0
- package/dist/hooks/magic-context/raw-ordinal-warmup.d.ts.map +1 -0
- package/dist/hooks/magic-context/read-session-chunk.d.ts +19 -1
- package/dist/hooks/magic-context/read-session-chunk.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-formatting.d.ts +5 -0
- package/dist/hooks/magic-context/read-session-formatting.d.ts.map +1 -1
- package/dist/hooks/magic-context/read-session-raw.d.ts +118 -1
- package/dist/hooks/magic-context/read-session-raw.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/reasoning-budget.d.ts.map +1 -1
- package/dist/hooks/magic-context/rust-mode-transform.d.ts +36 -0
- package/dist/hooks/magic-context/rust-mode-transform.d.ts.map +1 -1
- package/dist/hooks/magic-context/sentinel.d.ts +41 -1
- package/dist/hooks/magic-context/sentinel.d.ts.map +1 -1
- package/dist/hooks/magic-context/shared-compartment-boundaries.d.ts +8 -1
- package/dist/hooks/magic-context/shared-compartment-boundaries.d.ts.map +1 -1
- package/dist/hooks/magic-context/strict-thinking-prefix.d.ts +8 -0
- package/dist/hooks/magic-context/strict-thinking-prefix.d.ts.map +1 -0
- package/dist/hooks/magic-context/strip-content.d.ts +14 -2
- package/dist/hooks/magic-context/strip-content.d.ts.map +1 -1
- package/dist/hooks/magic-context/system-prompt-hash.d.ts +1 -0
- package/dist/hooks/magic-context/system-prompt-hash.d.ts.map +1 -1
- package/dist/hooks/magic-context/tag-messages.d.ts +8 -0
- package/dist/hooks/magic-context/tag-messages.d.ts.map +1 -1
- package/dist/hooks/magic-context/tag-owner-warmup.d.ts +6 -0
- package/dist/hooks/magic-context/tag-owner-warmup.d.ts.map +1 -0
- package/dist/hooks/magic-context/tail-hygiene-walk.d.ts.map +1 -1
- package/dist/hooks/magic-context/token-count-exact.d.ts +35 -0
- package/dist/hooks/magic-context/token-count-exact.d.ts.map +1 -0
- package/dist/hooks/magic-context/transform-postprocess-phase.d.ts +13 -0
- package/dist/hooks/magic-context/transform-postprocess-phase.d.ts.map +1 -1
- package/dist/hooks/magic-context/transform.d.ts +9 -2
- package/dist/hooks/magic-context/transform.d.ts.map +1 -1
- package/dist/hooks/magic-context/wrapup-orchestrator.d.ts.map +1 -1
- package/dist/{index-q6hef7fh.js → index-0sahzkwr.js} +6 -19
- package/dist/{index-k5bdx1bx.js → index-0w56v4fm.js} +3 -5
- package/dist/{index-5gq3b2ya.js → index-1bt88epp.js} +227 -205
- package/dist/{index-cwf6s3ay.js → index-1g30axtz.js} +3279 -2907
- package/dist/{index-5a2r0p9f.js → index-1r0k9js3.js} +20 -13
- package/dist/index-2bvekkfy.js +11 -0
- package/dist/{index-6d9e1m08.js → index-2jcbj7r1.js} +13301 -13225
- package/dist/index-2jgwttpt.js +3269 -0
- package/dist/index-4dhv7mqz.js +131 -0
- package/dist/{index-sj29b3z2.js → index-4mjhqadz.js} +3 -3
- package/dist/{index-0c82743p.js → index-57mrqed8.js} +17 -15
- package/dist/{index-b35pxds2.js → index-58e3y90n.js} +1 -18
- package/dist/index-7jzrrxap.js +931 -0
- package/dist/index-8ajstryz.js +18 -0
- package/dist/{index-sfpzqvdz.js → index-8cd2j99z.js} +2 -3
- package/dist/{index-6wkcswft.js → index-9qjqq45k.js} +29 -19
- package/dist/{index-adwfkpex.js → index-9rt53q79.js} +23 -23
- package/dist/index-b7mv1jx3.js +1060 -0
- package/dist/index-d9vfe7xq.js +16 -0
- package/dist/{index-gg8j07zz.js → index-ezmszwbd.js} +8 -6
- package/dist/index-fb3zxn06.js +13 -0
- package/dist/index-fr0wbhdn.js +43 -0
- package/dist/{index-mc22ayvf.js → index-ghc9f0n7.js} +11 -9
- package/dist/index-gzcmtmar.js +171 -0
- package/dist/{index-w2t4ah5j.js → index-h2py7207.js} +6762 -7400
- package/dist/index-h2wc01qk.js +120 -0
- package/dist/index-h5zfkjyk.js +1277 -0
- package/dist/{index-92bp57hg.js → index-ha87j7a8.js} +1343 -149
- package/dist/index-hj2q50k0.js +856 -0
- package/dist/{index-wx8a6bw3.js → index-kb9nn0a0.js} +270 -53
- package/dist/index-kmpvemph.js +1314 -0
- package/dist/index-kp5qe690.js +3030 -0
- package/dist/{index-m5fe6jch.js → index-kq57tdf0.js} +152 -2453
- package/dist/{v2/server-fq7kq32k.js → index-mfkzp7qj.js} +1 -16
- package/dist/{v2/server-njt3np1k.js → index-nm6a8xpd.js} +220 -961
- package/dist/{index-hybnrwq0.js → index-nsjyysj0.js} +137 -130
- package/dist/index-nydv6g8r.js +3569 -0
- package/dist/index-pavzsdc6.js +17 -0
- package/dist/index-peshmj6h.js +152 -0
- package/dist/index-pxwp2hjk.js +571 -0
- package/dist/{v2/server-yr3zj7e7.js → index-qt1qqasc.js} +6 -7
- package/dist/{v2/server-51dv1pr5.js → index-qx53vezw.js} +301 -27
- package/dist/{index-rrrsepyw.js → index-s4j7t92z.js} +90 -85
- package/dist/{index-9pk9exrb.js → index-stbr4ce6.js} +18 -18
- package/dist/{index-fzbvakh0.js → index-tqf7yg27.js} +3 -3
- package/dist/index-vkbqdnkj.js +2307 -0
- package/dist/{index-8da2zjhz.js → index-z1tjp257.js} +9 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +608 -349
- package/dist/logger-ewak5q1s.js +20 -0
- package/dist/message-index-bounded-h0mrd4pr.js +124 -0
- package/dist/{v2/message-time-backfill-1f9tzvcs.js → message-time-backfill-8x06r9kx.js} +8 -6
- package/dist/migration-worker.js +25 -18
- package/dist/{model-resolution-xhfmyyvy.js → model-resolution-nx97z3x7.js} +1 -1
- package/dist/plugin/dream-timer.d.ts +1 -1
- package/dist/plugin/dream-timer.d.ts.map +1 -1
- package/dist/plugin/hooks/create-session-hooks.d.ts +3 -0
- package/dist/plugin/hooks/create-session-hooks.d.ts.map +1 -1
- package/dist/plugin/host-stall-profiler-report.d.ts +1 -66
- package/dist/plugin/host-stall-profiler-report.d.ts.map +1 -1
- package/dist/plugin/host-stall-profiler.d.ts +2 -95
- package/dist/plugin/host-stall-profiler.d.ts.map +1 -1
- package/dist/plugin/messages-transform.d.ts +0 -13
- package/dist/plugin/messages-transform.d.ts.map +1 -1
- package/dist/plugin/rpc-handlers.d.ts.map +1 -1
- package/dist/plugin/tool-registry.d.ts.map +1 -1
- package/dist/project-embedding-registry-rtt0djyb.js +88 -0
- package/dist/raw-ordinal-warmup-worker.js +60 -0
- package/dist/{read-session-chunk-4jey7hpt.js → read-session-chunk-ty89v75e.js} +17 -9
- package/dist/read-session-raw-8sjbc9h0.js +60 -0
- package/dist/recomp-orchestrator-4f1yyd1q.js +57 -0
- package/dist/{v2/safe-notification-target-eb1n1vfb.js → safe-notification-target-q0cyrx3x.js} +4 -2
- package/dist/search-pz4f4wge.js +45 -0
- package/dist/{v2/send-session-notification-c0wtscea.js → send-session-notification-38cd5dqt.js} +10 -7
- package/dist/shared/auto-search-lifecycle.d.ts +14 -0
- package/dist/shared/auto-search-lifecycle.d.ts.map +1 -1
- package/dist/shared/conflict-detector.d.ts.map +1 -1
- package/dist/shared/host-stall-profiler-bun.d.ts +46 -0
- package/dist/shared/host-stall-profiler-bun.d.ts.map +1 -0
- package/dist/shared/host-stall-profiler-common.d.ts +58 -0
- package/dist/shared/host-stall-profiler-common.d.ts.map +1 -0
- package/dist/shared/host-stall-profiler-node.d.ts +36 -0
- package/dist/shared/host-stall-profiler-node.d.ts.map +1 -0
- package/dist/shared/host-stall-profiler-report.d.ts +68 -0
- package/dist/shared/host-stall-profiler-report.d.ts.map +1 -0
- package/dist/shared/host-stall-profiler.d.ts +5 -0
- package/dist/shared/host-stall-profiler.d.ts.map +1 -0
- package/dist/shared/logger.d.ts.map +1 -1
- package/dist/shared/model-resolution.d.ts +2 -3
- package/dist/shared/model-resolution.d.ts.map +1 -1
- package/dist/shared/models-dev-temperature.d.ts +18 -0
- package/dist/shared/models-dev-temperature.d.ts.map +1 -0
- package/dist/shared/project-directory-key.d.ts +16 -0
- package/dist/shared/project-directory-key.d.ts.map +1 -1
- package/dist/shared/sqlite.d.ts +30 -0
- package/dist/shared/sqlite.d.ts.map +1 -1
- package/dist/shared/stable-json.d.ts.map +1 -1
- package/dist/shared/subagent-temperature.d.ts +46 -0
- package/dist/shared/subagent-temperature.d.ts.map +1 -0
- package/dist/shared/user-facing-codes.d.ts +0 -5
- package/dist/shared/user-facing-codes.d.ts.map +1 -1
- package/dist/sqlite-context-pragmas-mv9jqwjh.js +6 -0
- package/dist/sqlite-mhjkerzq.js +46 -0
- package/dist/storage-memory-07fx57k6.js +71 -0
- package/dist/storage-tags-k0pda32s.js +133 -0
- package/dist/{task-config-v81k8jvk.js → task-config-cgpg0nvh.js} +2 -2
- package/dist/tools/ctx-expand/tools.d.ts.map +1 -1
- package/dist/tools/ctx-note/constants.d.ts +4 -0
- package/dist/tools/ctx-note/constants.d.ts.map +1 -1
- package/dist/tools/ctx-note/tools.d.ts +1 -0
- package/dist/tools/ctx-note/tools.d.ts.map +1 -1
- package/dist/tools/ctx-reduce/tools.d.ts.map +1 -1
- package/dist/tools/ctx-search/tools.d.ts.map +1 -1
- package/dist/tools/ctx-search/types.d.ts +1 -0
- package/dist/tools/ctx-search/types.d.ts.map +1 -1
- package/dist/tools/parameter-descriptions.d.ts +2 -2
- package/dist/tools/parameter-descriptions.d.ts.map +1 -1
- package/dist/{transform-postprocess-phase-z5hzpsxv.js → transform-postprocess-phase-tck4g20s.js} +35 -20
- package/dist/transformers-node-wasm.js +18415 -18415
- package/dist/v2/auto-search-worker.js +27 -30
- package/dist/v2/{context-14v1hr8b.js → context-crbt6p1y.js} +4708 -4218
- package/dist/v2/{derive-budgets-nc9avxz8.js → derive-budgets-fgej9j46.js} +4 -3
- package/dist/v2/embedding-activity-g1dhes6g.js +10 -0
- package/dist/v2/embedding-backfill-ph1qfyn3.js +21 -0
- package/dist/v2/embedding-cache-mgyr73ef.js +16 -0
- package/dist/v2/embedding-worker.js +12 -9
- package/dist/v2/fold/host-media.d.ts +4 -0
- package/dist/v2/fold/host-media.d.ts.map +1 -1
- package/dist/v2/fold/memory-cache.d.ts +70 -0
- package/dist/v2/fold/memory-cache.d.ts.map +1 -0
- package/dist/v2/fold/native-codec.d.ts +10 -0
- package/dist/v2/fold/native-codec.d.ts.map +1 -0
- package/dist/v2/fold/native-replay.d.ts +58 -0
- package/dist/v2/fold/native-replay.d.ts.map +1 -0
- package/dist/v2/fold/policy.d.ts +24 -0
- package/dist/v2/fold/policy.d.ts.map +1 -0
- package/dist/v2/harness-e4avh192.js +10 -0
- package/dist/v2/hidden-child-native.d.ts.map +1 -1
- package/dist/v2/hidden-completion.d.ts +7 -0
- package/dist/v2/hidden-completion.d.ts.map +1 -1
- package/dist/v2/hooks/context.d.ts +2 -2
- package/dist/v2/hooks/context.d.ts.map +1 -1
- package/dist/v2/hooks/dream-manual.d.ts +1 -1
- package/dist/v2/hooks/dream-manual.d.ts.map +1 -1
- package/dist/v2/hooks/dream-timer.d.ts.map +1 -1
- package/dist/v2/hooks/dream-trigger.d.ts +5 -3
- package/dist/v2/hooks/dream-trigger.d.ts.map +1 -1
- package/dist/v2/hooks/generate.d.ts +9 -2
- package/dist/v2/hooks/generate.d.ts.map +1 -1
- package/dist/v2/hooks/payload.d.ts.map +1 -1
- package/dist/v2/hooks/tools.d.ts.map +1 -1
- package/dist/v2/hooks/types.d.ts +6 -0
- package/dist/v2/hooks/types.d.ts.map +1 -1
- package/dist/v2/logger-pj02s7sr.js +19 -0
- package/dist/v2/message-index-bounded-xwqdywxg.js +123 -0
- package/dist/{message-time-backfill-r5epkzj3.js → v2/message-time-backfill-cje68egj.js} +7 -7
- package/dist/v2/migration-worker.js +24 -17
- package/dist/v2/{model-resolution-xhfmyyvy.js → model-resolution-nx97z3x7.js} +1 -1
- package/dist/v2/project-embedding-registry-d6m7tyxr.js +86 -0
- package/dist/v2/raw-ordinal-warmup-worker.js +60 -0
- package/dist/v2/{read-session-chunk-gyyv7w2r.js → read-session-chunk-8p5mdryx.js} +16 -8
- package/dist/v2/read-session-raw-j8dvp7f4.js +59 -0
- package/dist/v2/recomp-orchestrator-ckfgt6wq.js +57 -0
- package/dist/{safe-notification-target-43r8jsxw.js → v2/safe-notification-target-y3p1hce9.js} +3 -3
- package/dist/v2/search-ym8rehhz.js +45 -0
- package/dist/{send-session-notification-0m68ms3n.js → v2/send-session-notification-5m0yapqx.js} +9 -8
- package/dist/v2/{server-rz514f14.js → server-19zjmn02.js} +2044 -2060
- package/dist/v2/server-1tk82krw.js +796 -0
- package/dist/v2/server-2bvekkfy.js +11 -0
- package/dist/v2/{server-ajzeteqw.js → server-2ra6pwf3.js} +1 -18
- package/dist/v2/server-2s6ayq3t.js +1048 -0
- package/dist/v2/{server-fcdehk1s.js → server-2s9qz6n7.js} +4 -4
- package/dist/v2/server-3j4d00kf.js +171 -0
- package/dist/v2/{server-14vq4kpm.js → server-3t0q2cqx.js} +3 -3
- package/dist/v2/server-4dhv7mqz.js +131 -0
- package/dist/v2/server-4ez8mntn.js +3213 -0
- package/dist/v2/{server-6r257mf5.js → server-676xw7at.js} +3 -3
- package/dist/v2/{server-vs5gpnd4.js → server-6byqfbqf.js} +165 -145
- package/dist/v2/server-7ekna9zs.js +120 -0
- package/dist/v2/server-7h861yms.js +1272 -0
- package/dist/v2/server-7jzrrxap.js +931 -0
- package/dist/v2/server-8ajstryz.js +18 -0
- package/dist/v2/{server-sfpzqvdz.js → server-8cd2j99z.js} +2 -3
- package/dist/v2/{server-cpepxy2q.js → server-8k2agx29.js} +14 -12
- package/dist/v2/server-c5rrgrcd.js +3545 -0
- package/dist/v2/server-d9vfe7xq.js +16 -0
- package/dist/v2/server-fb3zxn06.js +13 -0
- package/dist/v2/server-fr0wbhdn.js +43 -0
- package/dist/v2/{server-y10vbq6y.js → server-hb6xhh9q.js} +11 -1053
- package/dist/v2/server-jvxzm1jy.js +3023 -0
- package/dist/v2/{server-wx8a6bw3.js → server-kb9nn0a0.js} +270 -53
- package/dist/{index-5eqk6z3s.js → v2/server-kzns2hbz.js} +301 -27
- package/dist/{index-rrbbspwh.js → v2/server-mfkzp7qj.js} +1 -16
- package/dist/v2/server-pavzsdc6.js +17 -0
- package/dist/v2/{server-vd4e7174.js → server-pj4pjv02.js} +21 -17
- package/dist/v2/{server-e0c1b7a7.js → server-q4ph9bwn.js} +1340 -148
- package/dist/{index-yr3zj7e7.js → v2/server-qt1qqasc.js} +6 -7
- package/dist/v2/{server-qdjnb2z1.js → server-r5p3b1wy.js} +11 -9
- package/dist/v2/{server-d0sraw7m.js → server-sa8jvrfc.js} +291 -286
- package/dist/v2/server-ss95ky04.js +1048 -0
- package/dist/v2/{server-1qbnzc80.js → server-t4k4qexw.js} +142 -150
- package/dist/{index-x3kwrmqk.js → v2/server-v4mewb78.js} +35 -792
- package/dist/v2/server-w32kmdez.js +154 -0
- package/dist/v2/{server-nf82q6pt.js → server-x4hscabv.js} +5547 -5449
- package/dist/v2/server-xwz4dqh9.js +569 -0
- package/dist/v2/{server-efhwzx05.js → server-ycw9qqcy.js} +23 -23
- package/dist/v2/{server-50hvkg3v.js → server-zm570tr2.js} +160 -158
- package/dist/v2/server-zp53y8js.js +1311 -0
- package/dist/v2/server.js +16 -14
- package/dist/v2/sqlite-context-pragmas-mv9jqwjh.js +6 -0
- package/dist/v2/sqlite-mhjkerzq.js +46 -0
- package/dist/v2/storage-memory-07fx57k6.js +71 -0
- package/dist/v2/storage-tags-8vw924zn.js +132 -0
- package/dist/v2/store-reader.d.ts +24 -2
- package/dist/v2/store-reader.d.ts.map +1 -1
- package/dist/v2/{task-config-tbndqyny.js → task-config-x0hq3qfd.js} +2 -2
- package/dist/v2/transformers-node-wasm.js +18415 -18415
- package/dist/v2/tui/index.d.ts.map +1 -1
- package/dist/v2/tui/types.d.ts +1 -10
- package/dist/v2/tui/types.d.ts.map +1 -1
- package/dist/v2/{wrapup-orchestrator-nbz854vc.js → wrapup-orchestrator-a7efxaax.js} +51 -30
- package/dist/wrapup-orchestrator-barbc6h9.js +44 -0
- package/package.json +4 -3
- package/src/agents/magic-context-prompt.ts +27 -2
- package/src/agents/smart-notes-enabled.test.ts +294 -0
- package/src/agents/smart-notes-on.golden.json +70 -0
- package/src/config/index.test.ts +67 -1
- package/src/config/index.ts +2 -0
- package/src/config/latch-permanence-guard.test.ts +4 -0
- package/src/config/mural-model-deprecation.ts +24 -0
- package/src/config/project-security.hostile-matrix.test.ts +4 -44
- package/src/config/project-security.test.ts +9 -14
- package/src/config/project-security.ts +13 -55
- package/src/config/schema/magic-context.test.ts +2 -2
- package/src/config/schema/magic-context.ts +16 -10
- package/src/features/magic-context/dreamer/task-registry.ts +6 -0
- package/src/shared/auto-search-lifecycle.ts +43 -0
- package/src/shared/conflict-detector.test.ts +56 -0
- package/src/shared/conflict-detector.ts +16 -5
- package/src/shared/host-stall-profiler-bun.ts +358 -0
- package/src/shared/host-stall-profiler-common.ts +159 -0
- package/src/shared/host-stall-profiler-node.test.ts +234 -0
- package/src/shared/host-stall-profiler-node.ts +274 -0
- package/src/shared/host-stall-profiler-report.ts +248 -0
- package/src/shared/host-stall-profiler.ts +57 -0
- package/src/shared/logger.test.ts +38 -0
- package/src/shared/logger.ts +10 -2
- package/src/shared/model-resolution.test.ts +54 -17
- package/src/shared/model-resolution.ts +6 -17
- package/src/shared/models-dev-temperature.ts +107 -0
- package/src/shared/project-directory-key.test.ts +59 -0
- package/src/shared/project-directory-key.ts +20 -0
- package/src/shared/sqlite.test.ts +52 -0
- package/src/shared/sqlite.ts +339 -23
- package/src/shared/stable-json-linear.test.ts +109 -0
- package/src/shared/stable-json.ts +37 -7
- package/src/shared/subagent-temperature.test.ts +270 -0
- package/src/shared/subagent-temperature.ts +110 -0
- package/src/shared/user-facing-codes.ts +2 -6
- package/src/shared/write-transaction-attribution.test.ts +2 -2
- package/src/v2/tui/host-contract.test.ts +41 -67
- package/src/v2/tui/index.ts +6 -214
- package/src/v2/tui/types.ts +5 -17
- package/dist/features/magic-context/checkout-claim-fake-subc.test-support.d.ts +0 -45
- package/dist/features/magic-context/checkout-claim-fake-subc.test-support.d.ts.map +0 -1
- package/dist/features/magic-context/checkout-claim.d.ts +0 -155
- package/dist/features/magic-context/checkout-claim.d.ts.map +0 -1
- package/dist/index-bb36vgr3.js +0 -6608
- package/dist/index-fnn5pjtt.js +0 -6554
- package/dist/recomp-orchestrator-rervg6q4.js +0 -42
- package/dist/v2/recomp-orchestrator-42vjba7p.js +0 -42
- package/dist/v2/server-3trjk1hx.js +0 -6360
- package/dist/v2/server-nm9n3aqq.js +0 -6461
- package/dist/wrapup-orchestrator-b2dztrar.js +0 -29
- /package/dist/{index-5prbx026.js → index-2pp04pmg.js} +0 -0
- /package/dist/v2/{index-5prbx026.js → index-2pp04pmg.js} +0 -0
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared host stall report helpers. Both JavaScriptCore and V8 samples use
|
|
3
|
+
* innermost-first frames so native calls can be attributed to their JS caller.
|
|
4
|
+
*
|
|
5
|
+
* Kept separate from runtime backends so attribution can be tested without
|
|
6
|
+
* running watchdog timers or starting a sampling profiler.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { readFileSync } from "node:fs";
|
|
10
|
+
import * as path from "node:path";
|
|
11
|
+
|
|
12
|
+
/** One frame from Bun's JavaScriptCore sampling API; V8 frames are normalized to this shape. */
|
|
13
|
+
export interface JscSampleFrame {
|
|
14
|
+
name?: string;
|
|
15
|
+
sourceURL?: string;
|
|
16
|
+
line?: number;
|
|
17
|
+
column?: number;
|
|
18
|
+
category?: string;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/** One sample: `frames[0]` is the innermost (currently executing) frame. */
|
|
22
|
+
export interface JscSampleTrace {
|
|
23
|
+
/** Monotonic seconds. JSC has a separate origin; V8 conversion uses the watchdog clock. */
|
|
24
|
+
timestamp?: number;
|
|
25
|
+
frames?: JscSampleFrame[];
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/** Deepest stack kept per sample; deeper frames are folded into one marker. */
|
|
29
|
+
export const MAX_STACK_DEPTH = 64;
|
|
30
|
+
export const TOP_STACK_COUNT = 30;
|
|
31
|
+
export const TOP_FRAME_COUNT = 30;
|
|
32
|
+
|
|
33
|
+
/** JSC uses UINT32_MAX for "no line/column known". */
|
|
34
|
+
const UNKNOWN_POSITION = 4294967295;
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Owners that never explain a stall by themselves: a native host function is
|
|
38
|
+
* attributed to its JavaScript caller, and host-core/runtime frames sit below
|
|
39
|
+
* every plugin hook. A sample is attributed to the innermost frame whose owner
|
|
40
|
+
* is NOT one of these, so a plugin calling a blocking native API is blamed,
|
|
41
|
+
* not the native API or the host that invoked the plugin.
|
|
42
|
+
*/
|
|
43
|
+
const BACKGROUND_OWNERS = new Set(["native", "runtime", "opencode", "pi", "omp"]);
|
|
44
|
+
|
|
45
|
+
const packageNameCache = new Map<string, string | null>();
|
|
46
|
+
|
|
47
|
+
function urlToPath(url: string): string {
|
|
48
|
+
if (url.startsWith("file://")) {
|
|
49
|
+
try {
|
|
50
|
+
return decodeURIComponent(new URL(url).pathname);
|
|
51
|
+
} catch {
|
|
52
|
+
return url.slice("file://".length);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return url;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Nearest `package.json` name above a source file, memoized per directory.
|
|
60
|
+
* Only reached for sources outside `node_modules` (a plugin loaded from a
|
|
61
|
+
* local checkout), and only after a stall has ended, so the bounded
|
|
62
|
+
* synchronous reads never run on a hot path.
|
|
63
|
+
*/
|
|
64
|
+
function nearestPackageName(filePath: string): string | null {
|
|
65
|
+
let dir = path.dirname(filePath);
|
|
66
|
+
const visited: string[] = [];
|
|
67
|
+
for (let depth = 0; depth < 12; depth++) {
|
|
68
|
+
const cached = packageNameCache.get(dir);
|
|
69
|
+
if (cached !== undefined) {
|
|
70
|
+
for (const seen of visited) packageNameCache.set(seen, cached);
|
|
71
|
+
return cached;
|
|
72
|
+
}
|
|
73
|
+
visited.push(dir);
|
|
74
|
+
try {
|
|
75
|
+
const parsed = JSON.parse(readFileSync(path.join(dir, "package.json"), "utf8")) as {
|
|
76
|
+
name?: unknown;
|
|
77
|
+
};
|
|
78
|
+
const name = typeof parsed.name === "string" && parsed.name ? parsed.name : null;
|
|
79
|
+
if (name) {
|
|
80
|
+
for (const seen of visited) packageNameCache.set(seen, name);
|
|
81
|
+
return name;
|
|
82
|
+
}
|
|
83
|
+
} catch {
|
|
84
|
+
// No readable package.json at this level; keep walking up.
|
|
85
|
+
}
|
|
86
|
+
const parent = path.dirname(dir);
|
|
87
|
+
if (parent === dir) break;
|
|
88
|
+
dir = parent;
|
|
89
|
+
}
|
|
90
|
+
for (const seen of visited) packageNameCache.set(seen, null);
|
|
91
|
+
return null;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Map a frame's source URL to the code that owns it.
|
|
96
|
+
*
|
|
97
|
+
* - no URL: `native` (a host function such as a SQLite `get` or `readFileSync`)
|
|
98
|
+
* - Bun/Node builtin modules: `runtime`
|
|
99
|
+
* - the compiled OpenCode binary's embedded filesystem (`$bunfs`, `~BUN`): `opencode`
|
|
100
|
+
* - anything under `node_modules/<pkg>`: `npm:<pkg>` (the innermost package)
|
|
101
|
+
* - Pi/OMP core packages: `pi` / `omp`; agent extensions: package name or `extension:<entry>`
|
|
102
|
+
* - a file in an OpenCode `plugin/` or `plugins/` directory: `plugin:<file>`
|
|
103
|
+
* - any other file: `pkg:<name>` from the nearest package.json, else `file:<path>`
|
|
104
|
+
*/
|
|
105
|
+
export function sourceOwner(sourceURL: string | undefined): string {
|
|
106
|
+
if (!sourceURL) return "native";
|
|
107
|
+
if (/^(?:node|bun|builtin|internal):/.test(sourceURL)) return "runtime";
|
|
108
|
+
if (sourceURL.includes("$bunfs") || sourceURL.includes("~BUN")) return "opencode";
|
|
109
|
+
const filePath = urlToPath(sourceURL).replaceAll("\\", "/");
|
|
110
|
+
const modules = [...filePath.matchAll(/\/node_modules\/((?:@[^/]+\/)?[^/]+)/g)];
|
|
111
|
+
const innermost = modules.at(-1);
|
|
112
|
+
if (innermost) {
|
|
113
|
+
const name = innermost[1];
|
|
114
|
+
if (name === "@cortexkit/pi-magic-context") return `pkg:${name}`;
|
|
115
|
+
if (/^@(?:earendil-works|mariozechner)\/pi-(?:coding-agent|agent-core|ai|tui)$/.test(name))
|
|
116
|
+
return "pi";
|
|
117
|
+
if (/^@oh-my-pi\/pi-(?:coding-agent|agent-core|ai|tui)$/.test(name)) return "omp";
|
|
118
|
+
return `npm:${name}`;
|
|
119
|
+
}
|
|
120
|
+
const extension = filePath.match(/\/(?:\.pi|\.omp)\/agent\/extensions\/([^/]+)/);
|
|
121
|
+
if (extension) {
|
|
122
|
+
const name = nearestPackageName(filePath);
|
|
123
|
+
return name ? `pkg:${name}` : `extension:${extension[1]}`;
|
|
124
|
+
}
|
|
125
|
+
const pluginDir = filePath.match(/\/plugins?\/([^/]+)$/);
|
|
126
|
+
if (pluginDir && /\/(?:\.?opencode)\/plugins?\//.test(filePath)) {
|
|
127
|
+
return `plugin:${pluginDir[1]}`;
|
|
128
|
+
}
|
|
129
|
+
const name = nearestPackageName(filePath);
|
|
130
|
+
return name ? `pkg:${name}` : `file:${filePath}`;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
function frameLabel(frame: JscSampleFrame): string {
|
|
134
|
+
const name = frame.name && frame.name.length > 0 ? frame.name : "(anonymous)";
|
|
135
|
+
if (!frame.sourceURL) return `${name} [native]`;
|
|
136
|
+
const line =
|
|
137
|
+
typeof frame.line === "number" && frame.line !== UNKNOWN_POSITION ? `:${frame.line}` : "";
|
|
138
|
+
return `${name} ${frame.sourceURL}${line}`;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
export interface OwnedFrame {
|
|
142
|
+
label: string;
|
|
143
|
+
owner: string;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/** Prefer the innermost plugin/extension frame over native, runtime or host-core callers. */
|
|
147
|
+
export function attributeSample(frames: OwnedFrame[]): string {
|
|
148
|
+
for (const frame of frames) {
|
|
149
|
+
if (!BACKGROUND_OWNERS.has(frame.owner)) return frame.owner;
|
|
150
|
+
}
|
|
151
|
+
for (const frame of frames) {
|
|
152
|
+
if (frame.owner !== "native") return frame.owner;
|
|
153
|
+
}
|
|
154
|
+
return "native";
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
export interface CountedFrame {
|
|
158
|
+
frame: string;
|
|
159
|
+
owner: string;
|
|
160
|
+
samples: number;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
export interface CountedStack {
|
|
164
|
+
samples: number;
|
|
165
|
+
owner: string;
|
|
166
|
+
frames: string[];
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
export interface StallAggregate {
|
|
170
|
+
samples: number;
|
|
171
|
+
owners: Array<{ owner: string; samples: number; percent: number }>;
|
|
172
|
+
/** Innermost frame of each sample, native host functions included. */
|
|
173
|
+
top_frames: CountedFrame[];
|
|
174
|
+
/** Innermost frame that has JavaScript source, i.e. the JS caller of any native frame. */
|
|
175
|
+
top_js_frames: CountedFrame[];
|
|
176
|
+
top_stacks: CountedStack[];
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
function bump<T>(map: Map<string, T & { samples: number }>, key: string, init: () => T): void {
|
|
180
|
+
const existing = map.get(key);
|
|
181
|
+
if (existing) existing.samples += 1;
|
|
182
|
+
else map.set(key, { ...init(), samples: 1 });
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
function topBySamples<T extends { samples: number }>(values: Iterable<T>, limit: number): T[] {
|
|
186
|
+
return [...values].sort((a, b) => b.samples - a.samples).slice(0, limit);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
export function aggregateTraces(traces: JscSampleTrace[]): StallAggregate {
|
|
190
|
+
const ownerOf = new Map<string, string>();
|
|
191
|
+
const owned = (frame: JscSampleFrame): OwnedFrame => {
|
|
192
|
+
const url = frame.sourceURL ?? "";
|
|
193
|
+
let owner = ownerOf.get(url);
|
|
194
|
+
if (owner === undefined) {
|
|
195
|
+
owner = sourceOwner(frame.sourceURL);
|
|
196
|
+
ownerOf.set(url, owner);
|
|
197
|
+
}
|
|
198
|
+
return { label: frameLabel(frame), owner };
|
|
199
|
+
};
|
|
200
|
+
|
|
201
|
+
const owners = new Map<string, { owner: string; samples: number }>();
|
|
202
|
+
const topFrames = new Map<string, CountedFrame>();
|
|
203
|
+
const topJsFrames = new Map<string, CountedFrame>();
|
|
204
|
+
const stacks = new Map<string, CountedStack>();
|
|
205
|
+
let samples = 0;
|
|
206
|
+
|
|
207
|
+
for (const trace of traces) {
|
|
208
|
+
const raw = Array.isArray(trace.frames) ? trace.frames : [];
|
|
209
|
+
if (raw.length === 0) continue;
|
|
210
|
+
samples += 1;
|
|
211
|
+
const frames = raw.slice(0, MAX_STACK_DEPTH).map(owned);
|
|
212
|
+
const owner = attributeSample(frames);
|
|
213
|
+
bump(owners, owner, () => ({ owner }));
|
|
214
|
+
|
|
215
|
+
const leaf = frames[0];
|
|
216
|
+
bump(topFrames, `${leaf.owner}\u0000${leaf.label}`, () => ({
|
|
217
|
+
frame: leaf.label,
|
|
218
|
+
owner: leaf.owner,
|
|
219
|
+
}));
|
|
220
|
+
const jsIndex = raw.findIndex(
|
|
221
|
+
(frame, index) => index < MAX_STACK_DEPTH && !!frame.sourceURL,
|
|
222
|
+
);
|
|
223
|
+
if (jsIndex >= 0) {
|
|
224
|
+
const js = frames[jsIndex];
|
|
225
|
+
bump(topJsFrames, `${js.owner}\u0000${js.label}`, () => ({
|
|
226
|
+
frame: js.label,
|
|
227
|
+
owner: js.owner,
|
|
228
|
+
}));
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
const labels = frames.map((frame) => `${frame.label} (${frame.owner})`);
|
|
232
|
+
if (raw.length > MAX_STACK_DEPTH) {
|
|
233
|
+
labels.push(`… ${raw.length - MAX_STACK_DEPTH} outer frames omitted`);
|
|
234
|
+
}
|
|
235
|
+
bump(stacks, labels.join("\n"), () => ({ owner, frames: labels }));
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
return {
|
|
239
|
+
samples,
|
|
240
|
+
owners: topBySamples(owners.values(), Number.POSITIVE_INFINITY).map((entry) => ({
|
|
241
|
+
...entry,
|
|
242
|
+
percent: samples === 0 ? 0 : Math.round((entry.samples / samples) * 1000) / 10,
|
|
243
|
+
})),
|
|
244
|
+
top_frames: topBySamples(topFrames.values(), TOP_FRAME_COUNT),
|
|
245
|
+
top_js_frames: topBySamples(topJsFrames.values(), TOP_FRAME_COUNT),
|
|
246
|
+
top_stacks: topBySamples(stacks.values(), TOP_STACK_COUNT),
|
|
247
|
+
};
|
|
248
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import * as path from "node:path";
|
|
2
|
+
import { getMagicContextStorageDir } from "./data-path";
|
|
3
|
+
import { createHostStallProfiler } from "./host-stall-profiler-bun";
|
|
4
|
+
import {
|
|
5
|
+
HOST_PROFILER_DIRNAME,
|
|
6
|
+
type HostStallProfilerHandle,
|
|
7
|
+
type ProfilerRuntimeDeps,
|
|
8
|
+
} from "./host-stall-profiler-common";
|
|
9
|
+
import { createNodeHostStallProfiler, type InspectorSession } from "./host-stall-profiler-node";
|
|
10
|
+
import { log } from "./logger";
|
|
11
|
+
|
|
12
|
+
export * from "./host-stall-profiler-common";
|
|
13
|
+
|
|
14
|
+
export function hostStallProfilerDir(): string {
|
|
15
|
+
return path.join(getMagicContextStorageDir(), HOST_PROFILER_DIRNAME);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const PROCESS_PROFILER_KEY = Symbol.for("cortexkit.magic-context.host-stall-profiler");
|
|
19
|
+
// Resolve at runtime: Node-only consumers do not install Bun's type declarations.
|
|
20
|
+
const jscModule: string = "bun:jsc";
|
|
21
|
+
|
|
22
|
+
/** All plugin/project instances watch the same main thread and share one sampler. */
|
|
23
|
+
export function startHostStallProfilerSwitch(): void {
|
|
24
|
+
try {
|
|
25
|
+
const holder = globalThis as unknown as Record<symbol, HostStallProfilerHandle | undefined>;
|
|
26
|
+
if (holder[PROCESS_PROFILER_KEY]) return;
|
|
27
|
+
const deps: ProfilerRuntimeDeps = {
|
|
28
|
+
profilerDir: hostStallProfilerDir,
|
|
29
|
+
now: () => performance.now(),
|
|
30
|
+
wallNow: () => Date.now(),
|
|
31
|
+
setInterval: (callback, ms) => {
|
|
32
|
+
const handle = setInterval(callback, ms);
|
|
33
|
+
(handle as { unref?: () => void }).unref?.();
|
|
34
|
+
return handle;
|
|
35
|
+
},
|
|
36
|
+
clearInterval: (handle) => clearInterval(handle as ReturnType<typeof setInterval>),
|
|
37
|
+
rss: () => process.memoryUsage.rss(),
|
|
38
|
+
log,
|
|
39
|
+
pid: process.pid,
|
|
40
|
+
bunVersion: process.versions.bun ?? null,
|
|
41
|
+
};
|
|
42
|
+
const handle = process.versions.bun
|
|
43
|
+
? createHostStallProfiler({ ...deps, loadJsc: () => import(jscModule) })
|
|
44
|
+
: createNodeHostStallProfiler({
|
|
45
|
+
...deps,
|
|
46
|
+
createSession: async () => {
|
|
47
|
+
const { Session } = await import("node:inspector");
|
|
48
|
+
return new Session() as unknown as InspectorSession;
|
|
49
|
+
},
|
|
50
|
+
memoryUsage: () => process.memoryUsage(),
|
|
51
|
+
});
|
|
52
|
+
holder[PROCESS_PROFILER_KEY] = handle;
|
|
53
|
+
handle.start();
|
|
54
|
+
} catch (error) {
|
|
55
|
+
log("[magic-context] host stall profiler: could not start the enable-file switch", error);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
@@ -129,6 +129,28 @@ if (scenario === "retry") {
|
|
|
129
129
|
predecessorMode: fs.statSync(predecessorPath).mode & 0o777,
|
|
130
130
|
files: fs.readdirSync(path.dirname(logPath)).filter((name) => name.startsWith("magic-context.log")).sort(),
|
|
131
131
|
}));
|
|
132
|
+
} else if (scenario === "stale-rotation") {
|
|
133
|
+
const maxLogBytes = 32 * 1024 * 1024;
|
|
134
|
+
fs.mkdirSync(path.dirname(logPath), { recursive: true });
|
|
135
|
+
fs.writeFileSync(logPath, Buffer.alloc(maxLogBytes - 200, "o"));
|
|
136
|
+
fs.chmodSync(logPath, 0o600);
|
|
137
|
+
// This process now caches a size just under the bound.
|
|
138
|
+
logger.log("cached size");
|
|
139
|
+
logger.flushLogger();
|
|
140
|
+
|
|
141
|
+
// Another process sharing the file rotates it: the full log becomes the
|
|
142
|
+
// predecessor and the current file starts over.
|
|
143
|
+
fs.copyFileSync(logPath, logPath + ".1");
|
|
144
|
+
fs.writeFileSync(logPath, "written by the other process\\n");
|
|
145
|
+
|
|
146
|
+
// A line that crosses the bound only by this process's stale cached size.
|
|
147
|
+
logger.log("x".repeat(400));
|
|
148
|
+
logger.flushLogger();
|
|
149
|
+
console.log(JSON.stringify({
|
|
150
|
+
current: fs.readFileSync(logPath, "utf8"),
|
|
151
|
+
predecessorFirstByte: fs.readFileSync(logPath + ".1")[0],
|
|
152
|
+
predecessorSize: fs.statSync(logPath + ".1").size,
|
|
153
|
+
}));
|
|
132
154
|
} else if (scenario === "hot-path") {
|
|
133
155
|
for (let index = 0; index < 20; index++) {
|
|
134
156
|
logger.log("hot-path-" + index);
|
|
@@ -182,6 +204,7 @@ async function runLoggerScenario<T>(
|
|
|
182
204
|
| "recovery"
|
|
183
205
|
| "diagnostics"
|
|
184
206
|
| "rotation"
|
|
207
|
+
| "stale-rotation"
|
|
185
208
|
| "hot-path"
|
|
186
209
|
| "retry"
|
|
187
210
|
| "bounded"
|
|
@@ -269,6 +292,21 @@ describe("logger", () => {
|
|
|
269
292
|
}
|
|
270
293
|
});
|
|
271
294
|
|
|
295
|
+
test("a stale cached size does not rotate a file another process already rotated", async () => {
|
|
296
|
+
const result = await runLoggerScenario<{
|
|
297
|
+
current: string;
|
|
298
|
+
predecessorFirstByte: number;
|
|
299
|
+
predecessorSize: number;
|
|
300
|
+
}>("stale-rotation");
|
|
301
|
+
|
|
302
|
+
// The other process's full predecessor survives, and the new line joins
|
|
303
|
+
// the restarted current file instead of replacing that predecessor.
|
|
304
|
+
expect(result.predecessorFirstByte).toBe("o".charCodeAt(0));
|
|
305
|
+
expect(result.predecessorSize).toBeGreaterThan(32 * 1024 * 1024 - 1024);
|
|
306
|
+
expect(result.current).toContain("written by the other process");
|
|
307
|
+
expect(result.current).toContain("x".repeat(400));
|
|
308
|
+
});
|
|
309
|
+
|
|
272
310
|
test("uses cached size between periodic rotation checks", async () => {
|
|
273
311
|
const result = await runLoggerScenario<HotPathScenarioResult>("hot-path");
|
|
274
312
|
|
package/src/shared/logger.ts
CHANGED
|
@@ -163,8 +163,16 @@ function flush(): void {
|
|
|
163
163
|
let currentSize = getCurrentLogSize(logFile);
|
|
164
164
|
const dataSize = Buffer.byteLength(data);
|
|
165
165
|
if (currentSize > 0 && currentSize + dataSize > MAX_LOG_FILE_BYTES) {
|
|
166
|
-
|
|
167
|
-
|
|
166
|
+
// Several processes share this file and each caches its size. A stale
|
|
167
|
+
// cache must not rotate a file another process already rotated: that
|
|
168
|
+
// second rotation would overwrite the full predecessor with the few
|
|
169
|
+
// lines written since. Decide on the file's real size instead.
|
|
170
|
+
flushesSinceSizeCheck = SIZE_CHECK_INTERVAL_FLUSHES;
|
|
171
|
+
currentSize = getCurrentLogSize(logFile);
|
|
172
|
+
if (currentSize > 0 && currentSize + dataSize > MAX_LOG_FILE_BYTES) {
|
|
173
|
+
rotateLogFile(logFile, currentSize);
|
|
174
|
+
currentSize = 0;
|
|
175
|
+
}
|
|
168
176
|
}
|
|
169
177
|
fs.appendFileSync(logFile, data, { encoding: "utf8", mode: 0o600 });
|
|
170
178
|
buffer = [];
|
|
@@ -231,41 +231,78 @@ describe("model-resolution", () => {
|
|
|
231
231
|
});
|
|
232
232
|
});
|
|
233
233
|
|
|
234
|
-
test("
|
|
234
|
+
test("resolves compress-cues to each harness's dreamer default and ignores mural.model", () => {
|
|
235
|
+
// The retired shared mural.model sits in the same config to prove it
|
|
236
|
+
// no longer feeds resolution on any harness.
|
|
235
237
|
const config = {
|
|
238
|
+
mural: { enabled: true, model: "google/antigravity-gemini-3.8-flash" },
|
|
236
239
|
dreamer: {
|
|
237
240
|
tasks: { "compress-cues": { schedule: "0 4 * * *" } },
|
|
238
241
|
opencode: {
|
|
239
242
|
model: { model: "open/default", variant: "default-variant" },
|
|
240
|
-
tasks: { "compress-cues": { variant: "task-local-must-not-leak" } },
|
|
241
243
|
},
|
|
242
244
|
pi: {
|
|
243
|
-
model: {
|
|
245
|
+
model: {
|
|
246
|
+
model: "google-antigravity/antigravity-gemini-3.8-flash",
|
|
247
|
+
thinking_level: "high",
|
|
248
|
+
},
|
|
244
249
|
tasks: { "compress-cues": {} },
|
|
245
250
|
},
|
|
246
251
|
},
|
|
247
252
|
};
|
|
248
253
|
|
|
249
254
|
expect(
|
|
250
|
-
resolveDreamerTaskModel({
|
|
251
|
-
config,
|
|
252
|
-
harness: "opencode",
|
|
253
|
-
task: "compress-cues",
|
|
254
|
-
muralModel: "mural/model",
|
|
255
|
-
}),
|
|
255
|
+
resolveDreamerTaskModel({ config, harness: "opencode", task: "compress-cues" }),
|
|
256
256
|
).toMatchObject({
|
|
257
|
-
primary: { model: "
|
|
257
|
+
primary: { model: "open/default", qualifier: "default-variant" },
|
|
258
258
|
fallbacks: [],
|
|
259
|
+
schedule: "0 4 * * *",
|
|
259
260
|
});
|
|
260
261
|
expect(
|
|
261
|
-
resolveDreamerTaskModel({
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
}
|
|
262
|
+
resolveDreamerTaskModel({ config, harness: "pi", task: "compress-cues" }),
|
|
263
|
+
).toMatchObject({
|
|
264
|
+
primary: {
|
|
265
|
+
model: "google-antigravity/antigravity-gemini-3.8-flash",
|
|
266
|
+
qualifier: "high",
|
|
267
|
+
},
|
|
268
|
+
fallbacks: [],
|
|
269
|
+
schedule: "0 4 * * *",
|
|
270
|
+
});
|
|
271
|
+
});
|
|
272
|
+
|
|
273
|
+
test("a per-harness compress-cues task override wins over the harness default", () => {
|
|
274
|
+
const config = {
|
|
275
|
+
mural: { enabled: true, model: "shared/must-not-win" },
|
|
276
|
+
dreamer: {
|
|
277
|
+
opencode: {
|
|
278
|
+
model: "open/default",
|
|
279
|
+
fallback_models: ["open/default-fallback"],
|
|
280
|
+
tasks: {
|
|
281
|
+
"compress-cues": {
|
|
282
|
+
model: { model: "open/cues", variant: "low" },
|
|
283
|
+
fallback_models: ["open/cues-fallback"],
|
|
284
|
+
},
|
|
285
|
+
},
|
|
286
|
+
},
|
|
287
|
+
pi: {
|
|
288
|
+
model: "pi/default",
|
|
289
|
+
thinking_level: "high",
|
|
290
|
+
tasks: { "compress-cues": { model: "pi/cues" } },
|
|
291
|
+
},
|
|
292
|
+
},
|
|
293
|
+
};
|
|
294
|
+
|
|
295
|
+
expect(
|
|
296
|
+
resolveDreamerTaskModel({ config, harness: "opencode", task: "compress-cues" }),
|
|
297
|
+
).toMatchObject({
|
|
298
|
+
primary: { model: "open/cues", qualifier: "low" },
|
|
299
|
+
fallbacks: [{ model: "open/cues-fallback" }],
|
|
300
|
+
});
|
|
301
|
+
// A task override without its own qualifier uses the harness default's qualifier.
|
|
302
|
+
expect(
|
|
303
|
+
resolveDreamerTaskModel({ config, harness: "pi", task: "compress-cues" }),
|
|
267
304
|
).toMatchObject({
|
|
268
|
-
primary: { model: "
|
|
305
|
+
primary: { model: "pi/cues", qualifier: "high" },
|
|
269
306
|
fallbacks: [],
|
|
270
307
|
});
|
|
271
308
|
});
|
|
@@ -137,14 +137,13 @@ export interface ResolvedDreamerTaskModel {
|
|
|
137
137
|
|
|
138
138
|
/**
|
|
139
139
|
* Resolve a dreamer task from one harness subtree. Model selection is task →
|
|
140
|
-
* harness default,
|
|
141
|
-
*
|
|
140
|
+
* harness default for every task, compress-cues included. Scheduling remains
|
|
141
|
+
* at dreamer.tasks.<task>.
|
|
142
142
|
*/
|
|
143
143
|
export function resolveDreamerTaskModel(args: {
|
|
144
144
|
config: unknown;
|
|
145
145
|
harness: ModelHarness;
|
|
146
146
|
task: string;
|
|
147
|
-
muralModel?: unknown;
|
|
148
147
|
}): ResolvedDreamerTaskModel {
|
|
149
148
|
const dreamer = asRecord(asRecord(args.config)?.dreamer);
|
|
150
149
|
const harnessBlock = resolveHarnessBlock(dreamer, args.harness);
|
|
@@ -166,19 +165,13 @@ export function resolveDreamerTaskModel(args: {
|
|
|
166
165
|
}
|
|
167
166
|
|
|
168
167
|
const taskQualifier = taskBlock?.[args.harness === "opencode" ? "variant" : "thinking_level"];
|
|
169
|
-
// A
|
|
170
|
-
// qualifier
|
|
168
|
+
// A task override without its own qualifier borrows the harness default's
|
|
169
|
+
// qualifier, whether written beside `model` or inside the default entry object.
|
|
171
170
|
const harnessQualifier =
|
|
172
171
|
harnessBlock[args.harness === "opencode" ? "variant" : "thinking_level"] ??
|
|
173
172
|
normalizeModelEntry(harnessBlock.model, args.harness)?.qualifier;
|
|
174
173
|
const taskHasModel = taskBlock !== undefined && hasOwn(taskBlock, "model");
|
|
175
|
-
const
|
|
176
|
-
!taskHasModel && args.task === "compress-cues" && Boolean(readString(args.muralModel));
|
|
177
|
-
const primarySource = taskHasModel
|
|
178
|
-
? taskBlock?.model
|
|
179
|
-
: usesMuralModel
|
|
180
|
-
? args.muralModel
|
|
181
|
-
: harnessBlock.model;
|
|
174
|
+
const primarySource = taskHasModel ? taskBlock?.model : harnessBlock.model;
|
|
182
175
|
const fallbackSource =
|
|
183
176
|
taskBlock !== undefined && hasOwn(taskBlock, "fallback_models")
|
|
184
177
|
? taskBlock.fallback_models
|
|
@@ -187,11 +180,7 @@ export function resolveDreamerTaskModel(args: {
|
|
|
187
180
|
return {
|
|
188
181
|
primary: resolvePrimaryEntry({
|
|
189
182
|
entry: primarySource,
|
|
190
|
-
|
|
191
|
-
// executing harness default rather than a task-local default.
|
|
192
|
-
defaultQualifier: usesMuralModel
|
|
193
|
-
? harnessQualifier
|
|
194
|
-
: (taskQualifier ?? harnessQualifier),
|
|
183
|
+
defaultQualifier: taskQualifier ?? harnessQualifier,
|
|
195
184
|
harness: args.harness,
|
|
196
185
|
}),
|
|
197
186
|
fallbacks: resolveFallbackEntries(fallbackSource, args.harness),
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Temperature capability from the models.dev catalog that OpenCode caches on disk.
|
|
3
|
+
*
|
|
4
|
+
* OpenCode 1 copies models.dev's `temperature` flag onto each model, but OpenCode 2's
|
|
5
|
+
* model rows, Pi's model registry and Oh My Pi's Gemini models carry no equivalent
|
|
6
|
+
* field. For those hosts the cached catalog is the only positive evidence on the
|
|
7
|
+
* machine, so a missing file, an unparsable file or a missing entry all mean "unknown"
|
|
8
|
+
* and the caller omits temperature.
|
|
9
|
+
*
|
|
10
|
+
* This module is bundled into the Pi/OMP historian child extension, so it must only
|
|
11
|
+
* depend on Node built-ins.
|
|
12
|
+
*/
|
|
13
|
+
import { readFileSync, statSync } from "node:fs";
|
|
14
|
+
import { homedir } from "node:os";
|
|
15
|
+
import { join } from "node:path";
|
|
16
|
+
|
|
17
|
+
export interface CatalogTemperature {
|
|
18
|
+
temperature: boolean;
|
|
19
|
+
/** The catalog entry that decided, as `provider/model`. */
|
|
20
|
+
entry: string;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Harness provider ids that name the same models.dev provider. Codex (`openai-codex`)
|
|
25
|
+
* is deliberately absent: the ChatGPT backend is a different transport from the
|
|
26
|
+
* OpenAI API that models.dev describes, so it gets no catalog answer and no temperature.
|
|
27
|
+
*/
|
|
28
|
+
const CATALOG_PROVIDER_ALIASES: Readonly<Record<string, string>> = {
|
|
29
|
+
"google-antigravity": "google",
|
|
30
|
+
"opencode-zen": "opencode",
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
/** The Antigravity auth plugins register Gemini models as `google/antigravity-<model>`. */
|
|
34
|
+
const ANTIGRAVITY_MODEL_PREFIX = "antigravity-";
|
|
35
|
+
|
|
36
|
+
type CatalogIndex = Map<string, boolean>;
|
|
37
|
+
|
|
38
|
+
let cached: { path: string; mtimeMs: number; size: number; index: CatalogIndex } | undefined;
|
|
39
|
+
|
|
40
|
+
/** OpenCode reads `OPENCODE_MODELS_PATH` instead of its cache when it is set. */
|
|
41
|
+
export function modelsDevCatalogPath(env: NodeJS.ProcessEnv = process.env): string {
|
|
42
|
+
if (env.OPENCODE_MODELS_PATH) return env.OPENCODE_MODELS_PATH;
|
|
43
|
+
return join(env.XDG_CACHE_HOME || join(homedir(), ".cache"), "opencode", "models.json");
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function buildIndex(raw: unknown): CatalogIndex {
|
|
47
|
+
const index: CatalogIndex = new Map();
|
|
48
|
+
if (!raw || typeof raw !== "object" || Array.isArray(raw)) return index;
|
|
49
|
+
for (const [providerID, provider] of Object.entries(raw as Record<string, unknown>)) {
|
|
50
|
+
const models = (provider as { models?: unknown } | null)?.models;
|
|
51
|
+
if (!models || typeof models !== "object") continue;
|
|
52
|
+
for (const [modelID, model] of Object.entries(models as Record<string, unknown>)) {
|
|
53
|
+
const temperature = (model as { temperature?: unknown } | null)?.temperature;
|
|
54
|
+
if (typeof temperature === "boolean")
|
|
55
|
+
index.set(`${providerID}/${modelID}`, temperature);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return index;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function loadIndex(): CatalogIndex | undefined {
|
|
62
|
+
const path = modelsDevCatalogPath();
|
|
63
|
+
try {
|
|
64
|
+
const stat = statSync(path);
|
|
65
|
+
if (cached?.path === path && cached.mtimeMs === stat.mtimeMs && cached.size === stat.size)
|
|
66
|
+
return cached.index;
|
|
67
|
+
const index = buildIndex(JSON.parse(readFileSync(path, "utf8")));
|
|
68
|
+
cached = { path, mtimeMs: stat.mtimeMs, size: stat.size, index };
|
|
69
|
+
return index;
|
|
70
|
+
} catch {
|
|
71
|
+
// Absent or partially written catalog: no evidence either way.
|
|
72
|
+
return undefined;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/** Spellings to try for a harness `provider/model` reference, most specific first. */
|
|
77
|
+
export function catalogCandidates(providerID: string, modelID: string): string[] {
|
|
78
|
+
const provider = Object.hasOwn(CATALOG_PROVIDER_ALIASES, providerID)
|
|
79
|
+
? CATALOG_PROVIDER_ALIASES[providerID]
|
|
80
|
+
: providerID;
|
|
81
|
+
const candidates = [`${provider}/${modelID}`];
|
|
82
|
+
if (provider === "google" && modelID.startsWith(ANTIGRAVITY_MODEL_PREFIX))
|
|
83
|
+
candidates.push(`google/${modelID.slice(ANTIGRAVITY_MODEL_PREFIX.length)}`);
|
|
84
|
+
return candidates;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Look `provider/model` up in the cached catalogue, trying only the exact spellings from
|
|
89
|
+
* `catalogCandidates`. A malformed reference, a missing catalogue or no entry returns undefined.
|
|
90
|
+
*/
|
|
91
|
+
export function catalogTemperature(model: string): CatalogTemperature | undefined {
|
|
92
|
+
const slash = model.indexOf("/");
|
|
93
|
+
if (slash <= 0 || slash === model.length - 1) return undefined;
|
|
94
|
+
const index = loadIndex();
|
|
95
|
+
if (!index) return undefined;
|
|
96
|
+
for (const entry of catalogCandidates(model.slice(0, slash), model.slice(slash + 1))) {
|
|
97
|
+
const temperature = index.get(entry);
|
|
98
|
+
if (temperature !== undefined) return { temperature, entry };
|
|
99
|
+
}
|
|
100
|
+
return undefined;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export const __catalogTest = {
|
|
104
|
+
reset(): void {
|
|
105
|
+
cached = undefined;
|
|
106
|
+
},
|
|
107
|
+
};
|