@kodax-ai/kodax 0.7.67 → 0.7.68
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/CHANGELOG.md +72 -0
- package/README.md +11 -6
- package/README_CN.md +12 -8
- package/dist/chunks/agent-DATNZOBK.js +2 -0
- package/dist/chunks/argument-completer-X7MMM7Y6.js +2 -0
- package/dist/chunks/chunk-5GL55MOH.js +36 -0
- package/dist/chunks/chunk-67XJ4YUA.js +703 -0
- package/dist/chunks/{chunk-YH5BTUQO.js → chunk-C4SBXBWH.js} +193 -190
- package/dist/chunks/{chunk-DEICMTHO.js → chunk-CC4BVVE7.js} +1 -1
- package/dist/chunks/{chunk-EN3O2C43.js → chunk-CTHUX5ZH.js} +2 -2
- package/dist/chunks/{chunk-YRBNXFHY.js → chunk-HFM2D5BP.js} +1 -1
- package/dist/chunks/chunk-HLBHSA2B.js +325 -0
- package/dist/chunks/{chunk-O7N22GJ3.js → chunk-K2NCKRVY.js} +16 -14
- package/dist/chunks/{chunk-KBBGDRER.js → chunk-KGAI32VS.js} +2 -2
- package/dist/chunks/{chunk-WCSSXBHR.js → chunk-KIQRCGVR.js} +13 -13
- package/dist/chunks/{chunk-W2XMNYLK.js → chunk-MP52BDK5.js} +12 -12
- package/dist/chunks/chunk-O5OJQFPY.js +307 -0
- package/dist/chunks/chunk-OIELNE6Z.js +56 -0
- package/dist/chunks/chunk-PEGSHZAA.js +5 -0
- package/dist/chunks/chunk-TOGESFRN.js +2 -0
- package/dist/chunks/compaction-config-BXEDHIQP.js +2 -0
- package/dist/chunks/{construction-bootstrap-GLEHQ2KB.js → construction-bootstrap-PYWJHO35.js} +1 -1
- package/dist/chunks/dist-76PJHNSG.js +2 -0
- package/dist/chunks/{dist-4PXB7U22.js → dist-HTDJRAD6.js} +1 -1
- package/dist/chunks/host-UAXIDZ6V.js +2 -0
- package/dist/chunks/run-manager-UCXB4G22.js +2 -0
- package/dist/chunks/utils-S63V5UCM.js +2 -0
- package/dist/index.d.ts +15 -15
- package/dist/index.js +1 -1
- package/dist/kodax_cli.js +1199 -1185
- package/dist/runtime-worker.js +1021 -1007
- package/dist/sdk-agent.d.ts +126 -18
- package/dist/sdk-agent.js +1 -1
- package/dist/sdk-coding.d.ts +18 -18
- package/dist/sdk-coding.js +1 -1
- package/dist/sdk-experimental-memory.d.ts +618 -0
- package/dist/sdk-experimental-memory.js +2 -0
- package/dist/sdk-llm.d.ts +6 -6
- package/dist/sdk-llm.js +1 -1
- package/dist/sdk-mcp.js +1 -1
- package/dist/sdk-media.d.ts +1 -1
- package/dist/sdk-repl.d.ts +15 -15
- package/dist/sdk-repl.js +1 -1
- package/dist/sdk-runtime.d.ts +11 -11
- package/dist/sdk-runtime.js +1 -1
- package/dist/sdk-session.d.ts +6 -6
- package/dist/sdk-session.js +1 -1
- package/dist/sdk-skills.js +1 -1
- package/dist/semantic-worker.js +12 -12
- package/dist/types-chunks/{base.d-DalIRhbb.d.ts → base.d-C8mXDhLL.d.ts} +1 -1
- package/dist/types-chunks/{bash-prefix-extractor.d-D57Gt6n8.d.ts → bash-prefix-extractor.d-Dm-T865v.d.ts} +24 -4
- package/dist/types-chunks/{capability-learning.d-BQB0M70w.d.ts → capability-learning.d-BLEmCib0.d.ts} +1 -1
- package/dist/types-chunks/{capsule.d-BZmqu_HL.d.ts → capsule.d-CzaamUUv.d.ts} +5 -5
- package/dist/types-chunks/{commands.d-Cg26ud-Y.d.ts → commands.d-DxKjVSNU.d.ts} +4 -4
- package/dist/types-chunks/{guardrail.d-vSaBe64I.d.ts → guardrail.d-CPDfZyJp.d.ts} +3 -3
- package/dist/types-chunks/{guardrail.d-Ds7JHxR1.d.ts → guardrail.d-D7r6zVSR.d.ts} +1 -1
- package/dist/types-chunks/{public-api.d-CPBMPDiU.d.ts → public-api.d-BcKbBy1E.d.ts} +6 -7
- package/dist/types-chunks/{resolver.d-CGkfRULj.d.ts → resolver.d-DmBnoilY.d.ts} +2 -2
- package/dist/types-chunks/{run-manager.d-lnwnfyNC.d.ts → run-manager.d-CSj7_kWk.d.ts} +1 -1
- package/dist/types-chunks/{sdk-session-ByoMLoUS.d.ts → sdk-session-C6nDgyh8.d.ts} +4 -4
- package/dist/types-chunks/{types.d-Bp4Lm1jv.d.ts → types.d-CO_ZkmOd.d.ts} +6 -1
- package/dist/types-chunks/{types.d-DYv3a1ka.d.ts → types.d-CzscbsG0.d.ts} +4 -4
- package/dist/types-chunks/{types.d-DG9B4SMm.d.ts → types.d-D2frCRaY.d.ts} +138 -8
- package/dist/types-chunks/{types.d-DU9lLkmE.d.ts → types.d-D9FKbAmf.d.ts} +2 -2
- package/dist/types-chunks/{utils.d-DMI-9GTR.d.ts → utils.d-DOXxnOnI.d.ts} +5 -5
- package/docs/SDK_EMBEDDER_GUIDE.md +108 -8
- package/package.json +5 -1
- package/dist/chunks/agent-E4V5SLX6.js +0 -2
- package/dist/chunks/argument-completer-N6RT5KYT.js +0 -2
- package/dist/chunks/chunk-AKMXJSGM.js +0 -56
- package/dist/chunks/chunk-CW32NQFO.js +0 -2
- package/dist/chunks/chunk-NVDK375I.js +0 -729
- package/dist/chunks/chunk-QI6SQ2UQ.js +0 -306
- package/dist/chunks/chunk-RS2GAABJ.js +0 -328
- package/dist/chunks/compaction-config-56NO42ZI.js +0 -2
- package/dist/chunks/dist-4UIRSSFS.js +0 -2
- package/dist/chunks/host-DMREFNSO.js +0 -2
- package/dist/chunks/run-manager-P5XMSGZ7.js +0 -2
- package/dist/chunks/utils-JENPFKAE.js +0 -2
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,78 @@ All notable changes to this project will be documented in this file.
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
## [0.7.68] - 2026-07-12
|
|
10
|
+
|
|
11
|
+
> Scope note: this release delivers **FEATURE_260**, the KodaX Memory Agent,
|
|
12
|
+
> as a thin experimental SDK and governed runtime extension over the existing
|
|
13
|
+
> F228 Memory Control Plane. It does not add a second memory database, a
|
|
14
|
+
> resident specialist agent, filesystem memory actions, or online self-modification.
|
|
15
|
+
|
|
16
|
+
### Added
|
|
17
|
+
|
|
18
|
+
- **Thin experimental Memory Agent SDK.** Added
|
|
19
|
+
`@kodax-ai/agent/experimental-memory` and the root `/experimental-memory`
|
|
20
|
+
entry with scoped `MemorySession` lifecycle, zero-wait passive recall,
|
|
21
|
+
read-only deliberate `query()`, bounded observations, and episode outcomes.
|
|
22
|
+
- **Deliberate governed recall for the Action LLM.** A session-bound
|
|
23
|
+
`memory_recall` tool exposes only one `need` field, returns prompt-safe
|
|
24
|
+
low-authority evidence from the same F228 plane, and keeps identity, scope,
|
|
25
|
+
revision, and sequence outside model input.
|
|
26
|
+
- **Auditable memory decisions and outcomes.** Trace-only
|
|
27
|
+
`MemoryDecisionReceipt` records candidate/selected/injected refs and policy
|
|
28
|
+
version; accepted Outcome Digests can conservatively link influence without
|
|
29
|
+
storing hidden reasoning or creating a second event store.
|
|
30
|
+
- **Bounded episode review and promotion.** Timed-out review work persists in a
|
|
31
|
+
scoped inbox for bounded next-session drain and revalidation. Promotion now
|
|
32
|
+
consults compatible claims before choosing create, evidence update,
|
|
33
|
+
condition refinement, conflict, no-action, reject, or quarantine.
|
|
34
|
+
|
|
35
|
+
### Changed
|
|
36
|
+
|
|
37
|
+
- **Memory applicability is exact and fail-closed.** Tenant, user, agent,
|
|
38
|
+
workspace, project, and branch identity participate in deterministic scope
|
|
39
|
+
checks; sibling/cross-user/cross-tenant fallback is prohibited.
|
|
40
|
+
- **Memory policy is source-versioned and cache-safe.** `f260-v0.7.68.2`
|
|
41
|
+
binds production reminder rules, evidence rendering, and deliberate-recall
|
|
42
|
+
tool bytes. Passive reminders only affect the dynamic suffix; deliberate
|
|
43
|
+
queries add a normal tool-call/result tail while preserving earlier provider
|
|
44
|
+
cache bytes.
|
|
45
|
+
- **Safety-critical boundaries remain deterministic.** Secret filtering,
|
|
46
|
+
memory-file mutation guards, poisoning/source-evidence checks, and governed
|
|
47
|
+
proposal/preview/fingerprint/apply remain zero-violation code gates rather
|
|
48
|
+
than probabilistic LLM recall thresholds.
|
|
49
|
+
- **Self-knowledge follows the v0.7.68 capability surface.** `kodax_manual`
|
|
50
|
+
now has a dedicated governed-memory topic, names all 43 built-in slash
|
|
51
|
+
commands under a two-way drift guard, and documents the current 10 SDK
|
|
52
|
+
subpaths plus Runtime and `/experimental-memory` ownership boundaries.
|
|
53
|
+
|
|
54
|
+
### Fixed
|
|
55
|
+
|
|
56
|
+
- **Post-review Memory Agent release hardening.** Repository identity now strips
|
|
57
|
+
Git remote userinfo/query credentials before scoped or legacy persistence;
|
|
58
|
+
managed-path guards are Windows-case-safe, protect governance sidecars, and
|
|
59
|
+
fail closed for non-read-only shell access to addressed memory roots. Episode
|
|
60
|
+
reviews use atomic processing claims with stale recovery, while proposal and
|
|
61
|
+
lifecycle stores serialize concurrent read-modify-write updates. Eval manifest
|
|
62
|
+
schema v2 binds untracked file bytes in addition to the tracked patch, corrupt
|
|
63
|
+
raw JSON fails loudly, and summary review state points to the separate
|
|
64
|
+
main-session review artifact instead of remaining permanently pending.
|
|
65
|
+
- **Runtime daemon state replacement is atomic.** Daemon lifecycle updates now
|
|
66
|
+
stage and rename `daemon.json` instead of truncating it in place, preventing
|
|
67
|
+
shutdown polling from mistaking a partial write for completed cleanup and
|
|
68
|
+
leaving an orphaned `stopping` process under full-suite load.
|
|
69
|
+
|
|
70
|
+
### Performance
|
|
71
|
+
|
|
72
|
+
- **The preregistered v2 memory-routing panel passes all release gates.** On
|
|
73
|
+
`ark/v4flash`, general immediate recall passed 59/60 (98.3%), high-value
|
|
74
|
+
recall 40/40, must-silent 200/200 (Wilson lower 98.1%), paired routing lift
|
|
75
|
+
was +73.3 percentage points with zero control regression, and bounded
|
|
76
|
+
two-decision recovery passed 20/20. The 520-cell panel represented 782,721
|
|
77
|
+
tokens and an estimated $0.004447 against the $0.02 cap. Main-session blinded
|
|
78
|
+
review recommends ship for routing value while documenting that the panel is
|
|
79
|
+
not an end-to-end task-completion claim.
|
|
80
|
+
|
|
9
81
|
## [0.7.67] - 2026-07-11
|
|
10
82
|
|
|
11
83
|
> Scope note: a stabilization and agent-efficiency release. **FEATURE_258**
|
package/README.md
CHANGED
|
@@ -379,7 +379,7 @@ kodax --repo-intelligence full --repo-intelligence-trace
|
|
|
379
379
|
|
|
380
380
|
## Architecture
|
|
381
381
|
|
|
382
|
-
KodaX uses a **monorepo architecture** with npm workspaces. Source layout currently has 4 workspace packages; published as a single bundled npm package `@kodax-ai/kodax` with
|
|
382
|
+
KodaX uses a **monorepo architecture** with npm workspaces. Source layout currently has 4 workspace packages; published as a single bundled npm package `@kodax-ai/kodax` with 10 SDK subpath exports (`/agent`, `/llm`, `/coding`, `/media`, `/repl`, `/skills`, `/mcp`, `/session`, `/runtime`, `/experimental-memory`; ADR-024 + ADR-032 + ADR-038, with ADR-036 consolidation):
|
|
383
383
|
|
|
384
384
|
```
|
|
385
385
|
KodaX/
|
|
@@ -405,7 +405,7 @@ KodaX/
|
|
|
405
405
|
│
|
|
406
406
|
├── src/ # CLI entry + SDK subpath entries
|
|
407
407
|
│ ├── kodax_cli.ts # Main CLI entry point (bin: `kodax`)
|
|
408
|
-
│ └── sdk-*.ts # SDK subpath re-exports → @kodax-ai/kodax/{agent,llm,coding,media,repl,skills,mcp,session,runtime}
|
|
408
|
+
│ └── sdk-*.ts # SDK subpath re-exports → @kodax-ai/kodax/{agent,llm,coding,media,repl,skills,mcp,session,runtime,experimental-memory}
|
|
409
409
|
│
|
|
410
410
|
└── package.json # Root workspace config; release.mjs rewrites name + injects subpath exports
|
|
411
411
|
```
|
|
@@ -454,9 +454,9 @@ Source-side workspace package names (`@kodax-ai/*`). npm consumers install the s
|
|
|
454
454
|
KodaX has two layers that consumers should understand separately:
|
|
455
455
|
|
|
456
456
|
- **Source-side**: 4 workspace packages above (what developers see when reading the repo).
|
|
457
|
-
- **npm-published**: a single bundled package `@kodax-ai/kodax` with
|
|
457
|
+
- **npm-published**: a single bundled package `@kodax-ai/kodax` with 10 SDK subpaths (what SDK consumers `import` from). The subpaths are split into two roles:
|
|
458
458
|
- **Full-package subpaths** (`/agent`, `/llm`, `/coding`, `/repl`) — each one maps 1:1 to a source workspace and exposes its complete public API.
|
|
459
|
-
- **Narrow-subset subpaths** (`/media`, `/skills`, `/mcp`, `/session`) — each one exposes only a focused capability slice carved out of `/agent` or `/repl`.
|
|
459
|
+
- **Narrow-subset subpaths** (`/media`, `/skills`, `/mcp`, `/session`, `/experimental-memory`) — each one exposes only a focused capability slice carved out of `/agent` or `/repl`. `/experimental-memory` is intentionally unstable and opt-in; the others are stable focused surfaces.
|
|
460
460
|
|
|
461
461
|
| Source package | npm subpath | Type | What you get | Example consumer |
|
|
462
462
|
|---|---|---|---|---|
|
|
@@ -465,6 +465,7 @@ KodaX has two layers that consumers should understand separately:
|
|
|
465
465
|
| `packages/agent` | `@kodax-ai/kodax/skills` | **Narrow subset** | Skills system only — `SkillRegistry` / `loadFullSkill` / `expandSkillForLLM` / ... (26 exports = pre-v0.7.43 `@kodax-ai/skills` complete API) | Skill loaders, IDE plugins |
|
|
466
466
|
| `packages/agent` | `@kodax-ai/kodax/mcp` | **Narrow subset** | MCP only — `McpCapabilityProvider` / `createMcpTransport` / `searchMcpCatalog` / ... (23 exports) | MCP server hosts |
|
|
467
467
|
| `packages/agent` | `@kodax-ai/kodax/media` | **Narrow subset** | Structured image/file/video input-artifact helpers (22 exports) | Desktop hosts and multimodal clients |
|
|
468
|
+
| `packages/agent` | `@kodax-ai/kodax/experimental-memory` | **Experimental subset** | Thin F228-backed `MemoryAgent` / `MemorySession` contracts for scoped recall, deliberate query, observations, and outcomes | SDK hosts explicitly evaluating FEATURE_260 |
|
|
468
469
|
| `packages/coding` | `@kodax-ai/kodax/coding` | Full package | Coding agent + 50+ tools + repo-intelligence (505 exports) | Build a Claude Code-shape product |
|
|
469
470
|
| `packages/repl` | `@kodax-ai/kodax/repl` | Full package | Ink TUI + permission modes + commands (217 exports) | Terminal-UI consumers |
|
|
470
471
|
| `packages/repl` | `@kodax-ai/kodax/session` | **Narrow subset** | Session management only — `listSessions` / `loadFullTranscript` / `appendClientNotice` / `forkSession` / `compactSession` / `watchSessions` / ... (17 exports) | IDE plugins and desktop hosts reading session history |
|
|
@@ -492,6 +493,8 @@ KodaX has two layers that consumers should understand separately:
|
|
|
492
493
|
|
|
493
494
|
**Paged Session Listing (FEATURE_261, v0.7.67)**: both `/session` `listSessions()` and `runtime.sessions.list()` accept an exact `surface` filter and opaque continuation `cursor`; each returned summary carries the cursor for the next page. Filtering happens before the page limit, so a host does not need to over-fetch mixed surfaces. See the [pagination recipes](docs/SDK_EMBEDDER_GUIDE.md#19-session-surface-filtering-and-cursor-pagination-feature_261-v0767).
|
|
494
495
|
|
|
496
|
+
**Experimental Memory Agent SDK (FEATURE_260, v0.7.68)**: `/experimental-memory` exposes the thin agent-layer `MemoryAgent` and scoped `MemorySession` lifecycle over the existing governed F228 plane. Passive recall is zero-wait; `query()` is read-only and deliberate; durable changes still require the proposal/preview/fingerprint/apply path. The Action LLM remains the final decision maker, recalled content stays low-authority, and safety/scope gates remain deterministic. See the [direct session and boundary guide](docs/SDK_EMBEDDER_GUIDE.md#21-experimental-governed-memory--experimental-memory-feature_260-v0768).
|
|
497
|
+
|
|
495
498
|
---
|
|
496
499
|
|
|
497
500
|
## Features
|
|
@@ -609,7 +612,7 @@ import { listSessions } from '@kodax-ai/kodax/session'; // session histo
|
|
|
609
612
|
import { createKodaXRuntime } from '@kodax-ai/kodax/runtime'; // embedded/daemon runtime API
|
|
610
613
|
```
|
|
611
614
|
|
|
612
|
-
All
|
|
615
|
+
All 11 SDK entries (root + 10 subpaths) share internal code via ESM chunk splitting — importing from `/agent` does not pull in `/repl`'s Ink + React surface.
|
|
613
616
|
|
|
614
617
|
For the complete host-facing contract — including embedded/Worker/daemon ownership,
|
|
615
618
|
external-agent registration and task control, session cursor pagination, workflow
|
|
@@ -912,7 +915,7 @@ await runKodaX({
|
|
|
912
915
|
|
|
913
916
|
## SDK Usage
|
|
914
917
|
|
|
915
|
-
KodaX ships as a single npm package `@kodax-ai/kodax` with
|
|
918
|
+
KodaX ships as a single npm package `@kodax-ai/kodax` with 10 SDK subpath exports (ADR-024 v0.7.39 + ADR-032 v0.7.42 + ADR-038 v0.7.49 + v0.7.56 `/media` + v0.7.64 `/runtime` + v0.7.68 `/experimental-memory`). Each subpath is tree-shake-friendly so consumers pull only what they need:
|
|
916
919
|
|
|
917
920
|
```bash
|
|
918
921
|
npm install @kodax-ai/kodax
|
|
@@ -929,6 +932,7 @@ import { SkillRegistry } from '@kodax-ai/kodax/skills'; // zero-dep sk
|
|
|
929
932
|
import { createMcpManager } from '@kodax-ai/kodax/mcp'; // MCP popout manager (v0.7.42)
|
|
930
933
|
import { listSessions } from '@kodax-ai/kodax/session'; // session history helpers
|
|
931
934
|
import { createKodaXRuntime } from '@kodax-ai/kodax/runtime'; // embedded/daemon runtime API
|
|
935
|
+
import { createMemoryAgent } from '@kodax-ai/kodax/experimental-memory'; // opt-in experimental memory SDK
|
|
932
936
|
```
|
|
933
937
|
|
|
934
938
|
> The SDK is **ESM-only**. CommonJS consumers (Electron main / Webpack CJS / `require()` callers) must use `await import('@kodax-ai/kodax/...')` — see [docs/SDK_EMBEDDER_GUIDE.md §5](docs/SDK_EMBEDDER_GUIDE.md#5-consuming-from-a-commonjs-context-electron-main-cjs-bundles).
|
|
@@ -1078,6 +1082,7 @@ await runInkInteractiveMode({ provider: 'zhipu-coding', effort: 'auto' });
|
|
|
1078
1082
|
| Coding tasks | `@kodax-ai/kodax/coding` | Complete coding agent + tools |
|
|
1079
1083
|
| Terminal app | `@kodax-ai/kodax/repl` | Full interactive experience |
|
|
1080
1084
|
| Runtime host / daemon client | `@kodax-ai/kodax/runtime` | Sessions, runs, events, permissions, catalog, MCP, artifacts, diagnostics |
|
|
1085
|
+
| Experimental governed memory | `@kodax-ai/kodax/experimental-memory` | Scoped `MemoryAgent` / `MemorySession` recall and outcome contracts |
|
|
1081
1086
|
|
|
1082
1087
|
---
|
|
1083
1088
|
|
package/README_CN.md
CHANGED
|
@@ -214,9 +214,10 @@ import { loadConfig } from '@kodax-ai/kodax/repl'; // REPL 配置 /
|
|
|
214
214
|
import { createMcpManager } from '@kodax-ai/kodax/mcp'; // MCP popout manager(v0.7.42 起)
|
|
215
215
|
import { listSessions } from '@kodax-ai/kodax/session'; // session 历史工具
|
|
216
216
|
import { createKodaXRuntime } from '@kodax-ai/kodax/runtime'; // embedded/Worker/daemon 宿主 API
|
|
217
|
+
import { createMemoryAgent } from '@kodax-ai/kodax/experimental-memory'; // opt-in 实验性记忆 SDK
|
|
217
218
|
```
|
|
218
219
|
|
|
219
|
-
|
|
220
|
+
11 个 SDK 入口(root + 10 subpath)通过 ESM 共享 chunk 复用底层代码 —— 只 import `/agent` 不会把 `/repl` 的 Ink + React 一起拉进来。
|
|
220
221
|
|
|
221
222
|
完整的宿主集成契约——包括 embedded/Worker/daemon 所有权、外部 Agent 注册与任务控制、session cursor 分页、workflow 模型分层和效率遥测——见 [SDK Embedder Integration Guide](docs/SDK_EMBEDDER_GUIDE.md)。
|
|
222
223
|
|
|
@@ -529,7 +530,7 @@ kodax --repo-intelligence full --repo-intelligence-trace
|
|
|
529
530
|
|
|
530
531
|
## 仓库结构
|
|
531
532
|
|
|
532
|
-
KodaX 是基于 npm workspaces 的 TypeScript monorepo,**源码层 4 个 workspace 包**(FEATURE_194 v0.7.43 包合并 — 9 → 4,ADR-036),npm 上以单 bundle 包 `@kodax-ai/kodax` 发布 +
|
|
533
|
+
KodaX 是基于 npm workspaces 的 TypeScript monorepo,**源码层 4 个 workspace 包**(FEATURE_194 v0.7.43 包合并 — 9 → 4,ADR-036),npm 上以单 bundle 包 `@kodax-ai/kodax` 发布 + 10 个 SDK subpath exports(`/agent`、`/llm`、`/coding`、`/media`、`/repl`、`/skills`、`/mcp`、`/session`、`/runtime`、`/experimental-memory`;ADR-024 + ADR-032 + ADR-038)。核心包:
|
|
533
534
|
|
|
534
535
|
| Workspace 包 | 作用 | 主要依赖 |
|
|
535
536
|
|----|------|---------|
|
|
@@ -538,16 +539,16 @@ KodaX 是基于 npm workspaces 的 TypeScript monorepo,**源码层 4 个 works
|
|
|
538
539
|
| `@kodax-ai/coding` | Coding Agent:50+ 工具(含 `dispatch_child_task`/`send_message`/`task_stop`)、role prompts、agent loop、auto-continue + repo-intelligence protocol(v0.7.43 inline) | `@kodax-ai/llm`, `@kodax-ai/agent` |
|
|
539
540
|
| `@kodax-ai/repl` | 完整交互式终端 UI(Ink / React、权限模式、命令系统、流式渲染) | `@kodax-ai/coding`, `ink`, `react` |
|
|
540
541
|
|
|
541
|
-
根目录 `src/kodax_cli.ts` 是 CLI 入口;`src/sdk-{agent,llm,coding,media,repl,skills,mcp,session}.ts` 是 SDK subpath 入口;构建产物在 `dist/`,单文件二进制在 `dist/binary/<target>/`。
|
|
542
|
+
根目录 `src/kodax_cli.ts` 是 CLI 入口;`src/sdk-{agent,llm,coding,media,repl,skills,mcp,session,runtime,experimental-memory}.ts` 是 SDK subpath 入口;构建产物在 `dist/`,单文件二进制在 `dist/binary/<target>/`。
|
|
542
543
|
|
|
543
544
|
### 源码层 vs npm 发布层
|
|
544
545
|
|
|
545
546
|
KodaX 有两层结构,SDK 用户需要分开理解:
|
|
546
547
|
|
|
547
548
|
- **源码层**:上面 4 个 workspace 包(开发者读代码时看到的物理结构)。
|
|
548
|
-
- **npm 发布层**:单个 bundled 包 `@kodax-ai/kodax`,对外暴露
|
|
549
|
+
- **npm 发布层**:单个 bundled 包 `@kodax-ai/kodax`,对外暴露 10 个 SDK subpath(SDK 消费者 `import` 时看到的接口)。subpath 分两种角色:
|
|
549
550
|
- **完整包 subpath**(`/agent`、`/llm`、`/coding`、`/repl`)—— 每个 1:1 对应一个源码包,暴露完整公开 API。
|
|
550
|
-
- **窄子集 subpath**(`/media`、`/skills`、`/mcp`、`/session`)—— 从 `/agent` 或 `/repl`
|
|
551
|
+
- **窄子集 subpath**(`/media`、`/skills`、`/mcp`、`/session`、`/experimental-memory`)—— 从 `/agent` 或 `/repl` 切出聚焦能力;`/experimental-memory` 明确为 opt-in 不稳定接口。
|
|
551
552
|
|
|
552
553
|
| 源码包 | npm subpath | 类型 | 内容 | 典型消费者 |
|
|
553
554
|
|---|---|---|---|---|
|
|
@@ -556,6 +557,7 @@ KodaX 有两层结构,SDK 用户需要分开理解:
|
|
|
556
557
|
| `packages/agent` | `@kodax-ai/kodax/skills` | **窄子集** | 仅 Skills 系统 —— `SkillRegistry` / `loadFullSkill` / `expandSkillForLLM` 等 (26 exports = v0.7.43 之前 `@kodax-ai/skills` 完整 API) | Skill 加载器、IDE 插件 |
|
|
557
558
|
| `packages/agent` | `@kodax-ai/kodax/mcp` | **窄子集** | 仅 MCP —— `McpCapabilityProvider` / `createMcpTransport` / `searchMcpCatalog` 等 (23 exports) | MCP server 宿主 |
|
|
558
559
|
| `packages/agent` | `@kodax-ai/kodax/media` | **窄子集** | 结构化图片/文件/视频输入 artifact helpers (22 exports) | 桌面宿主、多模态客户端 |
|
|
560
|
+
| `packages/agent` | `@kodax-ai/kodax/experimental-memory` | **实验性子集** | F228-backed `MemoryAgent` / `MemorySession` scope、recall、query、observation、outcome 契约 | 显式评估 FEATURE_260 的 SDK 宿主 |
|
|
559
561
|
| `packages/coding` | `@kodax-ai/kodax/coding` | 完整包 | Coding agent + 50+ 工具 + repo-intelligence (505 exports) | 构建 Claude Code 形态产品 |
|
|
560
562
|
| `packages/repl` | `@kodax-ai/kodax/repl` | 完整包 | Ink TUI + 权限模式 + 命令系统 (217 exports) | 终端 UI 消费者 |
|
|
561
563
|
| `packages/repl` | `@kodax-ai/kodax/session` | **窄子集** | 仅会话管理 —— `listSessions` / `loadFullTranscript` / `appendClientNotice` / `forkSession` / `compactSession` / `watchSessions` 等 (17 exports) | 读取 session 历史的 IDE 插件和桌面宿主 |
|
|
@@ -569,6 +571,8 @@ KodaX 有两层结构,SDK 用户需要分开理解:
|
|
|
569
571
|
|
|
570
572
|
**会话恢复与 ACP 污染修复(FEATURE_261,v0.7.67)**:直接运行 `kodax -r` 会进入可搜索、上下选择、Tab 补全和翻页的交互式会话选择器,并显示当前选中项的完整 session ID;`kodax -r <值>` 优先按完整 ID 恢复,ID 不存在时再按忽略大小写的完整标题匹配。标题唯一则直接恢复,同名标题则进入只包含候选项的选择器,绝不静默选第一条。`listSessions()` / Runtime / daemon 会话列表新增 `surface` 精确过滤和不透明 `cursor` 分页。ACP session 改为收到首个有效 prompt 后才持久化,ACP 测试强制使用临时 runtime home,避免测试记录写入真实 `~/.kodax/sessions`。`kodax -s cleanup-acp` 只预览严格匹配的空 ACP 污染记录;仅显式追加 `--apply-session-cleanup` 时才归档,不做永久删除。
|
|
571
573
|
|
|
574
|
+
**实验性 Memory Agent SDK(FEATURE_260,v0.7.68)**:`/experimental-memory` 暴露基于既有 F228 治理平面的薄 `MemoryAgent` 与 scoped `MemorySession`。被动 recall 零等待,`query()` 只读且由主 Action LLM 主动选择;持久化仍必须经过 proposal/preview/fingerprint/apply。召回内容保持低权限,安全与 scope 边界仍由确定性代码门禁承担。直接 session 示例与宿主边界见 [SDK Embedder Guide §21](docs/SDK_EMBEDDER_GUIDE.md#21-experimental-governed-memory--experimental-memory-feature_260-v0768)。
|
|
575
|
+
|
|
572
576
|
**外部 Agent SDK plane(FEATURE_258,v0.7.67)**:`/agent` 导出协议中立的 executor、registration、policy、credential broker、artifact policy、catalog 和 durable task 契约;`/runtime` 通过 `admin.agentRegistrations`、`agents`、`agentTasks` 向 embedded 与 daemon client 提供同一组 DTO API。Executor factory 是宿主函数,只能装入 inline owner,或在创建新的 in-process daemon owner 时装入;不能通过既有 daemon 连接或 Runtime Worker 边界注入。Plane 关闭后是终态:未完成的 wait 和后续所有服务调用都会拒绝;受限 Workflow 脚本会完整校验并传递 `phase` 与外部 `target`。完整所有权、注册、preflight、启动/等待/继续/取消/对账和安全边界见 [SDK Embedder Guide §18](docs/SDK_EMBEDDER_GUIDE.md#18-external-agent-executor-plane-feature_258-v0767)。
|
|
573
577
|
|
|
574
578
|
**成本受控 Workflow SDK(FEATURE_259,v0.7.67)**:SDK 调用方用 run-scoped `modelTiers` 与 `workflow.maxConcurrency` 配置路由和并发,workflow 作者只表达 `fast` / `balanced` / `deep` 语义意图。terminal workflow event 回显 tier/source/fallback/usage/duration,持久化 `run.json.efficiencyReport` 给出 token coverage、role/tier 启动数、packet-read 拓扑、review wave 和 quality gate 结果。完整配置与遥测读取方式见 [SDK Embedder Guide §20](docs/SDK_EMBEDDER_GUIDE.md#20-cost-disciplined-workflow-routing-and-telemetry-feature_259-v0767)。
|
|
@@ -596,9 +600,9 @@ KodaX/ # 4 workspace packages(FEATURE_194 v0.7.43)
|
|
|
596
600
|
│ └── repl/ # @kodax-ai/repl —— Ink TUI
|
|
597
601
|
├── src/
|
|
598
602
|
│ ├── kodax_cli.ts # CLI 主入口(bin: `kodax`)
|
|
599
|
-
│ └── sdk-*.ts # SDK subpath 入口 → @kodax-ai/kodax/{agent,llm,coding,media,repl,skills,mcp,session,runtime}
|
|
603
|
+
│ └── sdk-*.ts # SDK subpath 入口 → @kodax-ai/kodax/{agent,llm,coding,media,repl,skills,mcp,session,runtime,experimental-memory}
|
|
600
604
|
├── scripts/
|
|
601
|
-
│ ├── build-bundle.mjs # esbuild 单 bundle 多 entry 打包(CLI + root +
|
|
605
|
+
│ ├── build-bundle.mjs # esbuild 单 bundle 多 entry 打包(CLI + root + 10 SDK subpath + chunks)
|
|
602
606
|
│ ├── build-binary.mjs # Bun --compile 单文件二进制打包
|
|
603
607
|
│ └── release.mjs # ADR-024 release-time pkg name/exports 注入
|
|
604
608
|
└── .github/workflows/
|
|
@@ -692,7 +696,7 @@ KodaX 现在会把 Repo Intelligence 的本地缓存分成内置引擎 profile
|
|
|
692
696
|
## 文档
|
|
693
697
|
|
|
694
698
|
- [README.md](README.md) - 英文版 README
|
|
695
|
-
- [docs/SDK_EMBEDDER_GUIDE.md](docs/SDK_EMBEDDER_GUIDE.md) - SDK 宿主集成与 v0.7.
|
|
699
|
+
- [docs/SDK_EMBEDDER_GUIDE.md](docs/SDK_EMBEDDER_GUIDE.md) - SDK 宿主集成与 v0.7.68 公共 API 契约
|
|
696
700
|
- [docs/release.md](docs/release.md) - 单文件二进制构建与发布流程
|
|
697
701
|
- [docs/PRD.md](docs/PRD.md) - 产品需求
|
|
698
702
|
- [docs/ADR.md](docs/ADR.md) - 架构决策
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
// @kodax-ai/kodax — bundled distribution. See docs/ADR.md ADR-022 + ADR-024.
|
|
2
|
+
import{$ as g,I as c,J as d,K as e,L as f,aa as h,ta as i,za as j}from"./chunk-HLBHSA2B.js";import"./chunk-D6QVXQNI.js";import"./chunk-PEGSHZAA.js";import"./chunk-HFM2D5BP.js";import"./chunk-C4SBXBWH.js";import"./chunk-K2NCKRVY.js";import{kb as a,lb as b}from"./chunk-67XJ4YUA.js";import"./chunk-5GL55MOH.js";import"./chunk-PZTG2C33.js";import"./chunk-ONUPGMER.js";export{d as bucketProviderPayloadSize,g as buildAutoRepoIntelligenceContext,e as checkPromiseSignal,b as cleanupIncompleteToolCalls,h as describeTransientProviderRetry,f as emitResilienceDebug,c as estimateProviderPayloadBytes,j as runKodaX,i as saveSessionSnapshot,a as validateAndFixToolHistory};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
// @kodax-ai/kodax — bundled distribution. See docs/ADR.md ADR-022 + ADR-024.
|
|
2
|
+
import{Ba as a,Ca as b}from"./chunk-CTHUX5ZH.js";import"./chunk-OIELNE6Z.js";import"./chunk-TOGESFRN.js";import"./chunk-KIQRCGVR.js";import"./chunk-CC4BVVE7.js";import"./chunk-KGAI32VS.js";import"./chunk-HLBHSA2B.js";import"./chunk-D6QVXQNI.js";import"./chunk-PEGSHZAA.js";import"./chunk-HFM2D5BP.js";import"./chunk-C4SBXBWH.js";import"./chunk-K2NCKRVY.js";import"./chunk-67XJ4YUA.js";import"./chunk-5GL55MOH.js";import"./chunk-PZTG2C33.js";import"./chunk-ONUPGMER.js";export{a as ArgumentCompleter,b as createArgumentCompleter};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
// @kodax-ai/kodax — bundled distribution. See docs/ADR.md ADR-022 + ADR-024.
|
|
2
|
+
import{a as s}from"./chunk-ONUPGMER.js";var V=[];function ao(t){let e={id:Symbol("kodax-diagnostic-sink"),sink:t};V.push(e);let n=!1;return()=>{if(n)return;n=!0;let r=V.findIndex(i=>i.id===e.id);r>=0&&V.splice(r,1)}}s(ao,"setKodaXDiagnosticSink");function B(t){let e=V.at(-1)?.sink;if(e){try{e(t)}catch{}return}if(process.env.KODAX_DIAGNOSTICS_STDERR==="1")try{process.stderr.write(`${ln(t)}
|
|
3
|
+
`)}catch{}}s(B,"emitKodaXDiagnostic");function ln(t){let e=fn(t.detail);return`[${t.source}] ${t.level}: ${t.message}${e?` ${e}`:""}`}s(ln,"formatKodaXDiagnostic");function fn(t){if(t===void 0)return"";if(t instanceof Error)return t.stack??t.message;if(typeof t=="string")return t;try{return JSON.stringify(t)}catch{return String(t)}}s(fn,"formatDiagnosticDetail");import{mkdirSync as un}from"node:fs";import{homedir as mn}from"node:os";import{join as xe}from"node:path";var gn=".kodax",yn="KODAX_HOME",Ie;function mo(t){Ie=t}s(mo,"setAgentConfigHome");function tt(){if(Ie)return Ie;let t=process.env[yn];return t&&t.length>0?t:xe(mn(),gn)}s(tt,"getAgentConfigHome");function E(...t){return xe(tt(),...t)}s(E,"getAgentConfigPath");function go(t){if(typeof t!="string"||!/^[a-z][a-z0-9-]{1,31}$/.test(t))throw new Error(`getAppDataDir: invalid appId ${JSON.stringify(t)}. Must match /^[a-z][a-z0-9-]{1,31}$/ (lowercase kebab, 2\u201332 chars).`);if(t==="kodax"||t.startsWith("kodax-"))throw new Error(`getAppDataDir: appId ${JSON.stringify(t)} is reserved (the 'kodax' / 'kodax-*' prefix is reserved for first-party use).`);let e=xe(tt(),"apps",t);return un(e,{recursive:!0}),e}s(go,"getAppDataDir");import{createHash as nt}from"node:crypto";var rt=["tenantId","workspaceId","userId","agentId","projectId","sessionId"];function Z(t,e){return rt.every(n=>e[n]===void 0||e[n]===t[n])}s(Z,"matchesMemoryApplicability");function R(t,e){if(e.length===0)throw new Error(`${t} identity must not be empty`);return nt("sha256").update(`${t}\0${e}`).digest("hex")}s(R,"hashMemoryIdentityComponent");function Pe(t){let e=rt.filter(n=>t[n]!==void 0).map(n=>`${n}=${t[n]}`).join("\0");return nt("sha256").update(e).digest("hex")}s(Pe,"memoryApplicabilityFingerprint");var _e="f260-v0.7.68.2";import{createHash as hn}from"node:crypto";import{execSync as wn}from"node:child_process";import*as k from"node:path";function Q(t){return Rn(t).trim().replace(/^ssh:\/\//,"").replace(/^https?:\/\//,"").replace(/^git@/,"").replace(/\.git$/,"").replace(/[:@/\\]+/g,"-").replace(/^-+|-+$/g,"").toLowerCase()}s(Q,"sanitizeProjectKey");function Rn(t){let e=t.trim();if(!/^[a-z][a-z0-9+.-]*:\/\//i.test(e))return e;try{let n=new URL(e);return`${n.hostname}${n.port.length>0?`:${n.port}`:""}${n.pathname}`}catch{return e.replace(/^([a-z][a-z0-9+.-]*:\/\/)[^/@]+@/i,"$1").replace(/[?#].*$/,"")}}s(Rn,"remoteWithoutCredentials");function ee(t){let e=k.resolve(t).toLowerCase();return hn("sha256").update(e).digest("hex").slice(0,16)}s(ee,"hashCwd");function te(t){try{let n=wn("git config --get remote.origin.url",{cwd:t,encoding:"utf-8",stdio:["ignore","pipe","ignore"],timeout:1e3}).trim();return n.length>0?n:void 0}catch{return}}s(te,"tryGitRemote");function ne(t){let e=te(t),n=e?Q(e):`local-${ee(t)}`;return E("projects",n,"memory")}s(ne,"resolveMemoryRoot");function kn(t){return k.join(ne(t),"MEMORY.md")}s(kn,"resolveMemoryEntrypoint");function L(t,e){let n=e==="project"?"projectId":e==="workspace"?"workspaceId":e==="user"?"userId":"agentId",r=t[n];if(r===void 0||r.length===0)throw new Error(`${n} is required for ${e} memory`);return E("memory-scopes",R("tenant",t.tenantId),e,R(e,r))}s(L,"resolveScopedMemoryRoot");function Sn(t){let e=Ae(t),n=Ae(E("memory-scopes"));if(e.startsWith(n+k.sep)){let a=e.slice(n.length+1).split(k.sep);return a.length>=4&&/^[0-9a-f]{64}$/.test(a[0]??"")&&["project","workspace","agent","user"].includes(a[1]??"")&&/^[0-9a-f]{64}$/.test(a[2]??"")}let r=Ae(E("projects"));if(!e.startsWith(r+k.sep))return!1;let o=e.slice(r.length+1).split(k.sep);return o.length>=3&&o[1]==="memory"}s(Sn,"isAutoManagedMemoryFile");function Ae(t){let e=k.resolve(t);return process.platform==="win32"?e.toLowerCase():e}s(Ae,"comparablePath");function bn(t){let e=k.basename(t,".md").toLowerCase();if(e.startsWith("user_")||e==="user")return"user";if(e.startsWith("feedback_")||e==="feedback")return"feedback";if(e.startsWith("project_")||e==="project")return"project";if(e.startsWith("reference_")||e==="reference")return"reference"}s(bn,"parseMemoryTypeFromFilename");var vn=/^---\r?\n([\s\S]*?)\r?\n---\r?\n?/;function it(t){if(t==="user"||t==="feedback"||t==="project"||t==="reference")return t}s(it,"parseMemoryType");function $(t){let e=vn.exec(t);if(!e)return{frontmatter:{name:void 0,description:void 0,type:void 0},body:t};let n=e[1],r=t.slice(e[0].length).replace(/^\r?\n+/,""),i=ot(n);return{frontmatter:{name:typeof i.name=="string"?i.name:void 0,description:typeof i.description=="string"?i.description:void 0,type:it(i.type)},body:r}}s($,"parseMemoryFile");function ot(t){let e={},n=t.split(/\r?\n/);for(let r of n){if(!r.trim()||r.trim().startsWith("#"))continue;let i=r.indexOf(":");if(i===-1)continue;let o=r.slice(0,i).trim();if(!/^[A-Za-z_][A-Za-z0-9_-]*$/.test(o))continue;let a=r.slice(i+1).trim(),c=In(a);c!==void 0&&(e[o]=c)}return e}s(ot,"parseScalarFields");function In(t){if(t.length!==0){if(t.length>=2){let e=t.charAt(0),n=t.charAt(t.length-1);if(e==='"'&&n==='"'||e==="'"&&n==="'")return t.slice(1,-1)}return t}}s(In,"unquote");var xn=200,Pn=25e3;function _n(t){let e=t.trim(),n=e.length===0?[]:e.split(`
|
|
4
|
+
`),r=n.length,i=Buffer.byteLength(e,"utf-8"),o=r>200,a=i>25e3;if(!o&&!a)return{content:e,lineCount:r,byteCount:i,wasLineTruncated:o,wasByteTruncated:a};let c=o?n.slice(0,200).join(`
|
|
5
|
+
`):e;return Buffer.byteLength(c,"utf-8")>25e3&&(c=En(c,25e3)),{content:c+`
|
|
6
|
+
|
|
7
|
+
`+An({lineCount:r,byteCount:i,wasLineTruncated:o,wasByteTruncated:a}),lineCount:r,byteCount:i,wasLineTruncated:o,wasByteTruncated:a}}s(_n,"truncateEntrypointContent");function An(t){let{lineCount:e,byteCount:n,wasLineTruncated:r,wasByteTruncated:i}=t;return`> WARNING: MEMORY.md is ${i&&!r?`${Ee(n)} (limit: ${Ee(25e3)}) \u2014 index entries are too long`:r&&!i?`${e} lines (limit: 200)`:`${e} lines and ${Ee(n)}`}. Only part of it was loaded. Keep index entries to one line under ~200 chars; move detail into topic files.`}s(An,"formatTruncationWarning");function En(t,e){let n=Buffer.from(t,"utf-8");if(n.length<=e)return t;let r=10,i=-1;for(let o=e-1;o>=0;o--)if(n[o]===r){i=o;break}return i>0?n.subarray(0,i).toString("utf-8"):n.subarray(0,e).toString("utf-8")}s(En,"sliceToByteCap");function Ee(t){return t<1e3?`${t} B`:`${(t/1e3).toFixed(1)} KB`}s(Ee,"formatFileSize");import jn from"path";var z=new Set;function st(t){let e=t.trim();if(!e)throw new Error("Plugin skill path cannot be empty.");return jn.resolve(e)}s(st,"normalizePluginSkillPath");function $n(t){let e=st(t);return z.add(e),()=>{z.delete(e)}}s($n,"registerPluginSkillPath");function Fn(t){return z.delete(st(t))}s(Fn,"unregisterPluginSkillPath");function je(){return Array.from(z.values())}s(je,"listPluginSkillPaths");function Mn(){z.clear()}s(Mn,"clearPluginSkillPaths");import{homedir as Cn}from"os";import N from"path";import{fileURLToPath as Ln}from"url";import{dirname as Tn}from"path";var On=Ln(import.meta.url),Nn=Tn(On);function Dn(){return process.env.KODAX_BUNDLED==="true"?N.join(N.dirname(process.execPath),"builtin"):N.join(Nn,"builtin")}s(Dn,"resolveBuiltinPath");function $e(t){let e=Cn();return{projectPaths:t?[N.join(t,".kodax","skills")]:[],userPaths:[N.join(e,".kodax","skills"),N.join(e,".agents","skills")],pluginPaths:je(),builtinPath:Dn()}}s($e,"getDefaultSkillPaths");function Fe(t){let e=[];for(let n of t.projectPaths)e.push({path:n,source:"project"});for(let n of t.userPaths)e.push({path:n,source:"user"});for(let n of t.pluginPaths)e.push({path:n,source:"plugin"});return e.push({path:t.builtinPath,source:"builtin"}),e}s(Fe,"getSkillPathsFlat");import{readFile as Me,readdir as Wn}from"fs/promises";import{join as F,relative as Yn}from"path";import at from"yaml";var Kn=["SessionStart","UserPromptSubmit","PreToolUse","PostToolUse","Stop","SubagentStop","Notification"];function Un(t){let e=t.split(`
|
|
8
|
+
`),n=[];for(let r of e){let i=r.indexOf(":");if(i>0){let o=r.slice(0,i).trim(),a=r.slice(i+1).trim();if(a.includes(":")&&!a.startsWith('"')&&!a.startsWith("'")&&!a.startsWith("[")&&!a.startsWith("|")&&!a.startsWith(">")){n.push(`${o}: |-`),n.push(` ${a}`);continue}}n.push(r)}return n.join(`
|
|
9
|
+
`)}s(Un,"sanitizeYaml");function ct(t,e={}){let n=t.replace(/^/,"").replace(/\r\n/g,`
|
|
10
|
+
`).replace(/\r/g,`
|
|
11
|
+
`).trimStart();if(!n.startsWith(`---
|
|
12
|
+
`)){if(e.throwOnMissing)throw new Error("Invalid markdown: missing YAML frontmatter");return[null,t]}let r=n.indexOf(`
|
|
13
|
+
---
|
|
14
|
+
`,4);if(r===-1){let c=n.indexOf(`
|
|
15
|
+
---`,4);c!==-1&&c===n.length-4&&(r=c)}if(r===-1){if(e.throwOnMissing)throw new Error("Invalid markdown: unclosed YAML frontmatter");return[null,t]}let i=n.slice(4,r),o=n.slice(r+5).trim(),a;try{a=at.parse(i)??{}}catch{a=at.parse(Un(i))??{}}if(a==null||typeof a!="object"||Array.isArray(a)){if(e.throwOnMissing)throw new Error("Invalid markdown: YAML frontmatter must be an object");return[null,o]}return[a,o]}s(ct,"parseYamlFrontmatter");function dt(t){if(typeof t=="string"){let e=t.trim();return e.length>0?e:void 0}if(Array.isArray(t)){let e=t.map(n=>String(n).trim()).filter(n=>n.length>0);return e.length>0?e.join(", "):void 0}}s(dt,"normalizeAllowedToolsString");function Bn(t){if(typeof t=="string"){let e=t.trim();return e?{command:e}:void 0}if(t&&typeof t=="object"&&!Array.isArray(t)){let e=t,n=typeof e.command=="string"?e.command.trim():"";if(!n)return;let r=typeof e.matcher=="string"&&e.matcher.trim()?e.matcher.trim():void 0;return{command:n,matcher:r}}}s(Bn,"normalizeYamlHookEntry");function zn(t){if(t==null)return;let n=(Array.isArray(t)?t:[t]).map(r=>Bn(r)).filter(r=>r!==void 0);return n.length>0?n:void 0}s(zn,"normalizeYamlHookEntryList");function pt(t){if(!t||typeof t!="object"||Array.isArray(t))return;let e=t,n={};for(let r of Kn){let i=zn(e[r]);i&&(n[r]=i)}return Object.keys(n).length>0?n:void 0}s(pt,"normalizeYamlHookMap");function Ce(t){let[e,n]=ct(t,{throwOnMissing:!0});if(!e)throw new Error("Invalid SKILL.md: YAML frontmatter must be an object");if(!e.name||typeof e.name!="string")throw new Error('Invalid SKILL.md: missing required "name" field');if(!e.description||typeof e.description!="string")throw new Error('Invalid SKILL.md: missing required "description" field');return{frontmatter:{name:e.name,description:e.description,disableModelInvocation:e["disable-model-invocation"]===!0,userInvocable:e["user-invocable"]!==!1,allowedTools:dt(e["allowed-tools"]),context:e.context==="fork"?"fork":void 0,agent:typeof e.agent=="string"?e.agent:void 0,argumentHint:typeof e["argument-hint"]=="string"?e["argument-hint"]:void 0,model:typeof e.model=="string"?e.model:void 0,hooks:pt(e.hooks),license:typeof e.license=="string"?e.license:void 0,compatibility:typeof e.compatibility=="string"?e.compatibility:void 0,metadata:e.metadata&&typeof e.metadata=="object"&&!Array.isArray(e.metadata)?e.metadata:void 0},body:n}}s(Ce,"parseSkillMarkdown");async function Le(t,e){let n=F(t,"SKILL.md");try{let r=await Me(n,"utf-8"),{frontmatter:i}=Ce(r);return{name:i.name,description:i.description,userInvocable:i.userInvocable??!0,argumentHint:i.argumentHint,path:t,source:e,disableModelInvocation:i.disableModelInvocation??!1}}catch(r){return B({source:"agent:skills",level:"error",message:`Failed to load skill metadata from ${t}.`,detail:r}),null}}s(Le,"loadSkillMetadata");async function Te(t,e){let n=F(t,"SKILL.md");try{let r=await Me(n,"utf-8"),{frontmatter:i,body:o}=Ce(r),[a,c,d,p,f]=await Promise.all([D(F(t,"scripts")),D(F(t,"references")),D(F(t,"assets")),D(F(t,"templates")),D(F(t,"resources"))]);return{...i,path:t,skillFilePath:n,content:o,rawContent:o,loaded:!0,source:e,...a.length>0&&{scripts:a},...c.length>0&&{references:c},...d.length>0&&{assets:d},...p.length>0&&{templates:p},...f.length>0&&{resources:f}}}catch(r){return B({source:"agent:skills",level:"error",message:`Failed to load skill from ${t}.`,detail:r}),null}}s(Te,"loadFullSkill");async function D(t,e=t){let n=[];try{let r=await Wn(t,{withFileTypes:!0});r.sort((i,o)=>i.name.localeCompare(o.name));for(let i of r){let o=F(t,i.name);if(i.isDirectory()){n.push(...await D(o,e));continue}i.isFile()&&n.push({name:i.name,path:o,relativePath:Yn(e,o).replace(/\\/g,"/")})}}catch{}return n}s(D,"loadSkillFiles");async function qn(t){if(t.content)return t.content;let e=await Me(t.path,"utf-8");return t.content=e,e}s(qn,"loadSkillFileContent");import{readdir as Hn,stat as Oe}from"fs/promises";import{join as re,dirname as lt}from"path";async function ie(t,e){let n=new Map,r=[],o={...$e(t),...e},a=Fe(o);for(let{path:c,source:d}of a)try{let p=await Xn(c,d);for(let f of p)n.has(f.name)||n.set(f.name,f)}catch(p){r.push({path:c,error:p instanceof Error?p.message:String(p)})}return{skills:n,errors:r}}s(ie,"discoverSkills");async function Xn(t,e){let n=[];try{if(!(await Oe(t)).isDirectory())return n;let i=await Hn(t);for(let o of i){let a=re(t,o);try{if((await Oe(a)).isDirectory()){let d=re(a,"SKILL.md");try{if((await Oe(d)).isFile()){let f=await Le(a,e);f&&n.push(f)}}catch{}}}catch{}}}catch{}return n}s(Xn,"scanSkillDirectory");function ft(t,e){let n=[],r=[".kodax/skills"],i=t,o=lt(e);for(;i!==o&&i!=="/"&&i.length>3;){for(let c of r)n.push(re(i,c));let a=lt(i);if(a===i)break;i=a}return n}s(ft,"getNestedSkillPaths");async function Jn(t,e){let n=ft(t,e),r={projectPaths:[re(e,".kodax","skills"),...n]};return ie(e,r)}s(Jn,"discoverSkillsWithMonorepo");import{execSync as Gn}from"child_process";import Vn from"path";var Zn=new Set(["ls","cat","pwd","echo","whoami","date","which","whereis","tree","dir","type","get-childitem","get-content","select-string","get-location","grep","find","awk","sed","head","tail","less","more","wc","git status","git diff","git log","git show","git branch","git remote","git ls-files","git rev-parse","git grep","node","npm","yarn","pnpm","tsc","python","pip","go","cargo","rustc"]);function ut(t){if(!t||!t.trim())return!1;let e=t.trim().replace(/\s+/g," ").toLowerCase();for(let n of Zn)if(e===n||e.startsWith(`${n} `)){if(n==="sed"&&e.split(/\s+/).some(o=>o.startsWith("-i")||o==="--in-place"))return!1;if(n==="awk"){let i=e.split(/\s+/);if(i.includes("-f")||i.includes("--file"))return!1}if(["node","npm","yarn","pnpm","tsc","python","pip","go","cargo","rustc"].includes(n)){let i=e.split(/\s+/).slice(1);if(i.length>0&&!i.every(o=>/^(-v|--version|-h|--help)$/.test(o)))return!1}return!0}return!1}s(ut,"isSingleSafeDynamicContextCommand");function Qn(t){if(!t||!t.trim())return!1;let e=t.trim().replace(/\\\r?\n/g," ");if(/[<>|;`]|\$\(|(?<!&)&(?!&)/.test(e)||e.includes("\\")&&Vn.sep!=="\\"&&e.replace(/\\ /g,"").includes("\\"))return!1;let r=e.split(/\s*&&\s*/);if(r.length===1)return ut(r[0]);for(let i of r){let o=i?.trim();if(o&&!/^cd\s+/.test(o.toLowerCase())&&!ut(o))return!1}return!0}s(Qn,"isSafeDynamicContextCommand");function mt(t){let e=[],n="",r=!1,i="";for(let o=0;o<t.length;o++){let a=t[o];r?a===i?r=!1:n+=a:a==='"'||a==="'"?(r=!0,i=a):a===" "?n&&(e.push(n),n=""):n+=a}return n&&e.push(n),e}s(mt,"parseArguments");var W=class{static{s(this,"VariableResolver")}context;constructor(e){this.context=e}async resolve(e,n){let r=e,i=mt(n);return r=this.resolvePositionalArgs(r,i),r=this.resolveArguments(r,n),r=this.resolveEnvVars(r),r=await this.resolveDynamicContext(r),r}resolvePositionalArgs(e,n){return e.replace(/\$(\d+)(?![a-zA-Z0-9_])/g,(r,i)=>{let o=parseInt(i,10);return n[o]??""})}resolveArguments(e,n){return e.replace(/\$ARGUMENTS/g,n)}resolveEnvVars(e){let n={...this.context.environment,CLAUDE_SESSION_ID:this.context.sessionId??"",KODAX_SESSION_ID:this.context.sessionId??"",KODAX_WORKING_DIR:this.context.workingDirectory};return e.replace(/\$\{([A-Za-z_][A-Za-z0-9_]*)\}/g,(r,i)=>n[i]??r)}async resolveDynamicContext(e){let n=/!`([^`]+)`/g,r=[],i;for(;(i=n.exec(e))!==null;)r.push({match:i[0],command:i[1]});if(r.length===0)return e;let o=e;for(let{match:a,command:c}of r)try{let d=await this.executeDynamicCommand(c);o=o.replace(a,d)}catch(d){let p=d instanceof Error?d.message:String(d);o=o.replace(a,`[Error: ${p}]`)}return o}async executeDynamicCommand(e){if(this.context.disableDynamicContext)throw new Error("Dynamic context disabled by host. Skill `!`cmd`` blocks are not allowed in this environment.");if(this.context.executeDynamicContext){let n=await this.context.executeDynamicContext(e,this.context.workingDirectory);return typeof n=="string"?n.trim():""}if(!Qn(e))throw new Error("Unsafe dynamic context command blocked. Only simple read-only commands are allowed in !`...` blocks.");try{return Gn(e,{cwd:this.context.workingDirectory,encoding:"utf-8",timeout:5e3,maxBuffer:1048576,windowsHide:!0}).trim()}catch(n){throw n instanceof Error?new Error(`Command failed: ${n.message}`):n}}};function er(t){return new W(t)}s(er,"createResolver");async function T(t,e,n){return new W(n).resolve(t,e)}s(T,"resolveSkillContent");var oe=class{static{s(this,"SkillRegistry")}skillsByName=new Map;fullSkillsByName=new Map;projectRoot;customPaths;constructor(e,n){this.projectRoot=e,this.customPaths=n}async discover(){let e=await ie(this.projectRoot,this.customPaths);this.skillsByName.clear();for(let[n,r]of e.skills)this.skillsByName.set(n,r);if(e.errors.length>0)for(let{path:n,error:r}of e.errors)B({source:"agent:skills",level:"warn",message:`Error scanning ${n}.`,detail:r})}get skills(){return this.skillsByName}get(e){return this.skillsByName.get(e)}async loadFull(e){let n=this.fullSkillsByName.get(e);if(n)return n;let r=this.skillsByName.get(e);if(!r)throw new Error(`Skill not found: ${e}`);let i=await Te(r.path,r.source);if(!i)throw new Error(`Failed to load skill: ${e}`);return this.fullSkillsByName.set(e,i),i}async invoke(e,n,r){try{let i=await this.loadFull(e);return i.disableModelInvocation?{success:!1,content:"",error:`Skill "${e}" has model invocation disabled`}:{success:!0,content:await T(i.content,n,r)}}catch(i){return{success:!1,content:"",error:i instanceof Error?i.message:String(i)}}}async reload(){this.skillsByName.clear(),this.fullSkillsByName.clear(),await this.discover()}list(){return Array.from(this.skillsByName.values())}listUserInvocable(){return this.list().filter(e=>e.userInvocable)}getSystemPromptSnippet(){let e=this.list().filter(r=>!r.disableModelInvocation);if(e.length===0)return"";let n=["## Available Skills","","When users ask you to perform tasks, check if any of the available skills below match the request. Skills provide specialized capabilities and step-by-step instructions for specific workflows.","",'When users reference a "slash command" or "/<something>" (e.g. "/feature-list-tracker", "/skill:foo"), they are referring to a skill. Invoke it via the `skill` tool with the skill name.',"","**BLOCKING REQUIREMENT**: When a skill matches the user's request, you MUST invoke it via the `skill` tool BEFORE generating any other response about the task. Loading the skill is not optional and not something to defer \u2014 it is the FIRST action you take.","","NEVER mention a skill without actually calling the `skill` tool. Do not guess at skill names \u2014 only use skills listed below. Do NOT call `read` on a `SKILL.md` path to load a skill \u2014 that is the legacy path and bypasses the resolver.",""];for(let r of e){let i=r.argumentHint?` ${r.argumentHint}`:"";n.push(`- ${r.name}:${i} ${r.description}`)}return n.push(""),n.join(`
|
|
16
|
+
`)}has(e){return this.skillsByName.has(e)}get size(){return this.skillsByName.size}},K=null,gt;function se(t,e){return K&&t!==void 0&>!==t&&(K=null),K||(K=new oe(t,e),gt=t),K}s(se,"getSkillRegistry");async function Ne(t,e){let n=se(t,e);return await n.discover(),n}s(Ne,"initializeSkillRegistry");function tr(){K=null}s(tr,"resetSkillRegistry");var Y=class{static{s(this,"SkillExecutor")}context;constructor(e){this.context=e}async execute(e,n,r){let i=se();if(!i.has(e))return{success:!1,content:"",error:`Skill not found: ${e}`};try{let o=await i.loadFull(e),a=r?.mode??(o.context==="fork"?"fork":"inline"),c=await T(o.content,n,this.context);return a==="fork"?this.executeFork(o,c,r):this.executeInline(o,c,r)}catch(o){return{success:!1,content:"",error:o instanceof Error?o.message:String(o)}}}async executeInline(e,n,r){let i=this.buildPrompt(e,n);if(r?.onExecute)try{return{success:!0,content:await r.onExecute(i,e)}}catch(o){return{success:!1,content:"",error:o instanceof Error?o.message:String(o)}}return{success:!0,content:i}}async executeFork(e,n,r){return{success:!0,content:this.buildPrompt(e,n),artifacts:[{type:"text",name:"fork-config",content:JSON.stringify({agent:r?.agent??e.agent??"general-purpose",model:r?.model??e.model??"haiku",allowedTools:r?.allowedTools??this.parseAllowedTools(e.allowedTools)})}]}}buildPrompt(e,n){let r=[];return r.push(`[Using Skill: ${e.name}]`),r.push(""),e.allowedTools&&(r.push(`**Allowed Tools**: ${e.allowedTools}`),r.push("")),r.push(n),r.join(`
|
|
17
|
+
`)}parseAllowedTools(e){return e?e.split(",").map(n=>n.trim()).filter(Boolean):[]}};function nr(t){return new Y(t)}s(nr,"createExecutor");async function rr(t,e,n,r){return new Y(n).execute(t,e,r)}s(rr,"executeSkill");function yt(t){return t.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}s(yt,"escapeXml");var De=120;function ae(t){return t.replace(/\\/g,"/")}s(ae,"formatDisplayPath");function ir(t){return[...(t.references??[]).map(e=>({folder:"references",file:e})),...(t.scripts??[]).map(e=>({folder:"scripts",file:e})),...(t.assets??[]).map(e=>({folder:"assets",file:e})),...(t.templates??[]).map(e=>({folder:"templates",file:e})),...(t.resources??[]).map(e=>({folder:"resources",file:e}))]}s(ir,"collectSupportFiles");function or(t){let e=ir(t);if(e.length===0)return[];let n=[["references",t.references],["scripts",t.scripts],["assets",t.assets],["templates",t.templates],["resources",t.resources]],r=["Skill support files are rooted at the skill root above. When the skill references `references/...`, `assets/...`, `scripts/...`, `templates/...`, or `resources/...`, read it from this skill root.","","Support roots:"];for(let[i,o]of n)o?.length&&r.push(`- ${i}/: ${ae(`${t.path}/${i}`)} (${o.length} files)`);r.push("","Support file inventory:");for(let{folder:i,file:o}of e.slice(0,De))r.push(`- ${i}/${o.relativePath}: ${ae(o.path)}`);return e.length>De&&r.push(`- ... ${e.length-De} more files under ${ae(t.path)}`),r}s(or,"buildSupportFileContext");function sr(t,e,n){let r=[];r.push(`<skill name="${yt(t.name)}" location="${yt(t.path)}">`),r.push(""),r.push(`Skill root: ${ae(t.path)}`),t.source==="builtin"?r.push("This is a built-in KodaX skill."):t.source==="project"?r.push("This is a project-defined skill. Project work paths are relative to the project root; skill support files are relative to the skill root above."):t.source==="user"&&r.push("This is a user-defined skill."),r.push("");let i=or(t);return i.length>0&&(r.push(...i),r.push("")),r.push(e),n.trim()&&(r.push(""),r.push(`User provided arguments: ${n}`)),r.push(""),r.push("</skill>"),r.join(`
|
|
18
|
+
`)}s(sr,"buildSkillBlock");async function ar(t,e,n){let r=await T(t.content,e,n);return{content:sr(t,r,e),disableModelInvocation:t.disableModelInvocation??!1,skill:t}}s(ar,"expandSkillForLLM");function cr(t,e){let n=`Skill activated: ${t}`;return e.trim()&&(n+=` with arguments: ${e}`),n}s(cr,"formatSkillActivationMessage");import{mkdir as ht,open as dr,readFile as pr,rename as lr,rm as de,stat as fr,writeFile as ur}from"fs/promises";import{basename as mr,dirname as wt,join as gr}from"path";var Rt=1;function b(t){return typeof t=="object"&&t!==null&&!Array.isArray(t)}s(b,"isRecord");function yr(t){return t==="pending"||t==="approved"||t==="rejected"}s(yr,"isReviewStatus");function kt(t){return t==="foreground_user"||t==="assistant_tool"||t==="background_learning"}s(kt,"isSkillWriteOrigin");function S(t){return Array.isArray(t)&&t.every(e=>typeof e=="string")}s(S,"isStringArray");function ce(t){return b(t)&&Object.values(t).every(e=>typeof e=="string")}s(ce,"isStringRecord");function hr(t){return t==="record_usage"||t==="create"||t==="patch"||t==="archive"||t==="quarantine"||t==="delete"||t==="consolidate"||t==="direct_mutation"}s(hr,"isSkillGovernanceAction");function wr(t){return t==="save_from_run"||t==="revise_capsule"||t==="add_skill_reference"||t==="report_only"}s(wr,"isWorkflowSuggestedAction");function Rr(t){return t==="low"||t==="medium"||t==="high"}s(Rr,"isLearningRisk");function kr(t){return t==="user"||t==="feedback"||t==="project"||t==="reference"||t==="semantic_memory"}s(kr,"isMemoryKind");function Sr(t){return t==="foreground_user"||t==="assistant_tool"||t==="background_learning"||t==="external_provider"}s(Sr,"isMemoryWriteOrigin");function br(t){return t==="primary"||t==="subagent"||t==="workflow_child"||t==="cron"||t==="flush"||t==="compression"}s(br,"isMemoryExecutionContext");function vr(t){return b(t)&&S(t.workflowCapsules)&&S(t.savedWorkflows)&&S(t.constructedAgents)&&S(t.promptReferences)&&(t.action==="none"||t.action==="rewrite_proposal"||t.action==="block_until_manual_review")}s(vr,"isConsumerImpact");function Ir(t){return b(t)&&Sr(t.writeOrigin)&&br(t.executionContext)&&typeof t.sessionId=="string"&&(t.parentSessionId===void 0||typeof t.parentSessionId=="string")&&(t.platform===void 0||typeof t.platform=="string")&&(t.sourceTool===void 0||typeof t.sourceTool=="string")&&S(t.sourceRefs)&&typeof t.completedTurn=="boolean"&&(t.claimKind===void 0||xr(t.claimKind))&&(t.claimKey===void 0||typeof t.claimKey=="string")&&(t.actionSignature===void 0||typeof t.actionSignature=="string")&&(t.persistenceKind===void 0||t.persistenceKind==="create"||t.persistenceKind==="evidence_update"||t.persistenceKind==="condition_refinement")&&(t.targetRefId===void 0||typeof t.targetRefId=="string")&&(t.targetStorageUri===void 0||typeof t.targetStorageUri=="string")&&(t.preconditions===void 0||typeof t.preconditions=="string")&&(t.applicability===void 0||Pr(t.applicability))&&(t.requestedLifecycle===void 0||t.requestedLifecycle==="active"||t.requestedLifecycle==="provisional")&&(t.episodeOutcome===void 0||t.episodeOutcome==="succeeded"||t.episodeOutcome==="failed")&&(t.verifiedEvidence===void 0||typeof t.verifiedEvidence=="boolean")&&(t.evidenceProjectId===void 0||typeof t.evidenceProjectId=="string")}s(Ir,"isMemoryMetadata");function xr(t){return t==="fact"||t==="policy"||t==="preference"||t==="procedure"||t==="episode"}s(xr,"isMemoryClaimKind");function Pr(t){return!b(t)||typeof t.tenantId!="string"?!1:["workspaceId","userId","agentId","projectId","sessionId"].every(e=>t[e]===void 0||typeof t[e]=="string")}s(Pr,"isMemoryApplicability");function _r(t){if(!b(t))return!1;let e=t.destination;return typeof t.proposalId!="string"||!kt(t.origin)?!1:e==="skill_patch"||e==="skill_create"?t.userLabel==="method_guide"&&typeof t.skillName=="string"&&typeof t.whyDurable=="string"&&typeof t.trigger=="string"&&typeof t.changeSummary=="string"&&S(t.sourceTraceIds)&&typeof t.confidence=="number":e==="workflow_handoff"?t.userLabel==="runnable_workflow"&&S(t.evidenceRunIds)&&S(t.sourceTraceIds)&&wr(t.suggestedAction)&&typeof t.whyWorkflowNotSkill=="string"&&S(t.requiredWorkflowEvidence)&&Rr(t.risk)&&vr(t.consumerImpact)&&t.appliedByF224===!1:e==="memdir_handoff"?t.userLabel==="context_note"&&kr(t.memoryKind)&&typeof t.body=="string"&&Ir(t.metadata):e==="reasoning_handoff"?t.userLabel==="reasoning_report"&&typeof t.title=="string"&&typeof t.body=="string"&&S(t.sourceTraceIds):!1}s(_r,"isReviewableProposal");function Ar(t){return b(t)?t.kind==="write"?typeof t.relativePath=="string"&&typeof t.content=="string":t.kind==="delete"?typeof t.relativePath=="string":!1:!1}s(Ar,"isSkillMutationChange");function Er(t){if(!b(t)||t.kind!=="skill"||typeof t.skillRoot!="string"||t.skillRoot.length===0||!Array.isArray(t.changes)||!t.changes.every(Ar))return!1;let e=t.governance;return!(!b(e)||!hr(e.action)||e.source!=="project"&&e.source!=="user"&&e.source!=="plugin"&&e.source!=="builtin"&&e.source!=="external"||e.ownership!=="system"&&e.ownership!=="human"&&e.ownership!=="background_created"||!kt(e.origin)||e.pinned!==void 0&&typeof e.pinned!="boolean"||t.snapshotRoot!==void 0&&typeof t.snapshotRoot!="string")}s(Er,"isStoredLearningApplyPlan");function jr(t,e,n){if(!b(t)){n.push(`proposal entry ${e} is not an object`);return}let r=t.proposalId,i=t.status,o=t.proposal,a=t.applyPlan,c=t.createdAt,d=t.updatedAt,p=t.appliedAt,f=t.appliedChangedPaths,u=t.appliedSnapshotPath,l=t.approvedBy,y=t.approvedAt,g=t.approvalPolicyId,x=t.approvalPolicyReason,A=t.approvalExpectedFingerprints,j=t.approvalResultingFingerprints,O=t.rejectedReason;if(typeof r!="string"||r.length===0){n.push(`proposal entry ${e} has no proposalId`);return}if(!yr(i)){n.push(`proposal entry ${r} has invalid status`);return}if(!_r(o)){n.push(`proposal entry ${r} has invalid proposal payload`);return}if(o.proposalId!==r){n.push(`proposal entry ${r} has mismatched proposal payload id`);return}if(typeof c!="string"||typeof d!="string"){n.push(`proposal entry ${r} has invalid timestamps`);return}if(a!==void 0&&!Er(a)){n.push(`proposal entry ${r} has invalid apply plan`);return}if(p!==void 0&&typeof p!="string"){n.push(`proposal entry ${r} has invalid appliedAt`);return}if(f!==void 0&&!S(f)){n.push(`proposal entry ${r} has invalid applied changed paths`);return}if(l!==void 0&&l!=="user"&&l!=="host"){n.push(`proposal entry ${r} has invalid approvedBy`);return}if(!(y!==void 0&&typeof y!="string")&&!(g!==void 0&&typeof g!="string")&&!(x!==void 0&&typeof x!="string")&&!(A!==void 0&&!ce(A))&&!(j!==void 0&&!ce(j))){if(u!==void 0&&typeof u!="string"){n.push(`proposal entry ${r} has invalid applied snapshot path`);return}return{proposalId:r,status:i,proposal:o,...a!==void 0?{applyPlan:a}:{},createdAt:c,updatedAt:d,...typeof p=="string"?{appliedAt:p}:{},...S(f)?{appliedChangedPaths:f}:{},...l==="user"||l==="host"?{approvedBy:l}:{},...typeof y=="string"?{approvedAt:y}:{},...typeof g=="string"?{approvalPolicyId:g}:{},...typeof x=="string"?{approvalPolicyReason:x}:{},...ce(A)?{approvalExpectedFingerprints:A}:{},...ce(j)?{approvalResultingFingerprints:j}:{},...typeof u=="string"?{appliedSnapshotPath:u}:{},...typeof O=="string"?{rejectedReason:O}:{}}}}s(jr,"parseStoredProposal");function $r(t){let e;try{e=JSON.parse(t)}catch(o){let a=o instanceof Error?o.message:String(o);return{proposals:[],warnings:[`learning proposal store is not valid JSON: ${a}`]}}if(!b(e))return{proposals:[],warnings:["learning proposal store root is not an object"]};if(e.version!==Rt)return{proposals:[],warnings:["learning proposal store version is unsupported"]};if(!Array.isArray(e.proposals))return{proposals:[],warnings:["learning proposal store has no proposals array"]};let n=[];return{proposals:e.proposals.map((o,a)=>jr(o,a,n)).filter(o=>o!==void 0),warnings:n}}s($r,"parseStoreDocument");async function St(t,e){let n={version:Rt,proposals:e},r=wt(t);await ht(r,{recursive:!0});let i=gr(r,`.${mr(t)}.kodax-${process.pid}-${Date.now().toString(36)}.tmp`);try{await ur(i,`${JSON.stringify(n,null,2)}
|
|
19
|
+
`,"utf8"),await lr(i,t)}catch(o){throw await de(i,{force:!0}),o}}s(St,"writeStoreDocument");async function P(t){let e;try{e=await pr(t,"utf8")}catch(n){if(n.code==="ENOENT")return{proposals:[],warnings:[]};throw n}return $r(e)}s(P,"readLearningProposalStore");async function bt(t,e,n={}){return It(t,async()=>{let r=await P(t);if(r.warnings.length>0)throw new Error(`refusing to write corrupt learning proposal store: ${r.warnings.join("; ")}`);let o=(n.now??(()=>new Date().toISOString()))(),a=r.proposals.find(p=>p.proposalId===e.proposalId),c=a?{...a,proposal:e,...n.applyPlan!==void 0?{applyPlan:n.applyPlan}:{},updatedAt:o}:{proposalId:e.proposalId,status:"pending",proposal:e,...n.applyPlan!==void 0?{applyPlan:n.applyPlan}:{},createdAt:o,updatedAt:o},d=a?r.proposals.map(p=>p.proposalId===e.proposalId?c:p):[...r.proposals,c];return await St(t,d),c})}s(bt,"upsertLearningProposal");function vt(t){let e=te(t),n=e?Q(e):`local-${ee(t)}`;return E("projects",n,"learning","proposals.json")}s(vt,"resolveLearningProposalStore");async function pe(t,e,n,r={}){return It(t,async()=>{let i=await P(t);if(i.warnings.length>0)throw new Error(`refusing to write corrupt learning proposal store: ${i.warnings.join("; ")}`);let o=i.proposals.find(d=>d.proposalId===e);if(!o)throw new Error(`learning proposal not found: ${e}`);let a=r.now??(()=>new Date().toISOString()),c={...o,status:n,updatedAt:a(),...n==="approved"&&r.appliedAt!==void 0?{appliedAt:r.appliedAt}:{},...n==="approved"&&r.appliedChangedPaths!==void 0?{appliedChangedPaths:r.appliedChangedPaths}:{},...n==="approved"&&r.appliedSnapshotPath!==void 0?{appliedSnapshotPath:r.appliedSnapshotPath}:{},...n==="approved"&&r.approvedBy!==void 0?{approvedBy:r.approvedBy}:{},...n==="approved"&&r.approvedAt!==void 0?{approvedAt:r.approvedAt}:{},...n==="approved"&&r.approvalPolicyId!==void 0?{approvalPolicyId:r.approvalPolicyId}:{},...n==="approved"&&r.approvalPolicyReason!==void 0?{approvalPolicyReason:r.approvalPolicyReason}:{},...n==="approved"&&r.approvalExpectedFingerprints!==void 0?{approvalExpectedFingerprints:r.approvalExpectedFingerprints}:{},...n==="approved"&&r.approvalResultingFingerprints!==void 0?{approvalResultingFingerprints:r.approvalResultingFingerprints}:{},...n==="rejected"&&r.rejectedReason!==void 0?{rejectedReason:r.rejectedReason}:{rejectedReason:void 0}};return await St(t,i.proposals.map(d=>d.proposalId===e?c:d)),c})}s(pe,"updateLearningProposalStatus");async function It(t,e){let n=`${t}.lock`;await ht(wt(t),{recursive:!0});let r=await Fr(n);try{return await e()}finally{try{await r.close()}finally{await de(n,{force:!0})}}}s(It,"withStoreWriteLock");async function Fr(t){let e=Date.now()+5e3;for(;;)try{let n=await dr(t,"wx");try{return await n.writeFile(`${process.pid}
|
|
20
|
+
`,"utf8"),n}catch(r){throw await n.close(),await de(t,{force:!0}),r}}catch(n){if(!xt(n,"EEXIST"))throw n;if(await Mr(t)){await de(t,{force:!0});continue}if(Date.now()>=e)throw new Error(`learning proposal store lock timed out: ${t}`);await new Promise(r=>setTimeout(r,10))}}s(Fr,"acquireStoreWriteLock");async function Mr(t){try{return Date.now()-(await fr(t)).mtimeMs>3e4}catch(e){if(xt(e,"ENOENT"))return!1;throw e}}s(Mr,"isStaleStoreLock");function xt(t,e){return b(t)&&t.code===e}s(xt,"isFileError");import{createHash as Yr}from"node:crypto";import{readdir as Gt,readFile as qr,rename as Hr,rm as Vt,writeFile as Xr,mkdir as Jr}from"node:fs/promises";import{basename as _,dirname as Ct,join as h,relative as Gr,resolve as We,sep as Vr}from"node:path";import{createHmac as Cr,randomBytes as Lr}from"node:crypto";import{mkdir as Ke,open as Tr,readFile as le,rm as Ue,stat as Or,writeFile as Be}from"node:fs/promises";import v from"node:path";async function Pt(t,e){let n=await $t(t);return Object.keys(n.entries).length===0?e.lifecycle:n.entries[await jt(t,e.id)]?.lifecycle??e.lifecycle}s(Pt,"resolveManagedLifecycle");async function _t(t,e,n){await Et(t,e.id,"archived",n)}s(_t,"archiveManagedMemoryRef");async function At(t,e,n){if(e.storageUri===void 0||!Wr(t,e.storageUri))throw new Error("memory ref is not stored under the managed memory root");await Ue(e.storageUri,{force:!0}),await Ur(t,v.basename(e.storageUri)),await Et(t,e.id,"forgotten",n)}s(At,"forgetManagedMemoryRef");async function Et(t,e,n,r){await Nr(t,async()=>{let i=await $t(t),o=await jt(t,e);await zr(t,{version:1,entries:{...i.entries,[o]:{lifecycle:n,updatedAt:r}}})})}s(Et,"updateLifecycle");async function Nr(t,e){let n=v.join(t,".governance","lifecycle.lock");await Ke(v.dirname(n),{recursive:!0});let r=await Dr(n);try{await e()}finally{try{await r.close()}finally{await Ue(n,{force:!0})}}}s(Nr,"withLifecycleLock");async function Dr(t){let e=Date.now()+5e3;for(;;)try{return await Tr(t,"wx")}catch(n){if(!Mt(n))throw n;if(await Kr(t)){await Ue(t,{force:!0});continue}if(Date.now()>=e)throw new Error(`memory lifecycle lock timed out: ${t}`);await new Promise(r=>setTimeout(r,10))}}s(Dr,"acquireLifecycleLock");async function Kr(t){try{return Date.now()-(await Or(t)).mtimeMs>3e4}catch(e){if(fe(e))return!1;throw e}}s(Kr,"isStaleLifecycleLock");async function Ur(t,e){let n=v.join(t,"MEMORY.md");try{let i=(await le(n,"utf8")).split(/\r?\n/).filter(o=>!o.includes(`(${e})`)).join(`
|
|
21
|
+
`);await Be(n,i.endsWith(`
|
|
22
|
+
`)||i.length===0?i:`${i}
|
|
23
|
+
`,"utf8")}catch(r){if(!fe(r))throw r}}s(Ur,"removeIndexLine");async function jt(t,e){return Cr("sha256",await Br(t)).update(e).digest("hex")}s(jt,"tombstoneKey");async function Br(t){let e=v.join(t,".governance","tombstone.key");try{return await le(e)}catch(r){if(!fe(r))throw r}await Ke(v.dirname(e),{recursive:!0});let n=Lr(32);try{return await Be(e,n,{flag:"wx"}),n}catch(r){if(!Mt(r))throw r;return le(e)}}s(Br,"readOrCreateKey");async function $t(t){try{let e=JSON.parse(await le(Ft(t),"utf8"));if(!q(e)||e.version!==1||!q(e.entries))throw new Error("invalid memory lifecycle state");let n={};for(let[r,i]of Object.entries(e.entries)){if(!/^[0-9a-f]{64}$/.test(r)||!q(i))throw new Error("invalid memory lifecycle entry");if(i.lifecycle!=="archived"&&i.lifecycle!=="forgotten"||typeof i.updatedAt!="string")throw new Error("invalid memory lifecycle entry");n[r]={lifecycle:i.lifecycle,updatedAt:i.updatedAt}}return{version:1,entries:n}}catch(e){if(fe(e))return{version:1,entries:{}};throw e}}s($t,"readLifecycleState");async function zr(t,e){let n=Ft(t);await Ke(v.dirname(n),{recursive:!0}),await Be(n,`${JSON.stringify(e,null,2)}
|
|
24
|
+
`,"utf8")}s(zr,"writeState");function Ft(t){return v.join(t,".governance","lifecycle.json")}s(Ft,"statePath");function Wr(t,e){let n=v.resolve(t);return v.resolve(e).startsWith(`${n}${v.sep}`)}s(Wr,"isWithin");function q(t){return typeof t=="object"&&t!==null&&!Array.isArray(t)}s(q,"isRecord");function fe(t){return q(t)&&t.code==="ENOENT"}s(fe,"isMissing");function Mt(t){return q(t)&&t.code==="EEXIST"}s(Mt,"isAlreadyExists");var J="missing",Zt=1,Zr=1440*60*1e3,Qr=2,ei=200;function ti(t){return new ye(t)}s(ti,"createMemoryControlPlane");var ye=class{static{s(this,"MemoryControlPlane")}cwd;learningStorePath;memoryRoot;now;onEvent;projectDocs;extraRefs;sessionId;sessionLineage;artifactLedger;discoverSkills;memoryReviewer;identity;applicability;scopedRoots;constructor(e){this.cwd=e.cwd,this.learningStorePath=e.learningStorePath??vt(e.cwd),this.identity=e.identity,this.applicability=e.identity?.projectId!==void 0?{tenantId:e.identity.tenantId,projectId:e.identity.projectId}:void 0,this.memoryRoot=e.memoryRoot??(e.identity?.projectId!==void 0?L(e.identity,"project"):ne(e.cwd)),this.scopedRoots=e.memoryRoot!==void 0||e.identity===void 0?[]:ri(e.identity),this.now=e.now??(()=>new Date().toISOString()),this.onEvent=e.onEvent,this.projectDocs=e.projectDocs??ni(e.cwd),this.extraRefs=e.extraRefs??[],this.sessionId=e.sessionId??"current",this.sessionLineage=e.sessionLineage,this.artifactLedger=e.artifactLedger??[],this.discoverSkills=e.discoverSkills??!0,this.memoryReviewer=e.memoryReviewer}async listInbox(){let e=await P(this.learningStorePath);if(e.warnings.length>0)return[];let n=[];for(let r of e.proposals){if(r.status!=="pending")continue;let i=await this.projectLearningProposal(r);i!==void 0&&n.push(i)}return n}async showProposal(e){let n=await P(this.learningStorePath);if(n.warnings.length>0)return;let r=n.proposals.find(i=>H(i.proposalId)===e);return r===void 0?void 0:this.projectLearningProposal(r)}async approveProposal(e,n){let r=await this.showProposal(e);if(r===void 0)return I(e,"memory proposal not found");if(n===void 0)return I(e,"approval requires fingerprints from a shown proposal preview");let i={proposalId:r.id,approvedBy:"user",approvedAt:this.now(),expectedFingerprints:n},a=await this.adapterForProposal(r).applyProposal(r,i);return a.applied&&this.emit({type:"proposal.approved",proposalId:e}),a}async rejectProposal(e,n){let r=He(e);if(r===void 0)return{proposalId:e,rejected:!1,skippedReason:`invalid memory proposal id: ${e}`,warnings:[]};let i=await this.showProposal(e);if(i===void 0)return{proposalId:e,rejected:!1,skippedReason:"memory proposal not found",warnings:[]};await pe(this.learningStorePath,r,"rejected",n!==void 0&&n.trim().length>0?{rejectedReason:n}:{}),this.emit({type:"proposal.rejected",proposalId:e});let o=n?.trim(),a,c=[];if(o!==void 0&&o.length>0)try{a=await this.reviewMemoryFeedback({trigger:"proposal_rejected",userFeedback:o,sourceRefs:i.sourceRefs.map(d=>d.id),candidateRefIds:[...i.targetRefs.map(d=>d.id),...i.sourceRefs.map(d=>d.id)]}),c=a.warnings}catch(d){c=[`memory feedback review failed: ${Ht(d)}`]}return{proposalId:e,rejected:!0,...a!==void 0?{review:a}:{},warnings:c}}async listRefs(e={}){let n=[];n.push(...await this.listLearningRefs());for(let r of this.memdirAdapters())n.push(...await r.listRefs(e));return n.push(...this.listSessionTraceRefs()),n.push(...this.listArtifactLedgerRefs()),n.push(...await this.listProjectDocRefs()),n.push(...await this.listSkillRefs()),n.push(...this.extraRefs),n.filter(r=>Ge(r,e))}async readRef(e){return e.kind==="learning_proposal"||e.kind==="reasoning_report"?this.readLearningRef(e):e.kind==="memdir"?this.memdirAdapter().readRef(e):e.kind==="session_trace"?this.readSessionTraceRef(e):e.kind==="artifact_ledger"?this.readArtifactLedgerRef(e):Je(e,this.now)}async archiveRef(e){let n=(await this.listRefs()).find(r=>r.id===e);return n?.kind!=="memdir"?Jt(e,"archive"):(await _t(this.memoryRootForRef(n),n,this.now()),{refId:e,operation:"archive",acknowledged:!0,residualSourceRefs:n.sourceRefs,warnings:[]})}async forgetRef(e){return this.removeManagedRef(e,"forget")}async purgeRef(e){return this.removeManagedRef(e,"purge")}async removeManagedRef(e,n){let r=(await this.listRefs()).find(i=>i.id===e);return r?.kind!=="memdir"?Jt(e,n):(await At(this.memoryRootForRef(r),r,this.now()),{refId:e,operation:n,acknowledged:!0,residualSourceRefs:r.sourceRefs,warnings:n==="purge"&&r.sourceRefs.length>0?["source carriers follow their independent retention lifecycle"]:[]})}async runCurator(e={}){let n=await this.listRefs({includePrivate:e.includePrivate,includeSensitive:e.includeSensitive}),r=this.buildGovernanceReport(n);return this.emit({type:"curator.completed",reportId:r.reportId}),r}async maybeRunAutoCurator(e={}){if(e.enabled===!1)return{ran:!1,skippedReason:"disabled"};let n=this.now(),r=Math.max(0,e.intervalMs??Zr),i=Math.max(1,e.minRefs??Qr),o=hi(this.memoryRoot),a=await ki(o),c=a?.lastCheckedAt??a?.lastRunAt,d=c===void 0?void 0:Kt(c,r);if(d!==void 0&&Ii(d,n)>0)return{ran:!1,skippedReason:"not_due",nextEligibleAt:d};let p=(await this.listRefs({includePrivate:e.includePrivate,includeSensitive:e.includeSensitive})).filter(xi);if(p.length<i)return{ran:!1,skippedReason:"insufficient_refs"};let f=this.buildGovernanceReport(p),u=wi(this.memoryRoot,f);return await we(u,`${JSON.stringify(f,null,2)}
|
|
25
|
+
`),await Ri(this.memoryRoot,ei),await Si(o,{version:Zt,lastCheckedAt:n,lastRunAt:n,lastInventoryFingerprint:m(Ut(p)),lastReportPath:u}),this.emit({type:"curator.completed",reportId:f.reportId}),{ran:!0,report:f,reportPath:u,nextEligibleAt:Kt(n,r)}}async buildMemoryPack(e){let n=this.now(),r=Yt(e),i=m(r);if(e.ignoreMemory===!0||Wi(e.task))return{generatedAt:n,taskFingerprint:i,memoryRevision:m("suppressed"),candidates:[],promptHints:[],hints:[],omitted:["memory intentionally suppressed by request"],traceMetadata:{selectedRefIds:[],omittedRefIds:[],taskFingerprint:i,suppressed:!0}};let a=(await this.listRefs({includePrivate:e.includePrivate,includeSensitive:e.includeSensitive})).filter(l=>Li(l,e)).sort((l,y)=>me(y,r)-me(l,r)),c=Math.max(0,e.maxCandidates??12),d=Math.min(c,Math.max(0,e.maxHints??5)),p=a.slice(0,c),f=await this.buildPackHints(p,{...e,includeSnippets:!1}),u=await this.buildPackHints(p.slice(0,d),e);return this.emit({type:"pack.selected",refIds:u.map(l=>l.ref.id)}),{generatedAt:n,taskFingerprint:i,memoryRevision:m(Ut(a)),candidates:f,promptHints:u,hints:u,omitted:a.slice(c).map(l=>l.id),traceMetadata:{selectedRefIds:u.map(l=>l.ref.id),omittedRefIds:a.slice(c).map(l=>l.id),taskFingerprint:i,suppressed:!1}}}async reviewMemoryFeedback(e){let n=this.now(),r=e.sourceRefs??[],i=await this.selectReviewCandidateRefs(e),o={trigger:e.trigger,userFeedback:e.userFeedback??e.episodeDigest?.summary??"",...e.task!==void 0?{task:e.task}:{},sourceRefs:r,candidateRefs:i.candidateRefs,warnings:i.warnings};if(this.memoryReviewer===void 0){let d={trigger:e.trigger,createdAt:n,sourceRefs:r,candidateRefs:i.candidateRefs,actions:[],warnings:[...i.warnings,"memory reviewer unavailable; semantic memory review was not run"],...e.episodeDigest!==void 0?{episodeDigest:e.episodeDigest}:{}};return this.emit({type:"review.completed",trigger:e.trigger,actionCount:0}),d}let a=await this.memoryReviewer(o),c=e.episodeDigest===void 0?a:{...a,episodeDigest:e.episodeDigest};return this.emit({type:"review.completed",trigger:e.trigger,actionCount:c.actions.length}),c}async persistReviewPlan(e){return(await this.persistReviewPlanWithDecisions(e)).proposalIds}async persistReviewPlanWithDecisions(e){let n=[],r=[],i=await this.listRefs({includePrivate:!0}),o=(await P(this.learningStorePath)).proposals;for(let a=0;a<e.actions.length;a+=1){let c=e.actions[a],d=await this.consultReviewAction(e,c,a,i);if(d.kind==="conflict"||d.kind==="no_action"||d.kind==="reject"||d.kind==="quarantine"){r.push(d);continue}let p=d.existingRefId===void 0?void 0:i.find(A=>A.id===d.existingRefId),f=d.kind==="evidence_update"&&p!==void 0?Ki((await this.readRef(p)).body):c.proposedBody?.trim();if(f===void 0||f.length===0){r.push({actionIndex:a,kind:"reject",reason:"memory proposal body is empty",...d.existingRefId!==void 0?{existingRefId:d.existingRefId}:{}});continue}let u=`memory-review-${m([e.trigger,...e.sourceRefs,d.kind,d.existingRefId??"",c.summary,f].join("\0")).slice(0,24)}`,l=e.episodeDigest,y=Bi([...p?.sourceRefs??[],...l?.evidenceRefs??e.sourceRefs]),g=this.resolveReviewMemoryPlacement(e,c,p,o),x={destination:"memdir_handoff",proposalId:u,origin:"background_learning",userLabel:"context_note",memoryKind:g.memoryKind,body:f,metadata:{writeOrigin:"background_learning",executionContext:"primary",sessionId:l?.sessionId??"memory-review",sourceRefs:y,completedTurn:!0,persistenceKind:d.kind,...c.claimKind!==void 0?{claimKind:c.claimKind}:{},...c.claimKey!==void 0?{claimKey:c.claimKey}:{},...c.actionSignature!==void 0?{actionSignature:c.actionSignature}:{},...c.preconditions!==void 0?{preconditions:c.preconditions}:{},...g.applicability!==void 0?{applicability:g.applicability}:{},requestedLifecycle:g.requestedLifecycle,...l!==void 0?{episodeOutcome:l.outcome,verifiedEvidence:qe(l),...this.identity?.projectId!==void 0?{evidenceProjectId:this.identity.projectId}:{}}:{},...p!==void 0?{targetRefId:p.id,...p.storageUri!==void 0?{targetStorageUri:p.storageUri}:{}}:{}}};await bt(this.learningStorePath,x,{now:this.now}),n.push(u),r.push({...d,proposalId:u}),this.emit({type:"proposal.created",proposalId:H(u)})}return{proposalIds:n,decisions:r}}resolveReviewMemoryPlacement(e,n,r,i){if(n.claimKind==="preference"&&(e.trigger==="explicit_remember"||e.trigger==="user_correction")&&this.identity?.userId!==void 0)return{memoryKind:"user",applicability:{tenantId:this.identity.tenantId,userId:this.identity.userId},requestedLifecycle:"active"};if(n.claimKind!=="procedure"||n.claimKey===void 0||this.identity===void 0)return this.projectPlacement(n.claimKind);let o=e.episodeDigest,a=o!==void 0&&qe(o),c=Di(n.claimKey,i,a&&o?.outcome==="succeeded"?this.identity.projectId:void 0,a&&o?.outcome==="failed");if(!(r?.scope==="agent"||c.projects.size>=2))return this.projectPlacement("procedure");let p=c.successes>=3&&c.projects.size>=2&&!c.hasCounterexample;return{memoryKind:"semantic_memory",applicability:{tenantId:this.identity.tenantId,agentId:this.identity.agentId},requestedLifecycle:p?"active":"provisional"}}projectPlacement(e){return this.identity?.projectId===void 0?{memoryKind:"project",requestedLifecycle:"active"}:{memoryKind:"project",applicability:{tenantId:this.identity.tenantId,...e==="procedure"?{agentId:this.identity.agentId}:{},projectId:this.identity.projectId},requestedLifecycle:"active"}}async reviewEpisode(e,n){let r=await this.reviewMemoryFeedback({trigger:"episode_completed",episodeDigest:e,userFeedback:e.summary,task:e.objective,sourceRefs:e.evidenceRefs});if(Xt(n))return Xi(r,"episode review timed out");let i=await this.persistReviewPlanWithDecisions(r),o=i.proposalIds,a=[],c=[...r.warnings];for(let d of i.decisions){if(Xt(n)){c.push("episode review timed out before governed apply");break}let p=d.proposalId;if(p===void 0)continue;let f=r.actions[d.actionIndex];if(f===void 0||!Oi(f,e))continue;let u=await this.applyHostEligibleProposal(H(p),`${_e}:episode-promotion`,"verified low-risk episode memory");u.applied?a.push(p):u.skippedReason!==void 0&&c.push(u.skippedReason)}return{plan:r,proposalIds:o,appliedProposalIds:a,decisions:i.decisions,warnings:c}}async consultReviewAction(e,n,r,i){if(n.action==="conflict_report"||n.relationship==="conflict")return{actionIndex:r,kind:"conflict",reason:"review reported an unresolved contradiction"};if(n.action==="quarantine"||Ui(n.proposedBody??""))return{actionIndex:r,kind:"quarantine",reason:"memory content is restricted or explicitly quarantined"};if(n.action!=="write_memdir"&&n.action!=="patch_memdir"||n.proposedBody===void 0||n.proposedBody.trim().length===0)return{actionIndex:r,kind:"reject",reason:"review action is not a supported durable-memory mutation"};let o=Ni(n,e,i);if(o===void 0)return n.action==="patch_memdir"?{actionIndex:r,kind:"reject",reason:"patch target is missing or governance-incompatible"}:{actionIndex:r,kind:"create",reason:"no compatible governed claim exists"};if(o.lifecycle==="quarantined")return{actionIndex:r,kind:"quarantine",existingRefId:o.id,reason:"compatible claim is quarantined"};if(o.lifecycle==="archived"||o.authority==="proposal_only")return{actionIndex:r,kind:"reject",existingRefId:o.id,reason:"compatible claim is not eligible for governed update"};let a=await this.readRef(o),c=n.relationship==="same_claim"||zt(a.body)===zt(n.proposedBody),p=(e.episodeDigest?.evidenceRefs??e.sourceRefs).some(f=>!o.sourceRefs.includes(f));return c&&!p?{actionIndex:r,kind:"no_action",existingRefId:o.id,reason:"compatible claim and evidence already exist"}:{actionIndex:r,kind:c&&n.relationship!=="condition_refinement"?"evidence_update":"condition_refinement",existingRefId:o.id,reason:c?"compatible claim has new independent evidence":"compatible claim receives a reviewed condition refinement"}}async applyHostEligibleProposal(e,n,r){let i=await this.showProposal(e);if(i===void 0)return I(e,"memory proposal not found");let o=await this.adapterForProposal(i).applyProposal(i,{proposalId:i.id,approvedBy:"host",approvedAt:this.now(),expectedFingerprints:i.expectedFingerprints,policyId:n,policyReason:r});return o.applied&&this.emit({type:"proposal.approved",proposalId:e}),o}async projectLearningProposal(e){if(e.proposal.destination==="memdir_handoff")return this.projectMemdirHandoff(e,e.proposal);if(e.proposal.destination==="reasoning_handoff")return this.projectReasoningHandoff(e,e.proposal)}async projectMemdirHandoff(e,n){let r=this.memoryRootForHandoff(n),i=this.scopedRoots.find(u=>u.root===r),o=ai(r,n,e.proposalId),a=await ci(o.targetPath,n,e,i),c=await di(o.entrypointPath,i),d=ge(e),p={[a.id]:a.bodyFingerprint??J,[c.id]:c.bodyFingerprint??J},f={summary:`${n.metadata.persistenceKind==="evidence_update"||n.metadata.persistenceKind==="condition_refinement"?"Update":"Write"} ${n.memoryKind} memory from learning proposal ${e.proposalId}.`,changedRefs:[a,c],changedPaths:[o.targetPath,o.entrypointPath],beforeFingerprints:p,afterFingerprints:{[a.id]:m(o.content)},diff:o.content,warnings:[]};return{id:H(e.proposalId),action:n.metadata.persistenceKind==="evidence_update"||n.metadata.persistenceKind==="condition_refinement"?"patch_memdir":"write_memdir",targetRefs:[a,c],sourceRefs:[d],expectedFingerprints:p,rationale:`F224 classified this as ${n.memoryKind} memory.`,risk:"medium",preview:f,requiresApproval:!0,createdAt:e.createdAt}}projectReasoningHandoff(e,n){let r=Tt(e),i=ge(e),o={summary:`Record reasoning report handoff: ${n.title}`,changedRefs:[],changedPaths:[],beforeFingerprints:{[r.id]:r.bodyFingerprint??m(n.body)},warnings:["No stable reasoning-strategy carrier exists yet; approval records the handoff only."]};return{id:H(e.proposalId),action:"no_op",targetRefs:[r],sourceRefs:[i],expectedFingerprints:o.beforeFingerprints,rationale:"Reasoning handoff stays as a report until a stable carrier exists.",risk:"low",preview:o,requiresApproval:!0,createdAt:e.createdAt}}async listLearningRefs(){let e=await P(this.learningStorePath);if(e.warnings.length>0)return[];let n=[];for(let r of e.proposals)(r.proposal.destination==="memdir_handoff"||r.proposal.destination==="reasoning_handoff")&&n.push(ge(r)),r.proposal.destination==="reasoning_handoff"&&n.push(Tt(r));return n}async readLearningRef(e){let n=e.kind==="reasoning_report"?e.id.replace(/^reasoning_report:/,""):e.id.replace(/^learning_proposal:/,""),r=await P(this.learningStorePath),i=r.proposals.find(a=>a.proposalId===n);if(i===void 0)return{ref:e,body:"",bodyFingerprint:m(""),readAt:this.now(),warnings:[`learning proposal not found: ${n}`]};let o=Xe(i);return{ref:{...e,bodyFingerprint:m(o)},body:o,bodyFingerprint:m(o),readAt:this.now(),warnings:r.warnings}}async listProjectDocRefs(){let e=[];for(let n of this.projectDocs){let r=await M(n);r.exists&&e.push({kind:"project_doc",id:`project_doc:${Gr(this.cwd,n).replace(/\\/g,"/")}`,scope:"project",title:_(n),owner:"project",lifecycle:"readonly",authority:"read_only",visibility:"prompt_safe",sourceRefs:[],relatedRefs:[],bodyFingerprint:m(r.content),storageUri:n})}return e}listSessionTraceRefs(){return this.sessionLineage===void 0?[]:this.sessionLineage.entries.map(e=>ii(this.sessionId,e))}listArtifactLedgerRefs(){return this.artifactLedger.map(e=>oi(this.sessionId,e))}readSessionTraceRef(e){let n=Ot(e.id,"session_trace",this.sessionId),r=this.sessionLineage?.entries.find(o=>o.id===n),i=r===void 0?"":Re(r);return{ref:{...e,bodyFingerprint:m(i)},body:i,bodyFingerprint:m(i),readAt:this.now(),warnings:r===void 0?[`session trace entry not found: ${e.id}`]:[]}}readArtifactLedgerRef(e){let n=Ot(e.id,"artifact_ledger",this.sessionId),r=this.artifactLedger.find(o=>o.id===n),i=r===void 0?"":Re(r);return{ref:{...e,bodyFingerprint:m(i)},body:i,bodyFingerprint:m(i),readAt:this.now(),warnings:r===void 0?[`artifact ledger entry not found: ${e.id}`]:[]}}async listSkillRefs(){if(!this.discoverSkills)return[];let e;try{e=(await Ne(this.cwd)).list()}catch{return[]}return e.map(n=>({kind:"skill",id:`skill:${n.name}`,scope:n.source==="builtin"?"builtin":n.source==="user"?"user":"project",title:n.name,owner:n.source==="builtin"?"kodax":n.source==="user"?"user":"project",lifecycle:n.source==="builtin"?"readonly":"active",authority:"read_only",visibility:"prompt_safe",sourceRefs:[],relatedRefs:[],storageUri:h(n.path,"SKILL.md")}))}async buildPackHints(e,n){let r=[];for(let i of e){let o=n.includeSnippets===!0?await this.readRef(i):void 0;r.push({ref:i,hook:i.title??i.id,reason:Yi(i,Yt(n)),...o!==void 0&&o.body.trim().length>0?{bodySnippet:n.purpose==="deliberate_query"?qi(o.body):qt(o.body),bodyFingerprint:o.bodyFingerprint}:i.bodyFingerprint!==void 0?{bodyFingerprint:i.bodyFingerprint}:{}})}return r}async selectReviewCandidateRefs(e){let n=Math.max(0,e.maxRefs??6);if(n===0)return{candidateRefs:[],warnings:[]};let r=await this.listRefs({includePrivate:e.includePrivate,includeSensitive:e.includeSensitive}),i=[],o=e.candidateRefIds!==void 0&&e.candidateRefIds.length>0?zi(r,e.candidateRefIds,n,i):r.filter(Ti).sort((c,d)=>me(d,Wt(e))-me(c,Wt(e))).slice(0,n),a=[];for(let c of o)a.push(await this.readReviewCandidateRef(c));return{candidateRefs:a,warnings:i}}async readReviewCandidateRef(e){try{let n=await this.readRef(e);return{ref:n.ref,...n.body.trim().length>0?{bodySnippet:qt(n.body)}:{},bodyFingerprint:n.bodyFingerprint,warnings:n.warnings}}catch(n){return{ref:e,...e.bodyFingerprint!==void 0?{bodyFingerprint:e.bodyFingerprint}:{},warnings:[`failed to read memory ref: ${Ht(n)}`]}}}adapterForProposal(e){return e.action==="write_memdir"||e.action==="patch_memdir"?this.memdirAdapter():new Ye(this.learningStorePath,this.now)}memdirAdapter(){return this.memdirAdapters()[0]??new X(this.memoryRoot,this.learningStorePath,this.now)}memdirAdapters(){return this.scopedRoots.length===0?[new X(this.memoryRoot,this.learningStorePath,this.now,this.applicability,"project")]:this.scopedRoots.map(e=>new X(e.root,this.learningStorePath,this.now,e.applicability,e.scope))}memoryRootForHandoff(e){let n=e.memoryKind==="user"?"user":e.memoryKind==="semantic_memory"?"agent":"project";return this.scopedRoots.find(r=>r.scope===n)?.root??this.memoryRoot}memoryRootForRef(e){let n=e.storageUri===void 0?void 0:We(e.storageUri);return this.scopedRoots.find(r=>n?.startsWith(`${We(r.root)}${Vr}`))?.root??this.memoryRoot}emit(e){this.onEvent?.(e)}buildGovernanceReport(e){let n=this.now(),r=Ai(e);return{reportId:`memory-governance:${m(`${n}:${r.length}`).slice(0,12)}`,generatedAt:n,findings:r.length>0?r:[{kind:"no_op",severity:"info",refIds:[],summary:"No memory governance findings.",suggestedAction:"no_op"}],warnings:[]}}},Ye=class{static{s(this,"LearningHandoffAdapter")}learningStorePath;now;kind="learning_proposal";constructor(e,n){this.learningStorePath=e,this.now=n}async listRefs(e={}){let n=await P(this.learningStorePath);return n.warnings.length>0?[]:n.proposals.filter(r=>r.proposal.destination==="memdir_handoff"||r.proposal.destination==="reasoning_handoff").map(ge).filter(r=>Ge(r,e))}async readRef(e){return Je(e,this.now)}async previewProposal(e){return e.preview}async applyProposal(e,n){let r=He(e.id);if(r===void 0)return I(e.id,"invalid memory proposal id");if(!Hi(e.expectedFingerprints,n.expectedFingerprints))return I(e.id,"approval fingerprints do not match proposal preview");let i=await pe(this.learningStorePath,r,"approved",{appliedChangedPaths:[],approvedBy:n.approvedBy,approvedAt:n.approvedAt,approvalPolicyId:n.policyId,approvalPolicyReason:n.policyReason,approvalExpectedFingerprints:n.expectedFingerprints,approvalResultingFingerprints:n.expectedFingerprints,now:this.now});return{proposalId:e.id,applied:!0,changedRefs:e.targetRefs,changedPaths:[],warnings:i.status==="approved"?[]:["proposal status did not become approved"]}}},X=class{static{s(this,"MemdirMemoryAdapter")}memoryRoot;learningStorePath;now;applicability;scope;kind="memdir";constructor(e,n,r,i,o="project"){this.memoryRoot=e,this.learningStorePath=n,this.now=r,this.applicability=i,this.scope=o}async listRefs(e={}){let n=[],r=this.applicability===void 0?void 0:await P(this.learningStorePath),i;try{i=await Gt(this.memoryRoot,{withFileTypes:!0})}catch(o){if(Ve(o))return[];throw o}for(let o of i){if(!o.isFile()||!o.name.endsWith(".md")||o.name==="MEMORY.md")continue;let a=h(this.memoryRoot,o.name),c=await M(a);if(!c.exists)continue;let d=pi(a,c.content),p=await Pt(this.memoryRoot,d);if(p==="forgotten")continue;let f=p===d.lifecycle?d:{...d,lifecycle:p};if(this.applicability===void 0){n.push(f);continue}let u=he(f,this.scope,this.applicability),l=li(r?.proposals??[],u,c.content),y=l?.proposal.destination==="memdir_handoff"?l.proposal.metadata:void 0,g=y?.applicability===void 0?u:he(f,this.scope,y.applicability);n.push(l===void 0?{...u,lifecycle:"provisional",authority:"proposal_only"}:{...g,lifecycle:g.lifecycle==="archived"?"archived":y?.requestedLifecycle??"active",sourceRefs:l.proposal.destination==="memdir_handoff"?l.proposal.metadata.sourceRefs:g.sourceRefs,...l.proposal.destination==="memdir_handoff"&&l.proposal.metadata.claimKind!==void 0?{claimKind:l.proposal.metadata.claimKind}:{},...l.proposal.destination==="memdir_handoff"&&l.proposal.metadata.claimKey!==void 0?{claimKey:l.proposal.metadata.claimKey}:{},...l.proposal.destination==="memdir_handoff"&&l.proposal.metadata.actionSignature!==void 0?{actionSignature:l.proposal.metadata.actionSignature}:{},applyReceiptRef:`learning_proposal:${l.proposalId}`,expectedFingerprint:l.approvalExpectedFingerprints?.[g.id],resultingFingerprint:l.approvalResultingFingerprints?.[g.id]})}return n.filter(o=>Ge(o,e))}async readRef(e){return Je(e,this.now)}async previewProposal(e){return e.preview}async applyProposal(e,n){let r=He(e.id);if(r===void 0)return I(e.id,"invalid memory proposal id");let i=e.targetRefs.find(C=>C.kind==="memdir"&&C.storageUri!==void 0),o=e.targetRefs.find(C=>C.storageUri!==void 0&&_(C.storageUri)==="MEMORY.md");if(i?.storageUri===void 0||o?.storageUri===void 0)return I(e.id,"memory proposal has no memdir target");let a=n.expectedFingerprints[i.id],c=n.expectedFingerprints[o.id];if(a===void 0||c===void 0)return I(e.id,"approval fingerprints do not cover proposal preview");let p=[i,o].find(C=>Ci(C));if(p!==void 0)return I(e.id,`${p.id} is not mutable by memory governance`);let f=await M(i.storageUri),u=await M(o.storageUri),l=e.preview.diff??"",y=mi(i.storageUri,l),g=f.exists&&f.content===l,x=gi(u.content,i.storageUri,y),A=u.exists&&u.content===x;if(Lt(f)!==a&&!g)return I(e.id,"target memory changed after preview");if(Lt(u)!==c&&!g&&!A)return I(e.id,"MEMORY.md changed after preview");let j=[],O=[];return g?O.push("target memory already matched proposal content; completing approval"):(await we(i.storageUri,l),j.push(i.storageUri)),A?O.push("MEMORY.md already contained the proposal index line; completing approval"):(await we(o.storageUri,x),j.push(o.storageUri)),await pe(this.learningStorePath,r,"approved",{appliedAt:this.now(),appliedChangedPaths:[i.storageUri,o.storageUri],approvedBy:n.approvedBy,approvedAt:n.approvedAt,approvalPolicyId:n.policyId,approvalPolicyReason:n.policyReason,approvalExpectedFingerprints:n.expectedFingerprints,approvalResultingFingerprints:{[i.id]:m(l),[o.id]:m(x)},now:this.now}),{proposalId:e.id,applied:!0,changedRefs:e.targetRefs,changedPaths:j,warnings:O}}};function ni(t){return["README.md","AGENTS.md",h("docs","PRD.md"),h("docs","ADR.md"),h("docs","HLD.md"),h("docs","DD.md"),h("docs","FEATURE_LIST.md")].map(e=>We(t,e))}s(ni,"defaultProjectDocs");function ri(t){let e=[];return t.projectId!==void 0&&e.push({root:L(t,"project"),scope:"project",applicability:{tenantId:t.tenantId,projectId:t.projectId}}),t.workspaceId!==void 0&&e.push({root:L(t,"workspace"),scope:"workspace",applicability:{tenantId:t.tenantId,workspaceId:t.workspaceId}}),e.push({root:L(t,"agent"),scope:"agent",applicability:{tenantId:t.tenantId,agentId:t.agentId}}),t.userId!==void 0&&e.push({root:L(t,"user"),scope:"user",applicability:{tenantId:t.tenantId,userId:t.userId}}),e}s(ri,"buildScopedRoots");function H(t){return`memory:${t}`}s(H,"memoryProposalId");function He(t){return t.startsWith("memory:")?t.slice(7):void 0}s(He,"parseMemoryProposalId");function m(t){return`sha256:${Yr("sha256").update(t).digest("hex")}`}s(m,"fingerprint");function Lt(t){return t.exists?m(t.content):J}s(Lt,"fingerprintOrMissing");function Qt(t){return t.status==="pending"?"pending":t.status==="approved"?"trusted":"archived"}s(Qt,"lifecycleFromStatus");function ge(t){let e=Xe(t);return{kind:"learning_proposal",id:`learning_proposal:${t.proposalId}`,scope:"project",title:si(t),owner:"project",lifecycle:Qt(t),authority:"proposal_only",visibility:"prompt_safe",sourceRefs:en(t),relatedRefs:[],bodyFingerprint:m(e),createdAt:t.createdAt,updatedAt:t.updatedAt}}s(ge,"learningRefFromEntry");function Tt(t){let e=t.proposal.destination==="reasoning_handoff"?t.proposal.title:t.proposalId,n=Xe(t);return{kind:"reasoning_report",id:`reasoning_report:${t.proposalId}`,scope:"project",title:e,owner:"project",lifecycle:Qt(t),authority:"proposal_only",visibility:"prompt_safe",sourceRefs:en(t),relatedRefs:[`learning_proposal:${t.proposalId}`],bodyFingerprint:m(n),createdAt:t.createdAt,updatedAt:t.updatedAt}}s(Tt,"reasoningRefFromEntry");function ii(t,e){let n=Re(e);return{kind:"session_trace",id:`session_trace:${t}:${e.id}`,scope:"session",title:`Session ${e.type}: ${e.id}`,owner:"project",lifecycle:"provisional",authority:"read_only",visibility:"private",sourceRefs:[],relatedRefs:e.parentId===null?[]:[`session_trace:${t}:${e.parentId}`],version:"2",bodyFingerprint:m(n),createdAt:e.timestamp,updatedAt:e.timestamp}}s(ii,"sessionTraceRefFromEntry");function oi(t,e){let n=Re(e);return{kind:"artifact_ledger",id:`artifact_ledger:${t}:${e.id}`,scope:"session",title:e.summary??e.displayTarget??e.target,owner:"project",lifecycle:"provisional",authority:"read_only",visibility:"prompt_safe",sourceRefs:e.sessionEntryId===void 0?[]:[`session_trace:${t}:${e.sessionEntryId}`],relatedRefs:[],bodyFingerprint:m(n),createdAt:e.timestamp,updatedAt:e.timestamp}}s(oi,"artifactLedgerRefFromEntry");function Ot(t,e,n){let r=`${e}:${n}:`;return t.startsWith(r)?t.slice(r.length):""}s(Ot,"parseScopedMemoryRefId");function si(t){let e=t.proposal;return e.destination==="memdir_handoff"?`${e.memoryKind} memory handoff`:e.destination==="reasoning_handoff"?e.title:e.proposalId}s(si,"learningTitle");function en(t){let e=t.proposal;return e.destination==="memdir_handoff"?e.metadata.sourceRefs:e.destination==="reasoning_handoff"?e.sourceTraceIds:[]}s(en,"learningSourceRefs");function Xe(t){let e=t.proposal;return e.destination==="memdir_handoff"||e.destination==="reasoning_handoff"?e.body:JSON.stringify(e,null,2)}s(Xe,"learningBody");function ai(t,e,n){let r=fi(e.memoryKind),i=tn(e.body,`${e.memoryKind} memory`),o=ui(e.body)||i,a=e.metadata.targetStorageUri===void 0?`${r}_${Nt(i)}_${Nt(n)}.md`:_(e.metadata.targetStorageUri),c=e.metadata.targetStorageUri??h(t,a),d=["---",`name: ${Dt(i)}`,`description: ${Dt(o)}`,`type: ${r}`,"---","",e.body.trim(),""].join(`
|
|
26
|
+
`);return{targetPath:c,entrypointPath:h(t,"MEMORY.md"),content:d,indexLine:`- [${i}](${a}) - ${o}`}}s(ai,"buildMemdirWritePlan");async function ci(t,e,n,r){let i=await M(t),o={kind:"memdir",id:`memdir:${_(t)}`,scope:e.memoryKind==="user"?"user":"project",title:tn(e.body,`${e.memoryKind} memory`),owner:e.memoryKind==="user"?"user":"project",lifecycle:i.exists?"active":"pending",authority:"approved_write",visibility:"prompt_safe",sourceRefs:[`learning_proposal:${n.proposalId}`,...e.metadata.sourceRefs],relatedRefs:[],...e.metadata.claimKind!==void 0?{claimKind:e.metadata.claimKind}:{},...e.metadata.claimKey!==void 0?{claimKey:e.metadata.claimKey}:{},...e.metadata.actionSignature!==void 0?{actionSignature:e.metadata.actionSignature}:{},bodyFingerprint:i.exists?m(i.content):J,storageUri:t,createdAt:n.createdAt,updatedAt:n.updatedAt};return r===void 0?o:he(o,r.scope,e.metadata.applicability??r.applicability)}s(ci,"buildMemdirTargetRef");async function di(t,e){let n=await M(t),r={kind:"memdir",id:"memdir:MEMORY.md",scope:"project",title:"MEMORY.md",owner:"project",lifecycle:n.exists?"active":"pending",authority:"approved_write",visibility:"prompt_safe",sourceRefs:[],relatedRefs:[],bodyFingerprint:n.exists?m(n.content):J,storageUri:t};return e===void 0?r:he(r,e.scope,e.applicability)}s(di,"buildEntrypointRef");function pi(t,e){let n=$(e),r=_(t),i=n.frontmatter.type;return{kind:"memdir",id:`memdir:${r}`,scope:i==="user"?"user":"project",title:n.frontmatter.name??r,owner:i==="user"?"user":"project",lifecycle:"active",authority:r==="MEMORY.md"?"read_only":"approved_write",visibility:"prompt_safe",sourceRefs:[],relatedRefs:[],bodyFingerprint:m(e),storageUri:t}}s(pi,"memdirRefFromFile");function he(t,e,n){let r=Pe(n),i=t.storageUri===void 0?t.id:_(t.storageUri);return{...t,id:`memdir:${e}:${r}:${i}`,scope:e,scopeId:r,applicability:n}}s(he,"decorateScopedRef");function li(t,e,n){if(e.storageUri===void 0)return;let r=e.storageUri,i=m(n);for(let o=t.length-1;o>=0;o-=1){let a=t[o];if(a.status==="approved"&&a.appliedChangedPaths?.includes(r)===!0&&Object.values(a.approvalResultingFingerprints??{}).includes(i))return a}}s(li,"findApplyReceipt");function fi(t){return t==="user"||t==="feedback"||t==="project"||t==="reference"?t:"project"}s(fi,"memoryTypeForHandoff");function tn(t,e){let n=t.split(/\r?\n/).map(r=>r.trim()).find(r=>r.length>0);return n===void 0?e:n.replace(/^#+\s*/,"").slice(0,80)||e}s(tn,"titleFromBody");function ui(t){let e=t.replace(/\s+/g," ").trim();if(e.length===0)return;let n=e.search(/[.!?。!?]/);return(n>=0?e.slice(0,n+1):e).slice(0,160)}s(ui,"firstSentence");function Nt(t){let e=t.toLowerCase().replace(/[^a-z0-9]+/g,"_").replace(/^_+|_+$/g,"").slice(0,48);return e.length>0?e:"memory"}s(Nt,"slugify");function Dt(t){return JSON.stringify(t.replace(/\r?\n/g," "))}s(Dt,"quoteScalar");function mi(t,e){let n=$(e),r=n.frontmatter.name??_(t,".md"),i=n.frontmatter.description??r;return`- [${r}](${_(t)}) - ${i}`}s(mi,"indexLineFromContent");function gi(t,e,n){let r=t.trimEnd();if(yi(r,n))return`${r}
|
|
27
|
+
`;let i=_(e).replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),o=new RegExp(`^.*\\(${i}\\).*$`,"m");return o.test(r)?`${r.replace(o,n)}
|
|
28
|
+
`:r.length>0?`${n}
|
|
29
|
+
${r}
|
|
30
|
+
`:`${n}
|
|
31
|
+
`}s(gi,"upsertIndexLine");function yi(t,e){return t.trimEnd().split(/\r?\n/).includes(e)}s(yi,"indexContainsLine");async function M(t){try{return{exists:!0,content:await qr(t,"utf8")}}catch(e){if(Ve(e))return{exists:!1,content:""};throw e}}s(M,"readTextIfExists");async function we(t,e){await Jr(Ct(t),{recursive:!0});let n=h(Ct(t),`.${_(t)}.kodax-${process.pid}-${Date.now().toString(36)}.tmp`);try{await Xr(n,e,"utf8"),await Hr(n,t)}catch(r){throw await Vt(n,{force:!0}),r}}s(we,"writeFileAtomic");function hi(t){return h(t,".governance","auto-curate-state.json")}s(hi,"autoCuratorStatePath");function wi(t,e){let n=Bt(e.generatedAt),r=Bt(e.reportId);return h(t,".governance","reports",`${n}-${r}.json`)}s(wi,"autoCuratorReportPath");async function Ri(t,e){if(e<=0)return;let n=h(t,".governance","reports"),r;try{r=await Gt(n,{withFileTypes:!0})}catch(o){if(Ve(o))return;throw o}let i=r.filter(o=>o.isFile()&&o.name.endsWith(".json")).map(o=>o.name).sort((o,a)=>a.localeCompare(o));for(let o of i.slice(e))await Vt(h(n,o),{force:!0})}s(Ri,"pruneAutoCuratorReports");async function ki(t){let e=await M(t);if(e.exists)try{let n=JSON.parse(e.content);return bi(n)?n:void 0}catch{return}}s(ki,"readAutoCuratorState");async function Si(t,e){await we(t,`${JSON.stringify(e,null,2)}
|
|
32
|
+
`)}s(Si,"writeAutoCuratorState");function bi(t){return vi(t)?t.version===Zt&&ue(t.lastCheckedAt)&&ue(t.lastRunAt)&&ue(t.lastInventoryFingerprint)&&ue(t.lastReportPath):!1}s(bi,"isAutoCuratorState");function vi(t){return typeof t=="object"&&t!==null&&!Array.isArray(t)}s(vi,"isReadonlyRecord");function ue(t){return t===void 0||typeof t=="string"}s(ue,"optionalStringField");function Kt(t,e){let n=Date.parse(t),r=Number.isFinite(n)?n:Date.now();return new Date(r+e).toISOString()}s(Kt,"addMs");function Ii(t,e){let n=Date.parse(t),r=Date.parse(e);return!Number.isFinite(n)||!Number.isFinite(r)?0:n-r}s(Ii,"compareIso");function xi(t){return t.kind==="memdir"||t.kind==="learning_proposal"||t.kind==="reasoning_report"}s(xi,"isAutoCuratorCandidate");function Ut(t){return t.map(e=>[e.id,e.kind,e.scope,e.lifecycle,e.authority,e.visibility,e.bodyFingerprint??"",e.storageUri??"",e.updatedAt??"",e.title??""].join(" ")).sort().join(`
|
|
33
|
+
`)}s(Ut,"memoryInventoryPayload");function Bt(t){let e=t.replace(/[^a-zA-Z0-9._-]+/g,"-").replace(/^-+|-+$/g,"");return e.length>0?e:"report"}s(Bt,"sanitizePathSegment");async function Je(t,e){if(t.storageUri===void 0)return{ref:t,body:"",bodyFingerprint:m(""),readAt:e(),warnings:["memory ref has no storageUri"]};let n=await M(t.storageUri);if(!n.exists)return{ref:t,body:"",bodyFingerprint:m(""),readAt:e(),warnings:[`memory ref storage does not exist: ${t.storageUri}`]};let r=t.kind==="memdir"?$(n.content):void 0;return{ref:{...t,bodyFingerprint:m(n.content)},body:n.content,bodyFingerprint:m(n.content),...r!==void 0?{frontmatter:Pi(r.frontmatter)}:{},readAt:e(),warnings:[]}}s(Je,"readStorageBackedRef");function Pi(t){let e={};return t.name!==void 0&&(e.name=t.name),t.description!==void 0&&(e.description=t.description),t.type!==void 0&&(e.type=t.type),e}s(Pi,"frontmatterRecord");function Ge(t,e){return!(e.kinds!==void 0&&!e.kinds.includes(t.kind)||e.scopes!==void 0&&!e.scopes.includes(t.scope)||e.lifecycles!==void 0&&!e.lifecycles.includes(t.lifecycle)||t.visibility==="private"&&e.includePrivate!==!0||t.visibility==="sensitive"&&e.includeSensitive!==!0||e.query!==void 0&&!_i(t,e.query))}s(Ge,"matchesFilter");function _i(t,e){let n=e.trim().toLowerCase();return n.length===0?!0:[t.id,t.title??"",t.kind,t.scope,t.owner,...t.sourceRefs,...t.relatedRefs].some(r=>r.toLowerCase().includes(n))}s(_i,"refMatchesQuery");function Ai(t){let e=[];e.push(...Ei(t)),e.push(...ji(t)),e.push(...$i(t));for(let n of t)n.lifecycle==="stale"&&e.push({kind:"stale",severity:"warning",refIds:[n.id],summary:`${n.id} is stale and excluded from normal memory packs.`,suggestedAction:"archive"}),n.lifecycle==="quarantined"&&e.push({kind:"quarantined",severity:"warning",refIds:[n.id],summary:`${n.id} is quarantined and requires manual review.`,suggestedAction:"conflict_report"});return e}s(Ai,"buildGovernanceFindings");function Ei(t){let e=new Map;for(let n of t){if(n.bodyFingerprint===void 0||n.lifecycle==="archived")continue;let r=e.get(n.bodyFingerprint)??[];r.push(n.id),e.set(n.bodyFingerprint,r)}return Array.from(e.entries()).filter(([,n])=>n.length>1).map(([n,r])=>({kind:"duplicate",severity:"warning",refIds:r,summary:`Multiple refs share ${n}.`,suggestedAction:"conflict_report"}))}s(Ei,"duplicateFingerprintFindings");function ji(t){let e=new Map;for(let n of t){let r=Fi(n.title);if(r===void 0||n.bodyFingerprint===void 0||n.lifecycle==="archived")continue;let i=e.get(r)??[];i.push(n),e.set(r,i)}return Array.from(e.entries()).flatMap(([n,r])=>{let i=new Set(r.map(o=>o.bodyFingerprint));return r.length<2||i.size<=1?[]:[{kind:"conflict",severity:"warning",refIds:r.map(o=>o.id),summary:`Multiple refs use the title "${n}" with different fingerprints.`,suggestedAction:"conflict_report"}]})}s(ji,"conflictTitleFindings");function $i(t){let e=new Set(t.map(n=>n.id));return t.flatMap(n=>{let r=n.relatedRefs.filter(i=>Mi(i)&&!e.has(i));return r.length===0?[]:[{kind:"orphaned",severity:"warning",refIds:[n.id,...r],summary:`${n.id} points to missing memory ref(s): ${r.join(", ")}.`,suggestedAction:"conflict_report"}]})}s($i,"orphanedRefFindings");function Fi(t){let e=t?.trim().toLowerCase().replace(/\s+/g," ");return e!==void 0&&e.length>0?e:void 0}s(Fi,"normalizeConflictTitle");function Mi(t){return/^(learning_proposal|reasoning_report|memdir|session_trace|artifact_ledger|skill|project_doc|self_manual|workflow_run|working_context):/.test(t)}s(Mi,"isMemoryControlledRefId");function Ci(t){return t.authority==="read_only"||t.scope==="builtin"||t.pinned===!0}s(Ci,"isProtectedFromMutation");function Li(t,e){return t.applicability!==void 0&&(e.identity===void 0||!Z(e.identity,t.applicability))||t.visibility==="private"&&e.includePrivate!==!0||t.visibility==="sensitive"&&e.includeSensitive!==!0||t.authority==="proposal_only"?!1:t.lifecycle==="trusted"||t.lifecycle==="active"||t.lifecycle==="readonly"}s(Li,"isPackEligible");function Ti(t){return t.kind!=="memdir"&&t.kind!=="learning_proposal"&&t.kind!=="reasoning_report"?!1:t.lifecycle!=="archived"&&t.lifecycle!=="quarantined"}s(Ti,"isReviewCandidateEligible");function Oi(t,e){if(t.confidence!=="high"||t.risk!=="low"||e.visibility!=="prompt_safe"||e.evidenceRefs.length===0||!qe(e)||t.claimKind==="procedure"&&e.outcome!=="succeeded")return!1;let n=t.proposedBody??"";return n.length===0?!1:!/(?:api[_-]?key|authorization:\s*bearer|private key|password|secret|token\s*[:=])/i.test(n)}s(Oi,"isEligibleEpisodePromotion");function Ni(t,e,n){let r=new Set(t.targetRefIds),i=n.find(a=>r.has(a.id));if(i!==void 0)return ze(i,t)?i:void 0;if(r.size>0)return;if(t.claimKey!==void 0){let a=n.find(c=>c.claimKey===t.claimKey&&ze(c,t));if(a!==void 0)return a}let o=new Set(e.candidateRefs.map(a=>a.ref.id));return n.find(a=>o.has(a.id)&&ze(a,t))}s(Ni,"findCompatibleReviewRef");function ze(t,e){return!(t.kind!=="memdir"||t.visibility!=="prompt_safe"||e.claimKind!==void 0&&t.claimKind!==void 0&&t.claimKind!==e.claimKind)}s(ze,"isGovernanceCompatibleReviewRef");function zt(t){return $(t).body.replace(/\s+/g," ").trim().toLowerCase()}s(zt,"normalizeClaimBody");function Di(t,e,n,r){let i=n===void 0?0:1,o=r,a=new Set;n!==void 0&&a.add(n);for(let c of e){if(c.status==="rejected"||c.proposal.destination!=="memdir_handoff")continue;let d=c.proposal.metadata;if(d.claimKind!=="procedure"||d.claimKey!==t||d.verifiedEvidence!==!0)continue;let p=d.evidenceProjectId??d.applicability?.projectId;d.episodeOutcome==="succeeded"?(i+=1,p!==void 0&&a.add(p)):d.episodeOutcome==="failed"&&(o=!0)}return{successes:i,projects:a,hasCounterexample:o}}s(Di,"procedurePromotionHistory");function qe(t){return t.evidence?.some(e=>(e.grade==="authoritative"||e.grade==="verified")&&(e.source==="user"||e.source==="host"||e.source==="environment"))===!0}s(qe,"hasVerifiedDigestEvidence");function Ki(t){return $(t).body.trim()}s(Ki,"extractClaimBody");function Ui(t){return/(?:api[_-]?key|authorization:\s*bearer|private key|password|secret|token\s*[:=])/i.test(t)||/(?:ignore|disregard|override)\s+(?:all\s+)?(?:previous|prior|system|developer)\s+instructions?/i.test(t)||/<\/?(?:system|developer|assistant|tool|prompt)(?:\s|>)/i.test(t)}s(Ui,"isRestrictedMemoryBody");function Bi(t){return[...new Set(t)]}s(Bi,"uniqueStrings");function zi(t,e,n,r){let i=new Map(t.map(a=>[a.id,a])),o=[];for(let a of e.slice(0,n)){let c=i.get(a);c===void 0?r.push(`memory review candidate not found: ${a}`):o.push(c)}return o}s(zi,"selectRefsById");function Wt(t){return[t.task,t.userFeedback].filter(e=>e!==void 0&&e.trim().length>0).join(`
|
|
34
|
+
`)}s(Wt,"reviewTask");function Wi(t){return/\b(ignore|do not use|don't use|without)\s+(project\s+)?memory\b/i.test(t)}s(Wi,"shouldIgnoreMemory");function Yt(t){return[t.task,t.decisionIntent,t.actionSignature].filter(e=>e!==void 0&&e.trim().length>0).join(`
|
|
35
|
+
`)}s(Yt,"memoryPackRankingText");function me(t,e){let n=e.toLowerCase(),r=t.title?.toLowerCase()??"",i=0;t.pinned===!0&&(i+=50),t.scope==="project"&&(i+=20),t.scope==="user"&&(i+=10),(t.lifecycle==="trusted"||t.lifecycle==="readonly")&&(i+=10),r.length>0&&n.includes(r)&&(i+=30);for(let o of r.split(/[^a-z0-9]+/).filter(a=>a.length>=3))n.includes(o)&&(i+=3);return i}s(me,"scoreRef");function Yi(t,e){let n=t.title??t.id;return e.toLowerCase().includes(n.toLowerCase())?"Exact task/title overlap.":`${t.scope} ${t.kind} is eligible for deterministic recall.`}s(Yi,"packReason");function qt(t){return t.replace(/\s+/g," ").trim().slice(0,240)}s(qt,"firstSnippet");function qi(t){return $(t).body.replace(/```[\s\S]*?```/g," ").replace(/<\/?[^>]+>/g," ").replace(/^\s{0,3}(?:#{1,6}|[-*+]\s+|>\s*)/gm,"").replace(/[`*_~]/g,"").replace(/\s+/g," ").trim().slice(0,512)}s(qi,"promptSafeClaimSnippet");function Ht(t){return t instanceof Error?t.message:String(t)}s(Ht,"errorMessage");function Re(t){return JSON.stringify(t,null,2)}s(Re,"stringifyJson");function Hi(t,e){let n=Object.keys(t).sort(),r=Object.keys(e).sort();return n.length!==r.length?!1:n.every((i,o)=>i===r[o]&&t[i]===e[i])}s(Hi,"fingerprintsMatch");function I(t,e){return{proposalId:t,applied:!1,changedRefs:[],changedPaths:[],skippedReason:e,warnings:[]}}s(I,"skippedApply");function Xt(t){return t?.aborted===!0}s(Xt,"isAborted");function Xi(t,e){return{plan:t,proposalIds:[],appliedProposalIds:[],decisions:[],warnings:[...t.warnings,e]}}s(Xi,"cancelledEpisodeReview");function Jt(t,e){return{refId:t,operation:e,acknowledged:!1,residualSourceRefs:[],warnings:["managed memory ref not found"]}}s(Jt,"lifecycleNotFound");function Ve(t){return typeof t=="object"&&t!==null&&"code"in t&&t.code==="ENOENT"}s(Ve,"isMissingFile");import{randomUUID as rn}from"node:crypto";import{mkdir as on,readFile as Ji,readdir as sn,rename as an,rm as U,stat as Gi,writeFile as Vi}from"node:fs/promises";import w from"node:path";var Zi=5*6e4;async function Qi(t,e){if(e.sessionId!==t.sessionId)throw new Error("outcome digest session does not match review-inbox owner");let n={version:1,reviewKey:e.reviewKey,digest:e,ownerSessionRef:t.sessionId,ownerAgentHash:R("agent",t.agentId),...t.projectId!==void 0?{ownerProjectHash:R("project",t.projectId)}:{},createdAt:e.createdAt},r=Se(t,e.reviewKey);return await ve(r,n),{path:r,entry:n}}s(Qi,"persistPendingEpisodeReview");async function cn(t){let e=pn(t.tenantId),n=t.agentId===void 0?void 0:R("agent",t.agentId),r=t.projectId===void 0?void 0:R("project",t.projectId),i=await oo(e),o=[];for(let a of i){await io(e,a);let c=w.join(e,a,"pending");for(let d of await Ze(c)){let p=await Qe(w.join(c,d));p!==void 0&&(n!==void 0&&p.ownerAgentHash!==n||r!==void 0&&p.ownerProjectHash!==r||o.push(p))}}return o.sort((a,c)=>a.createdAt.localeCompare(c.createdAt)||a.reviewKey.localeCompare(c.reviewKey))}s(cn,"listPendingEpisodeReviews");async function eo(t,e,n){let r=await dn(t,e,n);return await U(Se(t,e),{force:!0}),{acknowledged:!0,receiptPath:r}}s(eo,"completeEpisodeReview");async function to(t,e){let n=w.join(ke(t),"pending"),r=0;for(let i of await Ze(n)){let o=w.join(n,i),a=await Qe(o);a!==void 0&&a.digest.sequence>e&&(await U(o,{force:!0}),r+=1)}return r}s(to,"rewindPendingEpisodeReviews");async function no(t,e){let n=await cn({tenantId:t.tenantId,agentId:t.agentId,...t.projectId!==void 0?{projectId:t.projectId}:{}}),r=Math.max(1,Math.min(8,e.maxEntries??8)),i={reviewed:0,discarded:0,deferred:0,failed:0,failures:[]};for(let o of n.slice(0,r)){let a={...t,sessionId:o.ownerSessionRef},c=await ro(a,o.reviewKey);if(c!==void 0)try{let d=await e.revalidate(o);if(d==="defer"){await nn(a,o,c),i.deferred+=1;continue}if(d==="discard"){await U(c,{force:!0}),i.discarded+=1;continue}let p=await e.review(o);await dn(a,o.reviewKey,p),await U(c,{force:!0}),i.reviewed+=1}catch(d){await nn(a,o,c),i.failed+=1,i.failures.push({reviewKey:o.reviewKey,error:d instanceof Error?d.message:String(d)})}}return i.deferred+=Math.max(0,n.length-r),i}s(no,"drainPendingEpisodeReviews");async function ro(t,e){let n=w.join(ke(t),"processing");await on(n,{recursive:!0});let r=w.join(n,`${be(e)}.${rn()}.json`);try{return await an(Se(t,e),r),r}catch(i){if(G(i))return;throw i}}s(ro,"claimPendingReview");async function nn(t,e,n){await ve(Se(t,e.reviewKey),e),await U(n,{force:!0})}s(nn,"restoreClaim");async function io(t,e){let n=w.join(t,e),r=w.join(n,"processing");for(let i of await Ze(r)){let o=w.join(r,i);try{if(Date.now()-(await Gi(o)).mtimeMs<=Zi)continue;let a=await Qe(o);if(a===void 0)continue;await ve(w.join(n,"pending",`${be(a.reviewKey)}.json`),a),await U(o,{force:!0})}catch(a){if(!G(a))throw a}}}s(io,"recoverStaleClaims");async function dn(t,e,n){let r={version:1,reviewKey:e,proposalIds:[...n],completedAt:new Date().toISOString()},i=w.join(ke(t),"receipts",`${be(e)}.json`);return await ve(i,r),i}s(dn,"writeEpisodeReviewReceipt");function pn(t){return E("memory-review-inbox",R("tenant",t))}s(pn,"tenantInboxRoot");function ke(t){return w.join(pn(t.tenantId),R("session",t.sessionId))}s(ke,"sessionInboxRoot");function Se(t,e){return w.join(ke(t),"pending",`${be(e)}.json`)}s(Se,"pendingPath");function be(t){return R("review",t)}s(be,"safeKey");async function ve(t,e){await on(w.dirname(t),{recursive:!0});let n=`${t}.${rn()}.tmp`;await Vi(n,`${JSON.stringify(e,null,2)}
|
|
36
|
+
`,"utf8"),await an(n,t)}s(ve,"writeJsonAtomic");async function oo(t){try{return(await sn(t,{withFileTypes:!0})).filter(e=>e.isDirectory()).map(e=>e.name)}catch(e){if(G(e))return[];throw e}}s(oo,"readDirectories");async function Ze(t){try{return(await sn(t,{withFileTypes:!0})).filter(e=>e.isFile()&&e.name.endsWith(".json")).map(e=>e.name)}catch(e){if(G(e))return[];throw e}}s(Ze,"readJsonFiles");async function Qe(t){try{let e=JSON.parse(await Ji(t,"utf8"));return!et(e)||e.version!==1||typeof e.reviewKey!="string"||typeof e.ownerSessionRef!="string"||typeof e.ownerAgentHash!="string"||e.ownerProjectHash!==void 0&&typeof e.ownerProjectHash!="string"||typeof e.createdAt!="string"||!so(e.digest)?void 0:e}catch(e){if(G(e)||e instanceof SyntaxError)return;throw e}}s(Qe,"readPending");function so(t){return et(t)?typeof t.id=="string"&&typeof t.reviewKey=="string"&&typeof t.sessionId=="string"&&typeof t.branchId=="string"&&Number.isSafeInteger(t.sequence)&&typeof t.objective=="string"&&typeof t.approach=="string"&&(t.outcome==="succeeded"||t.outcome==="failed")&&typeof t.summary=="string"&&Array.isArray(t.evidenceRefs)&&t.evidenceRefs.every(e=>typeof e=="string")&&(t.visibility==="prompt_safe"||t.visibility==="private"||t.visibility==="sensitive")&&typeof t.createdAt=="string":!1}s(so,"isOutcomeDigest");function et(t){return typeof t=="object"&&t!==null&&!Array.isArray(t)}s(et,"isRecord");function G(t){return et(t)&&t.code==="ENOENT"}s(G,"isMissing");export{ao as a,B as b,ln as c,mo as d,tt as e,E as f,go as g,Z as h,R as i,Pe as j,_e as k,Q as l,ee as m,te as n,ne as o,kn as p,L as q,Sn as r,bn as s,it as t,$ as u,ot as v,xn as w,Pn as x,_n as y,$n as z,Fn as A,je as B,Mn as C,$e as D,Fe as E,ct as F,dt as G,pt as H,Ce as I,Le as J,Te as K,qn as L,ie as M,ft as N,Jn as O,mt as P,W as Q,er as R,T as S,oe as T,se as U,Ne as V,tr as W,Y as X,nr as Y,rr as Z,ar as _,cr as $,P as aa,bt as ba,vt as ca,pe as da,ti as ea,ye as fa,Qi as ga,cn as ha,eo as ia,to as ja,no as ka};
|