vigiles 19.0.1 → 21.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.
@@ -6,7 +6,7 @@ exports.invalidToolPatterns = invalidToolPatterns;
6
6
  exports.gateAction = gateAction;
7
7
  exports.trimTrailingSeparators = trimTrailingSeparators;
8
8
  exports.commandView = commandView;
9
- exports.defineHook = defineHook;
9
+ exports.experimental_defineHook = experimental_defineHook;
10
10
  exports.decideProgram = decideProgram;
11
11
  exports.decisionExitCode = decisionExitCode;
12
12
  exports.checkHookImports = checkHookImports;
@@ -20,17 +20,17 @@ exports.verifyHookStamp = verifyHookStamp;
20
20
  exports.pathView = pathView;
21
21
  exports.projectRootOf = projectRootOf;
22
22
  exports.undecidablePathWarning = undecidablePathWarning;
23
- exports.defineFileGate = defineFileGate;
23
+ exports.experimental_defineFileGate = experimental_defineFileGate;
24
24
  exports.decideFileGate = decideFileGate;
25
- exports.definePromptGate = definePromptGate;
25
+ exports.experimental_definePromptGate = experimental_definePromptGate;
26
26
  exports.decidePromptGate = decidePromptGate;
27
- exports.defineStopGate = defineStopGate;
27
+ exports.experimental_defineStopGate = experimental_defineStopGate;
28
28
  exports.decideStopGate = decideStopGate;
29
- exports.defineInject = defineInject;
29
+ exports.experimental_defineInject = experimental_defineInject;
30
30
  exports.runInject = runInject;
31
31
  exports.injectionOf = injectionOf;
32
32
  exports.responseView = responseView;
33
- exports.defineReact = defineReact;
33
+ exports.experimental_defineReact = experimental_defineReact;
34
34
  exports.runReact = runReact;
35
35
  exports.outcomeWrites = outcomeWrites;
36
36
  exports.rememberHookSource = rememberHookSource;
