@skillstate/core 0.0.1 → 2.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.
Files changed (88) hide show
  1. package/dist/atomic-write.d.ts +40 -0
  2. package/dist/atomic-write.d.ts.map +1 -0
  3. package/dist/atomic-write.js +97 -0
  4. package/dist/atomic-write.js.map +1 -0
  5. package/dist/clock.d.ts +27 -0
  6. package/dist/clock.d.ts.map +1 -0
  7. package/dist/clock.js +45 -0
  8. package/dist/clock.js.map +1 -0
  9. package/dist/config.d.ts +43 -0
  10. package/dist/config.d.ts.map +1 -0
  11. package/dist/config.js +152 -0
  12. package/dist/config.js.map +1 -0
  13. package/dist/events.d.ts +59 -0
  14. package/dist/events.d.ts.map +1 -0
  15. package/dist/events.js +36 -0
  16. package/dist/events.js.map +1 -0
  17. package/dist/index.d.ts +20 -0
  18. package/dist/index.d.ts.map +1 -0
  19. package/dist/index.js +28 -0
  20. package/dist/index.js.map +1 -0
  21. package/dist/instrumentation.d.ts +35 -0
  22. package/dist/instrumentation.d.ts.map +1 -0
  23. package/dist/instrumentation.js +41 -0
  24. package/dist/instrumentation.js.map +1 -0
  25. package/dist/logger.d.ts +34 -0
  26. package/dist/logger.d.ts.map +1 -0
  27. package/dist/logger.js +40 -0
  28. package/dist/logger.js.map +1 -0
  29. package/dist/migrations.d.ts +35 -0
  30. package/dist/migrations.d.ts.map +1 -0
  31. package/dist/migrations.js +26 -0
  32. package/dist/migrations.js.map +1 -0
  33. package/dist/prompt-transformer.d.ts +106 -0
  34. package/dist/prompt-transformer.d.ts.map +1 -0
  35. package/dist/prompt-transformer.js +265 -0
  36. package/dist/prompt-transformer.js.map +1 -0
  37. package/dist/provider.d.ts +62 -0
  38. package/dist/provider.d.ts.map +1 -0
  39. package/dist/provider.js +46 -0
  40. package/dist/provider.js.map +1 -0
  41. package/dist/redaction.d.ts +26 -0
  42. package/dist/redaction.d.ts.map +1 -0
  43. package/dist/redaction.js +38 -0
  44. package/dist/redaction.js.map +1 -0
  45. package/dist/resilience.d.ts +83 -0
  46. package/dist/resilience.d.ts.map +1 -0
  47. package/dist/resilience.js +171 -0
  48. package/dist/resilience.js.map +1 -0
  49. package/dist/runtime.d.ts +223 -0
  50. package/dist/runtime.d.ts.map +1 -0
  51. package/dist/runtime.js +362 -0
  52. package/dist/runtime.js.map +1 -0
  53. package/dist/schemas/index.d.ts +2 -0
  54. package/dist/schemas/index.d.ts.map +1 -0
  55. package/dist/schemas/index.js +3 -0
  56. package/dist/schemas/index.js.map +1 -0
  57. package/dist/schemas/intercode-ctf.d.ts +3 -0
  58. package/dist/schemas/intercode-ctf.d.ts.map +1 -0
  59. package/dist/schemas/intercode-ctf.js +53 -0
  60. package/dist/schemas/intercode-ctf.js.map +1 -0
  61. package/dist/shutdown.d.ts +20 -0
  62. package/dist/shutdown.d.ts.map +1 -0
  63. package/dist/shutdown.js +42 -0
  64. package/dist/shutdown.js.map +1 -0
  65. package/dist/state-manager.d.ts +23 -0
  66. package/dist/state-manager.d.ts.map +1 -0
  67. package/dist/state-manager.js +129 -0
  68. package/dist/state-manager.js.map +1 -0
  69. package/dist/state-store.d.ts +48 -0
  70. package/dist/state-store.d.ts.map +1 -0
  71. package/dist/state-store.js +101 -0
  72. package/dist/state-store.js.map +1 -0
  73. package/dist/token-tracker.d.ts +104 -0
  74. package/dist/token-tracker.d.ts.map +1 -0
  75. package/dist/token-tracker.js +204 -0
  76. package/dist/token-tracker.js.map +1 -0
  77. package/dist/types.d.ts +61 -0
  78. package/dist/types.d.ts.map +1 -0
  79. package/dist/types.js +2 -0
  80. package/dist/types.js.map +1 -0
  81. package/dist/validate.d.ts +39 -0
  82. package/dist/validate.d.ts.map +1 -0
  83. package/dist/validate.js +180 -0
  84. package/dist/validate.js.map +1 -0
  85. package/package.json +21 -5
  86. package/LICENSE +0 -21
  87. package/README.md +0 -11
  88. package/index.js +0 -3
