gsd-pi 2.41.0-dev.cac69f9 → 2.42.0-dev.97e9e30

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 (115) hide show
  1. package/dist/resources/extensions/gsd/auto/loop.js +80 -0
  2. package/dist/resources/extensions/gsd/auto/phases.js +2 -2
  3. package/dist/resources/extensions/gsd/auto/session.js +6 -0
  4. package/dist/resources/extensions/gsd/auto-dashboard.js +2 -0
  5. package/dist/resources/extensions/gsd/auto.js +28 -1
  6. package/dist/resources/extensions/gsd/bootstrap/tool-call-loop-guard.js +7 -2
  7. package/dist/resources/extensions/gsd/commands/catalog.js +32 -0
  8. package/dist/resources/extensions/gsd/commands/handlers/workflow.js +146 -0
  9. package/dist/resources/extensions/gsd/context-injector.js +74 -0
  10. package/dist/resources/extensions/gsd/custom-execution-policy.js +47 -0
  11. package/dist/resources/extensions/gsd/custom-verification.js +145 -0
  12. package/dist/resources/extensions/gsd/custom-workflow-engine.js +164 -0
  13. package/dist/resources/extensions/gsd/dashboard-overlay.js +1 -0
  14. package/dist/resources/extensions/gsd/definition-loader.js +352 -0
  15. package/dist/resources/extensions/gsd/dev-execution-policy.js +24 -0
  16. package/dist/resources/extensions/gsd/dev-workflow-engine.js +82 -0
  17. package/dist/resources/extensions/gsd/engine-resolver.js +40 -0
  18. package/dist/resources/extensions/gsd/engine-types.js +8 -0
  19. package/dist/resources/extensions/gsd/execution-policy.js +8 -0
  20. package/dist/resources/extensions/gsd/graph.js +225 -0
  21. package/dist/resources/extensions/gsd/run-manager.js +134 -0
  22. package/dist/resources/extensions/gsd/workflow-engine.js +7 -0
  23. package/dist/resources/skills/create-workflow/SKILL.md +103 -0
  24. package/dist/resources/skills/create-workflow/references/feature-patterns.md +128 -0
  25. package/dist/resources/skills/create-workflow/references/verification-policies.md +76 -0
  26. package/dist/resources/skills/create-workflow/references/yaml-schema-v1.md +46 -0
  27. package/dist/resources/skills/create-workflow/templates/blog-post-pipeline.yaml +60 -0
  28. package/dist/resources/skills/create-workflow/templates/code-audit.yaml +60 -0
  29. package/dist/resources/skills/create-workflow/templates/release-checklist.yaml +66 -0
  30. package/dist/resources/skills/create-workflow/templates/workflow-definition.yaml +32 -0
  31. package/dist/resources/skills/create-workflow/workflows/create-from-scratch.md +104 -0
  32. package/dist/resources/skills/create-workflow/workflows/create-from-template.md +72 -0
  33. package/dist/web/standalone/.next/BUILD_ID +1 -1
  34. package/dist/web/standalone/.next/app-path-routes-manifest.json +15 -15
  35. package/dist/web/standalone/.next/build-manifest.json +2 -2
  36. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  37. package/dist/web/standalone/.next/server/app/_global-error.html +2 -2
  38. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  39. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  40. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  41. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  42. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  43. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  44. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  45. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  46. package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
  47. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  48. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  49. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  50. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  51. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  52. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  53. package/dist/web/standalone/.next/server/app/index.html +1 -1
  54. package/dist/web/standalone/.next/server/app/index.rsc +1 -1
  55. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  56. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
  57. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  58. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  59. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  60. package/dist/web/standalone/.next/server/app-paths-manifest.json +15 -15
  61. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  62. package/dist/web/standalone/.next/server/pages/500.html +2 -2
  63. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  64. package/package.json +1 -1
  65. package/packages/pi-coding-agent/package.json +1 -1
  66. package/pkg/package.json +1 -1
  67. package/src/resources/extensions/gsd/auto/loop.ts +91 -0
  68. package/src/resources/extensions/gsd/auto/phases.ts +2 -2
  69. package/src/resources/extensions/gsd/auto/session.ts +6 -0
  70. package/src/resources/extensions/gsd/auto-dashboard.ts +2 -0
  71. package/src/resources/extensions/gsd/auto.ts +31 -1
  72. package/src/resources/extensions/gsd/bootstrap/tool-call-loop-guard.ts +9 -2
  73. package/src/resources/extensions/gsd/commands/catalog.ts +32 -0
  74. package/src/resources/extensions/gsd/commands/handlers/workflow.ts +164 -0
  75. package/src/resources/extensions/gsd/context-injector.ts +100 -0
  76. package/src/resources/extensions/gsd/custom-execution-policy.ts +73 -0
  77. package/src/resources/extensions/gsd/custom-verification.ts +180 -0
  78. package/src/resources/extensions/gsd/custom-workflow-engine.ts +216 -0
  79. package/src/resources/extensions/gsd/dashboard-overlay.ts +1 -0
  80. package/src/resources/extensions/gsd/definition-loader.ts +462 -0
  81. package/src/resources/extensions/gsd/dev-execution-policy.ts +51 -0
  82. package/src/resources/extensions/gsd/dev-workflow-engine.ts +110 -0
  83. package/src/resources/extensions/gsd/engine-resolver.ts +57 -0
  84. package/src/resources/extensions/gsd/engine-types.ts +71 -0
  85. package/src/resources/extensions/gsd/execution-policy.ts +43 -0
  86. package/src/resources/extensions/gsd/graph.ts +312 -0
  87. package/src/resources/extensions/gsd/run-manager.ts +180 -0
  88. package/src/resources/extensions/gsd/tests/bundled-workflow-defs.test.ts +180 -0
  89. package/src/resources/extensions/gsd/tests/commands-workflow-custom.test.ts +283 -0
  90. package/src/resources/extensions/gsd/tests/context-injector.test.ts +313 -0
  91. package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +540 -0
  92. package/src/resources/extensions/gsd/tests/custom-verification.test.ts +382 -0
  93. package/src/resources/extensions/gsd/tests/custom-workflow-engine.test.ts +339 -0
  94. package/src/resources/extensions/gsd/tests/dashboard-custom-engine.test.ts +87 -0
  95. package/src/resources/extensions/gsd/tests/definition-loader.test.ts +778 -0
  96. package/src/resources/extensions/gsd/tests/dev-engine-wrapper.test.ts +318 -0
  97. package/src/resources/extensions/gsd/tests/e2e-workflow-pipeline-integration.test.ts +476 -0
  98. package/src/resources/extensions/gsd/tests/engine-interfaces-contract.test.ts +271 -0
  99. package/src/resources/extensions/gsd/tests/graph-operations.test.ts +599 -0
  100. package/src/resources/extensions/gsd/tests/iterate-engine-integration.test.ts +429 -0
  101. package/src/resources/extensions/gsd/tests/run-manager.test.ts +229 -0
  102. package/src/resources/extensions/gsd/tests/tool-call-loop-guard.test.ts +45 -0
  103. package/src/resources/extensions/gsd/workflow-engine.ts +38 -0
  104. package/src/resources/skills/create-workflow/SKILL.md +103 -0
  105. package/src/resources/skills/create-workflow/references/feature-patterns.md +128 -0
  106. package/src/resources/skills/create-workflow/references/verification-policies.md +76 -0
  107. package/src/resources/skills/create-workflow/references/yaml-schema-v1.md +46 -0
  108. package/src/resources/skills/create-workflow/templates/blog-post-pipeline.yaml +60 -0
  109. package/src/resources/skills/create-workflow/templates/code-audit.yaml +60 -0
  110. package/src/resources/skills/create-workflow/templates/release-checklist.yaml +66 -0
  111. package/src/resources/skills/create-workflow/templates/workflow-definition.yaml +32 -0
  112. package/src/resources/skills/create-workflow/workflows/create-from-scratch.md +104 -0
  113. package/src/resources/skills/create-workflow/workflows/create-from-template.md +72 -0
  114. /package/dist/web/standalone/.next/static/{EnGUNqHeGbE0tuuUkTJVA → PXrI5DoWsm7rwAVnEU2rD}/_buildManifest.js +0 -0
  115. /package/dist/web/standalone/.next/static/{EnGUNqHeGbE0tuuUkTJVA → PXrI5DoWsm7rwAVnEU2rD}/_ssgManifest.js +0 -0