@@ -536,10 +536,13 @@ function commandView(raw, root) {
536
536
  const tool = (name) => ({ tool: name });
537
537
  exports.tool = tool;
538
538
  /**
539
- * @experimental Compiled hooks are provisional — see docs/experimental.md.
540
- * Imported as `experimental_defineHook`; alias it at the import site.
539
+ * @experimental Compiled hooks are provisional — see docs/compiled-hooks.md#status--pending.
540
+ * Imported and CALLED as `experimental_defineHook` — do not alias the prefix away at
541
+ * the import. Measured 2026-08-21: with the alias in place the marker survived
542
+ * at 0 of 5 call sites in the only user-facing example, because a reader 200
543
+ * lines down sees `defineHook` without it and cannot tell it is provisional.
541
544
  */
542
- function defineHook(p) {
545
+ function experimental_defineHook(p) {
543
546
  return p;
544
547
  }
545
548
  // ---------------------------------------------------------------------------
@@ -918,10 +921,13 @@ const tools = (...names) => ({
918
921
  });
919
922
  exports.tools = tools;
920
923
  /**
921
- * @experimental Compiled hooks are provisional — see docs/experimental.md.
922
- * Imported as `experimental_defineFileGate`; alias it at the import site.
924
+ * @experimental Compiled hooks are provisional — see docs/compiled-hooks.md#status--pending.
925
+ * Imported and CALLED as `experimental_defineFileGate` — do not alias the prefix away at
926
+ * the import. Measured 2026-08-21: with the alias in place the marker survived
927
+ * at 0 of 5 call sites in the only user-facing example, because a reader 200
928
+ * lines down sees `defineFileGate` without it and cannot tell it is provisional.
923
929
  */
924
- function defineFileGate(p) {
930
+ function experimental_defineFileGate(p) {
925
931
  return { role: "gate", ...p };
926
932
  }
927
933
  /**
@@ -949,10 +955,13 @@ function decideFileGate(hook, raw, ctx = {}, root = typeof raw.cwd === "string"
949
955
  });
950
956
  }
951
957
  /**
952
- * @experimental Compiled hooks are provisional — see docs/experimental.md.
953
- * Imported as `experimental_definePromptGate`; alias it at the import site.
958
+ * @experimental Compiled hooks are provisional — see docs/compiled-hooks.md#status--pending.
959
+ * Imported and CALLED as `experimental_definePromptGate` — do not alias the prefix away at
960
+ * the import. Measured 2026-08-21: with the alias in place the marker survived
961
+ * at 0 of 5 call sites in the only user-facing example, because a reader 200
962
+ * lines down sees `definePromptGate` without it and cannot tell it is provisional.
954
963
  */
955
- function definePromptGate(p) {
964
+ function experimental_definePromptGate(p) {
956
965
  return { role: "prompt-gate", ...p };
957
966
  }
958
967
  /** Run a prompt gate against a raw UserPromptSubmit event (reads `prompt`). */
@@ -965,10 +974,13 @@ function decidePromptGate(hook, raw, ctx = {}) {
965
974
  });
966
975
  }
967
976
  /**
968
- * @experimental Compiled hooks are provisional — see docs/experimental.md.
969
- * Imported as `experimental_defineStopGate`; alias it at the import site.
977
+ * @experimental Compiled hooks are provisional — see docs/compiled-hooks.md#status--pending.
978
+ * Imported and CALLED as `experimental_defineStopGate` — do not alias the prefix away at
979
+ * the import. Measured 2026-08-21: with the alias in place the marker survived
980
+ * at 0 of 5 call sites in the only user-facing example, because a reader 200
981
+ * lines down sees `defineStopGate` without it and cannot tell it is provisional.
970
982
  */
971
- function defineStopGate(p) {
983
+ function experimental_defineStopGate(p) {
972
984
  return { role: "stop-gate", ...p };
973
985
  }
974
986
  /** Run a Stop gate against a raw Stop/SubagentStop event (reads `stop_hook_active`). */
@@ -994,10 +1006,13 @@ const inject = (context, ...records) => ({
994
1006
  });
995
1007
  exports.inject = inject;
996
1008
  /**
997
- * @experimental Compiled hooks are provisional — see docs/experimental.md.
998
- * Imported as `experimental_defineInject`; alias it at the import site.
1009
+ * @experimental Compiled hooks are provisional — see docs/compiled-hooks.md#status--pending.
1010
+ * Imported and CALLED as `experimental_defineInject` — do not alias the prefix away at
1011
+ * the import. Measured 2026-08-21: with the alias in place the marker survived
1012
+ * at 0 of 5 call sites in the only user-facing example, because a reader 200
1013
+ * lines down sees `defineInject` without it and cannot tell it is provisional.
999
1014
  */
1000
- function defineInject(p) {
1015
+ function experimental_defineInject(p) {
1001
1016
  return { role: "inject", ...p };
1002
1017
  }
1003
1018
  /**
@@ -1076,10 +1091,13 @@ const nothing = (...records) => ({
1076
1091
  });
1077
1092
  exports.nothing = nothing;
1078
1093
  /**
1079
- * @experimental Compiled hooks are provisional — see docs/experimental.md.
1080
- * Imported as `experimental_defineReact`; alias it at the import site.
1094
+ * @experimental Compiled hooks are provisional — see docs/compiled-hooks.md#status--pending.
1095
+ * Imported and CALLED as `experimental_defineReact` — do not alias the prefix away at
1096
+ * the import. Measured 2026-08-21: with the alias in place the marker survived
1097
+ * at 0 of 5 call sites in the only user-facing example, because a reader 200
1098
+ * lines down sees `defineReact` without it and cannot tell it is provisional.
1081
1099
  */
1082
- function defineReact(p) {
1100
+ function experimental_defineReact(p) {
1083
1101
  return { role: "react", ...p };
1084
1102
  }
1085
1103
  /**
@@ -86,7 +86,7 @@ exports.RULE_META = {
86
86
  defaultSeverity: "warn",
87
87
  summary: "A subagent's tools: are all real (no never-available / typo).",
88
88
  detector: "verifyToolContract / scoredIssues",
89
- upstreamPrevention: "typed agent() vocabulary + compileAgent — an unknown tool is a tsc/compile error",
89
+ upstreamPrevention: "typed experimental_agent() vocabulary + compileAgent — an unknown tool is a tsc/compile error",
90
90
  },
91
91
  "disallowed-tools-contract": {
92
92
  id: "disallowed-tools-contract",
@@ -95,7 +95,7 @@ exports.RULE_META = {
95
95
  defaultSeverity: "warn",
96
96
  summary: "A disallowedTools: entry isn't a typo that blocks nothing.",
97
97
  detector: "disallowedToolIssues",
98
- upstreamPrevention: "typed agent() vocabulary (a typo is a tsc error)",
98
+ upstreamPrevention: "typed experimental_agent() vocabulary (a typo is a tsc error)",
99
99
  },
100
100
  "subagent-frontmatter": {
101
101
  id: "subagent-frontmatter",
@@ -0,0 +1,50 @@
1
+ /**
2
+ * The one implementation of "fold the deprecated `result:` into `postcondition:`".
3
+ *
4
+ * 🔴 WHY THIS IS ITS OWN MODULE, and the mistake that produced it. The fold
5
+ * originally lived inside `experimental_skill()` alone, with a comment arguing
6
+ * that normalising "at the door" beats normalising at each reader — because a
7
+ * reader added later would silently read only the new field and drop every spec
8
+ * still on the old one. The argument was right. The identification of the door
9
+ * was wrong: `experimental_skill()` is not the only entrance.
10
+ *
11
+ * `compileSkill()` is public, and it accepts a `SkillSpec` STRUCTURALLY. That
12
+ * interface still advertises `result?: Gate`, so this compiles and is legal:
13
+ *
14
+ * compileSkill({ _specType: "skill", name, description, body, result: cmd("npm test") })
15
+ *
16
+ * Such a caller never touches the builder, so before this module the `## Result`
17
+ * section and its reference verification were both silently dropped — the exact
18
+ * defect the original comment predicted, arriving through the entrance it did not
19
+ * count. Found by a reviewer, not by me.
20
+ *
21
+ * So: one function, called at BOTH doors. That is not two sources of truth — it
22
+ * is one, used twice. Putting it in spec.ts would have meant either exporting it
23
+ * from `vigiles/spec` (public surface for an internal concern) or duplicating it
24
+ * in compile.ts (the thing being avoided). This module is imported by both and
25
+ * re-exported by neither, so it stays off every api report.
26
+ *
27
+ * ⚠️ IT IMPORTS NOTHING, including from spec.ts, and that is deliberate.
28
+ * `core/spec.ts` is the dependency ROOT of this package — it has zero imports of
29
+ * its own — and spec.ts has to call this. Naming `Gate` here would put a back
30
+ * edge into the root; a type-only import erases at runtime, but the graph would
31
+ * still read as a cycle to anyone (or any lint rule) looking at it. The fold does
32
+ * not care what a gate IS, only which of two properties holds one, so the shape
33
+ * is described structurally and the dependency stays one-directional.
34
+ */
35
+ /** Anything carrying the two spellings of a skill's terminal gate. */
36
+ interface HasPostcondition<G> {
37
+ readonly postcondition?: G;
38
+ /** @deprecated the old spelling; folded away by {@link foldLegacyPostcondition}. */
39
+ readonly result?: G;
40
+ }
41
+ /**
42
+ * Return `spec` with `result:` folded into `postcondition:` and `result` removed.
43
+ *
44
+ * Throws when both are set: they are the same field under two names, so which
45
+ * gate runs would otherwise be decided by which branch of the fold ran last —
46
+ * a coin flip in a place where the answer is a gate.
47
+ */
48
+ export declare function foldLegacyPostcondition<G, T extends HasPostcondition<G>>(spec: T): T;
49
+ export {};
50
+ //# sourceMappingURL=skill-normalize.d.ts.map
@@ -0,0 +1,60 @@
1
+ "use strict";
2
+ /**
3
+ * The one implementation of "fold the deprecated `result:` into `postcondition:`".
4
+ *
5
+ * 🔴 WHY THIS IS ITS OWN MODULE, and the mistake that produced it. The fold
6
+ * originally lived inside `experimental_skill()` alone, with a comment arguing
7
+ * that normalising "at the door" beats normalising at each reader — because a
8
+ * reader added later would silently read only the new field and drop every spec
9
+ * still on the old one. The argument was right. The identification of the door
10
+ * was wrong: `experimental_skill()` is not the only entrance.
11
+ *
12
+ * `compileSkill()` is public, and it accepts a `SkillSpec` STRUCTURALLY. That
13
+ * interface still advertises `result?: Gate`, so this compiles and is legal:
14
+ *
15
+ * compileSkill({ _specType: "skill", name, description, body, result: cmd("npm test") })
16
+ *
17
+ * Such a caller never touches the builder, so before this module the `## Result`
18
+ * section and its reference verification were both silently dropped — the exact
19
+ * defect the original comment predicted, arriving through the entrance it did not
20
+ * count. Found by a reviewer, not by me.
21
+ *
22
+ * So: one function, called at BOTH doors. That is not two sources of truth — it
23
+ * is one, used twice. Putting it in spec.ts would have meant either exporting it
24
+ * from `vigiles/spec` (public surface for an internal concern) or duplicating it
25
+ * in compile.ts (the thing being avoided). This module is imported by both and
26
+ * re-exported by neither, so it stays off every api report.
27
+ *
28
+ * ⚠️ IT IMPORTS NOTHING, including from spec.ts, and that is deliberate.
29
+ * `core/spec.ts` is the dependency ROOT of this package — it has zero imports of
30
+ * its own — and spec.ts has to call this. Naming `Gate` here would put a back
31
+ * edge into the root; a type-only import erases at runtime, but the graph would
32
+ * still read as a cycle to anyone (or any lint rule) looking at it. The fold does
33
+ * not care what a gate IS, only which of two properties holds one, so the shape
34
+ * is described structurally and the dependency stays one-directional.
35
+ */
36
+ Object.defineProperty(exports, "__esModule", { value: true });
37
+ exports.foldLegacyPostcondition = foldLegacyPostcondition;
38
+ /**
39
+ * Return `spec` with `result:` folded into `postcondition:` and `result` removed.
40
+ *
41
+ * Throws when both are set: they are the same field under two names, so which
42
+ * gate runs would otherwise be decided by which branch of the fold ran last —
43
+ * a coin flip in a place where the answer is a gate.
44
+ */
45
+ function foldLegacyPostcondition(spec) {
46
+ // This IS the one place the deprecated field may be read — the fold is what
47
+ // makes the old spelling work at all, so a lint that forbade it everywhere
48
+ // would forbid the alias window itself.
49
+ // eslint-disable-next-line @typescript-eslint/no-deprecated -- see above
50
+ const { result: legacy, ...rest } = spec;
51
+ if (!legacy)
52
+ return spec;
53
+ if (rest.postcondition) {
54
+ throw new Error("skill spec sets BOTH `postcondition:` and the deprecated `result:` — " +
55
+ "they are the same field under two names, so which gate runs is a " +
56
+ "coin flip. Keep `postcondition:` and delete `result:`.");
57
+ }
58
+ return { ...rest, postcondition: legacy };
59
+ }
60
+ //# sourceMappingURL=skill-normalize.js.map
@@ -71,7 +71,7 @@ export type StrictCmd = [keyof KnownNpmScripts] extends [never] ? string : `npm
71
71
  * MCP / unknown / wildcard.
72
72
  *
73
73
  * The default (`string` at both) imposes no constraint — any tool is accepted at
74
- * every level, the historical behaviour of an untyped `agent()`/`skill()`.
74
+ * every level, the historical behaviour of an untyped `experimental_agent()`/`skill()`.
75
75
  */
76
76
  export interface ToolVocabulary {
77
77
  /** Union of tool names allowed under `purity: "pure"`. */
@@ -94,8 +94,6 @@ export interface OpenToolVocabulary extends ToolVocabulary {
94
94
  * untyped surface accepts any tools.
95
95
  */
96
96
  export type AllowedAt<P extends AuthoredPurity | undefined, V extends ToolVocabulary> = P extends "pure" ? V["readOnly"] : P extends "bounded" ? V["bounded"] : string;
97
- export type ClaudeTool = "Read" | "Write" | "Edit" | "Bash" | "Grep" | "Glob" | "Agent" | "TodoWrite" | "WebSearch" | "WebFetch" | "NotebookEdit";
98
- export type HookEvent = "PreToolUse" | "PostToolUse" | "PreSession" | "PostSession" | "Notification";
99
97
  /** A rule delegated to an external tool (linter, ast-grep, dependency-cruiser, etc.) or to a vigiles-internal check. */
100
98
  export interface EnforceRule {
101
99
  readonly _kind: "enforce";
@@ -257,18 +255,18 @@ export type InstructionFragment = string | Ref | EffectRegion;
257
255
  /**
258
256
  * Tagged template literal for skill instructions with typed references.
259
257
  *
260
- * instructions`
258
+ * prose`
261
259
  * Check ${file("eslint.config.ts")} for rules.
262
260
  * Run ${cmd("npm test")} to verify.
263
261
  * See ${ref("skills/other/SKILL.md")} for format.
264
262
  * `
265
263
  */
266
- export declare function instructions(strings: TemplateStringsArray, ...values: InstructionFragment[]): InstructionFragment[];
264
+ export declare function prose(strings: TemplateStringsArray, ...values: InstructionFragment[]): InstructionFragment[];
267
265
  /**
268
266
  * Tagged template literal marking a side-effect boundary — usable as an
269
267
  * interpolated fragment inside a body / `instructions\`\``:
270
268
  *
271
- * instructions`
269
+ * prose`
272
270
  * ## Apply
273
271
  * ${effect`
274
272
  * Side effects are allowed ONLY here:
@@ -332,7 +330,7 @@ export interface ClaudeSpec {
332
330
  readonly rules: Record<string, Rule>;
333
331
  }
334
332
  /**
335
- * Input type for claude() — maxSectionLines is only valid when sections are provided.
333
+ * Input type for instructionFile() — maxSectionLines is only valid when sections are provided.
336
334
  * TypeScript errors if you set maxSectionLines without defining sections.
337
335
  */
338
336
  type ClaudeSpecBase = {
@@ -354,9 +352,9 @@ type ClaudeSpecInput = ClaudeSpecBase & ClaudeSpecSections;
354
352
  * Define a CLAUDE.md specification.
355
353
  *
356
354
  * // CLAUDE.md.spec.ts
357
- * export default claude({ commands: {...}, rules: {...} });
355
+ * export default instructionFile({ commands: {...}, rules: {...} });
358
356
  */
359
- export declare function claude(spec: ClaudeSpecInput): ClaudeSpec;
357
+ export declare function instructionFile(spec: ClaudeSpecInput): ClaudeSpec;
360
358
  /**
361
359
  * A deterministic gate on a skill step or its final result. A gate is one of:
362
360
  * a command (exit 0), a file (must exist), or a *project role* that resolves to
@@ -484,6 +482,25 @@ export interface SkillSpec {
484
482
  /**
485
483
  * Terminal postcondition — the skill is "done" only when this gate passes.
486
484
  * Compiles to a `## Result` section + a `vigiles:result` marker.
485
+ *
486
+ * 🔴 NAMED `postcondition`, NOT `result`, because `result` already means
487
+ * something else one screen down: {@link result} builds a subagent's typed
488
+ * ok/err CONTRACT (and reaches a skill through `output:`). Two concepts under
489
+ * one word, told apart only by whether you wrote `result:` or `output:
490
+ * result(...)` — the doc comment on {@link result} had to spend a line saying
491
+ * "distinct from a skill's `result:` postcondition gate", which is the tell.
492
+ * A name that needs a disambiguating sentence is the wrong name.
493
+ *
494
+ * The compiled MARKER stays `vigiles:result` deliberately: it is the wire
495
+ * format between the compiler and {@link parseSkillGates}, and every already
496
+ * compiled SKILL.md on disk carries it. Renaming the authoring field is a
497
+ * source-level change; renaming the marker would invalidate stamps.
498
+ */
499
+ readonly postcondition?: Gate;
500
+ /**
501
+ * @deprecated Renamed to {@link SkillSpec.postcondition}. Removed next
502
+ * major. Measured 2026-08-21: 0 of 46 specs in the consuming knowledge base
503
+ * set this field, so the window costs nothing and closes the collision above.
487
504
  */
488
505
  readonly result?: Gate;
489
506
  /**
@@ -524,7 +541,7 @@ export type SkillSpecInput<P extends AuthoredPurity | undefined, V extends ToolV
524
541
  * export default experimental_skill({ name: "my-skill", description: "…" });
525
542
  *
526
543
  * Generic over a tool `Vocabulary` (default `OpenToolVocabulary` — no
527
- * constraint), exactly like `agent()`: a vocabulary-bound `experimental_skill`
544
+ * constraint), exactly like `experimental_agent()`: a vocabulary-bound `experimental_skill`
528
545
  * (e.g. `vigiles/claude-code`) makes `purity: "pure"` + a side-effecting tool a
529
546
  * `tsc` error; the bare core one accepts any tools, as before.
530
547
  *
@@ -629,7 +646,7 @@ export interface AgentSpec {
629
646
  readonly purity?: AuthoredPurity;
630
647
  }
631
648
  /**
632
- * The input to `agent()` — `AgentSpec` minus the internal `_specType`, with the
649
+ * The input to `experimental_agent()` — `AgentSpec` minus the internal `_specType`, with the
633
650
  * `tools` list constrained by the declared `purity` and the tool vocabulary `V`.
634
651
  * `P` is inferred from the literal `purity` field (`const` inference), and
635
652
  * `tools` is then typed `AllowedAt<P, V>[]`:
@@ -637,7 +654,7 @@ export interface AgentSpec {
637
654
  * - `purity: "bounded"`→ `tools` may list `V["bounded"]` tools (admits `Bash`).
638
655
  * - no `purity` / `"dangerously-unrestricted"` → `tools` is `string[]` (open).
639
656
  *
640
- * With the open default vocabulary (core `agent()`) every level widens to
657
+ * With the open default vocabulary (core `experimental_agent()`) every level widens to
641
658
  * `string`, so any tools compile — backwards-compatible.
642
659
  */
643
660
  export type AgentSpecInput<P extends AuthoredPurity | undefined, V extends ToolVocabulary, Ok extends Shape = Shape, Err extends Shape = Shape> = Omit<AgentSpec, "_specType" | "tools" | "purity" | "output"> & {
@@ -672,12 +689,12 @@ export type OkOf<T> = T extends TypedOutcome<infer Ok, Shape> ? Ok : Shape;
672
689
  * Define a subagent specification (compiles to `agents/<name>.md`).
673
690
  *
674
691
  * // agents/reviewer.md.spec.ts
675
- * export default agent({
692
+ * export default experimental_agent({
676
693
  * name: "reviewer",
677
694
  * description: "Review a diff for correctness. Dispatch PROACTIVELY after edits.",
678
695
  * model: "sonnet",
679
696
  * tools: ["Read", "Grep", "Bash"],
680
- * body: instructions`Review the diff. Run ${cmd("npm test")} first.`,
697
+ * body: prose`Review the diff. Run ${cmd("npm test")} first.`,
681
698
  * rules: {
682
699
  * "no-floating": enforce("@typescript-eslint/no-floating-promises", "Await promises."),
683
700
  * },
@@ -686,15 +703,21 @@ export type OkOf<T> = T extends TypedOutcome<infer Ok, Shape> ? Ok : Shape;
686
703
  * Generic over a tool `Vocabulary` (default `OpenToolVocabulary` — no
687
704
  * constraint). A harness adapter re-exports a vocabulary-bound `agent` (e.g.
688
705
  * `vigiles/claude-code`) so `purity: "pure"` + a side-effecting tool is a `tsc`
689
- * error at edit time; the bare core `agent()` accepts any tools, as before.
706
+ * error at edit time; the bare core `experimental_agent()` accepts any tools, as before.
690
707
  *
691
708
  * Also generic over the result's `Ok`/`Err` shapes, inferred from `output:
692
709
  * result(...)`. The returned value is a `TypedAgentSpec<Ok, Err>` — an
693
710
  * `AgentSpec` that carries those shapes at the type level, so a typed `pipe`
694
711
  * can cross-reference the handoff. With no `output` the shapes default to the
695
712
  * erased `Shape`, and the value is still a plain `AgentSpec` — backwards-compatible.
713
+ *
714
+ * @experimental The SHAPE is not settled — the author is unsure of the design,
715
+ * which is exactly what this marker promises: the form may change. It is NOT a
716
+ * claim that the surface is unproven. Measured 2026-06-20: real Claude Code
717
+ * loaded a compiled `agents/code-reviewer.md`, dispatched to it and read it,
718
+ * 100% of trials — stronger end-to-end evidence than `experimental_skill` has.
696
719
  */
697
- export declare function agent<const P extends AuthoredPurity | undefined = undefined, V extends ToolVocabulary = OpenToolVocabulary, Ok extends Shape = Shape, Err extends Shape = Shape>(spec: AgentSpecInput<P, V, Ok, Err>): TypedAgentSpec<Ok, Err>;
720
+ declare function agentSpec<const P extends AuthoredPurity | undefined = undefined, V extends ToolVocabulary = OpenToolVocabulary, Ok extends Shape = Shape, Err extends Shape = Shape>(spec: AgentSpecInput<P, V, Ok, Err>): TypedAgentSpec<Ok, Err>;
698
721
  /**
699
722
  * The field types a result contract can declare (kept tiny + dependency-free).
700
723
  *
@@ -748,8 +771,9 @@ export interface OutputContract<Ok extends Shape = Shape, Err extends Shape = Sh
748
771
  * cross-reference one agent's `ok` against the next agent's needs at `tsc` time.
749
772
  * The return is still an `OutputContract`, so every existing consumer (the
750
773
  * `output:` field, `renderOutputContract`, `parseAgentResult`) is unchanged.
774
+
751
775
  */
752
- export declare function result<const Ok extends Shape, const Err extends Shape>(ok: Ok, err: Err): OutputContract<Ok, Err>;
776
+ declare function result<const Ok extends Shape, const Err extends Shape>(ok: Ok, err: Err): OutputContract<Ok, Err>;
753
777
  /** One step on a railway: dispatch a flat subagent (the "activity"). */
754
778
  export interface RailwayStep {
755
779
  readonly _step: "delegate";
@@ -780,8 +804,9 @@ export interface RailwayStep {
780
804
  * handoff that doesn't line up is a `tsc` error naming the offending field.
781
805
  * Omitting it (the historical 1-/2-arg call) keeps the exact string-path
782
806
  * behavior — fully backwards-compatible.
807
+
783
808
  */
784
- export declare function delegate(agent: string, task?: string, needsContract?: Shape): RailwayStep;
809
+ declare function delegate(agent: string, task?: string, needsContract?: Shape): RailwayStep;
785
810
  /**
786
811
  * A railway over flat subagents. `steps` run in order on the success track; the
787
812
  * first step that returns an error short-circuits to `onError`. `recover`
@@ -810,8 +835,9 @@ export interface Railway {
810
835
  * onError: delegate("reporter"),
811
836
  * recover: { step: delegate("fixer"), max: 2 },
812
837
  * })
838
+
813
839
  */
814
- export declare function railway(spec: Omit<Railway, "_specType">): Railway;
840
+ declare function railway(spec: Omit<Railway, "_specType">): Railway;
815
841
  /**
816
842
  * A subagent's INPUT contract — the fields it reads from the prior step's `ok`.
817
843
  * Declared via `needs(...)` and threaded into the typed agent so `pipe` can
@@ -831,8 +857,9 @@ export type NeedsContract<N extends Shape> = N;
831
857
  *
832
858
  * @experimental Experimental typed-composition surface — NOT part of the frozen
833
859
  * public API (pre-1.0); may change without a major bump.
860
+
834
861
  */
835
- export declare function experimental_needs<const N extends Shape>(shape: N): NeedsContract<N>;
862
+ declare function experimental_needs<const N extends Shape>(shape: N): NeedsContract<N>;
836
863
  /**
837
864
  * A typed pipeline step: a `TypedAgentSpec` paired with the input `needs` it
838
865
  * reads from the prior step's `ok`. `step()` builds one; `pipe` checks that the
@@ -848,15 +875,16 @@ export interface PipeStep<Needs extends Shape, Ok extends Shape, Err extends Sha
848
875
  }
849
876
  /**
850
877
  * Pair a typed agent with the input it `needs` from the previous step. The first
851
- * argument is an `agent()` VALUE (which carries its `result()` shape); the
878
+ * argument is an `experimental_agent()` VALUE (which carries its `result()` shape); the
852
879
  * second is the `needs(...)` input contract.
853
880
  *
854
881
  * pipeStep(implementer, needs({ plan: "string", files: "string[]" }))
855
882
  *
856
883
  * @experimental Experimental typed-composition surface — NOT part of the frozen
857
884
  * public API (pre-1.0); may change without a major bump.
885
+
858
886
  */
859
- export declare function experimental_pipeStep<Needs extends Shape, Ok extends Shape, Err extends Shape>(a: TypedAgentSpec<Ok, Err>, needsContract?: Needs): PipeStep<Needs, Ok, Err>;
887
+ declare function experimental_pipeStep<Needs extends Shape, Ok extends Shape, Err extends Shape>(a: TypedAgentSpec<Ok, Err>, needsContract?: Needs): PipeStep<Needs, Ok, Err>;
860
888
  /**
861
889
  * True iff `Producer` provides EVERY field `Consumer` needs, with matching
862
890
  * field types. When satisfiable it is `true`; otherwise it collapses to a
@@ -917,8 +945,9 @@ export interface Pipeline<Ok extends Shape, Err extends Shape> {
917
945
  *
918
946
  * @experimental Experimental typed-composition surface — NOT part of the frozen
919
947
  * public API (pre-1.0); may change without a major bump.
948
+
920
949
  */
921
- export declare function experimental_start<Ok extends Shape, Err extends Shape>(first: PipeStep<Record<string, never>, Ok, Err> | TypedAgentSpec<Ok, Err>): Pipeline<Ok, Err>;
950
+ declare function experimental_start<Ok extends Shape, Err extends Shape>(first: PipeStep<Record<string, never>, Ok, Err> | TypedAgentSpec<Ok, Err>): Pipeline<Ok, Err>;
922
951
  /**
923
952
  * Append a step to a typed pipeline. The handoff is CHECKED: the constraint
924
953
  * `Supplies<PriorOk, Needs>` must be `true`, else the `next` parameter's type
@@ -932,8 +961,9 @@ export declare function experimental_start<Ok extends Shape, Err extends Shape>(
932
961
  *
933
962
  * @experimental Experimental typed-composition surface — NOT part of the frozen
934
963
  * public API (pre-1.0); may change without a major bump.
964
+
935
965
  */
936
- export declare function experimental_andThen<PriorOk extends Shape, PriorErr extends Shape, Needs extends Shape, Ok extends Shape, Err extends Shape>(prior: Pipeline<PriorOk, PriorErr>, next: Supplies<PriorOk, Needs> extends true ? PipeStep<Needs, Ok, Err> : {
966
+ declare function experimental_andThen<PriorOk extends Shape, PriorErr extends Shape, Needs extends Shape, Ok extends Shape, Err extends Shape>(prior: Pipeline<PriorOk, PriorErr>, next: Supplies<PriorOk, Needs> extends true ? PipeStep<Needs, Ok, Err> : {
937
967
  readonly __HANDOFF_ERROR: Supplies<PriorOk, Needs>;
938
968
  }): Pipeline<Ok, PriorErr | Err>;
939
969
  /**
@@ -956,16 +986,16 @@ export declare function experimental_andThen<PriorOk extends Shape, PriorErr ext
956
986
  * @experimental Experimental typed-composition surface — NOT part of the frozen
957
987
  * public API (pre-1.0); may change without a major bump.
958
988
  */
959
- export declare function experimental_pipe<A extends Shape, AE extends Shape>(a: TypedAgentSpec<A, AE>): Pipeline<A, AE>;
960
- export declare function experimental_pipe<A extends Shape, AE extends Shape, BN extends Shape, B extends Shape, BE extends Shape>(a: TypedAgentSpec<A, AE>, b: Supplies<A, BN> extends true ? PipeStep<BN, B, BE> : {
989
+ declare function experimental_pipe<A extends Shape, AE extends Shape>(a: TypedAgentSpec<A, AE>): Pipeline<A, AE>;
990
+ declare function experimental_pipe<A extends Shape, AE extends Shape, BN extends Shape, B extends Shape, BE extends Shape>(a: TypedAgentSpec<A, AE>, b: Supplies<A, BN> extends true ? PipeStep<BN, B, BE> : {
961
991
  readonly __HANDOFF_ERROR: Supplies<A, BN>;
962
992
  }): Pipeline<B, AE | BE>;
963
- export declare function experimental_pipe<A extends Shape, AE extends Shape, BN extends Shape, B extends Shape, BE extends Shape, CN extends Shape, C extends Shape, CE extends Shape>(a: TypedAgentSpec<A, AE>, b: Supplies<A, BN> extends true ? PipeStep<BN, B, BE> : {
993
+ declare function experimental_pipe<A extends Shape, AE extends Shape, BN extends Shape, B extends Shape, BE extends Shape, CN extends Shape, C extends Shape, CE extends Shape>(a: TypedAgentSpec<A, AE>, b: Supplies<A, BN> extends true ? PipeStep<BN, B, BE> : {
964
994
  readonly __HANDOFF_ERROR: Supplies<A, BN>;
965
995
  }, c: Supplies<B, CN> extends true ? PipeStep<CN, C, CE> : {
966
996
  readonly __HANDOFF_ERROR: Supplies<B, CN>;
967
997
  }): Pipeline<C, AE | BE | CE>;
968
- export declare function experimental_pipe<A extends Shape, AE extends Shape, BN extends Shape, B extends Shape, BE extends Shape, CN extends Shape, C extends Shape, CE extends Shape, DN extends Shape, D extends Shape, DE extends Shape>(a: TypedAgentSpec<A, AE>, b: Supplies<A, BN> extends true ? PipeStep<BN, B, BE> : {
998
+ declare function experimental_pipe<A extends Shape, AE extends Shape, BN extends Shape, B extends Shape, BE extends Shape, CN extends Shape, C extends Shape, CE extends Shape, DN extends Shape, D extends Shape, DE extends Shape>(a: TypedAgentSpec<A, AE>, b: Supplies<A, BN> extends true ? PipeStep<BN, B, BE> : {
969
999
  readonly __HANDOFF_ERROR: Supplies<A, BN>;
970
1000
  }, c: Supplies<B, CN> extends true ? PipeStep<CN, C, CE> : {
971
1001
  readonly __HANDOFF_ERROR: Supplies<B, CN>;
@@ -1028,5 +1058,69 @@ export interface VigilesV2Config {
1028
1058
  readonly linters?: Record<string, LinterMode>;
1029
1059
  }
1030
1060
  export declare function defineConfig(config: VigilesV2Config): VigilesV2Config;
1061
+ /**
1062
+ * @deprecated Renamed to {@link instructionFile}. The builder compiles to
1063
+ * `CLAUDE.md` **and** `AGENTS.md` (see `InstructionTarget`), so a name taken from
1064
+ * one of the two harnesses was never right. Removed one major AFTER the one that introduces it.
1065
+ */
1066
+ export declare const claude: typeof instructionFile;
1067
+ /**
1068
+ * @deprecated Renamed to {@link prose}. It builds a prose FRAGMENT with typed
1069
+ * refs; the plural read as "the instruction file", which is what
1070
+ * {@link instructionFile} builds. Removed one major AFTER the one that introduces it.
1071
+ */
1072
+ export declare const instructions: typeof prose;
1073
+ /**
1074
+ * Define a subagent — and the ROOT of the subagent vocabulary.
1075
+ *
1076
+ * Everything that only makes sense for subagents hangs off this one symbol:
1077
+ * `experimental_agent.result()` (the outcome contract), `.railway()` / `.delegate()`
1078
+ * (the flat orchestrator), and `.pipe()` / `.start()` / `.andThen()` / `.pipeStep()` /
1079
+ * `.needs()` (the typed pipeline). Same chokepoint as `experimental_skill.input()`.
1080
+ *
1081
+ * WHY a root and not a prefix on each name: `railway()` and `delegate()` are
1082
+ * meaningless without a subagent, yet they shipped under STABLE names while the
1083
+ * builder they depend on is experimental — a stable name resting on an unstable
1084
+ * one. Prefixing each would carry the warning but multiply the vocabulary; a
1085
+ * namespace OBJECT was rejected for the reason the `vigiles/experimental` subpath
1086
+ * was retired in #169 — it marks the import line, out of view by the time anyone
1087
+ * reads the call. A member reached through the marked root cannot be destructured
1088
+ * free of its warning without renaming it, so the warning rides every call site.
1089
+ *
1090
+ * The rule this establishes: ONE experimental root per feature, everything else a
1091
+ * member of it, TYPES excluded (a type annotation is not a call site).
1092
+ *
1093
+ * @experimental
1094
+ */
1095
+ export declare const experimental_agent: typeof agentSpec & {
1096
+ result: typeof result;
1097
+ delegate: typeof delegate;
1098
+ railway: typeof railway;
1099
+ needs: typeof experimental_needs;
1100
+ pipeStep: typeof experimental_pipeStep;
1101
+ start: typeof experimental_start;
1102
+ andThen: typeof experimental_andThen;
1103
+ pipe: typeof experimental_pipe;
1104
+ };
1105
+ /**
1106
+ * @deprecated Renamed to {@link experimental_agent} — the shape is not settled.
1107
+ * Removed one major AFTER the one that introduces it.
1108
+ *
1109
+ * @experimental
1110
+ * vigiles:experimental-name-ok this IS the old spelling — prefixing a deprecated
1111
+ * alias would defeat the alias, which exists precisely so code written against
1112
+ * the unprefixed name keeps compiling for one major. It carries the tag because
1113
+ * it is the same function, and the tag is what the deprecation notice points at.
1114
+ */
1115
+ export declare const agent: typeof agentSpec & {
1116
+ result: typeof result;
1117
+ delegate: typeof delegate;
1118
+ railway: typeof railway;
1119
+ needs: typeof experimental_needs;
1120
+ pipeStep: typeof experimental_pipeStep;
1121
+ start: typeof experimental_start;
1122
+ andThen: typeof experimental_andThen;
1123
+ pipe: typeof experimental_pipe;
1124
+ };
1031
1125
  export {};
1032
1126
  //# sourceMappingURL=spec.d.ts.map