@kodax-ai/kodax 0.7.74 → 0.7.76

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/CHANGELOG.md +62 -0
  2. package/README.md +21 -1
  3. package/README_CN.md +17 -1
  4. package/dist/chunks/{agent-2ABIG5NW.js → agent-7X5CFET2.js} +1 -1
  5. package/dist/chunks/argument-completer-3NHIKB4N.js +2 -0
  6. package/dist/chunks/{chunk-XMP66YWG.js → chunk-4PWPNCNK.js} +4 -4
  7. package/dist/chunks/{chunk-C7TZAT3S.js → chunk-7FJNLJLF.js} +9 -9
  8. package/dist/chunks/chunk-COQYLD4U.js +5 -0
  9. package/dist/chunks/{chunk-XXQLPTAN.js → chunk-D3T24FJW.js} +7 -7
  10. package/dist/chunks/{chunk-F7AIEHSS.js → chunk-EI4JBQKL.js} +2 -2
  11. package/dist/chunks/{chunk-KPGVY6PF.js → chunk-HGT6WQ24.js} +4 -4
  12. package/dist/chunks/{chunk-7W6KYJU2.js → chunk-HS3XHF3R.js} +4 -4
  13. package/dist/chunks/{chunk-64M5HOCA.js → chunk-IDCGNQ4H.js} +1 -1
  14. package/dist/chunks/{chunk-5GH3SVI3.js → chunk-KAY2XLCP.js} +21 -21
  15. package/dist/chunks/{chunk-XM724XAA.js → chunk-OD6LVXU6.js} +4 -4
  16. package/dist/chunks/{chunk-VK5QTHS6.js → chunk-OSF3H4RR.js} +3 -3
  17. package/dist/chunks/{chunk-MBAPT2R5.js → chunk-PXKSE54E.js} +1 -1
  18. package/dist/chunks/{chunk-QH56WEHK.js → chunk-RDXRM3UI.js} +1 -1
  19. package/dist/chunks/{chunk-MVCAFD6M.js → chunk-SMT2JSM3.js} +1 -1
  20. package/dist/chunks/{chunk-VPURXE2F.js → chunk-TGMBHGZO.js} +119 -119
  21. package/dist/chunks/{chunk-UJS7JAO6.js → chunk-VWSLC2WO.js} +1 -1
  22. package/dist/chunks/{chunk-GAFFYJU3.js → chunk-Y3AMP22L.js} +12 -12
  23. package/dist/chunks/compaction-config-7J2XE35D.js +2 -0
  24. package/dist/chunks/{construction-bootstrap-BKNPJI7O.js → construction-bootstrap-5F5KF2BZ.js} +1 -1
  25. package/dist/chunks/{dist-EVEJAII2.js → dist-2RA7LSH3.js} +1 -1
  26. package/dist/chunks/{dist-6EK4H7TP.js → dist-URKXBOC6.js} +1 -1
  27. package/dist/chunks/host-RKZ2OGFT.js +2 -0
  28. package/dist/chunks/run-manager-7RM4HEH6.js +2 -0
  29. package/dist/chunks/{utils-GTJLL4GT.js → utils-X3TEH6IO.js} +1 -1
  30. package/dist/index.js +1 -1
  31. package/dist/kodax_cli.js +825 -825
  32. package/dist/provider-capabilities.json +35 -7
  33. package/dist/runtime-worker.js +756 -756
  34. package/dist/sdk-a2a.js +1 -1
  35. package/dist/sdk-agent.js +1 -1
  36. package/dist/sdk-coding.js +1 -1
  37. package/dist/sdk-experimental-memory.js +1 -1
  38. package/dist/sdk-llm.js +1 -1
  39. package/dist/sdk-mcp.js +1 -1
  40. package/dist/sdk-media.js +1 -1
  41. package/dist/sdk-repl.js +1 -1
  42. package/dist/sdk-runtime.d.ts +2 -1
  43. package/dist/sdk-runtime.js +1 -1
  44. package/dist/sdk-session.js +1 -1
  45. package/dist/sdk-skills.js +1 -1
  46. package/docs/SDK_EMBEDDER_GUIDE.md +144 -110
  47. package/package.json +1 -1
  48. package/dist/chunks/argument-completer-C45DEO34.js +0 -2
  49. package/dist/chunks/chunk-PP53SIIL.js +0 -5
  50. package/dist/chunks/compaction-config-QYCDOW3Q.js +0 -2
  51. package/dist/chunks/host-KS4TJKWQ.js +0 -2
  52. package/dist/chunks/run-manager-L7MKGQNX.js +0 -2
