@sun-asterisk/sungen 2.7.0-beta.1 → 3.0.0-beta.72
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/README.md +1 -1
- package/dist/cli/commands/add.js +3 -3
- package/dist/cli/commands/add.js.map +1 -1
- package/dist/cli/commands/audit.d.ts +3 -0
- package/dist/cli/commands/audit.d.ts.map +1 -0
- package/dist/cli/commands/audit.js +134 -0
- package/dist/cli/commands/audit.js.map +1 -0
- package/dist/cli/commands/blindspot.d.ts +3 -0
- package/dist/cli/commands/blindspot.d.ts.map +1 -0
- package/dist/cli/commands/blindspot.js +58 -0
- package/dist/cli/commands/blindspot.js.map +1 -0
- package/dist/cli/commands/capability.d.ts +3 -0
- package/dist/cli/commands/capability.d.ts.map +1 -0
- package/dist/cli/commands/capability.js +196 -0
- package/dist/cli/commands/capability.js.map +1 -0
- package/dist/cli/commands/challenge.d.ts +3 -0
- package/dist/cli/commands/challenge.d.ts.map +1 -0
- package/dist/cli/commands/challenge.js +102 -0
- package/dist/cli/commands/challenge.js.map +1 -0
- package/dist/cli/commands/feedback.d.ts +3 -0
- package/dist/cli/commands/feedback.d.ts.map +1 -0
- package/dist/cli/commands/feedback.js +72 -0
- package/dist/cli/commands/feedback.js.map +1 -0
- package/dist/cli/commands/flow-check.d.ts +3 -0
- package/dist/cli/commands/flow-check.d.ts.map +1 -0
- package/dist/cli/commands/flow-check.js +136 -0
- package/dist/cli/commands/flow-check.js.map +1 -0
- package/dist/cli/commands/generate.d.ts.map +1 -1
- package/dist/cli/commands/generate.js +50 -2
- package/dist/cli/commands/generate.js.map +1 -1
- package/dist/cli/commands/ledger.d.ts +3 -0
- package/dist/cli/commands/ledger.d.ts.map +1 -0
- package/dist/cli/commands/ledger.js +71 -0
- package/dist/cli/commands/ledger.js.map +1 -0
- package/dist/cli/commands/manifest.d.ts +3 -0
- package/dist/cli/commands/manifest.d.ts.map +1 -0
- package/dist/cli/commands/manifest.js +101 -0
- package/dist/cli/commands/manifest.js.map +1 -0
- package/dist/cli/commands/script-check.d.ts +3 -0
- package/dist/cli/commands/script-check.d.ts.map +1 -0
- package/dist/cli/commands/script-check.js +97 -0
- package/dist/cli/commands/script-check.js.map +1 -0
- package/dist/cli/commands/trace.d.ts +3 -0
- package/dist/cli/commands/trace.d.ts.map +1 -0
- package/dist/cli/commands/trace.js +110 -0
- package/dist/cli/commands/trace.js.map +1 -0
- package/dist/cli/commands/update.d.ts.map +1 -1
- package/dist/cli/commands/update.js +22 -9
- package/dist/cli/commands/update.js.map +1 -1
- package/dist/cli/index.js +20 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/generators/test-generator/adapters/adapter-interface.d.ts +1 -0
- package/dist/generators/test-generator/adapters/adapter-interface.d.ts.map +1 -1
- package/dist/generators/test-generator/adapters/adapter-registry.d.ts +13 -0
- package/dist/generators/test-generator/adapters/adapter-registry.d.ts.map +1 -1
- package/dist/generators/test-generator/adapters/adapter-registry.js +73 -1
- package/dist/generators/test-generator/adapters/adapter-registry.js.map +1 -1
- package/dist/generators/test-generator/adapters/index.d.ts +1 -1
- package/dist/generators/test-generator/adapters/index.d.ts.map +1 -1
- package/dist/generators/test-generator/adapters/index.js +5 -1
- package/dist/generators/test-generator/adapters/index.js.map +1 -1
- package/dist/generators/test-generator/adapters/playwright/templates/steps/actions/capture-variable.hbs +1 -0
- package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/all-contain-assertion.hbs +7 -0
- package/dist/generators/test-generator/adapters/playwright/templates/test-file.hbs +6 -0
- package/dist/generators/test-generator/code-generator.d.ts.map +1 -1
- package/dist/generators/test-generator/code-generator.js +6 -2
- package/dist/generators/test-generator/code-generator.js.map +1 -1
- package/dist/generators/test-generator/patterns/capture-patterns.d.ts +16 -0
- package/dist/generators/test-generator/patterns/capture-patterns.d.ts.map +1 -0
- package/dist/generators/test-generator/patterns/capture-patterns.js +54 -0
- package/dist/generators/test-generator/patterns/capture-patterns.js.map +1 -0
- package/dist/generators/test-generator/patterns/form-patterns.d.ts.map +1 -1
- package/dist/generators/test-generator/patterns/form-patterns.js +3 -1
- package/dist/generators/test-generator/patterns/form-patterns.js.map +1 -1
- package/dist/generators/test-generator/patterns/index.d.ts.map +1 -1
- package/dist/generators/test-generator/patterns/index.js +2 -0
- package/dist/generators/test-generator/patterns/index.js.map +1 -1
- package/dist/generators/test-generator/step-mapper.d.ts.map +1 -1
- package/dist/generators/test-generator/step-mapper.js +1 -0
- package/dist/generators/test-generator/step-mapper.js.map +1 -1
- package/dist/generators/test-generator/utils/data-resolver.d.ts +5 -0
- package/dist/generators/test-generator/utils/data-resolver.d.ts.map +1 -1
- package/dist/generators/test-generator/utils/data-resolver.js +17 -0
- package/dist/generators/test-generator/utils/data-resolver.js.map +1 -1
- package/dist/generators/test-generator/utils/runtime-data-transformer.d.ts.map +1 -1
- package/dist/generators/test-generator/utils/runtime-data-transformer.js +4 -0
- package/dist/generators/test-generator/utils/runtime-data-transformer.js.map +1 -1
- package/dist/generators/test-generator/utils/selector-resolver.d.ts.map +1 -1
- package/dist/generators/test-generator/utils/selector-resolver.js +12 -6
- package/dist/generators/test-generator/utils/selector-resolver.js.map +1 -1
- package/dist/harness/audit.d.ts +24 -0
- package/dist/harness/audit.d.ts.map +1 -0
- package/dist/harness/audit.js +115 -0
- package/dist/harness/audit.js.map +1 -0
- package/dist/harness/blindspot.d.ts +15 -0
- package/dist/harness/blindspot.d.ts.map +1 -0
- package/dist/harness/blindspot.js +85 -0
- package/dist/harness/blindspot.js.map +1 -0
- package/dist/harness/capability-plan.d.ts +49 -0
- package/dist/harness/capability-plan.d.ts.map +1 -0
- package/dist/harness/capability-plan.js +215 -0
- package/dist/harness/capability-plan.js.map +1 -0
- package/dist/harness/capability.d.ts +23 -0
- package/dist/harness/capability.d.ts.map +1 -0
- package/dist/harness/capability.js +98 -0
- package/dist/harness/capability.js.map +1 -0
- package/dist/harness/catalog/drivers.yaml +57 -0
- package/dist/harness/catalog/universal-viewpoints.yaml +114 -0
- package/dist/harness/challenge.d.ts +21 -0
- package/dist/harness/challenge.d.ts.map +1 -0
- package/dist/harness/challenge.js +151 -0
- package/dist/harness/challenge.js.map +1 -0
- package/dist/harness/feedback.d.ts +29 -0
- package/dist/harness/feedback.d.ts.map +1 -0
- package/dist/harness/feedback.js +106 -0
- package/dist/harness/feedback.js.map +1 -0
- package/dist/harness/flow-check.d.ts +23 -0
- package/dist/harness/flow-check.d.ts.map +1 -0
- package/dist/harness/flow-check.js +132 -0
- package/dist/harness/flow-check.js.map +1 -0
- package/dist/harness/flow-plan.d.ts +23 -0
- package/dist/harness/flow-plan.d.ts.map +1 -0
- package/dist/harness/flow-plan.js +166 -0
- package/dist/harness/flow-plan.js.map +1 -0
- package/dist/harness/intent.d.ts +11 -0
- package/dist/harness/intent.d.ts.map +1 -0
- package/dist/harness/intent.js +86 -0
- package/dist/harness/intent.js.map +1 -0
- package/dist/harness/ledger.d.ts +42 -0
- package/dist/harness/ledger.d.ts.map +1 -0
- package/dist/harness/ledger.js +171 -0
- package/dist/harness/ledger.js.map +1 -0
- package/dist/harness/manifest.d.ts +42 -0
- package/dist/harness/manifest.d.ts.map +1 -0
- package/dist/harness/manifest.js +209 -0
- package/dist/harness/manifest.js.map +1 -0
- package/dist/harness/parse.d.ts +22 -0
- package/dist/harness/parse.d.ts.map +1 -0
- package/dist/harness/parse.js +163 -0
- package/dist/harness/parse.js.map +1 -0
- package/dist/harness/script-check.d.ts +39 -0
- package/dist/harness/script-check.d.ts.map +1 -0
- package/dist/harness/script-check.js +251 -0
- package/dist/harness/script-check.js.map +1 -0
- package/dist/harness/secret-scan.d.ts +8 -0
- package/dist/harness/secret-scan.d.ts.map +1 -0
- package/dist/harness/secret-scan.js +88 -0
- package/dist/harness/secret-scan.js.map +1 -0
- package/dist/harness/sensors.d.ts +88 -0
- package/dist/harness/sensors.d.ts.map +1 -0
- package/dist/harness/sensors.js +232 -0
- package/dist/harness/sensors.js.map +1 -0
- package/dist/harness/trace.d.ts +31 -0
- package/dist/harness/trace.d.ts.map +1 -0
- package/dist/harness/trace.js +173 -0
- package/dist/harness/trace.js.map +1 -0
- package/dist/orchestrator/ai-rules-updater.d.ts +1 -0
- package/dist/orchestrator/ai-rules-updater.d.ts.map +1 -1
- package/dist/orchestrator/ai-rules-updater.js +55 -11
- package/dist/orchestrator/ai-rules-updater.js.map +1 -1
- package/dist/orchestrator/figma/spec-figma-renderer.d.ts +2 -2
- package/dist/orchestrator/figma/spec-figma-renderer.js +2 -2
- package/dist/orchestrator/figma/spec-figma-section-renderers.d.ts +1 -1
- package/dist/orchestrator/figma/spec-figma-section-renderers.js +1 -1
- package/dist/orchestrator/project-initializer.d.ts +5 -0
- package/dist/orchestrator/project-initializer.d.ts.map +1 -1
- package/dist/orchestrator/project-initializer.js +30 -6
- package/dist/orchestrator/project-initializer.js.map +1 -1
- package/dist/orchestrator/templates/ai-instructions/claude-agent-challenge.md +46 -0
- package/dist/orchestrator/templates/ai-instructions/claude-agent-discovery.md +32 -0
- package/dist/orchestrator/templates/ai-instructions/claude-agent-reviewer.md +37 -0
- package/dist/orchestrator/templates/ai-instructions/claude-cmd-add-flow.md +3 -3
- package/dist/orchestrator/templates/ai-instructions/claude-cmd-add-screen.md +5 -5
- package/dist/orchestrator/templates/ai-instructions/claude-cmd-create-test.md +36 -12
- package/dist/orchestrator/templates/ai-instructions/claude-cmd-design.md +12 -0
- package/dist/orchestrator/templates/ai-instructions/claude-cmd-feedback.md +36 -0
- package/dist/orchestrator/templates/ai-instructions/claude-cmd-review.md +27 -30
- package/dist/orchestrator/templates/ai-instructions/claude-cmd-run-test.md +4 -1
- package/dist/orchestrator/templates/ai-instructions/claude-config.md +1 -4
- package/dist/orchestrator/templates/ai-instructions/claude-skill-capture-mode-figma-mcp.md +82 -0
- package/dist/orchestrator/templates/ai-instructions/{github-skill-sungen-figma-source.md → claude-skill-capture-mode-figma-pat.md} +14 -48
- package/dist/orchestrator/templates/ai-instructions/claude-skill-capture-mode-live.md +60 -0
- package/dist/orchestrator/templates/ai-instructions/claude-skill-capture-mode-local.md +38 -0
- package/dist/orchestrator/templates/ai-instructions/claude-skill-capture.md +35 -0
- package/dist/orchestrator/templates/ai-instructions/claude-skill-harness-audit.md +84 -0
- package/dist/orchestrator/templates/ai-instructions/claude-skill-tc-generation.md +40 -1
- package/dist/orchestrator/templates/ai-instructions/copilot-cmd-add-flow.md +3 -3
- package/dist/orchestrator/templates/ai-instructions/copilot-cmd-add-screen.md +4 -4
- package/dist/orchestrator/templates/ai-instructions/copilot-cmd-create-test.md +18 -10
- package/dist/orchestrator/templates/ai-instructions/copilot-cmd-design.md +13 -0
- package/dist/orchestrator/templates/ai-instructions/copilot-cmd-feedback.md +24 -0
- package/dist/orchestrator/templates/ai-instructions/copilot-cmd-review.md +20 -30
- package/dist/orchestrator/templates/ai-instructions/copilot-cmd-run-test.md +2 -1
- package/dist/orchestrator/templates/ai-instructions/copilot-config.md +1 -4
- package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-capture-mode-figma-mcp.md +82 -0
- package/{src/orchestrator/templates/ai-instructions/claude-skill-figma-source.md → dist/orchestrator/templates/ai-instructions/github-skill-sungen-capture-mode-figma-pat.md} +14 -48
- package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-capture-mode-live.md +60 -0
- package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-capture-mode-local.md +38 -0
- package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-capture.md +35 -0
- package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-harness-audit.md +84 -0
- package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-selector-fix.md +1 -1
- package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-tc-generation.md +40 -1
- package/dist/orchestrator/templates/specs-test-data.ts +20 -6
- package/dist/tools/figma/figma-auth.d.ts +5 -2
- package/dist/tools/figma/figma-auth.d.ts.map +1 -1
- package/dist/tools/figma/figma-auth.js +19 -9
- package/dist/tools/figma/figma-auth.js.map +1 -1
- package/docs/orchestration-spec.md +267 -0
- package/package.json +12 -7
- package/src/cli/commands/add.ts +3 -3
- package/src/cli/commands/audit.ts +92 -0
- package/src/cli/commands/blindspot.ts +48 -0
- package/src/cli/commands/capability.ts +160 -0
- package/src/cli/commands/challenge.ts +55 -0
- package/src/cli/commands/feedback.ts +65 -0
- package/src/cli/commands/flow-check.ts +97 -0
- package/src/cli/commands/generate.ts +47 -2
- package/src/cli/commands/ledger.ts +61 -0
- package/src/cli/commands/manifest.ts +55 -0
- package/src/cli/commands/script-check.ts +50 -0
- package/src/cli/commands/trace.ts +60 -0
- package/src/cli/commands/update.ts +30 -10
- package/src/cli/index.ts +20 -0
- package/src/generators/test-generator/adapters/adapter-interface.ts +1 -0
- package/src/generators/test-generator/adapters/adapter-registry.ts +37 -0
- package/src/generators/test-generator/adapters/index.ts +4 -1
- package/src/generators/test-generator/adapters/playwright/templates/steps/actions/capture-variable.hbs +1 -0
- package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/all-contain-assertion.hbs +7 -0
- package/src/generators/test-generator/adapters/playwright/templates/test-file.hbs +6 -0
- package/src/generators/test-generator/code-generator.ts +6 -2
- package/src/generators/test-generator/patterns/capture-patterns.ts +59 -0
- package/src/generators/test-generator/patterns/form-patterns.ts +3 -1
- package/src/generators/test-generator/patterns/index.ts +2 -0
- package/src/generators/test-generator/step-mapper.ts +1 -0
- package/src/generators/test-generator/utils/data-resolver.ts +20 -0
- package/src/generators/test-generator/utils/runtime-data-transformer.ts +8 -0
- package/src/generators/test-generator/utils/selector-resolver.ts +13 -6
- package/src/harness/audit.ts +112 -0
- package/src/harness/blindspot.ts +51 -0
- package/src/harness/capability-plan.ts +180 -0
- package/src/harness/capability.ts +75 -0
- package/src/harness/catalog/drivers.yaml +57 -0
- package/src/harness/catalog/universal-viewpoints.yaml +114 -0
- package/src/harness/challenge.ts +131 -0
- package/src/harness/feedback.ts +84 -0
- package/src/harness/flow-check.ts +99 -0
- package/src/harness/flow-plan.ts +135 -0
- package/src/harness/intent.ts +58 -0
- package/src/harness/ledger.ts +155 -0
- package/src/harness/manifest.ts +173 -0
- package/src/harness/parse.ts +145 -0
- package/src/harness/script-check.ts +222 -0
- package/src/harness/secret-scan.ts +51 -0
- package/src/harness/sensors.ts +279 -0
- package/src/harness/trace.ts +138 -0
- package/src/orchestrator/ai-rules-updater.ts +57 -10
- package/src/orchestrator/figma/spec-figma-renderer.ts +2 -2
- package/src/orchestrator/figma/spec-figma-section-renderers.ts +1 -1
- package/src/orchestrator/project-initializer.ts +33 -7
- package/src/orchestrator/templates/ai-instructions/claude-agent-challenge.md +46 -0
- package/src/orchestrator/templates/ai-instructions/claude-agent-discovery.md +32 -0
- package/src/orchestrator/templates/ai-instructions/claude-agent-reviewer.md +37 -0
- package/src/orchestrator/templates/ai-instructions/claude-cmd-add-flow.md +3 -3
- package/src/orchestrator/templates/ai-instructions/claude-cmd-add-screen.md +5 -5
- package/src/orchestrator/templates/ai-instructions/claude-cmd-create-test.md +36 -12
- package/src/orchestrator/templates/ai-instructions/claude-cmd-design.md +12 -0
- package/src/orchestrator/templates/ai-instructions/claude-cmd-feedback.md +36 -0
- package/src/orchestrator/templates/ai-instructions/claude-cmd-review.md +27 -30
- package/src/orchestrator/templates/ai-instructions/claude-cmd-run-test.md +4 -1
- package/src/orchestrator/templates/ai-instructions/claude-config.md +1 -4
- package/src/orchestrator/templates/ai-instructions/claude-skill-capture-mode-figma-mcp.md +82 -0
- package/{dist/orchestrator/templates/ai-instructions/copilot-skill-figma-source.md → src/orchestrator/templates/ai-instructions/claude-skill-capture-mode-figma-pat.md} +14 -48
- package/src/orchestrator/templates/ai-instructions/claude-skill-capture-mode-live.md +60 -0
- package/src/orchestrator/templates/ai-instructions/claude-skill-capture-mode-local.md +38 -0
- package/src/orchestrator/templates/ai-instructions/claude-skill-capture.md +35 -0
- package/src/orchestrator/templates/ai-instructions/claude-skill-harness-audit.md +84 -0
- package/src/orchestrator/templates/ai-instructions/claude-skill-tc-generation.md +40 -1
- package/src/orchestrator/templates/ai-instructions/copilot-cmd-add-flow.md +3 -3
- package/src/orchestrator/templates/ai-instructions/copilot-cmd-add-screen.md +4 -4
- package/src/orchestrator/templates/ai-instructions/copilot-cmd-create-test.md +18 -10
- package/src/orchestrator/templates/ai-instructions/copilot-cmd-design.md +13 -0
- package/src/orchestrator/templates/ai-instructions/copilot-cmd-feedback.md +24 -0
- package/src/orchestrator/templates/ai-instructions/copilot-cmd-review.md +20 -30
- package/src/orchestrator/templates/ai-instructions/copilot-cmd-run-test.md +2 -1
- package/src/orchestrator/templates/ai-instructions/copilot-config.md +1 -4
- package/src/orchestrator/templates/ai-instructions/github-skill-sungen-capture-mode-figma-mcp.md +82 -0
- package/{dist/orchestrator/templates/ai-instructions/claude-skill-figma-source.md → src/orchestrator/templates/ai-instructions/github-skill-sungen-capture-mode-figma-pat.md} +14 -48
- package/src/orchestrator/templates/ai-instructions/github-skill-sungen-capture-mode-live.md +60 -0
- package/src/orchestrator/templates/ai-instructions/github-skill-sungen-capture-mode-local.md +38 -0
- package/src/orchestrator/templates/ai-instructions/github-skill-sungen-capture.md +35 -0
- package/src/orchestrator/templates/ai-instructions/github-skill-sungen-harness-audit.md +84 -0
- package/src/orchestrator/templates/ai-instructions/github-skill-sungen-selector-fix.md +1 -1
- package/src/orchestrator/templates/ai-instructions/github-skill-sungen-tc-generation.md +40 -1
- package/src/orchestrator/templates/specs-test-data.ts +20 -6
- package/src/tools/figma/figma-auth.ts +20 -9
- package/dist/orchestrator/templates/ai-instructions/claude-skill-capture-figma.md +0 -142
- package/dist/orchestrator/templates/ai-instructions/claude-skill-capture-live.md +0 -112
- package/dist/orchestrator/templates/ai-instructions/claude-skill-capture-local.md +0 -73
- package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-capture-figma.md +0 -142
- package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-capture-live.md +0 -112
- package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-capture-local.md +0 -73
- package/src/orchestrator/templates/ai-instructions/claude-skill-capture-figma.md +0 -142
- package/src/orchestrator/templates/ai-instructions/claude-skill-capture-live.md +0 -112
- package/src/orchestrator/templates/ai-instructions/claude-skill-capture-local.md +0 -73
- package/src/orchestrator/templates/ai-instructions/copilot-skill-figma-source.md +0 -151
- package/src/orchestrator/templates/ai-instructions/github-skill-sungen-capture-figma.md +0 -142
- package/src/orchestrator/templates/ai-instructions/github-skill-sungen-capture-live.md +0 -112
- package/src/orchestrator/templates/ai-instructions/github-skill-sungen-capture-local.md +0 -73
- package/src/orchestrator/templates/ai-instructions/github-skill-sungen-figma-source.md +0 -151
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export interface CapabilityProfile {
|
|
2
|
+
platform?: string;
|
|
3
|
+
enabled: string[];
|
|
4
|
+
source: 'capabilities.yaml' | 'absent';
|
|
5
|
+
}
|
|
6
|
+
export interface DriverMeta {
|
|
7
|
+
id: string;
|
|
8
|
+
kind: 'platform' | 'capability';
|
|
9
|
+
package: string;
|
|
10
|
+
runtime?: string;
|
|
11
|
+
adapter?: string;
|
|
12
|
+
capabilities: string[];
|
|
13
|
+
unblocks?: string[];
|
|
14
|
+
}
|
|
15
|
+
export declare function capabilitiesPath(cwd: string): string;
|
|
16
|
+
export declare function readCapabilities(cwd: string): CapabilityProfile;
|
|
17
|
+
export declare function writeCapabilities(cwd: string, profile: {
|
|
18
|
+
platform?: string;
|
|
19
|
+
enabled: string[];
|
|
20
|
+
}): string;
|
|
21
|
+
export declare function loadDriverCatalog(): Record<string, DriverMeta>;
|
|
22
|
+
export declare function driverMeta(id: string): DriverMeta | undefined;
|
|
23
|
+
//# sourceMappingURL=capability.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capability.d.ts","sourceRoot":"","sources":["../../src/harness/capability.ts"],"names":[],"mappings":"AAcA,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,MAAM,EAAE,mBAAmB,GAAG,QAAQ,CAAC;CACxC;AAED,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,UAAU,GAAG,YAAY,CAAC;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;CACrB;AAED,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAEpD;AAED,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,iBAAiB,CAa/D;AAED,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,EAAE,CAAA;CAAE,GAAG,MAAM,CAUxG;AAGD,wBAAgB,iBAAiB,IAAI,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAQ9D;AAED,wBAAgB,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,CAE7D"}
|
|
@@ -0,0 +1,98 @@
|
|
|
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.capabilitiesPath = capabilitiesPath;
|
|
37
|
+
exports.readCapabilities = readCapabilities;
|
|
38
|
+
exports.writeCapabilities = writeCapabilities;
|
|
39
|
+
exports.loadDriverCatalog = loadDriverCatalog;
|
|
40
|
+
exports.driverMeta = driverMeta;
|
|
41
|
+
/**
|
|
42
|
+
* Capability profile + driver catalog (harness-roadmap Phase 2a).
|
|
43
|
+
*
|
|
44
|
+
* Sungen core is runtime-agnostic: a project declares its PLATFORM driver (web →
|
|
45
|
+
* Playwright, mobile → Appium) + any capability drivers in qa/capabilities.yaml.
|
|
46
|
+
* There is no default runtime — but for back-compat, an ABSENT profile is treated
|
|
47
|
+
* as `web` (the bundled adapter) with a one-time notice + scaffold.
|
|
48
|
+
*
|
|
49
|
+
* This module is metadata + profile I/O only. It never installs or imports a driver.
|
|
50
|
+
*/
|
|
51
|
+
const fs = __importStar(require("fs"));
|
|
52
|
+
const path = __importStar(require("path"));
|
|
53
|
+
const yaml_1 = require("yaml");
|
|
54
|
+
function capabilitiesPath(cwd) {
|
|
55
|
+
return path.join(cwd, 'qa', 'capabilities.yaml');
|
|
56
|
+
}
|
|
57
|
+
function readCapabilities(cwd) {
|
|
58
|
+
const p = capabilitiesPath(cwd);
|
|
59
|
+
if (!fs.existsSync(p))
|
|
60
|
+
return { platform: undefined, enabled: [], source: 'absent' };
|
|
61
|
+
try {
|
|
62
|
+
const y = (0, yaml_1.parse)(fs.readFileSync(p, 'utf-8')) || {};
|
|
63
|
+
return {
|
|
64
|
+
platform: typeof y.platform === 'string' ? y.platform : undefined,
|
|
65
|
+
enabled: Array.isArray(y.enabled) ? y.enabled.map(String) : [],
|
|
66
|
+
source: 'capabilities.yaml',
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
catch {
|
|
70
|
+
return { platform: undefined, enabled: [], source: 'absent' };
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
function writeCapabilities(cwd, profile) {
|
|
74
|
+
const p = capabilitiesPath(cwd);
|
|
75
|
+
fs.mkdirSync(path.dirname(p), { recursive: true });
|
|
76
|
+
const body = '# Sungen capability profile — which runtime/drivers this project uses.\n' +
|
|
77
|
+
'# platform: the runtime adapter (web → Playwright, mobile → Appium). No default.\n' +
|
|
78
|
+
'# enabled: drivers turned on (added via `sungen capability add <driver>`).\n\n' +
|
|
79
|
+
(0, yaml_1.stringify)({ platform: profile.platform, enabled: profile.enabled });
|
|
80
|
+
fs.writeFileSync(p, body, 'utf-8');
|
|
81
|
+
return p;
|
|
82
|
+
}
|
|
83
|
+
let _catalog = null;
|
|
84
|
+
function loadDriverCatalog() {
|
|
85
|
+
if (_catalog)
|
|
86
|
+
return _catalog;
|
|
87
|
+
const p = path.join(__dirname, 'catalog', 'drivers.yaml');
|
|
88
|
+
const y = (0, yaml_1.parse)(fs.readFileSync(p, 'utf-8'));
|
|
89
|
+
const out = {};
|
|
90
|
+
for (const [id, meta] of Object.entries(y.drivers))
|
|
91
|
+
out[id] = { id, ...meta };
|
|
92
|
+
_catalog = out;
|
|
93
|
+
return out;
|
|
94
|
+
}
|
|
95
|
+
function driverMeta(id) {
|
|
96
|
+
return loadDriverCatalog()[id];
|
|
97
|
+
}
|
|
98
|
+
//# sourceMappingURL=capability.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capability.js","sourceRoot":"","sources":["../../src/harness/capability.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8BA,4CAEC;AAED,4CAaC;AAED,8CAUC;AAGD,8CAQC;AAED,gCAEC;AA1ED;;;;;;;;;GASG;AACH,uCAAyB;AACzB,2CAA6B;AAC7B,+BAAsE;AAkBtE,SAAgB,gBAAgB,CAAC,GAAW;IAC1C,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,EAAE,mBAAmB,CAAC,CAAC;AACnD,CAAC;AAED,SAAgB,gBAAgB,CAAC,GAAW;IAC1C,MAAM,CAAC,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC;IAChC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC;QAAE,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;IACrF,IAAI,CAAC;QACH,MAAM,CAAC,GAAG,IAAA,YAAS,EAAC,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC;QACvD,OAAO;YACL,QAAQ,EAAE,OAAO,CAAC,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS;YACjE,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE;YAC9D,MAAM,EAAE,mBAAmB;SAC5B,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;IAChE,CAAC;AACH,CAAC;AAED,SAAgB,iBAAiB,CAAC,GAAW,EAAE,OAAiD;IAC9F,MAAM,CAAC,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC;IAChC,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACnD,MAAM,IAAI,GACR,0EAA0E;QAC1E,oFAAoF;QACpF,gFAAgF;QAChF,IAAA,gBAAa,EAAC,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;IAC1E,EAAE,CAAC,aAAa,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;IACnC,OAAO,CAAC,CAAC;AACX,CAAC;AAED,IAAI,QAAQ,GAAsC,IAAI,CAAC;AACvD,SAAgB,iBAAiB;IAC/B,IAAI,QAAQ;QAAE,OAAO,QAAQ,CAAC;IAC9B,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,SAAS,EAAE,cAAc,CAAC,CAAC;IAC1D,MAAM,CAAC,GAAG,IAAA,YAAS,EAAC,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,OAAO,CAAC,CAAwD,CAAC;IACxG,MAAM,GAAG,GAA+B,EAAE,CAAC;IAC3C,KAAK,MAAM,CAAC,EAAE,EAAE,IAAI,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC;QAAE,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,EAAE,GAAG,IAAI,EAAE,CAAC;IAC9E,QAAQ,GAAG,GAAG,CAAC;IACf,OAAO,GAAG,CAAC;AACb,CAAC;AAED,SAAgB,UAAU,CAAC,EAAU;IACnC,OAAO,iBAAiB,EAAE,CAAC,EAAE,CAAC,CAAC;AACjC,CAAC"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# Driver Catalog (metadata only — NO driver code is bundled here).
|
|
2
|
+
# Lets Sungen RECOMMEND/RESOLVE a driver that may not be installed yet, and tells
|
|
3
|
+
# `sungen capability add` which package to install. See reports/sungen_phase2a_spec.md.
|
|
4
|
+
#
|
|
5
|
+
# kind: platform → the runtime/codegen adapter for a target (pick ONE per project)
|
|
6
|
+
# kind: capability → an extra ability added on top of a platform (Phase 3)
|
|
7
|
+
# unblocks: manual-reason codes (M1–M9) this driver can resolve (Phase 2b taxonomy)
|
|
8
|
+
|
|
9
|
+
drivers:
|
|
10
|
+
web:
|
|
11
|
+
kind: platform
|
|
12
|
+
package: "@sungen/driver-web" # Phase 2a: bundled Playwright adapter serves this (back-compat)
|
|
13
|
+
runtime: playwright
|
|
14
|
+
adapter: web # registry adapter name
|
|
15
|
+
capabilities: ["@ui"]
|
|
16
|
+
mobile:
|
|
17
|
+
kind: platform
|
|
18
|
+
package: "@sungen/driver-mobile"
|
|
19
|
+
runtime: appium
|
|
20
|
+
adapter: mobile
|
|
21
|
+
capabilities: ["@ui"]
|
|
22
|
+
|
|
23
|
+
api:
|
|
24
|
+
kind: capability
|
|
25
|
+
package: "@sungen/driver-api"
|
|
26
|
+
capabilities: ["@api", "@apiAssert", "@hybrid"]
|
|
27
|
+
unblocks: [M2]
|
|
28
|
+
data-factory:
|
|
29
|
+
kind: capability
|
|
30
|
+
package: "@sungen/driver-data-factory"
|
|
31
|
+
capabilities: ["@dataFactory"]
|
|
32
|
+
unblocks: [M1]
|
|
33
|
+
db:
|
|
34
|
+
kind: capability
|
|
35
|
+
package: "@sungen/driver-db"
|
|
36
|
+
capabilities: ["@dbAssert"]
|
|
37
|
+
unblocks: [M2]
|
|
38
|
+
mock:
|
|
39
|
+
kind: capability
|
|
40
|
+
package: "@sungen/driver-mock"
|
|
41
|
+
capabilities: ["@mock", "@network"]
|
|
42
|
+
unblocks: [M3]
|
|
43
|
+
mail-file:
|
|
44
|
+
kind: capability
|
|
45
|
+
package: "@sungen/driver-mail-file"
|
|
46
|
+
capabilities: ["@mail", "@file"]
|
|
47
|
+
unblocks: [M5]
|
|
48
|
+
contract:
|
|
49
|
+
kind: capability
|
|
50
|
+
package: "@sungen/driver-contract"
|
|
51
|
+
capabilities: ["@contract"]
|
|
52
|
+
unblocks: [M5]
|
|
53
|
+
specialized:
|
|
54
|
+
kind: capability
|
|
55
|
+
package: "@sungen/driver-specialized"
|
|
56
|
+
capabilities: ["@specialized"]
|
|
57
|
+
unblocks: [M6]
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
# Seed Universal Viewpoint Catalog (bundled, local — NOT a server).
|
|
2
|
+
# Role: REFERENCE for the Harness Coverage Gate (the "answer key" sensors check
|
|
3
|
+
# against). The AI still GENERATES the viewpoint-overview; this catalog only
|
|
4
|
+
# verifies that critical themes for a page-type were not missed.
|
|
5
|
+
#
|
|
6
|
+
# Each page-type lists must-cover themes. A theme is "covered" when the project's
|
|
7
|
+
# viewpoint-overview (or generated scenarios) contains one of its keywords.
|
|
8
|
+
# See docs/orchestration-spec.md §5.2 and reports/sungen_refactor_spec.md §9.
|
|
9
|
+
#
|
|
10
|
+
# `depth:` (optional, harness-roadmap P1) marks a theme as DATA-correctness:
|
|
11
|
+
# requires: data-assertion → scenarios on this theme must assert DATA (not just
|
|
12
|
+
# visibility) to count as "deep". Drives the depth gate.
|
|
13
|
+
# cross_screen: true → genuine depth needs another screen → use a flow
|
|
14
|
+
# (P5 `remember` / `see all … contain`); on one screen
|
|
15
|
+
# it should be @manual + deferred-to-flow, not shallow.
|
|
16
|
+
# keywords: → PRECISE data-noun keywords for depth matching (kept
|
|
17
|
+
# separate from coverage keywords to avoid matching
|
|
18
|
+
# navigation scenarios like "API list page").
|
|
19
|
+
# template: → the deep step the generator should emit by default.
|
|
20
|
+
# Themes with no `depth:` are visibility/navigation — landing/seeing IS the assertion.
|
|
21
|
+
|
|
22
|
+
page_types:
|
|
23
|
+
ecommerce-list:
|
|
24
|
+
detect_keywords: [cart, product, checkout, catalog, brand, category, "add to cart"]
|
|
25
|
+
must_cover:
|
|
26
|
+
- theme: list-data
|
|
27
|
+
keywords: [list, displayed, card, "product card", grid]
|
|
28
|
+
depth:
|
|
29
|
+
requires: data-assertion
|
|
30
|
+
cross_screen: false
|
|
31
|
+
keywords: ["product price", "product card", "every card", "all product", "product name", "displays a price", "card displays"]
|
|
32
|
+
template: "User see all [Product Price] contain {{currency}} (and name/image per card)"
|
|
33
|
+
- theme: product-detail-consistency
|
|
34
|
+
keywords: [consistent, consistency, match, "same product", "correct product"]
|
|
35
|
+
depth:
|
|
36
|
+
requires: data-assertion
|
|
37
|
+
cross_screen: true
|
|
38
|
+
keywords: ["product detail", "detail page", "same product name", "matching name", "consistency", "same price"]
|
|
39
|
+
template: "User remember [Product Name] text as {{v}} … User see [Detail Product Name] header with {{v}}"
|
|
40
|
+
- theme: cart-correctness
|
|
41
|
+
keywords: ["cart contains", quantity, "price", subtotal, "in cart", "cart content", "cart product"]
|
|
42
|
+
depth:
|
|
43
|
+
requires: data-assertion
|
|
44
|
+
cross_screen: true
|
|
45
|
+
keywords: ["cart product", "cart contains", "in cart", "cart item", "appears in the cart", "cart line", "subtotal", "quantity"]
|
|
46
|
+
template: "User remember [Product Name] text as {{v}} … User see all [Cart Product Name] contain {{v}}"
|
|
47
|
+
- theme: category-filter-correctness
|
|
48
|
+
keywords: ["belong to the selected category", "category result", "matching the selected category", "products belong to", "only products that belong to the selected category"]
|
|
49
|
+
depth:
|
|
50
|
+
requires: data-assertion
|
|
51
|
+
cross_screen: true
|
|
52
|
+
keywords: ["belong to the selected category", "category result", "products that belong", "matching the selected category"]
|
|
53
|
+
template: "User see all [Result Product Name] contain {{selected_category}}"
|
|
54
|
+
- theme: brand-filter-correctness
|
|
55
|
+
keywords: ["belong to the selected brand", "brand result", "only products ... brand", "products that belong to the selected brand", "all displayed products belong to"]
|
|
56
|
+
depth:
|
|
57
|
+
requires: data-assertion
|
|
58
|
+
cross_screen: true
|
|
59
|
+
keywords: ["belong to the selected brand", "brand result", "products that belong to the selected brand"]
|
|
60
|
+
template: "User see all [Result Product Name] contain {{selected_brand}}"
|
|
61
|
+
- theme: add-to-cart
|
|
62
|
+
keywords: ["add to cart", added, "added to cart"]
|
|
63
|
+
depth:
|
|
64
|
+
requires: data-assertion
|
|
65
|
+
cross_screen: false
|
|
66
|
+
keywords: ["add to cart", "added to cart", "added confirmation", "added message"]
|
|
67
|
+
template: "User see [Added Message] text contains {{added_message}} (not just the modal)"
|
|
68
|
+
|
|
69
|
+
form:
|
|
70
|
+
detect_keywords: [form, submit, field, input, validation]
|
|
71
|
+
must_cover:
|
|
72
|
+
- theme: required-validation
|
|
73
|
+
keywords: [required, empty, "must be", validation]
|
|
74
|
+
depth:
|
|
75
|
+
requires: data-assertion
|
|
76
|
+
cross_screen: false
|
|
77
|
+
keywords: ["required", "must be", "error message", "validation message"]
|
|
78
|
+
template: "User see [Field Error] message with {{error_text}}"
|
|
79
|
+
- theme: format-boundary
|
|
80
|
+
keywords: [format, invalid, boundary, length, range]
|
|
81
|
+
depth:
|
|
82
|
+
requires: data-assertion
|
|
83
|
+
cross_screen: false
|
|
84
|
+
keywords: ["invalid format", "boundary", "max length", "min length", "out of range"]
|
|
85
|
+
template: "User see [Field Error] message with {{error_text}}"
|
|
86
|
+
- theme: submit-success
|
|
87
|
+
keywords: [submit, success, saved, created]
|
|
88
|
+
depth:
|
|
89
|
+
requires: data-assertion
|
|
90
|
+
cross_screen: false
|
|
91
|
+
keywords: ["success message", "saved", "created", "confirmation"]
|
|
92
|
+
template: "User see [Success] message with {{success_text}}"
|
|
93
|
+
|
|
94
|
+
auth:
|
|
95
|
+
detect_keywords: [login, logout, password, signin, "sign in", credential]
|
|
96
|
+
must_cover:
|
|
97
|
+
- theme: valid-login
|
|
98
|
+
keywords: ["valid", login, success]
|
|
99
|
+
- theme: invalid-credential
|
|
100
|
+
keywords: ["invalid", "wrong password", error, incorrect]
|
|
101
|
+
depth:
|
|
102
|
+
requires: data-assertion
|
|
103
|
+
cross_screen: false
|
|
104
|
+
keywords: ["wrong password", "incorrect", "invalid credential", "error message"]
|
|
105
|
+
template: "User see [Login Error] message with {{error_text}}"
|
|
106
|
+
- theme: access-control
|
|
107
|
+
keywords: ["unauthorized", "redirect", "not logged in", permission]
|
|
108
|
+
|
|
109
|
+
# Universal themes worth checking on ANY page-type (low-weight reminders).
|
|
110
|
+
universal:
|
|
111
|
+
- theme: error-empty-state
|
|
112
|
+
keywords: ["empty", "no data", "no result", "failed", "error state"]
|
|
113
|
+
- theme: accessibility
|
|
114
|
+
keywords: ["keyboard", "tab order", "accessible", "aria", "focus"]
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export interface ChallengeFinding {
|
|
2
|
+
scenario?: string;
|
|
3
|
+
issue: string;
|
|
4
|
+
suggestion: string;
|
|
5
|
+
}
|
|
6
|
+
export interface ChallengeReport {
|
|
7
|
+
screen: string;
|
|
8
|
+
overCovered: {
|
|
9
|
+
bucket: string;
|
|
10
|
+
count: number;
|
|
11
|
+
note: string;
|
|
12
|
+
}[];
|
|
13
|
+
shallowThemes: string[];
|
|
14
|
+
collectionClaimSingular: ChallengeFinding[];
|
|
15
|
+
noveltyPrompts: string[];
|
|
16
|
+
explorationReadiness: string[];
|
|
17
|
+
}
|
|
18
|
+
export declare function buildChallenge(screenDir: string, screenName: string): ChallengeReport;
|
|
19
|
+
/** Render the Challenge Report as Markdown (advisory — not part of the official suite). */
|
|
20
|
+
export declare function renderChallengeMarkdown(r: ChallengeReport): string;
|
|
21
|
+
//# sourceMappingURL=challenge.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"challenge.d.ts","sourceRoot":"","sources":["../../src/harness/challenge.ts"],"names":[],"mappings":"AAuBA,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IAEf,WAAW,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC/D,aAAa,EAAE,MAAM,EAAE,CAAC;IAExB,uBAAuB,EAAE,gBAAgB,EAAE,CAAC;IAE5C,cAAc,EAAE,MAAM,EAAE,CAAC;IAEzB,oBAAoB,EAAE,MAAM,EAAE,CAAC;CAChC;AAkBD,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,eAAe,CA2CrF;AAED,2FAA2F;AAC3F,wBAAgB,uBAAuB,CAAC,CAAC,EAAE,eAAe,GAAG,MAAM,CA0BlE"}
|
|
@@ -0,0 +1,151 @@
|
|
|
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.buildChallenge = buildChallenge;
|
|
37
|
+
exports.renderChallengeMarkdown = renderChallengeMarkdown;
|
|
38
|
+
/**
|
|
39
|
+
* Challenge / Exploration Harness (harness-roadmap P4) — Loop 2.
|
|
40
|
+
*
|
|
41
|
+
* Production mode (Loop 1: create-test → audit gate → repair) is deterministic by
|
|
42
|
+
* design: same spec + viewpoint → same official suite. That is the *feature* for
|
|
43
|
+
* delivery/CI, but it can feel like "a machine that always outputs the same thing".
|
|
44
|
+
*
|
|
45
|
+
* The Challenge Harness is the antidote: it does NOT regenerate the suite — it
|
|
46
|
+
* ATTACKS the existing one to surface what production missed. It is advisory
|
|
47
|
+
* (never auto-merges) and read-only.
|
|
48
|
+
*
|
|
49
|
+
* This module is the DETERMINISTIC spine — three structural critics:
|
|
50
|
+
* 1. Coverage — over-covered (low-value) areas + shallow gate themes.
|
|
51
|
+
* 2. Depth — titles that claim a collection but assert a single element.
|
|
52
|
+
* 3. Novelty — risk-based prompts the AI `sungen-challenge` agent expands into
|
|
53
|
+
* concrete novelty candidates (semantic — not deterministic here).
|
|
54
|
+
*
|
|
55
|
+
* The AI agent layer adds the semantic + novelty judgement on top of this spine.
|
|
56
|
+
*/
|
|
57
|
+
const path = __importStar(require("path"));
|
|
58
|
+
const parse_1 = require("./parse");
|
|
59
|
+
const audit_1 = require("./audit");
|
|
60
|
+
// A collection claim = a PLURAL set noun (or an explicit quantifier) used with a
|
|
61
|
+
// DISPLAY verb. Plural-only avoids false-positives on single-item actions like
|
|
62
|
+
// "Adding A product ... shows the dialog" (which correctly asserts one item).
|
|
63
|
+
const PLURAL_NOUN = /\b(cards|items|products|rows|results|prices|entries|records)\b/i;
|
|
64
|
+
const QUANTIFIER = /\b(all|every|each)\b/i;
|
|
65
|
+
const DISPLAY_VERB = /\b(displays?|shows?|lists?|grid|contains?)\b/i;
|
|
66
|
+
/** Risk lenses the Novelty critic prompts the AI to explore (beyond the catalog). */
|
|
67
|
+
const NOVELTY_LENSES = [
|
|
68
|
+
'double-submit / rapid repeat of the primary action (duplicate side-effects?)',
|
|
69
|
+
'state after partial / slow load (assert against a not-yet-ready page)',
|
|
70
|
+
'boundary & unusual data (very long text, 0 / max quantity, special chars)',
|
|
71
|
+
'concurrency / back-button / refresh mid-flow',
|
|
72
|
+
'historical-incident mindset — what has broken on similar screens before?',
|
|
73
|
+
];
|
|
74
|
+
function buildChallenge(screenDir, screenName) {
|
|
75
|
+
const featurePath = path.join(screenDir, 'features', `${screenName}.feature`);
|
|
76
|
+
const scenarios = (0, parse_1.loadScenarios)(featurePath);
|
|
77
|
+
const audit = (0, audit_1.runAudit)(screenDir, screenName);
|
|
78
|
+
// 1. Coverage critic — over-covered buckets (secondary >> business-core) + shallow themes.
|
|
79
|
+
const buckets = audit.balance.byBucket;
|
|
80
|
+
const core = buckets['business-core'] || 0;
|
|
81
|
+
const overCovered = [];
|
|
82
|
+
for (const [bucket, count] of Object.entries(buckets)) {
|
|
83
|
+
if (['business-core', 'other'].includes(bucket))
|
|
84
|
+
continue;
|
|
85
|
+
if (core > 0 && count > core * 1.5) {
|
|
86
|
+
overCovered.push({ bucket, count, note: `${count} scenarios vs ${core} business-core — likely low-value expansion; trim toward correctness.` });
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
const shallowThemes = audit.gate.gaps.filter((g) => g.status === 'shallow').map((g) => g.theme);
|
|
90
|
+
// 2. Depth critic — title claims a collection but the assertion is singular (no "see all").
|
|
91
|
+
const collectionClaimSingular = [];
|
|
92
|
+
for (const s of scenarios) {
|
|
93
|
+
if (s.manual || s.category === 'NAV')
|
|
94
|
+
continue;
|
|
95
|
+
const claimsCollection = (PLURAL_NOUN.test(s.name) || QUANTIFIER.test(s.name)) && DISPLAY_VERB.test(s.name);
|
|
96
|
+
const assertsAll = /\bsee all\b/.test(s.haystack);
|
|
97
|
+
if (claimsCollection && !assertsAll) {
|
|
98
|
+
collectionClaimSingular.push({
|
|
99
|
+
scenario: s.name,
|
|
100
|
+
issue: 'Title implies a set (cards/items/all) but the assertion targets a single element.',
|
|
101
|
+
suggestion: 'Prove EVERY member: `Then User see all [<Card/Row>] contain {{...}}` instead of a single `see [X]`.',
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
// 3. Novelty critic — deterministic prompts; the AI agent expands these into candidates.
|
|
106
|
+
const noveltyPrompts = NOVELTY_LENSES.map((l) => `Find 1 non-obvious, valuable scenario via: ${l}`);
|
|
107
|
+
// Roll-up — exploration readiness signals (not a fake score).
|
|
108
|
+
const explorationReadiness = [];
|
|
109
|
+
if (collectionClaimSingular.length)
|
|
110
|
+
explorationReadiness.push(`${collectionClaimSingular.length} title↔assertion gap(s) — deterministic depth critic flagged these; an AI Business-Depth critic should confirm + fix.`);
|
|
111
|
+
if (overCovered.length)
|
|
112
|
+
explorationReadiness.push(`${overCovered.length} possibly over-covered area(s) — rebalance toward correctness.`);
|
|
113
|
+
if (shallowThemes.length)
|
|
114
|
+
explorationReadiness.push(`Shallow themes: ${shallowThemes.join(', ')}.`);
|
|
115
|
+
explorationReadiness.push('Novelty candidates are NOT generated deterministically — run the `sungen-challenge` agent (Claude) or its inline criteria (Copilot) to propose them, then QA accept/reject (≤20% of official, no auto-merge).');
|
|
116
|
+
return { screen: screenName, overCovered, shallowThemes, collectionClaimSingular, noveltyPrompts, explorationReadiness };
|
|
117
|
+
}
|
|
118
|
+
/** Render the Challenge Report as Markdown (advisory — not part of the official suite). */
|
|
119
|
+
function renderChallengeMarkdown(r) {
|
|
120
|
+
const lines = [];
|
|
121
|
+
lines.push(`# Challenge Report — ${r.screen}`, '');
|
|
122
|
+
lines.push('> Advisory (Loop 2 / exploration mode). Does NOT change the official suite — it attacks it to surface blind spots. QA decides what to adopt.', '');
|
|
123
|
+
lines.push('## Depth — title claims a collection but asserts a single element');
|
|
124
|
+
if (r.collectionClaimSingular.length) {
|
|
125
|
+
lines.push('| Scenario | Issue | Suggested |', '|---|---|---|');
|
|
126
|
+
for (const f of r.collectionClaimSingular)
|
|
127
|
+
lines.push(`| ${f.scenario} | ${f.issue} | ${f.suggestion} |`);
|
|
128
|
+
}
|
|
129
|
+
else
|
|
130
|
+
lines.push('_none_');
|
|
131
|
+
lines.push('');
|
|
132
|
+
lines.push('## Coverage — possibly over-covered / shallow');
|
|
133
|
+
if (r.overCovered.length)
|
|
134
|
+
for (const o of r.overCovered)
|
|
135
|
+
lines.push(`- **${o.bucket}** — ${o.note}`);
|
|
136
|
+
if (r.shallowThemes.length)
|
|
137
|
+
lines.push(`- Shallow themes: ${r.shallowThemes.join(', ')}`);
|
|
138
|
+
if (!r.overCovered.length && !r.shallowThemes.length)
|
|
139
|
+
lines.push('_balanced_');
|
|
140
|
+
lines.push('');
|
|
141
|
+
lines.push('## Novelty — prompts for the AI critic (expand into candidates, ≤20% of official, no auto-merge)');
|
|
142
|
+
for (const p of r.noveltyPrompts)
|
|
143
|
+
lines.push(`- ${p}`);
|
|
144
|
+
lines.push('');
|
|
145
|
+
lines.push('## Exploration readiness');
|
|
146
|
+
for (const e of r.explorationReadiness)
|
|
147
|
+
lines.push(`- ${e}`);
|
|
148
|
+
lines.push('');
|
|
149
|
+
return lines.join('\n');
|
|
150
|
+
}
|
|
151
|
+
//# sourceMappingURL=challenge.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"challenge.js","sourceRoot":"","sources":["../../src/harness/challenge.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export type FeedbackType = 'test-design' | 'product' | 'other';
|
|
2
|
+
export type FeedbackDecision = 'accept' | 'reject' | 'edit' | 'add' | 'none';
|
|
3
|
+
export interface FeedbackEntry {
|
|
4
|
+
ts: string;
|
|
5
|
+
type: FeedbackType;
|
|
6
|
+
screen?: string;
|
|
7
|
+
target?: string;
|
|
8
|
+
decision?: FeedbackDecision;
|
|
9
|
+
message: string;
|
|
10
|
+
reason?: string;
|
|
11
|
+
source: string;
|
|
12
|
+
auditScore?: number;
|
|
13
|
+
}
|
|
14
|
+
export declare function recordFeedback(entry: Omit<FeedbackEntry, 'ts' | 'source' | 'auditScore'> & {
|
|
15
|
+
ts?: string;
|
|
16
|
+
source?: string;
|
|
17
|
+
}): string;
|
|
18
|
+
export declare function readFeedback(): FeedbackEntry[];
|
|
19
|
+
export interface FeedbackSummary {
|
|
20
|
+
total: number;
|
|
21
|
+
byType: Record<string, number>;
|
|
22
|
+
byDecision: Record<string, number>;
|
|
23
|
+
entries: FeedbackEntry[];
|
|
24
|
+
}
|
|
25
|
+
export declare function summarize(filter?: {
|
|
26
|
+
screen?: string;
|
|
27
|
+
type?: FeedbackType;
|
|
28
|
+
}): FeedbackSummary;
|
|
29
|
+
//# sourceMappingURL=feedback.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"feedback.d.ts","sourceRoot":"","sources":["../../src/harness/feedback.ts"],"names":[],"mappings":"AAeA,MAAM,MAAM,YAAY,GAAG,aAAa,GAAG,SAAS,GAAG,OAAO,CAAC;AAC/D,MAAM,MAAM,gBAAgB,GAAG,QAAQ,GAAG,QAAQ,GAAG,MAAM,GAAG,KAAK,GAAG,MAAM,CAAC;AAE7E,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,YAAY,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,gBAAgB,CAAC;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAaD,wBAAgB,cAAc,CAAC,KAAK,EAAE,IAAI,CAAC,aAAa,EAAE,IAAI,GAAG,QAAQ,GAAG,YAAY,CAAC,GAAG;IAAE,EAAE,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAgBpI;AAED,wBAAgB,YAAY,IAAI,aAAa,EAAE,CAI9C;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,OAAO,EAAE,aAAa,EAAE,CAAC;CAC1B;AAED,wBAAgB,SAAS,CAAC,MAAM,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,YAAY,CAAA;CAAE,GAAG,eAAe,CAW5F"}
|
|
@@ -0,0 +1,106 @@
|
|
|
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.recordFeedback = recordFeedback;
|
|
37
|
+
exports.readFeedback = readFeedback;
|
|
38
|
+
exports.summarize = summarize;
|
|
39
|
+
/**
|
|
40
|
+
* Feedback — local-first capture of QA feedback. The most valuable use of
|
|
41
|
+
* feedback is closing the learning loop WITHIN a project (feed reuse/regenerate
|
|
42
|
+
* + improve the Guide), which needs no server. A future opt-in `feedback sync`
|
|
43
|
+
* can push anonymized metadata to a central API (Nấc 2) — not implemented here.
|
|
44
|
+
*
|
|
45
|
+
* Two purposes are kept distinct:
|
|
46
|
+
* - test-design: a viewpoint/scenario is wrong / missing / duplicate → knowledge
|
|
47
|
+
* - product: Sungen itself did X wrong → telemetry/issue
|
|
48
|
+
*
|
|
49
|
+
* Storage: .sungen/feedback/feedback.jsonl (append-only)
|
|
50
|
+
*/
|
|
51
|
+
const fs = __importStar(require("fs"));
|
|
52
|
+
const path = __importStar(require("path"));
|
|
53
|
+
function feedbackPath() {
|
|
54
|
+
return path.join(process.cwd(), '.sungen', 'feedback', 'feedback.jsonl');
|
|
55
|
+
}
|
|
56
|
+
function currentAuditScore(screen) {
|
|
57
|
+
if (!screen)
|
|
58
|
+
return undefined;
|
|
59
|
+
const p = path.join(process.cwd(), '.sungen', 'reports', `${screen}-audit.json`);
|
|
60
|
+
if (!fs.existsSync(p))
|
|
61
|
+
return undefined;
|
|
62
|
+
try {
|
|
63
|
+
return JSON.parse(fs.readFileSync(p, 'utf-8'))?.score?.overall;
|
|
64
|
+
}
|
|
65
|
+
catch {
|
|
66
|
+
return undefined;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
function recordFeedback(entry) {
|
|
70
|
+
const p = feedbackPath();
|
|
71
|
+
fs.mkdirSync(path.dirname(p), { recursive: true });
|
|
72
|
+
const full = {
|
|
73
|
+
ts: entry.ts ?? new Date().toISOString(),
|
|
74
|
+
type: entry.type,
|
|
75
|
+
screen: entry.screen,
|
|
76
|
+
target: entry.target,
|
|
77
|
+
decision: entry.decision ?? 'none',
|
|
78
|
+
message: entry.message,
|
|
79
|
+
reason: entry.reason,
|
|
80
|
+
source: entry.source ?? 'qa',
|
|
81
|
+
auditScore: currentAuditScore(entry.screen),
|
|
82
|
+
};
|
|
83
|
+
fs.appendFileSync(p, JSON.stringify(full) + '\n', 'utf-8');
|
|
84
|
+
return p;
|
|
85
|
+
}
|
|
86
|
+
function readFeedback() {
|
|
87
|
+
const p = feedbackPath();
|
|
88
|
+
if (!fs.existsSync(p))
|
|
89
|
+
return [];
|
|
90
|
+
return fs.readFileSync(p, 'utf-8').split('\n').filter(Boolean).map((l) => JSON.parse(l));
|
|
91
|
+
}
|
|
92
|
+
function summarize(filter) {
|
|
93
|
+
let entries = readFeedback();
|
|
94
|
+
if (filter?.screen)
|
|
95
|
+
entries = entries.filter((e) => e.screen === filter.screen);
|
|
96
|
+
if (filter?.type)
|
|
97
|
+
entries = entries.filter((e) => e.type === filter.type);
|
|
98
|
+
const byType = {};
|
|
99
|
+
const byDecision = {};
|
|
100
|
+
for (const e of entries) {
|
|
101
|
+
byType[e.type] = (byType[e.type] || 0) + 1;
|
|
102
|
+
byDecision[e.decision || 'none'] = (byDecision[e.decision || 'none'] || 0) + 1;
|
|
103
|
+
}
|
|
104
|
+
return { total: entries.length, byType, byDecision, entries };
|
|
105
|
+
}
|
|
106
|
+
//# sourceMappingURL=feedback.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"feedback.js","sourceRoot":"","sources":["../../src/harness/feedback.ts"],"names":[],"mappings":"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"}
|