dryai 2.2.0 → 3.0.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/README.md +25 -21
- package/dest/cli.d.ts +68 -0
- package/dest/cli.js +147 -0
- package/dest/commands/skills/add.d.ts +2 -2
- package/dest/commands/skills/add.js +23 -7
- package/dest/commands/skills/index.d.ts +3 -3
- package/dest/commands/skills/index.js +10 -11
- package/dest/commands/skills/list.d.ts +2 -2
- package/dest/commands/skills/list.js +4 -3
- package/dest/commands/skills/rehash-all.d.ts +2 -2
- package/dest/commands/skills/rehash-all.js +6 -5
- package/dest/commands/skills/rehash.d.ts +2 -2
- package/dest/commands/skills/rehash.js +3 -2
- package/dest/commands/skills/remove.d.ts +2 -2
- package/dest/commands/skills/remove.js +3 -2
- package/dest/commands/skills/update-all.d.ts +2 -2
- package/dest/commands/skills/update-all.js +8 -7
- package/dest/commands/skills/update.d.ts +2 -2
- package/dest/commands/skills/update.js +6 -5
- package/dest/commands/sync.d.ts +6 -0
- package/dest/commands/sync.js +8 -0
- package/dest/lib/agent-definition-helpers.d.ts +74 -0
- package/dest/lib/agent-definition-helpers.js +68 -0
- package/dest/lib/agent-definitions.d.ts +333 -0
- package/dest/lib/agent-definitions.js +301 -0
- package/dest/lib/agent-types.d.ts +46 -0
- package/dest/lib/agent-types.js +1 -0
- package/dest/lib/agents.d.ts +81 -0
- package/dest/lib/agents.js +301 -0
- package/dest/lib/command-options.d.ts +1 -1
- package/dest/lib/command-options.js +1 -1
- package/dest/lib/context.d.ts +8 -25
- package/dest/lib/context.js +8 -26
- package/dest/lib/frontmatter.d.ts +27 -70
- package/dest/lib/frontmatter.js +23 -42
- package/dest/lib/object-helpers.d.ts +5 -0
- package/dest/lib/object-helpers.js +6 -0
- package/dest/lib/skills.d.ts +17 -93
- package/dest/lib/skills.js +25 -7
- package/dest/lib/sync.d.ts +7 -0
- package/dest/lib/sync.js +503 -0
- package/dest/main.js +6 -86
- package/package.json +3 -3
- package/dest/commands/install.d.ts +0 -3
- package/dest/commands/install.js +0 -4
- package/dest/lib/install.d.ts +0 -8
- package/dest/lib/install.js +0 -380
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Share AI config CLI
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Syncs command, rule, and skill sources from `~/.config/dryai` by default into supported agent targets.
|
|
4
4
|
|
|
5
5
|
Global CLI options:
|
|
6
6
|
|
|
@@ -18,7 +18,7 @@ Input config files live under the selected config root:
|
|
|
18
18
|
- `rules`
|
|
19
19
|
- `skills`
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
The current built-in agent config writes live output to these default roots:
|
|
22
22
|
|
|
23
23
|
- `~/.copilot/prompts`
|
|
24
24
|
- `~/.copilot/instructions`
|
|
@@ -43,11 +43,13 @@ See VS Code editor setup note below.
|
|
|
43
43
|
|
|
44
44
|
## Commands
|
|
45
45
|
|
|
46
|
-
### `
|
|
46
|
+
### `sync`
|
|
47
47
|
|
|
48
|
-
- Purpose:
|
|
48
|
+
- Purpose: Sync commands, rules, and skills from the selected config root into the configured agent target directories.
|
|
49
49
|
- Input roots: Reads from `commands`, `rules`, and `skills` under the selected config root.
|
|
50
|
-
- Output roots: Writes to
|
|
50
|
+
- Output roots: Writes to the live output paths listed in Config Layout by default.
|
|
51
|
+
- Pruning: Removes stale dryai-managed outputs that were written by earlier sync runs but are no longer present in the selected config root.
|
|
52
|
+
- Safety: Only prunes outputs tracked in `sync-manifest.json`; unrelated user files in target roots are left alone.
|
|
51
53
|
|
|
52
54
|
### `skills add`
|
|
53
55
|
|
|
@@ -144,20 +146,21 @@ dryai skills update-all --force
|
|
|
144
146
|
Rules are markdown files under `rules/`. `dryai` recognizes these rule frontmatter fields:
|
|
145
147
|
|
|
146
148
|
- `description`
|
|
147
|
-
- `copilot.applyTo`
|
|
148
|
-
- `cursor.alwaysApply`
|
|
149
|
-
- `cursor.globs`
|
|
149
|
+
- `agents.copilot.applyTo`
|
|
150
|
+
- `agents.cursor.alwaysApply`
|
|
151
|
+
- `agents.cursor.globs`
|
|
150
152
|
|
|
151
|
-
`cursor.globs` should be provided as one comma-separated glob string.
|
|
153
|
+
`agents.cursor.globs` should be provided as one comma-separated glob string.
|
|
152
154
|
|
|
153
155
|
```md
|
|
154
156
|
---
|
|
155
157
|
description: Reply with "Yes, Captain!" before answering when the user says "Make it so" or "Engage".
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
158
|
+
agents:
|
|
159
|
+
copilot:
|
|
160
|
+
applyTo: '**/*.tsx, **/*.ts, src/**/*.ts, src/**/*.tsx, src/**/*.js, src/**/*.jsx'
|
|
161
|
+
cursor:
|
|
162
|
+
alwaysApply: false
|
|
163
|
+
globs: '**/*.tsx, **/*.ts, src/**/*.ts, src/**/*.tsx, src/**/*.js, src/**/*.jsx'
|
|
161
164
|
---
|
|
162
165
|
|
|
163
166
|
# Say Yes Captain
|
|
@@ -171,14 +174,15 @@ Commands are markdown files under `commands/`. `dryai` recognizes these command
|
|
|
171
174
|
|
|
172
175
|
- `name`
|
|
173
176
|
- `description`
|
|
174
|
-
- `cursor.disable-model-invocation`
|
|
177
|
+
- `agents.cursor.disable-model-invocation`
|
|
175
178
|
|
|
176
179
|
```md
|
|
177
180
|
---
|
|
178
181
|
name: gen-commit-msg
|
|
179
182
|
description: Generate a conventional commit message from the current staged git diff.
|
|
180
|
-
|
|
181
|
-
|
|
183
|
+
agents:
|
|
184
|
+
cursor:
|
|
185
|
+
disable-model-invocation: true
|
|
182
186
|
---
|
|
183
187
|
|
|
184
188
|
# Generate Commit Message
|
|
@@ -188,9 +192,9 @@ Read the staged diff and produce a conventional commit message with a concise su
|
|
|
188
192
|
|
|
189
193
|
### Example Skill
|
|
190
194
|
|
|
191
|
-
Skills live in directories under `skills/`. The directory is copied as-is into the
|
|
195
|
+
Skills live in directories under `skills/`. The directory is copied as-is into the configured agent skill targets.
|
|
192
196
|
|
|
193
|
-
Unlike commands and rules, `dryai` does not define or validate a fixed skill frontmatter schema. Skill files are passed through unchanged, so the allowed frontmatter fields depend on the skill format expected by the target
|
|
197
|
+
Unlike commands and rules, `dryai` does not define or validate a fixed skill frontmatter schema. Skill files are passed through unchanged, so the allowed frontmatter fields depend on the skill format expected by the target agent.
|
|
194
198
|
|
|
195
199
|
```text
|
|
196
200
|
skills/
|
|
@@ -232,9 +236,9 @@ pnpm dev:dryai <...>
|
|
|
232
236
|
|
|
233
237
|
## VS Code Setup
|
|
234
238
|
|
|
235
|
-
VS Code
|
|
239
|
+
One current editor-specific note: VS Code does not automatically discover prompt files from the Copilot prompt target at `~/.copilot/prompts`.
|
|
236
240
|
|
|
237
|
-
Add this to your VS Code user settings
|
|
241
|
+
Add this to your VS Code user settings if you want prompt files installed by `dryai` into that target to be picked up:
|
|
238
242
|
|
|
239
243
|
```json
|
|
240
244
|
{
|
package/dest/cli.d.ts
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { type AgentsContext } from './lib/context.js';
|
|
4
|
+
declare const rootOptionsSchema: z.ZodObject<{
|
|
5
|
+
test: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
6
|
+
configRoot: z.ZodOptional<z.ZodString>;
|
|
7
|
+
outputRoot: z.ZodOptional<z.ZodString>;
|
|
8
|
+
}, z.core.$strip>;
|
|
9
|
+
export type RootOptions = z.output<typeof rootOptionsSchema>;
|
|
10
|
+
/**
|
|
11
|
+
* Raw stdout/stderr write functions, without newline conventions. These are
|
|
12
|
+
* the CLI-layer primitive used by Commander for help and version output; they
|
|
13
|
+
* also back the higher-level {@link CLIRuntime}.
|
|
14
|
+
*/
|
|
15
|
+
export type StdioWriters = {
|
|
16
|
+
writeOut: (output: string) => void;
|
|
17
|
+
writeErr: (output: string) => void;
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* The line-oriented output interface available to every command action.
|
|
21
|
+
*
|
|
22
|
+
* Both methods append a trailing newline. The `log*` prefix is used to make
|
|
23
|
+
* call sites trivially greppable ("where do we emit CLI output?") without
|
|
24
|
+
* colliding with `console.log` / `console.warn` or arbitrary variables.
|
|
25
|
+
*
|
|
26
|
+
* Commands should not reach for the underlying {@link StdioWriters.writeOut}
|
|
27
|
+
* / {@link StdioWriters.writeErr} stream writes; that raw byte-level stream
|
|
28
|
+
* access is confined to the CLI layer (Commander help/version output).
|
|
29
|
+
*/
|
|
30
|
+
export type CLIRuntime = {
|
|
31
|
+
/** Writes an informational message to stdout, with an appended newline. */
|
|
32
|
+
logInfo: (message: string) => void;
|
|
33
|
+
/** Writes a warning message to stderr, with an appended newline. */
|
|
34
|
+
logWarn: (message: string) => void;
|
|
35
|
+
};
|
|
36
|
+
/**
|
|
37
|
+
* The shared environment passed into every command action: the
|
|
38
|
+
* resolved domain context plus the runtime used for CLI output.
|
|
39
|
+
*/
|
|
40
|
+
export type CommandEnv = {
|
|
41
|
+
context: AgentsContext;
|
|
42
|
+
runtime: CLIRuntime;
|
|
43
|
+
};
|
|
44
|
+
export type CLIOptions = {
|
|
45
|
+
executableName?: string;
|
|
46
|
+
version: string;
|
|
47
|
+
stdioWriters?: StdioWriters;
|
|
48
|
+
};
|
|
49
|
+
/**
|
|
50
|
+
* Builds an AgentsContext from the parsed root options, expanding ~ in paths and applying --test path defaults.
|
|
51
|
+
*/
|
|
52
|
+
export declare function resolveActiveContext(rootOptions: RootOptions): AgentsContext;
|
|
53
|
+
/**
|
|
54
|
+
* Creates the production stdio writers backed by the real process streams.
|
|
55
|
+
*/
|
|
56
|
+
export declare function createProductionStdioWriters(): StdioWriters;
|
|
57
|
+
/**
|
|
58
|
+
* Builds and returns the Commander program with all subcommands and global flags registered.
|
|
59
|
+
*/
|
|
60
|
+
export declare function createCLI(options: CLIOptions): Command;
|
|
61
|
+
/**
|
|
62
|
+
* Parses argv and runs the matching command, returning the Commander program after completion.
|
|
63
|
+
*/
|
|
64
|
+
export declare function runCLI(input: {
|
|
65
|
+
argv: string[];
|
|
66
|
+
} & CLIOptions): Promise<Command>;
|
|
67
|
+
export {};
|
|
68
|
+
//# sourceMappingURL=cli.d.ts.map
|
package/dest/cli.js
ADDED
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { addSkillsCommand } from './commands/skills/index.js';
|
|
4
|
+
import { runSyncCommand } from './commands/sync.js';
|
|
5
|
+
import { describeSupportedAgents } from './lib/agents.js';
|
|
6
|
+
import { nonEmptyOptionStringSchema, parseOptionValue, parseOptionsObject, } from './lib/command-options.js';
|
|
7
|
+
import { createAgentsContext, resolveRequestedConfigRoot, resolveRequestedOutputRoot, } from './lib/context.js';
|
|
8
|
+
const rootOptionsSchema = z.object({
|
|
9
|
+
test: z.boolean().optional().default(false),
|
|
10
|
+
configRoot: nonEmptyOptionStringSchema.optional(),
|
|
11
|
+
outputRoot: nonEmptyOptionStringSchema.optional(),
|
|
12
|
+
});
|
|
13
|
+
/**
|
|
14
|
+
* Parses the top-level CLI options into a validated shape.
|
|
15
|
+
*/
|
|
16
|
+
function getRootOptions(program) {
|
|
17
|
+
return parseOptionsObject({
|
|
18
|
+
schema: rootOptionsSchema,
|
|
19
|
+
options: program.opts(),
|
|
20
|
+
optionsLabel: 'root options',
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Returns true if --test or --output-root was passed.
|
|
25
|
+
*/
|
|
26
|
+
function requestedOutputRootWasUsed(rootOptions) {
|
|
27
|
+
return rootOptions.test || rootOptions.outputRoot !== undefined;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Builds an AgentsContext from the parsed root options, expanding ~ in paths and applying --test path defaults.
|
|
31
|
+
*/
|
|
32
|
+
export function resolveActiveContext(rootOptions) {
|
|
33
|
+
const requestedConfigRoot = resolveRequestedConfigRoot({
|
|
34
|
+
...(rootOptions.configRoot ? { configRoot: rootOptions.configRoot } : {}),
|
|
35
|
+
});
|
|
36
|
+
const requestedOutputRoot = resolveRequestedOutputRoot({
|
|
37
|
+
test: rootOptions.test,
|
|
38
|
+
...(rootOptions.outputRoot ? { outputRoot: rootOptions.outputRoot } : {}),
|
|
39
|
+
});
|
|
40
|
+
return createAgentsContext({
|
|
41
|
+
...(requestedConfigRoot ? { inputRoot: requestedConfigRoot } : {}),
|
|
42
|
+
...(requestedOutputRoot ? { outputRoot: requestedOutputRoot } : {}),
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Derives a {@link CLIRuntime} from a pair of raw stdio writers by wrapping
|
|
47
|
+
* each writer with the line-oriented newline convention.
|
|
48
|
+
*/
|
|
49
|
+
function wrapStdioWriters(stdioWriters) {
|
|
50
|
+
return {
|
|
51
|
+
logInfo(message) {
|
|
52
|
+
stdioWriters.writeOut(`${message}\n`);
|
|
53
|
+
},
|
|
54
|
+
logWarn(message) {
|
|
55
|
+
stdioWriters.writeErr(`${message}\n`);
|
|
56
|
+
},
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Creates the production stdio writers backed by the real process streams.
|
|
61
|
+
*/
|
|
62
|
+
export function createProductionStdioWriters() {
|
|
63
|
+
return {
|
|
64
|
+
writeOut(output) {
|
|
65
|
+
process.stdout.write(output);
|
|
66
|
+
},
|
|
67
|
+
writeErr(output) {
|
|
68
|
+
process.stderr.write(output);
|
|
69
|
+
},
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Merges the provided CLIOptions with production defaults, returning a fully resolved options object.
|
|
74
|
+
*/
|
|
75
|
+
function resolveCLIOptions(options) {
|
|
76
|
+
return {
|
|
77
|
+
executableName: options.executableName ?? 'dryai',
|
|
78
|
+
version: options.version,
|
|
79
|
+
stdioWriters: options.stdioWriters ?? createProductionStdioWriters(),
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Builds and returns the Commander program with all subcommands and global flags registered.
|
|
84
|
+
*/
|
|
85
|
+
export function createCLI(options) {
|
|
86
|
+
const resolvedOptions = resolveCLIOptions(options);
|
|
87
|
+
const program = new Command();
|
|
88
|
+
const executableName = resolvedOptions.executableName;
|
|
89
|
+
const stdioWriters = resolvedOptions.stdioWriters;
|
|
90
|
+
const runtime = wrapStdioWriters(stdioWriters);
|
|
91
|
+
const resolveEnv = () => ({
|
|
92
|
+
context: resolveActiveContext(getRootOptions(program)),
|
|
93
|
+
runtime,
|
|
94
|
+
});
|
|
95
|
+
program.configureOutput({
|
|
96
|
+
writeOut: (output) => {
|
|
97
|
+
stdioWriters.writeOut(output);
|
|
98
|
+
},
|
|
99
|
+
writeErr: (output) => {
|
|
100
|
+
stdioWriters.writeErr(output);
|
|
101
|
+
},
|
|
102
|
+
});
|
|
103
|
+
program
|
|
104
|
+
.name(executableName)
|
|
105
|
+
.usage('[options] <command> [args]')
|
|
106
|
+
.helpOption('-h, --help', 'Display this message')
|
|
107
|
+
.version(resolvedOptions.version, '-v, --version', 'Display the current version')
|
|
108
|
+
.option('--test', 'Shortcut for writing generated output into ./output-test unless --output-root is also provided')
|
|
109
|
+
.option('--config-root <path>', 'Read configs from a different root instead of ~/.config/dryai', parseOptionValue({
|
|
110
|
+
schema: nonEmptyOptionStringSchema,
|
|
111
|
+
optionLabel: '--config-root',
|
|
112
|
+
}))
|
|
113
|
+
.option('--output-root <path>', 'Write generated output under a different root instead of the default home directory', parseOptionValue({
|
|
114
|
+
schema: nonEmptyOptionStringSchema,
|
|
115
|
+
optionLabel: '--output-root',
|
|
116
|
+
}))
|
|
117
|
+
.helpCommand(false)
|
|
118
|
+
.action(() => {
|
|
119
|
+
program.outputHelp();
|
|
120
|
+
});
|
|
121
|
+
program
|
|
122
|
+
.command('sync')
|
|
123
|
+
.description(`Sync generated output into ${describeSupportedAgents()} targets`)
|
|
124
|
+
.action(async () => {
|
|
125
|
+
const rootOptions = getRootOptions(program);
|
|
126
|
+
const env = resolveEnv();
|
|
127
|
+
await runSyncCommand(env);
|
|
128
|
+
if (requestedOutputRootWasUsed(rootOptions)) {
|
|
129
|
+
runtime.logInfo(`Generated output written to ${env.context.outputRoot}`);
|
|
130
|
+
}
|
|
131
|
+
});
|
|
132
|
+
addSkillsCommand({
|
|
133
|
+
program,
|
|
134
|
+
commandName: `${executableName} skills`,
|
|
135
|
+
resolveEnv,
|
|
136
|
+
});
|
|
137
|
+
return program;
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Parses argv and runs the matching command, returning the Commander program after completion.
|
|
141
|
+
*/
|
|
142
|
+
export async function runCLI(input) {
|
|
143
|
+
const { argv, ...options } = input;
|
|
144
|
+
const program = createCLI(options);
|
|
145
|
+
await program.parseAsync(argv, { from: 'user' });
|
|
146
|
+
return program;
|
|
147
|
+
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { CommandEnv } from '../../cli.js';
|
|
2
2
|
/**
|
|
3
3
|
* Imports one or more managed skills from a remote repository into the local skills directory.
|
|
4
4
|
*/
|
|
5
|
-
export declare function runSkillsAddCommand(
|
|
5
|
+
export declare function runSkillsAddCommand(env: CommandEnv, input: {
|
|
6
6
|
repo: string;
|
|
7
7
|
repoPath: string | undefined;
|
|
8
8
|
skillNames: string[];
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import fs from 'fs-extra';
|
|
2
|
-
import { cloneRemoteRepo, computeDirectoryHashes, createImportedSkillRecord, deriveSkillName, ensureSkillsLockfile, ensureSkillsRoot, findManagedSkill, formatManagedSkillSummary, getManagedSkillDirectory, loadSkillsLockfile, normalizeImportedSkillPath, normalizeRemoteRepo, replaceManagedSkillDirectory, resolveManagedSkillImportPath, resolveManagedSkillImportPathFromBase, resolveSkillSourceDirByPath, saveSkillsLockfile, timestampNow, upsertManagedSkill, } from '../../lib/skills.js';
|
|
2
|
+
import { cleanupRemoteRepoCheckout, cloneRemoteRepo, computeDirectoryHashes, createImportedSkillRecord, deriveSkillName, ensureSkillsLockfile, ensureSkillsRoot, findManagedSkill, formatManagedSkillSummary, getManagedSkillDirectory, loadSkillsLockfile, normalizeImportedSkillPath, normalizeRemoteRepo, replaceManagedSkillDirectory, resolveManagedSkillImportPath, resolveManagedSkillImportPathFromBase, resolveSkillSourceDirByPath, saveSkillsLockfile, timestampNow, upsertManagedSkill, } from '../../lib/skills.js';
|
|
3
3
|
/**
|
|
4
4
|
* Normalizes and de-duplicates requested skill names while preserving their input order.
|
|
5
5
|
*/
|
|
@@ -20,7 +20,22 @@ function normalizeRequestedSkillNames(skillNames) {
|
|
|
20
20
|
return uniqueSkillNames;
|
|
21
21
|
}
|
|
22
22
|
/**
|
|
23
|
-
*
|
|
23
|
+
* Returns the resolved repository-relative import path for a single requested skill.
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* // No base path — defaults to the repository `skills/` directory
|
|
27
|
+
* resolveRequestedImportPath({ basePath: undefined, requestedSkillName: 'my-skill' });
|
|
28
|
+
* // → 'skills/my-skill'
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* // With a base path — skill is resolved relative to that directory
|
|
32
|
+
* resolveRequestedImportPath({ basePath: 'tools', requestedSkillName: 'my-skill' });
|
|
33
|
+
* // → 'tools/my-skill'
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* // Base path of '.' — skill is resolved from the repository root
|
|
37
|
+
* resolveRequestedImportPath({ basePath: '.', requestedSkillName: 'my-skill' });
|
|
38
|
+
* // → 'my-skill'
|
|
24
39
|
*/
|
|
25
40
|
function resolveRequestedImportPath(input) {
|
|
26
41
|
const importPath = resolveManagedSkillImportPathFromBase({
|
|
@@ -32,7 +47,8 @@ function resolveRequestedImportPath(input) {
|
|
|
32
47
|
/**
|
|
33
48
|
* Imports one or more managed skills from a remote repository into the local skills directory.
|
|
34
49
|
*/
|
|
35
|
-
export async function runSkillsAddCommand(
|
|
50
|
+
export async function runSkillsAddCommand(env, input) {
|
|
51
|
+
const { context, runtime } = env;
|
|
36
52
|
const repo = normalizeRemoteRepo(input.repo);
|
|
37
53
|
const normalizedBasePath = normalizeImportedSkillPath(input.repoPath);
|
|
38
54
|
if (input.skillNames.length === 0) {
|
|
@@ -103,15 +119,15 @@ export async function runSkillsAddCommand(context, input) {
|
|
|
103
119
|
}
|
|
104
120
|
}
|
|
105
121
|
finally {
|
|
106
|
-
await checkout
|
|
122
|
+
await cleanupRemoteRepoCheckout(checkout);
|
|
107
123
|
}
|
|
108
124
|
for (const importedSkillSummary of importedSkillSummaries) {
|
|
109
|
-
|
|
125
|
+
runtime.logInfo(`Imported ${importedSkillSummary}`);
|
|
110
126
|
}
|
|
111
127
|
if (skippedSkillNames.length > 0) {
|
|
112
|
-
|
|
128
|
+
runtime.logWarn(`Skipped already-imported skills: ${skippedSkillNames.join(', ')}`);
|
|
113
129
|
}
|
|
114
130
|
if (importedSkillSummaries.length === 0) {
|
|
115
|
-
|
|
131
|
+
runtime.logInfo('No skills were imported.');
|
|
116
132
|
}
|
|
117
133
|
}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { Command } from 'commander';
|
|
2
|
-
import {
|
|
2
|
+
import type { CommandEnv } from '../../cli.js';
|
|
3
3
|
/**
|
|
4
4
|
* Registers the managed skills command tree on the parent CLI program.
|
|
5
5
|
*/
|
|
6
6
|
export declare function addSkillsCommand(input: {
|
|
7
|
-
|
|
7
|
+
program: Command;
|
|
8
8
|
commandName: string;
|
|
9
|
-
|
|
9
|
+
resolveEnv: () => CommandEnv;
|
|
10
10
|
}): Command;
|
|
11
11
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import { Command } from 'commander';
|
|
2
2
|
import dedent from 'dedent';
|
|
3
3
|
import { z } from 'zod';
|
|
4
|
-
import { nonEmptyOptionStringSchema, parseOptionsObject, parseOptionValue, } from '../../lib/command-options.js';
|
|
5
|
-
import {} from '../../lib/context.js';
|
|
6
4
|
import { runSkillsAddCommand } from './add.js';
|
|
7
5
|
import { runSkillsListCommand } from './list.js';
|
|
8
6
|
import { runSkillsRehashAllCommand } from './rehash-all.js';
|
|
@@ -10,6 +8,7 @@ import { runSkillsRehashCommand } from './rehash.js';
|
|
|
10
8
|
import { runSkillsRemoveCommand } from './remove.js';
|
|
11
9
|
import { runSkillsUpdateAllCommand } from './update-all.js';
|
|
12
10
|
import { runSkillsUpdateCommand } from './update.js';
|
|
11
|
+
import { nonEmptyOptionStringSchema, parseOptionsObject, parseOptionValue, } from '../../lib/command-options.js';
|
|
13
12
|
const skillsImportOptionsSchema = z.object({
|
|
14
13
|
skill: z.array(z.string()).optional(),
|
|
15
14
|
as: nonEmptyOptionStringSchema.optional(),
|
|
@@ -24,8 +23,8 @@ const skillsUpdateOptionsSchema = z.object({
|
|
|
24
23
|
* Registers the managed skills command tree on the parent CLI program.
|
|
25
24
|
*/
|
|
26
25
|
export function addSkillsCommand(input) {
|
|
27
|
-
const {
|
|
28
|
-
const skills =
|
|
26
|
+
const { program, commandName, resolveEnv } = input;
|
|
27
|
+
const skills = program
|
|
29
28
|
.command('skills')
|
|
30
29
|
.description('Manage imported skills')
|
|
31
30
|
.usage('<subcommand> [args]')
|
|
@@ -48,7 +47,7 @@ export function addSkillsCommand(input) {
|
|
|
48
47
|
.command('list')
|
|
49
48
|
.description('List local skills')
|
|
50
49
|
.action(async () => {
|
|
51
|
-
await runSkillsListCommand(
|
|
50
|
+
await runSkillsListCommand(resolveEnv());
|
|
52
51
|
});
|
|
53
52
|
skills
|
|
54
53
|
.command('add <repo>')
|
|
@@ -73,7 +72,7 @@ export function addSkillsCommand(input) {
|
|
|
73
72
|
options,
|
|
74
73
|
optionsLabel: 'skills add options',
|
|
75
74
|
});
|
|
76
|
-
await runSkillsAddCommand(
|
|
75
|
+
await runSkillsAddCommand(resolveEnv(), {
|
|
77
76
|
repo,
|
|
78
77
|
repoPath: parsedOptions.path,
|
|
79
78
|
skillNames: parsedOptions.skill ?? [],
|
|
@@ -86,19 +85,19 @@ export function addSkillsCommand(input) {
|
|
|
86
85
|
.command('remove <name>')
|
|
87
86
|
.description('Remove a managed skill')
|
|
88
87
|
.action(async (skillName) => {
|
|
89
|
-
await runSkillsRemoveCommand(
|
|
88
|
+
await runSkillsRemoveCommand(resolveEnv(), { skillName });
|
|
90
89
|
});
|
|
91
90
|
skills
|
|
92
91
|
.command('rehash <name>')
|
|
93
92
|
.description('Refresh stored file hashes for one managed skill')
|
|
94
93
|
.action(async (skillName) => {
|
|
95
|
-
await runSkillsRehashCommand(
|
|
94
|
+
await runSkillsRehashCommand(resolveEnv(), { skillName });
|
|
96
95
|
});
|
|
97
96
|
skills
|
|
98
97
|
.command('rehash-all')
|
|
99
98
|
.description('Refresh stored file hashes for all managed skills')
|
|
100
99
|
.action(async () => {
|
|
101
|
-
await runSkillsRehashAllCommand(
|
|
100
|
+
await runSkillsRehashAllCommand(resolveEnv());
|
|
102
101
|
});
|
|
103
102
|
skills
|
|
104
103
|
.command('update <name>')
|
|
@@ -110,7 +109,7 @@ export function addSkillsCommand(input) {
|
|
|
110
109
|
options,
|
|
111
110
|
optionsLabel: 'skills update options',
|
|
112
111
|
});
|
|
113
|
-
await runSkillsUpdateCommand(
|
|
112
|
+
await runSkillsUpdateCommand(resolveEnv(), {
|
|
114
113
|
force: parsedOptions.force,
|
|
115
114
|
skillName,
|
|
116
115
|
});
|
|
@@ -125,7 +124,7 @@ export function addSkillsCommand(input) {
|
|
|
125
124
|
options,
|
|
126
125
|
optionsLabel: 'skills update-all options',
|
|
127
126
|
});
|
|
128
|
-
await runSkillsUpdateAllCommand(
|
|
127
|
+
await runSkillsUpdateAllCommand(resolveEnv(), {
|
|
129
128
|
force: parsedOptions.force,
|
|
130
129
|
});
|
|
131
130
|
});
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { CommandEnv } from '../../cli.js';
|
|
2
2
|
/**
|
|
3
3
|
* Lists local skills and annotates which ones are managed by the lockfile.
|
|
4
4
|
*/
|
|
5
|
-
export declare function runSkillsListCommand(
|
|
5
|
+
export declare function runSkillsListCommand(env: CommandEnv): Promise<void>;
|
|
6
6
|
//# sourceMappingURL=list.d.ts.map
|
|
@@ -2,7 +2,8 @@ import { ensureSkillsRoot, findManagedSkill, formatManagedSkillSummary, listLoca
|
|
|
2
2
|
/**
|
|
3
3
|
* Lists local skills and annotates which ones are managed by the lockfile.
|
|
4
4
|
*/
|
|
5
|
-
export async function runSkillsListCommand(
|
|
5
|
+
export async function runSkillsListCommand(env) {
|
|
6
|
+
const { context, runtime } = env;
|
|
6
7
|
await ensureSkillsRoot(context);
|
|
7
8
|
const [localSkillDirectories, lockfile] = await Promise.all([
|
|
8
9
|
listLocalSkillDirectories(context),
|
|
@@ -19,8 +20,8 @@ export async function runSkillsListCommand(context) {
|
|
|
19
20
|
.map((managedSkill) => `- ${formatManagedSkillSummary(managedSkill)} missing-local-directory`);
|
|
20
21
|
const outputLines = [...localSkillLines, ...missingManagedLines];
|
|
21
22
|
if (outputLines.length === 0) {
|
|
22
|
-
|
|
23
|
+
runtime.logInfo('No local skills found.');
|
|
23
24
|
return;
|
|
24
25
|
}
|
|
25
|
-
|
|
26
|
+
runtime.logInfo(outputLines.join('\n'));
|
|
26
27
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { CommandEnv } from '../../cli.js';
|
|
2
2
|
/**
|
|
3
3
|
* Refreshes the stored file hashes for every managed skill using current local directory contents.
|
|
4
4
|
*/
|
|
5
|
-
export declare function runSkillsRehashAllCommand(
|
|
5
|
+
export declare function runSkillsRehashAllCommand(env: CommandEnv): Promise<void>;
|
|
6
6
|
//# sourceMappingURL=rehash-all.d.ts.map
|
|
@@ -3,10 +3,11 @@ import { computeDirectoryHashes, createUpdatedSkillRecord, formatManagedSkillSum
|
|
|
3
3
|
/**
|
|
4
4
|
* Refreshes the stored file hashes for every managed skill using current local directory contents.
|
|
5
5
|
*/
|
|
6
|
-
export async function runSkillsRehashAllCommand(
|
|
6
|
+
export async function runSkillsRehashAllCommand(env) {
|
|
7
|
+
const { context, runtime } = env;
|
|
7
8
|
let lockfile = await loadSkillsLockfile(context);
|
|
8
9
|
if (lockfile.skills.length === 0) {
|
|
9
|
-
|
|
10
|
+
runtime.logInfo('No managed skills to rehash.');
|
|
10
11
|
return;
|
|
11
12
|
}
|
|
12
13
|
const rehashedLines = [];
|
|
@@ -31,12 +32,12 @@ export async function runSkillsRehashAllCommand(context) {
|
|
|
31
32
|
}
|
|
32
33
|
await saveSkillsLockfile(context, { lockfile });
|
|
33
34
|
if (rehashedLines.length > 0) {
|
|
34
|
-
|
|
35
|
+
runtime.logInfo(`Rehashed ${rehashedLines.length} managed skills:\n${rehashedLines.join('\n')}`);
|
|
35
36
|
}
|
|
36
37
|
else {
|
|
37
|
-
|
|
38
|
+
runtime.logInfo('No managed skills were rehashed.');
|
|
38
39
|
}
|
|
39
40
|
if (skippedLines.length > 0) {
|
|
40
|
-
|
|
41
|
+
runtime.logWarn(`Skipped ${skippedLines.length} managed skills because the local directory is missing:\n${skippedLines.join('\n')}`);
|
|
41
42
|
}
|
|
42
43
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { CommandEnv } from '../../cli.js';
|
|
2
2
|
/**
|
|
3
3
|
* Refreshes the stored file hashes for one managed skill using the current local directory contents.
|
|
4
4
|
*/
|
|
5
|
-
export declare function runSkillsRehashCommand(
|
|
5
|
+
export declare function runSkillsRehashCommand(env: CommandEnv, input: {
|
|
6
6
|
skillName: string;
|
|
7
7
|
}): Promise<void>;
|
|
8
8
|
//# sourceMappingURL=rehash.d.ts.map
|
|
@@ -3,7 +3,8 @@ import { computeDirectoryHashes, createUpdatedSkillRecord, findManagedSkill, for
|
|
|
3
3
|
/**
|
|
4
4
|
* Refreshes the stored file hashes for one managed skill using the current local directory contents.
|
|
5
5
|
*/
|
|
6
|
-
export async function runSkillsRehashCommand(
|
|
6
|
+
export async function runSkillsRehashCommand(env, input) {
|
|
7
|
+
const { context, runtime } = env;
|
|
7
8
|
const { skillName } = input;
|
|
8
9
|
const lockfile = await loadSkillsLockfile(context);
|
|
9
10
|
const managedSkill = findManagedSkill(lockfile, { name: skillName });
|
|
@@ -24,5 +25,5 @@ export async function runSkillsRehashCommand(context, input) {
|
|
|
24
25
|
await saveSkillsLockfile(context, {
|
|
25
26
|
lockfile: upsertManagedSkill(lockfile, { updatedSkill }),
|
|
26
27
|
});
|
|
27
|
-
|
|
28
|
+
runtime.logInfo(`Rehashed ${formatManagedSkillSummary(updatedSkill)}`);
|
|
28
29
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { CommandEnv } from '../../cli.js';
|
|
2
2
|
/**
|
|
3
3
|
* Removes a managed skill from the local directory and updates the lockfile.
|
|
4
4
|
*/
|
|
5
|
-
export declare function runSkillsRemoveCommand(
|
|
5
|
+
export declare function runSkillsRemoveCommand(env: CommandEnv, input: {
|
|
6
6
|
skillName: string;
|
|
7
7
|
}): Promise<void>;
|
|
8
8
|
//# sourceMappingURL=remove.d.ts.map
|
|
@@ -2,7 +2,8 @@ import { findManagedSkill, formatManagedSkillSummary, loadSkillsLockfile, remove
|
|
|
2
2
|
/**
|
|
3
3
|
* Removes a managed skill from the local directory and updates the lockfile.
|
|
4
4
|
*/
|
|
5
|
-
export async function runSkillsRemoveCommand(
|
|
5
|
+
export async function runSkillsRemoveCommand(env, input) {
|
|
6
|
+
const { context, runtime } = env;
|
|
6
7
|
const { skillName } = input;
|
|
7
8
|
const lockfile = await loadSkillsLockfile(context);
|
|
8
9
|
const managedSkill = findManagedSkill(lockfile, { name: skillName });
|
|
@@ -13,5 +14,5 @@ export async function runSkillsRemoveCommand(context, input) {
|
|
|
13
14
|
await saveSkillsLockfile(context, {
|
|
14
15
|
lockfile: removeManagedSkill(lockfile, { name: skillName }),
|
|
15
16
|
});
|
|
16
|
-
|
|
17
|
+
runtime.logInfo(`Removed ${formatManagedSkillSummary(managedSkill)}`);
|
|
17
18
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { CommandEnv } from '../../cli.js';
|
|
2
2
|
/**
|
|
3
3
|
* Updates every managed skill from its tracked remote source and saves the refreshed lockfile.
|
|
4
4
|
*/
|
|
5
|
-
export declare function runSkillsUpdateAllCommand(
|
|
5
|
+
export declare function runSkillsUpdateAllCommand(env: CommandEnv, input: {
|
|
6
6
|
force: boolean;
|
|
7
7
|
}): Promise<void>;
|
|
8
8
|
//# sourceMappingURL=update-all.d.ts.map
|