@purveyors/cli 0.35.1 → 0.36.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/README.md +51 -12
  2. package/dist/commands/auth.d.ts.map +1 -1
  3. package/dist/commands/auth.js +6 -6
  4. package/dist/commands/auth.js.map +1 -1
  5. package/dist/commands/catalog.d.ts.map +1 -1
  6. package/dist/commands/catalog.js +84 -89
  7. package/dist/commands/catalog.js.map +1 -1
  8. package/dist/commands/context.js +2 -2
  9. package/dist/commands/context.js.map +1 -1
  10. package/dist/commands/inventory.js +32 -32
  11. package/dist/commands/inventory.js.map +1 -1
  12. package/dist/commands/manifest.js +3 -3
  13. package/dist/commands/manifest.js.map +1 -1
  14. package/dist/commands/market.d.ts.map +1 -1
  15. package/dist/commands/market.js +24 -24
  16. package/dist/commands/market.js.map +1 -1
  17. package/dist/commands/price-index.d.ts.map +1 -1
  18. package/dist/commands/price-index.js +17 -17
  19. package/dist/commands/price-index.js.map +1 -1
  20. package/dist/commands/procurement.d.ts.map +1 -1
  21. package/dist/commands/procurement.js +2 -2
  22. package/dist/commands/procurement.js.map +1 -1
  23. package/dist/commands/reference-profile.d.ts.map +1 -1
  24. package/dist/commands/reference-profile.js +15 -15
  25. package/dist/commands/reference-profile.js.map +1 -1
  26. package/dist/commands/roast.d.ts.map +1 -1
  27. package/dist/commands/roast.js +50 -50
  28. package/dist/commands/roast.js.map +1 -1
  29. package/dist/commands/sales.js +21 -21
  30. package/dist/commands/sales.js.map +1 -1
  31. package/dist/commands/skill.d.ts +3 -0
  32. package/dist/commands/skill.d.ts.map +1 -0
  33. package/dist/commands/skill.js +145 -0
  34. package/dist/commands/skill.js.map +1 -0
  35. package/dist/commands/tasting.d.ts.map +1 -1
  36. package/dist/commands/tasting.js +16 -16
  37. package/dist/commands/tasting.js.map +1 -1
  38. package/dist/lib/agent-skill.d.ts +110 -0
  39. package/dist/lib/agent-skill.d.ts.map +1 -0
  40. package/dist/lib/agent-skill.js +611 -0
  41. package/dist/lib/agent-skill.js.map +1 -0
  42. package/dist/lib/manifest.d.ts +2 -0
  43. package/dist/lib/manifest.d.ts.map +1 -1
  44. package/dist/lib/manifest.js +992 -351
  45. package/dist/lib/manifest.js.map +1 -1
  46. package/dist/program.d.ts.map +1 -1
  47. package/dist/program.js +68 -12
  48. package/dist/program.js.map +1 -1
  49. package/package.json +1 -1
