@bradtaylorsf/alpha-loop 1.0.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 (95) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +294 -0
  3. package/agents/implementer.md +30 -0
  4. package/agents/reviewer.md +29 -0
  5. package/dist/cli.d.ts +2 -0
  6. package/dist/cli.js +57 -0
  7. package/dist/cli.js.map +1 -0
  8. package/dist/commands/auth.d.ts +1 -0
  9. package/dist/commands/auth.js +89 -0
  10. package/dist/commands/auth.js.map +1 -0
  11. package/dist/commands/history.d.ts +8 -0
  12. package/dist/commands/history.js +185 -0
  13. package/dist/commands/history.js.map +1 -0
  14. package/dist/commands/init.d.ts +1 -0
  15. package/dist/commands/init.js +241 -0
  16. package/dist/commands/init.js.map +1 -0
  17. package/dist/commands/run.d.ts +15 -0
  18. package/dist/commands/run.js +321 -0
  19. package/dist/commands/run.js.map +1 -0
  20. package/dist/commands/scan.d.ts +1 -0
  21. package/dist/commands/scan.js +50 -0
  22. package/dist/commands/scan.js.map +1 -0
  23. package/dist/commands/sync.d.ts +20 -0
  24. package/dist/commands/sync.js +149 -0
  25. package/dist/commands/sync.js.map +1 -0
  26. package/dist/commands/vision.d.ts +1 -0
  27. package/dist/commands/vision.js +194 -0
  28. package/dist/commands/vision.js.map +1 -0
  29. package/dist/engine/agents.d.ts +41 -0
  30. package/dist/engine/agents.js +90 -0
  31. package/dist/engine/agents.js.map +1 -0
  32. package/dist/engine/config.d.ts +71 -0
  33. package/dist/engine/config.js +73 -0
  34. package/dist/engine/config.js.map +1 -0
  35. package/dist/engine/prerequisites.d.ts +34 -0
  36. package/dist/engine/prerequisites.js +90 -0
  37. package/dist/engine/prerequisites.js.map +1 -0
  38. package/dist/lib/agent.d.ts +25 -0
  39. package/dist/lib/agent.js +97 -0
  40. package/dist/lib/agent.js.map +1 -0
  41. package/dist/lib/config.d.ts +35 -0
  42. package/dist/lib/config.js +179 -0
  43. package/dist/lib/config.js.map +1 -0
  44. package/dist/lib/context.d.ts +17 -0
  45. package/dist/lib/context.js +96 -0
  46. package/dist/lib/context.js.map +1 -0
  47. package/dist/lib/github.d.ts +61 -0
  48. package/dist/lib/github.js +313 -0
  49. package/dist/lib/github.js.map +1 -0
  50. package/dist/lib/learning.d.ts +43 -0
  51. package/dist/lib/learning.js +207 -0
  52. package/dist/lib/learning.js.map +1 -0
  53. package/dist/lib/logger.d.ts +9 -0
  54. package/dist/lib/logger.js +28 -0
  55. package/dist/lib/logger.js.map +1 -0
  56. package/dist/lib/pipeline.d.ts +18 -0
  57. package/dist/lib/pipeline.js +456 -0
  58. package/dist/lib/pipeline.js.map +1 -0
  59. package/dist/lib/preflight.d.ts +33 -0
  60. package/dist/lib/preflight.js +123 -0
  61. package/dist/lib/preflight.js.map +1 -0
  62. package/dist/lib/prerequisites.d.ts +12 -0
  63. package/dist/lib/prerequisites.js +54 -0
  64. package/dist/lib/prerequisites.js.map +1 -0
  65. package/dist/lib/prompts.d.ts +44 -0
  66. package/dist/lib/prompts.js +102 -0
  67. package/dist/lib/prompts.js.map +1 -0
  68. package/dist/lib/session.d.ts +28 -0
  69. package/dist/lib/session.js +173 -0
  70. package/dist/lib/session.js.map +1 -0
  71. package/dist/lib/shell.d.ts +32 -0
  72. package/dist/lib/shell.js +95 -0
  73. package/dist/lib/shell.js.map +1 -0
  74. package/dist/lib/testing.d.ts +10 -0
  75. package/dist/lib/testing.js +51 -0
  76. package/dist/lib/testing.js.map +1 -0
  77. package/dist/lib/verify.d.ts +18 -0
  78. package/dist/lib/verify.js +235 -0
  79. package/dist/lib/verify.js.map +1 -0
  80. package/dist/lib/vision.d.ts +9 -0
  81. package/dist/lib/vision.js +21 -0
  82. package/dist/lib/vision.js.map +1 -0
  83. package/dist/lib/worktree.d.ts +29 -0
  84. package/dist/lib/worktree.js +153 -0
  85. package/dist/lib/worktree.js.map +1 -0
  86. package/package.json +63 -0
  87. package/templates/agents/implementer.md +34 -0
  88. package/templates/agents/reviewer.md +48 -0
  89. package/templates/skills/code-review/SKILL.md +58 -0
  90. package/templates/skills/git-workflow/SKILL.md +53 -0
  91. package/templates/skills/implementation-planning/SKILL.md +64 -0
  92. package/templates/skills/security-analysis/SKILL.md +560 -0
  93. package/templates/skills/security-analysis/scripts/security-scanner.sh +227 -0
  94. package/templates/skills/test-robustness/SKILL.md +897 -0
  95. package/templates/skills/testing-patterns/SKILL.md +75 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Bradley Taylor
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,294 @@
1
+ # Alpha Loop
2
+
3
+ Agent-agnostic automated development loop. Fetches issues from your GitHub project board (optionally filtered by milestone), implements them with an AI coding agent, runs tests, reviews the code, and creates PRs — then moves to the next issue until all matching issues are done.
4
+
5
+ **The Loop:** Plan (GitHub Issues) -> Build (AI Agent) -> Test -> Review -> Verify -> Learn -> Ship (PR)
6
+
7
+ ## Installation
8
+
9
+ ```bash
10
+ # Install globally
11
+ npm install -g @bradtaylorsf/alpha-loop
12
+
13
+ # Or run directly
14
+ npx @bradtaylorsf/alpha-loop
15
+ ```
16
+
17
+ ### Prerequisites
18
+
19
+ - **Node.js 20+**
20
+ - **git** — for worktree isolation
21
+ - **[GitHub CLI](https://cli.github.com/)** (`gh`) — authenticated with `gh auth login`
22
+ - **AI agent CLI** — currently supports:
23
+ - [Claude Code](https://claude.ai/code) (`claude`)
24
+ - [Codex](https://github.com/openai/codex) (`codex`)
25
+ - [OpenCode](https://github.com/sst/opencode) (`opencode`)
26
+ - **[Playwright CLI](https://www.npmjs.com/package/@playwright/cli)** (optional) — for live verification with screenshots
27
+
28
+ ## Quick Start
29
+
30
+ ```bash
31
+ # 1. Initialize config in your project
32
+ cd your-project
33
+ alpha-loop init
34
+
35
+ # 2. Edit .alpha-loop.yaml with your repo settings
36
+
37
+ # 3. Set up project vision (optional but recommended)
38
+ alpha-loop vision
39
+
40
+ # 4. Generate project context
41
+ alpha-loop scan
42
+
43
+ # 5. Run the loop — you'll be prompted to pick a milestone
44
+ alpha-loop run
45
+
46
+ # Or target a specific milestone directly
47
+ alpha-loop run --milestone "v1.0"
48
+
49
+ ```
50
+
51
+ ## How It Works
52
+
53
+ Alpha Loop implements a 12-step pipeline for each issue:
54
+
55
+ 1. **Status Update** — Labels issue `in-progress`, updates project board
56
+ 2. **Worktree** — Creates an isolated git worktree so work doesn't conflict with other issues
57
+ 3. **Plan** — Agent analyzes the issue and enriches it with implementation details
58
+ 4. **Implement** — Agent writes the code, guided by project vision, context, and learnings from previous issues
59
+ 5. **Test + Retry** — Runs your test command; if tests fail, agent fixes and retries (up to `max_test_retries`)
60
+ 6. **Verify + Retry** — Starts your dev server, uses playwright-cli to test the feature like a real user, takes screenshots
61
+ 7. **Review** — A review agent reads the diff, checks for gaps, security issues, and missing wiring — fixes what it can
62
+ 8. **Create PR** — Opens a PR with test results, review summary, and verification status
63
+ 9. **Learn** — Extracts learnings (patterns, anti-patterns, what worked/failed) for future sessions
64
+ 10. **Update Issue** — Posts results as a comment, updates labels
65
+ 11. **Auto-Merge** — Merges the PR to the session branch (if enabled)
66
+ 12. **Cleanup** — Removes the worktree
67
+
68
+ After all issues are processed, Alpha Loop generates a **session summary** that aggregates learnings across issues and produces actionable recommendations.
69
+
70
+ ### Milestone-Based Workflow
71
+
72
+ When you start the loop interactively, Alpha Loop shows your open milestones and lets you pick which one to work on:
73
+
74
+ ```
75
+ Open Milestones
76
+
77
+ 0 All issues (no milestone filter)
78
+ 1 v1.0 — MVP (5 open, 3/8 done · due 2026-04-15)
79
+ 2 v1.1 — Polish (10 open, 0/10 done)
80
+
81
+ Select milestone [0-2]: 1
82
+ ```
83
+
84
+ This lets you plan work in GitHub milestones and control exactly how much the loop processes per session. You can also pass `--milestone "v1.0"` to skip the prompt, or set `milestone: v1.0` in your config file.
85
+
86
+ ### Session Branches
87
+
88
+ When `auto_merge` is enabled (default), Alpha Loop creates a session branch (e.g., `session/20260331-002240`) and merges each issue's PR into it. This keeps your main branch clean until you're ready to merge the whole session.
89
+
90
+ ### Learnings
91
+
92
+ Each completed issue produces a learning file in `.alpha-loop/learnings/` with:
93
+ - What worked and what failed
94
+ - Reusable patterns discovered
95
+ - Anti-patterns to avoid
96
+ - Suggested skill/prompt updates
97
+
98
+ These learnings are automatically fed into future implementation prompts, so the agent gets smarter over time.
99
+
100
+ ### Screenshots
101
+
102
+ During live verification, the agent takes screenshots at key states and saves them to `.alpha-loop/sessions/<name>/screenshots/issue-<N>/`. These are kept locally (not committed to git) for debugging.
103
+
104
+ ## Commands
105
+
106
+ | Command | Description |
107
+ |---------|-------------|
108
+ | `alpha-loop init` | Create `.alpha-loop.yaml` config and install agent skills/templates |
109
+ | `alpha-loop run` | Fetch matching issues, process them all, then exit |
110
+ | `alpha-loop run --dry-run` | Preview without making changes |
111
+ | `alpha-loop scan` | Generate/refresh project context (`.alpha-loop/context.md`) |
112
+ | `alpha-loop vision` | Interactive project vision setup (`.alpha-loop/vision.md`) |
113
+ | `alpha-loop auth` | Save authenticated browser state for verification |
114
+ | `alpha-loop history` | View session history |
115
+ | `alpha-loop history <name>` | View a specific session |
116
+ | `alpha-loop history <name> --qa` | Show QA checklist for session |
117
+ | `alpha-loop history --clean` | Remove old session data |
118
+ | `alpha-loop sync` | Sync agent assets (AGENTS.md, skills) across agent directories |
119
+
120
+ ### Run Options
121
+
122
+ ```bash
123
+ alpha-loop run [options]
124
+
125
+ Options:
126
+ --dry-run Preview without making changes
127
+ --model <model> AI model to use (e.g., opus, sonnet)
128
+ --milestone <name> Only process issues in this milestone (skips interactive prompt)
129
+ --skip-tests Skip test execution
130
+ --skip-review Skip code review step
131
+ --skip-learn Skip learning extraction
132
+ --auto-merge Auto-merge PRs to session branch
133
+ --merge-to <branch> Use an existing branch instead of creating a new session branch
134
+ ```
135
+
136
+ ## Configuration
137
+
138
+ Running `alpha-loop init` creates a `.alpha-loop.yaml` file:
139
+
140
+ ```yaml
141
+ # Alpha Loop configuration
142
+ repo: owner/repo-name
143
+ model: opus
144
+ review_model: opus
145
+ label: ready
146
+ base_branch: main
147
+ test_command: pnpm test
148
+ dev_command: pnpm dev
149
+ port: 3000
150
+ auto_merge: true
151
+
152
+ # Safety limits (0 = unlimited)
153
+ max_issues: 20
154
+ max_session_duration: 7200 # 2 hours in seconds
155
+ ```
156
+
157
+ ### Configuration Reference
158
+
159
+ | Key | Default | Description |
160
+ |-----|---------|-------------|
161
+ | `repo` | (auto-detected) | GitHub repo in `owner/name` format |
162
+ | `model` | `opus` | AI model for implementation and verification |
163
+ | `review_model` | `opus` | AI model for code review and learning extraction |
164
+ | `label` | `ready` | GitHub label that marks issues as ready for the loop |
165
+ | `base_branch` | `master` | Branch to create PRs against |
166
+ | `test_command` | `pnpm test` | Command to run tests |
167
+ | `dev_command` | `pnpm dev` | Command to start the dev server for verification |
168
+ | `port` | `3000` | Port the dev server runs on |
169
+ | `max_test_retries` | `3` | Times to retry failing tests/verification |
170
+ | `milestone` | (none) | Only process issues in this milestone |
171
+ | `max_issues` | `0` | Max issues to process per session (0 = unlimited) |
172
+ | `max_session_duration` | `0` | Max session duration in seconds (0 = unlimited) |
173
+ | `auto_merge` | `true` | Auto-merge issue PRs into the session branch |
174
+ | `merge_to` | (none) | Use an existing branch instead of creating a session branch |
175
+ | `skip_tests` | `false` | Skip test execution |
176
+ | `skip_review` | `false` | Skip code review |
177
+ | `skip_verify` | `false` | Skip live verification |
178
+ | `skip_learn` | `false` | Skip learning extraction |
179
+ | `skip_e2e` | `false` | Skip E2E tests |
180
+ | `skip_install` | `false` | Skip `pnpm install` in worktrees |
181
+ | `skip_preflight` | `false` | Skip pre-flight test validation |
182
+ | `auto_cleanup` | `true` | Auto-remove worktrees after processing |
183
+
184
+ ### Environment Variables
185
+
186
+ All config options can be set via environment variables (uppercase, same names):
187
+
188
+ | Variable | Config Key |
189
+ |----------|------------|
190
+ | `REPO` | `repo` |
191
+ | `MODEL` | `model` |
192
+ | `REVIEW_MODEL` | `review_model` |
193
+ | `MAX_TEST_RETRIES` | `max_test_retries` |
194
+ | `MILESTONE` | `milestone` |
195
+ | `MAX_ISSUES` | `max_issues` |
196
+ | `MAX_SESSION_DURATION` | `max_session_duration` |
197
+ | `BASE_BRANCH` | `base_branch` |
198
+ | `TEST_COMMAND` | `test_command` |
199
+ | `DEV_COMMAND` | `dev_command` |
200
+ | `PORT` | `port` |
201
+ | `DRY_RUN` | `dry_run` |
202
+ | `SKIP_TESTS` | `skip_tests` |
203
+ | `SKIP_REVIEW` | `skip_review` |
204
+ | `SKIP_VERIFY` | `skip_verify` |
205
+ | `SKIP_LEARN` | `skip_learn` |
206
+ | `AUTO_MERGE` | `auto_merge` |
207
+ | `MERGE_TO` | `merge_to` |
208
+
209
+ **Precedence:** CLI flags > environment variables > `.alpha-loop.yaml` > auto-detection > defaults
210
+
211
+ ## GitHub Setup
212
+
213
+ ### Labels
214
+
215
+ Create these labels on your repo (or let the loop create them):
216
+
217
+ | Label | Purpose |
218
+ |-------|---------|
219
+ | `ready` | Issue is ready for the loop to pick up |
220
+ | `in-progress` | Loop is actively working on it |
221
+ | `in-review` | PR created, awaiting review |
222
+ | `done` | Merged and complete |
223
+ | `failed` | Loop failed after retries |
224
+
225
+ ### Milestones
226
+
227
+ Use GitHub milestones to group issues into planned releases or sprints. When you start the loop, you'll be prompted to pick a milestone — only issues in that milestone will be processed.
228
+
229
+ Create milestones at `github.com/<owner>/<repo>/milestones/new`. Set due dates to keep yourself on track.
230
+
231
+ ### GitHub Project Board
232
+
233
+ Alpha Loop reads issues from a GitHub Project board (v2). Issues are processed in board order, so you control priority by reordering. When combined with milestones, only "Todo" items in the selected milestone are processed.
234
+
235
+ Set the `project` number in your config (find it in your project URL: `github.com/users/<owner>/projects/<number>`).
236
+
237
+ ### Issue Format
238
+
239
+ Issues work best with structured acceptance criteria. Run `alpha-loop init` to install an issue template:
240
+
241
+ ```markdown
242
+ ## Description
243
+ What needs to be done.
244
+
245
+ ## Acceptance Criteria
246
+ - [ ] Specific, testable criterion
247
+ - [ ] Another criterion
248
+
249
+ ## Test Requirements
250
+ - Unit test for X
251
+ - E2E test for Y
252
+
253
+ ## Affected Files/Areas
254
+ - src/...
255
+ - tests/...
256
+ ```
257
+
258
+ ## Project Artifacts
259
+
260
+ | Directory | Git-tracked? | Purpose |
261
+ |-----------|-------------|---------|
262
+ | `.alpha-loop/vision.md` | Yes | Project vision document |
263
+ | `.alpha-loop/context.md` | Yes | Auto-generated project context |
264
+ | `.alpha-loop/learnings/` | Yes | Learning files from each issue + session summaries |
265
+ | `.alpha-loop/sessions/` | No (gitignored) | Session logs, results JSON, screenshots |
266
+ | `.alpha-loop/auth/` | No (gitignored) | Saved browser auth state for verification |
267
+ | `.worktrees/` | No (gitignored) | Temporary git worktrees during processing |
268
+
269
+ ## Development
270
+
271
+ ```bash
272
+ git clone https://github.com/bradtaylorsf/alpha-loop.git
273
+ cd alpha-loop
274
+ pnpm install
275
+ pnpm build
276
+ pnpm test
277
+
278
+ # Run in development mode
279
+ pnpm dev -- run --dry-run
280
+ ```
281
+
282
+ ### Tech Stack
283
+
284
+ | Layer | Technology |
285
+ |-------|------------|
286
+ | Runtime | Node.js, TypeScript, ESM |
287
+ | CLI Framework | Commander.js |
288
+ | AI Agents | Any CLI agent (Claude, Codex, OpenCode) |
289
+ | Source of Truth | GitHub (Issues = kanban, PRs = reviews) |
290
+ | Package Manager | pnpm |
291
+
292
+ ## License
293
+
294
+ MIT
@@ -0,0 +1,30 @@
1
+ ---
2
+ name: implementer
3
+ description: Implements GitHub issues by writing code, tests, and committing changes
4
+ agent: claude
5
+ model: sonnet
6
+ maxTurns: 30
7
+ permissionMode: acceptEdits
8
+ ---
9
+
10
+ # Implementer Agent
11
+
12
+ You are an expert software engineer implementing a GitHub issue. Your goal is to write clean, working code that satisfies the issue's acceptance criteria.
13
+
14
+ ## Workflow
15
+
16
+ 1. Read the issue description and acceptance criteria carefully
17
+ 2. Explore the codebase to understand existing patterns and conventions
18
+ 3. Implement the required changes following project conventions
19
+ 4. Write tests for your implementation
20
+ 5. Run the test suite to verify everything passes
21
+ 6. Commit your changes with a descriptive message
22
+
23
+ ## Guidelines
24
+
25
+ - Follow existing code style and conventions in the project
26
+ - Write tests for all new functionality
27
+ - Keep changes focused on the issue scope -- do not refactor unrelated code
28
+ - Use meaningful variable and function names
29
+ - Handle edge cases and errors appropriately
30
+ - Ensure all existing tests continue to pass
@@ -0,0 +1,29 @@
1
+ ---
2
+ name: reviewer
3
+ description: Reviews pull requests for code quality, correctness, and best practices
4
+ agent: claude
5
+ model: sonnet
6
+ maxTurns: 15
7
+ permissionMode: plan
8
+ ---
9
+
10
+ # Reviewer Agent
11
+
12
+ You are an expert code reviewer examining a pull request. Your goal is to ensure code quality, correctness, and adherence to project standards.
13
+
14
+ ## Review Checklist
15
+
16
+ 1. **Correctness** -- Does the code do what the issue requires?
17
+ 2. **Tests** -- Are there adequate tests? Do they cover edge cases?
18
+ 3. **Style** -- Does the code follow project conventions?
19
+ 4. **Security** -- Are there any security concerns (injection, XSS, etc.)?
20
+ 5. **Performance** -- Are there any obvious performance issues?
21
+ 6. **Simplicity** -- Is the code as simple as it can be?
22
+
23
+ ## Guidelines
24
+
25
+ - Focus on substantive issues, not nitpicks
26
+ - Suggest specific improvements with code examples when possible
27
+ - Approve if the code is good enough, even if not perfect
28
+ - Flag any breaking changes or backward compatibility concerns
29
+ - Check that the PR description accurately describes the changes
package/dist/cli.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
package/dist/cli.js ADDED
@@ -0,0 +1,57 @@
1
+ #!/usr/bin/env node
2
+ import { program } from 'commander';
3
+ import { initCommand } from './commands/init.js';
4
+ import { historyCommand } from './commands/history.js';
5
+ import { scanCommand } from './commands/scan.js';
6
+ import { visionCommand } from './commands/vision.js';
7
+ import { authCommand } from './commands/auth.js';
8
+ import { syncCommand } from './commands/sync.js';
9
+ program
10
+ .name('alpha-loop')
11
+ .description('Agent-agnostic automated development loop')
12
+ .version('1.0.0');
13
+ program
14
+ .command('init')
15
+ .description('Create .alpha-loop.yaml config template')
16
+ .action(initCommand);
17
+ program
18
+ .command('run')
19
+ .description('Run the loop — fetches matching issues and processes them all, then exits')
20
+ .option('--dry-run', 'Preview without changes')
21
+ .option('--model <model>', 'AI model to use')
22
+ .option('--skip-tests', 'Skip test execution')
23
+ .option('--skip-review', 'Skip code review')
24
+ .option('--skip-learn', 'Skip learning extraction')
25
+ .option('--milestone <name>', 'Only process issues in this milestone')
26
+ .option('--auto-merge', 'Auto-merge PRs to session branch')
27
+ .option('--merge-to <branch>', 'Use existing branch instead of creating session branch')
28
+ .option('--verbose', 'Stream live agent output to terminal')
29
+ .action(async (options) => {
30
+ const { runCommand } = await import('./commands/run.js');
31
+ await runCommand(options);
32
+ });
33
+ program
34
+ .command('history [session]')
35
+ .description('View session history')
36
+ .option('--qa', 'Show QA checklist for session')
37
+ .option('--clean', 'Remove old session data')
38
+ .action(historyCommand);
39
+ program
40
+ .command('scan')
41
+ .description('Generate/refresh project context')
42
+ .action(scanCommand);
43
+ program
44
+ .command('vision')
45
+ .description('Interactive project vision setup')
46
+ .action(visionCommand);
47
+ program
48
+ .command('auth')
49
+ .description('Save authenticated browser state')
50
+ .action(authCommand);
51
+ program
52
+ .command('sync')
53
+ .description('Sync AGENTS.md → CLAUDE.md and skills/ → .agents/skills/ + .claude/skills/')
54
+ .option('--check', 'Check for drift without syncing (exits non-zero if drift found)')
55
+ .action(syncCommand);
56
+ program.parse();
57
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEjD,OAAO;KACJ,IAAI,CAAC,YAAY,CAAC;KAClB,WAAW,CAAC,2CAA2C,CAAC;KACxD,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,OAAO;KACJ,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,yCAAyC,CAAC;KACtD,MAAM,CAAC,WAAW,CAAC,CAAC;AAEvB,OAAO;KACJ,OAAO,CAAC,KAAK,CAAC;KACd,WAAW,CAAC,2EAA2E,CAAC;KACxF,MAAM,CAAC,WAAW,EAAE,yBAAyB,CAAC;KAC9C,MAAM,CAAC,iBAAiB,EAAE,iBAAiB,CAAC;KAC5C,MAAM,CAAC,cAAc,EAAE,qBAAqB,CAAC;KAC7C,MAAM,CAAC,eAAe,EAAE,kBAAkB,CAAC;KAC3C,MAAM,CAAC,cAAc,EAAE,0BAA0B,CAAC;KAClD,MAAM,CAAC,oBAAoB,EAAE,uCAAuC,CAAC;KACrE,MAAM,CAAC,cAAc,EAAE,kCAAkC,CAAC;KAC1D,MAAM,CAAC,qBAAqB,EAAE,wDAAwD,CAAC;KACvF,MAAM,CAAC,WAAW,EAAE,sCAAsC,CAAC;KAC3D,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE;IACxB,MAAM,EAAE,UAAU,EAAE,GAAG,MAAM,MAAM,CAAC,mBAAmB,CAAC,CAAC;IACzD,MAAM,UAAU,CAAC,OAAO,CAAC,CAAC;AAC5B,CAAC,CAAC,CAAC;AAEL,OAAO;KACJ,OAAO,CAAC,mBAAmB,CAAC;KAC5B,WAAW,CAAC,sBAAsB,CAAC;KACnC,MAAM,CAAC,MAAM,EAAE,+BAA+B,CAAC;KAC/C,MAAM,CAAC,SAAS,EAAE,yBAAyB,CAAC;KAC5C,MAAM,CAAC,cAAc,CAAC,CAAC;AAE1B,OAAO;KACJ,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,kCAAkC,CAAC;KAC/C,MAAM,CAAC,WAAW,CAAC,CAAC;AAEvB,OAAO;KACJ,OAAO,CAAC,QAAQ,CAAC;KACjB,WAAW,CAAC,kCAAkC,CAAC;KAC/C,MAAM,CAAC,aAAa,CAAC,CAAC;AAEzB,OAAO;KACJ,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,kCAAkC,CAAC;KAC/C,MAAM,CAAC,WAAW,CAAC,CAAC;AAEvB,OAAO;KACJ,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,4EAA4E,CAAC;KACzF,MAAM,CAAC,SAAS,EAAE,iEAAiE,CAAC;KACpF,MAAM,CAAC,WAAW,CAAC,CAAC;AAEvB,OAAO,CAAC,KAAK,EAAE,CAAC"}
@@ -0,0 +1 @@
1
+ export declare function authCommand(): Promise<void>;
@@ -0,0 +1,89 @@
1
+ import * as fs from 'node:fs';
2
+ import * as path from 'node:path';
3
+ import * as readline from 'node:readline';
4
+ import { exec, run } from '../lib/shell.js';
5
+ import { loadConfig } from '../lib/config.js';
6
+ import { log } from '../lib/logger.js';
7
+ function ask(rl, question) {
8
+ return new Promise((resolve) => {
9
+ rl.question(question, (answer) => resolve(answer.trim()));
10
+ });
11
+ }
12
+ export async function authCommand() {
13
+ // Check for playwright-cli
14
+ const whichResult = exec('which playwright-cli');
15
+ if (whichResult.exitCode !== 0) {
16
+ log.error('playwright-cli not installed. Install with: npm install -g @playwright/cli@latest');
17
+ process.exitCode = 1;
18
+ return;
19
+ }
20
+ const config = loadConfig();
21
+ const projectDir = process.cwd();
22
+ const authDir = path.join(projectDir, '.alpha-loop', 'auth');
23
+ fs.mkdirSync(authDir, { recursive: true });
24
+ console.log('');
25
+ console.log('\x1b[1m\x1b[36mSave authenticated browser state\x1b[0m');
26
+ console.log('');
27
+ console.log('This will open a browser. Log in to your app, then the state');
28
+ console.log('(cookies, localStorage, sessions) will be saved for future');
29
+ console.log('verification runs.');
30
+ console.log('');
31
+ const defaultUrl = `http://localhost:${config.port ?? 3000}`;
32
+ const rl = readline.createInterface({
33
+ input: process.stdin,
34
+ output: process.stdout,
35
+ });
36
+ try {
37
+ const customUrl = await ask(rl, `App URL [${defaultUrl}]: `);
38
+ const appUrl = customUrl || defaultUrl;
39
+ console.log('');
40
+ console.log(`Opening browser at ${appUrl}...`);
41
+ console.log('Log in, then come back here and press Enter to save state.');
42
+ console.log('');
43
+ // Open browser in background
44
+ const browserPromise = run('playwright-cli', ['open', appUrl, '--headed', '--persistent']);
45
+ await ask(rl, 'Press Enter after you\'ve logged in... ');
46
+ // Save browser state
47
+ const saveResult = exec(`playwright-cli state-save "${authDir}/state.json"`);
48
+ if (saveResult.exitCode !== 0) {
49
+ log.warn('Could not save state via playwright-cli, trying cookie export...');
50
+ exec(`playwright-cli cookie-export "${authDir}/cookies.json"`);
51
+ exec(`playwright-cli localstorage-export "${authDir}/localstorage.json"`);
52
+ }
53
+ // Close browser
54
+ exec('playwright-cli close-all');
55
+ // Also wait for the background process to finish (it may already be done)
56
+ await Promise.race([browserPromise, new Promise((r) => setTimeout(r, 2000))]);
57
+ const stateExists = fs.existsSync(path.join(authDir, 'state.json'));
58
+ const cookiesExist = fs.existsSync(path.join(authDir, 'cookies.json'));
59
+ if (stateExists || cookiesExist) {
60
+ log.success(`Auth state saved to ${authDir}`);
61
+ console.log('');
62
+ console.log('Future verification runs will load this state automatically.');
63
+ console.log("Re-run 'auth' if your session expires.");
64
+ // Add to .gitignore
65
+ ensureGitignore(projectDir);
66
+ }
67
+ else {
68
+ log.error('Failed to save auth state');
69
+ process.exitCode = 1;
70
+ }
71
+ }
72
+ finally {
73
+ rl.close();
74
+ }
75
+ }
76
+ function ensureGitignore(projectDir) {
77
+ const gitignorePath = path.join(projectDir, '.gitignore');
78
+ if (!fs.existsSync(gitignorePath)) {
79
+ fs.writeFileSync(gitignorePath, '.alpha-loop/auth/\n');
80
+ log.info('Created .gitignore with .alpha-loop/auth/');
81
+ return;
82
+ }
83
+ const content = fs.readFileSync(gitignorePath, 'utf-8');
84
+ if (!content.includes('.alpha-loop/auth')) {
85
+ fs.appendFileSync(gitignorePath, '\n.alpha-loop/auth/\n');
86
+ log.info('Added .alpha-loop/auth/ to .gitignore');
87
+ }
88
+ }
89
+ //# sourceMappingURL=auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/commands/auth.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ export declare function historyList(sessionsDir: string): void;
2
+ export declare function historyDetail(sessionsDir: string, sessionName: string): void;
3
+ export declare function historyQa(sessionsDir: string, sessionName: string): void;
4
+ export declare function historyClean(sessionsDir: string): void;
5
+ export declare function historyCommand(session: string | undefined, options: {
6
+ qa?: boolean;
7
+ clean?: boolean;
8
+ }): void;