@sun-asterisk/sungen 3.1.2-beta.121 → 3.1.2-beta.123
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/capabilities/context.d.ts +17 -0
- package/dist/capabilities/context.d.ts.map +1 -1
- package/dist/capabilities/registry.d.ts +3 -1
- package/dist/capabilities/registry.d.ts.map +1 -1
- package/dist/capabilities/registry.js.map +1 -1
- package/dist/cli/commands/audit.d.ts.map +1 -1
- package/dist/cli/commands/audit.js +2 -1
- package/dist/cli/commands/audit.js.map +1 -1
- package/dist/cli/commands/context.d.ts.map +1 -1
- package/dist/cli/commands/context.js +2 -1
- package/dist/cli/commands/context.js.map +1 -1
- package/dist/cli/commands/delivery.d.ts.map +1 -1
- package/dist/cli/commands/delivery.js +13 -1
- package/dist/cli/commands/delivery.js.map +1 -1
- package/dist/cli/commands/generate.d.ts.map +1 -1
- package/dist/cli/commands/generate.js +2 -1
- package/dist/cli/commands/generate.js.map +1 -1
- package/dist/cli/commands/ledger.d.ts.map +1 -1
- package/dist/cli/commands/ledger.js +4 -2
- package/dist/cli/commands/ledger.js.map +1 -1
- package/dist/cli/commands/manifest.d.ts.map +1 -1
- package/dist/cli/commands/manifest.js +2 -1
- package/dist/cli/commands/manifest.js.map +1 -1
- package/dist/cli/commands/repair.d.ts +8 -0
- package/dist/cli/commands/repair.d.ts.map +1 -0
- package/dist/cli/commands/repair.js +97 -0
- package/dist/cli/commands/repair.js.map +1 -0
- package/dist/cli/commands/script-check.d.ts.map +1 -1
- package/dist/cli/commands/script-check.js +2 -1
- package/dist/cli/commands/script-check.js.map +1 -1
- package/dist/cli/commands/trace.d.ts.map +1 -1
- package/dist/cli/commands/trace.js +2 -1
- package/dist/cli/commands/trace.js.map +1 -1
- package/dist/cli/index.js +2 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/harness/repair.d.ts +20 -0
- package/dist/harness/repair.d.ts.map +1 -0
- package/dist/harness/repair.js +111 -0
- package/dist/harness/repair.js.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/orchestrator/templates/ai-instructions/claude-cmd-create-test.md +1 -1
- package/dist/orchestrator/templates/ai-instructions/claude-cmd-run-test.md +3 -3
- package/dist/orchestrator/templates/ai-instructions/claude-skill-api-design.md +4 -4
- package/dist/orchestrator/templates/ai-instructions/copilot-cmd-create-test.md +1 -1
- package/dist/orchestrator/templates/ai-instructions/copilot-cmd-run-test.md +3 -3
- package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-api-design.md +4 -4
- package/package.json +2 -2
- package/src/capabilities/context.ts +19 -0
- package/src/capabilities/registry.ts +3 -1
- package/src/cli/commands/audit.ts +2 -1
- package/src/cli/commands/context.ts +3 -2
- package/src/cli/commands/delivery.ts +11 -1
- package/src/cli/commands/generate.ts +2 -1
- package/src/cli/commands/ledger.ts +4 -2
- package/src/cli/commands/manifest.ts +2 -1
- package/src/cli/commands/repair.ts +57 -0
- package/src/cli/commands/script-check.ts +2 -1
- package/src/cli/commands/trace.ts +2 -1
- package/src/cli/index.ts +2 -0
- package/src/harness/repair.ts +75 -0
- package/src/index.ts +1 -1
- package/src/orchestrator/templates/ai-instructions/claude-cmd-create-test.md +1 -1
- package/src/orchestrator/templates/ai-instructions/claude-cmd-run-test.md +3 -3
- package/src/orchestrator/templates/ai-instructions/claude-skill-api-design.md +4 -4
- package/src/orchestrator/templates/ai-instructions/copilot-cmd-create-test.md +1 -1
- package/src/orchestrator/templates/ai-instructions/copilot-cmd-run-test.md +3 -3
- package/src/orchestrator/templates/ai-instructions/github-skill-sungen-api-design.md +4 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"script-check.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/script-check.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKpC,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"script-check.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/script-check.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKpC,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA+CjE"}
|
|
@@ -43,10 +43,11 @@ function registerScriptCheckCommand(program) {
|
|
|
43
43
|
.description('Verify the generated Playwright spec is a faithful 1:1 of the Gherkin feature (no hand-edit / stale drift)')
|
|
44
44
|
.option('-s, --screen <name>', 'Screen or flow name')
|
|
45
45
|
.option('--api <name>', 'API-first area or api flow (qa/api/<name>)')
|
|
46
|
+
.option('--area <name>', 'Alias of --api — an API-first area (qa/api/<name>)')
|
|
46
47
|
.option('--json', 'Output raw JSON')
|
|
47
48
|
.action(async (options) => {
|
|
48
49
|
try {
|
|
49
|
-
const name = options.screen || options.api;
|
|
50
|
+
const name = options.screen || options.api || options.area;
|
|
50
51
|
if (!name)
|
|
51
52
|
throw new Error('Provide --screen <name> (or --api <area>)');
|
|
52
53
|
const screen = path.join(process.cwd(), 'qa', 'screens', name);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"script-check.js","sourceRoot":"","sources":["../../../src/cli/commands/script-check.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAKA,
|
|
1
|
+
{"version":3,"file":"script-check.js","sourceRoot":"","sources":["../../../src/cli/commands/script-check.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"trace.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/trace.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKpC,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"trace.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/trace.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKpC,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAyD3D"}
|
|
@@ -43,11 +43,12 @@ function registerTraceCommand(program) {
|
|
|
43
43
|
.description('Visualise the executed test-design process (workflow/skill steps, repair loops), find bottlenecks, and show where to focus human review')
|
|
44
44
|
.option('-s, --screen <name>', 'Screen or flow name')
|
|
45
45
|
.option('--api <name>', 'API-first area or api flow (qa/api/<name>)')
|
|
46
|
+
.option('--area <name>', 'Alias of --api — an API-first area (qa/api/<name>)')
|
|
46
47
|
.option('--json', 'Output raw JSON')
|
|
47
48
|
.option('--mermaid', 'Print only the Mermaid flowchart')
|
|
48
49
|
.action((options) => {
|
|
49
50
|
try {
|
|
50
|
-
const name = options.screen || options.api;
|
|
51
|
+
const name = options.screen || options.api || options.area;
|
|
51
52
|
if (!name)
|
|
52
53
|
throw new Error('Provide --screen <name> (or --api <area>)');
|
|
53
54
|
const screen = path.join(process.cwd(), 'qa', 'screens', name);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"trace.js","sourceRoot":"","sources":["../../../src/cli/commands/trace.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAKA,
|
|
1
|
+
{"version":3,"file":"trace.js","sourceRoot":"","sources":["../../../src/cli/commands/trace.ts"],"names":[],"mappings":"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"}
|
package/dist/cli/index.js
CHANGED
|
@@ -28,6 +28,7 @@ const blindspot_1 = require("./commands/blindspot");
|
|
|
28
28
|
const capability_1 = require("./commands/capability");
|
|
29
29
|
const flow_check_1 = require("./commands/flow-check");
|
|
30
30
|
const context_1 = require("./commands/context");
|
|
31
|
+
const repair_1 = require("./commands/repair");
|
|
31
32
|
const registry_1 = require("../capabilities/registry");
|
|
32
33
|
const discover_1 = require("../capabilities/discover");
|
|
33
34
|
// Read version from package.json so `--version` never drifts from the released version.
|
|
@@ -62,6 +63,7 @@ async function main() {
|
|
|
62
63
|
(0, capability_1.registerCapabilityCommand)(program);
|
|
63
64
|
(0, flow_check_1.registerFlowCheckCommand)(program);
|
|
64
65
|
(0, context_1.registerContextCommand)(program);
|
|
66
|
+
(0, repair_1.registerRepairCommand)(program);
|
|
65
67
|
(0, ingest_1.registerIngestCommand)(program);
|
|
66
68
|
(0, eval_1.registerEvalCommand)(program);
|
|
67
69
|
// Capability-contributed CLI commands (Capability SPI): drivers own their authoring commands
|
package/dist/cli/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":";;AACA;;;GAGG;;AAEH,yCAAoC;AACpC,0CAAsD;AACtD,wCAAoD;AACpD,kDAA8D;AAC9D,kDAA8D;AAC9D,8CAA0D;AAC1D,kDAA8D;AAC9D,4CAAwD;AACxD,kDAA6D;AAC7D,oDAAgE;AAChE,4CAAwD;AACxD,8CAA0D;AAC1D,0CAAsD;AACtD,kDAA8D;AAC9D,8CAA0D;AAC1D,kDAA8D;AAC9D,0DAAqE;AACrE,4CAAwD;AACxD,oDAAgE;AAChE,oDAAgE;AAChE,sDAAkE;AAClE,sDAAiE;AACjE,gDAA4D;AAC5D,uDAA8D;AAC9D,uDAA2E;AAE3E,wFAAwF;AACxF,MAAM,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,oBAAoB,CAAwB,CAAC;AAEzE,KAAK,UAAU,IAAI;IACjB,MAAM,OAAO,GAAG,IAAI,mBAAO,EAAE,CAAC;IAE9B,OAAO;SACJ,IAAI,CAAC,QAAQ,CAAC;SACd,WAAW,CAAC,oEAAoE,CAAC;SACjF,OAAO,CAAC,OAAO,CAAC,CAAC;IAEpB,iBAAiB;IACjB,OAAO;SACJ,MAAM,CAAC,eAAe,EAAE,wBAAwB,CAAC,CAAC;IAErD,oBAAoB;IACpB,IAAA,0BAAmB,EAAC,OAAO,CAAC,CAAC;IAC7B,IAAA,wBAAkB,EAAC,OAAO,CAAC,CAAC;IAC5B,IAAA,kCAAuB,EAAC,OAAO,CAAC,CAAC;IACjC,IAAA,kCAAuB,EAAC,OAAO,CAAC,CAAC;IACjC,IAAA,8BAAqB,EAAC,OAAO,CAAC,CAAC;IAC/B,IAAA,kCAAuB,EAAC,OAAO,CAAC,CAAC;IACjC,IAAA,4BAAoB,EAAC,OAAO,CAAC,CAAC;IAC9B,IAAA,iCAAsB,EAAC,OAAO,CAAC,CAAC;IAChC,IAAA,oCAAwB,EAAC,OAAO,CAAC,CAAC;IAClC,IAAA,4BAAoB,EAAC,OAAO,CAAC,CAAC;IAC9B,IAAA,kCAAuB,EAAC,OAAO,CAAC,CAAC;IACjC,IAAA,8BAAqB,EAAC,OAAO,CAAC,CAAC;IAC/B,IAAA,kCAAuB,EAAC,OAAO,CAAC,CAAC;IACjC,IAAA,yCAA0B,EAAC,OAAO,CAAC,CAAC;IACpC,IAAA,4BAAoB,EAAC,OAAO,CAAC,CAAC;IAC9B,IAAA,oCAAwB,EAAC,OAAO,CAAC,CAAC;IAClC,IAAA,oCAAwB,EAAC,OAAO,CAAC,CAAC;IAClC,IAAA,sCAAyB,EAAC,OAAO,CAAC,CAAC;IACnC,IAAA,qCAAwB,EAAC,OAAO,CAAC,CAAC;IAClC,IAAA,gCAAsB,EAAC,OAAO,CAAC,CAAC;IAChC,IAAA,8BAAqB,EAAC,OAAO,CAAC,CAAC;IAC/B,IAAA,0BAAmB,EAAC,OAAO,CAAC,CAAC;IAE7B,6FAA6F;IAC7F,iFAAiF;IACjF,IAAA,0CAA+B,GAAE,CAAC;IAClC,KAAK,MAAM,GAAG,IAAI,6BAAkB,CAAC,GAAG,EAAE,EAAE,CAAC;QAC3C,KAAK,MAAM,eAAe,IAAI,GAAG,CAAC,WAAW,IAAI,EAAE;YAAE,eAAe,CAAC,OAAO,CAAC,CAAC;IAChF,CAAC;IAED,MAAM,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;AACzC,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IACrB,OAAO,CAAC,KAAK,CAAC,cAAc,EAAE,KAAK,CAAC,CAAC;IACrC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":";;AACA;;;GAGG;;AAEH,yCAAoC;AACpC,0CAAsD;AACtD,wCAAoD;AACpD,kDAA8D;AAC9D,kDAA8D;AAC9D,8CAA0D;AAC1D,kDAA8D;AAC9D,4CAAwD;AACxD,kDAA6D;AAC7D,oDAAgE;AAChE,4CAAwD;AACxD,8CAA0D;AAC1D,0CAAsD;AACtD,kDAA8D;AAC9D,8CAA0D;AAC1D,kDAA8D;AAC9D,0DAAqE;AACrE,4CAAwD;AACxD,oDAAgE;AAChE,oDAAgE;AAChE,sDAAkE;AAClE,sDAAiE;AACjE,gDAA4D;AAC5D,8CAA0D;AAC1D,uDAA8D;AAC9D,uDAA2E;AAE3E,wFAAwF;AACxF,MAAM,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,oBAAoB,CAAwB,CAAC;AAEzE,KAAK,UAAU,IAAI;IACjB,MAAM,OAAO,GAAG,IAAI,mBAAO,EAAE,CAAC;IAE9B,OAAO;SACJ,IAAI,CAAC,QAAQ,CAAC;SACd,WAAW,CAAC,oEAAoE,CAAC;SACjF,OAAO,CAAC,OAAO,CAAC,CAAC;IAEpB,iBAAiB;IACjB,OAAO;SACJ,MAAM,CAAC,eAAe,EAAE,wBAAwB,CAAC,CAAC;IAErD,oBAAoB;IACpB,IAAA,0BAAmB,EAAC,OAAO,CAAC,CAAC;IAC7B,IAAA,wBAAkB,EAAC,OAAO,CAAC,CAAC;IAC5B,IAAA,kCAAuB,EAAC,OAAO,CAAC,CAAC;IACjC,IAAA,kCAAuB,EAAC,OAAO,CAAC,CAAC;IACjC,IAAA,8BAAqB,EAAC,OAAO,CAAC,CAAC;IAC/B,IAAA,kCAAuB,EAAC,OAAO,CAAC,CAAC;IACjC,IAAA,4BAAoB,EAAC,OAAO,CAAC,CAAC;IAC9B,IAAA,iCAAsB,EAAC,OAAO,CAAC,CAAC;IAChC,IAAA,oCAAwB,EAAC,OAAO,CAAC,CAAC;IAClC,IAAA,4BAAoB,EAAC,OAAO,CAAC,CAAC;IAC9B,IAAA,kCAAuB,EAAC,OAAO,CAAC,CAAC;IACjC,IAAA,8BAAqB,EAAC,OAAO,CAAC,CAAC;IAC/B,IAAA,kCAAuB,EAAC,OAAO,CAAC,CAAC;IACjC,IAAA,yCAA0B,EAAC,OAAO,CAAC,CAAC;IACpC,IAAA,4BAAoB,EAAC,OAAO,CAAC,CAAC;IAC9B,IAAA,oCAAwB,EAAC,OAAO,CAAC,CAAC;IAClC,IAAA,oCAAwB,EAAC,OAAO,CAAC,CAAC;IAClC,IAAA,sCAAyB,EAAC,OAAO,CAAC,CAAC;IACnC,IAAA,qCAAwB,EAAC,OAAO,CAAC,CAAC;IAClC,IAAA,gCAAsB,EAAC,OAAO,CAAC,CAAC;IAChC,IAAA,8BAAqB,EAAC,OAAO,CAAC,CAAC;IAC/B,IAAA,8BAAqB,EAAC,OAAO,CAAC,CAAC;IAC/B,IAAA,0BAAmB,EAAC,OAAO,CAAC,CAAC;IAE7B,6FAA6F;IAC7F,iFAAiF;IACjF,IAAA,0CAA+B,GAAE,CAAC;IAClC,KAAK,MAAM,GAAG,IAAI,6BAAkB,CAAC,GAAG,EAAE,EAAE,CAAC;QAC3C,KAAK,MAAM,eAAe,IAAI,GAAG,CAAC,WAAW,IAAI,EAAE;YAAE,eAAe,CAAC,OAAO,CAAC,CAAC;IAChF,CAAC;IAED,MAAM,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;AACzC,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IACrB,OAAO,CAAC,KAAK,CAAC,cAAc,EAAE,KAAK,CAAC,CAAC;IACrC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export interface RepairProposal {
|
|
2
|
+
source: 'audit' | 'runtime';
|
|
3
|
+
signal: string;
|
|
4
|
+
ruleId: string;
|
|
5
|
+
fix: string;
|
|
6
|
+
}
|
|
7
|
+
export interface RepairPlan {
|
|
8
|
+
capability: string | undefined;
|
|
9
|
+
rulesAvailable: number;
|
|
10
|
+
proposals: RepairProposal[];
|
|
11
|
+
unmatched: string[];
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Build the repair plan for a unit.
|
|
15
|
+
* @param unitId capability-resolution id (`api/<area>`, `flows/<flow>`, or a screen)
|
|
16
|
+
* @param reportName the bare name used for `.sungen/reports/<name>-audit.json` (+ test-result)
|
|
17
|
+
* @param generatedDir the unit's specs/generated dir (for runtime failures); optional
|
|
18
|
+
*/
|
|
19
|
+
export declare function planRepair(unitId: string, reportName: string, cwd: string, generatedDir?: string): RepairPlan;
|
|
20
|
+
//# sourceMappingURL=repair.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"repair.d.ts","sourceRoot":"","sources":["../../src/harness/repair.ts"],"names":[],"mappings":"AAaA,MAAM,WAAW,cAAc;IAAG,MAAM,EAAE,OAAO,GAAG,SAAS,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE;AAC5G,MAAM,WAAW,UAAU;IACzB,UAAU,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,cAAc,EAAE,CAAC;IAC5B,SAAS,EAAE,MAAM,EAAE,CAAC;CACrB;AAyBD;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,UAAU,CAwB7G"}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.planRepair = planRepair;
|
|
37
|
+
/**
|
|
38
|
+
* Repair planner (#343) — the consumer of the `repair` capability SPI.
|
|
39
|
+
*
|
|
40
|
+
* Gathers the unit-capability's fix rules and matches them against the audit findings (always) and
|
|
41
|
+
* the latest Playwright failures (best-effort), turning them into a concrete fix plan. Deterministic:
|
|
42
|
+
* the AI repair loop and a human get the same proposals. Backs `sungen repair`.
|
|
43
|
+
*/
|
|
44
|
+
const fs = __importStar(require("fs"));
|
|
45
|
+
const path = __importStar(require("path"));
|
|
46
|
+
const registry_1 = require("../capabilities/registry");
|
|
47
|
+
const discover_1 = require("../capabilities/discover");
|
|
48
|
+
const audit_1 = require("./audit");
|
|
49
|
+
/** Collect failure messages from a Playwright JSON result file (best-effort, defensive). */
|
|
50
|
+
function failuresFromResult(file) {
|
|
51
|
+
const out = [];
|
|
52
|
+
try {
|
|
53
|
+
const r = JSON.parse(fs.readFileSync(file, 'utf8'));
|
|
54
|
+
const visit = (suite) => {
|
|
55
|
+
for (const sp of suite.specs ?? []) {
|
|
56
|
+
for (const t of sp.tests ?? []) {
|
|
57
|
+
for (const res of t.results ?? []) {
|
|
58
|
+
if (res.status === 'failed' || res.status === 'timedOut') {
|
|
59
|
+
const msg = res.error?.message || res.errors?.[0]?.message || res.status;
|
|
60
|
+
out.push(`${sp.title}: ${String(msg).split('\n')[0].slice(0, 200)}`);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
for (const s of suite.suites ?? [])
|
|
66
|
+
visit(s);
|
|
67
|
+
};
|
|
68
|
+
for (const s of r.suites ?? [])
|
|
69
|
+
visit(s);
|
|
70
|
+
}
|
|
71
|
+
catch { /* missing/!json → no runtime signals */ }
|
|
72
|
+
return out;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Build the repair plan for a unit.
|
|
76
|
+
* @param unitId capability-resolution id (`api/<area>`, `flows/<flow>`, or a screen)
|
|
77
|
+
* @param reportName the bare name used for `.sungen/reports/<name>-audit.json` (+ test-result)
|
|
78
|
+
* @param generatedDir the unit's specs/generated dir (for runtime failures); optional
|
|
79
|
+
*/
|
|
80
|
+
function planRepair(unitId, reportName, cwd, generatedDir) {
|
|
81
|
+
(0, discover_1.discoverAndRegisterCapabilities)();
|
|
82
|
+
const capId = (0, audit_1.scoringCapabilityFor)(unitId, registry_1.capabilityRegistry.defaultCapabilityId());
|
|
83
|
+
const rules = (capId ? registry_1.capabilityRegistry.get(capId)?.repair?.rules : undefined) ?? [];
|
|
84
|
+
const signals = [];
|
|
85
|
+
const auditPath = path.join(cwd, '.sungen', 'reports', `${reportName}-audit.json`);
|
|
86
|
+
if (fs.existsSync(auditPath)) {
|
|
87
|
+
try {
|
|
88
|
+
for (const f of JSON.parse(fs.readFileSync(auditPath, 'utf8')).findings ?? [])
|
|
89
|
+
signals.push({ source: 'audit', text: String(f) });
|
|
90
|
+
}
|
|
91
|
+
catch { /* ignore */ }
|
|
92
|
+
}
|
|
93
|
+
if (generatedDir && fs.existsSync(generatedDir)) {
|
|
94
|
+
for (const f of fs.readdirSync(generatedDir)) {
|
|
95
|
+
if (/test-result.*\.json$/.test(f))
|
|
96
|
+
for (const msg of failuresFromResult(path.join(generatedDir, f)))
|
|
97
|
+
signals.push({ source: 'runtime', text: msg });
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
const proposals = [];
|
|
101
|
+
const unmatched = [];
|
|
102
|
+
for (const s of signals) {
|
|
103
|
+
const rule = rules.find((r) => r.match.test(s.text));
|
|
104
|
+
if (rule)
|
|
105
|
+
proposals.push({ source: s.source, signal: s.text, ruleId: rule.id, fix: rule.fix });
|
|
106
|
+
else
|
|
107
|
+
unmatched.push(s.text);
|
|
108
|
+
}
|
|
109
|
+
return { capability: capId, rulesAvailable: rules.length, proposals, unmatched };
|
|
110
|
+
}
|
|
111
|
+
//# sourceMappingURL=repair.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"repair.js","sourceRoot":"","sources":["../../src/harness/repair.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
export { capabilityRegistry, CapabilityRegistry } from './capabilities/registry';
|
|
7
7
|
export type { CapabilityDescriptor } from './capabilities/registry';
|
|
8
8
|
export type { Sensor, SensorFinding, AdvisoryScanInput, GateInput } from './capabilities/sensor';
|
|
9
|
-
export type { Context, DiscoveryProvider, ContextMapper, GenerationUnit } from './capabilities/context';
|
|
9
|
+
export type { Context, DiscoveryProvider, ContextMapper, GenerationUnit, RepairProvider, RepairRule } from './capabilities/context';
|
|
10
10
|
export { discoverUnitContext } from './orchestrator/context-discovery';
|
|
11
11
|
export type { DiscoveredContext } from './orchestrator/context-discovery';
|
|
12
12
|
export type { PatternContext, StepPattern, StepTemplateData } from './generators/test-generator/patterns/types';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AACjF,YAAY,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AACpE,YAAY,EAAE,MAAM,EAAE,aAAa,EAAE,iBAAiB,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AACjG,YAAY,EAAE,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AACjF,YAAY,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AACpE,YAAY,EAAE,MAAM,EAAE,aAAa,EAAE,iBAAiB,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AACjG,YAAY,EAAE,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,cAAc,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpI,OAAO,EAAE,mBAAmB,EAAE,MAAM,kCAAkC,CAAC;AACvE,YAAY,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;AAG1E,YAAY,EAAE,cAAc,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,4CAA4C,CAAC;AAChH,YAAY,EAAE,UAAU,EAAE,MAAM,yCAAyC,CAAC;AAC1E,YAAY,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AAC9D,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,oBAAoB,EAAE,MAAM,kDAAkD,CAAC;AAGhH,OAAO,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AAGrE,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAClF,YAAY,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAI1D,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,cAAc,EAAE,aAAa,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAChI,YAAY,EAAE,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAC1E,YAAY,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC"}
|
|
@@ -27,7 +27,7 @@ Parse **name** from `$ARGUMENTS`. If missing, ask the user.
|
|
|
27
27
|
|
|
28
28
|
## API unit mode (driver-api)
|
|
29
29
|
|
|
30
|
-
If the unit is **api-first** (`qa/api/<name>/` or `qa/api/flows/<name>/`), the design loop differs — **no visual capture, no selectors**; the contract is the named-endpoint catalog. **Follow the `sungen-api-design` skill end-to-end** instead of the screen/flow steps below: `sungen context --
|
|
30
|
+
If the unit is **api-first** (`qa/api/<name>/` or `qa/api/flows/<name>/`), the design loop differs — **no visual capture, no selectors**; the contract is the named-endpoint catalog. **Follow the `sungen-api-design` skill end-to-end** instead of the screen/flow steps below: `sungen context --area <name>` (discover) → API viewpoint overview → generate `@api`/`@cases`/flow/`@concurrent`/`@query` scenarios → **`sungen audit --area <name>` gate + the `sungen-reviewer` sub-agent + repair loop to businessDepth ≥ 0.7** → record + trace. Then jump to the "Converge" next-step options (recommend `/sungen:run-test <name>`). The capture / viewpoint-group / selector steps do **not** apply.
|
|
31
31
|
|
|
32
32
|
## Steps
|
|
33
33
|
|
|
@@ -37,15 +37,15 @@ Skip this pre-flight when `--env` matches the base locale (no overlay needed in
|
|
|
37
37
|
If the unit is **api-first**, skip every selector/capture phase (an API test has no DOM). Instead:
|
|
38
38
|
|
|
39
39
|
1. **Resolve the datasource** — ensure the `kind: api` datasource's `base_url` + auth are wired in `qa/datasources.yaml` + `.env.qa` (the `${X_URL}` key from `sungen api init`). A `production` datasource is refused unless `SUNGEN_ALLOW_PROD=1`.
|
|
40
|
-
2. **Compile**: `[ -x ./bin/sungen.js ] && ./bin/sungen.js generate --
|
|
40
|
+
2. **Compile**: `[ -x ./bin/sungen.js ] && ./bin/sungen.js generate --area <name> || npx sungen generate --area <name>` → `specs/generated/api/<name>/`.
|
|
41
41
|
3. **Run**: `npx playwright test specs/generated/api/<name>/<name>.spec.ts` (per-spec JSON results, as below).
|
|
42
42
|
4. **Auto-fix** (no selectors — the failure classes differ): use `sungen-error-mapping`.
|
|
43
43
|
- **401/403** → wire `@hybrid` + `@auth:<role>` (reuse the UI session) or the catalog `Bearer :token` header; suggest `sungen makeauth <role>`.
|
|
44
44
|
- **datasource/base_url unresolved** → set the `${X_URL}` key in `.env.qa`.
|
|
45
45
|
- **missing/empty bound param** → trace `{{var}}` to test-data or a prior `@api` response; fill it.
|
|
46
|
-
- **`expect.status` mismatch** → reconcile against `apis.yaml`/spec (the catalog is the oracle); **never hand-edit the generated spec** (re-`generate --
|
|
46
|
+
- **`expect.status` mismatch** → reconcile against `apis.yaml`/spec (the catalog is the oracle); **never hand-edit the generated spec** (re-`generate --area` instead).
|
|
47
47
|
- **flaky** → enforce self-cleaning flows, per-row isolation (`@cases`), `@concurrent` caps.
|
|
48
|
-
5. **Integrity + trace** — `sungen script-check --
|
|
48
|
+
5. **Integrity + trace** — `sungen script-check --area <name>` (verify the spec is a 1:1 of the Gherkin; on DRIFT re-`generate --area`, never hand-edit) and `sungen trace --area <name>` (process map + HUMAN-LOOP FOCUS). Then report + offer next steps.
|
|
49
49
|
|
|
50
50
|
## Pre-run (phased — per `sungen-selector-fix` skill)
|
|
51
51
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: sungen-api-design
|
|
3
|
-
description: The API-first design loop for an api unit (qa/api/<area> or qa/api/flows/<flow>) — discover the catalog, lay out the API viewpoints, generate @api/@cases/flow/@concurrent scenarios, then drive the sungen audit --
|
|
3
|
+
description: The API-first design loop for an api unit (qa/api/<area> or qa/api/flows/<flow>) — discover the catalog, lay out the API viewpoints, generate @api/@cases/flow/@concurrent scenarios, then drive the sungen audit --area gate + reviewer + repair to a high businessDepth (≥0.7). Use when create-test/run-test detects an api unit (no selectors, no visual capture).
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# API design loop (driver-api · Orchestration + Harness)
|
|
@@ -10,7 +10,7 @@ Use this when the unit is **api-first** — `qa/api/<area>/` or `qa/api/flows/<f
|
|
|
10
10
|
## The loop (mirror of /sungen:design, API-native)
|
|
11
11
|
|
|
12
12
|
### 1. Discover (no capture)
|
|
13
|
-
Run `sungen context --
|
|
13
|
+
Run `sungen context --area <name>` — it reads the catalog and prints the **endpoints** + the **generation units** (one `matrix` unit per endpoint, an `async` unit per mutating endpoint, a `flow` unit for an api flow). Read `qa/api/<name>/requirements/spec.md` if present. No `apis.yaml` yet? → `sungen api import <openapi|csv>` or `sungen api add --area <name>` first.
|
|
14
14
|
|
|
15
15
|
### 2. API viewpoint overview (by method-profile)
|
|
16
16
|
For each endpoint, cover its viewpoints — severity-weighted by method:
|
|
@@ -29,7 +29,7 @@ Bands: **~70%** success+failure matrix · **~20%** flows (auth/CRUD chains) · *
|
|
|
29
29
|
- **Idempotency**: `@api:<name> @concurrent:N` + `expect {{name.ok_count}} is 1`, cross-checked with `@query` (the DB is the oracle).
|
|
30
30
|
|
|
31
31
|
### 4. Gate + repair (always — businessDepth ≥ 0.7 is the bar)
|
|
32
|
-
Run `sungen audit --
|
|
32
|
+
Run `sungen audit --area <name>`; read `gateStatus` + `findings`. Then the **semantic reviewer** (sungen-reviewer sub-agent, API criteria). Repair **both** (budget 3 rounds), re-audit until PASS:
|
|
33
33
|
|
|
34
34
|
| Finding | Repair |
|
|
35
35
|
|---|---|
|
|
@@ -41,7 +41,7 @@ Run `sungen audit --api <name>`; read `gateStatus` + `findings`. Then the **sema
|
|
|
41
41
|
Stop when the gate PASSes + businessDepth ≥ 0.7, or the budget is exhausted → report residual gaps honestly (mark genuinely-unautomatable cases `@manual` with an oracle). Never fake a pass.
|
|
42
42
|
|
|
43
43
|
### 5. Record + converge
|
|
44
|
-
`sungen manifest --
|
|
44
|
+
`sungen manifest --area <name>` (reuse) and ledger each phase; show the trace + the HUMAN-LOOP FOCUS. (Integrity `script-check`/`trace` for api: see run-test.)
|
|
45
45
|
|
|
46
46
|
## Rules
|
|
47
47
|
- **No HTTP, no selectors** — only `.feature` + the reviewed `apis.yaml` + `test-data`.
|
|
@@ -22,7 +22,7 @@ You are a **Senior QA Engineer**. You structure test cases by viewpoint categori
|
|
|
22
22
|
|
|
23
23
|
## API unit mode (driver-api)
|
|
24
24
|
|
|
25
|
-
If the unit is **api-first** (`qa/api/<name>/` or `qa/api/flows/<name>/`), the design loop differs — **no visual capture, no selectors**; the contract is the named-endpoint catalog. **Follow the `sungen-api-design` skill end-to-end** instead of the screen/flow steps: `sungen context --
|
|
25
|
+
If the unit is **api-first** (`qa/api/<name>/` or `qa/api/flows/<name>/`), the design loop differs — **no visual capture, no selectors**; the contract is the named-endpoint catalog. **Follow the `sungen-api-design` skill end-to-end** instead of the screen/flow steps: `sungen context --area <name>` (discover) → API viewpoint overview → generate `@api`/`@cases`/flow/`@concurrent`/`@query` scenarios → **`sungen audit --area <name>` gate + reviewer + repair loop to businessDepth ≥ 0.7** → record + trace. Then recommend `/sungen-run-test <name>`. The capture / viewpoint-group / selector steps do **not** apply.
|
|
26
26
|
|
|
27
27
|
## Steps
|
|
28
28
|
|
|
@@ -36,10 +36,10 @@ Skip when `--env` matches the base locale.
|
|
|
36
36
|
|
|
37
37
|
If the unit is **api-first**, skip every selector/capture phase (an API test has no DOM):
|
|
38
38
|
1. **Resolve the datasource** — `base_url` + auth wired in `qa/datasources.yaml` + `.env.qa` (`${X_URL}` from `sungen api init`); a `production` datasource is refused unless `SUNGEN_ALLOW_PROD=1`.
|
|
39
|
-
2. **Compile**: `npx sungen generate --
|
|
39
|
+
2. **Compile**: `npx sungen generate --area <name>` → `specs/generated/api/<name>/`.
|
|
40
40
|
3. **Run**: `npx playwright test specs/generated/api/<name>/<name>.spec.ts`.
|
|
41
|
-
4. **Auto-fix** (use `sungen-error-mapping`): 401/403 → `@hybrid`+`@auth` or `Bearer :token` header (`sungen makeauth`); base_url unresolved → set `${X_URL}`; missing param → trace `{{var}}` to test-data/a prior `@api` response; `expect.status` mismatch → reconcile against `apis.yaml` (re-`generate --
|
|
42
|
-
5. **Integrity + trace** — `sungen script-check --
|
|
41
|
+
4. **Auto-fix** (use `sungen-error-mapping`): 401/403 → `@hybrid`+`@auth` or `Bearer :token` header (`sungen makeauth`); base_url unresolved → set `${X_URL}`; missing param → trace `{{var}}` to test-data/a prior `@api` response; `expect.status` mismatch → reconcile against `apis.yaml` (re-`generate --area`, never hand-edit the spec); flaky → self-clean + `@concurrent` caps.
|
|
42
|
+
5. **Integrity + trace** — `sungen script-check --area <name>` (1:1; on DRIFT re-`generate --area`, never hand-edit the spec) + `sungen trace --area <name>` (process map + HUMAN-LOOP FOCUS). Report + offer next steps.
|
|
43
43
|
|
|
44
44
|
## Pre-run (phased — per `sungen-selector-fix` skill)
|
|
45
45
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: sungen-api-design
|
|
3
|
-
description: The API-first design loop for an api unit (qa/api/<area> or qa/api/flows/<flow>) — discover the catalog, lay out the API viewpoints, generate @api/@cases/flow/@concurrent scenarios, then drive the sungen audit --
|
|
3
|
+
description: The API-first design loop for an api unit (qa/api/<area> or qa/api/flows/<flow>) — discover the catalog, lay out the API viewpoints, generate @api/@cases/flow/@concurrent scenarios, then drive the sungen audit --area gate + reviewer + repair to a high businessDepth (≥0.7). Use when create-test/run-test detects an api unit (no selectors, no visual capture).
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# API design loop (driver-api · Orchestration + Harness)
|
|
@@ -10,7 +10,7 @@ Use this when the unit is **api-first** — `qa/api/<area>/` or `qa/api/flows/<f
|
|
|
10
10
|
## The loop (mirror of /sungen:design, API-native)
|
|
11
11
|
|
|
12
12
|
### 1. Discover (no capture)
|
|
13
|
-
Run `sungen context --
|
|
13
|
+
Run `sungen context --area <name>` — it reads the catalog and prints the **endpoints** + the **generation units** (one `matrix` unit per endpoint, an `async` unit per mutating endpoint, a `flow` unit for an api flow). Read `qa/api/<name>/requirements/spec.md` if present. No `apis.yaml` yet? → `sungen api import <openapi|csv>` or `sungen api add --area <name>` first.
|
|
14
14
|
|
|
15
15
|
### 2. API viewpoint overview (by method-profile)
|
|
16
16
|
For each endpoint, cover its viewpoints — severity-weighted by method:
|
|
@@ -29,7 +29,7 @@ Bands: **~70%** success+failure matrix · **~20%** flows (auth/CRUD chains) · *
|
|
|
29
29
|
- **Idempotency**: `@api:<name> @concurrent:N` + `expect {{name.ok_count}} is 1`, cross-checked with `@query` (the DB is the oracle).
|
|
30
30
|
|
|
31
31
|
### 4. Gate + repair (always — businessDepth ≥ 0.7 is the bar)
|
|
32
|
-
Run `sungen audit --
|
|
32
|
+
Run `sungen audit --area <name>`; read `gateStatus` + `findings`. Then the **semantic reviewer** (sungen-reviewer sub-agent, API criteria). Repair **both** (budget 3 rounds), re-audit until PASS:
|
|
33
33
|
|
|
34
34
|
| Finding | Repair |
|
|
35
35
|
|---|---|
|
|
@@ -41,7 +41,7 @@ Run `sungen audit --api <name>`; read `gateStatus` + `findings`. Then the **sema
|
|
|
41
41
|
Stop when the gate PASSes + businessDepth ≥ 0.7, or the budget is exhausted → report residual gaps honestly (mark genuinely-unautomatable cases `@manual` with an oracle). Never fake a pass.
|
|
42
42
|
|
|
43
43
|
### 5. Record + converge
|
|
44
|
-
`sungen manifest --
|
|
44
|
+
`sungen manifest --area <name>` (reuse) and ledger each phase; show the trace + the HUMAN-LOOP FOCUS. (Integrity `script-check`/`trace` for api: see run-test.)
|
|
45
45
|
|
|
46
46
|
## Rules
|
|
47
47
|
- **No HTTP, no selectors** — only `.feature` + the reviewed `apis.yaml` + `test-data`.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sun-asterisk/sungen",
|
|
3
|
-
"version": "3.1.2-beta.
|
|
3
|
+
"version": "3.1.2-beta.123",
|
|
4
4
|
"description": "Deterministic E2E Test Compiler - Gherkin + Selectors → Playwright tests",
|
|
5
5
|
"main": "src/index.ts",
|
|
6
6
|
"types": "src/index.ts",
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
"node": ">=18.0.0"
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
|
-
"@sungen/driver-ui": "3.1.2-beta.
|
|
36
|
+
"@sungen/driver-ui": "3.1.2-beta.123",
|
|
37
37
|
"@anthropic-ai/sdk": "^0.71.0",
|
|
38
38
|
"@babel/parser": "^7.28.5",
|
|
39
39
|
"@babel/traverse": "^7.28.5",
|
|
@@ -44,3 +44,22 @@ export interface ContextMapper {
|
|
|
44
44
|
/** Turn the Context into generation units (+ modes), honouring the kernel's band targets. */
|
|
45
45
|
decompose(ctx: Context, bands?: Record<string, number>): GenerationUnit[];
|
|
46
46
|
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Repair phase hook — a capability's deterministic fix catalog. Each rule matches a finding (audit
|
|
50
|
+
* gap) or a runtime failure message and proposes a concrete fix. `sungen repair` gathers the
|
|
51
|
+
* unit-capability's rules and turns the findings/failures into an actionable plan; the AI repair
|
|
52
|
+
* loop and a human get the same proposals. Drivers/projects extend the catalog by adding rules.
|
|
53
|
+
*/
|
|
54
|
+
export interface RepairRule {
|
|
55
|
+
/** Stable id, e.g. 'api-error' | 'api-auth'. */
|
|
56
|
+
id: string;
|
|
57
|
+
/** Matches a finding or failure message. */
|
|
58
|
+
match: RegExp;
|
|
59
|
+
/** The concrete repair instruction to apply. */
|
|
60
|
+
fix: string;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export interface RepairProvider {
|
|
64
|
+
rules: RepairRule[];
|
|
65
|
+
}
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
*/
|
|
14
14
|
import type { StepPattern } from '../generators/test-generator/patterns/types';
|
|
15
15
|
import type { Sensor } from './sensor';
|
|
16
|
-
import type { DiscoveryProvider, ContextMapper } from './context';
|
|
16
|
+
import type { DiscoveryProvider, ContextMapper, RepairProvider } from './context';
|
|
17
17
|
|
|
18
18
|
export interface CapabilityDescriptor {
|
|
19
19
|
/** Stable id: 'ui' | 'db' | 'api' | 'core' | … */
|
|
@@ -29,6 +29,8 @@ export interface CapabilityDescriptor {
|
|
|
29
29
|
/** Orchestration phase hooks — declared in R1, consumed by the pipeline from R2 onward. */
|
|
30
30
|
discovery?: DiscoveryProvider; // sources → Context slice
|
|
31
31
|
contextMapper?: ContextMapper; // Context → generation units + modes
|
|
32
|
+
/** Repair phase: the capability's deterministic fix catalog (audit/runtime finding → fix). */
|
|
33
|
+
repair?: RepairProvider;
|
|
32
34
|
/** Provider for this capability's viewpoint catalog (UI: the 17-pattern universal catalog). */
|
|
33
35
|
viewpoints?: () => unknown;
|
|
34
36
|
/**
|
|
@@ -92,10 +92,11 @@ export function registerAuditCommand(program: Command): void {
|
|
|
92
92
|
.description('Harness: measure test-design quality (viewpoint gate, depth, balance, duplicates, traceability)')
|
|
93
93
|
.option('-s, --screen <name>', 'Screen or flow name to audit')
|
|
94
94
|
.option('--api <name>', 'API-first area or api flow to audit (e.g. orders, flows/signup)')
|
|
95
|
+
.option('--area <name>', 'Alias of --api — an API-first area (qa/api/<name>)')
|
|
95
96
|
.option('--json', 'Output the raw JSON report')
|
|
96
97
|
.action((options) => {
|
|
97
98
|
try {
|
|
98
|
-
const name = options.screen || options.api;
|
|
99
|
+
const name = options.screen || options.api || options.area;
|
|
99
100
|
if (!name) throw new Error('Provide --screen <name> (or --api <area>)');
|
|
100
101
|
const dir = findScreenDir(name);
|
|
101
102
|
if (!dir) throw new Error(`Not found: qa/screens/${name}, qa/flows/${name}, or qa/api/${name}`);
|
|
@@ -16,10 +16,11 @@ export function registerContextCommand(program: Command): void {
|
|
|
16
16
|
.option('-s, --screen <name>', 'Screen name')
|
|
17
17
|
.option('--flow <name>', 'Flow name (resolved as flows/<name>)')
|
|
18
18
|
.option('--api <name>', 'API-first area or api flow (resolved as api/<name>)')
|
|
19
|
+
.option('--area <name>', 'Alias of --api — an API-first area (qa/api/<name>)')
|
|
19
20
|
.option('--json', 'Print the raw JSON')
|
|
20
|
-
.action(async (o: { screen?: string; flow?: string; api?: string; json?: boolean }) => {
|
|
21
|
+
.action(async (o: { screen?: string; flow?: string; api?: string; area?: string; json?: boolean }) => {
|
|
21
22
|
try {
|
|
22
|
-
const unitId = o.api ? `api/${o.api}` : o.flow ? `flows/${o.flow}` : o.screen;
|
|
23
|
+
const unitId = (o.api || o.area) ? `api/${o.api || o.area}` : o.flow ? `flows/${o.flow}` : o.screen;
|
|
23
24
|
if (!unitId) throw new Error('Provide --screen <name>, --flow <name>, or --api <area>.');
|
|
24
25
|
const cwd = process.cwd();
|
|
25
26
|
const result = await discoverUnitContext(unitId, cwd);
|
|
@@ -94,7 +94,14 @@ function listAllTargets(cwd: string): DeliveryTarget[] {
|
|
|
94
94
|
};
|
|
95
95
|
scan('screen');
|
|
96
96
|
scan('flow');
|
|
97
|
-
scan('api', (n) => n === 'flows');
|
|
97
|
+
scan('api', (n) => n === 'flows'); // api areas: qa/api/<area>
|
|
98
|
+
// api flows: qa/api/flows/<flow> → screen `flows/<flow>`, kind 'api' (paths compose to qa/api/flows/… + specs/generated/api/flows/…)
|
|
99
|
+
const apiFlowsRoot = path.join(cwd, 'qa', 'api', 'flows');
|
|
100
|
+
if (fs.existsSync(apiFlowsRoot)) {
|
|
101
|
+
for (const d of fs.readdirSync(apiFlowsRoot, { withFileTypes: true })) {
|
|
102
|
+
if (d.isDirectory()) targets.push(...listFeatureTargets(cwd, path.posix.join('flows', d.name), 'api'));
|
|
103
|
+
}
|
|
104
|
+
}
|
|
98
105
|
|
|
99
106
|
return targets.sort((a, b) => a.featureBaseName.localeCompare(b.featureBaseName));
|
|
100
107
|
}
|
|
@@ -113,6 +120,9 @@ function resolveTargetsFromArg(cwd: string, name: string): DeliveryTarget[] {
|
|
|
113
120
|
if (fs.existsSync(path.join(cwd, 'qa', 'flows', name))) return listFeatureTargets(cwd, name, 'flow');
|
|
114
121
|
if (fs.existsSync(path.join(cwd, 'qa', 'screens', name))) return listFeatureTargets(cwd, name, 'screen');
|
|
115
122
|
if (fs.existsSync(path.join(cwd, 'qa', 'api', name))) return listFeatureTargets(cwd, name, 'api');
|
|
123
|
+
// `flows/<flow>` or a bare api-flow name → qa/api/flows/<flow>
|
|
124
|
+
const apiFlow = name.startsWith('flows/') ? name : path.posix.join('flows', name);
|
|
125
|
+
if (fs.existsSync(path.join(cwd, 'qa', 'api', apiFlow))) return listFeatureTargets(cwd, apiFlow, 'api');
|
|
116
126
|
// Treat as feature basename — find the parent unit that hosts it.
|
|
117
127
|
const candidates = listAllTargets(cwd).filter((t) => t.featureBaseName === name);
|
|
118
128
|
if (candidates.length > 0) return candidates;
|
|
@@ -95,6 +95,7 @@ export function registerGenerateCommand(program: Command): void {
|
|
|
95
95
|
.option('-s, --screen <name>', 'Generate tests for a specific screen')
|
|
96
96
|
.option('--flow <name>', 'Generate tests for a specific flow')
|
|
97
97
|
.option('--api <name>', 'Generate tests for an API-first area or api flow (e.g. orders, flows/signup)')
|
|
98
|
+
.option('--area <name>', 'Alias of --api — an API-first area (qa/api/<name>)')
|
|
98
99
|
.option('--all', 'Generate tests for all screens, flows, and API areas')
|
|
99
100
|
.option('--framework <name>', 'Override the platform driver (else read from qa/capabilities.yaml)')
|
|
100
101
|
.option('--inline-data', 'Hardcode test data at compile time instead of runtime loading')
|
|
@@ -102,7 +103,7 @@ export function registerGenerateCommand(program: Command): void {
|
|
|
102
103
|
try {
|
|
103
104
|
const screenName = options.screen;
|
|
104
105
|
const flowName = options.flow;
|
|
105
|
-
const apiName = options.api;
|
|
106
|
+
const apiName = options.api || options.area;
|
|
106
107
|
|
|
107
108
|
// Find feature files
|
|
108
109
|
let featureFiles: string[];
|
|
@@ -11,6 +11,7 @@ export function registerLedgerCommand(program: Command): void {
|
|
|
11
11
|
.description('Append a step event to the ledger')
|
|
12
12
|
.option('-s, --screen <name>', 'Screen or flow name')
|
|
13
13
|
.option('--api <name>', 'API-first area or api flow (qa/api/<name>)')
|
|
14
|
+
.option('--area <name>', 'Alias of --api — an API-first area (qa/api/<name>)')
|
|
14
15
|
.requiredOption('--step <name>', 'Step name (discovery | viewpoint | gherkin | audit | repair:1 ...)')
|
|
15
16
|
.option('--run <id>', 'Run id — groups all phases of one create-test invocation (else auto-segmented by time gap)')
|
|
16
17
|
.option('--model <id>', 'Model id')
|
|
@@ -20,7 +21,7 @@ export function registerLedgerCommand(program: Command): void {
|
|
|
20
21
|
.option('--note <text>', 'Free note')
|
|
21
22
|
.action((o) => {
|
|
22
23
|
try {
|
|
23
|
-
const name = o.screen || o.api;
|
|
24
|
+
const name = o.screen || o.api || o.area;
|
|
24
25
|
if (!name) throw new Error('Provide --screen <name> (or --api <area>)');
|
|
25
26
|
recordEvent(name, {
|
|
26
27
|
step: o.step, runId: o.run, model: o.model, tokensIn: o.tokensIn, tokensOut: o.tokensOut, ms: o.ms, note: o.note,
|
|
@@ -37,11 +38,12 @@ export function registerLedgerCommand(program: Command): void {
|
|
|
37
38
|
.description('Summarise ledger + efficiency verdicts (pulls audit score if present)')
|
|
38
39
|
.option('-s, --screen <name>', 'Screen or flow name')
|
|
39
40
|
.option('--api <name>', 'API-first area or api flow (qa/api/<name>)')
|
|
41
|
+
.option('--area <name>', 'Alias of --api — an API-first area (qa/api/<name>)')
|
|
40
42
|
.option('--all-runs', 'Aggregate ALL runs (default: latest run only)')
|
|
41
43
|
.option('--json', 'Output raw JSON')
|
|
42
44
|
.action((o) => {
|
|
43
45
|
try {
|
|
44
|
-
const name = o.screen || o.api;
|
|
46
|
+
const name = o.screen || o.api || o.area;
|
|
45
47
|
if (!name) throw new Error('Provide --screen <name> (or --api <area>)');
|
|
46
48
|
const r = buildReport(name, { allRuns: o.allRuns });
|
|
47
49
|
if (o.json) { console.log(JSON.stringify(r, null, 2)); return; }
|
|
@@ -17,11 +17,12 @@ export function registerManifestCommand(program: Command): void {
|
|
|
17
17
|
.description('Spec-fingerprint manifest: build a scenario↔spec-section map, or diff to plan keep/regenerate/retire')
|
|
18
18
|
.option('-s, --screen <name>', 'Screen or flow name')
|
|
19
19
|
.option('--api <name>', 'API-first area or api flow (qa/api/<name>)')
|
|
20
|
+
.option('--area <name>', 'Alias of --api — an API-first area (qa/api/<name>)')
|
|
20
21
|
.option('--diff', 'Compare current spec vs stored manifest → change plan')
|
|
21
22
|
.option('--json', 'Output raw JSON')
|
|
22
23
|
.action((options) => {
|
|
23
24
|
try {
|
|
24
|
-
const name = options.screen || options.api;
|
|
25
|
+
const name = options.screen || options.api || options.area;
|
|
25
26
|
if (!name) throw new Error('Provide --screen <name> (or --api <area>)');
|
|
26
27
|
const dir = findScreenDir(name);
|
|
27
28
|
if (!dir) throw new Error(`Not found: qa/screens|flows|api/${name}`);
|