@ductape/cli 0.2.23 → 0.3.1

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 (104) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/README.md +7 -0
  3. package/dist/commands/db-migrate.js +47 -8
  4. package/dist/commands/migrate-codebase.d.ts +190 -0
  5. package/dist/commands/migrate-codebase.js +776 -0
  6. package/dist/commands/migration-artifact.d.ts +28 -0
  7. package/dist/commands/migration-artifact.js +101 -0
  8. package/dist/commands/migration-assurance.d.ts +10 -0
  9. package/dist/commands/migration-assurance.js +120 -0
  10. package/dist/commands/migration-capabilities.d.ts +53 -0
  11. package/dist/commands/migration-capabilities.js +66 -0
  12. package/dist/commands/migration-database.d.ts +26 -0
  13. package/dist/commands/migration-database.js +162 -0
  14. package/dist/commands/migration-e2e.d.ts +68 -0
  15. package/dist/commands/migration-e2e.js +189 -0
  16. package/dist/commands/migration-environments.d.ts +20 -0
  17. package/dist/commands/migration-environments.js +58 -0
  18. package/dist/commands/migration-generated.d.ts +68 -0
  19. package/dist/commands/migration-generated.js +217 -0
  20. package/dist/commands/migration-portfolio.d.ts +88 -0
  21. package/dist/commands/migration-portfolio.js +223 -0
  22. package/dist/commands/migration-products.d.ts +23 -0
  23. package/dist/commands/migration-products.js +88 -0
  24. package/dist/commands/migration-review.d.ts +248 -0
  25. package/dist/commands/migration-review.js +624 -0
  26. package/dist/commands/migration-secrets.d.ts +24 -0
  27. package/dist/commands/migration-secrets.js +93 -0
  28. package/dist/commands/migration-slice.d.ts +132 -0
  29. package/dist/commands/migration-slice.js +266 -0
  30. package/dist/commands/migration-verification.d.ts +12 -0
  31. package/dist/commands/migration-verification.js +194 -0
  32. package/dist/commands/products.d.ts +1 -0
  33. package/dist/commands/products.js +33 -1
  34. package/dist/commands/secrets.d.ts +8 -0
  35. package/dist/commands/secrets.js +44 -0
  36. package/dist/index.js +376 -4
  37. package/dist/lib/migration-artifact.d.ts +19 -0
  38. package/dist/lib/migration-artifact.js +114 -0
  39. package/package.json +8 -1
  40. package/API_PARITY.md +0 -58
  41. package/DB_MIGRATE_PLAN.md +0 -223
  42. package/ductape.example.ts +0 -18
  43. package/src/commands/apply.ts +0 -153
  44. package/src/commands/apps-import.ts +0 -43
  45. package/src/commands/apps.ts +0 -92
  46. package/src/commands/cloud.ts +0 -68
  47. package/src/commands/completion.ts +0 -119
  48. package/src/commands/db-migrate.ts +0 -209
  49. package/src/commands/db-schema.ts +0 -429
  50. package/src/commands/db.ts +0 -63
  51. package/src/commands/generate.ts +0 -74
  52. package/src/commands/graph.ts +0 -51
  53. package/src/commands/init.ts +0 -39
  54. package/src/commands/install.ts +0 -76
  55. package/src/commands/link.ts +0 -84
  56. package/src/commands/login.ts +0 -145
  57. package/src/commands/logout.ts +0 -7
  58. package/src/commands/platform.ts +0 -123
  59. package/src/commands/products.ts +0 -228
  60. package/src/commands/profiles.ts +0 -23
  61. package/src/commands/resources.ts +0 -213
  62. package/src/commands/secrets.ts +0 -46
  63. package/src/commands/unlink.ts +0 -15
  64. package/src/commands/whoami.ts +0 -27
  65. package/src/commands/workspaces.ts +0 -98
  66. package/src/index.ts +0 -523
  67. package/src/lib/api-client.ts +0 -88
  68. package/src/lib/app-import.ts +0 -82
  69. package/src/lib/apply-loaders.ts +0 -30
  70. package/src/lib/config.ts +0 -230
  71. package/src/lib/context-store.ts +0 -77
  72. package/src/lib/db-methods.ts +0 -56
  73. package/src/lib/db-types.ts +0 -104
  74. package/src/lib/encryption.ts +0 -12
  75. package/src/lib/forms/enums.ts +0 -52
  76. package/src/lib/forms/index.ts +0 -8
  77. package/src/lib/forms/prompt.ts +0 -209
  78. package/src/lib/forms/schemas.ts +0 -288
  79. package/src/lib/forms/types.ts +0 -27
  80. package/src/lib/http.ts +0 -76
  81. package/src/lib/integrations.ts +0 -110
  82. package/src/lib/interactive-opts.ts +0 -13
  83. package/src/lib/migration-files.ts +0 -58
  84. package/src/lib/output.ts +0 -39
  85. package/src/lib/platform-api.ts +0 -209
  86. package/src/lib/proxy/context.ts +0 -94
  87. package/src/lib/proxy/db-proxy.ts +0 -40
  88. package/src/lib/proxy/graph-proxy.ts +0 -64
  89. package/src/lib/proxy/sdk-proxy.ts +0 -58
  90. package/src/lib/read-body.ts +0 -57
  91. package/src/lib/resources.ts +0 -160
  92. package/src/lib/schema-loader.ts +0 -152
  93. package/src/lib/snippets.ts +0 -165
  94. package/src/lib/templates.ts +0 -157
  95. package/src/lib/workspace-context.ts +0 -43
  96. package/src/lib/workspaces.ts +0 -283
  97. package/test/apply-loaders.test.ts +0 -40
  98. package/test/encryption.test.ts +0 -20
  99. package/test/forms.test.ts +0 -25
  100. package/test/http.test.ts +0 -15
  101. package/test/platform-api.test.ts +0 -42
  102. package/test/resources.test.ts +0 -23
  103. package/test/workspace-resolve.test.ts +0 -29
  104. package/tsconfig.json +0 -15
