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
@@ -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,7 +64,7 @@ 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;
@@ -177,7 +93,7 @@ export declare function createImportedSkillRecord(input: {
177
93
  repo: string;
178
94
  }): ManagedSkill;
179
95
  /**
180
- * 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.
181
97
  */
182
98
  export declare function createUpdatedSkillRecord(input: {
183
99
  commit: string;
@@ -186,7 +102,7 @@ export declare function createUpdatedSkillRecord(input: {
186
102
  updatedAt: string;
187
103
  }): ManagedSkill;
188
104
  /**
189
- * 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.
190
106
  */
191
107
  export declare function computeDirectoryHashes(directoryPath: string): Promise<ManagedSkillFiles>;
192
108
  /**
@@ -207,7 +123,11 @@ export declare function cloneRemoteRepo(input: {
207
123
  repo: string;
208
124
  }): Promise<RemoteRepoCheckout>;
209
125
  /**
210
- * 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.
211
131
  */
212
132
  export declare function resolveSkillSourceDir(input: {
213
133
  checkoutDir: string;
@@ -215,7 +135,7 @@ export declare function resolveSkillSourceDir(input: {
215
135
  skillName: string;
216
136
  }): Promise<string>;
217
137
  /**
218
- * Resolves and validates an arbitrary managed skill directory path from a temporary repository checkout.
138
+ * Returns the source directory path for a skill at an explicit repository-relative path, confirming the directory and SKILL.md exist.
219
139
  */
220
140
  export declare function resolveSkillSourceDirByPath(input: {
221
141
  checkoutDir: string;
@@ -230,6 +150,10 @@ export declare function fetchRemoteSkillSnapshot(input: {
230
150
  repo: string;
231
151
  skillPath: string;
232
152
  }): Promise<RemoteSkillSnapshot>;
153
+ /**
154
+ * Removes one temporary remote skill snapshot returned by `fetchRemoteSkillSnapshot`.
155
+ */
156
+ export declare function cleanupRemoteSkillSnapshot(snapshot: RemoteSkillSnapshot): Promise<void>;
233
157
  export declare function replaceManagedSkillDirectory({ targetDir, sourceDir, }: {
234
158
  targetDir: string;
235
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();
@@ -180,7 +180,7 @@ export function createImportedSkillRecord(input) {
180
180
  };
181
181
  }
182
182
  /**
183
- * 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.
184
184
  */
185
185
  export function createUpdatedSkillRecord(input) {
186
186
  return {
@@ -191,7 +191,7 @@ export function createUpdatedSkillRecord(input) {
191
191
  };
192
192
  }
193
193
  /**
194
- * 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.
195
195
  */
196
196
  export async function computeDirectoryHashes(directoryPath) {
197
197
  const relativeFilePaths = await listRelativeFilePaths(directoryPath);
@@ -221,8 +221,14 @@ export async function detectLocalSkillEdits(input) {
221
221
  };
222
222
  }
223
223
  const currentFiles = await computeDirectoryHashes(input.skillDir);
224
- const changedFiles = [...new Set([...Object.keys(input.storedFiles), ...Object.keys(currentFiles)])]
225
- .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])
226
232
  .sort((left, right) => left.localeCompare(right));
227
233
  return {
228
234
  changedFiles,
@@ -263,7 +269,13 @@ export async function cloneRemoteRepo(input) {
263
269
  }
264
270
  }
265
271
  /**
266
- * 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.
267
279
  */
268
280
  export async function resolveSkillSourceDir(input) {
269
281
  const skillPath = resolveManagedSkillImportPath({
@@ -281,7 +293,7 @@ export async function resolveSkillSourceDir(input) {
281
293
  return sourceDir;
282
294
  }
283
295
  /**
284
- * Resolves and validates an arbitrary managed skill directory path from a temporary repository checkout.
296
+ * Returns the source directory path for a skill at an explicit repository-relative path, confirming the directory and SKILL.md exist.
285
297
  */
286
298
  export async function resolveSkillSourceDirByPath(input) {
287
299
  const normalizedSkillPath = normalizeImportedSkillPath(input.skillPath);
@@ -332,6 +344,12 @@ export async function fetchRemoteSkillSnapshot(input) {
332
344
  });
333
345
  }
334
346
  }
347
+ /**
348
+ * Removes one temporary remote skill snapshot returned by `fetchRemoteSkillSnapshot`.
349
+ */
350
+ export async function cleanupRemoteSkillSnapshot(snapshot) {
351
+ await snapshot.cleanup();
352
+ }
335
353
  export async function replaceManagedSkillDirectory({ targetDir, sourceDir, }) {
336
354
  await fs.ensureDir(path.dirname(targetDir));
337
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