@skillstate/opencode 2.0.7 → 2.2.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.
@@ -79,9 +79,5 @@ export declare class OpenCodeAdapter implements PlatformAdapter {
79
79
  * Returns the absolute destination path.
80
80
  */
81
81
  savePluginCode(target: string | StatePathRef, options?: GeneratePluginOptions): Promise<string>;
82
- /**
83
- * Describe the schema fields for inclusion in prompts.
84
- */
85
- private describeSchema;
86
82
  }
87
83
  //# sourceMappingURL=opencode-adapter.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"opencode-adapter.d.ts","sourceRoot":"","sources":["../src/opencode-adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,KAAK,EACV,UAAU,EACV,UAAU,EACV,cAAc,EACd,WAAW,EACX,eAAe,EAChB,MAAM,kBAAkB,CAAC;AAM1B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAErD,8DAA8D;AAC9D,MAAM,WAAW,qBAAqB;IACpC,0DAA0D;IAC1D,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED;;GAEG;AACH,qBAAa,eAAgB,YAAW,eAAe;IACrD,QAAQ,CAAC,IAAI,cAAc;IAE3B,OAAO,CAAC,WAAW,CAAmD;IAEtE;;;;OAIG;IACH,WAAW,CAAC,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,cAAc,GAAG,MAAM,CAsB3D;IAED;;OAEG;IACH,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI,CAEhD;IAED;;OAEG;IACH,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAE7C;IAED;;;;;OAKG;IACH,YAAY,CACV,KAAK,EAAE,UAAU,EACjB,WAAW,EAAE,WAAW,EACxB,IAAI,EAAE,cAAc,GACnB,MAAM,CAER;IAED;;;;;;;OAOG;IACH,eAAe,CAAC,IAAI,EAAE,cAAc,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CA0ChE;IAED;;;;;;;;;;;;;;;OAeG;IACH,kBAAkB,CAAC,OAAO,CAAC,EAAE,qBAAqB,GAAG,MAAM,CAa1D;IAED;;;;;OAKG;IACG,cAAc,CAClB,MAAM,EAAE,MAAM,GAAG,YAAY,EAC7B,OAAO,CAAC,EAAE,qBAAqB,GAC9B,OAAO,CAAC,MAAM,CAAC,CAOjB;IAMD;;OAEG;IACH,OAAO,CAAC,cAAc;CASvB"}
