@crewhaus/slash-commands 0.2.4 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +14 -3
- package/dist/index.js +34 -9
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -8,6 +8,15 @@ export type SlashCommand = {
|
|
|
8
8
|
};
|
|
9
9
|
export type LoadCommandsOptions = {
|
|
10
10
|
readonly cwd?: string;
|
|
11
|
+
/** Home directory override for the user-level root (tests). */
|
|
12
|
+
readonly homeDir?: string;
|
|
13
|
+
/**
|
|
14
|
+
* Builtin command directories, merged at LOWEST precedence. Each entry is
|
|
15
|
+
* read as a flat directory of `<name>.md` files (no `.crewhaus/commands`
|
|
16
|
+
* suffix is appended). User (`~/.crewhaus/commands`) and project
|
|
17
|
+
* (`<cwd>/.crewhaus/commands`) commands override builtins by name.
|
|
18
|
+
*/
|
|
19
|
+
readonly builtinDirs?: ReadonlyArray<string>;
|
|
11
20
|
};
|
|
12
21
|
export type ExpandResult = {
|
|
13
22
|
readonly handled: boolean;
|
|
@@ -20,9 +29,11 @@ export declare class SlashCommandError extends CrewhausError {
|
|
|
20
29
|
constructor(message: string, cause?: unknown);
|
|
21
30
|
}
|
|
22
31
|
/**
|
|
23
|
-
* Read every `.md` file directly under
|
|
24
|
-
*
|
|
25
|
-
*
|
|
32
|
+
* Read every `.md` file directly under each command root — builtin dirs
|
|
33
|
+
* first, then `~/.crewhaus/commands/`, then `<cwd>/.crewhaus/commands/` —
|
|
34
|
+
* so later roots override earlier ones by name. Each file's basename (sans
|
|
35
|
+
* extension) becomes its key in the returned map. Subdirectories are not
|
|
36
|
+
* currently walked (v1 keeps the namespace flat).
|
|
26
37
|
*/
|
|
27
38
|
export declare function loadCommands(opts?: LoadCommandsOptions): Promise<Map<string, SlashCommand>>;
|
|
28
39
|
type ParsedCommand = {
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,17 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Catalog R9 `slash-commands` — markdown-templated user-input shortcuts
|
|
3
|
-
* loaded from
|
|
3
|
+
* loaded from three kinds of roots, lowest precedence first (later roots
|
|
4
|
+
* override earlier ones by command name):
|
|
5
|
+
*
|
|
6
|
+
* 0. builtin directories (`opts.builtinDirs`) — shipped defaults, e.g.
|
|
7
|
+
* `@crewhaus/default-skills`' `commands/` dir. Each entry is used as
|
|
8
|
+
* the commands directory itself (it is NOT suffixed with
|
|
9
|
+
* `.crewhaus/commands`).
|
|
10
|
+
* 1. `~/.crewhaus/commands/<name>.md` — user-level commands.
|
|
11
|
+
* 2. `<cwd>/.crewhaus/commands/<name>.md` — project commands.
|
|
12
|
+
*
|
|
13
|
+
* A user or project command with a builtin's name replaces it wholesale, so
|
|
14
|
+
* builtins are overridable (and, with an empty body, effectively disabled).
|
|
4
15
|
*
|
|
5
16
|
* Each file is a markdown body with optional YAML frontmatter:
|
|
6
17
|
*
|
|
@@ -25,6 +36,7 @@
|
|
|
25
36
|
* package is pure: filesystem read + string templating, no I/O elsewhere.
|
|
26
37
|
*/
|
|
27
38
|
import { existsSync, readFileSync, readdirSync, statSync } from "node:fs";
|
|
39
|
+
import { homedir } from "node:os";
|
|
28
40
|
import { basename, join } from "node:path";
|
|
29
41
|
import { CrewhausError } from "@crewhaus/errors";
|
|
30
42
|
import { parse as parseYaml } from "yaml";
|
|
@@ -37,22 +49,36 @@ export class SlashCommandError extends CrewhausError {
|
|
|
37
49
|
}
|
|
38
50
|
}
|
|
39
51
|
/**
|
|
40
|
-
* Read every `.md` file directly under
|
|
41
|
-
*
|
|
42
|
-
*
|
|
52
|
+
* Read every `.md` file directly under each command root — builtin dirs
|
|
53
|
+
* first, then `~/.crewhaus/commands/`, then `<cwd>/.crewhaus/commands/` —
|
|
54
|
+
* so later roots override earlier ones by name. Each file's basename (sans
|
|
55
|
+
* extension) becomes its key in the returned map. Subdirectories are not
|
|
56
|
+
* currently walked (v1 keeps the namespace flat).
|
|
43
57
|
*/
|
|
44
58
|
export async function loadCommands(opts = {}) {
|
|
45
59
|
const cwd = opts.cwd ?? process.cwd();
|
|
46
|
-
const
|
|
47
|
-
|
|
48
|
-
|
|
60
|
+
const home = opts.homeDir ?? homedir();
|
|
61
|
+
const userRoot = join(home, COMMANDS_RELATIVE);
|
|
62
|
+
const projectRoot = join(cwd, COMMANDS_RELATIVE);
|
|
63
|
+
const roots = [...(opts.builtinDirs ?? []), userRoot];
|
|
64
|
+
if (projectRoot !== userRoot)
|
|
65
|
+
roots.push(projectRoot);
|
|
49
66
|
const out = new Map();
|
|
67
|
+
for (const root of roots) {
|
|
68
|
+
readCommandsUnder(root, out);
|
|
69
|
+
}
|
|
70
|
+
return out;
|
|
71
|
+
}
|
|
72
|
+
/** Read one commands root into `out` (later writers override by name). */
|
|
73
|
+
function readCommandsUnder(root, out) {
|
|
74
|
+
if (!existsSync(root))
|
|
75
|
+
return;
|
|
50
76
|
let entries;
|
|
51
77
|
try {
|
|
52
78
|
entries = readdirSync(root);
|
|
53
79
|
}
|
|
54
80
|
catch {
|
|
55
|
-
return
|
|
81
|
+
return;
|
|
56
82
|
}
|
|
57
83
|
for (const entry of entries) {
|
|
58
84
|
if (!entry.endsWith(".md"))
|
|
@@ -92,7 +118,6 @@ export async function loadCommands(opts = {}) {
|
|
|
92
118
|
...(parsed.argumentHint !== undefined ? { argumentHint: parsed.argumentHint } : {}),
|
|
93
119
|
});
|
|
94
120
|
}
|
|
95
|
-
return out;
|
|
96
121
|
}
|
|
97
122
|
/**
|
|
98
123
|
* Split a slash-command markdown file into its optional frontmatter and
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@crewhaus/slash-commands",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Markdown-templated slash commands with $ARGUMENTS substitution",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
"test": "bun test src"
|
|
16
16
|
},
|
|
17
17
|
"dependencies": {
|
|
18
|
-
"@crewhaus/errors": "0.
|
|
18
|
+
"@crewhaus/errors": "0.3.1",
|
|
19
19
|
"yaml": "^2.6.0"
|
|
20
20
|
},
|
|
21
21
|
"license": "Apache-2.0",
|