@cortexkit/opencode-magic-context 0.33.0 → 0.34.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/config/agent-disable.d.ts +22 -0
- package/dist/config/agent-disable.d.ts.map +1 -1
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/project-security.d.ts +7 -0
- package/dist/config/project-security.d.ts.map +1 -1
- package/dist/config/schema/magic-context.d.ts +144 -24
- package/dist/config/schema/magic-context.d.ts.map +1 -1
- package/dist/config/transform-mode.d.ts +2 -0
- package/dist/config/transform-mode.d.ts.map +1 -1
- package/dist/{conflict-warning-hook-bwa99a04.js → conflict-warning-hook-fvpfvt0w.js} +1 -1
- package/dist/{derive-budgets-e9j09sjr.js → derive-budgets-9crp0cvd.js} +1 -1
- package/dist/features/builtin-commands/commands.d.ts +1 -1
- package/dist/features/builtin-commands/commands.d.ts.map +1 -1
- package/dist/features/magic-context/compaction-marker.d.ts +106 -0
- package/dist/features/magic-context/compaction-marker.d.ts.map +1 -1
- package/dist/features/magic-context/compartment-chunk-embedding.d.ts +0 -2
- package/dist/features/magic-context/compartment-chunk-embedding.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/classify.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/evaluate-smart-notes.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/map-memories.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/refresh-primers.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/task-executor.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/task-registry.d.ts +0 -1
- package/dist/features/magic-context/dreamer/task-registry.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/verify.d.ts.map +1 -1
- package/dist/features/magic-context/fail-closed-block.d.ts +10 -0
- package/dist/features/magic-context/fail-closed-block.d.ts.map +1 -1
- package/dist/features/magic-context/git-commits/index.d.ts +2 -2
- package/dist/features/magic-context/git-commits/index.d.ts.map +1 -1
- package/dist/features/magic-context/git-commits/storage-git-commit-embeddings.d.ts +0 -2
- package/dist/features/magic-context/git-commits/storage-git-commit-embeddings.d.ts.map +1 -1
- package/dist/features/magic-context/git-commits/storage-git-commits.d.ts +0 -13
- package/dist/features/magic-context/git-commits/storage-git-commits.d.ts.map +1 -1
- package/dist/features/magic-context/memory/embedding-identity.d.ts.map +1 -1
- package/dist/features/magic-context/memory/embedding-local.d.ts +7 -1
- package/dist/features/magic-context/memory/embedding-local.d.ts.map +1 -1
- package/dist/features/magic-context/memory/embedding.d.ts +1 -2
- package/dist/features/magic-context/memory/embedding.d.ts.map +1 -1
- package/dist/features/magic-context/memory/memory-migration.d.ts +0 -6
- package/dist/features/magic-context/memory/memory-migration.d.ts.map +1 -1
- package/dist/features/magic-context/memory/project-identity.d.ts +2 -6
- package/dist/features/magic-context/memory/project-identity.d.ts.map +1 -1
- package/dist/features/magic-context/memory/storage-memory-embeddings.d.ts +0 -1
- package/dist/features/magic-context/memory/storage-memory-embeddings.d.ts.map +1 -1
- package/dist/features/magic-context/memory/storage-memory.d.ts +1 -6
- package/dist/features/magic-context/memory/storage-memory.d.ts.map +1 -1
- package/dist/features/magic-context/memory/verification-paths.d.ts +0 -1
- package/dist/features/magic-context/memory/verification-paths.d.ts.map +1 -1
- package/dist/features/magic-context/migrations.d.ts.map +1 -1
- package/dist/features/magic-context/mural/compress-cues.d.ts.map +1 -1
- package/dist/features/magic-context/mural/render-mural.d.ts.map +1 -1
- package/dist/features/magic-context/mural/storage-mural.d.ts +0 -1
- package/dist/features/magic-context/mural/storage-mural.d.ts.map +1 -1
- package/dist/features/magic-context/overflow-detection.d.ts +8 -1
- package/dist/features/magic-context/overflow-detection.d.ts.map +1 -1
- package/dist/features/magic-context/project-embedding-registry.d.ts +16 -2
- package/dist/features/magic-context/project-embedding-registry.d.ts.map +1 -1
- package/dist/features/magic-context/scheduler.d.ts.map +1 -1
- package/dist/features/magic-context/schema-fence-probe.d.ts +28 -0
- package/dist/features/magic-context/schema-fence-probe.d.ts.map +1 -0
- package/dist/features/magic-context/sidekick/agent.d.ts.map +1 -1
- package/dist/features/magic-context/smart-notes/capabilities.d.ts +0 -2
- package/dist/features/magic-context/smart-notes/capabilities.d.ts.map +1 -1
- package/dist/features/magic-context/smart-notes/compiler.d.ts +0 -1
- package/dist/features/magic-context/smart-notes/compiler.d.ts.map +1 -1
- package/dist/features/magic-context/smart-notes/types.d.ts +0 -16
- package/dist/features/magic-context/smart-notes/types.d.ts.map +1 -1
- package/dist/features/magic-context/storage-db.d.ts +35 -1
- package/dist/features/magic-context/storage-db.d.ts.map +1 -1
- package/dist/features/magic-context/storage-meta-persisted.d.ts +38 -5
- package/dist/features/magic-context/storage-meta-persisted.d.ts.map +1 -1
- package/dist/features/magic-context/storage-meta.d.ts +1 -1
- package/dist/features/magic-context/storage-meta.d.ts.map +1 -1
- package/dist/features/magic-context/storage.d.ts +1 -1
- package/dist/features/magic-context/storage.d.ts.map +1 -1
- package/dist/features/magic-context/user-memory/review-user-memories.d.ts.map +1 -1
- package/dist/features/magic-context/user-memory/storage-user-memory.d.ts +0 -2
- package/dist/features/magic-context/user-memory/storage-user-memory.d.ts.map +1 -1
- package/dist/hooks/auto-update-checker/types.d.ts +0 -3
- package/dist/hooks/auto-update-checker/types.d.ts.map +1 -1
- package/dist/hooks/magic-context/boundary-execution.d.ts +1 -1
- package/dist/hooks/magic-context/boundary-execution.d.ts.map +1 -1
- package/dist/hooks/magic-context/cache-busting-signals.d.ts +1 -1
- package/dist/hooks/magic-context/cache-busting-signals.d.ts.map +1 -1
- package/dist/hooks/magic-context/channel2-delivery.d.ts.map +1 -1
- package/dist/hooks/magic-context/child-session-spawn.d.ts +26 -0
- package/dist/hooks/magic-context/child-session-spawn.d.ts.map +1 -0
- package/dist/hooks/magic-context/command-handler.d.ts +2 -0
- package/dist/hooks/magic-context/command-handler.d.ts.map +1 -1
- package/dist/hooks/magic-context/compaction-marker-manager.d.ts +49 -0
- package/dist/hooks/magic-context/compaction-marker-manager.d.ts.map +1 -1
- package/dist/hooks/magic-context/compaction-off-transition.d.ts +96 -0
- package/dist/hooks/magic-context/compaction-off-transition.d.ts.map +1 -0
- package/dist/hooks/magic-context/compartment-parser.d.ts +12 -0
- package/dist/hooks/magic-context/compartment-parser.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-runner-historian.d.ts +2 -0
- package/dist/hooks/magic-context/compartment-runner-historian.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-runner-incremental.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-runner-mapping.d.ts +0 -12
- package/dist/hooks/magic-context/compartment-runner-mapping.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-runner-partial-recomp.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-runner-recomp.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-trigger.d.ts +12 -5
- package/dist/hooks/magic-context/compartment-trigger.d.ts.map +1 -1
- package/dist/hooks/magic-context/ctx-reduce-availability.d.ts +47 -1
- package/dist/hooks/magic-context/ctx-reduce-availability.d.ts.map +1 -1
- package/dist/hooks/magic-context/emergency-drop.d.ts +2 -2
- package/dist/hooks/magic-context/event-handler.d.ts +7 -0
- package/dist/hooks/magic-context/event-handler.d.ts.map +1 -1
- package/dist/hooks/magic-context/event-resolvers.d.ts +13 -21
- package/dist/hooks/magic-context/event-resolvers.d.ts.map +1 -1
- package/dist/hooks/magic-context/final-wire-token-estimate.d.ts +2 -0
- package/dist/hooks/magic-context/final-wire-token-estimate.d.ts.map +1 -1
- package/dist/hooks/magic-context/heuristic-cleanup.d.ts +1 -1
- package/dist/hooks/magic-context/historian-prompt.generated.d.ts +1 -1
- package/dist/hooks/magic-context/historian-prompt.generated.d.ts.map +1 -1
- package/dist/hooks/magic-context/hook-handlers.d.ts +1 -0
- package/dist/hooks/magic-context/hook-handlers.d.ts.map +1 -1
- package/dist/hooks/magic-context/hook.d.ts +11 -1
- package/dist/hooks/magic-context/hook.d.ts.map +1 -1
- package/dist/hooks/magic-context/inject-compartments.d.ts +18 -0
- package/dist/hooks/magic-context/inject-compartments.d.ts.map +1 -1
- package/dist/hooks/magic-context/protected-tail-boundary.d.ts.map +1 -1
- package/dist/hooks/magic-context/read-session-db.d.ts.map +1 -1
- package/dist/hooks/magic-context/read-session-true-raw-tokens.d.ts.map +1 -1
- package/dist/hooks/magic-context/rust-mode-transform.d.ts +3 -0
- package/dist/hooks/magic-context/rust-mode-transform.d.ts.map +1 -1
- package/dist/hooks/magic-context/send-session-notification.d.ts +20 -1
- package/dist/hooks/magic-context/send-session-notification.d.ts.map +1 -1
- package/dist/hooks/magic-context/sentinel.d.ts +39 -0
- package/dist/hooks/magic-context/sentinel.d.ts.map +1 -1
- package/dist/hooks/magic-context/tag-messages.d.ts.map +1 -1
- package/dist/hooks/magic-context/tool-drop-target.d.ts +19 -0
- package/dist/hooks/magic-context/tool-drop-target.d.ts.map +1 -1
- package/dist/hooks/magic-context/transform-compartment-phase.d.ts +3 -0
- package/dist/hooks/magic-context/transform-compartment-phase.d.ts.map +1 -1
- package/dist/hooks/magic-context/transform-postprocess-phase.d.ts +30 -0
- package/dist/hooks/magic-context/transform-postprocess-phase.d.ts.map +1 -1
- package/dist/hooks/magic-context/transform.d.ts +27 -0
- package/dist/hooks/magic-context/transform.d.ts.map +1 -1
- package/dist/{index-kxz4tn6m.js → index-56yjaeb2.js} +56 -4
- package/dist/{index-bmkea2dq.js → index-b563sga5.js} +40 -287
- package/dist/{index-y1c9tcm3.js → index-cn960ffd.js} +101 -20
- package/dist/{index-k5y60ymm.js → index-dtas91s5.js} +27 -6
- package/dist/index-fcyvznch.js +279 -0
- package/dist/{index-63dq2g4d.js → index-ry8rh8cv.js} +138 -24
- package/dist/{index-h86twgsp.js → index-s0mdn690.js} +2113 -1067
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1356 -627
- package/dist/plugin/embedding-bootstrap.d.ts.map +1 -1
- package/dist/plugin/hooks/create-session-hooks.d.ts +19 -8
- package/dist/plugin/hooks/create-session-hooks.d.ts.map +1 -1
- package/dist/plugin/messages-transform.d.ts +10 -0
- package/dist/plugin/messages-transform.d.ts.map +1 -1
- package/dist/plugin/rpc-handlers.d.ts +3 -7
- package/dist/plugin/rpc-handlers.d.ts.map +1 -1
- package/dist/plugin/tool-registry.d.ts +8 -0
- package/dist/plugin/tool-registry.d.ts.map +1 -1
- package/dist/{recomp-orchestrator-yh7pepvx.js → recomp-orchestrator-8e82vmvb.js} +6 -5
- package/dist/send-session-notification-6njqewzk.js +20 -0
- package/dist/shared/conflict-detector.d.ts +38 -1
- package/dist/shared/conflict-detector.d.ts.map +1 -1
- package/dist/shared/conflict-fixer.d.ts +18 -1
- package/dist/shared/conflict-fixer.d.ts.map +1 -1
- package/dist/shared/context-limit-provenance.d.ts +3 -0
- package/dist/shared/context-limit-provenance.d.ts.map +1 -0
- package/dist/shared/escalation-bands.d.ts +9 -0
- package/dist/shared/escalation-bands.d.ts.map +1 -0
- package/dist/shared/format-threshold.d.ts +1 -1
- package/dist/shared/models-dev-cache.d.ts +29 -3
- package/dist/shared/models-dev-cache.d.ts.map +1 -1
- package/dist/shared/rpc-server.d.ts.map +1 -1
- package/dist/shared/rpc-types.d.ts +46 -1
- package/dist/shared/rpc-types.d.ts.map +1 -1
- package/dist/shared/sqlite.d.ts +9 -4
- package/dist/shared/sqlite.d.ts.map +1 -1
- package/dist/shared/storage-permissions.d.ts +5 -0
- package/dist/shared/storage-permissions.d.ts.map +1 -0
- package/dist/{storage-meta-session-1phy0b1z.js → storage-meta-session-xt41zbw4.js} +2 -1
- package/dist/{task-config-dn9k9szr.js → task-config-5nx3qfz8.js} +1 -2
- package/dist/tui/compaction-off.d.ts +13 -0
- package/dist/tui/compaction-off.d.ts.map +1 -0
- package/dist/tui/data/context-db.d.ts.map +1 -1
- package/dist/tui-compiled/compaction-off.d.ts +13 -0
- package/dist/tui-compiled/compaction-off.d.ts.map +1 -0
- package/dist/tui-compiled/data/context-db.d.ts.map +1 -1
- package/package.json +8 -3
- package/src/agents/dreamer.ts +68 -0
- package/src/agents/hidden-agent-registrations.ts +331 -0
- package/src/agents/historian.ts +3 -0
- package/src/agents/language-directive.test.ts +138 -0
- package/src/agents/language-directive.ts +121 -0
- package/src/agents/magic-context-prompt.language.test.ts +35 -0
- package/src/agents/magic-context-prompt.test.ts +292 -0
- package/src/agents/magic-context-prompt.ts +182 -0
- package/src/agents/permissions.test.ts +252 -0
- package/src/agents/permissions.ts +186 -0
- package/src/agents/sidekick.ts +1 -0
- package/src/agents/smart-note-compiler.ts +1 -0
- package/src/config/agent-disable.ts +106 -0
- package/src/config/compaction-accessor-guard.test.ts +82 -0
- package/src/config/compaction-backcompat.test.ts +52 -0
- package/src/config/index.test.ts +904 -0
- package/src/config/index.ts +601 -0
- package/src/config/migrate-config-location.test.ts +332 -0
- package/src/config/migrate-config-location.ts +635 -0
- package/src/config/migrate-dreamer-v2.test.ts +287 -0
- package/src/config/migrate-dreamer-v2.ts +336 -0
- package/src/config/migrate-experimental.ts +159 -0
- package/src/config/project-security.test.ts +366 -0
- package/src/config/project-security.ts +588 -0
- package/src/config/prune-config-leaf.test.ts +78 -0
- package/src/config/prune-config-leaf.ts +68 -0
- package/src/config/removed-config-keys.test.ts +116 -0
- package/src/config/schema/agent-overrides.ts +45 -0
- package/src/config/schema/magic-context.test.ts +358 -0
- package/src/config/schema/magic-context.ts +1002 -0
- package/src/config/transform-mode.test.ts +62 -0
- package/src/config/transform-mode.ts +34 -0
- package/src/config/variable.test.ts +323 -0
- package/src/config/variable.ts +192 -0
- package/src/features/magic-context/defaults.ts +1 -0
- package/src/features/magic-context/dreamer/cron.ts +243 -0
- package/src/features/magic-context/dreamer/task-registry.ts +104 -0
- package/src/shared/conflict-detector.test.ts +251 -1
- package/src/shared/conflict-detector.ts +84 -5
- package/src/shared/conflict-fixer.test.ts +309 -0
- package/src/shared/conflict-fixer.ts +82 -5
- package/src/shared/context-limit-provenance.ts +6 -0
- package/src/shared/escalation-bands.test.ts +23 -0
- package/src/shared/escalation-bands.ts +18 -0
- package/src/shared/format-threshold.ts +1 -1
- package/src/shared/models-dev-cache.test.ts +171 -0
- package/src/shared/models-dev-cache.ts +195 -38
- package/src/shared/rpc-server.ts +27 -18
- package/src/shared/rpc-types.ts +46 -1
- package/src/shared/sqlite.ts +13 -33
- package/src/shared/storage-permissions.ts +20 -0
- package/src/tui/compaction-off.test.ts +56 -0
- package/src/tui/compaction-off.ts +29 -0
- package/src/tui/data/context-db.ts +6 -0
- package/src/tui/index.tsx +113 -65
- package/src/tui/slots/sidebar-content.tsx +139 -83
- package/src/tui-compiled/compaction-off.ts +29 -0
- package/src/tui-compiled/data/context-db.ts +6 -0
- package/src/tui-compiled/index.tsx +558 -455
- package/src/tui-compiled/slots/sidebar-content.tsx +237 -161
- package/dist/config/schema.d.ts +0 -3
- package/dist/config/schema.d.ts.map +0 -1
- package/dist/features/magic-context/plugin-messages.d.ts +0 -75
- package/dist/features/magic-context/plugin-messages.d.ts.map +0 -1
- package/dist/hooks/magic-context/compartment-runner-state-xml.d.ts +0 -21
- package/dist/hooks/magic-context/compartment-runner-state-xml.d.ts.map +0 -1
- package/dist/index-anhrfygk.js +0 -57
- package/dist/send-session-notification-tghq9gnh.js +0 -11
- package/dist/shared/opencode-compaction-detector.d.ts +0 -2
- package/dist/shared/opencode-compaction-detector.d.ts.map +0 -1
- package/dist/shared/transcript-opencode.d.ts +0 -71
- package/dist/shared/transcript-opencode.d.ts.map +0 -1
- package/dist/tools/index.d.ts +0 -6
- package/dist/tools/index.d.ts.map +0 -1
- package/src/shared/opencode-compaction-detector.test.ts +0 -239
- package/src/shared/opencode-compaction-detector.ts +0 -81
- package/src/shared/transcript-opencode.ts +0 -302
- /package/dist/{index-v7fmc1s2.js → index-ygcng9t8.js} +0 -0
|
@@ -1,302 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* OpenCode adapter for the harness-agnostic transcript interface.
|
|
3
|
-
*
|
|
4
|
-
* This is a thin proxy over OpenCode's `MessageLike[]` (i.e. `{ info,
|
|
5
|
-
* parts: unknown[] }[]`) — it does NOT copy data. Mutations through
|
|
6
|
-
* `setText`/`setToolOutput`/`replaceWithSentinel` write directly into
|
|
7
|
-
* the source `parts[]` arrays, exactly as the existing OpenCode-only
|
|
8
|
-
* transform code does today. `commit()` is a no-op because OpenCode's
|
|
9
|
-
* AI SDK reads `parts[]` back from the same array we mutated.
|
|
10
|
-
*
|
|
11
|
-
* This module is the boundary that lets the rest of the transform code
|
|
12
|
-
* (which moves to use the Transcript interface in 4b.2) work both for
|
|
13
|
-
* OpenCode and Pi without branching on harness type. By the end of 4b
|
|
14
|
-
* the only OpenCode-aware code in the plugin is this file plus
|
|
15
|
-
* `messages-transform.ts`.
|
|
16
|
-
*
|
|
17
|
-
* ## Mutation contract recap
|
|
18
|
-
*
|
|
19
|
-
* Magic Context's transform mutates message parts in three ways:
|
|
20
|
-
*
|
|
21
|
-
* 1. **Tag prefix injection** — prepends `§N§ ` to text parts and
|
|
22
|
-
* tool result outputs. Repeated tagging is idempotent because
|
|
23
|
-
* `prependTag` strips any existing prefix first.
|
|
24
|
-
*
|
|
25
|
-
* 2. **Sentinel replacement** — when a queued drop fires, the part is
|
|
26
|
-
* replaced with a `[dropped §N§]` or `[truncated §N§]` placeholder.
|
|
27
|
-
* The original tag number is preserved so the agent's mental
|
|
28
|
-
* model of "what was here" survives.
|
|
29
|
-
*
|
|
30
|
-
* 3. **Structural noise stripping** — `step-start`/`step-finish`
|
|
31
|
-
* wrappers and similar structural metadata are replaced with empty
|
|
32
|
-
* sentinel parts so they don't consume tag numbers or get tagged
|
|
33
|
-
* themselves.
|
|
34
|
-
*
|
|
35
|
-
* The OpenCode adapter implements (1) and (2) by editing `part.text` /
|
|
36
|
-
* `part.state.output` in place. For (3), structural parts surface as
|
|
37
|
-
* `kind: "structural"` so callers can filter them out. Adapter does NOT
|
|
38
|
-
* itself perform stripping — that's the transform pipeline's job, called
|
|
39
|
-
* after the adapter wraps the messages.
|
|
40
|
-
*
|
|
41
|
-
* Step 4b.1 ships the adapter alone. The existing OpenCode transform
|
|
42
|
-
* code keeps using `MessageLike[]` directly until 4b.2 migrates the
|
|
43
|
-
* tagging+drops layer to use Transcript instances.
|
|
44
|
-
*/
|
|
45
|
-
|
|
46
|
-
import { estimateTokens } from "../hooks/magic-context/read-session-formatting";
|
|
47
|
-
import { isRecord } from "./record-type-guard";
|
|
48
|
-
import type {
|
|
49
|
-
Transcript,
|
|
50
|
-
TranscriptMessage,
|
|
51
|
-
TranscriptPart,
|
|
52
|
-
TranscriptPartKind,
|
|
53
|
-
} from "./transcript";
|
|
54
|
-
|
|
55
|
-
/**
|
|
56
|
-
* The OpenCode `MessageLike` shape. Re-declared here to avoid a circular
|
|
57
|
-
* import with `tag-messages.ts` (which lives in the magic-context hooks
|
|
58
|
-
* tree and depends on storage). Keeping a local minimal type also makes
|
|
59
|
-
* the adapter trivially unit-testable without booting OpenCode SDK
|
|
60
|
-
* types.
|
|
61
|
-
*
|
|
62
|
-
* MUST stay structurally compatible with `tag-messages.ts MessageLike` —
|
|
63
|
-
* if that file's MessageLike adds a required field, this one needs to
|
|
64
|
-
* add it too. The build will fail loudly if the shapes diverge.
|
|
65
|
-
*/
|
|
66
|
-
export interface OpenCodeMessageLike {
|
|
67
|
-
info: { id?: string; role?: string; sessionID?: string };
|
|
68
|
-
parts: unknown[];
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
/**
|
|
72
|
-
* Wrap an existing `MessageLike[]` as a Transcript. Zero copies — every
|
|
73
|
-
* `TranscriptPart` returned proxies the matching entry in the source
|
|
74
|
-
* `parts` array, and mutations are reflected immediately.
|
|
75
|
-
*/
|
|
76
|
-
export function createOpenCodeTranscript(messages: OpenCodeMessageLike[]): Transcript {
|
|
77
|
-
const transcriptMessages: TranscriptMessage[] = messages.map((message) => ({
|
|
78
|
-
info: {
|
|
79
|
-
id: message.info.id,
|
|
80
|
-
role: message.info.role ?? "unknown",
|
|
81
|
-
sessionId: message.info.sessionID,
|
|
82
|
-
},
|
|
83
|
-
// `parts` is a getter so newly-replaced sentinels inside the
|
|
84
|
-
// underlying array are surfaced on the next read. Cheap; allocs
|
|
85
|
-
// one wrapper per part per access. Adapter callers iterate
|
|
86
|
-
// `messages` once per pass so the cost is O(parts) per pass —
|
|
87
|
-
// same as before the adapter existed.
|
|
88
|
-
get parts(): TranscriptPart[] {
|
|
89
|
-
return message.parts.map((part, index) => createOpenCodePart(message, index, part));
|
|
90
|
-
},
|
|
91
|
-
}));
|
|
92
|
-
|
|
93
|
-
return {
|
|
94
|
-
messages: transcriptMessages,
|
|
95
|
-
harness: "opencode",
|
|
96
|
-
// OpenCode reads parts back from the same `parts[]` array we
|
|
97
|
-
// mutated, so there's nothing to flush. Adapters that buffer
|
|
98
|
-
// mutations (Pi) override this.
|
|
99
|
-
commit(): void {
|
|
100
|
-
/* no-op for OpenCode */
|
|
101
|
-
},
|
|
102
|
-
};
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
/**
|
|
106
|
-
* Construct a TranscriptPart proxy over a single OpenCode part.
|
|
107
|
-
*
|
|
108
|
-
* Held by `parts` getter calls only; never cached because the underlying
|
|
109
|
-
* `parts[]` array can be mutated in place (sentinel replacement) and
|
|
110
|
-
* cached proxies would point at stale data. The constructor cost is
|
|
111
|
-
* trivial — small object literal, no allocations beyond the closure.
|
|
112
|
-
*/
|
|
113
|
-
function createOpenCodePart(
|
|
114
|
-
parent: OpenCodeMessageLike,
|
|
115
|
-
index: number,
|
|
116
|
-
rawPart: unknown,
|
|
117
|
-
): TranscriptPart {
|
|
118
|
-
const kind = classifyOpenCodePart(rawPart);
|
|
119
|
-
const id = extractPartId(rawPart);
|
|
120
|
-
|
|
121
|
-
return {
|
|
122
|
-
kind,
|
|
123
|
-
id,
|
|
124
|
-
getText(): string | undefined {
|
|
125
|
-
return readOpenCodePartText(rawPart);
|
|
126
|
-
},
|
|
127
|
-
setText(newText: string): boolean {
|
|
128
|
-
return writeOpenCodePartText(rawPart, newText);
|
|
129
|
-
},
|
|
130
|
-
setToolOutput(newText: string): boolean {
|
|
131
|
-
return writeOpenCodeToolOutput(rawPart, newText);
|
|
132
|
-
},
|
|
133
|
-
getToolMetadata(): {
|
|
134
|
-
toolName: string | undefined;
|
|
135
|
-
inputByteSize: number;
|
|
136
|
-
inputTokenCount: number;
|
|
137
|
-
} {
|
|
138
|
-
return readOpenCodeToolMetadata(rawPart);
|
|
139
|
-
},
|
|
140
|
-
getToolInput(): Record<string, unknown> | null {
|
|
141
|
-
return readOpenCodeToolInput(rawPart);
|
|
142
|
-
},
|
|
143
|
-
setToolInput(input: Record<string, unknown>): boolean {
|
|
144
|
-
return writeOpenCodeToolInput(rawPart, input);
|
|
145
|
-
},
|
|
146
|
-
replaceWithSentinel(sentinelText: string): boolean {
|
|
147
|
-
// Build a synthetic text part that carries the sentinel as
|
|
148
|
-
// its content. Subsequent passes see this as a normal text
|
|
149
|
-
// part with kind="text" — but the existing tagging code is
|
|
150
|
-
// idempotent and won't double-tag a part that already has
|
|
151
|
-
// the right prefix, so re-processing is safe.
|
|
152
|
-
//
|
|
153
|
-
// We DON'T preserve the original part type. Sentinels are
|
|
154
|
-
// always text — that's the contract the existing
|
|
155
|
-
// apply-operations code expects.
|
|
156
|
-
const sentinelPart = { type: "text", text: sentinelText };
|
|
157
|
-
parent.parts[index] = sentinelPart;
|
|
158
|
-
return true;
|
|
159
|
-
},
|
|
160
|
-
};
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
/** Classify part kind based on `type` field. Falls back to "unknown". */
|
|
164
|
-
function classifyOpenCodePart(part: unknown): TranscriptPartKind {
|
|
165
|
-
if (!isRecord(part)) return "unknown";
|
|
166
|
-
const type = part.type;
|
|
167
|
-
if (typeof type !== "string") return "unknown";
|
|
168
|
-
switch (type) {
|
|
169
|
-
case "text":
|
|
170
|
-
return "text";
|
|
171
|
-
case "reasoning":
|
|
172
|
-
return "thinking";
|
|
173
|
-
case "tool":
|
|
174
|
-
return "tool_use";
|
|
175
|
-
case "file":
|
|
176
|
-
return "file";
|
|
177
|
-
case "image":
|
|
178
|
-
return "image";
|
|
179
|
-
case "step-start":
|
|
180
|
-
case "step-finish":
|
|
181
|
-
return "structural";
|
|
182
|
-
default:
|
|
183
|
-
return "unknown";
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
/**
|
|
188
|
-
* Extract a stable per-part identifier when present. Used by the dropped-
|
|
189
|
-
* placeholder watermark to track which sentinels are already replayed
|
|
190
|
-
* across passes.
|
|
191
|
-
*/
|
|
192
|
-
function extractPartId(part: unknown): string | undefined {
|
|
193
|
-
if (!isRecord(part)) return undefined;
|
|
194
|
-
if (typeof part.id === "string" && part.id.length > 0) return part.id;
|
|
195
|
-
if (typeof part.callID === "string" && part.callID.length > 0) return part.callID;
|
|
196
|
-
return undefined;
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
function readOpenCodePartText(part: unknown): string | undefined {
|
|
200
|
-
if (!isRecord(part)) return undefined;
|
|
201
|
-
if (typeof part.text === "string") return part.text;
|
|
202
|
-
if (typeof part.thinking === "string") return part.thinking;
|
|
203
|
-
if (part.type === "tool") {
|
|
204
|
-
const state = isRecord(part.state) ? part.state : null;
|
|
205
|
-
const output = state && typeof state.output === "string" ? state.output : "";
|
|
206
|
-
return output;
|
|
207
|
-
}
|
|
208
|
-
return undefined;
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
function writeOpenCodePartText(part: unknown, newText: string): boolean {
|
|
212
|
-
if (!isRecord(part)) return false;
|
|
213
|
-
const writable = part as Record<string, unknown>;
|
|
214
|
-
if (typeof writable.text === "string") {
|
|
215
|
-
if (writable.text === newText) return false;
|
|
216
|
-
writable.text = newText;
|
|
217
|
-
return true;
|
|
218
|
-
}
|
|
219
|
-
if (typeof writable.thinking === "string") {
|
|
220
|
-
if (writable.thinking === newText) return false;
|
|
221
|
-
writable.thinking = newText;
|
|
222
|
-
return true;
|
|
223
|
-
}
|
|
224
|
-
return false;
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
function writeOpenCodeToolOutput(part: unknown, newText: string): boolean {
|
|
228
|
-
if (!isRecord(part)) return false;
|
|
229
|
-
if (part.type !== "tool") return false;
|
|
230
|
-
const state = isRecord(part.state) ? (part.state as Record<string, unknown>) : null;
|
|
231
|
-
if (!state) return false;
|
|
232
|
-
if (typeof state.output !== "string") return false;
|
|
233
|
-
if (state.output === newText) return false;
|
|
234
|
-
state.output = newText;
|
|
235
|
-
return true;
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
function readOpenCodeToolMetadata(part: unknown): {
|
|
239
|
-
toolName: string | undefined;
|
|
240
|
-
inputByteSize: number;
|
|
241
|
-
inputTokenCount: number;
|
|
242
|
-
} {
|
|
243
|
-
if (!isRecord(part)) return { toolName: undefined, inputByteSize: 0, inputTokenCount: 0 };
|
|
244
|
-
if (part.type !== "tool") return { toolName: undefined, inputByteSize: 0, inputTokenCount: 0 };
|
|
245
|
-
|
|
246
|
-
// OpenCode parts use `tool` as the tool name field; some legacy
|
|
247
|
-
// shapes use `toolName` or `name`. Match all three for forward
|
|
248
|
-
// compatibility with shape evolution.
|
|
249
|
-
const toolName =
|
|
250
|
-
typeof part.tool === "string"
|
|
251
|
-
? part.tool
|
|
252
|
-
: typeof part.toolName === "string"
|
|
253
|
-
? part.toolName
|
|
254
|
-
: typeof part.name === "string"
|
|
255
|
-
? part.name
|
|
256
|
-
: undefined;
|
|
257
|
-
|
|
258
|
-
const state = isRecord(part.state) ? part.state : null;
|
|
259
|
-
const input = state?.input ?? part.args ?? part.input;
|
|
260
|
-
|
|
261
|
-
let inputByteSize = 0;
|
|
262
|
-
let inputTokenCount = 0;
|
|
263
|
-
if (input !== undefined && input !== null) {
|
|
264
|
-
try {
|
|
265
|
-
const serialized = typeof input === "string" ? input : JSON.stringify(input);
|
|
266
|
-
inputByteSize = serialized.length;
|
|
267
|
-
inputTokenCount = serialized ? estimateTokens(serialized) : 0;
|
|
268
|
-
} catch {
|
|
269
|
-
inputByteSize = 0;
|
|
270
|
-
inputTokenCount = 0;
|
|
271
|
-
}
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
return { toolName, inputByteSize, inputTokenCount };
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
/** Non-mutating read of an OpenCode tool part's input object (or null). */
|
|
278
|
-
function readOpenCodeToolInput(part: unknown): Record<string, unknown> | null {
|
|
279
|
-
if (!isRecord(part)) return null;
|
|
280
|
-
const state = isRecord(part.state) ? part.state : null;
|
|
281
|
-
const input = state?.input ?? part.args ?? part.input;
|
|
282
|
-
return isRecord(input) ? input : null;
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
/** Replace an OpenCode tool part's input object in place. Returns true if a
|
|
286
|
-
* writable input slot was found. */
|
|
287
|
-
function writeOpenCodeToolInput(part: unknown, input: Record<string, unknown>): boolean {
|
|
288
|
-
if (!isRecord(part)) return false;
|
|
289
|
-
if (isRecord(part.state) && isRecord(part.state.input)) {
|
|
290
|
-
part.state.input = input;
|
|
291
|
-
return true;
|
|
292
|
-
}
|
|
293
|
-
if (isRecord(part.args)) {
|
|
294
|
-
part.args = input;
|
|
295
|
-
return true;
|
|
296
|
-
}
|
|
297
|
-
if (isRecord(part.input)) {
|
|
298
|
-
part.input = input;
|
|
299
|
-
return true;
|
|
300
|
-
}
|
|
301
|
-
return false;
|
|
302
|
-
}
|
|
File without changes
|