@ryuenn3123/agentic-senior-core 4.4.0 → 5.2.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 (201) hide show
  1. package/.agents/plugins/agentic-senior-core/plugin.json +3 -0
  2. package/.agents/plugins/agentic-senior-core/rules/agentic-senior-core.md +131 -0
  3. package/.agents/plugins/agentic-senior-core/skills/asc/SKILL.md +16 -0
  4. package/.agents/plugins/agentic-senior-core/skills/asc-audit/SKILL.md +28 -0
  5. package/.agents/plugins/agentic-senior-core/skills/asc-refactor/SKILL.md +35 -0
  6. package/.agents/plugins/agentic-senior-core/skills/asc-review/SKILL.md +54 -0
  7. package/.agents/rules/agentic-senior-core.md +131 -0
  8. package/.claude-plugin/marketplace.json +17 -0
  9. package/.claude-plugin/plugin.json +17 -0
  10. package/.clinerules/agentic-senior-core.md +94 -0
  11. package/.codex-plugin/plugin.json +24 -0
  12. package/.cursor/rules/agentic-senior-core.mdc +99 -0
  13. package/.devin-plugin/plugin.json +13 -0
  14. package/.github/copilot-instructions.md +94 -0
  15. package/.github/plugin/marketplace.json +20 -0
  16. package/.github/plugin/plugin.json +16 -0
  17. package/.kiro/steering/agentic-senior-core.md +94 -0
  18. package/.openclaw/skills/asc/SKILL.md +23 -0
  19. package/.openclaw/skills/asc-audit/SKILL.md +28 -0
  20. package/.openclaw/skills/asc-review/SKILL.md +54 -0
  21. package/.opencode/plugins/agentic-senior-core.mjs +31 -0
  22. package/.windsurf/rules/agentic-senior-core.md +94 -0
  23. package/AGENTS.md +126 -127
  24. package/CONTRIBUTING.md +93 -63
  25. package/README.md +190 -110
  26. package/__init__.py +61 -0
  27. package/bin/agentic-senior-core.js +42 -41
  28. package/commands/asc-audit.md +1 -0
  29. package/commands/asc-audit.toml +2 -0
  30. package/commands/asc-help.md +9 -0
  31. package/commands/asc-help.toml +2 -0
  32. package/commands/asc-refactor.md +1 -0
  33. package/commands/asc-refactor.toml +2 -0
  34. package/commands/asc-review.md +1 -0
  35. package/commands/asc-review.toml +2 -0
  36. package/gemini-extension.json +10 -0
  37. package/hooks/copilot-hooks.json +21 -0
  38. package/hooks/hooks.json +31 -0
  39. package/hooks/session-start.js +36 -0
  40. package/hooks/subagent-start.js +38 -0
  41. package/lib/cli/commands/adapter.mjs +109 -0
  42. package/lib/cli/commands/clean.mjs +63 -0
  43. package/lib/cli/commands/status.mjs +94 -0
  44. package/package.json +43 -60
  45. package/plugin.yaml +16 -0
  46. package/scripts/uninstall.js +38 -0
  47. package/skills/asc/SKILL.md +16 -0
  48. package/skills/asc-audit/SKILL.md +28 -0
  49. package/skills/asc-refactor/SKILL.md +35 -0
  50. package/skills/asc-review/SKILL.md +54 -0
  51. package/.agent-context/policies/llm-judge-threshold.json +0 -29
  52. package/.agent-context/prompts/bootstrap-design.md +0 -63
  53. package/.agent-context/prompts/compact-natural-mode.md +0 -100
  54. package/.agent-context/prompts/init-project.md +0 -60
  55. package/.agent-context/prompts/refactor.md +0 -38
  56. package/.agent-context/prompts/review-code.md +0 -31
  57. package/.agent-context/review-checklists/architecture-review.md +0 -57
  58. package/.agent-context/review-checklists/pr-checklist.md +0 -134
  59. package/.agent-context/rules/api-docs.md +0 -24
  60. package/.agent-context/rules/api-versioning.md +0 -16
  61. package/.agent-context/rules/architecture.md +0 -38
  62. package/.agent-context/rules/background-jobs.md +0 -17
  63. package/.agent-context/rules/config-and-flags.md +0 -16
  64. package/.agent-context/rules/database-design.md +0 -18
  65. package/.agent-context/rules/docker-runtime.md +0 -17
  66. package/.agent-context/rules/error-handling.md +0 -16
  67. package/.agent-context/rules/event-driven.md +0 -16
  68. package/.agent-context/rules/frontend-architecture.md +0 -54
  69. package/.agent-context/rules/microservices.md +0 -16
  70. package/.agent-context/rules/migrations.md +0 -16
  71. package/.agent-context/rules/observability.md +0 -16
  72. package/.agent-context/rules/performance.md +0 -16
  73. package/.agent-context/rules/realtime.md +0 -16
  74. package/.agent-context/rules/resilience.md +0 -18
  75. package/.agent-context/rules/security.md +0 -18
  76. package/.agent-context/rules/testing.md +0 -16
  77. package/.agent-context/state/README.md +0 -25
  78. package/.agent-context/state/architecture-map.md +0 -40
  79. package/.agent-context/state/benchmark-comparison-schema.json +0 -181
  80. package/.agent-context/state/benchmark-reproducibility.json +0 -87
  81. package/.agent-context/state/benchmark-thresholds.json +0 -10
  82. package/.agent-context/state/benchmark-writer-judge-config.json +0 -58
  83. package/.agent-context/state/dependency-map.md +0 -41
  84. package/.agent-context/state/memory-adapter-contract.json +0 -52
  85. package/.agent-context/state/memory-schema-v1.json +0 -88
  86. package/GEMINI.md +0 -1
  87. package/benchmarks/README.md +0 -60
  88. package/benchmarks/compact-natural-mode/fixtures.mjs +0 -359
  89. package/benchmarks/compact-natural-mode/scorer.mjs +0 -331
  90. package/benchmarks/runtime-token-saver/fixtures.mjs +0 -836
  91. package/lib/cli/adaptive-context/catalog.mjs +0 -394
  92. package/lib/cli/adaptive-context/file-signals.mjs +0 -100
  93. package/lib/cli/adaptive-context/implications.mjs +0 -44
  94. package/lib/cli/adaptive-context.mjs +0 -151
  95. package/lib/cli/audits/typography-palette-anti-repeat/color-utils.mjs +0 -156
  96. package/lib/cli/audits/typography-palette-anti-repeat/file-scanner.mjs +0 -103
  97. package/lib/cli/audits/typography-palette-anti-repeat/typography-utils.mjs +0 -70
  98. package/lib/cli/backup.mjs +0 -210
  99. package/lib/cli/commands/context.mjs +0 -140
  100. package/lib/cli/commands/init/project-context.mjs +0 -60
  101. package/lib/cli/commands/init/runtime-environment.mjs +0 -59
  102. package/lib/cli/commands/init/setup-decisions.mjs +0 -83
  103. package/lib/cli/commands/init.mjs +0 -654
  104. package/lib/cli/commands/launch.mjs +0 -76
  105. package/lib/cli/commands/optimize.mjs +0 -284
  106. package/lib/cli/commands/rollback.mjs +0 -64
  107. package/lib/cli/commands/upgrade/token-optimization-state.mjs +0 -51
  108. package/lib/cli/commands/upgrade.mjs +0 -451
  109. package/lib/cli/compiler.mjs +0 -187
  110. package/lib/cli/constants.mjs +0 -136
  111. package/lib/cli/detector/constants.mjs +0 -135
  112. package/lib/cli/detector/design-evidence/collector.mjs +0 -256
  113. package/lib/cli/detector/design-evidence/constants.mjs +0 -39
  114. package/lib/cli/detector/design-evidence/file-traversal.mjs +0 -83
  115. package/lib/cli/detector/design-evidence/structured-attribute-evidence.mjs +0 -117
  116. package/lib/cli/detector/design-evidence/summary.mjs +0 -109
  117. package/lib/cli/detector/design-evidence/utility-helpers.mjs +0 -122
  118. package/lib/cli/detector/design-evidence.mjs +0 -25
  119. package/lib/cli/detector/stack-detection.mjs +0 -243
  120. package/lib/cli/detector/ui-signals.mjs +0 -150
  121. package/lib/cli/detector/workspace-scan.mjs +0 -177
  122. package/lib/cli/detector.mjs +0 -23
  123. package/lib/cli/init-detection-flow.mjs +0 -48
  124. package/lib/cli/init-options.mjs +0 -237
  125. package/lib/cli/init-selection.mjs +0 -29
  126. package/lib/cli/memory-continuity.mjs +0 -537
  127. package/lib/cli/preflight.mjs +0 -76
  128. package/lib/cli/project-scaffolder/constants.mjs +0 -69
  129. package/lib/cli/project-scaffolder/discovery.mjs +0 -272
  130. package/lib/cli/project-scaffolder/prompt-builders.mjs +0 -171
  131. package/lib/cli/project-scaffolder/storage.mjs +0 -144
  132. package/lib/cli/project-scaffolder/ui-scope-detection.mjs +0 -36
  133. package/lib/cli/project-scaffolder.mjs +0 -29
  134. package/lib/cli/rollback.mjs +0 -66
  135. package/lib/cli/token-optimization.mjs +0 -401
  136. package/lib/cli/utils/filesystem.mjs +0 -81
  137. package/lib/cli/utils/managed-surface.mjs +0 -280
  138. package/lib/cli/utils/prompting.mjs +0 -44
  139. package/lib/cli/utils.mjs +0 -479
  140. package/mcp.json +0 -134
  141. package/scripts/adaptive-context/fixtures.mjs +0 -183
  142. package/scripts/adaptive-context-benchmark.mjs +0 -9
  143. package/scripts/ascx-runtime-token-saver-benchmark.mjs +0 -9
  144. package/scripts/benchmark-evidence-bundle.mjs +0 -645
  145. package/scripts/benchmark-gate.mjs +0 -121
  146. package/scripts/benchmark-intelligence.mjs +0 -33
  147. package/scripts/benchmark-writer-judge-matrix.mjs +0 -379
  148. package/scripts/build-release-benchmark-bundle.mjs +0 -202
  149. package/scripts/bump-version.mjs +0 -103
  150. package/scripts/clean-local-artifacts.mjs +0 -78
  151. package/scripts/compact-natural-mode-benchmark.mjs +0 -9
  152. package/scripts/context-triggered-audit.mjs +0 -391
  153. package/scripts/detection-benchmark.mjs +0 -127
  154. package/scripts/docs-quality-drift-report.mjs +0 -358
  155. package/scripts/documentation-boundary-audit.mjs +0 -305
  156. package/scripts/explain-on-demand-audit.mjs +0 -427
  157. package/scripts/forbidden-content-check.mjs +0 -123
  158. package/scripts/frontend-usability-audit.mjs +0 -243
  159. package/scripts/generate-sbom.mjs +0 -61
  160. package/scripts/governance-weekly-report.mjs +0 -466
  161. package/scripts/llm-judge/checklist-loader.mjs +0 -45
  162. package/scripts/llm-judge/constants.mjs +0 -66
  163. package/scripts/llm-judge/diff-collection.mjs +0 -74
  164. package/scripts/llm-judge/prompting.mjs +0 -78
  165. package/scripts/llm-judge/providers.mjs +0 -111
  166. package/scripts/llm-judge/verdict.mjs +0 -134
  167. package/scripts/llm-judge.mjs +0 -200
  168. package/scripts/memory-continuity-benchmark.mjs +0 -322
  169. package/scripts/quality-trend-report.mjs +0 -289
  170. package/scripts/release-gate/audit-checks.mjs +0 -441
  171. package/scripts/release-gate/constants.mjs +0 -53
  172. package/scripts/release-gate/runtime.mjs +0 -63
  173. package/scripts/release-gate/static-checks.mjs +0 -182
  174. package/scripts/release-gate.mjs +0 -42
  175. package/scripts/rules-guardian-audit.mjs +0 -580
  176. package/scripts/single-source-lazy-loading-audit.mjs +0 -449
  177. package/scripts/sync-thin-adapters.mjs +0 -72
  178. package/scripts/token-optimization-benchmark.mjs +0 -252
  179. package/scripts/ui-design-judge/constants.mjs +0 -13
  180. package/scripts/ui-design-judge/design-execution-summary.mjs +0 -81
  181. package/scripts/ui-design-judge/git-input.mjs +0 -134
  182. package/scripts/ui-design-judge/prompting.mjs +0 -52
  183. package/scripts/ui-design-judge/providers.mjs +0 -102
  184. package/scripts/ui-design-judge/reporting.mjs +0 -183
  185. package/scripts/ui-design-judge/rubric-calibration.mjs +0 -214
  186. package/scripts/ui-design-judge/rubric-goldset.json +0 -188
  187. package/scripts/ui-design-judge.mjs +0 -319
  188. package/scripts/ui-rubric-calibration.mjs +0 -35
  189. package/scripts/validate/audits/cache-layer-contract.mjs +0 -230
  190. package/scripts/validate/audits/caching-scope-hygiene.mjs +0 -235
  191. package/scripts/validate/audits/file-size.mjs +0 -158
  192. package/scripts/validate/audits/reflection-citations.mjs +0 -130
  193. package/scripts/validate/audits/release-bundle.mjs +0 -135
  194. package/scripts/validate/audits/rule-id-uniqueness.mjs +0 -278
  195. package/scripts/validate/config.mjs +0 -501
  196. package/scripts/validate/coverage-checks.mjs +0 -446
  197. package/scripts/validate/file-structure.mjs +0 -158
  198. package/scripts/validate/markdown-content.mjs +0 -109
  199. package/scripts/validate/project-metadata.mjs +0 -166
  200. package/scripts/validate/utils.mjs +0 -52
  201. package/scripts/validate.mjs +0 -267
