@skillstate/codex 2.2.1 → 3.0.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 +32 -25
- package/dist/codex-adapter.d.ts +16 -14
- package/dist/codex-adapter.d.ts.map +1 -1
- package/dist/codex-adapter.js +39 -27
- package/dist/codex-adapter.js.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
# @skillstate/codex
|
|
4
4
|
|
|
5
|
-
**OpenAI Codex CLI adapter (codex 0.142) for the @skillstate/core runtime — `hooks.json` lifecycle hooks, hook scripts, MCP registration,
|
|
5
|
+
**OpenAI Codex CLI adapter (codex 0.142) for the @skillstate/core runtime — `hooks.json` lifecycle hooks, hook scripts, MCP registration, and a programmatic O(1) fork-trim session.**
|
|
6
6
|
|
|
7
7
|
[](https://www.npmjs.com/package/@skillstate/codex)
|
|
8
8
|
[](https://www.npmjs.com/package/@skillstate/codex)
|
|
@@ -22,27 +22,35 @@ into **OpenAI Codex CLI** (0.142) sessions. It generates:
|
|
|
22
22
|
Bash tool outputs (`PostToolUse` matcher `^Bash$`);
|
|
23
23
|
- **self-contained `.cjs` hook scripts** (Node builtins only, no
|
|
24
24
|
`@skillstate/*` import) that resolve the per-project state from the session
|
|
25
|
-
`cwd` at runtime — one
|
|
25
|
+
`cwd` at runtime — one machine-level script directory serves every project,
|
|
26
|
+
and every script is inert when the cwd has no skillstate state;
|
|
26
27
|
- a **`[mcp_servers.skillstate]` TOML block** for `~/.codex/config.toml`
|
|
27
|
-
(used by `@skillstate/cli
|
|
28
|
-
- a **`SKILL.md`** for `~/.codex/skills/<name>/` that makes the hook-injected
|
|
29
|
-
state authoritative (history is not reliable);
|
|
28
|
+
(used by `@skillstate/cli install`; see `buildCodexMcpToml`);
|
|
30
29
|
- **`CodexForkSession`** (`fork-trim.ts`) — a `codex app-server` JSON-RPC
|
|
31
30
|
client providing **programmatic O(1) history trimming** via
|
|
32
31
|
`thread/fork` / `thread/rollback` (experimental, non-interactive runs).
|
|
33
32
|
|
|
33
|
+
There is NO Codex `SKILL.md` — the bootstrap is the hook-injected state plus
|
|
34
|
+
the skillstate MCP tools, and Codex has no project config support: the glue
|
|
35
|
+
is MACHINE-LEVEL and belongs to `skillstate install`, which wires `~/.codex`
|
|
36
|
+
once while every project's state (`.skillstate/skillstate.json`) is picked up
|
|
37
|
+
automatically from the session cwd.
|
|
38
|
+
|
|
34
39
|
> **@non-paper** — no adapters exist in arXiv 2608.26263v3. This adapter is an
|
|
35
40
|
> additive integration, not part of the paper.
|
|
36
41
|
|
|
37
42
|
## Installation
|
|
38
43
|
|
|
39
|
-
The
|
|
40
|
-
|
|
44
|
+
The machine-level install (hooks + scripts + MCP, once per machine,
|
|
45
|
+
idempotent, with backups — project state needs no install):
|
|
41
46
|
|
|
42
47
|
```bash
|
|
43
|
-
npm i -g @skillstate/cli && skillstate
|
|
48
|
+
npm i -g @skillstate/cli && skillstate install
|
|
44
49
|
```
|
|
45
50
|
|
|
51
|
+
(`skillstate init` in a project prints a hint to run this when it detects
|
|
52
|
+
the `~/.codex` marker; `skillstate uninstall --machine` rolls it back.)
|
|
53
|
+
|
|
46
54
|
Or use the adapter as a library:
|
|
47
55
|
|
|
48
56
|
```bash
|
|
@@ -55,7 +63,6 @@ Requires Node.js >= 20. TypeScript types are bundled.
|
|
|
55
63
|
|
|
56
64
|
```ts
|
|
57
65
|
import { CodexAdapter, CodexForkSession, resolveStateForCwd } from '@skillstate/codex';
|
|
58
|
-
import { INTERCODE_CTF_SPEC } from '@skillstate/core/schemas';
|
|
59
66
|
|
|
60
67
|
const adapter = new CodexAdapter();
|
|
61
68
|
|
|
@@ -92,14 +99,13 @@ const scriptPath = await adapter.saveHookScript(
|
|
|
92
99
|
'/home/me/.codex/hooks/skillstate/post-tool-use.cjs',
|
|
93
100
|
statePath,
|
|
94
101
|
);
|
|
95
|
-
|
|
96
|
-
// SKILL.md for ~/.codex/skills/skillstate/SKILL.md — the injected state is
|
|
97
|
-
// authoritative; persist via the MCP tools state.patch / state.get, and/or
|
|
98
|
-
// print a fenced ```json state_patch block inside a Bash call:
|
|
99
|
-
const skillMd = adapter.generateSkillMd(INTERCODE_CTF_SPEC, './.skillstate/skillstate.json');
|
|
100
|
-
await adapter.saveSkillMd('~/.codex/skills/skillstate/SKILL.md', INTERCODE_CTF_SPEC);
|
|
101
102
|
```
|
|
102
103
|
|
|
104
|
+
There is no `generateSkillMd`/`saveSkillMd` on this adapter: Codex has no
|
|
105
|
+
SKILL.md — the hook-injected state is authoritative, full read/write goes
|
|
106
|
+
through the skillstate MCP tools (`state.patch` / `state.get`), and/or the
|
|
107
|
+
agent prints a fenced ```json `state_patch` block inside a Bash call.
|
|
108
|
+
|
|
103
109
|
### Programmatic O(1) — `CodexForkSession` (experimental)
|
|
104
110
|
|
|
105
111
|
Codex hooks cannot trim host history (hook outputs are limited to
|
|
@@ -155,18 +161,15 @@ Events (`CodexHookEvent`): `'user-prompt-submit' | 'session-start-compact' | 'po
|
|
|
155
161
|
```json block or raw JSON, wrapper-tolerant), applies the ⊕
|
|
156
162
|
null-deletion merge and writes the state file; stdout is `{}` or a
|
|
157
163
|
`systemMessage` when the patch is invalid.
|
|
158
|
-
- `generateSkillMd(spec, statePath?): string` — `SKILL.md` frontmatter
|
|
159
|
-
(name/description/version + `execution_context`) and the state-based
|
|
160
|
-
process body.
|
|
161
164
|
- `mergeHooksConfig(existingJson, options?): string` — idempotent merge of the
|
|
162
165
|
skillstate hook groups into an existing `hooks.json` (foreign hooks are
|
|
163
166
|
preserved; missing/malformed files start a fresh document).
|
|
164
167
|
- `codexHookScriptPath(scriptDir, event): string` — canonical absolute `.cjs`
|
|
165
168
|
path (`<scriptDir>/<event>.cjs`).
|
|
166
169
|
- `saveHooksConfig(target, statePath, options?): Promise<string>`,
|
|
167
|
-
`saveHookScript(event, target, statePath?): Promise<string
|
|
168
|
-
|
|
169
|
-
|
|
170
|
+
`saveHookScript(event, target, statePath?): Promise<string>` — atomic
|
|
171
|
+
writes returning the absolute destination. (There is no SKILL.md for
|
|
172
|
+
Codex: bootstrap = hook-injected state + MCP tools.)
|
|
170
173
|
- `resolveStateForCwd(cwd, home?): string` — per-project state resolution
|
|
171
174
|
shared by the hooks, the fork-trim session, and the CLI install.
|
|
172
175
|
- `new CodexForkSession({ cwd, codexBin?, home?, requestTimeoutMs?,
|
|
@@ -180,10 +183,12 @@ Events (`CodexHookEvent`): `'user-prompt-submit' | 'session-start-compact' | 'po
|
|
|
180
183
|
O(1) path is `CodexForkSession` (`fork-trim.ts`, `codex app-server`
|
|
181
184
|
`thread/fork` / `thread/rollback`) — **experimental**, for non-interactive
|
|
182
185
|
runs.
|
|
183
|
-
- One
|
|
184
|
-
|
|
186
|
+
- One machine-level `hooks.json` + one script directory serve **every
|
|
187
|
+
project** (installed once by `skillstate install`): each script resolves
|
|
188
|
+
the per-project state from the session `cwd`
|
|
185
189
|
(`<cwd>/.skillstate/skillstate.json`; the global bucket
|
|
186
|
-
`~/.skillstate/global/skillstate.json` when cwd === home)
|
|
190
|
+
`~/.skillstate/global/skillstate.json` when cwd === home) and is inert
|
|
191
|
+
when the project has no state — hooks never create state files.
|
|
187
192
|
- The `post-tool-use` script accepts both fenced ```json blocks and an
|
|
188
193
|
unfenced JSON object, and tolerates wrappers such as `Here is: {...}`.
|
|
189
194
|
Malformed outputs are rejected and never persisted.
|
|
@@ -194,7 +199,9 @@ Events (`CodexHookEvent`): `'user-prompt-submit' | 'session-start-compact' | 'po
|
|
|
194
199
|
|
|
195
200
|
- Paper: [arXiv:2608.26263](https://arxiv.org/abs/2608.26263).
|
|
196
201
|
- Core runtime: [`@skillstate/core`](../core).
|
|
197
|
-
- Host install CLI: [`@skillstate/cli`](../cli) (`skillstate
|
|
202
|
+
- Host install CLI: [`@skillstate/cli`](../cli) (`skillstate install` —
|
|
203
|
+
machine-level Codex glue; `skillstate init` — per-project wiring for every
|
|
204
|
+
detected host).
|
|
198
205
|
- [`state.md`](../../state.md) — design notes.
|
|
199
206
|
- Other adapters: `@skillstate/claude`, `@skillstate/opencode`, `@skillstate/mcp`.
|
|
200
207
|
|
package/dist/codex-adapter.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { resolveHostStateForCwd } from '@skillstate/core';
|
|
2
|
-
import type {
|
|
2
|
+
import type { StatePathRef } from '@skillstate/core';
|
|
3
3
|
/** Codex hook events this adapter generates scripts for (script/CLI names). */
|
|
4
4
|
export type CodexHookEvent = 'user-prompt-submit' | 'session-start-compact' | 'post-tool-use';
|
|
5
5
|
/** All {@link CodexHookEvent} values in generation order. */
|
|
@@ -85,6 +85,12 @@ export declare class CodexAdapter {
|
|
|
85
85
|
* and writes the state file (under the built-in cross-process lock);
|
|
86
86
|
* stdout is `{}` or a `systemMessage` when the patch is invalid.
|
|
87
87
|
*
|
|
88
|
+
* INERT WITHOUT STATE: all three scripts resolve the per-project state
|
|
89
|
+
* path first and, when the state FILE does not exist, are no-ops — the
|
|
90
|
+
* inject scripts emit `{}` (no `hookSpecificOutput`, the interrupted-
|
|
91
|
+
* session meta check is skipped since it implies state) and
|
|
92
|
+
* `post-tool-use` writes nothing. Hooks NEVER create state files.
|
|
93
|
+
*
|
|
88
94
|
* AGENT-SCOPED STATE: the hook stdin's `session_id` scopes the state to
|
|
89
95
|
* `<cwd>/.skillstate/agents/<session-prefix>/skillstate.json`, so
|
|
90
96
|
* parallel Codex sessions never last-writer-win over each other.
|
|
@@ -102,17 +108,13 @@ export declare class CodexAdapter {
|
|
|
102
108
|
* current state JSON read from the SESSION cwd. Brand specifics stay in
|
|
103
109
|
* the adapter (comment lines only); the `contextSuffix` is the shared
|
|
104
110
|
* {@link HISTORY_UNRELIABLE_NOTE} from `@skillstate/core`.
|
|
111
|
+
*
|
|
112
|
+
* INERT WITHOUT STATE: after resolving `statePath` the script emits `{}`
|
|
113
|
+
* (no `hookSpecificOutput`, nothing added as developer context) when the
|
|
114
|
+
* state FILE does not exist — the interrupted-session meta check is
|
|
115
|
+
* skipped too, since a session-meta sidecar implies state.
|
|
105
116
|
*/
|
|
106
117
|
private buildInjectScriptTemplate;
|
|
107
|
-
/**
|
|
108
|
-
* Generate a SKILL.md for Codex's skill directory
|
|
109
|
-
* (`~/.codex/skills/<name>/SKILL.md`). The body instructs the agent to
|
|
110
|
-
* treat the hook-injected state as authoritative (history is not
|
|
111
|
-
* reliable), to orient via `state.summary` (full dump via `state.get`),
|
|
112
|
-
* and to persist via `state.patch` — the PostToolUse hook also merges any
|
|
113
|
-
* fenced ```json `state_patch` block printed by a Bash tool call.
|
|
114
|
-
*/
|
|
115
|
-
generateSkillMd(spec: ProceduralSpec, statePath?: string): string;
|
|
116
118
|
/**
|
|
117
119
|
* Generate the hooks.json document and persist it via the shared
|
|
118
120
|
* `saveGenerated`. Both the destination and the embedded state path
|
|
@@ -139,11 +141,11 @@ export declare class CodexAdapter {
|
|
|
139
141
|
*/
|
|
140
142
|
saveHookScript(event: CodexHookEvent, target: string | StatePathRef, statePath?: string | StatePathRef): Promise<string>;
|
|
141
143
|
/**
|
|
142
|
-
*
|
|
143
|
-
*
|
|
144
|
+
* PostToolUse script: extract state_patch, ⊕ merge, persist.
|
|
145
|
+
*
|
|
146
|
+
* INERT WITHOUT STATE: when the state file does not exist the hook
|
|
147
|
+
* writes nothing and emits `{}` — hooks NEVER create state files.
|
|
144
148
|
*/
|
|
145
|
-
saveSkillMd(target: string | StatePathRef, spec: ProceduralSpec, statePath?: string): Promise<string>;
|
|
146
|
-
/** PostToolUse script: extract state_patch, ⊕ merge, persist. */
|
|
147
149
|
private buildPostToolUseScript;
|
|
148
150
|
}
|
|
149
151
|
//# sourceMappingURL=codex-adapter.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"codex-adapter.d.ts","sourceRoot":"","sources":["../src/codex-adapter.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"codex-adapter.d.ts","sourceRoot":"","sources":["../src/codex-adapter.ts"],"names":[],"mappings":"AAmCA,OAAO,EAKL,sBAAsB,EAGvB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAErD,+EAA+E;AAC/E,MAAM,MAAM,cAAc,GACtB,oBAAoB,GACpB,uBAAuB,GACvB,eAAe,CAAC;AAEpB,6DAA6D;AAC7D,eAAO,MAAM,iBAAiB,2EAIgB,CAAC;AAE/C,6EAA6E;AAC7E,eAAO,MAAM,2BAA2B,cAAc,CAAC;AAEvD,2DAA2D;AAC3D,eAAO,MAAM,2BAA2B,WAAW,CAAC;AAEpD;;;GAGG;AACH,eAAO,MAAM,8BAA8B,OAAO,CAAC;AAEnD,gFAAgF;AAChF,eAAO,MAAM,0BAA0B,KAAK,CAAC;AAE7C,4DAA4D;AAC5D,MAAM,WAAW,uBAAuB;IACtC;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,2EAA2E;IAC3E,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,mFAAmF;IACnF,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,8EAA8E;IAC9E,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,kBAAkB,+BAAyB,CAAC;AAEzD;;;;;;;;GAQG;AAEH,qBAAa,YAAY;IACvB,QAAQ,CAAC,IAAI,WAAW;IAExB;;;;;OAKG;IACH,mBAAmB,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,cAAc,GAAG,MAAM,CAEpE;IAED;;;;;;;;;;;OAWG;IACH,mBAAmB,CACjB,SAAS,EAAE,MAAM,GAAG,YAAY,EAChC,OAAO,CAAC,EAAE,uBAAuB,GAChC,MAAM,CA6CR;IAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA6BG;IACH,kBAAkB,CAChB,KAAK,EAAE,cAAc,EACrB,SAAS,CAAC,EAAE,MAAM,GAAG,YAAY,GAChC,MAAM,CAiBR;IAED;;;;;;;;;;;;;OAaG;IACH,OAAO,CAAC,yBAAyB;IAkFjC;;;;;OAKG;IACG,eAAe,CACnB,MAAM,EAAE,MAAM,GAAG,YAAY,EAC7B,SAAS,EAAE,MAAM,GAAG,YAAY,EAChC,OAAO,CAAC,EAAE,uBAAuB,GAChC,OAAO,CAAC,MAAM,CAAC,CAEjB;IAED;;;;;;;;;OASG;IACH,gBAAgB,CAAC,YAAY,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,uBAAuB,GAAG,MAAM,CAahF;IAED;;;;;OAKG;IACG,cAAc,CAClB,KAAK,EAAE,cAAc,EACrB,MAAM,EAAE,MAAM,GAAG,YAAY,EAC7B,SAAS,CAAC,EAAE,MAAM,GAAG,YAAY,GAChC,OAAO,CAAC,MAAM,CAAC,CAEjB;IAMD;;;;;OAKG;IACH,OAAO,CAAC,sBAAsB;CA8E/B"}
|
package/dist/codex-adapter.js
CHANGED
|
@@ -23,10 +23,17 @@
|
|
|
23
23
|
* with fresh state injection. The programmatic O(1) path lives in
|
|
24
24
|
* `fork-trim.ts` (codex app-server thread/fork + thread/rollback).
|
|
25
25
|
*
|
|
26
|
+
* PROJECT-LOCAL / INERT WITHOUT STATE: every generated script resolves the
|
|
27
|
+
* state from the session cwd at runtime and is INERT when the cwd has no
|
|
28
|
+
* skillstate state file — inject hooks emit `{}` (no additionalContext,
|
|
29
|
+
* nothing added as developer context) and `post-tool-use` writes nothing
|
|
30
|
+
* (hooks NEVER create state files). A fresh clone behaves like a vanilla
|
|
31
|
+
* Codex install, so the one global script dir serves every project.
|
|
32
|
+
*
|
|
26
33
|
* @non-paper — no adapters exist in arXiv 2608.26263v3.
|
|
27
34
|
*/
|
|
28
35
|
import * as path from 'node:path';
|
|
29
|
-
import { HISTORY_UNRELIABLE_NOTE, hookRuntimeSnippet, INTERRUPTED_SESSION_NOTE, mergeHookGroups, resolveHostStateForCwd, resolveTarget, saveGenerated,
|
|
36
|
+
import { HISTORY_UNRELIABLE_NOTE, hookRuntimeSnippet, INTERRUPTED_SESSION_NOTE, mergeHookGroups, resolveHostStateForCwd, resolveTarget, saveGenerated, } from '@skillstate/core';
|
|
30
37
|
/** All {@link CodexHookEvent} values in generation order. */
|
|
31
38
|
export const CODEX_HOOK_EVENTS = [
|
|
32
39
|
'user-prompt-submit',
|
|
@@ -139,6 +146,12 @@ export class CodexAdapter {
|
|
|
139
146
|
* and writes the state file (under the built-in cross-process lock);
|
|
140
147
|
* stdout is `{}` or a `systemMessage` when the patch is invalid.
|
|
141
148
|
*
|
|
149
|
+
* INERT WITHOUT STATE: all three scripts resolve the per-project state
|
|
150
|
+
* path first and, when the state FILE does not exist, are no-ops — the
|
|
151
|
+
* inject scripts emit `{}` (no `hookSpecificOutput`, the interrupted-
|
|
152
|
+
* session meta check is skipped since it implies state) and
|
|
153
|
+
* `post-tool-use` writes nothing. Hooks NEVER create state files.
|
|
154
|
+
*
|
|
142
155
|
* AGENT-SCOPED STATE: the hook stdin's `session_id` scopes the state to
|
|
143
156
|
* `<cwd>/.skillstate/agents/<session-prefix>/skillstate.json`, so
|
|
144
157
|
* parallel Codex sessions never last-writer-win over each other.
|
|
@@ -170,6 +183,11 @@ export class CodexAdapter {
|
|
|
170
183
|
* current state JSON read from the SESSION cwd. Brand specifics stay in
|
|
171
184
|
* the adapter (comment lines only); the `contextSuffix` is the shared
|
|
172
185
|
* {@link HISTORY_UNRELIABLE_NOTE} from `@skillstate/core`.
|
|
186
|
+
*
|
|
187
|
+
* INERT WITHOUT STATE: after resolving `statePath` the script emits `{}`
|
|
188
|
+
* (no `hookSpecificOutput`, nothing added as developer context) when the
|
|
189
|
+
* state FILE does not exist — the interrupted-session meta check is
|
|
190
|
+
* skipped too, since a session-meta sidecar implies state.
|
|
173
191
|
*/
|
|
174
192
|
buildInjectScriptTemplate(options) {
|
|
175
193
|
// SessionStart is a real session boundary: when the session-meta
|
|
@@ -177,7 +195,8 @@ export class CodexAdapter {
|
|
|
177
195
|
// this session was killed before it could finalize), the hook appends
|
|
178
196
|
// the shared INTERRUPTED_SESSION_NOTE — with the preserved state path
|
|
179
197
|
// substituted — so the model reviews progress/blockers first. A fresh
|
|
180
|
-
// MCP launch overwrites the status back to `running`.
|
|
198
|
+
// MCP launch overwrites the status back to `running`. The check only
|
|
199
|
+
// runs when state exists (no state → inert, no sidecar read).
|
|
181
200
|
const interruptedCheck = options.hookEventName === 'SessionStart';
|
|
182
201
|
return [
|
|
183
202
|
'#!/usr/bin/env node',
|
|
@@ -185,6 +204,8 @@ export class CodexAdapter {
|
|
|
185
204
|
'// Self-contained CommonJS: reads one hook JSON document on stdin,',
|
|
186
205
|
'// resolves the state from the SESSION cwd, and emits',
|
|
187
206
|
'// { hookSpecificOutput: { hookEventName, additionalContext } }.',
|
|
207
|
+
'// INERT without state: no state file → stdout is "{}" (no context',
|
|
208
|
+
'// is added; hooks never create state files).',
|
|
188
209
|
options.header,
|
|
189
210
|
"'use strict';",
|
|
190
211
|
'const fs = require("fs");',
|
|
@@ -214,6 +235,10 @@ export class CodexAdapter {
|
|
|
214
235
|
' path.resolve(os.homedir()),',
|
|
215
236
|
' agentId,',
|
|
216
237
|
' );',
|
|
238
|
+
' if (!stateFileExists(statePath, fs)) {',
|
|
239
|
+
' process.stdout.write("{}");',
|
|
240
|
+
' return;',
|
|
241
|
+
' }',
|
|
217
242
|
' const state = readStateEnvelope(statePath, (p) => fs.readFileSync(p, "utf-8"));',
|
|
218
243
|
' let contextSuffix = ' + JSON.stringify(options.contextSuffix) + ';',
|
|
219
244
|
...(interruptedCheck
|
|
@@ -241,23 +266,6 @@ export class CodexAdapter {
|
|
|
241
266
|
'',
|
|
242
267
|
].join('\n');
|
|
243
268
|
}
|
|
244
|
-
/**
|
|
245
|
-
* Generate a SKILL.md for Codex's skill directory
|
|
246
|
-
* (`~/.codex/skills/<name>/SKILL.md`). The body instructs the agent to
|
|
247
|
-
* treat the hook-injected state as authoritative (history is not
|
|
248
|
-
* reliable), to orient via `state.summary` (full dump via `state.get`),
|
|
249
|
-
* and to persist via `state.patch` — the PostToolUse hook also merges any
|
|
250
|
-
* fenced ```json `state_patch` block printed by a Bash tool call.
|
|
251
|
-
*/
|
|
252
|
-
generateSkillMd(spec, statePath) {
|
|
253
|
-
return skillMdBody({
|
|
254
|
-
hostLabel: 'Codex',
|
|
255
|
-
injectionPhrase: 'provided as developer context',
|
|
256
|
-
hooks: { inject: 'UserPromptSubmit', reInject: 'SessionStart', patchHook: 'PostToolUse' },
|
|
257
|
-
spec,
|
|
258
|
-
statePath,
|
|
259
|
-
});
|
|
260
|
-
}
|
|
261
269
|
/**
|
|
262
270
|
* Generate the hooks.json document and persist it via the shared
|
|
263
271
|
* `saveGenerated`. Both the destination and the embedded state path
|
|
@@ -297,17 +305,15 @@ export class CodexAdapter {
|
|
|
297
305
|
async saveHookScript(event, target, statePath) {
|
|
298
306
|
return saveGenerated(target, this.generateHookScript(event, statePath));
|
|
299
307
|
}
|
|
300
|
-
/**
|
|
301
|
-
* Generate a SKILL.md and persist it via the shared `saveGenerated`.
|
|
302
|
-
* Returns the absolute destination path.
|
|
303
|
-
*/
|
|
304
|
-
async saveSkillMd(target, spec, statePath) {
|
|
305
|
-
return saveGenerated(target, this.generateSkillMd(spec, statePath));
|
|
306
|
-
}
|
|
307
308
|
/* ------------------------------------------------------------------ */
|
|
308
309
|
/* Internal helpers */
|
|
309
310
|
/* ------------------------------------------------------------------ */
|
|
310
|
-
/**
|
|
311
|
+
/**
|
|
312
|
+
* PostToolUse script: extract state_patch, ⊕ merge, persist.
|
|
313
|
+
*
|
|
314
|
+
* INERT WITHOUT STATE: when the state file does not exist the hook
|
|
315
|
+
* writes nothing and emits `{}` — hooks NEVER create state files.
|
|
316
|
+
*/
|
|
311
317
|
buildPostToolUseScript(header) {
|
|
312
318
|
const fence = '```';
|
|
313
319
|
return [
|
|
@@ -317,6 +323,8 @@ export class CodexAdapter {
|
|
|
317
323
|
'// extracts state_patch from the tool_response (fenced ```json block or',
|
|
318
324
|
'// raw JSON), applies the null-deletion merge and writes the state file.',
|
|
319
325
|
'// stdout is "{}" or a systemMessage when the patch is invalid.',
|
|
326
|
+
'// INERT without state: no state file → stdout is "{}", nothing is',
|
|
327
|
+
'// written (hooks never create state files).',
|
|
320
328
|
header,
|
|
321
329
|
"'use strict';",
|
|
322
330
|
'const fs = require("fs");',
|
|
@@ -343,6 +351,10 @@ export class CodexAdapter {
|
|
|
343
351
|
' path.resolve(os.homedir()),',
|
|
344
352
|
' resolveAgentIdFromSession(input.session_id),',
|
|
345
353
|
' );',
|
|
354
|
+
' if (!stateFileExists(statePath, fs)) {',
|
|
355
|
+
' process.stdout.write(JSON.stringify(output));',
|
|
356
|
+
' return;',
|
|
357
|
+
' }',
|
|
346
358
|
' const response = input.tool_response;',
|
|
347
359
|
' let result;',
|
|
348
360
|
' if (isPlainObject(response) && isPlainObject(response.state_patch)) {',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"codex-adapter.js","sourceRoot":"","sources":["../src/codex-adapter.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"codex-adapter.js","sourceRoot":"","sources":["../src/codex-adapter.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@skillstate/codex",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.0",
|
|
4
4
|
"description": "OpenAI Codex platform adapter for the skillstate runtime.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -21,6 +21,6 @@
|
|
|
21
21
|
},
|
|
22
22
|
"license": "MIT",
|
|
23
23
|
"dependencies": {
|
|
24
|
-
"@skillstate/core": "^
|
|
24
|
+
"@skillstate/core": "^3.0.0"
|
|
25
25
|
}
|
|
26
26
|
}
|