@xemahq/opencode-xema-plugin 0.1.13 → 0.3.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.
Files changed (40) hide show
  1. package/README.md +33 -5
  2. package/dist/.source-stamp.json +2 -2
  3. package/dist/context.d.ts +0 -1
  4. package/dist/context.d.ts.map +1 -1
  5. package/dist/context.js +0 -1
  6. package/dist/context.js.map +1 -1
  7. package/dist/hooks/subagent-fanout-ceiling.d.ts +39 -0
  8. package/dist/hooks/subagent-fanout-ceiling.d.ts.map +1 -0
  9. package/dist/hooks/subagent-fanout-ceiling.js +188 -0
  10. package/dist/hooks/subagent-fanout-ceiling.js.map +1 -0
  11. package/dist/index.d.ts +1 -1
  12. package/dist/index.d.ts.map +1 -1
  13. package/dist/index.js +35 -14
  14. package/dist/index.js.map +1 -1
  15. package/dist/opencode-types.d.ts +14 -20
  16. package/dist/opencode-types.d.ts.map +1 -1
  17. package/dist/opencode-types.js +1 -3
  18. package/dist/opencode-types.js.map +1 -1
  19. package/package.json +4 -5
  20. package/plugin.mjs +7463 -2324
  21. package/dist/session-state.d.ts +0 -20
  22. package/dist/session-state.d.ts.map +0 -1
  23. package/dist/session-state.js +0 -43
  24. package/dist/session-state.js.map +0 -1
  25. package/dist/tools/runtime.d.ts +0 -2
  26. package/dist/tools/runtime.d.ts.map +0 -1
  27. package/dist/tools/runtime.js +0 -2
  28. package/dist/tools/runtime.js.map +0 -1
  29. package/dist/tools/service-token.d.ts +0 -3
  30. package/dist/tools/service-token.d.ts.map +0 -1
  31. package/dist/tools/service-token.js +0 -31
  32. package/dist/tools/service-token.js.map +0 -1
  33. package/dist/tools/shared.d.ts +0 -3
  34. package/dist/tools/shared.d.ts.map +0 -1
  35. package/dist/tools/shared.js +0 -11
  36. package/dist/tools/shared.js.map +0 -1
  37. package/dist/tools/xema-memory.d.ts +0 -31
  38. package/dist/tools/xema-memory.d.ts.map +0 -1
  39. package/dist/tools/xema-memory.js +0 -157
  40. package/dist/tools/xema-memory.js.map +0 -1
package/README.md CHANGED
@@ -28,16 +28,44 @@
28
28
 
29
29
  ## Overview
30
30
 
31
- An Opencode plugin that registers Xema-namespaced runtime tools and a dynamic
32
- system-prompt overlay hook. The plugin is evaluated once at agent startup; it
33
- registers its tools unconditionally and defers per-role authorization to
34
- tool-execution time, where each tool reads the invocation context from the
35
- worker filesystem and rejects calls the invoking role is not permitted to make.
31
+ An Opencode plugin that registers Xema-namespaced runtime tools, a dynamic
32
+ system-prompt overlay hook, and the sub-agent fan-out ceiling. The plugin is
33
+ evaluated once at agent startup; it registers its tools unconditionally and
34
+ defers per-role authorization to tool-execution time, where each tool reads the
35
+ invocation context from the worker filesystem and rejects calls the invoking
36
+ role is not permitted to make.
36
37
 
37
38
  ## When to use it
38
39
 
39
40
  - Use it to add the Xema runtime tools and prompt overlay to an Opencode agent
40
41
  runtime.
42
+ - Use it to bound how many sub-agents one worker may run at once.
43
+
44
+ ## The sub-agent fan-out ceiling
45
+
46
+ Opencode bounds how DEEP delegation may nest (`subagent_depth`). Nothing bounds
47
+ how WIDE a turn may go, so at the platform's declared depth an unbounded
48
+ branching factor is an unbounded process — every `task` call is forked with no
49
+ pool, no semaphore and no queue.
50
+
51
+ This plugin adds the missing pool cap. It is BACKPRESSURE, not a refusal: when
52
+ the worker is already running its ceiling of sub-agents, the next `task` call
53
+ WAITS for a slot instead of being denied. An agent that cannot spawn a helper
54
+ would produce a wrong answer; one that waits produces a slower right one.
55
+
56
+ Configuration exists to TIGHTEN, never to enable:
57
+
58
+ | | |
59
+ |---|---|
60
+ | Default | 8 concurrent `task` calls per worker |
61
+ | Tighten with | `XEMA_SUBAGENT_FANOUT_LIMIT` (1..8) |
62
+ | Unset or empty | the platform default — never zero, never "off" |
63
+ | Above the default | refused at boot, with the reason |
64
+
65
+ Every degradation is logged: a task that waits says so and for how long, and
66
+ both leak backstops (a `session.idle` sweep and a per-permit TTL) name what they
67
+ reclaimed. A ceiling that silently stops binding is indistinguishable from
68
+ working software until somebody asks.
41
69
 
