@topogram/cli 0.3.78 → 0.3.79

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 (79) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/package.json +2 -2
  3. package/src/agent-brief.js +29 -23
  4. package/src/agent-ops/query-builders/change-risk/{import-plan.js → extract-plan.js} +1 -1
  5. package/src/agent-ops/query-builders/change-risk/review-packets.js +5 -5
  6. package/src/agent-ops/query-builders/change-risk.js +1 -1
  7. package/src/agent-ops/query-builders/common.js +2 -2
  8. package/src/agent-ops/query-builders/multi-agent.js +1 -1
  9. package/src/agent-ops/query-builders/workflow-context-shared.js +4 -4
  10. package/src/catalog/provenance.js +1 -1
  11. package/src/cli/catalog-alias.d.ts +2 -0
  12. package/src/cli/catalog-alias.js +2 -2
  13. package/src/cli/command-parsers/core.js +9 -5
  14. package/src/cli/command-parsers/import.js +11 -17
  15. package/src/cli/command-parsers/project.js +0 -3
  16. package/src/cli/commands/catalog/copy.js +3 -3
  17. package/src/cli/commands/catalog/help.js +1 -2
  18. package/src/cli/commands/catalog/list.js +7 -4
  19. package/src/cli/commands/catalog/show.js +4 -4
  20. package/src/cli/commands/copy.js +356 -0
  21. package/src/cli/commands/doctor.js +1 -1
  22. package/src/cli/commands/import/adopt.js +9 -9
  23. package/src/cli/commands/import/check.js +15 -15
  24. package/src/cli/commands/import/diff.js +6 -6
  25. package/src/cli/commands/import/help.js +43 -34
  26. package/src/cli/commands/import/paths.js +3 -3
  27. package/src/cli/commands/import/plan.js +8 -8
  28. package/src/cli/commands/import/refresh.js +25 -24
  29. package/src/cli/commands/import/status-history.js +4 -4
  30. package/src/cli/commands/import/workspace.js +16 -16
  31. package/src/cli/commands/import-runner.js +6 -5
  32. package/src/cli/commands/import.js +4 -1
  33. package/src/cli/commands/init.js +67 -0
  34. package/src/cli/commands/query/{import-adopt.js → extract-adopt.js} +2 -2
  35. package/src/cli/commands/query/runner/change.js +2 -2
  36. package/src/cli/commands/query/runner/{import-adopt.js → extract-adopt.js} +9 -9
  37. package/src/cli/commands/query/runner/index.js +1 -1
  38. package/src/cli/commands/query/runner/workflow.js +7 -7
  39. package/src/cli/commands/query/workspace.js +4 -4
  40. package/src/cli/commands/release-status.js +2 -2
  41. package/src/cli/commands/source.js +2 -2
  42. package/src/cli/commands/template/check.js +2 -2
  43. package/src/cli/commands/template/list-show.js +4 -4
  44. package/src/cli/dispatcher.js +18 -3
  45. package/src/cli/help-dispatch.js +22 -8
  46. package/src/cli/help.js +68 -52
  47. package/src/cli/migration-guidance.js +9 -0
  48. package/src/generator/context/bundle.js +14 -7
  49. package/src/generator/context/diff.js +8 -1
  50. package/src/generator/context/digest.js +10 -1
  51. package/src/generator/context/shared/domain-sdlc.js +5 -1
  52. package/src/generator/context/shared/relationships.js +20 -5
  53. package/src/generator/context/shared/summaries.js +26 -0
  54. package/src/generator/context/shared.d.ts +1 -0
  55. package/src/generator/context/shared.js +1 -0
  56. package/src/generator/context/slice/core.js +9 -5
  57. package/src/generator/context/slice/sdlc.js +31 -2
  58. package/src/generator/context/task-mode.js +3 -3
  59. package/src/import/core/runner/reports.js +4 -4
  60. package/src/import/provenance.js +16 -16
  61. package/src/init-project.js +215 -0
  62. package/src/new-project/constants.js +1 -1
  63. package/src/new-project/create.js +2 -2
  64. package/src/new-project/project-files.js +7 -7
  65. package/src/reconcile/journeys.js +8 -3
  66. package/src/record-blocks.js +125 -0
  67. package/src/resolver/index.js +3 -0
  68. package/src/resolver/journeys.js +74 -0
  69. package/src/resolver/normalize.js +25 -0
  70. package/src/sdlc/adopt.js +1 -1
  71. package/src/validator/common.js +34 -1
  72. package/src/validator/index.js +4 -0
  73. package/src/validator/kinds.d.ts +2 -0
  74. package/src/validator/kinds.js +34 -1
  75. package/src/validator/per-kind/journey.js +233 -0
  76. package/src/workflows/docs-generate.js +4 -1
  77. package/src/workflows/reconcile/bundle-core/index.js +4 -2
  78. package/src/workflows/reconcile/canonical-surface.js +4 -1
  79. package/src/cli/commands/new.js +0 -94
