@nimiplatform/nimi-coding 0.1.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 (186) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +348 -0
  3. package/adapters/README.md +25 -0
  4. package/adapters/claude/README.md +89 -0
  5. package/adapters/claude/profile.yaml +70 -0
  6. package/adapters/codex/README.md +53 -0
  7. package/adapters/codex/profile.yaml +78 -0
  8. package/adapters/oh-my-codex/README.md +185 -0
  9. package/adapters/oh-my-codex/profile.yaml +46 -0
  10. package/bin/nimicoding.mjs +6 -0
  11. package/cli/commands/admit-high-risk-decision.mjs +108 -0
  12. package/cli/commands/audit-sweep.mjs +341 -0
  13. package/cli/commands/blueprint-audit.mjs +91 -0
  14. package/cli/commands/clear.mjs +168 -0
  15. package/cli/commands/closeout.mjs +183 -0
  16. package/cli/commands/decide-high-risk-execution.mjs +124 -0
  17. package/cli/commands/doctor.mjs +53 -0
  18. package/cli/commands/generate-spec-derived-docs.mjs +131 -0
  19. package/cli/commands/handoff.mjs +123 -0
  20. package/cli/commands/ingest-high-risk-execution.mjs +95 -0
  21. package/cli/commands/review-high-risk-execution.mjs +95 -0
  22. package/cli/commands/start.mjs +717 -0
  23. package/cli/commands/topic-formatters.mjs +382 -0
  24. package/cli/commands/topic-goal.mjs +33 -0
  25. package/cli/commands/topic-options-shared.mjs +27 -0
  26. package/cli/commands/topic-options-workflow.mjs +767 -0
  27. package/cli/commands/topic-options.mjs +626 -0
  28. package/cli/commands/topic-runner.mjs +169 -0
  29. package/cli/commands/topic.mjs +795 -0
  30. package/cli/commands/validate-acceptance.mjs +5 -0
  31. package/cli/commands/validate-ai-governance.mjs +214 -0
  32. package/cli/commands/validate-execution-packet.mjs +5 -0
  33. package/cli/commands/validate-orchestration-state.mjs +5 -0
  34. package/cli/commands/validate-prompt.mjs +5 -0
  35. package/cli/commands/validate-spec-audit.mjs +27 -0
  36. package/cli/commands/validate-spec-governance.mjs +124 -0
  37. package/cli/commands/validate-spec-tree.mjs +27 -0
  38. package/cli/commands/validate-worker-output.mjs +5 -0
  39. package/cli/constants.mjs +489 -0
  40. package/cli/help.mjs +134 -0
  41. package/cli/index.mjs +103 -0
  42. package/cli/lib/adapter-profiles.mjs +403 -0
  43. package/cli/lib/audit-execution.mjs +52 -0
  44. package/cli/lib/audit-sweep-runtime/admissions.mjs +381 -0
  45. package/cli/lib/audit-sweep-runtime/audit-validity.mjs +333 -0
  46. package/cli/lib/audit-sweep-runtime/chunks.mjs +697 -0
  47. package/cli/lib/audit-sweep-runtime/closeout.mjs +144 -0
  48. package/cli/lib/audit-sweep-runtime/codex-auditor-evidence.mjs +639 -0
  49. package/cli/lib/audit-sweep-runtime/codex-auditor.mjs +515 -0
  50. package/cli/lib/audit-sweep-runtime/common.mjs +329 -0
  51. package/cli/lib/audit-sweep-runtime/coverage-quality.mjs +172 -0
  52. package/cli/lib/audit-sweep-runtime/evidence-assignment.mjs +152 -0
  53. package/cli/lib/audit-sweep-runtime/format.mjs +57 -0
  54. package/cli/lib/audit-sweep-runtime/ingest.mjs +486 -0
  55. package/cli/lib/audit-sweep-runtime/inventory-spec-chunks.mjs +198 -0
  56. package/cli/lib/audit-sweep-runtime/inventory.mjs +728 -0
  57. package/cli/lib/audit-sweep-runtime/ledger.mjs +315 -0
  58. package/cli/lib/audit-sweep-runtime/p0p1-profile.mjs +101 -0
  59. package/cli/lib/audit-sweep-runtime/remediation.mjs +349 -0
  60. package/cli/lib/audit-sweep-runtime/rerun.mjs +129 -0
  61. package/cli/lib/audit-sweep-runtime/risk-budget.mjs +300 -0
  62. package/cli/lib/audit-sweep-runtime/status.mjs +62 -0
  63. package/cli/lib/audit-sweep-runtime/validators-ledger.mjs +215 -0
  64. package/cli/lib/audit-sweep-runtime/validators.mjs +758 -0
  65. package/cli/lib/audit-sweep.mjs +18 -0
  66. package/cli/lib/authority-convergence.mjs +309 -0
  67. package/cli/lib/blueprint-audit.mjs +370 -0
  68. package/cli/lib/bootstrap.mjs +228 -0
  69. package/cli/lib/closeout.mjs +623 -0
  70. package/cli/lib/codex-sdk-runner.mjs +76 -0
  71. package/cli/lib/contracts.mjs +180 -0
  72. package/cli/lib/doctor.mjs +18 -0
  73. package/cli/lib/entrypoints.mjs +274 -0
  74. package/cli/lib/external-execution.mjs +101 -0
  75. package/cli/lib/fs-helpers.mjs +33 -0
  76. package/cli/lib/handoff.mjs +785 -0
  77. package/cli/lib/high-risk-admission.mjs +442 -0
  78. package/cli/lib/high-risk-decision.mjs +324 -0
  79. package/cli/lib/high-risk-ingest.mjs +317 -0
  80. package/cli/lib/high-risk-review.mjs +263 -0
  81. package/cli/lib/internal/contracts-loaders.mjs +132 -0
  82. package/cli/lib/internal/contracts-parse-high-risk.mjs +131 -0
  83. package/cli/lib/internal/contracts-parse.mjs +457 -0
  84. package/cli/lib/internal/contracts-validators.mjs +398 -0
  85. package/cli/lib/internal/doctor-bootstrap-surface.mjs +359 -0
  86. package/cli/lib/internal/doctor-delegated-surface.mjs +256 -0
  87. package/cli/lib/internal/doctor-finalize.mjs +385 -0
  88. package/cli/lib/internal/doctor-format.mjs +286 -0
  89. package/cli/lib/internal/doctor-inspectors.mjs +294 -0
  90. package/cli/lib/internal/doctor-state.mjs +205 -0
  91. package/cli/lib/internal/governance/ai/ai-context-budget-core.mjs +315 -0
  92. package/cli/lib/internal/governance/ai/ai-structure-budget-core.mjs +358 -0
  93. package/cli/lib/internal/governance/ai/check-agents-freshness.mjs +155 -0
  94. package/cli/lib/internal/governance/ai/check-high-risk-doc-metadata-core.mjs +173 -0
  95. package/cli/lib/internal/governance/config.mjs +150 -0
  96. package/cli/lib/internal/governance/runner.mjs +35 -0
  97. package/cli/lib/internal/governance/shared/read-yaml-with-fragments.mjs +49 -0
  98. package/cli/lib/internal/validators-artifacts.mjs +515 -0
  99. package/cli/lib/internal/validators-shared.mjs +28 -0
  100. package/cli/lib/internal/validators-spec-helpers.mjs +186 -0
  101. package/cli/lib/internal/validators-spec.mjs +410 -0
  102. package/cli/lib/shared.mjs +83 -0
  103. package/cli/lib/topic-draft-packets.mjs +48 -0
  104. package/cli/lib/topic-goal.mjs +361 -0
  105. package/cli/lib/topic-runner.mjs +772 -0
  106. package/cli/lib/topic.mjs +93 -0
  107. package/cli/lib/ui.mjs +178 -0
  108. package/cli/lib/validators.mjs +78 -0
  109. package/cli/lib/value-helpers.mjs +24 -0
  110. package/cli/lib/yaml-helpers.mjs +133 -0
  111. package/cli/nimicoding.mjs +1 -0
  112. package/cli/seeds/bootstrap.mjs +47 -0
  113. package/config/audit-execution-artifacts.yaml +20 -0
  114. package/config/bootstrap.yaml +6 -0
  115. package/config/external-execution-artifacts.yaml +16 -0
  116. package/config/host-adapter.yaml +30 -0
  117. package/config/host-profile.yaml +29 -0
  118. package/config/installer-evidence.yaml +31 -0
  119. package/config/skill-installer.yaml +23 -0
  120. package/config/skill-manifest.yaml +46 -0
  121. package/config/skills.yaml +30 -0
  122. package/config/spec-generation-inputs.yaml +25 -0
  123. package/contracts/acceptance.schema.yaml +16 -0
  124. package/contracts/admission-checklist.schema.yaml +15 -0
  125. package/contracts/audit-chunk.schema.yaml +110 -0
  126. package/contracts/audit-closeout.schema.yaml +51 -0
  127. package/contracts/audit-finding.schema.yaml +61 -0
  128. package/contracts/audit-ledger.schema.yaml +138 -0
  129. package/contracts/audit-plan.schema.yaml +123 -0
  130. package/contracts/audit-remediation-map.schema.yaml +51 -0
  131. package/contracts/audit-rerun.schema.yaml +31 -0
  132. package/contracts/audit-sweep-result.yaml +49 -0
  133. package/contracts/authority-convergence-audit.schema.yaml +19 -0
  134. package/contracts/closeout.schema.yaml +25 -0
  135. package/contracts/decision-review.schema.yaml +16 -0
  136. package/contracts/doc-spec-audit-result.yaml +19 -0
  137. package/contracts/execution-packet.schema.yaml +49 -0
  138. package/contracts/external-host-compatibility.yaml +22 -0
  139. package/contracts/forbidden-shortcuts.catalog.yaml +23 -0
  140. package/contracts/high-risk-admission.schema.yaml +23 -0
  141. package/contracts/high-risk-execution-result.yaml +20 -0
  142. package/contracts/orchestration-state.schema.yaml +41 -0
  143. package/contracts/overflow-continuation.schema.yaml +12 -0
  144. package/contracts/packet.schema.yaml +30 -0
  145. package/contracts/pending-note.schema.yaml +17 -0
  146. package/contracts/prompt.schema.yaml +12 -0
  147. package/contracts/remediation.schema.yaml +16 -0
  148. package/contracts/result.schema.yaml +24 -0
  149. package/contracts/spec-generation-audit.schema.yaml +31 -0
  150. package/contracts/spec-generation-inputs.schema.yaml +39 -0
  151. package/contracts/spec-reconstruction-result.yaml +37 -0
  152. package/contracts/topic-goal.schema.yaml +78 -0
  153. package/contracts/topic-run-ledger.schema.yaml +72 -0
  154. package/contracts/topic-step-decision.schema.yaml +45 -0
  155. package/contracts/topic.schema.yaml +65 -0
  156. package/contracts/true-close.schema.yaml +15 -0
  157. package/contracts/wave.schema.yaml +29 -0
  158. package/contracts/worker-output.schema.yaml +15 -0
  159. package/methodology/audit-sweep-p0p1-recall.yaml +45 -0
  160. package/methodology/authority-convergence-policy.yaml +42 -0
  161. package/methodology/core.yaml +25 -0
  162. package/methodology/four-closure-policy.yaml +28 -0
  163. package/methodology/overflow-continuation-policy.yaml +14 -0
  164. package/methodology/role-separation-policy.yaml +28 -0
  165. package/methodology/skill-exchange-projection.yaml +114 -0
  166. package/methodology/skill-handoff.yaml +34 -0
  167. package/methodology/skill-installer-result.yaml +27 -0
  168. package/methodology/skill-installer-summary-projection.yaml +181 -0
  169. package/methodology/skill-runtime.yaml +23 -0
  170. package/methodology/spec-reconstruction.yaml +63 -0
  171. package/methodology/spec-target-truth-profile.yaml +53 -0
  172. package/methodology/topic-lifecycle-report.yaml +144 -0
  173. package/methodology/topic-lifecycle.yaml +37 -0
  174. package/methodology/topic-naming-ontology.yaml +21 -0
  175. package/methodology/topic-ontology.yaml +38 -0
  176. package/methodology/topic-validation-policy.yaml +9 -0
  177. package/methodology/wave-dag-policy.yaml +14 -0
  178. package/package.json +50 -0
  179. package/spec/_meta/command-gating-matrix.yaml +110 -0
  180. package/spec/_meta/generate-drift-migration-checklist.yaml +155 -0
  181. package/spec/_meta/governance-routing-cutover-checklist.yaml +35 -0
  182. package/spec/_meta/phase2-impacted-surface-matrix.yaml +44 -0
  183. package/spec/_meta/spec-authority-cutover-readiness.yaml +104 -0
  184. package/spec/_meta/spec-tree-model.yaml +72 -0
  185. package/spec/bootstrap-state.yaml +99 -0
  186. package/spec/product-scope.yaml +56 -0
