sdd-forge 0.1.0-alpha.3 → 0.1.0-alpha.32

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 (250) hide show
  1. package/README.md +123 -31
  2. package/package.json +13 -6
  3. package/src/README.md +201 -0
  4. package/src/docs/commands/agents.js +213 -0
  5. package/src/docs/commands/changelog.js +242 -0
  6. package/src/docs/commands/data.js +188 -0
  7. package/src/docs/commands/enrich.js +439 -0
  8. package/src/docs/commands/forge.js +458 -0
  9. package/src/docs/commands/init.js +256 -0
  10. package/src/docs/commands/readme.js +187 -0
  11. package/src/docs/commands/review.js +308 -0
  12. package/src/docs/commands/scan.js +365 -0
  13. package/src/docs/commands/text.js +714 -0
  14. package/src/docs/commands/translate.js +228 -0
  15. package/src/docs/data/agents.js +138 -0
  16. package/src/docs/data/docs.js +219 -0
  17. package/src/docs/data/lang.js +109 -0
  18. package/src/docs/data/project.js +56 -0
  19. package/src/docs/lib/command-context.js +180 -0
  20. package/src/docs/lib/concurrency.js +47 -0
  21. package/src/docs/lib/data-source-loader.js +44 -0
  22. package/src/docs/lib/data-source.js +102 -0
  23. package/src/docs/lib/directive-parser.js +314 -0
  24. package/src/docs/lib/forge-prompts.js +199 -0
  25. package/src/docs/lib/resolver-factory.js +118 -0
  26. package/src/docs/lib/review-parser.js +85 -0
  27. package/src/docs/lib/scan-source.js +59 -0
  28. package/src/docs/lib/scanner.js +292 -0
  29. package/src/docs/lib/template-merger.js +386 -0
  30. package/src/docs/lib/test-env-detection.js +50 -0
  31. package/src/docs/lib/text-prompts.js +286 -0
  32. package/src/docs.js +215 -0
  33. package/src/flow/commands/cleanup.js +86 -0
  34. package/src/flow/commands/merge.js +88 -0
  35. package/src/flow/commands/resume.js +163 -0
  36. package/src/flow/commands/review.js +301 -0
  37. package/src/flow/{flow.js → commands/start.js} +65 -35
  38. package/src/flow/commands/status.js +227 -0
  39. package/src/flow.js +59 -0
  40. package/src/help.js +69 -42
  41. package/src/lib/agent.js +342 -0
  42. package/src/lib/agents-md.js +25 -0
  43. package/src/lib/cli.js +66 -0
  44. package/src/lib/config.js +74 -2
  45. package/src/lib/entrypoint.js +23 -0
  46. package/src/lib/flow-state.js +199 -0
  47. package/src/lib/i18n.js +274 -0
  48. package/src/lib/presets.js +81 -0
  49. package/src/lib/progress.js +217 -0
  50. package/src/lib/types.js +251 -0
  51. package/src/locale/en/messages.json +117 -0
  52. package/src/locale/en/prompts.json +70 -0
  53. package/src/locale/en/ui.json +354 -0
  54. package/src/locale/ja/messages.json +117 -0
  55. package/src/locale/ja/prompts.json +70 -0
  56. package/src/locale/ja/ui.json +354 -0
  57. package/src/presets/base/data/package.js +52 -0
  58. package/src/presets/base/preset.json +11 -0
  59. package/src/presets/base/templates/en/AGENTS.sdd.md +24 -0
  60. package/src/presets/base/templates/en/development.md +40 -0
  61. package/src/presets/base/templates/en/guardrail.md +18 -0
  62. package/src/presets/base/templates/en/overview.md +43 -0
  63. package/src/presets/base/templates/en/project_structure.md +33 -0
  64. package/src/presets/base/templates/en/stack_and_ops.md +40 -0
  65. package/src/presets/base/templates/ja/AGENTS.sdd.md +24 -0
  66. package/src/presets/base/templates/ja/development.md +40 -0
  67. package/src/presets/base/templates/ja/guardrail.md +18 -0
  68. package/src/presets/base/templates/ja/overview.md +43 -0
  69. package/src/presets/base/templates/ja/project_structure.md +33 -0
  70. package/src/presets/base/templates/ja/stack_and_ops.md +40 -0
  71. package/src/presets/cakephp2/data/config.js +176 -0
  72. package/src/presets/cakephp2/data/controllers.js +117 -0
  73. package/src/presets/cakephp2/data/docker.js +17 -0
  74. package/src/presets/cakephp2/data/email.js +35 -0
  75. package/src/presets/cakephp2/data/libs.js +76 -0
  76. package/src/presets/cakephp2/data/models.js +118 -0
  77. package/src/presets/cakephp2/data/shells.js +48 -0
  78. package/src/presets/cakephp2/data/tables.js +122 -0
  79. package/src/presets/cakephp2/data/tests.js +30 -0
  80. package/src/presets/cakephp2/data/views.js +56 -0
  81. package/src/presets/cakephp2/preset.json +14 -0
  82. package/src/presets/cakephp2/scan/assets.js +68 -0
  83. package/src/presets/cakephp2/scan/base-classes.js +170 -0
  84. package/src/presets/cakephp2/scan/business.js +102 -0
  85. package/src/presets/cakephp2/scan/config.js +129 -0
  86. package/src/{analyzers/analyze-models.js → presets/cakephp2/scan/models.js} +3 -1
  87. package/src/presets/cakephp2/scan/notifications.js +78 -0
  88. package/src/presets/cakephp2/scan/security.js +85 -0
  89. package/src/presets/cakephp2/scan/shells-detail.js +56 -0
  90. package/src/presets/cakephp2/scan/testing.js +37 -0
  91. package/src/presets/cakephp2/scan/views.js +228 -0
  92. package/src/presets/cakephp2/templates/en/guardrail.md +11 -0
  93. package/src/presets/cakephp2/templates/ja/auth_and_session.md +22 -0
  94. package/src/presets/cakephp2/templates/ja/controller_routes.md +13 -0
  95. package/src/presets/cakephp2/templates/ja/db_tables.md +22 -0
  96. package/src/presets/cakephp2/templates/ja/development.md +50 -0
  97. package/src/presets/cakephp2/templates/ja/guardrail.md +11 -0
  98. package/src/presets/cakephp2/templates/ja/project_structure.md +39 -0
  99. package/src/presets/cakephp2/templates/ja/stack_and_ops.md +48 -0
  100. package/src/presets/cli/data/modules.js +52 -0
  101. package/src/presets/cli/preset.json +13 -0
  102. package/src/presets/cli/templates/en/README.md +37 -0
  103. package/src/presets/cli/templates/en/commands.md +40 -0
  104. package/src/presets/cli/templates/en/config.md +40 -0
  105. package/src/presets/cli/templates/en/guardrail.md +8 -0
  106. package/src/presets/cli/templates/ja/README.md +37 -0
  107. package/src/presets/cli/templates/ja/commands.md +40 -0
  108. package/src/presets/cli/templates/ja/config.md +40 -0
  109. package/src/presets/cli/templates/ja/guardrail.md +8 -0
  110. package/src/presets/laravel/data/commands.js +24 -0
  111. package/src/presets/laravel/data/config.js +97 -0
  112. package/src/presets/laravel/data/controllers.js +81 -0
  113. package/src/presets/laravel/data/models.js +80 -0
  114. package/src/presets/laravel/data/routes.js +56 -0
  115. package/src/presets/laravel/data/tables.js +85 -0
  116. package/src/presets/laravel/preset.json +16 -0
  117. package/src/presets/laravel/scan/config.js +93 -0
  118. package/src/presets/laravel/scan/controllers.js +77 -0
  119. package/src/presets/laravel/scan/migrations.js +147 -0
  120. package/src/presets/laravel/scan/models.js +157 -0
  121. package/src/presets/laravel/scan/routes.js +121 -0
  122. package/src/presets/laravel/templates/en/guardrail.md +11 -0
  123. package/src/presets/laravel/templates/ja/auth_and_session.md +29 -0
  124. package/src/presets/laravel/templates/ja/controller_routes.md +44 -0
  125. package/src/presets/laravel/templates/ja/db_tables.md +22 -0
  126. package/src/presets/laravel/templates/ja/guardrail.md +11 -0
  127. package/src/presets/laravel/templates/ja/project_structure.md +13 -0
  128. package/src/presets/laravel/templates/ja/stack_and_ops.md +42 -0
  129. package/src/presets/lib/composer-utils.js +61 -0
  130. package/src/presets/library/preset.json +13 -0
  131. package/src/presets/library/templates/en/guardrail.md +5 -0
  132. package/src/presets/library/templates/ja/README.md +18 -0
  133. package/src/presets/library/templates/ja/guardrail.md +5 -0
  134. package/src/presets/library/templates/ja/public_api.md +33 -0
  135. package/src/presets/library/templates/ja/usage.md +40 -0
  136. package/src/presets/node-cli/preset.json +16 -0
  137. package/src/presets/node-cli/templates/en/README.md +31 -0
  138. package/src/presets/node-cli/templates/en/cli_commands.md +30 -0
  139. package/src/presets/node-cli/templates/en/configuration.md +30 -0
  140. package/src/presets/node-cli/templates/en/development_testing.md +48 -0
  141. package/src/presets/node-cli/templates/en/guardrail.md +5 -0
  142. package/src/presets/node-cli/templates/en/internal_design.md +35 -0
  143. package/src/presets/node-cli/templates/en/overview.md +30 -0
  144. package/src/presets/node-cli/templates/ja/README.md +31 -0
  145. package/src/presets/node-cli/templates/ja/cli_commands.md +30 -0
  146. package/src/presets/node-cli/templates/ja/commands.md +2 -0
  147. package/src/presets/node-cli/templates/ja/config.md +2 -0
  148. package/src/presets/node-cli/templates/ja/configuration.md +30 -0
  149. package/src/presets/node-cli/templates/ja/development.md +2 -0
  150. package/src/presets/node-cli/templates/ja/development_testing.md +48 -0
  151. package/src/presets/node-cli/templates/ja/guardrail.md +5 -0
  152. package/src/presets/node-cli/templates/ja/internal_design.md +35 -0
  153. package/src/presets/node-cli/templates/ja/overview.md +30 -0
  154. package/src/presets/node-cli/templates/ja/project_structure.md +2 -0
  155. package/src/presets/node-cli/templates/ja/stack_and_ops.md +2 -0
  156. package/src/presets/symfony/data/commands.js +24 -0
  157. package/src/presets/symfony/data/config.js +92 -0
  158. package/src/presets/symfony/data/controllers.js +72 -0
  159. package/src/presets/symfony/data/entities.js +67 -0
  160. package/src/presets/symfony/data/routes.js +70 -0
  161. package/src/presets/symfony/data/tables.js +67 -0
  162. package/src/presets/symfony/preset.json +16 -0
  163. package/src/presets/symfony/scan/config.js +101 -0
  164. package/src/presets/symfony/scan/controllers.js +96 -0
  165. package/src/presets/symfony/scan/entities.js +142 -0
  166. package/src/presets/symfony/scan/migrations.js +149 -0
  167. package/src/presets/symfony/scan/routes.js +199 -0
  168. package/src/presets/symfony/templates/en/guardrail.md +11 -0
  169. package/src/presets/symfony/templates/ja/auth_and_session.md +29 -0
  170. package/src/presets/symfony/templates/ja/controller_routes.md +42 -0
  171. package/src/presets/symfony/templates/ja/db_tables.md +29 -0
  172. package/src/presets/symfony/templates/ja/guardrail.md +11 -0
  173. package/src/presets/symfony/templates/ja/project_structure.md +13 -0
  174. package/src/presets/symfony/templates/ja/stack_and_ops.md +42 -0
  175. package/src/presets/webapp/data/controllers.js +74 -0
  176. package/src/presets/webapp/data/models.js +86 -0
  177. package/src/presets/webapp/data/routes.js +68 -0
  178. package/src/presets/webapp/data/shells.js +65 -0
  179. package/src/presets/webapp/data/tables.js +63 -0
  180. package/src/presets/webapp/data/webapp-data-source.js +26 -0
  181. package/src/presets/webapp/preset.json +17 -0
  182. package/src/presets/webapp/templates/en/guardrail.md +14 -0
  183. package/src/presets/webapp/templates/ja/README.md +24 -0
  184. package/src/presets/webapp/templates/ja/auth_and_session.md +46 -0
  185. package/src/presets/webapp/templates/ja/batch_and_shell.md +43 -0
  186. package/src/presets/webapp/templates/ja/business_logic.md +46 -0
  187. package/src/presets/webapp/templates/ja/controller_routes.md +50 -0
  188. package/src/presets/webapp/templates/ja/database_architecture.md +40 -0
  189. package/src/presets/webapp/templates/ja/db_tables.md +32 -0
  190. package/src/presets/webapp/templates/ja/guardrail.md +14 -0
  191. package/src/presets-cmd.js +67 -0
  192. package/src/sdd-forge.js +59 -0
  193. package/src/setup.js +571 -0
  194. package/src/spec/commands/gate.js +310 -0
  195. package/src/spec/commands/guardrail.js +251 -0
  196. package/src/spec/commands/init.js +324 -0
  197. package/src/spec.js +39 -0
  198. package/src/templates/config.example.json +49 -0
  199. package/src/templates/skills/sdd-forge.flow-impl/SKILL.md +148 -0
  200. package/src/templates/skills/sdd-forge.flow-merge/SKILL.md +178 -0
  201. package/src/templates/skills/sdd-forge.flow-plan/SKILL.md +254 -0
  202. package/src/templates/skills/sdd-forge.flow-resume/SKILL.md +33 -0
  203. package/src/templates/skills/sdd-forge.flow-status/SKILL.md +94 -0
  204. package/src/upgrade.js +183 -0
  205. package/src/analyzers/analyze-controllers.js +0 -85
  206. package/src/analyzers/analyze-extras.js +0 -944
  207. package/src/analyzers/analyze-routes.js +0 -50
  208. package/src/analyzers/analyze-shells.js +0 -75
  209. package/src/analyzers/scan.js +0 -116
  210. package/src/bin/sdd-forge.js +0 -133
  211. package/src/engine/directive-parser.js +0 -72
  212. package/src/engine/init.js +0 -253
  213. package/src/engine/populate.js +0 -192
  214. package/src/engine/readme.js +0 -174
  215. package/src/engine/renderers.js +0 -150
  216. package/src/engine/resolver.js +0 -568
  217. package/src/engine/tfill.js +0 -617
  218. package/src/forge/forge.js +0 -684
  219. package/src/projects/add.js +0 -73
  220. package/src/projects/projects.js +0 -91
  221. package/src/projects/setdefault.js +0 -37
  222. package/src/spec/gate.js +0 -101
  223. package/src/spec/spec.js +0 -198
  224. package/src/templates/checks/check-controller-coverage.sh +0 -46
  225. package/src/templates/checks/check-db-coverage.sh +0 -87
  226. package/src/templates/checks/check-node-cli-docs.sh +0 -125
  227. package/src/templates/checks/check-temp-docs.sh +0 -100
  228. package/src/templates/checks/generate-change-log.sh +0 -142
  229. package/src/templates/checks/self-review-temp-docs.sh +0 -19
  230. package/src/templates/locale/ja/messages.json +0 -9
  231. package/src/templates/locale/ja/node-cli/01_overview.md +0 -23
  232. package/src/templates/locale/ja/node-cli/02_cli_commands.md +0 -23
  233. package/src/templates/locale/ja/node-cli/03_configuration.md +0 -23
  234. package/src/templates/locale/ja/node-cli/04_internal_design.md +0 -30
  235. package/src/templates/locale/ja/node-cli/05_development.md +0 -49
  236. package/src/templates/locale/ja/node-cli/README.md +0 -41
  237. package/src/templates/locale/ja/php-mvc/01_architecture.md +0 -23
  238. package/src/templates/locale/ja/php-mvc/02_stack_and_ops.md +0 -45
  239. package/src/templates/locale/ja/php-mvc/03_project_structure.md +0 -46
  240. package/src/templates/locale/ja/php-mvc/04_development.md +0 -69
  241. package/src/templates/locale/ja/php-mvc/05_auth_and_session.md +0 -48
  242. package/src/templates/locale/ja/php-mvc/06_database_architecture.md +0 -23
  243. package/src/templates/locale/ja/php-mvc/07_db_tables.md +0 -31
  244. package/src/templates/locale/ja/php-mvc/08_controller_routes.md +0 -33
  245. package/src/templates/locale/ja/php-mvc/09_business_logic.md +0 -27
  246. package/src/templates/locale/ja/php-mvc/10_batch_and_shell.md +0 -25
  247. package/src/templates/locale/ja/php-mvc/README.md +0 -34
  248. package/src/templates/locale/ja/prompts.json +0 -4
  249. package/src/templates/locale/ja/sections.json +0 -6
  250. /package/src/{analyzers → docs}/lib/php-array-parser.js +0 -0
