ralphy-spec 0.2.0 → 0.3.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 (118) hide show
  1. package/CHANGELOG.md +32 -0
  2. package/README.ja.md +38 -15
  3. package/README.ko.md +38 -15
  4. package/README.md +38 -15
  5. package/README.zh.md +38 -15
  6. package/dist/cli/budget.d.ts +3 -0
  7. package/dist/cli/budget.d.ts.map +1 -0
  8. package/dist/cli/budget.js +77 -0
  9. package/dist/cli/budget.js.map +1 -0
  10. package/dist/cli/init.d.ts.map +1 -1
  11. package/dist/cli/init.js +6 -0
  12. package/dist/cli/init.js.map +1 -1
  13. package/dist/cli/run.d.ts.map +1 -1
  14. package/dist/cli/run.js +42 -9
  15. package/dist/cli/run.js.map +1 -1
  16. package/dist/cli/status.d.ts.map +1 -1
  17. package/dist/cli/status.js +31 -0
  18. package/dist/cli/status.js.map +1 -1
  19. package/dist/core/artifacts/budget-writer.d.ts +11 -0
  20. package/dist/core/artifacts/budget-writer.d.ts.map +1 -0
  21. package/dist/core/artifacts/budget-writer.js +28 -0
  22. package/dist/core/artifacts/budget-writer.js.map +1 -0
  23. package/dist/core/artifacts/run-log-writer.d.ts +20 -0
  24. package/dist/core/artifacts/run-log-writer.d.ts.map +1 -0
  25. package/dist/core/artifacts/run-log-writer.js +40 -0
  26. package/dist/core/artifacts/run-log-writer.js.map +1 -0
  27. package/dist/core/artifacts/run-log-writer.test.d.ts +2 -0
  28. package/dist/core/artifacts/run-log-writer.test.d.ts.map +1 -0
  29. package/dist/core/artifacts/run-log-writer.test.js +37 -0
  30. package/dist/core/artifacts/run-log-writer.test.js.map +1 -0
  31. package/dist/core/artifacts/status-writer.d.ts +16 -0
  32. package/dist/core/artifacts/status-writer.d.ts.map +1 -0
  33. package/dist/core/artifacts/status-writer.js +52 -0
  34. package/dist/core/artifacts/status-writer.js.map +1 -0
  35. package/dist/core/artifacts/status-writer.test.d.ts +2 -0
  36. package/dist/core/artifacts/status-writer.test.d.ts.map +1 -0
  37. package/dist/core/artifacts/status-writer.test.js +47 -0
  38. package/dist/core/artifacts/status-writer.test.js.map +1 -0
  39. package/dist/core/artifacts/task-artifacts.d.ts +19 -0
  40. package/dist/core/artifacts/task-artifacts.d.ts.map +1 -0
  41. package/dist/core/artifacts/task-artifacts.js +35 -0
  42. package/dist/core/artifacts/task-artifacts.js.map +1 -0
  43. package/dist/core/artifacts/tasks-writer.d.ts +19 -0
  44. package/dist/core/artifacts/tasks-writer.d.ts.map +1 -0
  45. package/dist/core/artifacts/tasks-writer.js +67 -0
  46. package/dist/core/artifacts/tasks-writer.js.map +1 -0
  47. package/dist/core/artifacts/tasks-writer.test.d.ts +2 -0
  48. package/dist/core/artifacts/tasks-writer.test.d.ts.map +1 -0
  49. package/dist/core/artifacts/tasks-writer.test.js +28 -0
  50. package/dist/core/artifacts/tasks-writer.test.js.map +1 -0
  51. package/dist/core/budgets/errors.d.ts +5 -0
  52. package/dist/core/budgets/errors.d.ts.map +1 -0
  53. package/dist/core/budgets/errors.js +11 -0
  54. package/dist/core/budgets/errors.js.map +1 -0
  55. package/dist/core/engine/constraints.d.ts +16 -0
  56. package/dist/core/engine/constraints.d.ts.map +1 -0
  57. package/dist/core/engine/constraints.js +21 -0
  58. package/dist/core/engine/constraints.js.map +1 -0
  59. package/dist/core/engine/constraints.policy.test.d.ts +2 -0
  60. package/dist/core/engine/constraints.policy.test.d.ts.map +1 -0
  61. package/dist/core/engine/constraints.policy.test.js +85 -0
  62. package/dist/core/engine/constraints.policy.test.js.map +1 -0
  63. package/dist/core/engine/loop.d.ts.map +1 -1
  64. package/dist/core/engine/loop.hardcap.test.d.ts +2 -0
  65. package/dist/core/engine/loop.hardcap.test.d.ts.map +1 -0
  66. package/dist/core/engine/loop.hardcap.test.js +77 -0
  67. package/dist/core/engine/loop.hardcap.test.js.map +1 -0
  68. package/dist/core/engine/loop.js +511 -13
  69. package/dist/core/engine/loop.js.map +1 -1
  70. package/dist/core/memory/persistence.d.ts +9 -0
  71. package/dist/core/memory/persistence.d.ts.map +1 -1
  72. package/dist/core/memory/persistence.js +19 -1
  73. package/dist/core/memory/persistence.js.map +1 -1
  74. package/dist/core/reporting/failure-summary.d.ts +23 -0
  75. package/dist/core/reporting/failure-summary.d.ts.map +1 -0
  76. package/dist/core/reporting/failure-summary.js +63 -0
  77. package/dist/core/reporting/failure-summary.js.map +1 -0
  78. package/dist/core/reporting/failure-summary.test.d.ts +2 -0
  79. package/dist/core/reporting/failure-summary.test.d.ts.map +1 -0
  80. package/dist/core/reporting/failure-summary.test.js +22 -0
  81. package/dist/core/reporting/failure-summary.test.js.map +1 -0
  82. package/dist/core/spec/loader.d.ts.map +1 -1
  83. package/dist/core/spec/loader.js +12 -1
  84. package/dist/core/spec/loader.js.map +1 -1
  85. package/dist/core/spec/schemas.d.ts +857 -0
  86. package/dist/core/spec/schemas.d.ts.map +1 -1
  87. package/dist/core/spec/schemas.js +28 -0
  88. package/dist/core/spec/schemas.js.map +1 -1
  89. package/dist/core/spec/sprint-defaults.d.ts +16 -0
  90. package/dist/core/spec/sprint-defaults.d.ts.map +1 -0
  91. package/dist/core/spec/sprint-defaults.js +55 -0
  92. package/dist/core/spec/sprint-defaults.js.map +1 -0
  93. package/dist/core/spec/sprint-defaults.test.d.ts +2 -0
  94. package/dist/core/spec/sprint-defaults.test.d.ts.map +1 -0
  95. package/dist/core/spec/sprint-defaults.test.js +51 -0
  96. package/dist/core/spec/sprint-defaults.test.js.map +1 -0
  97. package/dist/core/spec/types.d.ts +11 -0
  98. package/dist/core/spec/types.d.ts.map +1 -1
  99. package/dist/core/validators/types.d.ts +1 -1
  100. package/dist/core/validators/types.d.ts.map +1 -1
  101. package/dist/core/workspace/scope-detector.d.ts +13 -0
  102. package/dist/core/workspace/scope-detector.d.ts.map +1 -0
  103. package/dist/core/workspace/scope-detector.js +34 -0
  104. package/dist/core/workspace/scope-detector.js.map +1 -0
  105. package/dist/core/workspace/worktree-mode.d.ts.map +1 -1
  106. package/dist/core/workspace/worktree-mode.js +2 -1
  107. package/dist/core/workspace/worktree-mode.js.map +1 -1
  108. package/dist/index.js +3 -1
  109. package/dist/index.js.map +1 -1
  110. package/dist/templates/claude-code/ralphy-archive.md +1 -1
  111. package/dist/templates/claude-code/ralphy-implement.md +1 -1
  112. package/dist/templates/claude-code/ralphy-plan.md +1 -1
  113. package/dist/templates/claude-code/ralphy-validate.md +1 -1
  114. package/dist/templates/cursor/ralphy-archive.md +1 -1
  115. package/dist/templates/cursor/ralphy-implement.md +1 -1
  116. package/dist/templates/cursor/ralphy-plan.md +1 -1
  117. package/dist/templates/cursor/ralphy-validate.md +1 -1
  118. package/package.json +7 -4
