rhachet 1.12.3 → 1.13.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/invokeBriefs.js +1 -1
- package/dist/contract/cli/invokeBriefs.js.map +1 -1
- package/dist/contract/cli/invokeBriefsBoot.d.ts +3 -1
- package/dist/contract/cli/invokeBriefsBoot.js +10 -7
- package/dist/contract/cli/invokeBriefsBoot.js.map +1 -1
- package/dist/contract/cli/invokeBriefsLink.js +8 -5
- package/dist/contract/cli/invokeBriefsLink.js.map +1 -1
- package/dist/contract/cli/invokeRoles.d.ts +1 -1
- package/dist/contract/cli/invokeRoles.js +5 -3
- package/dist/contract/cli/invokeRoles.js.map +1 -1
- package/dist/contract/cli/invokeRolesBoot.d.ts +3 -1
- package/dist/contract/cli/invokeRolesBoot.js +13 -51
- package/dist/contract/cli/invokeRolesBoot.js.map +1 -1
- package/dist/contract/cli/invokeRolesCost.d.ts +11 -0
- package/dist/contract/cli/invokeRolesCost.js +92 -0
- package/dist/contract/cli/invokeRolesCost.js.map +1 -0
- package/dist/contract/cli/invokeRolesLink.js +9 -6
- package/dist/contract/cli/invokeRolesLink.js.map +1 -1
- package/dist/domain/objects/RoleRegistry.d.ts +4 -0
- package/dist/domain/objects/RoleRegistry.js.map +1 -1
- package/dist/logic/invoke/inferRepoByRole.d.ts +10 -0
- package/dist/logic/invoke/inferRepoByRole.js +25 -0
- package/dist/logic/invoke/inferRepoByRole.js.map +1 -0
- package/dist/logic/role/extractSkillDocumentation.d.ts +12 -0
- package/dist/logic/role/extractSkillDocumentation.js +57 -0
- package/dist/logic/role/extractSkillDocumentation.js.map +1 -0
- package/dist/logic/role/formatCostTree.d.ts +21 -0
- package/dist/logic/role/formatCostTree.js +112 -0
- package/dist/logic/role/formatCostTree.js.map +1 -0
- package/dist/logic/role/getRoleFileCosts.d.ts +43 -0
- package/dist/logic/role/getRoleFileCosts.js +96 -0
- package/dist/logic/role/getRoleFileCosts.js.map +1 -0
- package/package.json +3 -1
|
@@ -13,7 +13,7 @@ const invokeBriefs = ({ program, registries, }) => {
|
|
|
13
13
|
.command('briefs')
|
|
14
14
|
.description('manage role briefs (link, boot)');
|
|
15
15
|
(0, invokeBriefsLink_1.invokeBriefsLink)({ command: briefsCommand, registries });
|
|
16
|
-
(0, invokeBriefsBoot_1.invokeBriefsBoot)({ command: briefsCommand });
|
|
16
|
+
(0, invokeBriefsBoot_1.invokeBriefsBoot)({ command: briefsCommand, registries });
|
|
17
17
|
};
|
|
18
18
|
exports.invokeBriefs = invokeBriefs;
|
|
19
19
|
//# sourceMappingURL=invokeBriefs.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"invokeBriefs.js","sourceRoot":"","sources":["../../../src/contract/cli/invokeBriefs.ts"],"names":[],"mappings":";;;AAGA,yDAAsD;AACtD,yDAAsD;AAEtD;;;;GAIG;AACI,MAAM,YAAY,GAAG,CAAC,EAC3B,OAAO,EACP,UAAU,GAIX,EAAQ,EAAE;IACT,MAAM,aAAa,GAAG,OAAO;SAC1B,OAAO,CAAC,QAAQ,CAAC;SACjB,WAAW,CAAC,iCAAiC,CAAC,CAAC;IAElD,IAAA,mCAAgB,EAAC,EAAE,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,CAAC,CAAC;IACzD,IAAA,mCAAgB,EAAC,EAAE,OAAO,EAAE,aAAa,EAAE,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"invokeBriefs.js","sourceRoot":"","sources":["../../../src/contract/cli/invokeBriefs.ts"],"names":[],"mappings":";;;AAGA,yDAAsD;AACtD,yDAAsD;AAEtD;;;;GAIG;AACI,MAAM,YAAY,GAAG,CAAC,EAC3B,OAAO,EACP,UAAU,GAIX,EAAQ,EAAE;IACT,MAAM,aAAa,GAAG,OAAO;SAC1B,OAAO,CAAC,QAAQ,CAAC;SACjB,WAAW,CAAC,iCAAiC,CAAC,CAAC;IAElD,IAAA,mCAAgB,EAAC,EAAE,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,CAAC,CAAC;IACzD,IAAA,mCAAgB,EAAC,EAAE,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,CAAC,CAAC;AAC3D,CAAC,CAAC;AAbW,QAAA,YAAY,gBAavB"}
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import type { Command } from 'commander';
|
|
2
|
+
import type { RoleRegistry } from '../../domain/objects/RoleRegistry';
|
|
2
3
|
/**
|
|
3
4
|
* .what = adds the "briefs boot" subcommand to the CLI
|
|
4
5
|
* .why = outputs all brief files with stats for context loading
|
|
5
6
|
* .how = reads all files in .agent/repo=$repo/role=$role/briefs and prints them with formatting
|
|
6
7
|
*/
|
|
7
|
-
export declare const invokeBriefsBoot: ({ command }: {
|
|
8
|
+
export declare const invokeBriefsBoot: ({ command, registries, }: {
|
|
8
9
|
command: Command;
|
|
10
|
+
registries: RoleRegistry[];
|
|
9
11
|
}) => void;
|
|
@@ -6,29 +6,32 @@ const node_fs_1 = require("node:fs");
|
|
|
6
6
|
const node_path_1 = require("node:path");
|
|
7
7
|
const helpful_errors_1 = require("helpful-errors");
|
|
8
8
|
const rhachet_artifact_git_1 = require("rhachet-artifact-git");
|
|
9
|
+
const inferRepoByRole_1 = require("../../logic/invoke/inferRepoByRole");
|
|
9
10
|
/**
|
|
10
11
|
* .what = adds the "briefs boot" subcommand to the CLI
|
|
11
12
|
* .why = outputs all brief files with stats for context loading
|
|
12
13
|
* .how = reads all files in .agent/repo=$repo/role=$role/briefs and prints them with formatting
|
|
13
14
|
*/
|
|
14
|
-
const invokeBriefsBoot = ({ command }) => {
|
|
15
|
+
const invokeBriefsBoot = ({ command, registries, }) => {
|
|
15
16
|
command
|
|
16
17
|
.command('boot')
|
|
17
18
|
.description('boot context from role briefs (print all brief files)')
|
|
18
19
|
.option('--repo <slug>', 'the repository slug for the role')
|
|
19
20
|
.option('--role <slug>', 'the role to boot briefs for')
|
|
20
21
|
.action(async (opts) => {
|
|
21
|
-
if (!opts.repo)
|
|
22
|
-
helpful_errors_1.BadRequestError.throw('--repo is required (e.g., --repo ehmpathy)');
|
|
23
22
|
if (!opts.role)
|
|
24
23
|
helpful_errors_1.BadRequestError.throw('--role is required (e.g., --role mechanic)');
|
|
25
|
-
const repoSlug = opts.repo;
|
|
26
24
|
const roleSlug = opts.role;
|
|
27
|
-
const
|
|
25
|
+
const repo = opts.repo
|
|
26
|
+
? registries.find((r) => r.slug === opts.repo)
|
|
27
|
+
: (0, inferRepoByRole_1.inferRepoByRole)({ registries, roleSlug });
|
|
28
|
+
if (!repo)
|
|
29
|
+
helpful_errors_1.BadRequestError.throw(`No repo found with slug "${opts.repo}"`);
|
|
30
|
+
const briefsDir = (0, node_path_1.resolve)(process.cwd(), '.agent', `repo=${repo.slug}`, `role=${roleSlug}`, 'briefs');
|
|
28
31
|
const gitRoot = await (0, rhachet_artifact_git_1.getGitRepoRoot)({ from: briefsDir });
|
|
29
32
|
// Check if briefs directory exists
|
|
30
33
|
if (!(0, node_fs_1.existsSync)(briefsDir)) {
|
|
31
|
-
helpful_errors_1.BadRequestError.throw(`Briefs directory not found: ${briefsDir}\nRun "rhachet briefs link --repo ${
|
|
34
|
+
helpful_errors_1.BadRequestError.throw(`Briefs directory not found: ${briefsDir}\nRun "rhachet briefs link --repo ${repo.slug} --role ${roleSlug}" first`);
|
|
32
35
|
}
|
|
33
36
|
// Recursively read all files, including those in symlinked directories
|
|
34
37
|
const getAllFiles = (dir) => {
|
|
@@ -109,7 +112,7 @@ const invokeBriefsBoot = ({ command }) => {
|
|
|
109
112
|
// Print each file
|
|
110
113
|
for (const filepath of files) {
|
|
111
114
|
const content = (0, node_fs_1.readFileSync)(filepath, 'utf-8');
|
|
112
|
-
const relativePath = `.agent/repo=${
|
|
115
|
+
const relativePath = `.agent/repo=${repo.slug}/role=${roleSlug}/briefs/${(0, node_path_1.relative)(briefsDir, filepath)}`;
|
|
113
116
|
console.log('#####################################################');
|
|
114
117
|
console.log('#####################################################');
|
|
115
118
|
console.log('#####################################################');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"invokeBriefsBoot.js","sourceRoot":"","sources":["../../../src/contract/cli/invokeBriefsBoot.ts"],"names":[],"mappings":";;;AAAA,2DAA8C;AAC9C,qCAA0E;AAC1E,yCAA8C;AAE9C,mDAAiD;AACjD,+DAAsD;
|
|
1
|
+
{"version":3,"file":"invokeBriefsBoot.js","sourceRoot":"","sources":["../../../src/contract/cli/invokeBriefsBoot.ts"],"names":[],"mappings":"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"}
|
|
@@ -4,6 +4,7 @@ exports.invokeBriefsLink = void 0;
|
|
|
4
4
|
const node_path_1 = require("node:path");
|
|
5
5
|
const helpful_errors_1 = require("helpful-errors");
|
|
6
6
|
const assureFindRole_1 = require("../../logic/invoke/assureFindRole");
|
|
7
|
+
const inferRepoByRole_1 = require("../../logic/invoke/inferRepoByRole");
|
|
7
8
|
const symlinkResourceDirectories_1 = require("../../logic/invoke/link/symlinkResourceDirectories");
|
|
8
9
|
/**
|
|
9
10
|
* .what = adds the "briefs link" subcommand to the CLI
|
|
@@ -17,21 +18,23 @@ const invokeBriefsLink = ({ command, registries, }) => {
|
|
|
17
18
|
.option('--repo <slug>', 'the repository slug for the role')
|
|
18
19
|
.option('--role <slug>', 'the role to link briefs for')
|
|
19
20
|
.action((opts) => {
|
|
20
|
-
if (!opts.repo)
|
|
21
|
-
helpful_errors_1.BadRequestError.throw('--repo is required (e.g., --repo ehmpathy)');
|
|
22
21
|
if (!opts.role)
|
|
23
22
|
helpful_errors_1.BadRequestError.throw('--role is required (e.g., --role mechanic)');
|
|
24
|
-
const repoSlug = opts.repo;
|
|
25
23
|
// Find the role from registries
|
|
26
24
|
const role = (0, assureFindRole_1.assureFindRole)({ registries, slug: opts.role });
|
|
25
|
+
const repo = opts.repo
|
|
26
|
+
? registries.find((r) => r.slug === opts.repo)
|
|
27
|
+
: (0, inferRepoByRole_1.inferRepoByRole)({ registries, roleSlug: opts.role });
|
|
28
|
+
if (!repo)
|
|
29
|
+
helpful_errors_1.BadRequestError.throw(`No repo found with slug "${opts.repo}"`);
|
|
27
30
|
// Check if role has briefs configured
|
|
28
31
|
if (role.briefs.dirs.length === 0) {
|
|
29
32
|
helpful_errors_1.BadRequestError.throw(`Role "${role.slug}" does not have briefs configured`);
|
|
30
33
|
}
|
|
31
34
|
console.log(``);
|
|
32
|
-
console.log(`📎 Linking briefs for role "${role.slug}" from repo "${
|
|
35
|
+
console.log(`📎 Linking briefs for role "${role.slug}" from repo "${repo.slug}"...`);
|
|
33
36
|
// Create .agent/repo=$repo/role=$role/briefs directory and link briefs
|
|
34
|
-
const briefsDir = (0, node_path_1.resolve)(process.cwd(), '.agent', `repo=${
|
|
37
|
+
const briefsDir = (0, node_path_1.resolve)(process.cwd(), '.agent', `repo=${repo.slug}`, `role=${role.slug}`, 'briefs');
|
|
35
38
|
const totalFiles = (0, symlinkResourceDirectories_1.symlinkResourceDirectories)({
|
|
36
39
|
sourceDirs: role.briefs.dirs,
|
|
37
40
|
targetDir: briefsDir,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"invokeBriefsLink.js","sourceRoot":"","sources":["../../../src/contract/cli/invokeBriefsLink.ts"],"names":[],"mappings":";;;AAAA,yCAAoC;AAEpC,mDAAiD;AAEjD,sEAAmE;AACnE,mGAAgG;AAGhG;;;;GAIG;AACI,MAAM,gBAAgB,GAAG,CAAC,EAC/B,OAAO,EACP,UAAU,GAIX,EAAQ,EAAE;IACT,OAAO;SACJ,OAAO,CAAC,MAAM,CAAC;SACf,WAAW,CAAC,qDAAqD,CAAC;SAClE,MAAM,CAAC,eAAe,EAAE,kCAAkC,CAAC;SAC3D,MAAM,CAAC,eAAe,EAAE,6BAA6B,CAAC;SACtD,MAAM,CAAC,CAAC,IAAsC,EAAE,EAAE;QACjD,IAAI,CAAC,IAAI,CAAC,IAAI;YACZ,gCAAe,CAAC,KAAK,CAAC,4CAA4C,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"invokeBriefsLink.js","sourceRoot":"","sources":["../../../src/contract/cli/invokeBriefsLink.ts"],"names":[],"mappings":";;;AAAA,yCAAoC;AAEpC,mDAAiD;AAEjD,sEAAmE;AACnE,wEAAqE;AACrE,mGAAgG;AAGhG;;;;GAIG;AACI,MAAM,gBAAgB,GAAG,CAAC,EAC/B,OAAO,EACP,UAAU,GAIX,EAAQ,EAAE;IACT,OAAO;SACJ,OAAO,CAAC,MAAM,CAAC;SACf,WAAW,CAAC,qDAAqD,CAAC;SAClE,MAAM,CAAC,eAAe,EAAE,kCAAkC,CAAC;SAC3D,MAAM,CAAC,eAAe,EAAE,6BAA6B,CAAC;SACtD,MAAM,CAAC,CAAC,IAAsC,EAAE,EAAE;QACjD,IAAI,CAAC,IAAI,CAAC,IAAI;YACZ,gCAAe,CAAC,KAAK,CAAC,4CAA4C,CAAC,CAAC;QAEtE,gCAAgC;QAChC,MAAM,IAAI,GAAG,IAAA,+BAAc,EAAC,EAAE,UAAU,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;QAC7D,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI;YACpB,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI,CAAC;YAC9C,CAAC,CAAC,IAAA,iCAAe,EAAC,EAAE,UAAU,EAAE,QAAQ,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;QACzD,IAAI,CAAC,IAAI;YACP,gCAAe,CAAC,KAAK,CAAC,4BAA4B,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC;QAElE,sCAAsC;QACtC,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAClC,gCAAe,CAAC,KAAK,CACnB,SAAS,IAAI,CAAC,IAAI,mCAAmC,CACtD,CAAC;QACJ,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAChB,OAAO,CAAC,GAAG,CACT,+BAA+B,IAAI,CAAC,IAAI,gBAAgB,IAAI,CAAC,IAAI,MAAM,CACxE,CAAC;QAEF,uEAAuE;QACvE,MAAM,SAAS,GAAG,IAAA,mBAAO,EACvB,OAAO,CAAC,GAAG,EAAE,EACb,QAAQ,EACR,QAAQ,IAAI,CAAC,IAAI,EAAE,EACnB,QAAQ,IAAI,CAAC,IAAI,EAAE,EACnB,QAAQ,CACT,CAAC;QAEF,MAAM,UAAU,GAAG,IAAA,uDAA0B,EAAC;YAC5C,UAAU,EAAE,IAAI,CAAC,MAAM,CAAC,IAAI;YAC5B,SAAS,EAAE,SAAS;YACpB,YAAY,EAAE,QAAQ;SACvB,CAAC,CAAC;QAEH,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAChB,OAAO,CAAC,GAAG,CAAC,aAAa,UAAU,gBAAgB,SAAS,EAAE,CAAC,CAAC;QAChE,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;AACP,CAAC,CAAC;AAvDW,QAAA,gBAAgB,oBAuD3B"}
|
|
@@ -3,7 +3,7 @@ import type { RoleRegistry } from '../sdk';
|
|
|
3
3
|
/**
|
|
4
4
|
* .what = adds the "roles" command to the CLI with subcommands
|
|
5
5
|
* .why = manages role resources (briefs and skills) in .agent/ directory structure
|
|
6
|
-
* .how = registers "link" and "
|
|
6
|
+
* .how = registers "link", "boot", and "cost" subcommands under "roles"
|
|
7
7
|
*/
|
|
8
8
|
export declare const invokeRoles: ({ program, registries, }: {
|
|
9
9
|
program: Command;
|
|
@@ -2,18 +2,20 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.invokeRoles = void 0;
|
|
4
4
|
const invokeRolesBoot_1 = require("./invokeRolesBoot");
|
|
5
|
+
const invokeRolesCost_1 = require("./invokeRolesCost");
|
|
5
6
|
const invokeRolesLink_1 = require("./invokeRolesLink");
|
|
6
7
|
/**
|
|
7
8
|
* .what = adds the "roles" command to the CLI with subcommands
|
|
8
9
|
* .why = manages role resources (briefs and skills) in .agent/ directory structure
|
|
9
|
-
* .how = registers "link" and "
|
|
10
|
+
* .how = registers "link", "boot", and "cost" subcommands under "roles"
|
|
10
11
|
*/
|
|
11
12
|
const invokeRoles = ({ program, registries, }) => {
|
|
12
13
|
const rolesCommand = program
|
|
13
14
|
.command('roles')
|
|
14
|
-
.description('manage role resources (link, boot)');
|
|
15
|
+
.description('manage role resources (link, boot, cost)');
|
|
15
16
|
(0, invokeRolesLink_1.invokeRolesLink)({ command: rolesCommand, registries });
|
|
16
|
-
(0, invokeRolesBoot_1.invokeRolesBoot)({ command: rolesCommand });
|
|
17
|
+
(0, invokeRolesBoot_1.invokeRolesBoot)({ command: rolesCommand, registries });
|
|
18
|
+
(0, invokeRolesCost_1.invokeRolesCost)({ command: rolesCommand, registries });
|
|
17
19
|
};
|
|
18
20
|
exports.invokeRoles = invokeRoles;
|
|
19
21
|
//# sourceMappingURL=invokeRoles.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"invokeRoles.js","sourceRoot":"","sources":["../../../src/contract/cli/invokeRoles.ts"],"names":[],"mappings":";;;AAGA,uDAAoD;AACpD,uDAAoD;AAEpD;;;;GAIG;AACI,MAAM,WAAW,GAAG,CAAC,EAC1B,OAAO,EACP,UAAU,GAIX,EAAQ,EAAE;IACT,MAAM,YAAY,GAAG,OAAO;SACzB,OAAO,CAAC,OAAO,CAAC;SAChB,WAAW,CAAC,
|
|
1
|
+
{"version":3,"file":"invokeRoles.js","sourceRoot":"","sources":["../../../src/contract/cli/invokeRoles.ts"],"names":[],"mappings":";;;AAGA,uDAAoD;AACpD,uDAAoD;AACpD,uDAAoD;AAEpD;;;;GAIG;AACI,MAAM,WAAW,GAAG,CAAC,EAC1B,OAAO,EACP,UAAU,GAIX,EAAQ,EAAE;IACT,MAAM,YAAY,GAAG,OAAO;SACzB,OAAO,CAAC,OAAO,CAAC;SAChB,WAAW,CAAC,0CAA0C,CAAC,CAAC;IAE3D,IAAA,iCAAe,EAAC,EAAE,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,CAAC,CAAC;IACvD,IAAA,iCAAe,EAAC,EAAE,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,CAAC,CAAC;IACvD,IAAA,iCAAe,EAAC,EAAE,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,CAAC,CAAC;AACzD,CAAC,CAAC;AAdW,QAAA,WAAW,eActB"}
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import type { Command } from 'commander';
|
|
2
|
+
import type { RoleRegistry } from '../../domain/objects/RoleRegistry';
|
|
2
3
|
/**
|
|
3
4
|
* .what = adds the "roles boot" subcommand to the CLI
|
|
4
5
|
* .why = outputs role resources (briefs and skills) with stats for context loading
|
|
5
6
|
* .how = reads all files in .agent/repo=$repo/role=$role and prints them with formatting
|
|
6
7
|
*/
|
|
7
|
-
export declare const invokeRolesBoot: ({ command }: {
|
|
8
|
+
export declare const invokeRolesBoot: ({ command, registries, }: {
|
|
8
9
|
command: Command;
|
|
10
|
+
registries: RoleRegistry[];
|
|
9
11
|
}) => void;
|
|
@@ -6,71 +6,33 @@ const node_fs_1 = require("node:fs");
|
|
|
6
6
|
const node_path_1 = require("node:path");
|
|
7
7
|
const helpful_errors_1 = require("helpful-errors");
|
|
8
8
|
const rhachet_artifact_git_1 = require("rhachet-artifact-git");
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
* .why = agents should understand what skills do, not how they do it
|
|
12
|
-
* .how = reads file and extracts only comments/documentation at the top
|
|
13
|
-
*/
|
|
14
|
-
const extractSkillDocumentation = (filepath) => {
|
|
15
|
-
const content = (0, node_fs_1.readFileSync)(filepath, 'utf-8');
|
|
16
|
-
const lines = content.split('\n');
|
|
17
|
-
const docLines = [];
|
|
18
|
-
// Extract shebang and leading comments/documentation
|
|
19
|
-
for (const line of lines) {
|
|
20
|
-
const trimmed = line.trim();
|
|
21
|
-
// Include shebang
|
|
22
|
-
if (trimmed.startsWith('#!')) {
|
|
23
|
-
docLines.push(line);
|
|
24
|
-
continue;
|
|
25
|
-
}
|
|
26
|
-
// Include comment lines (shell, python, etc)
|
|
27
|
-
if (trimmed.startsWith('#') ||
|
|
28
|
-
trimmed.startsWith('//') ||
|
|
29
|
-
trimmed.startsWith('*')) {
|
|
30
|
-
docLines.push(line);
|
|
31
|
-
continue;
|
|
32
|
-
}
|
|
33
|
-
// Stop at first non-comment, non-blank line
|
|
34
|
-
if (trimmed !== '') {
|
|
35
|
-
break;
|
|
36
|
-
}
|
|
37
|
-
// Include blank lines between comments
|
|
38
|
-
docLines.push(line);
|
|
39
|
-
}
|
|
40
|
-
// If we got some documentation, add a note about implementation being hidden
|
|
41
|
-
if (docLines.length > 0) {
|
|
42
|
-
docLines.push('');
|
|
43
|
-
docLines.push('# [implementation hidden - use skill to execute]');
|
|
44
|
-
}
|
|
45
|
-
else {
|
|
46
|
-
docLines.push('# [no documentation found]');
|
|
47
|
-
docLines.push('# [implementation hidden - use skill to execute]');
|
|
48
|
-
}
|
|
49
|
-
return docLines.join('\n');
|
|
50
|
-
};
|
|
9
|
+
const inferRepoByRole_1 = require("../../logic/invoke/inferRepoByRole");
|
|
10
|
+
const extractSkillDocumentation_1 = require("../../logic/role/extractSkillDocumentation");
|
|
51
11
|
/**
|
|
52
12
|
* .what = adds the "roles boot" subcommand to the CLI
|
|
53
13
|
* .why = outputs role resources (briefs and skills) with stats for context loading
|
|
54
14
|
* .how = reads all files in .agent/repo=$repo/role=$role and prints them with formatting
|
|
55
15
|
*/
|
|
56
|
-
const invokeRolesBoot = ({ command }) => {
|
|
16
|
+
const invokeRolesBoot = ({ command, registries, }) => {
|
|
57
17
|
command
|
|
58
18
|
.command('boot')
|
|
59
19
|
.description('boot context from role resources (briefs and skills)')
|
|
60
20
|
.option('--repo <slug>', 'the repository slug for the role')
|
|
61
21
|
.option('--role <slug>', 'the role to boot resources for')
|
|
62
22
|
.action(async (opts) => {
|
|
63
|
-
if (!opts.repo)
|
|
64
|
-
helpful_errors_1.BadRequestError.throw('--repo is required (e.g., --repo ehmpathy)');
|
|
65
23
|
if (!opts.role)
|
|
66
24
|
helpful_errors_1.BadRequestError.throw('--role is required (e.g., --role mechanic)');
|
|
67
|
-
const repoSlug = opts.repo;
|
|
68
25
|
const roleSlug = opts.role;
|
|
69
|
-
const
|
|
26
|
+
const repo = opts.repo
|
|
27
|
+
? registries.find((r) => r.slug === opts.repo)
|
|
28
|
+
: (0, inferRepoByRole_1.inferRepoByRole)({ registries, roleSlug });
|
|
29
|
+
if (!repo)
|
|
30
|
+
helpful_errors_1.BadRequestError.throw(`No repo found with slug "${opts.repo}"`);
|
|
31
|
+
const roleDir = (0, node_path_1.resolve)(process.cwd(), '.agent', `repo=${repo.slug}`, `role=${roleSlug}`);
|
|
70
32
|
const gitRoot = await (0, rhachet_artifact_git_1.getGitRepoRoot)({ from: roleDir });
|
|
71
33
|
// Check if role directory exists
|
|
72
34
|
if (!(0, node_fs_1.existsSync)(roleDir)) {
|
|
73
|
-
helpful_errors_1.BadRequestError.throw(`Role directory not found: ${roleDir}\nRun "rhachet roles link --repo ${
|
|
35
|
+
helpful_errors_1.BadRequestError.throw(`Role directory not found: ${roleDir}\nRun "rhachet roles link --repo ${repo.slug} --role ${roleSlug}" first`);
|
|
74
36
|
}
|
|
75
37
|
// Recursively read all files, including those in symlinked directories
|
|
76
38
|
const getAllFiles = (dir) => {
|
|
@@ -108,7 +70,7 @@ const invokeRolesBoot = ({ command }) => {
|
|
|
108
70
|
const isSkill = filepath.startsWith(skillsDir);
|
|
109
71
|
if (isSkill) {
|
|
110
72
|
// For skills, only count documentation
|
|
111
|
-
const doc = extractSkillDocumentation(filepath);
|
|
73
|
+
const doc = (0, extractSkillDocumentation_1.extractSkillDocumentation)(filepath);
|
|
112
74
|
totalChars += doc.length;
|
|
113
75
|
}
|
|
114
76
|
else {
|
|
@@ -171,7 +133,7 @@ const invokeRolesBoot = ({ command }) => {
|
|
|
171
133
|
printStats();
|
|
172
134
|
// Print each file
|
|
173
135
|
for (const filepath of allFiles) {
|
|
174
|
-
const relativePath = `.agent/repo=${
|
|
136
|
+
const relativePath = `.agent/repo=${repo.slug}/role=${roleSlug}/${(0, node_path_1.relative)(roleDir, filepath)}`;
|
|
175
137
|
const isSkill = filepath.startsWith(skillsDir);
|
|
176
138
|
console.log('#####################################################');
|
|
177
139
|
console.log('#####################################################');
|
|
@@ -181,7 +143,7 @@ const invokeRolesBoot = ({ command }) => {
|
|
|
181
143
|
console.log('');
|
|
182
144
|
// Get content based on file type
|
|
183
145
|
const content = isSkill
|
|
184
|
-
? extractSkillDocumentation(filepath)
|
|
146
|
+
? (0, extractSkillDocumentation_1.extractSkillDocumentation)(filepath)
|
|
185
147
|
: (0, node_fs_1.readFileSync)(filepath, 'utf-8');
|
|
186
148
|
// Print content with indentation
|
|
187
149
|
const indentedContent = content
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"invokeRolesBoot.js","sourceRoot":"","sources":["../../../src/contract/cli/invokeRolesBoot.ts"],"names":[],"mappings":";;;AAAA,2DAA8C;AAC9C,qCAA0E;AAC1E,yCAA8C;AAE9C,mDAAiD;AACjD,+DAAsD;
|
|
1
|
+
{"version":3,"file":"invokeRolesBoot.js","sourceRoot":"","sources":["../../../src/contract/cli/invokeRolesBoot.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Command } from 'commander';
|
|
2
|
+
import type { RoleRegistry } from '../../domain/objects/RoleRegistry';
|
|
3
|
+
/**
|
|
4
|
+
* .what = adds the "roles cost" subcommand to the CLI
|
|
5
|
+
* .why = outputs role resource costs without loading full file contents
|
|
6
|
+
* .how = reads files in .agent/repo=$repo/role=$role and computes per-file token/cost estimates
|
|
7
|
+
*/
|
|
8
|
+
export declare const invokeRolesCost: ({ command, registries, }: {
|
|
9
|
+
command: Command;
|
|
10
|
+
registries: RoleRegistry[];
|
|
11
|
+
}) => void;
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.invokeRolesCost = void 0;
|
|
4
|
+
const node_fs_1 = require("node:fs");
|
|
5
|
+
const node_path_1 = require("node:path");
|
|
6
|
+
const helpful_errors_1 = require("helpful-errors");
|
|
7
|
+
const inferRepoByRole_1 = require("../../logic/invoke/inferRepoByRole");
|
|
8
|
+
const formatCostTree_1 = require("../../logic/role/formatCostTree");
|
|
9
|
+
const getRoleFileCosts_1 = require("../../logic/role/getRoleFileCosts");
|
|
10
|
+
/**
|
|
11
|
+
* .what = adds the "roles cost" subcommand to the CLI
|
|
12
|
+
* .why = outputs role resource costs without loading full file contents
|
|
13
|
+
* .how = reads files in .agent/repo=$repo/role=$role and computes per-file token/cost estimates
|
|
14
|
+
*/
|
|
15
|
+
const invokeRolesCost = ({ command, registries, }) => {
|
|
16
|
+
command
|
|
17
|
+
.command('cost')
|
|
18
|
+
.description('show token/cost estimates for role resources')
|
|
19
|
+
.option('--repo <slug>', 'the repository slug for the role')
|
|
20
|
+
.option('--role <slug>', 'the role to analyze')
|
|
21
|
+
.action((opts) => {
|
|
22
|
+
// validate role is provided
|
|
23
|
+
if (!opts.role)
|
|
24
|
+
helpful_errors_1.BadRequestError.throw('--role is required (e.g., --role mechanic)');
|
|
25
|
+
const roleSlug = opts.role;
|
|
26
|
+
// resolve repo from option or inference
|
|
27
|
+
const repo = opts.repo
|
|
28
|
+
? registries.find((r) => r.slug === opts.repo)
|
|
29
|
+
: (0, inferRepoByRole_1.inferRepoByRole)({ registries, roleSlug });
|
|
30
|
+
if (!repo)
|
|
31
|
+
helpful_errors_1.BadRequestError.throw(`No repo found with slug "${opts.repo}"`);
|
|
32
|
+
// build role directory path
|
|
33
|
+
const roleDir = (0, node_path_1.resolve)(process.cwd(), '.agent', `repo=${repo.slug}`, `role=${roleSlug}`);
|
|
34
|
+
// check if role directory exists
|
|
35
|
+
if (!(0, node_fs_1.existsSync)(roleDir)) {
|
|
36
|
+
helpful_errors_1.BadRequestError.throw(`Role directory not found: ${roleDir}\nRun "rhachet roles link --repo ${repo.slug} --role ${roleSlug}" first`);
|
|
37
|
+
}
|
|
38
|
+
// get file costs
|
|
39
|
+
const fileCosts = (0, getRoleFileCosts_1.getRoleFileCosts)({
|
|
40
|
+
roleDir,
|
|
41
|
+
repoSlug: repo.slug,
|
|
42
|
+
roleSlug,
|
|
43
|
+
});
|
|
44
|
+
// handle empty role
|
|
45
|
+
if (fileCosts.length === 0) {
|
|
46
|
+
console.log(``);
|
|
47
|
+
console.log(`⚠️ No resources found in ${roleDir}`);
|
|
48
|
+
console.log(``);
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
// aggregate costs
|
|
52
|
+
const summary = (0, getRoleFileCosts_1.aggregateFileCosts)(fileCosts);
|
|
53
|
+
// format cost for display
|
|
54
|
+
const costFormatted = summary.totalCost < 0.01 ? `< $0.01` : (0, formatCostTree_1.formatCost)(summary.totalCost);
|
|
55
|
+
// print header
|
|
56
|
+
console.log(``);
|
|
57
|
+
console.log(`🌊 Role Cost Report: ${roleSlug} @ ${repo.slug}`);
|
|
58
|
+
console.log(``);
|
|
59
|
+
// print tree structure with costs
|
|
60
|
+
const rootPath = `.agent/repo=${repo.slug}/role=${roleSlug}`;
|
|
61
|
+
const tree = (0, formatCostTree_1.formatCostTree)({ fileCosts, rootPath });
|
|
62
|
+
console.log(tree);
|
|
63
|
+
console.log(``);
|
|
64
|
+
// print summary
|
|
65
|
+
console.log(`Summary:`);
|
|
66
|
+
console.log(` ├── files = ${summary.totalFiles}`);
|
|
67
|
+
console.log(` │ ├── briefs = ${summary.briefFiles}`);
|
|
68
|
+
console.log(` │ ├── skills = ${summary.skillFiles}`);
|
|
69
|
+
console.log(` │ └── other = ${summary.otherFiles}`);
|
|
70
|
+
console.log(` ├── chars = ${summary.totalChars.toLocaleString('en-US')}`);
|
|
71
|
+
console.log(` └── tokens ≈ ${summary.totalTokens.toLocaleString('en-US')} (${costFormatted} at $3/mil)`);
|
|
72
|
+
console.log(``);
|
|
73
|
+
// print top 10 token sources
|
|
74
|
+
const top10 = [...fileCosts]
|
|
75
|
+
.sort((a, b) => b.tokens - a.tokens)
|
|
76
|
+
.slice(0, 10);
|
|
77
|
+
console.log(`Top 10 Token Sources:`);
|
|
78
|
+
top10.forEach((file, index) => {
|
|
79
|
+
const isLast = index === top10.length - 1;
|
|
80
|
+
const prefix = isLast ? '└──' : '├──';
|
|
81
|
+
const tokens = file.tokens.toLocaleString('en-US');
|
|
82
|
+
const cost = (0, formatCostTree_1.formatCost)(file.cost);
|
|
83
|
+
const pct = ((file.tokens / summary.totalTokens) * 100).toFixed(1);
|
|
84
|
+
const fileName = file.relativePath.split('/').pop();
|
|
85
|
+
const docsOnly = file.isDocsOnly ? ' [docs only]' : '';
|
|
86
|
+
console.log(` ${prefix} ${tokens} tokens (${pct}%) ${fileName}${docsOnly}`);
|
|
87
|
+
});
|
|
88
|
+
console.log(``);
|
|
89
|
+
});
|
|
90
|
+
};
|
|
91
|
+
exports.invokeRolesCost = invokeRolesCost;
|
|
92
|
+
//# sourceMappingURL=invokeRolesCost.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"invokeRolesCost.js","sourceRoot":"","sources":["../../../src/contract/cli/invokeRolesCost.ts"],"names":[],"mappings":";;;AAAA,qCAAqC;AACrC,yCAAoC;AAEpC,mDAAiD;AAGjD,wEAAqE;AACrE,oEAA6E;AAC7E,wEAG2C;AAE3C;;;;GAIG;AACI,MAAM,eAAe,GAAG,CAAC,EAC9B,OAAO,EACP,UAAU,GAIX,EAAQ,EAAE;IACT,OAAO;SACJ,OAAO,CAAC,MAAM,CAAC;SACf,WAAW,CAAC,8CAA8C,CAAC;SAC3D,MAAM,CAAC,eAAe,EAAE,kCAAkC,CAAC;SAC3D,MAAM,CAAC,eAAe,EAAE,qBAAqB,CAAC;SAC9C,MAAM,CAAC,CAAC,IAAsC,EAAE,EAAE;QACjD,4BAA4B;QAC5B,IAAI,CAAC,IAAI,CAAC,IAAI;YACZ,gCAAe,CAAC,KAAK,CAAC,4CAA4C,CAAC,CAAC;QAEtE,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC;QAE3B,wCAAwC;QACxC,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI;YACpB,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI,CAAC;YAC9C,CAAC,CAAC,IAAA,iCAAe,EAAC,EAAE,UAAU,EAAE,QAAQ,EAAE,CAAC,CAAC;QAC9C,IAAI,CAAC,IAAI;YACP,gCAAe,CAAC,KAAK,CAAC,4BAA4B,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC;QAElE,4BAA4B;QAC5B,MAAM,OAAO,GAAG,IAAA,mBAAO,EACrB,OAAO,CAAC,GAAG,EAAE,EACb,QAAQ,EACR,QAAQ,IAAI,CAAC,IAAI,EAAE,EACnB,QAAQ,QAAQ,EAAE,CACnB,CAAC;QAEF,iCAAiC;QACjC,IAAI,CAAC,IAAA,oBAAU,EAAC,OAAO,CAAC,EAAE,CAAC;YACzB,gCAAe,CAAC,KAAK,CACnB,6BAA6B,OAAO,oCAAoC,IAAI,CAAC,IAAI,WAAW,QAAQ,SAAS,CAC9G,CAAC;QACJ,CAAC;QAED,iBAAiB;QACjB,MAAM,SAAS,GAAG,IAAA,mCAAgB,EAAC;YACjC,OAAO;YACP,QAAQ,EAAE,IAAI,CAAC,IAAI;YACnB,QAAQ;SACT,CAAC,CAAC;QAEH,oBAAoB;QACpB,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC3B,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAChB,OAAO,CAAC,GAAG,CAAC,6BAA6B,OAAO,EAAE,CAAC,CAAC;YACpD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAChB,OAAO;QACT,CAAC;QAED,kBAAkB;QAClB,MAAM,OAAO,GAAG,IAAA,qCAAkB,EAAC,SAAS,CAAC,CAAC;QAE9C,0BAA0B;QAC1B,MAAM,aAAa,GACjB,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAA,2BAAU,EAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QAEvE,eAAe;QACf,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAChB,OAAO,CAAC,GAAG,CAAC,wBAAwB,QAAQ,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;QAC/D,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAEhB,kCAAkC;QAClC,MAAM,QAAQ,GAAG,eAAe,IAAI,CAAC,IAAI,SAAS,QAAQ,EAAE,CAAC;QAC7D,MAAM,IAAI,GAAG,IAAA,+BAAc,EAAC,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC,CAAC;QACrD,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAClB,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAEhB,gBAAgB;QAChB,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QACxB,OAAO,CAAC,GAAG,CAAC,iBAAiB,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC;QACnD,OAAO,CAAC,GAAG,CAAC,sBAAsB,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC;QACxD,OAAO,CAAC,GAAG,CAAC,sBAAsB,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC;QACxD,OAAO,CAAC,GAAG,CAAC,qBAAqB,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC;QACvD,OAAO,CAAC,GAAG,CACT,iBAAiB,OAAO,CAAC,UAAU,CAAC,cAAc,CAAC,OAAO,CAAC,EAAE,CAC9D,CAAC;QACF,OAAO,CAAC,GAAG,CACT,kBAAkB,OAAO,CAAC,WAAW,CAAC,cAAc,CAAC,OAAO,CAAC,KAAK,aAAa,aAAa,CAC7F,CAAC;QACF,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAEhB,6BAA6B;QAC7B,MAAM,KAAK,GAAG,CAAC,GAAG,SAAS,CAAC;aACzB,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC;aACnC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QAEhB,OAAO,CAAC,GAAG,CAAC,uBAAuB,CAAC,CAAC;QACrC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE;YAC5B,MAAM,MAAM,GAAG,KAAK,KAAK,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;YAC1C,MAAM,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC;YACtC,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC;YACnD,MAAM,IAAI,GAAG,IAAA,2BAAU,EAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACnC,MAAM,GAAG,GAAG,CAAC,CAAC,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;YACnE,MAAM,QAAQ,GAAG,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC;YACpD,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,CAAC;YACvD,OAAO,CAAC,GAAG,CACT,KAAK,MAAM,IAAI,MAAM,YAAY,GAAG,MAAM,QAAQ,GAAG,QAAQ,EAAE,CAChE,CAAC;QACJ,CAAC,CAAC,CAAC;QACH,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;AACP,CAAC,CAAC;AA5GW,QAAA,eAAe,mBA4G1B"}
|
|
@@ -6,6 +6,7 @@ const node_path_1 = require("node:path");
|
|
|
6
6
|
const helpful_errors_1 = require("helpful-errors");
|
|
7
7
|
const assureFindRole_1 = require("../../logic/invoke/assureFindRole");
|
|
8
8
|
const getAgentReadmeTemplates_1 = require("../../logic/invoke/getAgentReadmeTemplates");
|
|
9
|
+
const inferRepoByRole_1 = require("../../logic/invoke/inferRepoByRole");
|
|
9
10
|
const findsertFile_1 = require("../../logic/invoke/link/findsertFile");
|
|
10
11
|
const symlinkResourceDirectories_1 = require("../../logic/invoke/link/symlinkResourceDirectories");
|
|
11
12
|
/**
|
|
@@ -20,19 +21,21 @@ const invokeRolesLink = ({ command, registries, }) => {
|
|
|
20
21
|
.option('--repo <slug>', 'the repository slug for the role')
|
|
21
22
|
.option('--role <slug>', 'the role to link resources for')
|
|
22
23
|
.action((opts) => {
|
|
23
|
-
if (!opts.repo)
|
|
24
|
-
helpful_errors_1.BadRequestError.throw('--repo is required (e.g., --repo ehmpathy)');
|
|
25
24
|
if (!opts.role)
|
|
26
25
|
helpful_errors_1.BadRequestError.throw('--role is required (e.g., --role mechanic)');
|
|
27
|
-
const repoSlug = opts.repo;
|
|
28
26
|
const role = (0, assureFindRole_1.assureFindRole)({ registries, slug: opts.role });
|
|
27
|
+
const repo = opts.repo
|
|
28
|
+
? registries.find((r) => r.slug === opts.repo)
|
|
29
|
+
: (0, inferRepoByRole_1.inferRepoByRole)({ registries, roleSlug: opts.role });
|
|
30
|
+
if (!repo)
|
|
31
|
+
helpful_errors_1.BadRequestError.throw(`No repo found with slug "${opts.repo}"`);
|
|
29
32
|
console.log(``);
|
|
30
|
-
console.log(`🔗 Linking role "${role.slug}" from repo "${
|
|
33
|
+
console.log(`🔗 Linking role "${role.slug}" from repo "${repo.slug}"...`);
|
|
31
34
|
console.log(``);
|
|
32
35
|
// Create .agent directory structure
|
|
33
36
|
const agentDir = (0, node_path_1.resolve)(process.cwd(), '.agent');
|
|
34
37
|
const repoThisDir = (0, node_path_1.resolve)(agentDir, 'repo=.this');
|
|
35
|
-
const repoRoleDir = (0, node_path_1.resolve)(agentDir, `repo=${
|
|
38
|
+
const repoRoleDir = (0, node_path_1.resolve)(agentDir, `repo=${repo.slug}`, `role=${role.slug}`);
|
|
36
39
|
(0, node_fs_1.mkdirSync)(agentDir, { recursive: true });
|
|
37
40
|
(0, node_fs_1.mkdirSync)(repoThisDir, { recursive: true });
|
|
38
41
|
(0, node_fs_1.mkdirSync)(repoRoleDir, { recursive: true });
|
|
@@ -66,7 +69,7 @@ const invokeRolesLink = ({ command, registries, }) => {
|
|
|
66
69
|
resourceName: 'skills',
|
|
67
70
|
});
|
|
68
71
|
console.log(``);
|
|
69
|
-
console.log(`🔗 Linked role "${role.slug}" from repo "${
|
|
72
|
+
console.log(`🔗 Linked role "${role.slug}" from repo "${repo.slug}"`);
|
|
70
73
|
if (briefsCount > 0)
|
|
71
74
|
console.log(` - ${briefsCount} brief(s) linked`);
|
|
72
75
|
if (skillsCount > 0)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"invokeRolesLink.js","sourceRoot":"","sources":["../../../src/contract/cli/invokeRolesLink.ts"],"names":[],"mappings":";;;AAAA,qCAAmD;AACnD,yCAA8C;AAE9C,mDAAiD;AAEjD,sEAAmE;AACnE,wFAGoD;AACpD,uEAAoE;AACpE,mGAAgG;AAGhG;;;;GAIG;AACI,MAAM,eAAe,GAAG,CAAC,EAC9B,OAAO,EACP,UAAU,GAIX,EAAQ,EAAE;IACT,OAAO;SACJ,OAAO,CAAC,MAAM,CAAC;SACf,WAAW,CAAC,sDAAsD,CAAC;SACnE,MAAM,CAAC,eAAe,EAAE,kCAAkC,CAAC;SAC3D,MAAM,CAAC,eAAe,EAAE,gCAAgC,CAAC;SACzD,MAAM,CAAC,CAAC,IAAsC,EAAE,EAAE;QACjD,IAAI,CAAC,IAAI,CAAC,IAAI;YACZ,gCAAe,CAAC,KAAK,CAAC,4CAA4C,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"invokeRolesLink.js","sourceRoot":"","sources":["../../../src/contract/cli/invokeRolesLink.ts"],"names":[],"mappings":";;;AAAA,qCAAmD;AACnD,yCAA8C;AAE9C,mDAAiD;AAEjD,sEAAmE;AACnE,wFAGoD;AACpD,wEAAqE;AACrE,uEAAoE;AACpE,mGAAgG;AAGhG;;;;GAIG;AACI,MAAM,eAAe,GAAG,CAAC,EAC9B,OAAO,EACP,UAAU,GAIX,EAAQ,EAAE;IACT,OAAO;SACJ,OAAO,CAAC,MAAM,CAAC;SACf,WAAW,CAAC,sDAAsD,CAAC;SACnE,MAAM,CAAC,eAAe,EAAE,kCAAkC,CAAC;SAC3D,MAAM,CAAC,eAAe,EAAE,gCAAgC,CAAC;SACzD,MAAM,CAAC,CAAC,IAAsC,EAAE,EAAE;QACjD,IAAI,CAAC,IAAI,CAAC,IAAI;YACZ,gCAAe,CAAC,KAAK,CAAC,4CAA4C,CAAC,CAAC;QAEtE,MAAM,IAAI,GAAG,IAAA,+BAAc,EAAC,EAAE,UAAU,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;QAC7D,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI;YACpB,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI,CAAC;YAC9C,CAAC,CAAC,IAAA,iCAAe,EAAC,EAAE,UAAU,EAAE,QAAQ,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;QACzD,IAAI,CAAC,IAAI;YACP,gCAAe,CAAC,KAAK,CAAC,4BAA4B,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC;QAElE,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAChB,OAAO,CAAC,GAAG,CAAC,oBAAoB,IAAI,CAAC,IAAI,gBAAgB,IAAI,CAAC,IAAI,MAAM,CAAC,CAAC;QAC1E,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAEhB,oCAAoC;QACpC,MAAM,QAAQ,GAAG,IAAA,mBAAO,EAAC,OAAO,CAAC,GAAG,EAAE,EAAE,QAAQ,CAAC,CAAC;QAClD,MAAM,WAAW,GAAG,IAAA,mBAAO,EAAC,QAAQ,EAAE,YAAY,CAAC,CAAC;QACpD,MAAM,WAAW,GAAG,IAAA,mBAAO,EACzB,QAAQ,EACR,QAAQ,IAAI,CAAC,IAAI,EAAE,EACnB,QAAQ,IAAI,CAAC,IAAI,EAAE,CACpB,CAAC;QAEF,IAAA,mBAAS,EAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACzC,IAAA,mBAAS,EAAC,WAAW,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC5C,IAAA,mBAAS,EAAC,WAAW,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAE5C,4BAA4B;QAC5B,IAAA,2BAAY,EAAC;YACX,IAAI,EAAE,IAAA,mBAAO,EAAC,QAAQ,EAAE,WAAW,CAAC;YACpC,QAAQ,EAAE,IAAA,oDAA0B,GAAE;SACvC,CAAC,CAAC;QAEH,uCAAuC;QACvC,IAAA,2BAAY,EAAC;YACX,IAAI,EAAE,IAAA,mBAAO,EAAC,WAAW,EAAE,WAAW,CAAC;YACvC,QAAQ,EAAE,IAAA,wDAA8B,GAAE;SAC3C,CAAC,CAAC;QAEH,gDAAgD;QAChD,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,MAAM,cAAc,GAAG,IAAA,mBAAO,EAAC,WAAW,EAAE,WAAW,CAAC,CAAC;YACzD,MAAM,sBAAsB,GAAG,IAAA,oBAAQ,EAAC,OAAO,CAAC,GAAG,EAAE,EAAE,cAAc,CAAC,CAAC;YACvE,IAAA,uBAAa,EAAC,cAAc,EAAE,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;YACnD,OAAO,CAAC,GAAG,CAAC,OAAO,sBAAsB,aAAa,CAAC,CAAC;QAC1D,CAAC;QAED,4BAA4B;QAC5B,MAAM,WAAW,GAAG,IAAA,uDAA0B,EAAC;YAC7C,UAAU,EAAE,IAAI,CAAC,MAAM,CAAC,IAAI;YAC5B,SAAS,EAAE,IAAA,mBAAO,EAAC,WAAW,EAAE,QAAQ,CAAC;YACzC,YAAY,EAAE,QAAQ;SACvB,CAAC,CAAC;QAEH,4BAA4B;QAC5B,MAAM,WAAW,GAAG,IAAA,uDAA0B,EAAC;YAC7C,UAAU,EAAE,IAAI,CAAC,MAAM,CAAC,IAAI;YAC5B,SAAS,EAAE,IAAA,mBAAO,EAAC,WAAW,EAAE,QAAQ,CAAC;YACzC,YAAY,EAAE,QAAQ;SACvB,CAAC,CAAC;QAEH,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAChB,OAAO,CAAC,GAAG,CAAC,mBAAmB,IAAI,CAAC,IAAI,gBAAgB,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC;QACtE,IAAI,WAAW,GAAG,CAAC;YAAE,OAAO,CAAC,GAAG,CAAC,OAAO,WAAW,kBAAkB,CAAC,CAAC;QACvE,IAAI,WAAW,GAAG,CAAC;YAAE,OAAO,CAAC,GAAG,CAAC,OAAO,WAAW,kBAAkB,CAAC,CAAC;QACvE,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;AACP,CAAC,CAAC;AAhFW,QAAA,eAAe,mBAgF1B"}
|
|
@@ -7,10 +7,14 @@ import { Role } from './Role';
|
|
|
7
7
|
* - enables composition of registries
|
|
8
8
|
* - supports cli and documentation introspection
|
|
9
9
|
* - supports fluid composition of roles via delegation (e.g., one role can runtime delegate to another that it found via registry)
|
|
10
|
+
*
|
|
11
|
+
* .note = a RoleRegistry is synonymous with a "repo" in CLI commands;
|
|
12
|
+
* the registry slug is used as the repo slug (e.g., --repo ehmpathy)
|
|
10
13
|
*/
|
|
11
14
|
export interface RoleRegistry {
|
|
12
15
|
/**
|
|
13
16
|
* .what = unique identifier for this registry
|
|
17
|
+
* .note = this is also used as the "repo" slug in CLI commands
|
|
14
18
|
*/
|
|
15
19
|
slug: string;
|
|
16
20
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RoleRegistry.js","sourceRoot":"","sources":["../../../src/domain/objects/RoleRegistry.ts"],"names":[],"mappings":";;;AAAA,mDAA8C;AAE9C,iCAA8B;
|
|
1
|
+
{"version":3,"file":"RoleRegistry.js","sourceRoot":"","sources":["../../../src/domain/objects/RoleRegistry.ts"],"names":[],"mappings":";;;AAAA,mDAA8C;AAE9C,iCAA8B;AA+B9B,MAAa,YACX,SAAQ,6BAA0B;;AADpC,oCAQC;AAJe,mBAAM,GAAG,CAAC,MAAM,CAAU,CAAC;AAC3B,mBAAM,GAAG;IACrB,KAAK,EAAE,WAAI;CACZ,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { RoleRegistry } from '../../domain/objects/RoleRegistry';
|
|
2
|
+
/**
|
|
3
|
+
* .what = infers the repo (registry) when only one has the specified role
|
|
4
|
+
* .why = allows omitting --repo when there's no ambiguity
|
|
5
|
+
* .how = searches registries for the one containing the role
|
|
6
|
+
*/
|
|
7
|
+
export declare const inferRepoByRole: (input: {
|
|
8
|
+
registries: RoleRegistry[];
|
|
9
|
+
roleSlug: string;
|
|
10
|
+
}) => RoleRegistry;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.inferRepoByRole = void 0;
|
|
4
|
+
const helpful_errors_1 = require("helpful-errors");
|
|
5
|
+
/**
|
|
6
|
+
* .what = infers the repo (registry) when only one has the specified role
|
|
7
|
+
* .why = allows omitting --repo when there's no ambiguity
|
|
8
|
+
* .how = searches registries for the one containing the role
|
|
9
|
+
*/
|
|
10
|
+
const inferRepoByRole = (input) => {
|
|
11
|
+
// Find all registries (repos) that have the specified role
|
|
12
|
+
const matchingRepos = input.registries.filter((registry) => registry.roles.some((role) => role.slug === input.roleSlug));
|
|
13
|
+
// Handle unique match
|
|
14
|
+
if (matchingRepos.length === 1)
|
|
15
|
+
return matchingRepos[0];
|
|
16
|
+
// Handle ambiguous case
|
|
17
|
+
if (matchingRepos.length > 1) {
|
|
18
|
+
const repoList = matchingRepos.map((r) => ` - ${r.slug}`).join('\n');
|
|
19
|
+
helpful_errors_1.BadRequestError.throw(`Multiple repos have role "${input.roleSlug}":\n${repoList}\nPlease specify --repo to disambiguate.`);
|
|
20
|
+
}
|
|
21
|
+
// Handle not found case
|
|
22
|
+
helpful_errors_1.BadRequestError.throw(`No repo has role "${input.roleSlug}".\nCheck that the role exists in your registries.`);
|
|
23
|
+
};
|
|
24
|
+
exports.inferRepoByRole = inferRepoByRole;
|
|
25
|
+
//# sourceMappingURL=inferRepoByRole.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inferRepoByRole.js","sourceRoot":"","sources":["../../../src/logic/invoke/inferRepoByRole.ts"],"names":[],"mappings":";;;AAAA,mDAAiD;AAIjD;;;;GAIG;AACI,MAAM,eAAe,GAAG,CAAC,KAG/B,EAAgB,EAAE;IACjB,2DAA2D;IAC3D,MAAM,aAAa,GAAG,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE,EAAE,CACzD,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,KAAK,CAAC,QAAQ,CAAC,CAC5D,CAAC;IAEF,sBAAsB;IACtB,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,aAAa,CAAC,CAAC,CAAE,CAAC;IAEzD,wBAAwB;IACxB,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC7B,MAAM,QAAQ,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACtE,gCAAe,CAAC,KAAK,CACnB,6BAA6B,KAAK,CAAC,QAAQ,OAAO,QAAQ,0CAA0C,CACrG,CAAC;IACJ,CAAC;IAED,wBAAwB;IACxB,gCAAe,CAAC,KAAK,CACnB,qBAAqB,KAAK,CAAC,QAAQ,oDAAoD,CACxF,CAAC;AACJ,CAAC,CAAC;AAxBW,QAAA,eAAe,mBAwB1B"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* .what = extracts documentation from a skill file without showing implementation
|
|
3
|
+
* .why = agents should understand what skills do, not how they do it
|
|
4
|
+
* .how = reads file and extracts only comments/documentation at the top
|
|
5
|
+
*/
|
|
6
|
+
export declare const extractSkillDocumentation: (filepath: string) => string;
|
|
7
|
+
/**
|
|
8
|
+
* .what = extracts documentation from skill file content string
|
|
9
|
+
* .why = enables testing without file system access
|
|
10
|
+
* .how = parses content and extracts shebang + leading comments
|
|
11
|
+
*/
|
|
12
|
+
export declare const extractSkillDocumentationFromContent: (content: string) => string;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.extractSkillDocumentationFromContent = exports.extractSkillDocumentation = void 0;
|
|
4
|
+
const node_fs_1 = require("node:fs");
|
|
5
|
+
/**
|
|
6
|
+
* .what = extracts documentation from a skill file without showing implementation
|
|
7
|
+
* .why = agents should understand what skills do, not how they do it
|
|
8
|
+
* .how = reads file and extracts only comments/documentation at the top
|
|
9
|
+
*/
|
|
10
|
+
const extractSkillDocumentation = (filepath) => {
|
|
11
|
+
const content = (0, node_fs_1.readFileSync)(filepath, 'utf-8');
|
|
12
|
+
return (0, exports.extractSkillDocumentationFromContent)(content);
|
|
13
|
+
};
|
|
14
|
+
exports.extractSkillDocumentation = extractSkillDocumentation;
|
|
15
|
+
/**
|
|
16
|
+
* .what = extracts documentation from skill file content string
|
|
17
|
+
* .why = enables testing without file system access
|
|
18
|
+
* .how = parses content and extracts shebang + leading comments
|
|
19
|
+
*/
|
|
20
|
+
const extractSkillDocumentationFromContent = (content) => {
|
|
21
|
+
const lines = content.split('\n');
|
|
22
|
+
const docLines = [];
|
|
23
|
+
// extract shebang and leading comments/documentation
|
|
24
|
+
for (const line of lines) {
|
|
25
|
+
const trimmed = line.trim();
|
|
26
|
+
// include shebang
|
|
27
|
+
if (trimmed.startsWith('#!')) {
|
|
28
|
+
docLines.push(line);
|
|
29
|
+
continue;
|
|
30
|
+
}
|
|
31
|
+
// include comment lines (shell, python, etc)
|
|
32
|
+
if (trimmed.startsWith('#') ||
|
|
33
|
+
trimmed.startsWith('//') ||
|
|
34
|
+
trimmed.startsWith('*')) {
|
|
35
|
+
docLines.push(line);
|
|
36
|
+
continue;
|
|
37
|
+
}
|
|
38
|
+
// stop at first non-comment, non-blank line
|
|
39
|
+
if (trimmed !== '') {
|
|
40
|
+
break;
|
|
41
|
+
}
|
|
42
|
+
// include blank lines between comments
|
|
43
|
+
docLines.push(line);
|
|
44
|
+
}
|
|
45
|
+
// add note about implementation being hidden
|
|
46
|
+
if (docLines.length > 0) {
|
|
47
|
+
docLines.push('');
|
|
48
|
+
docLines.push('# [implementation hidden - use skill to execute]');
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
docLines.push('# [no documentation found]');
|
|
52
|
+
docLines.push('# [implementation hidden - use skill to execute]');
|
|
53
|
+
}
|
|
54
|
+
return docLines.join('\n');
|
|
55
|
+
};
|
|
56
|
+
exports.extractSkillDocumentationFromContent = extractSkillDocumentationFromContent;
|
|
57
|
+
//# sourceMappingURL=extractSkillDocumentation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extractSkillDocumentation.js","sourceRoot":"","sources":["../../../src/logic/role/extractSkillDocumentation.ts"],"names":[],"mappings":";;;AAAA,qCAAuC;AAEvC;;;;GAIG;AACI,MAAM,yBAAyB,GAAG,CAAC,QAAgB,EAAU,EAAE;IACpE,MAAM,OAAO,GAAG,IAAA,sBAAY,EAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAChD,OAAO,IAAA,4CAAoC,EAAC,OAAO,CAAC,CAAC;AACvD,CAAC,CAAC;AAHW,QAAA,yBAAyB,6BAGpC;AAEF;;;;GAIG;AACI,MAAM,oCAAoC,GAAG,CAClD,OAAe,EACP,EAAE;IACV,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAClC,MAAM,QAAQ,GAAa,EAAE,CAAC;IAE9B,qDAAqD;IACrD,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;QAE5B,kBAAkB;QAClB,IAAI,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YAC7B,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACpB,SAAS;QACX,CAAC;QAED,6CAA6C;QAC7C,IACE,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC;YACvB,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC;YACxB,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,EACvB,CAAC;YACD,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACpB,SAAS;QACX,CAAC;QAED,4CAA4C;QAC5C,IAAI,OAAO,KAAK,EAAE,EAAE,CAAC;YACnB,MAAM;QACR,CAAC;QAED,uCAAuC;QACvC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACtB,CAAC;IAED,6CAA6C;IAC7C,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxB,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAClB,QAAQ,CAAC,IAAI,CAAC,kDAAkD,CAAC,CAAC;IACpE,CAAC;SAAM,CAAC;QACN,QAAQ,CAAC,IAAI,CAAC,4BAA4B,CAAC,CAAC;QAC5C,QAAQ,CAAC,IAAI,CAAC,kDAAkD,CAAC,CAAC;IACpE,CAAC;IAED,OAAO,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC7B,CAAC,CAAC;AA7CW,QAAA,oCAAoC,wCA6C/C"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { FileCost } from './getRoleFileCosts';
|
|
2
|
+
/**
|
|
3
|
+
* .what = formats a cost value as a dollar string
|
|
4
|
+
* .why = consistent cost display across the tree
|
|
5
|
+
* .how = uses fixed precision based on cost magnitude
|
|
6
|
+
*/
|
|
7
|
+
export declare const formatCost: (cost: number) => string;
|
|
8
|
+
/**
|
|
9
|
+
* .what = formats token count with thousands separators
|
|
10
|
+
* .why = improves readability for large token counts
|
|
11
|
+
*/
|
|
12
|
+
export declare const formatTokens: (tokens: number) => string;
|
|
13
|
+
/**
|
|
14
|
+
* .what = formats file costs as a tree structure with token/cost annotations
|
|
15
|
+
* .why = provides visual cost breakdown for role resources
|
|
16
|
+
* .how = builds tree from file paths and renders with box-drawing characters
|
|
17
|
+
*/
|
|
18
|
+
export declare const formatCostTree: (input: {
|
|
19
|
+
fileCosts: FileCost[];
|
|
20
|
+
rootPath: string;
|
|
21
|
+
}) => string;
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.formatCostTree = exports.formatTokens = exports.formatCost = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* .what = formats a cost value as a dollar string
|
|
6
|
+
* .why = consistent cost display across the tree
|
|
7
|
+
* .how = uses fixed precision based on cost magnitude
|
|
8
|
+
*/
|
|
9
|
+
const formatCost = (cost) => {
|
|
10
|
+
if (cost < 0.001)
|
|
11
|
+
return '$0.000';
|
|
12
|
+
if (cost < 0.01)
|
|
13
|
+
return `$${cost.toFixed(3)}`;
|
|
14
|
+
return `$${cost.toFixed(2)}`;
|
|
15
|
+
};
|
|
16
|
+
exports.formatCost = formatCost;
|
|
17
|
+
/**
|
|
18
|
+
* .what = formats token count with thousands separators
|
|
19
|
+
* .why = improves readability for large token counts
|
|
20
|
+
*/
|
|
21
|
+
const formatTokens = (tokens) => {
|
|
22
|
+
return tokens.toLocaleString('en-US');
|
|
23
|
+
};
|
|
24
|
+
exports.formatTokens = formatTokens;
|
|
25
|
+
/**
|
|
26
|
+
* .what = builds a tree structure from flat file costs
|
|
27
|
+
* .why = enables hierarchical rendering of directory structure
|
|
28
|
+
* .how = splits paths and builds nested map of nodes
|
|
29
|
+
*/
|
|
30
|
+
const buildTree = (fileCosts, rootPath) => {
|
|
31
|
+
const root = {
|
|
32
|
+
name: rootPath,
|
|
33
|
+
isFile: false,
|
|
34
|
+
children: new Map(),
|
|
35
|
+
};
|
|
36
|
+
for (const fileCost of fileCosts) {
|
|
37
|
+
// extract path relative to root
|
|
38
|
+
const relativePath = fileCost.relativePath.replace(`${rootPath}/`, '');
|
|
39
|
+
const parts = relativePath.split('/');
|
|
40
|
+
let current = root;
|
|
41
|
+
for (let i = 0; i < parts.length; i++) {
|
|
42
|
+
const part = parts[i];
|
|
43
|
+
const isLastPart = i === parts.length - 1;
|
|
44
|
+
if (!current.children.has(part)) {
|
|
45
|
+
current.children.set(part, {
|
|
46
|
+
name: part,
|
|
47
|
+
isFile: isLastPart,
|
|
48
|
+
fileCost: isLastPart ? fileCost : undefined,
|
|
49
|
+
children: new Map(),
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
current = current.children.get(part);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return root;
|
|
56
|
+
};
|
|
57
|
+
/**
|
|
58
|
+
* .what = renders a tree node and its children as formatted lines
|
|
59
|
+
* .why = produces the visual tree structure with box-drawing characters
|
|
60
|
+
* .how = recursively renders children with appropriate prefixes
|
|
61
|
+
*/
|
|
62
|
+
const renderNode = (node, prefix, isLast, isRoot) => {
|
|
63
|
+
const lines = [];
|
|
64
|
+
// determine connector character
|
|
65
|
+
const connector = isRoot ? '' : isLast ? '└── ' : '├── ';
|
|
66
|
+
const childPrefix = isRoot ? '' : prefix + (isLast ? ' ' : '│ ');
|
|
67
|
+
// format the line for this node
|
|
68
|
+
if (node.isFile && node.fileCost) {
|
|
69
|
+
const tokens = (0, exports.formatTokens)(node.fileCost.tokens);
|
|
70
|
+
const cost = (0, exports.formatCost)(node.fileCost.cost);
|
|
71
|
+
const docsOnly = node.fileCost.isDocsOnly ? ' [docs only]' : '';
|
|
72
|
+
// right-align cost info
|
|
73
|
+
const costInfo = `${tokens} tokens (${cost})${docsOnly}`;
|
|
74
|
+
lines.push(`${prefix}${connector}${node.name} ${costInfo}`);
|
|
75
|
+
}
|
|
76
|
+
else if (!isRoot) {
|
|
77
|
+
lines.push(`${prefix}${connector}${node.name}`);
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
lines.push(node.name);
|
|
81
|
+
}
|
|
82
|
+
// render children
|
|
83
|
+
const children = Array.from(node.children.values()).sort((a, b) => {
|
|
84
|
+
// directories first, then alphabetical
|
|
85
|
+
if (a.isFile !== b.isFile)
|
|
86
|
+
return a.isFile ? 1 : -1;
|
|
87
|
+
return a.name.localeCompare(b.name);
|
|
88
|
+
});
|
|
89
|
+
children.forEach((child, index) => {
|
|
90
|
+
const isLastChild = index === children.length - 1;
|
|
91
|
+
lines.push(...renderNode(child, childPrefix, isLastChild, false));
|
|
92
|
+
});
|
|
93
|
+
return lines;
|
|
94
|
+
};
|
|
95
|
+
/**
|
|
96
|
+
* .what = formats file costs as a tree structure with token/cost annotations
|
|
97
|
+
* .why = provides visual cost breakdown for role resources
|
|
98
|
+
* .how = builds tree from file paths and renders with box-drawing characters
|
|
99
|
+
*/
|
|
100
|
+
const formatCostTree = (input) => {
|
|
101
|
+
const { fileCosts, rootPath } = input;
|
|
102
|
+
// handle empty case
|
|
103
|
+
if (fileCosts.length === 0) {
|
|
104
|
+
return `${rootPath}\n (empty)`;
|
|
105
|
+
}
|
|
106
|
+
// build and render tree
|
|
107
|
+
const tree = buildTree(fileCosts, rootPath);
|
|
108
|
+
const lines = renderNode(tree, '', true, true);
|
|
109
|
+
return lines.join('\n');
|
|
110
|
+
};
|
|
111
|
+
exports.formatCostTree = formatCostTree;
|
|
112
|
+
//# sourceMappingURL=formatCostTree.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"formatCostTree.js","sourceRoot":"","sources":["../../../src/logic/role/formatCostTree.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* .what = represents the cost breakdown for a single file
|
|
3
|
+
* .why = enables per-file cost analysis and aggregation
|
|
4
|
+
*/
|
|
5
|
+
export interface FileCost {
|
|
6
|
+
path: string;
|
|
7
|
+
relativePath: string;
|
|
8
|
+
chars: number;
|
|
9
|
+
tokens: number;
|
|
10
|
+
cost: number;
|
|
11
|
+
type: 'brief' | 'skill' | 'other';
|
|
12
|
+
isDocsOnly: boolean;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* .what = recursively collects all files from a directory, following symlinks
|
|
16
|
+
* .why = need to traverse role directories including symlinked briefs/skills
|
|
17
|
+
* .how = uses statSync which follows symlinks to traverse directories
|
|
18
|
+
*/
|
|
19
|
+
export declare const getAllFiles: (dir: string) => string[];
|
|
20
|
+
/**
|
|
21
|
+
* .what = calculates token costs for all files in a role directory
|
|
22
|
+
* .why = shared between "roles boot" and "roles cost" commands
|
|
23
|
+
* .how = reads files, applies skill doc extraction, computes tokens
|
|
24
|
+
*/
|
|
25
|
+
export declare const getRoleFileCosts: (input: {
|
|
26
|
+
roleDir: string;
|
|
27
|
+
repoSlug: string;
|
|
28
|
+
roleSlug: string;
|
|
29
|
+
}) => FileCost[];
|
|
30
|
+
/**
|
|
31
|
+
* .what = aggregates file costs into summary statistics
|
|
32
|
+
* .why = provides total counts for display in cost reports
|
|
33
|
+
* .how = reduces file costs array into summary object
|
|
34
|
+
*/
|
|
35
|
+
export declare const aggregateFileCosts: (fileCosts: FileCost[]) => {
|
|
36
|
+
totalFiles: number;
|
|
37
|
+
briefFiles: number;
|
|
38
|
+
skillFiles: number;
|
|
39
|
+
otherFiles: number;
|
|
40
|
+
totalChars: number;
|
|
41
|
+
totalTokens: number;
|
|
42
|
+
totalCost: number;
|
|
43
|
+
};
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.aggregateFileCosts = exports.getRoleFileCosts = exports.getAllFiles = void 0;
|
|
4
|
+
const node_fs_1 = require("node:fs");
|
|
5
|
+
const node_path_1 = require("node:path");
|
|
6
|
+
const extractSkillDocumentation_1 = require("./extractSkillDocumentation");
|
|
7
|
+
/**
|
|
8
|
+
* .what = recursively collects all files from a directory, following symlinks
|
|
9
|
+
* .why = need to traverse role directories including symlinked briefs/skills
|
|
10
|
+
* .how = uses statSync which follows symlinks to traverse directories
|
|
11
|
+
*/
|
|
12
|
+
const getAllFiles = (dir) => {
|
|
13
|
+
const entries = (0, node_fs_1.readdirSync)(dir);
|
|
14
|
+
const files = [];
|
|
15
|
+
for (const entry of entries) {
|
|
16
|
+
const fullPath = (0, node_path_1.resolve)(dir, entry);
|
|
17
|
+
const stats = (0, node_fs_1.statSync)(fullPath);
|
|
18
|
+
if (stats.isDirectory()) {
|
|
19
|
+
files.push(...(0, exports.getAllFiles)(fullPath));
|
|
20
|
+
}
|
|
21
|
+
else if (stats.isFile()) {
|
|
22
|
+
files.push(fullPath);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
return files;
|
|
26
|
+
};
|
|
27
|
+
exports.getAllFiles = getAllFiles;
|
|
28
|
+
/**
|
|
29
|
+
* .what = calculates token costs for all files in a role directory
|
|
30
|
+
* .why = shared between "roles boot" and "roles cost" commands
|
|
31
|
+
* .how = reads files, applies skill doc extraction, computes tokens
|
|
32
|
+
*/
|
|
33
|
+
const getRoleFileCosts = (input) => {
|
|
34
|
+
const { roleDir, repoSlug, roleSlug } = input;
|
|
35
|
+
// define directories for type classification
|
|
36
|
+
const briefsDir = (0, node_path_1.resolve)(roleDir, 'briefs');
|
|
37
|
+
const skillsDir = (0, node_path_1.resolve)(roleDir, 'skills');
|
|
38
|
+
// collect all files
|
|
39
|
+
const allFiles = (0, exports.getAllFiles)(roleDir).sort();
|
|
40
|
+
// calculate cost per million tokens ($3/mil)
|
|
41
|
+
const costPerMillionTokens = 3;
|
|
42
|
+
// compute costs for each file
|
|
43
|
+
const fileCosts = allFiles.map((filepath) => {
|
|
44
|
+
const isSkill = filepath.startsWith(skillsDir);
|
|
45
|
+
const isBrief = filepath.startsWith(briefsDir);
|
|
46
|
+
// determine content to count
|
|
47
|
+
const contentToCount = isSkill
|
|
48
|
+
? (0, extractSkillDocumentation_1.extractSkillDocumentation)(filepath)
|
|
49
|
+
: (0, node_fs_1.readFileSync)(filepath, 'utf-8');
|
|
50
|
+
// calculate metrics
|
|
51
|
+
const chars = contentToCount.length;
|
|
52
|
+
const tokens = Math.ceil(chars / 4);
|
|
53
|
+
const cost = (tokens / 1000000) * costPerMillionTokens;
|
|
54
|
+
// determine file type
|
|
55
|
+
const type = isSkill
|
|
56
|
+
? 'skill'
|
|
57
|
+
: isBrief
|
|
58
|
+
? 'brief'
|
|
59
|
+
: 'other';
|
|
60
|
+
return {
|
|
61
|
+
path: filepath,
|
|
62
|
+
relativePath: `.agent/repo=${repoSlug}/role=${roleSlug}/${(0, node_path_1.relative)(roleDir, filepath)}`,
|
|
63
|
+
chars,
|
|
64
|
+
tokens,
|
|
65
|
+
cost,
|
|
66
|
+
type,
|
|
67
|
+
isDocsOnly: isSkill,
|
|
68
|
+
};
|
|
69
|
+
});
|
|
70
|
+
return fileCosts;
|
|
71
|
+
};
|
|
72
|
+
exports.getRoleFileCosts = getRoleFileCosts;
|
|
73
|
+
/**
|
|
74
|
+
* .what = aggregates file costs into summary statistics
|
|
75
|
+
* .why = provides total counts for display in cost reports
|
|
76
|
+
* .how = reduces file costs array into summary object
|
|
77
|
+
*/
|
|
78
|
+
const aggregateFileCosts = (fileCosts) => {
|
|
79
|
+
const briefFiles = fileCosts.filter((f) => f.type === 'brief').length;
|
|
80
|
+
const skillFiles = fileCosts.filter((f) => f.type === 'skill').length;
|
|
81
|
+
const otherFiles = fileCosts.filter((f) => f.type === 'other').length;
|
|
82
|
+
const totalChars = fileCosts.reduce((sum, f) => sum + f.chars, 0);
|
|
83
|
+
const totalTokens = fileCosts.reduce((sum, f) => sum + f.tokens, 0);
|
|
84
|
+
const totalCost = fileCosts.reduce((sum, f) => sum + f.cost, 0);
|
|
85
|
+
return {
|
|
86
|
+
totalFiles: fileCosts.length,
|
|
87
|
+
briefFiles,
|
|
88
|
+
skillFiles,
|
|
89
|
+
otherFiles,
|
|
90
|
+
totalChars,
|
|
91
|
+
totalTokens,
|
|
92
|
+
totalCost,
|
|
93
|
+
};
|
|
94
|
+
};
|
|
95
|
+
exports.aggregateFileCosts = aggregateFileCosts;
|
|
96
|
+
//# sourceMappingURL=getRoleFileCosts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getRoleFileCosts.js","sourceRoot":"","sources":["../../../src/logic/role/getRoleFileCosts.ts"],"names":[],"mappings":"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"}
|
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.13.0",
|
|
6
6
|
"repository": "ehmpathy/rhachet",
|
|
7
7
|
"homepage": "https://github.com/ehmpathy/rhachet",
|
|
8
8
|
"keywords": [
|
|
@@ -89,6 +89,8 @@
|
|
|
89
89
|
"esbuild-register": "3.6.0",
|
|
90
90
|
"husky": "8.0.3",
|
|
91
91
|
"jest": "30.2.0",
|
|
92
|
+
"rhachet": "1.12.3",
|
|
93
|
+
"rhachet-roles-ehmpathy": "1.12.1",
|
|
92
94
|
"test-fns": "1.7.0",
|
|
93
95
|
"tsx": "4.20.6",
|
|
94
96
|
"typescript": "5.4.5"
|