@@ -0,0 +1,611 @@
1
+ import { createHash } from 'node:crypto';
2
+ import { mkdir, readFile, realpath, rename, writeFile } from 'node:fs/promises';
3
+ import { homedir } from 'node:os';
4
+ import { basename, dirname, join, relative, resolve, sep } from 'node:path';
5
+ import { PrvrsError } from './errors.js';
6
+ import { HEADLESS_LOGIN_STEPS, getCliManifest, } from './manifest.js';
7
+ /**
8
+ * Agent instructions rendered from the CLI manifest. The manifest stays the
9
+ * single source of truth: commands, flags, auth, output, exit codes, ID types,
10
+ * and workflows all come from `getCliManifest()`, so the skill cannot drift
11
+ * from the contract it describes.
12
+ */
13
+ export const AGENT_SKILL_NAME = 'purveyors';
14
+ export const AGENT_SKILL_FILE = 'SKILL.md';
15
+ /**
16
+ * Supporting file in the same skill folder. Agent Skills clients load SKILL.md
17
+ * when the skill triggers and read other files only when SKILL.md points to
18
+ * them, so the step-by-step workflows, which grow with the manifest, live here.
19
+ * See https://code.claude.com/docs/en/skills#add-supporting-files and
20
+ * https://agentskills.io/specification#progressive-disclosure
21
+ */
22
+ export const AGENT_WORKFLOWS_FILE = 'workflows.md';
23
+ /** Every file in the skill folder, SKILL.md first. */
24
+ export const AGENT_SKILL_FILES = [AGENT_SKILL_FILE, AGENT_WORKFLOWS_FILE];
25
+ /** Upper bound for the rendered SKILL.md, enforced by tests. */
26
+ export const AGENT_SKILL_MAX_BYTES = 8 * 1024;
27
+ /** Upper bound for the rendered workflows.md, enforced by tests. */
28
+ export const AGENT_WORKFLOWS_MAX_BYTES = 16 * 1024;
29
+ const SKILL_TOPICS = 'green coffee sourcing, the purveyors.io coffee catalog, green coffee prices and market moves, green inventory, roast logging and Artisan .alog files, sales, and tasting notes';
30
+ export const AGENT_SKILL_DESCRIPTION = `${capitalize(SKILL_TOPICS)}, through the \`purvey\` CLI. Use when the user wants to find or compare green coffees or suppliers, check prices or market signals, track inventory, log, import, or plan roasts, record sales, or rate coffees.`;
31
+ export const SKILL_TARGETS = ['claude', 'agents', 'agents-md'];
32
+ export const SKILL_SCOPES = ['user', 'project'];
33
+ const ACCESS_LABELS = {
34
+ none: 'no sign-in',
35
+ viewer: 'sign-in',
36
+ member: 'member role',
37
+ mixed: 'mixed access',
38
+ };
39
+ // Per-command labels, used when a group's commands differ in access.
40
+ const COMMAND_ACCESS_LABELS = {
41
+ none: 'public default view',
42
+ viewer: 'sign-in',
43
+ member: 'member role',
44
+ };
45
+ // Error patterns whose guidance another skill section already gives in full.
46
+ const ERROR_PATTERNS_COVERED_ELSEWHERE = new Set([
47
+ 'Not logged in',
48
+ 'Wrong ID type',
49
+ 'Parser mistakes like unknown options or commands',
50
+ 'Missing required args in write commands',
51
+ ]);
52
+ function capitalize(text) {
53
+ return text.charAt(0).toUpperCase() + text.slice(1);
54
+ }
55
+ function sha256(text) {
56
+ return createHash('sha256').update(text, 'utf8').digest('hex');
57
+ }
58
+ /**
59
+ * List a group's commands. When access differs across them, label each run of
60
+ * commands with its own access so an agent never picks a protected command
61
+ * expecting the public slice.
62
+ */
63
+ function renderGroupCommands(group) {
64
+ const commands = [
65
+ ...(group.command ? [{ name: `${group.name} itself`, auth: group.command.auth }] : []),
66
+ ...(group.subcommands ?? []).map(({ name, auth }) => ({ name, auth })),
67
+ ];
68
+ if (commands.every((command) => command.auth === group.auth)) {
69
+ return commands.map((command) => command.name).join(', ');
70
+ }
71
+ const byAccess = new Map();
72
+ for (const command of commands) {
73
+ byAccess.set(command.auth, [...(byAccess.get(command.auth) ?? []), command.name]);
74
+ }
75
+ return [...byAccess]
76
+ .map(([auth, names]) => `${names.join(', ')} (${COMMAND_ACCESS_LABELS[auth]})`)
77
+ .join('; ');
78
+ }
79
+ function renderWhenToUse(manifest) {
80
+ // Credential-free groups (auth, config, context, manifest, skill) are setup
81
+ // and reference surfaces, covered in their own sections below.
82
+ const dataGroups = manifest.commandGroups.filter((group) => group.auth !== 'none');
83
+ return [
84
+ '## When to use it',
85
+ '',
86
+ `Use \`${manifest.binary}\` for any Purveyors task instead of scraping purveyors.io or guessing API calls. Command groups and their access:`,
87
+ '',
88
+ ...dataGroups.map((group) => `- **${group.name}** (${ACCESS_LABELS[group.auth]}): ${group.summary}. Commands: ${renderGroupCommands(group)}.`),
89
+ ];
90
+ }
91
+ function renderSetup(manifest) {
92
+ return [
93
+ '## Set up and sign in',
94
+ '',
95
+ `1. Install (${manifest.nodeVersion}): \`npm install -g ${manifest.packageName}\`, then check \`purvey --version\`.`,
96
+ '2. Check for an existing login: `purvey auth status --json` prints `"authenticated": true` and the role, or exits 3 when signed out.',
97
+ '3. If not signed in, run `purvey auth login --headless`. It prints the URL at once, then waits:',
98
+ ...HEADLESS_LOGIN_STEPS.map((step, index) => ` ${index + 1}. ${step}`),
99
+ '',
100
+ ' If your shell tool shows output only after a command exits, run it in the background to read the URL. Show the URL to the user; sign-in is done when the command exits 0. Rerun it if the request expires.',
101
+ '4. Never ask the user to paste an API key, token, or password into the chat. The CLI stores its own scoped key in ' +
102
+ `\`${manifest.files.credentials}\`; \`PURVEYORS_API_KEY\` or \`PARCHMENT_API_KEY\` in the environment overrides it.`,
103
+ '5. "sign-in" commands work for any signed-in account; "member role" needs a Purveyors membership; "public default view" runs signed out, but filters and longer windows need Parchment Intelligence. reference-profile needs Studio access. Missing access exits 3; relay the message to the user instead of retrying.',
104
+ ];
105
+ }
106
+ function renderOutput(manifest) {
107
+ const { structuredErrors } = manifest.outputContract;
108
+ const fields = (names) => names.map((field) => `\`${field}\``).join(', ');
109
+ return [
110
+ '## Output, errors, and exit codes',
111
+ '',
112
+ '- stdout carries the result as compact JSON by default; parse it rather than scraping text. Leave off `--pretty` when parsing.',
113
+ `- In a non-interactive shell, a failure prints one JSON envelope on ${structuredErrors.channel} with ${fields(structuredErrors.guaranteedFields)} and sometimes ${fields(structuredErrors.optionalFields)}. Progress messages also go to ${structuredErrors.channel}.`,
114
+ `- Exit codes: ${manifest.exitCodes.map((code) => `\`${code.exitCode}\` ${code.description}`).join('; ')}.`,
115
+ ];
116
+ }
117
+ function renderIdMap(manifest) {
118
+ return [
119
+ '## ID map',
120
+ '',
121
+ 'IDs are not interchangeable. Pass the type each command expects:',
122
+ '',
123
+ ...manifest.idTypes.map((id) => `- \`${id.name}\`: ${id.usedBy.join(', ')}`),
124
+ ];
125
+ }
126
+ /** SKILL.md names each workflow and points to workflows.md for the steps. */
127
+ function renderWorkflowIndex(manifest) {
128
+ return [
129
+ '## Workflows',
130
+ '',
131
+ `Before a multi-step task, read [${AGENT_WORKFLOWS_FILE}](${AGENT_WORKFLOWS_FILE}) next to this file (if missing: \`purvey skill print --file ${AGENT_WORKFLOWS_FILE}\`). It has the commands for:`,
132
+ '',
133
+ ...manifest.workflows.map((workflow) => `- ${workflow.title}`),
134
+ ];
135
+ }
136
+ function renderWorkflowsBody(manifest) {
137
+ const lines = [
138
+ `# Purveyors workflows (\`${manifest.binary}\` CLI)`,
139
+ '',
140
+ `Command sequences for multi-step tasks. [${AGENT_SKILL_FILE}](${AGENT_SKILL_FILE}) covers sign-in, access, the ID map, and the working rules; they apply here too.`,
141
+ '',
142
+ '- IDs and file paths below are placeholders. Take real IDs from search or list output, and check the ID map for the type each command takes.',
143
+ '- Leave off `--pretty` when parsing.',
144
+ '- Confirm with the user before a step that changes their data.',
145
+ ];
146
+ for (const workflow of manifest.workflows) {
147
+ lines.push('', `## ${workflow.title}`, '', '```sh', ...workflow.commands, '```');
148
+ }
149
+ lines.push('');
150
+ return lines.join('\n');
151
+ }
152
+ function renderRules(manifest) {
153
+ return [
154
+ '## Working rules',
155
+ '',
156
+ '- Give every value on the command line: positional arguments per `--help`, flags for the rest. Do not use `--form`, which prompts interactively.',
157
+ '- Confirm with the user before commands that change their data: add, create, update, delete, record, rate, import, save, and watch.',
158
+ ...manifest.errorPatterns
159
+ .filter((pattern) => !ERROR_PATTERNS_COVERED_ELSEWHERE.has(pattern.title))
160
+ .map((pattern) => `- ${pattern.title}${pattern.exitCodes.length > 0 ? ` (exit ${pattern.exitCodes.join('/')})` : ''}: ${pattern.guidance.join(' ')}`),
161
+ ];
162
+ }
163
+ function renderReference(manifest) {
164
+ return [
165
+ '## Full contract',
166
+ '',
167
+ `\`${manifest.machineSurfaces.shellManifest}\` prints the full contract as JSON: every command, argument, flag, default, auth requirement, and example. Check it before using a flag not shown here:`,
168
+ '',
169
+ '```sh',
170
+ 'purvey manifest | jq \'.commandGroups[] | select(.name == "catalog")\'',
171
+ 'purvey catalog search --help',
172
+ '```',
173
+ '',
174
+ `\`${manifest.machineSurfaces.humanReference}\` prints it as dense text. Docs: ${manifest.docs
175
+ .filter((link) => new URL(link.url).hostname.endsWith('purveyors.io'))
176
+ .map((link) => `[${link.label}](${link.url})`)
177
+ .join(', ')}.`,
178
+ '',
179
+ `After upgrading the CLI, refresh this file and ${AGENT_WORKFLOWS_FILE}: rerun \`purvey skill install\` with the same \`--target\` (\`claude\` for Claude Code, \`agents\` for Codex and Cursor).`,
180
+ ];
181
+ }
182
+ function renderSkillBody(manifest, version) {
183
+ return [
184
+ '---',
185
+ `name: ${AGENT_SKILL_NAME}`,
186
+ `description: ${JSON.stringify(AGENT_SKILL_DESCRIPTION)}`,
187
+ 'metadata:',
188
+ ` generated-by: ${JSON.stringify(`${manifest.packageName} ${version}`)}`,
189
+ '---',
190
+ '',
191
+ `# Purveyors (\`${manifest.binary}\` CLI)`,
192
+ '',
193
+ ...renderWhenToUse(manifest),
194
+ '',
195
+ ...renderSetup(manifest),
196
+ '',
197
+ ...renderOutput(manifest),
198
+ '',
199
+ ...renderIdMap(manifest),
200
+ '',
201
+ ...renderWorkflowIndex(manifest),
202
+ '',
203
+ ...renderRules(manifest),
204
+ '',
205
+ ...renderReference(manifest),
206
+ '',
207
+ ].join('\n');
208
+ }
209
+ /**
210
+ * The trailing comment records a hash of everything above it, so `install` can
211
+ * tell an unedited earlier copy (safe to update) from one with local edits
212
+ * (needs --force).
213
+ */
214
+ function seal(body, version, printCommand) {
215
+ return `${body}<!-- generated by @purveyors/cli ${version} (${printCommand}); sha256:${sha256(body)} -->\n`;
216
+ }
217
+ const SKILL_SEAL_PATTERN = /<!-- generated by @purveyors\/cli \S+ \(purvey skill print[^)]*\); sha256:([0-9a-f]{64}) -->\n?$/;
218
+ /** Render SKILL.md in the open Agent Skills format. */
219
+ export function renderAgentSkill(version, manifest = getCliManifest()) {
220
+ return seal(renderSkillBody(manifest, version), version, 'purvey skill print');
221
+ }
222
+ /** Render workflows.md, the supporting file SKILL.md points to for step-by-step workflows. */
223
+ export function renderAgentWorkflows(version, manifest = getCliManifest()) {
224
+ return seal(renderWorkflowsBody(manifest), version, `purvey skill print --file ${AGENT_WORKFLOWS_FILE}`);
225
+ }
226
+ /** Render one file of the skill folder. */
227
+ export function renderAgentSkillFile(file, version, manifest = getCliManifest()) {
228
+ return file === AGENT_SKILL_FILE
229
+ ? renderAgentSkill(version, manifest)
230
+ : renderAgentWorkflows(version, manifest);
231
+ }
232
+ function isUnmodifiedGeneratedSkill(text) {
233
+ const match = SKILL_SEAL_PATTERN.exec(text);
234
+ return Boolean(match && sha256(text.slice(0, match.index)) === match[1]);
235
+ }
236
+ const AGENTS_MD_BEGIN = '<!-- BEGIN purvey agent instructions';
237
+ const AGENTS_MD_END = '<!-- END purvey agent instructions -->';
238
+ const AGENTS_MD_BEGIN_PATTERN = /^<!-- BEGIN purvey agent instructions: generated by @purveyors\/cli \S+ \(purvey skill print --agents-md\); sha256:([0-9a-f]{64}) -->$/;
239
+ function renderAgentsMdInner(manifest) {
240
+ const exitCodes = manifest.exitCodes
241
+ .map((code) => `${code.exitCode} ${code.code.toLowerCase().replace(/_/g, ' ')}`)
242
+ .join(', ');
243
+ return [
244
+ `## Purveyors coffee data (\`${manifest.binary}\` CLI)`,
245
+ '',
246
+ `- Use \`${manifest.binary}\` for ${SKILL_TOPICS}. Install with \`npm install -g ${manifest.packageName}\`.`,
247
+ '- Sign in with `purvey auth login --headless`: show the user the approval URL it prints and wait for it to exit 0. Never ask for an API key, token, or password in chat.',
248
+ `- stdout is JSON; failures print a JSON envelope on stderr. Exit codes: ${exitCodes}.`,
249
+ `- IDs are not interchangeable (${manifest.idTypes.map((id) => `\`${id.name}\``).join(', ')}); check which one a command takes.`,
250
+ '- Do not use `--form`. Confirm with the user before commands that change their data.',
251
+ `- Full contract: \`${manifest.machineSurfaces.shellManifest}\`. For the fuller guide with workflows as a skill, run \`purvey skill install --target claude\` in Claude Code, or \`--target agents\` in Codex, Cursor, and other Agent Skills tools.`,
252
+ '',
253
+ ].join('\n');
254
+ }
255
+ /** Render the marked AGENTS.md block; markers let `install` refresh it in place. */
256
+ export function renderAgentsMdBlock(version, manifest = getCliManifest()) {
257
+ const inner = renderAgentsMdInner(manifest);
258
+ return `${AGENTS_MD_BEGIN}: generated by @purveyors/cli ${version} (purvey skill print --agents-md); sha256:${sha256(inner)} -->\n${inner}${AGENTS_MD_END}\n`;
259
+ }
260
+ function findAgentsMdBlock(text, path) {
261
+ const start = text.indexOf(AGENTS_MD_BEGIN);
262
+ if (start === -1) {
263
+ return null;
264
+ }
265
+ const endMarker = text.indexOf(AGENTS_MD_END, start);
266
+ const beginLineEnd = text.indexOf('\n', start);
267
+ if (endMarker === -1 ||
268
+ beginLineEnd === -1 ||
269
+ beginLineEnd > endMarker ||
270
+ text.indexOf(AGENTS_MD_BEGIN, start + 1) !== -1) {
271
+ throw new PrvrsError('CONFIG_ERROR', `${path} has an incomplete or repeated purvey agent instructions block. Fix or remove its BEGIN/END markers, then re-run.`, { path, reason: 'malformed-block' });
272
+ }
273
+ let end = endMarker + AGENTS_MD_END.length;
274
+ if (text[end] === '\n') {
275
+ end += 1;
276
+ }
277
+ const match = AGENTS_MD_BEGIN_PATTERN.exec(text.slice(start, beginLineEnd));
278
+ const inner = text.slice(beginLineEnd + 1, endMarker);
279
+ return { start, end, unmodified: Boolean(match && sha256(inner) === match[1]) };
280
+ }
281
+ export function resolveSkillInstallPath(target, scope, roots = {}) {
282
+ const home = roots.home ?? homedir();
283
+ const cwd = roots.cwd ?? process.cwd();
284
+ if (target === 'agents-md') {
285
+ return join(cwd, 'AGENTS.md');
286
+ }
287
+ const base = scope === 'user' ? home : cwd;
288
+ const toolDir = target === 'claude' ? '.claude' : '.agents';
289
+ return join(base, toolDir, 'skills', AGENT_SKILL_NAME, AGENT_SKILL_FILE);
290
+ }
291
+ function parseTarget(value) {
292
+ if (!value) {
293
+ throw new PrvrsError('INVALID_ARGUMENT', `--target is required: ${SKILL_TARGETS.join(', ')}. Use claude for Claude Code, agents for Codex, Cursor, and other Agent Skills clients, or agents-md for this repository's AGENTS.md.`);
294
+ }
295
+ if (!SKILL_TARGETS.includes(value)) {
296
+ throw new PrvrsError('INVALID_ARGUMENT', `Unknown --target "${value}". Use one of: ${SKILL_TARGETS.join(', ')}.`);
297
+ }
298
+ return value;
299
+ }
300
+ function parseScope(target, value) {
301
+ if (value !== undefined && !SKILL_SCOPES.includes(value)) {
302
+ throw new PrvrsError('INVALID_ARGUMENT', `Unknown --scope "${value}". Use one of: ${SKILL_SCOPES.join(', ')}.`);
303
+ }
304
+ if (target === 'agents-md') {
305
+ if (value === 'user') {
306
+ throw new PrvrsError('INVALID_ARGUMENT', 'AGENTS.md is repository-level. Run from the repository root without --scope, or with --scope project.');
307
+ }
308
+ return 'project';
309
+ }
310
+ return value ?? 'user';
311
+ }
312
+ async function readExisting(path) {
313
+ try {
314
+ return await readFile(path, 'utf8');
315
+ }
316
+ catch (error) {
317
+ const code = error.code;
318
+ if (code === 'ENOENT') {
319
+ return null;
320
+ }
321
+ if (code === 'EISDIR') {
322
+ throw new PrvrsError('CONFIG_ERROR', `${path} is a directory, not a file.`, { path });
323
+ }
324
+ throw error;
325
+ }
326
+ }
327
+ function refuseOverwrite(path, what) {
328
+ throw new PrvrsError('CONFIG_ERROR', `${what} at ${path} has local edits or was not written by purvey. Keep it, or re-run with --force to replace it.`, { path, reason: 'modified' });
329
+ }
330
+ /** Returns null when the file has local edits and `force` is off. */
331
+ function planSkillFile(existing, desired, force) {
332
+ if (existing === null)
333
+ return { action: 'create', content: desired };
334
+ if (existing === desired)
335
+ return { action: 'unchanged', content: desired };
336
+ if (isUnmodifiedGeneratedSkill(existing))
337
+ return { action: 'update', content: desired };
338
+ if (force)
339
+ return { action: 'overwrite', content: desired };
340
+ return null;
341
+ }
342
+ /**
343
+ * Plan every file in the skill folder before writing any of them, so a refusal
344
+ * leaves the folder exactly as it was. A folder from a single-file install has
345
+ * no workflows.md yet; that file is simply created.
346
+ */
347
+ async function planSkillFolder(skillPath, version, manifest, force) {
348
+ const planned = [];
349
+ const refused = [];
350
+ for (const file of AGENT_SKILL_FILES) {
351
+ const path = join(dirname(skillPath), file);
352
+ const plan = planSkillFile(await readExisting(path), renderAgentSkillFile(file, version, manifest), force);
353
+ if (plan) {
354
+ planned.push({ file, path, ...plan });
355
+ }
356
+ else {
357
+ refused.push(path);
358
+ }
359
+ }
360
+ if (refused.length > 0) {
361
+ const files = refused.map((path) => basename(path)).join(' and ');
362
+ const [verb, past, pronoun] = refused.length > 1 ? ['have', 'were', 'them'] : ['has', 'was', 'it'];
363
+ throw new PrvrsError('CONFIG_ERROR', `${files} in ${dirname(skillPath)} ${verb} local edits or ${past} not written by purvey. Nothing was written. Keep ${pronoun}, or re-run with --force to replace ${pronoun}.`, { path: refused[0], paths: refused, reason: 'modified' });
364
+ }
365
+ return planned;
366
+ }
367
+ const ACTION_RANK = ['overwrite', 'update', 'create', 'unchanged'];
368
+ function summarizeActions(actions) {
369
+ return ACTION_RANK.find((action) => actions.includes(action)) ?? 'unchanged';
370
+ }
371
+ function planAgentsMd(existing, block, path, force) {
372
+ if (existing === null)
373
+ return { action: 'create', content: block };
374
+ const current = findAgentsMdBlock(existing, path);
375
+ if (!current) {
376
+ const separator = existing.length === 0 ? '' : existing.endsWith('\n') ? '\n' : '\n\n';
377
+ return { action: 'append', content: `${existing}${separator}${block}` };
378
+ }
379
+ const content = existing.slice(0, current.start) + block + existing.slice(current.end);
380
+ if (content === existing)
381
+ return { action: 'unchanged', content };
382
+ if (current.unmodified)
383
+ return { action: 'update', content };
384
+ if (force)
385
+ return { action: 'overwrite', content };
386
+ return refuseOverwrite(path, 'The purvey block in AGENTS.md');
387
+ }
388
+ // ─── Claude Code and AGENTS.md ───────────────────────────────────────────────
389
+ export const CLAUDE_CODE_AGENTS_MD_DOCS = 'https://code.claude.com/docs/en/memory#agents-md';
390
+ /** Per directory, any of these makes Claude Code read CLAUDE.md files instead of AGENTS.md. */
391
+ const CLAUDE_MD_NAMES = ['CLAUDE.md', join('.claude', 'CLAUDE.md'), 'CLAUDE.local.md'];
392
+ /** Claude Code expands imports up to four hops deep. */
393
+ const MAX_IMPORT_HOPS = 4;
394
+ async function readIfFile(path) {
395
+ try {
396
+ return await readFile(path, 'utf8');
397
+ }
398
+ catch {
399
+ return null;
400
+ }
401
+ }
402
+ async function canonicalPath(path) {
403
+ try {
404
+ return await realpath(path);
405
+ }
406
+ catch {
407
+ return resolve(path);
408
+ }
409
+ }
410
+ /**
411
+ * CLAUDE.md files in `cwd` and every directory above it, nearest first. The
412
+ * user-level ~/.claude/CLAUDE.md loads alongside AGENTS.md, so it does not count.
413
+ */
414
+ async function findClaudeMdFiles(cwd, home) {
415
+ const userClaudeMd = resolve(home, '.claude', 'CLAUDE.md');
416
+ const found = [];
417
+ let dir = resolve(cwd);
418
+ for (;;) {
419
+ for (const name of CLAUDE_MD_NAMES) {
420
+ const path = join(dir, name);
421
+ if (path !== userClaudeMd && (await readIfFile(path)) !== null) {
422
+ found.push(path);
423
+ }
424
+ }
425
+ const parent = dirname(dir);
426
+ if (parent === dir)
427
+ return found;
428
+ dir = parent;
429
+ }
430
+ }
431
+ /** `@path` imports, skipping fenced blocks, code spans, and HTML comments. */
432
+ function importPaths(text, fromDir, home) {
433
+ const prose = text
434
+ .replace(/^(```|~~~)[\s\S]*?^\1/gm, '')
435
+ .replace(/<!--[\s\S]*?-->/g, '')
436
+ .replace(/`[^`\n]*`/g, '');
437
+ return [...prose.matchAll(/(?:^|\s)@((?:\\ |\S)+)/g)].map(([, raw]) => {
438
+ const path = raw.replace(/\\ /g, ' ');
439
+ return path.startsWith('~/') ? join(home, path.slice(2)) : resolve(fromDir, path);
440
+ });
441
+ }
442
+ async function importsFile(file, target, home, hops = MAX_IMPORT_HOPS, seen = new Set()) {
443
+ if (hops === 0 || seen.has(file))
444
+ return false;
445
+ seen.add(file);
446
+ const text = await readIfFile(file);
447
+ if (text === null)
448
+ return false;
449
+ for (const path of importPaths(text, dirname(file), home)) {
450
+ if ((await canonicalPath(path)) === target ||
451
+ (await importsFile(path, target, home, hops - 1, seen))) {
452
+ return true;
453
+ }
454
+ }
455
+ return false;
456
+ }
457
+ async function detectClaudeCodeVisibility(agentsMdPath, cwd, home) {
458
+ const claudeMdFiles = await findClaudeMdFiles(cwd, home);
459
+ const target = await canonicalPath(agentsMdPath);
460
+ for (const file of claudeMdFiles) {
461
+ // A CLAUDE.md symlinked to AGENTS.md loads the same content.
462
+ if ((await canonicalPath(file)) === target || (await importsFile(file, target, home))) {
463
+ return {
464
+ visibility: {
465
+ visible: true,
466
+ via: 'claude-md-import',
467
+ reason: `${file} imports AGENTS.md, so Claude Code loads the block.`,
468
+ claudeMdFiles,
469
+ },
470
+ importedBy: file,
471
+ };
472
+ }
473
+ }
474
+ if (claudeMdFiles.length === 0) {
475
+ return {
476
+ visibility: {
477
+ visible: true,
478
+ via: 'agents-md',
479
+ reason: 'No CLAUDE.md, .claude/CLAUDE.md, or CLAUDE.local.md in this directory or above it, so Claude Code v2.1.277 or later reads AGENTS.md directly.',
480
+ claudeMdFiles,
481
+ },
482
+ importedBy: null,
483
+ };
484
+ }
485
+ return {
486
+ visibility: {
487
+ visible: false,
488
+ via: null,
489
+ reason: `Claude Code reads ${claudeMdFiles.join(', ')} instead of AGENTS.md and finds no @AGENTS.md import. Re-run with --link-claude-md to add an @AGENTS.md import, or install the skill with --target claude. See ${CLAUDE_CODE_AGENTS_MD_DOCS}`,
490
+ claudeMdFiles,
491
+ },
492
+ importedBy: null,
493
+ };
494
+ }
495
+ /**
496
+ * Plan the `@AGENTS.md` import for --link-claude-md. It goes into this
497
+ * directory's CLAUDE.md (or .claude/CLAUDE.md), creating CLAUDE.md when only a
498
+ * CLAUDE.local.md or a parent directory's CLAUDE.md exists. Files above the
499
+ * project may be shared by other projects, and CLAUDE.local.md is personal, so
500
+ * neither is edited.
501
+ */
502
+ async function planClaudeMdLink(agentsMdPath, cwd, detected) {
503
+ if (detected.importedBy)
504
+ return { path: detected.importedBy, action: 'unchanged' };
505
+ if (detected.visibility.visible)
506
+ return { path: null, action: 'not-needed' };
507
+ const rootClaudeMd = join(resolve(cwd), 'CLAUDE.md');
508
+ const dotClaudeMd = join(resolve(cwd), '.claude', 'CLAUDE.md');
509
+ const files = detected.visibility.claudeMdFiles;
510
+ const path = files.includes(rootClaudeMd) || !files.includes(dotClaudeMd) ? rootClaudeMd : dotClaudeMd;
511
+ const line = `@${relative(dirname(path), agentsMdPath).split(sep).join('/')}\n`;
512
+ const existing = await readExisting(path);
513
+ if (existing === null)
514
+ return { path, action: 'create', content: line };
515
+ const separator = existing.length === 0 ? '' : existing.endsWith('\n') ? '\n' : '\n\n';
516
+ return { path, action: 'append', content: `${existing}${separator}${line}` };
517
+ }
518
+ async function writeFileAtomically(path, content) {
519
+ await mkdir(dirname(path), { recursive: true });
520
+ const tempPath = `${path}.purvey-${process.pid}.tmp`;
521
+ await writeFile(tempPath, content, 'utf8');
522
+ await rename(tempPath, path);
523
+ }
524
+ /**
525
+ * Install the generated instructions. Never touches credentials or the network.
526
+ * claude and agents write both files of the skill folder; agents-md writes one
527
+ * block. Identical content is left alone, unedited earlier output is updated,
528
+ * and anything else needs `force`. For agents-md, also reports whether Claude Code
529
+ * will load the block, and with `linkClaudeMd` makes sure it does.
530
+ */
531
+ export async function installAgentSkill(options) {
532
+ const target = parseTarget(options.target);
533
+ const scope = parseScope(target, options.scope);
534
+ if (options.linkClaudeMd && target !== 'agents-md') {
535
+ throw new PrvrsError('INVALID_ARGUMENT', '--link-claude-md applies only to --target agents-md. Claude Code loads --target claude skills directly.');
536
+ }
537
+ const path = resolveSkillInstallPath(target, scope, options);
538
+ const manifest = options.manifest ?? getCliManifest();
539
+ const force = Boolean(options.force);
540
+ const dryRun = Boolean(options.dryRun);
541
+ if (target !== 'agents-md') {
542
+ const planned = await planSkillFolder(path, options.version, manifest, force);
543
+ const files = [];
544
+ // SKILL.md goes last, so it never points to a workflows.md that failed to write.
545
+ for (const plan of [...planned].reverse()) {
546
+ const written = !dryRun && plan.action !== 'unchanged';
547
+ if (written) {
548
+ await writeFileAtomically(plan.path, plan.content);
549
+ }
550
+ files.unshift({
551
+ file: plan.file,
552
+ path: plan.path,
553
+ action: plan.action,
554
+ written,
555
+ bytes: Buffer.byteLength(plan.content, 'utf8'),
556
+ });
557
+ }
558
+ return {
559
+ target,
560
+ scope,
561
+ path,
562
+ action: summarizeActions(files.map((file) => file.action)),
563
+ written: files.some((file) => file.written),
564
+ dryRun,
565
+ cliVersion: options.version,
566
+ bytes: files.reduce((total, file) => total + file.bytes, 0),
567
+ files,
568
+ };
569
+ }
570
+ const plan = planAgentsMd(await readExisting(path), renderAgentsMdBlock(options.version, manifest), path, force);
571
+ const written = !dryRun && plan.action !== 'unchanged';
572
+ if (written) {
573
+ await writeFileAtomically(path, plan.content);
574
+ }
575
+ return {
576
+ target,
577
+ scope,
578
+ path,
579
+ action: plan.action,
580
+ written,
581
+ dryRun,
582
+ cliVersion: options.version,
583
+ bytes: Buffer.byteLength(plan.content, 'utf8'),
584
+ claudeCode: await resolveClaudeCode(path, options, dryRun),
585
+ };
586
+ }
587
+ async function resolveClaudeCode(agentsMdPath, options, dryRun) {
588
+ const cwd = options.cwd ?? process.cwd();
589
+ const detected = await detectClaudeCodeVisibility(agentsMdPath, cwd, options.home ?? homedir());
590
+ if (!options.linkClaudeMd)
591
+ return detected.visibility;
592
+ const link = await planClaudeMdLink(agentsMdPath, cwd, detected);
593
+ if (link.content === undefined) {
594
+ return {
595
+ ...detected.visibility,
596
+ link: { path: link.path, action: link.action, written: false },
597
+ };
598
+ }
599
+ if (!dryRun) {
600
+ // Write through a symlinked CLAUDE.md rather than replacing the link.
601
+ await writeFileAtomically(await canonicalPath(link.path), link.content);
602
+ }
603
+ return {
604
+ visible: true,
605
+ via: 'claude-md-import',
606
+ reason: `${link.path} ${dryRun ? 'would import' : 'now imports'} AGENTS.md, so Claude Code loads the block.`,
607
+ claudeMdFiles: detected.visibility.claudeMdFiles,
608
+ link: { path: link.path, action: link.action, written: !dryRun },
609
+ };
610
+ }
611
+ //# sourceMappingURL=agent-skill.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-skill.js","sourceRoot":"","sources":["../../src/lib/agent-skill.ts"],"names":[],"mappings":"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"}
@@ -118,5 +118,7 @@ export interface CliManifest {
118
118
  errorPatterns: CliErrorPatternContract[];
119
119
  }
120
120
  export declare function getCliManifest(): CliManifest;
121
+ /** Device-approval steps for `purvey auth login --headless`, shared by context text and the agent skill. */
122
+ export declare const HEADLESS_LOGIN_STEPS: readonly ["CLI prints a purveyors.io approval URL", "User opens it in any browser, signs in, and approves access", "CLI completes automatically; nothing is pasted back"];
121
123
  export declare function renderContextText(manifest?: CliManifest): string;
122
124
  //# sourceMappingURL=manifest.d.ts.map