package/CHANGELOG.md ADDED
@@ -0,0 +1,32 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [0.2.0] - 2026-01-23
9
+
10
+ ### Added
11
+ - Initial public release of `ralphy-spec`.
12
+ - Astro-powered documentation site with i18n (en/zh/ko/ja).
13
+
14
+ ### Changed
15
+ - N/A
16
+
17
+ ### Fixed
18
+ - N/A
19
+
20
+ ## [0.3.0] - 2026-01-23
21
+
22
+ ### Added
23
+ - Budget intelligence: three-tier budgets (optimal → warning → hard) with hard-cap blocking + failure summaries.
24
+ - Sprint semantics: `sprint.size` defaults, `sprint.intent` constraints, and configurable scope guard policy (`off|warn|block`).
25
+ - Artifact system: `ralphy-spec/` folder, STATUS/TASKS/BUDGET writers, per-task artifacts, immutable run logs, and `--artifact-dir`.
26
+ - New CLI command: `ralphy-spec budget` and a full CLI docs page on the website.
27
+ - Test suite (Vitest) covering the above behaviors.
28
+
29
+ ### Changed
30
+ - `ralphy-spec run` now supports `worktree` mode and real backend selection (`cursor|opencode|claude-code|noop`).
31
+ - Docs + README (all languages) updated to reflect the new artifacts and CLI.
32
+
package/README.ja.md CHANGED
@@ -5,6 +5,8 @@
5
5
  **スペック駆動AI開発 + 反復実行。** OpenSpecとRalph Loopを組み合わせて、予測可能なAI支援コーディングを実現します。
6
6
 
