@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.
- package/CHANGELOG.md +7 -0
- package/README.md +7 -0
- package/dist/commands/db-migrate.js +47 -8
- package/dist/commands/migrate-codebase.d.ts +190 -0
- package/dist/commands/migrate-codebase.js +776 -0
- package/dist/commands/migration-artifact.d.ts +28 -0
- package/dist/commands/migration-artifact.js +101 -0
- package/dist/commands/migration-assurance.d.ts +10 -0
- package/dist/commands/migration-assurance.js +120 -0
- package/dist/commands/migration-capabilities.d.ts +53 -0
- package/dist/commands/migration-capabilities.js +66 -0
- package/dist/commands/migration-database.d.ts +26 -0
- package/dist/commands/migration-database.js +162 -0
- package/dist/commands/migration-e2e.d.ts +68 -0
- package/dist/commands/migration-e2e.js +189 -0
- package/dist/commands/migration-environments.d.ts +20 -0
- package/dist/commands/migration-environments.js +58 -0
- package/dist/commands/migration-generated.d.ts +68 -0
- package/dist/commands/migration-generated.js +217 -0
- package/dist/commands/migration-portfolio.d.ts +88 -0
- package/dist/commands/migration-portfolio.js +223 -0
- package/dist/commands/migration-products.d.ts +23 -0
- package/dist/commands/migration-products.js +88 -0
- package/dist/commands/migration-review.d.ts +248 -0
- package/dist/commands/migration-review.js +624 -0
- package/dist/commands/migration-secrets.d.ts +24 -0
- package/dist/commands/migration-secrets.js +93 -0
- package/dist/commands/migration-slice.d.ts +132 -0
- package/dist/commands/migration-slice.js +266 -0
- package/dist/commands/migration-verification.d.ts +12 -0
- package/dist/commands/migration-verification.js +194 -0
- package/dist/commands/products.d.ts +1 -0
- package/dist/commands/products.js +33 -1
- package/dist/commands/secrets.d.ts +8 -0
- package/dist/commands/secrets.js +44 -0
- package/dist/index.js +376 -4
- package/dist/lib/migration-artifact.d.ts +19 -0
- package/dist/lib/migration-artifact.js +114 -0
- package/package.json +8 -1
- package/API_PARITY.md +0 -58
- package/DB_MIGRATE_PLAN.md +0 -223
- package/ductape.example.ts +0 -18
- package/src/commands/apply.ts +0 -153
- package/src/commands/apps-import.ts +0 -43
- package/src/commands/apps.ts +0 -92
- package/src/commands/cloud.ts +0 -68
- package/src/commands/completion.ts +0 -119
- package/src/commands/db-migrate.ts +0 -209
- package/src/commands/db-schema.ts +0 -429
- package/src/commands/db.ts +0 -63
- package/src/commands/generate.ts +0 -74
- package/src/commands/graph.ts +0 -51
- package/src/commands/init.ts +0 -39
- package/src/commands/install.ts +0 -76
- package/src/commands/link.ts +0 -84
- package/src/commands/login.ts +0 -145
- package/src/commands/logout.ts +0 -7
- package/src/commands/platform.ts +0 -123
- package/src/commands/products.ts +0 -228
- package/src/commands/profiles.ts +0 -23
- package/src/commands/resources.ts +0 -213
- package/src/commands/secrets.ts +0 -46
- package/src/commands/unlink.ts +0 -15
- package/src/commands/whoami.ts +0 -27
- package/src/commands/workspaces.ts +0 -98
- package/src/index.ts +0 -523
- package/src/lib/api-client.ts +0 -88
- package/src/lib/app-import.ts +0 -82
- package/src/lib/apply-loaders.ts +0 -30
- package/src/lib/config.ts +0 -230
- package/src/lib/context-store.ts +0 -77
- package/src/lib/db-methods.ts +0 -56
- package/src/lib/db-types.ts +0 -104
- package/src/lib/encryption.ts +0 -12
- package/src/lib/forms/enums.ts +0 -52
- package/src/lib/forms/index.ts +0 -8
- package/src/lib/forms/prompt.ts +0 -209
- package/src/lib/forms/schemas.ts +0 -288
- package/src/lib/forms/types.ts +0 -27
- package/src/lib/http.ts +0 -76
- package/src/lib/integrations.ts +0 -110
- package/src/lib/interactive-opts.ts +0 -13
- package/src/lib/migration-files.ts +0 -58
- package/src/lib/output.ts +0 -39
- package/src/lib/platform-api.ts +0 -209
- package/src/lib/proxy/context.ts +0 -94
- package/src/lib/proxy/db-proxy.ts +0 -40
- package/src/lib/proxy/graph-proxy.ts +0 -64
- package/src/lib/proxy/sdk-proxy.ts +0 -58
- package/src/lib/read-body.ts +0 -57
- package/src/lib/resources.ts +0 -160
- package/src/lib/schema-loader.ts +0 -152
- package/src/lib/snippets.ts +0 -165
- package/src/lib/templates.ts +0 -157
- package/src/lib/workspace-context.ts +0 -43
- package/src/lib/workspaces.ts +0 -283
- package/test/apply-loaders.test.ts +0 -40
- package/test/encryption.test.ts +0 -20
- package/test/forms.test.ts +0 -25
- package/test/http.test.ts +0 -15
- package/test/platform-api.test.ts +0 -42
- package/test/resources.test.ts +0 -23
- package/test/workspace-resolve.test.ts +0 -29
- 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
|
-
:
|
|
14
|
+
: result !== null
|
|
15
|
+
&& typeof result === 'object'
|
|
16
|
+
&& Array.isArray(result.data)
|
|
15
17
|
? result.data
|
|
16
|
-
:
|
|
17
|
-
|
|
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
|
-
|
|
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('
|
|
68
|
-
fail(`Migration "${migration.tag}"
|
|
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 {};
|