@inkobytes/nexus 1.0.5 → 1.0.7

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,17 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.0.7 - 2026-06-06
4
+
5
+ - Added `nexus install-skill` to install the bundled Nexus skill into `~/.agents/skills/nexus`.
6
+ - Added `--target` and `--force` options for custom or refreshed skill installs, with a guard against broad overwrite targets.
7
+ - Updated help, zsh completion, README docs, and regression coverage for the new skill installer command.
8
+
9
+ ## 1.0.6 - 2026-06-03
10
+
11
+ - Extended Nexus protocol drift checks so `nexus doctor` now covers the bundled `skills/nexus/SKILL.md`.
12
+ - Kept Nexus repo docs aligned with the agent-native release model while scoping root `README.md` doctor repair to the actual `@inkobytes/nexus` product repo.
13
+ - Added regression coverage for Nexus-product README repair and for avoiding root README mutation in ordinary consumer repos.
14
+
3
15
  ## 1.0.5 - 2026-06-03
4
16
 
5
17
  - Reframed doctor-managed agent guides around agent-native, file-native release flow instead of human-oriented feature commit bundling.
package/README.md CHANGED
@@ -71,6 +71,7 @@ Requires Node.js 18 or newer.
71
71
 
72
72
  - Colorized `nexus help` output for easier scanning in the terminal
73
73
  - Built-in `nexus completion zsh` support for shell completions
74
+ - Bundled `nexus install-skill` support for installing the Nexus agent skill into `~/.agents/skills`
74
75
 
75
76
  See [CHANGELOG.md](./CHANGELOG.md) for the release summary.
76
77
 
@@ -240,6 +241,18 @@ source <(nexus completion zsh)
240
241
 
241
242
  This gives `zsh` tab-completion for commands like `claim`, `release`, `doctor`, `drill`, and common agent handles such as `@codex` and `@claude`.
242
243
 
244
+ ### `nexus install-skill [--target <path>] [--force]`
245
+
246
+ Install the bundled Nexus agent skill into the shared agent skill directory.
247
+
248
+ ```bash
249
+ nexus install-skill
250
+ nexus install-skill --force
251
+ nexus install-skill --target ~/.agents/skills/nexus
252
+ ```
253
+
254
+ By default, Nexus copies `skills/nexus` from the published package into `~/.agents/skills/nexus`. Restart or refresh your agent session after installing so its skill registry can discover the new `nexus` skill.
255
+
243
256
  ### `nexus ledger [--json]`
244
257
 
245
258
  Show completed task entries from `_NEXUS_LEDGER.md`.
@@ -389,11 +402,13 @@ Nexus reads tasks from `_NEXUS_QUEUE.md`:
389
402
  - Affinity: cli, diagnostics
390
403
  - Cost: small
391
404
  - Auto-flow: yes
405
+ - Review: approved
406
+ - Approved by: human
392
407
  - Notes: Add a doctor section for stale locks with tests and clear fix guidance.
