@overshift/sfs 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (102) hide show
  1. package/README.md +215 -0
  2. package/dist/cli/coverage-output.d.ts +3 -0
  3. package/dist/cli/coverage-output.d.ts.map +1 -0
  4. package/dist/cli/coverage-output.js +74 -0
  5. package/dist/cli/coverage-output.js.map +1 -0
  6. package/dist/cli/coverage-types.d.ts +24 -0
  7. package/dist/cli/coverage-types.d.ts.map +1 -0
  8. package/dist/cli/coverage-types.js +2 -0
  9. package/dist/cli/coverage-types.js.map +1 -0
  10. package/dist/cli/coverage.d.ts +3 -0
  11. package/dist/cli/coverage.d.ts.map +1 -0
  12. package/dist/cli/coverage.js +69 -0
  13. package/dist/cli/coverage.js.map +1 -0
  14. package/dist/cli/init-templates.d.ts +5 -0
  15. package/dist/cli/init-templates.d.ts.map +1 -0
  16. package/dist/cli/init-templates.js +108 -0
  17. package/dist/cli/init-templates.js.map +1 -0
  18. package/dist/cli/init.d.ts +7 -0
  19. package/dist/cli/init.d.ts.map +1 -0
  20. package/dist/cli/init.js +170 -0
  21. package/dist/cli/init.js.map +1 -0
  22. package/dist/cli/run.d.ts +3 -0
  23. package/dist/cli/run.d.ts.map +1 -0
  24. package/dist/cli/run.js +58 -0
  25. package/dist/cli/run.js.map +1 -0
  26. package/dist/cli/story-extractor.d.ts +7 -0
  27. package/dist/cli/story-extractor.d.ts.map +1 -0
  28. package/dist/cli/story-extractor.js +130 -0
  29. package/dist/cli/story-extractor.js.map +1 -0
  30. package/dist/cli/validate.d.ts +2 -0
  31. package/dist/cli/validate.d.ts.map +1 -0
  32. package/dist/cli/validate.js +39 -0
  33. package/dist/cli/validate.js.map +1 -0
  34. package/dist/executor/assertion-executor.d.ts +7 -0
  35. package/dist/executor/assertion-executor.d.ts.map +1 -0
  36. package/dist/executor/assertion-executor.js +206 -0
  37. package/dist/executor/assertion-executor.js.map +1 -0
  38. package/dist/executor/config-loader.d.ts +5 -0
  39. package/dist/executor/config-loader.d.ts.map +1 -0
  40. package/dist/executor/config-loader.js +48 -0
  41. package/dist/executor/config-loader.js.map +1 -0
  42. package/dist/executor/executor-types.d.ts +64 -0
  43. package/dist/executor/executor-types.d.ts.map +1 -0
  44. package/dist/executor/executor-types.js +6 -0
  45. package/dist/executor/executor-types.js.map +1 -0
  46. package/dist/executor/retry-handler.d.ts +7 -0
  47. package/dist/executor/retry-handler.d.ts.map +1 -0
  48. package/dist/executor/retry-handler.js +32 -0
  49. package/dist/executor/retry-handler.js.map +1 -0
  50. package/dist/executor/run-context.d.ts +27 -0
  51. package/dist/executor/run-context.d.ts.map +1 -0
  52. package/dist/executor/run-context.js +52 -0
  53. package/dist/executor/run-context.js.map +1 -0
  54. package/dist/executor/run-engine.d.ts +9 -0
  55. package/dist/executor/run-engine.d.ts.map +1 -0
  56. package/dist/executor/run-engine.js +140 -0
  57. package/dist/executor/run-engine.js.map +1 -0
  58. package/dist/executor/session-manager.d.ts +16 -0
  59. package/dist/executor/session-manager.d.ts.map +1 -0
  60. package/dist/executor/session-manager.js +103 -0
  61. package/dist/executor/session-manager.js.map +1 -0
  62. package/dist/executor/shell-executor.d.ts +12 -0
  63. package/dist/executor/shell-executor.d.ts.map +1 -0
  64. package/dist/executor/shell-executor.js +66 -0
  65. package/dist/executor/shell-executor.js.map +1 -0
  66. package/dist/executor/step-executor.d.ts +6 -0
  67. package/dist/executor/step-executor.d.ts.map +1 -0
  68. package/dist/executor/step-executor.js +73 -0
  69. package/dist/executor/step-executor.js.map +1 -0
  70. package/dist/index.d.ts +3 -0
  71. package/dist/index.d.ts.map +1 -0
  72. package/dist/index.js +37 -0
  73. package/dist/index.js.map +1 -0
  74. package/dist/parser/assertion-parser.d.ts +3 -0
  75. package/dist/parser/assertion-parser.d.ts.map +1 -0
  76. package/dist/parser/assertion-parser.js +92 -0
  77. package/dist/parser/assertion-parser.js.map +1 -0
  78. package/dist/parser/command-parser.d.ts +3 -0
  79. package/dist/parser/command-parser.d.ts.map +1 -0
  80. package/dist/parser/command-parser.js +252 -0
  81. package/dist/parser/command-parser.js.map +1 -0
  82. package/dist/parser/config-parser.d.ts +16 -0
  83. package/dist/parser/config-parser.d.ts.map +1 -0
  84. package/dist/parser/config-parser.js +217 -0
  85. package/dist/parser/config-parser.js.map +1 -0
  86. package/dist/parser/sfs-parser.d.ts +3 -0
  87. package/dist/parser/sfs-parser.d.ts.map +1 -0
  88. package/dist/parser/sfs-parser.js +184 -0
  89. package/dist/parser/sfs-parser.js.map +1 -0
  90. package/dist/parser/step-parser.d.ts +3 -0
  91. package/dist/parser/step-parser.d.ts.map +1 -0
  92. package/dist/parser/step-parser.js +72 -0
  93. package/dist/parser/step-parser.js.map +1 -0
  94. package/dist/parser/types.d.ts +115 -0
  95. package/dist/parser/types.d.ts.map +1 -0
  96. package/dist/parser/types.js +3 -0
  97. package/dist/parser/types.js.map +1 -0
  98. package/dist/utils/mcp-detector.d.ts +9 -0
  99. package/dist/utils/mcp-detector.d.ts.map +1 -0
  100. package/dist/utils/mcp-detector.js +62 -0
  101. package/dist/utils/mcp-detector.js.map +1 -0
  102. package/package.json +72 -0
