@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.
Files changed (86) hide show
  1. package/CHANGELOG.md +39 -0
  2. package/DOCS.md +127 -128
  3. package/README.md +56 -75
  4. package/devops/build-binaries.ts +44 -62
  5. package/devops/devops.xdocs.md +8 -5
  6. package/devops/install.ps1 +182 -152
  7. package/devops/install.sh +197 -262
  8. package/devops/installers.spec.ts +31 -0
  9. package/devops/verify-release-assets.ts +17 -0
  10. package/docs/docs.xdocs.md +3 -1
  11. package/docs/plans/plans.xdocs.md +7 -0
  12. package/docs/plans/rfc-0034-cli-compliance-migration.md +586 -0
  13. package/docs/plans/upgrade-reliability-implementation.md +95 -0
  14. package/docs/reviews/implementation/implementation.xdocs.md +2 -0
  15. package/docs/reviews/implementation/rfc-0034-cli-compliance-migration-review.md +69 -0
  16. package/docs/reviews/plans/plans.xdocs.md +6 -0
  17. package/docs/reviews/plans/rfc-0034-cli-compliance-migration-review.md +80 -0
  18. package/docs/reviews/plans/upgrade-reliability-implementation-review.md +65 -0
  19. package/docs/superpowers/specs/2026-07-15-upgrade-reliability-design.md +662 -0
  20. package/docs/superpowers/specs/specs.xdocs.md +24 -0
  21. package/docs/superpowers/superpowers.xdocs.md +21 -0
  22. package/docs/todo/rfc-0034-cli-compliance-migration-implementation.md +77 -0
  23. package/docs/todo/rfc-0034-cli-compliance-migration.md +152 -0
  24. package/docs/todo/todo.xdocs.md +6 -2
  25. package/docs/validation/rfc-0034-cli-compliance-migration.md +83 -0
  26. package/docs/validation/upgrade-reliability.md +124 -0
  27. package/docs/validation/validation.xdocs.md +5 -0
  28. package/library/agents.d.ts +29 -4
  29. package/library/agents.d.ts.map +1 -1
  30. package/library/agents.js +143 -41
  31. package/library/cli.d.ts.map +1 -1
  32. package/library/cli.js +311 -331
  33. package/library/configuration.d.ts +57 -0
  34. package/library/configuration.d.ts.map +1 -0
  35. package/library/configuration.js +111 -0
  36. package/library/embedded-resources.d.ts +6 -1
  37. package/library/embedded-resources.d.ts.map +1 -1
  38. package/library/embedded-resources.js +10 -4
  39. package/library/executor.d.ts +5 -1
  40. package/library/executor.d.ts.map +1 -1
  41. package/library/executor.js +10 -10
  42. package/library/help.d.ts +8 -4
  43. package/library/help.d.ts.map +1 -1
  44. package/library/help.js +70 -46
  45. package/library/init.d.ts +8 -27
  46. package/library/init.d.ts.map +1 -1
  47. package/library/init.js +37 -159
  48. package/library/manifest.d.ts +4 -43
  49. package/library/manifest.d.ts.map +1 -1
  50. package/library/manifest.js +4 -125
  51. package/library/path-utils.d.ts +13 -0
  52. package/library/path-utils.d.ts.map +1 -0
  53. package/library/path-utils.js +82 -0
  54. package/library/recovery.d.ts +7 -0
  55. package/library/recovery.d.ts.map +1 -0
  56. package/library/recovery.js +23 -0
  57. package/library/release-catalog.d.ts +32 -0
  58. package/library/release-catalog.d.ts.map +1 -0
  59. package/library/release-catalog.js +124 -0
  60. package/library/self-management.d.ts +24 -4
  61. package/library/self-management.d.ts.map +1 -1
  62. package/library/self-management.js +279 -99
  63. package/library/storage.d.ts +13 -0
  64. package/library/storage.d.ts.map +1 -0
  65. package/library/storage.js +38 -0
  66. package/library/types.d.ts +11 -16
  67. package/library/types.d.ts.map +1 -1
  68. package/library/types.js +3 -0
  69. package/library/update-cache.d.ts +21 -0
  70. package/library/update-cache.d.ts.map +1 -0
  71. package/library/update-cache.js +68 -0
  72. package/library/upgrade-reporting.d.ts +11 -0
  73. package/library/upgrade-reporting.d.ts.map +1 -0
  74. package/library/upgrade-reporting.js +67 -0
  75. package/library/upgrade-types.d.ts +72 -0
  76. package/library/upgrade-types.d.ts.map +1 -0
  77. package/library/upgrade-types.js +3 -0
  78. package/package.json +6 -3
  79. package/scripts/runx-bin.mjs +49 -0
  80. package/scripts/runx-bin.spec.ts +62 -0
  81. package/scripts/scripts.xdocs.md +3 -3
  82. package/skills/guiho-s-runx/SKILL.md +64 -59
  83. package/skills/guiho-s-runx/guiho-s-runx.xdocs.md +7 -4
  84. package/skills/skills.xdocs.md +1 -1
  85. package/docs/todo/implement-runx-alpha.md +0 -36
  86. package/scripts/runx-bin.ts +0 -24
