kushi-agents 4.8.1 → 4.8.3
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/package.json +1 -1
- package/plugin/instructions/customer-hint-discovery.instructions.md +4 -3
- package/plugin/instructions/email-bootstrap-discovery.instructions.md +1 -1
- package/plugin/instructions/identity-resolution.instructions.md +10 -7
- package/plugin/instructions/meetings-bootstrap-discovery.instructions.md +1 -1
- package/plugin/instructions/sharepoint-bootstrap-discovery.instructions.md +1 -1
- package/plugin/instructions/teams-bootstrap-discovery.instructions.md +1 -1
- package/plugin/skills/bootstrap-project/SKILL.md +1 -1
- package/plugin/skills/setup/SKILL.md +15 -14
- package/plugin/templates/init/m365-auth.template.json +3 -3
- package/plugin/templates/init/project-evidence.template.yml +5 -5
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "kushi-agents",
|
|
3
|
-
"version": "4.8.
|
|
3
|
+
"version": "4.8.3",
|
|
4
4
|
"description": "Install Kushi — multi-source project evidence agent with snapshot+stream capture across Email, Teams, OneNote, Loop, SharePoint, Meetings, CRM, ADO. WorkIQ-only for M365 sources (Graph / m365_* FORBIDDEN as fallbacks; user-paste is first-class). Host-agnostic.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -44,7 +44,7 @@ For each source whose sweep runs:
|
|
|
44
44
|
|
|
45
45
|
1. **Append discovered IDs / URLs / paths to `<engagement-root>/<project>/integrations.yml#boundaries.<source>.<key>`** as plain strings (existing pull-* skills consume strings — do NOT change the array element type). Idempotent: deduplicate by exact-string equality.
|
|
46
46
|
|
|
47
|
-
2. **Write a sidecar discovery record to `<engagement-root>/<project>/Evidence
|
|
47
|
+
2. **Write a sidecar discovery record to `<engagement-root>/<project>/Evidence/<alias>/_discovery/<YYYY-MM-DD>_<source>_discovery.yml`** with the per-row metadata (`discovered_by`, `discovered_at`, `needs_review`, `query`, `request_id`, `confidence`). The sidecar lives **inside the contributor's alias folder** because discovery results are inherently per-identity (each contributor sees a different mailbox / chat / meeting set). Schema:
|
|
48
48
|
|
|
49
49
|
```yaml
|
|
50
50
|
source: email | teams | meetings | sharepoint
|
|
@@ -93,11 +93,12 @@ For each source whose sweep runs:
|
|
|
93
93
|
|
|
94
94
|
## Multi-contributor safety
|
|
95
95
|
|
|
96
|
-
When the boundary already has rows from another alias (or
|
|
96
|
+
When the boundary already has rows from another alias (or sibling `Evidence/<other-alias>/_discovery/` folders already have entries):
|
|
97
97
|
|
|
98
98
|
1. **Append-only** — the new alias's sweep adds rows that are not already present (dedupe by exact-string equality on the boundary value). Never remove or rewrite another alias's row.
|
|
99
|
-
2. **Sidecar
|
|
99
|
+
2. **Sidecar files are per-contributor-folder-per-source-per-date** — each contributor writes only into their own `Evidence/<alias>/_discovery/` folder. Filenames are NOT suffixed with `-<alias>` (folder already namespaces the owner). On the same day, contributors `ushak` and `stand` produce `Evidence/ushak/_discovery/2026-05-26_email_discovery.yml` and `Evidence/stand/_discovery/2026-05-26_email_discovery.yml` respectively — no collision possible. Bootstrap-status's Discovery Sweep Results table shows one row per source × alias.
|
|
100
100
|
3. **`Discovered by` column in bootstrap-status's per-source Context Artifact Status row** cites the most recent discovering alias. Preserve other aliases' rows in `## Contributors who have bootstrapped this project` per `multi-user-shared-files.instructions.md`.
|
|
101
|
+
4. **NEVER write to another contributor's `Evidence/<other-alias>/_discovery/` folder.** Reading other aliases' discovery sidecars (e.g. to merge already-confirmed candidates into the shared boundary) is allowed and expected; writing into them is forbidden.
|
|
101
102
|
|
|
102
103
|
## Rerun behavior
|
|
103
104
|
|
|
@@ -55,7 +55,7 @@ WorkIQ returns a markdown table. Parse rows where `folder path` is non-empty and
|
|
|
55
55
|
|
|
56
56
|
## Sidecar file shape
|
|
57
57
|
|
|
58
|
-
Written to `<engagement-root>/<project>/Evidence
|
|
58
|
+
Written to `<engagement-root>/<project>/Evidence/<alias>/_discovery/<YYYY-MM-DD>_email_discovery.yml` (per-contributor folder; no `-<alias>` filename suffix since the folder already namespaces the owner):
|
|
59
59
|
|
|
60
60
|
```yaml
|
|
61
61
|
source: email
|
|
@@ -85,13 +85,13 @@ The `setup` skill (added v4.4.4) extends this doctrine beyond identity to cover
|
|
|
85
85
|
| `project-evidence.yml` | `identity.alias` / `display_name` / `email` | YES | WorkIQ "Who am I?" |
|
|
86
86
|
| `project-evidence.yml` | `identity_status`, `identity_verified_at` | YES | written by setup |
|
|
87
87
|
| `project-evidence.yml` | `projects_root` | YES | cwd-ancestor detection; otherwise prompt |
|
|
88
|
-
| `project-evidence.yml` | `default_onenote_notebook` | **
|
|
88
|
+
| `project-evidence.yml` | `default_onenote_notebook` | **DEPRECATED (display-only as of v4.8.3)** | display-only mirror of `m365-auth.json#oneNote.defaultNotebookName`. NEVER gates OneNote. The `<skip>` sentinel is deprecated. |
|
|
89
89
|
| `project-evidence.yml` | `active_projects[]` | YES (list, may be empty) | the project arg if dispatched from `bootstrap <project>`; otherwise leave existing |
|
|
90
90
|
| `project-evidence.yml` | `workiq.cli_path` | OPTIONAL | only written when discovered via PATH/fallback, not already pinned |
|
|
91
91
|
| `m365-auth.json` | `_meta.owner` | YES | `<identity.email>` |
|
|
92
92
|
| `m365-auth.json` | `oneNote.defaultLinkOwner` | YES (when OneNote enabled) | `<identity.email>` — the user's own UPN, since OneNote queries default to the user's personal notebook |
|
|
93
93
|
| `m365-auth.json` | `oneNote.defaultNotebookId` | **NOT WRITTEN (kushi v4.7.3+)** | Per `workiq-onenote-query-shape.instructions.md`, WorkIQ has no notebook-ID lookup surface — any such probe punts to Graph Explorer. Setup persists `defaultNotebookName` only; section IDs are discovered per-section at bootstrap/refresh time using the natural-language WorkIQ pattern. |
|
|
94
|
-
| `m365-auth.json` | `oneNote.enabled` | YES | `false` when
|
|
94
|
+
| `m365-auth.json` | `oneNote.enabled` | YES | **default `true` (kushi v4.8.3+).** Single source of truth — the only field that gates OneNote across kushi. Set to `false` ONLY when the contributor explicitly opts out via `setup` or by hand. The legacy `project-evidence.yml#default_onenote_notebook == "<skip>"` sentinel is deprecated and no longer consulted. |
|
|
95
95
|
| `m365-auth.json` | `emailContext.folders[]` | OPTIONAL | user prompt: comma-sep list / `all` / blank. `all` or blank → `[]` (full mailbox) |
|
|
96
96
|
| `m365-auth.json` | `sharePointContext.localProjectsRoot` | YES | mirrors `<projects_root>` |
|
|
97
97
|
|
|
@@ -101,10 +101,12 @@ The `setup` skill (added v4.4.4) extends this doctrine beyond identity to cover
|
|
|
101
101
|
|
|
102
102
|
The `setup` skill does the deeper recovery (3-retry loop with `ask_user` choices).
|
|
103
103
|
|
|
104
|
-
### OneNote —
|
|
104
|
+
### OneNote — enabled by default, single switch (kushi v4.8.3+)
|
|
105
105
|
|
|
106
|
-
-
|
|
107
|
-
-
|
|
106
|
+
- **Default:** `m365Auth.oneNote.enabled: true`. OneNote is opt-out, not opt-in.
|
|
107
|
+
- **Single source of truth:** `m365Auth.oneNote.enabled` is the ONLY field that gates OneNote across kushi. Downstream skills (`pull-onenote`, `bootstrap-project` Step 4) MUST NOT inspect `project-evidence.yml#default_onenote_notebook` to decide whether to run OneNote.
|
|
108
|
+
- User explicitly opted out → set `oneNote.enabled: false`, leave other OneNote fields blank, OneNote source becomes a no-op (reported as `not-applicable` in run logs). Re-enable by hand-editing `m365-auth.json` (`enabled: true`) or by running `setup --reconfigure`.
|
|
109
|
+
- User gave a notebook name (or accepted the `ISE Work` default) → keep `enabled: true`, persist `defaultNotebookName`. Do NOT query WorkIQ for the notebook ID (per `workiq-onenote-query-shape.instructions.md` — no notebook-inventory surface). Section IDs are discovered per-section at bootstrap/refresh time.
|
|
108
110
|
- `defaultLinkOwner` is ALWAYS the user's own UPN unless the user explicitly overrides (shared/team-owned notebook case).
|
|
109
111
|
|
|
110
112
|
### Mailbox folders — multi-value with "all" sentinel
|
|
@@ -131,9 +133,10 @@ Both `all` and blank persist as `[]`. ALWAYS print after persisting:
|
|
|
131
133
|
```
|
|
132
134
|
Edit these files later if anything changes:
|
|
133
135
|
• <workspace>/.kushi/config/user/project-evidence.yml
|
|
134
|
-
identity, projects_root,
|
|
136
|
+
identity, projects_root, active_projects, workiq.cli_path
|
|
137
|
+
(default_onenote_notebook is display-only since v4.8.3 — edit m365-auth.json to enable/disable)
|
|
135
138
|
• <workspace>/.kushi/config/user/m365-auth.json
|
|
136
|
-
OneNote
|
|
139
|
+
OneNote enable/disable + notebook name (oneNote.enabled, oneNote.defaultNotebookName), email folder list, SharePoint root
|
|
137
140
|
• <workspace>/.kushi/config/shared/integrations.yml (team-wide; commit changes)
|
|
138
141
|
CRM environmentUrl + tenantId, ADO organization + project
|
|
139
142
|
|
|
@@ -60,7 +60,7 @@ This phrasing — **natural-language by subject + organizer + join URL request**
|
|
|
60
60
|
|
|
61
61
|
## Sidecar file shape
|
|
62
62
|
|
|
63
|
-
Written to `<engagement-root>/<project>/Evidence
|
|
63
|
+
Written to `<engagement-root>/<project>/Evidence/<alias>/_discovery/<YYYY-MM-DD>_meetings_discovery.yml` (per-contributor folder; no `-<alias>` filename suffix). Schema per `email-bootstrap-discovery.instructions.md` § Sidecar file shape, with `source: meetings`.
|
|
64
64
|
|
|
65
65
|
Additional field for meetings sidecar:
|
|
66
66
|
|
|
@@ -67,7 +67,7 @@ WorkIQ commonly punts on this query (see Empirical finding above). Apply this cl
|
|
|
67
67
|
|
|
68
68
|
## Sidecar file shape
|
|
69
69
|
|
|
70
|
-
Written to `<engagement-root>/<project>/Evidence
|
|
70
|
+
Written to `<engagement-root>/<project>/Evidence/<alias>/_discovery/<YYYY-MM-DD>_sharepoint_discovery.yml` (per-contributor folder; no `-<alias>` filename suffix). Schema per `email-bootstrap-discovery.instructions.md` § Sidecar file shape, with `source: sharepoint`.
|
|
71
71
|
|
|
72
72
|
```yaml
|
|
73
73
|
results:
|
|
@@ -87,7 +87,7 @@ WorkIQ returns the `chat ID` column populated as `N/A` (empirical, v4.8.1). The
|
|
|
87
87
|
|
|
88
88
|
## Sidecar file shape
|
|
89
89
|
|
|
90
|
-
Two sidecar files (one per query). Written to `<engagement-root>/<project>/Evidence
|
|
90
|
+
Two sidecar files (one per query). Written to `<engagement-root>/<project>/Evidence/<alias>/_discovery/<YYYY-MM-DD>_teams-chats_discovery.yml` and `<engagement-root>/<project>/Evidence/<alias>/_discovery/<YYYY-MM-DD>_teams-channels_discovery.yml` (per-contributor folder; no `-<alias>` filename suffix since the folder already namespaces the owner).
|
|
91
91
|
|
|
92
92
|
Schema is the same as `email-bootstrap-discovery.instructions.md` § Sidecar file shape, with `source: teams-chats` or `source: teams-channels`.
|
|
93
93
|
|
|
@@ -138,7 +138,7 @@ For each sweep:
|
|
|
138
138
|
3. Parse the response per the doctrine's parsing rules.
|
|
139
139
|
4. Cap at 10 candidates by recency (or per-doctrine ordering).
|
|
140
140
|
5. Append discovered values to `<project>/integrations.yml#boundaries.<source>.<key>` as plain strings (deduplicate by exact-string equality).
|
|
141
|
-
6. Write sidecar `<project>/Evidence
|
|
141
|
+
6. Write sidecar `<project>/Evidence/<alias>/_discovery/<YYYY-MM-DD>_<source>_discovery.yml` with per-row metadata (`discovered_by`, `discovered_at`, `needs_review: true`, `confidence`, `query`, `workiq_request_id`). The sidecar lives INSIDE the contributor's alias folder (discovery results are per-identity); filename is NOT suffixed with `-<alias>` since the folder already namespaces the owner.
|
|
142
142
|
7. If `> 10` candidates: append the remainder to `<project>/OPEN-QUESTIONS-DRAFT.md` under `## Discovery sweep — candidates over cap`.
|
|
143
143
|
8. If `0` candidates: write `last_status: unresolved` (NOT `blocked-config`) and append a one-line widen-hint suggestion to Open Questions.
|
|
144
144
|
9. If WorkIQ errors: write a `deferred-retry` marker per `deferred-retry-on-workiq-fail.instructions.md` and set `last_status: deferred`. Do NOT skip ahead to `blocked-config`.
|
|
@@ -126,24 +126,25 @@ Also write:
|
|
|
126
126
|
|
|
127
127
|
Bootstrap + refresh MUST refuse to start if `projects_root_status` is `syncing` or `manual-sync-pending` (see Step 6 footer).
|
|
128
128
|
|
|
129
|
-
4d. **OneNote (
|
|
129
|
+
4d. **OneNote (ENABLED BY DEFAULT — kushi v4.8.3+).** OneNote is on by default and gated by a **single switch**: `m365Auth.oneNote.enabled` in `m365-auth.json`. The `project-evidence.yml#default_onenote_notebook` field is now display-only and is NEVER used to gate OneNote (the `<skip>` sentinel is deprecated; existing values are tolerated but ignored).
|
|
130
130
|
|
|
131
|
-
`
|
|
131
|
+
Check `m365Auth.oneNote.enabled` AND `m365Auth.oneNote.defaultNotebookName`:
|
|
132
132
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
> • **No / not yet** — skip OneNote (you can enable later by editing `m365-auth.json` and re-running `@Kushi setup --reconfigure`)
|
|
133
|
+
- `enabled` is missing → set `true` (default-on).
|
|
134
|
+
- `defaultNotebookName` is a placeholder (`<Your Notebook Name>` / `<auto>` / empty) → prompt only for the notebook name (NOT for enable/disable). `ask_user`:
|
|
136
135
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
- Echo: `OneNote enabled. Notebook: "<name>". Section IDs will be discovered at bootstrap-project / refresh time via WorkIQ natural-language queries.`
|
|
136
|
+
> Which OneNote notebook does kushi pull from on this engagement?
|
|
137
|
+
> • **Use my default work notebook** — `ISE Work` (recommended for Microsoft consultants)
|
|
138
|
+
> • **A different notebook** — paste the exact display name
|
|
139
|
+
> • **Disable OneNote on this machine** — only pick if you genuinely never use OneNote (you can re-enable later by editing `m365-auth.json`)
|
|
142
140
|
|
|
143
|
-
|
|
144
|
-
-
|
|
145
|
-
|
|
146
|
-
-
|
|
141
|
+
- Default/different notebook: persist `defaultNotebookName: "<name>"` + ensure `enabled: true`. Do NOT auto-resolve a notebook ID via WorkIQ (per `workiq-onenote-query-shape.instructions.md`).
|
|
142
|
+
- Disable: set `enabled: false`, leave other OneNote fields blank, echo: `OneNote disabled for this contributor. Pull-onenote will report 'not-applicable' in run logs. Re-enable by setting m365Auth.oneNote.enabled: true in m365-auth.json.`
|
|
143
|
+
|
|
144
|
+
- `defaultNotebookName` is already populated AND `enabled: true` → silent skip.
|
|
145
|
+
- `enabled: false` (explicitly opted out previously) → silent skip; OneNote stays disabled. `--reconfigure` re-asks.
|
|
146
|
+
|
|
147
|
+
**Single source of truth:** Downstream skills (`pull-onenote`, bootstrap Step 4) gate ONLY on `m365Auth.oneNote.enabled`. Never inspect `default_onenote_notebook` to decide whether to run OneNote.
|
|
147
148
|
|
|
148
149
|
4d-loop. **Microsoft Loop (OPTIONAL — skip-friendly).** Check `default_loop_workspace` in `project-evidence.yml`. If it's a placeholder (`<Your Loop Workspace>` / `<auto>` / `<skip>` / empty):
|
|
149
150
|
|
|
@@ -16,9 +16,9 @@
|
|
|
16
16
|
},
|
|
17
17
|
"oneNote": {
|
|
18
18
|
"enabled": true,
|
|
19
|
-
"_enabled_note": "Set to false
|
|
20
|
-
"defaultNotebookName": "
|
|
21
|
-
"_defaultNotebookName_note": "
|
|
19
|
+
"_enabled_note": "DEFAULT-ON as of kushi v4.8.3. Single source of truth for whether OneNote runs anywhere in kushi. Set to false ONLY when this contributor genuinely does not use OneNote on this engagement; pull-onenote then no-ops and reports the source as `not-applicable` in run logs.",
|
|
20
|
+
"defaultNotebookName": "ISE Work",
|
|
21
|
+
"_defaultNotebookName_note": "Default notebook kushi pulls from. `ISE Work` is the standard Microsoft consultant notebook; override here or via `@Kushi setup` if you use a different one.",
|
|
22
22
|
"defaultNotebookId": "",
|
|
23
23
|
"_defaultNotebookId_note": "Optional. Auto-populated by `@Kushi setup` from defaultNotebookName via WorkIQ. Leave blank to defer.",
|
|
24
24
|
"defaultSectionResolverUrl": "",
|
|
@@ -30,11 +30,11 @@ email: <auto>
|
|
|
30
30
|
# macOS : '/Users/<you>/OneDrive - <Tenant>/<Team>/Engagement Assets'
|
|
31
31
|
projects_root: '<engagement-root>'
|
|
32
32
|
|
|
33
|
-
#
|
|
34
|
-
#
|
|
35
|
-
#
|
|
36
|
-
#
|
|
37
|
-
default_onenote_notebook:
|
|
33
|
+
# DEPRECATED as of v4.8.3 — display-only mirror of m365-auth.json#oneNote.defaultNotebookName.
|
|
34
|
+
# Does NOT gate OneNote. The single switch is m365Auth.oneNote.enabled in m365-auth.json
|
|
35
|
+
# (default `true`). To disable OneNote, set that field to false (or pick "Disable OneNote"
|
|
36
|
+
# during `@Kushi setup`). The legacy `<skip>` sentinel is tolerated but ignored.
|
|
37
|
+
default_onenote_notebook: ISE Work
|
|
38
38
|
|
|
39
39
|
# FILL ME IN — projects you actively work on. Kushi scans only these unless
|
|
40
40
|
# you ask otherwise. Match is fuzzy against subfolder names under projects_root.
|