package/README.md CHANGED
@@ -1,45 +1,137 @@
1
- # {{PROJECT_NAME}}
1
+ # <!-- {{data: project.name("")}} -->sdd-forge<!-- {{/data}} -->
2
2
 
3
- {{PROJECT_DESCRIPTION}}
3
+ <!-- {{data: docs.langSwitcher("absolute")}} -->
4
+ **English** | [日本語](https://github.com/SpreadWorks/sdd-forge/blob/main/docs/ja/README.md)
5
+ <!-- {{/data}} -->
4
6
 
5
- ## 技術スタック
7
+ [![npm version](https://img.shields.io/npm/v/sdd-forge.svg)](https://www.npmjs.com/package/sdd-forge)
8
+ [![license](https://img.shields.io/npm/l/sdd-forge.svg)](https://opensource.org/licenses/MIT)
9
+ [![downloads](https://img.shields.io/npm/dm/sdd-forge.svg)](https://www.npmjs.com/package/sdd-forge)
6
10
 
7
- | カテゴリ | 技術 |
8
- |----------|------|
9
- | 言語 | Node.js (ES Modules) |
10
- | 配布 | npm |
11
- | テスト | — |
11
+ > **Alpha:** APIs, command structure, and configuration formats may change without notice.
12
12
 
13
- ## クイックスタート
13
+ ## Spec-Driven Development — Design, implement, and document in a single flow
14
14
 
15
- ```bash
16
- npm install -g {{PACKAGE_NAME}}
17
- {{PACKAGE_NAME}} help
15
+ A spec-first development flow manager designed to work with AI coding agents.
16
+
17
+ ## The SDD Flow
18
+
19
+ Every feature goes through three phases, from spec to merge.
20
+
21
+ ```
22
+ plan ─────── Specification
23
+ │ ├─ draft Refine requirements through dialogue
24
+ │ ├─ spec Create spec (feature branch + spec.md)
25
+ │ ├─ gate Spec validation + guardrail check
26
+ │ └─ test Review test plan → write test code
27
+
28
+ implement ── Implementation
29
+ │ ├─ code Write code after gate PASS
30
+ │ └─ review AI code review
31
+
32
+ merge ────── Wrap-up
33
+ ├─ docs Auto-update documentation
34
+ ├─ commit Commit changes
35
+ └─ merge Merge to base branch → cleanup
18
36
  ```
19
37
 
20
- ## ドキュメント
38
+ ### AI stays in its lane
21
39
 
22
- | | 概要 |
23
- |----|------|
24
- | [01. ツール概要とアーキテクチャ](docs/01_overview.md) | `sdd-forge` は、PHP-MVC プロジェクト(CakePHP 等)における「仕様と実装の乖離」および「技術ドキュメントの作成・維持コスト」という課題を解決するための Node.js CLI ツールである。ソースコード静的解析(`scan`)・テンプレート駆動のドキュメント生成(`init` / `populate` / `tfill`)・仕様ゲート管理(`spec` / `gate`)・反復改善ループ(`forge`)を単一パッケージに統合し、Spec-Driven Development(SDD)ワークフローをコマンドラインから一貫して実行できる。 |
25
- | [02. CLI コマンドリファレンス](docs/02_cli_commands.md) | `SCRIPTS` オブジェクトから `scan:all` を含めると 19 コマンド(エントリは 18 だが `scan:all` は別処理)が確認できます。正確な数を数えます。 |
26
- | [03. 設定とカスタマイズ](docs/03_configuration.md) | sdd-forge の動作は `.sdd-forge/config.json` を中心とした複数の JSON 設定ファイルによって制御され、言語・テンプレートタイプ・AIプロバイダー・タイムアウト・テキスト生成挙動など幅広い項目をカスタマイズできる。プロジェクトごとのテンプレート差し替えは `project-overrides.json`、解析結果の表現上書きは `overrides.json` で行い、関心ごとに設定を分離できる構成になっている。 |
27
- | [04. 内部設計](docs/04_internal_design.md) | `src/bin/sdd-forge.js` がサブコマンドを各モジュール(`analyzers/`・`engine/`・`spec/`・`forge/`・`flow/`)へディスパッチし、共通ユーティリティ `lib/` を底辺として解析→生成→改善の方向で一方向に依存が流れる設計になっている。PHPソースを `analyzers/` が `analysis.json` へ変換し、`engine/populate` と `engine/tfill` がそのデータをテンプレートと組み合わせて `docs/` へ展開するパイプラインが中心的な処理フローである。 |
28
- | [05. 開発・テスト・配布](docs/05_development.md) | `npm link` を使ったビルド不要のローカル開発環境、外部依存ゼロの Node.js 実装、および `npm version` と `npm publish` による npm レジストリへのリリースフローを中心に構成された章である。テストフレームワークは現時点では導入されておらず、動作確認はコマンド直接実行による手動テストで行う。 |
40
+ Source code analysis, spec gate checks, and flow orchestration are all handled by deterministic commands. AI is not in charge of the flow — it assists with spec drafting, code review, and prose generation within well-defined boundaries.
29
41
 
30
- ## 開発ワークフロー(SDD)
42
+ - **Spec gate** — Programmatic validation of unresolved items and missing approvals. No PASS, no implementation
43
+ - **Guardrails** — Project-specific design principles checked against each spec
44
+ - **Compaction resilience** — Flow state and requirements are persisted, so you can resume after context compression
31
45
 
32
- 本プロジェクトは Spec-Driven Development(SDD)を採用しています。
46
+ ## Automatic Doc Sync
33
47
 
48
+ Source code is statically analyzed to extract file structure, classes, methods, configuration, and dependencies. The extracted data is injected into templates to produce structured documentation (`docs/`) and `README.md`.
49
+
50
+ Documentation is automatically refreshed during the merge phase, so docs and code never drift apart. With always-current docs, both humans and AI agents can understand the system without reading every source file.
51
+
52
+ ## Quick Start
53
+
54
+ ### Install
55
+
56
+ <pre>
57
+ npm install -g <!-- {{data: project.name("")}} -->sdd-forge<!-- {{/data}} -->
58
+ </pre>
59
+
60
+ ### Setup
61
+
62
+ <pre>
63
+ <!-- {{data: project.name("")}} -->sdd-forge<!-- {{/data}} --> setup
64
+ </pre>
65
+
66
+ An interactive wizard configures your project type (preset) and AI agent.
67
+
68
+ ### Generate docs for an existing project
69
+
70
+ If you already have source code, generate documentation to get a complete picture of the system. Especially useful for onboarding onto legacy codebases.
71
+
72
+ <pre>
73
+ <!-- {{data: project.name("")}} -->sdd-forge<!-- {{/data}} --> docs build
74
+ </pre>
75
+
76
+ ### Develop with the SDD flow
77
+
78
+ **[Claude Code](https://docs.anthropic.com/en/docs/claude-code)** — run each phase via skills:
79
+
80
+ | Skill | Phase |
81
+ |---|---|
82
+ | `/sdd-forge.flow-plan` | plan (specification) |
83
+ | `/sdd-forge.flow-impl` | implement (coding + review) |
84
+ | `/sdd-forge.flow-merge` | merge (wrap-up) |
85
+
86
+ **[Codex CLI](https://github.com/openai/codex)** — invoke via `$` prefix:
87
+
88
+ | Command | Phase |
89
+ |---|---|
90
+ | `$sdd-forge flow start` | plan (start specification) |
91
+ | `$sdd-forge flow review` | implement (AI code review) |
92
+ | `$sdd-forge flow merge` | merge (wrap-up) |
93
+
94
+ ## Commands
95
+
96
+ | Command | Description |
97
+ |---|---|
98
+ | `setup` | Register project and generate config |
99
+ | `docs build` | Run the full documentation pipeline |
100
+ | `docs readme` | Generate `README.md` from `docs/` |
101
+ | `docs review` | Check documentation quality |
102
+ | `flow start` | Start the SDD flow |
103
+ | `flow status` | Show flow progress |
104
+ | `presets` | List available presets |
105
+ | `help` | Show all commands |
106
+
107
+ See `sdd-forge help` or the [command reference](docs/cli_commands.md) for the full list.
108
+
109
+ ## Configuration
110
+
111
+ `setup` generates `.sdd-forge/config.json`:
112
+
113
+ ```jsonc
114
+ {
115
+ "type": "cli/node-cli", // project type (preset selection)
116
+ "lang": "en", // operating language
117
+ "defaultAgent": "claude", // AI agent
118
+ "providers": { ... } // agent settings
119
+ }
34
120
  ```
35
- 1. sdd-forge spec --title "..." — 仕様ファイル作成
36
- 2. sdd-forge gate --spec ... — 仕様ゲート(未解決事項がなければ PASS)
37
- 3. 実装
38
- 4. sdd-forge forge --prompt "..." — ドキュメント自動更新
39
- 5. sdd-forge review — ドキュメントレビュー
40
- ```
41
121
 
42
- 詳細は [CLAUDE.md](CLAUDE.md) の「SDDフロー」セクションを参照してください。
122
+ See the [configuration reference](docs/configuration.md) for details.
123
+
124
+ ## Documentation
125
+
126
+ <!-- {{data: docs.chapters("Chapter|Summary")}} -->
127
+ | Chapter | Summary |
128
+ | --- | --- |
129
+ | [01. Tool Overview and Architecture](https://github.com/SpreadWorks/sdd-forge/blob/main/docs/overview.md) | This chapter introduces sdd-forge, a CLI tool for Spec-Driven Development that automates technical documentation gene… |
130
+ | [02. CLI Command Reference](https://github.com/SpreadWorks/sdd-forge/blob/main/docs/cli_commands.md) | sdd-forge provides over 20 CLI commands organized into four namespaces (`docs`, `spec`, `flow`, and standalone comman… |
131
+ | [03. Configuration and Customization](https://github.com/SpreadWorks/sdd-forge/blob/main/docs/configuration.md) | sdd-forge uses a layered configuration system centered on `.sdd-forge/config.json`, supplemented by preset manifests … |
132
+ | [04. Internal Design](https://github.com/SpreadWorks/sdd-forge/blob/main/docs/internal_design.md) | This chapter describes sdd-forge's internal architecture: the three-layer directory structure under `src/`, the depen… |
133
+ <!-- {{/data}} -->
134
+
135
+ ## License
43
136
 
44
- <!-- MANUAL:START -->
45
- <!-- MANUAL:END -->
137
+ MIT
package/package.json CHANGED
@@ -1,10 +1,14 @@
1
1
  {
2
2
  "name": "sdd-forge",
3
- "version": "0.1.0-alpha.3",
4
- "description": "Spec-Driven Development tooling for PHP-MVC documentation generation",
3
+ "version": "0.1.0-alpha.32",
4
+ "description": "Spec-Driven Development tooling for automated documentation generation",
5
+ "repository": {
6
+ "type": "git",
7
+ "url": "https://github.com/SpreadWorks/sdd-forge.git"
8
+ },
5
9
  "type": "module",
6
10
  "bin": {
7
- "sdd-forge": "./src/bin/sdd-forge.js"
11
+ "sdd-forge": "./src/sdd-forge.js"
8
12
  },
9
13
  "files": [
10
14
  "src/"
@@ -15,9 +19,12 @@
15
19
  "keywords": [
16
20
  "sdd",
17
21
  "documentation",
18
- "php",
19
- "cakephp",
20
- "spec-driven-development"
22
+ "spec-driven-development",
23
+ "source-analysis",
24
+ "technical-docs"
21
25
  ],
26
+ "scripts": {
27
+ "test": "find tests -name '*.test.js' | xargs node --test"
28
+ },
22
29
  "license": "MIT"
23
30
  }
package/src/README.md ADDED
@@ -0,0 +1,201 @@
1
+ # sdd-forge — Internal Architecture
2
+
3
+ ## Overview
4
+
5
+ sdd-forge は Spec-Driven Development (SDD) のための CLI ツール。
6
+ 対象プロジェクトのソースコードを解析し、テンプレートベースのドキュメントを自動生成する。
7
+
8
+ - **Runtime**: Node.js >= 18
9
+ - **Module system**: ES Modules (`"type": "module"`)
10
+ - **External dependencies**: なし(Node.js 組み込み API のみ)
11
+
12
+ ## Directory Structure
13
+
14
+ ```text
15
+ src/
16
+ ├── sdd-forge.js # CLI エントリポイント(トップレベルディスパッチャ)
17
+ ├── docs.js # docs ディスパッチャ
18
+ ├── spec.js # spec ディスパッチャ
19
+ ├── flow.js # SDD フロー自動実行(直接実行コマンド)
20
+ ├── help.js # コマンド一覧表示
21
+
22
+ ├── docs/ # ドキュメント生成ドメイン
23
+ │ ├── commands/ # CLI コマンド(各サブコマンドの実装)
24
+ │ ├── lib/ # 共通ロジック(パーサー、レンダラー、リゾルバー等)
25
+ │ └── presets/ # フレームワーク固有の解析・テンプレート拡張
26
+ │ └── webapp/cakephp2/ # CakePHP 2.x 用プリセット
27
+
28
+ ├── specs/ # 仕様管理ドメイン
29
+ │ └── commands/ # CLI コマンド(spec 初期化、gate チェック)
30
+
31
+ ├── lib/ # パッケージ全体の共通ユーティリティ
32
+ │ ├── cli.js # repoRoot(), sourceRoot(), parseArgs()
33
+ │ ├── config.js # loadJsonFile(), 設定読み込み
34
+ │ ├── agent.js # AI エージェント抽象化
35
+ │ ├── process.js # プロセス実行ヘルパー
36
+ │ ├── projects.js # プロジェクト管理(登録、解決、デフォルト)
37
+ │ ├── i18n.js # 国際化(メッセージ・UI テキスト)
38
+ │ └── types.js # 型定義・定数
39
+
40
+ ├── presets/ # プリセット(テンプレート + DataSource + スキャン設定)
41
+ │ ├── base/templates/ja/ # 共通章テンプレート(全タイプ共通)
42
+ │ ├── webapp/templates/ja/ # Web アプリ用章テンプレート
43
+ │ ├── cli/templates/ja/ # CLI ツール用章テンプレート
44
+ │ ├── library/templates/ja/# ライブラリ用章テンプレート
45
+ │ ├── cakephp2/ # CakePHP 2.x(templates + data + scan)
46
+ │ ├── laravel/ # Laravel 8+
47
+ │ ├── symfony/ # Symfony 5+
48
+ │ └── node-cli/ # Node.js CLI
49
+ ├── locale/ # 言語別メッセージ
50
+ │ ├── en/ # English
51
+ │ └── ja/ # 日本語
52
+ │ ├── messages.json # CLI メッセージ
53
+ │ ├── prompts.json # AI プロンプトテンプレート
54
+ │ └── ui.json # UI テキスト
55
+ └── templates/ # 静的データ(npm publish に含まれる)
56
+ ├── config.example.json # .sdd-forge/config.json のサンプル
57
+ └── review-checklist.md # レビュー観点チェックリスト
58
+ ```
59
+
60
+ ## Command Routing
61
+
62
+ 3 段階のディスパッチで CLI コマンドをルーティングする。
63
+
64
+ ```
65
+ sdd-forge <cmd> [args]
66
+
67
+ ├─ sdd-forge.js # 1. プロジェクトコンテキスト解決 + ディスパッチ
68
+ │ ├─ docs.js # 2. docs サブコマンドのルーティング
69
+ │ │ └─ docs/commands/*.js # 3. 実際のコマンド実装
70
+ │ ├─ spec.js # 2. spec サブコマンドのルーティング
71
+ │ │ └─ spec/commands/*.js # 3. 実際のコマンド実装
72
+ │ ├─ flow.js # 2+3. 直接実行(ディスパッチャなし)
73
+ │ └─ help.js # 2+3. 直接実行
74
+ ```
75
+
76
+ - **ディスパッチャ** (`docs.js`, `spec.js`): サブコマンド名を受け取り、`commands/` 配下のスクリプトに `import()` で委譲する
77
+ - **直接実行コマンド** (`flow.js`, `help.js`): サブコマンドを持たず、引数をそのまま処理する
78
+
79
+ ### プロジェクトコンテキスト
80
+
81
+ `sdd-forge.js` は実行時に以下の環境変数を設定する:
82
+
83
+ | 環境変数 | 意味 | 設定元 |
84
+ |---|---|---|
85
+ | `SDD_SOURCE_ROOT` | 対象プロジェクトのソースコードルート | `projects.js` で解決 |
86
+ | `SDD_WORK_ROOT` | 作業ディレクトリ(`.sdd-forge/`, `docs/` の親) | `projects.js` で解決 |
87
+
88
+ 各コマンドは `lib/cli.js` の `sourceRoot()` / `repoRoot()` 経由でこれらを参照する。
89
+
90
+ ## Coding Rules
91
+
92
+ ### プロジェクト固有情報の埋め込み禁止
93
+
94
+ `src/` 配下のコードおよび `src/templates/` 配下のテンプレートに、特定プロジェクトの情報を直接書いてはならない。
95
+
96
+ - **禁止**: プロジェクト名、ホスト名、ポート番号、コンテナ名、固有 DB 名
97
+ - **許可**: `presets/` 配下のフレームワーク固有ロジック(汎用的な解析パターン)
98
+ - **設定**: プロジェクト固有の値は `.sdd-forge/config.json` で外部化する
99
+
100
+ ### 外部依存の禁止
101
+
102
+ Node.js 組み込み API (`fs`, `path`, `child_process`, `url` 等) のみを使用する。
103
+ npm パッケージへの依存を追加しないこと。
104
+
105
+ ### フォールバック値の抑制
106
+
107
+ 必須の設定値・環境変数が不足している場合は、黙ってデフォルト値で動作させず、エラーメッセージを出力して停止すること。
108
+
109
+ ```js
110
+ // NG
111
+ const agent = config.agent ?? "claude";
112
+
113
+ // OK
114
+ if (!config.agent) {
115
+ console.error("Error: 'agent' is not configured in config.json");
116
+ process.exit(1);
117
+ }
118
+ ```
119
+
120
+ ### コマンドファイルの構造
121
+
122
+ `commands/` 配下のファイルは以下のパターンに従う:
123
+
124
+ ```js
125
+ import { repoRoot, parseArgs } from "../../lib/cli.js";
126
+
127
+ function main() {
128
+ const args = process.argv.slice(2);
129
+ const opts = parseArgs(args, { flags: [...], options: [...] });
130
+
131
+ if (opts.help) {
132
+ console.log("Usage: ...");
133
+ process.exit(0);
134
+ }
135
+
136
+ // 実装
137
+ }
138
+
139
+ main();
140
+ ```
141
+
142
+ - `parseArgs()` で `--help` を処理する
143
+ - 直接実行ガード (`isDirectRun`) が必要なスクリプトは、`docs.js` の `build` パイプラインで `import()` される場合のみ
144
+
145
+ ### presets の追加
146
+
147
+ 新しいフレームワークプリセットを追加する場合:
148
+
149
+ 1. `docs/presets/<type>/<framework>/` ディレクトリを作成
150
+ 2. `scanner.js` — フレームワーク固有のスキャン拡張
151
+ 3. `resolver.js` — `{{data}}` ディレクティブのデータ解決ロジック
152
+ 4. `analyze-*.js` — 個別カテゴリの解析スクリプト(必要に応じて)
153
+ 5. `templates/locale/<lang>/<type>/<framework>/` に章テンプレートのオーバーライドを配置
154
+
155
+ ### テンプレート継承
156
+
157
+ テンプレートは `base → type → framework` の順で継承される。
158
+
159
+ ```
160
+ locale/ja/base/01_overview.md ← 全タイプ共通
161
+ locale/ja/webapp/05_auth_and_session.md ← webapp タイプ共通
162
+ locale/ja/webapp/cakephp2/05_auth_and_session.md ← CakePHP 2.x 固有オーバーライド
163
+ ```
164
+
165
+ より具体的なパスにファイルが存在すれば、そちらが優先される。
166
+
167
+ ## Agent Invocation (`lib/agent.js`)
168
+
169
+ ### 非同期呼び出しで `execFile` を使ってはならない
170
+
171
+ `callAgentAsync()` は CLI エージェント(`claude`, `codex` 等)を子プロセスとして起動する。
172
+ Node.js の `execFile`(非同期版)はデフォルトで stdin を `pipe` モードで開くが、
173
+ Claude CLI は stdin が pipe だと EOF を待ち続けてハングする。
174
+ `execFileSync`(同期版)は内部で stdin を即座に閉じるため問題が起きないが、
175
+ 非同期版では閉じられない。
176
+
177
+ **これは Node.js の既知の制限であり、`execFile` では stdin を `ignore` に設定できない。**
178
+
179
+ - [nodejs/node#60077](https://github.com/nodejs/node/issues/60077) — `execFile` で stdin を ignore に設定できない
180
+ - [anthropics/claude-code#771](https://github.com/anthropics/claude-code/issues/771) — Claude CLI が Node.js の `execFile` でハングする
181
+
182
+ **対策**: `child_process.spawn` を使い、`stdio: ["ignore", "pipe", "pipe"]` を明示する。
183
+
184
+ ```js
185
+ // NG: execFile — stdin が pipe のままでハングする
186
+ execFile("claude", args, opts, callback);
187
+
188
+ // OK: spawn — stdin を ignore で閉じる
189
+ const child = spawn("claude", args, {
190
+ stdio: ["ignore", "pipe", "pipe"],
191
+ ...opts,
192
+ });
193
+ ```
194
+
195
+ `forge.js` の `streamOutput` パスは既にこのパターンを使用している。
196
+
197
+ ## File Operations
198
+
199
+ - ファイルの削除・リネーム・移動は `git mv` / `git rm` を使用し、履歴を保持する
200
+ - コミットメッセージは英語。形式: `<type>: <subject>`
201
+ - type: `feat`, `fix`, `docs`, `refactor`, `chore`, `test`
@@ -0,0 +1,213 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * src/docs/commands/agents.js
4
+ *
5
+ * AGENTS.md を更新する。
6
+ * AGENTS.md 内の {{data: agents.sdd}} / {{data: agents.project}} ディレクティブを解決し、
7
+ * PROJECT セクションは AI で精査する。
8
+ */
9
+
10
+ import fs from "fs";
11
+ import path from "path";
12
+ import { runIfDirect } from "../../lib/entrypoint.js";
13
+ import { parseArgs } from "../../lib/cli.js";
14
+ import { sddOutputDir } from "../../lib/config.js";
15
+ import { callAgent, loadAgentConfig, DEFAULT_AGENT_TIMEOUT } from "../../lib/agent.js";
16
+ import { translate } from "../../lib/i18n.js";
17
+ import { resolveType } from "../../lib/types.js";
18
+ import { createResolver } from "../lib/resolver-factory.js";
19
+ import { createLogger } from "../../lib/progress.js";
20
+ import { parseDirectives, replaceBlockDirective, resolveDataDirectives } from "../lib/directive-parser.js";
21
+ import { resolveCommandContext, loadFullAnalysis, getChapterFiles, readText } from "../lib/command-context.js";
22
+
23
+ const logger = createLogger("agents");
24
+
25
+ // ---------------------------------------------------------------------------
26
+ // AI プロンプト構築
27
+ // ---------------------------------------------------------------------------
28
+
29
+ function buildAgentsSystemPrompt() {
30
+ const t = translate();
31
+ const rules = t.raw("prompts:agents.outputRules") || [];
32
+ return [
33
+ t("prompts:agents.systemPrompt"),
34
+ "",
35
+ "## Output Rules (strict)",
36
+ ...rules.map((r) => `- ${r}`),
37
+ ].join("\n");
38
+ }
39
+
40
+ function buildRefinePrompt(projectContent, docsContent, config, srcRoot, sddContent) {
41
+ const parts = [];
42
+
43
+ if (sddContent) {
44
+ parts.push("## SDD Section (already present — do not duplicate)");
45
+ parts.push(sddContent);
46
+ parts.push("");
47
+ }
48
+
49
+ parts.push("## Current PROJECT Section (template-generated)");
50
+ parts.push(projectContent);
51
+ parts.push("");
52
+
53
+ if (config.type) {
54
+ parts.push("## Project Config");
55
+ parts.push(`- type: ${config.type}`);
56
+ parts.push("");
57
+ }
58
+
59
+ const pkgPath = path.join(srcRoot, "package.json");
60
+ if (fs.existsSync(pkgPath)) {
61
+ try {
62
+ const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf8"));
63
+ if (pkg.scripts) {
64
+ parts.push("## package.json scripts");
65
+ parts.push(JSON.stringify(pkg.scripts, null, 2));
66
+ parts.push("");
67
+ }
68
+ } catch (_) { /* skip */ }
69
+ }
70
+
71
+ if (docsContent) {
72
+ parts.push("## Generated Documentation");
73
+ parts.push(docsContent);
74
+ }
75
+
76
+ return parts.join("\n");
77
+ }
78
+
79
+ // ---------------------------------------------------------------------------
80
+ // ディレクティブ解決
81
+ // ---------------------------------------------------------------------------
82
+
83
+ /**
84
+ * AGENTS.md 内の {{data}} ディレクティブを解決する。
85
+ * agents.project ディレクティブの解決結果を返す(AI 精査用)。
86
+ */
87
+ function resolveAgentsDirectives(text, resolveFn) {
88
+ let sddContent = null;
89
+ let projectContent = null;
90
+
91
+ const result = resolveDataDirectives(
92
+ text,
93
+ (source, method, labels) => resolveFn(source, method, {}, labels),
94
+ {
95
+ onResolve(d, rendered) {
96
+ if (d.source === "agents" && d.method === "sdd") sddContent = rendered;
97
+ if (d.source === "agents" && d.method === "project") projectContent = rendered;
98
+ },
99
+ },
100
+ );
101
+
102
+ return { text: result.text, sddContent, projectContent };
103
+ }
104
+
105
+ /**
106
+ * AI 精査後の PROJECT セクションで、ディレクティブ内部を差し替える。
107
+ */
108
+ function replaceProjectContent(text, refined) {
109
+ const directives = parseDirectives(text);
110
+ const lines = text.split("\n");
111
+
112
+ for (let i = directives.length - 1; i >= 0; i--) {
113
+ const d = directives[i];
114
+ if (d.type !== "data" || d.source !== "agents" || d.method !== "project") continue;
115
+ if (d.endLine < 0) continue;
116
+
117
+ replaceBlockDirective(lines, d, refined);
118
+ break;
119
+ }
120
+
121
+ return lines.join("\n");
122
+ }
123
+
124
+ // ---------------------------------------------------------------------------
125
+ // Main
126
+ // ---------------------------------------------------------------------------
127
+
128
+ async function main(ctx) {
129
+ if (!ctx) {
130
+ const cli = parseArgs(process.argv.slice(2), {
131
+ flags: ["--dry-run"],
132
+ options: [],
133
+ defaults: { dryRun: false },
134
+ });
135
+
136
+ if (cli.help) {
137
+ const tu = translate();
138
+ const h = tu.raw("ui:help.cmdHelp.agents");
139
+ const o = h.options;
140
+ console.log([
141
+ h.usage, "", ` ${h.desc}`, ` ${h.descDetail}`, "", "Options:",
142
+ ` ${o.dryRun}`,
143
+ ].join("\n"));
144
+ return;
145
+ }
146
+
147
+ ctx = resolveCommandContext(cli);
148
+ ctx.dryRun = cli.dryRun;
149
+ }
150
+
151
+ const { root, srcRoot, config, lang, t } = ctx;
152
+
153
+ const agentsPath = path.join(srcRoot, "AGENTS.md");
154
+ if (!fs.existsSync(agentsPath)) {
155
+ throw new Error(t("messages:agents.notFound", { path: agentsPath }));
156
+ }
157
+
158
+ // Load analysis
159
+ const analysis = loadFullAnalysis(root);
160
+ if (!analysis) {
161
+ throw new Error(t("messages:agents.analysisNotFound", { path: path.join(sddOutputDir(root), "analysis.json") }));
162
+ }
163
+
164
+ // Load generated docs as context (instead of raw analysis.json)
165
+ const docsDir = path.join(root, "docs");
166
+ const chapterFiles = getChapterFiles(docsDir, { type: ctx.type, configChapters: ctx.config?.chapters });
167
+ const docsContent = chapterFiles.map((f) => readText(path.join(docsDir, f))).join("\n\n");
168
+ const readmeContent = readText(path.join(srcRoot, "README.md"));
169
+ const combinedDocs = [docsContent, readmeContent].filter(Boolean).join("\n\n---\n\n");
170
+
171
+ // Create resolver and resolve {{data}} directives
172
+ const resolvedType = resolveType(config.type || "base");
173
+ const resolver = await createResolver(resolvedType, root, { configChapters: config.chapters });
174
+ const resolveFn = (source, method, a, labels) => resolver.resolve(source, method, analysis, labels);
175
+
176
+ let content = fs.readFileSync(agentsPath, "utf8");
177
+ const { text: resolved, sddContent, projectContent } = resolveAgentsDirectives(content, resolveFn);
178
+ content = resolved;
179
+
180
+ // AI refinement for PROJECT section
181
+ if (projectContent) {
182
+ const agent = loadAgentConfig(config, "docs.agents");
183
+
184
+ logger.log(t("messages:agents.refining"));
185
+ const systemPrompt = buildAgentsSystemPrompt();
186
+ const prompt = buildRefinePrompt(projectContent, combinedDocs, config, srcRoot, sddContent);
187
+
188
+ try {
189
+ const result = callAgent(agent, prompt, DEFAULT_AGENT_TIMEOUT * 1000, undefined, { systemPrompt });
190
+
191
+ let refined = result.trim();
192
+
193
+ content = replaceProjectContent(content, refined);
194
+ } catch (err) {
195
+ throw new Error(`AI agent call failed: ${err.message}`);
196
+ }
197
+
198
+ logger.log(t("messages:agents.generated"));
199
+ }
200
+
201
+ if (ctx.dryRun) {
202
+ logger.log(t("messages:agents.dryRun", { path: agentsPath }));
203
+ console.log(content);
204
+ return;
205
+ }
206
+
207
+ fs.writeFileSync(agentsPath, content, "utf8");
208
+ console.log(t("messages:agents.updated", { path: agentsPath }));
209
+ }
210
+
211
+ export { main };
212
+
213
+ runIfDirect(import.meta.url, main);