7
7
  **ウェブサイト:** [https://ralphy-spec.org](https://ralphy-spec.org)
8
+ **ドキュメント:** [https://ralphy-spec.org/ja/docs/](https://ralphy-spec.org/ja/docs/)
9
+ **変更履歴:** [https://ralphy-spec.org/ja/changelog/](https://ralphy-spec.org/ja/changelog/) · [GitHub](https://github.com/wenqingyu/ralphy-openspec/blob/main/CHANGELOG.md)
8
10
 
9
11
  ## クイックスタート
10
12
 
@@ -12,25 +14,34 @@
12
14
  npx ralphy-spec init
13
15
  ```
14
16
 
17
+ CLI 基本:
18
+
19
+ ```bash
20
+ ralphy-spec run --dry-run
21
+ ralphy-spec run
22
+ ralphy-spec status
23
+ ralphy-spec budget --json
24
+ ```
25
+
15
26
  次に、AIツールに対応するコマンドを使用します:
16
27
 
17
28
  ### Cursor
18
29
 
19
30
  | コマンド | 機能 |
20
31
  |----------|------|
21
- | `/ralphy:plan` | 要件からスペック作成 |
22
- | `/ralphy:implement` | 反復ループでビルド |
23
- | `/ralphy:validate` | 受け入れ基準を検証 |
24
- | `/ralphy:archive` | 完了してアーカイブ |
32
+ | `/ralphy-plan` | 要件からスペック作成 |
33
+ | `/ralphy-implement` | 反復ループでビルド |
34
+ | `/ralphy-validate` | 受け入れ基準を検証 |
35
+ | `/ralphy-archive` | 完了してアーカイブ |
25
36
 
26
37
  ### Claude Code
27
38
 
28
39
  | コマンド | 機能 |
29
40
  |----------|------|
30
- | `/ralphy:plan` | 要件からスペック作成 |
31
- | `/ralphy:implement` | 反復ループでビルド |
32
- | `/ralphy:validate` | 受け入れ基準を検証 |
33
- | `/ralphy:archive` | 完了してアーカイブ |
41
+ | `/ralphy-plan` | 要件からスペック作成 |
42
+ | `/ralphy-implement` | 反復ループでビルド |
43
+ | `/ralphy-validate` | 受け入れ基準を検証 |
44
+ | `/ralphy-archive` | 完了してアーカイブ |
34
45
 
35
46
  ### OpenCode
36
47
 
@@ -50,16 +61,16 @@ ralph "Follow AGENTS.md to implement add-api. Output <promise>TASK_COMPLETE</pro
50
61
 
51
62
  ```bash
52
63
  # 1. 計画: アイデアからスペック作成
53
- You: /ralphy:plan JWT ユーザー認証を追加
64
+ You: /ralphy-plan JWT ユーザー認証を追加
54
65
 
55
66
  # 2. 実装: AIが反復的にビルド
56
- You: /ralphy:implement add-user-auth
67
+ You: /ralphy-implement add-user-auth
57
68
 
58
69
  # 3. 検証: テストパスを確認
59
- You: /ralphy:validate
70
+ You: /ralphy-validate
60
71
 
61
72
  # 4. アーカイブ: 変更を完了
62
- You: /ralphy:archive add-user-auth
73
+ You: /ralphy-archive add-user-auth
63
74
  ```
64
75
 
65
76
  ## 作成されるファイル
@@ -79,11 +90,23 @@ openspec/
79
90
  ├── archive/ # 完了
80
91
  └── project.md # コンテキスト
81
92
 
82
- .ralphy/
83
- ├── config.json
84
- └── ralph-loop.state.json
93
+ ralphy-spec/ # ローカル状態 + アーティファクト(IDE向け)
94
+ ├── state.db # SQLite 実行/タスクログ
95
+ ├── STATUS.md # ライブ状態(`ralphy-spec status` が優先)
96
+ ├── TASKS.md # タスクボード
97
+ ├── BUDGET.md # コスト/予算
98
+ ├── runs/ # 不変の実行ログ(`runs/<runId>.md`)
99
+ ├── logs/ # バックエンド出力(ベストエフォート)
100
+ ├── worktrees/ # Git worktree(worktreeモード時)
101
+ └── tasks/ # タスク別アーティファクト(CONTEXT / REPAIR / NOTES)
102
+ └── <taskId>/
103
+ ├── CONTEXT.md
104
+ ├── REPAIR.md
105
+ └── NOTES.md
85
106
  ```
86
107
 
108
+ > 注: 既存の `.ralphy/` フォルダが見つかった場合、`ralphy-spec/` へ自動的に移行します。
109
+
87
110
  ## 仕組み
88
111
 
89
112
  **Ralph Wiggum Loop:** AIがタスク完了まで同じプロンプトを繰り返し受け取ります。各イテレーションで、ファイルの以前の作業を見て自己修正します。
package/README.ko.md CHANGED
@@ -5,6 +5,8 @@
5
5
  **스펙 기반 AI 개발 + 반복 실행.** OpenSpec과 Ralph Loop를 결합하여 예측 가능한 AI 지원 코딩을 실현합니다.
6
6
 
7
7
  **웹사이트:** [https://ralphy-spec.org](https://ralphy-spec.org)
8
+ **문서:** [https://ralphy-spec.org/ko/docs/](https://ralphy-spec.org/ko/docs/)
9
+ **변경 로그:** [https://ralphy-spec.org/ko/changelog/](https://ralphy-spec.org/ko/changelog/) · [GitHub](https://github.com/wenqingyu/ralphy-openspec/blob/main/CHANGELOG.md)
8
10
 
9
11
  ## 빠른 시작
10
12
 
@@ -12,25 +14,34 @@
12
14
  npx ralphy-spec init
13
15
  ```
14
16
 
17
+ CLI 기본 사용:
18
+
19
+ ```bash
20
+ ralphy-spec run --dry-run
21
+ ralphy-spec run
22
+ ralphy-spec status
23
+ ralphy-spec budget --json
24
+ ```
25
+
15
26
  그런 다음 AI 도구에 맞는 명령을 사용하세요:
16
27
 
17
28
  ### Cursor
18
29
 
19
30
  | 명령 | 기능 |
20
31
  |------|------|
21
- | `/ralphy:plan` | 요구사항에서 스펙 생성 |
22
- | `/ralphy:implement` | 반복 루프로 빌드 |
23
- | `/ralphy:validate` | 인수 기준 검증 |
24
- | `/ralphy:archive` | 완료 및 아카이브 |
32
+ | `/ralphy-plan` | 요구사항에서 스펙 생성 |
33
+ | `/ralphy-implement` | 반복 루프로 빌드 |
34
+ | `/ralphy-validate` | 인수 기준 검증 |
35
+ | `/ralphy-archive` | 완료 및 아카이브 |
25
36
 
26
37
  ### Claude Code
27
38
 
28
39
  | 명령 | 기능 |
29
40
  |------|------|
30
- | `/ralphy:plan` | 요구사항에서 스펙 생성 |
31
- | `/ralphy:implement` | 반복 루프로 빌드 |
32
- | `/ralphy:validate` | 인수 기준 검증 |
33
- | `/ralphy:archive` | 완료 및 아카이브 |
41
+ | `/ralphy-plan` | 요구사항에서 스펙 생성 |
42
+ | `/ralphy-implement` | 반복 루프로 빌드 |
43
+ | `/ralphy-validate` | 인수 기준 검증 |
44
+ | `/ralphy-archive` | 완료 및 아카이브 |
34
45
 
35
46
  ### OpenCode
36
47
 
@@ -50,16 +61,16 @@ ralph "Follow AGENTS.md to implement add-api. Output <promise>TASK_COMPLETE</pro
50
61
 
51
62
  ```bash
52
63
  # 1. 계획: 아이디어에서 스펙 생성
53
- You: /ralphy:plan JWT 사용자 인증 추가
64
+ You: /ralphy-plan JWT 사용자 인증 추가
54
65
 
55
66
  # 2. 구현: AI가 반복적으로 빌드
56
- You: /ralphy:implement add-user-auth
67
+ You: /ralphy-implement add-user-auth
57
68
 
58
69
  # 3. 검증: 테스트 통과 확인
59
- You: /ralphy:validate
70
+ You: /ralphy-validate
60
71
 
61
72
  # 4. 아카이브: 변경 완료
62
- You: /ralphy:archive add-user-auth
73
+ You: /ralphy-archive add-user-auth
63
74
  ```
64
75
 
65
76
  ## 생성되는 파일
@@ -79,11 +90,23 @@ openspec/
79
90
  ├── archive/ # 완료됨
80
91
  └── project.md # 컨텍스트
81
92
 
82
- .ralphy/
83
- ├── config.json
84
- └── ralph-loop.state.json
93
+ ralphy-spec/ # 로컬 상태 + 아티팩트(IDE 친화적)
94
+ ├── state.db # SQLite 실행/태스크 로그
95
+ ├── STATUS.md # 라이브 상태(`ralphy-spec status`가 우선 사용)
96
+ ├── TASKS.md # 태스크 보드
97
+ ├── BUDGET.md # 비용/예산
98
+ ├── runs/ # 불변 실행 로그(`runs/<runId>.md`)
99
+ ├── logs/ # 백엔드 원본 출력(가능한 경우)
100
+ ├── worktrees/ # Git worktree(worktree 모드 사용 시)
101
+ └── tasks/ # 태스크별 아티팩트(CONTEXT / REPAIR / NOTES)
102
+ └── <taskId>/
103
+ ├── CONTEXT.md
104
+ ├── REPAIR.md
105
+ └── NOTES.md
85
106
  ```
86
107
 
108
+ > 참고: 기존 `.ralphy/` 폴더가 있으면 자동으로 `ralphy-spec/`로 마이그레이션됩니다.
109
+
87
110
  ## 작동 방식
88
111
 
89
112
  **Ralph Wiggum Loop:** AI가 작업 완료까지 동일한 프롬프트를 반복적으로 받습니다. 각 반복에서 파일의 이전 작업을 보고 자기 수정합니다.
package/README.md CHANGED
@@ -5,6 +5,8 @@
5
5
  **Spec-driven AI development with iterative execution.** Combines OpenSpec + Ralph Loop for predictable AI-assisted coding.
6
6
 
7
7
  **Website:** [https://ralphy-spec.org](https://ralphy-spec.org)
8
+ **Docs:** [https://ralphy-spec.org/en/docs/](https://ralphy-spec.org/en/docs/)
9
+ **Changelog:** [https://ralphy-spec.org/en/changelog/](https://ralphy-spec.org/en/changelog/) · [GitHub](https://github.com/wenqingyu/ralphy-openspec/blob/main/CHANGELOG.md)
8
10
 
9
11
  ## Quick Start
10
12
 
@@ -12,25 +14,34 @@
12
14
  npx ralphy-spec init
13
15
  ```
14
16
 
17
+ CLI basics:
18
+
19
+ ```bash
20
+ ralphy-spec run --dry-run
21
+ ralphy-spec run
22
+ ralphy-spec status
23
+ ralphy-spec budget --json
24
+ ```
25
+
15
26
  Then use the commands for your AI tool:
16
27
 
17
28
  ### Cursor
18
29
 
19
30
  | Command | What it does |
20
31
  |---------|--------------|
21
- | `/ralphy:plan` | Create specs from requirements |
22
- | `/ralphy:implement` | Build with iterative loop |
23
- | `/ralphy:validate` | Verify acceptance criteria |
24
- | `/ralphy:archive` | Complete and archive |
32
+ | `/ralphy-plan` | Create specs from requirements |
33
+ | `/ralphy-implement` | Build with iterative loop |
34
+ | `/ralphy-validate` | Verify acceptance criteria |
35
+ | `/ralphy-archive` | Complete and archive |
25
36
 
26
37
  ### Claude Code
27
38
 
28
39
  | Command | What it does |
29
40
  |---------|--------------|
30
- | `/ralphy:plan` | Create specs from requirements |
31
- | `/ralphy:implement` | Build with iterative loop |
32
- | `/ralphy:validate` | Verify acceptance criteria |
33
- | `/ralphy:archive` | Complete and archive |
41
+ | `/ralphy-plan` | Create specs from requirements |
42
+ | `/ralphy-implement` | Build with iterative loop |
43
+ | `/ralphy-validate` | Verify acceptance criteria |
44
+ | `/ralphy-archive` | Complete and archive |
34
45
 
35
46
  ### OpenCode
36
47
 
@@ -50,16 +61,16 @@ ralph "Follow AGENTS.md to implement add-api. Output <promise>TASK_COMPLETE</pro
50
61
 
51
62
  ```bash
52
63
  # 1. Plan: Create spec from your idea
53
- You: /ralphy:plan Add user authentication with JWT
64
+ You: /ralphy-plan Add user authentication with JWT
54
65
 
55
66
  # 2. Implement: AI builds it iteratively
56
- You: /ralphy:implement add-user-auth
67
+ You: /ralphy-implement add-user-auth
57
68
 
58
69
  # 3. Validate: Verify tests pass
59
- You: /ralphy:validate
70
+ You: /ralphy-validate
60
71
 
61
72
  # 4. Archive: Complete the change
62
- You: /ralphy:archive add-user-auth
73
+ You: /ralphy-archive add-user-auth
63
74
  ```
64
75
 
65
76
  ## What Gets Created
@@ -79,11 +90,23 @@ openspec/
79
90
  ├── archive/ # Completed
80
91
  └── project.md # Context
81
92
 
82
- .ralphy/
83
- ├── config.json
84
- └── ralph-loop.state.json
93
+ ralphy-spec/ # Local state + artifacts (IDE-friendly)
94
+ ├── state.db # SQLite run/task ledger
95
+ ├── STATUS.md # Live run snapshot (primary for `ralphy-spec status`)
96
+ ├── TASKS.md # Task board view
97
+ ├── BUDGET.md # Spend/budget breakdown
98
+ ├── runs/ # Immutable run logs (`runs/<runId>.md`)
99
+ ├── logs/ # Raw backend outputs (best-effort)
100
+ ├── worktrees/ # Git worktrees per task (when enabled)
101
+ └── tasks/ # Per-task artifacts (CONTEXT / REPAIR / NOTES)
102
+ └── <taskId>/
103
+ ├── CONTEXT.md
104
+ ├── REPAIR.md
105
+ └── NOTES.md
85
106
  ```
86
107
 
108
+ > Note: Legacy `.ralphy/` folders are migrated to `ralphy-spec/` automatically when found.
109
+
87
110
  ## How It Works
88
111
 
89
112
  **Ralph Wiggum Loop:** AI receives the same prompt repeatedly until task completion. Each iteration, it sees previous work in files and self-corrects.
package/README.zh.md CHANGED
@@ -5,6 +5,8 @@
5
5
  **规范驱动的 AI 开发 + 迭代执行。** 结合 OpenSpec 和 Ralph 循环,实现可预测的 AI 辅助编码。
6
6
 
7
7
  **官网:** [https://ralphy-spec.org](https://ralphy-spec.org)
8
+ **文档:** [https://ralphy-spec.org/zh/docs/](https://ralphy-spec.org/zh/docs/)
9
+ **更新日志:** [https://ralphy-spec.org/zh/changelog/](https://ralphy-spec.org/zh/changelog/) · [GitHub](https://github.com/wenqingyu/ralphy-openspec/blob/main/CHANGELOG.md)
8
10
 
9
11
  ## 快速开始
10
12
 
@@ -12,25 +14,34 @@
12
14
  npx ralphy-spec init
13
15
  ```
14
16
 
17
+ CLI 基础用法:
18
+
19
+ ```bash
20
+ ralphy-spec run --dry-run
21
+ ralphy-spec run
22
+ ralphy-spec status
23
+ ralphy-spec budget --json
24
+ ```
25
+
15
26
  然后使用你的 AI 工具对应的命令:
16
27
 
17
28
  ### Cursor
18
29
 
19
30
  | 命令 | 功能 |
20
31
  |------|------|
21
- | `/ralphy:plan` | 从需求创建规范 |
22
- | `/ralphy:implement` | 迭代循环构建 |
23
- | `/ralphy:validate` | 验证验收标准 |
24
- | `/ralphy:archive` | 完成并归档 |
32
+ | `/ralphy-plan` | 从需求创建规范 |
33
+ | `/ralphy-implement` | 迭代循环构建 |
34
+ | `/ralphy-validate` | 验证验收标准 |
35
+ | `/ralphy-archive` | 完成并归档 |
25
36
 
26
37
  ### Claude Code
27
38
 
28
39
  | 命令 | 功能 |
29
40
  |------|------|
30
- | `/ralphy:plan` | 从需求创建规范 |
31
- | `/ralphy:implement` | 迭代循环构建 |
32
- | `/ralphy:validate` | 验证验收标准 |
33
- | `/ralphy:archive` | 完成并归档 |
41
+ | `/ralphy-plan` | 从需求创建规范 |
42
+ | `/ralphy-implement` | 迭代循环构建 |
43
+ | `/ralphy-validate` | 验证验收标准 |
44
+ | `/ralphy-archive` | 完成并归档 |
34
45
 
35
46
  ### OpenCode
36
47
 
@@ -50,16 +61,16 @@ ralph "Follow AGENTS.md to implement add-api. Output <promise>TASK_COMPLETE</pro
50
61
 
51
62
  ```bash
52
63
  # 1. 规划:从你的想法创建规范
53
- You: /ralphy:plan 添加 JWT 用户认证
64
+ You: /ralphy-plan 添加 JWT 用户认证
54
65
 
55
66
  # 2. 实现:AI 迭代构建
56
- You: /ralphy:implement add-user-auth
67
+ You: /ralphy-implement add-user-auth
57
68
 
58
69
  # 3. 验证:确保测试通过
59
- You: /ralphy:validate
70
+ You: /ralphy-validate
60
71
 
61
72
  # 4. 归档:完成变更
62
- You: /ralphy:archive add-user-auth
73
+ You: /ralphy-archive add-user-auth
63
74
  ```
64
75
 
65
76
  ## 创建的文件
@@ -79,11 +90,23 @@ openspec/
79
90
  ├── archive/ # 已完成
80
91
  └── project.md # 上下文
81
92
 
82
- .ralphy/
83
- ├── config.json
84
- └── ralph-loop.state.json
93
+ ralphy-spec/ # 本地状态 + 可读产物(IDE 友好)
94
+ ├── state.db # SQLite 运行/任务日志
95
+ ├── STATUS.md # 实时状态(`ralphy-spec status` 优先读取)
96
+ ├── TASKS.md # 任务看板
97
+ ├── BUDGET.md # 花费/预算
98
+ ├── runs/ # 不可变运行日志(`runs/<runId>.md`)
99
+ ├── logs/ # 后端原始输出(尽力写入)
100
+ ├── worktrees/ # Git worktree(启用 worktree 模式时)
101
+ └── tasks/ # 单任务产物(CONTEXT / REPAIR / NOTES)
102
+ └── <taskId>/
103
+ ├── CONTEXT.md
104
+ ├── REPAIR.md
105
+ └── NOTES.md
85
106
  ```
86
107
 
108
+ > 注意:如果检测到旧的 `.ralphy/`,会自动迁移到 `ralphy-spec/` 并提示。
109
+
87
110
  ## 工作原理
88
111
 
89
112
  **Ralph Wiggum 循环:** AI 重复接收相同提示直到任务完成。每次迭代,它都能看到文件中的之前工作并自我纠正。
@@ -0,0 +1,3 @@
1
+ import type { Command } from "commander";
2
+ export declare function registerBudgetCommand(program: Command): void;
3
+ //# sourceMappingURL=budget.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"budget.d.ts","sourceRoot":"","sources":["../../src/cli/budget.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAQzC,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAwE5D"}
@@ -0,0 +1,77 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.registerBudgetCommand = registerBudgetCommand;
7
+ const promises_1 = __importDefault(require("node:fs/promises"));
8
+ const node_path_1 = __importDefault(require("node:path"));
9
+ const persistence_1 = require("../core/memory/persistence");
10
+ const folders_1 = require("../core/folders");
11
+ const spend_1 = require("../core/reporting/spend");
12
+ const loader_1 = require("../core/spec/loader");
13
+ function registerBudgetCommand(program) {
14
+ program
15
+ .command("budget")
16
+ .description("Show budget/spend information for the latest run")
17
+ .option("--json", "Machine-readable output", false)
18
+ .action(async (opts) => {
19
+ const repoRoot = process.cwd();
20
+ const candidateRoots = [];
21
+ try {
22
+ const spec = await new loader_1.SpecLoader(repoRoot).loadProjectSpec();
23
+ if (spec.artifacts?.rootDir)
24
+ candidateRoots.push(spec.artifacts.rootDir);
25
+ }
26
+ catch {
27
+ // ignore
28
+ }
29
+ candidateRoots.push(undefined);
30
+ for (const rootDir of candidateRoots) {
31
+ const budgetPath = node_path_1.default.join((0, folders_1.getRalphyRoot)(repoRoot, rootDir), folders_1.FILES.budget);
32
+ try {
33
+ const md = await promises_1.default.readFile(budgetPath, "utf8");
34
+ if (!opts.json) {
35
+ process.stdout.write(md.trimEnd() + "\n");
36
+ return;
37
+ }
38
+ // If JSON requested, fall back to DB-derived structure below.
39
+ break;
40
+ }
41
+ catch {
42
+ // try next
43
+ }
44
+ }
45
+ const persistence = await persistence_1.PersistenceLayer.openForRepo(repoRoot);
46
+ try {
47
+ const run = persistence.getLatestRun();
48
+ if (!run) {
49
+ process.stdout.write(opts.json ? JSON.stringify({ ok: true, run: null }) + "\n" : "No runs found.\n");
50
+ return;
51
+ }
52
+ const ledger = persistence.listLedger({ runId: run.runId, limit: 2000 });
53
+ const entries = (0, spend_1.extractSpendFromLedger)(ledger);
54
+ const breakdown = (0, spend_1.aggregateSpend)(entries);
55
+ if (opts.json) {
56
+ process.stdout.write(JSON.stringify({
57
+ ok: true,
58
+ runId: run.runId,
59
+ spend: {
60
+ total: breakdown.total,
61
+ byTask: Object.fromEntries(breakdown.byTask),
62
+ byBackend: Object.fromEntries(breakdown.byBackend),
63
+ byPhase: Object.fromEntries(breakdown.byPhase),
64
+ entries: breakdown.entries,
65
+ },
66
+ }, null, 2) + "\n");
67
+ }
68
+ else {
69
+ process.stdout.write(`No ${folders_1.FILES.budget} artifact found.\nRun again with artifacts enabled to generate it.\n`);
70
+ }
71
+ }
72
+ finally {
73
+ persistence.close();
74
+ }
75
+ });
76
+ }
77
+ //# sourceMappingURL=budget.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"budget.js","sourceRoot":"","sources":["../../src/cli/budget.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/cli/init.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAuCzC,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAkC1D"}
1
+ {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/cli/init.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAwCzC,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAyC1D"}
package/dist/cli/init.js CHANGED
@@ -8,6 +8,7 @@ const inquirer_1 = __importDefault(require("inquirer"));
8
8
  const detector_1 = require("../utils/detector");
9
9
  const installer_1 = require("../utils/installer");
10
10
  const paths_1 = require("../utils/paths");
11
+ const folders_1 = require("../core/folders");
11
12
  function parseToolsArg(arg) {
12
13
  if (!arg)
13
14
  return undefined;
@@ -60,7 +61,12 @@ function registerInitCommand(program) {
60
61
  const tools = options.tools ?? (await promptForTools(defaultTools));
61
62
  await (0, installer_1.ensureOpenSpecScaffold)(options.dir);
62
63
  await (0, installer_1.installToolTemplates)(options.dir, tools, { force: options.force });
64
+ await (0, folders_1.ensureRalphyFolders)(options.dir);
63
65
  process.stdout.write(`Initialized Ralph-OpenSpec in ${options.dir}\nConfigured tools: ${tools.join(", ")}\n`);
66
+ process.stdout.write(`\nArtifact folder created: ${(0, folders_1.getRalphyRoot)(options.dir)}\n` +
67
+ `\n.gitignore suggestions:\n` +
68
+ `- Commit: ${(0, folders_1.getRalphyRoot)(options.dir)}/STATUS.md, ${(0, folders_1.getRalphyRoot)(options.dir)}/TASKS.md, ${(0, folders_1.getRalphyRoot)(options.dir)}/BUDGET.md\n` +
69
+ `- Ignore: ${(0, folders_1.getRalphyRoot)(options.dir)}/state.db, ${(0, folders_1.getRalphyRoot)(options.dir)}/runs/, ${(0, folders_1.getRalphyRoot)(options.dir)}/logs/, ${(0, folders_1.getRalphyRoot)(options.dir)}/worktrees/\n`);
64
70
  });
65
71
  }
66
72
  //# sourceMappingURL=init.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/cli/init.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/cli/init.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../src/cli/run.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAQzC,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA+EzD"}
1
+ {"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../src/cli/run.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA4BzC,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAiGzD"}
package/dist/cli/run.js CHANGED
@@ -7,18 +7,42 @@ exports.registerRunCommand = registerRunCommand;
7
7
  const node_path_1 = __importDefault(require("node:path"));
8
8
  const loader_1 = require("../core/spec/loader");
9
9
  const dag_1 = require("../core/spec/dag");
10
+ const claude_code_1 = require("../core/backends/claude-code");
11
+ const cursor_1 = require("../core/backends/cursor");
10
12
  const noop_1 = require("../core/backends/noop");
13
+ const opencode_1 = require("../core/backends/opencode");
11
14
  const patch_mode_1 = require("../core/workspace/patch-mode");
15
+ const worktree_mode_1 = require("../core/workspace/worktree-mode");
12
16
  const loop_1 = require("../core/engine/loop");
17
+ function createBackend(id) {
18
+ switch (id) {
19
+ case "cursor":
20
+ return new cursor_1.CursorBackend();
21
+ case "opencode":
22
+ return new opencode_1.OpenCodeBackend();
23
+ case "claude-code":
24
+ return new claude_code_1.ClaudeCodeBackend();
25
+ case "noop":
26
+ return new noop_1.NoopBackend("noop");
27
+ default:
28
+ // Fallback: treat as noop for unknown ids (but retain id for diagnostics).
29
+ return new noop_1.NoopBackend(id);
30
+ }
31
+ }
13
32
  function registerRunCommand(program) {
14
33
  program
15
34
  .command("run")
16
35
  .description("Execute the ralphy-spec engine loop")
17
- .option("--backend <id>", "Backend id: cursor|opencode|claude-code", "cursor")
18
- .option("--workspace <mode>", "Workspace mode: worktree|patch", "patch")
36
+ .option("--backend <id>", "Backend id: cursor|opencode|claude-code|noop")
37
+ .option("--workspace <mode>", "Workspace mode: worktree|patch")
38
+ .option("--artifact-dir <dir>", "Override artifact root directory (enables artifacts)")
19
39
  .option("--task <taskId>", "Run a single task (skips dependency checks)")
20
40
  .option("--dry-run", "Validate spec and print plan only", false)
21
41
  .option("--json", "Machine-readable output", false)
42
+ .addHelpText("after", `\nConcepts:\n` +
43
+ `- Budget tiers: optimal -> warning -> hard. WARNING enables degrade behaviors; HARD blocks the task.\n` +
44
+ `- Sprint sizing: XS/S/M/L/XL (optional per task via sprint.size).\n` +
45
+ `- Sprint intent: fix|feature|refactor|infra (optional per task via sprint.intent).\n`)
22
46
  .action(async (opts) => {
23
47
  const repoRoot = process.cwd();
24
48
  const loader = new loader_1.SpecLoader(repoRoot);
@@ -32,6 +56,16 @@ function registerRunCommand(program) {
32
56
  process.exitCode = 4;
33
57
  return;
34
58
  }
59
+ if (opts.artifactDir) {
60
+ spec = {
61
+ ...spec,
62
+ artifacts: {
63
+ ...(spec.artifacts ?? {}),
64
+ enabled: true,
65
+ rootDir: opts.artifactDir,
66
+ },
67
+ };
68
+ }
35
69
  // Always build DAG in run/dry-run to validate deps/cycles unless --task is used.
36
70
  try {
37
71
  if (!opts.task)
@@ -50,13 +84,12 @@ function registerRunCommand(program) {
50
84
  process.stdout.write(opts.json ? JSON.stringify(out, null, 2) + "\n" : `${plan.join("\n")}\n`);
51
85
  return;
52
86
  }
53
- if (opts.workspace === "worktree") {
54
- process.stderr.write(`Workspace mode "worktree" is not implemented in this MVP. Use --workspace patch.\n`);
55
- process.exitCode = 6;
56
- return;
57
- }
58
- const backend = new noop_1.NoopBackend(opts.backend);
59
- const workspace = new patch_mode_1.PatchModeWorkspace(node_path_1.default.resolve(repoRoot));
87
+ const backendId = opts.backend ?? spec.defaults.backend ?? "cursor";
88
+ const workspaceMode = opts.workspace ?? spec.defaults.workspaceMode ?? "patch";
89
+ const backend = createBackend(backendId);
90
+ const workspace = workspaceMode === "worktree"
91
+ ? new worktree_mode_1.WorktreeModeWorkspace(node_path_1.default.resolve(repoRoot))
92
+ : new patch_mode_1.PatchModeWorkspace(node_path_1.default.resolve(repoRoot));
60
93
  const engine = new loop_1.EngineLoop();
61
94
  const outcome = await engine.run({
62
95
  repoRoot,