@@ -29,11 +29,12 @@ are NOT obvious from inspecting the type definitions alone:
29
29
  19. [Session surface filtering and cursor pagination](#19-session-surface-filtering-and-cursor-pagination-feature_261-v0767)
30
30
  20. [Cost-disciplined workflow routing and telemetry](#20-cost-disciplined-workflow-routing-and-telemetry-feature_259-v0767)
31
31
  21. [Experimental governed memory — `/experimental-memory`](#21-experimental-governed-memory--experimental-memory-feature_260-v0768)
32
- 22. [Bidirectional A2A 1.0 — `/a2a`](#22-bidirectional-a2a-10--a2a-feature_267-v0769)
33
- 23. [Shared Coder daemon for Space and IDE hosts](#23-shared-coder-daemon-for-space-and-ide-hosts-feature_269-v0769)
34
- 24. [Runtime-owned Auto Mode and plan-approval bridges](#24-runtime-owned-auto-mode-and-plan-approval-bridges-v0772v0773)
32
+ 22. [Bidirectional A2A 1.0 — `/a2a`](#22-bidirectional-a2a-10--a2a-feature_267-v0769)
33
+ 23. [Shared Coder daemon for Space and IDE hosts](#23-shared-coder-daemon-for-space-and-ide-hosts-feature_269-v0769)
34
+ 24. [Runtime-owned Auto Mode and plan-approval bridges](#24-runtime-owned-auto-mode-and-plan-approval-bridges-v0772v0773)
35
35
  25. [Always-on context compaction and bounded transcript recovery](#25-always-on-context-compaction-and-bounded-transcript-recovery-v0774)
36
36
  26. [Agent mailbox control versus SDK event telemetry](#26-agent-mailbox-control-versus-sdk-event-telemetry-v0774)
37
+ 27. [Windows GUI background subprocess visibility](#27-windows-gui-background-subprocess-visibility-v0775)
37
38
 
38
39
  §1–§3 (and the Phase-7/8 MCP-popout surface in §1) land in v0.7.42
39
40
  under FEATURE_186 (see [ADR-032](ADR.md#adr-032-sdk-embedder-surface-closure-feature_186-v0742)).
@@ -717,28 +718,28 @@ const replay = await loadSession('s_my_chat');
717
718
  const scrollback = await loadFullTranscript('s_my_chat');
718
719
  const compacted = await compactSession('s_my_chat', { dryRun: true });
719
720
 
720
- await appendClientNotice('s_my_chat', {
721
- source: 'space',
722
- content: '/doctor ok',
723
- });
724
- ```
725
-
726
- ### Auto-resume selection in v0.7.74
727
-
728
- With `session.autoResume: true` (or `resume: true`) and no explicit ID, KodaX
729
- calls `storage.list(context.gitRoot, { limit: 1000 })` and chooses the first
730
- newest-first summary whose `msgCount > 0`. This prevents newer zero-message
731
- ACP/bootstrap placeholders from shadowing a real conversation. An explicit
732
- `session.id` always wins. Custom `KodaXSessionStorage` implementations should
733
- therefore honor the optional `limit` argument and return `msgCount` accurately;
734
- they may return fewer than 1000 records.
735
-
736
- The standalone interactive CLI additionally restores the persisted
737
- workspace/runtime identity before the next turn. SDK embedders still own
738
- `context.gitRoot`, `context.executionCwd`, and storage construction; do not rely
739
- on process cwd as a substitute for host-owned runtime context.
740
-
741
- ### What `createSessionManager()` returns (v0.7.43+)
721
+ await appendClientNotice('s_my_chat', {
722
+ source: 'space',
723
+ content: '/doctor ok',
724
+ });
725
+ ```
726
+
727
+ ### Auto-resume selection in v0.7.74
728
+
729
+ With `session.autoResume: true` (or `resume: true`) and no explicit ID, KodaX
730
+ calls `storage.list(context.gitRoot, { limit: 1000 })` and chooses the first
731
+ newest-first summary whose `msgCount > 0`. This prevents newer zero-message
732
+ ACP/bootstrap placeholders from shadowing a real conversation. An explicit
733
+ `session.id` always wins. Custom `KodaXSessionStorage` implementations should
734
+ therefore honor the optional `limit` argument and return `msgCount` accurately;
735
+ they may return fewer than 1000 records.
736
+
737
+ The standalone interactive CLI additionally restores the persisted
738
+ workspace/runtime identity before the next turn. SDK embedders still own
739
+ `context.gitRoot`, `context.executionCwd`, and storage construction; do not rely
740
+ on process cwd as a substitute for host-owned runtime context.
741
+
742
+ ### What `createSessionManager()` returns (v0.7.43+)
742
743
 
743
744
  ```ts
744
745
  interface SessionManager {
@@ -3929,10 +3930,10 @@ const queued = await runtime.runs.submitInput({
3929
3930
  operation: { operationId: loadOrCreatePendingOperationId('space-input-17') },
3930
3931
  });
3931
3932
 
3932
- if (!queued.accepted) {
3933
- // stale_run, unsupported_capability, or interrupt_window_closed:
3934
- // show the factual result and preserve the user's unsent input.
3935
- }
3933
+ if (!queued.accepted) {
3934
+ // stale_run, unsupported_capability, or interrupt_window_closed:
3935
+ // show the factual result and preserve the user's unsent input.
3936
+ }
3936
3937
  ```
3937
3938
 
3938
3939
  For input that must join the current active Run, submit `delivery:'interrupt'`.
@@ -3941,19 +3942,19 @@ owning Run's `interruptInputs`. At the next safe boundary, all accumulated
3941
3942
  interrupts are drained FIFO, remain separate user messages in one next LLM
3942
3943
  request, and produce one `run.input.delivered` event whose `inputs` array is the
3943
3944
  complete ordered batch. Exact operation retries return the same `inputId`.
3944
- The accepted result's `runId` is the existing owning Run (equal to
3945
- `afterRunId`), not a newly created continuation.
3946
-
3947
- Interrupt admission closes when the Runner publishes its final completion or
3948
- terminal error signal, or when the Run's supplied `abortSignal` aborts, even if
3949
- the outer Run is still settling. Non-terminal observer diagnostics do not close
3950
- the window. A submission after closure returns `accepted:false` with
3951
- `reason:'interrupt_window_closed'` and is not queued. Keep the original input
3952
- available for retry after the Run ends; do not silently change its delivery to
3953
- `after_turn`. As a final race/recovery
3954
- guard, inspect terminal Run status: any `interruptInputs` entry whose state is
3955
- `terminal` was not delivered. Reconcile it by `inputId` and present a visible
3956
- non-delivery outcome rather than leaving a pending queue indicator.
3945
+ The accepted result's `runId` is the existing owning Run (equal to
3946
+ `afterRunId`), not a newly created continuation.
3947
+
3948
+ Interrupt admission closes when the Runner publishes its final completion or
3949
+ terminal error signal, or when the Run's supplied `abortSignal` aborts, even if
3950
+ the outer Run is still settling. Non-terminal observer diagnostics do not close
3951
+ the window. A submission after closure returns `accepted:false` with
3952
+ `reason:'interrupt_window_closed'` and is not queued. Keep the original input
3953
+ available for retry after the Run ends; do not silently change its delivery to
3954
+ `after_turn`. As a final race/recovery
3955
+ guard, inspect terminal Run status: any `interruptInputs` entry whose state is
3956
+ `terminal` was not delivered. Reconcile it by `inputId` and present a visible
3957
+ non-delivery outcome rather than leaving a pending queue indicator.
3957
3958
 
3958
3959
  ```ts
3959
3960
  const interrupted = await runtime.runs.submitInput({
@@ -3967,11 +3968,13 @@ const interrupted = await runtime.runs.submitInput({
3967
3968
 
3968
3969
  Run status exposes acceptance/start/queue times, authenticated origin,
3969
3970
  `sessionOrder`, and a single terminal fact. Important terminal codes include
3970
- `runtime_restarted`, `daemon_crashed`, `credential_unavailable`,
3971
- `host_not_dispatched`, `host_outcome_unknown`, and
3972
- `control_history_untrusted`. Respect `effectOutcome`; `unknown` must never be
3973
- presented as success or automatically retried. After a lost response, query
3974
- `runtime.operations.get({ operationId, journalEpoch })`; applied receipts
3971
+ `runtime_restarted`, `daemon_crashed`, `credential_unavailable`,
3972
+ `host_not_dispatched`, `host_outcome_unknown`, and
3973
+ `control_history_untrusted`. Managed tasks that require user input use
3974
+ `terminal.code = 'blocked'`; surface `terminal.message` when present instead of
3975
+ replacing it with a generic run failure. Respect `effectOutcome`; `unknown` must
3976
+ never be presented as success or automatically retried. After a lost response,
3977
+ query `runtime.operations.get({ operationId, journalEpoch })`; applied receipts
3975
3978
  include the canonical result. Permission grants remain daemon-owned and
3976
3979
  revisioned.
3977
3980
 
@@ -4541,74 +4544,104 @@ for (const hit of found.hits) {
4541
4544
  }
4542
4545
  ```
4543
4546
 
4544
- Search is deterministic Unicode lexical/metadata ranking, not an embedding or
4545
- background-model index. The Action LLM gets the corresponding
4546
- `session_history_search` and `session_history_read` pair only when its current
4547
- Run owns full-lineage-capable Session storage. A root Run reads its root
4548
- lineage. A persistent child Run gets a separately minted hidden
4549
- `managed-task-worker` Session and can recover only that child's compacted
4550
- history; it is never given root-history access. Storage-less Runs and a tool
4551
- visibility policy that hides either member expose neither member. Results are
4552
- low-authority historical evidence; current instructions and freshly verified
4553
- workspace state take precedence. System/control entries, hidden-only content,
4554
- synthetic current or legacy `[对话历史摘要]` checkpoints, and `[compacted]`
4555
- placeholders are neither searchable nor directly readable. Short ordinary
4556
- terms do not gain a metadata match merely because they occur inside a random
4557
- entry ID; direct identifier lookup is reserved for a sufficiently specific ID
4558
- query. Sessions compacted by older builds without an exact main/sidecar copy
4559
- cannot reconstruct bytes that were already discarded.
4560
-
4561
- Clients that depend on these guarantees should require
4562
- `contextCompaction: 3`, `transcriptPaging: 1`, and `transcriptSearch: 1` during
4563
- connection.
4547
+ Search is deterministic Unicode lexical/metadata ranking, not an embedding or
4548
+ background-model index. The Action LLM gets the corresponding
4549
+ `session_history_search` and `session_history_read` pair only when its current
4550
+ Run owns full-lineage-capable Session storage. A root Run reads its root
4551
+ lineage. A persistent child Run gets a separately minted hidden
4552
+ `managed-task-worker` Session and can recover only that child's compacted
4553
+ history; it is never given root-history access. Storage-less Runs and a tool
4554
+ visibility policy that hides either member expose neither member. Results are
4555
+ low-authority historical evidence; current instructions and freshly verified
4556
+ workspace state take precedence. System/control entries, hidden-only content,
4557
+ synthetic current or legacy `[对话历史摘要]` checkpoints, and `[compacted]`
4558
+ placeholders are neither searchable nor directly readable. Short ordinary
4559
+ terms do not gain a metadata match merely because they occur inside a random
4560
+ entry ID; direct identifier lookup is reserved for a sufficiently specific ID
4561
+ query. Sessions compacted by older builds without an exact main/sidecar copy
4562
+ cannot reconstruct bytes that were already discarded.
4563
+
4564
+ Clients that depend on these guarantees should require
4565
+ `contextCompaction: 3`, `transcriptPaging: 1`, and `transcriptSearch: 1` during
4566
+ connection.
4567
+
4568
+ ---
4569
+
4570
+ ## 26. Agent mailbox control versus SDK event telemetry (v0.7.74)
4571
+
4572
+ The model-visible `wait_agent` tool and the public Runtime Actor event APIs have
4573
+ different jobs. Do not expose `runtime.agents.wait()` to the model as though it
4574
+ were the same operation.
4575
+
4576
+ | Need | API | Wake/data contract |
4577
+ |---|---|---|
4578
+ | Let the action model yield until useful coordination evidence exists | `wait_agent({ timeout_ms })` | Caller-scoped Agent mailbox, root user input, interruption, or timeout; returns only a small acknowledgement. |
4579
+ | Render or diagnose Actor activity | `runtime.agents.events(sessionId, afterSequence?)` | Bounded event snapshot/replay, including progress and terminal events. |
4580
+ | Long-poll Actor telemetry from a host | `runtime.agents.wait(sessionId, afterSequence?, timeoutMs?)` | Returns the next sequenced Actor event, including progress. |
4581
+ | Read one known result | `runtime.agents.output(sessionId, actorPath, turnId?)` | Bounded current/terminal output and structured artifact metadata. |
4582
+ | Deliver a real user follow-up to the active root Run | `runtime.runs.submitInput(...)` | Ordered active-run input delivered at the next safe Runner boundary; requires `interruptInput:1`. |
4583
+
4584
+ For example, a host activity view can replay the current tail and then wait
4585
+ from its last sequence without causing another action-model request:
4586
+
4587
+ ```ts
4588
+ const snapshot = await runtime.agents.events(session.id);
4589
+ for (const event of snapshot) renderActorEvent(event);
4590
+
4591
+ const afterSequence = snapshot.at(-1)?.sequence;
4592
+ const next = await runtime.agents.wait(session.id, afterSequence, 30_000);
4593
+ if (next) renderActorEvent(next);
4594
+ ```
4595
+
4596
+ Model `wait_agent` has only `timeout_ms` in its schema (10,000 to 3,600,000 ms,
4597
+ default 120,000). Actor progress and Runtime `system-reminder` messages do not
4598
+ end that wait. A scoped Agent message/completion produces `mailbox`; queued root
4599
+ input produces `user_input_pending`; cancellation and expiry produce
4600
+ `interrupted` and `wait_expired`. Authenticated Agent evidence is drained at the
4601
+ next safe Runner boundary as synthetic context, while root input remains a real
4602
+ user turn. The acknowledgement itself never carries raw event batches.
4603
+
4604
+ Completion delivery is post-transcript and crash-recoverable. The Actor snapshot
4605
+ persists the explicit root completion turn IDs that still await transcript
4606
+ acknowledgement. A hard restart republishes only those IDs; a same-process
4607
+ Runtime rebuild deduplicates the projected queue by child turn ID. Once the
4608
+ parent transcript commits and acknowledges the completion, later restores do
4609
+ not replay it. Legacy snapshots without the explicit pending set do not infer
4610
+ replay work from historical mailbox content.
4611
+
4612
+ This separation changes no Actor event capability or daemon version: existing
4613
+ SDK snapshot, replay, and long-poll clients keep their telemetry surface. It
4614
+ only prevents high-frequency progress from becoming a model control signal.
4564
4615
 
4565
4616
  ---
4566
4617
 
4567
- ## 26. Agent mailbox control versus SDK event telemetry (v0.7.74)
4568
-
4569
- The model-visible `wait_agent` tool and the public Runtime Actor event APIs have
4570
- different jobs. Do not expose `runtime.agents.wait()` to the model as though it
4571
- were the same operation.
4572
-
4573
- | Need | API | Wake/data contract |
4574
- |---|---|---|
4575
- | Let the action model yield until useful coordination evidence exists | `wait_agent({ timeout_ms })` | Caller-scoped Agent mailbox, root user input, interruption, or timeout; returns only a small acknowledgement. |
4576
- | Render or diagnose Actor activity | `runtime.agents.events(sessionId, afterSequence?)` | Bounded event snapshot/replay, including progress and terminal events. |
4577
- | Long-poll Actor telemetry from a host | `runtime.agents.wait(sessionId, afterSequence?, timeoutMs?)` | Returns the next sequenced Actor event, including progress. |
4578
- | Read one known result | `runtime.agents.output(sessionId, actorPath, turnId?)` | Bounded current/terminal output and structured artifact metadata. |
4579
- | Deliver a real user follow-up to the active root Run | `runtime.runs.submitInput(...)` | Ordered active-run input delivered at the next safe Runner boundary; requires `interruptInput:1`. |
4580
-
4581
- For example, a host activity view can replay the current tail and then wait
4582
- from its last sequence without causing another action-model request:
4618
+ ## 27. Windows GUI background subprocess visibility (v0.7.75)
4583
4619
 
4584
- ```ts
4585
- const snapshot = await runtime.agents.events(session.id);
4586
- for (const event of snapshot) renderActorEvent(event);
4620
+ KodaX SDK hosts do not need to add process-wide console suppression around the
4621
+ Runtime. In the v0.7.75 release candidate, Runtime Worker-reachable
4622
+ non-interactive/background child processes request `windowsHide: true` at their
4623
+ own spawn boundary. The covered paths include:
4587
4624
 
4588
- const afterSequence = snapshot.at(-1)?.sequence;
4589
- const next = await runtime.agents.wait(session.id, afterSequence, 30_000);
4590
- if (next) renderActorEvent(next);
4591
- ```
4625
+ - memory and Git metadata probes;
4626
+ - provider CLI execution and ACP servers;
4627
+ - LSP acquisition and language servers;
4628
+ - clipboard helpers, worktrees, review commands, and extension commands;
4629
+ - managed-task checkpoints and sandbox helpers.
4592
4630
 
4593
- Model `wait_agent` has only `timeout_ms` in its schema (10,000 to 3,600,000 ms,
4594
- default 120,000). Actor progress and Runtime `system-reminder` messages do not
4595
- end that wait. A scoped Agent message/completion produces `mailbox`; queued root
4596
- input produces `user_input_pending`; cancellation and expiry produce
4597
- `interrupted` and `wait_expired`. Authenticated Agent evidence is drained at the
4598
- next safe Runner boundary as synthetic context, while root input remains a real
4599
- user turn. The acknowledgement itself never carries raw event batches.
4631
+ The contract is intentionally narrow. Explicit external editors, terminal
4632
+ commands, and PTY sessions remain interactive. POSIX-only `ps`, `tmux`, and
4633
+ sandbox branches are reviewed bundle-audit exceptions rather than Windows
4634
+ visibility paths.
4600
4635
 
4601
- Completion delivery is post-transcript and crash-recoverable. The Actor snapshot
4602
- persists the explicit root completion turn IDs that still await transcript
4603
- acknowledgement. A hard restart republishes only those IDs; a same-process
4604
- Runtime rebuild deduplicates the projected queue by child turn ID. Once the
4605
- parent transcript commits and acknowledges the completion, later restores do
4606
- not replay it. Legacy snapshots without the explicit pending set do not infer
4607
- replay work from historical mailbox content.
4608
-
4609
- This separation changes no Actor event capability or daemon version: existing
4610
- SDK snapshot, replay, and long-poll clients keep their telemetry surface. It
4611
- only prevents high-frequency progress from becoming a model control signal.
4636
+ `npm run build:bundle` audits every statically identifiable child-process call
4637
+ reachable from `dist/runtime-worker.js`. The packaged Electron daemon smoke then
4638
+ runs 20 ordinary queries with a Win32 probe and checks that the expected Git
4639
+ children never own a visible console window. These checks validate the SDK
4640
+ boundary, but they do not replace product-level validation in the packaged host.
4641
+ KodaX Space should install the exact v0.7.75 tarball and complete
4642
+ [`ISSUE_205_v0.7.75_REGRESSION_GUIDE.md`](test-guides/ISSUE_205_v0.7.75_REGRESSION_GUIDE.md)
4643
+ on Windows 10 and Windows 11 as a non-blocking product validation follow-up.
4644
+ This follow-up does not gate SDK packaging, tagging, or publication.
4612
4645
 
4613
4646
  ---
4614
4647
 
@@ -4616,8 +4649,9 @@ only prevents high-frequency progress from becoming a model control signal.
4616
4649
 
4617
4650
  - [README.md](../README.md) — end-user CLI quick start
4618
4651
  - [docs/ADR.md ADR-024](ADR.md#adr-024-npm-发布物正名-kodax-aikodax--sdk-subpath-exports-形式化-v0739) — SDK subpath architecture rationale
4619
- - [docs/ADR.md ADR-032](ADR.md#adr-032-sdk-embedder-surface-closure-feature_186-v0742) — FEATURE_186 design record (all 8 phases)
4620
- - [docs/ADR.md ADR-057](ADR.md#adr-057-large-compaction-is-an-always-on-context-scoped-full-coverage-transaction) — v0.7.74 compaction and exact-history ownership
4652
+ - [docs/ADR.md ADR-032](ADR.md#adr-032-sdk-embedder-surface-closure-feature_186-v0742) — FEATURE_186 design record (all 8 phases)
4653
+ - [docs/ADR.md ADR-057](ADR.md#adr-057-large-compaction-is-an-always-on-context-scoped-full-coverage-transaction) — v0.7.74 compaction and exact-history ownership
4621
4654
  - [docs/ADR.md ADR-058](ADR.md#adr-058-model-agent-wait-is-mailbox-control-not-event-telemetry) — mailbox control versus Actor telemetry
4622
4655
  - [docs/features/v0.7.42.md FEATURE_186](features/v0.7.42.md#feature_186-sdk-embedder-surface-closure--kodax-space-gap-list--mcp-popout) — gap-by-gap landing matrix
4623
4656
  - [docs/features/v0.7.74.md](features/v0.7.74.md) — v0.7.74 release-candidate design and verification record
4657
+ - [docs/features/v0.7.75.md](features/v0.7.75.md) — v0.7.75 Windows GUI and Sidecar/Runtime stabilization candidate
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kodax-ai/kodax",
3
- "version": "0.7.74",
3
+ "version": "0.7.76",
4
4
  "description": "KodaX lightweight coding agent - TypeScript implementation with 16 built-in LLM provider aliases, published as a Node-free single-file CLI and SDK",
5
5
  "type": "module",
6
6
  "private": false,
@@ -1,2 +0,0 @@
1
- // @kodax-ai/kodax — bundled distribution. See docs/ADR.md ADR-022 + ADR-024.
2
- import{Ja as a,Ka as b}from"./chunk-7W6KYJU2.js";import"./chunk-XMP66YWG.js";import"./chunk-QH56WEHK.js";import"./chunk-VPURXE2F.js";import"./chunk-MVCAFD6M.js";import"./chunk-VK5QTHS6.js";import"./chunk-XM724XAA.js";import"./chunk-64M5HOCA.js";import"./chunk-MBAPT2R5.js";import"./chunk-C7TZAT3S.js";import"./chunk-XXQLPTAN.js";import"./chunk-UJS7JAO6.js";import"./chunk-GAFFYJU3.js";import"./chunk-PP53SIIL.js";import"./chunk-F7AIEHSS.js";import"./chunk-ONUPGMER.js";export{a as ArgumentCompleter,b as createArgumentCompleter};
@@ -1,5 +0,0 @@
1
- // @kodax-ai/kodax — bundled distribution. See docs/ADR.md ADR-022 + ADR-024.
2
- import{g as R,h as _}from"./chunk-F7AIEHSS.js";import{a as r}from"./chunk-ONUPGMER.js";var u=class extends Error{static{r(this,"KodaXMediaError")}code;detail;cause;constructor(e,i,o={}){super(i),this.name="KodaXMediaError",this.code=e,this.detail=o.detail,this.cause=o.cause}},p=class extends u{static{r(this,"ImageResizeError")}constructor(e,i={}){super(i.code??"IMAGE_TOO_LARGE",e,i),this.name="ImageResizeError"}};import O from"node:path";var Z={".gif":"image/gif",".jpeg":"image/jpeg",".jpg":"image/jpeg",".png":"image/png",".webp":"image/webp"},ee={".3gp":"video/3gpp",".3gpp":"video/3gpp",".avi":"video/x-msvideo",".flv":"video/x-flv",".mov":"video/quicktime",".mp4":"video/mp4",".mpeg":"video/mpeg",".mpg":"video/mpeg",".webm":"video/webm",".wmv":"video/x-ms-wmv"};function N(t){return Z[O.extname(t).toLowerCase()]}r(N,"inferImageMediaType");function $(t){return ee[O.extname(t).toLowerCase()]}r($,"inferVideoMediaType");function te(t,e={}){let i=e.mediaType??N(t);return{kind:"image",path:t,...i?{mediaType:i}:{},...e.source?{source:e.source}:{},...e.description?{description:e.description}:{}}}r(te,"createImageArtifactFromPath");function ie(t,e={}){if(e.mediaType!==void 0&&e.mimeType!==void 0&&e.mediaType!==e.mimeType)throw new u("UNSUPPORTED_MEDIA_TYPE",`File artifact mediaType and mimeType disagree: ${e.mediaType} != ${e.mimeType}.`);return{kind:"file",path:t,...e.mediaType?{mediaType:e.mediaType}:{},...e.mimeType?{mimeType:e.mimeType}:{},...e.name?{name:e.name}:{},...e.source?{source:e.source}:{},...e.description?{description:e.description}:{}}}r(ie,"createFileArtifactFromPath");function re(t,e={}){let i=e.mediaType??$(t);if(!i)throw new u("UNSUPPORTED_MEDIA_TYPE",`Cannot infer video media type from path: ${t}.`);return{kind:"video",path:t,mediaType:i,...e.name?{name:e.name}:{},...e.source?{source:e.source}:{},...e.description?{description:e.description}:{}}}r(re,"createVideoArtifactFromPath");import{Jimp as ne}from"jimp";var F=2e3,C=Math.floor(3.75*1024*1024),oe=[80,60,40];async function A(t,e={}){let i=e.maxDimension??F,o=e.targetBytes??C;if(t.length===0)throw new p("Empty image buffer.",{code:"IMAGE_DECODE_FAILED"});let n;try{n=await ne.read(t)}catch(c){let I=c instanceof Error?c.message:String(c);throw new p(`Failed to decode image: ${I}`,{code:"IMAGE_DECODE_FAILED",cause:c})}let{width:a,height:d}=n.bitmap,s=Math.max(a,d);if(s>i){let c=i/s;n.resize({w:Math.max(1,Math.round(a*c)),h:Math.max(1,Math.round(d*c))})}let m=n.bitmap.width,l=n.bitmap.height;if(e.preferMediaType!=="image/jpeg"){let c=await n.getBuffer("image/png");if(c.length<=o)return{buffer:Buffer.from(c),mediaType:"image/png",width:m,height:l}}for(let c of oe){let I=await n.getBuffer("image/jpeg",{quality:c});if(I.length<=o)return{buffer:Buffer.from(I),mediaType:"image/jpeg",width:m,height:l}}if(e.preferMediaType==="image/jpeg"){let c=await n.getBuffer("image/png");if(c.length<=o)return{buffer:Buffer.from(c),mediaType:"image/png",width:m,height:l}}throw new p(`Image still exceeds budget (${o} bytes raw) after PNG and JPEG q40 compression. Try a smaller image or take a fresh screenshot of a smaller region.`,{code:"IMAGE_TOO_LARGE"})}r(A,"normalizePastedImage");import{spawn as L}from"node:child_process";import{mkdtemp as ae,readFile as se,rm as de}from"node:fs/promises";import{tmpdir as me}from"node:os";import U from"node:path";var q=5e3;async function X(){switch(process.platform){case"darwin":return ce();case"win32":return fe();case"linux":return pe();default:throw new u("UNSUPPORTED_PLATFORM",`Clipboard image fallback is not supported on platform "${process.platform}".`)}}r(X,"readClipboardImage");async function ue(t={}){let e=await X();return e?A(e,t):null}r(ue,"readAndNormalizeClipboardImage");async function j(t){let e=await ae(U.join(me(),"kodax-clip-")),i=U.join(e,"clip.png");try{return await t(i)}finally{await de(e,{recursive:!0,force:!0}).catch(o=>{})}}r(j,"runWithTempPng");async function ce(){return j(async t=>{let e=`set png_data to (the clipboard as \xABclass PNGf\xBB)
3
- set fh to open for access POSIX file "${t.replace(/"/g,'\\"')}" with write permission
4
- write png_data to fh
5
- close access fh`;return await G("osascript",["-e",e])?B(t):null})}r(ce,"readMacClipboard");async function fe(){return j(async t=>{let e=["Add-Type -AssemblyName System.Drawing | Out-Null","$img = Get-Clipboard -Format Image","if ($null -eq $img) { exit 1 }",`$img.Save('${t.replace(/'/g,"''")}', [System.Drawing.Imaging.ImageFormat]::Png)`].join("; ");return await G("powershell",["-NoProfile","-Command",e])?B(t):null})}r(fe,"readWinClipboard");async function pe(){return await K("wl-paste",["--type","image/png"])??K("xclip",["-selection","clipboard","-t","image/png","-o"])}r(pe,"readLinuxClipboard");async function B(t){try{let e=await se(t);return e.length>0?e:null}catch(e){return null}}r(B,"readNonEmptyFile");function G(t,e){return new Promise(i=>{let o=!1,n=L(t,[...e],{stdio:"ignore"}),a=setTimeout(()=>{o||(o=!0,n.kill(),i(!1))},q);n.once("error",()=>{o||(o=!0,clearTimeout(a),i(!1))}),n.once("exit",d=>{o||(o=!0,clearTimeout(a),i(d===0))})})}r(G,"runCommand");function K(t,e){return new Promise(i=>{let o=!1,n=[],a=L(t,[...e],{stdio:["ignore","pipe","ignore"]}),d=setTimeout(()=>{o||(o=!0,a.kill(),i(null))},q);a.stdout?.on("data",s=>n.push(s)),a.once("error",()=>{o||(o=!0,clearTimeout(d),i(null))}),a.once("exit",s=>{if(o)return;if(o=!0,clearTimeout(d),s!==0){i(null);return}let m=Buffer.concat(n);i(m.length>0?m:null)})})}r(K,"collectStdoutBytes");import{createHash as le}from"node:crypto";import{mkdir as ge,readdir as he,stat as Te,unlink as ye,writeFile as Ie}from"node:fs/promises";import{tmpdir as Ee}from"node:os";import x from"node:path";var Y="KODAX_PASTE_TMP_DIR",z=1440*60*1e3;function Q(){return process.env[Y]??x.join(Ee(),"kodax-paste")}r(Q,"resolvePasteTmpDir");function we(t){let e=t?.trim().replace(/[^A-Za-z0-9._-]+/g,"-").replace(/^-+|-+$/g,"");return e&&e.length>0?e:"paste"}r(we,"sanitizeFileNamePrefix");async function _e(t,e={}){let i=e.directory??Q();await ge(i,{recursive:!0});let o=t.mediaType==="image/jpeg"?".jpg":".png",n=le("sha256").update(t.buffer).digest("hex").slice(0,16),a=`${we(e.fileNamePrefix)}-${n}${o}`,d=x.join(i,a);return await Ie(d,t.buffer),{type:"image",path:d,mediaType:t.mediaType}}r(_e,"persistImageAsBlock");async function Ae(t=Date.now()){let e=Q(),i;try{i=await he(e)}catch(a){return 0}let o=t-z,n=0;return await Promise.all(i.filter(a=>/-[0-9a-f]{16}\.(?:png|jpg)$/.test(a)).map(async a=>{let d=x.join(e,a);try{(await Te(d)).mtimeMs<o&&(await ye(d),n+=1)}catch(s){}})),n}r(Ae,"prunePasteTmpDir");var h=["image/png","image/jpeg","image/webp","image/gif"],T=["video/mp4","video/mpeg","video/quicktime","video/x-msvideo","video/x-flv","video/webm","video/x-ms-wmv","video/3gpp"],xe=[],ke=new Set(["anthropic","openai"]),Me=new Set(["ark-coding/doubao-seed-2.0-code","ark-coding/doubao-seed-2.0-pro","ark-coding/kimi-k2.6","ark-coding/kimi-k2.7-code","ark-coding/minimax-m3","qwen-token-plan/qwen3.8-max-preview","qwen-token-plan/qwen3.7-plus","qwen-token-plan/qwen3.6-flash"]),De=new Set(["kimi-code/kimi-for-coding","kimi-code/kimi-for-coding-highspeed","kimi-code/k3","kimi/kimi-k2.5","kimi/kimi-k2.6","kimi/kimi-k2.7-code","kimi/kimi-k2.7-code-highspeed","minimax-coding/minimax-m3","minimax/minimax-m3","mimo-coding/mimo-v2.5","mimo/mimo-v2.5"]);function k(t){return{nativeSupported:!1,sdkSupported:!1,status:"unsupported",mediaTypes:[],maxCount:0,reason:t}}r(k,"unsupported");function Pe(t){return{nativeSupported:!0,sdkSupported:!0,status:"supported",mediaTypes:h,nativeMediaTypes:h,reason:t}}r(Pe,"supportedImage");function ve(t){return{nativeSupported:!0,sdkSupported:!1,status:"provider-native-unwired",mediaTypes:[],nativeMediaTypes:T,maxCount:0,reason:t}}r(ve,"nativeVideoUnwired");function Se(t){return t.trim().toLowerCase()}r(Se,"normalizeProvider");function be(t){return _[t]?.model}r(be,"resolveProviderDefaultModel");function V(t,e){if(!e)return;let i=e.trim().toLowerCase();if(t==="kimi"){if(i==="k2.5")return"kimi-k2.5";if(i==="k2.6")return"kimi-k2.6";if(i==="k2.7-code")return"kimi-k2.7-code";if(i==="k2.7-code-highspeed")return"kimi-k2.7-code-highspeed"}return t==="kimi-code"&&i==="k3-256k"?"k3":(t==="minimax-coding"||t==="minimax")&&i==="minimax-m3"?"minimax-m3":i}r(V,"normalizeModel");function Re(t){if(!ke.has(t))return!1;let e=_[t];return e?R(e.capabilityProfile).multimodalSupport!=="none":!1}r(Re,"hasOfficialImageSupport");function Oe(t,e){let i=V(t,e);if(!i)return!1;let o=`${t}/${i}`;return De.has(o)}r(Oe,"hasSourceBackedNativeMedia");function Ne(t,e){let i=V(t,e);return i?Me.has(`${t}/${i}`):!1}r(Ne,"hasSourceBackedImage");function $e(t,e,i){if(i)return"source-backed";if(e){if(t==="openai")return"openai-official";if(t==="anthropic")return"anthropic-official"}}r($e,"resolveImageCapabilityRoute");function Fe(t){switch(t){case"openai-official":return"Model route supports KodaX image input. Direct-path image/gif is sent as image/gif, but OpenAI requires non-animated GIF semantics.";case"anthropic-official":return"Model route supports KodaX image input. Direct-path image/gif is sent as image/gif, but Anthropic uses only the first frame of animated GIFs.";case"source-backed":return"Model route supports KodaX image input. Direct-path image/gif is sent as image/gif; animated-GIF interpretation is provider-owned."}}r(Fe,"imageCapabilityReason");function M(t){let e=Se(t.provider),i=t.model?.trim()||be(e),o=Re(e),n=Oe(e,i),a=n||Ne(e,i),d=$e(e,o,a),s=d!==void 0,m=n;return{text:!0,image:s?Pe(Fe(d)):k("No verified KodaX image-input route for this provider/model."),video:m?ve("Model route is native-video capable, but KodaX SDK video sending is not wired yet. Reject or downgrade before send."):k("No verified native video route for this provider/model."),file:k("File artifact contract is stable, but KodaX SDK file sending/extraction is not wired yet. Reject or downgrade before send.")}}r(M,"getModelInputCapabilities");function Ce(t){return h.includes(t)}r(Ce,"isKnownImageMediaType");function Ue(t){return T.includes(t)}r(Ue,"isKnownVideoMediaType");function D(t){return`${t.provider}${t.model?`/${t.model}`:""}`}r(D,"routeLabel");function P(t){return t.reason?`${t.status}: ${t.reason}`:t.status}r(P,"capabilityDetail");function v(t,e){if(t.length===0)return;let i=M(e);for(let o of t){let n=o;if(n.kind==="image"){if(!i.image.nativeSupported||!i.image.sdkSupported)throw new u("MODEL_INPUT_UNSUPPORTED",`Provider/model cannot consume image artifacts: ${D(e)}.`,{detail:P(i.image)});if(typeof n.mediaType=="string"&&!Ce(n.mediaType))throw new u("UNSUPPORTED_MEDIA_TYPE",`Unsupported image media type: ${n.mediaType}.`);continue}throw n.kind==="video"?typeof n.mediaType!="string"||!Ue(n.mediaType)?new u("UNSUPPORTED_MEDIA_TYPE",`Unsupported video media type: ${String(n.mediaType)}.`,{detail:`Supported video media types: ${T.join(", ")}`}):new u("MODEL_INPUT_UNSUPPORTED",`Provider/model cannot consume video artifacts through this SDK runtime: ${D(e)}.`,{detail:P(i.video)}):n.kind==="file"?typeof n.mediaType=="string"&&typeof n.mimeType=="string"&&n.mediaType!==n.mimeType?new u("UNSUPPORTED_MEDIA_TYPE",`File artifact mediaType and mimeType disagree: ${n.mediaType} != ${n.mimeType}.`):new u("MODEL_INPUT_UNSUPPORTED",`Provider/model cannot consume file artifacts through this SDK runtime: ${D(e)}.`,{detail:P(i.file)}):new u("MODEL_INPUT_UNSUPPORTED",`Unsupported input artifact kind: ${String(n.kind)}.`)}}r(v,"validateInputArtifactsForModel");var g={user:0,background:1};function Ke(t,e){return g[t]<=g[e]}r(Ke,"priorityWithinMax");function W(t,e){return!(t.agentId!==e.agentId||!Ke(t.priority,e.maxPriority)||e.mode!==void 0&&t.mode!==e.mode||e.id!==void 0&&t.id!==e.id||e.predicate&&!e.predicate(t))}r(W,"matchesFilter");var w=class{static{r(this,"MessageQueue")}messages=[];nextSeq=1;listeners=new Set;snapshotRef=Object.freeze([]);notify(e){this.snapshotRef=Object.freeze([...this.messages]);for(let i of this.listeners)try{i(e)}catch{}}subscribe=r(e=>(this.listeners.add(e),()=>{this.listeners.delete(e)}),"subscribe");getSnapshot=r(()=>this.snapshotRef,"getSnapshot");enqueue(e){let i=`msg-${this.nextSeq++}`,o={id:i,priority:e.priority,mode:e.mode,content:e.content,agentId:e.agentId,inputArtifacts:e.inputArtifacts,taskResult:e.taskResult,enqueuedAt:Date.now()};return this.messages=[...this.messages,o],this.notify({kind:"enqueued",message:o}),i}dequeue(e){let i=[];for(let s=0;s<this.messages.length;s++){let m=this.messages[s];m&&W(m,e)&&i.push({originalIndex:s,message:m})}i.sort((s,m)=>{let l=g[s.message.priority]-g[m.message.priority];return l!==0?l:s.originalIndex-m.originalIndex});let o=e.limit,n=typeof o=="number"&&i.length>o?i.slice(0,o):i;if(n.length===0)return[];let a=new Set(n.map(s=>s.originalIndex));this.messages=this.messages.filter((s,m)=>!a.has(m));let d=n.map(s=>s.message);return this.notify({kind:"dequeued",messages:d}),d}peek(e){let i=[];for(let a=0;a<this.messages.length;a++){let d=this.messages[a];d&&W(d,e)&&i.push({originalIndex:a,message:d})}i.sort((a,d)=>{let s=g[a.message.priority]-g[d.message.priority];return s!==0?s:a.originalIndex-d.originalIndex});let o=e.limit;return(typeof o=="number"&&i.length>o?i.slice(0,o):i).map(a=>a.message)}size(){return this.messages.length}count(e){return this.peek(e).length}has(e){return this.count(e)>0}clear(){if(this.messages.length===0)return;let e=this.messages;this.messages=[],this.notify({kind:"cleared",messages:e})}},E;function y(){return E||(E=new w),E}r(y,"getMessageQueue");function Le(){E=void 0}r(Le,"_resetMessageQueueForTests");function S(t,e){return t?`actor:${t}:${e}`:e==="/root"?void 0:e}r(S,"actorQueueId");var f=new Map;function qe(t){f.set(t,(f.get(t)??0)+1);let e=!1;return()=>{if(e)return;e=!0;let i=f.get(t);i===void 0||i<=1?f.delete(t):f.set(t,i-1)}}r(qe,"registerActiveRootQueueRoute");function b(){if(f.size!==0){if(f.size===1)return f.keys().next().value;throw new Error("Cannot infer queued follow-up target: multiple Actor root sessions are active. Pass sessionId or agentId explicitly.")}}r(b,"resolveActiveRootQueueRoute");function Xe(){f.clear()}r(Xe,"_resetActiveRootQueueRoutesForTests");var H=new Set(["wait_agent"]);function J(t){return t.some(i=>H.has(i))?"background":"user"}r(J,"midTurnDrainPriority");function je(t){let e=J(t.lastTurnToolNames);return y().dequeue({agentId:t.agentId,maxPriority:e,limit:t.limit})}r(je,"maybeDrainMidTurn");function Be(t){if(v(t.inputArtifacts??[],t),t.agentId!==void 0&&t.sessionId!==void 0)throw new Error("enqueueWithArtifacts accepts either agentId or sessionId, not both.");if(t.sessionId!==void 0&&t.sessionId.trim().length===0)throw new Error("enqueueWithArtifacts sessionId must not be empty.");let e=t.agentId??(t.sessionId!==void 0?S(t.sessionId,"/root"):b());return y().enqueue({priority:t.priority??"user",mode:"prompt",content:t.content,agentId:e,inputArtifacts:t.inputArtifacts})}r(Be,"enqueueWithArtifacts");export{u as a,p as b,N as c,$ as d,te as e,ie as f,re as g,F as h,C as i,A as j,X as k,ue as l,Y as m,z as n,_e as o,Ae as p,h as q,T as r,xe as s,M as t,v as u,w as v,y as w,Le as x,S as y,qe as z,b as A,Xe as B,H as C,J as D,je as E,Be as F};
@@ -1,2 +0,0 @@
1
- // @kodax-ai/kodax — bundled distribution. See docs/ADR.md ADR-022 + ADR-024.
2
- import{a}from"./chunk-QH56WEHK.js";import"./chunk-UJS7JAO6.js";import"./chunk-GAFFYJU3.js";import"./chunk-PP53SIIL.js";import"./chunk-F7AIEHSS.js";import"./chunk-ONUPGMER.js";export{a as loadCompactionConfig};
@@ -1,2 +0,0 @@
1
- // @kodax-ai/kodax — bundled distribution. See docs/ADR.md ADR-022 + ADR-024.
2
- import{j as a}from"./chunk-MVCAFD6M.js";import"./chunk-VK5QTHS6.js";import"./chunk-MBAPT2R5.js";import"./chunk-C7TZAT3S.js";import"./chunk-XXQLPTAN.js";import"./chunk-UJS7JAO6.js";import"./chunk-GAFFYJU3.js";import"./chunk-PP53SIIL.js";import"./chunk-F7AIEHSS.js";import"./chunk-ONUPGMER.js";export{a as startManagedWorkflow};
@@ -1,2 +0,0 @@
1
- // @kodax-ai/kodax — bundled distribution. See docs/ADR.md ADR-022 + ADR-024.
2
- import{I as a,J as b}from"./chunk-VK5QTHS6.js";import"./chunk-C7TZAT3S.js";import"./chunk-XXQLPTAN.js";import"./chunk-UJS7JAO6.js";import"./chunk-GAFFYJU3.js";import"./chunk-PP53SIIL.js";import"./chunk-F7AIEHSS.js";import"./chunk-ONUPGMER.js";export{a as createWorkflowRunManager,b as getDefaultWorkflowRunManager};