@noetic-tools/context 1.2.0 → 1.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.
Files changed (34) hide show
  1. package/README.md +2 -3
  2. package/dist/context/layer-provides.d.ts +1 -1
  3. package/dist/context/layer-provides.js +1 -1
  4. package/dist/context/layers/{file-reference.d.ts → filesystem.d.ts} +1 -1
  5. package/dist/context/layers/{file-reference.js → filesystem.js} +3 -3
  6. package/dist/context/layers/{history-window.d.ts → history.d.ts} +4 -4
  7. package/dist/context/layers/{history-window.js → history.js} +6 -6
  8. package/dist/context/layers/{static-content.d.ts → instructions.d.ts} +2 -2
  9. package/dist/context/layers/{static-content.js → instructions.js} +2 -2
  10. package/dist/context/layers/{observational-context.d.ts → observations.d.ts} +12 -12
  11. package/dist/context/layers/{observational-context.js → observations.js} +7 -7
  12. package/dist/context/layers/plan-prompts.d.ts +1 -1
  13. package/dist/context/layers/plan-prompts.js +19 -28
  14. package/dist/context/layers/plan-state.d.ts +31 -0
  15. package/dist/context/layers/plan-state.js +12 -0
  16. package/dist/context/layers/{plan-context.d.ts → plan.d.ts} +6 -28
  17. package/dist/context/layers/plan.js +697 -0
  18. package/dist/context/layers/{working-memory-context.d.ts → scratchpad.d.ts} +13 -13
  19. package/dist/context/layers/{working-memory-context.js → scratchpad.js} +8 -8
  20. package/dist/context/layers/steering.js +1 -1
  21. package/dist/context/layers/{durable-task-state.d.ts → task-state.d.ts} +20 -20
  22. package/dist/context/layers/{durable-task-state.js → task-state.js} +9 -9
  23. package/dist/context/layers/{temporal-context.d.ts → temporal.d.ts} +5 -5
  24. package/dist/context/layers/{temporal-context.js → temporal.js} +5 -5
  25. package/dist/context/layers/{tool-context-layer.d.ts → tool-calls.d.ts} +2 -2
  26. package/dist/context/layers/{tool-context-layer.js → tool-calls.js} +1 -1
  27. package/dist/context/strip-unresolved.d.ts +1 -1
  28. package/dist/context/strip-unresolved.js +1 -1
  29. package/dist/index.d.ts +9 -10
  30. package/dist/index.js +9 -10
  31. package/package.json +2 -2
  32. package/dist/context/layers/plan-context.js +0 -683
  33. package/dist/deprecated.d.ts +0 -43
  34. package/dist/deprecated.js +0 -28
package/README.md CHANGED
@@ -11,9 +11,8 @@ provides:
11
11
  - The **lifecycle, budget, and projection machinery** that converges layer
12
12
  outputs into the assembled LLM context (`assembleView`, `allocateBudgets`,
13
13
  layer state stores, scoping).
14
- - The **built-in layers**: working memory, history window, observational
15
- context, plan, temporal, steering, file reference, static content, durable
16
- task state, and the tool context layer.
14
+ - The **built-in layers**: instructions, history, scratchpad, observations,
15
+ temporal, filesystem, plan, task state, tool calls, and steering.
17
16
 
