@thesmurph/agentlink 0.1.0 → 0.1.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,14 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.1.1
4
+
5
+ - `list` shows what is linked rather than only what is installed. A `✓` means
6
+ agentlink is linking that harness; a trailing note appears when a harness is
7
+ installed but not linked, or linked but not installed. `list --json` gains
8
+ `selected` and a top-level `linked` array.
9
+ - Fixed: `list` printed one mark for two different facts, so a deselected
10
+ harness looked selected. The selection itself was always saved correctly.
11
+
3
12
  ## 0.1.0
4
13
 
5
14
  First release.
package/README.md CHANGED
@@ -32,7 +32,7 @@ agentlink init create AGENTS.md + .agents/skills, migrate, link
32
32
  agentlink sync re-link after adding or moving a skill
33
33
  agentlink fix fold stray real copies into .agents, then link
34
34
  agentlink select change which harnesses are linked
35
- agentlink list every harness, where it reads from, whether it is installed
35
+ agentlink list what is linked, where each harness reads from, what is installed
36
36
  agentlink doctor drift, duplicates, invalid skills, broken links
37
37
  agentlink adopt move an existing CLAUDE.md or GEMINI.md into AGENTS.md
38
38
  agentlink unlink remove the links agentlink created
package/dist/cli.js CHANGED
@@ -326,9 +326,12 @@ async function syncLinks(paths, chosen, options, context) {
326
326
  process.exit(1);
327
327
  }