1
+ {"version":3,"file":"opencode-adapter.d.ts","sourceRoot":"","sources":["../src/opencode-adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,KAAK,EACV,UAAU,EACV,UAAU,EACV,cAAc,EACd,WAAW,EACX,eAAe,EAChB,MAAM,kBAAkB,CAAC;AAW1B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAErD,8DAA8D;AAC9D,MAAM,WAAW,qBAAqB;IACpC,0DAA0D;IAC1D,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED;;GAEG;AACH,qBAAa,eAAgB,YAAW,eAAe;IACrD,QAAQ,CAAC,IAAI,cAAc;IAE3B,OAAO,CAAC,WAAW,CAAmD;IAEtE;;;;OAIG;IACH,WAAW,CAAC,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,cAAc,GAAG,MAAM,CAe3D;IAED;;OAEG;IACH,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI,CAEhD;IAED;;OAEG;IACH,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAE7C;IAED;;;;;OAKG;IACH,YAAY,CACV,KAAK,EAAE,UAAU,EACjB,WAAW,EAAE,WAAW,EACxB,IAAI,EAAE,cAAc,GACnB,MAAM,CAER;IAED;;;;;;;OAOG;IACH,eAAe,CAAC,IAAI,EAAE,cAAc,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAkChE;IAED;;;;;;;;;;;;;;;OAeG;IACH,kBAAkB,CAAC,OAAO,CAAC,EAAE,qBAAqB,GAAG,MAAM,CAa1D;IAED;;;;;OAKG;IACG,cAAc,CAClB,MAAM,EAAE,MAAM,GAAG,YAAY,EAC7B,OAAO,CAAC,EAAE,qBAAqB,GAC9B,OAAO,CAAC,MAAM,CAAC,CAOjB;CAKF"}
@@ -1,5 +1,5 @@
1
1
  import { PromptTransformer } from '@skillstate/core';
2
- import { atomicWriteFile, resolveStatePath, } from '@skillstate/core';
2
+ import { atomicWriteFile, describeSchema, REASONING_DISCARDED_NOTE, resolveStatePath, STATE_PATCH_CONTRACT, } from '@skillstate/core';
3
3
  /**
4
4
  * OpenCode platform adapter (@non-paper; see module doc).
5
5
  */
@@ -13,7 +13,7 @@ export class OpenCodeAdapter {
13
13
  */
14
14
  injectState(state, spec) {
15
15
  const stateJson = JSON.stringify(state);
16
- const schemaDesc = this.describeSchema(spec.schema);
16
+ const schemaDesc = describeSchema(spec.schema);
17
17
  return `<skill name="${spec.id}">
18
18
  <instructions>${spec.instructions}</instructions>
19
19
  ${schemaDesc}
@@ -22,16 +22,9 @@ ${stateJson}
22
22
  </state>
23
23
  </skill>
24
24
 
25
- Respond with step-by-step reasoning followed by a JSON block containing both your State Patch and your Action. The JSON block MUST have exactly these two keys:
25
+ Respond with:
26
26
 
27
- \`\`\`json
28
- {
29
- "state_patch": { "key": "new_value", "obsolete_key": null },
30
- "action": "your_action_here"
31
- }
32
- \`\`\`
33
-
34
- In \`state_patch\`, set keys to null to delete them. Only include fields you want to change. Omit fields to leave them unchanged.`;
27
+ ${STATE_PATCH_CONTRACT}`;
35
28
  }
36
29
  /**
37
30
  * Extract the state_patch from an LLM response containing a fenced JSON block.
@@ -89,20 +82,12 @@ plugin; only the current state and the latest observation matter.
89
82
  1. Read the current state from the state file.
90
83
  2. Observe the result of your last action.
91
84
  3. Reason about what to do next, given the state and the observation.
92
- 4. Respond with a JSON block containing both your State Patch and your Action. The JSON block MUST have exactly these two keys:
85
+ 4. Respond with:
93
86
 
94
- \`\`\`json
95
- {
96
- "state_patch": { "key": "new_value", "obsolete_key": null },
97
- "action": "next_action_name"
98
- }
99
- \`\`\`
87
+ ${STATE_PATCH_CONTRACT}
100
88
 
101
- - In \`state_patch\`, set keys to null to delete them. Only include fields you
102
- want to change. Omit fields to leave them unchanged.
103
89
  - \`action\` names what you will do next (e.g. "continue", "done").
104
- - Reasoning is discarded after execution — put anything you need to persist
105
- into \`state_patch\`.`;
90
+ - ${REASONING_DISCARDED_NOTE}`;
106
91
  }
107
92
  /**
108
93
  * Generate an OpenCode plugin file.
@@ -147,17 +132,5 @@ export default createSkillStatePlugin({
147
132
  await atomicWriteFile(dest, this.generatePluginCode(options));
148
133
  return dest;
149
134
  }
150
- /* ------------------------------------------------------------------ */
151
- /* Internal helpers */
152
- /* ------------------------------------------------------------------ */
153
- /**
154
- * Describe the schema fields for inclusion in prompts.
155
- */
156
- describeSchema(schema) {
157
- const fields = Object.entries(schema)
158
- .map(([name, field]) => `- ${name} (${field.type}): ${field.description ?? 'no description'}`)
159
- .join('\n');
160
- return `## Schema\n${fields}`;
161
- }
162
135
  }
163
136
  //# sourceMappingURL=opencode-adapter.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"opencode-adapter.js","sourceRoot":"","sources":["../src/opencode-adapter.ts"],"names":[],"mappings":"AAqBA,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EACL,eAAe,EACf,gBAAgB,GACjB,MAAM,kBAAkB,CAAC;AAS1B;;GAEG;AACH,MAAM,OAAO,eAAe;IACjB,IAAI,GAAG,UAAU,CAAC;IAEnB,WAAW,GAAG,IAAI,iBAAiB,CAAC,EAAE,QAAQ,EAAE,UAAU,EAAE,CAAC,CAAC;IAEtE;;;;OAIG;IACH,WAAW,CAAC,KAAiB,EAAE,IAAoB;QACjD,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QACxC,MAAM,UAAU,GAAG,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAEpD,OAAO,gBAAgB,IAAI,CAAC,EAAE;gBAClB,IAAI,CAAC,YAAY;EAC/B,UAAU;;EAEV,SAAS;;;;;;;;;;;;;kIAauH,CAAC;IACjI,CAAC;IAED;;OAEG;IACH,YAAY,CAAC,QAAgB;QAC3B,OAAO,IAAI,CAAC,WAAW,CAAC,iBAAiB,CAAC,QAAQ,CAAC,CAAC;IACtD,CAAC;IAED;;OAEG;IACH,aAAa,CAAC,QAAgB;QAC5B,OAAO,IAAI,CAAC,WAAW,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;IAClD,CAAC;IAED;;;;;OAKG;IACH,YAAY,CACV,KAAiB,EACjB,WAAwB,EACxB,IAAoB;QAEpB,OAAO,IAAI,CAAC,WAAW,CAAC,iBAAiB,CAAC,IAAI,EAAE,KAAK,EAAE,WAAW,CAAC,CAAC;IACtE,CAAC;IAED;;;;;;;OAOG;IACH,eAAe,CAAC,IAAoB,EAAE,SAAkB;QACtD,MAAM,iBAAiB,GAAG,SAAS,IAAI,oBAAoB,CAAC;QAE5D,OAAO;QACH,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC;eAClB,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,YAAY,CAAC;WACrC,IAAI,CAAC,OAAO;;gBAEP,iBAAiB;;;;IAI7B,IAAI,CAAC,IAAI;;EAEX,IAAI,CAAC,YAAY;;;;yCAIsB,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;wBAuBlC,CAAC;IACvB,CAAC;IAED;;;;;;;;;;;;;;;OAeG;IACH,kBAAkB,CAAC,OAA+B;QAChD,MAAM,UAAU,GAAG,OAAO,EAAE,kBAAkB,IAAI,CAAC,CAAC;QACpD,OAAO;;;;;;;;wBAQa,UAAU;;CAEjC,CAAC;IACA,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,cAAc,CAClB,MAA6B,EAC7B,OAA+B;QAE/B,MAAM,IAAI,GACR,OAAO,MAAM,KAAK,QAAQ;YACxB,CAAC,CAAC,MAAM;YACR,CAAC,CAAC,gBAAgB,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;QACjD,MAAM,eAAe,CAAC,IAAI,EAAE,IAAI,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC,CAAC;QAC9D,OAAO,IAAI,CAAC;IACd,CAAC;IAED,wEAAwE;IACxE,yEAAyE;IACzE,wEAAwE;IAExE;;OAEG;IACK,cAAc,CAAC,MAAgC;QACrD,MAAM,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC;aAClC,GAAG,CACF,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,EAAE,CAChB,KAAK,IAAI,KAAK,KAAK,CAAC,IAAI,MAAM,KAAK,CAAC,WAAW,IAAI,gBAAgB,EAAE,CACxE;aACA,IAAI,CAAC,IAAI,CAAC,CAAC;QACd,OAAO,cAAc,MAAM,EAAE,CAAC;IAChC,CAAC;CACF"}
1
+ {"version":3,"file":"opencode-adapter.js","sourceRoot":"","sources":["../src/opencode-adapter.ts"],"names":[],"mappings":"AAqBA,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EACL,eAAe,EACf,cAAc,EACd,wBAAwB,EACxB,gBAAgB,EAChB,oBAAoB,GAGrB,MAAM,kBAAkB,CAAC;AAS1B;;GAEG;AACH,MAAM,OAAO,eAAe;IACjB,IAAI,GAAG,UAAU,CAAC;IAEnB,WAAW,GAAG,IAAI,iBAAiB,CAAC,EAAE,QAAQ,EAAE,UAAU,EAAE,CAAC,CAAC;IAEtE;;;;OAIG;IACH,WAAW,CAAC,KAAiB,EAAE,IAAoB;QACjD,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QACxC,MAAM,UAAU,GAAG,cAAc,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAE/C,OAAO,gBAAgB,IAAI,CAAC,EAAE;gBAClB,IAAI,CAAC,YAAY;EAC/B,UAAU;;EAEV,SAAS;;;;;;EAMT,oBAAoB,EAAE,CAAC;IACvB,CAAC;IAED;;OAEG;IACH,YAAY,CAAC,QAAgB;QAC3B,OAAO,IAAI,CAAC,WAAW,CAAC,iBAAiB,CAAC,QAAQ,CAAC,CAAC;IACtD,CAAC;IAED;;OAEG;IACH,aAAa,CAAC,QAAgB;QAC5B,OAAO,IAAI,CAAC,WAAW,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;IAClD,CAAC;IAED;;;;;OAKG;IACH,YAAY,CACV,KAAiB,EACjB,WAAwB,EACxB,IAAoB;QAEpB,OAAO,IAAI,CAAC,WAAW,CAAC,iBAAiB,CAAC,IAAI,EAAE,KAAK,EAAE,WAAW,CAAC,CAAC;IACtE,CAAC;IAED;;;;;;;OAOG;IACH,eAAe,CAAC,IAAoB,EAAE,SAAkB;QACtD,MAAM,iBAAiB,GAAG,SAAS,IAAI,oBAAoB,CAAC;QAE5D,OAAO;QACH,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC;eAClB,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,YAAY,CAAC;WACrC,IAAI,CAAC,OAAO;;gBAEP,iBAAiB;;;;IAI7B,IAAI,CAAC,IAAI;;EAEX,IAAI,CAAC,YAAY;;;;yCAIsB,iBAAiB;;;;;;;;;;;;EAYxD,oBAAoB;;;IAGlB,wBAAwB,EAAE,CAAC;IAC7B,CAAC;IAED;;;;;;;;;;;;;;;OAeG;IACH,kBAAkB,CAAC,OAA+B;QAChD,MAAM,UAAU,GAAG,OAAO,EAAE,kBAAkB,IAAI,CAAC,CAAC;QACpD,OAAO;;;;;;;;wBAQa,UAAU;;CAEjC,CAAC;IACA,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,cAAc,CAClB,MAA6B,EAC7B,OAA+B;QAE/B,MAAM,IAAI,GACR,OAAO,MAAM,KAAK,QAAQ;YACxB,CAAC,CAAC,MAAM;YACR,CAAC,CAAC,gBAAgB,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;QACjD,MAAM,eAAe,CAAC,IAAI,EAAE,IAAI,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC,CAAC;QAC9D,OAAO,IAAI,CAAC;IACd,CAAC;CAKF"}
package/dist/plugin.d.ts CHANGED
@@ -1,61 +1,77 @@
1
- import type { SkillStatePlugin } from './plugin-types.js';
1
+ import { mergePatch, resolveHostStateForCwd } from '@skillstate/core';
2
+ import type { OpenCodeMessage, SkillStatePlugin } from './plugin-types.js';
2
3
  export * from './plugin-types.js';
4
+ /**
5
+ * Resolve the per-project state file for a session working directory
6
+ * (`cwd` of the current opencode session) — the core single source of
7
+ * truth (`resolveHostStateForCwd`): `<cwd>/.skillstate/skillstate.json`,
8
+ * or the global bucket `<home>/.skillstate/global/skillstate.json` when
9
+ * cwd equals home. A non-empty `agentId` scopes the file under
10
+ * `<bucket>/agents/<agentId>/skillstate.json`. Pure path arithmetic via
11
+ * `path.resolve`, no filesystem access.
12
+ */
13
+ export { resolveHostStateForCwd as resolveStatePathForCwd };
14
+ export { mergePatch };
15
+ /** Agent scope used by the plugin when no session id is available. */
16
+ export declare const PLUGIN_DEFAULT_AGENT_ID = "default";
3
17
  /** Options for {@link createSkillStatePlugin}. */
4
18
  export interface SkillStatePluginOptions {
5
19
  /** Non-system messages kept in the prompt (default 3). */
6
20
  maxHistoryMessages?: number;
7
21
  }
8
- /**
9
- * Resolve the per-project state file for a session working directory
10
- * (`cwd` of the current opencode session):
11
- *
12
- * - `cwd === home` — a session launched straight from `$HOME` has no single
13
- * project, so state goes to the global bucket
14
- * `<home>/.skillstate/global/skillstate.json`;
15
- * - any other cwd (including subdirectories of `$HOME`) — the state lives in
16
- * the project: `<cwd>/.skillstate/skillstate.json`.
17
- *
18
- * Pure path arithmetic: both arguments are normalized via `path.resolve`
19
- * before comparison, and there is NO filesystem access. The same project
20
- * directory therefore always maps to the same state file no matter where
21
- * the host was launched from, while different projects never share state.
22
- * Zero-dep by design (node builtins only) so generated plugins and the MCP
23
- * server can inline the same semantics. Keep any copy in sync.
24
- */
25
- export declare function resolveStatePathForCwd(cwd: string, home: string): string;
26
22
  /**
27
23
  * Read the state file. Missing or corrupt files yield `{}` (best-effort).
28
24
  * The on-disk envelope is `{ version: 1, state }` (migrations-compatible);
29
- * a bare object is tolerated and treated as the state itself.
25
+ * a bare object is tolerated and treated as the state itself. Thin fs
26
+ * adapter over the core hook-runtime {@link readStateEnvelope}.
30
27
  */
31
28
  export declare function readSkillState(statePath: string): Record<string, unknown>;
32
29
  /**
33
30
  * Persist the state file (best-effort: read-only environments are ignored).
34
31
  * Creates the parent directory when missing (the per-project resolver may
35
- * target a fresh `<cwd>/.skillstate/`). Writes the `{ version: 1, state }`
36
- * envelope so `migrate()`/runtime resume read the same file.
32
+ * target a fresh `<cwd>/.skillstate/agents/<id>/`). Writes the
33
+ * `{ version: 1, state }` envelope so `migrate()`/runtime resume read the
34
+ * same file — via the core hook-runtime {@link saveStateEnvelope} — under
35
+ * the cross-process sync lock {@link lockStateWrite} (2-3 parallel agent
36
+ * processes never interleave state writes).
37
37
  */
38
38
  export declare function saveSkillState(statePath: string, state: Record<string, unknown>): void;
39
39
  /**
40
- * Paper ⊕ merge: `null` deletes a key, nested plain objects merge
41
- * recursively, everything else replaces.
40
+ * Atomic READ-MERGE-WRITE of one `state_patch` (paper ⊕: null deletes):
41
+ * the whole critical section runs inside {@link lockStateWrite}, so two
42
+ * concurrent writers apply BOTH patches instead of racing between the
43
+ * read and the write. Best-effort: lock contention or unwritable state
44
+ * files are swallowed — the tool flow never breaks.
42
45
  */
43
- export declare function mergePatch(base: Record<string, unknown>, patch: Record<string, unknown>): Record<string, unknown>;
46
+ export declare function mergeSkillState(statePath: string, patch: Record<string, unknown>): Record<string, unknown>;
44
47
  /**
45
48
  * Extract the `state_patch` object from an LLM response's fenced ```json
46
49
  * block; `null` when there is no block, it is malformed, or it carries no
47
- * object-shaped `state_patch`.
50
+ * object-shaped `state_patch`. Thin adapter over the core hook-runtime
51
+ * {@link findFencedPatch} (the invalid/truncated outcomes collapse to
52
+ * `null`, preserving the legacy boolean contract).
48
53
  */
49
54
  export declare function extractPatch(response: string): Record<string, unknown> | null;
55
+ /**
56
+ * Agent id for an opencode hook call: the 8-char session prefix from
57
+ * `input.sessionID` when the hook carries it, else the first non-synthetic
58
+ * message's `info.sessionID` (the transform hook input is empty — the
59
+ * session lives on the message envelopes), else `'default'` (the plugin
60
+ * trims the history of one session context).
61
+ */
62
+ export declare function pluginAgentId(input: {
63
+ sessionID?: unknown;
64
+ }, messages?: OpenCodeMessage[]): string;
50
65
  /**
51
66
  * Build the OpenCode plugin function with the same behavior for every host
52
67
  * entry point (thin generated loaders, direct imports).
53
68
  *
54
69
  * State resolution is ALWAYS per-project: the state file path is computed
55
70
  * from the session cwd on EVERY hook call via
56
- * `resolveStatePathForCwd(process.cwd(), os.homedir())` — each project gets
57
- * its own `<cwd>/.skillstate/skillstate.json`, and a session launched from
58
- * `$HOME` uses the global bucket.
71
+ * `resolveStatePathForCwd(process.cwd(), os.homedir(), agentId)` — each
72
+ * project gets its own `<cwd>/.skillstate/`, each session (sub-agent) its
73
+ * isolated `agents/<session>/` copy, and a session launched from `$HOME`
74
+ * uses the global bucket.
59
75
  */
60
76
  export declare function createSkillStatePlugin(options?: SkillStatePluginOptions): SkillStatePlugin;
61
77
  //# sourceMappingURL=plugin.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EAGV,gBAAgB,EACjB,MAAM,mBAAmB,CAAC;AAE3B,cAAc,mBAAmB,CAAC;AAElC,kDAAkD;AAClD,MAAM,WAAW,uBAAuB;IACtC,0DAA0D;IAC1D,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAOxE;AAOD;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAqBzE;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAOtF;AAED;;;GAGG;AACH,wBAAgB,UAAU,CACxB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC7B,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAazB;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAY7E;AAKD;;;;;;;;;GASG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,GAAE,uBAA4B,GAAG,gBAAgB,CAgF9F"}
1
+ {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AA+BA,OAAO,EAGL,UAAU,EAGV,sBAAsB,EAEvB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EACV,eAAe,EAEf,gBAAgB,EACjB,MAAM,mBAAmB,CAAC;AAE3B,cAAc,mBAAmB,CAAC;AAElC;;;;;;;;GAQG;AACH,OAAO,EAAE,sBAAsB,IAAI,sBAAsB,EAAE,CAAC;AAE5D,OAAO,EAAE,UAAU,EAAE,CAAC;AAEtB,sEAAsE;AACtE,eAAO,MAAM,uBAAuB,YAAY,CAAC;AAEjD,kDAAkD;AAClD,MAAM,WAAW,uBAAuB;IACtC,0DAA0D;IAC1D,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAEzE;AAED;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAWtF;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAC7B,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC7B,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAYzB;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAG7E;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAC3B,KAAK,EAAE;IAAE,SAAS,CAAC,EAAE,OAAO,CAAA;CAAE,EAC9B,QAAQ,CAAC,EAAE,eAAe,EAAE,GAC3B,MAAM,CAWR;AAKD;;;;;;;;;;GAUG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,GAAE,uBAA4B,GAAG,gBAAgB,CAiF9F"}
package/dist/plugin.js CHANGED
@@ -2,7 +2,10 @@
2
2
  * Static OpenCode plugin — the SINGLE SOURCE OF TRUTH for the skillstate
3
3
  * host integration. `OpenCodeAdapter.generatePluginCode` emits a thin loader
4
4
  * that imports `createSkillStatePlugin` from this module; the per-project
5
- * state resolution lives inside the plugin itself.
5
+ * state resolution lives in `@skillstate/core`
6
+ * (`resolveHostStateForCwd`, re-exported here) and the hook logic
7
+ * (envelope read/write, ⊕ merge, patch extraction) in the core
8
+ * hook-runtime — this module only adapts it to the OpenCode hooks.
6
9
  *
7
10
  * Hooks (opencode 1.17 contract, verified on host):
8
11
  * - `experimental.chat.messages.transform` — entries are `{ info, parts }`
@@ -13,120 +16,109 @@
13
16
  * `output.context` so the compaction summary preserves it.
14
17
  * - `tool.execute.after` — the tool response is `output.output`; a fenced
15
18
  * ```json `state_patch` block is merged (paper ⊕: null deletes) and saved.
19
+ *
20
+ * AGENT-SCOPED STATE: the opencode hook inputs carry the session id
21
+ * (`input.sessionID`; message envelopes carry `info.sessionID`), so every
22
+ * hook scopes the state file to `<cwd>/.skillstate/agents/<session>/` —
23
+ * parallel opencode sessions (sub-agents) never last-writer-win over the
24
+ * main state. When no session id is available the `'default'` agent is
25
+ * used (the plugin trims the history of one session context). Writes go
26
+ * through the core cross-process sync lock (`lockStateWrite`) so a
27
+ * session state file is never interleaved between processes.
16
28
  */
17
29
  import * as fs from 'node:fs';
18
30
  import * as os from 'node:os';
19
31
  import * as path from 'node:path';
32
+ import { findFencedPatch, lockStateWrite, mergePatch, readStateEnvelope, resolveAgentIdFromSession, resolveHostStateForCwd, saveStateEnvelope, } from '@skillstate/core';
20
33
  export * from './plugin-types.js';
21
34
  /**
22
35
  * Resolve the per-project state file for a session working directory
23
- * (`cwd` of the current opencode session):
24
- *
25
- * - `cwd === home` — a session launched straight from `$HOME` has no single
26
- * project, so state goes to the global bucket
27
- * `<home>/.skillstate/global/skillstate.json`;
28
- * - any other cwd (including subdirectories of `$HOME`) — the state lives in
29
- * the project: `<cwd>/.skillstate/skillstate.json`.
30
- *
31
- * Pure path arithmetic: both arguments are normalized via `path.resolve`
32
- * before comparison, and there is NO filesystem access. The same project
33
- * directory therefore always maps to the same state file no matter where
34
- * the host was launched from, while different projects never share state.
35
- * Zero-dep by design (node builtins only) so generated plugins and the MCP
36
- * server can inline the same semantics. Keep any copy in sync.
36
+ * (`cwd` of the current opencode session) — the core single source of
37
+ * truth (`resolveHostStateForCwd`): `<cwd>/.skillstate/skillstate.json`,
38
+ * or the global bucket `<home>/.skillstate/global/skillstate.json` when
39
+ * cwd equals home. A non-empty `agentId` scopes the file under
40
+ * `<bucket>/agents/<agentId>/skillstate.json`. Pure path arithmetic via
41
+ * `path.resolve`, no filesystem access.
37
42
  */
38
- export function resolveStatePathForCwd(cwd, home) {
39
- const resolvedCwd = path.resolve(cwd);
40
- const resolvedHome = path.resolve(home);
41
- if (resolvedCwd === resolvedHome) {
42
- return path.join(resolvedHome, '.skillstate', 'global', 'skillstate.json');
43
- }
44
- return path.join(resolvedCwd, '.skillstate', 'skillstate.json');
45
- }
46
- /** True for plain (non-null, non-array) objects. */
47
- function isPlainObject(value) {
48
- return typeof value === 'object' && value !== null && !Array.isArray(value);
49
- }
43
+ export { resolveHostStateForCwd as resolveStatePathForCwd };
44
+ export { mergePatch };
45
+ /** Agent scope used by the plugin when no session id is available. */
46
+ export const PLUGIN_DEFAULT_AGENT_ID = 'default';
50
47
  /**
51
48
  * Read the state file. Missing or corrupt files yield `{}` (best-effort).
52
49
  * The on-disk envelope is `{ version: 1, state }` (migrations-compatible);
53
- * a bare object is tolerated and treated as the state itself.
50
+ * a bare object is tolerated and treated as the state itself. Thin fs
51
+ * adapter over the core hook-runtime {@link readStateEnvelope}.
54
52
  */
55
53
  export function readSkillState(statePath) {
56
- try {
57
- if (fs.existsSync(statePath)) {
58
- const parsed = JSON.parse(fs.readFileSync(statePath, 'utf-8'));
59
- if (typeof parsed === 'object' &&
60
- parsed !== null &&
61
- 'state' in parsed &&
62
- typeof parsed['state'] === 'object' &&
63
- parsed['state'] !== null) {
64
- return parsed['state'];
65
- }
66
- if (typeof parsed === 'object' && parsed !== null) {
67
- return parsed;
68
- }
69
- }
70
- }
71
- catch {
72
- // Corrupt or unreadable state file — fall back to empty state.
73
- }
74
- return {};
54
+ return readStateEnvelope(statePath, (p) => fs.readFileSync(p, 'utf-8'));
75
55
  }
76
56
  /**
77
57
  * Persist the state file (best-effort: read-only environments are ignored).
78
58
  * Creates the parent directory when missing (the per-project resolver may
79
- * target a fresh `<cwd>/.skillstate/`). Writes the `{ version: 1, state }`
80
- * envelope so `migrate()`/runtime resume read the same file.
59
+ * target a fresh `<cwd>/.skillstate/agents/<id>/`). Writes the
60
+ * `{ version: 1, state }` envelope so `migrate()`/runtime resume read the
61
+ * same file — via the core hook-runtime {@link saveStateEnvelope} — under
62
+ * the cross-process sync lock {@link lockStateWrite} (2-3 parallel agent
63
+ * processes never interleave state writes).
81
64
  */
82
65
  export function saveSkillState(statePath, state) {
83
66
  try {
84
67
  fs.mkdirSync(path.dirname(statePath), { recursive: true });
85
- fs.writeFileSync(statePath, `${JSON.stringify({ version: 1, state }, null, 2)}\n`);
68
+ lockStateWrite(statePath, fs, () => saveStateEnvelope(statePath, state, (p, data) => fs.writeFileSync(p, data)));
86
69
  }
87
70
  catch {
88
71
  // Best-effort: read-only environments or permission issues.
89
72
  }
90
73
  }
91
74
  /**
92
- * Paper ⊕ merge: `null` deletes a key, nested plain objects merge
93
- * recursively, everything else replaces.
75
+ * Atomic READ-MERGE-WRITE of one `state_patch` (paper ⊕: null deletes):
76
+ * the whole critical section runs inside {@link lockStateWrite}, so two
77
+ * concurrent writers apply BOTH patches instead of racing between the
78
+ * read and the write. Best-effort: lock contention or unwritable state
79
+ * files are swallowed — the tool flow never breaks.
94
80
  */
95
- export function mergePatch(base, patch) {
96
- const result = { ...base };
97
- for (const key of Object.keys(patch)) {
98
- const value = patch[key];
99
- if (value === null) {
100
- delete result[key];
101
- }
102
- else if (isPlainObject(value) && isPlainObject(result[key])) {
103
- result[key] = mergePatch(result[key], value);
104
- }
105
- else {
106
- result[key] = value;
107
- }
81
+ export function mergeSkillState(statePath, patch) {
82
+ try {
83
+ fs.mkdirSync(path.dirname(statePath), { recursive: true });
84
+ let merged = {};
85
+ lockStateWrite(statePath, fs, () => {
86
+ merged = mergePatch(readSkillState(statePath), patch);
87
+ saveStateEnvelope(statePath, merged, (p, data) => fs.writeFileSync(p, data));
88
+ });
89
+ return merged;
90
+ }
91
+ catch {
92
+ return readSkillState(statePath);
108
93
  }
109
- return result;
110
94
  }
111
95
  /**
112
96
  * Extract the `state_patch` object from an LLM response's fenced ```json
113
97
  * block; `null` when there is no block, it is malformed, or it carries no
114
- * object-shaped `state_patch`.
98
+ * object-shaped `state_patch`. Thin adapter over the core hook-runtime
99
+ * {@link findFencedPatch} (the invalid/truncated outcomes collapse to
100
+ * `null`, preserving the legacy boolean contract).
115
101
  */
116
102
  export function extractPatch(response) {
117
- const match = response.match(/```json\s*\n?([\s\S]*?)\n?\s*```/);
118
- if (!match)
119
- return null;
120
- try {
121
- const parsed = JSON.parse(match[1]);
122
- if (isPlainObject(parsed) && isPlainObject(parsed['state_patch'])) {
123
- return parsed['state_patch'];
124
- }
125
- }
126
- catch {
127
- // Malformed JSON — ignore.
128
- }
129
- return null;
103
+ const result = findFencedPatch(response);
104
+ return 'patch' in result ? result.patch : null;
105
+ }
106
+ /**
107
+ * Agent id for an opencode hook call: the 8-char session prefix from
108
+ * `input.sessionID` when the hook carries it, else the first non-synthetic
109
+ * message's `info.sessionID` (the transform hook input is empty — the
110
+ * session lives on the message envelopes), else `'default'` (the plugin
111
+ * trims the history of one session context).
112
+ */
113
+ export function pluginAgentId(input, messages) {
114
+ const direct = resolveAgentIdFromSession(input?.sessionID);
115
+ if (direct.length > 0)
116
+ return direct;
117
+ const fromMessages = (messages ?? []).find((m) => typeof m.info?.sessionID === 'string' &&
118
+ m.info.sessionID.length > 0 &&
119
+ m.info.sessionID !== 'skillstate');
120
+ const indirect = resolveAgentIdFromSession(fromMessages?.info.sessionID);
121
+ return indirect.length > 0 ? indirect : PLUGIN_DEFAULT_AGENT_ID;
130
122
  }
131
123
  /** Synthetic message ids for the injected state carrier. */
132
124
  const STATE_MESSAGE_ID = 'skillstate-state-inject';
@@ -136,12 +128,13 @@ const STATE_MESSAGE_ID = 'skillstate-state-inject';
136
128
  *
137
129
  * State resolution is ALWAYS per-project: the state file path is computed
138
130
  * from the session cwd on EVERY hook call via
139
- * `resolveStatePathForCwd(process.cwd(), os.homedir())` — each project gets
140
- * its own `<cwd>/.skillstate/skillstate.json`, and a session launched from
141
- * `$HOME` uses the global bucket.
131
+ * `resolveStatePathForCwd(process.cwd(), os.homedir(), agentId)` — each
132
+ * project gets its own `<cwd>/.skillstate/`, each session (sub-agent) its
133
+ * isolated `agents/<session>/` copy, and a session launched from `$HOME`
134
+ * uses the global bucket.
142
135
  */
143
136
  export function createSkillStatePlugin(options = {}) {
144
- const resolvePath = () => resolveStatePathForCwd(process.cwd(), os.homedir());
137
+ const resolvePath = (agentId) => resolveHostStateForCwd(process.cwd(), os.homedir(), agentId);
145
138
  const maxHistory = options.maxHistoryMessages ?? 3;
146
139
  return async () => {
147
140
  return {
@@ -150,8 +143,9 @@ export function createSkillStatePlugin(options = {}) {
150
143
  // plus the last `maxHistory` non-system messages, then injects a
151
144
  // synthetic state element. Old messages are DROPPED from the prompt,
152
145
  // not just hidden.
153
- 'experimental.chat.messages.transform': async (_input, output) => {
154
- const state = readSkillState(resolvePath());
146
+ 'experimental.chat.messages.transform': async (input, output) => {
147
+ const agentId = pluginAgentId(input, output.messages);
148
+ const state = readSkillState(resolvePath(agentId));
155
149
  const messages = output.messages;
156
150
  const systemMessages = messages.filter((m) => m.info.role === 'system');
157
151
  const trimmed = messages
@@ -188,8 +182,9 @@ export function createSkillStatePlugin(options = {}) {
188
182
  // ── Compaction context injection ───────────────────────────────────
189
183
  // Before compaction, inject the current state into the context so the
190
184
  // compaction summary preserves state even after history is compressed.
191
- 'experimental.session.compacting': async (_input, output) => {
192
- const state = readSkillState(resolvePath());
185
+ 'experimental.session.compacting': async (input, output) => {
186
+ const agentId = pluginAgentId(input);
187
+ const state = readSkillState(resolvePath(agentId));
193
188
  if (!Array.isArray(output.context)) {
194
189
  output.context = [];
195
190
  }
@@ -197,15 +192,16 @@ export function createSkillStatePlugin(options = {}) {
197
192
  },
198
193
  // ── State persistence from LLM responses ───────────────────────────
199
194
  // After tool execution, extract state_patch from the tool response
200
- // (output.output), merge it, and save to disk.
201
- 'tool.execute.after': async (_input, output) => {
195
+ // (output.output), and atomically merge it into the session-scoped
196
+ // state (read + merge + write all inside the cross-process lock).
197
+ 'tool.execute.after': async (input, output) => {
202
198
  const response = output.output ?? '';
203
199
  if (typeof response !== 'string')
204
200
  return;
205
- const statePath = resolvePath();
206
201
  const patch = extractPatch(response);
207
202
  if (patch) {
208
- saveSkillState(statePath, mergePatch(readSkillState(statePath), patch));
203
+ const agentId = pluginAgentId(input);
204
+ mergeSkillState(resolvePath(agentId), patch);
209
205
  }
210
206
  },
211
207
  };
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.js","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"plugin.js","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@skillstate/opencode",
3
- "version": "2.0.7",
3
+ "version": "2.2.0",
4
4
  "description": "OpenCode platform adapter for the skillstate runtime.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",