@@ -290,7 +290,7 @@ export function renderReleaseStatusMarkdown(payload) {
290
290
  "The external Todo demo is the canonical end-to-end consumer proof for the current catalog-backed workflow:",
291
291
  "",
292
292
  "```bash",
293
- "topogram new ./todo-demo --template todo",
293
+ "topogram copy todo ./todo-demo",
294
294
  "cd ./todo-demo",
295
295
  "npm install",
296
296
  "npm run check",
@@ -300,7 +300,7 @@ export function renderReleaseStatusMarkdown(payload) {
300
300
  "npm run app:runtime",
301
301
  "```",
302
302
  "",
303
- "The demo CI also verifies `topogram new` from the default public catalog and from the repo-local catalog fixture. That prevents local fixtures from masking a broken published catalog alias."
303
+ "The demo CI also verifies `topogram copy` from the default public catalog and from the repo-local catalog fixture. That prevents local fixtures from masking a broken published catalog alias."
304
304
  );
305
305
  const reportDiagnostics = [...matrix.diagnostics];
306
306
  if (reportDiagnostics.length > 0) {
@@ -239,7 +239,7 @@ export function printTopogramSourceStatus(payload) {
239
239
  }
240
240
  }
241
241
  console.log("");
242
- console.log(`${TOPOGRAM_SOURCE_FILE} records catalog-copy provenance only. Local edits are allowed.`);
242
+ console.log(`${TOPOGRAM_SOURCE_FILE} records copy provenance only. Local edits are allowed.`);
243
243
  console.log("Template attachment controls update tracking. Detaching makes the project fully owned by this workspace.");
244
244
  console.log("Template baseline drift does not block `topogram check` or `topogram generate`.");
245
245
  console.log("Implementation trust is separate and can block check/generate when review is required.");
@@ -250,7 +250,7 @@ export function printTopogramSourceStatus(payload) {
250
250
  } else if (payload.project?.templateBaseline?.state === "diverged") {
251
251
  console.log("Next: local template-derived changes are owned by this project. Run `topogram template update --check` only when reviewing upstream template changes.");
252
252
  } else if (!payload.exists) {
253
- console.log("Next: use `topogram catalog copy <id> <target>` for pure topogram provenance, or continue with template/project provenance above.");
253
+ console.log("Next: use `topogram copy <id> <target>` for pure topogram provenance, or continue with template/project provenance above.");
254
254
  } else {
255
255
  console.log("Next: run `topogram check` or `topogram generate`.");
256
256
  }
@@ -124,7 +124,7 @@ function diagnosticForTemplateCreateFailure(message, templateSpec, step) {
124
124
  code: "template_symlink_unsupported",
125
125
  message,
126
126
  path: path.isAbsolute(templateSpec) ? templateSpec : null,
127
- suggestedFix: "Replace template symlinks with real files or directories, then rerun `topogram new` or `topogram template check`.",
127
+ suggestedFix: "Replace template symlinks with real files or directories, then rerun `topogram copy` or `topogram template check`.",
128
128
  step
129
129
  });
130
130
  }
@@ -132,7 +132,7 @@ function diagnosticForTemplateCreateFailure(message, templateSpec, step) {
132
132
  code: "template_create_failed",
133
133
  message,
134
134
  path: path.isAbsolute(templateSpec) ? templateSpec : null,
135
- suggestedFix: "Fix the template pack so topogram new can create a starter from it.",
135
+ suggestedFix: "Fix the template pack so topogram copy can create a starter from it.",
136
136
  step
137
137
  });
138
138
  }