328
328
  async function runList(paths, options) {
329
+ const state = readState(paths);
330
+ const selected = new Set(state.harnesses);
329
331
  const rows = detectAll().map(({ harness, installed, reasons }) => ({
330
332
  id: harness.id,
331
333
  label: harness.label,
334
+ selected: selected.has(harness.id),
332
335
  installed,
333
336
  reasons,
334
337
  instructions: describe(harness.instructions[paths.scope]),
@@ -338,18 +341,26 @@ async function runList(paths, options) {
338
341
  source: harness.source,
339
342
  }));
340
343
  if (options.json) {
341
- process.stdout.write(`${JSON.stringify({ scope: paths.scope, harnesses: rows }, null, 2)}\n`);
344
+ process.stdout.write(`${JSON.stringify({ scope: paths.scope, root: paths.root, linked: [...selected], harnesses: rows }, null, 2)}\n`);
342
345
  return;
343
346
  }
344
347
  const width = Math.max(...rows.map((row) => row.label.length));
345
- process.stdout.write(`\n${BOLD}harnesses${RESET} ${DIM}· scope: ${paths.scope}${RESET}\n\n`);
348
+ const installedCount = rows.filter((row) => row.installed).length;
349
+ process.stdout.write(`\n${BOLD}harnesses${RESET} ${DIM}· scope: ${paths.scope} · ${selected.size} linked · ${installedCount} installed here${RESET}\n\n`);
346
350
  for (const row of rows) {
347
- const mark = row.installed ? `${GREEN}●${RESET}` : `${DIM}○${RESET}`;
351
+ // The leading mark is the tool's own state: what is actually linked.
352
+ // Availability is only called out when it is surprising.
353
+ const mark = row.selected ? `${GREEN}✓${RESET}` : `${DIM}·${RESET}`;
354
+ const note = row.selected && !row.installed
355
+ ? ` ${YELLOW}selected, not installed${RESET}`
356
+ : !row.selected && row.installed
357
+ ? ` ${DIM}installed, not linked${RESET}`
358
+ : "";
348
359
  const flag = !row.instructionsVerified || !row.skillsVerified ? ` ${YELLOW}unverified${RESET}` : "";
349
- process.stdout.write(` ${mark} ${row.label.padEnd(width)} ${DIM}instructions${RESET} ${row.instructions} ${DIM}skills${RESET} ${row.skills}${flag}\n`);
360
+ process.stdout.write(` ${mark} ${row.label.padEnd(width)} ${DIM}instructions${RESET} ${row.instructions} ${DIM}skills${RESET} ${row.skills}${flag}${note}\n`);
350
361
  }
351
- process.stdout.write(`\n ${GREEN}●${RESET} present on this machine ${DIM}native = harness reads AGENTS.md / .agents/skills itself${RESET}\n` +
352
- ` ${DIM}agentlink list --json prints the source URL for every row${RESET}\n`);
362
+ process.stdout.write(`\n ${GREEN}✓${RESET} linked ${DIM}·${RESET} not linked ${DIM}change with \`agentlink select\`${RESET}\n` +
363
+ ` ${DIM}native = harness reads AGENTS.md / .agents/skills itself; list --json prints the source URL for every row${RESET}\n`);
353
364
  }
354
365
  function describe(endpoint) {
355
366
  if (endpoint.native)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thesmurph/agentlink",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "One source of truth for agent instructions and skills, symlinked into every coding-agent harness.",
5
5
  "keywords": [
6
6
  "agents.md",
package/src/cli.ts CHANGED
@@ -388,9 +388,12 @@ async function syncLinks(
388
388
  }
389
389
 
390
390
  async function runList(paths: ScopePaths, options: Options): Promise<void> {
391
+ const state = readState(paths);
392
+ const selected = new Set(state.harnesses);
391
393
  const rows = detectAll().map(({ harness, installed, reasons }) => ({
392
394
  id: harness.id,
393
395
  label: harness.label,
396
+ selected: selected.has(harness.id),
394
397
  installed,
395
398
  reasons,
396
399
  instructions: describe(harness.instructions[paths.scope]),
@@ -401,25 +404,35 @@ async function runList(paths: ScopePaths, options: Options): Promise<void> {
401
404
  }));
402
405
 
403
406
  if (options.json) {
404
- process.stdout.write(`${JSON.stringify({ scope: paths.scope, harnesses: rows }, null, 2)}\n`);
407
+ process.stdout.write(
408
+ `${JSON.stringify({ scope: paths.scope, root: paths.root, linked: [...selected], harnesses: rows }, null, 2)}\n`,
409
+ );
405
410
  return;
406
411
  }
407
412
 
408
413
  const width = Math.max(...rows.map((row) => row.label.length));
414
+ const installedCount = rows.filter((row) => row.installed).length;
409
415
  process.stdout.write(
410
- `\n${BOLD}harnesses${RESET} ${DIM}· scope: ${paths.scope}${RESET}\n\n`,
416
+ `\n${BOLD}harnesses${RESET} ${DIM}· scope: ${paths.scope} · ${selected.size} linked · ${installedCount} installed here${RESET}\n\n`,
411
417
  );
412
418
  for (const row of rows) {
413
- const mark = row.installed ? `${GREEN}●${RESET}` : `${DIM}○${RESET}`;
414
- const flag =
415
- !row.instructionsVerified || !row.skillsVerified ? ` ${YELLOW}unverified${RESET}` : "";
419
+ // The leading mark is the tool's own state: what is actually linked.
420
+ // Availability is only called out when it is surprising.
421
+ const mark = row.selected ? `${GREEN}✓${RESET}` : `${DIM}·${RESET}`;
422
+ const note =
423
+ row.selected && !row.installed
424
+ ? ` ${YELLOW}selected, not installed${RESET}`
425
+ : !row.selected && row.installed
426
+ ? ` ${DIM}installed, not linked${RESET}`
427
+ : "";
428
+ const flag = !row.instructionsVerified || !row.skillsVerified ? ` ${YELLOW}unverified${RESET}` : "";
416
429
  process.stdout.write(
417
- ` ${mark} ${row.label.padEnd(width)} ${DIM}instructions${RESET} ${row.instructions} ${DIM}skills${RESET} ${row.skills}${flag}\n`,
430
+ ` ${mark} ${row.label.padEnd(width)} ${DIM}instructions${RESET} ${row.instructions} ${DIM}skills${RESET} ${row.skills}${flag}${note}\n`,
418
431
  );
419
432
  }
420
433
  process.stdout.write(
421
- `\n ${GREEN}●${RESET} present on this machine ${DIM}native = harness reads AGENTS.md / .agents/skills itself${RESET}\n` +
422
- ` ${DIM}agentlink list --json prints the source URL for every row${RESET}\n`,
434
+ `\n ${GREEN}✓${RESET} linked ${DIM}·${RESET} not linked ${DIM}change with \`agentlink select\`${RESET}\n` +
435
+ ` ${DIM}native = harness reads AGENTS.md / .agents/skills itself; list --json prints the source URL for every row${RESET}\n`,
423
436
  );
424
437
  }
425
438