@@ -0,0 +1,341 @@
1
+ import {
2
+ buildAuditSweepCloseoutImport,
3
+ buildAuditSweepLedger,
4
+ buildAuditSweepRemediationMap,
5
+ createAuditSweepPlan,
6
+ admitAuditSweepRemediationMap,
7
+ dispatchAuditSweepChunk,
8
+ formatAuditSweepPayload,
9
+ getAuditSweepStatus,
10
+ ingestAuditSweepChunk,
11
+ resolveAuditSweepFinding,
12
+ reviewAuditSweepChunk,
13
+ runCodexAuditSweepChunk,
14
+ skipAuditSweepChunk,
15
+ validateAuditSweepArtifacts,
16
+ } from "../lib/audit-sweep.mjs";
17
+ import { localize } from "../lib/ui.mjs";
18
+
19
+ function readRequiredValue(args, index, optionName, commandName) {
20
+ const next = args[index + 1];
21
+ if (!next || next.startsWith("--")) {
22
+ return {
23
+ ok: false,
24
+ error: `${localize(
25
+ `nimicoding audit-sweep ${commandName} refused: ${optionName} requires a value.`,
26
+ `nimicoding audit-sweep ${commandName} 已拒绝:${optionName} 需要一个值。`,
27
+ )}\n`,
28
+ };
29
+ }
30
+ return { ok: true, value: next };
31
+ }
32
+
33
+ function unknownOption(commandName, arg) {
34
+ return {
35
+ ok: false,
36
+ error: `${localize(
37
+ `nimicoding audit-sweep ${commandName} refused: unknown option ${arg}.`,
38
+ `nimicoding audit-sweep ${commandName} 已拒绝:未知选项 ${arg}。`,
39
+ )}\n`,
40
+ };
41
+ }
42
+
43
+ function parseOptions(args, commandName, spec) {
44
+ const options = Object.fromEntries(Object.entries(spec).map(([name, config]) => [name, config.default ?? null]));
45
+
46
+ for (let index = 0; index < args.length; index += 1) {
47
+ const arg = args[index];
48
+ if (arg === "--json") {
49
+ options.json = true;
50
+ continue;
51
+ }
52
+
53
+ const entry = Object.entries(spec).find(([, config]) => config.flag === arg);
54
+ if (!entry) {
55
+ return unknownOption(commandName, arg);
56
+ }
57
+ const [name, config] = entry;
58
+ const value = readRequiredValue(args, index, arg, commandName);
59
+ if (!value.ok) {
60
+ return value;
61
+ }
62
+ if (config.type === "positive-int") {
63
+ const parsed = Number(value.value);
64
+ if (!Number.isInteger(parsed) || parsed <= 0) {
65
+ return {
66
+ ok: false,
67
+ error: `${localize(
68
+ `nimicoding audit-sweep ${commandName} refused: ${arg} must be a positive integer.`,
69
+ `nimicoding audit-sweep ${commandName} 已拒绝:${arg} 必须是正整数。`,
70
+ )}\n`,
71
+ };
72
+ }
73
+ options[name] = parsed;
74
+ } else {
75
+ options[name] = value.value;
76
+ }
77
+ index += 1;
78
+ }
79
+
80
+ const missing = Object.entries(spec)
81
+ .filter(([, config]) => config.required)
82
+ .filter(([name]) => !options[name])
83
+ .map(([, config]) => config.flag);
84
+ if (missing.length > 0) {
85
+ return {
86
+ ok: false,
87
+ error: `${localize(
88
+ `nimicoding audit-sweep ${commandName} refused: missing required options: ${missing.join(", ")}.`,
89
+ `nimicoding audit-sweep ${commandName} 已拒绝:缺少必填选项:${missing.join(", ")}。`,
90
+ )}\n`,
91
+ };
92
+ }
93
+
94
+ return { ok: true, options };
95
+ }
96
+
97
+ function parsePlanOptions(args) {
98
+ return parseOptions(args, "plan", {
99
+ root: { flag: "--root", required: true },
100
+ chunkBasis: { flag: "--chunk-basis" },
101
+ criteria: { flag: "--criteria" },
102
+ exclude: { flag: "--exclude" },
103
+ ignore: { flag: "--ignore" },
104
+ ignoreOwner: { flag: "--ignore-owner" },
105
+ ignoreReason: { flag: "--ignore-reason" },
106
+ maxFilesPerChunk: { flag: "--max-files", type: "positive-int" },
107
+ maxSweepFindings: { flag: "--max-sweep-findings", type: "positive-int" },
108
+ maxDomainFindings: { flag: "--max-domain-findings", type: "positive-int" },
109
+ maxSweepHighRiskFindings: { flag: "--max-sweep-high-risk-findings", type: "positive-int" },
110
+ maxDomainHighRiskFindings: { flag: "--max-domain-high-risk-findings", type: "positive-int" },
111
+ sweepId: { flag: "--sweep-id" },
112
+ json: { default: false },
113
+ });
114
+ }
115
+
116
+ function parseChunkDispatchOptions(args) {
117
+ return parseOptions(args, "chunk dispatch", {
118
+ sweepId: { flag: "--sweep-id", required: true },
119
+ chunkId: { flag: "--chunk-id", required: true },
120
+ dispatchedAt: { flag: "--dispatched-at", required: true },
121
+ auditor: { flag: "--auditor" },
122
+ json: { default: false },
123
+ });
124
+ }
125
+
126
+ function parseChunkIngestOptions(args) {
127
+ return parseOptions(args, "chunk ingest", {
128
+ sweepId: { flag: "--sweep-id", required: true },
129
+ chunkId: { flag: "--chunk-id", required: true },
130
+ fromPath: { flag: "--from", required: true },
131
+ verifiedAt: { flag: "--verified-at", required: true },
132
+ json: { default: false },
133
+ });
134
+ }
135
+
136
+ function parseChunkAuditCodexOptions(args) {
137
+ return parseOptions(args, "chunk audit-codex", {
138
+ sweepId: { flag: "--sweep-id", required: true },
139
+ chunkId: { flag: "--chunk-id", required: true },
140
+ dispatchedAt: { flag: "--dispatched-at", required: true },
141
+ verifiedAt: { flag: "--verified-at", required: true },
142
+ reviewedAt: { flag: "--reviewed-at", required: true },
143
+ auditor: { flag: "--auditor" },
144
+ reviewer: { flag: "--reviewer" },
145
+ summary: { flag: "--summary" },
146
+ codexBin: { flag: "--codex-bin" },
147
+ fromRawOutput: { flag: "--from-raw-output" },
148
+ timeoutMs: { flag: "--timeout-ms", type: "positive-int" },
149
+ json: { default: false },
150
+ });
151
+ }
152
+
153
+ function parseChunkReviewOptions(args) {
154
+ return parseOptions(args, "chunk review", {
155
+ sweepId: { flag: "--sweep-id", required: true },
156
+ chunkId: { flag: "--chunk-id", required: true },
157
+ verdict: { flag: "--verdict", required: true },
158
+ reviewedAt: { flag: "--reviewed-at", required: true },
159
+ reviewer: { flag: "--reviewer" },
160
+ summary: { flag: "--summary" },
161
+ json: { default: false },
162
+ });
163
+ }
164
+
165
+ function parseChunkSkipOptions(args) {
166
+ return parseOptions(args, "chunk skip", {
167
+ sweepId: { flag: "--sweep-id", required: true },
168
+ chunkId: { flag: "--chunk-id", required: true },
169
+ reason: { flag: "--reason", required: true },
170
+ skippedAt: { flag: "--skipped-at", required: true },
171
+ json: { default: false },
172
+ });
173
+ }
174
+
175
+ function parseLedgerBuildOptions(args) {
176
+ return parseOptions(args, "ledger build", {
177
+ sweepId: { flag: "--sweep-id", required: true },
178
+ verifiedAt: { flag: "--verified-at" },
179
+ json: { default: false },
180
+ });
181
+ }
182
+
183
+ function parseRemediationMapBuildOptions(args) {
184
+ return parseOptions(args, "remediation-map build", {
185
+ sweepId: { flag: "--sweep-id", required: true },
186
+ verifiedAt: { flag: "--verified-at" },
187
+ maxFindingsPerWave: { flag: "--max-findings", type: "positive-int" },
188
+ json: { default: false },
189
+ });
190
+ }
191
+
192
+ function parseRemediationMapAdmitOptions(args) {
193
+ return parseOptions(args, "remediation-map admit", {
194
+ sweepId: { flag: "--sweep-id", required: true },
195
+ topicId: { flag: "--topic-id", required: true },
196
+ json: { default: false },
197
+ });
198
+ }
199
+
200
+ function parseFindingResolveOptions(args) {
201
+ return parseOptions(args, "finding resolve", {
202
+ sweepId: { flag: "--sweep-id", required: true },
203
+ findingId: { flag: "--finding-id", required: true },
204
+ disposition: { flag: "--disposition", required: true },
205
+ fromPath: { flag: "--from", required: true },
206
+ verifiedAt: { flag: "--verified-at", required: true },
207
+ json: { default: false },
208
+ });
209
+ }
210
+
211
+ function parseSweepIdOptions(args, commandName, timestampRequired = false) {
212
+ return parseOptions(args, commandName, {
213
+ sweepId: { flag: "--sweep-id", required: true },
214
+ verifiedAt: { flag: "--verified-at", required: timestampRequired },
215
+ json: { default: false },
216
+ });
217
+ }
218
+
219
+ function parseValidateOptions(args) {
220
+ return parseOptions(args, "validate", {
221
+ sweepId: { flag: "--sweep-id", required: true },
222
+ scope: { flag: "--scope", default: "all" },
223
+ json: { default: false },
224
+ });
225
+ }
226
+
227
+ function parseAuditSweepOptions(args) {
228
+ const [command, subcommand] = args;
229
+ if (command === "plan") {
230
+ return { ok: true, action: "plan", parsed: parsePlanOptions(args.slice(1)) };
231
+ }
232
+ if (command === "chunk" && subcommand === "dispatch") {
233
+ return { ok: true, action: "chunk-dispatch", parsed: parseChunkDispatchOptions(args.slice(2)) };
234
+ }
235
+ if (command === "chunk" && subcommand === "ingest") {
236
+ return { ok: true, action: "chunk-ingest", parsed: parseChunkIngestOptions(args.slice(2)) };
237
+ }
238
+ if (command === "chunk" && subcommand === "audit-codex") {
239
+ return { ok: true, action: "chunk-audit-codex", parsed: parseChunkAuditCodexOptions(args.slice(2)) };
240
+ }
241
+ if (command === "chunk" && subcommand === "review") {
242
+ return { ok: true, action: "chunk-review", parsed: parseChunkReviewOptions(args.slice(2)) };
243
+ }
244
+ if (command === "chunk" && subcommand === "skip") {
245
+ return { ok: true, action: "chunk-skip", parsed: parseChunkSkipOptions(args.slice(2)) };
246
+ }
247
+ if (command === "ledger" && subcommand === "build") {
248
+ return { ok: true, action: "ledger-build", parsed: parseLedgerBuildOptions(args.slice(2)) };
249
+ }
250
+ if (command === "remediation-map" && subcommand === "build") {
251
+ return { ok: true, action: "remediation-map-build", parsed: parseRemediationMapBuildOptions(args.slice(2)) };
252
+ }
253
+ if (command === "remediation-map" && subcommand === "admit") {
254
+ return { ok: true, action: "remediation-map-admit", parsed: parseRemediationMapAdmitOptions(args.slice(2)) };
255
+ }
256
+ if (command === "finding" && subcommand === "resolve") {
257
+ return { ok: true, action: "finding-resolve", parsed: parseFindingResolveOptions(args.slice(2)) };
258
+ }
259
+ if (command === "closeout" && subcommand === "summary") {
260
+ return { ok: true, action: "closeout-summary", parsed: parseSweepIdOptions(args.slice(2), "closeout summary", true) };
261
+ }
262
+ if (command === "status") {
263
+ return { ok: true, action: "status", parsed: parseSweepIdOptions(args.slice(1), "status") };
264
+ }
265
+ if (command === "validate") {
266
+ return { ok: true, action: "validate", parsed: parseValidateOptions(args.slice(1)) };
267
+ }
268
+
269
+ return {
270
+ ok: false,
271
+ error: `${localize(
272
+ "nimicoding audit-sweep refused: expected one of `plan`, `chunk dispatch`, `chunk audit-codex`, `chunk ingest`, `chunk review`, `chunk skip`, `ledger build`, `remediation-map build`, `remediation-map admit`, `finding resolve`, `closeout summary`, `status`, or `validate`.",
273
+ "nimicoding audit-sweep 已拒绝:需要使用 `plan`、`chunk dispatch`、`chunk ingest`、`chunk review`、`chunk skip`、`ledger build`、`remediation-map build`、`remediation-map admit`、`finding resolve`、`closeout summary`、`status` 或 `validate`。",
274
+ )}\n`,
275
+ };
276
+ }
277
+
278
+ function writeStream(stream, text) {
279
+ return new Promise((resolve, reject) => {
280
+ stream.write(text, (error) => {
281
+ if (error) {
282
+ reject(error);
283
+ return;
284
+ }
285
+ resolve();
286
+ });
287
+ });
288
+ }
289
+
290
+ export async function runAuditSweep(args) {
291
+ const selected = parseAuditSweepOptions(args);
292
+ if (!selected.ok) {
293
+ process.stderr.write(selected.error);
294
+ return 2;
295
+ }
296
+ if (!selected.parsed.ok) {
297
+ process.stderr.write(selected.parsed.error);
298
+ return 2;
299
+ }
300
+
301
+ const runners = {
302
+ plan: createAuditSweepPlan,
303
+ "chunk-dispatch": dispatchAuditSweepChunk,
304
+ "chunk-ingest": ingestAuditSweepChunk,
305
+ "chunk-audit-codex": runCodexAuditSweepChunk,
306
+ "chunk-review": reviewAuditSweepChunk,
307
+ "chunk-skip": skipAuditSweepChunk,
308
+ "ledger-build": buildAuditSweepLedger,
309
+ "remediation-map-build": buildAuditSweepRemediationMap,
310
+ "remediation-map-admit": admitAuditSweepRemediationMap,
311
+ "finding-resolve": resolveAuditSweepFinding,
312
+ "closeout-summary": buildAuditSweepCloseoutImport,
313
+ status: getAuditSweepStatus,
314
+ validate: validateAuditSweepArtifacts,
315
+ };
316
+ const payload = await runners[selected.action](process.cwd(), selected.parsed.options);
317
+ if (payload.inputError) {
318
+ process.stderr.write(payload.error);
319
+ return payload.exitCode;
320
+ }
321
+ if (selected.parsed.options.json) {
322
+ await writeStream(process.stdout, `${JSON.stringify(payload, null, 2)}\n`);
323
+ } else {
324
+ await writeStream(process.stdout, formatAuditSweepPayload(payload));
325
+ }
326
+ return payload.exitCode;
327
+ }
328
+
329
+ export {
330
+ parseAuditSweepOptions,
331
+ parseChunkAuditCodexOptions,
332
+ parseChunkDispatchOptions,
333
+ parseChunkIngestOptions,
334
+ parseChunkReviewOptions,
335
+ parseChunkSkipOptions,
336
+ parseFindingResolveOptions,
337
+ parsePlanOptions,
338
+ parseRemediationMapAdmitOptions,
339
+ parseRemediationMapBuildOptions,
340
+ parseValidateOptions,
341
+ };
@@ -0,0 +1,91 @@
1
+ import {
2
+ buildBlueprintAuditPayload,
3
+ formatBlueprintAuditPayload,
4
+ writeBlueprintAuditArtifact,
5
+ } from "../lib/shared.mjs";
6
+ import { localize } from "../lib/ui.mjs";
7
+
8
+ function parseBlueprintAuditOptions(args) {
9
+ const options = {
10
+ json: false,
11
+ writeLocal: false,
12
+ blueprintRoot: null,
13
+ canonicalRoot: null,
14
+ };
15
+
16
+ for (let index = 0; index < args.length; index += 1) {
17
+ const arg = args[index];
18
+
19
+ if (arg === "--json") {
20
+ options.json = true;
21
+ continue;
22
+ }
23
+
24
+ if (arg === "--write-local") {
25
+ options.writeLocal = true;
26
+ continue;
27
+ }
28
+
29
+ if (arg === "--blueprint-root" || arg === "--canonical-root") {
30
+ const next = args[index + 1];
31
+ if (!next || next.startsWith("--")) {
32
+ return {
33
+ ok: false,
34
+ error: `${localize(
35
+ `nimicoding blueprint-audit refused: ${arg} requires a value.`,
36
+ `nimicoding blueprint-audit 已拒绝:${arg} 需要一个值。`,
37
+ )}\n`,
38
+ };
39
+ }
40
+
41
+ if (arg === "--blueprint-root") {
42
+ options.blueprintRoot = next;
43
+ } else {
44
+ options.canonicalRoot = next;
45
+ }
46
+ index += 1;
47
+ continue;
48
+ }
49
+
50
+ return {
51
+ ok: false,
52
+ error: `${localize(
53
+ `nimicoding blueprint-audit refused: unknown option ${arg}.`,
54
+ `nimicoding blueprint-audit 已拒绝:未知选项 ${arg}。`,
55
+ )}\n`,
56
+ };
57
+ }
58
+
59
+ return {
60
+ ok: true,
61
+ options,
62
+ };
63
+ }
64
+
65
+ export async function runBlueprintAudit(args) {
66
+ const parsed = parseBlueprintAuditOptions(args);
67
+ if (!parsed.ok) {
68
+ process.stderr.write(parsed.error);
69
+ return 2;
70
+ }
71
+
72
+ const payload = await buildBlueprintAuditPayload(process.cwd(), parsed.options);
73
+ if (payload.inputError) {
74
+ process.stderr.write(payload.error);
75
+ return payload.exitCode;
76
+ }
77
+
78
+ if (parsed.options.writeLocal) {
79
+ await writeBlueprintAuditArtifact(process.cwd(), payload);
80
+ }
81
+
82
+ if (parsed.options.json) {
83
+ process.stdout.write(`${JSON.stringify(payload, null, 2)}\n`);
84
+ } else {
85
+ process.stdout.write(formatBlueprintAuditPayload(payload));
86
+ }
87
+
88
+ return payload.exitCode;
89
+ }
90
+
91
+ export { parseBlueprintAuditOptions };
@@ -0,0 +1,168 @@
1
+ import { createInterface } from "node:readline/promises";
2
+ import process from "node:process";
3
+
4
+ import {
5
+ previewBootstrapRemoval,
6
+ previewEntrypointRemoval,
7
+ removeManagedBootstrapFiles,
8
+ removeManagedEntrypoints,
9
+ } from "../lib/shared.mjs";
10
+ import {
11
+ localize,
12
+ styleHeading,
13
+ styleLabel,
14
+ styleMuted,
15
+ } from "../lib/ui.mjs";
16
+
17
+ function parseClearOptions(args) {
18
+ const options = {
19
+ yes: false,
20
+ };
21
+
22
+ for (const arg of args) {
23
+ if (arg === "--yes") {
24
+ options.yes = true;
25
+ continue;
26
+ }
27
+
28
+ return {
29
+ ok: false,
30
+ error: `${localize(
31
+ `nimicoding clear refused: unknown option ${arg}.`,
32
+ `nimicoding clear 已拒绝:未知选项 ${arg}。`,
33
+ )}\n`,
34
+ };
35
+ }
36
+
37
+ return { ok: true, options };
38
+ }
39
+
40
+ function canPromptInteractively() {
41
+ return Boolean(process.stdin.isTTY && process.stdout.isTTY);
42
+ }
43
+
44
+ async function confirmClear(prompt) {
45
+ const rl = createInterface({
46
+ input: process.stdin,
47
+ output: process.stdout,
48
+ });
49
+
50
+ try {
51
+ const answer = (await rl.question(`${prompt}${localize(" [Y/n] ", " [Y/n] ")}`)).trim().toLowerCase();
52
+ if (answer.length === 0) {
53
+ return true;
54
+ }
55
+ return answer === "y" || answer === "yes";
56
+ } finally {
57
+ rl.close();
58
+ }
59
+ }
60
+
61
+ function formatList(items, emptyLine) {
62
+ return items.length > 0 ? items.map((item) => ` - ${item}`).join("\n") : emptyLine;
63
+ }
64
+
65
+ export async function runClear(args) {
66
+ const parsed = parseClearOptions(args);
67
+ if (!parsed.ok) {
68
+ process.stderr.write(parsed.error);
69
+ return 2;
70
+ }
71
+
72
+ const projectRoot = process.cwd();
73
+ const entrypointPreview = await previewEntrypointRemoval(projectRoot);
74
+ const bootstrapPreview = await previewBootstrapRemoval(projectRoot);
75
+
76
+ if (canPromptInteractively() && !parsed.options.yes) {
77
+ process.stdout.write(`${styleHeading(localize(`nimicoding clear: ${projectRoot}`, `nimicoding clear:${projectRoot}`))}
78
+
79
+ ${styleLabel(localize("What I can clear:", "我可以清理的内容:"))}
80
+ ${formatList(
81
+ [
82
+ ...entrypointPreview.map((filePath) => `${localize("managed AI block in", "托管 AI 区块:")} ${filePath}`),
83
+ ...bootstrapPreview.removableFiles,
84
+ ],
85
+ localize(" - no nimicoding-managed files are ready to clear", " - 当前没有可清理的 nimicoding 托管文件"),
86
+ )}
87
+
88
+ ${styleLabel(localize("What I will keep:", "我会保留的内容:"))}
89
+ - .nimi/spec/**
90
+ - .nimi/local/**
91
+ - .nimi/cache/**
92
+ ${bootstrapPreview.preservedModifiedFiles.length > 0
93
+ ? `\n${styleMuted(localize("I also found package-owned bootstrap files that were changed locally, so I will leave them in place:", "我还发现了一些包拥有的 bootstrap 文件已被本地修改,因此我会保留它们:"))}\n${bootstrapPreview.preservedModifiedFiles.map((filePath) => ` - ${filePath}`).join("\n")}`
94
+ : ""}
95
+
96
+ `);
97
+ }
98
+
99
+ const hasWork = entrypointPreview.length > 0 || bootstrapPreview.removableFiles.length > 0;
100
+ if (!hasWork && bootstrapPreview.preservedModifiedFiles.length === 0) {
101
+ process.stdout.write(`${styleHeading(localize(`nimicoding clear: ${projectRoot}`, `nimicoding clear:${projectRoot}`))}
102
+
103
+ ${styleLabel(localize("What I cleared:", "我已清理的内容:"))}
104
+ ${localize(" - nothing needed clearing", " - 没有需要清理的内容")}
105
+
106
+ ${styleLabel(localize("What I kept:", "我保留的内容:"))}
107
+ - .nimi/spec/**
108
+ - .nimi/local/**
109
+ - .nimi/cache/**
110
+
111
+ ${styleMuted(localize("No nimicoding-managed bootstrap files or managed AI blocks were found.", "没有检测到 nimicoding 托管的 bootstrap 文件或托管 AI 区块。"))}
112
+ `);
113
+ return 0;
114
+ }
115
+
116
+ if (!parsed.options.yes && canPromptInteractively()) {
117
+ const approved = await confirmClear(localize(
118
+ "Clear the nimicoding-managed setup now?",
119
+ "现在清理 nimicoding 托管的项目初始化内容吗?",
120
+ ));
121
+ if (!approved) {
122
+ process.stdout.write(`${styleHeading(localize("nimicoding clear canceled", "nimicoding clear 已取消"))}
123
+
124
+ ${styleMuted(localize("No files were changed.", "没有修改任何文件。"))}
125
+ `);
126
+ return 0;
127
+ }
128
+ }
129
+
130
+ const removedEntrypoints = await removeManagedEntrypoints(projectRoot);
131
+ const removedBootstrap = await removeManagedBootstrapFiles(projectRoot);
132
+
133
+ process.stdout.write(`${styleHeading(localize(`nimicoding clear: ${projectRoot}`, `nimicoding clear:${projectRoot}`))}
134
+
135
+ ${styleLabel(localize("What I cleared:", "我已清理的内容:"))}
136
+ ${formatList(
137
+ [
138
+ ...removedEntrypoints.updatedFiles.map((filePath) => `${localize("updated", "已更新")}: ${filePath}`),
139
+ ...removedEntrypoints.removedFiles.map((filePath) => `${localize("removed", "已移除")}: ${filePath}`),
140
+ ...removedBootstrap.removedFiles.map((filePath) => `${localize("removed", "已移除")}: ${filePath}`),
141
+ ...removedBootstrap.removedDirs.map((dirPath) => `${localize("removed empty dir", "已移除空目录")}: ${dirPath}/`),
142
+ ],
143
+ localize(" - nothing was cleared", " - 没有清理任何内容"),
144
+ )}
145
+
146
+ ${styleLabel(localize("What I kept:", "我保留的内容:"))}
147
+ - .nimi/spec/**
148
+ - .nimi/local/**
149
+ - .nimi/cache/**
150
+ ${removedBootstrap.preservedModifiedFiles.length > 0
151
+ ? `\n${removedBootstrap.preservedModifiedFiles.map((filePath) => ` - ${localize("kept because it was modified", "已保留,因为它已被修改")}: ${filePath}`).join("\n")}`
152
+ : ""}
153
+
154
+ ${styleLabel(localize("What You Should Review Next:", "你下一步应该检查什么:"))}
155
+ - ${localize(
156
+ "If you want to fully remove project-local AI truth, review .nimi/spec/** and local artifacts manually.",
157
+ "如果你想完整移除项目本地 AI truth,请手动检查 .nimi/spec/** 和本地产物。",
158
+ )}
159
+ - ${localize(
160
+ "If you want nimicoding again later, run `nimicoding start`.",
161
+ "如果以后还要重新接入 nimicoding,请运行 `nimicoding start`。",
162
+ )}
163
+ `);
164
+
165
+ return 0;
166
+ }
167
+
168
+ export { parseClearOptions };