@yycholla/pi-dynamic-workflows 3.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.
- package/LICENSE +22 -0
- package/README.md +325 -0
- package/assets/readme/hero.png +0 -0
- package/assets/readme/hero.svg +70 -0
- package/assets/readme/package-cover.png +0 -0
- package/assets/readme/package-cover.svg +66 -0
- package/assets/readme/workflow.png +0 -0
- package/assets/readme/workflow.svg +77 -0
- package/dist/accept-workflow-guidance.d.ts +14 -0
- package/dist/accept-workflow-guidance.js +53 -0
- package/dist/adversarial-review.d.ts +30 -0
- package/dist/adversarial-review.js +107 -0
- package/dist/agent-history.d.ts +20 -0
- package/dist/agent-history.js +122 -0
- package/dist/agent-registry.d.ts +83 -0
- package/dist/agent-registry.js +190 -0
- package/dist/agent.d.ts +364 -0
- package/dist/agent.js +714 -0
- package/dist/builtin-commands.d.ts +19 -0
- package/dist/builtin-commands.js +251 -0
- package/dist/builtin-workflows.d.ts +45 -0
- package/dist/builtin-workflows.js +121 -0
- package/dist/code-review.d.ts +26 -0
- package/dist/code-review.js +181 -0
- package/dist/config.d.ts +37 -0
- package/dist/config.js +44 -0
- package/dist/deep-research.d.ts +30 -0
- package/dist/deep-research.js +124 -0
- package/dist/display.d.ts +134 -0
- package/dist/display.js +248 -0
- package/dist/effort-command.d.ts +28 -0
- package/dist/effort-command.js +68 -0
- package/dist/enums.d.ts +69 -0
- package/dist/enums.js +78 -0
- package/dist/errors.d.ts +113 -0
- package/dist/errors.js +140 -0
- package/dist/extension-reload.d.ts +37 -0
- package/dist/extension-reload.js +78 -0
- package/dist/fs-persistence.d.ts +63 -0
- package/dist/fs-persistence.js +102 -0
- package/dist/index.d.ts +57 -0
- package/dist/index.js +35 -0
- package/dist/logger.d.ts +21 -0
- package/dist/logger.js +66 -0
- package/dist/model-routing.d.ts +30 -0
- package/dist/model-routing.js +50 -0
- package/dist/model-spec.d.ts +29 -0
- package/dist/model-spec.js +252 -0
- package/dist/model-tier-config.d.ts +133 -0
- package/dist/model-tier-config.js +249 -0
- package/dist/run-persistence.d.ts +180 -0
- package/dist/run-persistence.js +294 -0
- package/dist/saved-commands.d.ts +28 -0
- package/dist/saved-commands.js +100 -0
- package/dist/shared-store.d.ts +98 -0
- package/dist/shared-store.js +212 -0
- package/dist/structured-output.d.ts +19 -0
- package/dist/structured-output.js +30 -0
- package/dist/task-panel.d.ts +61 -0
- package/dist/task-panel.js +422 -0
- package/dist/usage-limit-scheduler.d.ts +145 -0
- package/dist/usage-limit-scheduler.js +368 -0
- package/dist/web-tools.d.ts +20 -0
- package/dist/web-tools.js +120 -0
- package/dist/workflow-authoring-coverage.d.ts +70 -0
- package/dist/workflow-authoring-coverage.js +421 -0
- package/dist/workflow-authoring-reference.d.ts +20 -0
- package/dist/workflow-authoring-reference.js +156 -0
- package/dist/workflow-capability-contract.d.ts +131 -0
- package/dist/workflow-capability-contract.js +604 -0
- package/dist/workflow-commands.d.ts +18 -0
- package/dist/workflow-commands.js +260 -0
- package/dist/workflow-comprehension.d.ts +133 -0
- package/dist/workflow-comprehension.js +1321 -0
- package/dist/workflow-context-measurement.d.ts +72 -0
- package/dist/workflow-context-measurement.js +213 -0
- package/dist/workflow-control-tool.d.ts +30 -0
- package/dist/workflow-control-tool.js +176 -0
- package/dist/workflow-delivery-choice.d.ts +20 -0
- package/dist/workflow-delivery-choice.js +48 -0
- package/dist/workflow-editor.d.ts +93 -0
- package/dist/workflow-editor.js +363 -0
- package/dist/workflow-manager.d.ts +492 -0
- package/dist/workflow-manager.js +1124 -0
- package/dist/workflow-paths.d.ts +22 -0
- package/dist/workflow-paths.js +46 -0
- package/dist/workflow-release-gate.d.ts +39 -0
- package/dist/workflow-release-gate.js +309 -0
- package/dist/workflow-saved.d.ts +38 -0
- package/dist/workflow-saved.js +126 -0
- package/dist/workflow-settings.d.ts +70 -0
- package/dist/workflow-settings.js +131 -0
- package/dist/workflow-tool.d.ts +71 -0
- package/dist/workflow-tool.js +367 -0
- package/dist/workflow-ui.d.ts +182 -0
- package/dist/workflow-ui.js +1587 -0
- package/dist/workflow.d.ts +333 -0
- package/dist/workflow.js +1151 -0
- package/dist/workflows-models-command.d.ts +31 -0
- package/dist/workflows-models-command.js +156 -0
- package/dist/worktree.d.ts +25 -0
- package/dist/worktree.js +61 -0
- package/extensions/workflow.ts +151 -0
- package/package.json +104 -0
- package/skills/workflow-authoring/SKILL.md +30 -0
- package/skills/workflow-authoring/examples/adversarial-verification.js +63 -0
- package/skills/workflow-authoring/examples/bounded-semantic-retry.js +56 -0
- package/skills/workflow-authoring/examples/classify-and-act.js +67 -0
- package/skills/workflow-authoring/examples/fan-out-and-synthesize.js +47 -0
- package/skills/workflow-authoring/examples/generate-and-filter.js +68 -0
- package/skills/workflow-authoring/examples/loop-until-done.js +68 -0
- package/skills/workflow-authoring/examples/phased-budgets.js +75 -0
- package/skills/workflow-authoring/examples/saved-nested-workflows.js +44 -0
- package/skills/workflow-authoring/examples/structured-output.js +37 -0
- package/skills/workflow-authoring/examples/tournament.js +81 -0
- package/skills/workflow-authoring/examples/validated-gate.js +63 -0
- package/skills/workflow-authoring/references/capabilities.md +41 -0
- package/skills/workflow-authoring/references/capability-details.md +357 -0
- package/skills/workflow-authoring/references/common-helpers.md +4 -0
- package/skills/workflow-authoring/references/debugging.md +27 -0
- package/skills/workflow-authoring/references/focused-recipes.md +11 -0
- package/skills/workflow-authoring/references/helpers.md +9 -0
- package/skills/workflow-authoring/references/lifecycle.md +33 -0
- package/skills/workflow-authoring/references/pattern-selection.md +15 -0
- package/skills/workflow-authoring/references/quality-helpers.md +8 -0
- package/skills/workflow-authoring/references/registry-ownership.md +15 -0
- package/skills/workflow-authoring/references/retry-helper.md +5 -0
- package/skills/workflow-authoring/references/review.md +43 -0
- package/skills/workflow-authoring/references/runtime.md +27 -0
- package/skills/workflow-authoring/references/specialized-helpers.md +19 -0
- package/skills/workflow-authoring/references/versions.md +13 -0
- package/skills/workflow-patterns/SKILL.md +51 -0
- package/src/accept-workflow-guidance.ts +71 -0
- package/src/adversarial-review.ts +120 -0
- package/src/agent-history.ts +157 -0
- package/src/agent-registry.ts +221 -0
- package/src/agent.ts +929 -0
- package/src/builtin-commands.ts +286 -0
- package/src/builtin-workflows.ts +155 -0
- package/src/code-review.ts +183 -0
- package/src/config.ts +55 -0
- package/src/deep-research.ts +135 -0
- package/src/display.ts +367 -0
- package/src/effort-command.ts +87 -0
- package/src/enums.ts +77 -0
- package/src/errors.ts +199 -0
- package/src/extension-reload.ts +100 -0
- package/src/fs-persistence.ts +124 -0
- package/src/index.ts +176 -0
- package/src/logger.ts +88 -0
- package/src/model-routing.ts +73 -0
- package/src/model-spec.ts +309 -0
- package/src/model-tier-config.ts +296 -0
- package/src/run-persistence.ts +484 -0
- package/src/saved-commands.ts +115 -0
- package/src/shared-store.ts +228 -0
- package/src/structured-output.ts +47 -0
- package/src/task-panel.ts +490 -0
- package/src/usage-limit-scheduler.ts +432 -0
- package/src/web-tools.ts +124 -0
- package/src/workflow-authoring-coverage.ts +486 -0
- package/src/workflow-authoring-reference.ts +186 -0
- package/src/workflow-capability-contract.ts +806 -0
- package/src/workflow-commands.ts +287 -0
- package/src/workflow-comprehension.ts +1673 -0
- package/src/workflow-context-measurement.ts +262 -0
- package/src/workflow-control-tool.ts +238 -0
- package/src/workflow-delivery-choice.ts +69 -0
- package/src/workflow-editor.ts +444 -0
- package/src/workflow-manager.ts +1405 -0
- package/src/workflow-paths.ts +63 -0
- package/src/workflow-release-gate.ts +529 -0
- package/src/workflow-saved.ts +180 -0
- package/src/workflow-settings.ts +194 -0
- package/src/workflow-tool.ts +464 -0
- package/src/workflow-ui.ts +1789 -0
- package/src/workflow.ts +1615 -0
- package/src/workflows-models-command.ts +211 -0
- package/src/worktree.ts +76 -0
|
@@ -0,0 +1,486 @@
|
|
|
1
|
+
import {
|
|
2
|
+
CapabilityClassification,
|
|
3
|
+
CapabilitySupport,
|
|
4
|
+
DiscoveryPlacement,
|
|
5
|
+
WorkflowAuthoringProtection,
|
|
6
|
+
} from "./enums.js";
|
|
7
|
+
import { WORKFLOW_CAPABILITY_DEFINITION } from "./workflow-capability-contract.js";
|
|
8
|
+
import { COMPREHENSION_SCENARIOS } from "./workflow-comprehension.js";
|
|
9
|
+
|
|
10
|
+
/** Exact installed guidance location retained for an authoring surface without model evidence. */
|
|
11
|
+
export interface ProtectedGuidanceSurface {
|
|
12
|
+
path: string;
|
|
13
|
+
anchor?: string;
|
|
14
|
+
requiredText?: string;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/** Evidence and optimization policy for one stable workflow authoring surface. */
|
|
18
|
+
export interface WorkflowAuthoringCoverageEntry {
|
|
19
|
+
id: string;
|
|
20
|
+
kind: string;
|
|
21
|
+
reference: { path: string; anchor?: string };
|
|
22
|
+
example?: string;
|
|
23
|
+
behaviorEvidence: readonly string[];
|
|
24
|
+
comprehensionScenarios: readonly string[];
|
|
25
|
+
protection: WorkflowAuthoringProtection;
|
|
26
|
+
protectedGuidance: readonly ProtectedGuidanceSurface[];
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/** Scenario identifiers that release checks may accept as provider-backed evidence. */
|
|
30
|
+
export const WORKFLOW_COMPREHENSION_SCENARIO_IDS = COMPREHENSION_SCENARIOS.map(({ id }) => id);
|
|
31
|
+
|
|
32
|
+
/** Mixed guidance files that require explicit acceptance while behavioral coverage remains partial. */
|
|
33
|
+
export const WORKFLOW_AUTHORING_FROZEN_FILES = [
|
|
34
|
+
{
|
|
35
|
+
path: "skills/workflow-authoring/SKILL.md",
|
|
36
|
+
sha256: "d2843c4d928b6f622271c65bf4cf5d54cb219efca0ce92d8c5f4d8204365bf91",
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
path: "skills/workflow-authoring/references/runtime.md",
|
|
40
|
+
sha256: "14f1c4496c523d2e37316a7c96041a22630a65d342d08fdd77aeca2d325e22a3",
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
path: "skills/workflow-authoring/references/helpers.md",
|
|
44
|
+
sha256: "1c8d253649f00412511f17ffc08c6156797b99de72ae037e14f2ea92ac33a11e",
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
path: "skills/workflow-authoring/references/specialized-helpers.md",
|
|
48
|
+
sha256: "7597c94bbacea885697fb2d05a96ed9ec39403ca6d3a94547bf8ce5e233b2c76",
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
path: "skills/workflow-authoring/references/lifecycle.md",
|
|
52
|
+
sha256: "e2f187a7b633beef0ca257e6782f72a140fc06b37a58aac423432d36d1dc19ee",
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
path: "skills/workflow-authoring/references/pattern-selection.md",
|
|
56
|
+
sha256: "923988a1b4d506a7b330bf5e4b8ab47cf8456edcfe6674b5d8d8848264633c3d",
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
path: "skills/workflow-authoring/references/focused-recipes.md",
|
|
60
|
+
sha256: "30906054232f67029e31f71b3b093f9949f6de9116e4381f433009c401f2c5c7",
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
path: "skills/workflow-authoring/references/registry-ownership.md",
|
|
64
|
+
sha256: "daf324448be16732c6796fd6359d1b1b842fa550ed616a6154f556d6ec1ef0b9",
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
path: "skills/workflow-authoring/references/review.md",
|
|
68
|
+
sha256: "2bd97acb87a8f6e9514892cdf5c431305b3d8952ba9761c1c203c217b08c9e7d",
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
path: "skills/workflow-authoring/references/debugging.md",
|
|
72
|
+
sha256: "2938e635f5856f2934e42c9cc3b7035a66d53176f4ab2beadfeabb9abf42e6cc",
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
path: "skills/workflow-authoring/examples/classify-and-act.js",
|
|
76
|
+
sha256: "23d0d9f37ee8648cd29ca526b0b23cf55bd3ac57efd02e1b93e227bcd0c18603",
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
path: "skills/workflow-authoring/examples/tournament.js",
|
|
80
|
+
sha256: "3a90bd3055c5e38e13fd8d7447173fc2e6a141fbc33b9bcc8a84723b7ab9d2e6",
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
path: "skills/workflow-authoring/examples/validated-gate.js",
|
|
84
|
+
sha256: "1cb4b3941ae61ebd1e12ada899f7d04678fe858a307c7fabc408603a4b9ba889",
|
|
85
|
+
},
|
|
86
|
+
] as const;
|
|
87
|
+
|
|
88
|
+
const RUNTIME_PATH = "skills/workflow-authoring/references/runtime.md";
|
|
89
|
+
const SPECIALIZED_HELPERS_PATH = "skills/workflow-authoring/references/specialized-helpers.md";
|
|
90
|
+
const LIFECYCLE_PATH = "skills/workflow-authoring/references/lifecycle.md";
|
|
91
|
+
const PATTERN_PATH = "skills/workflow-authoring/references/pattern-selection.md";
|
|
92
|
+
const RECIPE_PATH = "skills/workflow-authoring/references/focused-recipes.md";
|
|
93
|
+
const SKILL_PATH = "skills/workflow-authoring/SKILL.md";
|
|
94
|
+
const WRITE_EDIT_ROUTE: ProtectedGuidanceSurface = {
|
|
95
|
+
path: SKILL_PATH,
|
|
96
|
+
requiredText:
|
|
97
|
+
"- **Write or edit:** start with [runtime](references/runtime.md). Add [pattern selection](references/pattern-selection.md) for topology, [lifecycle](references/lifecycle.md) for limits or resume, and [focused recipes](references/focused-recipes.md) for the matching concern.",
|
|
98
|
+
};
|
|
99
|
+
const HELPER_ROUTE: ProtectedGuidanceSurface = {
|
|
100
|
+
path: SKILL_PATH,
|
|
101
|
+
requiredText:
|
|
102
|
+
"- **Helper task:** read [quality helpers](references/quality-helpers.md) only for `verify` or `judgePanel`, the [retry helper](references/retry-helper.md) only for `retry`, and [specialized helpers](references/specialized-helpers.md) only for `completenessCheck`, `loopUntilDry`, `gate`, or `checkpoint`.",
|
|
103
|
+
};
|
|
104
|
+
const ROUTING_ROUTE: ProtectedGuidanceSurface = {
|
|
105
|
+
path: SKILL_PATH,
|
|
106
|
+
requiredText:
|
|
107
|
+
"- **Routing:** read [registry ownership](references/registry-ownership.md) before using `model`, `tier`, phase models, or `agentType`; use environment-specific names only when context supplies them.",
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
const CAPABILITY_SCENARIOS: Readonly<Record<string, readonly string[]>> = {
|
|
111
|
+
"workflow.runtime.agent": WORKFLOW_COMPREHENSION_SCENARIO_IDS,
|
|
112
|
+
"workflow.runtime.parallel": [
|
|
113
|
+
"quick-write",
|
|
114
|
+
"full-write",
|
|
115
|
+
"coverage-fan-out-synthesize",
|
|
116
|
+
"coverage-generate-filter",
|
|
117
|
+
"coverage-judge-panel",
|
|
118
|
+
],
|
|
119
|
+
"workflow.runtime.workflow": ["full-edit"],
|
|
120
|
+
"workflow.runtime.verify": ["full-review"],
|
|
121
|
+
"workflow.runtime.judgePanel": ["coverage-judge-panel"],
|
|
122
|
+
"workflow.runtime.retry": ["full-retry"],
|
|
123
|
+
"workflow.runtime.phase": ["full-edit"],
|
|
124
|
+
"workflow.script.metadata": WORKFLOW_COMPREHENSION_SCENARIO_IDS,
|
|
125
|
+
"workflow.script.return-value": WORKFLOW_COMPREHENSION_SCENARIO_IDS,
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
const FROZEN_GUIDANCE_BY_CAPABILITY: Readonly<Record<string, readonly ProtectedGuidanceSurface[]>> = {
|
|
129
|
+
"workflow.runtime.pipeline": [
|
|
130
|
+
{
|
|
131
|
+
path: RUNTIME_PATH,
|
|
132
|
+
requiredText:
|
|
133
|
+
"`pipeline()` runs stages sequentially per item while items proceed concurrently. Each stage receives `(previousValue, originalItem, index)` and forwards `null` to the next stage, so guard missing coverage first.",
|
|
134
|
+
},
|
|
135
|
+
],
|
|
136
|
+
"workflow.runtime.loopUntilDry": [
|
|
137
|
+
{
|
|
138
|
+
path: SPECIALIZED_HELPERS_PATH,
|
|
139
|
+
requiredText:
|
|
140
|
+
"`loopUntilDry({ round, key, consecutiveEmpty, maxRounds })` | `round(index)` is zero-based. Defaults: `JSON.stringify` key, two dry rounds, 50 rounds. Null, non-array, and duplicate-only rounds are dry. Token-budget or agent-limit exhaustion returns the partial array without a termination reason; keep failed-round identity and stopping state outside the helper.",
|
|
141
|
+
},
|
|
142
|
+
],
|
|
143
|
+
"workflow.runtime.completenessCheck": [
|
|
144
|
+
{
|
|
145
|
+
path: SPECIALIZED_HELPERS_PATH,
|
|
146
|
+
requiredText:
|
|
147
|
+
"`completenessCheck(args, results)` | Returns `{ complete, missing? }` or recoverable `null`. The critic sees only the first 4,000 serialized characters, so chunk or summarize larger evidence. Treat the verdict as advisory.",
|
|
148
|
+
},
|
|
149
|
+
],
|
|
150
|
+
"workflow.runtime.gate": [
|
|
151
|
+
{
|
|
152
|
+
path: SPECIALIZED_HELPERS_PATH,
|
|
153
|
+
requiredText:
|
|
154
|
+
"`gate(thunk, validator, { attempts })` | Calls `thunk(feedback, attempt)` with initial `undefined` feedback and a zero-based attempt. `validator(value)` returns `{ ok, feedback? }`, synchronously or asynchronously; a bare boolean is not accepted. Three attempts by default. Returns `{ ok, value, attempts }`, including the last value on exhaustion.",
|
|
155
|
+
},
|
|
156
|
+
],
|
|
157
|
+
"workflow.runtime.checkpoint": [
|
|
158
|
+
{
|
|
159
|
+
path: SPECIALIZED_HELPERS_PATH,
|
|
160
|
+
requiredText:
|
|
161
|
+
"`checkpoint(prompt, options?)` | Journals a human/default decision. Only foreground confirm and documented headless behavior work; input, select, and timeout are declared-only.",
|
|
162
|
+
},
|
|
163
|
+
{
|
|
164
|
+
path: LIFECYCLE_PATH,
|
|
165
|
+
requiredText:
|
|
166
|
+
"A workflow invocation is backgrounded by default, and background workflows are headless: they cannot display checkpoint confirmation.",
|
|
167
|
+
},
|
|
168
|
+
],
|
|
169
|
+
"workflow.runtime.log": [
|
|
170
|
+
{ path: SKILL_PATH, requiredText: "Use `log()` for new code; `console` is compatibility-only." },
|
|
171
|
+
],
|
|
172
|
+
"workflow.runtime.args": [
|
|
173
|
+
{
|
|
174
|
+
path: RUNTIME_PATH,
|
|
175
|
+
requiredText:
|
|
176
|
+
"The runtime supplies `agent`, `parallel`, `pipeline`, `workflow`, quality/control helpers, `phase`, `log`, `args`, `cwd`, restricted `process.cwd()`, and `budget`.",
|
|
177
|
+
},
|
|
178
|
+
],
|
|
179
|
+
"workflow.runtime.cwd": [
|
|
180
|
+
{
|
|
181
|
+
path: RUNTIME_PATH,
|
|
182
|
+
requiredText:
|
|
183
|
+
"The runtime supplies `agent`, `parallel`, `pipeline`, `workflow`, quality/control helpers, `phase`, `log`, `args`, `cwd`, restricted `process.cwd()`, and `budget`.",
|
|
184
|
+
},
|
|
185
|
+
],
|
|
186
|
+
"workflow.runtime.process": [
|
|
187
|
+
{
|
|
188
|
+
path: RUNTIME_PATH,
|
|
189
|
+
requiredText:
|
|
190
|
+
"The runtime supplies `agent`, `parallel`, `pipeline`, `workflow`, quality/control helpers, `phase`, `log`, `args`, `cwd`, restricted `process.cwd()`, and `budget`.",
|
|
191
|
+
},
|
|
192
|
+
],
|
|
193
|
+
"workflow.runtime.budget": [
|
|
194
|
+
{
|
|
195
|
+
path: LIFECYCLE_PATH,
|
|
196
|
+
requiredText:
|
|
197
|
+
"Token and phase budgets are soft pre-call gates. Spend lands after agents finish, so concurrent work can overshoot.",
|
|
198
|
+
},
|
|
199
|
+
],
|
|
200
|
+
"workflow.runtime.console": [
|
|
201
|
+
{ path: SKILL_PATH, requiredText: "Use `log()` for new code; `console` is compatibility-only." },
|
|
202
|
+
],
|
|
203
|
+
"workflow.tool-input.script": [{ path: RUNTIME_PATH, anchor: "script-envelope" }],
|
|
204
|
+
"workflow.tool-input.args": [
|
|
205
|
+
{
|
|
206
|
+
path: LIFECYCLE_PATH,
|
|
207
|
+
requiredText: "Pass timestamps, randomness, and external decisions through `args`.",
|
|
208
|
+
},
|
|
209
|
+
],
|
|
210
|
+
"workflow.tool-input.background": [
|
|
211
|
+
{
|
|
212
|
+
path: LIFECYCLE_PATH,
|
|
213
|
+
requiredText:
|
|
214
|
+
"A workflow invocation is backgrounded by default, and background workflows are headless: they cannot display checkpoint confirmation.",
|
|
215
|
+
},
|
|
216
|
+
],
|
|
217
|
+
"workflow.tool-input.maxAgents": [
|
|
218
|
+
{
|
|
219
|
+
path: LIFECYCLE_PATH,
|
|
220
|
+
requiredText:
|
|
221
|
+
"Set finite bounds that match the work: `maxAgents`, `concurrency`, `agentRetries`, `agentTimeoutMs`, and `tokenBudget` at invocation time; loop and semantic-retry bounds inside the script.",
|
|
222
|
+
},
|
|
223
|
+
],
|
|
224
|
+
"workflow.tool-input.concurrency": [
|
|
225
|
+
{
|
|
226
|
+
path: LIFECYCLE_PATH,
|
|
227
|
+
requiredText:
|
|
228
|
+
"Set finite bounds that match the work: `maxAgents`, `concurrency`, `agentRetries`, `agentTimeoutMs`, and `tokenBudget` at invocation time; loop and semantic-retry bounds inside the script.",
|
|
229
|
+
},
|
|
230
|
+
],
|
|
231
|
+
"workflow.tool-input.agentRetries": [
|
|
232
|
+
{
|
|
233
|
+
path: LIFECYCLE_PATH,
|
|
234
|
+
requiredText:
|
|
235
|
+
"Set finite bounds that match the work: `maxAgents`, `concurrency`, `agentRetries`, `agentTimeoutMs`, and `tokenBudget` at invocation time; loop and semantic-retry bounds inside the script.",
|
|
236
|
+
},
|
|
237
|
+
],
|
|
238
|
+
"workflow.tool-input.agentTimeoutMs": [
|
|
239
|
+
{
|
|
240
|
+
path: LIFECYCLE_PATH,
|
|
241
|
+
requiredText:
|
|
242
|
+
"Set finite bounds that match the work: `maxAgents`, `concurrency`, `agentRetries`, `agentTimeoutMs`, and `tokenBudget` at invocation time; loop and semantic-retry bounds inside the script.",
|
|
243
|
+
},
|
|
244
|
+
],
|
|
245
|
+
"workflow.tool-input.tokenBudget": [
|
|
246
|
+
{
|
|
247
|
+
path: LIFECYCLE_PATH,
|
|
248
|
+
requiredText:
|
|
249
|
+
"Token and phase budgets are soft pre-call gates. Spend lands after agents finish, so concurrent work can overshoot.",
|
|
250
|
+
},
|
|
251
|
+
],
|
|
252
|
+
"workflow.tool-input.resumeFromRunId": [
|
|
253
|
+
{
|
|
254
|
+
path: LIFECYCLE_PATH,
|
|
255
|
+
requiredText:
|
|
256
|
+
"Resume replays only the longest unchanged prefix of journaled calls. Once one call is new, changed, or unusable, that call and all later calls execute live.",
|
|
257
|
+
},
|
|
258
|
+
],
|
|
259
|
+
"workflow.script.determinism": [
|
|
260
|
+
{
|
|
261
|
+
path: SKILL_PATH,
|
|
262
|
+
requiredText:
|
|
263
|
+
"Write plain JavaScript without imports or filesystem modules. Pass nondeterminism through `args`; `Date.now()`, `Math.random()`, and no-argument `new Date()` are unavailable.",
|
|
264
|
+
},
|
|
265
|
+
],
|
|
266
|
+
"workflow.compat.markdown-fences": [
|
|
267
|
+
{
|
|
268
|
+
path: RUNTIME_PATH,
|
|
269
|
+
requiredText:
|
|
270
|
+
"Generated entries marked `supported` are authoring API. `console` and whole-script Markdown fences are compatibility-only.",
|
|
271
|
+
},
|
|
272
|
+
],
|
|
273
|
+
"workflow.dynamic.model-routes": [
|
|
274
|
+
{
|
|
275
|
+
path: RUNTIME_PATH,
|
|
276
|
+
requiredText:
|
|
277
|
+
"Use exact `model`, nonstandard `tier`, or `agentType` only when context supplies its name and purpose.",
|
|
278
|
+
},
|
|
279
|
+
],
|
|
280
|
+
"workflow.dynamic.agent-types": [
|
|
281
|
+
{
|
|
282
|
+
path: RUNTIME_PATH,
|
|
283
|
+
requiredText:
|
|
284
|
+
"Use exact `model`, nonstandard `tier`, or `agentType` only when context supplies its name and purpose.",
|
|
285
|
+
},
|
|
286
|
+
],
|
|
287
|
+
};
|
|
288
|
+
|
|
289
|
+
/** Stable orchestration-pattern identifiers covered by the authoring inventory. */
|
|
290
|
+
export const WORKFLOW_AUTHORING_PATTERN_IDS = [
|
|
291
|
+
"workflow.pattern.classify-and-act",
|
|
292
|
+
"workflow.pattern.fan-out-and-synthesize",
|
|
293
|
+
"workflow.pattern.adversarial-verification",
|
|
294
|
+
"workflow.pattern.generate-and-filter",
|
|
295
|
+
"workflow.pattern.tournament",
|
|
296
|
+
"workflow.pattern.loop-until-done",
|
|
297
|
+
] as const;
|
|
298
|
+
|
|
299
|
+
/** Stable focused-recipe identifiers covered by the authoring inventory. */
|
|
300
|
+
export const WORKFLOW_AUTHORING_RECIPE_IDS = [
|
|
301
|
+
"workflow.recipe.phased-budgets",
|
|
302
|
+
"workflow.recipe.saved-nested-workflows",
|
|
303
|
+
"workflow.recipe.bounded-semantic-retry",
|
|
304
|
+
"workflow.recipe.validator-feedback",
|
|
305
|
+
"workflow.recipe.structured-output",
|
|
306
|
+
] as const;
|
|
307
|
+
|
|
308
|
+
const PATTERN_COVERAGE: readonly WorkflowAuthoringCoverageEntry[] = [
|
|
309
|
+
{
|
|
310
|
+
id: "workflow.pattern.classify-and-act",
|
|
311
|
+
kind: "pattern",
|
|
312
|
+
reference: { path: PATTERN_PATH },
|
|
313
|
+
example: "skills/workflow-authoring/examples/classify-and-act.js",
|
|
314
|
+
behaviorEvidence: ["tests/workflow-authoring-skill.test.ts"],
|
|
315
|
+
comprehensionScenarios: [],
|
|
316
|
+
protection: WorkflowAuthoringProtection.GUIDANCE_FROZEN,
|
|
317
|
+
protectedGuidance: [
|
|
318
|
+
WRITE_EDIT_ROUTE,
|
|
319
|
+
{
|
|
320
|
+
path: PATTERN_PATH,
|
|
321
|
+
requiredText:
|
|
322
|
+
"| Heterogeneous items need different handling | Classify and act | Finish all classification before routed action; ledger classification and action failures by item ID | [Adapt](../examples/classify-and-act.js) |",
|
|
323
|
+
},
|
|
324
|
+
],
|
|
325
|
+
},
|
|
326
|
+
{
|
|
327
|
+
id: "workflow.pattern.fan-out-and-synthesize",
|
|
328
|
+
kind: "pattern",
|
|
329
|
+
reference: { path: PATTERN_PATH, anchor: "fan-out-and-synthesize" },
|
|
330
|
+
example: "skills/workflow-authoring/examples/fan-out-and-synthesize.js",
|
|
331
|
+
behaviorEvidence: ["tests/workflow-authoring-skill.test.ts", "tests/workflow-comprehension.test.ts"],
|
|
332
|
+
comprehensionScenarios: ["coverage-fan-out-synthesize"],
|
|
333
|
+
protection: WorkflowAuthoringProtection.BEHAVIORALLY_COVERED,
|
|
334
|
+
protectedGuidance: [],
|
|
335
|
+
},
|
|
336
|
+
{
|
|
337
|
+
id: "workflow.pattern.adversarial-verification",
|
|
338
|
+
kind: "pattern",
|
|
339
|
+
reference: { path: PATTERN_PATH },
|
|
340
|
+
example: "skills/workflow-authoring/examples/adversarial-verification.js",
|
|
341
|
+
behaviorEvidence: ["tests/workflow-authoring-skill.test.ts", "tests/workflow-comprehension.test.ts"],
|
|
342
|
+
comprehensionScenarios: ["full-review"],
|
|
343
|
+
protection: WorkflowAuthoringProtection.BEHAVIORALLY_COVERED,
|
|
344
|
+
protectedGuidance: [],
|
|
345
|
+
},
|
|
346
|
+
{
|
|
347
|
+
id: "workflow.pattern.generate-and-filter",
|
|
348
|
+
kind: "pattern",
|
|
349
|
+
reference: { path: PATTERN_PATH },
|
|
350
|
+
example: "skills/workflow-authoring/examples/generate-and-filter.js",
|
|
351
|
+
behaviorEvidence: ["tests/workflow-authoring-skill.test.ts", "tests/workflow-comprehension.test.ts"],
|
|
352
|
+
comprehensionScenarios: ["coverage-generate-filter"],
|
|
353
|
+
protection: WorkflowAuthoringProtection.BEHAVIORALLY_COVERED,
|
|
354
|
+
protectedGuidance: [],
|
|
355
|
+
},
|
|
356
|
+
{
|
|
357
|
+
id: "workflow.pattern.tournament",
|
|
358
|
+
kind: "pattern",
|
|
359
|
+
reference: { path: PATTERN_PATH },
|
|
360
|
+
example: "skills/workflow-authoring/examples/tournament.js",
|
|
361
|
+
behaviorEvidence: ["tests/workflow-authoring-skill.test.ts"],
|
|
362
|
+
comprehensionScenarios: [],
|
|
363
|
+
protection: WorkflowAuthoringProtection.GUIDANCE_FROZEN,
|
|
364
|
+
protectedGuidance: [
|
|
365
|
+
WRITE_EDIT_ROUTE,
|
|
366
|
+
{
|
|
367
|
+
path: PATTERN_PATH,
|
|
368
|
+
requiredText:
|
|
369
|
+
"| Pairwise comparison beats absolute scoring | Tournament | Let JavaScript run the bounded bracket and byes; agents compare one pair; ledger match failures | [Adapt](../examples/tournament.js) |",
|
|
370
|
+
},
|
|
371
|
+
],
|
|
372
|
+
},
|
|
373
|
+
{
|
|
374
|
+
id: "workflow.pattern.loop-until-done",
|
|
375
|
+
kind: "pattern",
|
|
376
|
+
reference: { path: PATTERN_PATH },
|
|
377
|
+
example: "skills/workflow-authoring/examples/loop-until-done.js",
|
|
378
|
+
behaviorEvidence: ["tests/workflow-authoring-skill.test.ts", "tests/workflow-comprehension.test.ts"],
|
|
379
|
+
comprehensionScenarios: ["full-loop"],
|
|
380
|
+
protection: WorkflowAuthoringProtection.BEHAVIORALLY_COVERED,
|
|
381
|
+
protectedGuidance: [],
|
|
382
|
+
},
|
|
383
|
+
];
|
|
384
|
+
|
|
385
|
+
const RECIPE_COVERAGE: readonly WorkflowAuthoringCoverageEntry[] = [
|
|
386
|
+
{
|
|
387
|
+
id: "workflow.recipe.phased-budgets",
|
|
388
|
+
kind: "recipe",
|
|
389
|
+
reference: { path: RECIPE_PATH },
|
|
390
|
+
example: "skills/workflow-authoring/examples/phased-budgets.js",
|
|
391
|
+
behaviorEvidence: ["tests/workflow-authoring-skill.test.ts", "tests/workflow-comprehension.test.ts"],
|
|
392
|
+
comprehensionScenarios: ["full-edit"],
|
|
393
|
+
protection: WorkflowAuthoringProtection.BEHAVIORALLY_COVERED,
|
|
394
|
+
protectedGuidance: [],
|
|
395
|
+
},
|
|
396
|
+
{
|
|
397
|
+
id: "workflow.recipe.saved-nested-workflows",
|
|
398
|
+
kind: "recipe",
|
|
399
|
+
reference: { path: RECIPE_PATH },
|
|
400
|
+
example: "skills/workflow-authoring/examples/saved-nested-workflows.js",
|
|
401
|
+
behaviorEvidence: ["tests/workflow-authoring-skill.test.ts", "tests/workflow-comprehension.test.ts"],
|
|
402
|
+
comprehensionScenarios: ["full-edit"],
|
|
403
|
+
protection: WorkflowAuthoringProtection.BEHAVIORALLY_COVERED,
|
|
404
|
+
protectedGuidance: [],
|
|
405
|
+
},
|
|
406
|
+
{
|
|
407
|
+
id: "workflow.recipe.bounded-semantic-retry",
|
|
408
|
+
kind: "recipe",
|
|
409
|
+
reference: { path: RECIPE_PATH },
|
|
410
|
+
example: "skills/workflow-authoring/examples/bounded-semantic-retry.js",
|
|
411
|
+
behaviorEvidence: ["tests/workflow-authoring-skill.test.ts", "tests/workflow-comprehension.test.ts"],
|
|
412
|
+
comprehensionScenarios: ["full-retry"],
|
|
413
|
+
protection: WorkflowAuthoringProtection.BEHAVIORALLY_COVERED,
|
|
414
|
+
protectedGuidance: [],
|
|
415
|
+
},
|
|
416
|
+
{
|
|
417
|
+
id: "workflow.recipe.validator-feedback",
|
|
418
|
+
kind: "recipe",
|
|
419
|
+
reference: { path: RECIPE_PATH },
|
|
420
|
+
example: "skills/workflow-authoring/examples/validated-gate.js",
|
|
421
|
+
behaviorEvidence: ["tests/workflow-authoring-skill.test.ts"],
|
|
422
|
+
comprehensionScenarios: [],
|
|
423
|
+
protection: WorkflowAuthoringProtection.GUIDANCE_FROZEN,
|
|
424
|
+
protectedGuidance: [
|
|
425
|
+
WRITE_EDIT_ROUTE,
|
|
426
|
+
{
|
|
427
|
+
path: RECIPE_PATH,
|
|
428
|
+
requiredText:
|
|
429
|
+
"| Validator feedback | Follow the exact `gate()` callbacks in [specialized helpers](specialized-helpers.md). Return the gate outcome and attempt ledger so feedback and exhaustion remain visible. | [Validated gate](../examples/validated-gate.js) |",
|
|
430
|
+
},
|
|
431
|
+
],
|
|
432
|
+
},
|
|
433
|
+
{
|
|
434
|
+
id: "workflow.recipe.structured-output",
|
|
435
|
+
kind: "recipe",
|
|
436
|
+
reference: { path: RECIPE_PATH },
|
|
437
|
+
example: "skills/workflow-authoring/examples/structured-output.js",
|
|
438
|
+
behaviorEvidence: ["tests/workflow-authoring-skill.test.ts", "tests/workflow-comprehension.test.ts"],
|
|
439
|
+
comprehensionScenarios: ["full-write", "full-debug", "full-loop", "full-retry"],
|
|
440
|
+
protection: WorkflowAuthoringProtection.BEHAVIORALLY_COVERED,
|
|
441
|
+
protectedGuidance: [],
|
|
442
|
+
},
|
|
443
|
+
];
|
|
444
|
+
|
|
445
|
+
const HELPER_CAPABILITY_IDS = new Set([
|
|
446
|
+
"workflow.runtime.verify",
|
|
447
|
+
"workflow.runtime.judgePanel",
|
|
448
|
+
"workflow.runtime.completenessCheck",
|
|
449
|
+
"workflow.runtime.loopUntilDry",
|
|
450
|
+
"workflow.runtime.retry",
|
|
451
|
+
"workflow.runtime.gate",
|
|
452
|
+
"workflow.runtime.checkpoint",
|
|
453
|
+
]);
|
|
454
|
+
|
|
455
|
+
const CONTRACT_COVERAGE: readonly WorkflowAuthoringCoverageEntry[] = WORKFLOW_CAPABILITY_DEFINITION.capabilities
|
|
456
|
+
.filter(({ discovery, support }) => discovery !== DiscoveryPlacement.NONE && support !== CapabilitySupport.INTERNAL)
|
|
457
|
+
.map((capability) => {
|
|
458
|
+
const comprehensionScenarios = CAPABILITY_SCENARIOS[capability.id] ?? [];
|
|
459
|
+
const frozenGuidance = FROZEN_GUIDANCE_BY_CAPABILITY[capability.id] ?? [];
|
|
460
|
+
const route =
|
|
461
|
+
capability.classification === CapabilityClassification.DYNAMIC_REFERENCE
|
|
462
|
+
? ROUTING_ROUTE
|
|
463
|
+
: HELPER_CAPABILITY_IDS.has(capability.id)
|
|
464
|
+
? HELPER_ROUTE
|
|
465
|
+
: WRITE_EDIT_ROUTE;
|
|
466
|
+
const protectedGuidance = comprehensionScenarios.length > 0 ? [] : [...frozenGuidance, route];
|
|
467
|
+
return {
|
|
468
|
+
id: capability.id,
|
|
469
|
+
kind: capability.classification,
|
|
470
|
+
reference: capability.staticReference ?? { path: "skills/workflow-authoring/references/capabilities.md" },
|
|
471
|
+
behaviorEvidence: capability.behaviorEvidence,
|
|
472
|
+
comprehensionScenarios,
|
|
473
|
+
protection:
|
|
474
|
+
comprehensionScenarios.length > 0
|
|
475
|
+
? WorkflowAuthoringProtection.BEHAVIORALLY_COVERED
|
|
476
|
+
: WorkflowAuthoringProtection.GUIDANCE_FROZEN,
|
|
477
|
+
protectedGuidance,
|
|
478
|
+
};
|
|
479
|
+
});
|
|
480
|
+
|
|
481
|
+
/** Complete release-gated inventory of behavioral coverage and frozen authoring guidance. */
|
|
482
|
+
export const WORKFLOW_AUTHORING_COVERAGE: readonly WorkflowAuthoringCoverageEntry[] = [
|
|
483
|
+
...CONTRACT_COVERAGE,
|
|
484
|
+
...PATTERN_COVERAGE,
|
|
485
|
+
...RECIPE_COVERAGE,
|
|
486
|
+
];
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
import { readFileSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import {
|
|
4
|
+
CapabilityClassification,
|
|
5
|
+
CapabilitySupport,
|
|
6
|
+
type OptionDescriptor,
|
|
7
|
+
type StaticCapabilityFact,
|
|
8
|
+
WORKFLOW_CAPABILITY_CONTRACT,
|
|
9
|
+
} from "./workflow-capability-contract.js";
|
|
10
|
+
|
|
11
|
+
const GENERATED_MARKER = "<!-- GENERATED from WORKFLOW_CAPABILITY_CONTRACT; do not edit by hand. -->";
|
|
12
|
+
const TABLE_START = "<!-- BEGIN GENERATED SUPPORTED WORKFLOW CAPABILITIES -->";
|
|
13
|
+
const TABLE_END = "<!-- END GENERATED SUPPORTED WORKFLOW CAPABILITIES -->";
|
|
14
|
+
|
|
15
|
+
/** Package-relative compact capability index generated from the contract. */
|
|
16
|
+
export const CAPABILITY_INDEX_PATH = "skills/workflow-authoring/references/capabilities.md";
|
|
17
|
+
|
|
18
|
+
/** Package-relative exhaustive generated capability reference. */
|
|
19
|
+
export const CAPABILITY_DETAIL_PATH = "skills/workflow-authoring/references/capability-details.md";
|
|
20
|
+
|
|
21
|
+
/** Documents that embed the byte-identical supported-capability table. */
|
|
22
|
+
export const CAPABILITY_TABLE_PUBLICATION_PATHS = [
|
|
23
|
+
CAPABILITY_INDEX_PATH,
|
|
24
|
+
"README.md",
|
|
25
|
+
"docs/workflow-authoring.md",
|
|
26
|
+
] as const;
|
|
27
|
+
/** All generated capability publication surfaces checked for drift. */
|
|
28
|
+
export const CAPABILITY_PUBLICATION_PATHS = [...CAPABILITY_TABLE_PUBLICATION_PATHS, CAPABILITY_DETAIL_PATH] as const;
|
|
29
|
+
|
|
30
|
+
function escapeTable(value: string): string {
|
|
31
|
+
return value.replaceAll("|", "\\|").replaceAll("\n", " ");
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function display(value: string | null): string {
|
|
35
|
+
return value === null ? "—" : `\`${escapeTable(value)}\``;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function optionText(option: OptionDescriptor): string {
|
|
39
|
+
const required = option.optional ? "optional" : "required";
|
|
40
|
+
const defaultValue = option.default === null ? "" : `; default: ${option.default}`;
|
|
41
|
+
const constraints = option.constraints.length === 0 ? "" : `; ${option.constraints.join("; ")}`;
|
|
42
|
+
const dynamic = option.dynamicReference === null ? "" : `; dynamic reference: ${option.dynamicReference}`;
|
|
43
|
+
return `- \`${option.name}\`: ${option.type} (${required}${defaultValue}${constraints}${dynamic})`;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function compactOptions(fact: StaticCapabilityFact): string {
|
|
47
|
+
if (!fact.options) return "—";
|
|
48
|
+
return fact.options.options
|
|
49
|
+
.map((option) => {
|
|
50
|
+
const optionality = option.optional ? "optional" : "required";
|
|
51
|
+
const defaultValue = option.default === null ? "" : `; default: ${option.default}`;
|
|
52
|
+
return `\`${escapeTable(option.name)}\`: ${escapeTable(option.type)} (${optionality}${escapeTable(defaultValue)})`;
|
|
53
|
+
})
|
|
54
|
+
.join("<br>");
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function publishedFacts(): readonly StaticCapabilityFact[] {
|
|
58
|
+
return WORKFLOW_CAPABILITY_CONTRACT.projectStaticReferenceFacts().filter(
|
|
59
|
+
(fact) =>
|
|
60
|
+
fact.support === CapabilitySupport.SUPPORTED &&
|
|
61
|
+
(fact.classification === CapabilityClassification.RUNTIME_GLOBAL ||
|
|
62
|
+
fact.classification === CapabilityClassification.WORKFLOW_TOOL_INPUT),
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/** The byte-identical generated block embedded in every public documentation surface. */
|
|
67
|
+
export function renderSupportedCapabilityTable(): string {
|
|
68
|
+
const rows = publishedFacts().map(
|
|
69
|
+
(fact) =>
|
|
70
|
+
`| ${escapeTable(fact.label)} | ${fact.classification} | ${display(fact.signature)} | ${compactOptions(fact)} |`,
|
|
71
|
+
);
|
|
72
|
+
return `${TABLE_START}
|
|
73
|
+
| Name | Classification | Signature | Options and defaults |
|
|
74
|
+
| --- | --- | --- | --- |
|
|
75
|
+
${rows.join("\n")}
|
|
76
|
+
${TABLE_END}`;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function replaceSupportedCapabilityTable(document: string): string | null {
|
|
80
|
+
const start = document.indexOf(TABLE_START);
|
|
81
|
+
const end = document.indexOf(TABLE_END, start + TABLE_START.length);
|
|
82
|
+
if (start < 0 || end < 0 || document.indexOf(TABLE_START, start + TABLE_START.length) >= 0) return null;
|
|
83
|
+
const after = end + TABLE_END.length;
|
|
84
|
+
return `${document.slice(0, start)}${renderSupportedCapabilityTable()}${document.slice(after)}`;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/** Regenerates only contract-owned content, preserving hand-written prose around marked blocks. */
|
|
88
|
+
export function writeWorkflowCapabilityPublications(root: string): void {
|
|
89
|
+
for (const path of CAPABILITY_TABLE_PUBLICATION_PATHS) {
|
|
90
|
+
const absolutePath = join(root, path);
|
|
91
|
+
if (path === CAPABILITY_INDEX_PATH) {
|
|
92
|
+
writeFileSync(absolutePath, renderWorkflowCapabilityReference());
|
|
93
|
+
continue;
|
|
94
|
+
}
|
|
95
|
+
const source = readFileSync(absolutePath, "utf8");
|
|
96
|
+
const refreshed = replaceSupportedCapabilityTable(source);
|
|
97
|
+
if (refreshed === null) throw new Error(`Missing or duplicate generated capability-table anchors in ${path}.`);
|
|
98
|
+
writeFileSync(absolutePath, refreshed);
|
|
99
|
+
}
|
|
100
|
+
writeFileSync(join(root, CAPABILITY_DETAIL_PATH), renderWorkflowCapabilityDetails());
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/** Returns every stale surface in stable publication order. Overrides are useful to CI callers and tests. */
|
|
104
|
+
export function checkWorkflowCapabilityPublications(
|
|
105
|
+
root: string,
|
|
106
|
+
overrides: Readonly<Partial<Record<(typeof CAPABILITY_PUBLICATION_PATHS)[number], string>>> = {},
|
|
107
|
+
): string[] {
|
|
108
|
+
const stale: string[] = [];
|
|
109
|
+
for (const path of CAPABILITY_TABLE_PUBLICATION_PATHS) {
|
|
110
|
+
const actual = overrides[path] ?? readFileSync(join(root, path), "utf8");
|
|
111
|
+
if (path === CAPABILITY_INDEX_PATH) {
|
|
112
|
+
if (actual !== renderWorkflowCapabilityReference()) stale.push(path);
|
|
113
|
+
continue;
|
|
114
|
+
}
|
|
115
|
+
const refreshed = replaceSupportedCapabilityTable(actual);
|
|
116
|
+
if (refreshed === null || refreshed !== actual) stale.push(path);
|
|
117
|
+
}
|
|
118
|
+
const details = overrides[CAPABILITY_DETAIL_PATH] ?? readFileSync(join(root, CAPABILITY_DETAIL_PATH), "utf8");
|
|
119
|
+
if (details !== renderWorkflowCapabilityDetails()) stale.push(CAPABILITY_DETAIL_PATH);
|
|
120
|
+
return stale;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
function anchorFor(fact: StaticCapabilityFact): string {
|
|
124
|
+
const anchor = fact.reference?.split("#")[1];
|
|
125
|
+
if (!anchor) throw new Error(`Static capability fact ${fact.id} has no reference anchor.`);
|
|
126
|
+
return anchor;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
function detail(fact: StaticCapabilityFact): string {
|
|
130
|
+
const lines = [
|
|
131
|
+
`<a id="${anchorFor(fact)}"></a>`,
|
|
132
|
+
`## ${fact.label}`,
|
|
133
|
+
"",
|
|
134
|
+
`- Classification: \`${fact.classification}\``,
|
|
135
|
+
`- Support: \`${fact.support}\``,
|
|
136
|
+
`- Signature: ${display(fact.signature)}`,
|
|
137
|
+
];
|
|
138
|
+
if (fact.options) {
|
|
139
|
+
lines.push(`- Option shape: \`${fact.options.id}\``, ...fact.options.options.map(optionText));
|
|
140
|
+
}
|
|
141
|
+
if (fact.constraints.length > 0) lines.push(...fact.constraints.map((constraint) => `- Constraint: ${constraint}`));
|
|
142
|
+
if (fact.dynamicReference) {
|
|
143
|
+
lines.push(
|
|
144
|
+
`- Dynamic reference owner: \`${fact.dynamicReference.owner}\``,
|
|
145
|
+
`- Item shape: \`${fact.dynamicReference.itemShape}\``,
|
|
146
|
+
`- Future lookup connection: \`${fact.dynamicReference.connection}\``,
|
|
147
|
+
"- Live values are intentionally absent from this static reference.",
|
|
148
|
+
);
|
|
149
|
+
}
|
|
150
|
+
return `${lines.join("\n")}\n`;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/** Compact generated entrypoint for ordinary exact-name and signature lookup. */
|
|
154
|
+
/** Render the compact index that routes exact lookups to exhaustive details. */
|
|
155
|
+
export function renderWorkflowCapabilityReference(): string {
|
|
156
|
+
const { definition } = WORKFLOW_CAPABILITY_CONTRACT;
|
|
157
|
+
return `${GENERATED_MARKER}
|
|
158
|
+
# Workflow capability index
|
|
159
|
+
|
|
160
|
+
Contract format: \`${definition.versions.format.version}\`<br>
|
|
161
|
+
Contract content / skill / extension: \`${definition.versions.content.version}\`
|
|
162
|
+
|
|
163
|
+
This compact generated index covers supported runtime globals and workflow-tool inputs. For constraints, compatibility behavior, internal boundaries, and dynamic-reference ownership, follow the [exhaustive generated facts](capability-details.md).
|
|
164
|
+
|
|
165
|
+
## Supported capability index
|
|
166
|
+
|
|
167
|
+
${renderSupportedCapabilityTable()}
|
|
168
|
+
`;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/** Exhaustive generated fact projection and stable anchor owner. */
|
|
172
|
+
/** Render exhaustive static facts while leaving live catalogues as dynamic references. */
|
|
173
|
+
export function renderWorkflowCapabilityDetails(): string {
|
|
174
|
+
const { definition } = WORKFLOW_CAPABILITY_CONTRACT;
|
|
175
|
+
const facts = WORKFLOW_CAPABILITY_CONTRACT.projectStaticReferenceFacts();
|
|
176
|
+
|
|
177
|
+
return `${GENERATED_MARKER}
|
|
178
|
+
# Exhaustive workflow capability facts
|
|
179
|
+
|
|
180
|
+
Contract format: \`${definition.versions.format.version}\`<br>
|
|
181
|
+
Contract content / skill / extension: \`${definition.versions.content.version}\`
|
|
182
|
+
|
|
183
|
+
Every exact fact below is projected from the installed extension's capability contract. Explanatory judgment belongs in the hand-written references next to this file.
|
|
184
|
+
|
|
185
|
+
${facts.map(detail).join("\n")}`;
|
|
186
|
+
}
|