@volter/sdk 0.5.208 → 0.5.210
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
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@volter/sdk",
|
|
3
3
|
"author": "Volter AI, Inc.",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
|
-
"version": "0.5.
|
|
5
|
+
"version": "0.5.210",
|
|
6
6
|
"publishConfig": {
|
|
7
7
|
"access": "public"
|
|
8
8
|
},
|
|
@@ -487,7 +487,7 @@
|
|
|
487
487
|
"@fortawesome/react-fontawesome": "^3.2.0",
|
|
488
488
|
"@storybook/react": "10.6.0",
|
|
489
489
|
"@types/node": "^22.0.0",
|
|
490
|
-
"@volter/project": "0.5.
|
|
490
|
+
"@volter/project": "0.5.210",
|
|
491
491
|
"mediabunny": "1.56.2",
|
|
492
492
|
"postcss": "8.5.28",
|
|
493
493
|
"rrweb": "2.1.6",
|
|
@@ -52,14 +52,36 @@ export function commandLine(verb: string): string {
|
|
|
52
52
|
}
|
|
53
53
|
|
|
54
54
|
/**
|
|
55
|
-
*
|
|
56
|
-
* `
|
|
57
|
-
*
|
|
55
|
+
* The npx a person types on this machine. Windows PowerShell's script policy
|
|
56
|
+
* refuses the bare `npx` (its `.ps1` shim) where `npx.cmd` runs in every shell
|
|
57
|
+
* (the 0.5.208 blind walk's returning user).
|
|
58
|
+
*/
|
|
59
|
+
function npx(): string {
|
|
60
|
+
const windows =
|
|
61
|
+
typeof navigator !== 'undefined'
|
|
62
|
+
? navigator.platform.startsWith('Win')
|
|
63
|
+
: (globalThis as { process?: { platform?: string } }).process?.platform === 'win32';
|
|
64
|
+
return windows ? 'npx.cmd' : 'npx';
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* One verb as a person runs it from the project folder, through the project's
|
|
69
|
+
* own install: `npx --no-install cyclotron edit .`. The bare command is on no
|
|
70
|
+
* PATH the install line or npx sets. `null` before the identity is known.
|
|
71
|
+
*/
|
|
72
|
+
export function projectCommandLine(verb: string): string | null {
|
|
73
|
+
return names ? `${npx()} --no-install ${names.command} ${verb}` : null;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Several verbs run in order from the project folder, one line each so the
|
|
78
|
+
* paste runs in any shell (`&&` is not Windows PowerShell 5.1's):
|
|
79
|
+
* `npx --no-install cyclotron close` then `npx --no-install cyclotron edit .`.
|
|
80
|
+
* Before the identity is known: ``the editor's `close`, then `edit .` ``.
|
|
58
81
|
*/
|
|
59
82
|
export function commandSequence(verbs: readonly string[]): string {
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
? verbs.map((verb) => `${known.command} ${verb}`).join(' && ')
|
|
83
|
+
return names
|
|
84
|
+
? verbs.map((verb) => projectCommandLine(verb)).join('\n')
|
|
63
85
|
: `the editor's ${verbs.map((verb) => `\`${verb}\``).join(', then ')}`;
|
|
64
86
|
}
|
|
65
87
|
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
export interface StartupFailureNotice {
|
|
23
23
|
readonly message: string;
|
|
24
24
|
readonly guidance: string | null;
|
|
25
|
-
/** The recovery
|
|
25
|
+
/** The recovery to paste, one command per line (`commandSequence`), when it has one. */
|
|
26
26
|
readonly command: string | null;
|
|
27
27
|
/**
|
|
28
28
|
* STILL TRYING, not refused: a slow start that may yet succeed (detection that keeps being
|
|
@@ -31,11 +31,13 @@
|
|
|
31
31
|
* `AGENTS.md`, `CLAUDE.md`), so the project's agent servers and instructions keep working.
|
|
32
32
|
*/
|
|
33
33
|
import { spawn } from 'node:child_process';
|
|
34
|
-
import { existsSync, lstatSync, readFileSync } from 'node:fs';
|
|
34
|
+
import { existsSync, lstatSync, readFileSync, statSync } from 'node:fs';
|
|
35
35
|
import { mkdir, readdir, readFile, rename, rm, rmdir, writeFile } from 'node:fs/promises';
|
|
36
36
|
import { dirname, join, relative, resolve, sep } from 'node:path';
|
|
37
37
|
import { MANIFEST_FILENAME } from '@volter/project/manifest/filename';
|
|
38
38
|
import { hasManifest } from '@volter/project/manifest/locate';
|
|
39
|
+
import { EDITOR_SESSION_DISCOVERY_TIMEOUT_MS, HttpSessionDiscovery } from './discovery';
|
|
40
|
+
import { readLiveRegisteredSessions } from './registry-format';
|
|
39
41
|
import { compareSemver } from './editor-compatibility';
|
|
40
42
|
|
|
41
43
|
export const UPGRADE_USAGE = "upgrade [version] # move this project's @volter packages and its engine pin to one release (default: latest); from a project made before 0.5.203, run the newest release's own: npx <package>@latest upgrade";
|
|
@@ -351,10 +353,44 @@ async function readRelease(product: UpgradingProduct, requested: string | undefi
|
|
|
351
353
|
return await npmView(spec);
|
|
352
354
|
} catch (error) {
|
|
353
355
|
const reason = error instanceof Error ? error.message : String(error);
|
|
354
|
-
throw new Error(`Could not read ${spec} from the registry (${reason}). Name a published version: ${product.command
|
|
356
|
+
throw new Error(`Could not read ${spec} from the registry (${reason}). Name a published version: ${projectLine(product.command, 'upgrade <version>')}.`);
|
|
355
357
|
}
|
|
356
358
|
}
|
|
357
359
|
|
|
360
|
+
/** Whether an editor session is open on `project` now (the same folder on disk, however it was typed).
|
|
361
|
+
* The Next lines close one first; with none open, `close` runs the project's OLD install, whose
|
|
362
|
+
* refusal before 0.5.210 was a wall about other sessions and exit 1. The registry names each live
|
|
363
|
+
* editor's project; a registered editor that did not answer may be this one, and a question nobody
|
|
364
|
+
* could answer keeps the close line. */
|
|
365
|
+
async function editorOpenOn(project: string): Promise<boolean> {
|
|
366
|
+
try {
|
|
367
|
+
const here = statSync(project, { bigint: true });
|
|
368
|
+
const isHere = (path: string | null): boolean => {
|
|
369
|
+
if (path === null) return false;
|
|
370
|
+
try {
|
|
371
|
+
const there = statSync(path, { bigint: true });
|
|
372
|
+
return there.dev === here.dev && there.ino === here.ino;
|
|
373
|
+
} catch {
|
|
374
|
+
return false;
|
|
375
|
+
}
|
|
376
|
+
};
|
|
377
|
+
const registered = readLiveRegisteredSessions();
|
|
378
|
+
if (registered.length === 0) return false;
|
|
379
|
+
if (registered.some((session) => isHere(session.project))) return true;
|
|
380
|
+
const answered = await new HttpSessionDiscovery().listSessions(EDITOR_SESSION_DISCOVERY_TIMEOUT_MS);
|
|
381
|
+
// listSessions drops a session whose probe failed, and throws only when none answered.
|
|
382
|
+
return answered.length < registered.length || answered.some((session) => isHere(session.project));
|
|
383
|
+
} catch {
|
|
384
|
+
return true;
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
/** A verb as a person runs it from the project folder, through its own install and in any shell (the Next lines
|
|
389
|
+
* at the end of `upgradeProject` say why). */
|
|
390
|
+
function projectLine(command: string, verb: string): string {
|
|
391
|
+
return `${process.platform === 'win32' ? 'npx.cmd' : 'npx'} --no-install ${command} ${verb}`;
|
|
392
|
+
}
|
|
393
|
+
|
|
358
394
|
export async function upgradeProject(product: UpgradingProduct, requested?: string, cwd = process.cwd()): Promise<void> {
|
|
359
395
|
if (requested !== undefined && !EXACT_VERSION.test(requested))
|
|
360
396
|
throw new Error(`${product.command} upgrade takes an exact version (e.g. 0.5.189), not "${requested}".`);
|
|
@@ -401,7 +437,7 @@ export async function upgradeProject(product: UpgradingProduct, requested?: stri
|
|
|
401
437
|
if (pkg.workspaces !== undefined) {
|
|
402
438
|
const members = Array.isArray(pkg.workspaces) ? pkg.workspaces
|
|
403
439
|
: Array.isArray((pkg.workspaces as { packages?: unknown }).packages) ? (pkg.workspaces as { packages: unknown[] }).packages : [];
|
|
404
|
-
kept.push(`workspace members${members.length > 0 ? ` (${members.map(String).join(', ')})` : ''} are not upgraded: run ${product.command
|
|
440
|
+
kept.push(`workspace members${members.length > 0 ? ` (${members.map(String).join(', ')})` : ''} are not upgraded: run ${projectLine(product.command, 'upgrade')} in each member that is a project`);
|
|
405
441
|
}
|
|
406
442
|
|
|
407
443
|
let packagesChanged = false;
|
|
@@ -588,7 +624,7 @@ export async function upgradeProject(product: UpgradingProduct, requested?: stri
|
|
|
588
624
|
if (requested === undefined)
|
|
589
625
|
throw new Error(
|
|
590
626
|
`${product.packageName}@latest is ${release.version} (engine ${engine}), older than the ${backwards} this project is on, so upgrading to it would move the project backwards. ` +
|
|
591
|
-
`Nothing was changed. To go back on purpose, name the version: ${product.command
|
|
627
|
+
`Nothing was changed. To go back on purpose, name the version: ${projectLine(product.command, `upgrade ${release.version}`)}.`,
|
|
592
628
|
);
|
|
593
629
|
warnings.push(`This moves the project BACKWARDS, from ${backwards} to ${product.packageName}@${release.version} (engine ${engine}), because that version was named.`);
|
|
594
630
|
}
|
|
@@ -650,20 +686,30 @@ export async function upgradeProject(product: UpgradingProduct, requested?: stri
|
|
|
650
686
|
for (const line of changed) console.log(` + ${line}`);
|
|
651
687
|
if (kept.length > 0) console.log('Left as it was:');
|
|
652
688
|
for (const line of kept) console.log(` = ${line}`);
|
|
689
|
+
// Every printed command runs as typed in any shell from the project folder: `&&` is not Windows
|
|
690
|
+
// PowerShell 5.1's, an inline `#` comment is an argument to cmd, the product's bare command is on
|
|
691
|
+
// no PATH an install line or npx sets, and PowerShell's script policy refuses a bare `npx`/`npm`
|
|
692
|
+
// (their `.ps1` shims) where the `.cmd` names run (the 0.5.208 blind walk's returning user).
|
|
693
|
+
const [npm, npx] = process.platform === 'win32' ? ['npm.cmd', 'npx.cmd'] : ['npm', 'npx'];
|
|
653
694
|
if (changed.length === 0) {
|
|
654
695
|
// NOTHING TO MOVE, YET AN EDITOR REFUSED: then the editor that refused is not this project's
|
|
655
696
|
// own installation (an older global install, another checkout), and saying "already on"
|
|
656
697
|
// alone left the person with no next step (#146 review).
|
|
657
|
-
console.log(`If an editor still refuses this project, it is running from another installation: open it with this project's own,
|
|
698
|
+
console.log(`If an editor still refuses this project, it is running from another installation: open it with this project's own, \`${npx} --no-install ${product.command} edit .\` in ${project}.`);
|
|
658
699
|
return;
|
|
659
700
|
}
|
|
660
701
|
if (retired !== null)
|
|
661
|
-
console.log(`This project now opens in ${product.packageName}. Its command is ${product.command}: from the project folder,
|
|
662
|
-
console.log(
|
|
663
|
-
if (packagesChanged && !linked) console.log(` npm install # in ${project}; installs the versions above`);
|
|
702
|
+
console.log(`This project now opens in ${product.packageName}. Its command is ${product.command}: from the project folder, \`${npx} --no-install ${product.command} <command>\`.`);
|
|
703
|
+
console.log(`Next, in ${project}, one line at a time:`);
|
|
664
704
|
// A running session keeps the editor it started with: new packages need a new session, while a
|
|
665
|
-
// pin that moved alone is read again by the page's Retry.
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
705
|
+
// pin that moved alone is read again by the page's Retry. The old session is closed before
|
|
706
|
+
// `npm install` replaces the packages under it, and by the command it was started with.
|
|
707
|
+
if (packagesChanged) {
|
|
708
|
+
if (await editorOpenOn(project))
|
|
709
|
+
console.log(` ${npx} --no-install ${linked ? product.command : retired?.command ?? product.command} close`);
|
|
710
|
+
if (!linked) console.log(` ${npm} install`);
|
|
711
|
+
console.log(` ${npx} --no-install ${product.command} edit .`);
|
|
712
|
+
} else {
|
|
713
|
+
console.log(` Press Retry on the editor page that refused the project, or run: ${npx} --no-install ${product.command} edit .`);
|
|
714
|
+
}
|
|
669
715
|
}
|