rhachet 1.14.0 → 1.15.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.
- package/dist/contract/cli/invoke.js +4 -1
- package/dist/contract/cli/invoke.js.map +1 -1
- package/dist/contract/cli/invokeRun.d.ts +8 -0
- package/dist/contract/cli/invokeRun.js +52 -0
- package/dist/contract/cli/invokeRun.js.map +1 -0
- package/dist/domain.objects/RoleSkillExecutable.d.ts +29 -0
- package/dist/domain.objects/RoleSkillExecutable.js +9 -0
- package/dist/domain.objects/RoleSkillExecutable.js.map +1 -0
- package/dist/domain.objects/index.d.ts +1 -0
- package/dist/domain.objects/index.js +1 -0
- package/dist/domain.objects/index.js.map +1 -1
- package/dist/domain.operations/invoke/discoverSkillExecutables.d.ts +10 -0
- package/dist/domain.operations/invoke/discoverSkillExecutables.js +85 -0
- package/dist/domain.operations/invoke/discoverSkillExecutables.js.map +1 -0
- package/dist/domain.operations/invoke/executeSkill.d.ts +9 -0
- package/dist/domain.operations/invoke/executeSkill.js +27 -0
- package/dist/domain.operations/invoke/executeSkill.js.map +1 -0
- package/dist/domain.operations/invoke/findUniqueSkillExecutable.d.ts +10 -0
- package/dist/domain.operations/invoke/findUniqueSkillExecutable.js +41 -0
- package/dist/domain.operations/invoke/findUniqueSkillExecutable.js.map +1 -0
- package/package.json +1 -1
|
@@ -14,6 +14,7 @@ const invokeInit_1 = require("./invokeInit");
|
|
|
14
14
|
const invokeList_1 = require("./invokeList");
|
|
15
15
|
const invokeReadme_1 = require("./invokeReadme");
|
|
16
16
|
const invokeRoles_1 = require("./invokeRoles");
|
|
17
|
+
const invokeRun_1 = require("./invokeRun");
|
|
17
18
|
/**
|
|
18
19
|
* .what = main entrypoint for CLI execution
|
|
19
20
|
* .why =
|
|
@@ -25,7 +26,8 @@ const invokeRoles_1 = require("./invokeRoles");
|
|
|
25
26
|
*/
|
|
26
27
|
const invoke = async (input) => {
|
|
27
28
|
// treat init command specially - it's purpose is to run before configs exists
|
|
28
|
-
|
|
29
|
+
// note: only the bare 'init' command, not 'roles init' which requires config
|
|
30
|
+
if (input.args[0] === 'init') {
|
|
29
31
|
const program = new commander_1.Command();
|
|
30
32
|
program.name('rhachet');
|
|
31
33
|
(0, invokeInit_1.invokeInit)({ program });
|
|
@@ -63,6 +65,7 @@ const invoke = async (input) => {
|
|
|
63
65
|
(0, invokeReadme_1.invokeReadme)({ program, registries });
|
|
64
66
|
(0, invokeList_1.invokeList)({ program, registries });
|
|
65
67
|
(0, invokeRoles_1.invokeRoles)({ program, registries });
|
|
68
|
+
(0, invokeRun_1.invokeRun)({ program });
|
|
66
69
|
(0, invokeChoose_1.invokeChoose)({ program });
|
|
67
70
|
(0, invokeAsk_1.invokeAsk)({ program, config: { path: configPath }, registries, hooks });
|
|
68
71
|
// invoke it
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"invoke.js","sourceRoot":"","sources":["../../../src/contract/cli/invoke.ts"],"names":[],"mappings":";;;AAAA,yCAAoC;AACpC,mDAAiD;AACjD,+DAAsD;AAEtD,uFAAoF;AACpF,6FAA0F;AAC1F,2FAAwF;AAExF,yCAAoC;AACpC,2CAAwC;AACxC,iDAA8C;AAC9C,6CAA0C;AAC1C,6CAA0C;AAC1C,iDAA8C;AAC9C,+CAA4C;
|
|
1
|
+
{"version":3,"file":"invoke.js","sourceRoot":"","sources":["../../../src/contract/cli/invoke.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.invokeRun = void 0;
|
|
4
|
+
const helpful_errors_1 = require("helpful-errors");
|
|
5
|
+
const executeSkill_1 = require("../../domain.operations/invoke/executeSkill");
|
|
6
|
+
const findUniqueSkillExecutable_1 = require("../../domain.operations/invoke/findUniqueSkillExecutable");
|
|
7
|
+
/**
|
|
8
|
+
* .what = extracts all args after 'run' command from process.argv
|
|
9
|
+
* .why = captures full arg list for passthrough to skill
|
|
10
|
+
*/
|
|
11
|
+
const getRawArgsAfterRun = () => {
|
|
12
|
+
const argv = process.argv;
|
|
13
|
+
const runIdx = argv.indexOf('run');
|
|
14
|
+
if (runIdx === -1)
|
|
15
|
+
return [];
|
|
16
|
+
return argv.slice(runIdx + 1);
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* .what = adds the "run" command to the CLI
|
|
20
|
+
* .why = discovers and executes skills from linked role directories
|
|
21
|
+
*/
|
|
22
|
+
const invokeRun = ({ program }) => {
|
|
23
|
+
program
|
|
24
|
+
.command('run')
|
|
25
|
+
.description('run a skill from linked role directories')
|
|
26
|
+
.option('-s, --skill <slug>', 'the skill to execute')
|
|
27
|
+
.option('--repo <slug>', 'filter to specific repo')
|
|
28
|
+
.option('--role <slug>', 'filter to specific role')
|
|
29
|
+
.allowUnknownOption(true)
|
|
30
|
+
.allowExcessArguments(true)
|
|
31
|
+
.action(async (opts) => {
|
|
32
|
+
// validate skill is provided
|
|
33
|
+
if (!opts.skill)
|
|
34
|
+
helpful_errors_1.BadRequestError.throw('--skill is required (e.g., --skill init.claude)');
|
|
35
|
+
// find unique skill
|
|
36
|
+
const skill = (0, findUniqueSkillExecutable_1.findUniqueSkillExecutable)({
|
|
37
|
+
repoSlug: opts.repo,
|
|
38
|
+
roleSlug: opts.role,
|
|
39
|
+
skillSlug: opts.skill,
|
|
40
|
+
});
|
|
41
|
+
// log which skill will run
|
|
42
|
+
console.log(``);
|
|
43
|
+
console.log(`🌊 skill "${skill.slug}" from repo=${skill.repoSlug} role=${skill.roleSlug}`);
|
|
44
|
+
console.log(``);
|
|
45
|
+
// get all args after 'run' for passthrough
|
|
46
|
+
const rawArgs = getRawArgsAfterRun();
|
|
47
|
+
// execute with all args passed through
|
|
48
|
+
(0, executeSkill_1.executeSkill)({ skill, args: rawArgs });
|
|
49
|
+
});
|
|
50
|
+
};
|
|
51
|
+
exports.invokeRun = invokeRun;
|
|
52
|
+
//# sourceMappingURL=invokeRun.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"invokeRun.js","sourceRoot":"","sources":["../../../src/contract/cli/invokeRun.ts"],"names":[],"mappings":";;;AACA,mDAAiD;AAEjD,6EAA0E;AAC1E,uGAAoG;AAEpG;;;GAGG;AACH,MAAM,kBAAkB,GAAG,GAAa,EAAE;IACxC,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAC1B,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IACnC,IAAI,MAAM,KAAK,CAAC,CAAC;QAAE,OAAO,EAAE,CAAC;IAC7B,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;AAChC,CAAC,CAAC;AAEF;;;GAGG;AACI,MAAM,SAAS,GAAG,CAAC,EAAE,OAAO,EAAwB,EAAQ,EAAE;IACnE,OAAO;SACJ,OAAO,CAAC,KAAK,CAAC;SACd,WAAW,CAAC,0CAA0C,CAAC;SACvD,MAAM,CAAC,oBAAoB,EAAE,sBAAsB,CAAC;SACpD,MAAM,CAAC,eAAe,EAAE,yBAAyB,CAAC;SAClD,MAAM,CAAC,eAAe,EAAE,yBAAyB,CAAC;SAClD,kBAAkB,CAAC,IAAI,CAAC;SACxB,oBAAoB,CAAC,IAAI,CAAC;SAC1B,MAAM,CAAC,KAAK,EAAE,IAAsD,EAAE,EAAE;QACvE,6BAA6B;QAC7B,IAAI,CAAC,IAAI,CAAC,KAAK;YACb,gCAAe,CAAC,KAAK,CACnB,iDAAiD,CAClD,CAAC;QAEJ,oBAAoB;QACpB,MAAM,KAAK,GAAG,IAAA,qDAAyB,EAAC;YACtC,QAAQ,EAAE,IAAI,CAAC,IAAI;YACnB,QAAQ,EAAE,IAAI,CAAC,IAAI;YACnB,SAAS,EAAE,IAAI,CAAC,KAAK;SACtB,CAAC,CAAC;QAEH,2BAA2B;QAC3B,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAChB,OAAO,CAAC,GAAG,CACT,aAAa,KAAK,CAAC,IAAI,eAAe,KAAK,CAAC,QAAQ,SAAS,KAAK,CAAC,QAAQ,EAAE,CAC9E,CAAC;QACF,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAEhB,2CAA2C;QAC3C,MAAM,OAAO,GAAG,kBAAkB,EAAE,CAAC;QAErC,uCAAuC;QACvC,IAAA,2BAAY,EAAC,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;IACzC,CAAC,CAAC,CAAC;AACP,CAAC,CAAC;AApCW,QAAA,SAAS,aAoCpB"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { DomainLiteral } from 'domain-objects';
|
|
2
|
+
/**
|
|
3
|
+
* .what = represents a discovered executable skill file from a role directory
|
|
4
|
+
* .why = enables skill discovery and execution via `rhachet run --skill`
|
|
5
|
+
*/
|
|
6
|
+
export interface RoleSkillExecutable {
|
|
7
|
+
/**
|
|
8
|
+
* .what = skill identifier derived from filename
|
|
9
|
+
* .example = "init.bhuild", "git.worktree"
|
|
10
|
+
*/
|
|
11
|
+
slug: string;
|
|
12
|
+
/**
|
|
13
|
+
* .what = absolute path to the executable file
|
|
14
|
+
*/
|
|
15
|
+
path: string;
|
|
16
|
+
/**
|
|
17
|
+
* .what = the repo (registry) this skill belongs to
|
|
18
|
+
* .example = "ehmpathy", ".this"
|
|
19
|
+
*/
|
|
20
|
+
repoSlug: string;
|
|
21
|
+
/**
|
|
22
|
+
* .what = the role this skill belongs to
|
|
23
|
+
* .example = "mechanic", "designer"
|
|
24
|
+
*/
|
|
25
|
+
roleSlug: string;
|
|
26
|
+
}
|
|
27
|
+
export declare class RoleSkillExecutable extends DomainLiteral<RoleSkillExecutable> implements RoleSkillExecutable {
|
|
28
|
+
static unique: readonly ["repoSlug", "roleSlug", "slug"];
|
|
29
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.RoleSkillExecutable = void 0;
|
|
4
|
+
const domain_objects_1 = require("domain-objects");
|
|
5
|
+
class RoleSkillExecutable extends domain_objects_1.DomainLiteral {
|
|
6
|
+
}
|
|
7
|
+
exports.RoleSkillExecutable = RoleSkillExecutable;
|
|
8
|
+
RoleSkillExecutable.unique = ['repoSlug', 'roleSlug', 'slug'];
|
|
9
|
+
//# sourceMappingURL=RoleSkillExecutable.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RoleSkillExecutable.js","sourceRoot":"","sources":["../../src/domain.objects/RoleSkillExecutable.ts"],"names":[],"mappings":";;;AAAA,mDAA+C;AA8B/C,MAAa,mBACX,SAAQ,8BAAkC;;AAD5C,kDAKC;AADe,0BAAM,GAAG,CAAC,UAAU,EAAE,UAAU,EAAE,MAAM,CAAU,CAAC"}
|
|
@@ -34,6 +34,7 @@ __exportStar(require("./RoleContext"), exports);
|
|
|
34
34
|
__exportStar(require("./RoleRegistry"), exports);
|
|
35
35
|
__exportStar(require("./RoleSkill"), exports);
|
|
36
36
|
__exportStar(require("./RoleSkillArgGetter"), exports);
|
|
37
|
+
__exportStar(require("./RoleSkillExecutable"), exports);
|
|
37
38
|
__exportStar(require("./RoleTrait"), exports);
|
|
38
39
|
__exportStar(require("./Template"), exports);
|
|
39
40
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/domain.objects/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,2CAAyB;AACzB,iDAA+B;AAC/B,gDAA8B;AAC9B,6CAA2B;AAC3B,iDAA+B;AAC/B,gDAA8B;AAC9B,mDAAiC;AACjC,+CAA6B;AAC7B,gDAA8B;AAC9B,2CAAyB;AACzB,4CAA0B;AAE1B,2BAA2B;AAC3B,4BAA4B;AAE5B,gDAA8B;AAC9B,+CAA6B;AAC7B,yCAAuB;AACvB,gDAA8B;AAC9B,iDAA+B;AAC/B,8CAA4B;AAC5B,uDAAqC;AACrC,8CAA4B;AAC5B,6CAA2B"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/domain.objects/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,2CAAyB;AACzB,iDAA+B;AAC/B,gDAA8B;AAC9B,6CAA2B;AAC3B,iDAA+B;AAC/B,gDAA8B;AAC9B,mDAAiC;AACjC,+CAA6B;AAC7B,gDAA8B;AAC9B,2CAAyB;AACzB,4CAA0B;AAE1B,2BAA2B;AAC3B,4BAA4B;AAE5B,gDAA8B;AAC9B,+CAA6B;AAC7B,yCAAuB;AACvB,gDAA8B;AAC9B,iDAA+B;AAC/B,8CAA4B;AAC5B,uDAAqC;AACrC,wDAAsC;AACtC,8CAA4B;AAC5B,6CAA2B"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { RoleSkillExecutable } from '../../domain.objects/RoleSkillExecutable';
|
|
2
|
+
/**
|
|
3
|
+
* .what = discovers executable skill files from linked role directories
|
|
4
|
+
* .why = enables `rhachet run --skill` to find and execute skills
|
|
5
|
+
*/
|
|
6
|
+
export declare const discoverSkillExecutables: (input: {
|
|
7
|
+
repoSlug?: string;
|
|
8
|
+
roleSlug?: string;
|
|
9
|
+
skillSlug?: string;
|
|
10
|
+
}) => RoleSkillExecutable[];
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.discoverSkillExecutables = void 0;
|
|
4
|
+
const RoleSkillExecutable_1 = require("../../domain.objects/RoleSkillExecutable");
|
|
5
|
+
const node_fs_1 = require("node:fs");
|
|
6
|
+
const node_path_1 = require("node:path");
|
|
7
|
+
/**
|
|
8
|
+
* .what = recursively finds all executable files in a directory
|
|
9
|
+
* .why = skills can be nested in subdirectories (e.g., claude.hooks/)
|
|
10
|
+
*/
|
|
11
|
+
const getAllFilesFromDir = (dir) => {
|
|
12
|
+
// skip if directory does not exist
|
|
13
|
+
if (!(0, node_fs_1.existsSync)(dir))
|
|
14
|
+
return [];
|
|
15
|
+
const entries = (0, node_fs_1.readdirSync)(dir);
|
|
16
|
+
const files = [];
|
|
17
|
+
for (const entry of entries) {
|
|
18
|
+
const fullPath = (0, node_path_1.resolve)(dir, entry);
|
|
19
|
+
const stats = (0, node_fs_1.statSync)(fullPath);
|
|
20
|
+
if (stats.isDirectory()) {
|
|
21
|
+
files.push(...getAllFilesFromDir(fullPath));
|
|
22
|
+
}
|
|
23
|
+
else if (stats.isFile()) {
|
|
24
|
+
files.push(fullPath);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
return files;
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
* .what = extracts skill slug from a filename
|
|
31
|
+
* .why = skill files may have .sh extension or be extensionless
|
|
32
|
+
*/
|
|
33
|
+
const extractSlugFromFilename = (filename) => {
|
|
34
|
+
// remove .sh extension if present
|
|
35
|
+
if (filename.endsWith('.sh'))
|
|
36
|
+
return filename.slice(0, -3);
|
|
37
|
+
return filename;
|
|
38
|
+
};
|
|
39
|
+
/**
|
|
40
|
+
* .what = discovers executable skill files from linked role directories
|
|
41
|
+
* .why = enables `rhachet run --skill` to find and execute skills
|
|
42
|
+
*/
|
|
43
|
+
const discoverSkillExecutables = (input) => {
|
|
44
|
+
const agentDir = (0, node_path_1.resolve)(process.cwd(), '.agent');
|
|
45
|
+
// skip if .agent directory does not exist
|
|
46
|
+
if (!(0, node_fs_1.existsSync)(agentDir))
|
|
47
|
+
return [];
|
|
48
|
+
// discover repo directories
|
|
49
|
+
const repoEntries = (0, node_fs_1.readdirSync)(agentDir).filter((entry) => entry.startsWith('repo='));
|
|
50
|
+
const skills = [];
|
|
51
|
+
for (const repoEntry of repoEntries) {
|
|
52
|
+
const repoSlug = repoEntry.replace('repo=', '');
|
|
53
|
+
// filter by repoSlug if specified
|
|
54
|
+
if (input.repoSlug && repoSlug !== input.repoSlug)
|
|
55
|
+
continue;
|
|
56
|
+
const repoDir = (0, node_path_1.resolve)(agentDir, repoEntry);
|
|
57
|
+
// discover role directories
|
|
58
|
+
const roleEntries = (0, node_fs_1.readdirSync)(repoDir).filter((entry) => entry.startsWith('role='));
|
|
59
|
+
for (const roleEntry of roleEntries) {
|
|
60
|
+
const roleSlug = roleEntry.replace('role=', '');
|
|
61
|
+
// filter by roleSlug if specified
|
|
62
|
+
if (input.roleSlug && roleSlug !== input.roleSlug)
|
|
63
|
+
continue;
|
|
64
|
+
const skillsDir = (0, node_path_1.resolve)(repoDir, roleEntry, 'skills');
|
|
65
|
+
// get all files from skills directory
|
|
66
|
+
const skillFiles = getAllFilesFromDir(skillsDir);
|
|
67
|
+
for (const skillPath of skillFiles) {
|
|
68
|
+
const filename = (0, node_path_1.basename)(skillPath);
|
|
69
|
+
const slug = extractSlugFromFilename(filename);
|
|
70
|
+
// filter by skillSlug if specified
|
|
71
|
+
if (input.skillSlug && slug !== input.skillSlug)
|
|
72
|
+
continue;
|
|
73
|
+
skills.push(new RoleSkillExecutable_1.RoleSkillExecutable({
|
|
74
|
+
slug,
|
|
75
|
+
path: skillPath,
|
|
76
|
+
repoSlug,
|
|
77
|
+
roleSlug,
|
|
78
|
+
}));
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
return skills;
|
|
83
|
+
};
|
|
84
|
+
exports.discoverSkillExecutables = discoverSkillExecutables;
|
|
85
|
+
//# sourceMappingURL=discoverSkillExecutables.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"discoverSkillExecutables.js","sourceRoot":"","sources":["../../../src/domain.operations/invoke/discoverSkillExecutables.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { RoleSkillExecutable } from '../../domain.objects/RoleSkillExecutable';
|
|
2
|
+
/**
|
|
3
|
+
* .what = executes a skill script with passthrough args
|
|
4
|
+
* .why = runs the discovered skill with full arg passthrough
|
|
5
|
+
*/
|
|
6
|
+
export declare const executeSkill: (input: {
|
|
7
|
+
skill: RoleSkillExecutable;
|
|
8
|
+
args: string[];
|
|
9
|
+
}) => void;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.executeSkill = void 0;
|
|
4
|
+
const node_child_process_1 = require("node:child_process");
|
|
5
|
+
/**
|
|
6
|
+
* .what = executes a skill script with passthrough args
|
|
7
|
+
* .why = runs the discovered skill with full arg passthrough
|
|
8
|
+
*/
|
|
9
|
+
const executeSkill = (input) => {
|
|
10
|
+
// build command with args
|
|
11
|
+
const command = [input.skill.path, ...input.args]
|
|
12
|
+
.map((arg) => {
|
|
13
|
+
// quote args with spaces
|
|
14
|
+
if (arg.includes(' '))
|
|
15
|
+
return `"${arg}"`;
|
|
16
|
+
return arg;
|
|
17
|
+
})
|
|
18
|
+
.join(' ');
|
|
19
|
+
// execute with inherited stdio
|
|
20
|
+
(0, node_child_process_1.execSync)(command, {
|
|
21
|
+
cwd: process.cwd(),
|
|
22
|
+
stdio: 'inherit',
|
|
23
|
+
shell: '/bin/bash',
|
|
24
|
+
});
|
|
25
|
+
};
|
|
26
|
+
exports.executeSkill = executeSkill;
|
|
27
|
+
//# sourceMappingURL=executeSkill.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"executeSkill.js","sourceRoot":"","sources":["../../../src/domain.operations/invoke/executeSkill.ts"],"names":[],"mappings":";;;AAEA,2DAA8C;AAE9C;;;GAGG;AACI,MAAM,YAAY,GAAG,CAAC,KAG5B,EAAQ,EAAE;IACT,0BAA0B;IAC1B,MAAM,OAAO,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,EAAE,GAAG,KAAK,CAAC,IAAI,CAAC;SAC9C,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE;QACX,yBAAyB;QACzB,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC;YAAE,OAAO,IAAI,GAAG,GAAG,CAAC;QACzC,OAAO,GAAG,CAAC;IACb,CAAC,CAAC;SACD,IAAI,CAAC,GAAG,CAAC,CAAC;IAEb,+BAA+B;IAC/B,IAAA,6BAAQ,EAAC,OAAO,EAAE;QAChB,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE;QAClB,KAAK,EAAE,SAAS;QAChB,KAAK,EAAE,WAAW;KACnB,CAAC,CAAC;AACL,CAAC,CAAC;AAnBW,QAAA,YAAY,gBAmBvB"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { RoleSkillExecutable } from '../../domain.objects/RoleSkillExecutable';
|
|
2
|
+
/**
|
|
3
|
+
* .what = finds exactly one skill executable by slug, with optional repo/role filters
|
|
4
|
+
* .why = ensures unambiguous skill resolution before execution
|
|
5
|
+
*/
|
|
6
|
+
export declare const findUniqueSkillExecutable: (input: {
|
|
7
|
+
repoSlug?: string;
|
|
8
|
+
roleSlug?: string;
|
|
9
|
+
skillSlug: string;
|
|
10
|
+
}) => RoleSkillExecutable;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.findUniqueSkillExecutable = void 0;
|
|
4
|
+
const helpful_errors_1 = require("helpful-errors");
|
|
5
|
+
const discoverSkillExecutables_1 = require("./discoverSkillExecutables");
|
|
6
|
+
/**
|
|
7
|
+
* .what = finds exactly one skill executable by slug, with optional repo/role filters
|
|
8
|
+
* .why = ensures unambiguous skill resolution before execution
|
|
9
|
+
*/
|
|
10
|
+
const findUniqueSkillExecutable = (input) => {
|
|
11
|
+
// discover skills with filters
|
|
12
|
+
const matches = (0, discoverSkillExecutables_1.discoverSkillExecutables)({
|
|
13
|
+
repoSlug: input.repoSlug,
|
|
14
|
+
roleSlug: input.roleSlug,
|
|
15
|
+
skillSlug: input.skillSlug,
|
|
16
|
+
});
|
|
17
|
+
// handle no matches
|
|
18
|
+
if (matches.length === 0) {
|
|
19
|
+
const filters = [
|
|
20
|
+
input.repoSlug ? `--repo ${input.repoSlug}` : null,
|
|
21
|
+
input.roleSlug ? `--role ${input.roleSlug}` : null,
|
|
22
|
+
]
|
|
23
|
+
.filter(Boolean)
|
|
24
|
+
.join(' ');
|
|
25
|
+
const hint = filters
|
|
26
|
+
? `no skill "${input.skillSlug}" found with ${filters}`
|
|
27
|
+
: `no skill "${input.skillSlug}" found in any linked role`;
|
|
28
|
+
helpful_errors_1.BadRequestError.throw(hint, { input });
|
|
29
|
+
}
|
|
30
|
+
// handle multiple matches
|
|
31
|
+
if (matches.length > 1) {
|
|
32
|
+
const matchList = matches
|
|
33
|
+
.map((m) => ` - repo=${m.repoSlug} role=${m.roleSlug}`)
|
|
34
|
+
.join('\n');
|
|
35
|
+
helpful_errors_1.BadRequestError.throw(`multiple skills found for "${input.skillSlug}":\n${matchList}\n\nuse --repo and/or --role to disambiguate`, { input, matches });
|
|
36
|
+
}
|
|
37
|
+
// return unique match
|
|
38
|
+
return matches[0];
|
|
39
|
+
};
|
|
40
|
+
exports.findUniqueSkillExecutable = findUniqueSkillExecutable;
|
|
41
|
+
//# sourceMappingURL=findUniqueSkillExecutable.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"findUniqueSkillExecutable.js","sourceRoot":"","sources":["../../../src/domain.operations/invoke/findUniqueSkillExecutable.ts"],"names":[],"mappings":";;;AAAA,mDAAiD;AAIjD,yEAAsE;AAEtE;;;GAGG;AACI,MAAM,yBAAyB,GAAG,CAAC,KAIzC,EAAuB,EAAE;IACxB,+BAA+B;IAC/B,MAAM,OAAO,GAAG,IAAA,mDAAwB,EAAC;QACvC,QAAQ,EAAE,KAAK,CAAC,QAAQ;QACxB,QAAQ,EAAE,KAAK,CAAC,QAAQ;QACxB,SAAS,EAAE,KAAK,CAAC,SAAS;KAC3B,CAAC,CAAC;IAEH,oBAAoB;IACpB,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,MAAM,OAAO,GAAG;YACd,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,UAAU,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,IAAI;YAClD,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,UAAU,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,IAAI;SACnD;aACE,MAAM,CAAC,OAAO,CAAC;aACf,IAAI,CAAC,GAAG,CAAC,CAAC;QAEb,MAAM,IAAI,GAAG,OAAO;YAClB,CAAC,CAAC,aAAa,KAAK,CAAC,SAAS,gBAAgB,OAAO,EAAE;YACvD,CAAC,CAAC,aAAa,KAAK,CAAC,SAAS,4BAA4B,CAAC;QAE7D,gCAAe,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;IACzC,CAAC;IAED,0BAA0B;IAC1B,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACvB,MAAM,SAAS,GAAG,OAAO;aACtB,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,YAAY,CAAC,CAAC,QAAQ,SAAS,CAAC,CAAC,QAAQ,EAAE,CAAC;aACvD,IAAI,CAAC,IAAI,CAAC,CAAC;QAEd,gCAAe,CAAC,KAAK,CACnB,8BAA8B,KAAK,CAAC,SAAS,OAAO,SAAS,8CAA8C,EAC3G,EAAE,KAAK,EAAE,OAAO,EAAE,CACnB,CAAC;IACJ,CAAC;IAED,sBAAsB;IACtB,OAAO,OAAO,CAAC,CAAC,CAAE,CAAC;AACrB,CAAC,CAAC;AA1CW,QAAA,yBAAyB,6BA0CpC"}
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "rhachet",
|
|
3
3
|
"author": "ehmpathy",
|
|
4
4
|
"description": "A framework for reliable, thorough thought. Weave threads of thought via stitches.",
|
|
5
|
-
"version": "1.
|
|
5
|
+
"version": "1.15.0",
|
|
6
6
|
"repository": "ehmpathy/rhachet",
|
|
7
7
|
"homepage": "https://github.com/ehmpathy/rhachet",
|
|
8
8
|
"keywords": [
|