@skillstate/opencode 2.2.1 → 2.2.2
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 +17 -9
- package/dist/plugin-types.d.ts +7 -0
- package/dist/plugin-types.d.ts.map +1 -1
- package/dist/plugin.d.ts +25 -7
- package/dist/plugin.d.ts.map +1 -1
- package/dist/plugin.js +91 -22
- package/dist/plugin.js.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -138,12 +138,16 @@ Root path `@skillstate/opencode` exports the adapter and the static plugin:
|
|
|
138
138
|
- `createSkillStatePlugin({ maxHistoryMessages? })` — the static plugin
|
|
139
139
|
factory (single source of truth for the hook logic); state is resolved from
|
|
140
140
|
the session cwd on every hook call via
|
|
141
|
-
`resolveStatePathForCwd(process.cwd(), os.homedir())
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
141
|
+
`resolveStatePathForCwd(process.cwd(), os.homedir(), agentId)`. The
|
|
142
|
+
`event` hook registers sub-agent sessions from the host bus
|
|
143
|
+
(`session.created`/`session.updated` carry `info.parentID`): a sub-agent
|
|
144
|
+
session resolves to `agents/<parentPrefix>-<sessionPrefix>/` instead of
|
|
145
|
+
overwriting its parent's state file.
|
|
146
|
+
- `resolveStatePathForCwd(cwd, home?, agentId?): string` — the per-project
|
|
147
|
+
state path resolution (pure path arithmetic, no filesystem access).
|
|
148
|
+
- `pluginAgentId(input, messages?)` / `scopedAgentId(agentId)` /
|
|
149
|
+
`registerSessionParent(sessionId, parentId)` / `resetSessionParents()` —
|
|
150
|
+
the agent-scope plumbing (session id → `agents/` directory name).
|
|
147
151
|
- `readSkillState` / `saveSkillState` / `mergePatch` / `extractPatch` — the
|
|
148
152
|
plugin's state helpers, shared by the static plugin.
|
|
149
153
|
- `savePluginCode(target, options?): Promise<string>` — writes the plugin
|
|
@@ -162,9 +166,13 @@ Root path `@skillstate/opencode` exports the adapter and the static plugin:
|
|
|
162
166
|
- The generated plugin is a **thin loader**: it imports
|
|
163
167
|
`createSkillStatePlugin` from `@skillstate/opencode` (one source of truth).
|
|
164
168
|
Hook logic lives only in `src/plugin.ts` — regenerate rather than editing
|
|
165
|
-
generated files.
|
|
166
|
-
|
|
167
|
-
session cwd
|
|
169
|
+
generated files. **WHERE STATE LIVES** (each opencode session reads AND
|
|
170
|
+
writes the same path within its cwd — no cross-file surprises):
|
|
171
|
+
- main session: `<cwd>/.skillstate/skillstate.json`
|
|
172
|
+
- sub-agent session (Task sub-agents carry `parentID` on the session):
|
|
173
|
+
`<cwd>/.skillstate/agents/<parentPrefix>-<sessionPrefix>/skillstate.json`
|
|
174
|
+
- a session started in `$HOME`: the global bucket
|
|
175
|
+
`~/.skillstate/global/...` with the same main/sub split.
|
|
168
176
|
- Depends on [`@skillstate/core`](../core) for `PromptTransformer`,
|
|
169
177
|
`atomicWriteFile`, and `resolveStatePath`.
|
|
170
178
|
|
package/dist/plugin-types.d.ts
CHANGED
|
@@ -40,6 +40,13 @@ export interface ToolExecuteAfterOutput {
|
|
|
40
40
|
}
|
|
41
41
|
/** OpenCode hooks used by the skillstate plugin. */
|
|
42
42
|
export interface SkillStateHooks {
|
|
43
|
+
/**
|
|
44
|
+
* Host event bus (`session.created`/`session.updated` carry the full
|
|
45
|
+
* Session, including `parentID`) — feeds the sub-agent registry.
|
|
46
|
+
*/
|
|
47
|
+
event?: (input: {
|
|
48
|
+
event: unknown;
|
|
49
|
+
}) => Promise<void>;
|
|
43
50
|
'experimental.chat.messages.transform'?: (input: Record<string, never>, output: MessagesTransformOutput) => Promise<void>;
|
|
44
51
|
'experimental.session.compacting'?: (input: {
|
|
45
52
|
sessionID: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin-types.d.ts","sourceRoot":"","sources":["../src/plugin-types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,oEAAoE;AACpE,MAAM,MAAM,mBAAmB,GAAG,MAAM,GAAG,WAAW,GAAG,QAAQ,CAAC;AAElE;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE;QAAE,IAAI,EAAE,mBAAmB,GAAG,MAAM,CAAC;QAAC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;KAAE,CAAC;IACrE,KAAK,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;KAAE,CAAC,CAAC;CACvE;AAED,gEAAgE;AAChE,MAAM,WAAW,uBAAuB;IACtC,0EAA0E;IAC1E,QAAQ,EAAE,eAAe,EAAE,CAAC;CAC7B;AAED,2DAA2D;AAC3D,MAAM,WAAW,uBAAuB;IACtC,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,8CAA8C;AAC9C,MAAM,WAAW,sBAAsB;IACrC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,kEAAkE;IAClE,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,oDAAoD;AACpD,MAAM,WAAW,eAAe;IAC9B,sCAAsC,CAAC,EAAE,CACvC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,EAC5B,MAAM,EAAE,uBAAuB,KAC5B,OAAO,CAAC,IAAI,CAAC,CAAC;IACnB,iCAAiC,CAAC,EAAE,CAClC,KAAK,EAAE;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,EAC5B,MAAM,EAAE,uBAAuB,KAC5B,OAAO,CAAC,IAAI,CAAC,CAAC;IACnB,oBAAoB,CAAC,EAAE,CACrB,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,OAAO,CAAA;KAAE,EACzE,MAAM,EAAE,sBAAsB,KAC3B,OAAO,CAAC,IAAI,CAAC,CAAC;CACpB;AAED;;;GAGG;AACH,MAAM,MAAM,gBAAgB,GAAG,CAAC,KAAK,EAAE;IACrC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,CAAC,CAAC,EAAE,OAAO,CAAC;IACZ,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB,KAAK,OAAO,CAAC,eAAe,CAAC,CAAC"}
|
|
1
|
+
{"version":3,"file":"plugin-types.d.ts","sourceRoot":"","sources":["../src/plugin-types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,oEAAoE;AACpE,MAAM,MAAM,mBAAmB,GAAG,MAAM,GAAG,WAAW,GAAG,QAAQ,CAAC;AAElE;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE;QAAE,IAAI,EAAE,mBAAmB,GAAG,MAAM,CAAC;QAAC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;KAAE,CAAC;IACrE,KAAK,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;KAAE,CAAC,CAAC;CACvE;AAED,gEAAgE;AAChE,MAAM,WAAW,uBAAuB;IACtC,0EAA0E;IAC1E,QAAQ,EAAE,eAAe,EAAE,CAAC;CAC7B;AAED,2DAA2D;AAC3D,MAAM,WAAW,uBAAuB;IACtC,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,8CAA8C;AAC9C,MAAM,WAAW,sBAAsB;IACrC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,kEAAkE;IAClE,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,oDAAoD;AACpD,MAAM,WAAW,eAAe;IAC9B;;;OAGG;IACH,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE;QAAE,KAAK,EAAE,OAAO,CAAA;KAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACrD,sCAAsC,CAAC,EAAE,CACvC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,EAC5B,MAAM,EAAE,uBAAuB,KAC5B,OAAO,CAAC,IAAI,CAAC,CAAC;IACnB,iCAAiC,CAAC,EAAE,CAClC,KAAK,EAAE;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,EAC5B,MAAM,EAAE,uBAAuB,KAC5B,OAAO,CAAC,IAAI,CAAC,CAAC;IACnB,oBAAoB,CAAC,EAAE,CACrB,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,OAAO,CAAA;KAAE,EACzE,MAAM,EAAE,sBAAsB,KAC3B,OAAO,CAAC,IAAI,CAAC,CAAC;CACpB;AAED;;;GAGG;AACH,MAAM,MAAM,gBAAgB,GAAG,CAAC,KAAK,EAAE;IACrC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,CAAC,CAAC,EAAE,OAAO,CAAC;IACZ,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB,KAAK,OAAO,CAAC,eAAe,CAAC,CAAC"}
|
package/dist/plugin.d.ts
CHANGED
|
@@ -12,8 +12,6 @@ export * from './plugin-types.js';
|
|
|
12
12
|
*/
|
|
13
13
|
export { resolveHostStateForCwd as resolveStatePathForCwd };
|
|
14
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";
|
|
17
15
|
/** Options for {@link createSkillStatePlugin}. */
|
|
18
16
|
export interface SkillStatePluginOptions {
|
|
19
17
|
/** Non-system messages kept in the prompt (default 3). */
|
|
@@ -53,15 +51,35 @@ export declare function mergeSkillState(statePath: string, patch: Record<string,
|
|
|
53
51
|
*/
|
|
54
52
|
export declare function extractPatch(response: string): Record<string, unknown> | null;
|
|
55
53
|
/**
|
|
56
|
-
* Agent id for an opencode hook call
|
|
57
|
-
*
|
|
58
|
-
*
|
|
59
|
-
*
|
|
60
|
-
*
|
|
54
|
+
* Agent id for an opencode hook call.
|
|
55
|
+
*
|
|
56
|
+
* MAIN SESSION → `''` (the ROOT state file `<cwd>/.skillstate/skillstate.json`
|
|
57
|
+
* — the SAME file the skillstate MCP tools and the CLI address, so the
|
|
58
|
+
* injected state and `state.patch` can never disagree). A session
|
|
59
|
+
* registered as a SUB-AGENT via the host event bus
|
|
60
|
+
* (`session.created`/`updated` carry `info.parentID`) resolves to
|
|
61
|
+
* `<parentPrefix>-<sessionPrefix>` — an isolated copy under `agents/` that
|
|
62
|
+
* never last-writer-wins the main state; the main agent folds it back with
|
|
63
|
+
* `agent.merge`. No session id at all → `''` (root: a single context).
|
|
61
64
|
*/
|
|
62
65
|
export declare function pluginAgentId(input: {
|
|
63
66
|
sessionID?: unknown;
|
|
64
67
|
}, messages?: OpenCodeMessage[]): string;
|
|
68
|
+
/**
|
|
69
|
+
* Widen an agent id for a registered sub-agent session:
|
|
70
|
+
* `<parentPrefix>-<sessionPrefix>`. Plain sessions resolve to `''` (the
|
|
71
|
+
* main/root scope — NOT their own agents/ copy).
|
|
72
|
+
*/
|
|
73
|
+
export declare function scopedAgentId(agentId: string): string;
|
|
74
|
+
/**
|
|
75
|
+
* Record a session→parent edge from the host event stream. `sessionId`
|
|
76
|
+
* with a non-empty `parentID` registers that session as a sub-agent of
|
|
77
|
+
* `parentID`; an empty `parentID` (the main session being updated after
|
|
78
|
+
* the fact) clears a stale registration. Exposed for tests.
|
|
79
|
+
*/
|
|
80
|
+
export declare function registerSessionParent(sessionId: unknown, parentId: unknown): void;
|
|
81
|
+
/** Test-only: forget every registered session→parent edge. */
|
|
82
|
+
export declare function resetSessionParents(): void;
|
|
65
83
|
/**
|
|
66
84
|
* Build the OpenCode plugin function with the same behavior for every host
|
|
67
85
|
* entry point (thin generated loaders, direct imports).
|
package/dist/plugin.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAmCA,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,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;;;;;;;;;;;GAWG;AACH,wBAAgB,aAAa,CAC3B,KAAK,EAAE;IAAE,SAAS,CAAC,EAAE,OAAO,CAAA;CAAE,EAC9B,QAAQ,CAAC,EAAE,eAAe,EAAE,GAC3B,MAAM,CAeR;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAGrD;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,GAAG,IAAI,CAUjF;AAED,8DAA8D;AAC9D,wBAAgB,mBAAmB,IAAI,IAAI,CAE1C;AAgBD;;;;;;;;;;GAUG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,GAAE,uBAA4B,GAAG,gBAAgB,CAwG9F"}
|
package/dist/plugin.js
CHANGED
|
@@ -18,13 +18,17 @@
|
|
|
18
18
|
* ```json `state_patch` block is merged (paper ⊕: null deletes) and saved.
|
|
19
19
|
*
|
|
20
20
|
* AGENT-SCOPED STATE: the opencode hook inputs carry the session id
|
|
21
|
-
* (`input.sessionID`; message envelopes carry `info.sessionID`)
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
21
|
+
* (`input.sessionID`; message envelopes carry `info.sessionID`). The MAIN
|
|
22
|
+
* session resolves to the ROOT state file
|
|
23
|
+
* `<cwd>/.skillstate/skillstate.json` — the same file the skillstate MCP
|
|
24
|
+
* tools and the CLI address, so the injected state and `state.patch` can
|
|
25
|
+
* never disagree. SUB-AGENT sessions (registered from the host event bus —
|
|
26
|
+
* `session.created`/`session.updated` carry `info.parentID`) resolve to
|
|
27
|
+
* isolated `agents/<parentPrefix>-<sessionPrefix>/` copies and never
|
|
28
|
+
* last-writer-win the main state; the main agent folds them back with
|
|
29
|
+
* `agent.merge`. Writes go through the core cross-process sync lock
|
|
30
|
+
* (`lockStateWrite`) so a state file is never interleaved between
|
|
31
|
+
* processes.
|
|
28
32
|
*/
|
|
29
33
|
import * as fs from 'node:fs';
|
|
30
34
|
import * as os from 'node:os';
|
|
@@ -42,8 +46,6 @@ export * from './plugin-types.js';
|
|
|
42
46
|
*/
|
|
43
47
|
export { resolveHostStateForCwd as resolveStatePathForCwd };
|
|
44
48
|
export { mergePatch };
|
|
45
|
-
/** Agent scope used by the plugin when no session id is available. */
|
|
46
|
-
export const PLUGIN_DEFAULT_AGENT_ID = 'default';
|
|
47
49
|
/**
|
|
48
50
|
* Read the state file. Missing or corrupt files yield `{}` (best-effort).
|
|
49
51
|
* The on-disk envelope is `{ version: 1, state }` (migrations-compatible);
|
|
@@ -104,24 +106,72 @@ export function extractPatch(response) {
|
|
|
104
106
|
return 'patch' in result ? result.patch : null;
|
|
105
107
|
}
|
|
106
108
|
/**
|
|
107
|
-
* Agent id for an opencode hook call
|
|
108
|
-
*
|
|
109
|
-
*
|
|
110
|
-
*
|
|
111
|
-
*
|
|
109
|
+
* Agent id for an opencode hook call.
|
|
110
|
+
*
|
|
111
|
+
* MAIN SESSION → `''` (the ROOT state file `<cwd>/.skillstate/skillstate.json`
|
|
112
|
+
* — the SAME file the skillstate MCP tools and the CLI address, so the
|
|
113
|
+
* injected state and `state.patch` can never disagree). A session
|
|
114
|
+
* registered as a SUB-AGENT via the host event bus
|
|
115
|
+
* (`session.created`/`updated` carry `info.parentID`) resolves to
|
|
116
|
+
* `<parentPrefix>-<sessionPrefix>` — an isolated copy under `agents/` that
|
|
117
|
+
* never last-writer-wins the main state; the main agent folds it back with
|
|
118
|
+
* `agent.merge`. No session id at all → `''` (root: a single context).
|
|
112
119
|
*/
|
|
113
120
|
export function pluginAgentId(input, messages) {
|
|
114
121
|
const direct = resolveAgentIdFromSession(input?.sessionID);
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
+
const sessionPrefix = direct.length > 0
|
|
123
|
+
? direct
|
|
124
|
+
: resolveAgentIdFromSession((messages ?? []).find((m) => typeof m.info?.sessionID === 'string' &&
|
|
125
|
+
m.info.sessionID.length > 0 &&
|
|
126
|
+
m.info.sessionID !== 'skillstate')?.info.sessionID);
|
|
127
|
+
if (sessionPrefix.length === 0)
|
|
128
|
+
return '';
|
|
129
|
+
return scopedAgentId(sessionPrefix);
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Widen an agent id for a registered sub-agent session:
|
|
133
|
+
* `<parentPrefix>-<sessionPrefix>`. Plain sessions resolve to `''` (the
|
|
134
|
+
* main/root scope — NOT their own agents/ copy).
|
|
135
|
+
*/
|
|
136
|
+
export function scopedAgentId(agentId) {
|
|
137
|
+
const parent = SUB_AGENT_PARENTS.get(agentId);
|
|
138
|
+
return parent === undefined ? '' : `${parent}-${agentId}`;
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Record a session→parent edge from the host event stream. `sessionId`
|
|
142
|
+
* with a non-empty `parentID` registers that session as a sub-agent of
|
|
143
|
+
* `parentID`; an empty `parentID` (the main session being updated after
|
|
144
|
+
* the fact) clears a stale registration. Exposed for tests.
|
|
145
|
+
*/
|
|
146
|
+
export function registerSessionParent(sessionId, parentId) {
|
|
147
|
+
if (typeof sessionId !== 'string' || sessionId.length === 0)
|
|
148
|
+
return;
|
|
149
|
+
const session = resolveAgentIdFromSession(sessionId);
|
|
150
|
+
if (session.length === 0)
|
|
151
|
+
return;
|
|
152
|
+
const parent = resolveAgentIdFromSession(parentId);
|
|
153
|
+
if (parent.length === 0 || parent === session) {
|
|
154
|
+
SUB_AGENT_PARENTS.delete(session);
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
SUB_AGENT_PARENTS.set(session, parent);
|
|
158
|
+
}
|
|
159
|
+
/** Test-only: forget every registered session→parent edge. */
|
|
160
|
+
export function resetSessionParents() {
|
|
161
|
+
SUB_AGENT_PARENTS.clear();
|
|
122
162
|
}
|
|
123
163
|
/** Synthetic message ids for the injected state carrier. */
|
|
124
164
|
const STATE_MESSAGE_ID = 'skillstate-state-inject';
|
|
165
|
+
/**
|
|
166
|
+
* The session ids known to be SUB-AGENT sessions, keyed by session id →
|
|
167
|
+
* parent session id. Populated from the `event` hook
|
|
168
|
+
* (`session.created`/`session.updated` carry `info.parentID`); consulted
|
|
169
|
+
* when resolving an agent id so a sub-agent's state lands in the SAME
|
|
170
|
+
* agents/<parent>/<session-8>/ scope as its hook-session (the task tool
|
|
171
|
+
* spawns sessions whose ids never appear as sub-agent prefixes — without
|
|
172
|
+
* this map a sub-agent would silently write the MAIN state).
|
|
173
|
+
*/
|
|
174
|
+
const SUB_AGENT_PARENTS = new Map();
|
|
125
175
|
/**
|
|
126
176
|
* Build the OpenCode plugin function with the same behavior for every host
|
|
127
177
|
* entry point (thin generated loaders, direct imports).
|
|
@@ -138,6 +188,25 @@ export function createSkillStatePlugin(options = {}) {
|
|
|
138
188
|
const maxHistory = options.maxHistoryMessages ?? 3;
|
|
139
189
|
return async () => {
|
|
140
190
|
return {
|
|
191
|
+
// ── Session registry ──────────────────────────────────────────────
|
|
192
|
+
// The host event bus carries full Session objects on
|
|
193
|
+
// session.created/updated — including `parentID`. Registering here
|
|
194
|
+
// is what makes sub-agent scoping work: a Task sub-agent's session
|
|
195
|
+
// (parentID set) resolves to agents/<parent>-<session>/ BEFORE its
|
|
196
|
+
// first hook fires, so it never touches the parent's state file.
|
|
197
|
+
event: async ({ event }) => {
|
|
198
|
+
const payload = event;
|
|
199
|
+
if (payload === null ||
|
|
200
|
+
typeof payload !== 'object' ||
|
|
201
|
+
payload['type'] !== 'session.created' && payload['type'] !== 'session.updated') {
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
const info = payload['properties']?.['info'];
|
|
205
|
+
if (info === null || typeof info !== 'object')
|
|
206
|
+
return;
|
|
207
|
+
const record = info;
|
|
208
|
+
registerSessionParent(record['id'], record['parentID']);
|
|
209
|
+
},
|
|
141
210
|
// ── O(1) history trimming ──────────────────────────────────────────
|
|
142
211
|
// Filters messages BEFORE each LLM call: keeps all system messages
|
|
143
212
|
// plus the last `maxHistory` non-system messages, then injects a
|
|
@@ -198,9 +267,9 @@ export function createSkillStatePlugin(options = {}) {
|
|
|
198
267
|
const response = output.output ?? '';
|
|
199
268
|
if (typeof response !== 'string')
|
|
200
269
|
return;
|
|
270
|
+
const agentId = pluginAgentId(input);
|
|
201
271
|
const patch = extractPatch(response);
|
|
202
272
|
if (patch) {
|
|
203
|
-
const agentId = pluginAgentId(input);
|
|
204
273
|
mergeSkillState(resolvePath(agentId), patch);
|
|
205
274
|
}
|
|
206
275
|
},
|
package/dist/plugin.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.js","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"plugin.js","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,EACL,eAAe,EACf,cAAc,EACd,UAAU,EACV,iBAAiB,EACjB,yBAAyB,EACzB,sBAAsB,EACtB,iBAAiB,GAClB,MAAM,kBAAkB,CAAC;AAO1B,cAAc,mBAAmB,CAAC;AAElC;;;;;;;;GAQG;AACH,OAAO,EAAE,sBAAsB,IAAI,sBAAsB,EAAE,CAAC;AAE5D,OAAO,EAAE,UAAU,EAAE,CAAC;AAQtB;;;;;GAKG;AACH,MAAM,UAAU,cAAc,CAAC,SAAiB;IAC9C,OAAO,iBAAiB,CAAC,SAAS,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,OAAO,CAAC,CAA4B,CAAC;AACrG,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,cAAc,CAAC,SAAiB,EAAE,KAA8B;IAC9E,IAAI,CAAC;QACH,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC3D,cAAc,CACZ,SAAS,EACT,EAAE,EACF,GAAG,EAAE,CAAC,iBAAiB,CAAC,SAAS,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAClF,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,4DAA4D;IAC9D,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,eAAe,CAC7B,SAAiB,EACjB,KAA8B;IAE9B,IAAI,CAAC;QACH,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC3D,IAAI,MAAM,GAA4B,EAAE,CAAC;QACzC,cAAc,CAAC,SAAS,EAAE,EAAE,EAAE,GAAG,EAAE;YACjC,MAAM,GAAG,UAAU,CAAC,cAAc,CAAC,SAAS,CAAC,EAAE,KAAK,CAAC,CAAC;YACtD,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;QAC/E,CAAC,CAAC,CAAC;QACH,OAAO,MAAM,CAAC;IAChB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,cAAc,CAAC,SAAS,CAAC,CAAC;IACnC,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,YAAY,CAAC,QAAgB;IAC3C,MAAM,MAAM,GAAG,eAAe,CAAC,QAAQ,CAAC,CAAC;IACzC,OAAO,OAAO,IAAI,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;AACjD,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,aAAa,CAC3B,KAA8B,EAC9B,QAA4B;IAE5B,MAAM,MAAM,GAAG,yBAAyB,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;IAC3D,MAAM,aAAa,GACjB,MAAM,CAAC,MAAM,GAAG,CAAC;QACf,CAAC,CAAC,MAAM;QACR,CAAC,CAAC,yBAAyB,CACvB,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC,IAAI,CACnB,CAAC,CAAC,EAAE,EAAE,CACJ,OAAO,CAAC,CAAC,IAAI,EAAE,SAAS,KAAK,QAAQ;YACrC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC;YAC3B,CAAC,CAAC,IAAI,CAAC,SAAS,KAAK,YAAY,CACpC,EAAE,IAAI,CAAC,SAAS,CAClB,CAAC;IACR,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAC1C,OAAO,aAAa,CAAC,aAAa,CAAC,CAAC;AACtC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAAC,OAAe;IAC3C,MAAM,MAAM,GAAG,iBAAiB,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IAC9C,OAAO,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,MAAM,IAAI,OAAO,EAAE,CAAC;AAC5D,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,qBAAqB,CAAC,SAAkB,EAAE,QAAiB;IACzE,IAAI,OAAO,SAAS,KAAK,QAAQ,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO;IACpE,MAAM,OAAO,GAAG,yBAAyB,CAAC,SAAS,CAAC,CAAC;IACrD,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO;IACjC,MAAM,MAAM,GAAG,yBAAyB,CAAC,QAAQ,CAAC,CAAC;IACnD,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,IAAI,MAAM,KAAK,OAAO,EAAE,CAAC;QAC9C,iBAAiB,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAClC,OAAO;IACT,CAAC;IACD,iBAAiB,CAAC,GAAG,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;AACzC,CAAC;AAED,8DAA8D;AAC9D,MAAM,UAAU,mBAAmB;IACjC,iBAAiB,CAAC,KAAK,EAAE,CAAC;AAC5B,CAAC;AAED,4DAA4D;AAC5D,MAAM,gBAAgB,GAAG,yBAAyB,CAAC;AAEnD;;;;;;;;GAQG;AACH,MAAM,iBAAiB,GAAG,IAAI,GAAG,EAAkB,CAAC;AAEpD;;;;;;;;;;GAUG;AACH,MAAM,UAAU,sBAAsB,CAAC,OAAO,GAA4B,EAAE;IAC1E,MAAM,WAAW,GAAG,CAAC,OAAe,EAAU,EAAE,CAC9C,sBAAsB,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,EAAE,CAAC,OAAO,EAAE,EAAE,OAAO,CAAC,CAAC;IAC/D,MAAM,UAAU,GAAG,OAAO,CAAC,kBAAkB,IAAI,CAAC,CAAC;IAEnD,OAAO,KAAK,IAAI,EAAE;QAChB,OAAO;YACL,qEAAqE;YACrE,qDAAqD;YACrD,mEAAmE;YACnE,mEAAmE;YACnE,mEAAmE;YACnE,iEAAiE;YACjE,KAAK,EAAE,KAAK,EAAE,EAAE,KAAK,EAAsB,EAAiB,EAAE;gBAC5D,MAAM,OAAO,GAAG,KAEH,CAAC;gBACd,IACE,OAAO,KAAK,IAAI;oBAChB,OAAO,OAAO,KAAK,QAAQ;oBAC3B,OAAO,CAAC,MAAM,CAAC,KAAK,iBAAiB,IAAI,OAAO,CAAC,MAAM,CAAC,KAAK,iBAAiB,EAC9E,CAAC;oBACD,OAAO;gBACT,CAAC;gBACD,MAAM,IAAI,GAAG,OAAO,CAAC,YAAY,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC;gBAC7C,IAAI,IAAI,KAAK,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ;oBAAE,OAAO;gBACtD,MAAM,MAAM,GAAG,IAA4C,CAAC;gBAC5D,qBAAqB,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC;YAC1D,CAAC;YAED,sEAAsE;YACtE,mEAAmE;YACnE,iEAAiE;YACjE,qEAAqE;YACrE,mBAAmB;YACnB,sCAAsC,EAAE,KAAK,EAC3C,KAAK,EACL,MAAM,EACS,EAAE;gBACjB,MAAM,OAAO,GAAG,aAAa,CAAC,KAAgC,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC;gBACjF,MAAM,KAAK,GAAG,cAAc,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC;gBACnD,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC;gBACjC,MAAM,cAAc,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC;gBACxE,MAAM,OAAO,GAAG,QAAQ;qBACrB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,KAAK,QAAQ,CAAC;qBACvC,KAAK,CAAC,CAAC,UAAU,CAAC,CAAC;gBAEtB,oEAAoE;gBACpE,uCAAuC;gBACvC,MAAM,YAAY,GAAoB;oBACpC,IAAI,EAAE;wBACJ,EAAE,EAAE,gBAAgB;wBACpB,SAAS,EAAE,YAAY;wBACvB,IAAI,EAAE,MAAM;wBACZ,IAAI,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE;wBACpB,KAAK,EAAE,YAAY;wBACnB,KAAK,EAAE,EAAE,UAAU,EAAE,YAAY,EAAE,OAAO,EAAE,YAAY,EAAE;qBAC3D;oBACD,KAAK,EAAE;wBACL;4BACE,EAAE,EAAE,GAAG,gBAAgB,OAAO;4BAC9B,SAAS,EAAE,YAAY;4BACvB,SAAS,EAAE,gBAAgB;4BAC3B,IAAI,EAAE,MAAM;4BACZ,SAAS,EAAE,IAAI;4BACf,IAAI,EAAE,+BAA+B,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE;yBAC7D;qBACF;iBACF,CAAC;gBAEF,oEAAoE;gBACpE,gEAAgE;gBAChE,MAAM,IAAI,GAAG,CAAC,GAAG,cAAc,EAAE,GAAG,OAAO,EAAE,YAAY,CAAC,CAAC;gBAC3D,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC;gBACpB,QAAQ,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC;YACzB,CAAC;YAED,sEAAsE;YACtE,sEAAsE;YACtE,uEAAuE;YACvE,iCAAiC,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAiB,EAAE;gBACxE,MAAM,OAAO,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC;gBACrC,MAAM,KAAK,GAAG,cAAc,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC;gBACnD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;oBACnC,MAAM,CAAC,OAAO,GAAG,EAAE,CAAC;gBACtB,CAAC;gBACD,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,eAAe,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;YAC9D,CAAC;YAED,sEAAsE;YACtE,mEAAmE;YACnE,mEAAmE;YACnE,kEAAkE;YAClE,oBAAoB,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAiB,EAAE;gBAC3D,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,IAAI,EAAE,CAAC;gBACrC,IAAI,OAAO,QAAQ,KAAK,QAAQ;oBAAE,OAAO;gBACzC,MAAM,OAAO,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC;gBACrC,MAAM,KAAK,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAC;gBACrC,IAAI,KAAK,EAAE,CAAC;oBACV,eAAe,CAAC,WAAW,CAAC,OAAO,CAAC,EAAE,KAAK,CAAC,CAAC;gBAC/C,CAAC;YACH,CAAC;SACwB,CAAC;IAC9B,CAAC,CAAC;AACJ,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@skillstate/opencode",
|
|
3
|
-
"version": "2.2.
|
|
3
|
+
"version": "2.2.2",
|
|
4
4
|
"description": "OpenCode platform adapter for the skillstate runtime.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -25,6 +25,6 @@
|
|
|
25
25
|
},
|
|
26
26
|
"license": "MIT",
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@skillstate/core": "^2.2.
|
|
28
|
+
"@skillstate/core": "^2.2.2"
|
|
29
29
|
}
|
|
30
30
|
}
|