package/README.md ADDED
@@ -0,0 +1,215 @@
1
+ # SFS (StoryFlowSteps)
2
+
3
+ An agent-oriented browser automation protocol for validating user story flows. SFS provides a high-level, natural language syntax for describing browser automation tests, designed to be executed by an AI agent using Playwright MCP.
4
+
5
+ ## Key Features
6
+
7
+ - **Agent-Oriented Design** - Built for AI agents to understand context and make intelligent decisions
8
+ - **Flexible Selectors** - Supports explicit selectors with fuzzy fallback matching
9
+ - **User Story Traceability** - Each SFS file maps to a user story (US-XXX-001) for coverage tracking
10
+ - **Natural Language Syntax** - Commands read like human actions
11
+ - **Multi-Environment Config** - Environment layering for CI/staging/local
12
+ - **Persona Management** - Define user roles with environment-specific credentials
13
+ - **Lifecycle Hooks** - Complete session orchestration (before/after session, before/after each)
14
+
15
+ ## Installation
16
+
17
+ ```bash
18
+ npm install @sfs/cli
19
+ ```
20
+
21
+ Requires Node.js >= 18.0.0
22
+
23
+ ## Quick Start
24
+
25
+ Initialize SFS in your project:
26
+
27
+ ```bash
28
+ npx sfs init
29
+ ```
30
+
31
+ This creates:
32
+ - `sfs.config.md` - Base configuration
33
+ - `example.sfs` - Example login flow
34
+
35
+ ## CLI Commands
36
+
37
+ ### Run SFS Flows
38
+
39
+ ```bash
40
+ npx sfs run # Run all .sfs files
41
+ npx sfs run stories/US-SHOP-01a.sfs # Run specific file
42
+ npx sfs run "stories/**/*.sfs" # Run with glob pattern
43
+ npx sfs run --env ci # Use CI-specific config
44
+ npx sfs run --headed # Show browser GUI
45
+ npx sfs run --verbose # Verbose output
46
+ ```
47
+
48
+ ### Validate Syntax
49
+
50
+ ```bash
51
+ npx sfs validate stories/US-SHOP-01a.sfs
52
+ npx sfs validate "stories/**/*.sfs"
53
+ ```
54
+
55
+ ### Coverage Report
56
+
57
+ ```bash
58
+ npx sfs coverage # Table format
59
+ npx sfs coverage --format json # JSON output
60
+ npx sfs coverage --format summary # Summary only
61
+ ```
62
+
63
+ ## SFS File Syntax
64
+
65
+ ```sfs
66
+ STORY US-LOGIN-01a
67
+ ENTRYPOINT http://localhost:3000
68
+ LOCALE en-US
69
+
70
+ HINT Standard login form with email and password fields
71
+ ON FAILURE capture screenshot and describe visible state
72
+
73
+ BEFORE THIS
74
+ ASSERT port 3000 is open
75
+
76
+ --- page-load ---
77
+ OBSERVE login form is visible
78
+
79
+ --- enter-credentials ---
80
+ TYPE "testuser@example.com" INTO email field >> selector:testid:email-input
81
+ TYPE "password123" INTO password field >> selector:testid:password-input
82
+ CAPTURE before-submit
83
+
84
+ --- submit-login ---
85
+ CLICK login button >> selector:testid:login-btn
86
+ WAIT FOR url contains /dashboard
87
+
88
+ --- verify-dashboard ---
89
+ OBSERVE dashboard content is visible
90
+ OBSERVE logout button is visible
91
+
92
+ DONE WHEN user is logged in and dashboard is visible
93
+ ```
94
+
95
+ ### Command Reference
96
+
97
+ | Category | Commands |
98
+ |----------|----------|
99
+ | **Interactions** | `CLICK`, `TYPE`, `SELECT`, `DOUBLE CLICK`, `HOVER`, `SCROLL TO`, `UPLOAD`, `PRESS`, `CLEAR` |
100
+ | **Navigation** | `NAVIGATE TO`, `WAIT FOR` |
101
+ | **Observations** | `OBSERVE`, `CAPTURE`, `READ ... INTO $var` |
102
+ | **Tabs** | `TAB EXPECT NEW`, `TAB SWITCH TO`, `TAB CLOSE`, `TAB COUNT IS` |
103
+ | **Dialogs** | `ACCEPT DIALOG`, `DISMISS DIALOG` |
104
+ | **Assertions** | `ASSERT port`, `ASSERT env`, `ASSERT file` |
105
+
106
+ ### Selectors
107
+
108
+ Commands support explicit selectors with fuzzy fallback:
109
+
110
+ ```sfs
111
+ CLICK login button # Fuzzy (agent resolves)
112
+ CLICK login button >> selector:testid:login-btn # Explicit with fallback
113
+ CLICK login button >> selector:css:.btn-login # CSS selector
114
+ CLICK login button >> selector:xpath://button[1] # XPath selector
115
+ CLICK login button >> selector:text:Log In # Text selector
116
+ ```
117
+
118
+ ## Configuration
119
+
120
+ ### sfs.config.md
121
+
122
+ ```markdown
123
+ # SFS Configuration
124
+
125
+ ## Settings
126
+
127
+ | Setting | Value |
128
+ |---------|-------|
129
+ | ENTRYPOINT | http://localhost:3000 |
130
+ | LOCALE | en-US |
131
+ | TIMEOUT | 30s |
132
+ | ON FAILURE | capture screenshot |
133
+ | PRESERVE STATE ON FAILURE | true |
134
+
135
+ ## Personas
136
+
137
+ | Persona | Username | Password | Description |
138
+ |---------|----------|----------|-------------|
139
+ | user | testuser@example.com | {{TEST_USER_PASSWORD}} | Standard user |
140
+ | admin | admin@example.com | {{ADMIN_PASSWORD}} | Administrator |
141
+ | guest | | | Unauthenticated |
142
+ ```
143
+
144
+ ### Environment Layering
145
+
146
+ Configuration files are merged in order:
147
+
148
+ ```
149
+ sfs.config.md → Base configuration
150
+ sfs.config.{env}.md → Environment-specific (ci, staging)
151
+ sfs.config.local.md → Local overrides (gitignored)
152
+ ```
153
+
154
+ ## Project Structure
155
+
156
+ ```
157
+ /stories/
158
+ sfs.config.md # Base config
159
+ sfs.config.ci.md # CI overrides
160
+ sfs.config.local.md # Local overrides (gitignored)
161
+
162
+ US-SHOP-01/
163
+ US-SHOP-01a.sfs # Primary flow
164
+ US-SHOP-01a.edge.sfs # Edge cases
165
+
166
+ /runs/ # Test output (gitignored)
167
+ 2024-02-04T14-30-00/
168
+ run.report.md
169
+ ```
170
+
171
+ ## Development
172
+
173
+ ```bash
174
+ npm install # Install dependencies
175
+ npm run dev # Run in development
176
+ npm run build # Build
177
+ npm test # Run tests
178
+ npm run lint # Lint
179
+ npm run format # Format
180
+ ```
181
+
182
+ ### Pre-commit Checks
183
+
184
+ This project uses a Definition of Done (DoD) quality gate that runs before each commit. The checks include:
185
+
186
+ **Critical (must pass):** build, test, lint, format
187
+ **Warnings (informational):** longfiles, knip, seccheck, audit
188
+
189
+ Run checks manually with npm scripts:
190
+
191
+ ```bash
192
+ npm run dod # Run all checks (default)
193
+ npm run dod:all # Run all checks (explicit)
194
+ npm run dod:core # Run only critical checks (faster)
195
+ npm run dod:skip # Skip all checks
196
+ ```
197
+
198
+ Commit with check level control:
199
+
200
+ ```bash
201
+ npm run commit:check -- -m "message" # All checks (default)
202
+ npm run commit:check:all -- -m "message" # All checks (explicit)
203
+ npm run commit:check:core -- -m "message" # Core checks only
204
+ npm run commit:check:skip -- -m "message" # Skip DoD checks
205
+ git commit --no-verify -m "message" # Skip all hooks
206
+ ```
207
+
208
+ ## Documentation
209
+
210
+ - [SFS Language Specification](SFS-SPEC.md)
211
+ - [Configuration Specification](SFS-CONFIG-SPEC.md)
212
+
213
+ ## License
214
+
215
+ MIT
@@ -0,0 +1,3 @@
1
+ import type { CoverageResult } from "./coverage-types.js";
2
+ export declare function outputResults(result: CoverageResult, format: string): void;
3
+ //# sourceMappingURL=coverage-output.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"coverage-output.d.ts","sourceRoot":"","sources":["../../src/cli/coverage-output.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAE1D,wBAAgB,aAAa,CAAC,MAAM,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAe1E"}
@@ -0,0 +1,74 @@
1
+ import chalk from "chalk";
2
+ export function outputResults(result, format) {
3
+ switch (format) {
4
+ case "json":
5
+ console.log(JSON.stringify(result, null, 2));
6
+ break;
7
+ case "summary":
8
+ outputSummary(result);
9
+ break;
10
+ case "table":
11
+ default:
12
+ outputTable(result);
13
+ break;
14
+ }
15
+ }
16
+ function outputSummary(result) {
17
+ const { stories, flows, covered, uncovered, coverage } = result;
18
+ console.log(`User Stories: ${stories.length}`);
19
+ console.log(`SFS Flows: ${flows.length}`);
20
+ console.log(`Covered: ${covered.length}`);
21
+ console.log(`Uncovered: ${uncovered.length}`);
22
+ console.log();
23
+ const coverageColor = coverage >= 80 ? chalk.green : coverage >= 50 ? chalk.yellow : chalk.red;
24
+ console.log(`Coverage: ${coverageColor(`${coverage.toFixed(1)}%`)}`);
25
+ }
26
+ function outputTable(result) {
27
+ const { stories, flows, covered, uncovered, coverage } = result;
28
+ console.log(chalk.bold("Summary"));
29
+ console.log(` User Stories: ${stories.length}`);
30
+ console.log(` SFS Flows: ${flows.length}`);
31
+ console.log();
32
+ if (stories.length > 0) {
33
+ console.log(chalk.bold("Coverage by Story"));
34
+ console.log();
35
+ console.log("| Story ID | Title | Source | Status | Flows |");
36
+ console.log("|----------|-------|--------|--------|-------|");
37
+ for (const story of stories) {
38
+ const storyFlows = flows.filter((f) => f.storyId === story.id);
39
+ const status = storyFlows.length > 0
40
+ ? chalk.green("✓ Covered")
41
+ : chalk.red("✗ Missing");
42
+ const flowCount = storyFlows.length > 0 ? storyFlows.length.toString() : "0";
43
+ const title = story.title ? truncate(story.title, 30) : "-";
44
+ const source = story.source === "single" ? "file" : "multi";
45
+ console.log(`| ${story.id} | ${title} | ${source} | ${status} | ${flowCount} |`);
46
+ }
47
+ console.log();
48
+ }
49
+ if (uncovered.length > 0) {
50
+ console.log(chalk.bold.red("Uncovered Stories"));
51
+ for (const id of uncovered) {
52
+ const story = stories.find((s) => s.id === id);
53
+ console.log(chalk.red(` ✗ ${id}${story?.title ? ` - ${story.title}` : ""}`));
54
+ }
55
+ console.log();
56
+ }
57
+ const orphanFlows = flows.filter((f) => !stories.some((s) => s.id === f.storyId));
58
+ if (orphanFlows.length > 0) {
59
+ console.log(chalk.bold.yellow("Flows without matching user stories"));
60
+ for (const flow of orphanFlows) {
61
+ console.log(chalk.yellow(` ⚠ ${flow.path} (STORY ${flow.storyId})`));
62
+ }
63
+ console.log();
64
+ }
65
+ const coverageColor = coverage >= 80 ? chalk.green : coverage >= 50 ? chalk.yellow : chalk.red;
66
+ console.log(chalk.bold("Overall Coverage"));
67
+ console.log(` ${coverageColor(`${coverage.toFixed(1)}%`)} (${covered.length}/${stories.length} stories)`);
68
+ }
69
+ function truncate(str, maxLen) {
70
+ if (str.length <= maxLen)
71
+ return str;
72
+ return str.slice(0, maxLen - 3) + "...";
73
+ }
74
+ //# sourceMappingURL=coverage-output.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"coverage-output.js","sourceRoot":"","sources":["../../src/cli/coverage-output.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ export interface CoverageOptions {
2
+ stories?: string;
3
+ sfs?: string;
4
+ format?: "table" | "json" | "summary";
5
+ }
6
+ export interface UserStory {
7
+ id: string;
8
+ title?: string;
9
+ path: string;
10
+ source: "single" | "multi";
11
+ }
12
+ export interface SfsFlow {
13
+ storyId: string;
14
+ path: string;
15
+ name: string;
16
+ }
17
+ export interface CoverageResult {
18
+ stories: UserStory[];
19
+ flows: SfsFlow[];
20
+ covered: string[];
21
+ uncovered: string[];
22
+ coverage: number;
23
+ }
24
+ //# sourceMappingURL=coverage-types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"coverage-types.d.ts","sourceRoot":"","sources":["../../src/cli/coverage-types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,eAAe;IAC9B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAAC;CACvC;AAED,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,QAAQ,GAAG,OAAO,CAAC;CAC5B;AAED,MAAM,WAAW,OAAO;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,SAAS,EAAE,CAAC;IACrB,KAAK,EAAE,OAAO,EAAE,CAAC;IACjB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;CAClB"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=coverage-types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"coverage-types.js","sourceRoot":"","sources":["../../src/cli/coverage-types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,3 @@
1
+ import type { CoverageOptions } from "./coverage-types.js";
2
+ export declare function coverageCommand(options: CoverageOptions): Promise<void>;
3
+ //# sourceMappingURL=coverage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"coverage.d.ts","sourceRoot":"","sources":["../../src/cli/coverage.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,eAAe,EAIhB,MAAM,qBAAqB,CAAC;AAU7B,wBAAsB,eAAe,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAsB7E"}
@@ -0,0 +1,69 @@
1
+ import { basename } from "path";
2
+ import { glob } from "glob";
3
+ import chalk from "chalk";
4
+ import { extractStoryIdFromFilename, extractStoryTitle, extractStoriesFromMultiFile, deduplicateStories, extractSfsStoryId, } from "./story-extractor.js";
5
+ import { outputResults } from "./coverage-output.js";
6
+ export async function coverageCommand(options) {
7
+ const storiesDir = options.stories ?? "stories";
8
+ const sfsPattern = options.sfs ?? "**/*.sfs";
9
+ const format = options.format ?? "table";
10
+ // Only show header for non-JSON formats
11
+ if (format !== "json") {
12
+ console.log(chalk.blue("SFS - User Story Coverage Report"));
13
+ console.log();
14
+ }
15
+ try {
16
+ const result = await calculateCoverage(storiesDir, sfsPattern);
17
+ outputResults(result, format);
18
+ }
19
+ catch (error) {
20
+ console.log(chalk.red(`Error: ${error instanceof Error ? error.message : "Unknown error"}`));
21
+ process.exit(1);
22
+ }
23
+ }
24
+ async function calculateCoverage(storiesDir, sfsPattern) {
25
+ const singleStoryFiles = await glob(`${storiesDir}/**/US-*.md`, {
26
+ ignore: ["**/node_modules/**", "**/*.sfs.md"],
27
+ });
28
+ const multiStoryFiles = await glob([
29
+ `${storiesDir}/**/*user-stories*.md`,
30
+ `${storiesDir}/**/*user.stories*.md`,
31
+ `${storiesDir}/**/*user_stories*.md`,
32
+ ], {
33
+ ignore: ["**/node_modules/**"],
34
+ });
35
+ const sfsFiles = await glob(sfsPattern, {
36
+ ignore: ["**/node_modules/**"],
37
+ });
38
+ const stories = [];
39
+ for (const file of singleStoryFiles) {
40
+ const id = extractStoryIdFromFilename(file);
41
+ if (id) {
42
+ const title = await extractStoryTitle(file);
43
+ stories.push({ id, title, path: file, source: "single" });
44
+ }
45
+ }
46
+ for (const file of multiStoryFiles) {
47
+ const multiStories = await extractStoriesFromMultiFile(file);
48
+ stories.push(...multiStories);
49
+ }
50
+ const uniqueStories = deduplicateStories(stories);
51
+ const flows = [];
52
+ for (const file of sfsFiles) {
53
+ const storyId = await extractSfsStoryId(file);
54
+ if (storyId) {
55
+ flows.push({
56
+ storyId,
57
+ path: file,
58
+ name: basename(file, ".sfs"),
59
+ });
60
+ }
61
+ }
62
+ const storyIds = new Set(uniqueStories.map((s) => s.id));
63
+ const coveredIds = new Set(flows.map((f) => f.storyId));
64
+ const covered = [...storyIds].filter((id) => coveredIds.has(id));
65
+ const uncovered = [...storyIds].filter((id) => !coveredIds.has(id));
66
+ const coverage = storyIds.size > 0 ? (covered.length / storyIds.size) * 100 : 100;
67
+ return { stories: uniqueStories, flows, covered, uncovered, coverage };
68
+ }
69
+ //# sourceMappingURL=coverage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"coverage.js","sourceRoot":"","sources":["../../src/cli/coverage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,MAAM,CAAC;AAChC,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,KAAK,MAAM,OAAO,CAAC;AAO1B,OAAO,EACL,0BAA0B,EAC1B,iBAAiB,EACjB,2BAA2B,EAC3B,kBAAkB,EAClB,iBAAiB,GAClB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAErD,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,OAAwB;IAC5D,MAAM,UAAU,GAAG,OAAO,CAAC,OAAO,IAAI,SAAS,CAAC;IAChD,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,IAAI,UAAU,CAAC;IAC7C,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC;IAEzC,wCAAwC;IACxC,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;QACtB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,kCAAkC,CAAC,CAAC,CAAC;QAC5D,OAAO,CAAC,GAAG,EAAE,CAAC;IAChB,CAAC;IAED,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,iBAAiB,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;QAC/D,aAAa,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,GAAG,CACT,KAAK,CAAC,GAAG,CACP,UAAU,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,EAAE,CACrE,CACF,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC;AAED,KAAK,UAAU,iBAAiB,CAC9B,UAAkB,EAClB,UAAkB;IAElB,MAAM,gBAAgB,GAAG,MAAM,IAAI,CAAC,GAAG,UAAU,aAAa,EAAE;QAC9D,MAAM,EAAE,CAAC,oBAAoB,EAAE,aAAa,CAAC;KAC9C,CAAC,CAAC;IAEH,MAAM,eAAe,GAAG,MAAM,IAAI,CAChC;QACE,GAAG,UAAU,uBAAuB;QACpC,GAAG,UAAU,uBAAuB;QACpC,GAAG,UAAU,uBAAuB;KACrC,EACD;QACE,MAAM,EAAE,CAAC,oBAAoB,CAAC;KAC/B,CACF,CAAC;IAEF,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,UAAU,EAAE;QACtC,MAAM,EAAE,CAAC,oBAAoB,CAAC;KAC/B,CAAC,CAAC;IAEH,MAAM,OAAO,GAAgB,EAAE,CAAC;IAChC,KAAK,MAAM,IAAI,IAAI,gBAAgB,EAAE,CAAC;QACpC,MAAM,EAAE,GAAG,0BAA0B,CAAC,IAAI,CAAC,CAAC;QAC5C,IAAI,EAAE,EAAE,CAAC;YACP,MAAM,KAAK,GAAG,MAAM,iBAAiB,CAAC,IAAI,CAAC,CAAC;YAC5C,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC;QAC5D,CAAC;IACH,CAAC;IAED,KAAK,MAAM,IAAI,IAAI,eAAe,EAAE,CAAC;QACnC,MAAM,YAAY,GAAG,MAAM,2BAA2B,CAAC,IAAI,CAAC,CAAC;QAC7D,OAAO,CAAC,IAAI,CAAC,GAAG,YAAY,CAAC,CAAC;IAChC,CAAC;IAED,MAAM,aAAa,GAAG,kBAAkB,CAAC,OAAO,CAAC,CAAC;IAElD,MAAM,KAAK,GAAc,EAAE,CAAC;IAC5B,KAAK,MAAM,IAAI,IAAI,QAAQ,EAAE,CAAC;QAC5B,MAAM,OAAO,GAAG,MAAM,iBAAiB,CAAC,IAAI,CAAC,CAAC;QAC9C,IAAI,OAAO,EAAE,CAAC;YACZ,KAAK,CAAC,IAAI,CAAC;gBACT,OAAO;gBACP,IAAI,EAAE,IAAI;gBACV,IAAI,EAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;aAC7B,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACzD,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;IAExD,MAAM,OAAO,GAAG,CAAC,GAAG,QAAQ,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;IACjE,MAAM,SAAS,GAAG,CAAC,GAAG,QAAQ,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;IAEpE,MAAM,QAAQ,GACZ,QAAQ,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,GAAG,QAAQ,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;IAEnE,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC;AACzE,CAAC"}
@@ -0,0 +1,5 @@
1
+ export declare const CONFIG_TEMPLATE = "# SFS Configuration\n\n## Settings\n\n| Setting | Value |\n|---------|-------|\n| ENTRYPOINT | http://localhost:3000 |\n| LOCALE | en-US |\n| TIMEOUT | 30000 |\n| ON FAILURE | capture screenshot |\n| PRESERVE STATE ON FAILURE | true |\n\n## Hints\n\n- Add context about your application here\n- Describe the UI layout, navigation patterns\n- Note any authentication requirements\n- Mention relevant test data or fixtures\n\n## Personas\n\n| Persona | Username | Password | Description |\n|---------|----------|----------|-------------|\n| user | testuser@example.com | {{TEST_USER_PASSWORD}} | Standard user account |\n| admin | admin@example.com | {{ADMIN_PASSWORD}} | Administrator with full access |\n| guest | | | Unauthenticated visitor |\n\n## Before Session\n\n```sfs\n# Validate environment\nASSERT file .env exists\nASSERT env-check\n\n# Start services (uncomment as needed)\n# SHELL docker compose up -d\n# WAIT FOR http://localhost:3000 to respond\n```\n\n## After Session\n\n```sfs\n# Collect logs\nSHELL mkdir -p {{RUN_DIR}}\n# SHELL docker compose logs > {{RUN_DIR}}/docker.log\n```\n\n## Before Each\n\n```sfs\n# Reset browser state\nCLEAR cookies\nCLEAR local storage\n```\n\n## After Each\n\n```sfs\n# Log completion\nSHELL echo \"$(date): Completed {{SFS_NAME}}\" >> {{RUN_DIR}}/execution.log\n```\n";
2
+ export declare const EXAMPLE_SFS = "# example.sfs\n# Example: Basic page load verification\n\nSTORY EXAMPLE-001\nENTRYPOINT http://localhost:3000\nLOCALE en-US\n\nHINT Replace with your application context\nHINT Describe the page layout and key elements\n\nON FAILURE capture screenshot and describe visible state\n\nBEFORE THIS\n ASSERT port 3000 is open\n\n--- page-load ---\nAS user\nOBSERVE page has loaded\nOBSERVE main content is visible\n\n--- verify-elements ---\n# Add your verification steps here\nOBSERVE expected elements are present\n\nDONE WHEN page loaded successfully with expected content\n";
3
+ export declare const GITIGNORE_ADDITIONS = "\n# SFS local config (may contain sensitive paths/settings)\nsfs.config.local.md\n\n# SFS run outputs\n/runs/\n/stories/runs/\n*.report.md\n\n# Failure screenshots\n/failures/\n";
4
+ export declare const SFS_SKILLS: string[];
5
+ //# sourceMappingURL=init-templates.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init-templates.d.ts","sourceRoot":"","sources":["../../src/cli/init-templates.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,eAAe,0yCA6D3B,CAAC;AAEF,eAAO,MAAM,WAAW,4lBAyBvB,CAAC;AAEF,eAAO,MAAM,mBAAmB,sLAW/B,CAAC;AAEF,eAAO,MAAM,UAAU,UAMtB,CAAC"}
@@ -0,0 +1,108 @@
1
+ export const CONFIG_TEMPLATE = `# SFS Configuration
2
+
3
+ ## Settings
4
+
5
+ | Setting | Value |
6
+ |---------|-------|
7
+ | ENTRYPOINT | http://localhost:3000 |
8
+ | LOCALE | en-US |
9
+ | TIMEOUT | 30000 |
10
+ | ON FAILURE | capture screenshot |
11
+ | PRESERVE STATE ON FAILURE | true |
12
+
13
+ ## Hints
14
+
15
+ - Add context about your application here
16
+ - Describe the UI layout, navigation patterns
17
+ - Note any authentication requirements
18
+ - Mention relevant test data or fixtures
19
+
20
+ ## Personas
21
+
22
+ | Persona | Username | Password | Description |
23
+ |---------|----------|----------|-------------|
24
+ | user | testuser@example.com | {{TEST_USER_PASSWORD}} | Standard user account |
25
+ | admin | admin@example.com | {{ADMIN_PASSWORD}} | Administrator with full access |
26
+ | guest | | | Unauthenticated visitor |
27
+
28
+ ## Before Session
29
+
30
+ \`\`\`sfs
31
+ # Validate environment
32
+ ASSERT file .env exists
33
+ ASSERT env-check
34
+
35
+ # Start services (uncomment as needed)
36
+ # SHELL docker compose up -d
37
+ # WAIT FOR http://localhost:3000 to respond
38
+ \`\`\`
39
+
40
+ ## After Session
41
+
42
+ \`\`\`sfs
43
+ # Collect logs
44
+ SHELL mkdir -p {{RUN_DIR}}
45
+ # SHELL docker compose logs > {{RUN_DIR}}/docker.log
46
+ \`\`\`
47
+
48
+ ## Before Each
49
+
50
+ \`\`\`sfs
51
+ # Reset browser state
52
+ CLEAR cookies
53
+ CLEAR local storage
54
+ \`\`\`
55
+
56
+ ## After Each
57
+
58
+ \`\`\`sfs
59
+ # Log completion
60
+ SHELL echo "$(date): Completed {{SFS_NAME}}" >> {{RUN_DIR}}/execution.log
61
+ \`\`\`
62
+ `;
63
+ export const EXAMPLE_SFS = `# example.sfs
64
+ # Example: Basic page load verification
65
+
66
+ STORY EXAMPLE-001
67
+ ENTRYPOINT http://localhost:3000
68
+ LOCALE en-US
69
+
70
+ HINT Replace with your application context
71
+ HINT Describe the page layout and key elements
72
+
73
+ ON FAILURE capture screenshot and describe visible state
74
+
75
+ BEFORE THIS
76
+ ASSERT port 3000 is open
77
+
78
+ --- page-load ---
79
+ AS user
80
+ OBSERVE page has loaded
81
+ OBSERVE main content is visible
82
+
83
+ --- verify-elements ---
84
+ # Add your verification steps here
85
+ OBSERVE expected elements are present
86
+
87
+ DONE WHEN page loaded successfully with expected content
88
+ `;
89
+ export const GITIGNORE_ADDITIONS = `
90
+ # SFS local config (may contain sensitive paths/settings)
91
+ sfs.config.local.md
92
+
93
+ # SFS run outputs
94
+ /runs/
95
+ /stories/runs/
96
+ *.report.md
97
+
98
+ # Failure screenshots
99
+ /failures/
100
+ `;
101
+ export const SFS_SKILLS = [
102
+ "from-user-story-to-sfs.md",
103
+ "write-sfs-session-reports.md",
104
+ "read-sfs-session-reports.md",
105
+ "validate-sfs-syntax.md",
106
+ "run-sfs-session.md",
107
+ ];
108
+ //# sourceMappingURL=init-templates.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init-templates.js","sourceRoot":"","sources":["../../src/cli/init-templates.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,eAAe,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6D9B,CAAC;AAEF,MAAM,CAAC,MAAM,WAAW,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;CAyB1B,CAAC;AAEF,MAAM,CAAC,MAAM,mBAAmB,GAAG;;;;;;;;;;;CAWlC,CAAC;AAEF,MAAM,CAAC,MAAM,UAAU,GAAG;IACxB,2BAA2B;IAC3B,8BAA8B;IAC9B,6BAA6B;IAC7B,wBAAwB;IACxB,oBAAoB;CACrB,CAAC"}
@@ -0,0 +1,7 @@
1
+ interface InitOptions {
2
+ force?: boolean;
3
+ skillsDir?: string;
4
+ }
5
+ export declare function initCommand(options: InitOptions): Promise<void>;
6
+ export {};
7
+ //# sourceMappingURL=init.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/cli/init.ts"],"names":[],"mappings":"AAkBA,UAAU,WAAW;IACnB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAsB,WAAW,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAqErE"}