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.
Files changed (47) hide show
  1. package/README.md +25 -21
  2. package/dest/cli.d.ts +68 -0
  3. package/dest/cli.js +147 -0
  4. package/dest/commands/skills/add.d.ts +2 -2
  5. package/dest/commands/skills/add.js +23 -7
  6. package/dest/commands/skills/index.d.ts +3 -3
  7. package/dest/commands/skills/index.js +10 -11
  8. package/dest/commands/skills/list.d.ts +2 -2
  9. package/dest/commands/skills/list.js +4 -3
  10. package/dest/commands/skills/rehash-all.d.ts +2 -2
  11. package/dest/commands/skills/rehash-all.js +6 -5
  12. package/dest/commands/skills/rehash.d.ts +2 -2
  13. package/dest/commands/skills/rehash.js +3 -2
  14. package/dest/commands/skills/remove.d.ts +2 -2
  15. package/dest/commands/skills/remove.js +3 -2
  16. package/dest/commands/skills/update-all.d.ts +2 -2
  17. package/dest/commands/skills/update-all.js +8 -7
  18. package/dest/commands/skills/update.d.ts +2 -2
  19. package/dest/commands/skills/update.js +6 -5
  20. package/dest/commands/sync.d.ts +6 -0
  21. package/dest/commands/sync.js +8 -0
  22. package/dest/lib/agent-definition-helpers.d.ts +74 -0
  23. package/dest/lib/agent-definition-helpers.js +68 -0
  24. package/dest/lib/agent-definitions.d.ts +333 -0
  25. package/dest/lib/agent-definitions.js +301 -0
  26. package/dest/lib/agent-types.d.ts +46 -0
  27. package/dest/lib/agent-types.js +1 -0
  28. package/dest/lib/agents.d.ts +81 -0
  29. package/dest/lib/agents.js +301 -0
  30. package/dest/lib/command-options.d.ts +1 -1
  31. package/dest/lib/command-options.js +1 -1
  32. package/dest/lib/context.d.ts +8 -25
  33. package/dest/lib/context.js +8 -26
  34. package/dest/lib/frontmatter.d.ts +27 -70
  35. package/dest/lib/frontmatter.js +23 -42
  36. package/dest/lib/object-helpers.d.ts +5 -0
  37. package/dest/lib/object-helpers.js +6 -0
  38. package/dest/lib/skills.d.ts +17 -93
  39. package/dest/lib/skills.js +25 -7
  40. package/dest/lib/sync.d.ts +7 -0
  41. package/dest/lib/sync.js +503 -0
  42. package/dest/main.js +6 -86
  43. package/package.json +3 -3
  44. package/dest/commands/install.d.ts +0 -3
  45. package/dest/commands/install.js +0 -4
  46. package/dest/lib/install.d.ts +0 -8
  47. package/dest/lib/install.js +0 -380
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Share AI config CLI
2
2
 
3
- Installs command, rule, and skill sources from `~/.config/dryai` by default into Copilot and Cursor targets.
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
- Live output is written to:
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
- ### `install`
46
+ ### `sync`
47
47
 