@@ -1,272 +0,0 @@
1
- import fs from 'node:fs/promises';
2
-
3
- import { askChoice, askYesNo } from '../utils.mjs';
4
- import {
5
- ARCHITECTURE_STYLE_CHOICES,
6
- DOC_INDEX_FILE_NAME,
7
- DOCKER_STRATEGY_CHOICES,
8
- SUPPORTED_DOC_LANGUAGES,
9
- } from './constants.mjs';
10
-
11
- const PROJECT_SCOPE_CHOICES = [
12
- 'Frontend only',
13
- 'Backend only',
14
- 'Both (frontend + backend)',
15
- ];
16
-
17
- const AGENT_RECOMMENDATION_REQUIRED = 'Agent recommendation required from current brief, repo evidence, and live official docs';
18
-
19
- function parseBooleanLikeValue(rawValue) {
20
- const normalizedValue = String(rawValue || '').trim().toLowerCase();
21
- if (['true', 'yes', 'y', '1'].includes(normalizedValue)) {
22
- return true;
23
- }
24
-
25
- if (['false', 'no', 'n', '0'].includes(normalizedValue)) {
26
- return false;
27
- }
28
-
29
- return null;
30
- }
31
-
32
- function resolveDockerStrategy({ dockerStrategy, useDocker, useDockerDevelopment, useDockerProduction }) {
33
- if (typeof dockerStrategy === 'string' && dockerStrategy.trim().length > 0) {
34
- const normalizedDockerStrategy = dockerStrategy.trim().toLowerCase();
35
- const directMatch = DOCKER_STRATEGY_CHOICES.find(
36
- (dockerStrategyChoice) => dockerStrategyChoice.toLowerCase() === normalizedDockerStrategy
37
- );
38
-
39
- if (directMatch) {
40
- return directMatch;
41
- }
42
- }
43
-
44
- const normalizedUseDocker = typeof useDocker === 'boolean' ? useDocker : parseBooleanLikeValue(useDocker);
45
- const normalizedUseDockerDevelopment = typeof useDockerDevelopment === 'boolean'
46
- ? useDockerDevelopment
47
- : parseBooleanLikeValue(useDockerDevelopment);
48
- const normalizedUseDockerProduction = typeof useDockerProduction === 'boolean'
49
- ? useDockerProduction
50
- : parseBooleanLikeValue(useDockerProduction);
51
-
52
- if (normalizedUseDocker === false) {
53
- return DOCKER_STRATEGY_CHOICES[0];
54
- }
55
-
56
- if (normalizedUseDockerDevelopment === true && normalizedUseDockerProduction === true) {
57
- return DOCKER_STRATEGY_CHOICES[3];
58
- }
59
-
60
- if (normalizedUseDockerDevelopment === true && normalizedUseDockerProduction !== true) {
61
- return DOCKER_STRATEGY_CHOICES[1];
62
- }
63
-
64
- if (normalizedUseDockerProduction === true && normalizedUseDockerDevelopment !== true) {
65
- return DOCKER_STRATEGY_CHOICES[2];
66
- }
67
-
68
- if (normalizedUseDocker === true) {
69
- return DOCKER_STRATEGY_CHOICES[3];
70
- }
71
-
72
- return DOCKER_STRATEGY_CHOICES[0];
73
- }
74
-
75
- function resolveArchitectureStyle(rawArchitectureStyle) {
76
- const normalizedArchitectureStyle = String(rawArchitectureStyle || '').trim().toLowerCase();
77
-
78
- if (!normalizedArchitectureStyle) {
79
- return AGENT_RECOMMENDATION_REQUIRED;
80
- }
81
-
82
- if (normalizedArchitectureStyle === 'monolith' || normalizedArchitectureStyle === 'modular monolith') {
83
- return ARCHITECTURE_STYLE_CHOICES[0];
84
- }
85
-
86
- if (
87
- normalizedArchitectureStyle === 'microservice'
88
- || normalizedArchitectureStyle === 'microservices'
89
- || normalizedArchitectureStyle === 'distributed'
90
- || normalizedArchitectureStyle === 'distributed system'
91
- || normalizedArchitectureStyle === 'microservice / distributed system'
92
- ) {
93
- return ARCHITECTURE_STYLE_CHOICES[1];
94
- }
95
-
96
- const directMatch = ARCHITECTURE_STYLE_CHOICES.find(
97
- (architectureStyleChoice) => architectureStyleChoice.toLowerCase() === normalizedArchitectureStyle
98
- );
99
-
100
- return directMatch || ARCHITECTURE_STYLE_CHOICES[0];
101
- }
102
-
103
- export function normalizeDocsLanguage(rawDocsLanguage = 'en') {
104
- const normalizedDocsLanguage = String(rawDocsLanguage || 'en').trim().toLowerCase();
105
- return SUPPORTED_DOC_LANGUAGES.has(normalizedDocsLanguage) ? normalizedDocsLanguage : null;
106
- }
107
-
108
- export async function runProjectDiscovery(userInterface, options = {}) {
109
- console.log('\n--- Project Setup ---');
110
- console.log('I will ask the minimum needed questions, then let the AI agent recommend unresolved technical decisions from the brief, repo evidence, and live official docs.\n');
111
- console.log('You can answer in your own language.');
112
- console.log('CLI prompts stay in English, but non-English answers are fully supported.\n');
113
-
114
- const defaultProjectName = (options.defaultProjectName || '').trim();
115
- const defaultProjectDescription = String(options.defaultProjectDescription || '').trim();
116
- const defaultIncludeCiGuardrails = typeof options.defaultIncludeCiGuardrails === 'boolean'
117
- ? options.defaultIncludeCiGuardrails
118
- : true;
119
- const shouldAskForCiGuardrails = options.askForCiGuardrails !== false;
120
-
121
- const projectName = defaultProjectName || 'Untitled project';
122
- const briefPrompt = defaultProjectDescription
123
- ? `One-line project brief (press Enter to use current brief): `
124
- : 'One-line project brief (optional but recommended): ';
125
- const projectBriefAnswer = (await userInterface.question(briefPrompt)).trim();
126
- const projectDescription = projectBriefAnswer
127
- || defaultProjectDescription
128
- || 'Project brief unresolved. The AI agent must ask for or infer product context before implementation.';
129
-
130
- const projectScope = await askChoice('Project scope:', PROJECT_SCOPE_CHOICES, userInterface);
131
- const primaryDomain = projectScope === 'Frontend only'
132
- ? 'Frontend/UI application'
133
- : projectScope === 'Backend only'
134
- ? 'Backend/API service'
135
- : 'Fullstack product';
136
-
137
- const dockerStrategy = await askChoice(
138
- 'Containerization strategy:',
139
- DOCKER_STRATEGY_CHOICES,
140
- userInterface
141
- );
142
-
143
- const includeCiGuardrails = shouldAskForCiGuardrails
144
- ? await askYesNo(
145
- 'Enable CI/CD quality checks (guardrails) and the LLM Judge policy?',
146
- userInterface,
147
- defaultIncludeCiGuardrails
148
- )
149
- : defaultIncludeCiGuardrails;
150
-
151
- return {
152
- projectName,
153
- projectDescription,
154
- architectureStyle: AGENT_RECOMMENDATION_REQUIRED,
155
- includeCiGuardrails,
156
- primaryDomain,
157
- databaseChoice: AGENT_RECOMMENDATION_REQUIRED,
158
- authStrategy: AGENT_RECOMMENDATION_REQUIRED,
159
- dockerStrategy,
160
- features: [],
161
- additionalContext: 'Fresh-project technical decisions are intentionally unresolved. The AI agent must recommend them from current context and official docs before coding.',
162
- };
163
- }
164
-
165
- export function resolveProjectDocTargets(discoveryAnswers) {
166
- const hasDatabase = !discoveryAnswers.databaseChoice.toLowerCase().startsWith('none');
167
- const isApiOrWebDomain = ['API service', 'Web application'].includes(discoveryAnswers.primaryDomain)
168
- || discoveryAnswers.primaryDomain.toLowerCase().includes('api')
169
- || discoveryAnswers.primaryDomain.toLowerCase().includes('web')
170
- || discoveryAnswers.primaryDomain.toLowerCase().includes('fullstack');
171
-
172
- const requiredDocFileNames = [
173
- DOC_INDEX_FILE_NAME,
174
- 'project-brief.md',
175
- 'architecture-decision-record.md',
176
- 'flow-overview.md',
177
- ];
178
-
179
- if (hasDatabase) {
180
- requiredDocFileNames.push('database-schema.md');
181
- }
182
-
183
- if (isApiOrWebDomain) {
184
- requiredDocFileNames.push('api-contract.md');
185
- }
186
-
187
- return { requiredDocFileNames };
188
- }
189
-
190
- export function buildSynthesisContext(_discoveryAnswers, initContext) {
191
- const additionalStackFileNames = Array.isArray(initContext.additionalStackFileNames)
192
- ? initContext.additionalStackFileNames
193
- : [];
194
- const additionalBlueprintFileNames = Array.isArray(initContext.additionalBlueprintFileNames)
195
- ? initContext.additionalBlueprintFileNames
196
- : [];
197
-
198
- return {
199
- stackFileName: initContext.stackFileName,
200
- additionalStackFileNames,
201
- blueprintFileName: initContext.blueprintFileName,
202
- additionalBlueprintFileNames,
203
- runtimeEnvironmentKey: initContext.runtimeEnvironmentKey || 'linux',
204
- runtimeEnvironmentLabel: initContext.runtimeEnvironmentLabel || 'Linux',
205
- };
206
- }
207
-
208
- export async function loadProjectConfig(configFilePath) {
209
- const configContent = await fs.readFile(configFilePath, 'utf8');
210
- const configLines = configContent.split(/\r?\n/);
211
- const configEntries = {};
212
- let currentKey = null;
213
- let currentArrayValues = null;
214
-
215
- for (const configLine of configLines) {
216
- const trimmedLine = configLine.trim();
217
-
218
- if (!trimmedLine || trimmedLine.startsWith('#')) {
219
- continue;
220
- }
221
-
222
- if (trimmedLine.startsWith('- ') && currentKey && currentArrayValues !== null) {
223
- currentArrayValues.push(trimmedLine.slice(2).trim());
224
- continue;
225
- }
226
-
227
- if (currentKey && currentArrayValues !== null) {
228
- configEntries[currentKey] = currentArrayValues;
229
- currentKey = null;
230
- currentArrayValues = null;
231
- }
232
-
233
- const colonIndex = trimmedLine.indexOf(':');
234
- if (colonIndex === -1) {
235
- continue;
236
- }
237
-
238
- const entryKey = trimmedLine.slice(0, colonIndex).trim();
239
- const entryValue = trimmedLine.slice(colonIndex + 1).trim();
240
-
241
- if (!entryValue) {
242
- currentKey = entryKey;
243
- currentArrayValues = [];
244
- continue;
245
- }
246
-
247
- configEntries[entryKey] = entryValue;
248
- }
249
-
250
- if (currentKey && currentArrayValues !== null) {
251
- configEntries[currentKey] = currentArrayValues;
252
- }
253
-
254
- return {
255
- projectName: configEntries.projectName || configEntries.name || '',
256
- projectDescription: configEntries.projectDescription || configEntries.description || '',
257
- architectureStyle: resolveArchitectureStyle(configEntries.architectureStyle || configEntries.topology || configEntries.serviceTopology),
258
- includeCiGuardrails: parseBooleanLikeValue(configEntries.includeCiGuardrails) ?? parseBooleanLikeValue(configEntries.ci) ?? true,
259
- primaryDomain: configEntries.primaryDomain || configEntries.domain || AGENT_RECOMMENDATION_REQUIRED,
260
- databaseChoice: configEntries.databaseChoice || configEntries.database || AGENT_RECOMMENDATION_REQUIRED,
261
- authStrategy: configEntries.authStrategy || configEntries.auth || AGENT_RECOMMENDATION_REQUIRED,
262
- dockerStrategy: resolveDockerStrategy({
263
- dockerStrategy: configEntries.dockerStrategy || configEntries.containerStrategy,
264
- useDocker: configEntries.useDocker,
265
- useDockerDevelopment: configEntries.useDockerDevelopment || configEntries.dockerDevelopment,
266
- useDockerProduction: configEntries.useDockerProduction || configEntries.dockerProduction,
267
- }),
268
- features: Array.isArray(configEntries.features) ? configEntries.features : [],
269
- additionalContext: configEntries.additionalContext || configEntries.context || 'No additional context provided.',
270
- docsLang: configEntries.docsLang || configEntries.docsLanguage || 'en',
271
- };
272
- }
@@ -1,171 +0,0 @@
1
- import { toTitleCase } from '../utils.mjs';
2
- import {
3
- PROJECT_DOC_SYNTHESIS_PROMPT_VERSION,
4
- } from './constants.mjs';
5
-
6
- function buildDockerStrategyExecutionBlock(dockerStrategy) {
7
- const selectedDockerStrategy = String(dockerStrategy || '').trim();
8
- const normalizedDockerStrategy = selectedDockerStrategy.toLowerCase();
9
-
10
- if (!selectedDockerStrategy || normalizedDockerStrategy.startsWith('no docker')) {
11
- return [
12
- '## Docker Execution Gate',
13
- 'Docker was not selected. Do not create container assets unless the user changes scope.',
14
- ];
15
- }
16
-
17
- const requiredAssetFloor = [
18
- '.dockerignore',
19
- normalizedDockerStrategy.includes('development') || normalizedDockerStrategy.includes('both') ? 'compose.yaml for development' : null,
20
- normalizedDockerStrategy.includes('production') || normalizedDockerStrategy.includes('both') ? 'compose.prod.yaml or a documented production Compose override' : null,
21
- 'Dockerfile stage(s) derived from the actual stack',
22
- 'docs/docker-runtime.md or a deployment runbook with ports, entrypoints, health checks, and source URLs',
23
- ].filter(Boolean).join(', ');
24
-
25
- return [
26
- '## Docker Execution Gate',
27
- `Selected Docker strategy: ${selectedDockerStrategy}`,
28
- '- Load .agent-context/rules/docker-runtime.md and verify current official Docker docs before authoring assets.',
29
- '- Materialize Docker assets from the actual stack; do not stop at docs-only acknowledgement or runtime notes.',
30
- '- Required asset floor: ' + requiredAssetFloor + '.',
31
- '- Keep development and production lanes separate when both are selected.',
32
- '- If the user asks to create files without commands, write the files and documented commands, but do not execute Docker build, Compose, or registry commands.',
33
- '- If Docker is enabled for development, local development setup and first-build instructions in the README must use Docker (e.g., `docker compose up`) rather than fallback local commands like `npm run dev`.',
34
- ];
35
- }
36
-
37
- export function buildProjectContextBootstrapPrompt({
38
- discoveryAnswers,
39
- initContext,
40
- expectedDocFileNames,
41
- docsLanguage,
42
- }) {
43
- const featuresList = Array.isArray(discoveryAnswers.features) && discoveryAnswers.features.length > 0
44
- ? discoveryAnswers.features.map((feature, featureIndex) => `${featureIndex + 1}. ${feature}`).join('\n')
45
- : 'Derive the first concrete feature set from the project name, description, and domain. Do not invent arbitrary modules just to fill space.';
46
-
47
- const expectedDocsList = [
48
- 'README.md',
49
- ...expectedDocFileNames.map((fileName) => `docs/${fileName}`),
50
- ]
51
- .map((filePath, fileIndex) => `${fileIndex + 1}. ${filePath}`)
52
- .join('\n');
53
-
54
- return [
55
- '# Bootstrap Prompt: Dynamic Project Context Synthesis',
56
- '',
57
- `Protocol version: ${PROJECT_DOC_SYNTHESIS_PROMPT_VERSION}`,
58
- '',
59
- 'You are a Lead Solution Architect and Principal Engineer.',
60
- 'Write project context docs from scratch (no template rendering, no placeholder boilerplate).',
61
- '',
62
- '## Mission',
63
- `Create or update these files in ${docsLanguage.toUpperCase()} language:`,
64
- expectedDocsList,
65
- '',
66
- '## Hard Rules',
67
- '1. No copy-paste from external prose.',
68
- '2. Every major section must explain rationale, constraints, and required action.',
69
- '3. Keep database, auth, runtime, and architecture aligned with explicit project constraints below unless user requests migration.',
70
- '4. Output must be implementation-ready for engineers, not generic textbook explanation.',
71
- '5. For any ecosystem or technology claim, perform live web research and include citation metadata (source + fetchedAt timestamp) rather than relying on offline heuristics.',
72
- '6. Write for native English speakers at an 8th-grade reading level. Use clear, direct, plain language.',
73
- '7. Avoid emoji, AI cliches, buzzwords, academic phrasing, padding, and generic filler.',
74
- '8. Separate confirmed facts from assumptions explicitly. When context is incomplete, add an `Assumptions to Validate` section and a `Next Validation Action` line.',
75
- '9. If user inputs conflict with repo evidence, call out the conflict and choose the safer interpretation instead of silently forcing a generic answer.',
76
- '10. Do not invent modules or architecture layers only to make the docs look complete.',
77
- '11. If runtime or framework setup is unresolved, recommend the latest stable compatible option from the brief, constraints, and live official documentation before coding. If an official setup flow yields newer, better-supported defaults than manual package assembly, use that path after approval.',
78
- '12. Treat topology as an agent decision unless the user explicitly constrained it. If monolith fits, explain why. If a service split fits, document the evidence and service boundary logic.',
79
- '13. Required docs coverage must include a public and developer README entrypoint, feature plan, architecture rationale, flow, public API or integration contracts when relevant, data model when relevant, UI/design when relevant, security assumptions, testing strategy, runtime/deployment notes, and next validation actions.',
80
- '14. Use Mermaid.js as the default diagram format for flow, sequence, ER, architecture, C4, and state diagrams embedded in Markdown docs. Do not use PlantUML, ASCII art diagrams, Graphviz DOT, or Structurizr DSL. When updating existing docs that contain prose-only descriptions, convert relevant sections to Mermaid diagrams in the same change.',
81
- '15. README.md must be public and developer friendly, including for private projects: what it is, who it is for, setup, core workflow, configuration, and links to deeper docs. Do not include secrets, internal agent notes, private reasoning, or governance policy dumps.',
82
- '16. docs/doc-index.md is the low-token routing map for docs/*. Keep it short, list each active doc, and explain when an agent should read it. Do not make it the source of truth for requirements or architecture.',
83
- '17. Keep docs complete but compact. Add extra docs files only for stable, distinct, or long workflows such as hardware setup, deployment, operations, testing validation, or troubleshooting.',
84
- '18. Add SRS, PRD, technical-design, or ERD docs only when project evidence triggers them. Use PRD for product-roadmap/user-story ownership, SRS for contractual or multi-stakeholder acceptance criteria, technical-design for non-trivial architecture decisions, and ERD only as a separate file when the schema is too complex for docs/database-schema.md.',
85
- '',
86
- '## Project Inputs',
87
- `- Project name: ${discoveryAnswers.projectName}`,
88
- `- Project description: ${discoveryAnswers.projectDescription}`,
89
- `- Project topology decision: ${discoveryAnswers.architectureStyle}`,
90
- `- Primary domain: ${discoveryAnswers.primaryDomain}`,
91
- `- Database strategy: ${discoveryAnswers.databaseChoice}`,
92
- `- Auth strategy: ${discoveryAnswers.authStrategy}`,
93
- `- Docker strategy: ${discoveryAnswers.dockerStrategy}`,
94
- `- Runtime environment: ${initContext.runtimeEnvironmentLabel || initContext.runtimeEnvironmentKey || 'Linux'}`,
95
- `- Runtime constraint: ${initContext.stackFileName === 'agent-decision-runtime.md' ? 'agent recommendation required before coding' : toTitleCase(initContext.stackFileName)}`,
96
- `- Architecture constraint: ${initContext.blueprintFileName === 'agent-decision-architecture.md' ? 'agent recommendation required before coding' : toTitleCase(initContext.blueprintFileName)}`,
97
- `- Additional runtime constraints: ${Array.isArray(initContext.additionalStackFileNames) && initContext.additionalStackFileNames.length > 0 ? initContext.additionalStackFileNames.map((stackFileName) => toTitleCase(stackFileName)).join(', ') : 'none'}`,
98
- `- Additional architecture constraints: ${Array.isArray(initContext.additionalBlueprintFileNames) && initContext.additionalBlueprintFileNames.length > 0 ? initContext.additionalBlueprintFileNames.map((blueprintFileName) => toTitleCase(blueprintFileName)).join(', ') : 'none'}`,
99
- '',
100
- ...buildDockerStrategyExecutionBlock(discoveryAnswers.dockerStrategy),
101
- '',
102
- '## Key Features',
103
- featuresList,
104
- '',
105
- '## Additional Context',
106
- discoveryAnswers.additionalContext || 'No additional context provided.',
107
- '',
108
- '## Required Execution',
109
- '1. Create all required docs files listed above with complete Markdown content.',
110
- '2. Make the docs adaptive to the real repo and prompt context. These are living references, not frozen templates.',
111
- '3. In docs/doc-index.md, include a compact table with document path, purpose, reads-when triggers, status, and last-updated date.',
112
- '4. In docs/project-brief.md and docs/architecture-decision-record.md, include explicit sections for confirmed facts, assumptions to validate, and next validation actions whenever context is incomplete.',
113
- '5. Before implementation, use README.md plus docs/doc-index.md to select only the relevant docs for the current task instead of broad-reading docs/*.md.',
114
- '6. Before implementation, use the docs to confirm stack, runtime, architecture, public contracts, data, validation, and delivery assumptions.',
115
- '7. Keep content original, specific to this project, and actionable for implementation.',
116
- '8. After writing docs, continue coding tasks using these docs as living project context.',
117
- '',
118
- ].join('\n');
119
- }
120
-
121
- export function buildDesignBootstrapPrompt({
122
- discoveryAnswers,
123
- initContext,
124
- docsLanguage,
125
- }) {
126
-
127
- return [
128
- '# Bootstrap Prompt: Dynamic Design Contract Synthesis',
129
- '',
130
- `Protocol version: ${PROJECT_DOC_SYNTHESIS_PROMPT_VERSION}`,
131
- '',
132
- 'You are the Lead UI/UX Art Director for this project.',
133
- 'Create a compact design token file, not a fixed stylistic template or prose document.',
134
- '',
135
- '## Mission',
136
- `Author docs/DESIGN.md in ${docsLanguage.toUpperCase()} language as a compact token file under 400 tokens.`,
137
- '',
138
- '## Deliverables',
139
- '1. docs/DESIGN.md (compact token file)',
140
- '',
141
- '## Design Direction Process',
142
- 'Follow `.agent-context/prompts/bootstrap-design.md` for the three-step design direction:',
143
- '1. Name your defaults (three temptations and why each flattens this product)',
144
- '2. Choose a concrete anchor (googleable, specific, not a generic quality word)',
145
- '3. Record creative commitments (typography, palette, motion, composition)',
146
- '',
147
- '## Hard Rules',
148
- '1. Do not copy external style guides or anchor to famous product surfaces.',
149
- '2. Use repo evidence, active brief, current docs, and current official docs for technology choices.',
150
- '3. WCAG 2.2 AA is the hard floor. APCA is advisory perceptual tuning only.',
151
- '4. Research current official docs before importing any new UI-related library.',
152
- '5. Do not default to any component kit by habit, and do not avoid them when they fit.',
153
- '6. Keep research vocabulary internal; evidence, anchor, and category-code labels must not appear in public-facing docs.',
154
- '7. Treat production content as blocking: remove demo, placeholder, lorem, TODO, and scaffold copy.',
155
- '',
156
- '## Project Inputs',
157
- `- Project name: ${discoveryAnswers.projectName}`,
158
- `- Product context: ${discoveryAnswers.projectDescription}`,
159
- `- Project topology decision: ${discoveryAnswers.architectureStyle}`,
160
- `- Domain: ${discoveryAnswers.primaryDomain}`,
161
- `- Runtime constraint: ${initContext.stackFileName === 'agent-decision-runtime.md' ? 'agent recommendation required before coding' : toTitleCase(initContext.stackFileName)}`,
162
- `- Architecture constraint: ${initContext.blueprintFileName === 'agent-decision-architecture.md' ? 'agent recommendation required before coding' : toTitleCase(initContext.blueprintFileName)}`,
163
- '',
164
- '## Required Execution',
165
- '1. Follow the output format defined in `.agent-context/prompts/bootstrap-design.md`: Anchor, Tokens, Constraints, Previous Directions.',
166
- '2. Keep docs/DESIGN.md under 400 tokens. Rationale and derivation stay in working memory.',
167
- '3. Make the token file executable without screenshot dependency.',
168
- '4. After the token file exists, use it as a first-class source for future UI tasks.',
169
- '',
170
- ].join('\n');
171
- }
@@ -1,144 +0,0 @@
1
- import fs from 'node:fs/promises';
2
- import path from 'node:path';
3
-
4
- import { ensureDirectory, pathExists } from '../utils.mjs';
5
- import {
6
- PROJECT_DOC_FILE_NAMES,
7
- PROJECT_DOC_SYNTHESIS_PROMPT_VERSION,
8
- PROJECT_DOC_TEMPLATE_VERSION,
9
- UI_DESIGN_CONTRACT_FILE_NAMES,
10
- } from './constants.mjs';
11
- import {
12
- buildSynthesisContext,
13
- normalizeDocsLanguage,
14
- resolveProjectDocTargets,
15
- } from './discovery.mjs';
16
- import {
17
- shouldBootstrapDesignDocument,
18
- } from './ui-scope-detection.mjs';
19
- import {
20
- buildDesignBootstrapPrompt,
21
- buildProjectContextBootstrapPrompt,
22
- } from './prompt-builders.mjs';
23
-
24
- export async function generateProjectDocumentation(
25
- targetDirectoryPath,
26
- discoveryAnswers,
27
- initContext,
28
- options = {}
29
- ) {
30
- const normalizedDocsLanguage = normalizeDocsLanguage(options.docsLanguage || 'en');
31
- if (!normalizedDocsLanguage) {
32
- throw new Error(`Unsupported docs language: ${options.docsLanguage}. Supported values: en, id`);
33
- }
34
-
35
- const docsDirectoryPath = path.join(targetDirectoryPath, 'docs');
36
- const promptsDirectoryPath = path.join(targetDirectoryPath, '.agent-context', 'prompts');
37
- await ensureDirectory(docsDirectoryPath);
38
- await ensureDirectory(promptsDirectoryPath);
39
-
40
- const synthesisContext = buildSynthesisContext(discoveryAnswers, initContext);
41
- const { requiredDocFileNames } = resolveProjectDocTargets(discoveryAnswers);
42
- const expectedDocFileNames = [...requiredDocFileNames];
43
- const generatedPromptFileNames = [];
44
- const materializedFileNames = [];
45
- const shouldCreateDesignContract = shouldBootstrapDesignDocument(discoveryAnswers, initContext);
46
-
47
- if (shouldCreateDesignContract) {
48
- for (const designContractFileName of UI_DESIGN_CONTRACT_FILE_NAMES) {
49
- if (!expectedDocFileNames.includes(designContractFileName)) {
50
- expectedDocFileNames.push(designContractFileName);
51
- }
52
- }
53
- }
54
-
55
- const projectContextPromptFileName = 'bootstrap-project-context.md';
56
- const projectContextPromptContent = buildProjectContextBootstrapPrompt({
57
- discoveryAnswers,
58
- initContext: synthesisContext,
59
- expectedDocFileNames,
60
- docsLanguage: normalizedDocsLanguage,
61
- });
62
- await fs.writeFile(
63
- path.join(promptsDirectoryPath, projectContextPromptFileName),
64
- projectContextPromptContent,
65
- 'utf8'
66
- );
67
- generatedPromptFileNames.push(projectContextPromptFileName);
68
-
69
- if (shouldCreateDesignContract) {
70
- const designPromptFileName = 'bootstrap-design.md';
71
- const designPromptContent = buildDesignBootstrapPrompt({
72
- discoveryAnswers,
73
- initContext: synthesisContext,
74
- docsLanguage: normalizedDocsLanguage,
75
- });
76
- await fs.writeFile(path.join(promptsDirectoryPath, designPromptFileName), designPromptContent, 'utf8');
77
- generatedPromptFileNames.push(designPromptFileName);
78
- }
79
-
80
- return {
81
- docsDirectoryPath,
82
- generatedFileNames: expectedDocFileNames,
83
- generatedPromptFileNames,
84
- materializedFileNames,
85
- bootstrapMode: 'ai-synthesis',
86
- synthesisPromptVersion: PROJECT_DOC_SYNTHESIS_PROMPT_VERSION,
87
- templateVersion: PROJECT_DOC_TEMPLATE_VERSION,
88
- docsLanguage: normalizedDocsLanguage,
89
- discoveryAnswers,
90
- };
91
- }
92
-
93
- export async function isDirectoryEffectivelyEmpty(targetDirectoryPath) {
94
- try {
95
- const directoryEntries = await fs.readdir(targetDirectoryPath);
96
- const meaningfulEntries = directoryEntries.filter(
97
- (entryName) => entryName !== '.git' && entryName !== '.gitignore'
98
- );
99
- return meaningfulEntries.length === 0;
100
- } catch {
101
- return true;
102
- }
103
- }
104
-
105
- export async function hasExistingProjectDocs(targetDirectoryPath) {
106
- const projectBriefPath = path.join(targetDirectoryPath, 'docs', 'project-brief.md');
107
- return pathExists(projectBriefPath);
108
- }
109
-
110
- function extractTemplateVersion(documentContent) {
111
- const templateVersionMatch = documentContent.match(/^(?:Template version|Versi template):\s*(.+)$/im);
112
- return templateVersionMatch ? templateVersionMatch[1].trim() : null;
113
- }
114
-
115
- export async function detectProjectDocTemplateStaleness(targetDirectoryPath) {
116
- const docsDirectoryPath = path.join(targetDirectoryPath, 'docs');
117
- const checkedFileNames = [];
118
- const staleFiles = [];
119
-
120
- for (const projectDocFileName of PROJECT_DOC_FILE_NAMES) {
121
- const projectDocFilePath = path.join(docsDirectoryPath, projectDocFileName);
122
- if (!(await pathExists(projectDocFilePath))) {
123
- continue;
124
- }
125
-
126
- checkedFileNames.push(projectDocFileName);
127
- const projectDocContent = await fs.readFile(projectDocFilePath, 'utf8');
128
- const detectedTemplateVersion = extractTemplateVersion(projectDocContent);
129
-
130
- if (!detectedTemplateVersion || detectedTemplateVersion !== PROJECT_DOC_TEMPLATE_VERSION) {
131
- staleFiles.push({
132
- fileName: projectDocFileName,
133
- detectedTemplateVersion,
134
- });
135
- }
136
- }
137
-
138
- return {
139
- hasProjectDocs: checkedFileNames.length > 0,
140
- expectedTemplateVersion: PROJECT_DOC_TEMPLATE_VERSION,
141
- checkedFileNames,
142
- staleFiles,
143
- };
144
- }
@@ -1,36 +0,0 @@
1
- /**
2
- * UI scope detection utility. Determines whether a project needs
3
- * design bootstrap based on domain and blueprint signals.
4
- *
5
- * Extracted from design-contract/seed-signals.mjs so the design
6
- * contract module can be removed without breaking this dependency.
7
- */
8
-
9
- export function shouldBootstrapDesignDocument(discoveryAnswers, initContext) {
10
- const normalizedDomain = String(discoveryAnswers.primaryDomain || '').trim().toLowerCase();
11
- const normalizedBlueprint = String(initContext.blueprintFileName || '').trim().toLowerCase();
12
-
13
- const isUiDomain = normalizedDomain.includes('web')
14
- || normalizedDomain.includes('mobile')
15
- || normalizedDomain.includes('frontend')
16
- || normalizedDomain.includes('fullstack')
17
- || normalizedDomain.includes('ui');
18
-
19
- const isBackendOnlyDomain = normalizedDomain.includes('api service')
20
- || normalizedDomain.includes('cli tool')
21
- || normalizedDomain.includes('library');
22
-
23
- const blueprintLooksUi = normalizedBlueprint.includes('frontend')
24
- || normalizedBlueprint.includes('landing')
25
- || normalizedBlueprint.includes('ui');
26
-
27
- if (isUiDomain) {
28
- return true;
29
- }
30
-
31
- if (!isBackendOnlyDomain && blueprintLooksUi) {
32
- return true;
33
- }
34
-
35
- return false;
36
- }
@@ -1,29 +0,0 @@
1
- /**
2
- * Project scaffolder public surface.
3
- *
4
- * The implementation is grouped by function under `lib/cli/project-scaffolder/`
5
- * so discovery, design-contract logic, prompt building, and persistence do not
6
- * collapse into one oversized module.
7
- */
8
-
9
- export {
10
- PROJECT_DOC_TEMPLATE_VERSION,
11
- PROJECT_DOC_SYNTHESIS_PROMPT_VERSION,
12
- } from './project-scaffolder/constants.mjs';
13
-
14
- export {
15
- normalizeDocsLanguage,
16
- runProjectDiscovery,
17
- loadProjectConfig,
18
- } from './project-scaffolder/discovery.mjs';
19
-
20
- export {
21
- shouldBootstrapDesignDocument,
22
- } from './project-scaffolder/ui-scope-detection.mjs';
23
-
24
- export {
25
- generateProjectDocumentation,
26
- isDirectoryEffectivelyEmpty,
27
- hasExistingProjectDocs,
28
- detectProjectDocTemplateStaleness,
29
- } from './project-scaffolder/storage.mjs';