@topogram/cli 0.3.78 → 0.3.80
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/CHANGELOG.md +20 -0
- package/package.json +2 -2
- package/src/agent-brief.js +29 -23
- package/src/agent-ops/query-builders/change-risk/{import-plan.js → extract-plan.js} +1 -1
- package/src/agent-ops/query-builders/change-risk/review-packets.js +5 -5
- package/src/agent-ops/query-builders/change-risk.js +1 -1
- package/src/agent-ops/query-builders/common.js +2 -2
- package/src/agent-ops/query-builders/multi-agent.js +1 -1
- package/src/agent-ops/query-builders/workflow-context-shared.js +4 -4
- package/src/catalog/provenance.js +1 -1
- package/src/cli/catalog-alias.d.ts +2 -0
- package/src/cli/catalog-alias.js +2 -2
- package/src/cli/command-parser.js +2 -0
- package/src/cli/command-parsers/core.js +9 -5
- package/src/cli/command-parsers/extractor.js +40 -0
- package/src/cli/command-parsers/import.js +11 -17
- package/src/cli/command-parsers/project.js +0 -3
- package/src/cli/commands/catalog/copy.js +3 -3
- package/src/cli/commands/catalog/help.js +1 -2
- package/src/cli/commands/catalog/list.js +7 -4
- package/src/cli/commands/catalog/show.js +4 -4
- package/src/cli/commands/copy.js +356 -0
- package/src/cli/commands/doctor.js +1 -1
- package/src/cli/commands/extractor.js +451 -0
- package/src/cli/commands/import/adopt.js +9 -9
- package/src/cli/commands/import/check.js +15 -15
- package/src/cli/commands/import/diff.js +6 -6
- package/src/cli/commands/import/help.js +45 -34
- package/src/cli/commands/import/paths.js +3 -3
- package/src/cli/commands/import/plan.js +8 -8
- package/src/cli/commands/import/refresh.js +25 -24
- package/src/cli/commands/import/status-history.js +4 -4
- package/src/cli/commands/import/workspace.js +24 -18
- package/src/cli/commands/import-runner.js +10 -7
- package/src/cli/commands/import.js +4 -1
- package/src/cli/commands/init.js +67 -0
- package/src/cli/commands/query/{import-adopt.js → extract-adopt.js} +2 -2
- package/src/cli/commands/query/runner/change.js +2 -2
- package/src/cli/commands/query/runner/{import-adopt.js → extract-adopt.js} +9 -9
- package/src/cli/commands/query/runner/index.js +1 -1
- package/src/cli/commands/query/runner/workflow.js +7 -7
- package/src/cli/commands/query/workspace.js +4 -4
- package/src/cli/commands/release-status.js +2 -2
- package/src/cli/commands/source.js +2 -2
- package/src/cli/commands/template/check.js +2 -2
- package/src/cli/commands/template/list-show.js +4 -4
- package/src/cli/dispatcher.js +32 -3
- package/src/cli/help-dispatch.js +33 -8
- package/src/cli/help.js +79 -52
- package/src/cli/migration-guidance.js +9 -0
- package/src/cli/options.js +17 -0
- package/src/extractor/check.js +155 -0
- package/src/extractor/packages.js +295 -0
- package/src/extractor/registry.js +196 -0
- package/src/extractor-policy.js +249 -0
- package/src/generator/check.js +24 -87
- package/src/generator/context/bundle.js +14 -7
- package/src/generator/context/diff.js +8 -1
- package/src/generator/context/digest.js +10 -1
- package/src/generator/context/shared/domain-sdlc.js +5 -1
- package/src/generator/context/shared/relationships.js +20 -5
- package/src/generator/context/shared/summaries.js +26 -0
- package/src/generator/context/shared.d.ts +1 -0
- package/src/generator/context/shared.js +1 -0
- package/src/generator/context/slice/core.js +9 -5
- package/src/generator/context/slice/sdlc.js +31 -2
- package/src/generator/context/task-mode.js +3 -3
- package/src/generator/registry/index.js +16 -75
- package/src/generator-policy.js +9 -57
- package/src/import/core/registry.d.ts +3 -0
- package/src/import/core/registry.js +82 -8
- package/src/import/core/runner/reports.js +4 -4
- package/src/import/core/runner/run.js +2 -0
- package/src/import/core/runner/tracks.js +66 -4
- package/src/import/provenance.js +18 -17
- package/src/init-project.js +215 -0
- package/src/new-project/constants.js +1 -1
- package/src/new-project/create.js +2 -2
- package/src/new-project/project-files.js +7 -7
- package/src/package-adapters/adapter.js +64 -0
- package/src/package-adapters/file-map.js +30 -0
- package/src/package-adapters/index.js +27 -0
- package/src/package-adapters/manifest.js +108 -0
- package/src/package-adapters/policy.js +81 -0
- package/src/package-adapters/spec.js +51 -0
- package/src/reconcile/journeys.js +8 -3
- package/src/record-blocks.js +125 -0
- package/src/resolver/index.js +3 -0
- package/src/resolver/journeys.js +74 -0
- package/src/resolver/normalize.js +25 -0
- package/src/sdlc/adopt.js +1 -1
- package/src/validator/common.js +34 -1
- package/src/validator/index.js +4 -0
- package/src/validator/kinds.d.ts +2 -0
- package/src/validator/kinds.js +34 -1
- package/src/validator/per-kind/journey.js +233 -0
- package/src/workflows/docs-generate.js +4 -1
- package/src/workflows/reconcile/bundle-core/index.js +4 -2
- package/src/workflows/reconcile/canonical-surface.js +4 -1
- package/src/cli/commands/new.js +0 -94
package/src/cli/help.js
CHANGED
|
@@ -35,17 +35,18 @@ export function printUsage(options = {}) {
|
|
|
35
35
|
console.log(" or: topogram catalog show <id> [--json] [--catalog <path-or-source>]");
|
|
36
36
|
console.log(" or: topogram catalog doctor [--json] [--catalog <path-or-source>]");
|
|
37
37
|
console.log(" or: topogram catalog check <path-or-url> [--json]");
|
|
38
|
-
console.log(" or: topogram catalog copy <id> <target> [--version <version>] [--json] [--catalog <path-or-source>]");
|
|
39
38
|
console.log(" or: topogram package update-cli <version|--latest> [--json]");
|
|
40
|
-
console.log(" or: topogram
|
|
41
|
-
console.log(" or: topogram
|
|
42
|
-
console.log(" or: topogram
|
|
43
|
-
console.log(" or: topogram
|
|
44
|
-
console.log(" or: topogram
|
|
45
|
-
console.log(" or: topogram
|
|
46
|
-
console.log(" or: topogram
|
|
47
|
-
console.log(" or: topogram
|
|
48
|
-
console.log(" or: topogram
|
|
39
|
+
console.log(" or: topogram copy <source> <target> [--version <version>] [--catalog <path-or-source>] [--json]");
|
|
40
|
+
console.log(" or: topogram copy --list [--json] [--catalog <path-or-source>]");
|
|
41
|
+
console.log(" or: topogram extract <app-path> --out <target> [--from <track[,track]>] [--extractor <id-or-package-or-path>] [--json]");
|
|
42
|
+
console.log(" or: topogram extract refresh [path] [--from <app-path>] [--dry-run] [--json]");
|
|
43
|
+
console.log(" or: topogram extract diff [path] [--json]");
|
|
44
|
+
console.log(" or: topogram extract check [path] [--json]");
|
|
45
|
+
console.log(" or: topogram extract plan [path] [--json]");
|
|
46
|
+
console.log(" or: topogram adopt --list [path] [--json]");
|
|
47
|
+
console.log(" or: topogram adopt <selector> [path] [--dry-run|--write] [--force --reason <text>] [--json]");
|
|
48
|
+
console.log(" or: topogram extract status [path] [--json]");
|
|
49
|
+
console.log(" or: topogram extract history [path] [--verify] [--json]");
|
|
49
50
|
console.log(" or: topogram source status [path] [--local|--remote] [--json]");
|
|
50
51
|
console.log(" or: topogram template list [--json]");
|
|
51
52
|
console.log(" or: topogram template explain [path] [--json]");
|
|
@@ -66,9 +67,15 @@ export function printUsage(options = {}) {
|
|
|
66
67
|
console.log(" or: topogram generator policy check [path] [--json]");
|
|
67
68
|
console.log(" or: topogram generator policy explain [path] [--json]");
|
|
68
69
|
console.log(" or: topogram generator policy pin [package@version] [path] [--json]");
|
|
69
|
-
console.log(" or: topogram
|
|
70
|
-
console.log(" or: topogram
|
|
71
|
-
console.log(" or: topogram
|
|
70
|
+
console.log(" or: topogram extractor list [--json]");
|
|
71
|
+
console.log(" or: topogram extractor show <id-or-package> [--json]");
|
|
72
|
+
console.log(" or: topogram extractor check <path-or-package> [--json]");
|
|
73
|
+
console.log(" or: topogram extractor policy init [path] [--json]");
|
|
74
|
+
console.log(" or: topogram extractor policy status [path] [--json]");
|
|
75
|
+
console.log(" or: topogram extractor policy check [path] [--json]");
|
|
76
|
+
console.log(" or: topogram extractor policy explain [path] [--json]");
|
|
77
|
+
console.log(" or: topogram extractor policy pin [package@version] [path] [--json]");
|
|
78
|
+
console.log(" or: topogram init [path] [--with-sdlc] [--json]");
|
|
72
79
|
console.log("");
|
|
73
80
|
console.log("Common commands:");
|
|
74
81
|
console.log(" topogram version");
|
|
@@ -76,9 +83,10 @@ export function printUsage(options = {}) {
|
|
|
76
83
|
console.log(" topogram setup package-auth");
|
|
77
84
|
console.log(" topogram release status");
|
|
78
85
|
console.log(" topogram release roll-consumers --latest");
|
|
79
|
-
console.log(" topogram
|
|
80
|
-
console.log(" topogram
|
|
81
|
-
console.log(" topogram
|
|
86
|
+
console.log(" topogram init .");
|
|
87
|
+
console.log(" topogram copy --list");
|
|
88
|
+
console.log(" topogram copy hello-web ./my-app");
|
|
89
|
+
console.log(" topogram copy todo ./todo-app");
|
|
82
90
|
console.log(" topogram check");
|
|
83
91
|
console.log(" topogram check --json");
|
|
84
92
|
console.log(" topogram widget check --projection proj_web_surface");
|
|
@@ -98,22 +106,26 @@ export function printUsage(options = {}) {
|
|
|
98
106
|
console.log(" topogram generator show @topogram/generator-react-web");
|
|
99
107
|
console.log(" topogram generator check ./generator-package");
|
|
100
108
|
console.log(" topogram generator policy check");
|
|
109
|
+
console.log(" topogram extractor list");
|
|
110
|
+
console.log(" topogram extractor check ./extractor-package");
|
|
111
|
+
console.log(" topogram extractor policy check");
|
|
101
112
|
console.log(" topogram generate");
|
|
102
|
-
console.log(" topogram
|
|
103
|
-
console.log(" topogram
|
|
104
|
-
console.log(" topogram
|
|
105
|
-
console.log(" topogram
|
|
106
|
-
console.log(" topogram
|
|
107
|
-
console.log(" topogram
|
|
108
|
-
console.log(" topogram
|
|
109
|
-
console.log(" topogram
|
|
110
|
-
console.log(" topogram
|
|
113
|
+
console.log(" topogram extract ./existing-app --out ./extracted-topogram");
|
|
114
|
+
console.log(" topogram extract diff ./extracted-topogram");
|
|
115
|
+
console.log(" topogram extract refresh ./extracted-topogram --from ./existing-app --dry-run");
|
|
116
|
+
console.log(" topogram extract check ./extracted-topogram");
|
|
117
|
+
console.log(" topogram extract plan ./extracted-topogram");
|
|
118
|
+
console.log(" topogram adopt --list ./extracted-topogram");
|
|
119
|
+
console.log(" topogram adopt bundle:task ./extracted-topogram --dry-run");
|
|
120
|
+
console.log(" topogram extract status ./extracted-topogram");
|
|
121
|
+
console.log(" topogram extract history ./extracted-topogram --verify");
|
|
111
122
|
console.log("");
|
|
112
123
|
console.log("Fresh install:");
|
|
113
124
|
console.log(" npm install --save-dev @topogram/cli");
|
|
114
125
|
console.log(" npx topogram doctor");
|
|
115
126
|
console.log(" npx topogram template list");
|
|
116
|
-
console.log(" npx topogram
|
|
127
|
+
console.log(" npx topogram init .");
|
|
128
|
+
console.log(" npx topogram copy hello-web ./my-app");
|
|
117
129
|
console.log(" cd ./my-app && npm install && npm run check && npm run generate");
|
|
118
130
|
console.log(" npm --prefix app run compile");
|
|
119
131
|
console.log("");
|
|
@@ -123,7 +135,7 @@ export function printUsage(options = {}) {
|
|
|
123
135
|
console.log(" topogram catalog show todo");
|
|
124
136
|
console.log(" topogram catalog doctor");
|
|
125
137
|
console.log(" topogram catalog check topograms.catalog.json");
|
|
126
|
-
console.log(" topogram
|
|
138
|
+
console.log(" topogram copy hello ./hello-topogram");
|
|
127
139
|
console.log(" topogram source status --local");
|
|
128
140
|
console.log(" topogram source status --remote");
|
|
129
141
|
console.log("");
|
|
@@ -149,7 +161,7 @@ export function printUsage(options = {}) {
|
|
|
149
161
|
console.log(" topogram template update --apply");
|
|
150
162
|
console.log("");
|
|
151
163
|
console.log("Defaults: check/generate use ./topo, and generate writes ./app.");
|
|
152
|
-
console.log("Default starter: hello-web from the catalog. Run `topogram
|
|
164
|
+
console.log("Default starter: hello-web from the catalog. Run `topogram copy --list` for catalog aliases.");
|
|
153
165
|
console.log("Generated app commands are emitted into the output package.json.");
|
|
154
166
|
console.log("Run `topogram help <command>` for command-specific help.");
|
|
155
167
|
console.log("Run `topogram help all` for legacy and agent-facing commands.");
|
|
@@ -157,16 +169,12 @@ export function printUsage(options = {}) {
|
|
|
157
169
|
return;
|
|
158
170
|
}
|
|
159
171
|
console.log("");
|
|
160
|
-
console.log("
|
|
161
|
-
console.log("Usage: topogram create <path> [--template hello-web|todo|./local-template|@scope/template]");
|
|
172
|
+
console.log("Internal commands:");
|
|
162
173
|
console.log(" or: topogram template show <id> [--json] [--catalog <path-or-source>]");
|
|
163
|
-
console.log(" or: topogram import app <path> [--from <track[,track]>] [--write]");
|
|
164
174
|
console.log(" or: topogram validate <path>");
|
|
165
|
-
console.log(" or: node ./src/cli.js query work-packet <path> --mode
|
|
175
|
+
console.log(" or: node ./src/cli.js query work-packet <path> --mode extract-adopt --lane <id>");
|
|
166
176
|
console.log(" or: node ./src/cli.js <path> [--json] [--validate] [--resolve] [--workflow <name>] [--mode <id>] [--from <track[,track]>] [--adopt <selector>] [--refresh-adopted] [--shape <id>] [--capability <id>] [--widget <id>] [--projection <id>] [--entity <id>] [--journey <id>] [--surface <id>] [--task <id>] [--profile <id>] [--from-snapshot <path>] [--from-topogram <path>] [--write] [--out-dir <path>]");
|
|
167
177
|
console.log(" or: node ./src/cli.js emit <target> [path] [--json] [--write] [--out-dir <path>]");
|
|
168
|
-
console.log(" or: node ./src/cli.js import app <path> [--from <track[,track]>] [--write]");
|
|
169
|
-
console.log(" or: node ./src/cli.js import docs <path> [--write]");
|
|
170
178
|
console.log(" or: node ./src/cli.js generate journeys <path> [--write]");
|
|
171
179
|
console.log(" or: node ./src/cli.js report gaps <path> [--write]");
|
|
172
180
|
console.log(" or: node ./src/cli.js query task-mode <path> [--mode <id>] [--capability <id>] [--workflow <id>] [--projection <id>] [--widget <id>] [--entity <id>] [--journey <id>] [--from-topogram <path>]");
|
|
@@ -184,56 +192,75 @@ export function printUsage(options = {}) {
|
|
|
184
192
|
console.log(" or: node ./src/cli.js query verification-targets <path> [--mode <id>] [--capability <id>] [--workflow <id>] [--projection <id>] [--widget <id>] [--entity <id>] [--journey <id>] [--from-topogram <path>]");
|
|
185
193
|
console.log(" or: node ./src/cli.js query widget-behavior <path> [--projection <id>] [--widget <id>] [--json]");
|
|
186
194
|
console.log(" or: node ./src/cli.js query change-plan <path> [--mode <id>] [--capability <id>] [--workflow <id>] [--projection <id>] [--widget <id>] [--entity <id>] [--journey <id>] [--surface <id>] [--from-topogram <path>]");
|
|
187
|
-
console.log(" or: node ./src/cli.js query
|
|
195
|
+
console.log(" or: node ./src/cli.js query extract-plan <path>");
|
|
188
196
|
console.log(" or: node ./src/cli.js query risk-summary <path> [--mode <id>] [--capability <id>] [--workflow <id>] [--projection <id>] [--widget <id>] [--entity <id>] [--journey <id>] [--surface <id>] [--from-topogram <path>]");
|
|
189
197
|
console.log(" or: node ./src/cli.js query canonical-writes <path> [--mode <id>] [--capability <id>] [--workflow <id>] [--projection <id>] [--widget <id>] [--entity <id>] [--journey <id>] [--surface <id>] [--from-topogram <path>]");
|
|
190
198
|
console.log(" or: node ./src/cli.js query proceed-decision <path> [--mode <id>] [--capability <id>] [--workflow <id>] [--projection <id>] [--widget <id>] [--entity <id>] [--journey <id>] [--surface <id>] [--from-topogram <path>]");
|
|
191
199
|
console.log(" or: node ./src/cli.js query review-packet <path> [--mode <id>] [--capability <id>] [--workflow <id>] [--projection <id>] [--widget <id>] [--entity <id>] [--journey <id>] [--surface <id>] [--from-topogram <path>]");
|
|
192
200
|
console.log(" or: node ./src/cli.js query next-action <path> [--mode <id>] [--capability <id>] [--workflow <id>] [--projection <id>] [--widget <id>] [--entity <id>] [--journey <id>] [--from-topogram <path>]");
|
|
193
201
|
console.log(" or: node ./src/cli.js query single-agent-plan <path> --mode <id> [--capability <id>] [--workflow <id>] [--projection <id>] [--widget <id>] [--entity <id>] [--journey <id>] [--surface <id>] [--task <id>] [--plan <id>] [--bug <id>] [--from-topogram <path>]");
|
|
194
|
-
console.log(" or: node ./src/cli.js query multi-agent-plan <path> --mode
|
|
202
|
+
console.log(" or: node ./src/cli.js query multi-agent-plan <path> --mode extract-adopt");
|
|
195
203
|
console.log(" or: node ./src/cli.js query resolved-workflow-context <path> --mode <id> [--capability <id>] [--workflow <id>] [--projection <id>] [--widget <id>] [--entity <id>] [--journey <id>] [--surface <id>] [--provider <id>] [--preset <id>] [--from-topogram <path>]");
|
|
196
204
|
console.log(" or: node ./src/cli.js query workflow-preset-activation <path> --mode <id> [--provider <id>] [--preset <id>] [--from-topogram <path>]");
|
|
197
205
|
console.log(" or: node ./src/cli.js query workflow-preset-diff <path> --provider <id> [--preset <id>]");
|
|
198
206
|
console.log(" or: node ./src/cli.js query workflow-preset-customization <path> --provider <id> --preset <id>");
|
|
199
207
|
console.log(" or: node ./src/cli.js workflow-preset customize <path> --provider <id> --preset <id> [--out <path>] [--write]");
|
|
200
|
-
console.log(" or: node ./src/cli.js query lane-status <path> --mode
|
|
201
|
-
console.log(" or: node ./src/cli.js query handoff-status <path> --mode
|
|
208
|
+
console.log(" or: node ./src/cli.js query lane-status <path> --mode extract-adopt");
|
|
209
|
+
console.log(" or: node ./src/cli.js query handoff-status <path> --mode extract-adopt");
|
|
202
210
|
console.log(" or: node ./src/cli.js query auth-hints <path>");
|
|
203
211
|
console.log(" or: node ./src/cli.js query auth-review-packet <path> --bundle <slug>");
|
|
204
212
|
console.log(" or: node ./src/cli.js reconcile <path> [--write]");
|
|
205
213
|
console.log(" or: node ./src/cli.js reconcile adopt <selector> <path> [--refresh-adopted] [--write]");
|
|
206
214
|
console.log(" or: node ./src/cli.js adoption status <path> [--write]");
|
|
207
215
|
console.log("Targets: json-schema, docs, docs-index, verification-plan, verification-checklist, shape-transform-graph, shape-transform-debug, api-contract-graph, api-contract-debug, ui-contract-graph, ui-contract-debug, ui-widget-contract, widget-conformance-report, widget-behavior-report, ui-surface-contract, ui-surface-debug, sveltekit-app, swiftui-app, db-contract-graph, db-contract-debug, db-schema-snapshot, db-migration-plan, db-lifecycle-plan, db-lifecycle-bundle, environment-plan, environment-bundle, deployment-plan, deployment-bundle, runtime-smoke-plan, runtime-smoke-bundle, runtime-check-plan, runtime-check-bundle, compile-check-plan, compile-check-bundle, app-bundle-plan, app-bundle, native-parity-plan, native-parity-bundle, sql-migration, sql-schema, prisma-schema, drizzle-schema, persistence-scaffold, server-contract, hono-server, openapi, context-digest, context-diff, context-slice, context-bundle, context-report, context-task-mode");
|
|
208
|
-
console.log("Workflows:
|
|
209
|
-
console.log("
|
|
216
|
+
console.log("Workflows: scan-docs, reconcile, adoption-status, generate-docs, generate-journeys, refresh-docs, report-gaps");
|
|
217
|
+
console.log("Extract tracks: db, api, ui, cli, workflows, verification");
|
|
210
218
|
console.log("Reconcile adopt selectors: from-plan, actors, roles, enums, shapes, entities, capabilities, widgets, docs, journeys, workflows, ui, bundle:<slug>, projection-review:<id>, ui-review:<id>, workflow-review:<id>, bundle-review:<slug>");
|
|
211
219
|
}
|
|
212
220
|
|
|
213
221
|
/**
|
|
214
222
|
* @returns {void}
|
|
215
223
|
*/
|
|
216
|
-
export function
|
|
217
|
-
console.log("Usage: topogram
|
|
218
|
-
console.log(" or: topogram
|
|
224
|
+
export function printCopyHelp() {
|
|
225
|
+
console.log("Usage: topogram copy <source> <target> [--version <version>] [--catalog <path-or-source>] [--json]");
|
|
226
|
+
console.log(" or: topogram copy --list [--json] [--catalog <path-or-source>]");
|
|
219
227
|
console.log("");
|
|
220
|
-
console.log("
|
|
228
|
+
console.log("Copies a catalog template, template package/path, or pure Topogram source into a new project directory.");
|
|
221
229
|
console.log("");
|
|
222
230
|
console.log("Fresh install flow:");
|
|
223
231
|
console.log(" npm install --save-dev @topogram/cli");
|
|
224
|
-
console.log(" npx topogram
|
|
225
|
-
console.log(" npx topogram
|
|
232
|
+
console.log(" npx topogram copy --list");
|
|
233
|
+
console.log(" npx topogram copy hello-web ./my-app");
|
|
226
234
|
console.log(" cd ./my-app && npm install && npm run check && npm run generate");
|
|
227
235
|
console.log(" npm --prefix app run compile");
|
|
228
236
|
console.log("");
|
|
229
237
|
console.log("Examples:");
|
|
230
|
-
console.log(" topogram
|
|
231
|
-
console.log(" topogram
|
|
232
|
-
console.log(" topogram
|
|
233
|
-
console.log(" topogram
|
|
234
|
-
console.log(" topogram
|
|
238
|
+
console.log(" topogram copy --list");
|
|
239
|
+
console.log(" topogram copy hello-web ./my-app");
|
|
240
|
+
console.log(" topogram copy todo ./todo-app");
|
|
241
|
+
console.log(" topogram copy ./local-template ./my-app");
|
|
242
|
+
console.log(" topogram copy @scope/topogram-template ./my-app");
|
|
243
|
+
console.log("");
|
|
244
|
+
console.log("Template entries create starter projects. Topogram entries copy editable topo/ source.");
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
/**
|
|
248
|
+
* @returns {void}
|
|
249
|
+
*/
|
|
250
|
+
export function printInitHelp() {
|
|
251
|
+
console.log("Usage: topogram init [path] [--with-sdlc] [--json]");
|
|
252
|
+
console.log("");
|
|
253
|
+
console.log("Initializes an empty Topogram workspace in an existing or new repository without copying a template.");
|
|
235
254
|
console.log("");
|
|
236
|
-
console.log("
|
|
255
|
+
console.log("Defaults: path is the current directory. Init creates topo/, topogram.project.json, and starter guidance files only when they are missing.");
|
|
256
|
+
console.log("The default output is maintained ownership for '.', so Topogram will not overwrite app source.");
|
|
257
|
+
console.log("--with-sdlc also writes topogram.sdlc-policy.json with adopted/enforced defaults.");
|
|
258
|
+
console.log("");
|
|
259
|
+
console.log("Examples:");
|
|
260
|
+
console.log(" topogram init");
|
|
261
|
+
console.log(" topogram init . --with-sdlc");
|
|
262
|
+
console.log(" topogram init . --json");
|
|
263
|
+
console.log(" topogram init ./existing-app");
|
|
237
264
|
}
|
|
238
265
|
|
|
239
266
|
/**
|
|
@@ -30,6 +30,15 @@ export function cliMigrationError(args) {
|
|
|
30
30
|
if (args[0] === "component") {
|
|
31
31
|
return "Command 'topogram component' was renamed to 'topogram widget'.";
|
|
32
32
|
}
|
|
33
|
+
if (args[0] === "new" || args[0] === "create") {
|
|
34
|
+
return "Command 'topogram new' was replaced by 'topogram copy <source> <target>'. For example: topogram copy hello-web ./my-app.";
|
|
35
|
+
}
|
|
36
|
+
if (args[0] === "import") {
|
|
37
|
+
return "Command 'topogram import' was replaced by 'topogram extract' and top-level 'topogram adopt'.";
|
|
38
|
+
}
|
|
39
|
+
if (args[0] === "catalog" && args[1] === "copy") {
|
|
40
|
+
return "Command 'topogram catalog copy' was replaced by 'topogram copy <source> <target>'.";
|
|
41
|
+
}
|
|
33
42
|
if (args[0] === "migrate") {
|
|
34
43
|
return "Command 'topogram migrate workspace-folder' was removed. Use topo/ workspaces or configure topogram.project.json workspace to a non-legacy relative path.";
|
|
35
44
|
}
|
package/src/cli/options.js
CHANGED
|
@@ -22,6 +22,21 @@ export function optionValueIfPresent(args, flag) {
|
|
|
22
22
|
return value && !value.startsWith("-") ? value : null;
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
+
/**
|
|
26
|
+
* @param {string[]} args
|
|
27
|
+
* @param {string} flag
|
|
28
|
+
* @returns {string[]}
|
|
29
|
+
*/
|
|
30
|
+
export function optionValues(args, flag) {
|
|
31
|
+
const values = [];
|
|
32
|
+
for (let index = 0; index < args.length; index += 1) {
|
|
33
|
+
if (args[index] === flag && args[index + 1] && !args[index + 1].startsWith("-")) {
|
|
34
|
+
values.push(args[index + 1]);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return values;
|
|
38
|
+
}
|
|
39
|
+
|
|
25
40
|
/**
|
|
26
41
|
* @param {string[]} args
|
|
27
42
|
* @param {string} flag
|
|
@@ -51,6 +66,8 @@ export function parseCliOptions(args, commandArgs) {
|
|
|
51
66
|
workflowName: commandArgs?.workflowName || (!generateTarget && workflowFlagValue ? workflowFlagValue : null),
|
|
52
67
|
workflowId: generateTarget ? workflowFlagValue : null,
|
|
53
68
|
fromValue: optionValue(args, "--from"),
|
|
69
|
+
extractorSpecs: optionValues(args, "--extractor"),
|
|
70
|
+
extractorPolicyPath: optionValueIfPresent(args, "--extractor-policy"),
|
|
54
71
|
adoptValue: commandArgs?.adoptValue || optionValue(args, "--adopt"),
|
|
55
72
|
reasonValue: optionValueIfPresent(args, "--reason"),
|
|
56
73
|
modeId: optionValue(args, "--mode"),
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
createExtractorSmokeContext,
|
|
5
|
+
loadExtractorPackageAdapterForSpec,
|
|
6
|
+
validateExtractorAdapter
|
|
7
|
+
} from "./packages.js";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* @typedef {import("./registry.js").ExtractorManifest} ExtractorManifest
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* @typedef {Object} ExtractorCheckResult
|
|
15
|
+
* @property {boolean} ok
|
|
16
|
+
* @property {string} sourceSpec
|
|
17
|
+
* @property {"path"|"package"} source
|
|
18
|
+
* @property {string|null} packageName
|
|
19
|
+
* @property {string|null} packageRoot
|
|
20
|
+
* @property {string|null} manifestPath
|
|
21
|
+
* @property {ExtractorManifest|null} manifest
|
|
22
|
+
* @property {Array<{ name: string, ok: boolean, message: string }>} checks
|
|
23
|
+
* @property {string[]} errors
|
|
24
|
+
* @property {{ extractors: number, findings: number, candidateKeys: number, diagnostics: number }|null} smoke
|
|
25
|
+
* @property {boolean} executesPackageCode
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* @param {any} result
|
|
30
|
+
* @returns {{ ok: boolean, message: string, smoke: { findings: number, candidateKeys: number, diagnostics: number }|null }}
|
|
31
|
+
*/
|
|
32
|
+
function validateExtractResult(result) {
|
|
33
|
+
if (!result || typeof result !== "object" || Array.isArray(result)) {
|
|
34
|
+
return { ok: false, message: "extract(context) must return an object", smoke: null };
|
|
35
|
+
}
|
|
36
|
+
if (result.findings != null && !Array.isArray(result.findings)) {
|
|
37
|
+
return { ok: false, message: "extract(context) findings must be an array when present", smoke: null };
|
|
38
|
+
}
|
|
39
|
+
if (result.diagnostics != null && !Array.isArray(result.diagnostics)) {
|
|
40
|
+
return { ok: false, message: "extract(context) diagnostics must be an array when present", smoke: null };
|
|
41
|
+
}
|
|
42
|
+
if (!result.candidates || typeof result.candidates !== "object" || Array.isArray(result.candidates)) {
|
|
43
|
+
return { ok: false, message: "extract(context) result must include a candidates object", smoke: null };
|
|
44
|
+
}
|
|
45
|
+
for (const [key, value] of Object.entries(result.candidates)) {
|
|
46
|
+
if (!Array.isArray(value)) {
|
|
47
|
+
return { ok: false, message: `extract(context) candidates.${key} must be an array`, smoke: null };
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
return {
|
|
51
|
+
ok: true,
|
|
52
|
+
message: `extract(context) returned ${Object.keys(result.candidates).length} candidate bucket(s)`,
|
|
53
|
+
smoke: {
|
|
54
|
+
findings: Array.isArray(result.findings) ? result.findings.length : 0,
|
|
55
|
+
candidateKeys: Object.keys(result.candidates).length,
|
|
56
|
+
diagnostics: Array.isArray(result.diagnostics) ? result.diagnostics.length : 0
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* @param {string} sourceSpec
|
|
63
|
+
* @param {{ cwd?: string }} [options]
|
|
64
|
+
* @returns {ExtractorCheckResult}
|
|
65
|
+
*/
|
|
66
|
+
export function checkExtractorPack(sourceSpec, options = {}) {
|
|
67
|
+
/** @type {ExtractorCheckResult} */
|
|
68
|
+
const payload = {
|
|
69
|
+
ok: false,
|
|
70
|
+
sourceSpec,
|
|
71
|
+
source: "package",
|
|
72
|
+
packageName: null,
|
|
73
|
+
packageRoot: null,
|
|
74
|
+
manifestPath: null,
|
|
75
|
+
manifest: null,
|
|
76
|
+
checks: [],
|
|
77
|
+
errors: [],
|
|
78
|
+
smoke: null,
|
|
79
|
+
executesPackageCode: true
|
|
80
|
+
};
|
|
81
|
+
if (!sourceSpec || sourceSpec.startsWith("-")) {
|
|
82
|
+
payload.errors.push("Usage: topogram extractor check <path-or-package>");
|
|
83
|
+
payload.checks.push({ name: "source", ok: false, message: payload.errors[0] });
|
|
84
|
+
return payload;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const loaded = loadExtractorPackageAdapterForSpec(sourceSpec, options);
|
|
88
|
+
payload.source = loaded.source;
|
|
89
|
+
payload.packageName = loaded.packageName;
|
|
90
|
+
payload.packageRoot = loaded.packageRoot;
|
|
91
|
+
payload.manifestPath = loaded.manifestPath;
|
|
92
|
+
payload.manifest = loaded.manifest;
|
|
93
|
+
if (!loaded.manifest) {
|
|
94
|
+
payload.errors.push(...loaded.errors);
|
|
95
|
+
payload.checks.push({ name: "manifest-load", ok: false, message: loaded.errors.join(" ") || "Could not load extractor manifest." });
|
|
96
|
+
return payload;
|
|
97
|
+
}
|
|
98
|
+
payload.checks.push({ name: "manifest-load", ok: true, message: loaded.manifestPath || sourceSpec });
|
|
99
|
+
if (!loaded.adapter || loaded.errors.length > 0) {
|
|
100
|
+
payload.errors.push(...loaded.errors);
|
|
101
|
+
payload.checks.push({ name: "adapter-load", ok: false, message: loaded.errors.join(" ") || "Could not load extractor adapter." });
|
|
102
|
+
return payload;
|
|
103
|
+
}
|
|
104
|
+
payload.checks.push({ name: "adapter-load", ok: true, message: "Adapter export loaded." });
|
|
105
|
+
|
|
106
|
+
const adapterValidation = validateExtractorAdapter(loaded.adapter, loaded.manifest);
|
|
107
|
+
payload.checks.push({
|
|
108
|
+
name: "adapter-shape",
|
|
109
|
+
ok: adapterValidation.errors.length === 0,
|
|
110
|
+
message: adapterValidation.errors.length === 0 ? "Adapter shape is valid." : adapterValidation.errors.join(" ")
|
|
111
|
+
});
|
|
112
|
+
if (adapterValidation.errors.length > 0) {
|
|
113
|
+
payload.errors.push(...adapterValidation.errors);
|
|
114
|
+
return payload;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
const context = createExtractorSmokeContext();
|
|
118
|
+
let totalFindings = 0;
|
|
119
|
+
let totalCandidateKeys = 0;
|
|
120
|
+
let totalDiagnostics = 0;
|
|
121
|
+
for (const extractor of adapterValidation.extractors) {
|
|
122
|
+
try {
|
|
123
|
+
const detection = extractor.detect(context) || { score: 0, reasons: [] };
|
|
124
|
+
if (!detection || typeof detection !== "object" || typeof detection.score !== "number") {
|
|
125
|
+
payload.errors.push(`Extractor '${extractor.id}' detect(context) must return { score, reasons }.`);
|
|
126
|
+
continue;
|
|
127
|
+
}
|
|
128
|
+
const result = extractor.extract(context) || { findings: [], candidates: {} };
|
|
129
|
+
const validation = validateExtractResult(result);
|
|
130
|
+
if (!validation.ok || !validation.smoke) {
|
|
131
|
+
payload.errors.push(`Extractor '${extractor.id}' ${validation.message}.`);
|
|
132
|
+
continue;
|
|
133
|
+
}
|
|
134
|
+
totalFindings += validation.smoke.findings;
|
|
135
|
+
totalCandidateKeys += validation.smoke.candidateKeys;
|
|
136
|
+
totalDiagnostics += validation.smoke.diagnostics;
|
|
137
|
+
} catch (error) {
|
|
138
|
+
payload.errors.push(`Extractor '${extractor.id}' smoke failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
payload.checks.push({
|
|
142
|
+
name: "smoke-extract",
|
|
143
|
+
ok: payload.errors.length === 0,
|
|
144
|
+
message: payload.errors.length === 0 ? `Ran ${adapterValidation.extractors.length} extractor smoke check(s).` : payload.errors.join(" ")
|
|
145
|
+
});
|
|
146
|
+
payload.smoke = {
|
|
147
|
+
extractors: adapterValidation.extractors.length,
|
|
148
|
+
findings: totalFindings,
|
|
149
|
+
candidateKeys: totalCandidateKeys,
|
|
150
|
+
diagnostics: totalDiagnostics
|
|
151
|
+
};
|
|
152
|
+
payload.ok = payload.errors.length === 0;
|
|
153
|
+
return payload;
|
|
154
|
+
}
|
|
155
|
+
|