sdd-forge 0.1.0-alpha.32 → 0.1.0-alpha.361
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +11 -10
- package/package.json +7 -3
- package/src/AGENTS.md +420 -0
- package/src/docs/commands/agents.js +22 -7
- package/src/docs/commands/data.js +15 -13
- package/src/docs/commands/enrich.js +25 -9
- package/src/docs/commands/forge.js +2 -3
- package/src/docs/commands/init.js +19 -17
- package/src/docs/commands/readme.js +9 -6
- package/src/docs/commands/review.js +3 -3
- package/src/docs/commands/scan.js +37 -19
- package/src/docs/commands/text.js +105 -24
- package/src/docs/commands/translate.js +1 -1
- package/src/docs/data/agents.js +5 -4
- package/src/docs/data/docs.js +76 -8
- package/src/docs/data/lang.js +2 -2
- package/src/docs/data/text.js +32 -0
- package/src/docs/lib/command-context.js +3 -3
- package/src/docs/lib/directive-parser.js +335 -137
- package/src/docs/lib/forge-prompts.js +6 -6
- package/src/docs/lib/resolver-factory.js +73 -34
- package/src/docs/lib/scanner.js +1 -1
- package/src/docs/lib/template-merger.js +299 -89
- package/src/docs/lib/text-prompts.js +26 -18
- package/src/docs/lib/toml-parser.js +135 -0
- package/src/docs.js +23 -9
- package/src/flow/commands/cleanup.js +41 -22
- package/src/flow/commands/merge.js +104 -6
- package/src/flow/commands/resume.js +55 -5
- package/src/flow/commands/review.js +16 -6
- package/src/flow/commands/start.js +6 -14
- package/src/flow/commands/status.js +85 -38
- package/src/lib/flow-state.js +388 -28
- package/src/lib/i18n.js +4 -3
- package/src/lib/json-parse.js +31 -0
- package/src/lib/multi-select.js +265 -0
- package/src/lib/presets.js +95 -23
- package/src/lib/skills.js +96 -0
- package/src/lib/types.js +48 -22
- package/src/locale/en/prompts.json +4 -6
- package/src/locale/en/ui.json +19 -33
- package/src/locale/ja/prompts.json +4 -6
- package/src/locale/ja/ui.json +19 -33
- package/src/presets/api/preset.json +13 -0
- package/src/presets/api/templates/en/api_overview.md +22 -0
- package/src/presets/api/templates/en/authentication.md +22 -0
- package/src/presets/api/templates/ja/api_overview.md +22 -0
- package/src/presets/api/templates/ja/authentication.md +22 -0
- package/src/presets/architecture/preset.json +6 -0
- package/src/presets/base/data/structure.js +87 -0
- package/src/presets/base/preset.json +0 -1
- package/src/presets/base/templates/en/AGENTS.sdd.md +5 -1
- package/src/presets/base/templates/en/development.md +21 -19
- package/src/presets/base/templates/en/guardrail.md +20 -0
- package/src/presets/base/templates/en/layout.md +10 -0
- package/src/presets/base/templates/en/overview.md +22 -18
- package/src/presets/base/templates/en/project_structure.md +21 -19
- package/src/presets/base/templates/en/stack_and_ops.md +22 -18
- package/src/presets/base/templates/ja/AGENTS.sdd.md +5 -1
- package/src/presets/base/templates/ja/development.md +21 -19
- package/src/presets/base/templates/ja/guardrail.md +20 -0
- package/src/presets/base/templates/ja/layout.md +10 -0
- package/src/presets/base/templates/ja/overview.md +22 -18
- package/src/presets/base/templates/ja/project_structure.md +21 -19
- package/src/presets/base/templates/ja/stack_and_ops.md +22 -18
- package/src/presets/cakephp2/data/{shells.js → commands.js} +12 -12
- package/src/presets/cakephp2/data/config.js +2 -2
- package/src/presets/cakephp2/preset.json +1 -1
- package/src/presets/cakephp2/scan/{shells-detail.js → commands-detail.js} +9 -8
- package/src/presets/cakephp2/templates/en/auth_and_session.md +42 -0
- package/src/presets/cakephp2/templates/en/business_logic.md +16 -0
- package/src/presets/cakephp2/templates/en/commands.md +16 -0
- package/src/presets/cakephp2/templates/en/controller_routes.md +19 -0
- package/src/presets/cakephp2/templates/en/database_architecture.md +11 -0
- package/src/presets/cakephp2/templates/en/db_tables.md +16 -0
- package/src/presets/cakephp2/templates/en/development.md +46 -0
- package/src/presets/cakephp2/templates/en/guardrail.md +8 -0
- package/src/presets/cakephp2/templates/en/project_structure.md +31 -0
- package/src/presets/cakephp2/templates/en/stack_and_ops.md +43 -0
- package/src/presets/cakephp2/templates/ja/auth_and_session.md +23 -3
- package/src/presets/cakephp2/templates/ja/business_logic.md +16 -0
- package/src/presets/cakephp2/templates/ja/commands.md +16 -0
- package/src/presets/cakephp2/templates/ja/controller_routes.md +13 -7
- package/src/presets/cakephp2/templates/ja/database_architecture.md +11 -0
- package/src/presets/cakephp2/templates/ja/db_tables.md +6 -12
- package/src/presets/cakephp2/templates/ja/development.md +13 -17
- package/src/presets/cakephp2/templates/ja/guardrail.md +8 -0
- package/src/presets/cakephp2/templates/ja/project_structure.md +13 -21
- package/src/presets/cakephp2/templates/ja/stack_and_ops.md +18 -23
- package/src/presets/ci/data/pipelines.js +89 -0
- package/src/presets/ci/preset.json +15 -0
- package/src/presets/ci/scan/workflows.js +289 -0
- package/src/presets/ci/templates/en/ci_cd.md +27 -0
- package/src/presets/ci/templates/ja/ci_cd.md +27 -0
- package/src/presets/cli/data/commands.js +52 -0
- package/src/presets/cli/preset.json +1 -1
- package/src/presets/cli/templates/en/README.md +12 -14
- package/src/presets/cli/templates/en/commands.md +22 -27
- package/src/presets/cli/templates/en/config.md +19 -18
- package/src/presets/cli/templates/en/guardrail.md +6 -0
- package/src/presets/cli/templates/ja/README.md +12 -14
- package/src/presets/cli/templates/ja/commands.md +22 -27
- package/src/presets/cli/templates/ja/config.md +19 -18
- package/src/presets/cli/templates/ja/guardrail.md +6 -0
- package/src/presets/database/data/schema.js +36 -0
- package/src/presets/database/preset.json +8 -0
- package/src/presets/database/templates/en/database.md +16 -0
- package/src/presets/database/templates/ja/database.md +16 -0
- package/src/presets/drizzle/data/schema.js +128 -0
- package/src/presets/drizzle/preset.json +21 -0
- package/src/presets/drizzle/scan/schema.js +114 -0
- package/src/presets/drizzle/templates/en/database.md +11 -0
- package/src/presets/drizzle/templates/en/schema.md +20 -0
- package/src/presets/drizzle/templates/ja/database.md +11 -0
- package/src/presets/drizzle/templates/ja/schema.md +20 -0
- package/src/presets/edge/data/runtime.js +93 -0
- package/src/presets/edge/preset.json +8 -0
- package/src/presets/edge/templates/en/edge_runtime.md +20 -0
- package/src/presets/edge/templates/ja/edge_runtime.md +20 -0
- package/src/presets/graphql/data/schema.js +119 -0
- package/src/presets/graphql/preset.json +18 -0
- package/src/presets/graphql/scan/schema.js +108 -0
- package/src/presets/graphql/templates/en/api_overview.md +8 -0
- package/src/presets/graphql/templates/en/authentication.md +15 -0
- package/src/presets/graphql/templates/en/schema.md +27 -0
- package/src/presets/graphql/templates/ja/api_overview.md +8 -0
- package/src/presets/graphql/templates/ja/authentication.md +15 -0
- package/src/presets/graphql/templates/ja/schema.md +27 -0
- package/src/presets/hono/data/middleware.js +37 -0
- package/src/presets/hono/preset.json +19 -0
- package/src/presets/hono/scan/middleware.js +68 -0
- package/src/presets/hono/templates/en/middleware.md +13 -0
- package/src/presets/hono/templates/ja/middleware.md +13 -0
- package/src/presets/js-webapp/preset.json +24 -0
- package/src/presets/laravel/data/commands.js +8 -14
- package/src/presets/laravel/preset.json +1 -1
- package/src/presets/laravel/scan/config.js +108 -0
- package/src/presets/laravel/scan/routes.js +62 -5
- package/src/presets/laravel/templates/en/auth_and_session.md +29 -0
- package/src/presets/laravel/templates/en/controller_routes.md +34 -0
- package/src/presets/laravel/templates/en/db_tables.md +16 -0
- package/src/presets/laravel/templates/en/guardrail.md +8 -0
- package/src/presets/laravel/templates/en/project_structure.md +13 -0
- package/src/presets/laravel/templates/en/stack_and_ops.md +34 -0
- package/src/presets/laravel/templates/ja/auth_and_session.md +13 -13
- package/src/presets/laravel/templates/ja/controller_routes.md +18 -28
- package/src/presets/laravel/templates/ja/db_tables.md +10 -16
- package/src/presets/laravel/templates/ja/guardrail.md +8 -0
- package/src/presets/laravel/templates/ja/project_structure.md +7 -7
- package/src/presets/laravel/templates/ja/stack_and_ops.md +15 -23
- package/src/presets/library/preset.json +1 -1
- package/src/presets/library/templates/en/README.md +16 -0
- package/src/presets/library/templates/en/guardrail.md +4 -0
- package/src/presets/library/templates/en/public_api.md +34 -0
- package/src/presets/library/templates/en/usage.md +41 -0
- package/src/presets/library/templates/ja/README.md +5 -7
- package/src/presets/library/templates/ja/guardrail.md +4 -0
- package/src/presets/library/templates/ja/public_api.md +16 -15
- package/src/presets/library/templates/ja/usage.md +19 -18
- package/src/presets/monorepo/data/monorepo.js +80 -0
- package/src/presets/monorepo/preset.json +6 -0
- package/src/presets/nextjs/data/components.js +103 -0
- package/src/presets/nextjs/data/routes.js +187 -0
- package/src/presets/nextjs/preset.json +35 -0
- package/src/presets/nextjs/scan/components.js +53 -0
- package/src/presets/nextjs/scan/routes.js +175 -0
- package/src/presets/nextjs/templates/en/components.md +27 -0
- package/src/presets/nextjs/templates/en/middleware.md +13 -0
- package/src/presets/nextjs/templates/en/pages_routing.md +27 -0
- package/src/presets/nextjs/templates/en/route_handlers.md +13 -0
- package/src/presets/nextjs/templates/ja/components.md +27 -0
- package/src/presets/nextjs/templates/ja/middleware.md +13 -0
- package/src/presets/nextjs/templates/ja/pages_routing.md +27 -0
- package/src/presets/nextjs/templates/ja/route_handlers.md +13 -0
- package/src/presets/node-cli/preset.json +3 -1
- package/src/presets/node-cli/templates/en/README.md +9 -9
- package/src/presets/node-cli/templates/en/cli_commands.md +9 -8
- package/src/presets/node-cli/templates/en/configuration.md +9 -8
- package/src/presets/node-cli/templates/en/development_testing.md +10 -9
- package/src/presets/node-cli/templates/en/guardrail.md +4 -0
- package/src/presets/node-cli/templates/en/internal_design.md +10 -9
- package/src/presets/node-cli/templates/en/overview.md +9 -8
- package/src/presets/node-cli/templates/ja/README.md +9 -9
- package/src/presets/node-cli/templates/ja/cli_commands.md +9 -8
- package/src/presets/node-cli/templates/ja/configuration.md +9 -8
- package/src/presets/node-cli/templates/ja/development_testing.md +10 -9
- package/src/presets/node-cli/templates/ja/guardrail.md +4 -0
- package/src/presets/node-cli/templates/ja/internal_design.md +10 -9
- package/src/presets/node-cli/templates/ja/overview.md +9 -8
- package/src/presets/php-webapp/preset.json +10 -0
- package/src/presets/postgres/data/database.js +19 -0
- package/src/presets/postgres/preset.json +6 -0
- package/src/presets/postgres/templates/en/database.md +9 -0
- package/src/presets/postgres/templates/ja/database.md +9 -0
- package/src/presets/principle/preset.json +5 -0
- package/src/presets/r2/data/storage.js +69 -0
- package/src/presets/r2/preset.json +8 -0
- package/src/presets/r2/templates/en/storage.md +11 -0
- package/src/presets/r2/templates/ja/storage.md +11 -0
- package/src/presets/rest/preset.json +14 -0
- package/src/presets/rest/templates/en/api_overview.md +8 -0
- package/src/presets/rest/templates/en/authentication.md +15 -0
- package/src/presets/rest/templates/en/endpoints.md +20 -0
- package/src/presets/rest/templates/ja/api_overview.md +8 -0
- package/src/presets/rest/templates/ja/authentication.md +15 -0
- package/src/presets/rest/templates/ja/endpoints.md +20 -0
- package/src/presets/storage/data/buckets.js +22 -0
- package/src/presets/storage/preset.json +8 -0
- package/src/presets/storage/templates/en/storage.md +20 -0
- package/src/presets/storage/templates/ja/storage.md +20 -0
- package/src/presets/symfony/data/commands.js +8 -14
- package/src/presets/symfony/preset.json +1 -1
- package/src/presets/symfony/scan/controllers.js +4 -6
- package/src/presets/symfony/scan/php-attributes.js +72 -0
- package/src/presets/symfony/scan/routes.js +4 -6
- package/src/presets/symfony/templates/en/auth_and_session.md +29 -0
- package/src/presets/symfony/templates/en/business_logic.md +10 -0
- package/src/presets/symfony/templates/en/controller_routes.md +32 -0
- package/src/presets/symfony/templates/en/db_tables.md +21 -0
- package/src/presets/symfony/templates/en/guardrail.md +8 -0
- package/src/presets/symfony/templates/en/project_structure.md +13 -0
- package/src/presets/symfony/templates/en/stack_and_ops.md +34 -0
- package/src/presets/symfony/templates/ja/auth_and_session.md +13 -13
- package/src/presets/symfony/templates/ja/business_logic.md +10 -0
- package/src/presets/symfony/templates/ja/controller_routes.md +16 -26
- package/src/presets/symfony/templates/ja/db_tables.md +13 -21
- package/src/presets/symfony/templates/ja/guardrail.md +8 -0
- package/src/presets/symfony/templates/ja/project_structure.md +7 -7
- package/src/presets/symfony/templates/ja/stack_and_ops.md +15 -23
- package/src/presets/web-design/NOTICE +10 -0
- package/src/presets/web-design/preset.json +5 -0
- package/src/presets/web-design/templates/en/guardrail.md +34 -0
- package/src/presets/web-design/templates/ja/guardrail.md +34 -0
- package/src/presets/webapp/data/{shells.js → commands.js} +9 -12
- package/src/presets/webapp/preset.json +2 -2
- package/src/presets/webapp/templates/en/README.md +22 -0
- package/src/presets/webapp/templates/en/auth_and_session.md +47 -0
- package/src/presets/webapp/templates/en/business_logic.md +45 -0
- package/src/presets/webapp/templates/en/commands.md +42 -0
- package/src/presets/webapp/templates/en/controller_routes.md +49 -0
- package/src/presets/webapp/templates/en/database_architecture.md +41 -0
- package/src/presets/webapp/templates/en/db_tables.md +29 -0
- package/src/presets/webapp/templates/en/guardrail.md +10 -0
- package/src/presets/webapp/templates/ja/README.md +7 -9
- package/src/presets/webapp/templates/ja/auth_and_session.md +23 -22
- package/src/presets/webapp/templates/ja/business_logic.md +23 -24
- package/src/presets/webapp/templates/ja/commands.md +42 -0
- package/src/presets/webapp/templates/ja/controller_routes.md +25 -26
- package/src/presets/webapp/templates/ja/database_architecture.md +21 -20
- package/src/presets/webapp/templates/ja/db_tables.md +15 -18
- package/src/presets/webapp/templates/ja/guardrail.md +10 -0
- package/src/presets/workers/data/bindings.js +84 -0
- package/src/presets/workers/preset.json +23 -0
- package/src/presets/workers/scan/bindings.js +129 -0
- package/src/presets/workers/templates/en/bindings.md +20 -0
- package/src/presets/workers/templates/en/edge_runtime.md +11 -0
- package/src/presets/workers/templates/ja/bindings.md +20 -0
- package/src/presets/workers/templates/ja/edge_runtime.md +11 -0
- package/src/presets-cmd.js +48 -33
- package/src/setup.js +352 -352
- package/src/spec/commands/gate.js +9 -12
- package/src/spec/commands/guardrail.js +276 -63
- package/src/spec/commands/init.js +9 -3
- package/src/spec/commands/lint.js +164 -0
- package/src/spec.js +1 -0
- package/src/templates/skills/sdd-forge.flow-finalize/SKILL.en.md +248 -0
- package/src/templates/skills/sdd-forge.flow-finalize/SKILL.ja.md +248 -0
- package/src/templates/skills/sdd-forge.flow-impl/SKILL.en.md +166 -0
- package/src/templates/skills/sdd-forge.flow-impl/SKILL.ja.md +166 -0
- package/src/templates/skills/sdd-forge.flow-plan/SKILL.en.md +273 -0
- package/src/templates/skills/sdd-forge.flow-plan/{SKILL.md → SKILL.ja.md} +70 -51
- package/src/templates/skills/sdd-forge.flow-resume/{SKILL.md → SKILL.en.md} +2 -1
- package/src/templates/skills/sdd-forge.flow-resume/SKILL.ja.md +34 -0
- package/src/templates/skills/sdd-forge.flow-status/{SKILL.md → SKILL.en.md} +4 -4
- package/src/templates/skills/sdd-forge.flow-status/SKILL.ja.md +94 -0
- package/src/templates/skills/sdd-forge.flow-sync/SKILL.en.md +42 -0
- package/src/templates/skills/sdd-forge.flow-sync/SKILL.ja.md +42 -0
- package/src/upgrade.js +3 -98
- package/src/README.md +0 -201
- package/src/presets/node-cli/templates/ja/commands.md +0 -2
- package/src/presets/node-cli/templates/ja/config.md +0 -2
- package/src/presets/node-cli/templates/ja/development.md +0 -2
- package/src/presets/node-cli/templates/ja/project_structure.md +0 -2
- package/src/presets/node-cli/templates/ja/stack_and_ops.md +0 -2
- package/src/presets/webapp/templates/ja/batch_and_shell.md +0 -43
- package/src/templates/skills/sdd-forge.flow-impl/SKILL.md +0 -148
- package/src/templates/skills/sdd-forge.flow-merge/SKILL.md +0 -178
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
# <!-- {{data
|
|
1
|
+
# <!-- {{data("cli.project.name")}} -->sdd-forge<!-- {{/data}} -->
|
|
2
2
|
|
|
3
|
-
<!-- {{data
|
|
3
|
+
<!-- {{data("cli.docs.langSwitcher", {labels: "absolute"})}} -->
|
|
4
4
|
**English** | [日本語](https://github.com/SpreadWorks/sdd-forge/blob/main/docs/ja/README.md)
|
|
5
5
|
<!-- {{/data}} -->
|
|
6
6
|
|
|
@@ -54,13 +54,13 @@ Documentation is automatically refreshed during the merge phase, so docs and cod
|
|
|
54
54
|
### Install
|
|
55
55
|
|
|
56
56
|
<pre>
|
|
57
|
-
npm install -g <!-- {{data
|
|
57
|
+
npm install -g <!-- {{data("cli.project.name")}} -->sdd-forge<!-- {{/data}} -->
|
|
58
58
|
</pre>
|
|
59
59
|
|
|
60
60
|
### Setup
|
|
61
61
|
|
|
62
62
|
<pre>
|
|
63
|
-
<!-- {{data
|
|
63
|
+
<!-- {{data("cli.project.name")}} -->sdd-forge<!-- {{/data}} --> setup
|
|
64
64
|
</pre>
|
|
65
65
|
|
|
66
66
|
An interactive wizard configures your project type (preset) and AI agent.
|
|
@@ -70,7 +70,7 @@ An interactive wizard configures your project type (preset) and AI agent.
|
|
|
70
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
71
|
|
|
72
72
|
<pre>
|
|
73
|
-
<!-- {{data
|
|
73
|
+
<!-- {{data("cli.project.name")}} -->sdd-forge<!-- {{/data}} --> docs build
|
|
74
74
|
</pre>
|
|
75
75
|
|
|
76
76
|
### Develop with the SDD flow
|
|
@@ -123,13 +123,14 @@ See the [configuration reference](docs/configuration.md) for details.
|
|
|
123
123
|
|
|
124
124
|
## Documentation
|
|
125
125
|
|
|
126
|
-
<!-- {{data
|
|
126
|
+
<!-- {{data("cli.docs.chapters", {header: "", labels: "Chapter|Summary", ignoreError: true})}} -->
|
|
127
127
|
| Chapter | Summary |
|
|
128
128
|
| --- | --- |
|
|
129
|
-
| [
|
|
130
|
-
| [
|
|
131
|
-
| [
|
|
132
|
-
| [
|
|
129
|
+
| [Tool Overview and Architecture](https://github.com/SpreadWorks/sdd-forge/blob/main/docs/overview.md) | sdd-forge is a CLI tool that automates technical documentation generation through source code analysis and provides a… |
|
|
130
|
+
| [Technology Stack and Operations](https://github.com/SpreadWorks/sdd-forge/blob/main/docs/stack_and_ops.md) | sdd-forge is a CLI tool built entirely in JavaScript on Node.js, using ES modules with zero external dependencies. |
|
|
131
|
+
| [Project Structure](https://github.com/SpreadWorks/sdd-forge/blob/main/docs/project_structure.md) | The project consists of 1 top-level source directory (src/) containing 157 files across 5 major areas: CLI entry poin… |
|
|
132
|
+
| [CLI Command Reference](https://github.com/SpreadWorks/sdd-forge/blob/main/docs/cli_commands.md) | sdd-forge provides over 25 CLI commands organized into four namespaces — docs (12 subcommands), spec (4 subcommands),… |
|
|
133
|
+
| [Configuration and Customization](https://github.com/SpreadWorks/sdd-forge/blob/main/docs/configuration.md) | sdd-forge uses two primary configuration files — .sdd-forge/config.json for project-specific settings and preset.json… |
|
|
133
134
|
<!-- {{/data}} -->
|
|
134
135
|
|
|
135
136
|
## License
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sdd-forge",
|
|
3
|
-
"version": "0.1.0-alpha.
|
|
3
|
+
"version": "0.1.0-alpha.361",
|
|
4
4
|
"description": "Spec-Driven Development tooling for automated documentation generation",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -11,7 +11,8 @@
|
|
|
11
11
|
"sdd-forge": "./src/sdd-forge.js"
|
|
12
12
|
},
|
|
13
13
|
"files": [
|
|
14
|
-
"src/"
|
|
14
|
+
"src/",
|
|
15
|
+
"!src/presets/*/tests/"
|
|
15
16
|
],
|
|
16
17
|
"engines": {
|
|
17
18
|
"node": ">=18.0.0"
|
|
@@ -24,7 +25,10 @@
|
|
|
24
25
|
"technical-docs"
|
|
25
26
|
],
|
|
26
27
|
"scripts": {
|
|
27
|
-
"test": "
|
|
28
|
+
"test": "node tests/run.js",
|
|
29
|
+
"test:unit": "node tests/run.js --scope unit",
|
|
30
|
+
"test:e2e": "node tests/run.js --scope e2e",
|
|
31
|
+
"test:acceptance": "node tests/acceptance/run.js"
|
|
28
32
|
},
|
|
29
33
|
"license": "MIT"
|
|
30
34
|
}
|
package/src/AGENTS.md
ADDED
|
@@ -0,0 +1,420 @@
|
|
|
1
|
+
# sdd-forge — 内部アーキテクチャとルール
|
|
2
|
+
|
|
3
|
+
このドキュメントは `src/` 配下のコード(npm パッケージとして配布される)の開発ルールを定義する。
|
|
4
|
+
|
|
5
|
+
## プロジェクト概要
|
|
6
|
+
|
|
7
|
+
- **パッケージ:** `sdd-forge`
|
|
8
|
+
- **説明:** ソースコード解析に基づくドキュメント自動生成と SDD ワークフローを提供する CLI ツール
|
|
9
|
+
- **モジュール形式:** ES Modules (`"type": "module"`)
|
|
10
|
+
- **ランタイム:** Node.js >= 18.0.0
|
|
11
|
+
- **外部依存:** なし(Node.js 組み込みモジュールのみ)
|
|
12
|
+
- **エントリポイント:** `./src/sdd-forge.js`
|
|
13
|
+
|
|
14
|
+
## ディレクトリ構造
|
|
15
|
+
|
|
16
|
+
```
|
|
17
|
+
src/
|
|
18
|
+
├── sdd-forge.js CLI エントリポイント(トップレベルディスパッチャ)
|
|
19
|
+
├── docs.js docs ディスパッチャ
|
|
20
|
+
├── spec.js spec ディスパッチャ
|
|
21
|
+
├── flow.js flow ディスパッチャ
|
|
22
|
+
├── setup.js / upgrade.js / presets-cmd.js / help.js 独立コマンド
|
|
23
|
+
├── lib/ 全レイヤー共有ユーティリティ
|
|
24
|
+
│ ├── cli.js repoRoot, sourceRoot, parseArgs, PKG_DIR
|
|
25
|
+
│ ├── config.js .sdd-forge/config.json ローダー
|
|
26
|
+
│ ├── agent.js AI エージェント呼び出し
|
|
27
|
+
│ ├── presets.js プリセット自動探索・親チェーン解決
|
|
28
|
+
│ ├── flow-state.js SDD フロー状態永続化
|
|
29
|
+
│ ├── i18n.js 3層 i18n(ドメイン名前空間付き)
|
|
30
|
+
│ └── types.js 型エイリアス解決・バリデーション
|
|
31
|
+
├── docs/
|
|
32
|
+
│ ├── commands/ scan, enrich, init, data, text, readme,
|
|
33
|
+
│ │ forge, review, changelog, agents, translate
|
|
34
|
+
│ ├── data/ 共通 DataSource(project, docs, lang, agents)
|
|
35
|
+
│ └── lib/ ドキュメント生成エンジン
|
|
36
|
+
├── flow/commands/ start, status, review, merge, resume, cleanup
|
|
37
|
+
├── spec/commands/ init, gate, guardrail
|
|
38
|
+
├── presets/ プリセット群(後述)
|
|
39
|
+
├── locale/ en/, ja/
|
|
40
|
+
└── templates/ スキャフォールドテンプレート
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## コマンドルーティング
|
|
44
|
+
|
|
45
|
+
3段階ディスパッチ: `sdd-forge.js` → `docs.js`/`spec.js`/`flow.js` → `commands/*.js`
|
|
46
|
+
|
|
47
|
+
```
|
|
48
|
+
sdd-forge <cmd> [args]
|
|
49
|
+
│
|
|
50
|
+
├─ sdd-forge.js # 1. プロジェクトコンテキスト解決 + ディスパッチ
|
|
51
|
+
│ ├─ docs.js # 2. docs サブコマンドのルーティング
|
|
52
|
+
│ │ └─ docs/commands/*.js # 3. 実際のコマンド実装
|
|
53
|
+
│ ├─ spec.js # 2. spec サブコマンドのルーティング
|
|
54
|
+
│ │ └─ spec/commands/*.js
|
|
55
|
+
│ ├─ flow.js # 2+3. 直接実行(ディスパッチャなし)
|
|
56
|
+
│ └─ help.js # 2+3. 直接実行
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### プロジェクトコンテキスト
|
|
60
|
+
|
|
61
|
+
`sdd-forge.js` は実行時に以下の環境変数を設定する:
|
|
62
|
+
|
|
63
|
+
| 環境変数 | 意味 | 設定元 |
|
|
64
|
+
|---|---|---|
|
|
65
|
+
| `SDD_SOURCE_ROOT` | 対象プロジェクトのソースコードルート | `cli.js` で解決 |
|
|
66
|
+
| `SDD_WORK_ROOT` | 作業ディレクトリ(`.sdd-forge/`, `docs/` の親) | `cli.js` で解決 |
|
|
67
|
+
|
|
68
|
+
### ドキュメント生成パイプライン
|
|
69
|
+
|
|
70
|
+
`sdd-forge docs build` は以下のパイプラインを順に実行する:
|
|
71
|
+
|
|
72
|
+
```
|
|
73
|
+
scan → enrich → init → data → text → readme → agents → [translate]
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
| ステップ | 役割 |
|
|
77
|
+
|---|---|
|
|
78
|
+
| **scan** | ソースコードをスキャンし analysis.json を生成 |
|
|
79
|
+
| **enrich** | AI で analysis エントリーに summary/chapter/role を付与 |
|
|
80
|
+
| **init** | テンプレートを継承チェーンでマージし docs/ に出力 |
|
|
81
|
+
| **data** | `{{data}}` ディレクティブを analysis データで置換 |
|
|
82
|
+
| **text** | `{{text}}` ディレクティブを AI 生成テキストで埋める |
|
|
83
|
+
| **readme** | README.md を生成 |
|
|
84
|
+
| **agents** | AGENTS.md を生成 |
|
|
85
|
+
|
|
86
|
+
---
|
|
87
|
+
|
|
88
|
+
## プリセットシステム
|
|
89
|
+
|
|
90
|
+
### 概要
|
|
91
|
+
|
|
92
|
+
プリセットはフレームワーク固有のスキャン設定・DataSource・テンプレートをパッケージ化する。
|
|
93
|
+
`parent` フィールドによる単一継承チェーンで構成される。
|
|
94
|
+
|
|
95
|
+
```
|
|
96
|
+
base → webapp → js-webapp → hono
|
|
97
|
+
base → webapp → js-webapp → nextjs
|
|
98
|
+
base → webapp → php-webapp → cakephp2
|
|
99
|
+
base → webapp → php-webapp → laravel
|
|
100
|
+
base → webapp → php-webapp → symfony
|
|
101
|
+
base → cli → node-cli
|
|
102
|
+
base → library
|
|
103
|
+
base → database → drizzle
|
|
104
|
+
base → edge → workers
|
|
105
|
+
base → storage → r2
|
|
106
|
+
base → api → rest
|
|
107
|
+
base → api → graphql
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### preset.json の構造
|
|
111
|
+
|
|
112
|
+
```json
|
|
113
|
+
{
|
|
114
|
+
"parent": "webapp",
|
|
115
|
+
"label": "CakePHP 2.x",
|
|
116
|
+
"aliases": [],
|
|
117
|
+
"chapters": ["overview.md", "stack_and_ops.md", ...],
|
|
118
|
+
"scan": {
|
|
119
|
+
"include": ["app/**/*.php"],
|
|
120
|
+
"exclude": ["vendor/**"]
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
| フィールド | 説明 |
|
|
126
|
+
|---|---|
|
|
127
|
+
| `parent` | 親プリセットの key(継承チェーン) |
|
|
128
|
+
| `label` | 表示名 |
|
|
129
|
+
| `chapters` | このプリセットの章順序(子は親の chapters を上書き) |
|
|
130
|
+
| `scan.include` | スキャン対象の glob パターン |
|
|
131
|
+
| `scan.exclude` | 除外パターン |
|
|
132
|
+
|
|
133
|
+
### プリセットディレクトリ構成
|
|
134
|
+
|
|
135
|
+
```
|
|
136
|
+
presets/<key>/
|
|
137
|
+
├── preset.json プリセット定義
|
|
138
|
+
├── data/ DataSource クラス群
|
|
139
|
+
│ ├── config.js 設定解析
|
|
140
|
+
│ ├── controllers.js コントローラ解析
|
|
141
|
+
│ └── ...
|
|
142
|
+
├── scan/ scan パーサー群
|
|
143
|
+
│ ├── routes.js ルート解析
|
|
144
|
+
│ ├── config.js 設定解析
|
|
145
|
+
│ └── ...
|
|
146
|
+
├── tests/ プリセット固有テスト
|
|
147
|
+
│ ├── unit/ ユニットテスト(scan パーサー I/O テスト等)
|
|
148
|
+
│ └── e2e/ E2E テスト(統合スキャンテスト等)
|
|
149
|
+
└── templates/ 章テンプレート
|
|
150
|
+
├── ja/
|
|
151
|
+
│ ├── overview.md
|
|
152
|
+
│ ├── stack_and_ops.md
|
|
153
|
+
│ └── ...
|
|
154
|
+
└── en/
|
|
155
|
+
└── ...
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
---
|
|
159
|
+
|
|
160
|
+
## プリセット作成ルール
|
|
161
|
+
|
|
162
|
+
### MUST: プリセット作成手順(トップダウン設計)
|
|
163
|
+
|
|
164
|
+
プリセットの構成要素は以下の順序で作成すること:
|
|
165
|
+
|
|
166
|
+
1. **テンプレート** (`templates/`) — どんなドキュメントを出力するか定義する
|
|
167
|
+
2. **DataSource** (`data/`) — テンプレートが必要とするデータを定義する
|
|
168
|
+
3. **scan パーサー** (`scan/`) — DataSource にデータを供給するパーサーを実装する
|
|
169
|
+
|
|
170
|
+
消費者(テンプレート)→ 仲介者(DataSource)→ 生産者(scan)の順に作ることで、不要なパーサーを書かず、必要なデータの漏れがなくなる。
|
|
171
|
+
|
|
172
|
+
### MUST: プリセットテストの作成
|
|
173
|
+
|
|
174
|
+
プリセットは `tests/` ディレクトリを含むこと。
|
|
175
|
+
|
|
176
|
+
- `tests/unit/` — scan パーサーの I/O テスト。最小限のフィクスチャを `createTmpDir()` で作成し、パーサー関数の入出力を検証する
|
|
177
|
+
- `tests/e2e/` — preset.json の scan 設定検証、フルスキャンパイプラインテスト
|
|
178
|
+
- `npm test -- --preset <name>` でプリセット毎のテストを実行できること
|
|
179
|
+
- テストファイルは npm パッケージには含まれない(package.json の `files` で除外済み)
|
|
180
|
+
|
|
181
|
+
### MUST: scan DataSource と data DataSource の対応
|
|
182
|
+
|
|
183
|
+
**data DataSource が `analysis.X` を読むなら、チェーン内に `X` を書く scan DataSource が必要。**
|
|
184
|
+
|
|
185
|
+
- scan DataSource は `match(file)` + `scan(files)` メソッドを持ち、ファイルを解析して `analysis[name]` に書き込む
|
|
186
|
+
- data DataSource は `analysis[key]` を読んでマークダウンテーブルを生成する
|
|
187
|
+
- この2つは対であるべき
|
|
188
|
+
- scan DataSource を実装できるなら実装する(フレームワーク固有の scan は子プリセットで実装する)
|
|
189
|
+
- scan DataSource を実装できない場合は、data DataSource も作ってはならない。テンプレートは `{{text}}` にする
|
|
190
|
+
- **data DataSource だけが存在し、対応する scan DataSource がない状態はルール違反**
|
|
191
|
+
|
|
192
|
+
```
|
|
193
|
+
✅ 正しい例:
|
|
194
|
+
scan DataSource "modules" → analysis.modules に書き込む
|
|
195
|
+
data DataSource modules.list() → analysis.modules を読む
|
|
196
|
+
|
|
197
|
+
❌ 間違い:
|
|
198
|
+
data DataSource schema.tables() → analysis.schemas を読む
|
|
199
|
+
→ analysis.schemas を書く scan DataSource がどこにもない
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
### MUST: `{{data}}` と `{{text}}` の使い分け
|
|
203
|
+
|
|
204
|
+
| 条件 | ディレクティブ |
|
|
205
|
+
|---|---|
|
|
206
|
+
| scan で構造的に収集できるデータ | `{{data("preset.source.method")}}` |
|
|
207
|
+
| scan で収集不可(フレームワーク固有すぎる) | `{{text({prompt: "..."})}}` |
|
|
208
|
+
|
|
209
|
+
**判断基準**: そのデータを正規表現やパーサーで機械的に抽出できるか?
|
|
210
|
+
- YES → `{{data}}`(テーブル形式で正確なデータを提供)
|
|
211
|
+
- NO → `{{text}}`(AI がソースコードと analysis コンテキストから文章を生成)
|
|
212
|
+
|
|
213
|
+
### MUST: 親テンプレートは `{{text}}`、子が `{{data}}` で override
|
|
214
|
+
|
|
215
|
+
フレームワーク固有のデータを表示する箇所は、親(webapp 等)テンプレートでは `{{text}}` + `{%block%}` で定義し、子プリセットが block override で `{{data}}` に差し替える。
|
|
216
|
+
|
|
217
|
+
```markdown
|
|
218
|
+
<!-- webapp/templates/ja/auth_and_session.md -->
|
|
219
|
+
<!-- {%block "auth_config"%} -->
|
|
220
|
+
<!-- {{text({prompt: "認証設定を説明してください。"})}} -->
|
|
221
|
+
<!-- {{/text}} -->
|
|
222
|
+
<!-- {%/block%} -->
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
```markdown
|
|
226
|
+
<!-- cakephp2/templates/ja/auth_and_session.md -->
|
|
227
|
+
<!-- {%extends%} -->
|
|
228
|
+
<!-- {%block "auth_config"%} -->
|
|
229
|
+
<!-- {{data("cakephp2.config.auth", {labels: "項目|内容"})}} -->
|
|
230
|
+
<!-- {{/data}} -->
|
|
231
|
+
<!-- {%/block%} -->
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
これにより:
|
|
235
|
+
- webapp 単体: AI が文章を生成(scan データがなくても動く)
|
|
236
|
+
- cakephp2: scan データから正確なテーブルを出力
|
|
237
|
+
- 将来のプリセット: override テンプレートを追加するだけ
|
|
238
|
+
|
|
239
|
+
### MUST: enrich は静的収集データの加工に留める
|
|
240
|
+
|
|
241
|
+
enrich フェーズは scan が収集したエントリーへのメタデータ付与(summary, chapter, role)のみを行う。
|
|
242
|
+
新しい analysis カテゴリの生成や、scan が見つけていないデータの創出は行わない。
|
|
243
|
+
|
|
244
|
+
### DataSource の2種類
|
|
245
|
+
|
|
246
|
+
**1. Scannable DataSource(scan + data 兼用)**
|
|
247
|
+
|
|
248
|
+
```javascript
|
|
249
|
+
import { Scannable } from "../../../docs/lib/scan-source.js";
|
|
250
|
+
import { DataSource } from "../../../docs/lib/data-source.js";
|
|
251
|
+
|
|
252
|
+
export default class ModulesSource extends Scannable(DataSource) {
|
|
253
|
+
match(file) { return file.ext === ".js"; }
|
|
254
|
+
scan(files) { return { modules: [...], summary: { total: files.length } }; }
|
|
255
|
+
list(analysis, labels) { /* analysis.modules を読んでテーブル生成 */ }
|
|
256
|
+
}
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
- `match(file)`: このソースが処理すべきファイルか判定
|
|
260
|
+
- `scan(files)`: マッチしたファイルを解析し、analysis に書き込むデータを返す
|
|
261
|
+
- その他メソッド: data コマンドで呼ばれ、analysis を読んでマークダウンを返す
|
|
262
|
+
|
|
263
|
+
**2. Data-only DataSource(data 専用)**
|
|
264
|
+
|
|
265
|
+
```javascript
|
|
266
|
+
import { DataSource } from "../../../docs/lib/data-source.js";
|
|
267
|
+
|
|
268
|
+
export default class SchemaSource extends DataSource {
|
|
269
|
+
tables(analysis, labels) { /* analysis.schemas.tables を読んでテーブル生成 */ }
|
|
270
|
+
}
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
- `scan()` / `match()` を持たない
|
|
274
|
+
- analysis にデータがあれば動作する(なければ null を返す)
|
|
275
|
+
- **MUST**: このパターンを使う場合、読む analysis キーを書く scan DataSource がチェーン内に存在する必要がある。対応する scan がないなら data DataSource を作ってはならない
|
|
276
|
+
|
|
277
|
+
---
|
|
278
|
+
|
|
279
|
+
## テンプレート構文
|
|
280
|
+
|
|
281
|
+
### ディレクティブ
|
|
282
|
+
|
|
283
|
+
**出力ディレクティブ** (`{{ }}`):
|
|
284
|
+
|
|
285
|
+
```html
|
|
286
|
+
<!-- {{data("preset.source.method", {labels: "ヘッダ1|ヘッダ2"})}} -->
|
|
287
|
+
<!-- {{/data}} -->
|
|
288
|
+
|
|
289
|
+
<!-- {{text({prompt: "説明を書いてください。", mode: "deep"})}} -->
|
|
290
|
+
<!-- {{/text}} -->
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
**制御ディレクティブ** (`{% %}`):
|
|
294
|
+
|
|
295
|
+
```html
|
|
296
|
+
<!-- {%extends "layout"%} -->
|
|
297
|
+
|
|
298
|
+
<!-- {%block "content"%} -->
|
|
299
|
+
...
|
|
300
|
+
<!-- {%/block%} -->
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
### テンプレート継承
|
|
304
|
+
|
|
305
|
+
`{%extends%}` で親テンプレートのブロックを継承・上書きする。
|
|
306
|
+
|
|
307
|
+
```
|
|
308
|
+
layout.md(レイアウト)
|
|
309
|
+
└─ overview.md({%extends "layout"%} で継承)
|
|
310
|
+
└─ cakephp2/overview.md({%extends%} で override)
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
**layout.md のナビゲーション**: layout を extends するテンプレートは自動的にナビゲーション(前後章リンク)が付与される。extends しないテンプレートにはナビが付かない。
|
|
314
|
+
|
|
315
|
+
### block のネスト
|
|
316
|
+
|
|
317
|
+
block は入れ子にできる。親ブロック内にネストされたブロックは、子テンプレートで個別に override 可能。
|
|
318
|
+
|
|
319
|
+
```markdown
|
|
320
|
+
<!-- {%block "content"%} -->
|
|
321
|
+
## 見出し
|
|
322
|
+
<!-- {%block "section_a"%} -->
|
|
323
|
+
セクション A の内容
|
|
324
|
+
<!-- {%/block%} -->
|
|
325
|
+
<!-- {%block "section_b"%} -->
|
|
326
|
+
セクション B の内容
|
|
327
|
+
<!-- {%/block%} -->
|
|
328
|
+
<!-- {%/block%} -->
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
---
|
|
332
|
+
|
|
333
|
+
## コーディングルール
|
|
334
|
+
|
|
335
|
+
### プロジェクト固有情報の埋め込み禁止
|
|
336
|
+
|
|
337
|
+
`src/` 配下のコードおよびテンプレートに、特定プロジェクトの情報を直接書いてはならない。
|
|
338
|
+
|
|
339
|
+
- **禁止**: プロジェクト名、ホスト名、ポート番号、コンテナ名、固有 DB 名
|
|
340
|
+
- **許可**: `presets/` 配下のフレームワーク固有ロジック(汎用的な解析パターン)
|
|
341
|
+
- **設定**: プロジェクト固有の値は `.sdd-forge/config.json` で外部化する
|
|
342
|
+
|
|
343
|
+
### 外部依存の禁止
|
|
344
|
+
|
|
345
|
+
Node.js 組み込み API (`fs`, `path`, `child_process`, `url` 等) のみを使用する。
|
|
346
|
+
npm パッケージへの依存を追加しないこと。
|
|
347
|
+
|
|
348
|
+
### フォールバック値の抑制
|
|
349
|
+
|
|
350
|
+
必須の設定値・環境変数が不足している場合は、黙ってデフォルト値で動作させず、エラーメッセージを出力して停止すること。
|
|
351
|
+
|
|
352
|
+
### コマンドファイルの構造
|
|
353
|
+
|
|
354
|
+
`commands/` 配下のファイルは以下のパターンに従う:
|
|
355
|
+
|
|
356
|
+
```javascript
|
|
357
|
+
import { runIfDirect } from "../../lib/entrypoint.js";
|
|
358
|
+
import { parseArgs } from "../../lib/cli.js";
|
|
359
|
+
import { resolveCommandContext } from "../lib/command-context.js";
|
|
360
|
+
|
|
361
|
+
async function main(ctx) {
|
|
362
|
+
if (!ctx) {
|
|
363
|
+
const cli = parseArgs(process.argv.slice(2), { ... });
|
|
364
|
+
if (cli.help) { printHelp(); return; }
|
|
365
|
+
ctx = resolveCommandContext(cli);
|
|
366
|
+
}
|
|
367
|
+
// 実装
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
export { main };
|
|
371
|
+
runIfDirect(import.meta.url, main);
|
|
372
|
+
```
|
|
373
|
+
|
|
374
|
+
### AI エージェント呼び出し (`lib/agent.js`)
|
|
375
|
+
|
|
376
|
+
**非同期呼び出しで `execFile` を使ってはならない。**
|
|
377
|
+
|
|
378
|
+
`child_process.spawn` を使い、`stdio: ["ignore", "pipe", "pipe"]` を明示する。
|
|
379
|
+
`execFile` は stdin を pipe モードで開くが、Claude CLI は stdin が pipe だと EOF を待ち続けてハングする。
|
|
380
|
+
|
|
381
|
+
```javascript
|
|
382
|
+
// NG: execFile — stdin が pipe のままでハングする
|
|
383
|
+
execFile("claude", args, opts, callback);
|
|
384
|
+
|
|
385
|
+
// OK: spawn — stdin を ignore で閉じる
|
|
386
|
+
const child = spawn("claude", args, {
|
|
387
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
388
|
+
...opts,
|
|
389
|
+
});
|
|
390
|
+
```
|
|
391
|
+
|
|
392
|
+
---
|
|
393
|
+
|
|
394
|
+
## テスト
|
|
395
|
+
|
|
396
|
+
### プリセット整合性テスト
|
|
397
|
+
|
|
398
|
+
`tests/unit/presets/preset-scan-integrity.test.js` が以下を自動検証する:
|
|
399
|
+
|
|
400
|
+
1. **scan パターンと scan DataSource の整合性** — preset.json に scan.include を定義しているプリセットは、チェーン内に scan DataSource を持つ
|
|
401
|
+
2. **テンプレートの data ディレクティブと DataSource メソッドの整合性** — `{{data("preset.source.method")}}` が参照するメソッドが DataSource に存在する
|
|
402
|
+
3. **analysis キーのカバレッジ** — data DataSource が `analysis.X` を読むなら、`X` を書く scan DataSource がプリセットエコシステム内に存在する
|
|
403
|
+
|
|
404
|
+
**新しいプリセットを追加・変更したら `npm test` を実行し、整合性テストがパスすることを確認すること。**
|
|
405
|
+
|
|
406
|
+
### プリセット固有テスト
|
|
407
|
+
|
|
408
|
+
プリセット固有テストの配置ルールとテスト内容は「プリセット作成ルール > MUST: プリセットテストの作成」を参照。
|
|
409
|
+
|
|
410
|
+
**プリセット毎のテスト実行:**
|
|
411
|
+
|
|
412
|
+
```bash
|
|
413
|
+
npm test -- --preset laravel # tests/unit + tests/e2e + src/presets/laravel/tests/
|
|
414
|
+
npm test -- --preset symfony # tests/unit + tests/e2e + src/presets/symfony/tests/
|
|
415
|
+
```
|
|
416
|
+
|
|
417
|
+
### テストルール
|
|
418
|
+
|
|
419
|
+
- テストを通すためにテストコードを修正してはならない
|
|
420
|
+
- テスト失敗時はまずシナリオの妥当性を確認し、妥当であればプロダクトコードを修正する
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* src/docs/commands/agents.js
|
|
4
4
|
*
|
|
5
5
|
* AGENTS.md を更新する。
|
|
6
|
-
* AGENTS.md 内の {{data
|
|
6
|
+
* AGENTS.md 内の {{data("agents.sdd")}} / {{data("agents.project")}} ディレクティブを解決し、
|
|
7
7
|
* PROJECT セクションは AI で精査する。
|
|
8
8
|
*/
|
|
9
9
|
|
|
@@ -14,11 +14,11 @@ import { parseArgs } from "../../lib/cli.js";
|
|
|
14
14
|
import { sddOutputDir } from "../../lib/config.js";
|
|
15
15
|
import { callAgent, loadAgentConfig, DEFAULT_AGENT_TIMEOUT } from "../../lib/agent.js";
|
|
16
16
|
import { translate } from "../../lib/i18n.js";
|
|
17
|
-
import { resolveType } from "../../lib/types.js";
|
|
18
17
|
import { createResolver } from "../lib/resolver-factory.js";
|
|
19
18
|
import { createLogger } from "../../lib/progress.js";
|
|
20
19
|
import { parseDirectives, replaceBlockDirective, resolveDataDirectives } from "../lib/directive-parser.js";
|
|
21
20
|
import { resolveCommandContext, loadFullAnalysis, getChapterFiles, readText } from "../lib/command-context.js";
|
|
21
|
+
import { loadSddTemplate } from "../../lib/agents-md.js";
|
|
22
22
|
|
|
23
23
|
const logger = createLogger("agents");
|
|
24
24
|
|
|
@@ -52,7 +52,8 @@ function buildRefinePrompt(projectContent, docsContent, config, srcRoot, sddCont
|
|
|
52
52
|
|
|
53
53
|
if (config.type) {
|
|
54
54
|
parts.push("## Project Config");
|
|
55
|
-
|
|
55
|
+
const typeStr = Array.isArray(config.type) ? config.type.join(", ") : config.type;
|
|
56
|
+
parts.push(`- type: ${typeStr}`);
|
|
56
57
|
parts.push("");
|
|
57
58
|
}
|
|
58
59
|
|
|
@@ -90,7 +91,7 @@ function resolveAgentsDirectives(text, resolveFn) {
|
|
|
90
91
|
|
|
91
92
|
const result = resolveDataDirectives(
|
|
92
93
|
text,
|
|
93
|
-
(source, method, labels) => resolveFn(source, method, {}, labels),
|
|
94
|
+
(preset, source, method, labels) => resolveFn(preset, source, method, {}, labels),
|
|
94
95
|
{
|
|
95
96
|
onResolve(d, rendered) {
|
|
96
97
|
if (d.source === "agents" && d.method === "sdd") sddContent = rendered;
|
|
@@ -152,7 +153,21 @@ async function main(ctx) {
|
|
|
152
153
|
|
|
153
154
|
const agentsPath = path.join(srcRoot, "AGENTS.md");
|
|
154
155
|
if (!fs.existsSync(agentsPath)) {
|
|
155
|
-
|
|
156
|
+
// Generate from template
|
|
157
|
+
const sddSection = loadSddTemplate(lang || config?.lang || "en");
|
|
158
|
+
const template = [
|
|
159
|
+
`# ${path.basename(srcRoot)}`,
|
|
160
|
+
"",
|
|
161
|
+
'<!-- {{data("agents.sdd")}} -->',
|
|
162
|
+
sddSection,
|
|
163
|
+
"<!-- {{/data}} -->",
|
|
164
|
+
"",
|
|
165
|
+
'<!-- {{data("agents.project")}} -->',
|
|
166
|
+
"<!-- {{/data}} -->",
|
|
167
|
+
"",
|
|
168
|
+
].join("\n");
|
|
169
|
+
fs.writeFileSync(agentsPath, template, "utf8");
|
|
170
|
+
logger.log(`created ${agentsPath}`);
|
|
156
171
|
}
|
|
157
172
|
|
|
158
173
|
// Load analysis
|
|
@@ -169,9 +184,9 @@ async function main(ctx) {
|
|
|
169
184
|
const combinedDocs = [docsContent, readmeContent].filter(Boolean).join("\n\n---\n\n");
|
|
170
185
|
|
|
171
186
|
// Create resolver and resolve {{data}} directives
|
|
172
|
-
const resolvedType =
|
|
187
|
+
const resolvedType = config.type || "base";
|
|
173
188
|
const resolver = await createResolver(resolvedType, root, { configChapters: config.chapters });
|
|
174
|
-
const resolveFn = (source, method, a, labels) => resolver.resolve(source, method, analysis, labels);
|
|
189
|
+
const resolveFn = (preset, source, method, a, labels) => resolver.resolve(preset, source, method, analysis, labels);
|
|
175
190
|
|
|
176
191
|
let content = fs.readFileSync(agentsPath, "utf8");
|
|
177
192
|
const { text: resolved, sddContent, projectContent } = resolveAgentsDirectives(content, resolveFn);
|
|
@@ -33,7 +33,7 @@ const logger = createLogger("data");
|
|
|
33
33
|
* @param {string} text - テンプレート全文
|
|
34
34
|
* @param {Object} analysis - analysis.json
|
|
35
35
|
* @param {string} fileName - ログ出力用ファイル名
|
|
36
|
-
* @param {function} [resolveFn] - (source, method, analysis, labels) => rendered string
|
|
36
|
+
* @param {function} [resolveFn] - (preset, source, method, analysis, labels) => rendered string
|
|
37
37
|
* @returns {{ text: string, replaced: number, skipped: number }}
|
|
38
38
|
*/
|
|
39
39
|
function processTemplate(text, analysis, fileName, resolveFn) {
|
|
@@ -45,7 +45,7 @@ function processTemplate(text, analysis, fileName, resolveFn) {
|
|
|
45
45
|
|
|
46
46
|
const result = resolveDataDirectives(
|
|
47
47
|
text,
|
|
48
|
-
(source, method, labels) => resolveFn(source, method, analysis, labels),
|
|
48
|
+
(preset, source, method, labels) => resolveFn(preset, source, method, analysis, labels),
|
|
49
49
|
{
|
|
50
50
|
onSkip(d) {
|
|
51
51
|
if (d.type === "text") {
|
|
@@ -55,7 +55,7 @@ function processTemplate(text, analysis, fileName, resolveFn) {
|
|
|
55
55
|
},
|
|
56
56
|
onUnresolved(d) {
|
|
57
57
|
unresolved++;
|
|
58
|
-
logger.log(`UNRESOLVED {{data}} in ${fileName}:${d.line + 1}: ${d.source}.${d.method} → null`);
|
|
58
|
+
logger.log(`UNRESOLVED {{data}} in ${fileName}:${d.line + 1}: ${d.preset}.${d.source}.${d.method} → null`);
|
|
59
59
|
},
|
|
60
60
|
},
|
|
61
61
|
);
|
|
@@ -128,7 +128,7 @@ async function main(ctx) {
|
|
|
128
128
|
let resolveFn;
|
|
129
129
|
try {
|
|
130
130
|
const resolver = await createResolver(type, root, { docsDir, configChapters: ctx.config?.chapters });
|
|
131
|
-
resolveFn = (source, method, a, labels) => resolver.resolve(source, method, a, labels);
|
|
131
|
+
resolveFn = (preset, source, method, a, labels) => resolver.resolve(preset, source, method, a, labels);
|
|
132
132
|
logger.verbose(`resolver: ${type}`);
|
|
133
133
|
} catch (err) {
|
|
134
134
|
throw new Error(t("messages:data.resolverFailed", { message: err.message }));
|
|
@@ -146,15 +146,17 @@ async function main(ctx) {
|
|
|
146
146
|
for (const file of docsFiles) {
|
|
147
147
|
const filePath = path.join(docsDir, file);
|
|
148
148
|
const original = fs.readFileSync(filePath, "utf8");
|
|
149
|
-
// Inject file path context for
|
|
150
|
-
const
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
149
|
+
// Inject file path context for file-aware resolvers
|
|
150
|
+
const fileRelPath = `${docsDirRel}/${file}`;
|
|
151
|
+
const FILE_CONTEXT_RULES = {
|
|
152
|
+
"lang.links": (_labels) => [fileRelPath],
|
|
153
|
+
"docs.langSwitcher": (labels) => [labels[0] || "relative", fileRelPath],
|
|
154
|
+
"docs.nav": (_labels) => [fileRelPath],
|
|
155
|
+
};
|
|
156
|
+
const wrappedResolveFn = (preset, source, method, a, labels) => {
|
|
157
|
+
const rule = FILE_CONTEXT_RULES[`${source}.${method}`];
|
|
158
|
+
if (rule) return resolveFn(preset, source, method, a, rule(labels));
|
|
159
|
+
return resolveFn(preset, source, method, a, labels);
|
|
158
160
|
};
|
|
159
161
|
const result = processTemplate(original, analysis, file, wrappedResolveFn);
|
|
160
162
|
|