package/CHANGELOG.md CHANGED
@@ -1,5 +1,12 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.3.0 - 2026-07-26
4
+
5
+ - Added AI-led migration planning with new-codebase defaults and immutable original E2E gates.
6
+ - Added review ledgers, parity slices, multi-repository verification, SCC partition proposals, and semantic database evidence.
7
+ - Added frontend, session, resilience, component, runtime, SDK, generated/vendor, and third-party assurance matrices.
8
+ - Added verified product-environment create/update commands, secured artifacts, Ed25519 signatures, and parallel-review merging.
9
+
3
10
  ## Unreleased
4
11
 
5
12
  ### Added
package/README.md CHANGED
@@ -1,5 +1,12 @@
1
1
  # @ductape/cli
2
2
 
3
+ ## AI-led codebase migration
4
+
5
+ Create and pass project-level E2E tests against the original codebase first, then bind them with
6
+ `ductape migration-e2e init`. Run `ductape migrate-codebase --e2e-baseline <manifest>`; the default is a
7
+ separate new codebase. Migration commands record advisory or verification evidence and never generate
8
+ application source. Finish with the unchanged original suite through `migration-e2e final`.
9
+
3
10
  Terminal interface for Ductape — **same transport as the Workbench** (encrypted sdk-proxy / db-proxy / graph-proxy).
4
11
 
5
12
  ## Install
@@ -11,15 +11,41 @@ async function getAppliedTags(proxy, dbContext) {
11
11
  const result = await proxy.execute('migration.history', [], dbContext);
12
12
  const list = Array.isArray(result)
13
13
  ? result
14
- : Array.isArray(result.data)
14
+ : result !== null
15
+ && typeof result === 'object'
16
+ && Array.isArray(result.data)
15
17
  ? result.data
16
- : [];
17
- return list.map((r) => r.tag ?? '').filter(Boolean);
18
+ : null;
19
+ if (!Array.isArray(list)) {
20
+ throw new Error('migration.history returned an invalid response instead of a history array');
21
+ }
22
+ return list.map((entry, index) => {
23
+ if (entry === null || typeof entry !== 'object' || typeof entry.tag !== 'string') {
24
+ throw new Error(`migration.history returned an invalid entry at index ${index}`);
25
+ }
26
+ return entry.tag;
27
+ });
18
28
  }
19
- catch {
20
- return [];
29
+ catch (error) {
30
+ throw new Error(`Could not read migration history for ${dbContext.product}/${dbContext.database}:${dbContext.env}. ` +
31
+ 'Migration state is unknown; no migrations were classified as pending.', { cause: error });
21
32
  }
22
33
  }
