@guiho/runx 0.2.0

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 (72) hide show
  1. package/CHANGELOG.md +39 -0
  2. package/DOCS.md +118 -0
  3. package/LICENSE.md +36 -0
  4. package/README.md +79 -0
  5. package/SECURITY.md +28 -0
  6. package/devops/build-binaries.ts +99 -0
  7. package/devops/devops.xdocs.md +25 -0
  8. package/devops/install.ps1 +216 -0
  9. package/devops/install.sh +324 -0
  10. package/docs/architecture/architecture.xdocs.md +20 -0
  11. package/docs/architecture/cli-architecture.md +39 -0
  12. package/docs/decisions/alpha-boundaries.md +29 -0
  13. package/docs/decisions/decisions.xdocs.md +19 -0
  14. package/docs/docs.xdocs.md +24 -0
  15. package/docs/plans/alpha-implementation.md +27 -0
  16. package/docs/plans/plans.xdocs.md +19 -0
  17. package/docs/requirements/alpha-command-catalog.md +41 -0
  18. package/docs/requirements/requirements.xdocs.md +19 -0
  19. package/docs/todo/implement-runx-alpha.md +36 -0
  20. package/docs/todo/protect-branches-and-tag-creation.md +83 -0
  21. package/docs/todo/todo.xdocs.md +21 -0
  22. package/docs/validation/alpha-implementation-summary.md +52 -0
  23. package/docs/validation/validation.xdocs.md +21 -0
  24. package/library/agents.d.ts +11 -0
  25. package/library/agents.d.ts.map +1 -0
  26. package/library/agents.js +51 -0
  27. package/library/cli.d.ts +3 -0
  28. package/library/cli.d.ts.map +1 -0
  29. package/library/cli.js +146 -0
  30. package/library/embedded-resources.d.ts +7 -0
  31. package/library/embedded-resources.d.ts.map +1 -0
  32. package/library/embedded-resources.js +5 -0
  33. package/library/errors.d.ts +6 -0
  34. package/library/errors.d.ts.map +1 -0
  35. package/library/errors.js +12 -0
  36. package/library/executor.d.ts +3 -0
  37. package/library/executor.d.ts.map +1 -0
  38. package/library/executor.js +24 -0
  39. package/library/flags.d.ts +5 -0
  40. package/library/flags.d.ts.map +1 -0
  41. package/library/flags.js +32 -0
  42. package/library/guiho-runx-bin.d.ts +3 -0
  43. package/library/guiho-runx-bin.d.ts.map +1 -0
  44. package/library/guiho-runx-bin.js +3 -0
  45. package/library/guiho-runx-native-bin.d.ts +3 -0
  46. package/library/guiho-runx-native-bin.d.ts.map +1 -0
  47. package/library/guiho-runx-native-bin.js +5 -0
  48. package/library/guiho-runx.d.ts +4 -0
  49. package/library/guiho-runx.d.ts.map +1 -0
  50. package/library/guiho-runx.js +2 -0
  51. package/library/help.d.ts +6 -0
  52. package/library/help.d.ts.map +1 -0
  53. package/library/help.js +47 -0
  54. package/library/manifest.d.ts +41 -0
  55. package/library/manifest.d.ts.map +1 -0
  56. package/library/manifest.js +112 -0
  57. package/library/render.d.ts +6 -0
  58. package/library/render.d.ts.map +1 -0
  59. package/library/render.js +40 -0
  60. package/library/self-management.d.ts +13 -0
  61. package/library/self-management.d.ts.map +1 -0
  62. package/library/self-management.js +82 -0
  63. package/library/types.d.ts +31 -0
  64. package/library/types.d.ts.map +1 -0
  65. package/library/types.js +0 -0
  66. package/package.json +77 -0
  67. package/scripts/runx-bin.ts +18 -0
  68. package/scripts/scripts.xdocs.md +20 -0
  69. package/skills/guiho-s-runx/SKILL.md +57 -0
  70. package/skills/guiho-s-runx/agents/openai.yaml +4 -0
  71. package/skills/guiho-s-runx/guiho-s-runx.xdocs.md +22 -0
  72. package/skills/skills.xdocs.md +19 -0
