@chenguangyao/devflow-kit 0.1.43

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 (198) hide show
  1. package/CHANGELOG.md +232 -0
  2. package/LICENSE +21 -0
  3. package/README.md +539 -0
  4. package/bin/devflow.js +9 -0
  5. package/docs/RFC-001-devflow-kit.md +617 -0
  6. package/docs/RFC-002-workflow-kernel.md +134 -0
  7. package/docs/enterprise-integration-supplement.md +274 -0
  8. package/docs/internal-gitlab-setup.md +426 -0
  9. package/docs/marketplace-skills.md +231 -0
  10. package/docs/migration-from-arb.md +232 -0
  11. package/docs/tooling-overview.md +774 -0
  12. package/docs/workflow-orchestration.md +695 -0
  13. package/docs/workflow-ui-prototype.html +271 -0
  14. package/package.json +52 -0
  15. package/schemas/config.schema.json +51 -0
  16. package/schemas/delta.schema.json +22 -0
  17. package/schemas/state.schema.json +130 -0
  18. package/schemas/status-surface.schema.json +197 -0
  19. package/schemas/workflow-confirmation-surface.schema.json +70 -0
  20. package/schemas/workflow-picker.schema.json +94 -0
  21. package/scripts/postinstall.js +101 -0
  22. package/scripts/render-workflow-ui-prototype.js +271 -0
  23. package/skills/apply/SKILL.md +313 -0
  24. package/skills/apply/references/discipline-checklist.md +145 -0
  25. package/skills/apply/references/subagent-implementer-prompt.md +113 -0
  26. package/skills/apply/references/subagent-orchestration.md +150 -0
  27. package/skills/apply/references/subagent-reviewer-prompt.md +180 -0
  28. package/skills/apply/references/tdd-loop.md +287 -0
  29. package/skills/apply/references/when-plan-is-wrong.md +279 -0
  30. package/skills/apply/references/worktree-swarm.md +292 -0
  31. package/skills/archive/SKILL.md +229 -0
  32. package/skills/archive/references/conflict-resolution.md +336 -0
  33. package/skills/archive/references/knowledge-deposit.md +381 -0
  34. package/skills/archive/references/spec-merge.md +365 -0
  35. package/skills/brainstorm/SKILL.md +123 -0
  36. package/skills/brainstorm/references/proposal-template.md +244 -0
  37. package/skills/brainstorm/references/question-catalog.md +168 -0
  38. package/skills/brainstorm/references/session-template.md +184 -0
  39. package/skills/ci-fix/SKILL.md +63 -0
  40. package/skills/ci-fix/references/loop.md +25 -0
  41. package/skills/code-review/SKILL.md +279 -0
  42. package/skills/code-review/references/escalation-playbook.md +192 -0
  43. package/skills/code-review/references/language-cheatsheets/go.md +175 -0
  44. package/skills/code-review/references/language-cheatsheets/java-spring-mybatis.md +246 -0
  45. package/skills/code-review/references/language-cheatsheets/python.md +170 -0
  46. package/skills/code-review/references/language-cheatsheets/vue.md +199 -0
  47. package/skills/code-review/references/output-template.md +275 -0
  48. package/skills/code-review/references/review-checklist.md +251 -0
  49. package/skills/complexity-grading/SKILL.md +259 -0
  50. package/skills/deliver/SKILL.md +271 -0
  51. package/skills/deliver/references/delivery-modes.md +299 -0
  52. package/skills/deliver/references/notify.md +359 -0
  53. package/skills/deliver/references/pr-description.md +319 -0
  54. package/skills/dependency-upgrade/SKILL.md +57 -0
  55. package/skills/dependency-upgrade/references/risk-matrix.md +38 -0
  56. package/skills/df-orchestrator/SKILL.md +407 -0
  57. package/skills/df-orchestrator/references/complexity-grading.md +177 -0
  58. package/skills/df-orchestrator/references/escalation-matrix.md +191 -0
  59. package/skills/df-orchestrator/references/routing-rules.md +290 -0
  60. package/skills/df-orchestrator/references/workflow-state-machine.md +208 -0
  61. package/skills/frontend-quality/SKILL.md +61 -0
  62. package/skills/frontend-quality/references/checklist.md +35 -0
  63. package/skills/handoff-resume/SKILL.md +59 -0
  64. package/skills/handoff-resume/references/handoff-template.md +54 -0
  65. package/skills/plan/SKILL.md +166 -0
  66. package/skills/plan/references/task-breakdown.md +207 -0
  67. package/skills/plan/references/task-sequencing.md +143 -0
  68. package/skills/plan/references/task-template.md +248 -0
  69. package/skills/requirement-analysis/SKILL.md +499 -0
  70. package/skills/requirement-analysis/references/acceptance-criteria.md +183 -0
  71. package/skills/requirement-analysis/references/code-recon.md +151 -0
  72. package/skills/requirement-analysis/references/edge-case-catalog.md +164 -0
  73. package/skills/requirement-analysis/references/requirement-template.md +339 -0
  74. package/skills/requirement-analysis/references/scope-negotiation.md +162 -0
  75. package/skills/security-hardening/SKILL.md +60 -0
  76. package/skills/security-hardening/references/checklist.md +42 -0
  77. package/skills/tech-spec/SKILL.md +388 -0
  78. package/skills/tech-spec/references/api-contract-design.md +172 -0
  79. package/skills/tech-spec/references/decision-records.md +110 -0
  80. package/skills/tech-spec/references/design-template.md +301 -0
  81. package/skills/tech-spec/references/rollout-and-rollback.md +203 -0
  82. package/skills/tech-spec/references/spec-delta-conventions.md +250 -0
  83. package/skills/tech-spec/references/transaction-patterns.md +212 -0
  84. package/skills/test-spec/SKILL.md +219 -0
  85. package/skills/test-spec/references/coverage-strategy.md +218 -0
  86. package/skills/test-spec/references/edge-case-to-test.md +143 -0
  87. package/skills/test-spec/references/test-case-template.md +276 -0
  88. package/skills/verify/SKILL.md +232 -0
  89. package/skills/verify/references/nfr-verification.md +292 -0
  90. package/skills/verify/references/report-templates.md +510 -0
  91. package/skills/verify/references/self-test-guide.md +240 -0
  92. package/skills/verify/references/verify-rollback-map.md +247 -0
  93. package/src/cli/commands/_helpers.js +108 -0
  94. package/src/cli/commands/_submit.js +718 -0
  95. package/src/cli/commands/apply.js +198 -0
  96. package/src/cli/commands/archive.js +180 -0
  97. package/src/cli/commands/checkpoint.js +113 -0
  98. package/src/cli/commands/deliver.js +377 -0
  99. package/src/cli/commands/deploy.js +504 -0
  100. package/src/cli/commands/design.js +158 -0
  101. package/src/cli/commands/disable.js +21 -0
  102. package/src/cli/commands/doctor.js +178 -0
  103. package/src/cli/commands/enable.js +21 -0
  104. package/src/cli/commands/flow.js +645 -0
  105. package/src/cli/commands/help.js +93 -0
  106. package/src/cli/commands/ingest.js +602 -0
  107. package/src/cli/commands/init.js +341 -0
  108. package/src/cli/commands/knowledge.js +523 -0
  109. package/src/cli/commands/logs.js +43 -0
  110. package/src/cli/commands/new.js +202 -0
  111. package/src/cli/commands/plan.js +49 -0
  112. package/src/cli/commands/propose.js +27 -0
  113. package/src/cli/commands/provider.js +698 -0
  114. package/src/cli/commands/report.js +143 -0
  115. package/src/cli/commands/requirement.js +227 -0
  116. package/src/cli/commands/review.js +301 -0
  117. package/src/cli/commands/skills.js +457 -0
  118. package/src/cli/commands/status.js +925 -0
  119. package/src/cli/commands/switch.js +27 -0
  120. package/src/cli/commands/sync.js +47 -0
  121. package/src/cli/commands/test.js +366 -0
  122. package/src/cli/commands/uninstall.js +32 -0
  123. package/src/cli/commands/update.js +74 -0
  124. package/src/cli/commands/verify.js +354 -0
  125. package/src/cli/commands/worktree.js +78 -0
  126. package/src/cli/index.js +72 -0
  127. package/src/cli/parse-args.js +102 -0
  128. package/src/core/autodetect.js +271 -0
  129. package/src/core/change.js +208 -0
  130. package/src/core/checkpoint.js +217 -0
  131. package/src/core/config.js +60 -0
  132. package/src/core/delta.js +290 -0
  133. package/src/core/markers.js +59 -0
  134. package/src/core/paths.js +173 -0
  135. package/src/core/plan-tasks.js +36 -0
  136. package/src/core/project-routing.js +285 -0
  137. package/src/core/projects.js +200 -0
  138. package/src/core/state.js +200 -0
  139. package/src/core/workflow-check.js +177 -0
  140. package/src/core/workflow-init.js +34 -0
  141. package/src/core/workflow-picker.js +154 -0
  142. package/src/core/workflow-policy.js +119 -0
  143. package/src/core/workflow-suggest.js +181 -0
  144. package/src/core/workflow-verify.js +88 -0
  145. package/src/core/workflow.js +433 -0
  146. package/src/core/worktree.js +241 -0
  147. package/src/knowledge/categories.js +107 -0
  148. package/src/knowledge/classify.js +125 -0
  149. package/src/knowledge/deposit.js +414 -0
  150. package/src/knowledge/migrate.js +149 -0
  151. package/src/knowledge/mr.js +219 -0
  152. package/src/knowledge/query.js +131 -0
  153. package/src/knowledge/registry.js +151 -0
  154. package/src/knowledge/sync.js +179 -0
  155. package/src/providers/base.js +74 -0
  156. package/src/providers/drivers/api-yapi.js +78 -0
  157. package/src/providers/drivers/ci-jenkins.js +109 -0
  158. package/src/providers/drivers/intake-confluence.js +544 -0
  159. package/src/providers/drivers/kb-git.js +549 -0
  160. package/src/providers/drivers/kb-weknora.js +472 -0
  161. package/src/providers/drivers/notify-smtp.js +515 -0
  162. package/src/providers/drivers/observability-oss.js +43 -0
  163. package/src/providers/drivers/observability-sls.js +50 -0
  164. package/src/providers/lifecycle.js +135 -0
  165. package/src/providers/loader.js +132 -0
  166. package/src/providers/local.js +190 -0
  167. package/src/providers/userconfig.js +283 -0
  168. package/src/reports/aggregate.js +185 -0
  169. package/src/reports/coverage.js +163 -0
  170. package/src/reports/detect.js +143 -0
  171. package/src/reports/parse.js +236 -0
  172. package/src/templates/files/ci/github.yml +38 -0
  173. package/src/templates/files/ci/gitlab.yml +27 -0
  174. package/src/templates/files/design.md +63 -0
  175. package/src/templates/files/ide/devflow-workflow.md +58 -0
  176. package/src/templates/files/ide/project-overview-reference.md +1 -0
  177. package/src/templates/files/ide/project-overview.md +27 -0
  178. package/src/templates/files/knowledge-index.json +17 -0
  179. package/src/templates/files/knowledge.md +28 -0
  180. package/src/templates/files/meta.json +8 -0
  181. package/src/templates/files/plan.md +38 -0
  182. package/src/templates/files/proposal.md +33 -0
  183. package/src/templates/files/reports/contract-test.md +40 -0
  184. package/src/templates/files/reports/e2e-test.md +30 -0
  185. package/src/templates/files/reports/integration-test.md +36 -0
  186. package/src/templates/files/reports/joint-test.md +58 -0
  187. package/src/templates/files/reports/perf.md +24 -0
  188. package/src/templates/files/reports/regression.md +20 -0
  189. package/src/templates/files/reports/remote-test.md +55 -0
  190. package/src/templates/files/reports/self-test.md +43 -0
  191. package/src/templates/files/reports/smoke-test.md +22 -0
  192. package/src/templates/files/reports/unit-test.md +36 -0
  193. package/src/templates/files/requirement.md +51 -0
  194. package/src/templates/files/review.md +38 -0
  195. package/src/templates/files/tests.md +36 -0
  196. package/src/templates/files/verify.md +32 -0
  197. package/src/templates/index.js +21 -0
  198. package/src/utils/log.js +37 -0