48
- - Purpose: Install commands, rules, and skills from the selected config root into the Copilot and Cursor target directories.
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 `~/.copilot/prompts`, `~/.copilot/instructions`, `~/.copilot/skills`, `~/.cursor/rules`, and `~/.cursor/skills` by default.
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
- copilot:
157
- applyTo: '**/*.tsx, **/*.ts, src/**/*.ts, src/**/*.tsx, src/**/*.js, src/**/*.jsx'
158
- cursor:
159
- alwaysApply: false
160
- globs: '**/*.tsx, **/*.ts, src/**/*.ts, src/**/*.tsx, src/**/*.js, src/**/*.jsx'
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
- cursor:
181
- disable-model-invocation: true
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 Copilot and Cursor skills targets.
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 editor or agent.
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 Copilot does not automatically discover prompt files from `~/.copilot/prompts`.
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 so prompt files installed by `dryai` are picked up:
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 { AgentsContext } from '../../lib/context.js';
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(context: AgentsContext, input: {
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
- * Resolves the remote repository path for one managed skill import request.
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(context, input) {
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.cleanup();
122
+ await cleanupRemoteRepoCheckout(checkout);
107
123
  }
108
124
  for (const importedSkillSummary of importedSkillSummaries) {
109
- console.log(`Imported ${importedSkillSummary}`);
125
+ runtime.logInfo(`Imported ${importedSkillSummary}`);
110
126
  }
111
127
  if (skippedSkillNames.length > 0) {
112
- console.warn(`Skipped already-imported skills: ${skippedSkillNames.join(', ')}`);
128
+ runtime.logWarn(`Skipped already-imported skills: ${skippedSkillNames.join(', ')}`);
113
129
  }
114
130
  if (importedSkillSummaries.length === 0) {
115
- console.log('No skills were imported.');
131
+ runtime.logInfo('No skills were imported.');
116
132
  }
117
133
  }
@@ -1,11 +1,11 @@
1
1
  import { Command } from 'commander';
2
- import { type AgentsContext } from '../../lib/context.js';
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
- parent: Command;
7
+ program: Command;
8
8
  commandName: string;
9
- resolveContext: () => AgentsContext;
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 { parent, commandName, resolveContext } = input;
28
- const skills = parent
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(resolveContext());
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(resolveContext(), {
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(resolveContext(), { skillName });
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(resolveContext(), { skillName });
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(resolveContext());
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(resolveContext(), {
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(resolveContext(), {
127
+ await runSkillsUpdateAllCommand(resolveEnv(), {
129
128
  force: parsedOptions.force,
130
129
  });
131
130
  });
@@ -1,6 +1,6 @@
1
- import type { AgentsContext } from '../../lib/context.js';
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(context: AgentsContext): Promise<void>;
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(context) {
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
- console.log('No local skills found.');
23
+ runtime.logInfo('No local skills found.');
23
24
  return;
24
25
  }
25
- console.log(outputLines.join('\n'));
26
+ runtime.logInfo(outputLines.join('\n'));
26
27
  }
@@ -1,6 +1,6 @@
1
- import type { AgentsContext } from '../../lib/context.js';
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(context: AgentsContext): Promise<void>;
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(context) {
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
- console.log('No managed skills to rehash.');
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
- console.log(`Rehashed ${rehashedLines.length} managed skills:\n${rehashedLines.join('\n')}`);
35
+ runtime.logInfo(`Rehashed ${rehashedLines.length} managed skills:\n${rehashedLines.join('\n')}`);
35
36
  }
36
37
  else {
37
- console.log('No managed skills were rehashed.');
38
+ runtime.logInfo('No managed skills were rehashed.');
38
39
  }
39
40
  if (skippedLines.length > 0) {
40
- console.warn(`Skipped ${skippedLines.length} managed skills because the local directory is missing:\n${skippedLines.join('\n')}`);
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 { AgentsContext } from '../../lib/context.js';
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(context: AgentsContext, input: {
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(context, input) {
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
- console.log(`Rehashed ${formatManagedSkillSummary(updatedSkill)}`);
28
+ runtime.logInfo(`Rehashed ${formatManagedSkillSummary(updatedSkill)}`);
28
29
  }
@@ -1,8 +1,8 @@
1
- import type { AgentsContext } from '../../lib/context.js';
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(context: AgentsContext, input: {
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(context, input) {
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
- console.log(`Removed ${formatManagedSkillSummary(managedSkill)}`);
17
+ runtime.logInfo(`Removed ${formatManagedSkillSummary(managedSkill)}`);
17
18
  }
@@ -1,8 +1,8 @@
1
- import type { AgentsContext } from '../../lib/context.js';
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(context: AgentsContext, input: {
5
+ export declare function runSkillsUpdateAllCommand(env: CommandEnv, input: {
6
6
  force: boolean;
7
7
  }): Promise<void>;
8
8
  //# sourceMappingURL=update-all.d.ts.map