@guiho/runx 0.2.7 → 0.4.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 +39 -0
- package/DOCS.md +127 -128
- package/README.md +56 -75
- package/devops/build-binaries.ts +44 -62
- package/devops/devops.xdocs.md +8 -5
- package/devops/install.ps1 +182 -152
- package/devops/install.sh +197 -262
- package/devops/installers.spec.ts +31 -0
- package/devops/verify-release-assets.ts +17 -0
- package/docs/docs.xdocs.md +3 -1
- package/docs/plans/plans.xdocs.md +7 -0
- package/docs/plans/rfc-0034-cli-compliance-migration.md +586 -0
- package/docs/plans/upgrade-reliability-implementation.md +95 -0
- package/docs/reviews/implementation/implementation.xdocs.md +2 -0
- package/docs/reviews/implementation/rfc-0034-cli-compliance-migration-review.md +69 -0
- package/docs/reviews/plans/plans.xdocs.md +6 -0
- package/docs/reviews/plans/rfc-0034-cli-compliance-migration-review.md +80 -0
- package/docs/reviews/plans/upgrade-reliability-implementation-review.md +65 -0
- package/docs/superpowers/specs/2026-07-15-upgrade-reliability-design.md +662 -0
- package/docs/superpowers/specs/specs.xdocs.md +24 -0
- package/docs/superpowers/superpowers.xdocs.md +21 -0
- package/docs/todo/rfc-0034-cli-compliance-migration-implementation.md +77 -0
- package/docs/todo/rfc-0034-cli-compliance-migration.md +152 -0
- package/docs/todo/todo.xdocs.md +6 -2
- package/docs/validation/rfc-0034-cli-compliance-migration.md +83 -0
- package/docs/validation/upgrade-reliability.md +124 -0
- package/docs/validation/validation.xdocs.md +5 -0
- package/library/agents.d.ts +29 -4
- package/library/agents.d.ts.map +1 -1
- package/library/agents.js +143 -41
- package/library/cli.d.ts.map +1 -1
- package/library/cli.js +311 -331
- package/library/configuration.d.ts +57 -0
- package/library/configuration.d.ts.map +1 -0
- package/library/configuration.js +111 -0
- package/library/embedded-resources.d.ts +6 -1
- package/library/embedded-resources.d.ts.map +1 -1
- package/library/embedded-resources.js +10 -4
- package/library/executor.d.ts +5 -1
- package/library/executor.d.ts.map +1 -1
- package/library/executor.js +10 -10
- package/library/help.d.ts +8 -4
- package/library/help.d.ts.map +1 -1
- package/library/help.js +70 -46
- package/library/init.d.ts +8 -27
- package/library/init.d.ts.map +1 -1
- package/library/init.js +37 -159
- package/library/manifest.d.ts +4 -43
- package/library/manifest.d.ts.map +1 -1
- package/library/manifest.js +4 -125
- package/library/path-utils.d.ts +13 -0
- package/library/path-utils.d.ts.map +1 -0
- package/library/path-utils.js +82 -0
- package/library/recovery.d.ts +7 -0
- package/library/recovery.d.ts.map +1 -0
- package/library/recovery.js +23 -0
- package/library/release-catalog.d.ts +32 -0
- package/library/release-catalog.d.ts.map +1 -0
- package/library/release-catalog.js +124 -0
- package/library/self-management.d.ts +24 -4
- package/library/self-management.d.ts.map +1 -1
- package/library/self-management.js +279 -99
- package/library/storage.d.ts +13 -0
- package/library/storage.d.ts.map +1 -0
- package/library/storage.js +38 -0
- package/library/types.d.ts +11 -16
- package/library/types.d.ts.map +1 -1
- package/library/types.js +3 -0
- package/library/update-cache.d.ts +21 -0
- package/library/update-cache.d.ts.map +1 -0
- package/library/update-cache.js +68 -0
- package/library/upgrade-reporting.d.ts +11 -0
- package/library/upgrade-reporting.d.ts.map +1 -0
- package/library/upgrade-reporting.js +67 -0
- package/library/upgrade-types.d.ts +72 -0
- package/library/upgrade-types.d.ts.map +1 -0
- package/library/upgrade-types.js +3 -0
- package/package.json +6 -3
- package/scripts/runx-bin.mjs +49 -0
- package/scripts/runx-bin.spec.ts +62 -0
- package/scripts/scripts.xdocs.md +3 -3
- package/skills/guiho-s-runx/SKILL.md +64 -59
- package/skills/guiho-s-runx/guiho-s-runx.xdocs.md +7 -4
- package/skills/skills.xdocs.md +1 -1
- package/docs/todo/implement-runx-alpha.md +0 -36
- package/scripts/runx-bin.ts +0 -24
package/library/types.d.ts
CHANGED
|
@@ -1,31 +1,26 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
export type ResolvedCommand
|
|
1
|
+
/**
|
|
2
|
+
* @copyright Copyright © 2026 GUIHO Technologies as represented by Cristóvão GUIHO. All Rights Reserved.
|
|
3
|
+
*/
|
|
4
|
+
import type { RunXCommand, RunXManifest } from './configuration.js';
|
|
5
|
+
export type { AgentScope, CliOptions, OutputFormat, ResolvedCommand, RunXCommand, RunXManifest, UpdateResult, };
|
|
6
|
+
type ResolvedCommand = RunXCommand & {
|
|
6
7
|
index: number;
|
|
7
8
|
selector: string;
|
|
8
9
|
manifestPath: string;
|
|
9
10
|
cwd: string;
|
|
10
11
|
};
|
|
11
|
-
|
|
12
|
-
|
|
12
|
+
type OutputFormat = 'text' | 'json';
|
|
13
|
+
type CliOptions = {
|
|
13
14
|
cwd: string;
|
|
14
|
-
|
|
15
|
+
config?: string;
|
|
15
16
|
format: OutputFormat;
|
|
16
17
|
verbose: boolean;
|
|
17
18
|
};
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
export type UpdateResult = {
|
|
19
|
+
type AgentScope = 'local' | 'global';
|
|
20
|
+
type UpdateResult = {
|
|
21
21
|
currentVersion: string;
|
|
22
22
|
latestVersion: string;
|
|
23
23
|
updateAvailable: boolean;
|
|
24
24
|
url?: string;
|
|
25
25
|
};
|
|
26
|
-
export type RunXUpgradeResult = UpdateResult & {
|
|
27
|
-
executablePath: string;
|
|
28
|
-
scheduled: boolean;
|
|
29
|
-
upToDate: boolean;
|
|
30
|
-
};
|
|
31
26
|
//# sourceMappingURL=types.d.ts.map
|
package/library/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../source/types.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../source/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAEnE,YAAY,EACV,UAAU,EACV,UAAU,EACV,YAAY,EACZ,eAAe,EACf,WAAW,EACX,YAAY,EACZ,YAAY,GACb,CAAA;AAED,KAAK,eAAe,GAAG,WAAW,GAAG;IACnC,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,EAAE,MAAM,CAAA;IAChB,YAAY,EAAE,MAAM,CAAA;IACpB,GAAG,EAAE,MAAM,CAAA;CACZ,CAAA;AAED,KAAK,YAAY,GAAG,MAAM,GAAG,MAAM,CAAA;AAEnC,KAAK,UAAU,GAAG;IAChB,GAAG,EAAE,MAAM,CAAA;IACX,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,MAAM,EAAE,YAAY,CAAA;IACpB,OAAO,EAAE,OAAO,CAAA;CACjB,CAAA;AAED,KAAK,UAAU,GAAG,OAAO,GAAG,QAAQ,CAAA;AAEpC,KAAK,YAAY,GAAG;IAClB,cAAc,EAAE,MAAM,CAAA;IACtB,aAAa,EAAE,MAAM,CAAA;IACrB,eAAe,EAAE,OAAO,CAAA;IACxB,GAAG,CAAC,EAAE,MAAM,CAAA;CACb,CAAA"}
|
package/library/types.js
CHANGED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @copyright Copyright © 2026 GUIHO Technologies as represented by Cristóvão GUIHO. All Rights Reserved.
|
|
3
|
+
*/
|
|
4
|
+
import type { Static } from '@sinclair/typebox';
|
|
5
|
+
export { cacheSchema, readCachedUpdateNotice, runUpdateWorker, spawnUpdateWorker, updateCachePath, };
|
|
6
|
+
export type { UpdateCache, };
|
|
7
|
+
declare const cacheSchema: import("@sinclair/typebox").TObject<{
|
|
8
|
+
newVersionAvailable: import("@sinclair/typebox").TBoolean;
|
|
9
|
+
latestVersion: import("@sinclair/typebox").TString;
|
|
10
|
+
upgradeCommand: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
11
|
+
lastCheck: import("@sinclair/typebox").TString;
|
|
12
|
+
}>;
|
|
13
|
+
type UpdateCache = Static<typeof cacheSchema>;
|
|
14
|
+
declare function updateCachePath(): string;
|
|
15
|
+
declare function readCachedUpdateNotice(verbose?: boolean): Promise<string | null>;
|
|
16
|
+
declare function spawnUpdateWorker(): void;
|
|
17
|
+
declare function runUpdateWorker(options?: {
|
|
18
|
+
fetchImpl?: typeof fetch;
|
|
19
|
+
now?: () => Date;
|
|
20
|
+
}): Promise<UpdateCache>;
|
|
21
|
+
//# sourceMappingURL=update-cache.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"update-cache.d.ts","sourceRoot":"","sources":["../source/update-cache.ts"],"names":[],"mappings":"AAAA;;GAEG;AAUH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAA;AAE/C,OAAO,EACL,WAAW,EACX,sBAAsB,EACtB,eAAe,EACf,iBAAiB,EACjB,eAAe,GAChB,CAAA;AACD,YAAY,EACV,WAAW,GACZ,CAAA;AAED,QAAA,MAAM,WAAW;;;;;EAKkB,CAAA;AAEnC,KAAK,WAAW,GAAG,MAAM,CAAC,OAAO,WAAW,CAAC,CAAA;AAE7C,iBAAS,eAAe,IAAI,MAAM,CAEjC;AAED,iBAAe,sBAAsB,CAAC,OAAO,UAAQ,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAY7E;AAED,iBAAS,iBAAiB,IAAI,IAAI,CAYjC;AAED,iBAAe,eAAe,CAAC,OAAO,GAAE;IAAE,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,IAAI,CAAA;CAAO,GAAG,OAAO,CAAC,WAAW,CAAC,CAiBjH"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @copyright Copyright © 2026 GUIHO Technologies as represented by Cristóvão GUIHO. All Rights Reserved.
|
|
3
|
+
*/
|
|
4
|
+
import { Type } from '@sinclair/typebox';
|
|
5
|
+
import { Value } from '@sinclair/typebox/value';
|
|
6
|
+
import { gt, valid } from 'semver';
|
|
7
|
+
import { readVersion } from './help.js';
|
|
8
|
+
import { fetchReleaseCatalog, resolveUpgradePlatform } from './release-catalog.js';
|
|
9
|
+
import { globalRunXDirectory, movePath, readTextIfExists, writeTextFile } from './storage.js';
|
|
10
|
+
import { joinPath } from './path-utils.js';
|
|
11
|
+
export { cacheSchema, readCachedUpdateNotice, runUpdateWorker, spawnUpdateWorker, updateCachePath, };
|
|
12
|
+
const cacheSchema = Type.Object({
|
|
13
|
+
newVersionAvailable: Type.Boolean(),
|
|
14
|
+
latestVersion: Type.String(),
|
|
15
|
+
upgradeCommand: Type.Optional(Type.String()),
|
|
16
|
+
lastCheck: Type.String(),
|
|
17
|
+
}, { additionalProperties: false });
|
|
18
|
+
function updateCachePath() {
|
|
19
|
+
return joinPath(globalRunXDirectory(), 'cache.json');
|
|
20
|
+
}
|
|
21
|
+
async function readCachedUpdateNotice(verbose = false) {
|
|
22
|
+
const raw = await readTextIfExists(updateCachePath());
|
|
23
|
+
if (raw === null)
|
|
24
|
+
return null;
|
|
25
|
+
try {
|
|
26
|
+
const cache = Value.Decode(cacheSchema, JSON.parse(raw));
|
|
27
|
+
return cache.newVersionAvailable
|
|
28
|
+
? 'New version available. Run this command to upgrade: runx upgrade'
|
|
29
|
+
: null;
|
|
30
|
+
}
|
|
31
|
+
catch (error) {
|
|
32
|
+
if (verbose)
|
|
33
|
+
process.stderr.write(`warning: ignored invalid RunX update cache: ${error instanceof Error ? error.message : String(error)}\n`);
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
function spawnUpdateWorker() {
|
|
38
|
+
if (Bun.env.RUNX_DISABLE_UPDATE_WORKER === '1')
|
|
39
|
+
return;
|
|
40
|
+
const command = process.execPath.toLowerCase().includes('bun')
|
|
41
|
+
? [process.execPath, Bun.main, '--check-updates-worker']
|
|
42
|
+
: [process.execPath, '--check-updates-worker'];
|
|
43
|
+
Bun.spawn(command, {
|
|
44
|
+
detached: true,
|
|
45
|
+
stdout: 'ignore',
|
|
46
|
+
stderr: 'ignore',
|
|
47
|
+
stdin: 'ignore',
|
|
48
|
+
env: process.env,
|
|
49
|
+
}).unref();
|
|
50
|
+
}
|
|
51
|
+
async function runUpdateWorker(options = {}) {
|
|
52
|
+
const currentVersion = readVersion();
|
|
53
|
+
const platform = resolveUpgradePlatform();
|
|
54
|
+
const catalog = await fetchReleaseCatalog({ ...platform, currentVersion, fetchImpl: options.fetchImpl });
|
|
55
|
+
const latestVersion = catalog.latestStableVersion ?? currentVersion;
|
|
56
|
+
const newVersionAvailable = Boolean(valid(currentVersion) && valid(latestVersion) && gt(latestVersion, currentVersion));
|
|
57
|
+
const cache = {
|
|
58
|
+
newVersionAvailable,
|
|
59
|
+
latestVersion,
|
|
60
|
+
...(newVersionAvailable ? { upgradeCommand: 'runx upgrade' } : {}),
|
|
61
|
+
lastCheck: (options.now?.() ?? new Date()).toISOString(),
|
|
62
|
+
};
|
|
63
|
+
const path = updateCachePath();
|
|
64
|
+
const temporary = `${path}.${process.pid}.${crypto.randomUUID()}.tmp`;
|
|
65
|
+
await writeTextFile(temporary, `${JSON.stringify(cache, null, 2)}\n`);
|
|
66
|
+
await movePath(temporary, path);
|
|
67
|
+
return cache;
|
|
68
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @copyright Copyright © 2026 GUIHO Technologies as represented by Cristóvão GUIHO. All Rights Reserved.
|
|
3
|
+
*/
|
|
4
|
+
import type { ReleaseCatalog, UpgradeEnvelope, UpgradeEvent, UpgradePlan } from './upgrade-types.js';
|
|
5
|
+
export { renderReleaseCatalog, renderUpgradeEvent, renderUpgradeHeading, renderUpgradePlan, renderUpgradeResult, };
|
|
6
|
+
declare const renderUpgradeHeading: () => string;
|
|
7
|
+
declare const renderUpgradePlan: (plan: UpgradePlan) => string;
|
|
8
|
+
declare const renderUpgradeEvent: (event: UpgradeEvent) => string;
|
|
9
|
+
declare const renderUpgradeResult: (result: UpgradeEnvelope) => string;
|
|
10
|
+
declare const renderReleaseCatalog: (catalog: ReleaseCatalog) => string;
|
|
11
|
+
//# sourceMappingURL=upgrade-reporting.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"upgrade-reporting.d.ts","sourceRoot":"","sources":["../source/upgrade-reporting.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAwB,cAAc,EAAE,eAAe,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAE1H,OAAO,EACL,oBAAoB,EACpB,kBAAkB,EAClB,oBAAoB,EACpB,iBAAiB,EACjB,mBAAmB,GACpB,CAAA;AAED,QAAA,MAAM,oBAAoB,QAAO,MAId,CAAA;AAEnB,QAAA,MAAM,iBAAiB,SAAU,WAAW,KAAG,MAS5B,CAAA;AAEnB,QAAA,MAAM,kBAAkB,UAAW,YAAY,KAAG,MAWjD,CAAA;AAED,QAAA,MAAM,mBAAmB,WAAY,eAAe,KAAG,MAWtD,CAAA;AAYD,QAAA,MAAM,oBAAoB,YAAa,cAAc,KAAG,MAavD,CAAA"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @copyright Copyright © 2026 GUIHO Technologies as represented by Cristóvão GUIHO. All Rights Reserved.
|
|
3
|
+
*/
|
|
4
|
+
export { renderReleaseCatalog, renderUpgradeEvent, renderUpgradeHeading, renderUpgradePlan, renderUpgradeResult, };
|
|
5
|
+
const renderUpgradeHeading = () => [
|
|
6
|
+
'------------------------------------------------------------',
|
|
7
|
+
' Upgrading the CLI',
|
|
8
|
+
'------------------------------------------------------------',
|
|
9
|
+
].join('\n') + '\n';
|
|
10
|
+
const renderUpgradePlan = (plan) => [
|
|
11
|
+
` current : ${plan.currentVersion}`,
|
|
12
|
+
` target : ${plan.targetVersion}`,
|
|
13
|
+
` os : ${plan.os}`,
|
|
14
|
+
` arch : ${plan.arch}`,
|
|
15
|
+
` binary : ${plan.assetName}`,
|
|
16
|
+
` path : ${plan.executablePath.replaceAll('\\', '/')}`,
|
|
17
|
+
` url : ${plan.assetUrl}`,
|
|
18
|
+
'------------------------------------------------------------',
|
|
19
|
+
].join('\n') + '\n';
|
|
20
|
+
const renderUpgradeEvent = (event) => {
|
|
21
|
+
if (event.status !== 'started' || event.phase === 'plan')
|
|
22
|
+
return '';
|
|
23
|
+
const labels = {
|
|
24
|
+
download: 'Downloading...',
|
|
25
|
+
validate: 'Validating...',
|
|
26
|
+
replace: 'Replacing...',
|
|
27
|
+
verify: 'Verifying...',
|
|
28
|
+
cleanup: 'Cleaning up...',
|
|
29
|
+
};
|
|
30
|
+
const label = labels[event.phase];
|
|
31
|
+
return label ? `${label}\n` : '';
|
|
32
|
+
};
|
|
33
|
+
const renderUpgradeResult = (result) => {
|
|
34
|
+
const summary = result.outcome === 'upgraded'
|
|
35
|
+
? `Upgrade complete: ${result.plan?.currentVersion} -> ${result.plan?.targetVersion}`
|
|
36
|
+
: result.outcome === 'up-to-date'
|
|
37
|
+
? `Already up to date: ${result.result?.installedVersion ?? result.recovery.targetVersion}`
|
|
38
|
+
: result.outcome === 'dry-run'
|
|
39
|
+
? `Dry run complete: ${result.plan?.currentVersion} -> ${result.plan?.targetVersion}`
|
|
40
|
+
: result.outcome === 'rolled-back'
|
|
41
|
+
? `Upgrade failed during ${result.error?.phase ?? 'replace'}; restored RunX ${result.result?.installedVersion ?? result.recovery.targetVersion}.`
|
|
42
|
+
: `Upgrade failed during ${result.error?.phase ?? 'plan'}.`;
|
|
43
|
+
return `${summary}\n\n${renderRecovery(result.recovery, result.outcome === 'failed' || result.outcome === 'rolled-back')}\n`;
|
|
44
|
+
};
|
|
45
|
+
const renderRecovery = (recovery, repair) => [
|
|
46
|
+
recovery.targetSource === 'fallback-current'
|
|
47
|
+
? `Repair reinstall (target lookup failed; pinned to installed RunX ${recovery.targetVersion}):`
|
|
48
|
+
: `${repair ? 'To repair RunX' : 'If the new version is not active'}, install RunX ${recovery.targetVersion} directly:`,
|
|
49
|
+
` ${recovery.installCommand}`,
|
|
50
|
+
'',
|
|
51
|
+
'If RunX is still running and blocks installation, stop it first:',
|
|
52
|
+
` ${recovery.stopProcessCommand}`,
|
|
53
|
+
].join('\n');
|
|
54
|
+
const renderReleaseCatalog = (catalog) => {
|
|
55
|
+
const headers = ['VERSION', 'CHANNEL', 'PUBLISHED', 'CURRENT', 'LATEST', 'ASSET'];
|
|
56
|
+
const rows = catalog.releases.map((release) => [
|
|
57
|
+
release.version,
|
|
58
|
+
release.channel,
|
|
59
|
+
release.publishedAt?.slice(0, 10) ?? '-',
|
|
60
|
+
release.current ? 'yes' : '',
|
|
61
|
+
release.latestStable ? 'yes' : '',
|
|
62
|
+
release.compatibleAsset ? 'yes' : 'no',
|
|
63
|
+
]);
|
|
64
|
+
const widths = headers.map((header, index) => Math.max(header.length, ...rows.map((row) => row[index]?.length ?? 0)));
|
|
65
|
+
const line = (values) => values.map((value, index) => value.padEnd(widths[index] ?? value.length)).join(' ').trimEnd();
|
|
66
|
+
return ['AVAILABLE RUNX VERSIONS', '', line(headers), ...rows.map(line)].join('\n') + '\n';
|
|
67
|
+
};
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @copyright Copyright © 2026 GUIHO Technologies as represented by Cristóvão GUIHO. All Rights Reserved.
|
|
3
|
+
*/
|
|
4
|
+
export type UpgradeOs = 'windows' | 'darwin' | 'linux';
|
|
5
|
+
export type UpgradeArch = 'x64' | 'arm64';
|
|
6
|
+
export type UpgradeVariant = 'baseline' | 'default' | 'modern';
|
|
7
|
+
export type ReleaseAsset = {
|
|
8
|
+
name: string;
|
|
9
|
+
url: string;
|
|
10
|
+
};
|
|
11
|
+
export type ReleaseCatalogEntry = {
|
|
12
|
+
tag: string;
|
|
13
|
+
version: string;
|
|
14
|
+
channel: string;
|
|
15
|
+
prerelease: boolean;
|
|
16
|
+
publishedAt: string | null;
|
|
17
|
+
current: boolean;
|
|
18
|
+
latestStable: boolean;
|
|
19
|
+
compatibleAsset: ReleaseAsset | null;
|
|
20
|
+
};
|
|
21
|
+
export type ReleaseCatalog = {
|
|
22
|
+
schemaVersion: 1;
|
|
23
|
+
command: 'runx upgrade list';
|
|
24
|
+
currentVersion: string;
|
|
25
|
+
latestStableVersion: string | null;
|
|
26
|
+
releases: ReleaseCatalogEntry[];
|
|
27
|
+
};
|
|
28
|
+
export type RecoveryInstructions = {
|
|
29
|
+
targetVersion: string;
|
|
30
|
+
targetSource: 'resolved' | 'fallback-current';
|
|
31
|
+
installCommand: string;
|
|
32
|
+
stopProcessCommand: string;
|
|
33
|
+
};
|
|
34
|
+
export type UpgradePlan = {
|
|
35
|
+
currentVersion: string;
|
|
36
|
+
targetVersion: string;
|
|
37
|
+
os: UpgradeOs;
|
|
38
|
+
arch: UpgradeArch;
|
|
39
|
+
assetName: string;
|
|
40
|
+
assetUrl: string;
|
|
41
|
+
executablePath: string;
|
|
42
|
+
};
|
|
43
|
+
export type UpgradePhase = 'plan' | 'download' | 'validate' | 'replace' | 'verify' | 'cache' | 'cleanup';
|
|
44
|
+
export type UpgradePhaseStatus = 'started' | 'succeeded' | 'skipped' | 'failed';
|
|
45
|
+
export type UpgradeEvent = {
|
|
46
|
+
sequence: number;
|
|
47
|
+
phase: UpgradePhase;
|
|
48
|
+
status: UpgradePhaseStatus;
|
|
49
|
+
message?: string;
|
|
50
|
+
};
|
|
51
|
+
export type UpgradeOutcome = 'upgraded' | 'up-to-date' | 'dry-run' | 'rolled-back' | 'failed';
|
|
52
|
+
export type UpgradeResult = {
|
|
53
|
+
installedVersion: string;
|
|
54
|
+
cleanupDeferred: boolean;
|
|
55
|
+
};
|
|
56
|
+
export type UpgradeErrorCode = 'release_lookup_failed' | 'release_payload_invalid' | 'no_compatible_asset' | 'download_failed' | 'download_invalid' | 'backup_failed' | 'replace_failed' | 'verification_failed' | 'rollback_failed' | 'installer_verification_failed';
|
|
57
|
+
export type UpgradeError = {
|
|
58
|
+
code: UpgradeErrorCode;
|
|
59
|
+
phase: UpgradePhase;
|
|
60
|
+
message: string;
|
|
61
|
+
};
|
|
62
|
+
export type UpgradeEnvelope = {
|
|
63
|
+
schemaVersion: 1;
|
|
64
|
+
command: 'runx upgrade';
|
|
65
|
+
outcome: UpgradeOutcome;
|
|
66
|
+
plan: UpgradePlan | null;
|
|
67
|
+
events: UpgradeEvent[];
|
|
68
|
+
result: UpgradeResult | null;
|
|
69
|
+
recovery: RecoveryInstructions;
|
|
70
|
+
error: UpgradeError | null;
|
|
71
|
+
};
|
|
72
|
+
//# sourceMappingURL=upgrade-types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"upgrade-types.d.ts","sourceRoot":"","sources":["../source/upgrade-types.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@guiho/runx",
|
|
3
3
|
"description": "A language-agnostic, documented command catalog and local CLI executor.",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.4.1",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./library/guiho-runx.js",
|
|
7
7
|
"types": "./library/guiho-runx.d.ts",
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
}
|
|
13
13
|
},
|
|
14
14
|
"bin": {
|
|
15
|
-
"runx": "scripts/runx-bin.
|
|
15
|
+
"runx": "scripts/runx-bin.mjs"
|
|
16
16
|
},
|
|
17
17
|
"files": [
|
|
18
18
|
"library/",
|
|
@@ -57,6 +57,7 @@
|
|
|
57
57
|
"build": "rm -rf library && tsc -p .",
|
|
58
58
|
"binary": "bun build source/guiho-runx-native-bin.ts --compile --outfile bin/runx",
|
|
59
59
|
"binaries": "bun run devops/build-binaries.ts",
|
|
60
|
+
"verify-assets": "bun run devops/verify-release-assets.ts",
|
|
60
61
|
"test": "bun test",
|
|
61
62
|
"typecheck": "tsc -p . --noEmit",
|
|
62
63
|
"check": "bun run typecheck && bun test",
|
|
@@ -69,10 +70,12 @@
|
|
|
69
70
|
},
|
|
70
71
|
"dependencies": {
|
|
71
72
|
"@sinclair/typebox": "^0.34.52",
|
|
72
|
-
"citty": "^0.2.2"
|
|
73
|
+
"citty": "^0.2.2",
|
|
74
|
+
"semver": "^7.8.5"
|
|
73
75
|
},
|
|
74
76
|
"devDependencies": {
|
|
75
77
|
"@types/bun": "^1.3.14",
|
|
78
|
+
"@types/semver": "^7.7.1",
|
|
76
79
|
"typescript": "^7.0.2"
|
|
77
80
|
}
|
|
78
81
|
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @copyright Copyright © 2026 GUIHO Technologies as represented by Cristóvão GUIHO. All Rights Reserved.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { spawn } from 'node:child_process'
|
|
8
|
+
import { chmod, mkdir, rename, rm, stat, writeFile } from 'node:fs/promises'
|
|
9
|
+
import { arch, homedir, platform } from 'node:os'
|
|
10
|
+
import { join } from 'node:path'
|
|
11
|
+
|
|
12
|
+
import packageJson from '../package.json' with { type: 'json' }
|
|
13
|
+
|
|
14
|
+
const os = platform() === 'win32' ? 'windows' : platform() === 'darwin' ? 'darwin' : platform() === 'linux' ? 'linux' : null
|
|
15
|
+
const cpu = arch() === 'x64' ? 'x64' : arch() === 'arm64' ? 'arm64' : null
|
|
16
|
+
if (!os || !cpu) fail(`Unsupported platform: ${platform()} ${arch()}`)
|
|
17
|
+
|
|
18
|
+
const suffix = os === 'windows' ? '.exe' : ''
|
|
19
|
+
const asset = cpu === 'arm64' ? `runx-${os}-arm64${suffix}` : `runx-${os}-x64-baseline${suffix}`
|
|
20
|
+
const cache = process.env.RUNX_NATIVE_CACHE || join(homedir(), '.guiho', 'runx', 'npm', packageJson.version)
|
|
21
|
+
const executable = join(cache, `runx${suffix}`)
|
|
22
|
+
const tag = encodeURIComponent(`@guiho/runx@${packageJson.version}`)
|
|
23
|
+
const downloadBase = (process.env.RUNX_DOWNLOAD_BASE_URL || 'https://github.com/CGuiho/runx/releases/download').replace(/\/$/, '')
|
|
24
|
+
const url = `${downloadBase}/${tag}/${asset}`
|
|
25
|
+
|
|
26
|
+
try {
|
|
27
|
+
await stat(executable)
|
|
28
|
+
} catch {
|
|
29
|
+
await mkdir(cache, { recursive: true })
|
|
30
|
+
const response = await fetch(url, { redirect: 'follow' })
|
|
31
|
+
if (!response.ok) fail(`Could not download ${asset}: HTTP ${response.status}`)
|
|
32
|
+
const temporary = `${executable}.${process.pid}.tmp`
|
|
33
|
+
await writeFile(temporary, new Uint8Array(await response.arrayBuffer()), { flag: 'wx' })
|
|
34
|
+
if (os !== 'windows') await chmod(temporary, 0o755)
|
|
35
|
+
await rename(temporary, executable)
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const child = spawn(executable, process.argv.slice(2), { env: process.env, stdio: 'inherit' })
|
|
39
|
+
child.once('error', (error) => fail(error.message))
|
|
40
|
+
child.once('exit', (code, signal) => {
|
|
41
|
+
if (signal) process.kill(process.pid, signal)
|
|
42
|
+
else process.exit(code ?? 1)
|
|
43
|
+
})
|
|
44
|
+
|
|
45
|
+
function fail(message) {
|
|
46
|
+
process.stderr.write(`error: ${message}\n`)
|
|
47
|
+
void rm(executable, { force: true }).catch(() => undefined)
|
|
48
|
+
process.exit(1)
|
|
49
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @copyright Copyright © 2026 GUIHO Technologies as represented by Cristóvão GUIHO. All Rights Reserved.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { afterEach, expect, test } from 'bun:test'
|
|
6
|
+
import { mkdtemp, rm } from 'node:fs/promises'
|
|
7
|
+
import { tmpdir } from 'node:os'
|
|
8
|
+
import { join } from 'node:path'
|
|
9
|
+
|
|
10
|
+
let directory = ''
|
|
11
|
+
|
|
12
|
+
afterEach(async () => {
|
|
13
|
+
if (directory) await rm(directory, { recursive: true, force: true })
|
|
14
|
+
directory = ''
|
|
15
|
+
})
|
|
16
|
+
|
|
17
|
+
test('packed npm bootstrap downloads and delegates with Node while Bun is absent from PATH', async () => {
|
|
18
|
+
const node = Bun.which('node')
|
|
19
|
+
if (!node) throw new Error('Node is required for the npm bootstrap test.')
|
|
20
|
+
directory = await mkdtemp(join(tmpdir(), 'runx-npm-'))
|
|
21
|
+
const root = Bun.fileURLToPath(new URL('..', import.meta.url))
|
|
22
|
+
const packed = Bun.spawn([process.execPath, 'pm', 'pack', '--destination', directory, '--ignore-scripts'], {
|
|
23
|
+
cwd: root,
|
|
24
|
+
stdout: 'pipe',
|
|
25
|
+
stderr: 'pipe',
|
|
26
|
+
})
|
|
27
|
+
const [packCode, packOutput, packError] = await Promise.all([
|
|
28
|
+
packed.exited,
|
|
29
|
+
new Response(packed.stdout).text(),
|
|
30
|
+
new Response(packed.stderr).text(),
|
|
31
|
+
])
|
|
32
|
+
expect(packCode, packError).toBe(0)
|
|
33
|
+
const archiveName = [...new Bun.Glob('*.tgz').scanSync({ cwd: directory, onlyFiles: true })][0]
|
|
34
|
+
expect(archiveName, packOutput).toBeDefined()
|
|
35
|
+
const extraction = Bun.spawn(['tar', '-xzf', join(directory, archiveName), '-C', directory])
|
|
36
|
+
expect(await extraction.exited).toBe(0)
|
|
37
|
+
|
|
38
|
+
const server = Bun.serve({ port: 0, fetch: () => new Response(Bun.file(process.execPath)) })
|
|
39
|
+
try {
|
|
40
|
+
const wrapper = join(directory, 'package', 'scripts', 'runx-bin.mjs')
|
|
41
|
+
const child = Bun.spawn([node, wrapper, '--version'], {
|
|
42
|
+
cwd: join(directory, 'package'),
|
|
43
|
+
env: {
|
|
44
|
+
...process.env,
|
|
45
|
+
PATH: join(node, '..'),
|
|
46
|
+
RUNX_NATIVE_CACHE: join(directory, 'native-cache'),
|
|
47
|
+
RUNX_DOWNLOAD_BASE_URL: `http://127.0.0.1:${server.port}`,
|
|
48
|
+
},
|
|
49
|
+
stdout: 'pipe',
|
|
50
|
+
stderr: 'pipe',
|
|
51
|
+
})
|
|
52
|
+
const [exitCode, stdout, stderr] = await Promise.all([
|
|
53
|
+
child.exited,
|
|
54
|
+
new Response(child.stdout).text(),
|
|
55
|
+
new Response(child.stderr).text(),
|
|
56
|
+
])
|
|
57
|
+
expect(exitCode, stderr).toBe(0)
|
|
58
|
+
expect(stdout.trim()).toBe(process.versions.bun)
|
|
59
|
+
} finally {
|
|
60
|
+
server.stop(true)
|
|
61
|
+
}
|
|
62
|
+
})
|
package/scripts/scripts.xdocs.md
CHANGED
|
@@ -4,7 +4,8 @@ description: Package-manager launcher scripts for RunX.
|
|
|
4
4
|
parent: runx
|
|
5
5
|
children: []
|
|
6
6
|
files:
|
|
7
|
-
runx-bin.
|
|
7
|
+
runx-bin.mjs: Node-compatible npm bootstrap that downloads, caches, and delegates to the exact native release binary.
|
|
8
|
+
runx-bin.spec.ts: Packs the npm package and proves Node-only bootstrap download/delegation with Bun absent from PATH.
|
|
8
9
|
documents: {}
|
|
9
10
|
tags:
|
|
10
11
|
- scripts
|
|
@@ -16,5 +17,4 @@ flags: []
|
|
|
16
17
|
status: stable
|
|
17
18
|
---
|
|
18
19
|
|
|
19
|
-
The
|
|
20
|
-
and development checkouts without requiring unpublished source files.
|
|
20
|
+
The npm launcher contains no RunX domain logic and requires no Bun installation.
|
|
@@ -1,73 +1,78 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: guiho-s-runx
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
created: 2026-07-
|
|
6
|
-
|
|
7
|
-
|
|
3
|
+
description: Use when inspecting, validating, documenting, or safely executing a RunX runx.yaml command catalog.
|
|
4
|
+
purpose: Teach agents the supported RunX catalog inspection and execution workflow.
|
|
5
|
+
created: 2026-07-18
|
|
6
|
+
flags:
|
|
7
|
+
- bundled
|
|
8
8
|
tags:
|
|
9
|
-
- agents
|
|
10
9
|
- runx
|
|
10
|
+
- cli
|
|
11
11
|
keywords:
|
|
12
|
-
- runx
|
|
13
|
-
- citty
|
|
12
|
+
- runx.yaml
|
|
14
13
|
- command catalog
|
|
15
14
|
- dry run
|
|
15
|
+
owner: guiho-s-runx
|
|
16
|
+
metadata:
|
|
17
|
+
version: "0.2.0"
|
|
16
18
|
---
|
|
17
19
|
|
|
18
20
|
# GUIHO RunX
|
|
19
21
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
- `runx
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
- Use `runx <command> --help` for command-specific Citty usage. `runx -h` and
|
|
46
|
-
`runx -v` are global operations and do not require a manifest.
|
|
47
|
-
|
|
48
|
-
## Maintain Manifests
|
|
49
|
-
|
|
50
|
-
- Keep `uid`, `id`, `group`, `summary`, `description`, and `command` present.
|
|
51
|
-
- Keep UIDs stable; never reuse a UID for a materially different command.
|
|
52
|
-
- Use a group for organization, a concise summary for listings, and a complete
|
|
53
|
-
description for prerequisites, effects, and risk.
|
|
54
|
-
- Set `confirm: always` for destructive, release, deployment, migration, and
|
|
55
|
-
production-impacting commands when confirmation is useful.
|
|
56
|
-
- Run `runx check` after every manifest change. It rejects unknown fields,
|
|
57
|
-
duplicate UIDs/selectors, missing descriptions, invalid working directories,
|
|
58
|
-
and unsupported shell choices.
|
|
59
|
-
|
|
60
|
-
## Useful Commands
|
|
22
|
+
## Inspect Before Execution
|
|
23
|
+
|
|
24
|
+
1. Run `runx check --format json`.
|
|
25
|
+
2. Run `runx list --format json`.
|
|
26
|
+
3. Prefer a stable UID for automation.
|
|
27
|
+
4. Run `runx describe <uid>` before unfamiliar work.
|
|
28
|
+
5. Run `runx run <uid> --dry-run` before any mutation or high-impact command.
|
|
29
|
+
|
|
30
|
+
RunX manifests are trusted executable code. A group name is not a safety
|
|
31
|
+
boundary. Never add `--yes` unless the developer explicitly authorizes the
|
|
32
|
+
specific confirmation-gated command.
|
|
33
|
+
|
|
34
|
+
## Configuration
|
|
35
|
+
|
|
36
|
+
RunX resolves YAML only:
|
|
37
|
+
|
|
38
|
+
1. `--config <path>`;
|
|
39
|
+
2. effective-cwd `runx.yaml`;
|
|
40
|
+
3. `~/.guiho/runx/runx.yaml`.
|
|
41
|
+
|
|
42
|
+
It does not search parent directories.
|
|
43
|
+
|
|
44
|
+
## Execute
|
|
45
|
+
|
|
46
|
+
Use only:
|
|
61
47
|
|
|
62
48
|
```text
|
|
63
|
-
runx
|
|
64
|
-
runx -h Show generated command help.
|
|
65
|
-
runx -v Show the installed version.
|
|
66
|
-
runx list List the nearest manifest.
|
|
67
|
-
runx describe <uid> Explain one command without execution.
|
|
68
|
-
runx run <uid> --dry-run Inspect the execution plan.
|
|
69
|
-
runx r <uid> Run through the short alias.
|
|
70
|
-
runx agents install local Install this skill into .agents/skills.
|
|
71
|
-
runx --help-tree Show the command hierarchy.
|
|
72
|
-
runx --help-docs Show manifest documentation guidance.
|
|
49
|
+
runx run <uid>
|
|
73
50
|
```
|
|
51
|
+
|
|
52
|
+
Listing, describing, checking, help, agent operations, and dry runs must never
|
|
53
|
+
execute a manifest command. Preserve the child command's exact exit code.
|
|
54
|
+
|
|
55
|
+
## Maintain Catalogs
|
|
56
|
+
|
|
57
|
+
- Keep `uid`, `id`, `group`, `summary`, `description`, and `command`.
|
|
58
|
+
- Keep UIDs stable and never reuse one for materially different behavior.
|
|
59
|
+
- Use `confirm: always` for destructive, release, deployment, migration, and
|
|
60
|
+
production-impacting operations.
|
|
61
|
+
- Do not place secrets in `runx.yaml`.
|
|
62
|
+
- Run `runx check` after every change.
|
|
63
|
+
|
|
64
|
+
## Agent And Upgrade Commands
|
|
65
|
+
|
|
66
|
+
```text
|
|
67
|
+
runx agent skill list
|
|
68
|
+
runx agent skill show guiho-s-runx
|
|
69
|
+
runx agent instruction show
|
|
70
|
+
runx agent prompt list --names
|
|
71
|
+
runx agent prompt show guiho-i-runx
|
|
72
|
+
runx upgrade check
|
|
73
|
+
runx upgrade list
|
|
74
|
+
runx upgrade --dry-run
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
Use `--help`, `--help-tree`, or `--help-docs` at any command scope for the
|
|
78
|
+
current executable contract.
|