42
70
  ## Installation
43
71
 
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "algorithm": "sha256/len-framed-v1",
3
- "hash": "db148b94ce3037192dfbb8b60936b8b7af6162413cc6073819a29863cc5a79af",
4
- "fileCount": 14
3
+ "hash": "91dded28129122882a0e5cd97ec25a1d294fd8f648c614ff68e6f520cd42e13f",
4
+ "fileCount": 10
5
5
  }
package/dist/context.d.ts CHANGED
@@ -39,7 +39,6 @@ declare const ContextJsonSchema: z.ZodObject<{
39
39
  "own-pages-only": "own-pages-only";
40
40
  "full-write": "full-write";
41
41
  }>;
42
- allowedXemaTools: z.ZodArray<z.ZodString>;
43
42
  }, z.core.$strip>;
44
43
  git: z.ZodOptional<z.ZodNullable<z.ZodObject<{
45
44
  autoCommit: z.ZodEnum<{
@@ -1 +1 @@
1
- {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,QAAA,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAuFrB,CAAC;AAEH,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAClE,MAAM,MAAM,cAAc,GAAG,iBAAiB,CAAC,YAAY,CAAC,CAAC,MAAM,CAAC,CAAC;AAUrE,wBAAgB,qBAAqB,CACnC,YAAY,EAAE,MAAM,GACnB,iBAAiB,GAAG,IAAI,CAQ1B;AAUD,wBAAgB,4BAA4B,CAC1C,YAAY,EAAE,MAAM,EACpB,QAAQ,EAAE,MAAM,GACf,iBAAiB,GAAG,IAAI,CAiB1B"}
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,QAAA,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAgGrB,CAAC;AAEH,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAClE,MAAM,MAAM,cAAc,GAAG,iBAAiB,CAAC,YAAY,CAAC,CAAC,MAAM,CAAC,CAAC;AAUrE,wBAAgB,qBAAqB,CACnC,YAAY,EAAE,MAAM,GACnB,iBAAiB,GAAG,IAAI,CAQ1B;AAUD,wBAAgB,4BAA4B,CAC1C,YAAY,EAAE,MAAM,EACpB,QAAQ,EAAE,MAAM,GACf,iBAAiB,GAAG,IAAI,CAiB1B"}
package/dist/context.js CHANGED
@@ -37,7 +37,6 @@ const ContextJsonSchema = z.object({
37
37
  mayWriteKnowledgeBase: z.boolean().default(true),
38
38
  mayEditRepos: z.boolean().default(false),
39
39
  writePolicy: z.enum(['read-only', 'own-pages-only', 'full-write']),
40
- allowedXemaTools: z.array(z.string()).min(1),
41
40
  }),
42
41
  git: z
43
42
  .object({
@@ -1 +1 @@
1
- {"version":3,"file":"context.js","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"context.js","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,39 @@
1
+ export declare const TASK_TOOL_ID = "task";
2
+ export declare const DEFAULT_SUBAGENT_FANOUT_LIMIT = 8;
3
+ export declare const DEFAULT_FANOUT_WAIT_TIMEOUT_MS: number;
4
+ export declare const DEFAULT_PERMIT_TTL_MS: number;
5
+ export declare const FANOUT_LIMIT_ENV = "XEMA_SUBAGENT_FANOUT_LIMIT";
6
+ export declare function resolveSubagentFanoutLimit(env?: Readonly<Record<string, string | undefined>>): number;
7
+ export interface FanoutCeilingStats {
8
+ readonly limit: number;
9
+ readonly inFlight: number;
10
+ readonly waiting: number;
11
+ readonly waitedCount: number;
12
+ readonly timedOutCount: number;
13
+ readonly sweptCount: number;
14
+ readonly ttlReclaimedCount: number;
15
+ readonly armedTimers: number;
16
+ }
17
+ export interface SubagentFanoutCeiling {
18
+ readonly before: (input: {
19
+ tool: string;
20
+ sessionID: string;
21
+ callID: string;
22
+ }) => Promise<void>;
23
+ readonly after: (input: {
24
+ tool: string;
25
+ sessionID: string;
26
+ callID: string;
27
+ }) => void;
28
+ readonly onSessionIdle: (sessionId: string) => void;
29
+ readonly dispose: () => void;
30
+ readonly stats: () => FanoutCeilingStats;
31
+ }
32
+ export interface FanoutCeilingOptions {
33
+ readonly limit: number;
34
+ readonly waitTimeoutMs?: number;
35
+ readonly permitTtlMs?: number;
36
+ readonly now?: () => number;
37
+ }
38
+ export declare function createSubagentFanoutCeiling(options: FanoutCeilingOptions): SubagentFanoutCeiling;
39
+ //# sourceMappingURL=subagent-fanout-ceiling.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"subagent-fanout-ceiling.d.ts","sourceRoot":"","sources":["../../src/hooks/subagent-fanout-ceiling.ts"],"names":[],"mappings":"AA0FA,eAAO,MAAM,YAAY,SAAS,CAAC;AA6CnC,eAAO,MAAM,6BAA6B,IAAI,CAAC;AAW/C,eAAO,MAAM,8BAA8B,QAAiB,CAAC;AAU7D,eAAO,MAAM,qBAAqB,QAAiB,CAAC;AAGpD,eAAO,MAAM,gBAAgB,+BAA+B,CAAC;AAyB7D,wBAAgB,0BAA0B,CACxC,GAAG,GAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAe,GAC9D,MAAM,CA8BR;AAoBD,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAEzB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAE7B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAE/B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;IAiBnC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAC9B;AAED,MAAM,WAAW,qBAAqB;IAEpC,QAAQ,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE;QACvB,IAAI,EAAE,MAAM,CAAC;QACb,SAAS,EAAE,MAAM,CAAC;QAClB,MAAM,EAAE,MAAM,CAAC;KAChB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAEpB,QAAQ,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE;QACtB,IAAI,EAAE,MAAM,CAAC;QACb,SAAS,EAAE,MAAM,CAAC;QAClB,MAAM,EAAE,MAAM,CAAC;KAChB,KAAK,IAAI,CAAC;IAEX,QAAQ,CAAC,aAAa,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAgBpD,QAAQ,CAAC,OAAO,EAAE,MAAM,IAAI,CAAC;IAC7B,QAAQ,CAAC,KAAK,EAAE,MAAM,kBAAkB,CAAC;CAC1C;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAE9B,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;CAC7B;AAOD,wBAAgB,2BAA2B,CACzC,OAAO,EAAE,oBAAoB,GAC5B,qBAAqB,CAgPvB"}
@@ -0,0 +1,188 @@
1
+ import { info, warn, debug } from '../logger.js';
2
+ export const TASK_TOOL_ID = 'task';
3
+ export const DEFAULT_SUBAGENT_FANOUT_LIMIT = 8;
4
+ export const DEFAULT_FANOUT_WAIT_TIMEOUT_MS = 10 * 60 * 1000;
5
+ export const DEFAULT_PERMIT_TTL_MS = 30 * 60 * 1000;
6
+ export const FANOUT_LIMIT_ENV = 'XEMA_SUBAGENT_FANOUT_LIMIT';
7
+ export function resolveSubagentFanoutLimit(env = process.env) {
8
+ const declared = env[FANOUT_LIMIT_ENV];
9
+ if (declared === undefined || declared.trim() === '') {
10
+ return DEFAULT_SUBAGENT_FANOUT_LIMIT;
11
+ }
12
+ const parsed = Number(declared.trim());
13
+ if (!Number.isInteger(parsed)) {
14
+ throw new Error(`${FANOUT_LIMIT_ENV}="${declared}" is not an integer. Expected a whole number of ` +
15
+ `concurrently executing sub-agent tasks between 1 and ${DEFAULT_SUBAGENT_FANOUT_LIMIT}.`);
16
+ }
17
+ if (parsed < 1) {
18
+ throw new Error(`${FANOUT_LIMIT_ENV}="${declared}" is below 1. A ceiling of 0 would park EVERY delegation ` +
19
+ `until it timed out, turning a resource bound into an outage. Remove the variable to ` +
20
+ `accept the platform default (${DEFAULT_SUBAGENT_FANOUT_LIMIT}).`);
21
+ }
22
+ if (parsed > DEFAULT_SUBAGENT_FANOUT_LIMIT) {
23
+ throw new Error(`${FANOUT_LIMIT_ENV}="${declared}" is above the platform default ` +
24
+ `(${DEFAULT_SUBAGENT_FANOUT_LIMIT}). Configuration may only TIGHTEN this ceiling. The ` +
25
+ `default is a stated platform decision; a wider one moves ` +
26
+ `DEFAULT_SUBAGENT_FANOUT_LIMIT, where the grounds are recorded.`);
27
+ }
28
+ return parsed;
29
+ }
30
+ export function createSubagentFanoutCeiling(options) {
31
+ const limit = options.limit;
32
+ const waitTimeoutMs = options.waitTimeoutMs ?? DEFAULT_FANOUT_WAIT_TIMEOUT_MS;
33
+ const permitTtlMs = options.permitTtlMs ?? DEFAULT_PERMIT_TTL_MS;
34
+ const now = options.now ?? (() => Date.now());
35
+ const held = new Map();
36
+ const waiters = [];
37
+ let waitedCount = 0;
38
+ let timedOutCount = 0;
39
+ let sweptCount = 0;
40
+ let ttlReclaimedCount = 0;
41
+ const armed = new Set();
42
+ function arm(fn, ms, keepProcessAlive) {
43
+ const timer = setTimeout(() => {
44
+ armed.delete(timer);
45
+ fn();
46
+ }, ms);
47
+ if (!keepProcessAlive)
48
+ timer.unref?.();
49
+ armed.add(timer);
50
+ return timer;
51
+ }
52
+ function disarm(timer) {
53
+ if (timer === undefined)
54
+ return;
55
+ clearTimeout(timer);
56
+ armed.delete(timer);
57
+ }
58
+ function take(callId, sessionId) {
59
+ const ttlTimer = arm(() => {
60
+ if (!held.has(callId))
61
+ return;
62
+ ttlReclaimedCount += 1;
63
+ warn(`fanout-ceiling: permit TTL expired for call=${callId} session=${sessionId} after ` +
64
+ `${permitTtlMs}ms — force-releasing. A task held a slot longer than any healthy ` +
65
+ `sub-agent turn; the pool would otherwise have shrunk permanently.`);
66
+ release(callId, 'ttl');
67
+ }, permitTtlMs, false);
68
+ held.set(callId, { sessionId, acquiredAt: now(), ttlTimer });
69
+ }
70
+ function release(callId, reason) {
71
+ const permit = held.get(callId);
72
+ if (permit === undefined)
73
+ return;
74
+ disarm(permit.ttlTimer);
75
+ held.delete(callId);
76
+ if (reason !== 'completed') {
77
+ debug(`fanout-ceiling: reclaimed call=${callId} via ${reason} ` +
78
+ `(held ${now() - permit.acquiredAt}ms)`);
79
+ }
80
+ drain();
81
+ }
82
+ function drain() {
83
+ while (waiters.length > 0 && held.size < limit) {
84
+ const next = waiters.shift();
85
+ if (next === undefined)
86
+ return;
87
+ disarm(next.timer);
88
+ const waitedMs = now() - next.since;
89
+ waitedCount += 1;
90
+ take(next.callId, next.sessionId);
91
+ info(`fanout-ceiling: admitted call=${next.callId} session=${next.sessionId} after waiting ` +
92
+ `${waitedMs}ms (limit=${limit}, in-flight=${held.size}, still waiting=${waiters.length})`);
93
+ next.grant();
94
+ }
95
+ }
96
+ async function before(input) {
97
+ if (input.tool !== TASK_TOOL_ID)
98
+ return;
99
+ const { callID: callId, sessionID: sessionId } = input;
100
+ if (held.size < limit) {
101
+ take(callId, sessionId);
102
+ debug(`fanout-ceiling: admitted call=${callId} immediately ` +
103
+ `(in-flight=${held.size}/${limit})`);
104
+ return;
105
+ }
106
+ const since = now();
107
+ warn(`fanout-ceiling: sub-agent fan-out at ceiling — call=${callId} session=${sessionId} is ` +
108
+ `WAITING (limit=${limit}, in-flight=${held.size}, already waiting=${waiters.length}). ` +
109
+ `This is backpressure, not a refusal: the task will start when a slot frees.`);
110
+ await new Promise((resolve) => {
111
+ const waiter = {
112
+ callId,
113
+ sessionId,
114
+ since,
115
+ grant: resolve,
116
+ timer: undefined,
117
+ };
118
+ waiter.timer = arm(() => {
119
+ const idx = waiters.indexOf(waiter);
120
+ if (idx === -1)
121
+ return;
122
+ waiters.splice(idx, 1);
123
+ timedOutCount += 1;
124
+ warn(`fanout-ceiling: call=${callId} session=${sessionId} waited ${waitTimeoutMs}ms and is ` +
125
+ `being ADMITTED OVER the ceiling (limit=${limit}, in-flight=${held.size}). The pool ` +
126
+ `did not free a slot in that window — suspect a leaked permit or a stuck sub-agent.`);
127
+ take(callId, sessionId);
128
+ resolve();
129
+ }, waitTimeoutMs, true);
130
+ waiters.push(waiter);
131
+ });
132
+ }
133
+ function after(input) {
134
+ if (input.tool !== TASK_TOOL_ID)
135
+ return;
136
+ release(input.callID, 'completed');
137
+ }
138
+ function onSessionIdle(sessionId) {
139
+ const stale = [];
140
+ for (const [callId, permit] of held) {
141
+ if (permit.sessionId === sessionId)
142
+ stale.push(callId);
143
+ }
144
+ if (stale.length === 0)
145
+ return;
146
+ sweptCount += stale.length;
147
+ warn(`fanout-ceiling: session=${sessionId} went idle still holding ${stale.length} permit(s) ` +
148
+ `[${stale.join(', ')}] — reclaiming. These tasks ended without a tool.execute.after, ` +
149
+ `which upstream does not fire on the failure path.`);
150
+ for (const callId of stale)
151
+ release(callId, 'session-idle');
152
+ }
153
+ function dispose() {
154
+ const parked = waiters.length;
155
+ const outstanding = held.size;
156
+ while (waiters.length > 0) {
157
+ const w = waiters.shift();
158
+ if (w === undefined)
159
+ break;
160
+ disarm(w.timer);
161
+ w.grant();
162
+ }
163
+ for (const permit of held.values())
164
+ disarm(permit.ttlTimer);
165
+ held.clear();
166
+ if (parked > 0 || outstanding > 0) {
167
+ info(`fanout-ceiling: disposed — released ${parked} parked task(s) and disarmed ` +
168
+ `${outstanding} permit timer(s).`);
169
+ }
170
+ }
171
+ return {
172
+ before,
173
+ after,
174
+ onSessionIdle,
175
+ dispose,
176
+ stats: () => ({
177
+ limit,
178
+ inFlight: held.size,
179
+ waiting: waiters.length,
180
+ waitedCount,
181
+ timedOutCount,
182
+ sweptCount,
183
+ ttlReclaimedCount,
184
+ armedTimers: armed.size,
185
+ }),
186
+ };
187
+ }
188
+ //# sourceMappingURL=subagent-fanout-ceiling.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"subagent-fanout-ceiling.js","sourceRoot":"","sources":["../../src/hooks/subagent-fanout-ceiling.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -2,8 +2,8 @@ import type { Plugin } from './opencode-types.js';
2
2
  export declare const XemaPlugin: Plugin;
3
3
  export declare function __resetBootCacheForTests(): void;
4
4
  export default XemaPlugin;
5
+ export { createSubagentFanoutCeiling, resolveSubagentFanoutLimit, DEFAULT_SUBAGENT_FANOUT_LIMIT, DEFAULT_FANOUT_WAIT_TIMEOUT_MS, DEFAULT_PERMIT_TTL_MS, FANOUT_LIMIT_ENV, TASK_TOOL_ID, type SubagentFanoutCeiling, type FanoutCeilingOptions, type FanoutCeilingStats, } from './hooks/subagent-fanout-ceiling.js';
5
6
  export { readInvocationContext } from './context.js';
6
7
  export type { InvocationContext, InvocationRole } from './context.js';
7
8
  export * from './errors.js';
8
- export { loadSessionState, loadSessionStateForTool, ensureRoleAllowed, ContextMissingError, RoleNotAllowedError, type SessionState, } from './session-state.js';
9
9
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AA0CA,OAAO,KAAK,EAAS,MAAM,EAAkB,MAAM,qBAAqB,CAAC;AAuBzE,eAAO,MAAM,UAAU,EAAE,MAgBxB,CAAC;AA+BF,wBAAgB,wBAAwB,IAAI,IAAI,CAE/C;AAyBD,eAAe,UAAU,CAAC;AAG1B,OAAO,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AACrD,YAAY,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACtE,cAAc,aAAa,CAAC;AAC5B,OAAO,EACL,gBAAgB,EAChB,uBAAuB,EACvB,iBAAiB,EACjB,mBAAmB,EACnB,mBAAmB,EACnB,KAAK,YAAY,GAClB,MAAM,oBAAoB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAqFA,OAAO,KAAK,EAIV,MAAM,EACP,MAAM,qBAAqB,CAAC;AAkB7B,eAAO,MAAM,UAAU,EAAE,MAgBxB,CAAC;AAmFF,wBAAgB,wBAAwB,IAAI,IAAI,CAE/C;AA2BD,eAAe,UAAU,CAAC;AAG1B,OAAO,EACL,2BAA2B,EAC3B,0BAA0B,EAC1B,6BAA6B,EAC7B,8BAA8B,EAC9B,qBAAqB,EACrB,gBAAgB,EAChB,YAAY,EACZ,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,EACzB,KAAK,kBAAkB,GACxB,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AACrD,YAAY,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACtE,cAAc,aAAa,CAAC"}
package/dist/index.js CHANGED
@@ -1,9 +1,9 @@
1
1
  import { existsSync } from 'node:fs';
2
2
  import { join } from 'node:path';
3
3
  import { buildSessionIdleAutocommit } from './hooks/session-idle-autocommit.js';
4
+ import { createSubagentFanoutCeiling, resolveSubagentFanoutLimit, } from './hooks/subagent-fanout-ceiling.js';
4
5
  import { buildSystemPromptOverlay } from './hooks/system-prompt-overlay.js';
5
- import { info, isDebug } from './logger.js';
6
- import { buildXemaMemoryGetTool, buildXemaMemorySetTool, } from './tools/xema-memory.js';
6
+ import { info, isDebug, warn } from './logger.js';
7
7
  const bootCache = new Map();
8
8
  export const XemaPlugin = async (ctx) => {
9
9
  const { directory } = ctx;
@@ -22,31 +22,52 @@ export const XemaPlugin = async (ctx) => {
22
22
  }
23
23
  };
24
24
  async function doBoot(directory) {
25
- const tools = buildAllTools(directory);
26
- const toolNames = Object.keys(tools).sort((a, b) => a.localeCompare(b));
27
25
  const contextPath = join(directory, 'context.json');
28
26
  const contextPresentAtBoot = existsSync(contextPath);
29
- info(`boot: directory=${directory} tools=${toolNames.length} [${toolNames.join(', ')}] ` +
27
+ info(`boot: directory=${directory} tools=0 (hooks only) ` +
30
28
  `context.json=${contextPresentAtBoot ? 'present' : 'absent'} ` +
31
29
  `debug=${isDebug() ? 'on' : 'off'}`);
30
+ const fanoutLimit = resolveSubagentFanoutLimit();
31
+ const fanout = createSubagentFanoutCeiling({ limit: fanoutLimit });
32
+ const autocommit = buildSessionIdleAutocommit(directory);
33
+ info(`boot: subagent fan-out ceiling active (limit=${fanoutLimit} concurrent task calls ` +
34
+ `per worker; tighten with XEMA_SUBAGENT_FANOUT_LIMIT)`);
32
35
  const hooks = {
33
- tool: tools,
34
36
  'experimental.chat.system.transform': buildSystemPromptOverlay(directory),
35
- event: buildSessionIdleAutocommit(directory),
37
+ 'tool.execute.before': async (input) => {
38
+ await fanout.before(input);
39
+ },
40
+ 'tool.execute.after': (input) => {
41
+ fanout.after(input);
42
+ },
43
+ dispose: async () => {
44
+ fanout.dispose();
45
+ },
46
+ event: async (input) => {
47
+ const evt = input.event;
48
+ if (evt.type === 'session.idle') {
49
+ const sessionId = evt.properties
50
+ ?.sessionID;
51
+ if (sessionId) {
52
+ try {
53
+ fanout.onSessionIdle(sessionId);
54
+ }
55
+ catch (err) {
56
+ const message = err instanceof Error ? err.message : String(err);
57
+ warn(`fanout-ceiling: session-idle sweep failed: ${message}`);
58
+ }
59
+ }
60
+ }
61
+ await autocommit(input);
62
+ },
36
63
  };
37
64
  return hooks;
38
65
  }
39
66
  export function __resetBootCacheForTests() {
40
67
  bootCache.clear();
41
68
  }
42
- function buildAllTools(workspaceDir) {
43
- return {
44
- xema_memory_set: buildXemaMemorySetTool(workspaceDir),
45
- xema_memory_get: buildXemaMemoryGetTool(workspaceDir),
46
- };
47
- }
48
69
  export default XemaPlugin;
70
+ export { createSubagentFanoutCeiling, resolveSubagentFanoutLimit, DEFAULT_SUBAGENT_FANOUT_LIMIT, DEFAULT_FANOUT_WAIT_TIMEOUT_MS, DEFAULT_PERMIT_TTL_MS, FANOUT_LIMIT_ENV, TASK_TOOL_ID, } from './hooks/subagent-fanout-ceiling.js';
49
71
  export { readInvocationContext } from './context.js';
50
72
  export * from './errors.js';
51
- export { loadSessionState, loadSessionStateForTool, ensureRoleAllowed, ContextMissingError, RoleNotAllowedError, } from './session-state.js';
52
73
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAoCA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,OAAO,EAAE,0BAA0B,EAAE,MAAM,oCAAoC,CAAC;AAChF,OAAO,EAAE,wBAAwB,EAAE,MAAM,kCAAkC,CAAC;AAC5E,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAG5C,OAAO,EACL,sBAAsB,EACtB,sBAAsB,GACvB,MAAM,wBAAwB,CAAC;AAgBhC,MAAM,SAAS,GAAG,IAAI,GAAG,EAA0B,CAAC;AAEpD,MAAM,CAAC,MAAM,UAAU,GAAW,KAAK,EAAE,GAAG,EAAE,EAAE;IAC9C,MAAM,EAAE,SAAS,EAAE,GAAG,GAAG,CAAC;IAC1B,MAAM,MAAM,GAAG,SAAS,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IACxC,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QACzB,OAAO,MAAM,CAAC;IAChB,CAAC;IACD,MAAM,OAAO,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC;IAClC,SAAS,CAAC,GAAG,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;IAClC,IAAI,CAAC;QACH,OAAO,MAAM,OAAO,CAAC;IACvB,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QAGb,SAAS,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QAC5B,MAAM,GAAG,CAAC;IACZ,CAAC;AACH,CAAC,CAAC;AAEF,KAAK,UAAU,MAAM,CAAC,SAAiB;IACrC,MAAM,KAAK,GAAG,aAAa,CAAC,SAAS,CAAC,CAAC;IACvC,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC;IACxE,MAAM,WAAW,GAAG,IAAI,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC;IACpD,MAAM,oBAAoB,GAAG,UAAU,CAAC,WAAW,CAAC,CAAC;IAErD,IAAI,CACF,mBAAmB,SAAS,UAAU,SAAS,CAAC,MAAM,KAAK,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI;QACjF,gBAAgB,oBAAoB,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,GAAG;QAC9D,SAAS,OAAO,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,EAAE,CACtC,CAAC;IAEF,MAAM,KAAK,GAAU;QACnB,IAAI,EAAE,KAAK;QACX,oCAAoC,EAAE,wBAAwB,CAAC,SAAS,CAAC;QAMzE,KAAK,EAAE,0BAA0B,CAAC,SAAS,CAAC;KAC7C,CAAC;IACF,OAAO,KAAK,CAAC;AACf,CAAC;AAMD,MAAM,UAAU,wBAAwB;IACtC,SAAS,CAAC,KAAK,EAAE,CAAC;AACpB,CAAC;AAED,SAAS,aAAa,CAAC,YAAoB;IACzC,OAAO;QACL,eAAe,EAAE,sBAAsB,CAAC,YAAY,CAAC;QACrD,eAAe,EAAE,sBAAsB,CAAC,YAAY,CAAC;KAiBtD,CAAC;AACJ,CAAC;AAED,eAAe,UAAU,CAAC;AAG1B,OAAO,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AAErD,cAAc,aAAa,CAAC;AAC5B,OAAO,EACL,gBAAgB,EAChB,uBAAuB,EACvB,iBAAiB,EACjB,mBAAmB,EACnB,mBAAmB,GAEpB,MAAM,oBAAoB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -1,21 +1,3 @@
1
- import type { z } from 'zod';
2
- interface ToolContext {
3
- sessionID: string;
4
- messageID: string;
5
- agent: string;
6
- directory: string;
7
- worktree: string;
8
- abort: AbortSignal;
9
- metadata(input: {
10
- title?: string;
11
- metadata?: Record<string, unknown>;
12
- }): void;
13
- }
14
- export interface ToolDefinition<Args extends z.ZodRawShape = z.ZodRawShape> {
15
- description: string;
16
- args: Args;
17
- execute(args: z.infer<z.ZodObject<Args>>, context: ToolContext): Promise<string>;
18
- }
19
1
  export interface ExperimentalChatModel {
20
2
  providerID?: string;
21
3
  modelID?: string;
@@ -37,8 +19,21 @@ export type OpencodeEvent = OpencodeSessionIdleEvent | {
37
19
  type: string;
38
20
  properties?: Record<string, unknown>;
39
21
  };
22
+ export interface ToolExecuteHookInput {
23
+ tool: string;
24
+ sessionID: string;
25
+ callID: string;
26
+ }
40
27
  export interface Hooks {
41
- tool?: Record<string, ToolDefinition>;
28
+ dispose?: () => Promise<void>;
29
+ 'tool.execute.before'?: (input: ToolExecuteHookInput, output: {
30
+ args: unknown;
31
+ }) => Promise<void> | void;
32
+ 'tool.execute.after'?: (input: ToolExecuteHookInput, output: {
33
+ title: string;
34
+ output: string;
35
+ metadata: unknown;
36
+ }) => Promise<void> | void;
42
37
  'experimental.chat.system.transform'?: (input: ExperimentalChatSystemTransformInput, output: ExperimentalChatSystemTransformOutput) => Promise<void> | void;
43
38
  event?: (input: {
44
39
  event: OpencodeEvent;
@@ -50,6 +45,5 @@ interface PluginInput {
50
45
  serverUrl: URL;
51
46
  }
52
47
  export type Plugin = (input: PluginInput) => Promise<Hooks>;
53
- export declare function tool<Args extends z.ZodRawShape>(input: ToolDefinition<Args>): ToolDefinition<Args>;
54
48
  export {};
55
49
  //# sourceMappingURL=opencode-types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"opencode-types.d.ts","sourceRoot":"","sources":["../src/opencode-types.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAE7B,UAAU,WAAW;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,WAAW,CAAC;IACnB,QAAQ,CAAC,KAAK,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,GAAG,IAAI,CAAC;CAC/E;AAED,MAAM,WAAW,cAAc,CAAC,IAAI,SAAS,CAAC,CAAC,WAAW,GAAG,CAAC,CAAC,WAAW;IACxE,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,IAAI,CAAC;IACX,OAAO,CACL,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,EAChC,OAAO,EAAE,WAAW,GACnB,OAAO,CAAC,MAAM,CAAC,CAAC;CACpB;AAQD,MAAM,WAAW,qBAAqB;IACpC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,oCAAoC;IACnD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,qBAAqB,CAAC;CAC9B;AAED,MAAM,WAAW,qCAAqC;IACpD,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAUD,MAAM,MAAM,wBAAwB,GAAG;IACrC,IAAI,EAAE,cAAc,CAAC;IACrB,UAAU,EAAE;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC;CACnC,CAAC;AAEF,MAAM,MAAM,aAAa,GACrB,wBAAwB,GACxB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,CAAC;AAE3D,MAAM,WAAW,KAAK;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IAOtC,oCAAoC,CAAC,EAAE,CACrC,KAAK,EAAE,oCAAoC,EAC3C,MAAM,EAAE,qCAAqC,KAC1C,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAQ1B,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE;QAAE,KAAK,EAAE,aAAa,CAAA;KAAE,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;CACnE;AAED,UAAU,WAAW;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,GAAG,CAAC;CAChB;AAED,MAAM,MAAM,MAAM,GAAG,CAAC,KAAK,EAAE,WAAW,KAAK,OAAO,CAAC,KAAK,CAAC,CAAC;AAO5D,wBAAgB,IAAI,CAAC,IAAI,SAAS,CAAC,CAAC,WAAW,EAC7C,KAAK,EAAE,cAAc,CAAC,IAAI,CAAC,GAC1B,cAAc,CAAC,IAAI,CAAC,CAEtB"}
1
+ {"version":3,"file":"opencode-types.d.ts","sourceRoot":"","sources":["../src/opencode-types.ts"],"names":[],"mappings":"AAuBA,MAAM,WAAW,qBAAqB;IACpC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,oCAAoC;IACnD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,qBAAqB,CAAC;CAC9B;AAED,MAAM,WAAW,qCAAqC;IACpD,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAUD,MAAM,MAAM,wBAAwB,GAAG;IACrC,IAAI,EAAE,cAAc,CAAC;IACrB,UAAU,EAAE;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC;CACnC,CAAC;AAEF,MAAM,MAAM,aAAa,GACrB,wBAAwB,GACxB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,CAAC;AAY3D,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,KAAK;IAOpB,OAAO,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAU9B,qBAAqB,CAAC,EAAE,CACtB,KAAK,EAAE,oBAAoB,EAC3B,MAAM,EAAE;QAAE,IAAI,EAAE,OAAO,CAAA;KAAE,KACtB,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAO1B,oBAAoB,CAAC,EAAE,CACrB,KAAK,EAAE,oBAAoB,EAC3B,MAAM,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,OAAO,CAAA;KAAE,KACzD,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAO1B,oCAAoC,CAAC,EAAE,CACrC,KAAK,EAAE,oCAAoC,EAC3C,MAAM,EAAE,qCAAqC,KAC1C,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAQ1B,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE;QAAE,KAAK,EAAE,aAAa,CAAA;KAAE,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;CACnE;AAED,UAAU,WAAW;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,GAAG,CAAC;CAChB;AAED,MAAM,MAAM,MAAM,GAAG,CAAC,KAAK,EAAE,WAAW,KAAK,OAAO,CAAC,KAAK,CAAC,CAAC"}
@@ -1,4 +1,2 @@
1
- export function tool(input) {
2
- return input;
3
- }
1
+ export {};
4
2
  //# sourceMappingURL=opencode-types.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"opencode-types.js","sourceRoot":"","sources":["../src/opencode-types.ts"],"names":[],"mappings":"AAsGA,MAAM,UAAU,IAAI,CAClB,KAA2B;IAE3B,OAAO,KAAK,CAAC;AACf,CAAC"}
1
+ {"version":3,"file":"opencode-types.js","sourceRoot":"","sources":["../src/opencode-types.ts"],"names":[],"mappings":""}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@xemahq/opencode-xema-plugin",
3
- "version": "0.1.13",
4
- "description": "Opencode plugin providing Xema-namespaced runtime tools (xema_memory_*) and the dynamic system-prompt overlay hook.",
3
+ "version": "0.3.0",
4
+ "description": "Opencode plugin providing the Xema dynamic system-prompt overlay hook, the per-turn session.idle auto-commit, and the sub-agent fan-out ceiling. Contributes no tools.",
5
5
  "license": "Apache-2.0",
6
6
  "author": "Neuralchowder Inc. <developer@xema.dev> (https://xema.dev)",
7
7
  "homepage": "https://xema.dev",
@@ -24,8 +24,7 @@
24
24
  ],
25
25
  "peerDependencies": {
26
26
  "@opencode-ai/plugin": "^1.0.0",
27
- "zod": "^4.0.0",
28
- "@xemahq/kernel-contracts": ">=12.0.0"
27
+ "zod": "^4.0.0"
29
28
  },
30
29
  "devDependencies": {
31
30
  "@opencode-ai/plugin": "^1.15.10",
@@ -33,7 +32,7 @@
33
32
  "esbuild": "^0.25.4",
34
33
  "typescript": "5.9.3",
35
34
  "zod": "^4.3.6",
36
- "@xemahq/kernel-contracts": "^19.0.0"
35
+ "@xemahq/contracts": "^0.1.0"
37
36
  },
38
37
  "exports": {
39
38
  ".": {