package/library/agents.js CHANGED
@@ -1,51 +1,153 @@
1
- import { mkdir, readFile, writeFile } from 'node:fs/promises';
2
- import { homedir } from 'node:os';
3
- import { dirname, join } from 'node:path';
1
+ /**
2
+ * @copyright Copyright © 2026 GUIHO Technologies as represented by Cristóvão GUIHO. All Rights Reserved.
3
+ */
4
4
  import { RunXError } from './errors.js';
5
- const managedStart = '<!-- BEGIN RUNX AGENT INSTRUCTIONS -->';
6
- const managedEnd = '<!-- END RUNX AGENT INSTRUCTIONS -->';
7
- export const installAgentSkill = async (scope, tool, cwd) => {
8
- const root = scope === 'global' ? homedir() : cwd;
5
+ import { homeDirectory, joinPath, resolvePath } from './path-utils.js';
6
+ import { ensureDirectory, pathExists, readTextIfExists, removePath, writeTextFile } from './storage.js';
7
+ export { applyAgentInstructions, installAgentSkill, listAgentPrompts, listAgentSkills, removeAgentInstructions, showAgentInstructions, showAgentPrompt, showAgentSkill, uninstallAgentSkill, updateAgentInstructions, updateAgentSkill, };
8
+ const skillId = 'guiho-s-runx';
9
+ const promptId = 'guiho-i-runx';
10
+ const managedStart = '<!-- BEGIN RUNX — DO NOT EDIT THIS SECTION -->';
11
+ const managedEnd = '<!-- END RUNX -->';
12
+ async function installAgentSkill(scope, cwd) {
13
+ return writeSkillTargets(scope, cwd);
14
+ }
15
+ async function updateAgentSkill(scope, cwd) {
16
+ return writeSkillTargets(scope, cwd);
17
+ }
18
+ async function uninstallAgentSkill(scope, cwd) {
19
+ const targets = skillDirectories(scope, cwd);
20
+ for (const target of targets)
21
+ await removePath(target);
22
+ return targets;
23
+ }
24
+ function listAgentSkills(filter) {
25
+ const skills = [{ id: skillId, description: 'Inspect, validate, describe, and safely execute RunX command catalogs.' }];
26
+ const keyword = filter?.trim().toLowerCase();
27
+ return keyword ? skills.filter((skill) => `${skill.id} ${skill.description}`.toLowerCase().includes(keyword)) : skills;
28
+ }
29
+ async function showAgentSkill(id) {
30
+ if (id !== skillId)
31
+ throw new RunXError(`Unknown RunX skill: ${id}`, 2);
32
+ return {
33
+ id,
34
+ path: `skills/${skillId}/SKILL.md`,
35
+ description: listAgentSkills()[0].description,
36
+ metadata: { version: '0.1.0', package: '@guiho/runx' },
37
+ };
38
+ }
39
+ async function applyAgentInstructions(cwd) {
40
+ return reconcileInstructions(cwd, 'apply');
41
+ }
42
+ async function updateAgentInstructions(cwd) {
43
+ return reconcileInstructions(cwd, 'update');
44
+ }
45
+ async function removeAgentInstructions(cwd) {
46
+ const changed = [];
47
+ for (const path of await instructionTargets(cwd)) {
48
+ const existing = await readTextIfExists(path);
49
+ if (existing === null)
50
+ continue;
51
+ const next = removeManagedBlock(existing);
52
+ if (next !== existing) {
53
+ await writeTextFile(path, next);
54
+ changed.push(path);
55
+ }
56
+ }
57
+ return changed;
58
+ }
59
+ async function showAgentInstructions() {
60
+ return instructionBlock();
61
+ }
62
+ function listAgentPrompts(namesOnly = false) {
63
+ return namesOnly
64
+ ? [promptId]
65
+ : [{ id: promptId, description: 'Guide an agent through safe RunX catalog inspection and execution.' }];
66
+ }
67
+ async function showAgentPrompt(id) {
68
+ if (id !== promptId)
69
+ throw new RunXError(`Unknown RunX prompt: ${id}`, 2);
70
+ return readBundledPrompt();
71
+ }
72
+ async function writeSkillTargets(scope, cwd) {
9
73
  const skill = await readBundledSkill();
10
- const targets = tool === 'all' ? ['agents', 'claude'] : [tool];
11
74
  const installed = [];
12
- for (const target of targets) {
13
- const directory = target === 'agents'
14
- ? join(root, '.agents', 'skills', 'guiho-s-runx')
15
- : join(root, '.claude', 'skills', 'guiho-s-runx');
16
- const path = join(directory, 'SKILL.md');
17
- await mkdir(directory, { recursive: true });
18
- await writeFile(path, skill, 'utf8');
75
+ for (const directory of skillDirectories(scope, cwd)) {
76
+ const path = joinPath(directory, 'SKILL.md');
77
+ await ensureDirectory(directory);
78
+ await writeTextFile(path, skill);
19
79
  installed.push(path);
20
80
  }
21
81
  return installed;
22
- };
23
- export const installAgentInstructions = async (cwd) => {
24
- const path = join(cwd, 'AGENTS.md');
25
- let existing = '';
26
- try {
27
- existing = await readFile(path, 'utf8');
28
- }
29
- catch (error) {
30
- if (!(error instanceof Error && 'code' in error && error.code === 'ENOENT'))
31
- throw error;
82
+ }
83
+ function skillDirectories(scope, cwd) {
84
+ const root = scope === 'global' ? homeDirectory() : resolvePath(cwd);
85
+ return [
86
+ joinPath(root, '.agents', 'skills', skillId),
87
+ joinPath(root, '.claude', 'skills', skillId),
88
+ ];
89
+ }
90
+ async function instructionTargets(cwd) {
91
+ const root = resolvePath(cwd);
92
+ const agents = joinPath(root, 'AGENTS.md');
93
+ const claude = joinPath(root, 'CLAUDE.md');
94
+ const agentsExists = await pathExists(agents);
95
+ const claudeExists = await pathExists(claude);
96
+ if (agentsExists && claudeExists)
97
+ return [agents, claude];
98
+ if (claudeExists)
99
+ return [claude];
100
+ return [agents];
101
+ }
102
+ async function reconcileInstructions(cwd, _action) {
103
+ const changed = [];
104
+ for (const path of await instructionTargets(cwd)) {
105
+ const existing = await readTextIfExists(path) ?? '';
106
+ const next = replaceManagedBlock(existing, instructionBlock());
107
+ if (next !== existing) {
108
+ await writeTextFile(path, next);
109
+ changed.push(path);
110
+ }
32
111
  }
33
- const section = `${managedStart}\n## RunX Command Catalog\n\nUse the bundled \`guiho-s-runx\` skill whenever working with \`runx.yaml\` manifests. Inspect with \`runx check --format json\` and \`runx list --format json\` before selecting a command. Use a UID for automation and require explicit developer approval before \`--yes\` on confirmation-gated commands.\n${managedEnd}`;
34
- const pattern = new RegExp(`${escapeRegExp(managedStart)}[\\s\\S]*?${escapeRegExp(managedEnd)}`, 'g');
35
- const next = pattern.test(existing) ? existing.replace(pattern, section) : `${existing.trimEnd()}${existing.trim() ? '\n\n' : ''}${section}\n`;
36
- await mkdir(dirname(path), { recursive: true });
37
- await writeFile(path, next, 'utf8');
38
- return path;
39
- };
40
- const readBundledSkill = async () => {
112
+ return changed;
113
+ }
114
+ function instructionBlock() {
115
+ return `${managedStart}
116
+ ## RunX Command Catalog
117
+
118
+ Load the \`guiho-s-runx\` skill before working with \`runx.yaml\`. Inspect with
119
+ \`runx check --format json\` and \`runx list --format json\`, select stable UIDs,
120
+ use \`runx run <uid> --dry-run\` before unfamiliar work, and add \`--yes\` only
121
+ after explicit approval for a confirmation-gated command.
122
+ ${managedEnd}
123
+ `;
124
+ }
125
+ function replaceManagedBlock(existing, block) {
126
+ const pattern = new RegExp(`${escapeRegExp(managedStart)}[\\s\\S]*?${escapeRegExp(managedEnd)}\\s*`, 'g');
127
+ const stripped = existing.replace(pattern, '').trimEnd();
128
+ return `${stripped}${stripped ? '\n\n' : ''}${block}`;
129
+ }
130
+ function removeManagedBlock(existing) {
131
+ const pattern = new RegExp(`\\s*${escapeRegExp(managedStart)}[\\s\\S]*?${escapeRegExp(managedEnd)}\\s*`, 'g');
132
+ const next = existing.replace(pattern, '\n').trimEnd();
133
+ return next ? `${next}\n` : '';
134
+ }
135
+ async function readBundledSkill() {
41
136
  if (globalThis.__RUNX_EMBEDDED_RESOURCES__?.skill)
42
137
  return globalThis.__RUNX_EMBEDDED_RESOURCES__.skill;
43
138
  const path = new URL('../skills/guiho-s-runx/SKILL.md', import.meta.url);
44
- try {
45
- return await Bun.file(path).text();
46
- }
47
- catch {
48
- throw new RunXError('Bundled guiho-s-runx skill is unavailable. Reinstall RunX from an official release.');
49
- }
50
- };
51
- const escapeRegExp = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
139
+ if (!(await Bun.file(path).exists()))
140
+ throw new RunXError('Bundled guiho-s-runx skill is unavailable.', 5);
141
+ return Bun.file(path).text();
142
+ }
143
+ async function readBundledPrompt() {
144
+ if (globalThis.__RUNX_EMBEDDED_RESOURCES__?.prompt)
145
+ return globalThis.__RUNX_EMBEDDED_RESOURCES__.prompt;
146
+ const path = new URL('../prompts/guiho-i-runx.md', import.meta.url);
147
+ if (!(await Bun.file(path).exists()))
148
+ throw new RunXError('Bundled guiho-i-runx prompt is unavailable.', 5);
149
+ return Bun.file(path).text();
150
+ }
151
+ function escapeRegExp(value) {
152
+ return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
153
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../source/cli.ts"],"names":[],"mappings":"AAAA;;GAEG;AAaH,OAAO,KAAK,EAAkB,UAAU,EAAkB,MAAM,OAAO,CAAA;AAGvE,OAAO,EACL,MAAM,EACN,uBAAuB,EACvB,WAAW,GACZ,CAAA;AA8PD,QAAA,MAAiB,WAAW,iBAAwB,CAAA;AAEpD,iBAAe,MAAM,CAAC,OAAO,GAAE,MAAM,EAA0B,GAAG,OAAO,CAAC,IAAI,CAAC,CAY9E;AAED,iBAAe,uBAAuB,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAiBxE"}
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../source/cli.ts"],"names":[],"mappings":"AAAA;;GAEG;AA8BH,OAAO,KAAK,EAAkB,UAAU,EAAkB,MAAM,OAAO,CAAA;AAIvE,OAAO,EACL,MAAM,EACN,uBAAuB,EACvB,WAAW,GACZ,CAAA;AAsPD,QAAA,MAAiB,WAAW,iBAAwB,CAAA;AAEpD,iBAAe,MAAM,CAAC,OAAO,GAAE,MAAM,EAA0B,GAAG,OAAO,CAAC,IAAI,CAAC,CAuB9E;AAED,iBAAe,uBAAuB,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAexE"}