dryai 2.1.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 +140 -122
  2. package/dest/cli.d.ts +68 -0
  3. package/dest/cli.js +147 -0
  4. package/dest/commands/skills/add.d.ts +4 -3
  5. package/dest/commands/skills/add.js +44 -12
  6. package/dest/commands/skills/index.d.ts +3 -3
  7. package/dest/commands/skills/index.js +19 -12
  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 +35 -93
  39. package/dest/lib/skills.js +66 -8
  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
@@ -1,72 +1,37 @@
1
1
  import { z } from 'zod';
2
+ import type { CLIRuntime } from '../cli.js';
3
+ export { compactObject } from './object-helpers.js';
2
4
  export declare const nonEmptyStringSchema: z.ZodString;
5
+ export declare const agentFrontmatterSectionSchema: z.ZodObject<{}, z.core.$catchall<z.ZodUnknown>>;
6
+ export declare const agentFrontmatterSectionsSchema: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{}, z.core.$catchall<z.ZodUnknown>>>>;
7
+ /**
8
+ * Builds the Zod schema for the `agents:` frontmatter section by combining each agent's per-kind source schema from the registry.
9
+ */
10
+ export declare function createAgentFrontmatterSectionsSchema(kind: 'command' | 'rule'): z.ZodOptional<z.ZodObject<{
11
+ [x: string]: z.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>;
12
+ }, z.core.$catchall<z.ZodObject<{}, z.core.$catchall<z.ZodUnknown>>>>>;
13
+ export declare const commandAgentFrontmatterSectionsSchema: z.ZodOptional<z.ZodObject<{
14
+ [x: string]: z.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>;
15
+ }, z.core.$catchall<z.ZodObject<{}, z.core.$catchall<z.ZodUnknown>>>>>;
16
+ export declare const ruleAgentFrontmatterSectionsSchema: z.ZodOptional<z.ZodObject<{
17
+ [x: string]: z.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>;
18
+ }, z.core.$catchall<z.ZodObject<{}, z.core.$catchall<z.ZodUnknown>>>>>;
3
19
  export declare const commandFrontmatterSchema: z.ZodObject<{
4
20
  name: z.ZodString;
5
21
  description: z.ZodString;
6
- cursor: z.ZodOptional<z.ZodObject<{
7
- 'disable-model-invocation': z.ZodOptional<z.ZodBoolean>;
8
- }, "strict", z.ZodTypeAny, {
9
- 'disable-model-invocation'?: boolean | undefined;
10
- }, {
11
- 'disable-model-invocation'?: boolean | undefined;
12
- }>>;
13
- }, "strict", z.ZodTypeAny, {
14
- name: string;
15
- description: string;
16
- cursor?: {
17
- 'disable-model-invocation'?: boolean | undefined;
18
- } | undefined;
19
- }, {
20
- name: string;
21
- description: string;
22
- cursor?: {
23
- 'disable-model-invocation'?: boolean | undefined;
24
- } | undefined;
25
- }>;
22
+ agents: z.ZodOptional<z.ZodObject<{
23
+ [x: string]: z.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>;
24
+ }, z.core.$catchall<z.ZodObject<{}, z.core.$catchall<z.ZodUnknown>>>>>;
25
+ }, z.core.$strict>;
26
26
  export declare const ruleFrontmatterSchema: z.ZodObject<{
27
27
  description: z.ZodString;
28
- copilot: z.ZodObject<{
29
- applyTo: z.ZodString;
30
- }, "strict", z.ZodTypeAny, {
31
- applyTo: string;
32
- }, {
33
- applyTo: string;
34
- }>;
35
- cursor: z.ZodOptional<z.ZodObject<{
36
- alwaysApply: z.ZodOptional<z.ZodBoolean>;
37
- globs: z.ZodOptional<z.ZodString>;
38
- }, "strict", z.ZodTypeAny, {
39
- alwaysApply?: boolean | undefined;
40
- globs?: string | undefined;
41
- }, {
42
- alwaysApply?: boolean | undefined;
43
- globs?: string | undefined;
44
- }>>;
45
- }, "strict", z.ZodTypeAny, {
46
- description: string;
47
- copilot: {
48
- applyTo: string;
49
- };
50
- cursor?: {
51
- alwaysApply?: boolean | undefined;
52
- globs?: string | undefined;
53
- } | undefined;
54
- }, {
55
- description: string;
56
- copilot: {
57
- applyTo: string;
58
- };
59
- cursor?: {
60
- alwaysApply?: boolean | undefined;
61
- globs?: string | undefined;
62
- } | undefined;
63
- }>;
28
+ agents: z.ZodOptional<z.ZodObject<{
29
+ [x: string]: z.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>;
30
+ }, z.core.$catchall<z.ZodObject<{}, z.core.$catchall<z.ZodUnknown>>>>>;
31
+ }, z.core.$strict>;
32
+ export type AgentFrontmatterSections = z.infer<typeof agentFrontmatterSectionsSchema>;
64
33
  export type CommandFrontmatter = z.infer<typeof commandFrontmatterSchema>;