393
408
  ```
394
409
 
395
410
  The queue is the executable priority surface. Standup is for comms and human context.
396
- Keep items dashboard-friendly: include `Id`, `Epic`, `Status`, `Depends on`, `Files`, `Affinity`, `Cost`, `Auto-flow`, and `Notes`. Use `Files` to expose conflict surfaces, `Depends on` for hard blockers, and `Auto-flow: no` when a task needs planning or human approval before an agent grabs it.
411
+ Keep items dashboard-friendly: include `Id`, `Epic`, `Status`, `Depends on`, `Files`, `Affinity`, `Cost`, `Auto-flow`, and `Notes`. Use `Files` to expose conflict surfaces, `Depends on` for hard blockers, and `Auto-flow: no` when a task needs planning or human approval before an agent grabs it. Auto-flow work in `Ready Queue` should also include `Review: approved` and `Approved by: human`, or `doctor` will flag it and `nexus next` may skip it.
397
412
 
398
413
  Add `Drills` when a task has known failure-mode guidance:
399
414
 
@@ -408,12 +423,13 @@ When `Drills` is absent, `nexus next` may surface obvious related drills from ta
408
423
  The agent rule of thumb:
409
424
 
410
425
  1. Run `nexus start` when entering an existing repo; it does not replace claim/release.
411
- 2. Read `USER.md` when present.
412
- 3. Read continuity and latest memory when present.
413
- 4. Read `_NEXUS_QUEUE.md` before taking follow-on work.
414
- 5. Claim before touching shared project files.
415
- 6. Release when finished.
416
- 7. Use `nexus next @Agent` instead of free-roaming.
426
+ 2. Read `_NEXUS_CONSTITUTION.md`.
427
+ 3. Read `USER.md` when present.
428
+ 4. Read continuity and latest memory when present.
429
+ 5. Read `_NEXUS_QUEUE.md` before taking follow-on work.
430
+ 6. Claim before touching shared project files.
431
+ 7. Release each claimed tracked file as soon as it reaches a coherent checkpoint.
432
+ 8. Use `nexus next @Agent` instead of free-roaming.
417
433
 
418
434
  Use model names as lock handles so ownership stays clear:
419
435
 
@@ -424,6 +440,8 @@ Use model names as lock handles so ownership stays clear:
424
440
 
425
441
  Agent-local continuity and memory files are exempt from claim/release unless the human says otherwise.
426
442
 
443
+ Nexus is agent-native and file-native, not human-native: optimize for concurrency and rollback, not feature-commit aesthetics. Do not hold claims to bundle related work into prettier feature commits; that blocks other agents waiting on files.
444
+
427
445
  When a lead agent uses subagents, tools, or parallel workers, the lead still owns the repo effects. Claim the full path scope before delegating shared-file work, give subagents the claimed path and boundaries, re-read affected files before release, and mention delegated work when it changed files, tests, or risk.
428
446
 
429
447
  Supply-chain rule: agents should not install third-party packages that have existed for less than 14 days. If package age cannot be verified, stop and ask the human. `nexus doctor` also flags install hooks and package scripts that look like they could exfiltrate data.
@@ -445,7 +463,7 @@ Avoid introducing extra startup names in scripts or narration.
445
463
 
446
464
  Nexus ships an agent skill at `skills/nexus/SKILL.md`.
447
465
 
448
- The CLI is the coordination engine. The skill is the lean playbook for this flow: `start -> claim -> release`.
466
+ The CLI is the coordination engine. The skill is the lean playbook for this flow: `start -> claim -> work -> release -> next`.
449
467
 
450
468
  ## Legacy Helper Transition
451
469
 
package/bin/nexus.js CHANGED
@@ -20,12 +20,13 @@ const COMMANDS = {
20
20
  ledger: () => import('../src/commands/ledger.js'),
21
21
  drill: () => import('../src/commands/drill.js'),
22
22
  soul: () => import('../src/commands/soul.js'),
23
+ 'install-skill': () => import('../src/commands/install-skill.js'),
23
24
  chmod: () => import('../src/commands/chmod.js'),
24
25
  db: () => import('../src/commands/db.js'),
25
26
  help: () => import('../src/commands/help.js'),
26
27
  };
27
28
 
28
- const VERSION = '1.0.1';
29
+ const VERSION = '1.0.7';
29
30
  const COLORS = createColors();
30
31
 
31
32
  const args = argv.slice(2);
@@ -76,6 +77,7 @@ function printHelp() {
76
77
  ['db <backup|list|restore|schedule>', 'Database backup and recovery'],
77
78
  ['drill <list|show|run|report>', 'Inspect or run protocol drills'],
78
79
  ['soul [--file <path>] [--status | --remove]', 'Manage local soul overlay in agent files'],
80
+ ['install-skill [--target <path>] [--force]', 'Install bundled Nexus skill into ~/.agents/skills'],
79
81
  ['help', 'Show this help'],
80
82
  ];
81
83
 
@@ -89,6 +91,7 @@ function printHelp() {
89
91
  'nexus metrics --json',
90
92
  'nexus ledger backfill',
91
93
  'nexus drill show wrong-repo-push',
94
+ 'nexus install-skill',
92
95
  'nexus claim src/lib/components/login/ @claude "Building login UI"',
93
96
  'nexus release src/lib/components/login/ "feat: login form component"',
94
97
  'nexus standup "2026-06-01 08:38 AM @codex [DONE]: Updated tests"',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inkobytes/nexus",
3
- "version": "1.0.5",
3
+ "version": "1.0.7",
4
4
  "description": "Multi-agent coordination CLI for coding agents sharing a local repository",
5
5
  "type": "module",
6
6
  "bin": {
@@ -10,24 +10,27 @@ Nexus CLI is the coordination engine. This skill is only the agent playbook.
10
10
  ## Loop
11
11
 
12
12
  1. Run `nexus start`; set `NEXUS_AGENT` for your CLI, or pass `--agent @agy|@claude|@codex|@gemini`. Start is orientation only, not permission to edit.
13
- 2. Read `USER.md` if present for local user preferences.
14
- 3. Read continuity and latest memory when present.
15
- 4. Read `_NEXUS_QUEUE.md` and `_NEXUS_STANDUP.md`.
16
- 5. Choose user-assigned work or `nexus next @Agent`; do not free-roam into `Auto-flow: no`.
17
- 6. Claim exact shared files before reading/editing:
13
+ 2. Read `_NEXUS_CONSTITUTION.md`.
14
+ 3. Read `USER.md` if present for local user preferences.
15
+ 4. Read continuity and latest memory when present.
16
+ 5. Read `_NEXUS_QUEUE.md` and `_NEXUS_STANDUP.md`.
17
+ 6. Choose user-assigned work or `nexus next @Agent`; do not free-roam into `Auto-flow: no`.
18
+ 7. Claim exact shared files before reading/editing:
18
19
 
19
20
  ```bash
