@warble/codex-local 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,211 @@
1
+ # `@warble/codex-local`
2
+
3
+ `codex:local` is Warble's model-level local Codex dispatcher. It consumes the same compiled
4
+ `ir.json` as every other back-end; it does not read profile YAML and it does not route through the
5
+ Claude SDK dispatcher.
6
+
7
+ The one-shot capability profile remains deliberately Setup-only:
8
+
9
+ - analytical `skill` realization;
10
+ - `one_shot` trigger and `none` outcome;
11
+ - exactly one unconditional `strong` step;
12
+ - locked `setup_execution` scope `"."`;
13
+ - exactly two capabilities: `llm:strong` and one of `source_connect` or `context_build`;
14
+ - exactly one locked guardrail: `setup_execution` with scope `"."`.
15
+
16
+ The persistent-session path supports the canonical three-step read-only Ask shape and the canonical
17
+ two-step `generate_dashboard` shape. It maps each
18
+ IR `llm_call` to a named Codex custom agent, binds `cheap` and `strong` independently, verifies child
19
+ thread role/model attribution, and enforces exact `produces` to `consumes` marshalling. The parent may
20
+ only orchestrate. A successful generate skips repair; a failed generate permits exactly one strong
21
+ repair attempt, whose failure loud-fails the run. Any flattening, wrong agent/model/tool, or malformed
22
+ child envelope is an isolation/parity violation. Dashboard planning must successfully introspect
23
+ through the allowlisted Wren MCP, composition must successfully query through it, and the terminal
24
+ value must validate against the IR-declared KPI/table/chart/definition render contract. The validated
25
+ render envelope is the consumer-persistable artifact output; neither parent nor child receives file
26
+ mutation access. If only the best-effort render envelope is invalid, the runtime preserves the
27
+ terminal answer, emits `render_degraded`, and exposes no artifact reference; execution, isolation,
28
+ or data failures still loud-fail.
29
+
30
+ ## Isolation contract
31
+
32
+ Runtime dispatch launches `codex exec` with an ephemeral configuration that ignores user config and
33
+ project rules, disables project-root discovery and project-document loading, uses approval policy
34
+ `never` plus a read-only sandbox, disables shell/file
35
+ mutation/web/browser/app/plugin/skill/delegation surfaces, and exposes only an explicit MCP
36
+ `enabled_tools` allowlist. OpenAI/Codex API-key billing variables are removed from the child
37
+ environment; authentication remains owned by the installed Codex CLI and is never read or copied by
38
+ this package.
39
+
40
+ The JSONL mapper also treats any shell, file-change, web, image, child-agent, non-allowlisted MCP,
41
+ unfinished MCP, or tool-free successful turn as an isolation violation and loud-fails the run.
42
+ Stream events retain only MCP call identity and success state; raw arguments, results, and errors are
43
+ never emitted. Timeout, cancellation, and mapper failures terminate the Codex process group with a
44
+ bounded TERM-to-KILL escalation so MCP descendants cannot survive the dispatch.
45
+
46
+ Persistent interactive sessions use `codex app-server` and retain the same sandbox, feature
47
+ disablement, billing-environment sanitization, required MCP server, and exact enabled-tool
48
+ allowlist. Their conversation source of truth is Codex thread history. Warble stores and returns
49
+ only stable thread/turn references, message item identities without transcript text, and sanitized
50
+ allowlisted MCP artifact references. It does not reconstruct transcripts into prompts or use
51
+ workspace files as conversation storage.
52
+
53
+ For analytical components, Warble writes one mode-0600 custom-agent TOML layer per IR step into a private temporary directory
54
+ for the lifetime of the runtime. The parent config contains only collaboration roles; each child
55
+ layer carries its own model and exact MCP allowlist, disables further delegation, and inherits the
56
+ read-only/approval boundary. The directory is removed when the runtime closes and never contains
57
+ credentials.
58
+
59
+ The caller must provide `CodexSessionRuntime` with
60
+ `externalAuthentication: "provisioned"` and a dedicated persistent `codexHome` that:
61
+
62
+ - is an existing absolute directory outside the project working directory;
63
+ - is not the default Codex home and contains no `config.toml`;
64
+ - was authenticated externally before Warble starts; and
65
+ - remains caller-owned so thread history survives app-server restarts.
66
+
67
+ For example, provision and authenticate it directly with Codex (choose a private path outside the
68
+ project):
69
+
70
+ ```bash
71
+ mkdir -p /absolute/private/path/warble-codex-home
72
+ CODEX_HOME=/absolute/private/path/warble-codex-home codex login
73
+ ```
74
+
75
+ Warble never reads or copies the resulting credentials. Session lifecycle operations are `start`,
76
+ `resume`, `read`, `turn`, `steer`, `interrupt`, and `fork`. Timeout, protocol failure, and app-server
77
+ disconnects close the process tree and yield an explicit failed or resume-required session state.
78
+
79
+ MCP command arguments are configuration, not a credential transport. Do not place passwords,
80
+ tokens, connection strings, or other secret values in `--server-arg`; the Setup MCP server must
81
+ obtain any credentials through its own approved mechanism.
82
+
83
+ ## Commands
84
+
85
+ ```bash
86
+ npm ci
87
+ npm run check-types
88
+ npm test
89
+ npm run build
90
+
91
+ node dist/cli.js manifest ../../examples/provision-agent/ir.golden.json \
92
+ --server-command /absolute/path/to/setup-mcp \
93
+ --source-tool attach_source --context-tool compose_context
94
+
95
+ node dist/cli.js dispatch ../../examples/provision-agent/ir.golden.json \
96
+ "attach a disposable source" --component attach_source \
97
+ --project /absolute/path/to/project \
98
+ --server-command /absolute/path/to/setup-mcp \
99
+ --source-tool attach_source --context-tool compose_context --stream-json
100
+
101
+ # authenticated subscription picker data; no thread or turn is started
102
+ node dist/cli.js list-models --project /absolute/path/to/project \
103
+ --codex-home /absolute/private/path/warble-codex-home --timeout 10000
104
+ ```
105
+
106
+ `list-models` starts a read-only app-server transport, paginates `model/list` with hidden models
107
+ disabled, and emits exactly one versioned JSON object. It only returns model ID, display name,
108
+ description, default state, and supported reasoning efforts; authentication, runtime, timeout, and
109
+ protocol failures are sanitized into the same JSON contract. It never starts a Codex thread or turn.
110
+ `--codex-home`, `--codex-bin`, and `--project` select the same local identity/runtime inputs as the
111
+ other commands; omitting `--codex-home` uses the caller's normal logged-in Codex identity.
112
+
113
+ `dispatch`, `manifest`, and `describe` are the only IR commands. The dispatcher selects the
114
+ supported native contract from the selected component's IR shape and requires `--component` for
115
+ scoped contracts; profile families are never encoded as CLI verbs. Analytical execution uses
116
+ explicit tier bindings and purpose-built Wren MCP tools. `answer_query` or `generate_dashboard`
117
+ select the analytical contract; the latter runs strong planning followed by cheap composition and
118
+ emits a `render_artifact` event before its terminal answer:
119
+
120
+ ```bash
121
+ node dist/cli.js manifest ../../examples/analysis-agent/ir.golden.json \
122
+ --component answer_query \
123
+ --orchestrator-model <driver-model> --cheap-model <cheap-model> --strong-model <strong-model> \
124
+ --server-command /absolute/path/to/wren \
125
+ --server-arg serve --server-arg mcp --server-arg=--project \
126
+ --server-arg /absolute/path/to/wren-project --server-arg=--quiet \
127
+ --inspect-tool get_context --query-tool run_sql
128
+
129
+ node dist/cli.js dispatch ../../examples/analysis-agent/ir.golden.json "top customers" \
130
+ --component answer_query --project /absolute/path/to/wren-project \
131
+ --codex-home /absolute/private/path/warble-codex-home \
132
+ --orchestrator-model <driver-model> --cheap-model <cheap-model> --strong-model <strong-model> \
133
+ --server-command /absolute/path/to/wren \
134
+ --server-arg serve --server-arg mcp --server-arg=--project \
135
+ --server-arg /absolute/path/to/wren-project --server-arg=--quiet \
136
+ --inspect-tool get_context --query-tool run_sql --stream-json
137
+
138
+ node dist/cli.js dispatch ../../examples/analysis-agent/ir.golden.json "build an orders dashboard" \
139
+ --component generate_dashboard --project /absolute/path/to/wren-project \
140
+ --codex-home /absolute/private/path/warble-codex-home \
141
+ --orchestrator-model <driver-model> --cheap-model <cheap-model> --strong-model <strong-model> \
142
+ --server-command /absolute/path/to/wren \
143
+ --server-arg serve --server-arg mcp --server-arg=--project \
144
+ --server-arg /absolute/path/to/wren-project --server-arg=--quiet \
145
+ --inspect-tool get_context --query-tool run_sql --stream-json
146
+ ```
147
+
148
+ Read-only enrichment is selected by the enrichment component's pinned context binding and exact
149
+ capabilities. It uses the same generic operations and an isolated app-server session; the
150
+ host-executed `apply_changes` contract always wall-hits before an app-server process can start:
151
+
152
+ ```bash
153
+ node dist/cli.js dispatch ../../examples/propose-apply-agent/ir.golden.json "inspect available context" \
154
+ --component survey_context --project /absolute/path/to/wren-project \
155
+ --codex-home /absolute/private/path/warble-codex-home \
156
+ --server-command /absolute/path/to/wren \
157
+ --server-arg serve --server-arg mcp --server-arg=--project \
158
+ --server-arg /absolute/path/to/wren-project --server-arg=--quiet \
159
+ --semantic-tool get_context --raw-material-tool read_raw_material --stream-json
160
+ ```
161
+
162
+ The committed test suite uses a fake Codex executable and a disposable non-secret MCP server. The
163
+ authenticated live smoke is opt-in:
164
+
165
+ ```bash
166
+ WARBLE_CODEX_LIVE_SMOKE=1 npm run smoke:live
167
+ ```
168
+
169
+ That command spends one local Codex model call. It must not run in normal CI.
170
+
171
+ The persistent-session gate is separate and requires the dedicated home above:
172
+
173
+ ```bash
174
+ WARBLE_CODEX_SESSION_LIVE_SMOKE=1 \
175
+ WARBLE_CODEX_SESSION_HOME=/absolute/private/path/warble-codex-home \
176
+ npm run smoke:session-live
177
+ ```
178
+
179
+ It spends one model call, then restarts app-server and verifies that the original thread and history
180
+ resume. It never defaults to the user's normal Codex home and must not run in normal CI.
181
+ `WARBLE_CODEX_JS_ENTRY=/absolute/path/to/codex.js` may be set in a restricted environment that can
182
+ spawn Node but cannot execute Codex's `env node` launcher directly.
183
+
184
+ The authenticated Ask parity gate uses the same dedicated home and a disposable MCP server. It
185
+ verifies the cheap/strong named child roles, effective models, exact `run_sql` attribution, and the
186
+ successful no-repair path without reading a real data source:
187
+
188
+ ```bash
189
+ WARBLE_CODEX_ASK_LIVE_SMOKE=1 \
190
+ WARBLE_CODEX_SESSION_HOME=/absolute/private/path/warble-codex-home \
191
+ npm run smoke:ask-live
192
+ ```
193
+
194
+ This opt-in gate spends one parent turn plus two child-agent turns and must not run in normal CI.
195
+ It proves Codex delegation and named-tool attribution against the disposable protocol fixture; it
196
+ does not boot a real Wren project. The production tool binding uses Wren MCP's read-only
197
+ `get_context` and `run_sql` tools shown in the commands above.
198
+
199
+ The dashboard parity gate uses the same fixture but requires strong planning, cheap composition,
200
+ successful `get_context`/`run_sql` calls, a verified KPI/chart/table/definition envelope, and the
201
+ stable render-artifact reference:
202
+
203
+ ```bash
204
+ WARBLE_CODEX_DASHBOARD_LIVE_SMOKE=1 \
205
+ WARBLE_CODEX_SESSION_HOME=/absolute/private/path/warble-codex-home \
206
+ npm run smoke:dashboard-live
207
+ ```
208
+
209
+ It spends one parent turn plus two child-agent turns and must not run in normal CI. Real-project
210
+ dashboard persistence is the consuming GenBI integration gate, not part of this disposable protocol
211
+ smoke.
package/dist/cli.d.ts ADDED
@@ -0,0 +1 @@
1
+ #!/usr/bin/env node