@@ -0,0 +1,362 @@
1
+ import { StateManager } from './state-manager.js';
2
+ import { PromptTransformer } from './prompt-transformer.js';
3
+ import { withRetry, withTimeout } from './resilience.js';
4
+ import { clone } from './clock.js';
5
+ /**
6
+ * @non-paper rejection reason when `run()` trips a char budget. Carries
7
+ * the committed prefix (`partialResults`, WITHOUT the exceeding step —
8
+ * the trip rolls its state and tracker entry back) so callers can resume
9
+ * or report deterministically.
10
+ */
11
+ export class BudgetExceededError extends Error {
12
+ maxChars;
13
+ totalChars;
14
+ partialResults;
15
+ constructor(maxChars, totalChars, partialResults) {
16
+ super(`Char budget exceeded: ${totalChars} > ${maxChars}`);
17
+ this.name = 'BudgetExceededError';
18
+ this.maxChars = maxChars;
19
+ this.totalChars = totalChars;
20
+ this.partialResults = partialResults;
21
+ }
22
+ }
23
+ /** Deterministic fallback action when the patch is rejected after all retries. */
24
+ const INVALID_PATCH_ACTION = '__invalid_patch__';
25
+ const DEFAULT_MAX_VALIDATION_RETRIES = 2;
26
+ const DEFAULT_MAX_STEPS = 100;
27
+ const FENCE_MARKER = '```json';
28
+ /**
29
+ * @non-paper: `withTimeout` needs a numeric deadline, so signal-only waits
30
+ * use the max setTimeout delay — effectively no timeout. The timer is
31
+ * cleared on settle, so the process never actually waits this long.
32
+ */
33
+ const SIGNAL_ONLY_TIMEOUT_MS = 0x7fffffff;
34
+ /**
35
+ * Reasoning (Rt) is everything before the response's JSON fence. It is
36
+ * returned to the caller but NEVER stored in state (§3.2: Rt discarded
37
+ * permanently). Only called on responses that parsed successfully, so the
38
+ * fence exists.
39
+ */
40
+ function extractReasoning(response) {
41
+ return response.slice(0, response.indexOf(FENCE_MARKER)).trim();
42
+ }
43
+ /**
44
+ * Re-prompt after a failed attempt (paper §7): same prompt plus corrective
45
+ * feedback appended. Malformed outputs cannot corrupt Σt (Limitations) —
46
+ * the state is only ever replaced by a validated merge.
47
+ */
48
+ function withRetryFeedback(prompt, reason) {
49
+ return `${prompt}\n\nYour previous response was invalid: ${reason}. Respond again. Reasoning is discarded; respond with the JSON block with exactly these two keys: state_patch and action.`;
50
+ }
51
+ /**
52
+ * Algorithm 1 runtime (paper §3.2) with the §7 rollback-retry cycle.
53
+ *
54
+ * Each step: format the paper-exact prompt At = (P, Σt, Ot), call the LLM,
55
+ * parse the response (Rt, ΔΣt, at), validate ΔΣt against the schema, merge
56
+ * it (Σt+1 = Σt ⊕ ΔΣt), and execute the action. The model never receives
57
+ * previous observations, actions, or reasoning (§3). Failed attempts
58
+ * re-prompt with corrective feedback; after exhausting retries the step
59
+ * fails deterministically — the state is left untouched and the action
60
+ * becomes `__invalid_patch__`.
61
+ *
62
+ * Reasoning is returned but never stored, and merged states are fresh
63
+ * objects, so a rejected patch can never leak into state (rollback is free).
64
+ */
65
+ export class SkillStateRuntime {
66
+ spec;
67
+ llm;
68
+ execute;
69
+ tracker;
70
+ maxValidationRetries;
71
+ timeoutMs;
72
+ signal;
73
+ retry;
74
+ clock;
75
+ events;
76
+ logger;
77
+ tokenBudget;
78
+ charsBudget;
79
+ transformer = new PromptTransformer();
80
+ currentState;
81
+ stepCounter = 0;
82
+ constructor(options) {
83
+ this.spec = options.spec;
84
+ this.llm = options.llm;
85
+ this.execute = options.execute;
86
+ this.tracker = options.tracker;
87
+ this.maxValidationRetries =
88
+ options.maxValidationRetries ?? DEFAULT_MAX_VALIDATION_RETRIES;
89
+ this.timeoutMs = options.timeoutMs;
90
+ this.signal = options.signal;
91
+ this.retry = options.retry;
92
+ this.clock = options.clock;
93
+ this.events = options.events;
94
+ this.logger = options.logger;
95
+ this.tokenBudget = options.tokenBudget;
96
+ this.charsBudget = options.charsBudget;
97
+ this.currentState = options.initialState
98
+ ? structuredClone(options.initialState)
99
+ : StateManager.createInitialState(options.spec.schema);
100
+ }
101
+ /** Current state Σt (read-only copy). */
102
+ get state() {
103
+ return structuredClone(this.currentState);
104
+ }
105
+ /**
106
+ * @non-paper resilience wrapper (additive, opt-in).
107
+ *
108
+ * Paper path: no `timeoutMs`/`signal`/`retry` options — `fn` is invoked
109
+ * directly, byte-for-byte the paper behavior (no timer, no extra attempt).
110
+ * Resilience path: the call is threaded through `withTimeout` (deadline
111
+ * and/or abort) and, when `retry` is set, transient throws are re-issued
112
+ * via `withRetry`. Validation-retry (§7) semantics above this are
113
+ * unchanged: a TRANSPORT throw still propagates out of `step` exactly as
114
+ * a throwing `llm`/`execute` did before.
115
+ */
116
+ invokeResilient(fn) {
117
+ if (this.timeoutMs === undefined &&
118
+ this.signal === undefined &&
119
+ this.retry === undefined) {
120
+ return fn();
121
+ }
122
+ const attempt = () => {
123
+ const pending = fn();
124
+ if (this.timeoutMs === undefined && this.signal === undefined) {
125
+ return pending;
126
+ }
127
+ return withTimeout(pending, this.timeoutMs ?? SIGNAL_ONLY_TIMEOUT_MS, this.signal);
128
+ };
129
+ if (this.retry === undefined) {
130
+ return attempt();
131
+ }
132
+ return withRetry(attempt, this.retry);
133
+ }
134
+ /**
135
+ * @non-paper LLM dispatch (Wave 4 DX, additive).
136
+ *
137
+ * Paper path: `llm` is a legacy `LLMFn` — called verbatim with the
138
+ * prompt, exactly as before. Provider path: `llm.call(prompt, opts?)`
139
+ * is used instead, forwarding the runtime `signal?` so aborts reach
140
+ * the provider; both paths stay inside `invokeResilient`, so the
141
+ * `timeoutMs`/`signal`/`retry` transport semantics are identical.
142
+ */
143
+ invokeLLM(prompt) {
144
+ const llm = this.llm;
145
+ if (typeof llm === 'function') {
146
+ return this.invokeResilient(async () => ({ text: await llm(prompt) }));
147
+ }
148
+ const opts = this.signal !== undefined ? { signal: this.signal } : undefined;
149
+ return this.invokeResilient(() => llm.call(prompt, opts));
150
+ }
151
+ /**
152
+ * @non-paper timestamp source: injected `clock` or `Date.now()`.
153
+ * The default path is exactly the paper core's `Date.now()`.
154
+ */
155
+ now() {
156
+ return this.clock?.now() ?? Date.now();
157
+ }
158
+ /** @non-paper: first defined budget cap wins (run-level beats ctor-level). */
159
+ resolveMaxChars(runOpts) {
160
+ return (runOpts?.maxChars ??
161
+ runOpts?.tokenBudget?.maxChars ??
162
+ runOpts?.charsBudget?.maxChars ??
163
+ this.tokenBudget?.maxChars ??
164
+ this.charsBudget?.maxChars);
165
+ }
166
+ /** @non-paper: tracker total when tracked, local tally otherwise. */
167
+ currentTotalChars(localTotal) {
168
+ return this.tracker?.getBookkeeping().totalChars ?? localTotal;
169
+ }
170
+ /**
171
+ * Execute one Algorithm 1 step for observation Ot.
172
+ *
173
+ * Paper-exact Algorithm 1 + §7 rollback-retry; the @non-paper
174
+ * `events`/`logger` options only OBSERVE (emitted payloads never feed
175
+ * back into prompts, merges, or validation).
176
+ */
177
+ async step(observation) {
178
+ this.stepCounter += 1;
179
+ const stepNumber = this.stepCounter;
180
+ this.events?.emit('step:start', { step: stepNumber, observation });
181
+ try {
182
+ // 1. Construct the prompt At = (P, Σt, Ot) — paper-exact format.
183
+ // The observation is passed through verbatim: no trimming, no size
184
+ // rejection. The O(1) footprint is a property of the method (no
185
+ // history is ever re-sent), not of input caps.
186
+ const basePrompt = this.transformer.formatPaper(this.spec, this.currentState, observation);
187
+ const maxAttempts = 1 + this.maxValidationRetries;
188
+ let prompt = basePrompt;
189
+ let response = '';
190
+ let lastError = '';
191
+ let attempts = 0;
192
+ let accepted = null;
193
+ let responseChars = 0;
194
+ let promptCharsOverride;
195
+ // 2-4. Call the LLM, parse, validate — retrying with corrective feedback
196
+ // on parse or validation failure (§7 rollback-retry cycle).
197
+ while (attempts < maxAttempts) {
198
+ attempts += 1;
199
+ const produced = await this.invokeLLM(prompt);
200
+ response = produced.text;
201
+ const usage = produced.usage;
202
+ if (promptCharsOverride === undefined && usage?.promptChars !== undefined) {
203
+ promptCharsOverride = usage.promptChars;
204
+ }
205
+ responseChars += usage?.completionChars ?? response.length;
206
+ const parsed = this.transformer.parseResponse(response);
207
+ if (parsed.ok) {
208
+ const validation = StateManager.validatePatch(this.spec.schema, parsed.patch);
209
+ if (validation.valid) {
210
+ accepted = {
211
+ patch: parsed.patch,
212
+ action: parsed.action,
213
+ reasoning: extractReasoning(response),
214
+ };
215
+ break;
216
+ }
217
+ else {
218
+ lastError = validation.error;
219
+ }
220
+ }
221
+ else {
222
+ lastError = parsed.detail ?? parsed.reason;
223
+ }
224
+ prompt = withRetryFeedback(basePrompt, lastError);
225
+ }
226
+ // 5. On success: Σt+1 = Σt ⊕ ΔΣt. On exhaustion: state UNCHANGED —
227
+ // immutability makes rollback free (there is nothing to undo).
228
+ const invalidated = accepted === null;
229
+ const patch = accepted === null ? {} : accepted.patch;
230
+ const action = accepted === null ? INVALID_PATCH_ACTION : accepted.action;
231
+ const reasoning = accepted === null ? '' : accepted.reasoning;
232
+ const newState = accepted === null
233
+ ? this.currentState
234
+ : StateManager.mergeState(this.currentState, accepted.patch);
235
+ // 6. Execute at → new observation (synthesized error observation on
236
+ // exhaustion; the sentinel action is never executed).
237
+ const newObservation = accepted === null
238
+ ? {
239
+ content: `Invalid state patch after ${attempts} attempts: ${lastError}`,
240
+ timestamp: this.now(),
241
+ source: 'skillstate',
242
+ }
243
+ : await this.invokeResilient(() => this.execute(action, newState));
244
+ // 7. Record the step in the tracker. Sizes are raw string CHARS (§4.3):
245
+ // promptChars is |At| — measured, unless a provider reported
246
+ // `usage.promptChars` (preferred verbatim); responseChars accumulates
247
+ // every attempt's raw response (`usage.completionChars` when reported).
248
+ // No tokenizer, no estimates, no retry-separate accounting.
249
+ const promptChars = promptCharsOverride ?? basePrompt.length;
250
+ this.tracker?.recordStep({
251
+ step: stepNumber,
252
+ observation,
253
+ reasoning,
254
+ statePatch: patch,
255
+ action,
256
+ promptChars,
257
+ responseChars,
258
+ timestamp: this.now(),
259
+ success: !invalidated,
260
+ });
261
+ if (accepted !== null) {
262
+ this.currentState = newState;
263
+ }
264
+ // @non-paper observability (never feeds back into Algorithm 1).
265
+ this.events?.emit('step:end', { step: stepNumber, action, invalidated });
266
+ if (invalidated) {
267
+ this.events?.emit('step:error', { step: stepNumber, error: lastError });
268
+ this.logger?.warn('step:invalidated', { step: stepNumber, error: lastError });
269
+ }
270
+ else {
271
+ this.logger?.info('step:end', { step: stepNumber, action });
272
+ }
273
+ // 8. Return the step result (reasoning is returned, never stored)
274
+ return {
275
+ step: stepNumber,
276
+ observation,
277
+ reasoning,
278
+ statePatch: patch,
279
+ action,
280
+ newObservation,
281
+ newState,
282
+ validationAttempts: attempts,
283
+ invalidated,
284
+ promptChars,
285
+ responseChars,
286
+ };
287
+ }
288
+ catch (error) {
289
+ // @non-paper: transport throws (llm/execute, timeouts, aborts) still
290
+ // propagate exactly as before — observed first, never swallowed.
291
+ const message = error instanceof Error ? error.message : String(error);
292
+ this.events?.emit('step:error', { step: stepNumber, error: message });
293
+ this.logger?.error('step:error', { step: stepNumber, error: message });
294
+ throw error;
295
+ }
296
+ }
297
+ /**
298
+ * Run steps until isDone(result) is true or maxSteps is reached. Each
299
+ * step's input observation is the previous step's newObservation.
300
+ *
301
+ * @non-paper `runOpts`/constructor budgets cap cumulative CHARS
302
+ * (prompt+response, §4.3). On trip the exceeding step is rolled back —
303
+ * runtime state restored, its tracker entry truncated — and
304
+ * `BudgetExceededError` (with the committed prefix) is thrown alongside
305
+ * a `budget:exceeded` event. No budget = the paper-exact loop above,
306
+ * untouched.
307
+ */
308
+ async run(first, isDone, maxSteps = DEFAULT_MAX_STEPS, runOpts) {
309
+ const results = [];
310
+ const maxChars = this.resolveMaxChars(runOpts);
311
+ let localTotal = 0;
312
+ let observation = first;
313
+ for (let i = 0; i < maxSteps; i += 1) {
314
+ if (maxChars !== undefined &&
315
+ this.currentTotalChars(localTotal) > maxChars) {
316
+ // Resumed into an already-blown budget: stop before any new commit.
317
+ const total = this.currentTotalChars(localTotal);
318
+ this.events?.emit('budget:exceeded', {
319
+ step: results.length + 1,
320
+ totalChars: total,
321
+ maxChars,
322
+ });
323
+ this.logger?.warn('budget:exceeded', {
324
+ step: results.length + 1,
325
+ totalChars: total,
326
+ maxChars,
327
+ });
328
+ throw new BudgetExceededError(maxChars, total, results);
329
+ }
330
+ const trackerCountBefore = this.tracker?.getBookkeeping().stepCount ?? 0;
331
+ const stateBefore = clone(this.currentState);
332
+ const result = await this.step(observation);
333
+ const totalAfter = this.currentTotalChars(localTotal + result.promptChars + result.responseChars);
334
+ if (maxChars !== undefined && totalAfter > maxChars) {
335
+ // Roll back the exceeding step: no partial commit survives.
336
+ this.currentState = stateBefore;
337
+ this.tracker?.truncateTo(trackerCountBefore);
338
+ this.events?.emit('budget:exceeded', {
339
+ step: result.step,
340
+ totalChars: totalAfter,
341
+ maxChars,
342
+ });
343
+ this.logger?.warn('budget:exceeded', {
344
+ step: result.step,
345
+ totalChars: totalAfter,
346
+ maxChars,
347
+ });
348
+ throw new BudgetExceededError(maxChars, totalAfter, results);
349
+ }
350
+ if (this.tracker === undefined) {
351
+ localTotal += result.promptChars + result.responseChars;
352
+ }
353
+ results.push(result);
354
+ if (isDone(result)) {
355
+ break;
356
+ }
357
+ observation = result.newObservation;
358
+ }
359
+ return results;
360
+ }
361
+ }
362
+ //# sourceMappingURL=runtime.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime.js","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export * from './intercode-ctf.js';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/schemas/index.ts"],"names":[],"mappings":"AACA,cAAc,oBAAoB,CAAC"}
@@ -0,0 +1,3 @@
1
+ // Canonical procedural specifications (paper §3.1 datasets).
2
+ export * from './intercode-ctf.js';
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/schemas/index.ts"],"names":[],"mappings":"AAAA,6DAA6D;AAC7D,cAAc,oBAAoB,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { ProceduralSpec } from '../types.js';
2
+ export declare const INTERCODE_CTF_SPEC: ProceduralSpec;
3
+ //# sourceMappingURL=intercode-ctf.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"intercode-ctf.d.ts","sourceRoot":"","sources":["../../src/schemas/intercode-ctf.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAUlD,eAAO,MAAM,kBAAkB,EAAE,cA4ChC,CAAC"}
@@ -0,0 +1,53 @@
1
+ // ---------------------------------------------------------------------------
2
+ // Canonical InterCode CTF skill specification (paper §3.1)
3
+ // ---------------------------------------------------------------------------
4
+ //
5
+ // The InterCode CTF benchmark task: an agent operates a bash shell inside a
6
+ // Docker container and must locate a hidden flag. The paper fixes the state
7
+ // schema to exactly these five fields — this spec is the canonical encoding.
8
+ export const INTERCODE_CTF_SPEC = {
9
+ id: 'intercode-ctf',
10
+ name: 'InterCode CTF Agent',
11
+ version: '1.0.0',
12
+ instructions: `You are an autonomous CTF agent operating inside an InterCode CTF environment: a Docker container with a hidden flag somewhere on its filesystem.
13
+
14
+ Your actions are bash commands executed in the container (e.g. ls, cat, grep, find, strings, file, head, tail). Each step you issue exactly one command.
15
+
16
+ Strategy:
17
+ - Form a hypothesis about where the flag might be, test it with one command, then update your state.
18
+ - Record every command and hypothesis you have already tried in tested_hypotheses so you never repeat a failed approach.
19
+ - Keep working_dir synced with your current directory in the container.
20
+ - Track files that look promising in active_files; remove them (set to null) once you have ruled them out.
21
+ - Summarize the outcome of your last command in cmd_summary.
22
+ - When you discover a flag (format flag{...}), append it to discovered_flags.
23
+
24
+ Iterate hypothesis -> command -> observation -> state update until the flag is found. Once discovered_flags contains the flag, you are done.`,
25
+ schema: {
26
+ discovered_flags: {
27
+ type: 'array',
28
+ default: [],
29
+ description: 'Flags discovered so far',
30
+ },
31
+ tested_hypotheses: {
32
+ type: 'array',
33
+ default: [],
34
+ description: 'Commands/hypotheses already tested to avoid repetition',
35
+ },
36
+ active_files: {
37
+ type: 'array',
38
+ default: [],
39
+ description: 'Files currently under investigation',
40
+ },
41
+ working_dir: {
42
+ type: 'string',
43
+ default: '/',
44
+ description: 'Current working directory',
45
+ },
46
+ cmd_summary: {
47
+ type: 'string',
48
+ default: '',
49
+ description: 'Summary of last command executed',
50
+ },
51
+ },
52
+ };
53
+ //# sourceMappingURL=intercode-ctf.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"intercode-ctf.js","sourceRoot":"","sources":["../../src/schemas/intercode-ctf.ts"],"names":[],"mappings":"AAEA,8EAA8E;AAC9E,2DAA2D;AAC3D,8EAA8E;AAC9E,EAAE;AACF,4EAA4E;AAC5E,4EAA4E;AAC5E,6EAA6E;AAE7E,MAAM,CAAC,MAAM,kBAAkB,GAAmB;IAChD,EAAE,EAAE,eAAe;IACnB,IAAI,EAAE,qBAAqB;IAC3B,OAAO,EAAE,OAAO;IAChB,YAAY,EAAE;;;;;;;;;;;;6IAY6H;IAC3I,MAAM,EAAE;QACN,gBAAgB,EAAE;YAChB,IAAI,EAAE,OAAO;YACb,OAAO,EAAE,EAAE;YACX,WAAW,EAAE,yBAAyB;SACvC;QACD,iBAAiB,EAAE;YACjB,IAAI,EAAE,OAAO;YACb,OAAO,EAAE,EAAE;YACX,WAAW,EAAE,wDAAwD;SACtE;QACD,YAAY,EAAE;YACZ,IAAI,EAAE,OAAO;YACb,OAAO,EAAE,EAAE;YACX,WAAW,EAAE,qCAAqC;SACnD;QACD,WAAW,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,OAAO,EAAE,GAAG;YACZ,WAAW,EAAE,2BAA2B;SACzC;QACD,WAAW,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,OAAO,EAAE,EAAE;YACX,WAAW,EAAE,kCAAkC;SAChD;KACF;CACF,CAAC"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * @non-paper graceful-shutdown hook (Wave 4 DX).
3
+ *
4
+ * The paper has no process lifecycle; this module adds an OPTIONAL,
5
+ * additive seam: `installShutdown(save)` checkpoints once per signal.
6
+ *
7
+ * - Registers one shared handler for `SIGINT` and `SIGTERM`;
8
+ * - each signal best-effort invokes `save()` (sync throws and async
9
+ * rejections are swallowed — teardown must never crash);
10
+ * - returns an uninstall closure (idempotent) removing both listeners.
11
+ *
12
+ * The hook never calls `process.exit` itself: callers decide whether to
13
+ * exit after the checkpoint. Zero dependencies, Node >= 20, ESM.
14
+ */
15
+ /**
16
+ * @non-paper install a checkpoint-on-signal hook. Returns an idempotent
17
+ * uninstall function.
18
+ */
19
+ export declare function installShutdown(save: () => Promise<void>): () => void;
20
+ //# sourceMappingURL=shutdown.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shutdown.d.ts","sourceRoot":"","sources":["../src/shutdown.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAIH;;;GAGG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,MAAM,IAAI,CAoBrE"}
@@ -0,0 +1,42 @@
1
+ /**
2
+ * @non-paper graceful-shutdown hook (Wave 4 DX).
3
+ *
4
+ * The paper has no process lifecycle; this module adds an OPTIONAL,
5
+ * additive seam: `installShutdown(save)` checkpoints once per signal.
6
+ *
7
+ * - Registers one shared handler for `SIGINT` and `SIGTERM`;
8
+ * - each signal best-effort invokes `save()` (sync throws and async
9
+ * rejections are swallowed — teardown must never crash);
10
+ * - returns an uninstall closure (idempotent) removing both listeners.
11
+ *
12
+ * The hook never calls `process.exit` itself: callers decide whether to
13
+ * exit after the checkpoint. Zero dependencies, Node >= 20, ESM.
14
+ */
15
+ /// <reference types="node" />
16
+ /**
17
+ * @non-paper install a checkpoint-on-signal hook. Returns an idempotent
18
+ * uninstall function.
19
+ */
20
+ export function installShutdown(save) {
21
+ let installed = true;
22
+ const handler = () => {
23
+ try {
24
+ const pending = save();
25
+ pending.catch(() => { });
26
+ }
27
+ catch {
28
+ // Best-effort checkpoint: sync throws are swallowed like rejections.
29
+ }
30
+ };
31
+ process.on('SIGINT', handler);
32
+ process.on('SIGTERM', handler);
33
+ return () => {
34
+ if (installed === false) {
35
+ return;
36
+ }
37
+ installed = false;
38
+ process.removeListener('SIGINT', handler);
39
+ process.removeListener('SIGTERM', handler);
40
+ };
41
+ }
42
+ //# sourceMappingURL=shutdown.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shutdown.js","sourceRoot":"","sources":["../src/shutdown.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,8BAA8B;AAE9B;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,IAAyB;IACvD,IAAI,SAAS,GAAG,IAAI,CAAC;IACrB,MAAM,OAAO,GAAG,GAAS,EAAE;QACzB,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,IAAI,EAAE,CAAC;YACvB,OAAO,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;QAC1B,CAAC;QAAC,MAAM,CAAC;YACP,qEAAqE;QACvE,CAAC;IACH,CAAC,CAAC;IACF,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAC9B,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;IAC/B,OAAO,GAAG,EAAE;QACV,IAAI,SAAS,KAAK,KAAK,EAAE,CAAC;YACxB,OAAO;QACT,CAAC;QACD,SAAS,GAAG,KAAK,CAAC;QAClB,OAAO,CAAC,cAAc,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QAC1C,OAAO,CAAC,cAAc,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;IAC7C,CAAC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,23 @@
1
+ import type { SkillState, StatePatch, StateSchema, ValidationResult } from './types.js';
2
+ export declare function createInitialState(schema: StateSchema, overrides?: Partial<SkillState>): SkillState;
3
+ export declare function mergeState(state: SkillState, patch: StatePatch): SkillState;
4
+ export declare function validatePatch(schema: StateSchema, patch: StatePatch): ValidationResult;
5
+ export declare function serializeState(state: SkillState, options?: {
6
+ pretty?: boolean;
7
+ }): string;
8
+ export declare function deserializeState(json: string): SkillState;
9
+ export declare class StateManager {
10
+ static createInitialState: typeof createInitialState;
11
+ static mergeState: typeof mergeState;
12
+ static validatePatch: typeof validatePatch;
13
+ static serializeState: typeof serializeState;
14
+ static deserializeState: typeof deserializeState;
15
+ }
16
+ export declare function createStateManager(): {
17
+ createInitialState: typeof createInitialState;
18
+ mergeState: typeof mergeState;
19
+ validatePatch: typeof validatePatch;
20
+ serializeState: typeof serializeState;
21
+ deserializeState: typeof deserializeState;
22
+ };
23
+ //# sourceMappingURL=state-manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state-manager.d.ts","sourceRoot":"","sources":["../src/state-manager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,UAAU,EACV,UAAU,EACV,WAAW,EAEX,gBAAgB,EACjB,MAAM,YAAY,CAAC;AAMpB,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,WAAW,EACnB,SAAS,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,GAC9B,UAAU,CAWZ;AAcD,wBAAgB,UAAU,CAAC,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,GAAG,UAAU,CAkB3E;AAgDD,wBAAgB,aAAa,CAC3B,MAAM,EAAE,WAAW,EACnB,KAAK,EAAE,UAAU,GAChB,gBAAgB,CAkBlB;AAMD,wBAAgB,cAAc,CAC5B,KAAK,EAAE,UAAU,EACjB,OAAO,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAA;CAAE,GAC7B,MAAM,CAKR;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,CAEzD;AAMD,qBAAa,YAAY;IACvB,MAAM,CAAC,kBAAkB,4BAAsB;IAC/C,MAAM,CAAC,UAAU,oBAAc;IAC/B,MAAM,CAAC,aAAa,uBAAiB;IACrC,MAAM,CAAC,cAAc,wBAAkB;IACvC,MAAM,CAAC,gBAAgB,0BAAoB;CAC5C;AAMD,wBAAgB,kBAAkB;;;;;;EAQjC"}