20
21
  nexus claim <path> @Agent "intent"
21
22
  ```
22
23
 
23
- 7. Treat claim output as current file state. Ignore cached file memory when contents matter.
24
- 8. Work only inside the claimed surface and run focused validation.
25
- 9. If the user wants a commit, release through Nexus:
24
+ 8. Treat claim output as current file state. Ignore cached file memory when contents matter.
25
+ 9. Work only inside the claimed surface and run focused validation.
26
+ 10. Release each claimed tracked file through Nexus as soon as it reaches a coherent checkpoint:
26
27
 
27
28
  ```bash
28
29
  nexus release <path> "short commit message"
29
30
  ```
30
31
 
32
+ 11. Do not hold claims to bundle related work into a prettier feature commit. Nexus is agent-native and file-native: optimize for file availability, rollback safety, and agent throughput.
33
+
31
34
  ## Queue Items
32
35
 
33
36
  When adding work to `_NEXUS_QUEUE.md`, keep tasks dashboard-parseable and immediately actionable. Use this shape:
@@ -42,12 +45,15 @@ When adding work to `_NEXUS_QUEUE.md`, keep tasks dashboard-parseable and immedi
42
45
  - Affinity: cli, docs, dashboard
43
46
  - Cost: small
44
47
  - Auto-flow: yes
48
+ - Review: approved
49
+ - Approved by: human
45
50
  - Notes: One practical paragraph with scope, constraints, and definition of done.
46
51
  ```
47
52
 
48
53
  - `Files` should name the likely edit surface so other agents can spot conflicts before claiming.
49
54
  - `Depends on` should list hard blockers by `Id`; use `none` when the task is independent.
50
55
  - `Auto-flow: yes` means an agent can grab it after `nexus next`; use `no` when planning or human approval is needed.
56
+ - Auto-flow work in `Ready Queue` should include `Review: approved` and `Approved by: human`, or `doctor` will flag it and `nexus next` may skip it.
51
57
  - `Notes` should carry dashboard-useful context, not a whole design doc.
52
58
 
53
59
  ## Guardrails
@@ -54,6 +54,7 @@ commands=(
54
54
  'db:Database backup and recovery'
55
55
  'drill:Inspect or run protocol drills'
56
56
  'soul:Manage local soul overlay in agent files'
57
+ 'install-skill:Install bundled Nexus skill into ~/.agents/skills'
57
58
  'help:Show command help'
58
59
  )
59
60
 
@@ -116,6 +117,9 @@ case $words[2] in
116
117
  soul)
117
118
  _arguments '--file[Overlay file path]:path:_files' '--status[Show status]' '--remove[Remove overlay]'
118
119
  ;;
120
+ install-skill)
121
+ _arguments '--target[Install target]:path:_files' '--force[Refresh existing installation]'
122
+ ;;
119
123
  start)
120
124
  _arguments '--agent[Agent handle]:agent:(@agy @claude @codex @gemini)'
121
125
  ;;