34
+ function getMigrationResult(response, migrationTag) {
35
+ if (response === null || typeof response !== 'object')
36
+ return null;
37
+ const result = response[migrationTag];
38
+ if (result === null || typeof result !== 'object')
39
+ return null;
40
+ const success = result.success;
41
+ if (typeof success !== 'boolean')
42
+ return null;
43
+ const error = result.error;
44
+ return {
45
+ success,
46
+ ...(typeof error === 'string' ? { error } : {}),
47
+ };
48
+ }
23
49
  export async function runDbMigrate(opts) {
24
50
  const found = findProjectConfig();
25
51
  if (!found)
@@ -59,13 +85,26 @@ export async function runDbMigrate(opts) {
59
85
  }
60
86
  process.stdout.write(` Applying ${migration.tag}... `);
61
87
  try {
62
- await proxy.execute('migration.run', [[migration]], dbContext);
88
+ const response = await proxy.execute('migration.run', [[migration]], dbContext);
89
+ const migrationResult = getMigrationResult(response, migration.tag);
90
+ if (migrationResult && !migrationResult.success) {
91
+ throw new Error(migrationResult.error ?? 'SDK reported an unsuccessful migration');
92
+ }
93
+ // A successful HTTP response is not proof that the migration was
94
+ // recorded. Verify history before claiming success, including when
95
+ // talking to older proxies that serialize Map results as `{}`.
96
+ const appliedAfterRun = await getAppliedTags(proxy, dbContext);
97
+ if (!appliedAfterRun.includes(migration.tag)) {
98
+ throw new Error('the operation returned without error, but the migration tag is absent from migration history');
99
+ }
63
100
  console.log('done');
64
101
  totalApplied++;
65
102
  }
66
103
  catch (err) {
67
- console.log('failed');
68
- fail(`Migration "${migration.tag}" failed: ${err instanceof Error ? err.message : String(err)}`);
104
+ console.log('unverified');
105
+ fail(`Migration "${migration.tag}" could not be verified: ` +
106
+ `${err instanceof Error ? err.message : String(err)}. ` +
107
+ 'Do not rerun it until the live schema and migration history have been inspected.');
69
108
  }
70
109
  }
71
110
  }
