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,318 @@
1
+ /**
2
+ * dev-engine-wrapper.test.ts — Contract tests for the dev engine wrapper layer (S02).
3
+ *
4
+ * Tests bridgeDispatchAction mapping, DevWorkflowEngine delegation,
5
+ * DevExecutionPolicy stubs, resolver routing, kill switch, and
6
+ * auto.ts engine ID accessors.
7
+ */
8
+
9
+ import test, { describe, before, after } from "node:test";
10
+ import assert from "node:assert/strict";
11
+ import { mkdtempSync, mkdirSync, rmSync } from "node:fs";
12
+ import { join } from "node:path";
13
+ import { tmpdir } from "node:os";
14
+
15
+ // ── bridgeDispatchAction mapping ────────────────────────────────────────────
16
+
17
+ describe("bridgeDispatchAction", () => {
18
+ test("maps dispatch action with step fields", async () => {
19
+ const { bridgeDispatchAction } = await import(
20
+ "../dev-workflow-engine.ts"
21
+ );
22
+ const result = bridgeDispatchAction({
23
+ action: "dispatch",
24
+ unitType: "execute-task",
25
+ unitId: "T01",
26
+ prompt: "do stuff",
27
+ matchedRule: "foo",
28
+ } as any);
29
+
30
+ assert.equal(result.action, "dispatch");
31
+ assert.ok("step" in result);
32
+ const step = (result as any).step;
33
+ assert.equal(step.unitType, "execute-task");
34
+ assert.equal(step.unitId, "T01");
35
+ assert.equal(step.prompt, "do stuff");
36
+ });
37
+
38
+ test("maps stop action with reason and level", async () => {
39
+ const { bridgeDispatchAction } = await import(
40
+ "../dev-workflow-engine.ts"
41
+ );
42
+ const result = bridgeDispatchAction({
43
+ action: "stop",
44
+ reason: "done",
45
+ level: "info",
46
+ matchedRule: "bar",
47
+ } as any);
48
+
49
+ assert.equal(result.action, "stop");
50
+ assert.equal((result as any).reason, "done");
51
+ assert.equal((result as any).level, "info");
52
+ });
53
+
54
+ test("maps skip action", async () => {
55
+ const { bridgeDispatchAction } = await import(
56
+ "../dev-workflow-engine.ts"
57
+ );
58
+ const result = bridgeDispatchAction({
59
+ action: "skip",
60
+ matchedRule: "baz",
61
+ } as any);
62
+
63
+ assert.equal(result.action, "skip");
64
+ });
65
+ });
66
+
67
+ // ── DevWorkflowEngine ───────────────────────────────────────────────────────
68
+
69
+ describe("DevWorkflowEngine", () => {
70
+ test("engineId is 'dev'", async () => {
71
+ const { DevWorkflowEngine } = await import("../dev-workflow-engine.ts");
72
+ const engine = new DevWorkflowEngine();
73
+ assert.equal(engine.engineId, "dev");
74
+ });
75
+
76
+ test("deriveState returns EngineState with expected fields", async () => {
77
+ const { DevWorkflowEngine } = await import("../dev-workflow-engine.ts");
78
+ const engine = new DevWorkflowEngine();
79
+
80
+ // Create a minimal temp .gsd structure for deriveState
81
+ const tempDir = mkdtempSync(join(tmpdir(), "gsd-engine-test-"));
82
+ mkdirSync(join(tempDir, ".gsd", "milestones"), { recursive: true });
83
+
84
+ try {
85
+ const state = await engine.deriveState(tempDir);
86
+
87
+ assert.equal(typeof state.phase, "string", "phase should be a string");
88
+ assert.ok(
89
+ "currentMilestoneId" in state,
90
+ "state should have currentMilestoneId",
91
+ );
92
+ assert.ok(
93
+ "activeSliceId" in state,
94
+ "state should have activeSliceId",
95
+ );
96
+ assert.ok(
97
+ "activeTaskId" in state,
98
+ "state should have activeTaskId",
99
+ );
100
+ assert.equal(
101
+ typeof state.isComplete,
102
+ "boolean",
103
+ "isComplete should be boolean",
104
+ );
105
+ assert.ok("raw" in state, "state should have raw field");
106
+ } finally {
107
+ rmSync(tempDir, { recursive: true, force: true });
108
+ }
109
+ });
110
+
111
+ test("reconcile returns continue for non-complete state", async () => {
112
+ const { DevWorkflowEngine } = await import("../dev-workflow-engine.ts");
113
+ const engine = new DevWorkflowEngine();
114
+
115
+ const state = {
116
+ phase: "executing",
117
+ currentMilestoneId: "M001",
118
+ activeSliceId: "S01",
119
+ activeTaskId: "T01",
120
+ isComplete: false,
121
+ raw: {},
122
+ };
123
+
124
+ const result = await engine.reconcile(state, {
125
+ unitType: "execute-task",
126
+ unitId: "T01",
127
+ startedAt: Date.now() - 1000,
128
+ finishedAt: Date.now(),
129
+ });
130
+
131
+ assert.equal(result.outcome, "continue");
132
+ });
133
+
134
+ test("reconcile returns milestone-complete for complete state", async () => {
135
+ const { DevWorkflowEngine } = await import("../dev-workflow-engine.ts");
136
+ const engine = new DevWorkflowEngine();
137
+
138
+ const state = {
139
+ phase: "complete",
140
+ currentMilestoneId: "M001",
141
+ activeSliceId: null,
142
+ activeTaskId: null,
143
+ isComplete: true,
144
+ raw: {},
145
+ };
146
+
147
+ const result = await engine.reconcile(state, {
148
+ unitType: "execute-task",
149
+ unitId: "T01",
150
+ startedAt: Date.now() - 1000,
151
+ finishedAt: Date.now(),
152
+ });
153
+
154
+ assert.equal(result.outcome, "milestone-complete");
155
+ });
156
+
157
+ test("getDisplayMetadata returns expected fields", async () => {
158
+ const { DevWorkflowEngine } = await import("../dev-workflow-engine.ts");
159
+ const engine = new DevWorkflowEngine();
160
+
161
+ const state = {
162
+ phase: "executing",
163
+ currentMilestoneId: "M001",
164
+ activeSliceId: "S01",
165
+ activeTaskId: "T01",
166
+ isComplete: false,
167
+ raw: {},
168
+ };
169
+
170
+ const meta = engine.getDisplayMetadata(state);
171
+
172
+ assert.ok("engineLabel" in meta, "should have engineLabel");
173
+ assert.ok("currentPhase" in meta, "should have currentPhase");
174
+ assert.ok("progressSummary" in meta, "should have progressSummary");
175
+ assert.ok("stepCount" in meta, "should have stepCount");
176
+ assert.equal(meta.engineLabel, "GSD Dev");
177
+ });
178
+ });
179
+
180
+ // ── DevExecutionPolicy stubs ────────────────────────────────────────────────
181
+
182
+ describe("DevExecutionPolicy", () => {
183
+ test("verify returns 'continue'", async () => {
184
+ const { DevExecutionPolicy } = await import(
185
+ "../dev-execution-policy.ts"
186
+ );
187
+ const policy = new DevExecutionPolicy();
188
+ const result = await policy.verify("execute-task", "T01", {
189
+ basePath: "/tmp",
190
+ });
191
+ assert.equal(result, "continue");
192
+ });
193
+
194
+ test("selectModel returns null", async () => {
195
+ const { DevExecutionPolicy } = await import(
196
+ "../dev-execution-policy.ts"
197
+ );
198
+ const policy = new DevExecutionPolicy();
199
+ const result = await policy.selectModel("execute-task", "T01", {
200
+ basePath: "/tmp",
201
+ });
202
+ assert.equal(result, null);
203
+ });
204
+
205
+ test("recover returns { outcome: 'retry' }", async () => {
206
+ const { DevExecutionPolicy } = await import(
207
+ "../dev-execution-policy.ts"
208
+ );
209
+ const policy = new DevExecutionPolicy();
210
+ const result = await policy.recover("execute-task", "T01", {
211
+ basePath: "/tmp",
212
+ });
213
+ assert.deepEqual(result, { outcome: "retry" });
214
+ });
215
+
216
+ test("closeout returns { committed: false, artifacts: [] }", async () => {
217
+ const { DevExecutionPolicy } = await import(
218
+ "../dev-execution-policy.ts"
219
+ );
220
+ const policy = new DevExecutionPolicy();
221
+ const result = await policy.closeout("execute-task", "T01", {
222
+ basePath: "/tmp",
223
+ startedAt: Date.now(),
224
+ });
225
+ assert.deepEqual(result, { committed: false, artifacts: [] });
226
+ });
227
+
228
+ test("prepareWorkspace resolves without error", async () => {
229
+ const { DevExecutionPolicy } = await import(
230
+ "../dev-execution-policy.ts"
231
+ );
232
+ const policy = new DevExecutionPolicy();
233
+ await assert.doesNotReject(
234
+ () => policy.prepareWorkspace("/tmp", "M001"),
235
+ "prepareWorkspace should resolve without error",
236
+ );
237
+ });
238
+ });
239
+
240
+ // ── Resolver routing ────────────────────────────────────────────────────────
241
+
242
+ describe("Resolver routing", () => {
243
+ test("resolveEngine returns dev engine for null activeEngineId", async () => {
244
+ const { resolveEngine } = await import("../engine-resolver.ts");
245
+ const result = resolveEngine({ activeEngineId: null });
246
+ assert.ok(result.engine, "should return engine");
247
+ assert.ok(result.policy, "should return policy");
248
+ assert.equal(result.engine.engineId, "dev");
249
+ });
250
+
251
+ test("resolveEngine returns dev engine for 'dev' activeEngineId", async () => {
252
+ const { resolveEngine } = await import("../engine-resolver.ts");
253
+ const result = resolveEngine({ activeEngineId: "dev" });
254
+ assert.ok(result.engine, "should return engine");
255
+ assert.ok(result.policy, "should return policy");
256
+ assert.equal(result.engine.engineId, "dev");
257
+ });
258
+
259
+ test("resolveEngine throws for unknown activeEngineId without activeRunDir", async () => {
260
+ const { resolveEngine } = await import("../engine-resolver.ts");
261
+ assert.throws(
262
+ () => resolveEngine({ activeEngineId: "unknown" }),
263
+ /requires activeRunDir/,
264
+ "should throw when activeRunDir is missing for non-dev engine",
265
+ );
266
+ });
267
+ });
268
+
269
+ // ── Kill switch ─────────────────────────────────────────────────────────────
270
+
271
+ describe("Kill switch (GSD_ENGINE_BYPASS)", () => {
272
+ const originalBypass = process.env.GSD_ENGINE_BYPASS;
273
+
274
+ after(() => {
275
+ // Restore original env var state
276
+ if (originalBypass === undefined) {
277
+ delete process.env.GSD_ENGINE_BYPASS;
278
+ } else {
279
+ process.env.GSD_ENGINE_BYPASS = originalBypass;
280
+ }
281
+ });
282
+
283
+ test("GSD_ENGINE_BYPASS=1 does not affect resolveEngine (bypass checked in autoLoop)", async () => {
284
+ const { resolveEngine } = await import("../engine-resolver.ts");
285
+ process.env.GSD_ENGINE_BYPASS = "1";
286
+ try {
287
+ // resolveEngine should still resolve normally — bypass is checked in autoLoop
288
+ const { engine } = resolveEngine({ activeEngineId: null });
289
+ assert.ok(engine, "should return an engine even with bypass set");
290
+ } finally {
291
+ delete process.env.GSD_ENGINE_BYPASS;
292
+ }
293
+ });
294
+ });
295
+
296
+ // ── auto.ts engine ID accessors ─────────────────────────────────────────────
297
+
298
+ describe("auto.ts engine ID accessors", () => {
299
+ test("setActiveEngineId / getActiveEngineId round-trip", async () => {
300
+ const { setActiveEngineId, getActiveEngineId } = await import(
301
+ "../auto.ts"
302
+ );
303
+
304
+ setActiveEngineId("dev");
305
+ assert.equal(
306
+ getActiveEngineId(),
307
+ "dev",
308
+ "getActiveEngineId should return 'dev' after setting",
309
+ );
310
+
311
+ setActiveEngineId(null);
312
+ assert.equal(
313
+ getActiveEngineId(),
314
+ null,
315
+ "getActiveEngineId should return null after setting null",
316
+ );
317
+ });
318
+ });