@topogram/cli 0.3.62 → 0.3.64
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/adoption/plan.d.ts +6 -0
- package/src/adoption/reporting.d.ts +10 -0
- package/src/adoption/review-groups.d.ts +6 -0
- package/src/agent-brief.d.ts +3 -0
- package/src/agent-brief.js +495 -0
- package/src/agent-ops/query-builders.d.ts +26 -0
- package/src/archive/archive.d.ts +2 -0
- package/src/archive/compact.d.ts +1 -0
- package/src/archive/unarchive.d.ts +1 -0
- package/src/catalog.d.ts +10 -0
- package/src/catalog.js +62 -66
- package/src/cli/catalog-alias.d.ts +1 -0
- package/src/cli/command-parser.js +38 -0
- package/src/cli/command-parsers/core.js +102 -0
- package/src/cli/command-parsers/generator.js +39 -0
- package/src/cli/command-parsers/import.js +44 -0
- package/src/cli/command-parsers/legacy-workflow.js +21 -0
- package/src/cli/command-parsers/project.js +47 -0
- package/src/cli/command-parsers/sdlc.js +47 -0
- package/src/cli/command-parsers/shared.js +51 -0
- package/src/cli/command-parsers/template.js +48 -0
- package/src/cli/commands/agent.js +47 -0
- package/src/cli/commands/catalog.js +617 -0
- package/src/cli/commands/check.js +268 -0
- package/src/cli/commands/doctor.js +268 -0
- package/src/cli/commands/emit.js +149 -0
- package/src/cli/commands/generate.js +96 -0
- package/src/cli/commands/generator-policy.js +785 -0
- package/src/cli/commands/generator.js +443 -0
- package/src/cli/commands/import-runner.js +157 -0
- package/src/cli/commands/import.js +1734 -0
- package/src/cli/commands/inspect.js +55 -0
- package/src/cli/commands/new.js +94 -0
- package/src/cli/commands/package.js +815 -0
- package/src/cli/commands/query.js +1302 -0
- package/src/cli/commands/release-rollout.js +257 -0
- package/src/cli/commands/release-shared.js +528 -0
- package/src/cli/commands/release-status.js +429 -0
- package/src/cli/commands/release.js +107 -0
- package/src/cli/commands/sdlc.js +168 -0
- package/src/cli/commands/setup.js +76 -0
- package/src/cli/commands/source.js +291 -0
- package/src/cli/commands/template-runner.js +198 -0
- package/src/cli/commands/template.js +2145 -0
- package/src/cli/commands/trust.js +219 -0
- package/src/cli/commands/version.js +40 -0
- package/src/cli/commands/widget.js +168 -0
- package/src/cli/commands/workflow.js +63 -0
- package/src/cli/dispatcher.js +392 -0
- package/src/cli/help-dispatch.js +188 -0
- package/src/cli/help.js +296 -0
- package/src/cli/migration-guidance.js +59 -0
- package/src/cli/options.js +96 -0
- package/src/cli/output-safety.js +107 -0
- package/src/cli/path-normalization.js +29 -0
- package/src/cli.js +47 -11711
- package/src/example-implementation.d.ts +2 -0
- package/src/format.d.ts +1 -0
- package/src/generator/check.d.ts +1 -0
- package/src/generator/context/bundle.d.ts +1 -0
- package/src/generator/context/shared.d.ts +2 -0
- package/src/generator/native/parity-bundle.js +2 -1
- package/src/generator/surfaces/web/html-escape.js +22 -0
- package/src/generator/surfaces/web/react.js +10 -8
- package/src/generator/surfaces/web/sveltekit.js +7 -5
- package/src/generator/surfaces/web/vanilla.js +8 -4
- package/src/generator.d.ts +2 -0
- package/src/github-client.js +520 -0
- package/src/import/core/shared.js +20 -62
- package/src/import/extractors/api/flutter-dio.js +4 -8
- package/src/import/extractors/api/react-native-repository.js +4 -8
- package/src/import/index.d.ts +4 -0
- package/src/import/provenance.d.ts +4 -0
- package/src/new-project.js +100 -11
- package/src/npm-safety.js +79 -0
- package/src/parser.d.ts +1 -0
- package/src/path-helpers.d.ts +1 -0
- package/src/path-helpers.js +20 -0
- package/src/project-config.js +1 -0
- package/src/reconcile/docs.d.ts +8 -0
- package/src/reconcile/journeys.d.ts +1 -0
- package/src/resolver.d.ts +1 -0
- package/src/runtime-support.js +29 -0
- package/src/sdlc/adopt.d.ts +1 -0
- package/src/sdlc/check.d.ts +1 -0
- package/src/sdlc/explain.d.ts +1 -0
- package/src/sdlc/release.d.ts +1 -0
- package/src/sdlc/scaffold.d.ts +1 -0
- package/src/sdlc/transition.d.ts +1 -0
- package/src/text-helpers.d.ts +6 -0
- package/src/text-helpers.js +245 -0
- package/src/topogram-config.js +306 -0
- package/src/validator.d.ts +2 -0
- package/src/workflows/adoption/index.js +26 -0
- package/src/workflows/docs-generate.js +262 -0
- package/src/workflows/docs-scan.js +703 -0
- package/src/workflows/docs.js +15 -0
- package/src/workflows/import-app/api.js +799 -0
- package/src/workflows/import-app/db.js +538 -0
- package/src/workflows/import-app/index.js +30 -0
- package/src/workflows/import-app/shared.js +218 -0
- package/src/workflows/import-app/ui.js +443 -0
- package/src/workflows/import-app/workflow.js +159 -0
- package/src/workflows/reconcile/adoption-plan.js +742 -0
- package/src/workflows/reconcile/auth.js +692 -0
- package/src/workflows/reconcile/bundle-core.js +600 -0
- package/src/workflows/reconcile/bundle-shared.js +75 -0
- package/src/workflows/reconcile/candidate-model.js +477 -0
- package/src/workflows/reconcile/canonical-surface.js +264 -0
- package/src/workflows/reconcile/gap-report.js +333 -0
- package/src/workflows/reconcile/ids.js +6 -0
- package/src/workflows/reconcile/impacts.js +625 -0
- package/src/workflows/reconcile/index.js +7 -0
- package/src/workflows/reconcile/renderers.js +461 -0
- package/src/workflows/reconcile/summary.js +90 -0
- package/src/workflows/reconcile/workflow.js +309 -0
- package/src/workflows/shared.js +189 -0
- package/src/workflows/types.d.ts +93 -0
- package/src/workflows.d.ts +1 -0
- package/src/workflows.js +10 -7652
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
|
|
3
|
+
import fs from "node:fs";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
|
|
6
|
+
import {
|
|
7
|
+
buildPackageUpdateCliPayload,
|
|
8
|
+
CLI_PACKAGE_NAME,
|
|
9
|
+
isPackageVersion,
|
|
10
|
+
latestTopogramCliVersion
|
|
11
|
+
} from "./package.js";
|
|
12
|
+
import {
|
|
13
|
+
commandDiagnostic,
|
|
14
|
+
currentGitHead,
|
|
15
|
+
discoverTopogramCliVersionConsumers,
|
|
16
|
+
expectedConsumerWorkflowName,
|
|
17
|
+
hasStagedGitChanges,
|
|
18
|
+
inspectConsumerCi,
|
|
19
|
+
inspectGitWorktreeClean,
|
|
20
|
+
messageFromError,
|
|
21
|
+
runGit,
|
|
22
|
+
waitForConsumerCi
|
|
23
|
+
} from "./release-shared.js";
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* @typedef {Record<string, any>} AnyRecord
|
|
27
|
+
*/
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* @param {string} requested
|
|
31
|
+
* @param {{ cwd?: string, push?: boolean, watch?: boolean }} [options]
|
|
32
|
+
* @returns {{ ok: boolean, packageName: string, requestedVersion: string, requestedLatest: boolean, pushed: boolean, watched: boolean, consumers: Array<AnyRecord>, diagnostics: Array<AnyRecord>, errors: string[] }}
|
|
33
|
+
*/
|
|
34
|
+
export function buildReleaseRollConsumersPayload(requested, options = {}) {
|
|
35
|
+
const cwd = options.cwd || process.cwd();
|
|
36
|
+
const push = options.push !== false;
|
|
37
|
+
const watch = Boolean(options.watch);
|
|
38
|
+
const requestedLatest = requested === "latest" || requested === "--latest";
|
|
39
|
+
/** @type {Array<AnyRecord>} */
|
|
40
|
+
const diagnostics = [];
|
|
41
|
+
if (watch && !push) {
|
|
42
|
+
diagnostics.push({
|
|
43
|
+
code: "release_roll_watch_requires_push",
|
|
44
|
+
severity: "error",
|
|
45
|
+
message: "`topogram release roll-consumers --watch` requires pushing consumer commits.",
|
|
46
|
+
path: "release roll-consumers",
|
|
47
|
+
suggestedFix: "Remove --no-push or run without --watch and verify consumer CI separately."
|
|
48
|
+
});
|
|
49
|
+
return {
|
|
50
|
+
ok: false,
|
|
51
|
+
packageName: CLI_PACKAGE_NAME,
|
|
52
|
+
requestedVersion: requestedLatest ? "latest" : requested,
|
|
53
|
+
requestedLatest,
|
|
54
|
+
pushed: push,
|
|
55
|
+
watched: watch,
|
|
56
|
+
consumers: [],
|
|
57
|
+
diagnostics,
|
|
58
|
+
errors: diagnostics.map((diagnostic) => diagnostic.message)
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
const version = requestedLatest
|
|
62
|
+
? latestTopogramCliVersion(cwd)
|
|
63
|
+
: requested;
|
|
64
|
+
if (!isPackageVersion(version)) {
|
|
65
|
+
throw new Error("topogram release roll-consumers requires <version> or --latest.");
|
|
66
|
+
}
|
|
67
|
+
/** @type {Array<AnyRecord>} */
|
|
68
|
+
const consumers = [];
|
|
69
|
+
for (const consumer of discoverTopogramCliVersionConsumers(cwd)) {
|
|
70
|
+
const workflow = expectedConsumerWorkflowName(consumer.name);
|
|
71
|
+
/** @type {AnyRecord} */
|
|
72
|
+
const item = {
|
|
73
|
+
name: consumer.name,
|
|
74
|
+
root: consumer.root,
|
|
75
|
+
workflow,
|
|
76
|
+
updated: false,
|
|
77
|
+
committed: false,
|
|
78
|
+
pushed: false,
|
|
79
|
+
commit: null,
|
|
80
|
+
update: null,
|
|
81
|
+
ci: null,
|
|
82
|
+
diagnostics: []
|
|
83
|
+
};
|
|
84
|
+
consumers.push(item);
|
|
85
|
+
if (!consumer.root || !fs.existsSync(consumer.root)) {
|
|
86
|
+
item.diagnostics.push({
|
|
87
|
+
code: "release_consumer_repo_missing",
|
|
88
|
+
severity: "error",
|
|
89
|
+
message: `First-party consumer repo ${consumer.name} was not found.`,
|
|
90
|
+
path: consumer.path,
|
|
91
|
+
suggestedFix: `Clone ${consumer.name} beside the topogram repo, then rerun roll-consumers.`
|
|
92
|
+
});
|
|
93
|
+
diagnostics.push(...item.diagnostics);
|
|
94
|
+
continue;
|
|
95
|
+
}
|
|
96
|
+
const packagePath = path.join(consumer.root, "package.json");
|
|
97
|
+
if (!fs.existsSync(packagePath)) {
|
|
98
|
+
item.diagnostics.push({
|
|
99
|
+
code: "release_consumer_package_missing",
|
|
100
|
+
severity: "error",
|
|
101
|
+
message: `First-party consumer repo ${consumer.name} does not contain package.json.`,
|
|
102
|
+
path: packagePath,
|
|
103
|
+
suggestedFix: "Only package-backed first-party consumers can be rolled by this command."
|
|
104
|
+
});
|
|
105
|
+
diagnostics.push(...item.diagnostics);
|
|
106
|
+
continue;
|
|
107
|
+
}
|
|
108
|
+
const clean = inspectGitWorktreeClean(consumer.root);
|
|
109
|
+
if (clean.ok !== true) {
|
|
110
|
+
item.diagnostics.push({
|
|
111
|
+
code: "release_consumer_worktree_dirty",
|
|
112
|
+
severity: "error",
|
|
113
|
+
message: clean.error || `First-party consumer repo ${consumer.name} has uncommitted changes.`,
|
|
114
|
+
path: consumer.root,
|
|
115
|
+
suggestedFix: "Commit, stash, or discard unrelated consumer changes before rolling the CLI version."
|
|
116
|
+
});
|
|
117
|
+
diagnostics.push(...item.diagnostics);
|
|
118
|
+
continue;
|
|
119
|
+
}
|
|
120
|
+
try {
|
|
121
|
+
item.update = buildPackageUpdateCliPayload(version, { cwd: consumer.root });
|
|
122
|
+
item.updated = true;
|
|
123
|
+
} catch (error) {
|
|
124
|
+
item.diagnostics.push({
|
|
125
|
+
code: "release_consumer_update_failed",
|
|
126
|
+
severity: "error",
|
|
127
|
+
message: `Failed to update ${consumer.name}: ${messageFromError(error)}`,
|
|
128
|
+
path: consumer.root,
|
|
129
|
+
suggestedFix: "Fix the consumer update/check failure, then rerun roll-consumers."
|
|
130
|
+
});
|
|
131
|
+
diagnostics.push(...item.diagnostics);
|
|
132
|
+
continue;
|
|
133
|
+
}
|
|
134
|
+
const filesToStage = ["package.json", "package-lock.json", "topogram-cli.version"]
|
|
135
|
+
.filter((file) => fs.existsSync(path.join(consumer.root || "", file)));
|
|
136
|
+
const addResult = runGit(["add", ...filesToStage], consumer.root);
|
|
137
|
+
if (addResult.status !== 0) {
|
|
138
|
+
item.diagnostics.push(commandDiagnostic({
|
|
139
|
+
code: "release_consumer_git_add_failed",
|
|
140
|
+
severity: "error",
|
|
141
|
+
message: `Failed to stage ${consumer.name} CLI update.`,
|
|
142
|
+
path: consumer.root,
|
|
143
|
+
suggestedFix: "Inspect git output, stage the changed files manually, then commit and push.",
|
|
144
|
+
result: addResult
|
|
145
|
+
}));
|
|
146
|
+
diagnostics.push(...item.diagnostics);
|
|
147
|
+
continue;
|
|
148
|
+
}
|
|
149
|
+
const staged = hasStagedGitChanges(consumer.root);
|
|
150
|
+
if (!staged.ok) {
|
|
151
|
+
item.diagnostics.push(commandDiagnostic({
|
|
152
|
+
code: "release_consumer_git_diff_failed",
|
|
153
|
+
severity: "error",
|
|
154
|
+
message: `Could not inspect staged changes for ${consumer.name}.`,
|
|
155
|
+
path: consumer.root,
|
|
156
|
+
suggestedFix: "Inspect git status manually before committing.",
|
|
157
|
+
result: staged.result
|
|
158
|
+
}));
|
|
159
|
+
diagnostics.push(...item.diagnostics);
|
|
160
|
+
continue;
|
|
161
|
+
}
|
|
162
|
+
if (!staged.changed) {
|
|
163
|
+
item.ci = watch
|
|
164
|
+
? waitForConsumerCi(consumer)
|
|
165
|
+
: inspectConsumerCi(consumer, { strict: false });
|
|
166
|
+
item.diagnostics.push(...item.ci.diagnostics);
|
|
167
|
+
diagnostics.push(...item.ci.diagnostics);
|
|
168
|
+
continue;
|
|
169
|
+
}
|
|
170
|
+
const commitResult = runGit(["commit", "-m", `Update Topogram CLI to ${version}`], consumer.root);
|
|
171
|
+
if (commitResult.status !== 0) {
|
|
172
|
+
item.diagnostics.push(commandDiagnostic({
|
|
173
|
+
code: "release_consumer_git_commit_failed",
|
|
174
|
+
severity: "error",
|
|
175
|
+
message: `Failed to commit ${consumer.name} CLI update.`,
|
|
176
|
+
path: consumer.root,
|
|
177
|
+
suggestedFix: "Inspect git output, commit the consumer update manually, then push.",
|
|
178
|
+
result: commitResult
|
|
179
|
+
}));
|
|
180
|
+
diagnostics.push(...item.diagnostics);
|
|
181
|
+
continue;
|
|
182
|
+
}
|
|
183
|
+
item.committed = true;
|
|
184
|
+
item.commit = currentGitHead(consumer.root);
|
|
185
|
+
if (push) {
|
|
186
|
+
const pushResult = runGit(["push", "origin", "main"], consumer.root);
|
|
187
|
+
if (pushResult.status !== 0) {
|
|
188
|
+
item.diagnostics.push(commandDiagnostic({
|
|
189
|
+
code: "release_consumer_git_push_failed",
|
|
190
|
+
severity: "error",
|
|
191
|
+
message: `Failed to push ${consumer.name} CLI update.`,
|
|
192
|
+
path: consumer.root,
|
|
193
|
+
suggestedFix: "Push the consumer update manually, then confirm its verification workflow passes.",
|
|
194
|
+
result: pushResult
|
|
195
|
+
}));
|
|
196
|
+
diagnostics.push(...item.diagnostics);
|
|
197
|
+
continue;
|
|
198
|
+
}
|
|
199
|
+
item.pushed = true;
|
|
200
|
+
}
|
|
201
|
+
item.ci = watch
|
|
202
|
+
? waitForConsumerCi(consumer)
|
|
203
|
+
: inspectConsumerCi(consumer, { strict: false });
|
|
204
|
+
item.diagnostics.push(...item.ci.diagnostics);
|
|
205
|
+
diagnostics.push(...item.ci.diagnostics);
|
|
206
|
+
}
|
|
207
|
+
const errors = diagnostics
|
|
208
|
+
.filter((diagnostic) => diagnostic.severity === "error")
|
|
209
|
+
.map((diagnostic) => diagnostic.message);
|
|
210
|
+
return {
|
|
211
|
+
ok: errors.length === 0,
|
|
212
|
+
packageName: CLI_PACKAGE_NAME,
|
|
213
|
+
requestedVersion: version,
|
|
214
|
+
requestedLatest,
|
|
215
|
+
pushed: push,
|
|
216
|
+
watched: watch,
|
|
217
|
+
consumers,
|
|
218
|
+
diagnostics,
|
|
219
|
+
errors
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* @param {ReturnType<typeof buildReleaseRollConsumersPayload>} payload
|
|
225
|
+
* @returns {void}
|
|
226
|
+
*/
|
|
227
|
+
export function printReleaseRollConsumers(payload) {
|
|
228
|
+
console.log(payload.ok ? "Topogram consumer rollout completed." : "Topogram consumer rollout found issues.");
|
|
229
|
+
if (payload.requestedLatest) {
|
|
230
|
+
console.log(`Resolved latest version: ${payload.requestedVersion}`);
|
|
231
|
+
}
|
|
232
|
+
console.log(`Package: ${payload.packageName}@${payload.requestedVersion}`);
|
|
233
|
+
console.log(`Push: ${payload.pushed ? "enabled" : "disabled"}`);
|
|
234
|
+
console.log(`Watch: ${payload.watched ? "enabled" : "disabled"}`);
|
|
235
|
+
for (const consumer of payload.consumers) {
|
|
236
|
+
const state = consumer.committed
|
|
237
|
+
? consumer.pushed ? "pushed" : "committed"
|
|
238
|
+
: consumer.updated ? "updated" : "skipped";
|
|
239
|
+
console.log(`- ${consumer.name}: ${state}`);
|
|
240
|
+
if (consumer.update) {
|
|
241
|
+
console.log(` Checks run: ${consumer.update.scriptsRun.join(", ") || "none"}`);
|
|
242
|
+
}
|
|
243
|
+
if (consumer.commit) {
|
|
244
|
+
console.log(` Commit: ${consumer.commit}`);
|
|
245
|
+
}
|
|
246
|
+
if (consumer.ci?.run?.url) {
|
|
247
|
+
const run = consumer.ci.run;
|
|
248
|
+
console.log(` CI: ${run.workflowName || consumer.workflow} ${run.status || "unknown"}/${run.conclusion || "unknown"} ${run.url}`);
|
|
249
|
+
} else if (consumer.workflow) {
|
|
250
|
+
console.log(` CI: ${consumer.workflow} not found`);
|
|
251
|
+
}
|
|
252
|
+
for (const diagnostic of consumer.diagnostics || []) {
|
|
253
|
+
const label = diagnostic.severity === "error" ? "Error" : diagnostic.severity === "warning" ? "Warning" : "Note";
|
|
254
|
+
console.log(` ${label}: ${diagnostic.message}`);
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
}
|