65
34
  export type RuleFrontmatter = z.infer<typeof ruleFrontmatterSchema>;
66
- /**
67
- * Returns a copy of an object with all undefined-valued entries removed.
68
- */
69
- export declare function compactObject(value: Record<string, unknown>): Record<string, unknown>;
70
35
  /**
71
36
  * Returns whether a value is a non-null plain object and not an array.
72
37
  */
@@ -81,21 +46,13 @@ export declare function parseFrontmatter(fileContent: string): {
81
46
  /**
82
47
  * Validates parsed frontmatter against a schema and logs a skip message when validation fails.
83
48
  */
84
- export declare function validateFrontmatter<T>({ filePath, metadata, schema, }: {
49
+ export declare function validateFrontmatter<T>(runtime: CLIRuntime, { filePath, metadata, schema, }: {
85
50
  filePath: string;
86
51
  metadata: Record<string, unknown>;
87
52
  schema: z.ZodType<T>;
88
53
  }): T | null;
89
54
  /**
90
- * Normalizes rule frontmatter into the apply settings used by downstream generators.
91
- */
92
- export declare function normalizeRuleMetadata(metadata: RuleFrontmatter): {
93
- alwaysApply: boolean;
94
- globs: string | undefined;
95
- applyTo: string;
96
- };
97
- /**
98
- * Renders metadata and markdown body content back into a frontmatter document string.
55
+ * Serializes metadata as YAML frontmatter and combines it with the markdown body into a single document string.
99
56
  */
100
57
  export declare function renderMarkdown({ metadata, body, }: {
101
58
  metadata: Record<string, unknown>;
@@ -1,41 +1,37 @@
1
1
  import matter from 'gray-matter';
2
2
  import { z } from 'zod';
3
+ import { AGENT_DEFINITIONS } from './agent-definitions.js';
4
+ export { compactObject } from './object-helpers.js';
3
5
  export const nonEmptyStringSchema = z.string().trim().min(1);
6
+ export const agentFrontmatterSectionSchema = z.object({}).catchall(z.unknown());
7
+ export const agentFrontmatterSectionsSchema = z
8
+ .record(z.string(), agentFrontmatterSectionSchema)
9
+ .optional();
10
+ /**
11
+ * Builds the Zod schema for the `agents:` frontmatter section by combining each agent's per-kind source schema from the registry.
12
+ */
13
+ export function createAgentFrontmatterSectionsSchema(kind) {
14
+ const shape = {};
15
+ for (const [agent, definition] of Object.entries(AGENT_DEFINITIONS)) {
16
+ shape[agent] = definition[kind].frontmatterSection.schema;
17
+ }
18
+ return z.object(shape).catchall(agentFrontmatterSectionSchema).optional();
19
+ }
20
+ export const commandAgentFrontmatterSectionsSchema = createAgentFrontmatterSectionsSchema('command');
21
+ export const ruleAgentFrontmatterSectionsSchema = createAgentFrontmatterSectionsSchema('rule');
4
22
  export const commandFrontmatterSchema = z
5
23
  .object({
6
24
  name: nonEmptyStringSchema,
7
25
  description: nonEmptyStringSchema,
8
- cursor: z
9
- .object({
10
- 'disable-model-invocation': z.boolean().optional(),
11
- })
12
- .strict()
13
- .optional(),
26
+ agents: commandAgentFrontmatterSectionsSchema,
14
27
  })
15
28
  .strict();
16
29
  export const ruleFrontmatterSchema = z
17
30
  .object({
18
31
  description: nonEmptyStringSchema,
19
- copilot: z
20
- .object({
21
- applyTo: nonEmptyStringSchema,
22
- })
23
- .strict(),
24
- cursor: z
25
- .object({
26
- alwaysApply: z.boolean().optional(),
27
- globs: nonEmptyStringSchema.optional(),
28
- })
29
- .strict()
30
- .optional(),
32
+ agents: ruleAgentFrontmatterSectionsSchema,
31
33
  })
32
34
  .strict();
33
- /**
34
- * Returns a copy of an object with all undefined-valued entries removed.
35
- */
36
- export function compactObject(value) {
37
- return Object.fromEntries(Object.entries(value).filter(([, entryValue]) => entryValue !== undefined));
38
- }
39
35
  /**
40
36
  * Returns whether a value is a non-null plain object and not an array.
41
37
  */
@@ -55,7 +51,7 @@ export function parseFrontmatter(fileContent) {
55
51
  /**
56
52
  * Validates parsed frontmatter against a schema and logs a skip message when validation fails.
57
53
  */
58
- export function validateFrontmatter({ filePath, metadata, schema, }) {
54
+ export function validateFrontmatter(runtime, { filePath, metadata, schema, }) {
59
55
  const result = schema.safeParse(metadata);
60
56
  if (result.success) {
61
57
  return result.data;
@@ -66,26 +62,11 @@ export function validateFrontmatter({ filePath, metadata, schema, }) {
66
62
  return `${fieldPath}: ${issue.message}`;
67
63
  })
68
64
  .join('; ');
69
- console.log(`Skipping invalid frontmatter in ${filePath}: ${issues}`);
65
+ runtime.logInfo(`Skipping invalid frontmatter in ${filePath}: ${issues}`);
70
66
  return null;
71
67
  }
72
68
  /**
73
- * Normalizes rule frontmatter into the apply settings used by downstream generators.
74
- */
75
- export function normalizeRuleMetadata(metadata) {
76
- const copilotApplyTo = metadata.copilot.applyTo;
77
- const explicitAlwaysApply = metadata.cursor?.alwaysApply;
78
- const scopedGlobs = metadata.cursor?.globs ?? copilotApplyTo;
79
- const alwaysApply = explicitAlwaysApply ?? (scopedGlobs === undefined || scopedGlobs === '**');
80
- const globs = alwaysApply ? undefined : scopedGlobs;
81
- return {
82
- alwaysApply,
83
- globs,
84
- applyTo: copilotApplyTo,
85
- };
86
- }
87
- /**
88
- * Renders metadata and markdown body content back into a frontmatter document string.
69
+ * Serializes metadata as YAML frontmatter and combines it with the markdown body into a single document string.
89
70
  */
90
71
  export function renderMarkdown({ metadata, body, }) {
91
72
  const normalizedBody = body.trim();
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Returns a copy of an object with all undefined-valued entries removed.
3
+ */
4
+ export declare function compactObject(value: Record<string, unknown>): Record<string, unknown>;
5
+ //# sourceMappingURL=object-helpers.d.ts.map
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Returns a copy of an object with all undefined-valued entries removed.
3
+ */
4
+ export function compactObject(value) {
5
+ return Object.fromEntries(Object.entries(value).filter(([, entryValue]) => entryValue !== undefined));
6
+ }
@@ -10,26 +10,8 @@ declare const skillLockEntrySchema: z.ZodObject<{
10
10
  files: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
11
11
  importedAt: z.ZodString;
12
12
  updatedAt: z.ZodString;
13
- }, "strip", z.ZodTypeAny, {
14
- name: string;
15
- path: string;
16
- repo: string;
17
- commit: string;
18
- importedAt: string;
19
- updatedAt: string;
20
- ref?: string | undefined;
21
- files?: Record<string, string> | undefined;
22
- }, {
23
- name: string;
24
- path: string;
25
- repo: string;
26
- commit: string;
27
- importedAt: string;
28
- updatedAt: string;
29
- ref?: string | undefined;
30
- files?: Record<string, string> | undefined;
31
- }>;
32
- declare const skillsLockfileSchema: z.ZodEffects<z.ZodObject<{
13
+ }, z.core.$strip>;
14
+ declare const skillsLockfileSchema: z.ZodObject<{
33
15
  version: z.ZodLiteral<1>;
34
16
  skills: z.ZodArray<z.ZodObject<{
35
17
  name: z.ZodString;
@@ -40,74 +22,8 @@ declare const skillsLockfileSchema: z.ZodEffects<z.ZodObject<{
40
22
  files: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
41
23
  importedAt: z.ZodString;
42
24
  updatedAt: z.ZodString;
43
- }, "strip", z.ZodTypeAny, {
44
- name: string;
45
- path: string;
46
- repo: string;
47
- commit: string;
48
- importedAt: string;
49
- updatedAt: string;
50
- ref?: string | undefined;
51
- files?: Record<string, string> | undefined;
52
- }, {
53
- name: string;
54
- path: string;
55
- repo: string;
56
- commit: string;
57
- importedAt: string;
58
- updatedAt: string;
59
- ref?: string | undefined;
60
- files?: Record<string, string> | undefined;
61
- }>, "many">;
62
- }, "strip", z.ZodTypeAny, {
63
- skills: {
64
- name: string;
65
- path: string;
66
- repo: string;
67
- commit: string;
68
- importedAt: string;
69
- updatedAt: string;
70
- ref?: string | undefined;
71
- files?: Record<string, string> | undefined;
72
- }[];
73
- version: 1;
74
- }, {
75
- skills: {
76
- name: string;
77
- path: string;
78
- repo: string;
79
- commit: string;
80
- importedAt: string;
81
- updatedAt: string;
82
- ref?: string | undefined;
83
- files?: Record<string, string> | undefined;
84
- }[];
85
- version: 1;
86
- }>, {
87
- skills: {
88
- name: string;
89
- path: string;
90
- repo: string;
91
- commit: string;
92
- importedAt: string;
93
- updatedAt: string;
94
- ref?: string | undefined;
95
- files?: Record<string, string> | undefined;
96
- }[];
97
- version: 1;
98
- }, {
99
- skills: {
100
- name: string;
101
- path: string;
102
- repo: string;
103
- commit: string;
104
- importedAt: string;
105
- updatedAt: string;
106
- ref?: string | undefined;
107
- files?: Record<string, string> | undefined;
108
- }[];
109
- version: 1;
110
- }>;
25
+ }, z.core.$strip>>;
26
+ }, z.core.$strip>;
111
27
  export type ManagedSkill = z.infer<typeof skillLockEntrySchema>;
112
28
  export type SkillsLockfile = z.infer<typeof skillsLockfileSchema>;
113
29
  export type ManagedSkillFiles = z.infer<typeof managedSkillFilesSchema>;
@@ -148,12 +64,22 @@ export declare function deriveSkillName({ repo, skillPath, explicitName, }: {
148
64
  }): string;
149
65
  export declare function normalizeRemoteRepo(repo: string): string;
150
66
  /**
151
- * Builds the canonical remote path for a managed skill under the repository `skills/` directory.
67
+ * Returns the canonical remote path for a managed skill under the repository `skills/` directory.
152
68
  */
153
69
  export declare function resolveManagedSkillImportPath({ skillName, }: {
154
70
  skillName: string;
155
71
  }): string;
156
- export declare function normalizeImportedSkillPath(skillPath: string | undefined): string;
72
+ /**
73
+ * Normalizes an explicitly provided repository-relative skill path.
74
+ */
75
+ export declare function normalizeImportedSkillPath(skillPath: string | undefined): string | undefined;
76
+ /**
77
+ * Joins an optional base repository path with a requested managed skill name.
78
+ */
79
+ export declare function resolveManagedSkillImportPathFromBase(input: {
80
+ basePath: string | undefined;
81
+ skillName: string;
82
+ }): string;
157
83
  /**
158
84
  * Creates the lockfile record for a newly imported managed skill.
159
85
  */
@@ -167,7 +93,7 @@ export declare function createImportedSkillRecord(input: {
167
93
  repo: string;
168
94
  }): ManagedSkill;
169
95
  /**
170
- * Creates the next lockfile record for a managed skill after its local contents have been refreshed.
96
+ * Returns an updated lockfile record for an existing managed skill after a successful remote refresh.
171
97
  */
172
98
  export declare function createUpdatedSkillRecord(input: {
173
99
  commit: string;
@@ -176,7 +102,7 @@ export declare function createUpdatedSkillRecord(input: {
176
102
  updatedAt: string;
177
103
  }): ManagedSkill;
178
104
  /**
179
- * Computes stable SHA-256 hashes for every file within a managed skill directory.
105
+ * Returns a map of relative file path → SHA-256 hash for every file in directoryPath.
180
106
  */
181
107
  export declare function computeDirectoryHashes(directoryPath: string): Promise<ManagedSkillFiles>;
182
108
  /**
@@ -197,13 +123,25 @@ export declare function cloneRemoteRepo(input: {
197
123
  repo: string;
198
124
  }): Promise<RemoteRepoCheckout>;
199
125
  /**
200
- * Resolves and validates a managed skill directory from a temporary repository checkout.
126
+ * Removes one temporary repository checkout returned by `cloneRemoteRepo`.
127
+ */
128
+ export declare function cleanupRemoteRepoCheckout(checkout: RemoteRepoCheckout): Promise<void>;
129
+ /**
130
+ * Returns the source directory path for a skill at its default location (`skills/<skillName>`), confirming the directory and SKILL.md exist.
201
131
  */
202
132
  export declare function resolveSkillSourceDir(input: {
203
133
  checkoutDir: string;
204
134
  repo: string;
205
135
  skillName: string;
206
136
  }): Promise<string>;
137
+ /**
138
+ * Returns the source directory path for a skill at an explicit repository-relative path, confirming the directory and SKILL.md exist.
139
+ */
140
+ export declare function resolveSkillSourceDirByPath(input: {
141
+ checkoutDir: string;
142
+ repo: string;
143
+ skillPath: string;
144
+ }): Promise<string>;
207
145
  /**
208
146
  * Fetches a validated remote skill directory snapshot for a specific repository path.
209
147
  */
@@ -212,6 +150,10 @@ export declare function fetchRemoteSkillSnapshot(input: {
212
150
  repo: string;
213
151
  skillPath: string;
214
152
  }): Promise<RemoteSkillSnapshot>;
153
+ /**
154
+ * Removes one temporary remote skill snapshot returned by `fetchRemoteSkillSnapshot`.
155
+ */
156
+ export declare function cleanupRemoteSkillSnapshot(snapshot: RemoteSkillSnapshot): Promise<void>;
215
157
  export declare function replaceManagedSkillDirectory({ targetDir, sourceDir, }: {
216
158
  targetDir: string;
217
159
  sourceDir: string;
@@ -126,7 +126,7 @@ export function normalizeRemoteRepo(repo) {
126
126
  return trimmedRepo;
127
127
  }
128
128
  /**
129
- * Builds the canonical remote path for a managed skill under the repository `skills/` directory.
129
+ * Returns the canonical remote path for a managed skill under the repository `skills/` directory.
130
130
  */
131
131
  export function resolveManagedSkillImportPath({ skillName, }) {
132
132
  const trimmedSkillName = skillName.trim();
@@ -139,9 +139,30 @@ export function resolveManagedSkillImportPath({ skillName, }) {
139
139
  }
140
140
  return `skills/${trimmedSkillName}`;
141
141
  }
142
+ /**
143
+ * Normalizes an explicitly provided repository-relative skill path.
144
+ */
142
145
  export function normalizeImportedSkillPath(skillPath) {
143
- const normalizedPath = skillPath && skillPath.length > 0 ? skillPath : '.';
144
- return path.normalize(normalizedPath);
146
+ if (skillPath === undefined) {
147
+ return undefined;
148
+ }
149
+ return path.normalize(skillPath);
150
+ }
151
+ /**
152
+ * Joins an optional base repository path with a requested managed skill name.
153
+ */
154
+ export function resolveManagedSkillImportPathFromBase(input) {
155
+ const normalizedBasePath = normalizeImportedSkillPath(input.basePath);
156
+ const defaultSkillPath = resolveManagedSkillImportPath({
157
+ skillName: input.skillName,
158
+ });
159
+ if (normalizedBasePath === '.') {
160
+ return path.normalize(input.skillName);
161
+ }
162
+ if (normalizedBasePath === undefined) {
163
+ return defaultSkillPath;
164
+ }
165
+ return path.normalize(path.join(normalizedBasePath, input.skillName));
145
166
  }
146
167
  /**
147
168
  * Creates the lockfile record for a newly imported managed skill.
@@ -159,7 +180,7 @@ export function createImportedSkillRecord(input) {
159
180
  };
160
181
  }
161
182
  /**
162
- * Creates the next lockfile record for a managed skill after its local contents have been refreshed.
183
+ * Returns an updated lockfile record for an existing managed skill after a successful remote refresh.
163
184
  */
164
185
  export function createUpdatedSkillRecord(input) {
165
186
  return {
@@ -170,7 +191,7 @@ export function createUpdatedSkillRecord(input) {
170
191
  };
171
192
  }
172
193
  /**
173
- * Computes stable SHA-256 hashes for every file within a managed skill directory.
194
+ * Returns a map of relative file path → SHA-256 hash for every file in directoryPath.
174
195
  */
175
196
  export async function computeDirectoryHashes(directoryPath) {
176
197
  const relativeFilePaths = await listRelativeFilePaths(directoryPath);
@@ -200,8 +221,14 @@ export async function detectLocalSkillEdits(input) {
200
221
  };
201
222
  }
202
223
  const currentFiles = await computeDirectoryHashes(input.skillDir);
203
- const changedFiles = [...new Set([...Object.keys(input.storedFiles), ...Object.keys(currentFiles)])]
204
- .filter((relativeFilePath) => input.storedFiles?.[relativeFilePath] !== currentFiles[relativeFilePath])
224
+ const changedFiles = [
225
+ ...new Set([
226
+ ...Object.keys(input.storedFiles),
227
+ ...Object.keys(currentFiles),
228
+ ]),
229
+ ]
230
+ .filter((relativeFilePath) => input.storedFiles?.[relativeFilePath] !==
231
+ currentFiles[relativeFilePath])
205
232
  .sort((left, right) => left.localeCompare(right));
206
233
  return {
207
234
  changedFiles,
@@ -242,7 +269,13 @@ export async function cloneRemoteRepo(input) {
242
269
  }
243
270
  }
244
271
  /**
245
- * Resolves and validates a managed skill directory from a temporary repository checkout.
272
+ * Removes one temporary repository checkout returned by `cloneRemoteRepo`.
273
+ */
274
+ export async function cleanupRemoteRepoCheckout(checkout) {
275
+ await checkout.cleanup();
276
+ }
277
+ /**
278
+ * Returns the source directory path for a skill at its default location (`skills/<skillName>`), confirming the directory and SKILL.md exist.
246
279
  */
247
280
  export async function resolveSkillSourceDir(input) {
248
281
  const skillPath = resolveManagedSkillImportPath({
@@ -259,6 +292,25 @@ export async function resolveSkillSourceDir(input) {
259
292
  });
260
293
  return sourceDir;
261
294
  }
295
+ /**
296
+ * Returns the source directory path for a skill at an explicit repository-relative path, confirming the directory and SKILL.md exist.
297
+ */
298
+ export async function resolveSkillSourceDirByPath(input) {
299
+ const normalizedSkillPath = normalizeImportedSkillPath(input.skillPath);
300
+ if (normalizedSkillPath === undefined) {
301
+ throw new Error('Skill path may not be empty');
302
+ }
303
+ const sourceDir = resolveRemoteSkillDirectory({
304
+ checkoutDir: input.checkoutDir,
305
+ skillPath: normalizedSkillPath,
306
+ });
307
+ await validateRemoteSkillDirectory({
308
+ sourceDir,
309
+ skillPath: normalizedSkillPath,
310
+ repo: normalizeRemoteRepo(input.repo),
311
+ });
312
+ return sourceDir;
313
+ }
262
314
  /**
263
315
  * Fetches a validated remote skill directory snapshot for a specific repository path.
264
316
  */
@@ -292,6 +344,12 @@ export async function fetchRemoteSkillSnapshot(input) {
292
344
  });
293
345
  }
294
346
  }
347
+ /**
348
+ * Removes one temporary remote skill snapshot returned by `fetchRemoteSkillSnapshot`.
349
+ */
350
+ export async function cleanupRemoteSkillSnapshot(snapshot) {
351
+ await snapshot.cleanup();
352
+ }
295
353
  export async function replaceManagedSkillDirectory({ targetDir, sourceDir, }) {
296
354
  await fs.ensureDir(path.dirname(targetDir));
297
355
  const stagingRoot = await fs.mkdtemp(path.join(path.dirname(targetDir), `${path.basename(targetDir)}.`));
@@ -0,0 +1,7 @@
1
+ import type { CLIRuntime } from '../cli.js';
2
+ import type { AgentsContext } from './context.js';
3
+ /**
4
+ * Writes all command, rule, and skill outputs to their target directories, then prunes any stale dryai-managed files from prior runs.
5
+ */
6
+ export declare function syncToTargets(context: AgentsContext, runtime: CLIRuntime): Promise<void>;
7
+ //# sourceMappingURL=sync.d.ts.map