@@ -0,0 +1,21 @@
1
+ ---
2
+ subject: runx-todo
3
+ description: Linked task specifications for the RunX TODO index.
4
+ parent: runx-docs
5
+ children: []
6
+ files:
7
+ implement-runx-alpha.md: Defines the completion signals and constraints for the alpha task.
8
+ protect-branches-and-tag-creation.md: Records the verified active GitHub branch and release-tag rulesets for RunX.
9
+ documents:
10
+ implement-runx-alpha.md: Task specification for implementing RunX alpha.
11
+ protect-branches-and-tag-creation.md: Completed task specification with active RunX ruleset IDs, protected patterns, and verification evidence.
12
+ tags:
13
+ - todo
14
+ keywords:
15
+ - runx
16
+ - tasks
17
+ flags: []
18
+ status: stable
19
+ ---
20
+
21
+ Task specifications linked from the package-local RunX TODO index.
@@ -0,0 +1,52 @@
1
+ ---
2
+ name: RunX Alpha Implementation Summary
3
+ purpose: Summarize the first implemented RunX alpha and preserve its validation evidence.
4
+ description: Records delivered CLI behavior, agent and distribution support, checks run, and release boundaries.
5
+ created: 2026-07-12
6
+ flags:
7
+ - validated
8
+ tags:
9
+ - validation
10
+ - implementation
11
+ keywords:
12
+ - runx
13
+ - alpha
14
+ - summary
15
+ owner: runx-validation
16
+ ---
17
+
18
+ # RunX Alpha Implementation Summary
19
+
20
+ ## Implementation Summary
21
+
22
+ RunX is implemented as the open-source `@guiho/runx` Bun/TypeScript CLI. The
23
+ alpha discovers one nearest `runx.yaml`, validates it strictly with TypeBox,
24
+ lists documented commands through `runx list`, and runs an explicitly selected
25
+ command through `runx run` or `runx r`. A bare selector remains available as a
26
+ human shorthand; no-argument `runx` now shows the requested home page and usage.
27
+
28
+ The implementation includes UID/group-ID/index selector handling, JSON output,
29
+ describe, check, dry run, confirmation gates, help/help-tree/help-docs, bundled
30
+ `guiho-s-runx` skill installation, native upgrade and uninstall paths, Windows
31
+ and macOS/Linux direct installers, MIT licensing, and GitHub Actions CI. CI
32
+ validates only; npm and release publishing are intentionally absent.
33
+
34
+ ## Validation Evidence
35
+
36
+ - `bun run typecheck` passed.
37
+ - `bun test` passed with four tests covering manifest discovery, selector
38
+ behavior, flags, the `r` alias, dry runs, and real local command execution.
39
+ - `bun run build` passed and emitted the ignored TypeScript library output.
40
+ - `bun run binary` passed and emitted the ignored Windows native executable.
41
+ - The Bun source CLI displayed `--help`, `--help-tree`, and `--help-docs`.
42
+ - `xdocs tree`, `xdocs scan`, and `xdocs doctor --format json` passed. The
43
+ doctor reported only metadata warnings for the special-purpose skill file;
44
+ there were no descriptor, document, or tree errors.
45
+ - `mirror config check` passed. Mirror applied the local `0.1.0` minor release
46
+ and created `@guiho/runx@0.1.0`; the configuration did not push or publish.
47
+
48
+ ## Release Boundary
49
+
50
+ The initial external capability warranted and received a Mirror minor transition
51
+ from `0.0.0` to `0.1.0`. It created the configured local version commit and Git
52
+ tag without pushing either because `mirror.config.toml` sets `push = false`.
@@ -0,0 +1,21 @@
1
+ ---
2
+ subject: runx-validation
3
+ description: Validation evidence and implementation summaries for RunX releases.
4
+ parent: runx-docs
5
+ children: []
6
+ files:
7
+ alpha-implementation-summary.md: Records the completed alpha implementation, checks, and release boundaries.
8
+ documents:
9
+ alpha-implementation-summary.md: Validation summary for the first RunX implementation.
10
+ tags:
11
+ - validation
12
+ keywords:
13
+ - runx
14
+ - tests
15
+ - summary
16
+ flags: []
17
+ status: stable
18
+ ---
19
+
20
+ Validation records document exact checks, results, exclusions, and manual
21
+ release boundaries for RunX.
@@ -0,0 +1,11 @@
1
+ import type { AgentScope, AgentTool } from './types.js';
2
+ type EmbeddedResources = {
3
+ skill: string;
4
+ } | undefined;
5
+ declare global {
6
+ var __RUNX_EMBEDDED_RESOURCES__: EmbeddedResources;
7
+ }
8
+ export declare const installAgentSkill: (scope: AgentScope, tool: AgentTool, cwd: string) => Promise<string[]>;
9
+ export declare const installAgentInstructions: (cwd: string) => Promise<string>;
10
+ export {};
11
+ //# sourceMappingURL=agents.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agents.d.ts","sourceRoot":"","sources":["../source/agents.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AAGvD,KAAK,iBAAiB,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAAA;AAEtD,OAAO,CAAC,MAAM,CAAC;IACb,IAAI,2BAA2B,EAAE,iBAAiB,CAAA;CACnD;AAKD,eAAO,MAAM,iBAAiB,UAAiB,UAAU,QAAQ,SAAS,OAAO,MAAM,KAAG,OAAO,CAAC,MAAM,EAAE,CAiBzG,CAAA;AAED,eAAO,MAAM,wBAAwB,QAAe,MAAM,KAAG,OAAO,CAAC,MAAM,CAgB1E,CAAA"}
@@ -0,0 +1,51 @@
1
+ import { mkdir, readFile, writeFile } from 'node:fs/promises';
2
+ import { homedir } from 'node:os';
3
+ import { dirname, join } from 'node:path';
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;
9
+ const skill = await readBundledSkill();
10
+ const targets = tool === 'all' ? ['agents', 'claude'] : [tool];
11
+ 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');
19
+ installed.push(path);
20
+ }
21
+ 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;
32
+ }
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 () => {
41
+ if (globalThis.__RUNX_EMBEDDED_RESOURCES__?.skill)
42
+ return globalThis.__RUNX_EMBEDDED_RESOURCES__.skill;
43
+ 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, '\\$&');
@@ -0,0 +1,3 @@
1
+ export declare const runCli: (rawArgs?: string[]) => Promise<void>;
2
+ export declare const runCliWithErrorHandling: (rawArgs?: string[]) => Promise<void>;
3
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../source/cli.ts"],"names":[],"mappings":"AAaA,eAAO,MAAM,MAAM,aAAmB,MAAM,EAAE,KAA2B,OAAO,CAAC,IAAI,CAyBpF,CAAA;AAED,eAAO,MAAM,uBAAuB,aAAoB,MAAM,EAAE,KAAG,OAAO,CAAC,IAAI,CAY9E,CAAA"}
package/library/cli.js ADDED
@@ -0,0 +1,146 @@
1
+ import { resolve } from 'node:path';
2
+ import { installAgentInstructions, installAgentSkill } from './agents.js';
3
+ import { RunXError } from './errors.js';
4
+ import { runCommand } from './executor.js';
5
+ import { booleanFlag, parseArgs, stringFlag } from './flags.js';
6
+ import { readVersion, showCommandHelp, showHelpDocs, showHelpTree, showHome } from './help.js';
7
+ import { readManifest, resolveCommand } from './manifest.js';
8
+ import { renderDescription, renderExecutionPlan, renderJson, renderList } from './render.js';
9
+ import { checkForLatestVersion, listAvailableVersions, uninstallSelf, upgradeSelf } from './self-management.js';
10
+ const builtins = new Set(['list', 'describe', 'run', 'r', 'check', 'agents', 'upgrade', 'uninstall']);
11
+ export const runCli = async (rawArgs = process.argv.slice(2)) => {
12
+ const parsed = parseArgs(rawArgs);
13
+ const options = resolveOptions(parsed.flags);
14
+ if (booleanFlag(parsed.flags, 'version'))
15
+ return write(`${readVersion()}\n`);
16
+ if (booleanFlag(parsed.flags, 'helpTree'))
17
+ return write(`${showHelpTree()}\n`);
18
+ if (booleanFlag(parsed.flags, 'helpDocs'))
19
+ return write(showHelpDocs());
20
+ if (booleanFlag(parsed.flags, 'help'))
21
+ return write(parsed.command && builtins.has(parsed.command) ? showCommandHelp(parsed.command) : showHome());
22
+ if (!parsed.command)
23
+ return write(showHome());
24
+ if (!builtins.has(parsed.command)) {
25
+ await runSelectedCommand(parsed.command, parsed.positionals, options, parsed.flags);
26
+ return;
27
+ }
28
+ switch (parsed.command) {
29
+ case 'list':
30
+ await listCommands(options);
31
+ return;
32
+ case 'describe':
33
+ await describeCommand(parsed.positionals[0], options);
34
+ return;
35
+ case 'run':
36
+ case 'r':
37
+ await runSelectedCommand(parsed.positionals[0], parsed.positionals.slice(1), options, parsed.flags);
38
+ return;
39
+ case 'check':
40
+ await checkManifest(options);
41
+ return;
42
+ case 'agents':
43
+ await runAgents(parsed.positionals, options, parsed.flags);
44
+ return;
45
+ case 'upgrade':
46
+ await runUpgrade(parsed.positionals, options, parsed.flags);
47
+ return;
48
+ case 'uninstall':
49
+ await runUninstall(options, parsed.flags);
50
+ return;
51
+ }
52
+ };
53
+ export const runCliWithErrorHandling = async (rawArgs) => {
54
+ try {
55
+ await runCli(rawArgs);
56
+ }
57
+ catch (error) {
58
+ if (error instanceof RunXError) {
59
+ process.stderr.write(`error: ${error.message}\n`);
60
+ process.exitCode = error.exitCode;
61
+ return;
62
+ }
63
+ process.stderr.write(`error: ${error instanceof Error ? error.message : 'Unexpected failure.'}\n`);
64
+ process.exitCode = 1;
65
+ }
66
+ };
67
+ const listCommands = async (options) => {
68
+ const { manifest, path } = await readManifest(options.cwd, options.file);
69
+ write(options.format === 'json' ? renderJson({ manifestPath: path, manifest }) : renderList(manifest, path));
70
+ };
71
+ const describeCommand = async (selector, options) => {
72
+ if (!selector)
73
+ throw new RunXError('Missing selector. Usage: runx describe <selector>');
74
+ const { manifest, path } = await readManifest(options.cwd, options.file);
75
+ const command = resolveCommand(manifest, path, selector);
76
+ write(options.format === 'json' ? renderJson(command) : renderDescription(command));
77
+ };
78
+ const checkManifest = async (options) => {
79
+ const { manifest, path } = await readManifest(options.cwd, options.file);
80
+ const result = { valid: true, manifestPath: path, commandCount: manifest.commands.length, groups: Object.keys(manifest.groups) };
81
+ write(options.format === 'json' ? renderJson(result) : `valid: true\nmanifest: ${path}\ncommands: ${result.commandCount}\n`);
82
+ };
83
+ const runSelectedCommand = async (selector, _, options, flags) => {
84
+ if (!selector)
85
+ throw new RunXError('Missing selector. Usage: runx run <selector>');
86
+ const { manifest, path } = await readManifest(options.cwd, options.file);
87
+ const command = resolveCommand(manifest, path, selector);
88
+ if (booleanFlag(flags, 'dryRun')) {
89
+ write(options.format === 'json' ? renderJson({ dryRun: true, command }) : renderExecutionPlan(command));
90
+ return;
91
+ }
92
+ if (command.confirm === 'always' && !booleanFlag(flags, 'yes')) {
93
+ throw new RunXError(`Command ${command.uid} requires confirmation. Review it with \`runx describe ${command.uid}\` and rerun with --yes when authorized.`);
94
+ }
95
+ if (options.format === 'text')
96
+ write(`Running ${command.uid} (${command.selector})\n`);
97
+ const exitCode = await runCommand(command);
98
+ process.exitCode = exitCode;
99
+ };
100
+ const runAgents = async (positionals, options, flags) => {
101
+ const action = positionals[0];
102
+ if (action === 'install') {
103
+ const scope = (positionals[1] ?? 'local');
104
+ if (scope !== 'local' && scope !== 'global')
105
+ throw new RunXError('Agent scope must be local or global.');
106
+ const tool = (stringFlag(flags, 'tool') ?? 'agents');
107
+ if (!['agents', 'claude', 'all'].includes(tool))
108
+ throw new RunXError('Agent tool must be agents, claude, or all.');
109
+ const installed = await installAgentSkill(scope, tool, options.cwd);
110
+ write(options.format === 'json' ? renderJson({ installed }) : `${installed.map((path) => `installed: ${path}`).join('\n')}\n`);
111
+ return;
112
+ }
113
+ if (action === 'instructions') {
114
+ const path = await installAgentInstructions(options.cwd);
115
+ write(options.format === 'json' ? renderJson({ instructions: path }) : `updated: ${path}\n`);
116
+ return;
117
+ }
118
+ throw new RunXError('Usage: runx agents install <local|global> [--tool agents|claude|all] | runx agents instructions');
119
+ };
120
+ const runUpgrade = async (positionals, options, flags) => {
121
+ if (positionals[0] === 'check') {
122
+ const result = await checkForLatestVersion();
123
+ write(options.format === 'json' ? renderJson(result) : `current: ${result.currentVersion}\nlatest: ${result.latestVersion}\nupdate_available: ${result.updateAvailable}\n`);
124
+ return;
125
+ }
126
+ if (positionals[0] === 'list') {
127
+ const versions = await listAvailableVersions();
128
+ write(options.format === 'json' ? renderJson({ versions }) : `${versions.join('\n')}\n`);
129
+ return;
130
+ }
131
+ const result = await upgradeSelf(booleanFlag(flags, 'dryRun'));
132
+ write(options.format === 'json' ? renderJson(result) : `current: ${result.currentVersion}\ntarget: ${result.latestVersion}\npath: ${result.executablePath}\n${result.scheduled ? 'scheduled: true\n' : ''}`);
133
+ };
134
+ const runUninstall = async (options, flags) => {
135
+ const result = await uninstallSelf(booleanFlag(flags, 'dryRun'));
136
+ write(options.format === 'json' ? renderJson(result) : `path: ${result.executablePath}\n${result.dryRun ? 'dry_run: true\n' : result.scheduled ? 'scheduled: true\n' : 'uninstalled: true\n'}`);
137
+ };
138
+ const resolveOptions = (flags) => {
139
+ const format = stringFlag(flags, 'format') ?? 'text';
140
+ if (format !== 'text' && format !== 'json')
141
+ throw new RunXError('Invalid --format value. Expected text or json.');
142
+ return { cwd: resolve(stringFlag(flags, 'cwd') ?? process.cwd()), file: stringFlag(flags, 'file'), format: format, verbose: booleanFlag(flags, 'verbose') };
143
+ };
144
+ const write = (value) => {
145
+ process.stdout.write(value);
146
+ };
@@ -0,0 +1,7 @@
1
+ declare global {
2
+ var __RUNX_EMBEDDED_RESOURCES__: {
3
+ skill: string;
4
+ } | undefined;
5
+ }
6
+ export declare const registerEmbeddedResources: () => void;
7
+ //# sourceMappingURL=embedded-resources.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"embedded-resources.d.ts","sourceRoot":"","sources":["../source/embedded-resources.ts"],"names":[],"mappings":"AAGA,OAAO,CAAC,MAAM,CAAC;IACb,IAAI,2BAA2B,EAAE;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,SAAS,CAAA;CAC/D;AAED,eAAO,MAAM,yBAAyB,QAAO,IAE5C,CAAA"}
@@ -0,0 +1,5 @@
1
+ // @ts-expect-error Bun text imports embed the bundled agent skill in native binaries.
2
+ import skill from '../skills/guiho-s-runx/SKILL.md' with { type: 'text' };
3
+ export const registerEmbeddedResources = () => {
4
+ globalThis.__RUNX_EMBEDDED_RESOURCES__ = { skill };
5
+ };
@@ -0,0 +1,6 @@
1
+ export declare class RunXError extends Error {
2
+ readonly exitCode: number;
3
+ constructor(message: string, exitCode?: number);
4
+ }
5
+ export declare const invariant: (condition: unknown, message: string) => asserts condition;
6
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../source/errors.ts"],"names":[],"mappings":"AAAA,qBAAa,SAAU,SAAQ,KAAK;IAClC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IAEzB,YAAY,OAAO,EAAE,MAAM,EAAE,QAAQ,SAAI,EAIxC;CACF;AAED,eAAO,MAAM,SAAS,EAAE,CAAC,SAAS,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,SAExE,CAAA"}
@@ -0,0 +1,12 @@
1
+ export class RunXError extends Error {
2
+ exitCode;
3
+ constructor(message, exitCode = 1) {
4
+ super(message);
5
+ this.name = 'RunXError';
6
+ this.exitCode = exitCode;
7
+ }
8
+ }
9
+ export const invariant = (condition, message) => {
10
+ if (!condition)
11
+ throw new RunXError(message);
12
+ };
@@ -0,0 +1,3 @@
1
+ import type { ResolvedCommand } from './types.js';
2
+ export declare const runCommand: (command: ResolvedCommand) => Promise<number>;
3
+ //# sourceMappingURL=executor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"executor.d.ts","sourceRoot":"","sources":["../source/executor.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAGjD,eAAO,MAAM,UAAU,YAAmB,eAAe,KAAG,OAAO,CAAC,MAAM,CAWzE,CAAA"}
@@ -0,0 +1,24 @@
1
+ import { existsSync } from 'node:fs';
2
+ import { RunXError } from './errors.js';
3
+ export const runCommand = async (command) => {
4
+ if (!existsSync(command.cwd))
5
+ throw new RunXError(`Command working directory does not exist: ${command.cwd}`);
6
+ const process = Bun.spawn(shellArguments(command), {
7
+ cwd: command.cwd,
8
+ stdin: 'inherit',
9
+ stdout: 'inherit',
10
+ stderr: 'inherit',
11
+ });
12
+ return process.exited;
13
+ };
14
+ const shellArguments = (command) => {
15
+ switch (command.shell ?? 'auto') {
16
+ case 'bash': return ['bash', '-lc', command.command];
17
+ case 'sh': return ['sh', '-lc', command.command];
18
+ case 'powershell': return [process.platform === 'win32' ? 'powershell.exe' : 'pwsh', '-NoProfile', '-NonInteractive', '-Command', command.command];
19
+ case 'cmd': return ['cmd.exe', '/d', '/s', '/c', command.command];
20
+ case 'auto': return process.platform === 'win32'
21
+ ? ['cmd.exe', '/d', '/s', '/c', command.command]
22
+ : ['sh', '-lc', command.command];
23
+ }
24
+ };
@@ -0,0 +1,5 @@
1
+ import type { ParsedArgs } from './types.js';
2
+ export declare const parseArgs: (args: string[]) => ParsedArgs;
3
+ export declare const booleanFlag: (flags: ParsedArgs['flags'], name: string) => boolean;
4
+ export declare const stringFlag: (flags: ParsedArgs['flags'], name: string) => string | undefined;
5
+ //# sourceMappingURL=flags.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"flags.d.ts","sourceRoot":"","sources":["../source/flags.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAI5C,eAAO,MAAM,SAAS,SAAU,MAAM,EAAE,KAAG,UA8B1C,CAAA;AAED,eAAO,MAAM,WAAW,UAAW,UAAU,CAAC,OAAO,CAAC,QAAQ,MAAM,KAAG,OAA+B,CAAA;AAEtG,eAAO,MAAM,UAAU,UAAW,UAAU,CAAC,OAAO,CAAC,QAAQ,MAAM,KAAG,MAAM,GAAG,SAG9E,CAAA"}
@@ -0,0 +1,32 @@
1
+ const booleanFlags = new Set(['help', 'helpTree', 'helpDocs', 'version', 'verbose', 'dryRun', 'yes']);
2
+ export const parseArgs = (args) => {
3
+ const positionals = [];
4
+ const flags = {};
5
+ for (let index = 0; index < args.length; index += 1) {
6
+ const value = args[index];
7
+ if (!value.startsWith('--')) {
8
+ positionals.push(value);
9
+ continue;
10
+ }
11
+ const [rawName, inlineValue] = value.slice(2).split('=', 2);
12
+ const name = toCamelCase(rawName);
13
+ if (inlineValue !== undefined) {
14
+ flags[name] = inlineValue;
15
+ continue;
16
+ }
17
+ const next = args[index + 1];
18
+ if (!booleanFlags.has(name) && next && !next.startsWith('--')) {
19
+ flags[name] = next;
20
+ index += 1;
21
+ continue;
22
+ }
23
+ flags[name] = true;
24
+ }
25
+ return { command: positionals.shift(), positionals, flags };
26
+ };
27
+ export const booleanFlag = (flags, name) => flags[name] === true;
28
+ export const stringFlag = (flags, name) => {
29
+ const value = flags[name];
30
+ return typeof value === 'string' ? value : undefined;
31
+ };
32
+ const toCamelCase = (value) => value.replace(/-([a-z])/g, (_, letter) => letter.toUpperCase());
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env bun
2
+ export {};
3
+ //# sourceMappingURL=guiho-runx-bin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"guiho-runx-bin.d.ts","sourceRoot":"","sources":["../source/guiho-runx-bin.ts"],"names":[],"mappings":""}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env bun
2
+ import { runCliWithErrorHandling } from './cli.js';
3
+ await runCliWithErrorHandling();
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env bun
2
+ export {};
3
+ //# sourceMappingURL=guiho-runx-native-bin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"guiho-runx-native-bin.d.ts","sourceRoot":"","sources":["../source/guiho-runx-native-bin.ts"],"names":[],"mappings":""}
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env bun
2
+ import { registerEmbeddedResources } from './embedded-resources.js';
3
+ registerEmbeddedResources();
4
+ const { runCliWithErrorHandling } = await import('./cli.js');
5
+ await runCliWithErrorHandling();
@@ -0,0 +1,4 @@
1
+ export { runCli, runCliWithErrorHandling } from './cli.js';
2
+ export { findManifest, readManifest, resolveCommand } from './manifest.js';
3
+ export type { CliOptions, ResolvedCommand, RunXCommand, RunXManifest } from './types.js';
4
+ //# sourceMappingURL=guiho-runx.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"guiho-runx.d.ts","sourceRoot":"","sources":["../source/guiho-runx.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,uBAAuB,EAAE,MAAM,UAAU,CAAA;AAC1D,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA;AAC1E,YAAY,EAAE,UAAU,EAAE,eAAe,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA"}
@@ -0,0 +1,2 @@
1
+ export { runCli, runCliWithErrorHandling } from './cli.js';
2
+ export { findManifest, readManifest, resolveCommand } from './manifest.js';
@@ -0,0 +1,6 @@
1
+ export declare const readVersion: () => string;
2
+ export declare const showHome: () => string;
3
+ export declare const showHelpTree: () => string;
4
+ export declare const showHelpDocs: () => string;
5
+ export declare const showCommandHelp: (command: string) => string;
6
+ //# sourceMappingURL=help.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"help.d.ts","sourceRoot":"","sources":["../source/help.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,WAAW,QAAO,MAAiF,CAAA;AAEhH,eAAO,MAAM,QAAQ,QAAO,MAe3B,CAAA;AAED,eAAO,MAAM,YAAY,QAAO,MAapB,CAAA;AAEZ,eAAO,MAAM,YAAY,QAAO,MAU/B,CAAA;AAED,eAAO,MAAM,eAAe,YAAa,MAAM,KAAG,MAGjD,CAAA"}
@@ -0,0 +1,47 @@
1
+ import packageJson from '../package.json' with { type: 'json' };
2
+ export const readVersion = () => typeof packageJson.version === 'string' ? packageJson.version : '0.0.0';
3
+ export const showHome = () => `RunX ${readVersion()}
4
+
5
+ A documented, local command catalog for runx.yaml manifests.
6
+
7
+ Usage:
8
+ runx list [--file <path>] [--format <text|json>]
9
+ runx describe <selector>
10
+ runx run <selector> [--dry-run] [--yes]
11
+ runx r <selector> [--dry-run] [--yes]
12
+ runx <selector>
13
+
14
+ Start here:
15
+ runx list List every command in the nearest manifest.
16
+ runx --help-tree Show the complete command tree.
17
+ runx --help-docs Show manifest and agent documentation guidance.
18
+ `;
19
+ export const showHelpTree = () => [
20
+ 'runx',
21
+ '|- list',
22
+ '|- describe <selector>',
23
+ '|- run <selector>',
24
+ '| `- alias: r',
25
+ '|- check',
26
+ '|- agents',
27
+ '| |- install <local|global>',
28
+ '| `- instructions',
29
+ '|- upgrade [check|list]',
30
+ '`- uninstall',
31
+ '',
32
+ ].join('\n');
33
+ export const showHelpDocs = () => `RunX documentation
34
+
35
+ Manifest: runx.yaml, discovered from the current directory upward or selected with --file.
36
+ Required command fields: uid, id, group, summary, description, command.
37
+ Optional command fields: cwd, shell, tags, confirm.
38
+
39
+ Selectors resolve in this order: UID, group/id, one-based index, then an unambiguous ID.
40
+ Use UID values for automation. Use runx describe <selector> and runx run <selector> --dry-run before unfamiliar execution.
41
+
42
+ Agent skill: runx agents install local installs guiho-s-runx under .agents/skills.
43
+ `;
44
+ export const showCommandHelp = (command) => `RunX ${command}
45
+
46
+ Run \`runx --help-tree\` for command structure and \`runx --help-docs\` for manifest guidance.
47
+ `;
@@ -0,0 +1,41 @@
1
+ import type { ResolvedCommand, RunXManifest } from './types.js';
2
+ export declare const CommandSchema: import("@sinclair/typebox").TObject<{
3
+ uid: import("@sinclair/typebox").TString;
4
+ id: import("@sinclair/typebox").TString;
5
+ group: import("@sinclair/typebox").TString;
6
+ summary: import("@sinclair/typebox").TString;
7
+ description: import("@sinclair/typebox").TString;
8
+ command: import("@sinclair/typebox").TString;
9
+ cwd: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
10
+ shell: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TLiteral<"auto">, import("@sinclair/typebox").TLiteral<"bash">, import("@sinclair/typebox").TLiteral<"sh">, import("@sinclair/typebox").TLiteral<"powershell">, import("@sinclair/typebox").TLiteral<"cmd">]>>;
11
+ tags: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TArray<import("@sinclair/typebox").TString>>;
12
+ confirm: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TLiteral<"never">, import("@sinclair/typebox").TLiteral<"always">]>>;
13
+ }>;
14
+ export declare const ManifestSchema: import("@sinclair/typebox").TObject<{
15
+ version: import("@sinclair/typebox").TLiteral<1>;
16
+ project: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TObject<{
17
+ name: import("@sinclair/typebox").TString;
18
+ }>>;
19
+ groups: import("@sinclair/typebox").TRecord<import("@sinclair/typebox").TString, import("@sinclair/typebox").TObject<{
20
+ summary: import("@sinclair/typebox").TString;
21
+ }>>;
22
+ commands: import("@sinclair/typebox").TArray<import("@sinclair/typebox").TObject<{
23
+ uid: import("@sinclair/typebox").TString;
24
+ id: import("@sinclair/typebox").TString;
25
+ group: import("@sinclair/typebox").TString;
26
+ summary: import("@sinclair/typebox").TString;
27
+ description: import("@sinclair/typebox").TString;
28
+ command: import("@sinclair/typebox").TString;
29
+ cwd: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
30
+ shell: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TLiteral<"auto">, import("@sinclair/typebox").TLiteral<"bash">, import("@sinclair/typebox").TLiteral<"sh">, import("@sinclair/typebox").TLiteral<"powershell">, import("@sinclair/typebox").TLiteral<"cmd">]>>;
31
+ tags: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TArray<import("@sinclair/typebox").TString>>;
32
+ confirm: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TLiteral<"never">, import("@sinclair/typebox").TLiteral<"always">]>>;
33
+ }>>;
34
+ }>;
35
+ export declare const findManifest: (cwd: string, explicitFile?: string) => Promise<string>;
36
+ export declare const readManifest: (cwd: string, explicitFile?: string) => Promise<{
37
+ manifest: RunXManifest;
38
+ path: string;
39
+ }>;
40
+ export declare const resolveCommand: (manifest: RunXManifest, manifestPath: string, selector: string) => ResolvedCommand;
41
+ //# sourceMappingURL=manifest.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../source/manifest.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,eAAe,EAAe,YAAY,EAAE,MAAM,YAAY,CAAA;AAI5E,eAAO,MAAM,aAAa;;;;;;;;;;;EAiBS,CAAA;AAEnC,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;EAKQ,CAAA;AAInC,eAAO,MAAM,YAAY,QAAe,MAAM,iBAAiB,MAAM,KAAG,OAAO,CAAC,MAAM,CAiBrF,CAAA;AAED,eAAO,MAAM,YAAY,QAAe,MAAM,iBAAiB,MAAM,KAAG,OAAO,CAAC;IAAE,QAAQ,EAAE,YAAY,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAmBvH,CAAA;AAED,eAAO,MAAM,cAAc,aAAc,YAAY,gBAAgB,MAAM,YAAY,MAAM,KAAG,eAkC/F,CAAA"}