kushi-agents 5.0.0 → 5.0.2

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 (54) hide show
  1. package/README.md +30 -7
  2. package/bin/cli.mjs +73 -45
  3. package/package.json +51 -51
  4. package/plugin/instructions/agentskills-compliance.instructions.md +144 -0
  5. package/plugin/instructions/multi-host-install.instructions.md +125 -0
  6. package/plugin/instructions/plan-validate-execute.instructions.md +75 -0
  7. package/plugin/instructions/release-genealogy.instructions.md +52 -0
  8. package/plugin/skills/aggregate-project/SKILL.md +11 -2
  9. package/plugin/skills/apply-ado-update/SKILL.md +11 -2
  10. package/plugin/skills/ask-project/SKILL.md +1 -1
  11. package/plugin/skills/bootstrap-project/SKILL.md +39 -127
  12. package/plugin/skills/bootstrap-project/references/discovery-sweep.md +40 -0
  13. package/plugin/skills/bootstrap-project/references/pull-dispatch.md +50 -0
  14. package/plugin/skills/bootstrap-project/references/registry-persistence.md +55 -0
  15. package/plugin/skills/build-state/SKILL.md +50 -2
  16. package/plugin/skills/consolidate-evidence/SKILL.md +11 -2
  17. package/plugin/skills/dashboard/SKILL.md +20 -1
  18. package/plugin/skills/emit-vertex/SKILL.md +10 -1
  19. package/plugin/skills/fde-intake/SKILL.md +10 -1
  20. package/plugin/skills/fde-report/SKILL.md +10 -1
  21. package/plugin/skills/fde-triage/SKILL.md +10 -1
  22. package/plugin/skills/intro/SKILL.md +1 -1
  23. package/plugin/skills/link-entities/SKILL.md +43 -1
  24. package/plugin/skills/project-status/SKILL.md +1 -1
  25. package/plugin/skills/propose-ado-update/SKILL.md +11 -2
  26. package/plugin/skills/pull-ado/SKILL.md +26 -9
  27. package/plugin/skills/pull-crm/SKILL.md +39 -125
  28. package/plugin/skills/pull-crm/references/dataverse-doctrine.md +108 -0
  29. package/plugin/skills/pull-crm/references/legacy-shape.md +28 -0
  30. package/plugin/skills/pull-email/SKILL.md +33 -79
  31. package/plugin/skills/pull-email/references/retrieval-order.md +43 -0
  32. package/plugin/skills/pull-email/references/two-pass-pull.md +41 -0
  33. package/plugin/skills/pull-loop/SKILL.md +194 -177
  34. package/plugin/skills/pull-meetings/SKILL.md +35 -72
  35. package/plugin/skills/pull-meetings/references/legacy-stream.md +15 -0
  36. package/plugin/skills/pull-meetings/references/verbatim-capture.md +61 -0
  37. package/plugin/skills/pull-misc/SKILL.md +24 -7
  38. package/plugin/skills/pull-onenote/SKILL.md +207 -555
  39. package/plugin/skills/pull-onenote/references/playwright-fallback.md +111 -0
  40. package/plugin/skills/pull-onenote/references/preflight.md +85 -0
  41. package/plugin/skills/pull-onenote/references/runtime-contract.md +118 -0
  42. package/plugin/skills/pull-sharepoint/SKILL.md +26 -9
  43. package/plugin/skills/pull-teams/SKILL.md +26 -9
  44. package/plugin/skills/refresh-project/SKILL.md +24 -2
  45. package/plugin/skills/self-check/SKILL.md +9 -1
  46. package/plugin/skills/self-check/run.ps1 +216 -4
  47. package/plugin/skills/setup/SKILL.md +14 -120
  48. package/plugin/skills/setup/references/onedrive-pin-sync.md +60 -0
  49. package/plugin/skills/setup/references/recovery-prompts.md +81 -0
  50. package/plugin/skills/tour/SKILL.md +18 -1
  51. package/plugin/skills/vertex-link/SKILL.md +1 -1
  52. package/src/constants.mjs +39 -1
  53. package/src/multi-host-install.test.mjs +170 -0
  54. package/src/multi-host.mjs +277 -0
