@vodmal/vdx-cli 0.20.0 → 0.20.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/package.json +1 -1
- package/src/ai.ts +5 -1
- package/src/publish.ts +30 -8
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vodmal/vdx-cli",
|
|
3
|
-
"version": "0.20.
|
|
3
|
+
"version": "0.20.1",
|
|
4
4
|
"description": "vdx — unified lifecycle interface (up/down/build/test/check/fix) + versioned maturity audit with drift detection. Pairs with the vdx Claude Code plugin.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"vdx",
|
package/src/ai.ts
CHANGED
|
@@ -957,6 +957,8 @@ export interface ConversationChoice {
|
|
|
957
957
|
remote?: { host: string; id: string; reachable: boolean };
|
|
958
958
|
/** Continue it here only after a yes: another machine's that cannot be asked, or one running here already. */
|
|
959
959
|
askHere?: { id: string; why: string };
|
|
960
|
+
/** The person ended the question (Ctrl-D): start nothing. */
|
|
961
|
+
abort?: boolean;
|
|
960
962
|
/** For the person: what was found and what is taken. */
|
|
961
963
|
lines: string[];
|
|
962
964
|
}
|
|
@@ -1047,7 +1049,8 @@ export function chooseConversation(plan: LaunchPlan, deps: AiDeps, canAsk: boole
|
|
|
1047
1049
|
deps.log(' n) a new conversation');
|
|
1048
1050
|
for (let tries = 0; tries < 2; tries++) {
|
|
1049
1051
|
const answer = deps.ask(`Which one to continue? [1]: `);
|
|
1050
|
-
|
|
1052
|
+
// Ctrl-D at the question is a cancel, not "no terminal": start nothing.
|
|
1053
|
+
if (answer === null) return { args: [], abort: true, lines: ['no answer — nothing started'] };
|
|
1051
1054
|
const a = answer.trim();
|
|
1052
1055
|
if (/^n(ew)?$/i.test(a)) return { args: [], lines: ['a new conversation'] };
|
|
1053
1056
|
const c = a === '' ? found[0] : /^\d+$/.test(a) ? found[Number(a) - 1] : undefined;
|
|
@@ -1244,6 +1247,7 @@ export function runAi(opts: AiOptions, deps: AiDeps): number {
|
|
|
1244
1247
|
return EXIT_OK;
|
|
1245
1248
|
}
|
|
1246
1249
|
for (const l of choice?.lines ?? []) log(l);
|
|
1250
|
+
if (choice?.abort) return EXIT_LAUNCH_FAILED;
|
|
1247
1251
|
|
|
1248
1252
|
let askHere = choice?.askHere;
|
|
1249
1253
|
if (choice?.remote) {
|
package/src/publish.ts
CHANGED
|
@@ -392,6 +392,8 @@ export interface PublishDeps {
|
|
|
392
392
|
sleep: (ms: number) => void;
|
|
393
393
|
/** How long to wait for the registry to show the new version. */
|
|
394
394
|
registryWaitMs: number;
|
|
395
|
+
/** Rewrites one status line in place (a terminal); without it the wait logs a line now and then. */
|
|
396
|
+
progress?: (text: string) => void;
|
|
395
397
|
}
|
|
396
398
|
|
|
397
399
|
function sleepSync(ms: number): void {
|
|
@@ -407,6 +409,7 @@ export function defaultPublishDeps(): PublishDeps {
|
|
|
407
409
|
log: (line) => process.stderr.write(line + '\n'),
|
|
408
410
|
sleep: sleepSync,
|
|
409
411
|
registryWaitMs: 180_000,
|
|
412
|
+
progress: process.stderr.isTTY ? (text) => process.stderr.write(`\r${text}\x1b[K`) : undefined,
|
|
410
413
|
};
|
|
411
414
|
}
|
|
412
415
|
|
|
@@ -427,19 +430,38 @@ export function bumpLockText(text: string, version: string): string {
|
|
|
427
430
|
export function waitForRegistry(name: string, version: string, deps: PublishDeps): boolean {
|
|
428
431
|
const started = Date.now();
|
|
429
432
|
const deadline = started + deps.registryWaitMs;
|
|
430
|
-
|
|
431
|
-
|
|
433
|
+
const limit = Math.round(deps.registryWaitMs / 1000);
|
|
434
|
+
const seconds = () => Math.round((Date.now() - started) / 1000);
|
|
435
|
+
deps.log(
|
|
436
|
+
`→ waiting for the registry to show ${name}@${version} — npm has taken it; ` +
|
|
437
|
+
`the registry usually shows it within ~2 min (giving it ${limit} s)`,
|
|
438
|
+
);
|
|
439
|
+
const shown = () => {
|
|
432
440
|
try {
|
|
433
|
-
|
|
434
|
-
deps.log(`✓ ${name}@${version} is on the registry (${Math.round((Date.now() - started) / 1000)} s after publish)`);
|
|
435
|
-
return true;
|
|
436
|
-
}
|
|
441
|
+
return deps.npm(['view', `${name}@${version}`, 'version', '--prefer-online']).trim() === version;
|
|
437
442
|
} catch {
|
|
438
|
-
|
|
443
|
+
return false; // E404 until it is processed
|
|
444
|
+
}
|
|
445
|
+
};
|
|
446
|
+
// Ask npm every 10 s; between the asks, count the seconds on one line.
|
|
447
|
+
let lastLogged = 0;
|
|
448
|
+
for (let found = shown(); ; found = shown()) {
|
|
449
|
+
if (found) {
|
|
450
|
+
deps.progress?.('');
|
|
451
|
+
deps.log(`✓ ${name}@${version} is on the registry (${seconds()} s after publish)`);
|
|
452
|
+
return true;
|
|
439
453
|
}
|
|
440
454
|
if (Date.now() >= deadline) break;
|
|
441
|
-
|
|
455
|
+
for (let i = 0; i < 10 && Date.now() < deadline; i++) {
|
|
456
|
+
if (deps.progress) deps.progress(` … ${seconds()} s of ${limit} s`);
|
|
457
|
+
else if (seconds() - lastLogged >= 30) {
|
|
458
|
+
lastLogged = seconds();
|
|
459
|
+
deps.log(` … ${lastLogged} s`);
|
|
460
|
+
}
|
|
461
|
+
deps.sleep(1_000);
|
|
462
|
+
}
|
|
442
463
|
}
|
|
464
|
+
deps.progress?.('');
|
|
443
465
|
deps.log(
|
|
444
466
|
`! ${name}@${version} not visible on the registry after ${Math.round(deps.registryWaitMs / 60_000)} min — ` +
|
|
445
467
|
`npm accepted it; check later: npm view ${name}@${version} version`,
|