@guiho/runx 0.4.1 → 0.5.2
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 +56 -0
- package/DOCS.md +27 -5
- package/README.md +6 -1
- package/devops/build-binaries.ts +3 -3
- package/devops/devops.xdocs.md +9 -6
- package/devops/extract-release-notes.spec.ts +54 -0
- package/devops/extract-release-notes.ts +40 -0
- package/devops/install.ps1 +29 -6
- package/devops/install.sh +61 -22
- package/devops/installers.spec.ts +162 -5
- package/devops/verify-release-assets.ts +14 -0
- package/docs/architecture/architecture.xdocs.md +2 -1
- package/docs/architecture/cli-architecture.md +18 -9
- package/docs/decisions/decisions.xdocs.md +4 -0
- package/docs/decisions/markdown-release-assets-and-version-scoped-notes.md +84 -0
- package/docs/plans/automatic-agent-maintenance.md +120 -0
- package/docs/plans/linux-installer-latest-release.md +43 -0
- package/docs/plans/plans.xdocs.md +6 -0
- package/docs/plans/platform-aware-startup-greeting.md +43 -0
- package/docs/plans/rfc-0034-cli-compliance-migration.md +17 -8
- package/docs/plans/upgrade-reliability-implementation.md +1 -1
- package/docs/reviews/implementation/automatic-agent-maintenance-review.md +63 -0
- package/docs/reviews/implementation/bash-installer-review.md +42 -0
- package/docs/reviews/implementation/implementation.xdocs.md +14 -0
- package/docs/reviews/implementation/linux-installer-latest-release-review.md +49 -0
- package/docs/reviews/implementation/platform-aware-startup-greeting-review.md +51 -0
- package/docs/reviews/implementation/rfc-0034-cli-compliance-migration-review.md +5 -2
- package/docs/reviews/implementation/unicode-help-tree-review.md +41 -0
- package/docs/reviews/implementation/upgrade-reliability-issue-12-review.md +62 -0
- package/docs/reviews/implementation/upgrade-reliability-issue-13-review.md +63 -0
- package/docs/reviews/plans/automatic-agent-maintenance-review.md +56 -0
- package/docs/reviews/plans/plans.xdocs.md +2 -0
- package/docs/superpowers/specs/2026-07-15-upgrade-reliability-design.md +1 -1
- package/docs/todo/automatic-agent-maintenance-implementation.md +55 -0
- package/docs/todo/automatic-agent-maintenance.md +86 -0
- package/docs/todo/bash-installer.md +45 -0
- package/docs/todo/linux-installer-latest-release.md +47 -0
- package/docs/todo/platform-aware-startup-greeting.md +41 -0
- package/docs/todo/rfc-0034-cli-compliance-migration-implementation.md +7 -2
- package/docs/todo/rfc-0034-cli-compliance-migration.md +7 -3
- package/docs/todo/todo.xdocs.md +14 -0
- package/docs/todo/unicode-help-tree.md +44 -0
- package/docs/todo/upgrade-reliability.md +51 -0
- package/docs/validation/automatic-agent-maintenance.md +63 -0
- package/docs/validation/bash-installer.md +55 -0
- package/docs/validation/linux-installer-latest-release.md +50 -0
- package/docs/validation/platform-aware-startup-greeting.md +50 -0
- package/docs/validation/rfc-0034-cli-compliance-migration.md +10 -4
- package/docs/validation/unicode-help-tree.md +43 -0
- package/docs/validation/upgrade-reliability-issue-12.md +74 -0
- package/docs/validation/upgrade-reliability-issue-13.md +72 -0
- package/docs/validation/upgrade-reliability.md +38 -99
- package/docs/validation/validation.xdocs.md +16 -2
- package/library/agent-maintenance.d.ts +19 -0
- package/library/agent-maintenance.d.ts.map +1 -0
- package/library/agent-maintenance.js +49 -0
- package/library/agents.d.ts +6 -1
- package/library/agents.d.ts.map +1 -1
- package/library/agents.js +58 -11
- package/library/cli.d.ts +2 -1
- package/library/cli.d.ts.map +1 -1
- package/library/cli.js +34 -9
- package/library/recovery.js +1 -1
- package/library/release-catalog.d.ts +2 -1
- package/library/release-catalog.d.ts.map +1 -1
- package/library/release-catalog.js +9 -1
- package/library/storage.d.ts +2 -1
- package/library/storage.d.ts.map +1 -1
- package/library/storage.js +13 -1
- package/package.json +1 -1
- package/skills/guiho-s-runx/SKILL.md +11 -0
- package/skills/guiho-s-runx/guiho-s-runx.xdocs.md +4 -1
package/library/cli.js
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
import { Type } from '@sinclair/typebox';
|
|
5
5
|
import { Value } from '@sinclair/typebox/value';
|
|
6
6
|
import { defineCommand, renderUsage, runCommand as runCittyCommand } from 'citty';
|
|
7
|
+
import { agentMaintenanceWorkerCwd, runAgentMaintenanceWorker, spawnAgentMaintenanceWorker } from './agent-maintenance.js';
|
|
7
8
|
import { applyAgentInstructions, installAgentSkill, listAgentPrompts, listAgentSkills, removeAgentInstructions, showAgentInstructions, showAgentPrompt, showAgentSkill, uninstallAgentSkill, updateAgentInstructions, updateAgentSkill, } from './agents.js';
|
|
8
9
|
import { RunXError } from './errors.js';
|
|
9
10
|
import { runCommand } from './executor.js';
|
|
@@ -12,11 +13,11 @@ import { initializeRunXManifest } from './init.js';
|
|
|
12
13
|
import { readManifest, resolveCommand } from './manifest.js';
|
|
13
14
|
import { resolvePath } from './path-utils.js';
|
|
14
15
|
import { renderDescription, renderExecutionPlan, renderJson, renderList } from './render.js';
|
|
15
|
-
import { fetchReleaseCatalog, resolveUpgradePlatform } from './release-catalog.js';
|
|
16
|
+
import { fetchReleaseCatalog, paginateReleaseCatalog, resolveUpgradePlatform } from './release-catalog.js';
|
|
16
17
|
import { checkForLatestVersion, uninstallSelf, upgradeSelf } from './self-management.js';
|
|
17
18
|
import { readCachedUpdateNotice, runUpdateWorker, spawnUpdateWorker } from './update-cache.js';
|
|
18
19
|
import { renderReleaseCatalog, renderUpgradeEvent, renderUpgradeHeading, renderUpgradePlan, renderUpgradeResult } from './upgrade-reporting.js';
|
|
19
|
-
export { runCli, runCliWithErrorHandling, runxCommand, };
|
|
20
|
+
export { renderStartupBanner, runCli, runCliWithErrorHandling, runxCommand, };
|
|
20
21
|
class CliHandled extends Error {
|
|
21
22
|
}
|
|
22
23
|
class CliUsageError extends Error {
|
|
@@ -31,6 +32,14 @@ const formatSchema = Type.Union([Type.Literal('text'), Type.Literal('json')]);
|
|
|
31
32
|
const archSchema = Type.Union([Type.Literal('x64'), Type.Literal('arm64')]);
|
|
32
33
|
const variantSchema = Type.Union([Type.Literal('baseline'), Type.Literal('default'), Type.Literal('modern')]);
|
|
33
34
|
const positiveIntegerSchema = Type.Integer({ minimum: 1 });
|
|
35
|
+
const platformLabels = {
|
|
36
|
+
darwin: 'macOS',
|
|
37
|
+
linux: 'Linux',
|
|
38
|
+
win32: 'Windows',
|
|
39
|
+
};
|
|
40
|
+
function renderStartupBanner(platform = process.platform, version = readVersion()) {
|
|
41
|
+
return `Hello ${platformLabels[platform] ?? platform} - runx v${version}\n`;
|
|
42
|
+
}
|
|
34
43
|
const helpArgs = {
|
|
35
44
|
help: { type: 'boolean', alias: 'h', description: 'Show command help.' },
|
|
36
45
|
'help-tree': { type: 'boolean', description: 'Show this command hierarchy.' },
|
|
@@ -135,7 +144,7 @@ function createCommandTree() {
|
|
|
135
144
|
const upgradeList = leaf('runx upgrade list', 'List RunX releases newest first.', {
|
|
136
145
|
page: { type: 'string', valueHint: 'positive-integer', description: 'Select result page.' },
|
|
137
146
|
'per-page': { type: 'string', valueHint: 'positive-integer', description: 'Select page size.' },
|
|
138
|
-
'pre-releases': { type: 'boolean', description: '
|
|
147
|
+
'pre-releases': { type: 'boolean', description: 'Accepted explicitly; prereleases are always included.' },
|
|
139
148
|
arch: { type: 'string', valueHint: 'x64|arm64', description: 'Select target architecture.' },
|
|
140
149
|
variant: { type: 'string', valueHint: 'baseline|default|modern', description: 'Select x64 variant.' },
|
|
141
150
|
format: catalogArgs.format,
|
|
@@ -145,7 +154,11 @@ function createCommandTree() {
|
|
|
145
154
|
args: { ...upgradeArgs, ...helpArgs },
|
|
146
155
|
subCommands: { check: upgradeCheck, list: upgradeList },
|
|
147
156
|
setup: helpSetup(state),
|
|
148
|
-
run: async () =>
|
|
157
|
+
run: async () => {
|
|
158
|
+
if (state.command === upgradeCheck || state.command === upgradeList)
|
|
159
|
+
return;
|
|
160
|
+
await runUpgrade(options(state.args), state.args);
|
|
161
|
+
},
|
|
149
162
|
});
|
|
150
163
|
state.commands.set('upgrade', upgrade);
|
|
151
164
|
const uninstall = leaf('runx uninstall', 'Uninstall the native RunX executable.', {
|
|
@@ -169,7 +182,7 @@ function createCommandTree() {
|
|
|
169
182
|
},
|
|
170
183
|
run: ({ args }) => {
|
|
171
184
|
if (args._.length === 0)
|
|
172
|
-
write(
|
|
185
|
+
write(renderStartupBanner());
|
|
173
186
|
},
|
|
174
187
|
});
|
|
175
188
|
state.commands.set('', root);
|
|
@@ -229,6 +242,11 @@ async function runCli(rawArgs = process.argv.slice(2)) {
|
|
|
229
242
|
await runUpdateWorker();
|
|
230
243
|
return;
|
|
231
244
|
}
|
|
245
|
+
const maintenanceWorkerCwd = agentMaintenanceWorkerCwd(rawArgs);
|
|
246
|
+
if (maintenanceWorkerCwd !== null) {
|
|
247
|
+
await runAgentMaintenanceWorker(maintenanceWorkerCwd);
|
|
248
|
+
return;
|
|
249
|
+
}
|
|
232
250
|
const { command, state } = createCommandTree();
|
|
233
251
|
const cleanOutput = rawArgs.some((arg) => ['-h', '--help', '-v', '--version', '--help-tree', '--help-docs'].includes(arg) || arg.startsWith('--help-tree-depth'));
|
|
234
252
|
if (!cleanOutput) {
|
|
@@ -253,6 +271,14 @@ async function runCli(rawArgs = process.argv.slice(2)) {
|
|
|
253
271
|
throw new CliUsageError(error.message, await renderUsage(state.command));
|
|
254
272
|
throw error;
|
|
255
273
|
}
|
|
274
|
+
finally {
|
|
275
|
+
if (shouldScheduleAgentMaintenance(rawArgs)) {
|
|
276
|
+
spawnAgentMaintenanceWorker(resolvePath(state.args.cwd ?? process.cwd()));
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
function shouldScheduleAgentMaintenance(rawArgs) {
|
|
281
|
+
return !['agent', 'uninstall'].includes(rawArgs[0] ?? '');
|
|
256
282
|
}
|
|
257
283
|
async function runCliWithErrorHandling(rawArgs) {
|
|
258
284
|
try {
|
|
@@ -335,11 +361,10 @@ async function runUpgradeList(args) {
|
|
|
335
361
|
const requestedArch = args.arch ? decode(archSchema, args.arch, '--arch') : process.arch;
|
|
336
362
|
const platform = resolveUpgradePlatform(process.platform, requestedArch);
|
|
337
363
|
const variant = decode(variantSchema, args.variant ?? 'baseline', '--variant');
|
|
338
|
-
const page = positiveInteger(args.page
|
|
339
|
-
const perPage = positiveInteger(args.perPage
|
|
364
|
+
const page = args.page ? positiveInteger(args.page, '--page') : undefined;
|
|
365
|
+
const perPage = args.perPage ? positiveInteger(args.perPage, '--per-page') : undefined;
|
|
340
366
|
const catalog = await fetchReleaseCatalog({ ...platform, variant, currentVersion: readVersion() });
|
|
341
|
-
const
|
|
342
|
-
const paged = { ...catalog, releases: filtered.slice((page - 1) * perPage, page * perPage) };
|
|
367
|
+
const paged = paginateReleaseCatalog(catalog, page, perPage);
|
|
343
368
|
write(options(args).format === 'json' ? renderJson(paged) : renderReleaseCatalog(paged));
|
|
344
369
|
}
|
|
345
370
|
async function runUpgrade(optionsValue, args) {
|
package/library/recovery.js
CHANGED
|
@@ -15,7 +15,7 @@ const createRecoveryInstructions = (targetVersion, os, targetSource = 'resolved'
|
|
|
15
15
|
return {
|
|
16
16
|
targetVersion,
|
|
17
17
|
targetSource,
|
|
18
|
-
installCommand: `curl -fsSL ${installerBaseUrl}/install.sh |
|
|
18
|
+
installCommand: `curl -fsSL ${installerBaseUrl}/install.sh | bash -s -- --version '${escapeShell(targetVersion)}'`,
|
|
19
19
|
stopProcessCommand: 'pkill -x runx',
|
|
20
20
|
};
|
|
21
21
|
};
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* @copyright Copyright © 2026 GUIHO Technologies as represented by Cristóvão GUIHO. All Rights Reserved.
|
|
3
3
|
*/
|
|
4
4
|
import type { ReleaseAsset, ReleaseCatalog, UpgradeArch, UpgradeOs, UpgradeVariant } from './upgrade-types.js';
|
|
5
|
-
export { assetCandidates, fetchReleaseCatalog, findCompatibleAsset, normalizeReleaseVersion, resolveUpgradePlatform, };
|
|
5
|
+
export { assetCandidates, fetchReleaseCatalog, findCompatibleAsset, normalizeReleaseVersion, paginateReleaseCatalog, resolveUpgradePlatform, };
|
|
6
6
|
declare const githubReleaseSchema: import("@sinclair/typebox").TObject<{
|
|
7
7
|
tag_name: import("@sinclair/typebox").TString;
|
|
8
8
|
draft: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TBoolean>;
|
|
@@ -29,4 +29,5 @@ declare const findCompatibleAsset: (release: GitHubRelease, platform: ReleasePla
|
|
|
29
29
|
declare const assetCandidates: ({ os, arch, variant }: ReleasePlatform) => string[];
|
|
30
30
|
declare const resolveUpgradePlatform: (platform?: NodeJS.Platform, architecture?: NodeJS.Architecture) => ReleasePlatform;
|
|
31
31
|
declare const normalizeReleaseVersion: (tag: string) => string;
|
|
32
|
+
declare const paginateReleaseCatalog: (catalog: ReleaseCatalog, page?: number, perPage?: number) => ReleaseCatalog;
|
|
32
33
|
//# sourceMappingURL=release-catalog.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"release-catalog.d.ts","sourceRoot":"","sources":["../source/release-catalog.ts"],"names":[],"mappings":"AAAA;;GAEG;AAMH,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAuB,WAAW,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAA;AAEnI,OAAO,EACL,eAAe,EACf,mBAAmB,EACnB,mBAAmB,EACnB,uBAAuB,EACvB,sBAAsB,GACvB,CAAA;AAED,QAAA,MAAM,mBAAmB;;;;;;;;;;EAUS,CAAA;AAIlC,MAAM,MAAM,aAAa,GAAG,OAAO,mBAAmB,EAAE,MAAM,CAAC,OAAO,mBAAmB,CAAC,CAAA;AAE1F,MAAM,MAAM,eAAe,GAAG;IAC5B,EAAE,EAAE,SAAS,CAAA;IACb,IAAI,EAAE,WAAW,CAAA;IACjB,OAAO,EAAE,cAAc,CAAA;CACxB,CAAA;AAED,KAAK,mBAAmB,GAAG,eAAe,GAAG;IAC3C,cAAc,EAAE,MAAM,CAAA;IACtB,SAAS,CAAC,EAAE,OAAO,KAAK,CAAA;CACzB,CAAA;AAID,QAAA,MAAM,mBAAmB,YAAmB,mBAAmB,KAAG,OAAO,CAAC,cAAc,CAoCvF,CAAA;AAkBD,QAAA,MAAM,mBAAmB,YAAa,aAAa,YAAY,eAAe,KAAG,YAAY,GAAG,IAM/F,CAAA;AAED,QAAA,MAAM,eAAe,0BAA2B,eAAe,KAAG,MAAM,EAUvE,CAAA;AAED,QAAA,MAAM,sBAAsB,sEAA+D,eAM1F,CAAA;AAED,QAAA,MAAM,uBAAuB,QAAS,MAAM,KAAG,MAA6D,CAAA"}
|
|
1
|
+
{"version":3,"file":"release-catalog.d.ts","sourceRoot":"","sources":["../source/release-catalog.ts"],"names":[],"mappings":"AAAA;;GAEG;AAMH,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAuB,WAAW,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAA;AAEnI,OAAO,EACL,eAAe,EACf,mBAAmB,EACnB,mBAAmB,EACnB,uBAAuB,EACvB,sBAAsB,EACtB,sBAAsB,GACvB,CAAA;AAED,QAAA,MAAM,mBAAmB;;;;;;;;;;EAUS,CAAA;AAIlC,MAAM,MAAM,aAAa,GAAG,OAAO,mBAAmB,EAAE,MAAM,CAAC,OAAO,mBAAmB,CAAC,CAAA;AAE1F,MAAM,MAAM,eAAe,GAAG;IAC5B,EAAE,EAAE,SAAS,CAAA;IACb,IAAI,EAAE,WAAW,CAAA;IACjB,OAAO,EAAE,cAAc,CAAA;CACxB,CAAA;AAED,KAAK,mBAAmB,GAAG,eAAe,GAAG;IAC3C,cAAc,EAAE,MAAM,CAAA;IACtB,SAAS,CAAC,EAAE,OAAO,KAAK,CAAA;CACzB,CAAA;AAID,QAAA,MAAM,mBAAmB,YAAmB,mBAAmB,KAAG,OAAO,CAAC,cAAc,CAoCvF,CAAA;AAkBD,QAAA,MAAM,mBAAmB,YAAa,aAAa,YAAY,eAAe,KAAG,YAAY,GAAG,IAM/F,CAAA;AAED,QAAA,MAAM,eAAe,0BAA2B,eAAe,KAAG,MAAM,EAUvE,CAAA;AAED,QAAA,MAAM,sBAAsB,sEAA+D,eAM1F,CAAA;AAED,QAAA,MAAM,uBAAuB,QAAS,MAAM,KAAG,MAA6D,CAAA;AAE5G,QAAA,MAAM,sBAAsB,YAAa,cAAc,SAAS,MAAM,YAAY,MAAM,KAAG,cAM1F,CAAA"}
|
|
@@ -5,7 +5,7 @@ import { Type } from '@sinclair/typebox';
|
|
|
5
5
|
import { Value } from '@sinclair/typebox/value';
|
|
6
6
|
import { compare, parse, valid } from 'semver';
|
|
7
7
|
import { RunXError } from './errors.js';
|
|
8
|
-
export { assetCandidates, fetchReleaseCatalog, findCompatibleAsset, normalizeReleaseVersion, resolveUpgradePlatform, };
|
|
8
|
+
export { assetCandidates, fetchReleaseCatalog, findCompatibleAsset, normalizeReleaseVersion, paginateReleaseCatalog, resolveUpgradePlatform, };
|
|
9
9
|
const githubReleaseSchema = Type.Object({
|
|
10
10
|
tag_name: Type.String(),
|
|
11
11
|
draft: Type.Optional(Type.Boolean()),
|
|
@@ -100,6 +100,14 @@ const resolveUpgradePlatform = (platform = process.platform, architecture = proc
|
|
|
100
100
|
return { os, arch, variant: 'baseline' };
|
|
101
101
|
};
|
|
102
102
|
const normalizeReleaseVersion = (tag) => tag.replace(/^@guiho\/runx@/, '').replace(/^v/, '');
|
|
103
|
+
const paginateReleaseCatalog = (catalog, page, perPage) => {
|
|
104
|
+
if (page === undefined && perPage === undefined)
|
|
105
|
+
return catalog;
|
|
106
|
+
const selectedPage = page ?? 1;
|
|
107
|
+
const selectedPageSize = perPage ?? 20;
|
|
108
|
+
const start = (selectedPage - 1) * selectedPageSize;
|
|
109
|
+
return { ...catalog, releases: catalog.releases.slice(start, start + selectedPageSize) };
|
|
110
|
+
};
|
|
103
111
|
const releaseChannel = (version, prerelease) => {
|
|
104
112
|
const parsed = parse(version);
|
|
105
113
|
if (!parsed)
|
package/library/storage.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @copyright Copyright © 2026 GUIHO Technologies as represented by Cristóvão GUIHO. All Rights Reserved.
|
|
3
3
|
*/
|
|
4
|
-
export { copyTextFile, ensureDirectory, globalRunXDirectory, movePath, pathExists, readTextIfExists, removePath, writeTextFile, };
|
|
4
|
+
export { copyTextFile, ensureDirectory, globalRunXDirectory, movePath, pathExists, readTextIfExists, removePath, writeTextFile, writeTextFileAtomic, };
|
|
5
5
|
declare function globalRunXDirectory(): string;
|
|
6
6
|
declare function pathExists(path: string): Promise<boolean>;
|
|
7
7
|
declare function ensureDirectory(path: string): Promise<void>;
|
|
@@ -9,5 +9,6 @@ declare function removePath(path: string): Promise<void>;
|
|
|
9
9
|
declare function movePath(from: string, to: string): Promise<void>;
|
|
10
10
|
declare function readTextIfExists(path: string): Promise<string | null>;
|
|
11
11
|
declare function writeTextFile(path: string, value: string): Promise<void>;
|
|
12
|
+
declare function writeTextFileAtomic(path: string, value: string): Promise<void>;
|
|
12
13
|
declare function copyTextFile(source: string, target: string): Promise<void>;
|
|
13
14
|
//# sourceMappingURL=storage.d.ts.map
|
package/library/storage.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../source/storage.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,OAAO,EACL,YAAY,EACZ,eAAe,EACf,mBAAmB,EACnB,QAAQ,EACR,UAAU,EACV,gBAAgB,EAChB,UAAU,EACV,aAAa,
|
|
1
|
+
{"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../source/storage.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,OAAO,EACL,YAAY,EACZ,eAAe,EACf,mBAAmB,EACnB,QAAQ,EACR,UAAU,EACV,gBAAgB,EAChB,UAAU,EACV,aAAa,EACb,mBAAmB,GACpB,CAAA;AAED,iBAAS,mBAAmB,IAAI,MAAM,CAErC;AAED,iBAAe,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAExD;AAED,iBAAe,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE1D;AAED,iBAAe,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAErD;AAED,iBAAe,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAQ/D;AAED,iBAAe,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAEpE;AAED,iBAAe,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAGvE;AAED,iBAAe,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAU7E;AAED,iBAAe,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAEzE"}
|
package/library/storage.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
import { $ } from 'bun';
|
|
5
5
|
import { directoryName, homeDirectory, joinPath } from './path-utils.js';
|
|
6
|
-
export { copyTextFile, ensureDirectory, globalRunXDirectory, movePath, pathExists, readTextIfExists, removePath, writeTextFile, };
|
|
6
|
+
export { copyTextFile, ensureDirectory, globalRunXDirectory, movePath, pathExists, readTextIfExists, removePath, writeTextFile, writeTextFileAtomic, };
|
|
7
7
|
function globalRunXDirectory() {
|
|
8
8
|
return joinPath(homeDirectory(), '.guiho', 'runx');
|
|
9
9
|
}
|
|
@@ -33,6 +33,18 @@ async function writeTextFile(path, value) {
|
|
|
33
33
|
await ensureDirectory(directoryName(path));
|
|
34
34
|
await Bun.write(path, value);
|
|
35
35
|
}
|
|
36
|
+
async function writeTextFileAtomic(path, value) {
|
|
37
|
+
await ensureDirectory(directoryName(path));
|
|
38
|
+
const temporary = `${path}.${process.pid}.${crypto.randomUUID()}.tmp`;
|
|
39
|
+
try {
|
|
40
|
+
await Bun.write(temporary, value);
|
|
41
|
+
await movePath(temporary, path);
|
|
42
|
+
}
|
|
43
|
+
catch (error) {
|
|
44
|
+
await removePath(temporary);
|
|
45
|
+
throw error;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
36
48
|
async function copyTextFile(source, target) {
|
|
37
49
|
await writeTextFile(target, await Bun.file(source).text());
|
|
38
50
|
}
|
package/package.json
CHANGED
|
@@ -76,3 +76,14 @@ runx upgrade --dry-run
|
|
|
76
76
|
|
|
77
77
|
Use `--help`, `--help-tree`, or `--help-docs` at any command scope for the
|
|
78
78
|
current executable contract.
|
|
79
|
+
|
|
80
|
+
## Automatic Agent Maintenance
|
|
81
|
+
|
|
82
|
+
Ordinary RunX commands schedule a silent, non-blocking worker that keeps the
|
|
83
|
+
bundled skill current in both global agent-tool directories and reconciles one
|
|
84
|
+
compact managed block in the nearest `AGENTS.md`. A current installation is not
|
|
85
|
+
rewritten. Automatic failures never fail or pollute the foreground command.
|
|
86
|
+
|
|
87
|
+
Explicit `runx agent ...` commands remain the manual repair and local-scope
|
|
88
|
+
interface. Explicit agent-resource removal and `runx uninstall` do not schedule
|
|
89
|
+
automatic reinstallation.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
subject: guiho-s-runx
|
|
3
|
-
description: Agent workflow for safe RunX catalog
|
|
3
|
+
description: Agent workflow for safe RunX catalog work, automatic resource maintenance, and verified native upgrade/list/recovery operations.
|
|
4
4
|
parent: runx-skills
|
|
5
5
|
children: []
|
|
6
6
|
files:
|
|
@@ -17,6 +17,7 @@ keywords:
|
|
|
17
17
|
- dry run
|
|
18
18
|
- runx upgrade
|
|
19
19
|
- recovery install
|
|
20
|
+
- automatic maintenance
|
|
20
21
|
flags: []
|
|
21
22
|
status: stable
|
|
22
23
|
---
|
|
@@ -24,3 +25,5 @@ status: stable
|
|
|
24
25
|
The skill makes manifest inspection, UID selection, dry runs, and explicit
|
|
25
26
|
confirmation the default agent workflow for RunX commands and teaches agents
|
|
26
27
|
how to interpret transactional native upgrades and their recovery contract.
|
|
28
|
+
Ordinary RunX invocations also reconcile the current global skill and nearest
|
|
29
|
+
managed project instruction block through a silent detached worker.
|