@@ -0,0 +1,382 @@
1
+ /**
2
+ * custom-verification.test.ts — Tests for runCustomVerification().
3
+ *
4
+ * Tests all four verification policies (content-heuristic, shell-command,
5
+ * prompt-verify, human-review) plus edge cases (no policy, missing file).
6
+ * Each test creates a temp run directory with a DEFINITION.yaml and
7
+ * optional test artifacts.
8
+ */
9
+
10
+ import { describe, it } from "node:test";
11
+ import assert from "node:assert/strict";
12
+ import { mkdtempSync, writeFileSync, mkdirSync } from "node:fs";
13
+ import { join } from "node:path";
14
+ import { tmpdir } from "node:os";
15
+ import { stringify } from "yaml";
16
+ import { runCustomVerification } from "../custom-verification.ts";
17
+ import type { WorkflowDefinition } from "../definition-loader.ts";
18
+
19
+ /** Create a temp run directory with the given definition and optional files. */
20
+ function makeTempRun(
21
+ def: WorkflowDefinition,
22
+ files?: Record<string, string>,
23
+ ): string {
24
+ const runDir = mkdtempSync(join(tmpdir(), "cv-test-"));
25
+ writeFileSync(join(runDir, "DEFINITION.yaml"), stringify(def), "utf-8");
26
+
27
+ if (files) {
28
+ for (const [relPath, content] of Object.entries(files)) {
29
+ const absPath = join(runDir, relPath);
30
+ // Ensure parent directories exist
31
+ const parentDir = join(absPath, "..");
32
+ mkdirSync(parentDir, { recursive: true });
33
+ writeFileSync(absPath, content, "utf-8");
34
+ }
35
+ }
36
+
37
+ return runDir;
38
+ }
39
+
40
+ /** Minimal valid workflow definition factory. */
41
+ function makeDef(
42
+ steps: WorkflowDefinition["steps"],
43
+ ): WorkflowDefinition {
44
+ return {
45
+ version: 1,
46
+ name: "test-workflow",
47
+ steps,
48
+ };
49
+ }
50
+
51
+ // ─── content-heuristic tests ────────────────────────────────────────────
52
+
53
+ describe("content-heuristic policy", () => {
54
+ it("returns 'continue' when file exists and meets size/pattern", () => {
55
+ const def = makeDef([
56
+ {
57
+ id: "step-1",
58
+ name: "Generate report",
59
+ prompt: "Generate a report",
60
+ requires: [],
61
+ produces: ["report.md"],
62
+ verify: {
63
+ policy: "content-heuristic",
64
+ minSize: 10,
65
+ pattern: "# Report",
66
+ },
67
+ },
68
+ ]);
69
+
70
+ const runDir = makeTempRun(def, {
71
+ "report.md": "# Report\n\nThis is a valid report with sufficient content.",
72
+ });
73
+
74
+ const result = runCustomVerification(runDir, "step-1");
75
+ assert.equal(result, "continue");
76
+ });
77
+
78
+ it("returns 'pause' when produces file is missing", () => {
79
+ const def = makeDef([
80
+ {
81
+ id: "step-1",
82
+ name: "Generate report",
83
+ prompt: "Generate a report",
84
+ requires: [],
85
+ produces: ["report.md"],
86
+ verify: { policy: "content-heuristic" },
87
+ },
88
+ ]);
89
+
90
+ // No files created — report.md doesn't exist
91
+ const runDir = makeTempRun(def);
92
+
93
+ const result = runCustomVerification(runDir, "step-1");
94
+ assert.equal(result, "pause");
95
+ });
96
+
97
+ it("returns 'pause' when file exists but below minSize", () => {
98
+ const def = makeDef([
99
+ {
100
+ id: "step-1",
101
+ name: "Generate report",
102
+ prompt: "Generate a report",
103
+ requires: [],
104
+ produces: ["report.md"],
105
+ verify: {
106
+ policy: "content-heuristic",
107
+ minSize: 1000,
108
+ },
109
+ },
110
+ ]);
111
+
112
+ const runDir = makeTempRun(def, {
113
+ "report.md": "tiny",
114
+ });
115
+
116
+ const result = runCustomVerification(runDir, "step-1");
117
+ assert.equal(result, "pause");
118
+ });
119
+
120
+ it("returns 'pause' when file exists but pattern does not match", () => {
121
+ const def = makeDef([
122
+ {
123
+ id: "step-1",
124
+ name: "Generate report",
125
+ prompt: "Generate a report",
126
+ requires: [],
127
+ produces: ["report.md"],
128
+ verify: {
129
+ policy: "content-heuristic",
130
+ pattern: "^# Summary",
131
+ },
132
+ },
133
+ ]);
134
+
135
+ const runDir = makeTempRun(def, {
136
+ "report.md": "This has no heading at all.",
137
+ });
138
+
139
+ const result = runCustomVerification(runDir, "step-1");
140
+ assert.equal(result, "pause");
141
+ });
142
+
143
+ it("returns 'continue' when produces is empty", () => {
144
+ const def = makeDef([
145
+ {
146
+ id: "step-1",
147
+ name: "Think step",
148
+ prompt: "Think about the problem",
149
+ requires: [],
150
+ produces: [],
151
+ verify: { policy: "content-heuristic" },
152
+ },
153
+ ]);
154
+
155
+ const runDir = makeTempRun(def);
156
+
157
+ const result = runCustomVerification(runDir, "step-1");
158
+ assert.equal(result, "continue");
159
+ });
160
+
161
+ it("returns 'continue' when file exists with no minSize or pattern checks", () => {
162
+ const def = makeDef([
163
+ {
164
+ id: "step-1",
165
+ name: "Generate output",
166
+ prompt: "Generate output",
167
+ requires: [],
168
+ produces: ["output.txt"],
169
+ verify: { policy: "content-heuristic" },
170
+ },
171
+ ]);
172
+
173
+ const runDir = makeTempRun(def, {
174
+ "output.txt": "",
175
+ });
176
+
177
+ const result = runCustomVerification(runDir, "step-1");
178
+ assert.equal(result, "continue");
179
+ });
180
+ });
181
+
182
+ // ─── shell-command tests ────────────────────────────────────────────────
183
+
184
+ describe("shell-command policy", () => {
185
+ it("returns 'continue' when command exits 0", () => {
186
+ const def = makeDef([
187
+ {
188
+ id: "step-1",
189
+ name: "Build artifact",
190
+ prompt: "Build the artifact",
191
+ requires: [],
192
+ produces: ["artifact.txt"],
193
+ verify: {
194
+ policy: "shell-command",
195
+ command: "test -f artifact.txt",
196
+ },
197
+ },
198
+ ]);
199
+
200
+ const runDir = makeTempRun(def, {
201
+ "artifact.txt": "content",
202
+ });
203
+
204
+ const result = runCustomVerification(runDir, "step-1");
205
+ assert.equal(result, "continue");
206
+ });
207
+
208
+ it("returns 'retry' when command exits non-zero", () => {
209
+ const def = makeDef([
210
+ {
211
+ id: "step-1",
212
+ name: "Build artifact",
213
+ prompt: "Build the artifact",
214
+ requires: [],
215
+ produces: ["artifact.txt"],
216
+ verify: {
217
+ policy: "shell-command",
218
+ command: "test -f nonexistent-file.txt",
219
+ },
220
+ },
221
+ ]);
222
+
223
+ const runDir = makeTempRun(def);
224
+
225
+ const result = runCustomVerification(runDir, "step-1");
226
+ assert.equal(result, "retry");
227
+ });
228
+ });
229
+
230
+ // ─── prompt-verify tests ────────────────────────────────────────────────
231
+
232
+ describe("prompt-verify policy", () => {
233
+ it("returns 'pause'", () => {
234
+ const def = makeDef([
235
+ {
236
+ id: "step-1",
237
+ name: "Creative step",
238
+ prompt: "Write something creative",
239
+ requires: [],
240
+ produces: ["creative.md"],
241
+ verify: {
242
+ policy: "prompt-verify",
243
+ prompt: "Does the creative output meet the brief?",
244
+ },
245
+ },
246
+ ]);
247
+
248
+ const runDir = makeTempRun(def);
249
+
250
+ const result = runCustomVerification(runDir, "step-1");
251
+ assert.equal(result, "pause");
252
+ });
253
+ });
254
+
255
+ // ─── human-review tests ─────────────────────────────────────────────────
256
+
257
+ describe("human-review policy", () => {
258
+ it("returns 'pause'", () => {
259
+ const def = makeDef([
260
+ {
261
+ id: "step-1",
262
+ name: "Review step",
263
+ prompt: "Prepare for review",
264
+ requires: [],
265
+ produces: ["review-doc.md"],
266
+ verify: { policy: "human-review" },
267
+ },
268
+ ]);
269
+
270
+ const runDir = makeTempRun(def);
271
+
272
+ const result = runCustomVerification(runDir, "step-1");
273
+ assert.equal(result, "pause");
274
+ });
275
+ });
276
+
277
+ // ─── no verify policy tests ─────────────────────────────────────────────
278
+
279
+ describe("no verify policy", () => {
280
+ it("returns 'continue' when step has no verify field", () => {
281
+ const def = makeDef([
282
+ {
283
+ id: "step-1",
284
+ name: "Simple step",
285
+ prompt: "Do something simple",
286
+ requires: [],
287
+ produces: [],
288
+ // No verify field
289
+ },
290
+ ]);
291
+
292
+ const runDir = makeTempRun(def);
293
+
294
+ const result = runCustomVerification(runDir, "step-1");
295
+ assert.equal(result, "continue");
296
+ });
297
+
298
+ it("returns 'continue' when step ID is not found in definition", () => {
299
+ const def = makeDef([
300
+ {
301
+ id: "step-1",
302
+ name: "Only step",
303
+ prompt: "Only step",
304
+ requires: [],
305
+ produces: [],
306
+ },
307
+ ]);
308
+
309
+ const runDir = makeTempRun(def);
310
+
311
+ const result = runCustomVerification(runDir, "nonexistent-step");
312
+ assert.equal(result, "continue");
313
+ });
314
+ });
315
+
316
+ // ─── missing DEFINITION.yaml ────────────────────────────────────────────
317
+
318
+ describe("error handling", () => {
319
+ it("throws when DEFINITION.yaml is missing", () => {
320
+ const runDir = mkdtempSync(join(tmpdir(), "cv-test-nodef-"));
321
+ // No DEFINITION.yaml written
322
+
323
+ assert.throws(
324
+ () => runCustomVerification(runDir, "step-1"),
325
+ /ENOENT/,
326
+ );
327
+ });
328
+ });
329
+
330
+ // ─── CustomExecutionPolicy integration ──────────────────────────────────
331
+
332
+ describe("CustomExecutionPolicy.verify() integration", () => {
333
+ it("extracts stepId from unitId and calls runCustomVerification", async () => {
334
+ // Import the policy class
335
+ const { CustomExecutionPolicy } = await import("../custom-execution-policy.ts");
336
+
337
+ const def = makeDef([
338
+ {
339
+ id: "analyze",
340
+ name: "Analyze",
341
+ prompt: "Analyze the data",
342
+ requires: [],
343
+ produces: ["analysis.md"],
344
+ verify: { policy: "content-heuristic" },
345
+ },
346
+ ]);
347
+
348
+ const runDir = makeTempRun(def, {
349
+ "analysis.md": "Analysis complete.",
350
+ });
351
+
352
+ const policy = new CustomExecutionPolicy(runDir);
353
+ const result = await policy.verify("custom-step", "my-workflow/analyze", {
354
+ basePath: "/tmp",
355
+ });
356
+ assert.equal(result, "continue");
357
+ });
358
+
359
+ it("returns 'pause' when content-heuristic fails via policy", async () => {
360
+ const { CustomExecutionPolicy } = await import("../custom-execution-policy.ts");
361
+
362
+ const def = makeDef([
363
+ {
364
+ id: "generate",
365
+ name: "Generate",
366
+ prompt: "Generate output",
367
+ requires: [],
368
+ produces: ["output.md"],
369
+ verify: { policy: "content-heuristic" },
370
+ },
371
+ ]);
372
+
373
+ // No output.md created
374
+ const runDir = makeTempRun(def);
375
+
376
+ const policy = new CustomExecutionPolicy(runDir);
377
+ const result = await policy.verify("custom-step", "my-workflow/generate", {
378
+ basePath: "/tmp",
379
+ });
380
+ assert.equal(result, "pause");
381
+ });
382
+ });