@@ -0,0 +1,190 @@
1
+ type MigrationMode = 'in-place' | 'new-codebase';
2
+ type Language = 'typescript' | 'go' | 'java' | 'dotnet';
3
+ interface MigrationPlan {
4
+ version: 2;
5
+ artifact_kind: 'ai_review_bootstrap';
6
+ authority: 'advisory_only';
7
+ execution_provenance?: {
8
+ mcp_client?: {
9
+ name: string;
10
+ version: string;
11
+ source: 'mcp_initialize_handshake';
12
+ trust: 'protocol_asserted_unverified';
13
+ };
14
+ ai_model: {
15
+ status: 'unavailable';
16
+ reason: 'MCP does not provide a server-verifiable model identity';
17
+ };
18
+ };
19
+ source: string;
20
+ mode: MigrationMode;
21
+ destination: string;
22
+ product: {
23
+ tag: string;
24
+ name: string;
25
+ exists?: boolean;
26
+ created?: boolean;
27
+ };
28
+ target_database: string;
29
+ languages: Language[];
30
+ frameworks: string[];
31
+ workspace_boundaries: Array<{
32
+ system: 'bazel' | 'buck' | 'pants' | 'nx' | 'turborepo' | 'maven' | 'gradle' | 'dotnet';
33
+ evidence: string[];
34
+ requires_ai_review: true;
35
+ }>;
36
+ workspace_units: Array<{
37
+ manifest: string;
38
+ kind: 'node' | 'go' | 'maven' | 'gradle' | 'dotnet' | 'nx';
39
+ nearest_boundary?: string;
40
+ ownership_status: 'contextual_review_required';
41
+ }>;
42
+ generated_source_hints: Array<{
43
+ file: string;
44
+ evidence: string;
45
+ confidence: 'low';
46
+ requires_ai_review: true;
47
+ }>;
48
+ scan_safety: {
49
+ symlinks_followed: false;
50
+ symlinks_skipped: string[];
51
+ git_submodules: Array<{
52
+ name: string;
53
+ path: string;
54
+ url?: string;
55
+ }>;
56
+ };
57
+ scan_policy: {
58
+ max_file_bytes: number;
59
+ binary_files: 'exclude';
60
+ include_patterns: string[];
61
+ exclude_patterns: string[];
62
+ exclusions: Array<{
63
+ file: string;
64
+ reason: string;
65
+ }>;
66
+ };
67
+ environments: string[];
68
+ secrets: Array<{
69
+ key: string;
70
+ source: string;
71
+ environment: string;
72
+ value: '[REDACTED]';
73
+ }>;
74
+ secret_references: Array<{
75
+ key: string;
76
+ source: string;
77
+ system: 'docker' | 'kubernetes' | 'github' | 'gitlab' | 'jenkins' | 'circleci' | 'azure_devops' | 'spring' | 'dotnet' | 'terraform' | 'aws' | 'gcp' | 'azure';
78
+ environment: string;
79
+ value: '[NOT_READ]';
80
+ requires_ai_review: true;
81
+ }>;
82
+ potential_secret_exposures: Array<{
83
+ source: string;
84
+ line: number;
85
+ kind: 'password' | 'token' | 'secret' | 'private_key' | 'connection_string';
86
+ fingerprint: string;
87
+ value: '[NOT_RETURNED]';
88
+ confidence: 'low';
89
+ requires_human_security_review: true;
90
+ }>;
91
+ deterministic_hints: {
92
+ databases: Array<{
93
+ evidence: string;
94
+ kind: string;
95
+ confidence: 'low';
96
+ requires_ai_review: true;
97
+ }>;
98
+ third_party_apis: Array<{
99
+ host: string;
100
+ occurrences: number;
101
+ methods: string[];
102
+ paths: string[];
103
+ recommended_app_tag: string;
104
+ confidence: 'low';
105
+ requires_ai_review: true;
106
+ }>;
107
+ };
108
+ existing_migrations: string[];
109
+ existing_schemas: string[];
110
+ migration_imports: Array<{
111
+ source: string;
112
+ checksum: string;
113
+ order: number;
114
+ status: 'manual_review_required';
115
+ reason: string;
116
+ }>;
117
+ conversion_warnings: string[];
118
+ review_queue: Array<{
119
+ file: string;
120
+ review_status: 'pending';
121
+ inspect_for: string[];
122
+ safety: 'names_only' | 'normal';
123
+ }>;
124
+ evidence_ledger_template: {
125
+ file: string;
126
+ purpose: string;
127
+ dependencies: string[];
128
+ interfaces: string[];
129
+ functional_parity_requirements: string[];
130
+ operational_parity_requirements: string[];
131
+ findings: Array<{
132
+ kind: string;
133
+ evidence: string;
134
+ location: {
135
+ start_line: number;
136
+ end_line: number;
137
+ };
138
+ symbol: {
139
+ kind: 'module' | 'class' | 'interface' | 'function' | 'method' | 'field' | 'route' | 'event' | 'schema' | 'other';
140
+ name: string;
141
+ qualified_name?: string;
142
+ };
143
+ classification: 'observed' | 'inferred' | 'proposed' | 'confirmed';
144
+ confidence: 'low' | 'medium' | 'high';
145
+ requires_followup: string[];
146
+ }>;
147
+ decision: 'pending';
148
+ };
149
+ ai_working_standards: {
150
+ global: string[];
151
+ languages: Record<Language, string[]>;
152
+ };
153
+ output_paths: {
154
+ plan: string;
155
+ migration_evidence: string;
156
+ review_ledger_template: string;
157
+ guide: string;
158
+ };
159
+ next_steps: string[];
160
+ }
161
+ export declare function writeMigrationGuidance(plan: MigrationPlan): void;
162
+ export declare function inspectMigrationCodebase(opts: {
163
+ source: string;
164
+ mode?: MigrationMode;
165
+ destination?: string;
166
+ product?: string;
167
+ name?: string;
168
+ database?: string;
169
+ maxFileBytes?: number;
170
+ include?: string[];
171
+ exclude?: string[];
172
+ }): MigrationPlan;
173
+ export declare function runMigrateCodebase(opts: {
174
+ source?: string;
175
+ e2eBaseline: string;
176
+ mode?: MigrationMode;
177
+ destination?: string;
178
+ product?: string;
179
+ name?: string;
180
+ database?: string;
181
+ maxFileBytes?: number;
182
+ include?: string[];
183
+ exclude?: string[];
184
+ ensureProduct?: boolean;
185
+ write?: boolean;
186
+ json?: boolean;
187
+ mcpClientName?: string;
188
+ mcpClientVersion?: string;
189
+ }): Promise<void>;
190
+ export {};