@@ -81,7 +81,7 @@ function templateListItemFromCatalogEntry(entry, source) {
81
81
  */
82
82
  export function printTemplateList(payload) {
83
83
  console.log("Template starters:");
84
- console.log("Catalog aliases resolve to versioned package installs. Local paths and full package specs can also be used with `topogram new`.");
84
+ console.log("Catalog aliases resolve to versioned package installs. Local paths and full package specs can also be used with `topogram copy`.");
85
85
  if (payload.catalog.source) {
86
86
  console.log(`Catalog: ${payload.catalog.source} (${payload.catalog.loaded ? "loaded" : "unavailable"})`);
87
87
  } else {
@@ -93,10 +93,10 @@ export function printTemplateList(payload) {
93
93
  const surfaces = Array.isArray(template.surfaces) && template.surfaces.length > 0
94
94
  ? template.surfaces.join(", ")
95
95
  : "not declared";
96
- const command = template.recommendedCommand || `topogram new ./my-app --template ${shellCommandArg(template.id)}`;
96
+ const command = template.recommendedCommand || `topogram copy ${shellCommandArg(template.id)} ./my-app`;
97
97
  console.log(`- ${template.id}@${template.version}${defaultLabel}`);
98
98
  console.log(` Source: ${template.source} | Surfaces: ${surfaces} | Stack: ${stack} | Executable implementation: ${template.includesExecutableImplementation ? "yes" : "no"}`);
99
- console.log(` New: ${command}`);
99
+ console.log(` Copy: ${command}`);
100
100
  }
101
101
  for (const diagnostic of payload.diagnostics) {
102
102
  console.warn(`Warning: ${diagnostic.message}`);
@@ -137,7 +137,7 @@ function templateDecisionSummary(template, sourceKind, packageSpec, commands) {
137
137
  version: template.defaultVersion || template.version || null,
138
138
  executableImplementation: executable,
139
139
  policyImpact: executable
140
- ? "Copies implementation/ code into the project; topogram new does not execute it, but topogram generate may load it after local trust is recorded."
140
+ ? "Copies implementation/ code into the project; topogram copy does not execute it, but topogram generate may load it after local trust is recorded."
141
141
  : "No executable implementation trust is required for this template.",
142
142
  recommendedCommand: commands.primary,
143
143
  followUp: commands.followUp,
@@ -5,12 +5,13 @@ import { buildVersionPayload, printVersion } from "./commands/version.js";
5
5
  import { runAgentBriefCommand } from "./commands/agent.js";
6
6
  import { runCatalogCommand } from "./commands/catalog.js";
7
7
  import { runCheckCommand } from "./commands/check.js";
8
+ import { runCopyCommand } from "./commands/copy.js";
8
9
  import { runEmitCommand } from "./commands/emit.js";
9
10
  import { runGenerateAppCommand } from "./commands/generate.js";
10
11
  import { runGeneratorCommand } from "./commands/generator.js";
11
12
  import { runGeneratorPolicyCommand } from "./commands/generator-policy.js";
12
13
  import { runImportCommand } from "./commands/import-runner.js";
13
- import { runNewProjectCommand } from "./commands/new.js";
14
+ import { runInitProjectCommand } from "./commands/init.js";
14
15
  import { runPackageCommand } from "./commands/package.js";
15
16
  import { runParseCommand, runResolveCommand } from "./commands/inspect.js";
16
17
  import {
@@ -238,6 +239,16 @@ export async function runCliDispatch(context) {
238
239
  });
239
240
  }
240
241
 
242
+ if (commandArgs?.copyCommand) {
243
+ return runCopyCommand({
244
+ commandArgs,
245
+ catalogSource,
246
+ requestedVersion,
247
+ json: emitJson,
248
+ cwd: process.cwd()
249
+ });
250
+ }
251
+
241
252
  if (commandArgs?.packageCommand) {
242
253
  return runPackageCommand({ commandArgs, inputPath, json: emitJson });
243
254
  }
@@ -261,8 +272,12 @@ export async function runCliDispatch(context) {
261
272
  return runSourceCommand({ commandArgs, inputPath, args, json: emitJson });
262
273
  }
263
274
 
264
- if (commandArgs?.newProject) {
265
- return runNewProjectCommand(effectiveInputPath, { templateName, catalogSource, cwd: process.cwd() });
275
+ if (commandArgs?.initProject) {
276
+ return runInitProjectCommand(effectiveInputPath || ".", {
277
+ json: emitJson,
278
+ cwd: process.cwd(),
279
+ withSdlc: args.includes("--with-sdlc")
280
+ });
266
281
  }
267
282
 
268
283
  if (commandArgs?.templateCommand) {
@@ -16,7 +16,8 @@ import {
16
16
  printGeneratorHelp
17
17
  } from "./commands/generator.js";
18
18
  import {
19
- printImportHelp
19
+ printAdoptHelp,
20
+ printExtractHelp
20
21
  } from "./commands/import.js";
21
22
  import {
22
23
  printPackageHelp
@@ -42,7 +43,8 @@ import {
42
43
  import {
43
44
  printEmitHelp,
44
45
  printGenerateHelp,
45
- printNewHelp,
46
+ printInitHelp,
47
+ printCopyHelp,
46
48
  printUsage,
47
49
  printWidgetHelp
48
50
  } from "./help.js";
@@ -52,8 +54,12 @@ import {
52
54
  * @returns {boolean}
53
55
  */
54
56
  export function printCommandHelp(command) {
55
- if (command === "new" || command === "create") {
56
- printNewHelp();
57
+ if (command === "copy") {
58
+ printCopyHelp();
59
+ return true;
60
+ }
61
+ if (command === "init") {
62
+ printInitHelp();
57
63
  return true;
58
64
  }
59
65
  if (command === "generate") {
@@ -112,8 +118,12 @@ export function printCommandHelp(command) {
112
118
  printTrustHelp();
113
119
  return true;
114
120
  }
115
- if (command === "import") {
116
- printImportHelp();
121
+ if (command === "extract") {
122
+ printExtractHelp();
123
+ return true;
124
+ }
125
+ if (command === "adopt") {
126
+ printAdoptHelp();
117
127
  return true;
118
128
  }
119
129
  if (command === "check") {
@@ -170,8 +180,12 @@ export function handleUnparsedCommandHelp(args) {
170
180
  printTemplateHelp();
171
181
  return args[1] ? 1 : 0;
172
182
  }
173
- if (args[0] === "import") {
174
- printImportHelp();
183
+ if (args[0] === "extract") {
184
+ printExtractHelp();
185
+ return args[1] ? 1 : 0;
186
+ }
187
+ if (args[0] === "adopt") {
188
+ printAdoptHelp();
175
189
  return args[1] ? 1 : 0;
176
190
  }
177
191
  if (args[0] === "query") {
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 import <app-path> --out <target> [--from <track[,track]>] [--json]");
41
- console.log(" or: topogram import refresh [path] [--from <app-path>] [--dry-run] [--json]");
42
- console.log(" or: topogram import diff [path] [--json]");
43
- console.log(" or: topogram import check [path] [--json]");
44
- console.log(" or: topogram import plan [path] [--json]");
45
- console.log(" or: topogram import adopt --list [path] [--json]");
46
- console.log(" or: topogram import adopt <selector> [path] [--dry-run|--write] [--force --reason <text>] [--json]");
47
- console.log(" or: topogram import status [path] [--json]");
48
- console.log(" or: topogram import history [path] [--verify] [--json]");
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]>] [--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,7 @@ 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 new <path> [--template hello-web|todo|./local-template|@scope/template]");
70
- console.log(" or: topogram new <path> --template <package> --allow-local-npmrc");
71
- console.log(" or: topogram new --list-templates [--json] [--catalog <path-or-source>]");
70
+ console.log(" or: topogram init [path] [--with-sdlc] [--json]");
72
71
  console.log("");
73
72
  console.log("Common commands:");
74
73
  console.log(" topogram version");
@@ -76,9 +75,10 @@ export function printUsage(options = {}) {
76
75
  console.log(" topogram setup package-auth");
77
76
  console.log(" topogram release status");
78
77
  console.log(" topogram release roll-consumers --latest");
79
- console.log(" topogram new ./my-app");
80
- console.log(" topogram new --list-templates");
81
- console.log(" topogram new ./my-app --template todo");
78
+ console.log(" topogram init .");
79
+ console.log(" topogram copy --list");
80
+ console.log(" topogram copy hello-web ./my-app");
81
+ console.log(" topogram copy todo ./todo-app");
82
82
  console.log(" topogram check");
83
83
  console.log(" topogram check --json");
84
84
  console.log(" topogram widget check --projection proj_web_surface");
@@ -99,21 +99,22 @@ export function printUsage(options = {}) {
99
99
  console.log(" topogram generator check ./generator-package");
100
100
  console.log(" topogram generator policy check");
101
101
  console.log(" topogram generate");
102
- console.log(" topogram import ./existing-app --out ./imported-topogram");
103
- console.log(" topogram import diff ./imported-topogram");
104
- console.log(" topogram import refresh ./imported-topogram --from ./existing-app --dry-run");
105
- console.log(" topogram import check ./imported-topogram");
106
- console.log(" topogram import plan ./imported-topogram");
107
- console.log(" topogram import adopt --list ./imported-topogram");
108
- console.log(" topogram import adopt bundle:task ./imported-topogram --dry-run");
109
- console.log(" topogram import status ./imported-topogram");
110
- console.log(" topogram import history ./imported-topogram --verify");
102
+ console.log(" topogram extract ./existing-app --out ./extracted-topogram");
103
+ console.log(" topogram extract diff ./extracted-topogram");
104
+ console.log(" topogram extract refresh ./extracted-topogram --from ./existing-app --dry-run");
105
+ console.log(" topogram extract check ./extracted-topogram");
106
+ console.log(" topogram extract plan ./extracted-topogram");
107
+ console.log(" topogram adopt --list ./extracted-topogram");
108
+ console.log(" topogram adopt bundle:task ./extracted-topogram --dry-run");
109
+ console.log(" topogram extract status ./extracted-topogram");
110
+ console.log(" topogram extract history ./extracted-topogram --verify");
111
111
  console.log("");
112
112
  console.log("Fresh install:");
113
113
  console.log(" npm install --save-dev @topogram/cli");
114
114
  console.log(" npx topogram doctor");
115
115
  console.log(" npx topogram template list");
116
- console.log(" npx topogram new ./my-app --template hello-web");
116
+ console.log(" npx topogram init .");
117
+ console.log(" npx topogram copy hello-web ./my-app");
117
118
  console.log(" cd ./my-app && npm install && npm run check && npm run generate");
118
119
  console.log(" npm --prefix app run compile");
119
120
  console.log("");
@@ -123,7 +124,7 @@ export function printUsage(options = {}) {
123
124
  console.log(" topogram catalog show todo");
124
125
  console.log(" topogram catalog doctor");
125
126
  console.log(" topogram catalog check topograms.catalog.json");
126
- console.log(" topogram catalog copy hello ./hello-topogram");
127
+ console.log(" topogram copy hello ./hello-topogram");
127
128
  console.log(" topogram source status --local");
128
129
  console.log(" topogram source status --remote");
129
130
  console.log("");
@@ -149,7 +150,7 @@ export function printUsage(options = {}) {
149
150
  console.log(" topogram template update --apply");
150
151
  console.log("");
151
152
  console.log("Defaults: check/generate use ./topo, and generate writes ./app.");
152
- console.log("Default starter: hello-web from the catalog. Run `topogram template list` for catalog aliases.");
153
+ console.log("Default starter: hello-web from the catalog. Run `topogram copy --list` for catalog aliases.");
153
154
  console.log("Generated app commands are emitted into the output package.json.");
154
155
  console.log("Run `topogram help <command>` for command-specific help.");
155
156
  console.log("Run `topogram help all` for legacy and agent-facing commands.");
@@ -157,16 +158,12 @@ export function printUsage(options = {}) {
157
158
  return;
158
159
  }
159
160
  console.log("");
160
- console.log("Legacy and internal commands:");
161
- console.log("Usage: topogram create <path> [--template hello-web|todo|./local-template|@scope/template]");
161
+ console.log("Internal commands:");
162
162
  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
163
  console.log(" or: topogram validate <path>");
165
- console.log(" or: node ./src/cli.js query work-packet <path> --mode import-adopt --lane <id>");
164
+ console.log(" or: node ./src/cli.js query work-packet <path> --mode extract-adopt --lane <id>");
166
165
  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
166
  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
167
  console.log(" or: node ./src/cli.js generate journeys <path> [--write]");
171
168
  console.log(" or: node ./src/cli.js report gaps <path> [--write]");
172
169
  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 +181,75 @@ export function printUsage(options = {}) {
184
181
  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
182
  console.log(" or: node ./src/cli.js query widget-behavior <path> [--projection <id>] [--widget <id>] [--json]");
186
183
  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 import-plan <path>");
184
+ console.log(" or: node ./src/cli.js query extract-plan <path>");
188
185
  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
186
  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
187
  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
188
  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
189
  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
190
  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 import-adopt");
191
+ console.log(" or: node ./src/cli.js query multi-agent-plan <path> --mode extract-adopt");
195
192
  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
193
  console.log(" or: node ./src/cli.js query workflow-preset-activation <path> --mode <id> [--provider <id>] [--preset <id>] [--from-topogram <path>]");
197
194
  console.log(" or: node ./src/cli.js query workflow-preset-diff <path> --provider <id> [--preset <id>]");
198
195
  console.log(" or: node ./src/cli.js query workflow-preset-customization <path> --provider <id> --preset <id>");
199
196
  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 import-adopt");
201
- console.log(" or: node ./src/cli.js query handoff-status <path> --mode import-adopt");
197
+ console.log(" or: node ./src/cli.js query lane-status <path> --mode extract-adopt");
198
+ console.log(" or: node ./src/cli.js query handoff-status <path> --mode extract-adopt");
202
199
  console.log(" or: node ./src/cli.js query auth-hints <path>");
203
200
  console.log(" or: node ./src/cli.js query auth-review-packet <path> --bundle <slug>");
204
201
  console.log(" or: node ./src/cli.js reconcile <path> [--write]");
205
202
  console.log(" or: node ./src/cli.js reconcile adopt <selector> <path> [--refresh-adopted] [--write]");
206
203
  console.log(" or: node ./src/cli.js adoption status <path> [--write]");
207
204
  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: import-app, scan-docs, reconcile, adoption-status, generate-docs, generate-journeys, refresh-docs, report-gaps");
209
- console.log("Import tracks: db, api, ui, workflows, verification");
205
+ console.log("Workflows: scan-docs, reconcile, adoption-status, generate-docs, generate-journeys, refresh-docs, report-gaps");
206
+ console.log("Extract tracks: db, api, ui, cli, workflows, verification");
210
207
  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
208
  }
212
209
 
213
210
  /**
214
211
  * @returns {void}
215
212
  */
216
- export function printNewHelp() {
217
- console.log("Usage: topogram new <path> [--template <alias|package|path>] [--catalog <path-or-source>]");
218
- console.log(" or: topogram new --list-templates [--json] [--catalog <path-or-source>]");
213
+ export function printCopyHelp() {
214
+ console.log("Usage: topogram copy <source> <target> [--version <version>] [--catalog <path-or-source>] [--json]");
215
+ console.log(" or: topogram copy --list [--json] [--catalog <path-or-source>]");
219
216
  console.log("");
220
- console.log("Creates a new editable Topogram workspace from a template package or local template path.");
217
+ console.log("Copies a catalog template, template package/path, or pure Topogram source into a new project directory.");
221
218
  console.log("");
222
219
  console.log("Fresh install flow:");
223
220
  console.log(" npm install --save-dev @topogram/cli");
224
- console.log(" npx topogram template list");
225
- console.log(" npx topogram new ./my-app --template hello-web");
221
+ console.log(" npx topogram copy --list");
222
+ console.log(" npx topogram copy hello-web ./my-app");
226
223
  console.log(" cd ./my-app && npm install && npm run check && npm run generate");
227
224
  console.log(" npm --prefix app run compile");
228
225
  console.log("");
229
226
  console.log("Examples:");
230
- console.log(" topogram new ./my-app");
231
- console.log(" topogram new --list-templates");
232
- console.log(" topogram new ./my-app --template hello-web");
233
- console.log(" topogram new ./my-app --template ./local-template");
234
- console.log(" topogram new ./my-app --template @scope/topogram-template");
227
+ console.log(" topogram copy --list");
228
+ console.log(" topogram copy hello-web ./my-app");
229
+ console.log(" topogram copy todo ./todo-app");
230
+ console.log(" topogram copy ./local-template ./my-app");
231
+ console.log(" topogram copy @scope/topogram-template ./my-app");
232
+ console.log("");
233
+ console.log("Template entries create starter projects. Topogram entries copy editable topo/ source.");
234
+ }
235
+
236
+ /**
237
+ * @returns {void}
238
+ */
239
+ export function printInitHelp() {
240
+ console.log("Usage: topogram init [path] [--with-sdlc] [--json]");
241
+ console.log("");
242
+ console.log("Initializes an empty Topogram workspace in an existing or new repository without copying a template.");
235
243
  console.log("");
236
- console.log("Default template: hello-web from the configured catalog.");
244
+ console.log("Defaults: path is the current directory. Init creates topo/, topogram.project.json, and starter guidance files only when they are missing.");
245
+ console.log("The default output is maintained ownership for '.', so Topogram will not overwrite app source.");
246
+ console.log("--with-sdlc also writes topogram.sdlc-policy.json with adopted/enforced defaults.");
247
+ console.log("");
248
+ console.log("Examples:");
249
+ console.log(" topogram init");
250
+ console.log(" topogram init . --with-sdlc");
251
+ console.log(" topogram init . --json");
252
+ console.log(" topogram init ./existing-app");
237
253
  }
238
254
 
239
255
  /**
@@ -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
  }
@@ -12,6 +12,7 @@ import {
12
12
  stableSortedStrings,
13
13
  summarizeById,
14
14
  summarizeDocsByIds,
15
+ summarizeJourneyLikeByIds,
15
16
  summarizeStatementsByIds,
16
17
  verificationIdsForTarget
17
18
  } from "./shared.js";
@@ -89,9 +90,12 @@ function uiBundle(graph) {
89
90
  .map((doc) => doc.id)
90
91
  );
91
92
  const journeys = stableSortedStrings(
92
- (graph.docs || [])
93
- .filter((doc) => doc.kind === "journey" && (doc.relatedProjections || []).some((id) => projections.includes(id)))
94
- .map((doc) => doc.id)
93
+ [
94
+ ...(graph.byKind.journey || []),
95
+ ...(graph.docs || []).filter((doc) => doc.kind === "journey")
96
+ ]
97
+ .filter((journey) => (journey.relatedProjections || []).some((id) => projections.includes(id)))
98
+ .map((journey) => journey.id)
95
99
  );
96
100
  const rules = stableSortedStrings(capabilities.flatMap((capabilityId) => {
97
101
  return (graph.byKind.rule || [])
@@ -112,7 +116,7 @@ function uiBundle(graph) {
112
116
  projections: summarizeStatementsByIds(graph, projections),
113
117
  capabilities: summarizeStatementsByIds(graph, capabilities),
114
118
  workflows: summarizeDocsByIds(graph, workflows),
115
- journeys: summarizeDocsByIds(graph, journeys),
119
+ journeys: summarizeJourneyLikeByIds(graph, journeys),
116
120
  rules: summarizeStatementsByIds(graph, rules)
117
121
  },
118
122
  dependencies: {
@@ -131,7 +135,7 @@ function uiBundle(graph) {
131
135
  review_boundaries: {
132
136
  projections: projections.map((id) => ({ id, review_boundary: summarizeById(graph, id)?.reviewBoundary || null })),
133
137
  workflows: workflows.map((id) => ({ id, review_boundary: reviewBoundaryForWorkflowDoc((graph.docs || []).find((doc) => doc.id === id)) })),
134
- journeys: journeys.map((id) => ({ id, review_boundary: reviewBoundaryForJourneyDoc((graph.docs || []).find((doc) => doc.id === id)) }))
138
+ journeys: journeys.map((id) => ({ id, review_boundary: reviewBoundaryForJourneyDoc(summarizeById(graph, id) || null) }))
135
139
  }
136
140
  };
137
141
  }
@@ -186,7 +190,10 @@ function dbBundle(graph) {
186
190
  function maintainedAppBundle(graph) {
187
191
  const proofStories = maintainedProofMetadata(graph);
188
192
  const projections = stableSortedStrings((graph.byKind.projection || []).map((item) => item.id));
189
- const journeys = stableSortedStrings((graph.docs || []).filter((doc) => doc.kind === "journey").map((doc) => doc.id));
193
+ const journeys = stableSortedStrings([
194
+ ...(graph.byKind.journey || []).map((item) => item.id),
195
+ ...(graph.docs || []).filter((doc) => doc.kind === "journey").map((doc) => doc.id)
196
+ ]);
190
197
  const verifications = stableSortedStrings((graph.byKind.verification || []).map((item) => item.id));
191
198
  const maintainedFiles = stableSortedStrings(proofStories.flatMap((item) => item.maintainedFiles || []));
192
199
  const emittedDependencies = stableSortedStrings(proofStories.flatMap((item) => item.emittedDependencies || []));
@@ -215,7 +222,7 @@ function maintainedAppBundle(graph) {
215
222
  },
216
223
  included_surfaces: {
217
224
  projections: summarizeStatementsByIds(graph, projections),
218
- journeys: summarizeDocsByIds(graph, journeys),
225
+ journeys: summarizeJourneyLikeByIds(graph, journeys),
219
226
  maintained_files_in_scope: maintainedFiles,
220
227
  emitted_artifact_dependencies: emittedDependencies,
221
228
  human_owned_seams: humanOwnedSeams,
@@ -16,10 +16,17 @@ import {
16
16
  import { defaultOwnershipBoundary } from "../../policy/review-boundaries.js";
17
17
 
18
18
  function normalizeTargetMap(graph, kind) {
19
- if (kind === "workflow" || kind === "journey") {
19
+ if (kind === "workflow") {
20
20
  const docs = (graph.docs || []).filter((doc) => doc.kind === kind);
21
21
  return new Map(docs.map((doc) => [doc.id, summarizeDoc(doc)]));
22
22
  }
23
+ if (kind === "journey") {
24
+ const journeys = [
25
+ ...(graph.byKind?.journey || []).map((statement) => summarizeStatement(statement)),
26
+ ...(graph.docs || []).filter((doc) => doc.kind === kind).map((doc) => summarizeDoc(doc))
27
+ ];
28
+ return new Map(journeys.map((journey) => [journey.id, journey]));
29
+ }
23
30
 
24
31
  return new Map(((graph.byKind[kind] || []).map((statement) => [statement.id, summarizeStatement(statement)])));
25
32
  }
@@ -138,6 +138,11 @@ function journeyDigest(graph, journey) {
138
138
  id: journey.id
139
139
  },
140
140
  summary: summarizeById(graph, journey.id),
141
+ steps: (journey.steps || []).map((step) => ({
142
+ id: step.id,
143
+ intent: step.intent || null,
144
+ after: [...(step.after || [])]
145
+ })),
141
146
  verifications: verificationIdsForTarget(graph, [journey.id, ...(journey.relatedCapabilities || [])]),
142
147
  review_boundary: reviewBoundaryForJourneyDoc(journey),
143
148
  ownership_boundary: defaultOwnershipBoundary()
@@ -174,7 +179,11 @@ export function generateContextDigest(graph) {
174
179
  files[`projections/${projection.id}.context-digest.json`] = projectionDigest(graph, projection);
175
180
  }
176
181
 
177
- for (const journey of (graph.docs || []).filter((doc) => doc.kind === "journey").sort((a, b) => a.id.localeCompare(b.id))) {
182
+ const journeys = [
183
+ ...(graph.byKind.journey || []),
184
+ ...(graph.docs || []).filter((doc) => doc.kind === "journey")
185
+ ].sort((a, b) => a.id.localeCompare(b.id));
186
+ for (const journey of journeys) {
178
187
  files[`journeys/${journey.id}.context-digest.json`] = journeyDigest(graph, journey);
179
188
  }
180
189
 
@@ -287,9 +287,13 @@ export function getWorkflowDoc(graph, workflowId) {
287
287
  * @returns {any}
288
288
  */
289
289
  export function getJourneyDoc(graph, journeyId) {
290
+ const journey = (graph.byKind?.journey || []).find(/** @param {any} item */ (item) => item.id === journeyId);
291
+ if (journey) {
292
+ return journey;
293
+ }
290
294
  const doc = (graph.docs || []).find(/** @param {any} item */ (item) => item.kind === "journey" && item.id === journeyId);
291
295
  if (!doc) {
292
- throw new Error(`No journey doc found with id '${journeyId}'`);
296
+ throw new Error(`No journey found with id '${journeyId}'`);
293
297
  }
294
298
  return doc;
295
299
  }
@@ -45,10 +45,13 @@ export function verificationsFor(graph, predicate) {
45
45
  * @returns {any}
46
46
  */
47
47
  export function relatedJourneysForCapability(graph, capabilityId) {
48
- return relatedDocs(
49
- graph,
50
- /** @param {import("./types.d.ts").ContextDoc} doc */ (doc) => doc.kind === "journey" && (doc.relatedCapabilities || []).includes(capabilityId)
51
- );
48
+ return [
49
+ ...(graph.byKind?.journey || []).filter(/** @param {any} journey */ (journey) => (journey.relatedCapabilities || []).includes(capabilityId)),
50
+ ...relatedDocs(
51
+ graph,
52
+ /** @param {import("./types.d.ts").ContextDoc} doc */ (doc) => doc.kind === "journey" && (doc.relatedCapabilities || []).includes(capabilityId)
53
+ )
54
+ ];
52
55
  }
53
56
 
54
57
  /**
@@ -395,6 +398,15 @@ export function summarizeDocsByIds(graph, ids) {
395
398
  .map(summarizeDoc);
396
399
  }
397
400
 
401
+ /**
402
+ * @param {import("./types.d.ts").ContextGraph} graph
403
+ * @param {Iterable<string>} ids
404
+ * @returns {any}
405
+ */
406
+ export function summarizeJourneyLikeByIds(graph, ids) {
407
+ return stableSortedStrings(ids).map(/** @param {string} id */ (id) => summarizeById(graph, id)).filter(Boolean);
408
+ }
409
+
398
410
  /**
399
411
  * @param {import("./types.d.ts").ContextGraph} graph
400
412
  * @returns {any}
@@ -403,7 +415,10 @@ export function workspaceInventory(graph) {
403
415
  return {
404
416
  capabilities: stableSortedStrings((graph.byKind.capability || []).map(/** @param {any} item */ (item) => item.id)),
405
417
  workflows: stableSortedStrings((graph.docs || []).filter(/** @param {import("./types.d.ts").ContextDoc} doc */ (doc) => doc.kind === "workflow").map(/** @param {import("./types.d.ts").ContextDoc} doc */ (doc) => doc.id)),
406
- journeys: stableSortedStrings((graph.docs || []).filter(/** @param {import("./types.d.ts").ContextDoc} doc */ (doc) => doc.kind === "journey").map(/** @param {import("./types.d.ts").ContextDoc} doc */ (doc) => doc.id)),
418
+ journeys: stableSortedStrings([
419
+ ...(graph.byKind.journey || []).map(/** @param {any} item */ (item) => item.id),
420
+ ...(graph.docs || []).filter(/** @param {import("./types.d.ts").ContextDoc} doc */ (doc) => doc.kind === "journey").map(/** @param {import("./types.d.ts").ContextDoc} doc */ (doc) => doc.id)
421
+ ]),
407
422
  entities: stableSortedStrings((graph.byKind.entity || []).map(/** @param {any} item */ (item) => item.id)),
408
423
  projections: stableSortedStrings((graph.byKind.projection || []).map(/** @param {any} item */ (item) => item.id)),
409
424
  widgets: stableSortedStrings((graph.byKind.widget || []).map(/** @param {any} item */ (item) => item.id)),