@@ -352,6 +352,7 @@ export default function doctor(args) {
352
352
  const sections = {
353
353
  'Nexus Files': [],
354
354
  'Agent Instructions': [],
355
+ 'Docs & Skills': [],
355
356
  Security: [],
356
357
  'Package Privacy': [],
357
358
  'Git Privacy': [],
@@ -513,6 +514,37 @@ export default function doctor(args) {
513
514
  }
514
515
  }
515
516
 
517
+ const protocolDocs = [];
518
+ if (isNexusProductRepo(root)) {
519
+ protocolDocs.push({
520
+ path: 'README.md',
521
+ label: 'README.md',
522
+ repair: repairReadmeProtocolDoc,
523
+ });
524
+ }
525
+ protocolDocs.push({
526
+ path: 'skills/nexus/SKILL.md',
527
+ label: 'skills/nexus/SKILL.md',
528
+ repair: repairNexusSkillDoc,
529
+ });
530
+
531
+ for (const doc of protocolDocs) {
532
+ const path = join(root, doc.path);
533
+ if (!existsSync(path)) continue;
534
+ const existing = readFileSync(path, 'utf-8');
535
+ const next = doc.repair(existing);
536
+ if (next === existing) continue;
537
+ if (fix) {
538
+ writeFileSync(path, next, 'utf-8');
539
+ changes.push(`updated ${doc.label}`);
540
+ } else {
541
+ sections['Docs & Skills'].push({
542
+ issue: `${doc.label} is out of sync with current Nexus protocol wording`,
543
+ fix: 'Run `nexus doctor --fix`.',
544
+ });
545
+ }
546
+ }
547
+
516
548
  const locks = listLocks();
517
549
  const staleLocks = locks.filter((lock) => lock.age !== null && lock.age >= config.staleThreshold);
518
550
  const freshLocks = locks.filter((lock) => lock.age === null || lock.age < config.staleThreshold);
@@ -947,6 +979,140 @@ function replaceLegacyHelperCommands(content) {
947
979
  .join('\n');
948
980
  }
949
981
 
982
+ function isNexusProductRepo(root) {
983
+ const packagePath = join(root, 'package.json');
984
+ if (!existsSync(packagePath)) return false;
985
+
986
+ try {
987
+ const pkg = JSON.parse(readFileSync(packagePath, 'utf-8'));
988
+ return pkg?.name === '@inkobytes/nexus';
989
+ } catch {
990
+ return false;
991
+ }
992
+ }
993
+
994
+ function repairReadmeProtocolDoc(content) {
995
+ return content
996
+ .replace(
997
+ [
998
+ '- [ ] TASK/Codex: Add doctor stale-lock category',
999
+ ' - Id: doctor-stale-locks',
1000
+ ' - Epic: Release hygiene',
1001
+ ' - Status: Ready',
1002
+ ' - Depends on: none',
1003
+ ' - Files: src/commands/doctor.js',
1004
+ ' - Affinity: cli, diagnostics',
1005
+ ' - Cost: small',
1006
+ ' - Auto-flow: yes',
1007
+ ' - Notes: Add a doctor section for stale locks with tests and clear fix guidance.',
1008
+ ].join('\n'),
1009
+ [
1010
+ '- [ ] TASK/Codex: Add doctor stale-lock category',
1011
+ ' - Id: doctor-stale-locks',
1012
+ ' - Epic: Release hygiene',
1013
+ ' - Status: Ready',
1014
+ ' - Depends on: none',
1015
+ ' - Files: src/commands/doctor.js',
1016
+ ' - Affinity: cli, diagnostics',
1017
+ ' - Cost: small',
1018
+ ' - Auto-flow: yes',
1019
+ ' - Review: approved',
1020
+ ' - Approved by: human',
1021
+ ' - Notes: Add a doctor section for stale locks with tests and clear fix guidance.',
1022
+ ].join('\n'),
1023
+ )
1024
+ .replace(
1025
+ 'Keep items dashboard-friendly: include `Id`, `Epic`, `Status`, `Depends on`, `Files`, `Affinity`, `Cost`, `Auto-flow`, and `Notes`. Use `Files` to expose conflict surfaces, `Depends on` for hard blockers, and `Auto-flow: no` when a task needs planning or human approval before an agent grabs it.',
1026
+ 'Keep items dashboard-friendly: include `Id`, `Epic`, `Status`, `Depends on`, `Files`, `Affinity`, `Cost`, `Auto-flow`, and `Notes`. Use `Files` to expose conflict surfaces, `Depends on` for hard blockers, and `Auto-flow: no` when a task needs planning or human approval before an agent grabs it. Auto-flow work in `Ready Queue` should also include `Review: approved` and `Approved by: human`, or `doctor` will flag it and `nexus next` may skip it.',
1027
+ )
1028
+ .replace(
1029
+ [
1030
+ '1. Run `nexus start` when entering an existing repo; it does not replace claim/release.',
1031
+ '2. Read `USER.md` when present.',
1032
+ '3. Read continuity and latest memory when present.',
1033
+ '4. Read `_NEXUS_QUEUE.md` before taking follow-on work.',
1034
+ '5. Claim before touching shared project files.',
1035
+ '6. Release when finished.',
1036
+ '7. Use `nexus next @Agent` instead of free-roaming.',
1037
+ ].join('\n'),
1038
+ [
1039
+ '1. Run `nexus start` when entering an existing repo; it does not replace claim/release.',
1040
+ '2. Read `_NEXUS_CONSTITUTION.md`.',
1041
+ '3. Read `USER.md` when present.',
1042
+ '4. Read continuity and latest memory when present.',
1043
+ '5. Read `_NEXUS_QUEUE.md` before taking follow-on work.',
1044
+ '6. Claim before touching shared project files.',
1045
+ '7. Release each claimed tracked file as soon as it reaches a coherent checkpoint.',
1046
+ '8. Use `nexus next @Agent` instead of free-roaming.',
1047
+ ].join('\n'),
1048
+ )
1049
+ .replace(
1050
+ 'Agent-local continuity and memory files are exempt from claim/release unless the human says otherwise.',
1051
+ 'Agent-local continuity and memory files are exempt from claim/release unless the human says otherwise.\n\nNexus is agent-native and file-native, not human-native: optimize for concurrency and rollback, not feature-commit aesthetics. Do not hold claims to bundle related work into prettier feature commits; that blocks other agents waiting on files.',
1052
+ )
1053
+ .replace(
1054
+ 'The CLI is the coordination engine. The skill is the lean playbook for this flow: `start -> claim -> release`.',
1055
+ 'The CLI is the coordination engine. The skill is the lean playbook for this flow: `start -> claim -> work -> release -> next`.',
1056
+ );
1057
+ }
1058
+
1059
+ function repairNexusSkillDoc(content) {
1060
+ return content
1061
+ .replace(
1062
+ [
1063
+ '1. Run `nexus start`; set `NEXUS_AGENT` for your CLI, or pass `--agent @agy|@claude|@codex|@gemini`. Start is orientation only, not permission to edit.',
1064
+ '2. Read `USER.md` if present for local user preferences.',
1065
+ '3. Read continuity and latest memory when present.',
1066
+ '4. Read `_NEXUS_QUEUE.md` and `_NEXUS_STANDUP.md`.',
1067
+ '5. Choose user-assigned work or `nexus next @Agent`; do not free-roam into `Auto-flow: no`.',
1068
+ '6. Claim exact shared files before reading/editing:',
1069
+ ].join('\n'),
1070
+ [
1071
+ '1. Run `nexus start`; set `NEXUS_AGENT` for your CLI, or pass `--agent @agy|@claude|@codex|@gemini`. Start is orientation only, not permission to edit.',
1072
+ '2. Read `_NEXUS_CONSTITUTION.md`.',
1073
+ '3. Read `USER.md` if present for local user preferences.',
1074
+ '4. Read continuity and latest memory when present.',
1075
+ '5. Read `_NEXUS_QUEUE.md` and `_NEXUS_STANDUP.md`.',
1076
+ '6. Choose user-assigned work or `nexus next @Agent`; do not free-roam into `Auto-flow: no`.',
1077
+ '7. Claim exact shared files before reading/editing:',
1078
+ ].join('\n'),
1079
+ )
1080
+ .replace(
1081
+ [
1082
+ '7. Treat claim output as current file state. Ignore cached file memory when contents matter.',
1083
+ '8. Work only inside the claimed surface and run focused validation.',
1084
+ '9. If the user wants a commit, release through Nexus:',
1085
+ ].join('\n'),
1086
+ [
1087
+ '8. Treat claim output as current file state. Ignore cached file memory when contents matter.',
1088
+ '9. Work only inside the claimed surface and run focused validation.',
1089
+ '10. Release each claimed tracked file through Nexus as soon as it reaches a coherent checkpoint:',
1090
+ ].join('\n'),
1091
+ )
1092
+ .replace(
1093
+ '```\\n\\n## Queue Items',
1094
+ '```\\n\\n11. Do not hold claims to bundle related work into a prettier feature commit. Nexus is agent-native and file-native: optimize for file availability, rollback safety, and agent throughput.\\n\\n## Queue Items',
1095
+ )
1096
+ .replace(
1097
+ [
1098
+ ' - Cost: small',
1099
+ ' - Auto-flow: yes',
1100
+ ' - Notes: One practical paragraph with scope, constraints, and definition of done.',
1101
+ ].join('\n'),
1102
+ [
1103
+ ' - Cost: small',
1104
+ ' - Auto-flow: yes',
1105
+ ' - Review: approved',
1106
+ ' - Approved by: human',
1107
+ ' - Notes: One practical paragraph with scope, constraints, and definition of done.',
1108
+ ].join('\n'),
1109
+ )
1110
+ .replace(
1111
+ '- `Auto-flow: yes` means an agent can grab it after `nexus next`; use `no` when planning or human approval is needed.\n- `Notes` should carry dashboard-useful context, not a whole design doc.',
1112
+ '- `Auto-flow: yes` means an agent can grab it after `nexus next`; use `no` when planning or human approval is needed.\n- Auto-flow work in `Ready Queue` should include `Review: approved` and `Approved by: human`, or `doctor` will flag it and `nexus next` may skip it.\n- `Notes` should carry dashboard-useful context, not a whole design doc.',
1113
+ );
1114
+ }
1115
+
950
1116
  const SUSPICIOUS_SCRIPT_PATTERNS = [
951
1117
  { pattern: /\b(curl|wget)\b/i, label: 'network download command' },
952
1118
  { pattern: /\b(nc|netcat|ncat|socat)\b/i, label: 'raw network transfer command' },
@@ -0,0 +1,83 @@
1
+ /**
2
+ * nexus install-skill - install the bundled Nexus agent skill
3
+ */
4
+
5
+ import { cpSync, existsSync, mkdirSync, rmSync } from 'fs';
6
+ import { basename, dirname, parse, resolve } from 'path';
7
+ import { fileURLToPath } from 'url';
8
+ import { homedir } from 'os';
9
+
10
+ const COMMAND_USAGE = 'Usage: nexus install-skill [--target <path>] [--force]';
11
+ const DEFAULT_TARGET = '~/.agents/skills/nexus';
12
+
13
+ function parseArgs(args) {
14
+ let target = DEFAULT_TARGET;
15
+ let force = false;
16
+
17
+ for (let index = 0; index < args.length; index += 1) {
18
+ const arg = args[index];
19
+ if (arg === '--force') {
20
+ force = true;
21
+ continue;
22
+ }
23
+
24
+ if (arg === '--target') {
25
+ const value = args[index + 1];
26
+ if (!value || value.startsWith('--')) throw new Error(COMMAND_USAGE);
27
+ target = value;
28
+ index += 1;
29
+ continue;
30
+ }
31
+
32
+ throw new Error(COMMAND_USAGE);
33
+ }
34
+
35
+ return { target, force };
36
+ }
37
+
38
+ function expandHome(path) {
39
+ if (path === '~') return homedir();
40
+ if (path.startsWith('~/')) return resolve(homedir(), path.slice(2));
41
+ return resolve(path);
42
+ }
43
+
44
+ function packageRoot() {
45
+ return resolve(dirname(fileURLToPath(import.meta.url)), '..', '..');
46
+ }
47
+
48
+ function assertSafeSkillTarget(destination) {
49
+ if (basename(destination) !== 'nexus') {
50
+ throw new Error('Install target must be the Nexus skill directory, for example ~/.agents/skills/nexus.');
51
+ }
52
+
53
+ if (destination === parse(destination).root || destination === homedir()) {
54
+ throw new Error('Install target is too broad.');
55
+ }
56
+ }
57
+
58
+ export default function installSkill(args) {
59
+ const { target, force } = parseArgs(args);
60
+ const source = resolve(packageRoot(), 'skills', 'nexus');
61
+ const destination = expandHome(target);
62
+
63
+ if (!existsSync(source)) {
64
+ throw new Error(`Bundled Nexus skill not found: ${source}`);
65
+ }
66
+
67
+ assertSafeSkillTarget(destination);
68
+
69
+ if (existsSync(destination)) {
70
+ if (!force) {
71
+ console.log(`Nexus skill already installed at ${destination}`);
72
+ console.log('Run `nexus install-skill --force` to refresh it.');
73
+ return;
74
+ }
75
+ rmSync(destination, { recursive: true, force: true });
76
+ }
77
+
78
+ mkdirSync(dirname(destination), { recursive: true });
79
+ cpSync(source, destination, { recursive: true });
80
+
81
+ console.log(`Installed Nexus skill to ${destination}`);
82
+ console.log('Restart or refresh your agent session so the skill registry can pick it up.');
83
+ }