package/README.md CHANGED
@@ -5,6 +5,11 @@
5
5
  [![license](https://img.shields.io/npm/l/kushi-agents.svg)](LICENSE)
6
6
  [![host: Clawpilot](https://img.shields.io/badge/host-Clawpilot-7c9cff)](https://gim-home.github.io/kushi/)
7
7
  [![host: VS Code](https://img.shields.io/badge/host-VS%20Code-007acc)](https://gim-home.github.io/kushi/)
8
+ [![spec: agentskills.io](https://img.shields.io/badge/spec-agentskills.io-22c55e)](https://agentskills.io/skill-creation/best-practices)
9
+
10
+ > **v5.0.1 spec-compliance pass.** Every `plugin/skills/<name>/SKILL.md` follows the [agentskills.io best practices](https://agentskills.io/skill-creation/best-practices) and [optimizing-descriptions](https://agentskills.io/skill-creation/optimizing-descriptions) guides: ≤ 500 lines & ≤ 5000 tokens, load-on-trigger references, top-5 gotchas, checklist orchestrators, validation loops, plan-validate-execute for graph + State writers, and "USE WHEN …" descriptions. Enforced by `self-check -Deep` D30.*.
11
+
12
+ > **Project lineage:** for the *why* behind each release — what built on what, what trade-offs were accepted, what external work inspired which design — see [`docs/genealogy.md`](docs/genealogy.md). Every release MUST add an entry there before tagging (enforced by `self-check` D31.genealogy).
8
13
 
9
14
  > A multi-skill GitHub Copilot agent for grounded engagement evidence — across Email, Teams, Meetings, OneNote, SharePoint, Dataverse (CRM), and Azure DevOps.
10
15
 
@@ -116,20 +121,38 @@ See [Quickstart](https://gim-home.github.io/kushi/getting-started/quickstart/) f
116
121
 
117
122
  ## Install
118
123
 
119
- Two install targets pick the one that matches how you talk to Copilot, optionally combined with a profile.
124
+ Kushi supports **two host surfaces** as first-class peers (v5.0.2+):
120
125
 
121
- **VS Code Chat** `.kushi/` in your workspace:
126
+ | Host | Install path | Best for |
127
+ |---------------------------------------|------------------------------------|-----------------------------------------|
128
+ | **Clawpilot CLI** | `~/.copilot/m-skills/kushi/` | Scheduled / overnight runs (e.g. `kushi refresh <project>` at 6 AM via automation) |
129
+ | **VS Code Chat** ("GitHub Copilot Chat") | `~/.vscode/chat/skills/kushi/` | Interactive use (`@kushi what's the MACC for X?`) |
130
+
131
+ Both hosts read the **same** Evidence/ tree on disk, so a refresh from one is immediately visible from the other — the same user routinely lives in both. SKILL content is host-agnostic (no per-host branching, enforced by self-check `D32.multi-host`).
122
132
 
123
133
  ```bash
124
- npx kushi-agents # default profile (standard)
125
- npx kushi-agents --profile core # aggregator only
134
+ # Install to a single host
135
+ npx kushi-agents --clawpilot # Clawpilot only
136
+ npx kushi-agents --vscode # VS Code Chat only
137
+
138
+ # Install to BOTH at once (auto-detects what's present + targets both)
139
+ npx kushi-agents --all-hosts
140
+
141
+ # Uninstall
142
+ npx kushi-agents --uninstall # all detected hosts
143
+ npx kushi-agents --uninstall --clawpilot # Clawpilot only
144
+ npx kushi-agents --uninstall --vscode # VS Code Chat only
145
+ npx kushi-agents --uninstall --all # both
146
+
147
+ # Legacy workspace install (per-project .kushi/ in cwd)
148
+ npx kushi-agents # default = standard profile
149
+ npx kushi-agents --profile core # aggregator only
126
150
  ```
127
151
 
128
- **Clawpilot CLI**`~/.copilot/m-skills/kushi/`:
152
+ The 2-host matrix is a deliberate cap see [`plugin/instructions/multi-host-install.instructions.md`](plugin/instructions/multi-host-install.instructions.md) for the rationale + per-host layout details.
129
153
 
130
154
  ```bash
131
- npx kushi-agents --clawpilot
132
- npx kushi-agents --clawpilot --profile full
155
+ npx kushi-agents --clawpilot --profile full # everything
133
156
  ```
134
157
 
135
158
  To switch profiles later, re-run with `--force` (cleanly handles downgrades):
package/bin/cli.mjs CHANGED
@@ -1,6 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  import { main } from '../src/main.mjs';
4
+ import { runMultiHost } from '../src/multi-host.mjs';
4
5
 
5
6
  const args = process.argv.slice(2);
6
7
 
@@ -10,72 +11,99 @@ if (args.includes('--help') || args.includes('-h')) {
10
11
 
11
12
  Installs the Kushi multi-source project-evidence + Q&A agent.
12
13
 
13
- Targets (pick one default is vscode):
14
- --target vscode Install to <cwd>/.kushi/ + update .vscode/settings.json
15
- --target clawpilot Install to ~/.copilot/m-skills/kushi/ for Clawpilot CLI
16
- --clawpilot Shortcut for --target clawpilot
14
+ Host installs (v5.0.2+install into a host's user-global skill folder):
15
+ --clawpilot Install to ~/.copilot/m-skills/kushi/
16
+ --vscode Install to ~/.vscode/chat/skills/kushi/ (a.k.a. GitHub Copilot Chat)
17
+ --all-hosts Install to BOTH hosts
18
+ --uninstall [--clawpilot|--vscode|--all]
19
+ Cleanly remove the kushi install + skills-metadata.json entry
20
+ from the chosen host(s). Default = all detected hosts.
21
+
22
+ Workspace install (legacy / default when no host flag is given):
23
+ --target vscode Install to <cwd>/.kushi/ + update .vscode/settings.json [default]
24
+ --target clawpilot Alias for --clawpilot (kept for back-compat)
17
25
 
18
26
  Profile (controls what gets installed):
19
- --profile core Aggregator only (pull + consolidate + ask). The
20
- Evidence/ folder is the public contract; suitable for
21
- external rollup integrations.
22
- --profile standard Core + State/ rollup (Kushi's default opinion). [DEFAULT]
23
- --profile full Standard + report packs (FDE weekly/customer/handoff).
27
+ --profile core Aggregator only (pull + consolidate + ask).
28
+ --profile standard Core + State/ rollup. [DEFAULT]
29
+ --profile full Standard + report packs.
24
30
 
25
31
  Options:
26
32
  --force Overwrite existing destination without asking
27
- --yes, -y Skip the project-root check (useful for scripted or
28
- agent-driven installs)
29
- --no-settings Skip .vscode/settings.json update (vscode target only)
30
- --no-instructions Skip .github/copilot-instructions.md merge (vscode target only)
33
+ --yes, -y Skip the project-root check
34
+ --no-settings Skip .vscode/settings.json update (vscode workspace target only)
35
+ --no-instructions Skip .github/copilot-instructions.md merge (vscode workspace target only)
31
36
 
32
37
  WorkIQ (REQUIRED — Kushi cannot pull evidence without it):
33
38
  --with-workiq Auto-install WorkIQ via winget (Windows) / brew (macOS)
34
39
  --workiq-path <abs> Use this explicit path to the workiq binary
35
- --skip-workiq-check Bypass the WorkIQ pre-flight check (CI / inspection only —
36
- bootstrap/refresh will block until WorkIQ is installed)
40
+ --skip-workiq-check Bypass the WorkIQ pre-flight check
37
41
 
38
42
  --help, -h Show this help
39
43
 
40
44
  After install, talk to Kushi:
41
- aggregate <project> Pull + consolidate (no State/) — all profiles
42
- bootstrap <project> First-time setup, 30d initial pull — standard+
43
- refresh <project> Incremental refresh + rebuild State/ — standard+
44
- state <project> Re-render State/ from existing Evidence — standard+
45
- consolidate <project> Merge per-user evidence — all profiles
46
- status <project> Show run-log — all profiles
47
- ask <project> <q> Cited Q&A over Evidence/ (auto-routes) — all profiles
45
+ bootstrap <project> First-time setup
46
+ refresh <project> Incremental refresh + rebuild State/
47
+ state <project> Re-render State/ from existing Evidence
48
+ consolidate <project> Merge per-user evidence
49
+ status <project> Show run-log
50
+ ask <project> <q> Cited Q&A over Evidence/ (auto-routes)
48
51
 
49
52
  In VS Code Chat the prefix is "@Kushi". In Clawpilot just say "kushi <verb>".
50
53
  `);
51
54
  process.exit(0);
52
55
  }
53
56
 
54
- let target = getFlag('--target');
55
- if (args.includes('--clawpilot')) {
56
- if (target && target !== 'clawpilot') {
57
- console.error(`\n Conflicting flags: --target ${target} and --clawpilot.\n`);
57
+ // ── multi-host mode (v5.0.2+) ───────────────────────────────────────────────
58
+ // Trigger when the user passes any of: --vscode, --all-hosts, --uninstall.
59
+ // --clawpilot ALONE continues to route through the legacy main.mjs path so
60
+ // the existing target=clawpilot flow stays byte-identical.
61
+ const wantsVscode = args.includes('--vscode');
62
+ const wantsAllHosts = args.includes('--all-hosts');
63
+ const wantsUninstall = args.includes('--uninstall');
64
+
65
+ if (wantsVscode || wantsAllHosts || wantsUninstall) {
66
+ const hosts = [];
67
+ if (args.includes('--clawpilot')) hosts.push('clawpilot');
68
+ if (wantsVscode) hosts.push('vscode');
69
+ const all = wantsAllHosts || args.includes('--all');
70
+
71
+ runMultiHost({
72
+ hosts,
73
+ all,
74
+ uninstall: wantsUninstall,
75
+ profile: getFlag('--profile'),
76
+ }).catch((err) => {
77
+ console.error(`\n ${err.message}\n`);
58
78
  process.exit(1);
79
+ });
80
+ } else {
81
+ let target = getFlag('--target');
82
+ if (args.includes('--clawpilot')) {
83
+ if (target && target !== 'clawpilot') {
84
+ console.error(`\n Conflicting flags: --target ${target} and --clawpilot.\n`);
85
+ process.exit(1);
86
+ }
87
+ target = 'clawpilot';
59
88
  }
60
- target = 'clawpilot';
61
- }
62
89
 
63
- const options = {
64
- force: args.includes('--force'),
65
- yes: args.includes('--yes') || args.includes('-y'),
66
- noSettings: args.includes('--no-settings'),
67
- noInstructions: args.includes('--no-instructions'),
68
- target,
69
- profile: getFlag('--profile'),
70
- withWorkiq: args.includes('--with-workiq'),
71
- workiqPath: getFlag('--workiq-path'),
72
- skipWorkiqCheck: args.includes('--skip-workiq-check'),
73
- };
74
-
75
- main(options).catch((err) => {
76
- console.error(`\n ${err.message}\n`);
77
- process.exit(1);
78
- });
90
+ const options = {
91
+ force: args.includes('--force'),
92
+ yes: args.includes('--yes') || args.includes('-y'),
93
+ noSettings: args.includes('--no-settings'),
94
+ noInstructions: args.includes('--no-instructions'),
95
+ target,
96
+ profile: getFlag('--profile'),
97
+ withWorkiq: args.includes('--with-workiq'),
98
+ workiqPath: getFlag('--workiq-path'),
99
+ skipWorkiqCheck: args.includes('--skip-workiq-check'),
100
+ };
101
+
102
+ main(options).catch((err) => {
103
+ console.error(`\n ${err.message}\n`);
104
+ process.exit(1);
105
+ });
106
+ }
79
107
 
80
108
  function getFlag(flag) {
81
109
  const idx = args.indexOf(flag);
@@ -85,4 +113,4 @@ function getFlag(flag) {
85
113
  const prefix = flag + '=';
86
114
  const match = args.find((a) => a.startsWith(prefix));
87
115
  return match ? match.slice(prefix.length) : undefined;
88
- }
116
+ }
package/package.json CHANGED
@@ -1,52 +1,52 @@
1
- {
2
- "name": "kushi-agents",
3
- "version": "5.0.0",
4
- "description": "Install Kushi — multi-source project evidence agent with Comprehensive Structured Capture (CSC) into weekly-only files across Email, Teams, OneNote, Loop, SharePoint, Meetings, CRM, ADO. Meetings retain a sibling verbatim/ audit folder. WorkIQ-only for M365 sources (Graph / m365_* FORBIDDEN as fallbacks; user-paste is first-class). Host-agnostic.",
5
- "type": "module",
6
- "bin": {
7
- "kushi-agents": "./bin/cli.mjs"
8
- },
9
- "files": [
10
- "bin/",
11
- "src/",
12
- "plugin/",
13
- ".github/copilot-instructions.kushi.md"
14
- ],
15
- "engines": {
16
- "node": ">=18.0.0"
17
- },
18
- "dependencies": {
19
- "@mozilla/readability": "^0.6.0",
20
- "jsdom": "^29.1.1",
21
- "jsonc-parser": "^3.3.1"
22
- },
23
- "keywords": [
24
- "vscode",
25
- "copilot",
26
- "agents",
27
- "kushi",
28
- "project-evidence",
29
- "workiq",
30
- "m365",
31
- "ai",
32
- "cli"
33
- ],
34
- "repository": {
35
- "type": "git",
36
- "url": "git+https://github.com/gim-home/kushi.git"
37
- },
38
- "homepage": "https://gim-home.github.io/kushi/",
39
- "bugs": {
40
- "url": "https://github.com/gim-home/kushi/issues"
41
- },
42
- "license": "MIT",
43
- "scripts": {
44
- "test": "node --test src/check-workiq.test.mjs src/seed-config.test.mjs src/sanitize-workiq-input.test.mjs src/detect-vertex-repo.test.mjs src/vertex-validate.test.mjs src/emit-vertex.e2e.test.mjs src/config-root-resolve.test.mjs src/forbidden-workiq-phrasings.test.mjs",
45
- "test:integration:bootstrap": "node src/bootstrap-dryrun.integration.test.mjs",
46
- "smoke": "node scripts/smoke.mjs",
47
- "prepublishOnly": "npm test && npm run smoke"
48
- },
49
- "publishConfig": {
50
- "access": "public"
51
- }
1
+ {
2
+ "name": "kushi-agents",
3
+ "version": "5.0.2",
4
+ "description": "Install Kushi — multi-source project evidence agent with Comprehensive Structured Capture (CSC) into weekly-only files across Email, Teams, OneNote, Loop, SharePoint, Meetings, CRM, ADO. Meetings retain a sibling verbatim/ audit folder. WorkIQ-only for M365 sources (Graph / m365_* FORBIDDEN as fallbacks; user-paste is first-class). Host-agnostic.",
5
+ "type": "module",
6
+ "bin": {
7
+ "kushi-agents": "./bin/cli.mjs"
8
+ },
9
+ "files": [
10
+ "bin/",
11
+ "src/",
12
+ "plugin/",
13
+ ".github/copilot-instructions.kushi.md"
14
+ ],
15
+ "engines": {
16
+ "node": ">=18.0.0"
17
+ },
18
+ "dependencies": {
19
+ "@mozilla/readability": "^0.6.0",
20
+ "jsdom": "^29.1.1",
21
+ "jsonc-parser": "^3.3.1"
22
+ },
23
+ "keywords": [
24
+ "vscode",
25
+ "copilot",
26
+ "agents",
27
+ "kushi",
28
+ "project-evidence",
29
+ "workiq",
30
+ "m365",
31
+ "ai",
32
+ "cli"
33
+ ],
34
+ "repository": {
35
+ "type": "git",
36
+ "url": "git+https://github.com/gim-home/kushi.git"
37
+ },
38
+ "homepage": "https://gim-home.github.io/kushi/",
39
+ "bugs": {
40
+ "url": "https://github.com/gim-home/kushi/issues"
41
+ },
42
+ "license": "MIT",
43
+ "scripts": {
44
+ "test": "node --test src/check-workiq.test.mjs src/seed-config.test.mjs src/sanitize-workiq-input.test.mjs src/detect-vertex-repo.test.mjs src/vertex-validate.test.mjs src/emit-vertex.e2e.test.mjs src/config-root-resolve.test.mjs src/forbidden-workiq-phrasings.test.mjs src/multi-host-install.test.mjs",
45
+ "test:integration:bootstrap": "node src/bootstrap-dryrun.integration.test.mjs",
46
+ "smoke": "node scripts/smoke.mjs",
47
+ "prepublishOnly": "npm test && npm run smoke"
48
+ },
49
+ "publishConfig": {
50
+ "access": "public"
51
+ }
52
52
  }
@@ -0,0 +1,144 @@
1
+ ---
2
+ name: "agentskills-compliance"
3
+ description: "Spec-compliance doctrine. Aligns every plugin/skills/<name>/SKILL.md with the conventions from https://agentskills.io/skill-creation/best-practices and /optimizing-descriptions. Defines size caps, load-on-trigger layout, gotchas, checklists, validation loops, plan-validate-execute, defaults-not-menus, and description-optimization rules. Enforced by self-check D30."
4
+ applies_to: "every plugin/skills/<name>/SKILL.md"
5
+ since: "kushi v5.0.1"
6
+ ---
7
+
8
+ # agentskills-compliance — doctrine
9
+
10
+ A SKILL.md is loaded **fully** into the agent's context window the moment it triggers. Every token competes with the conversation, system prompt, and other active skills. Compliance with the agentskills.io best-practices is therefore not stylistic — it is a context-budget contract.
11
+
12
+ Authoritative external references:
13
+
14
+ - <https://agentskills.io/skill-creation/best-practices>
15
+ - <https://agentskills.io/skill-creation/optimizing-descriptions>
16
+
17
+ ## Rules (HARD)
18
+
19
+ ### 1. Size cap
20
+
21
+ Every `plugin/skills/<name>/SKILL.md` MUST be:
22
+
23
+ - ≤ **500 lines**, AND
24
+ - ≤ **5000 tokens** (approximated by `char_count / 4`).
25
+
26
+ Oversize SKILLs MUST be split per rule 2 below. Enforced by `self-check D30.skill-size`.
27
+
28
+ ### 2. Load-on-trigger layout
29
+
30
+ `plugin/skills/<name>/SKILL.md` contains:
31
+
32
+ - front-matter (`name`, `version`, `description`)
33
+ - one-paragraph purpose
34
+ - `## Gotchas` (top 5) — pull-* skills MUST have this
35
+ - numbered or checklist procedure
36
+ - `## Validation loop` (writer skills)
37
+ - output contract
38
+
39
+ Bulk content (full canonical WorkIQ prompts, full error-mode taxonomies, deep schema details, worked examples) moves to `plugin/skills/<name>/references/<topic>.md`. Standard reference filenames:
40
+
41
+ | File | Contents |
42
+ |------|----------|
43
+ | `references/canonical-prompts.md` | Full WorkIQ prompt text (tier A/B/C, CSC, recovery) |
44
+ | `references/error-modes.md` | Error taxonomy with retry semantics |
45
+ | `references/taxonomy.md` | CSC schema deep details (where source-specific) |
46
+ | `references/examples.md` | Full worked examples |
47
+ | `references/playwright-fallback.md` | Opt-in fallback procedures |
48
+
49
+ Every reference cited from SKILL.md MUST be cited with an **explicit trigger**, not a passive link. Trigger templates:
50
+
51
+ ```
52
+ > Load references/canonical-prompts.md when constructing the WorkIQ query for this source.
53
+ > Load references/error-modes.md if the API returns non-200, or WorkIQ returns "throttled".
54
+ > Load references/playwright-fallback.md only when WorkIQ body-retrieval rate stays poor across ≥2 refreshes.
55
+ ```
56
+
57
+ Enforced by `self-check D30.references-layout`.
58
+
59
+ ### 3. Gotchas (top 5)
60
+
61
+ Every `pull-*` SKILL.md MUST surface its top 5 gotchas in a `## Gotchas` section near the top (immediately after the H1 / opening paragraph; before `## Steps` or `## Procedure`).
62
+
63
+ Format: bullet list. Each bullet starts with the **concrete failure mode**, then the correction.
64
+
65
+ ```markdown
66
+ ## Gotchas
67
+
68
+ - **Moved pages keep original wdsectionfileid** → if a section returns `page-body-unavailable` or zero `wdpartid` entries, the pages were authored elsewhere and moved. Open OneNote desktop, drag pages back into target section, retry.
69
+ - **WorkIQ tier C requires ONE page per call** — batching multiple pages into a single ask returns empty results. Loop over pageIds, one call each.
70
+ ```
71
+
72
+ Pull from `plugin/learnings/<source>.md` if present; else extract from the SKILL body itself. Enforced by `self-check D30.gotchas-section`.
73
+
74
+ ### 4. Checklists for orchestrators
75
+
76
+ Orchestrator SKILLs (`bootstrap-project`, `refresh-project`, `build-state`, `link-entities`, `dashboard`, `tour`) MUST use GitHub checkbox syntax `- [ ]` for their step lists so progress is trackable in tooling and in conversation.
77
+
78
+ ```markdown
79
+ - [ ] Step 1 — Resolve engagement root.
80
+ - [ ] Step 2 — Resolve project alias.
81
+ - [ ] Step 3 — Preflight per source.
82
+ ```
83
+
84
+ Enforced by `self-check D30.checklist-orchestrators`.
85
+
86
+ ### 5. Validation loops (writer skills)
87
+
88
+ Every skill that writes files to `Evidence/`, `State/`, `_graph/`, `dashboards/`, or `tours/` MUST end with a `## Validation loop` section:
89
+
90
+ ```markdown
91
+ ## Validation loop
92
+
93
+ After writing outputs:
94
+
95
+ 1. Run self-check targeted at this skill: `pwsh plugin/skills/self-check/run.ps1 -Targeted <area>`
96
+ 2. If failures: fix and re-run the affected step (not the whole skill).
97
+ 3. Repeat until self-check exits 0.
98
+ 4. Only then update `run-log.yml` with success status.
99
+ ```
100
+
101
+ Enforced by `self-check D30.validation-loop`.
102
+
103
+ ### 6. Plan-validate-execute (link-entities + build-state)
104
+
105
+ See `plan-validate-execute.instructions.md`. The skill writes a plan JSON, validates against a source of truth, then executes.
106
+
107
+ ### 7. Defaults not menus
108
+
109
+ Pick ONE tool for each procedure step. Alternatives are escape hatches and MUST live in `references/` (e.g. `references/playwright-fallback.md`), not in the main SKILL body. The SKILL.md procedure does not enumerate alternatives.
110
+
111
+ ### 8. Procedures over declarations
112
+
113
+ Write what the agent must DO, not what the skill IS. Imperative voice, concrete steps.
114
+
115
+ ### 9. Description optimization
116
+
117
+ Per <https://agentskills.io/skill-creation/optimizing-descriptions> the `description:` front-matter is the sole trigger signal. It MUST describe **WHEN to use** the skill (trigger conditions), not just what it does. Convention for kushi skills:
118
+
119
+ ```yaml
120
+ description: "USE WHEN <situational trigger> AND <precondition>. DO NOT USE for <near-miss>. <one-line capability summary>."
121
+ ```
122
+
123
+ - BAD: `"Pulls OneNote pages and saves them as markdown."`
124
+ - GOOD: `"USE WHEN refreshing project evidence for a known kushi project AND the project boundaries.onenote.section_ids list is non-empty. DO NOT USE for global OneNote search or non-kushi note capture."`
125
+
126
+ Hard limit: 1024 characters. Enforced loosely by `self-check D30.description-optimized` (checks for the literal substring `USE WHEN` or `WHEN ` near the start of `description:`).
127
+
128
+ ## Migration checklist (per oversized SKILL)
129
+
130
+ - [ ] Move full WorkIQ prompts → `references/canonical-prompts.md`
131
+ - [ ] Move full error taxonomy → `references/error-modes.md`
132
+ - [ ] Move source-specific schema details → `references/taxonomy.md`
133
+ - [ ] Move opt-in fallbacks (Playwright, Edge profile bootstrap) → `references/playwright-fallback.md`
134
+ - [ ] Add `## Gotchas` (top 5)
135
+ - [ ] Add `## Validation loop` (if writer)
136
+ - [ ] Replace inline blocks with "Load references/&lt;file&gt; when …" pointers
137
+ - [ ] Bump skill version (minor) since structure changed
138
+ - [ ] Re-run `self-check D30` and `npm test`
139
+
140
+ ## References
141
+
142
+ - `instructions/plan-validate-execute.instructions.md`
143
+ - `instructions/capture-learnings.instructions.md`
144
+ - `instructions/issue-recovery.instructions.md`
@@ -0,0 +1,125 @@
1
+ ---
2
+ name: "multi-host-install"
3
+ version: "1.0.0"
4
+ description: "USE WHEN installing kushi to a user-global host (Clawpilot or VS Code Chat), uninstalling, or wondering why kushi ships to two hosts (not three or N) and how the layouts differ. DO NOT USE for workspace-local .kushi/ install — that is the legacy --target vscode flow."
5
+ ---
6
+
7
+ # Multi-host install doctrine (v5.0.2+)
8
+
9
+ Kushi ships as a single host-agnostic skill bundle, installed into a host's
10
+ user-global skill folder by `npx kushi-agents`. **Exactly two hosts are
11
+ supported.** No third host. No N-host generality.
12
+
13
+ ## The 2-host matrix
14
+
15
+ | Host ID | Display name | Skill dir | Metadata file |
16
+ |--------------|-----------------------------------------|------------------------------------|----------------------------------------------|
17
+ | `clawpilot` | Clawpilot CLI | `~/.copilot/m-skills/kushi/` | `~/.copilot/m-skills/skills-metadata.json` |
18
+ | `vscode` | VS Code Chat ("GitHub Copilot Chat") | `~/.vscode/chat/skills/kushi/` | `~/.vscode/chat/skills/skills-metadata.json` |
19
+
20
+ > The VS Code Chat path is the canonical user-global skill folder location
21
+ > assumed by this doctrine. If a future VS Code Chat release ships a
22
+ > different canonical path, update `VSCODE_CHAT_DEST_SUBPATH` in
23
+ > `src/constants.mjs` — every other surface reads from there.
24
+
25
+ ## Why only these two
26
+
27
+ - **Clawpilot** — primary scheduled / overnight surface (e.g. `kushi refresh <project>`
28
+ run from a Clawpilot automation at 6 AM).
29
+ - **VS Code Chat** — primary interactive surface (`@kushi what's the MACC for X?`
30
+ asked the next morning).
31
+
32
+ The same user routinely lives in both — automation in Clawpilot, follow-up
33
+ questions in VS Code Chat. Both hosts read the **same** Evidence/ tree on disk,
34
+ so a refresh in one is visible from the other immediately.
35
+
36
+ A third host (e.g. a hypothetical web UI) would force per-host SKILL surgery
37
+ or a content-branching shim. The 2-host matrix is the deliberate stopping
38
+ point — it covers ≥ 99 % of the actual usage pattern and keeps cross-host
39
+ parity trivially enforceable.
40
+
41
+ ## Per-host layout
42
+
43
+ Both hosts get **byte-identical** content under their skill dir:
44
+
45
+ ```text
46
+ <host-skill-dir>/
47
+ ├── SKILL.md (mirrored from agents/kushi.agent.md)
48
+ ├── agents/kushi.agent.md
49
+ ├── instructions/<name>.instructions.md
50
+ ├── prompts/<name>.prompt.md
51
+ ├── skills/<name>/SKILL.md (+ references/, run.ps1, etc.)
52
+ ├── templates/<...>
53
+ ├── lib/<...>
54
+ ├── reference-packs/<...>
55
+ ├── config/
56
+ │ ├── shared/ (team-owned, safe to commit)
57
+ │ └── user/ (per-contributor, gitignored)
58
+ └── kushi-install.json (profile manifest)
59
+ ```
60
+
61
+ And at the **parent** dir, `skills-metadata.json` carries the host's skill
62
+ registry. The installer upserts a single `{"name": "kushi", ...}` entry that
63
+ points `instructions` at the host's own `SKILL.md` (absolute path).
64
+
65
+ There is **no per-host content branching**. A SKILL.md that opens with `WHEN
66
+ running on Clawpilot, do X; WHEN running on VS Code Chat, do Y` is a defect.
67
+
68
+ ## Detection rules
69
+
70
+ A host is **detected** when its parent dir exists on the file system:
71
+
72
+ | Host | Detection probe |
73
+ |------------|---------------------------------------|
74
+ | clawpilot | `~/.copilot/m-skills/` exists |
75
+ | vscode | `~/.vscode/chat/skills/` exists |
76
+
77
+ `bin/cli.mjs` runs detection before any install/uninstall and prints
78
+ `Detected hosts: …` so the user sees which targets will be touched by the
79
+ default behavior.
80
+
81
+ ## Install / uninstall flags
82
+
83
+ | Flag | Effect |
84
+ |--------------------------------------|--------|
85
+ | `--clawpilot` | Install to Clawpilot host (alone: also legacy `--target clawpilot` path) |
86
+ | `--vscode` | Install to VS Code Chat host |
87
+ | `--all-hosts` | Install to BOTH hosts (regardless of detection) |
88
+ | `--uninstall` | Uninstall from all *detected* hosts |
89
+ | `--uninstall --clawpilot` | Uninstall from Clawpilot only |
90
+ | `--uninstall --vscode` | Uninstall from VS Code Chat only |
91
+ | `--uninstall --all` | Uninstall from BOTH hosts |
92
+ | (no flag) | Workspace install (legacy `.kushi/` in cwd) |
93
+
94
+ ## `kushi refresh <project>` is host-agnostic
95
+
96
+ `refresh` is just a SKILL — the same `plugin/skills/refresh-project/SKILL.md`
97
+ content runs under both hosts. It writes Evidence to disk at the user-
98
+ configured engagement root (`~/Documents/Engagements/<project>/` by default),
99
+ which lives **outside** the host skill dir. That is why a Clawpilot-driven
100
+ refresh is immediately visible to a VS Code Chat `ask` — neither host owns
101
+ the data.
102
+
103
+ ## Cross-host parity rule
104
+
105
+ Every SKILL.md, prompt, instruction, template, and lib asset MUST work
106
+ identically under both hosts. Concretely:
107
+
108
+ - No `if (HOST === 'clawpilot') ...` style branching in any markdown body.
109
+ - No host-specific paths in skill content (always use `<engagement-root>` /
110
+ `<project>` placeholders that resolve at runtime via the standard
111
+ `engagement-root-resolution.instructions.md` chain).
112
+ - The two `SKILL.md` files (one per host) are required to be **byte-identical**
113
+ — enforced by `self-check` `D32.multi-host` in deep mode (temp-dir dry-run).
114
+
115
+ If a future feature genuinely requires host-specific behavior (e.g. UI affordance
116
+ only one host provides), it belongs in a host-specific *helper* outside `plugin/`
117
+ — not inside the shared skill bundle.
118
+
119
+ ## See also
120
+
121
+ - `host-portability.instructions.md` — older doctrine on per-host portability of
122
+ individual skill calls (still in force for runtime tool selection).
123
+ - `D32.multi-host` self-check (deep) — validates installer + temp-dir layout.
124
+ - `src/multi-host.mjs` — the installer/uninstaller implementation.
125
+ - `src/multi-host-install.test.mjs` — node:test coverage.