@boxes-dev/dvb 0.2.34 → 0.2.36
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/dist/bin/dvb.cjs +92 -128
- package/dist/devbox/commands/init/codex/local.d.ts +5 -5
- package/dist/devbox/commands/init/codex/local.d.ts.map +1 -1
- package/dist/devbox/commands/init/codex/local.js +5 -5
- package/dist/devbox/commands/init/codex/local.js.map +1 -1
- package/dist/devbox/commands/init/codex/plan.d.ts +19 -11
- package/dist/devbox/commands/init/codex/plan.d.ts.map +1 -1
- package/dist/devbox/commands/init/codex/plan.js +11 -3
- package/dist/devbox/commands/init/codex/plan.js.map +1 -1
- package/dist/devbox/commands/init/index.d.ts.map +1 -1
- package/dist/devbox/commands/init/index.js +79 -120
- package/dist/devbox/commands/init/index.js.map +1 -1
- package/dist/devbox/commands/init/state.d.ts +1 -2
- package/dist/devbox/commands/init/state.d.ts.map +1 -1
- package/dist/devbox/commands/init/state.js +0 -1
- package/dist/devbox/commands/init/state.js.map +1 -1
- package/package.json +1 -1
|
@@ -17,7 +17,7 @@ import { readRepoMarker, writeRepoMarker } from "./registry.js";
|
|
|
17
17
|
import { INIT_STEP_KEYS, readInitState, writeInitState } from "./state.js";
|
|
18
18
|
import { ensureSshConfig, ensureSshKey, copyToClipboard, openBrowser, parseGitRemote, readRemoteOrigin, setRemoteOrigin, verifySshAuth, } from "./ssh.js";
|
|
19
19
|
import { ensureKnownHostsFile, ensureLocalMountKey, ensureRemoteMountAccess, ensureSshdService, readLocalMountPublicKey, } from "../mountSsh.js";
|
|
20
|
-
import { createSetupArtifacts, promptForPlanApproval, promptForServicesApproval, readSetupPlan, readSetupEnvSecretsPlan, readSetupExternalPlan, readSetupExtraArtifactsPlan, readServicesPlan, runLocalServicesScan, runLocalSetupEnvSecretsScan, runLocalSetupExternalScan, runLocalSetupExtraArtifactsScan, runRemoteCodexSetup, uploadSetupPlan, mergeSetupScans, writeSetupPlan, writeSetupEnvSecretsSchema, writeSetupExternalSchema, writeSetupExtraArtifactsSchema,
|
|
20
|
+
import { createSetupArtifacts, promptForPlanApproval, promptForServicesApproval, readSetupPlan, readSetupEnvSecretsPlan, readSetupExternalPlan, readSetupExtraArtifactsPlan, readServicesPlan, runLocalServicesScan, runLocalSetupEnvSecretsScan, runLocalSetupExternalScan, runLocalSetupExtraArtifactsScan, runRemoteCodexSetup, uploadSetupPlan, mergeSetupScans, writeSetupPlan, writeSetupEnvSecretsSchema, writeSetupExternalSchema, writeSetupExtraArtifactsSchema, writeServicesSchema, } from "./codex/index.js";
|
|
21
21
|
import { mergeServicesToml, splitShellCommand, } from "../servicesToml.js";
|
|
22
22
|
import { runInitStep } from "./progress.js";
|
|
23
23
|
const resolveInitStatus = (steps, complete) => {
|
|
@@ -57,7 +57,6 @@ const migrateLegacyRepoDevboxDir = async ({ repoRoot, projectDir, }) => {
|
|
|
57
57
|
"box.json",
|
|
58
58
|
"init-state.json",
|
|
59
59
|
"setup.json",
|
|
60
|
-
"services.json",
|
|
61
60
|
"setup-artifacts.tgz",
|
|
62
61
|
"setup-artifacts.json",
|
|
63
62
|
"scans",
|
|
@@ -86,7 +85,7 @@ const buildServicesTomlUpdates = (services) => {
|
|
|
86
85
|
for (const service of services) {
|
|
87
86
|
const name = service.name.trim();
|
|
88
87
|
if (!name) {
|
|
89
|
-
throw new Error("Service name is required in
|
|
88
|
+
throw new Error("Service name is required in setup.json services.");
|
|
90
89
|
}
|
|
91
90
|
const parts = splitShellCommand(service.command ?? "");
|
|
92
91
|
const [cmd, ...args] = parts;
|
|
@@ -160,7 +159,7 @@ const enableRemoteServices = async ({ client, canonical, services, status, }) =>
|
|
|
160
159
|
for (const service of services) {
|
|
161
160
|
const name = service.name.trim();
|
|
162
161
|
if (!name) {
|
|
163
|
-
throw new Error("Service name is required in
|
|
162
|
+
throw new Error("Service name is required in setup.json services.");
|
|
164
163
|
}
|
|
165
164
|
status?.stage(`Enabling service: ${name}`);
|
|
166
165
|
const parts = splitShellCommand(service.command ?? "");
|
|
@@ -625,12 +624,12 @@ export const runInit = async (args) => {
|
|
|
625
624
|
}
|
|
626
625
|
const setupDir = projectDir;
|
|
627
626
|
const setupPath = path.join(setupDir, "setup.json");
|
|
628
|
-
|
|
627
|
+
let setupPlan;
|
|
629
628
|
try {
|
|
630
|
-
await
|
|
629
|
+
setupPlan = await readSetupPlan(setupPath);
|
|
631
630
|
}
|
|
632
631
|
catch {
|
|
633
|
-
throw new Error(`Missing setup plan (${setupPath}). Run \`dvb init\` first.`);
|
|
632
|
+
throw new Error(`Missing or invalid setup plan (${setupPath}). Run \`dvb init\` first.`);
|
|
634
633
|
}
|
|
635
634
|
const localArtifactsBundlePath = path.join(setupDir, "setup-artifacts.tgz");
|
|
636
635
|
const localArtifactsManifestPath = path.join(setupDir, "setup-artifacts.json");
|
|
@@ -690,13 +689,6 @@ export const runInit = async (args) => {
|
|
|
690
689
|
const remoteArtifactsBundlePath = path.posix.join(expandedWorkdir, ".devbox", "setup-artifacts.tgz");
|
|
691
690
|
const remoteArtifactsManifestPath = path.posix.join(expandedWorkdir, ".devbox", "setup-artifacts.json");
|
|
692
691
|
const pathSetup = 'export PATH="$(npm bin -g 2>/dev/null):$PATH"';
|
|
693
|
-
let servicesPlan = null;
|
|
694
|
-
try {
|
|
695
|
-
servicesPlan = await readServicesPlan(servicesPath);
|
|
696
|
-
}
|
|
697
|
-
catch {
|
|
698
|
-
servicesPlan = null;
|
|
699
|
-
}
|
|
700
692
|
await runInitStep({
|
|
701
693
|
enabled: progressEnabled,
|
|
702
694
|
title: "Configuring git safe.directory",
|
|
@@ -779,7 +771,7 @@ export const runInit = async (args) => {
|
|
|
779
771
|
await enableRemoteServices({
|
|
780
772
|
client,
|
|
781
773
|
canonical,
|
|
782
|
-
services:
|
|
774
|
+
services: setupPlan.services.backgroundServices,
|
|
783
775
|
status,
|
|
784
776
|
});
|
|
785
777
|
},
|
|
@@ -798,7 +790,7 @@ export const runInit = async (args) => {
|
|
|
798
790
|
socketInfo,
|
|
799
791
|
status,
|
|
800
792
|
pathSetup,
|
|
801
|
-
entrypoints:
|
|
793
|
+
entrypoints: setupPlan.services.appEntrypoints,
|
|
802
794
|
});
|
|
803
795
|
},
|
|
804
796
|
});
|
|
@@ -1094,22 +1086,20 @@ export const runInit = async (args) => {
|
|
|
1094
1086
|
});
|
|
1095
1087
|
const setupDir = projectDir;
|
|
1096
1088
|
const setupPath = path.join(setupDir, "setup.json");
|
|
1097
|
-
const servicesPath = path.join(setupDir, "services.json");
|
|
1098
1089
|
const scansDir = path.join(setupDir, "scans");
|
|
1099
1090
|
const logDir = path.join(setupDir, "logs");
|
|
1100
1091
|
const setupEnvSecretsScanPath = path.join(scansDir, "setup-env-secrets.json");
|
|
1101
1092
|
const setupExternalScanPath = path.join(scansDir, "setup-external.json");
|
|
1102
1093
|
const setupExtraArtifactsScanPath = path.join(scansDir, "setup-extra-artifacts.json");
|
|
1094
|
+
const servicesScanPath = path.join(scansDir, "services.json");
|
|
1103
1095
|
let setupArtifacts = null;
|
|
1104
1096
|
const nonInteractive = !process.stdin.isTTY || parsed.json;
|
|
1105
1097
|
const skipSetupPlan = shouldResume && initState?.steps.setupPlanWritten;
|
|
1106
|
-
const skipServicesPlan = shouldResume && initState?.steps.servicesPlanWritten;
|
|
1107
1098
|
const skipServicesConfig = shouldResume && initState?.steps.servicesConfigWritten;
|
|
1108
1099
|
const skipServicesEnable = shouldResume && initState?.steps.servicesEnabled;
|
|
1109
1100
|
const skipSetupUpload = nonInteractive || (shouldResume && initState?.steps.setupUploaded);
|
|
1110
1101
|
const skipCodexApply = nonInteractive || (shouldResume && initState?.steps.codexApplied);
|
|
1111
1102
|
let approvedPlan = null;
|
|
1112
|
-
let approvedServices = null;
|
|
1113
1103
|
const setupTempDir = await fs.mkdtemp(path.join(os.tmpdir(), "devbox-setup-"));
|
|
1114
1104
|
try {
|
|
1115
1105
|
await fs.mkdir(setupDir, { recursive: true, mode: 0o700 });
|
|
@@ -1129,7 +1119,7 @@ export const runInit = async (args) => {
|
|
|
1129
1119
|
};
|
|
1130
1120
|
const tryReadServicesPlan = async () => {
|
|
1131
1121
|
try {
|
|
1132
|
-
return await readServicesPlan(
|
|
1122
|
+
return await readServicesPlan(servicesScanPath);
|
|
1133
1123
|
}
|
|
1134
1124
|
catch {
|
|
1135
1125
|
return null;
|
|
@@ -1161,8 +1151,8 @@ export const runInit = async (args) => {
|
|
|
1161
1151
|
};
|
|
1162
1152
|
const shouldRetryCodexScan = (scanFullyCompleted, ...arrays) => !scanFullyCompleted && arrays.every((array) => array.length === 0);
|
|
1163
1153
|
let setupPlan = skipSetupPlan || !shouldResume ? null : await tryReadSetupPlan();
|
|
1164
|
-
let servicesPlan = skipServicesPlan || !shouldResume ? null : await tryReadServicesPlan();
|
|
1165
1154
|
const needsSetupScan = !skipSetupPlan && !setupPlan;
|
|
1155
|
+
let servicesPlan = !needsSetupScan || !shouldResume ? null : await tryReadServicesPlan();
|
|
1166
1156
|
let envSecretsScan = !needsSetupScan || !shouldResume ? null : await tryReadEnvSecretsScan();
|
|
1167
1157
|
let externalScan = !needsSetupScan || !shouldResume ? null : await tryReadExternalScan();
|
|
1168
1158
|
let extraArtifactsScan = !needsSetupScan || !shouldResume
|
|
@@ -1184,7 +1174,7 @@ export const runInit = async (args) => {
|
|
|
1184
1174
|
shouldRetryCodexScan(extraArtifactsScan.scanFullyCompleted, extraArtifactsScan.extraArtifacts)) {
|
|
1185
1175
|
extraArtifactsScan = null;
|
|
1186
1176
|
}
|
|
1187
|
-
const needsServicesScan =
|
|
1177
|
+
const needsServicesScan = needsSetupScan && !servicesPlan;
|
|
1188
1178
|
const needsEnvSecretsScan = needsSetupScan && !envSecretsScan;
|
|
1189
1179
|
const needsExternalScan = needsSetupScan && !externalScan;
|
|
1190
1180
|
const needsExtraArtifactsScan = needsSetupScan && !extraArtifactsScan;
|
|
@@ -1300,12 +1290,12 @@ export const runInit = async (args) => {
|
|
|
1300
1290
|
cwd: repoRoot,
|
|
1301
1291
|
logDir,
|
|
1302
1292
|
schemaPath: servicesSchemaPath,
|
|
1303
|
-
outputPath:
|
|
1293
|
+
outputPath: servicesScanPath,
|
|
1304
1294
|
homeDir: localHomeDir,
|
|
1305
1295
|
onProgress: updateServices,
|
|
1306
1296
|
}),
|
|
1307
|
-
read: async () => await readServicesPlan(
|
|
1308
|
-
outputPath:
|
|
1297
|
+
read: async () => await readServicesPlan(servicesScanPath),
|
|
1298
|
+
outputPath: servicesScanPath,
|
|
1309
1299
|
update: updateServices,
|
|
1310
1300
|
shouldRetry: (plan) => shouldRetryCodexScan(plan.scanFullyCompleted, plan.appEntrypoints, plan.backgroundServices),
|
|
1311
1301
|
});
|
|
@@ -1317,7 +1307,7 @@ export const runInit = async (args) => {
|
|
|
1317
1307
|
]);
|
|
1318
1308
|
if (needsServicesScan) {
|
|
1319
1309
|
if (!services) {
|
|
1320
|
-
throw new Error("Services
|
|
1310
|
+
throw new Error("Services scan missing.");
|
|
1321
1311
|
}
|
|
1322
1312
|
servicesPlan = services;
|
|
1323
1313
|
}
|
|
@@ -1331,11 +1321,18 @@ export const runInit = async (args) => {
|
|
|
1331
1321
|
if (!extraArtifacts) {
|
|
1332
1322
|
throw new Error("Extra artifacts scan missing.");
|
|
1333
1323
|
}
|
|
1324
|
+
if (!servicesPlan) {
|
|
1325
|
+
throw new Error("Services scan missing.");
|
|
1326
|
+
}
|
|
1334
1327
|
updateEnvSecrets("merging setup plan");
|
|
1335
1328
|
const merged = mergeSetupScans({
|
|
1336
1329
|
envSecrets,
|
|
1337
1330
|
external,
|
|
1338
1331
|
extraArtifacts,
|
|
1332
|
+
services: {
|
|
1333
|
+
appEntrypoints: servicesPlan.appEntrypoints,
|
|
1334
|
+
backgroundServices: servicesPlan.backgroundServices,
|
|
1335
|
+
},
|
|
1339
1336
|
});
|
|
1340
1337
|
await writeSetupPlan(setupPath, merged);
|
|
1341
1338
|
setupPlan = merged;
|
|
@@ -1390,7 +1387,7 @@ export const runInit = async (args) => {
|
|
|
1390
1387
|
? "starting"
|
|
1391
1388
|
: "cached"
|
|
1392
1389
|
: "skipped");
|
|
1393
|
-
updateServices(
|
|
1390
|
+
updateServices(needsServicesScan ? "starting" : "cached");
|
|
1394
1391
|
try {
|
|
1395
1392
|
await runLocalEnvironmentAnalysis({
|
|
1396
1393
|
updateEnvSecrets,
|
|
@@ -1411,15 +1408,9 @@ export const runInit = async (args) => {
|
|
|
1411
1408
|
if (!skipSetupPlan && !setupPlan) {
|
|
1412
1409
|
setupPlan = await readSetupPlan(setupPath);
|
|
1413
1410
|
}
|
|
1414
|
-
if (!skipServicesPlan && !servicesPlan) {
|
|
1415
|
-
servicesPlan = await readServicesPlan(servicesPath);
|
|
1416
|
-
}
|
|
1417
1411
|
if (!skipSetupPlan && !setupPlan) {
|
|
1418
1412
|
throw new Error("Setup plan missing.");
|
|
1419
1413
|
}
|
|
1420
|
-
if (!skipServicesPlan && !servicesPlan) {
|
|
1421
|
-
throw new Error("Services plan missing.");
|
|
1422
|
-
}
|
|
1423
1414
|
const scanStepUpdate = {};
|
|
1424
1415
|
if (!skipSetupPlan && setupPlan) {
|
|
1425
1416
|
if (!initState?.steps.setupEnvSecretsScanned) {
|
|
@@ -1434,11 +1425,9 @@ export const runInit = async (args) => {
|
|
|
1434
1425
|
if (!initState?.steps.setupPlanScanned) {
|
|
1435
1426
|
scanStepUpdate.setupPlanScanned = true;
|
|
1436
1427
|
}
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
!initState?.steps.servicesPlanScanned) {
|
|
1441
|
-
scanStepUpdate.servicesPlanScanned = true;
|
|
1428
|
+
if (!initState?.steps.servicesPlanScanned) {
|
|
1429
|
+
scanStepUpdate.servicesPlanScanned = true;
|
|
1430
|
+
}
|
|
1442
1431
|
}
|
|
1443
1432
|
if (Object.keys(scanStepUpdate).length > 0) {
|
|
1444
1433
|
await updateInitState({ steps: scanStepUpdate });
|
|
@@ -1446,26 +1435,21 @@ export const runInit = async (args) => {
|
|
|
1446
1435
|
if (skipSetupPlan) {
|
|
1447
1436
|
approvedPlan = await readSetupPlan(setupPath);
|
|
1448
1437
|
}
|
|
1449
|
-
if (
|
|
1450
|
-
approvedServices = await readServicesPlan(servicesPath);
|
|
1451
|
-
}
|
|
1452
|
-
if (shouldResume && (approvedPlan || approvedServices)) {
|
|
1438
|
+
if (shouldResume && approvedPlan) {
|
|
1453
1439
|
const backfillStepUpdate = {};
|
|
1454
|
-
if (
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
backfillStepUpdate.setupExtraArtifactsScanned = true;
|
|
1463
|
-
}
|
|
1464
|
-
if (!initState?.steps.setupPlanScanned) {
|
|
1465
|
-
backfillStepUpdate.setupPlanScanned = true;
|
|
1466
|
-
}
|
|
1440
|
+
if (!initState?.steps.setupEnvSecretsScanned) {
|
|
1441
|
+
backfillStepUpdate.setupEnvSecretsScanned = true;
|
|
1442
|
+
}
|
|
1443
|
+
if (!initState?.steps.setupExternalScanned) {
|
|
1444
|
+
backfillStepUpdate.setupExternalScanned = true;
|
|
1445
|
+
}
|
|
1446
|
+
if (!initState?.steps.setupExtraArtifactsScanned) {
|
|
1447
|
+
backfillStepUpdate.setupExtraArtifactsScanned = true;
|
|
1467
1448
|
}
|
|
1468
|
-
if (
|
|
1449
|
+
if (!initState?.steps.setupPlanScanned) {
|
|
1450
|
+
backfillStepUpdate.setupPlanScanned = true;
|
|
1451
|
+
}
|
|
1452
|
+
if (!initState?.steps.servicesPlanScanned) {
|
|
1469
1453
|
backfillStepUpdate.servicesPlanScanned = true;
|
|
1470
1454
|
}
|
|
1471
1455
|
if (Object.keys(backfillStepUpdate).length > 0) {
|
|
@@ -1475,10 +1459,8 @@ export const runInit = async (args) => {
|
|
|
1475
1459
|
if (nonInteractive) {
|
|
1476
1460
|
if (setupPlan)
|
|
1477
1461
|
approvedPlan = setupPlan;
|
|
1478
|
-
if (servicesPlan)
|
|
1479
|
-
approvedServices = servicesPlan;
|
|
1480
1462
|
}
|
|
1481
|
-
else if (
|
|
1463
|
+
else if (!skipSetupPlan && setupPlan) {
|
|
1482
1464
|
if (!process.stdin.isTTY || parsed.json) {
|
|
1483
1465
|
throw new Error("Interactive terminal required to approve setup.");
|
|
1484
1466
|
}
|
|
@@ -1504,45 +1486,45 @@ export const runInit = async (args) => {
|
|
|
1504
1486
|
statCache.set(candidatePath, info);
|
|
1505
1487
|
return info;
|
|
1506
1488
|
};
|
|
1507
|
-
const buildApprovalSummary = async (
|
|
1489
|
+
const buildApprovalSummary = async (plan) => {
|
|
1508
1490
|
const lines = [];
|
|
1509
1491
|
lines.push("Setup");
|
|
1510
|
-
lines.push(`- .env files: ${
|
|
1511
|
-
for (const entry of
|
|
1492
|
+
lines.push(`- .env files: ${plan.envFiles.length}`);
|
|
1493
|
+
for (const entry of plan.envFiles) {
|
|
1512
1494
|
lines.push(` - ${toRepoRelativePath(repoRoot, entry.path)}`);
|
|
1513
1495
|
}
|
|
1514
|
-
lines.push(`- Secret/config files: ${
|
|
1515
|
-
for (const entry of
|
|
1496
|
+
lines.push(`- Secret/config files: ${plan.secretFiles.length}`);
|
|
1497
|
+
for (const entry of plan.secretFiles) {
|
|
1516
1498
|
lines.push(` - ${toRepoRelativePath(repoRoot, entry.path)}`);
|
|
1517
1499
|
}
|
|
1518
|
-
lines.push(`- Other artifacts: ${
|
|
1519
|
-
for (const entry of
|
|
1500
|
+
lines.push(`- Other artifacts: ${plan.extraArtifacts.length}`);
|
|
1501
|
+
for (const entry of plan.extraArtifacts) {
|
|
1520
1502
|
lines.push(` - ${toRepoRelativePath(repoRoot, entry.path)}`);
|
|
1521
1503
|
}
|
|
1522
|
-
lines.push(`- External dependencies: ${
|
|
1523
|
-
for (const entry of
|
|
1504
|
+
lines.push(`- External dependencies: ${plan.externalDependencies.length}`);
|
|
1505
|
+
for (const entry of plan.externalDependencies) {
|
|
1524
1506
|
lines.push(` - ${entry.version ? `${entry.name}@${entry.version}` : entry.name}`);
|
|
1525
1507
|
}
|
|
1526
|
-
lines.push(`- External config/secret files: ${
|
|
1527
|
-
for (const entry of
|
|
1508
|
+
lines.push(`- External config/secret files: ${plan.externalConfigs.length}`);
|
|
1509
|
+
for (const entry of plan.externalConfigs) {
|
|
1528
1510
|
lines.push(` - ${toRepoRelativePath(repoRoot, entry.path)}`);
|
|
1529
1511
|
}
|
|
1530
1512
|
lines.push("");
|
|
1531
1513
|
lines.push("Services");
|
|
1532
|
-
lines.push(`- App entrypoints: ${services.appEntrypoints.length}`);
|
|
1533
|
-
for (const entry of services.appEntrypoints) {
|
|
1514
|
+
lines.push(`- App entrypoints: ${plan.services.appEntrypoints.length}`);
|
|
1515
|
+
for (const entry of plan.services.appEntrypoints) {
|
|
1534
1516
|
lines.push(` - ${entry.command}`);
|
|
1535
1517
|
}
|
|
1536
|
-
lines.push(`- Background services: ${services.backgroundServices.length}`);
|
|
1537
|
-
for (const entry of services.backgroundServices) {
|
|
1518
|
+
lines.push(`- Background services: ${plan.services.backgroundServices.length}`);
|
|
1519
|
+
for (const entry of plan.services.backgroundServices) {
|
|
1538
1520
|
lines.push(` - ${entry.name}`);
|
|
1539
1521
|
}
|
|
1540
1522
|
const candidatePaths = new Set();
|
|
1541
1523
|
for (const entry of [
|
|
1542
|
-
...
|
|
1543
|
-
...
|
|
1544
|
-
...
|
|
1545
|
-
...
|
|
1524
|
+
...plan.envFiles,
|
|
1525
|
+
...plan.secretFiles,
|
|
1526
|
+
...plan.extraArtifacts,
|
|
1527
|
+
...plan.externalConfigs,
|
|
1546
1528
|
]) {
|
|
1547
1529
|
candidatePaths.add(entry.path);
|
|
1548
1530
|
}
|
|
@@ -1579,31 +1561,18 @@ export const runInit = async (args) => {
|
|
|
1579
1561
|
};
|
|
1580
1562
|
};
|
|
1581
1563
|
let draftSetup = setupPlan;
|
|
1582
|
-
let draftServices = servicesPlan;
|
|
1583
1564
|
while (true) {
|
|
1584
|
-
const nextSetup =
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
? approvedServices
|
|
1593
|
-
: await promptForServicesApproval({
|
|
1594
|
-
plan: servicesPlan,
|
|
1595
|
-
initialPlan: draftServices,
|
|
1596
|
-
});
|
|
1597
|
-
if (!nextSetup) {
|
|
1598
|
-
throw new Error("Setup plan missing.");
|
|
1599
|
-
}
|
|
1600
|
-
if (!nextServices) {
|
|
1601
|
-
throw new Error("Services plan missing.");
|
|
1602
|
-
}
|
|
1603
|
-
const { summary, warning, hasRisk } = await buildApprovalSummary({
|
|
1604
|
-
setup: nextSetup,
|
|
1605
|
-
services: nextServices,
|
|
1565
|
+
const nextSetup = await promptForPlanApproval({
|
|
1566
|
+
plan: setupPlan,
|
|
1567
|
+
repoRoot,
|
|
1568
|
+
initialPlan: draftSetup,
|
|
1569
|
+
});
|
|
1570
|
+
const nextServices = await promptForServicesApproval({
|
|
1571
|
+
plan: setupPlan.services,
|
|
1572
|
+
initialSelection: draftSetup?.services ?? null,
|
|
1606
1573
|
});
|
|
1574
|
+
const nextPlan = { ...nextSetup, services: nextServices };
|
|
1575
|
+
const { summary, warning, hasRisk } = await buildApprovalSummary(nextPlan);
|
|
1607
1576
|
clackNote(summary, "Selected setup requirements");
|
|
1608
1577
|
if (warning) {
|
|
1609
1578
|
clackNote(warning, "Special attention");
|
|
@@ -1621,8 +1590,7 @@ export const runInit = async (args) => {
|
|
|
1621
1590
|
throwInitCanceled();
|
|
1622
1591
|
}
|
|
1623
1592
|
if (decision === "edit") {
|
|
1624
|
-
draftSetup =
|
|
1625
|
-
draftServices = nextServices;
|
|
1593
|
+
draftSetup = nextPlan;
|
|
1626
1594
|
continue;
|
|
1627
1595
|
}
|
|
1628
1596
|
if (hasRisk) {
|
|
@@ -1636,31 +1604,22 @@ export const runInit = async (args) => {
|
|
|
1636
1604
|
throwInitCanceled();
|
|
1637
1605
|
}
|
|
1638
1606
|
if (!confirmed) {
|
|
1639
|
-
draftSetup =
|
|
1640
|
-
draftServices = nextServices;
|
|
1607
|
+
draftSetup = nextPlan;
|
|
1641
1608
|
continue;
|
|
1642
1609
|
}
|
|
1643
1610
|
}
|
|
1644
|
-
approvedPlan =
|
|
1645
|
-
approvedServices = nextServices;
|
|
1611
|
+
approvedPlan = nextPlan;
|
|
1646
1612
|
break;
|
|
1647
1613
|
}
|
|
1648
1614
|
}
|
|
1649
1615
|
if (!approvedPlan) {
|
|
1650
1616
|
throw new Error("Setup plan missing.");
|
|
1651
1617
|
}
|
|
1652
|
-
if (!approvedServices) {
|
|
1653
|
-
throw new Error("Services plan missing.");
|
|
1654
|
-
}
|
|
1655
1618
|
const ensuredPlan = approvedPlan;
|
|
1656
1619
|
if (!skipSetupPlan) {
|
|
1657
1620
|
await writeSetupPlan(setupPath, ensuredPlan);
|
|
1658
1621
|
await updateInitState({ steps: { setupPlanWritten: true } });
|
|
1659
1622
|
}
|
|
1660
|
-
if (!skipServicesPlan) {
|
|
1661
|
-
await writeServicesPlan(servicesPath, approvedServices);
|
|
1662
|
-
await updateInitState({ steps: { servicesPlanWritten: true } });
|
|
1663
|
-
}
|
|
1664
1623
|
if (!skipSetupUpload) {
|
|
1665
1624
|
setupArtifacts = await runInitStep({
|
|
1666
1625
|
enabled: progressEnabled,
|
|
@@ -1678,6 +1637,9 @@ export const runInit = async (args) => {
|
|
|
1678
1637
|
finally {
|
|
1679
1638
|
await fs.rm(setupTempDir, { recursive: true, force: true });
|
|
1680
1639
|
}
|
|
1640
|
+
if (!approvedPlan) {
|
|
1641
|
+
throw new Error("Setup plan missing.");
|
|
1642
|
+
}
|
|
1681
1643
|
const skipProvision = shouldResume && initState?.steps.workdirProvisioned;
|
|
1682
1644
|
if (skipProvision && !skipSetupUpload) {
|
|
1683
1645
|
await runInitStep({
|
|
@@ -2188,9 +2150,6 @@ export const runInit = async (args) => {
|
|
|
2188
2150
|
});
|
|
2189
2151
|
}
|
|
2190
2152
|
if (!skipServicesConfig) {
|
|
2191
|
-
if (!approvedServices) {
|
|
2192
|
-
throw new Error("Missing services plan output.");
|
|
2193
|
-
}
|
|
2194
2153
|
await runInitStep({
|
|
2195
2154
|
enabled: progressEnabled,
|
|
2196
2155
|
title: "Writing devbox.toml services",
|
|
@@ -2199,7 +2158,7 @@ export const runInit = async (args) => {
|
|
|
2199
2158
|
client,
|
|
2200
2159
|
canonical,
|
|
2201
2160
|
workdir: expandedWorkdir,
|
|
2202
|
-
services:
|
|
2161
|
+
services: approvedPlan.services.backgroundServices,
|
|
2203
2162
|
});
|
|
2204
2163
|
await updateInitState({ steps: { servicesConfigWritten: true } });
|
|
2205
2164
|
},
|
|
@@ -2326,7 +2285,7 @@ export const runInit = async (args) => {
|
|
|
2326
2285
|
await enableRemoteServices({
|
|
2327
2286
|
client,
|
|
2328
2287
|
canonical,
|
|
2329
|
-
services:
|
|
2288
|
+
services: approvedPlan.services.backgroundServices,
|
|
2330
2289
|
status,
|
|
2331
2290
|
});
|
|
2332
2291
|
await updateInitState({ steps: { servicesEnabled: true } });
|
|
@@ -2347,7 +2306,7 @@ export const runInit = async (args) => {
|
|
|
2347
2306
|
socketInfo,
|
|
2348
2307
|
status,
|
|
2349
2308
|
pathSetup,
|
|
2350
|
-
entrypoints:
|
|
2309
|
+
entrypoints: approvedPlan.services.appEntrypoints,
|
|
2351
2310
|
});
|
|
2352
2311
|
},
|
|
2353
2312
|
});
|