@@ -0,0 +1,202 @@
1
+ 'use strict';
2
+ const log = require('../../utils/log.js');
3
+ const change = require('../../core/change.js');
4
+ const config = require('../../core/config.js');
5
+ const state = require('../../core/state.js');
6
+ const routing = require('../../core/project-routing.js');
7
+ const checkpoint = require('../../core/checkpoint.js');
8
+ const workflowInit = require('../../core/workflow-init.js');
9
+ const templates = require('../../templates/index.js');
10
+ const { printWorkflowSelectionGuidance } = require('./_helpers.js');
11
+
12
+ async function run({ positional = [], flags = {}, cwd }) {
13
+ const root = cwd || process.cwd();
14
+ const slugInput = positional[0];
15
+ if (!slugInput) {
16
+ log.error('usage: devflow new <slug>');
17
+ process.exitCode = 2;
18
+ return;
19
+ }
20
+ const projectRouting = await resolvePreCreateProjectRouting(root, flags, 'new', slugInput);
21
+ const branchRoot = projectRouting && projectRouting.slugBranchSource ? projectRouting.slugBranchSource : root;
22
+ const slug = change.withCurrentBranchSlug(branchRoot, slugInput);
23
+ const title = flags.title || slugInput;
24
+ const micro = flags.micro === true || flags.mode === 'micro' || flags.level === 'L0';
25
+ const level = micro ? 'L0' : (flags.level || 'L2');
26
+
27
+ const { dir, state: st } = await change.create(root, {
28
+ slug,
29
+ title,
30
+ level,
31
+ source: { type: 'manual', ref: 'devflow new' },
32
+ });
33
+ if (projectRouting) {
34
+ st.projectRouting = projectRouting;
35
+ st.projects = projectRouting.recommended;
36
+ await routing.writeProjectRootsArtifact(root, slug, projectRouting, { source: 'new' });
37
+ state.logEvent(st, 'project routing selected', {
38
+ source: 'new',
39
+ status: projectRouting.status,
40
+ projects: st.projects.length,
41
+ });
42
+ await state.write(root, slug, st);
43
+ }
44
+ log.ok(`created change: ${slug}`);
45
+ log.dim(` ${dir}`);
46
+
47
+ if (micro) {
48
+ st.mode = 'micro';
49
+ state.setPhase(st, 'intake', 'completed');
50
+ markSkipped(st, 'requirement', 'micro mode');
51
+ markSkipped(st, 'design', 'micro mode');
52
+ markSkipped(st, 'archive', 'micro mode');
53
+ state.setPhase(st, 'plan', 'in_progress');
54
+ await change.writeArtifact(root, slug, 'plan.md', microPlan({ slug, title }));
55
+ state.logEvent(st, 'micro mode initialized', { level: 'L0', nextPhase: 'plan' });
56
+ await state.write(root, slug, st);
57
+ log.ok(`plan: ${dir}/plan.md`);
58
+ const draftResult = await createEntryWorkflowDraft(root, slug, { recipe: 'micro', reason: 'micro mode' });
59
+ if (draftResult) {
60
+ printWorkflowSelectionGuidance(slug);
61
+ }
62
+ return;
63
+ }
64
+
65
+ // Always create proposal.md from template (drafted from brainstorm)
66
+ const tpl = await templates.load('proposal.md');
67
+ const body = templates.render(tpl, {
68
+ slug,
69
+ title,
70
+ level,
71
+ source: 'manual',
72
+ sourceType: 'manual',
73
+ sourceRef: '(无外部输入,brainstorm 起步)',
74
+ summary: '这是手动创建的需求入口,尚未关联外部材料。后续在 requirement 阶段确认范围、验收口径和涉及项目。',
75
+ date: new Date().toISOString().slice(0, 10),
76
+ });
77
+ await change.writeArtifact(root, slug, 'proposal.md', body);
78
+ log.ok(`proposal: ${dir}/proposal.md`);
79
+ await ensureProblemCardCheckpoint(root, slug, {
80
+ title,
81
+ level,
82
+ source: 'manual',
83
+ projectRouting,
84
+ summary: 'proposal.md 已创建;请先补齐问题背景、目标、范围和验收口径。',
85
+ });
86
+
87
+ log.raw('');
88
+ log.dim('next: brainstorm in your IDE (use the devflow-brainstorm SKILL), then resolve the problem_card checkpoint.');
89
+ const draftResult = await createEntryWorkflowDraft(root, slug);
90
+ if (draftResult) {
91
+ printWorkflowSelectionGuidance(slug);
92
+ }
93
+ }
94
+
95
+ function markSkipped(st, phase, reason) {
96
+ st.phases = st.phases || {};
97
+ st.phases[phase] = st.phases[phase] || {};
98
+ st.phases[phase].status = 'skipped';
99
+ st.phases[phase].reason = reason;
100
+ st.phases[phase].ts = new Date().toISOString();
101
+ }
102
+
103
+ function microPlan({ slug, title }) {
104
+ const date = new Date().toISOString().slice(0, 10);
105
+ return [
106
+ `# Plan: ${title || slug}`,
107
+ '',
108
+ `> L0 micro plan, created ${date}. Keep this to 1-3 lines before apply.`,
109
+ '',
110
+ '1. 明确这次极简改动的文件、行为和验证命令。',
111
+ '2. apply 阶段只允许单文件、无 DDL、无接口契约变化;超出范围必须升级到 L1。',
112
+ '3. 完成后至少生成 `reports/test-report.md#unit`,再进入 review / verify / deliver。',
113
+ '',
114
+ ].join('\n');
115
+ }
116
+
117
+ async function resolvePreCreateProjectRouting(root, flags, source, query) {
118
+ const roots = parseRoots(flags.projectRoot || flags['project-root']);
119
+ if (roots.length) return routing.explicitProjectRouting(roots, { source });
120
+ if (flags['no-project-routing'] || flags.noProjectRouting) return null;
121
+
122
+ const searchRoots = parseRoots(flags.searchRoot || flags['search-root'] || flags.projectsRoot || root);
123
+ const result = await routing.routeProjects({
124
+ searchRoots,
125
+ query,
126
+ maxDepth: parseInt(flags.projectDepth || flags['project-depth'] || '3', 10),
127
+ topK: parseInt(flags.projectTopK || flags['project-top-k'] || '5', 10),
128
+ });
129
+ if (!result.recommended.length) return null;
130
+ return {
131
+ status: 'recommended',
132
+ source,
133
+ searchRoots: result.searchRoots,
134
+ queryTerms: routing.extractTerms(query).slice(0, 20),
135
+ candidates: result.candidates,
136
+ recommended: result.recommended,
137
+ slugBranchSource: result.recommended[0].root,
138
+ };
139
+ }
140
+
141
+ function parseRoots(value) {
142
+ return String(value || '')
143
+ .split(',')
144
+ .map((s) => s.trim())
145
+ .filter(Boolean);
146
+ }
147
+
148
+ async function ensureProblemCardCheckpoint(root, slug, details) {
149
+ const st = await state.read(root, slug);
150
+ if (checkpoint.latestPendingByType(st, 'problem_card')) return null;
151
+ if (checkpoint.hasResolvedDecision(st, 'problem_card', 'accept')) return null;
152
+
153
+ const projectNames = details.projectRouting && details.projectRouting.recommended && details.projectRouting.recommended.length
154
+ ? details.projectRouting.recommended.map((p) => `${p.name}:${p.role || 'candidate'}`).join(', ')
155
+ : '未确认';
156
+ const cp = checkpoint.addCheckpoint(st, {
157
+ type: 'problem_card',
158
+ phase: 'intake',
159
+ summary: `${details.title || slug};level=${details.level || st.level || 'L2'};projects=${projectNames}`,
160
+ question: '是否接受当前问题卡、复杂度分级和项目范围,并进入 requirement?',
161
+ options: [
162
+ { id: 'accept', label: '接受并进入需求分析', command: 'devflow checkpoint resolve --id=<checkpoint-id> --decision=accept' },
163
+ { id: 'revise', label: '继续补充问题卡', command: '编辑 proposal.md,必要时重跑 devflow new/ingest --project-root=...' },
164
+ ],
165
+ nextAction: 'devflow checkpoint resolve --id=<checkpoint-id> --decision=accept',
166
+ evidence: ['proposal.md'],
167
+ risks: ['未确认问题卡时直接 requirement,容易把错误范围带入后续设计和实现。'],
168
+ });
169
+ cp.options = cp.options.map((opt) => opt.id === 'accept'
170
+ ? { ...opt, command: `devflow checkpoint resolve --id=${cp.id} --decision=accept` }
171
+ : opt);
172
+ cp.nextAction = `devflow checkpoint resolve --id=${cp.id} --decision=accept`;
173
+ state.logEvent(st, 'checkpoint.add', { id: cp.id, type: cp.type, phase: cp.phase });
174
+ await state.write(root, slug, st);
175
+ log.raw('');
176
+ log.raw(checkpoint.renderNextStepCard(cp));
177
+ return cp;
178
+ }
179
+
180
+ async function createEntryWorkflowDraft(root, slug, opts = {}) {
181
+ try {
182
+ const cfg = (await config.read(root)) || {};
183
+ const st = await state.read(root, slug);
184
+ const result = workflowInit.draftRecommendedWorkflow(root, st, cfg, {
185
+ recipe: opts.recipe,
186
+ reason: opts.reason,
187
+ auto: true,
188
+ });
189
+ await state.write(root, slug, st);
190
+ if (result.created && result.recipe) {
191
+ log.ok(`workflow draft: ${result.recipe.label} (${result.recipe.id})`);
192
+ }
193
+ return result;
194
+ } catch (e) {
195
+ log.warn(`workflow draft not created: ${e.message}`);
196
+ log.dim(`workflow: devflow flow recommend --slug=${slug}`);
197
+ log.dim(` devflow flow draft --slug=${slug}${opts.recipe ? ` --recipe=${opts.recipe}` : ''}`);
198
+ return null;
199
+ }
200
+ }
201
+
202
+ module.exports = { run };
@@ -0,0 +1,49 @@
1
+ 'use strict';
2
+ const log = require('../../utils/log.js');
3
+ const state = require('../../core/state.js');
4
+ const checkpoint = require('../../core/checkpoint.js');
5
+ const helpers = require('./_helpers.js');
6
+
7
+ async function run({ flags = {}, positional = [], cwd }) {
8
+ const root = cwd || process.cwd();
9
+ const slug = await helpers.resolveSlug(root, flags, positional);
10
+ if (!slug) { process.exitCode = 1; return; }
11
+ const st = await helpers.loadStateOrFail(root, slug);
12
+ if (!st) { process.exitCode = 1; return; }
13
+ if (helpers.blockWorkflowStep(root, st, slug, 'plan', 'plan')) return;
14
+
15
+ await helpers.writePhaseArtifact(root, slug, st, 'plan.md', 'plan.md', {});
16
+ if (st.mode !== 'micro') {
17
+ state.setPhase(st, 'design', 'completed');
18
+ }
19
+ state.setPhase(st, 'plan', 'in_progress');
20
+ if (!checkpoint.latestPendingByType(st, 'plan_review')) {
21
+ const cp = checkpoint.addCheckpoint(st, {
22
+ type: 'plan_review',
23
+ phase: 'plan',
24
+ summary: 'plan.md 已生成或待完善,请先审查任务拆分、范围和执行模式',
25
+ question: '是否接受当前 plan,并允许进入 apply?',
26
+ options: [
27
+ { id: 'accept', label: '接受计划', command: 'devflow checkpoint resolve --id=<checkpoint-id> --decision=accept' },
28
+ { id: 'revise', label: '修改计划', command: '编辑 plan.md 后重新运行 devflow plan 或直接更新 checkpoint' },
29
+ ],
30
+ nextAction: 'devflow checkpoint resolve --id=<checkpoint-id> --decision=accept',
31
+ });
32
+ cp.options = cp.options.map((opt) => opt.id === 'accept'
33
+ ? { ...opt, command: `devflow checkpoint resolve --id=${cp.id} --decision=accept` }
34
+ : opt);
35
+ cp.nextAction = `devflow checkpoint resolve --id=${cp.id} --decision=accept`;
36
+ state.logEvent(st, 'checkpoint.add', { id: cp.id, type: cp.type, phase: cp.phase });
37
+ }
38
+ helpers.completeWorkflowStep(st, 'plan');
39
+ state.logEvent(st, 'plan scaffold');
40
+ await state.write(root, slug, st);
41
+ const pending = checkpoint.latestPendingByType(st, 'plan_review');
42
+ log.dim('next: review plan.md before apply');
43
+ if (pending) {
44
+ log.raw('');
45
+ log.raw(checkpoint.renderNextStepCard(pending));
46
+ }
47
+ }
48
+
49
+ module.exports = { run };
@@ -0,0 +1,27 @@
1
+ 'use strict';
2
+ const log = require('../../utils/log.js');
3
+ const state = require('../../core/state.js');
4
+ const helpers = require('./_helpers.js');
5
+
6
+ async function run({ flags = {}, positional = [], cwd }) {
7
+ const root = cwd || process.cwd();
8
+ const slug = await helpers.resolveSlug(root, flags, positional);
9
+ if (!slug) { process.exitCode = 1; return; }
10
+ const st = await helpers.loadStateOrFail(root, slug);
11
+ if (!st) { process.exitCode = 1; return; }
12
+
13
+ await helpers.writePhaseArtifact(root, slug, st, 'proposal.md', 'proposal.md', {
14
+ level: st.level,
15
+ source: (st.source && st.source.ref) || 'manual',
16
+ sourceType: (st.source && st.source.type) || 'manual',
17
+ sourceRef: (st.source && st.source.ref) || '',
18
+ summary: '',
19
+ });
20
+ state.setPhase(st, 'intake', 'completed');
21
+ state.setPhase(st, 'requirement', 'in_progress');
22
+ state.logEvent(st, 'propose');
23
+ await state.write(root, slug, st);
24
+ log.dim('next: devflow requirement');
25
+ }
26
+
27
+ module.exports = { run };