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.
- package/dist/resources/extensions/gsd/auto/loop.js +80 -0
- package/dist/resources/extensions/gsd/auto/phases.js +2 -2
- package/dist/resources/extensions/gsd/auto/session.js +6 -0
- package/dist/resources/extensions/gsd/auto-dashboard.js +2 -0
- package/dist/resources/extensions/gsd/auto.js +28 -1
- package/dist/resources/extensions/gsd/bootstrap/tool-call-loop-guard.js +7 -2
- package/dist/resources/extensions/gsd/commands/catalog.js +32 -0
- package/dist/resources/extensions/gsd/commands/handlers/workflow.js +146 -0
- package/dist/resources/extensions/gsd/context-injector.js +74 -0
- package/dist/resources/extensions/gsd/custom-execution-policy.js +47 -0
- package/dist/resources/extensions/gsd/custom-verification.js +145 -0
- package/dist/resources/extensions/gsd/custom-workflow-engine.js +164 -0
- package/dist/resources/extensions/gsd/dashboard-overlay.js +1 -0
- package/dist/resources/extensions/gsd/definition-loader.js +352 -0
- package/dist/resources/extensions/gsd/dev-execution-policy.js +24 -0
- package/dist/resources/extensions/gsd/dev-workflow-engine.js +82 -0
- package/dist/resources/extensions/gsd/engine-resolver.js +40 -0
- package/dist/resources/extensions/gsd/engine-types.js +8 -0
- package/dist/resources/extensions/gsd/execution-policy.js +8 -0
- package/dist/resources/extensions/gsd/graph.js +225 -0
- package/dist/resources/extensions/gsd/run-manager.js +134 -0
- package/dist/resources/extensions/gsd/workflow-engine.js +7 -0
- package/dist/resources/skills/create-workflow/SKILL.md +103 -0
- package/dist/resources/skills/create-workflow/references/feature-patterns.md +128 -0
- package/dist/resources/skills/create-workflow/references/verification-policies.md +76 -0
- package/dist/resources/skills/create-workflow/references/yaml-schema-v1.md +46 -0
- package/dist/resources/skills/create-workflow/templates/blog-post-pipeline.yaml +60 -0
- package/dist/resources/skills/create-workflow/templates/code-audit.yaml +60 -0
- package/dist/resources/skills/create-workflow/templates/release-checklist.yaml +66 -0
- package/dist/resources/skills/create-workflow/templates/workflow-definition.yaml +32 -0
- package/dist/resources/skills/create-workflow/workflows/create-from-scratch.md +104 -0
- package/dist/resources/skills/create-workflow/workflows/create-from-template.md +72 -0
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +15 -15
- package/dist/web/standalone/.next/build-manifest.json +2 -2
- package/dist/web/standalone/.next/prerender-manifest.json +3 -3
- package/dist/web/standalone/.next/server/app/_global-error.html +2 -2
- package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.html +1 -1
- package/dist/web/standalone/.next/server/app/index.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app-paths-manifest.json +15 -15
- package/dist/web/standalone/.next/server/pages/404.html +1 -1
- package/dist/web/standalone/.next/server/pages/500.html +2 -2
- package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
- package/package.json +1 -1
- package/packages/pi-coding-agent/package.json +1 -1
- package/pkg/package.json +1 -1
- package/src/resources/extensions/gsd/auto/loop.ts +91 -0
- package/src/resources/extensions/gsd/auto/phases.ts +2 -2
- package/src/resources/extensions/gsd/auto/session.ts +6 -0
- package/src/resources/extensions/gsd/auto-dashboard.ts +2 -0
- package/src/resources/extensions/gsd/auto.ts +31 -1
- package/src/resources/extensions/gsd/bootstrap/tool-call-loop-guard.ts +9 -2
- package/src/resources/extensions/gsd/commands/catalog.ts +32 -0
- package/src/resources/extensions/gsd/commands/handlers/workflow.ts +164 -0
- package/src/resources/extensions/gsd/context-injector.ts +100 -0
- package/src/resources/extensions/gsd/custom-execution-policy.ts +73 -0
- package/src/resources/extensions/gsd/custom-verification.ts +180 -0
- package/src/resources/extensions/gsd/custom-workflow-engine.ts +216 -0
- package/src/resources/extensions/gsd/dashboard-overlay.ts +1 -0
- package/src/resources/extensions/gsd/definition-loader.ts +462 -0
- package/src/resources/extensions/gsd/dev-execution-policy.ts +51 -0
- package/src/resources/extensions/gsd/dev-workflow-engine.ts +110 -0
- package/src/resources/extensions/gsd/engine-resolver.ts +57 -0
- package/src/resources/extensions/gsd/engine-types.ts +71 -0
- package/src/resources/extensions/gsd/execution-policy.ts +43 -0
- package/src/resources/extensions/gsd/graph.ts +312 -0
- package/src/resources/extensions/gsd/run-manager.ts +180 -0
- package/src/resources/extensions/gsd/tests/bundled-workflow-defs.test.ts +180 -0
- package/src/resources/extensions/gsd/tests/commands-workflow-custom.test.ts +283 -0
- package/src/resources/extensions/gsd/tests/context-injector.test.ts +313 -0
- package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +540 -0
- package/src/resources/extensions/gsd/tests/custom-verification.test.ts +382 -0
- package/src/resources/extensions/gsd/tests/custom-workflow-engine.test.ts +339 -0
- package/src/resources/extensions/gsd/tests/dashboard-custom-engine.test.ts +87 -0
- package/src/resources/extensions/gsd/tests/definition-loader.test.ts +778 -0
- package/src/resources/extensions/gsd/tests/dev-engine-wrapper.test.ts +318 -0
- package/src/resources/extensions/gsd/tests/e2e-workflow-pipeline-integration.test.ts +476 -0
- package/src/resources/extensions/gsd/tests/engine-interfaces-contract.test.ts +271 -0
- package/src/resources/extensions/gsd/tests/graph-operations.test.ts +599 -0
- package/src/resources/extensions/gsd/tests/iterate-engine-integration.test.ts +429 -0
- package/src/resources/extensions/gsd/tests/run-manager.test.ts +229 -0
- package/src/resources/extensions/gsd/tests/tool-call-loop-guard.test.ts +45 -0
- package/src/resources/extensions/gsd/workflow-engine.ts +38 -0
- package/src/resources/skills/create-workflow/SKILL.md +103 -0
- package/src/resources/skills/create-workflow/references/feature-patterns.md +128 -0
- package/src/resources/skills/create-workflow/references/verification-policies.md +76 -0
- package/src/resources/skills/create-workflow/references/yaml-schema-v1.md +46 -0
- package/src/resources/skills/create-workflow/templates/blog-post-pipeline.yaml +60 -0
- package/src/resources/skills/create-workflow/templates/code-audit.yaml +60 -0
- package/src/resources/skills/create-workflow/templates/release-checklist.yaml +66 -0
- package/src/resources/skills/create-workflow/templates/workflow-definition.yaml +32 -0
- package/src/resources/skills/create-workflow/workflows/create-from-scratch.md +104 -0
- package/src/resources/skills/create-workflow/workflows/create-from-template.md +72 -0
- /package/dist/web/standalone/.next/static/{EnGUNqHeGbE0tuuUkTJVA → PXrI5DoWsm7rwAVnEU2rD}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{EnGUNqHeGbE0tuuUkTJVA → PXrI5DoWsm7rwAVnEU2rD}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* engine-interfaces-contract.test.ts — Source-level contract tests for the
|
|
3
|
+
* engine abstraction layer (S01).
|
|
4
|
+
*
|
|
5
|
+
* TypeScript interfaces are erased by --experimental-strip-types, so these
|
|
6
|
+
* tests use source-level regex assertions on the .ts files to verify shapes.
|
|
7
|
+
* Runtime assertions cover AutoSession.activeEngineId and resolveEngine().
|
|
8
|
+
*
|
|
9
|
+
* Follows the same conventions as auto-session-encapsulation.test.ts.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import test, { describe } from "node:test";
|
|
13
|
+
import assert from "node:assert/strict";
|
|
14
|
+
import { readFileSync } from "node:fs";
|
|
15
|
+
import { join, dirname } from "node:path";
|
|
16
|
+
import { fileURLToPath } from "node:url";
|
|
17
|
+
|
|
18
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
19
|
+
const ENGINE_TYPES_PATH = join(__dirname, "..", "engine-types.ts");
|
|
20
|
+
const WORKFLOW_ENGINE_PATH = join(__dirname, "..", "workflow-engine.ts");
|
|
21
|
+
const EXECUTION_POLICY_PATH = join(__dirname, "..", "execution-policy.ts");
|
|
22
|
+
const ENGINE_RESOLVER_PATH = join(__dirname, "..", "engine-resolver.ts");
|
|
23
|
+
|
|
24
|
+
function readSource(path: string): string {
|
|
25
|
+
return readFileSync(path, "utf-8");
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// ── Import smoke tests ──────────────────────────────────────────────────────
|
|
29
|
+
|
|
30
|
+
describe("Import smoke tests", () => {
|
|
31
|
+
test("engine-types.ts can be dynamically imported", async () => {
|
|
32
|
+
const mod = await import("../engine-types.ts");
|
|
33
|
+
assert.ok(mod, "engine-types.ts should import without error");
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
test("workflow-engine.ts can be dynamically imported", async () => {
|
|
37
|
+
const mod = await import("../workflow-engine.ts");
|
|
38
|
+
assert.ok(mod, "workflow-engine.ts should import without error");
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
test("execution-policy.ts can be dynamically imported", async () => {
|
|
42
|
+
const mod = await import("../execution-policy.ts");
|
|
43
|
+
assert.ok(mod, "execution-policy.ts should import without error");
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
test("engine-resolver.ts can be dynamically imported", async () => {
|
|
47
|
+
const mod = await import("../engine-resolver.ts");
|
|
48
|
+
assert.ok(mod, "engine-resolver.ts should import without error");
|
|
49
|
+
assert.ok(
|
|
50
|
+
typeof mod.resolveEngine === "function",
|
|
51
|
+
"engine-resolver.ts should export resolveEngine function",
|
|
52
|
+
);
|
|
53
|
+
});
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
// ── Leaf-node constraint ────────────────────────────────────────────────────
|
|
57
|
+
|
|
58
|
+
describe("Leaf-node constraint", () => {
|
|
59
|
+
test("engine-types.ts has zero imports from GSD modules (only node: allowed)", () => {
|
|
60
|
+
const source = readSource(ENGINE_TYPES_PATH);
|
|
61
|
+
const lines = source.split("\n");
|
|
62
|
+
const violations: string[] = [];
|
|
63
|
+
|
|
64
|
+
for (let i = 0; i < lines.length; i++) {
|
|
65
|
+
const line = lines[i]!;
|
|
66
|
+
// Match import lines that reference relative paths (../ or ./)
|
|
67
|
+
if (/^import\s/.test(line) && /['"]\.\.?\// .test(line)) {
|
|
68
|
+
violations.push(`line ${i + 1}: ${line.trim()}`);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
assert.equal(
|
|
73
|
+
violations.length,
|
|
74
|
+
0,
|
|
75
|
+
`engine-types.ts must be a leaf node with zero GSD imports. ` +
|
|
76
|
+
`Only node: imports are allowed.\nViolations:\n${violations.join("\n")}`,
|
|
77
|
+
);
|
|
78
|
+
});
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
// ── EngineState shape ───────────────────────────────────────────────────────
|
|
82
|
+
|
|
83
|
+
describe("EngineState shape", () => {
|
|
84
|
+
test("EngineState has all required fields with correct types", () => {
|
|
85
|
+
const source = readSource(ENGINE_TYPES_PATH);
|
|
86
|
+
|
|
87
|
+
const requiredFields = [
|
|
88
|
+
"phase",
|
|
89
|
+
"currentMilestoneId",
|
|
90
|
+
"activeSliceId",
|
|
91
|
+
"activeTaskId",
|
|
92
|
+
"isComplete",
|
|
93
|
+
"raw",
|
|
94
|
+
];
|
|
95
|
+
|
|
96
|
+
for (const field of requiredFields) {
|
|
97
|
+
assert.ok(
|
|
98
|
+
source.includes(field),
|
|
99
|
+
`EngineState must contain field: ${field}`,
|
|
100
|
+
);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// raw must be typed unknown — not a GSD-specific type
|
|
104
|
+
assert.ok(
|
|
105
|
+
/raw:\s*unknown/.test(source),
|
|
106
|
+
"EngineState.raw must be typed 'unknown', not a GSD-specific type",
|
|
107
|
+
);
|
|
108
|
+
});
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
// ── EngineDispatchAction shape ──────────────────────────────────────────────
|
|
112
|
+
|
|
113
|
+
describe("EngineDispatchAction shape", () => {
|
|
114
|
+
test("EngineDispatchAction has dispatch, stop, and skip variants", () => {
|
|
115
|
+
const source = readSource(ENGINE_TYPES_PATH);
|
|
116
|
+
|
|
117
|
+
assert.ok(
|
|
118
|
+
/action:\s*"dispatch"/.test(source),
|
|
119
|
+
'EngineDispatchAction must have action: "dispatch" variant',
|
|
120
|
+
);
|
|
121
|
+
assert.ok(
|
|
122
|
+
/action:\s*"stop"/.test(source),
|
|
123
|
+
'EngineDispatchAction must have action: "stop" variant',
|
|
124
|
+
);
|
|
125
|
+
assert.ok(
|
|
126
|
+
/action:\s*"skip"/.test(source),
|
|
127
|
+
'EngineDispatchAction must have action: "skip" variant',
|
|
128
|
+
);
|
|
129
|
+
});
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
// ── WorkflowEngine interface shape ──────────────────────────────────────────
|
|
133
|
+
|
|
134
|
+
describe("WorkflowEngine interface shape", () => {
|
|
135
|
+
test("WorkflowEngine has engineId and all required methods", () => {
|
|
136
|
+
const source = readSource(WORKFLOW_ENGINE_PATH);
|
|
137
|
+
|
|
138
|
+
const requiredMembers = [
|
|
139
|
+
"engineId",
|
|
140
|
+
"deriveState",
|
|
141
|
+
"resolveDispatch",
|
|
142
|
+
"reconcile",
|
|
143
|
+
"getDisplayMetadata",
|
|
144
|
+
];
|
|
145
|
+
|
|
146
|
+
for (const member of requiredMembers) {
|
|
147
|
+
assert.ok(
|
|
148
|
+
source.includes(member),
|
|
149
|
+
`WorkflowEngine must contain member: ${member}`,
|
|
150
|
+
);
|
|
151
|
+
}
|
|
152
|
+
});
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
// ── ExecutionPolicy interface shape ─────────────────────────────────────────
|
|
156
|
+
|
|
157
|
+
describe("ExecutionPolicy interface shape", () => {
|
|
158
|
+
test("ExecutionPolicy has all required methods", () => {
|
|
159
|
+
const source = readSource(EXECUTION_POLICY_PATH);
|
|
160
|
+
|
|
161
|
+
const requiredMethods = [
|
|
162
|
+
"prepareWorkspace",
|
|
163
|
+
"selectModel",
|
|
164
|
+
"verify",
|
|
165
|
+
"recover",
|
|
166
|
+
"closeout",
|
|
167
|
+
];
|
|
168
|
+
|
|
169
|
+
for (const method of requiredMethods) {
|
|
170
|
+
assert.ok(
|
|
171
|
+
source.includes(method),
|
|
172
|
+
`ExecutionPolicy must contain method: ${method}`,
|
|
173
|
+
);
|
|
174
|
+
}
|
|
175
|
+
});
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
// ── Resolver stub behavior ──────────────────────────────────────────────────
|
|
179
|
+
|
|
180
|
+
describe("Resolver stub behavior", () => {
|
|
181
|
+
test("resolveEngine returns dev engine for null activeEngineId", async () => {
|
|
182
|
+
const { resolveEngine } = await import("../engine-resolver.ts");
|
|
183
|
+
const result = resolveEngine({ activeEngineId: null });
|
|
184
|
+
assert.ok(result.engine, "should return engine for null");
|
|
185
|
+
assert.equal(
|
|
186
|
+
result.engine.engineId,
|
|
187
|
+
"dev",
|
|
188
|
+
"engine.engineId should be 'dev' for null activeEngineId",
|
|
189
|
+
);
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
test("resolveEngine returns dev engine for 'dev' activeEngineId", async () => {
|
|
193
|
+
const { resolveEngine } = await import("../engine-resolver.ts");
|
|
194
|
+
const result = resolveEngine({ activeEngineId: "dev" });
|
|
195
|
+
assert.ok(result.engine, "should return engine for 'dev'");
|
|
196
|
+
assert.equal(
|
|
197
|
+
result.engine.engineId,
|
|
198
|
+
"dev",
|
|
199
|
+
"engine.engineId should be 'dev'",
|
|
200
|
+
);
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
test("resolveEngine throws for unknown activeEngineId without activeRunDir", async () => {
|
|
204
|
+
const { resolveEngine } = await import("../engine-resolver.ts");
|
|
205
|
+
assert.throws(
|
|
206
|
+
() => resolveEngine({ activeEngineId: "custom-xyz" }),
|
|
207
|
+
/activeRunDir/,
|
|
208
|
+
"resolveEngine should throw when custom engine has no activeRunDir",
|
|
209
|
+
);
|
|
210
|
+
});
|
|
211
|
+
|
|
212
|
+
test("resolveEngine returns custom engine for non-dev activeEngineId with activeRunDir", async () => {
|
|
213
|
+
const { resolveEngine } = await import("../engine-resolver.ts");
|
|
214
|
+
const result = resolveEngine({ activeEngineId: "custom-xyz", activeRunDir: "/tmp/test-run" });
|
|
215
|
+
assert.ok(result.engine, "should return engine for custom ID");
|
|
216
|
+
assert.equal(
|
|
217
|
+
result.engine.engineId,
|
|
218
|
+
"custom",
|
|
219
|
+
"engine.engineId should be 'custom' for non-dev activeEngineId",
|
|
220
|
+
);
|
|
221
|
+
});
|
|
222
|
+
|
|
223
|
+
test("ResolvedEngine type is exported (source check)", () => {
|
|
224
|
+
const source = readSource(ENGINE_RESOLVER_PATH);
|
|
225
|
+
assert.ok(
|
|
226
|
+
/export\s+(interface|type)\s+ResolvedEngine/.test(source),
|
|
227
|
+
"engine-resolver.ts must export ResolvedEngine type",
|
|
228
|
+
);
|
|
229
|
+
});
|
|
230
|
+
});
|
|
231
|
+
|
|
232
|
+
// ── AutoSession.activeEngineId ──────────────────────────────────────────────
|
|
233
|
+
|
|
234
|
+
describe("AutoSession.activeEngineId", () => {
|
|
235
|
+
test("defaults to null on a fresh AutoSession", async () => {
|
|
236
|
+
const { AutoSession } = await import("../auto/session.ts");
|
|
237
|
+
const session = new AutoSession();
|
|
238
|
+
assert.equal(
|
|
239
|
+
session.activeEngineId,
|
|
240
|
+
null,
|
|
241
|
+
"activeEngineId should default to null",
|
|
242
|
+
);
|
|
243
|
+
});
|
|
244
|
+
|
|
245
|
+
test("is null after reset()", async () => {
|
|
246
|
+
const { AutoSession } = await import("../auto/session.ts");
|
|
247
|
+
const session = new AutoSession();
|
|
248
|
+
session.activeEngineId = "dev";
|
|
249
|
+
session.reset();
|
|
250
|
+
assert.equal(
|
|
251
|
+
session.activeEngineId,
|
|
252
|
+
null,
|
|
253
|
+
"activeEngineId should be null after reset()",
|
|
254
|
+
);
|
|
255
|
+
});
|
|
256
|
+
|
|
257
|
+
test("appears in toJSON() output", async () => {
|
|
258
|
+
const { AutoSession } = await import("../auto/session.ts");
|
|
259
|
+
const session = new AutoSession();
|
|
260
|
+
const json = session.toJSON();
|
|
261
|
+
assert.ok(
|
|
262
|
+
"activeEngineId" in json,
|
|
263
|
+
"toJSON() must include activeEngineId",
|
|
264
|
+
);
|
|
265
|
+
assert.equal(
|
|
266
|
+
json.activeEngineId,
|
|
267
|
+
null,
|
|
268
|
+
"toJSON().activeEngineId should be null by default",
|
|
269
|
+
);
|
|
270
|
+
});
|
|
271
|
+
});
|