18
17
  It depends only on [`@noetic-tools/types`](https://www.npmjs.com/package/@noetic-tools/types).
19
18
  [`@noetic-tools/core`](https://www.npmjs.com/package/@noetic-tools/core) builds
@@ -21,7 +21,7 @@ export declare function layerData<T, TState>(opts: {
21
21
  * @param opts.execute - Async function receiving args, current state, and execution context.
22
22
  * @returns A `LayerFunctionDecl` to include in a layer's `provides`.
23
23
  */
24
- export declare function layerFn<TInput, TOutput, TState>(opts: {
24
+ export declare function layerFunction<TInput, TOutput, TState>(opts: {
25
25
  description: string;
26
26
  input: ZodType<TInput>;
27
27
  output: ZodType<TOutput>;
@@ -22,7 +22,7 @@ export function layerData(opts) {
22
22
  * @param opts.execute - Async function receiving args, current state, and execution context.
23
23
  * @returns A `LayerFunctionDecl` to include in a layer's `provides`.
24
24
  */
25
- export function layerFn(opts) {
25
+ export function layerFunction(opts) {
26
26
  return {
27
27
  kind: 'function',
28
28
  description: opts.description,
@@ -51,5 +51,5 @@ interface FileReferenceOptions {
51
51
  *
52
52
  * @public
53
53
  */
54
- export declare function fileReference(opts?: FileReferenceOptions): ContextLayer<FileReferenceState>;
54
+ export declare function filesystem(opts?: FileReferenceOptions): ContextLayer<FileReferenceState>;
55
55
  export {};
@@ -757,11 +757,11 @@ async function renderFileReferenceDelta({ prev, next, }) {
757
757
  *
758
758
  * @public
759
759
  */
760
- export function fileReference(opts) {
760
+ export function filesystem(opts) {
761
761
  const runtime = createFileReferenceRuntime(opts);
762
762
  return {
763
- id: 'file-reference',
764
- name: 'File Reference',
763
+ id: 'filesystem',
764
+ name: 'Filesystem',
765
765
  slot: runtime.slot,
766
766
  scope: 'thread',
767
767
  budget: 'auto',
@@ -15,17 +15,17 @@
15
15
  * slice boundary via `stripUnresolvedToolCalls`.
16
16
  */
17
17
  import type { ContextLayer } from '@noetic-tools/types';
18
- /** @public Configuration for the {@link historyWindow} layer. */
19
- export interface HistoryWindowConfig {
18
+ /** @public Configuration for the {@link history} layer. */
19
+ export interface HistoryConfig {
20
20
  /** Cap on the number of trailing items projected to the LLM. Defaults to 40. */
21
21
  maxItems?: number;
22
22
  }
23
23
  /**
24
- * Creates a history-window context layer that caps the trailing items projected
24
+ * Creates a history context layer that caps the trailing items projected
25
25
  * to the LLM. Storage stays unbounded; only the wire payload is narrowed.
26
26
  *
27
27
  * @public
28
28
  * @param config - Optional `{ maxItems }`. Defaults to 40.
29
29
  * @returns A `ContextLayer` that contributes only a `projectHistory` hook.
30
30
  */
31
- export declare function historyWindow(config?: HistoryWindowConfig): ContextLayer<null>;
31
+ export declare function history(config?: HistoryConfig): ContextLayer<null>;
@@ -32,8 +32,8 @@ const ANCHOR_SCAN_LIMIT = 4;
32
32
  function validateMaxItems(value) {
33
33
  if (!Number.isInteger(value) || value < MIN_MAX_ITEMS || value > MAX_MAX_ITEMS) {
34
34
  throw new NoeticConfigError({
35
- code: 'INVALID_HISTORY_WINDOW_MAX_ITEMS',
36
- message: `historyWindow: maxItems must be an integer in [${MIN_MAX_ITEMS}, ${MAX_MAX_ITEMS}], got ${value}`,
35
+ code: 'INVALID_HISTORY_MAX_ITEMS',
36
+ message: `history: maxItems must be an integer in [${MIN_MAX_ITEMS}, ${MAX_MAX_ITEMS}], got ${value}`,
37
37
  hint: 'Pass a sensible cap such as { maxItems: 40 }, or omit the layer to keep history uncapped.',
38
38
  });
39
39
  }
@@ -94,19 +94,19 @@ function findHeadAnchor(items, windowStart) {
94
94
  //#endregion
95
95
  //#region Public API
96
96
  /**
97
- * Creates a history-window context layer that caps the trailing items projected
97
+ * Creates a history context layer that caps the trailing items projected
98
98
  * to the LLM. Storage stays unbounded; only the wire payload is narrowed.
99
99
  *
100
100
  * @public
101
101
  * @param config - Optional `{ maxItems }`. Defaults to 40.
102
102
  * @returns A `ContextLayer` that contributes only a `projectHistory` hook.
103
103
  */
104
- export function historyWindow(config) {
104
+ export function history(config) {
105
105
  const maxItems = config?.maxItems ?? DEFAULT_MAX_ITEMS;
106
106
  validateMaxItems(maxItems);
107
107
  return {
108
- id: 'history-window',
109
- name: 'History Window',
108
+ id: 'history',
109
+ name: 'History',
110
110
  slot: HISTORY_WINDOW_SLOT,
111
111
  scope: 'execution',
112
112
  hooks: {
@@ -1,5 +1,5 @@
1
1
  import type { ContextScope } from '@noetic-tools/types';
2
- interface StaticContentOpts {
2
+ interface InstructionsOptions {
3
3
  id?: string;
4
4
  slot?: number;
5
5
  scope?: ContextScope;
@@ -13,7 +13,7 @@ interface StaticContentOpts {
13
13
  * @param opts - Configuration with a `load` function and optional id, slot, scope, and XML tag name.
14
14
  * @returns A `ContextLayer` that provides static instructional content to the model.
15
15
  */
16
- export declare function staticContent(opts: StaticContentOpts): {
16
+ export declare function instructions(opts: InstructionsOptions): {
17
17
  id: string;
18
18
  slot: number;
19
19
  scope: ContextScope;
@@ -6,10 +6,10 @@ import { estimateTokens, Slot } from '@noetic-tools/types';
6
6
  * @param opts - Configuration with a `load` function and optional id, slot, scope, and XML tag name.
7
7
  * @returns A `ContextLayer` that provides static instructional content to the model.
8
8
  */
9
- export function staticContent(opts) {
9
+ export function instructions(opts) {
10
10
  const tag = opts.tag ?? 'instructions';
11
11
  return {
12
- id: opts.id ?? 'static-content',
12
+ id: opts.id ?? 'instructions',
13
13
  slot: opts.slot ?? Slot.WORKING_MEMORY + 5,
14
14
  scope: opts.scope ?? 'resource',
15
15
  // Loaded once in `init` and never rewritten, so it can be pinned outright
@@ -1,11 +1,11 @@
1
- export interface ObservationalState {
1
+ export interface ObservationsState {
2
2
  observations: string[];
3
3
  buffer: string[];
4
4
  bufferTokens: number;
5
5
  version: number;
6
6
  }
7
7
  export type ObserverFn = (buffer: string[]) => Promise<string[]>;
8
- export interface ObservationalContextConfig {
8
+ export interface ObservationsConfig {
9
9
  bufferThreshold?: number;
10
10
  maxObservations?: number;
11
11
  scope?: 'thread' | 'resource';
@@ -18,8 +18,8 @@ export interface ObservationalContextConfig {
18
18
  * @param config - Optional configuration for buffer threshold, max observations, scope, and observer function.
19
19
  * @returns A `ContextLayer` that accumulates and summarizes observations over time.
20
20
  */
21
- export declare function observationalContext(config?: ObservationalContextConfig): {
22
- id: 'observational-context';
21
+ export declare function observations(config?: ObservationsConfig): {
22
+ id: 'observations';
23
23
  name: string;
24
24
  slot: 200;
25
25
  scope: "resource" | "thread";
@@ -33,24 +33,24 @@ export declare function observationalContext(config?: ObservationalContextConfig
33
33
  };
34
34
  hooks: {
35
35
  init({ storage }: import("@noetic-tools/types").InitParams): Promise<{
36
- state: ObservationalState;
36
+ state: ObservationsState;
37
37
  }>;
38
- recall({ state, budget }: import("@noetic-tools/types").RecallParams<ObservationalState>): Promise<{
38
+ recall({ state, budget }: import("@noetic-tools/types").RecallParams<ObservationsState>): Promise<{
39
39
  items: import("@noetic-tools/types").InputMessageItem[];
40
40
  tokenCount: number;
41
41
  } | null>;
42
- store({ newItems, state }: import("@noetic-tools/types").StoreParams<ObservationalState>): Promise<{
43
- state: ObservationalState;
42
+ store({ newItems, state }: import("@noetic-tools/types").StoreParams<ObservationsState>): Promise<{
43
+ state: ObservationsState;
44
44
  }>;
45
- onItemAppend({ items, state }: import("@noetic-tools/types").OnItemAppendParams<ObservationalState>): Promise<{
45
+ onItemAppend({ items, state }: import("@noetic-tools/types").OnItemAppendParams<ObservationsState>): Promise<{
46
46
  items: import("@noetic-tools/types").Item[];
47
47
  state?: undefined;
48
48
  } | {
49
49
  items: import("@noetic-tools/types").Item[];
50
- state: ObservationalState;
50
+ state: ObservationsState;
51
51
  }>;
52
- onSpawn({ parentState }: import("@noetic-tools/types").SpawnParams<ObservationalState>): Promise<{
53
- childState: ObservationalState;
52
+ onSpawn({ parentState }: import("@noetic-tools/types").SpawnParams<ObservationsState>): Promise<{
53
+ childState: ObservationsState;
54
54
  }>;
55
55
  };
56
56
  };
@@ -1,7 +1,7 @@
1
1
  import { collectInputText, collectOutputText, createMessage, estimateTokens, Slot, } from '@noetic-tools/types';
2
2
  const DEFAULT_BUFFER_THRESHOLD_TOKENS = 2_000;
3
3
  const DEFAULT_MAX_OBSERVATIONS = 50;
4
- function emptyObservationalState() {
4
+ function emptyObservationsState() {
5
5
  return {
6
6
  observations: [],
7
7
  buffer: [],
@@ -70,13 +70,13 @@ function renderObservationsWithinBudget(observations, budget) {
70
70
  * @param config - Optional configuration for buffer threshold, max observations, scope, and observer function.
71
71
  * @returns A `ContextLayer` that accumulates and summarizes observations over time.
72
72
  */
73
- export function observationalContext(config) {
73
+ export function observations(config) {
74
74
  const maxObs = config?.maxObservations ?? DEFAULT_MAX_OBSERVATIONS;
75
75
  const threshold = config?.bufferThreshold ?? DEFAULT_BUFFER_THRESHOLD_TOKENS;
76
76
  const observer = config?.observer;
77
77
  return {
78
- id: 'observational-context',
79
- name: 'Observational Context',
78
+ id: 'observations',
79
+ name: 'Observations',
80
80
  slot: Slot.OBSERVATIONS,
81
81
  scope: config?.scope ?? 'resource',
82
82
  budget: {
@@ -93,7 +93,7 @@ export function observationalContext(config) {
93
93
  async init({ storage }) {
94
94
  const saved = await storage.get('state');
95
95
  return {
96
- state: saved ?? emptyObservationalState(),
96
+ state: saved ?? emptyObservationsState(),
97
97
  };
98
98
  },
99
99
  async recall({ state, budget }) {
@@ -114,7 +114,7 @@ export function observationalContext(config) {
114
114
  },
115
115
  // Captures assistant output text.
116
116
  async store({ newItems, state }) {
117
- const s = state ?? emptyObservationalState();
117
+ const s = state ?? emptyObservationsState();
118
118
  const texts = collectOutputText(newItems);
119
119
  return {
120
120
  state: await accumulate(s, texts, {
@@ -126,7 +126,7 @@ export function observationalContext(config) {
126
126
  },
127
127
  // Captures user input and tool output text (pass-through; no transform).
128
128
  async onItemAppend({ items, state }) {
129
- const s = state ?? emptyObservationalState();
129
+ const s = state ?? emptyObservationsState();
130
130
  const texts = collectInputText(items);
131
131
  if (texts.length === 0) {
132
132
  return {
@@ -13,7 +13,7 @@
13
13
  * one runs for a given phase.
14
14
  */
15
15
  import type { WorkflowNode } from '@noetic-tools/types';
16
- import type { PlanState } from './plan-context.js';
16
+ import type { PlanState } from './plan-state.js';
17
17
  /** How the planning briefing shapes the turn. */
18
18
  export declare const PlanStyle: {
19
19
  /** Explore → design → review → write → exit. Best when the work's shape is known. */
@@ -203,24 +203,24 @@ Keep it scannable but executable. A reader should be able to skim the headers an
203
203
  /** One line per node kind, split into the work itself and the shape it runs in. */
204
204
  const KIND_ENTRIES = [
205
205
  {
206
- kind: 'llm',
206
+ kind: 'callModel',
207
207
  group: 'leaf',
208
- line: '`llm` — a model turn, driven by `instructions`; give it `tools` if it needs them',
208
+ line: '`callModel` — a model turn, driven by `instructions`; give it `tools` if it needs them',
209
209
  },
210
210
  {
211
- kind: 'tool',
211
+ kind: 'invokeTool',
212
212
  group: 'leaf',
213
- line: '`tool` — one deterministic tool call: `toolName` plus `args`',
213
+ line: '`invokeTool` — one deterministic tool call: `toolName` plus `args`',
214
214
  },
215
215
  {
216
- kind: 'run',
216
+ kind: 'runCode',
217
217
  group: 'leaf',
218
- line: '`run` — code in `execute`, run by a subprocess adapter the host must provide',
218
+ line: '`runCode` — code in `execute`, run by a subprocess adapter the host must provide',
219
219
  },
220
220
  {
221
- kind: 'claude-code',
221
+ kind: 'acp-agent',
222
222
  group: 'leaf',
223
- line: '`claude-code`, `codex`, `opencode`, `pi` — hand a `prompt` to a coding agent',
223
+ line: '`acp-agent` — hand a `prompt` to an external coding agent named by `agent` (e.g. `claude-code`, `codex`, `gemini`)',
224
224
  },
225
225
  {
226
226
  kind: 'sequence',
@@ -228,14 +228,14 @@ const KIND_ENTRIES = [
228
228
  line: '`sequence` — `steps` run in order, each fed the one before',
229
229
  },
230
230
  {
231
- kind: 'fork',
231
+ kind: 'inParallel',
232
232
  group: 'structure',
233
- line: '`fork` — `paths` run at once (or `each` over a runtime array); `mode` is `all`, `race` or `settle`, and `merge` says how the outputs of an `all` come back together',
233
+ line: '`inParallel` — `paths` run at once (or `each` over a runtime array); `mode` is `all`, `race` or `settle`, and `merge` says how the outputs of an `all` come back together',
234
234
  },
235
235
  {
236
- kind: 'branch',
236
+ kind: 'conditional',
237
237
  group: 'structure',
238
- line: '`branch` — the FIRST route whose `match` appears in the input wins, case-insensitively, so order the routes narrowest first; `default` catches the rest',
238
+ line: '`conditional` — the FIRST route whose `match` appears in the input wins, case-insensitively, so order the routes narrowest first; `default` catches the rest',
239
239
  },
240
240
  {
241
241
  kind: 'loop',
@@ -243,9 +243,9 @@ const KIND_ENTRIES = [
243
243
  line: '`loop` — run `body`, then repeat while the `until` predicate does not hold; the body always runs at least once',
244
244
  },
245
245
  {
246
- kind: 'every',
246
+ kind: 'schedule',
247
247
  group: 'structure',
248
- line: '`every` — run `step` on an interval of `ms`, forever; nothing after it ever runs, so put it last',
248
+ line: '`schedule` — run `step` on an `interval`, forever; nothing after it ever runs, so put it last',
249
249
  },
250
250
  {
251
251
  kind: 'spawn',
@@ -253,9 +253,9 @@ const KIND_ENTRIES = [
253
253
  line: '`spawn` — run `child` in an isolated context, so its work does not crowd this one',
254
254
  },
255
255
  {
256
- kind: 'provide',
256
+ kind: 'withContext',
257
257
  group: 'structure',
258
- line: '`provide` — run `child` with a named set of memory layers the host must have registered',
258
+ line: '`withContext` — run `child` with a named set of context layers the host must have registered',
259
259
  },
260
260
  {
261
261
  kind: 'subflow',
@@ -263,21 +263,12 @@ const KIND_ENTRIES = [
263
263
  line: '`subflow` — run a named workflow by `ref`',
264
264
  },
265
265
  ];
266
- /** The harness kinds share one line, so they are folded into the `claude-code` entry. */
267
- const HARNESS_KINDS = [
268
- 'claude-code',
269
- 'codex',
270
- 'opencode',
271
- 'pi',
272
- ];
273
266
  function kindEntries(allowed) {
274
267
  if (!allowed) {
275
268
  return KIND_ENTRIES;
276
269
  }
277
270
  const permitted = new Set(allowed);
278
- return KIND_ENTRIES.filter((entry) => entry.kind === 'claude-code'
279
- ? HARNESS_KINDS.some((kind) => permitted.has(kind))
280
- : permitted.has(entry.kind));
271
+ return KIND_ENTRIES.filter((entry) => permitted.has(entry.kind));
281
272
  }
282
273
  function treeGuide(schemaUrl, allowed) {
283
274
  const entries = kindEntries(allowed);
@@ -300,8 +291,8 @@ ${structure.join('\n')}
300
291
  **Shaping it**
301
292
  - Keep the tree the user reviews SMALL — about seven top-level nodes, readable at a glance. Push the mechanics down.
302
293
  - Factor detail into named workflows: define each with \`plan/setWorkflow\` \`{ "name": "<slug>", "document": {...} }\` and point at it with \`{ "kind": "subflow", "id": "...", "ref": "<slug>" }\`. Named workflows may reference each other but must not form a cycle, and every ref must resolve or the exit is rejected.
303
- - Fork work that is genuinely independent; sequence work where one step needs the last one's output. Do not fork for the look of it.
304
- - Prefer \`tool\` over \`llm\` wherever the step is deterministic. A model turn that always does the same thing is a slow, expensive tool call.
294
+ - Fan out work that is genuinely independent; sequence work where one step needs the last one's output. Do not fan out for the look of it.
295
+ - Prefer \`invokeTool\` over \`callModel\` wherever the step is deterministic. A model turn that always does the same thing is a slow, expensive tool call.
305
296
  - Always give a \`loop\` a \`maxIterations\`. Without one it stops at a hard ceiling of 1000 and fails the step.`;
306
297
  }
307
298
  const ACTIONS = `## Actions
@@ -0,0 +1,31 @@
1
+ import type { WorkflowDocument } from '@noetic-tools/types';
2
+ /**
3
+ * Persisted state shared by the plan layer (`plan.ts`) and its prompt
4
+ * renderers (`plan-prompts.ts`). Lives in its own leaf module so the two can
5
+ * both depend on it without importing each other.
6
+ */
7
+ export declare const PlanPhase: {
8
+ readonly Idle: 'idle';
9
+ readonly Planning: 'planning';
10
+ readonly Executing: 'executing';
11
+ readonly Completed: 'completed';
12
+ readonly Failed: 'failed';
13
+ };
14
+ export type PlanPhase = (typeof PlanPhase)[keyof typeof PlanPhase];
15
+ export interface PlanExecutionEntry {
16
+ timestamp: number;
17
+ version: number;
18
+ outcome: 'success' | 'failure' | 'aborted';
19
+ }
20
+ export interface PlanState {
21
+ phase: PlanPhase;
22
+ prd: string | null;
23
+ /** The reviewed plan: a complete JSON workflow document. */
24
+ planTree: WorkflowDocument | null;
25
+ /** Named workflows referenced from the tree via `{ kind: 'subflow', ref }` nodes. */
26
+ workflows: Record<string, WorkflowDocument>;
27
+ executionLog: PlanExecutionEntry[];
28
+ version: number;
29
+ /** Identifier of the on-disk plan session (set by `onEnterSession` host callback). */
30
+ planSlug?: string | null;
31
+ }
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Persisted state shared by the plan layer (`plan.ts`) and its prompt
3
+ * renderers (`plan-prompts.ts`). Lives in its own leaf module so the two can
4
+ * both depend on it without importing each other.
5
+ */
6
+ export const PlanPhase = {
7
+ Idle: 'idle',
8
+ Planning: 'planning',
9
+ Executing: 'executing',
10
+ Completed: 'completed',
11
+ Failed: 'failed',
12
+ };
@@ -1,31 +1,9 @@
1
- import type { ContextLayer, ContextScope, WorkflowDocument, WorkflowNode } from '@noetic-tools/types';
1
+ import type { ContextLayer, ContextScope, WorkflowNode } from '@noetic-tools/types';
2
2
  import { PlanStyle } from './plan-prompts.js';
3
+ import type { PlanState } from './plan-state.js';
3
4
  export { PlanStyle } from './plan-prompts.js';
4
- export declare const PlanPhase: {
5
- readonly Idle: 'idle';
6
- readonly Planning: 'planning';
7
- readonly Executing: 'executing';
8
- readonly Completed: 'completed';
9
- readonly Failed: 'failed';
10
- };
11
- export type PlanPhase = (typeof PlanPhase)[keyof typeof PlanPhase];
12
- export interface PlanExecutionEntry {
13
- timestamp: number;
14
- version: number;
15
- outcome: 'success' | 'failure' | 'aborted';
16
- }
17
- export interface PlanState {
18
- phase: PlanPhase;
19
- prd: string | null;
20
- /** The reviewed plan: a complete JSON workflow document. */
21
- planTree: WorkflowDocument | null;
22
- /** Named workflows referenced from the tree via `{ kind: 'subflow', ref }` nodes. */
23
- workflows: Record<string, WorkflowDocument>;
24
- executionLog: PlanExecutionEntry[];
25
- version: number;
26
- /** Identifier of the on-disk plan session (set by `onEnterSession` host callback). */
27
- planSlug?: string | null;
28
- }
5
+ export type { PlanExecutionEntry, PlanState } from './plan-state.js';
6
+ export { PlanPhase } from './plan-state.js';
29
7
  /** Host-supplied callback invoked when entering plan mode. Returns a session identifier the host owns (e.g. on-disk dir slug). */
30
8
  export type PlanEnterSessionCallback = () => Promise<{
31
9
  slug: string;
@@ -37,7 +15,7 @@ export type PlanEnterSessionCallback = () => Promise<{
37
15
  export type PlanExitCallback = (state: PlanState) => Promise<{
38
16
  approved: boolean;
39
17
  }>;
40
- export interface PlanContextConfig {
18
+ export interface PlanConfig {
41
19
  scope?: ContextScope;
42
20
  additionalAllowedTools?: string[];
43
21
  maxPrdLength?: number;
@@ -86,4 +64,4 @@ export interface PlanContextConfig {
86
64
  * @param config - Optional configuration for scope, allowed tools, and limits.
87
65
  * @returns A `ContextLayer` providing plan mode, PRD storage, and execution tracking.
88
66
  */
89
- export declare function planContext(config?: PlanContextConfig): ContextLayer<PlanState>;
67
+ export declare function plan(config?: PlanConfig): ContextLayer<PlanState>;