analyzthis_design 2.4.0 → 2.4.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/HOW-TO-USE.md +26 -8
- package/README.md +14 -1
- package/dist/HOW-TO-USE.md +26 -8
- package/dist/README.md +14 -1
- package/dist/bin/cli.js +130 -0
- package/dist/lib/accept.js +95 -0
- package/dist/lib/feedback-submit.js +2 -0
- package/dist/lib/install.js +7 -0
- package/dist/lib/mcp-server.js +18 -6
- package/dist/lib/receipt.js +102 -0
- package/dist/lib/session.js +52 -1
- package/dist/lib/share.js +131 -0
- package/dist/skills/accept/SKILL.md +52 -0
- package/dist/skills/getting-started/SKILL.md +3 -0
- package/dist/skills/share/SKILL.md +54 -0
- package/package.json +1 -1
- package/skills/accept/SKILL.md +52 -0
- package/skills/getting-started/SKILL.md +3 -0
- package/skills/share/SKILL.md +54 -0
package/HOW-TO-USE.md
CHANGED
|
@@ -313,21 +313,39 @@ Each persona reads the session state, so you do not need to repeat the task.
|
|
|
313
313
|
|
|
314
314
|
## 8. After the run — accept, reject, evolve
|
|
315
315
|
|
|
316
|
-
###
|
|
316
|
+
### Designer path (remember this)
|
|
317
317
|
|
|
318
|
-
|
|
319
|
-
|
|
318
|
+
In chat, after `/zara` or any persona:
|
|
319
|
+
|
|
320
|
+
```
|
|
321
|
+
/accept yes
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
or
|
|
325
|
+
|
|
326
|
+
```
|
|
327
|
+
/accept no — too much motion on the daily table
|
|
320
328
|
```
|
|
321
329
|
|
|
322
|
-
|
|
330
|
+
No terminal flags. `/accept` writes keep or skip for **local** evolution.
|
|
331
|
+
|
|
332
|
+
To send a correction to the published package:
|
|
333
|
+
|
|
334
|
+
```
|
|
335
|
+
/share
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
Then **yes** if the preview looks right. Redacted — no folder names, emails, or keys.
|
|
339
|
+
|
|
340
|
+
### CLI (same thing, if you prefer the terminal)
|
|
323
341
|
|
|
324
342
|
```bash
|
|
325
|
-
npx analyzthis_design
|
|
326
|
-
|
|
327
|
-
--correction "Use --color-primary and spacing-4 from tokens.css" \
|
|
328
|
-
--rating 2 --tags invented_tokens,missed_ds
|
|
343
|
+
npx analyzthis_design accept --keep --persona arjun
|
|
344
|
+
npx analyzthis_design accept --fix --persona arjun --because "Invented tokens — use tokens.css"
|
|
329
345
|
```
|
|
330
346
|
|
|
347
|
+
The older `session accept` / `feedback record` flags still work.
|
|
348
|
+
|
|
331
349
|
### Make the team learn
|
|
332
350
|
|
|
333
351
|
```bash
|
package/README.md
CHANGED
|
@@ -4,6 +4,12 @@ A set of AI design personas and a task-first evaluation framework that plugs int
|
|
|
4
4
|
|
|
5
5
|
Install once. Run structured UX critiques, multi-phase ideation, and task-grounded screen reviews — directly inside your AI chat. **No external LLM API keys required** for CLI orchestrator runs: **`/devi`** voices each persona from your host IDE (Cursor, Claude, etc.).
|
|
6
6
|
|
|
7
|
+
## v2.4.1 — `/accept` and `/share` (designer keep / skip / send)
|
|
8
|
+
|
|
9
|
+
After `/zara` (or any persona), type `/accept yes` or `/accept no` plus one sentence. No CLI flags. Writes keep or skip for **local** evolution. Slash-only notes still count.
|
|
10
|
+
|
|
11
|
+
To send a correction to the **published** package: `/share` (preview) then `/share yes`. Redacted. Uses the HTTP endpoint if configured; otherwise a GitHub issue on joshirishi/analyzthis_design.
|
|
12
|
+
|
|
7
13
|
## v2.4.0 — Claude-path efficiency (1 Sep 2026)
|
|
8
14
|
|
|
9
15
|
Same SHIP / REVISE / BLOCK. Fewer tokens on Claude Code and Claude Desktop. Not Caveman-speak. Not a proxy.
|
|
@@ -48,7 +54,7 @@ Pass `--global` to opt into the legacy merged behavior (read `config.sources` an
|
|
|
48
54
|
|
|
49
55
|
Use `npx analyzthis_design run-unchunked` for the legacy single-pass orchestrator.
|
|
50
56
|
|
|
51
|
-
**npm:** [analyzthis_design](https://www.npmjs.com/package/analyzthis_design) · **Current version:** 2.4.
|
|
57
|
+
**npm:** [analyzthis_design](https://www.npmjs.com/package/analyzthis_design) · **Current version:** 2.4.1 · **Step-by-step guide:** [HOW-TO-USE.md](./HOW-TO-USE.md)
|
|
52
58
|
|
|
53
59
|
---
|
|
54
60
|
|
|
@@ -149,6 +155,9 @@ Invoke critique personas for targeted, already-grounded questions. For **wirefra
|
|
|
149
155
|
| `/knowledge-bank` | Auto-populated from your connected vault (or from Kavi collect). All personas read this first. |
|
|
150
156
|
| `/design-reference` | CSV reference data (colors, typography, UX guidelines, stacks, …) |
|
|
151
157
|
| `/collect-knowledge` | Alias for `/kavi` |
|
|
158
|
+
| `/accept` | Keep or skip the last persona note (yes / no). Local evolution — no CLI flags. |
|
|
159
|
+
| `/share` | Send a correction to the package (preview, then yes). Redacted. |
|
|
160
|
+
| `/receipt` | Inferred token receipt for this project. Not a bill. |
|
|
152
161
|
|
|
153
162
|
---
|
|
154
163
|
|
|
@@ -742,6 +751,10 @@ npx analyzthis_design status
|
|
|
742
751
|
|
|
743
752
|
# Session (agentic)
|
|
744
753
|
npx analyzthis_design session init|show|reset [--project id] [--all]
|
|
754
|
+
npx analyzthis_design accept --keep [--persona zara] # designer keep (slash: /accept yes)
|
|
755
|
+
npx analyzthis_design accept --fix --because "one sentence" # designer skip (slash: /accept no)
|
|
756
|
+
npx analyzthis_design share # preview notes for the package
|
|
757
|
+
npx analyzthis_design share --send # send (slash: /share yes)
|
|
745
758
|
npx analyzthis_design session accept --persona <id> [--reject] [--comment "..."] [--correction "..."] [--rating 1-5] [--tags a,b]
|
|
746
759
|
|
|
747
760
|
# Persona feedback (v1.16)
|
package/dist/HOW-TO-USE.md
CHANGED
|
@@ -313,21 +313,39 @@ Each persona reads the session state, so you do not need to repeat the task.
|
|
|
313
313
|
|
|
314
314
|
## 8. After the run — accept, reject, evolve
|
|
315
315
|
|
|
316
|
-
###
|
|
316
|
+
### Designer path (remember this)
|
|
317
317
|
|
|
318
|
-
|
|
319
|
-
|
|
318
|
+
In chat, after `/zara` or any persona:
|
|
319
|
+
|
|
320
|
+
```
|
|
321
|
+
/accept yes
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
or
|
|
325
|
+
|
|
326
|
+
```
|
|
327
|
+
/accept no — too much motion on the daily table
|
|
320
328
|
```
|
|
321
329
|
|
|
322
|
-
|
|
330
|
+
No terminal flags. `/accept` writes keep or skip for **local** evolution.
|
|
331
|
+
|
|
332
|
+
To send a correction to the published package:
|
|
333
|
+
|
|
334
|
+
```
|
|
335
|
+
/share
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
Then **yes** if the preview looks right. Redacted — no folder names, emails, or keys.
|
|
339
|
+
|
|
340
|
+
### CLI (same thing, if you prefer the terminal)
|
|
323
341
|
|
|
324
342
|
```bash
|
|
325
|
-
npx analyzthis_design
|
|
326
|
-
|
|
327
|
-
--correction "Use --color-primary and spacing-4 from tokens.css" \
|
|
328
|
-
--rating 2 --tags invented_tokens,missed_ds
|
|
343
|
+
npx analyzthis_design accept --keep --persona arjun
|
|
344
|
+
npx analyzthis_design accept --fix --persona arjun --because "Invented tokens — use tokens.css"
|
|
329
345
|
```
|
|
330
346
|
|
|
347
|
+
The older `session accept` / `feedback record` flags still work.
|
|
348
|
+
|
|
331
349
|
### Make the team learn
|
|
332
350
|
|
|
333
351
|
```bash
|
package/dist/README.md
CHANGED
|
@@ -4,6 +4,12 @@ A set of AI design personas and a task-first evaluation framework that plugs int
|
|
|
4
4
|
|
|
5
5
|
Install once. Run structured UX critiques, multi-phase ideation, and task-grounded screen reviews — directly inside your AI chat. **No external LLM API keys required** for CLI orchestrator runs: **`/devi`** voices each persona from your host IDE (Cursor, Claude, etc.).
|
|
6
6
|
|
|
7
|
+
## v2.4.1 — `/accept` and `/share` (designer keep / skip / send)
|
|
8
|
+
|
|
9
|
+
After `/zara` (or any persona), type `/accept yes` or `/accept no` plus one sentence. No CLI flags. Writes keep or skip for **local** evolution. Slash-only notes still count.
|
|
10
|
+
|
|
11
|
+
To send a correction to the **published** package: `/share` (preview) then `/share yes`. Redacted. Uses the HTTP endpoint if configured; otherwise a GitHub issue on joshirishi/analyzthis_design.
|
|
12
|
+
|
|
7
13
|
## v2.4.0 — Claude-path efficiency (1 Sep 2026)
|
|
8
14
|
|
|
9
15
|
Same SHIP / REVISE / BLOCK. Fewer tokens on Claude Code and Claude Desktop. Not Caveman-speak. Not a proxy.
|
|
@@ -48,7 +54,7 @@ Pass `--global` to opt into the legacy merged behavior (read `config.sources` an
|
|
|
48
54
|
|
|
49
55
|
Use `npx analyzthis_design run-unchunked` for the legacy single-pass orchestrator.
|
|
50
56
|
|
|
51
|
-
**npm:** [analyzthis_design](https://www.npmjs.com/package/analyzthis_design) · **Current version:** 2.4.
|
|
57
|
+
**npm:** [analyzthis_design](https://www.npmjs.com/package/analyzthis_design) · **Current version:** 2.4.1 · **Step-by-step guide:** [HOW-TO-USE.md](./HOW-TO-USE.md)
|
|
52
58
|
|
|
53
59
|
---
|
|
54
60
|
|
|
@@ -149,6 +155,9 @@ Invoke critique personas for targeted, already-grounded questions. For **wirefra
|
|
|
149
155
|
| `/knowledge-bank` | Auto-populated from your connected vault (or from Kavi collect). All personas read this first. |
|
|
150
156
|
| `/design-reference` | CSV reference data (colors, typography, UX guidelines, stacks, …) |
|
|
151
157
|
| `/collect-knowledge` | Alias for `/kavi` |
|
|
158
|
+
| `/accept` | Keep or skip the last persona note (yes / no). Local evolution — no CLI flags. |
|
|
159
|
+
| `/share` | Send a correction to the package (preview, then yes). Redacted. |
|
|
160
|
+
| `/receipt` | Inferred token receipt for this project. Not a bill. |
|
|
152
161
|
|
|
153
162
|
---
|
|
154
163
|
|
|
@@ -742,6 +751,10 @@ npx analyzthis_design status
|
|
|
742
751
|
|
|
743
752
|
# Session (agentic)
|
|
744
753
|
npx analyzthis_design session init|show|reset [--project id] [--all]
|
|
754
|
+
npx analyzthis_design accept --keep [--persona zara] # designer keep (slash: /accept yes)
|
|
755
|
+
npx analyzthis_design accept --fix --because "one sentence" # designer skip (slash: /accept no)
|
|
756
|
+
npx analyzthis_design share # preview notes for the package
|
|
757
|
+
npx analyzthis_design share --send # send (slash: /share yes)
|
|
745
758
|
npx analyzthis_design session accept --persona <id> [--reject] [--comment "..."] [--correction "..."] [--rating 1-5] [--tags a,b]
|
|
746
759
|
|
|
747
760
|
# Persona feedback (v1.16)
|
package/dist/bin/cli.js
CHANGED
|
@@ -60,6 +60,10 @@ Usage:
|
|
|
60
60
|
session accept Mark a persona's last output accepted, for training export
|
|
61
61
|
(--persona <id>, optional --reject to unmark)
|
|
62
62
|
Optional feedback: --comment, --correction, --rating 1-5, --tags a,b
|
|
63
|
+
accept Designer keep / skip (same as /accept). --keep or --fix
|
|
64
|
+
Optional: --persona, --because "one sentence", --liked (keep, not shipped)
|
|
65
|
+
share Designer send-to-package (same as /share). Preview, then --send
|
|
66
|
+
Optional: --because "one sentence", --persona
|
|
63
67
|
|
|
64
68
|
── Persona feedback commands ─────────────────────────────────
|
|
65
69
|
feedback record Record unhappiness or a correction for a persona output
|
|
@@ -220,6 +224,10 @@ Usage:
|
|
|
220
224
|
npx analyzthis_design devi respond --run ~/.analyzthis_design/runs/... --step 001-arjun --file out.md
|
|
221
225
|
npx analyzthis_design run-unchunked --task "Review this screen" --provider anthropic
|
|
222
226
|
|
|
227
|
+
npx analyzthis_design accept --keep --persona zara
|
|
228
|
+
npx analyzthis_design accept --fix --persona zara --because "too much motion on the table"
|
|
229
|
+
npx analyzthis_design share
|
|
230
|
+
npx analyzthis_design share --send
|
|
223
231
|
npx analyzthis_design session accept --persona arjun
|
|
224
232
|
npx analyzthis_design session accept --persona arjun --reject \\
|
|
225
233
|
--comment "Invented tokens not in our DS" \\
|
|
@@ -322,6 +330,11 @@ const budgetVal = getFlag('budget');
|
|
|
322
330
|
const sequentialFlag = flags.includes('--sequential');
|
|
323
331
|
const maxChunksVal = getFlag('max-chunks');
|
|
324
332
|
const unchunkedFlag = flags.includes('--unchunked');
|
|
333
|
+
const keepFlag = flags.includes('--keep');
|
|
334
|
+
const fixFlag = flags.includes('--fix') || flags.includes('--no');
|
|
335
|
+
const likedFlag = flags.includes('--liked');
|
|
336
|
+
const becauseVal = getFlag('because');
|
|
337
|
+
const sendFlag = flags.includes('--send');
|
|
325
338
|
|
|
326
339
|
// ─── Commands ────────────────────────────────────────────────────────────────
|
|
327
340
|
|
|
@@ -993,6 +1006,123 @@ switch (cmd) {
|
|
|
993
1006
|
break;
|
|
994
1007
|
}
|
|
995
1008
|
|
|
1009
|
+
case 'accept': {
|
|
1010
|
+
const accept = require('../lib/accept');
|
|
1011
|
+
const wantKeep = keepFlag || yesFlag;
|
|
1012
|
+
const wantFix = fixFlag;
|
|
1013
|
+
try {
|
|
1014
|
+
if (wantKeep && wantFix) {
|
|
1015
|
+
console.error('\n ✗ Use --keep or --fix, not both.\n');
|
|
1016
|
+
process.exit(1);
|
|
1017
|
+
}
|
|
1018
|
+
if (!wantKeep && !wantFix) {
|
|
1019
|
+
const peek = accept.preview({ project: projectVal });
|
|
1020
|
+
console.log('\n Keep the last note?');
|
|
1021
|
+
console.log(' Yes: npx analyzthis_design accept --keep' + (peek.persona ? ` --persona ${peek.persona}` : ''));
|
|
1022
|
+
console.log(' No: npx analyzthis_design accept --fix --because "one sentence"');
|
|
1023
|
+
if (peek.persona) console.log(` Last persona: ${peek.persona}`);
|
|
1024
|
+
else console.log(' Last persona: not sure — add --persona zara (or arjun, meera, …)');
|
|
1025
|
+
console.log('');
|
|
1026
|
+
break;
|
|
1027
|
+
}
|
|
1028
|
+
if (wantKeep) {
|
|
1029
|
+
const result = accept.keep({
|
|
1030
|
+
project: projectVal,
|
|
1031
|
+
persona: personaVal,
|
|
1032
|
+
comment: commentVal || becauseVal || '',
|
|
1033
|
+
shipped: !likedFlag,
|
|
1034
|
+
note: commentVal || '',
|
|
1035
|
+
});
|
|
1036
|
+
console.log(`\n✅ Kept ${result.persona}'s note.` + (result.shipped ? ' Marked as shipped for evolution.' : ' Saved as liked (not shipped).') + '\n');
|
|
1037
|
+
break;
|
|
1038
|
+
}
|
|
1039
|
+
const result = accept.fix({
|
|
1040
|
+
project: projectVal,
|
|
1041
|
+
persona: personaVal,
|
|
1042
|
+
because: becauseVal || commentVal || '',
|
|
1043
|
+
correction: correctionVal || '',
|
|
1044
|
+
rating: ratingVal,
|
|
1045
|
+
tags: parseFeedbackTags(tagsVal),
|
|
1046
|
+
});
|
|
1047
|
+
console.log(`\n✅ Logged your fix for ${result.persona}. The team can learn from it.\n`);
|
|
1048
|
+
} catch (err) {
|
|
1049
|
+
if (err.code === 'NEED_PERSONA') {
|
|
1050
|
+
console.error('\n ✗ Which note? Add --persona zara (or arjun, meera, priya, noor, anuj, raj).\n');
|
|
1051
|
+
process.exit(1);
|
|
1052
|
+
}
|
|
1053
|
+
if (err.code === 'NEED_BECAUSE') {
|
|
1054
|
+
console.error('\n ✗ Add one sentence: --because "what was wrong or what you did instead"\n');
|
|
1055
|
+
process.exit(1);
|
|
1056
|
+
}
|
|
1057
|
+
console.error(`\n ✗ ${err.message}\n`);
|
|
1058
|
+
process.exit(1);
|
|
1059
|
+
}
|
|
1060
|
+
|
|
1061
|
+
break;
|
|
1062
|
+
}
|
|
1063
|
+
|
|
1064
|
+
case 'share': {
|
|
1065
|
+
const share = require('../lib/share');
|
|
1066
|
+
const acceptMod = require('../lib/accept');
|
|
1067
|
+
const wantSend = sendFlag || yesFlag;
|
|
1068
|
+
(async () => {
|
|
1069
|
+
try {
|
|
1070
|
+
if (!wantSend) {
|
|
1071
|
+
if (becauseVal || commentVal) {
|
|
1072
|
+
acceptMod.fix({
|
|
1073
|
+
project: projectVal,
|
|
1074
|
+
persona: personaVal,
|
|
1075
|
+
because: becauseVal || commentVal,
|
|
1076
|
+
correction: correctionVal || becauseVal || commentVal,
|
|
1077
|
+
});
|
|
1078
|
+
}
|
|
1079
|
+
const peek = share.preview({ project: projectVal, persona: personaVal, all: allFlag });
|
|
1080
|
+
if (!peek.count) {
|
|
1081
|
+
console.log('\n Nothing to send yet. After a critique: /accept no plus one sentence, then /share.\n');
|
|
1082
|
+
return;
|
|
1083
|
+
}
|
|
1084
|
+
console.log(`\n Ready to send ${peek.count} note(s) to the package (redacted — no folders, emails, or keys).`);
|
|
1085
|
+
peek.rows.slice(0, 5).forEach((r) => {
|
|
1086
|
+
console.log(` • ${r.persona}: ${(r.comment || r.correction || '').slice(0, 100)}`);
|
|
1087
|
+
});
|
|
1088
|
+
if (peek.rows.length > 5) console.log(` … and ${peek.rows.length - 5} more`);
|
|
1089
|
+
console.log(peek.hasHttp ? ' Path: configured HTTP endpoint.' : ' Path: GitHub issue on joshirishi/analyzthis_design.');
|
|
1090
|
+
console.log(' Send? Run: npx analyzthis_design share --send\n');
|
|
1091
|
+
return;
|
|
1092
|
+
}
|
|
1093
|
+
const result = await share.send({
|
|
1094
|
+
project: projectVal,
|
|
1095
|
+
persona: personaVal,
|
|
1096
|
+
because: becauseVal || commentVal || '',
|
|
1097
|
+
correction: correctionVal || '',
|
|
1098
|
+
all: allFlag,
|
|
1099
|
+
});
|
|
1100
|
+
if (result.via === 'github-link') {
|
|
1101
|
+
console.log(`\n ${result.message}`);
|
|
1102
|
+
console.log(` ${result.url}\n`);
|
|
1103
|
+
return;
|
|
1104
|
+
}
|
|
1105
|
+
console.log(`\n✅ ${result.message}` + (result.url ? `\n ${result.url}` : '') + '\n');
|
|
1106
|
+
} catch (err) {
|
|
1107
|
+
if (err.code === 'NOTHING') {
|
|
1108
|
+
console.error('\n ✗ Nothing to send yet. /accept no plus one sentence, then /share.\n');
|
|
1109
|
+
process.exit(1);
|
|
1110
|
+
}
|
|
1111
|
+
if (err.code === 'NEED_PERSONA') {
|
|
1112
|
+
console.error('\n ✗ Which note? Add --persona zara (or arjun, meera, priya, noor, anuj, raj).\n');
|
|
1113
|
+
process.exit(1);
|
|
1114
|
+
}
|
|
1115
|
+
if (err.code === 'NEED_BECAUSE') {
|
|
1116
|
+
console.error('\n ✗ Add one sentence: --because "what was wrong or what you did instead"\n');
|
|
1117
|
+
process.exit(1);
|
|
1118
|
+
}
|
|
1119
|
+
console.error(`\n ✗ ${err.message}\n`);
|
|
1120
|
+
process.exit(1);
|
|
1121
|
+
}
|
|
1122
|
+
})();
|
|
1123
|
+
break;
|
|
1124
|
+
}
|
|
1125
|
+
|
|
996
1126
|
// ── Persona feedback (v1.16) ────────────────────────────────────────────
|
|
997
1127
|
|
|
998
1128
|
case 'feedback': {
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Designer keep / skip for evolution.
|
|
5
|
+
* Slash /accept talks in yes/no. This module writes the session flags.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
var session = require('./session');
|
|
9
|
+
var feedback = require('./feedback');
|
|
10
|
+
var outcome = require('./outcome');
|
|
11
|
+
|
|
12
|
+
var PERSONA_IDS = session.PERSONA_IDS;
|
|
13
|
+
|
|
14
|
+
function resolvePersona(opts) {
|
|
15
|
+
var raw = String(opts.persona || '').toLowerCase().trim();
|
|
16
|
+
if (raw && PERSONA_IDS.indexOf(raw) === -1) {
|
|
17
|
+
var err = new Error('Unknown persona. Use: ' + PERSONA_IDS.join(', '));
|
|
18
|
+
err.code = 'BAD_PERSONA';
|
|
19
|
+
throw err;
|
|
20
|
+
}
|
|
21
|
+
var id = raw || session.inferLastPersona({ project: opts.project });
|
|
22
|
+
if (!id) {
|
|
23
|
+
var need = new Error('NEED_PERSONA');
|
|
24
|
+
need.code = 'NEED_PERSONA';
|
|
25
|
+
throw need;
|
|
26
|
+
}
|
|
27
|
+
return id;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function keep(opts) {
|
|
31
|
+
opts = opts || {};
|
|
32
|
+
var persona = resolvePersona(opts);
|
|
33
|
+
session.ensurePersonaOutput({
|
|
34
|
+
project: opts.project,
|
|
35
|
+
persona: persona,
|
|
36
|
+
text: opts.note,
|
|
37
|
+
});
|
|
38
|
+
session.markAccepted({ project: opts.project, persona: persona, accepted: true });
|
|
39
|
+
if (opts.comment) {
|
|
40
|
+
feedback.recordFeedback({
|
|
41
|
+
project: opts.project,
|
|
42
|
+
persona: persona,
|
|
43
|
+
satisfied: true,
|
|
44
|
+
rating: 5,
|
|
45
|
+
comment: opts.comment,
|
|
46
|
+
correction: '',
|
|
47
|
+
markRejected: false,
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
var shipped = opts.shipped !== false;
|
|
51
|
+
if (shipped) {
|
|
52
|
+
outcome.confirmOutcome({ project: opts.project, persona: persona, outcome: 'shipped' });
|
|
53
|
+
}
|
|
54
|
+
return { persona: persona, kept: true, shipped: shipped };
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function fix(opts) {
|
|
58
|
+
opts = opts || {};
|
|
59
|
+
var persona = resolvePersona(opts);
|
|
60
|
+
var because = String(opts.because || opts.comment || '').trim();
|
|
61
|
+
var correction = String(opts.correction || because).trim();
|
|
62
|
+
if (!because) {
|
|
63
|
+
var need = new Error('NEED_BECAUSE');
|
|
64
|
+
need.code = 'NEED_BECAUSE';
|
|
65
|
+
throw need;
|
|
66
|
+
}
|
|
67
|
+
session.ensurePersonaOutput({
|
|
68
|
+
project: opts.project,
|
|
69
|
+
persona: persona,
|
|
70
|
+
text: opts.note,
|
|
71
|
+
});
|
|
72
|
+
feedback.recordFeedback({
|
|
73
|
+
project: opts.project,
|
|
74
|
+
persona: persona,
|
|
75
|
+
satisfied: false,
|
|
76
|
+
rating: opts.rating != null ? Number(opts.rating) : 2,
|
|
77
|
+
comment: because,
|
|
78
|
+
correction: correction,
|
|
79
|
+
tags: opts.tags || ['other'],
|
|
80
|
+
markRejected: true,
|
|
81
|
+
});
|
|
82
|
+
outcome.confirmOutcome({ project: opts.project, persona: persona, outcome: 'revised' });
|
|
83
|
+
return { persona: persona, kept: false, because: because };
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function preview(opts) {
|
|
87
|
+
opts = opts || {};
|
|
88
|
+
var state = session.show({ project: opts.project });
|
|
89
|
+
return {
|
|
90
|
+
persona: session.inferLastPersona({ project: opts.project }),
|
|
91
|
+
hasSession: !!state,
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
module.exports = { keep, fix, preview, PERSONA_IDS };
|
package/dist/lib/install.js
CHANGED
|
@@ -34,6 +34,8 @@ const PROJECT_COMMANDS = [
|
|
|
34
34
|
'getting-started',
|
|
35
35
|
'devi',
|
|
36
36
|
'receipt',
|
|
37
|
+
'accept',
|
|
38
|
+
'share',
|
|
37
39
|
];
|
|
38
40
|
|
|
39
41
|
const SKILLS = [
|
|
@@ -62,6 +64,8 @@ const SKILLS = [
|
|
|
62
64
|
'design-reference',
|
|
63
65
|
'knowledge-bank',
|
|
64
66
|
'receipt',
|
|
67
|
+
'accept',
|
|
68
|
+
'share',
|
|
65
69
|
];
|
|
66
70
|
|
|
67
71
|
function getPackageVersion() {
|
|
@@ -129,6 +133,9 @@ function printWelcomeBanner(targetId, log = console.log) {
|
|
|
129
133
|
log(` ${p}design-critic 4-persona critique + composite score`);
|
|
130
134
|
log(` ${p}deliberation-protocol adversarial review rules (objections, Raj)`);
|
|
131
135
|
log(` ${p}devi host LLM: voice personas when CLI has no API keys`);
|
|
136
|
+
log(` ${p}accept keep or skip the last note (yes / no) — local evolution`);
|
|
137
|
+
log(` ${p}share send a correction to the package (preview, then yes)`);
|
|
138
|
+
log(` ${p}receipt inferred tokens for this project (not a bill)`);
|
|
132
139
|
|
|
133
140
|
log('');
|
|
134
141
|
log(' CLI (host mode — no API keys):');
|
package/dist/lib/mcp-server.js
CHANGED
|
@@ -268,9 +268,12 @@ var TOOLS = [
|
|
|
268
268
|
inputSchema: {
|
|
269
269
|
type: 'object',
|
|
270
270
|
properties: {
|
|
271
|
-
action: { type: 'string', enum: ['show', 'init', 'reset', 'accept'], description: 'show: display current state; init: create fresh; reset: delete; accept:
|
|
272
|
-
persona: { type: 'string', description: 'Persona ID (for accept action)' },
|
|
273
|
-
reject: { type: 'boolean', description: '
|
|
271
|
+
action: { type: 'string', enum: ['show', 'init', 'reset', 'accept'], description: 'show: display current state; init: create fresh; reset: delete; accept: keep or skip a persona note (designer /accept)' },
|
|
272
|
+
persona: { type: 'string', description: 'Persona ID (for accept action). Optional — last persona if omitted.' },
|
|
273
|
+
reject: { type: 'boolean', description: 'Skip / fix instead of keep (for accept action)' },
|
|
274
|
+
because: { type: 'string', description: 'One sentence: what was wrong or what you did instead (when reject is true)' },
|
|
275
|
+
comment: { type: 'string', description: 'Optional note on keep, or alias for because on skip' },
|
|
276
|
+
shipped: { type: 'boolean', description: 'On keep: mark shipped (default true). False = liked only.' },
|
|
274
277
|
},
|
|
275
278
|
required: ['action'],
|
|
276
279
|
},
|
|
@@ -591,9 +594,18 @@ function handleSession(args) {
|
|
|
591
594
|
return { result: 'Session reset.' };
|
|
592
595
|
}
|
|
593
596
|
if (action === 'accept') {
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
+
var accept = require('./accept');
|
|
598
|
+
if (args.reject) {
|
|
599
|
+
return { result: JSON.stringify(accept.fix({
|
|
600
|
+
persona: args.persona,
|
|
601
|
+
because: args.because || args.comment || '',
|
|
602
|
+
})) };
|
|
603
|
+
}
|
|
604
|
+
return { result: JSON.stringify(accept.keep({
|
|
605
|
+
persona: args.persona,
|
|
606
|
+
comment: args.comment || '',
|
|
607
|
+
shipped: args.shipped !== false,
|
|
608
|
+
})) };
|
|
597
609
|
}
|
|
598
610
|
} catch (e) {
|
|
599
611
|
return { error: e.message };
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Inferred token receipts for Claude-path (slash / MCP) turns.
|
|
5
|
+
* Never call this a bill. Never multiply into a monthly dollar. Never say verified.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
var session = require('./session');
|
|
9
|
+
|
|
10
|
+
var HOST_TURNS_CAP = 40;
|
|
11
|
+
var CHARS_PER_TOKEN = 4;
|
|
12
|
+
|
|
13
|
+
function inferTokens(text) {
|
|
14
|
+
return Math.ceil(String(text || '').length / CHARS_PER_TOKEN);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function formatFooter(inferredIn) {
|
|
18
|
+
return (
|
|
19
|
+
'\n\n---\nInferred context this turn: ' +
|
|
20
|
+
inferredIn +
|
|
21
|
+
' tokens (not a bill). Do not invent a dollar figure.'
|
|
22
|
+
);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function wrapPayload(text, meta) {
|
|
26
|
+
var body = String(text || '');
|
|
27
|
+
var inferredIn = inferTokens(body);
|
|
28
|
+
try {
|
|
29
|
+
session.logHostTurn({
|
|
30
|
+
path: (meta && meta.path) || 'mcp',
|
|
31
|
+
persona: (meta && meta.persona) || '',
|
|
32
|
+
inferred_in: inferredIn,
|
|
33
|
+
project: meta && meta.project,
|
|
34
|
+
verdicts: (meta && meta.verdicts) || 0,
|
|
35
|
+
});
|
|
36
|
+
} catch (e) {
|
|
37
|
+
// Session write is best-effort — never fail a tool call for a receipt.
|
|
38
|
+
}
|
|
39
|
+
return body + formatFooter(inferredIn);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function tokensPerVerdict(state) {
|
|
43
|
+
if (!state || !state.metrics) return null;
|
|
44
|
+
var m = state.metrics;
|
|
45
|
+
var host = (m.host_turns || []).reduce(function (sum, turn) {
|
|
46
|
+
return sum + (turn.inferred_in || 0);
|
|
47
|
+
}, 0);
|
|
48
|
+
var cliIn = m.input_tokens_est || 0;
|
|
49
|
+
var totalIn = host + cliIn;
|
|
50
|
+
var verdicts = m.verdicts_this_run || 0;
|
|
51
|
+
if (!verdicts && (m.experts_run || []).length) verdicts = 1;
|
|
52
|
+
if (!verdicts && (m.host_turns || []).length) verdicts = 1;
|
|
53
|
+
if (!verdicts || !totalIn) return null;
|
|
54
|
+
return Math.round(totalIn / verdicts);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function formatReport(state) {
|
|
58
|
+
if (!state) {
|
|
59
|
+
return 'No session found. Run: npx analyzthis_design session init';
|
|
60
|
+
}
|
|
61
|
+
var m = state.metrics || {};
|
|
62
|
+
var turns = m.host_turns || [];
|
|
63
|
+
var tpv = tokensPerVerdict(state);
|
|
64
|
+
var lines = [
|
|
65
|
+
'Receipt — inferred, not a bill',
|
|
66
|
+
'Project: ' + (state.project_id || ''),
|
|
67
|
+
'CLI est. tokens: ' + (m.input_tokens_est || 0) + ' in / ' + (m.output_tokens_est || 0) + ' out',
|
|
68
|
+
'Host turns logged: ' + turns.length,
|
|
69
|
+
];
|
|
70
|
+
turns.slice(-8).forEach(function (turn) {
|
|
71
|
+
lines.push(
|
|
72
|
+
' ' +
|
|
73
|
+
(turn.at || '') +
|
|
74
|
+
' ' +
|
|
75
|
+
(turn.path || '') +
|
|
76
|
+
' ' +
|
|
77
|
+
(turn.persona || '-') +
|
|
78
|
+
' ' +
|
|
79
|
+
(turn.inferred_in || 0) +
|
|
80
|
+
' tok'
|
|
81
|
+
);
|
|
82
|
+
});
|
|
83
|
+
if (tpv != null) lines.push('Tokens per verdict: ' + tpv + ' (inferred + CLI est. input / verdicts)');
|
|
84
|
+
else lines.push('Tokens per verdict: n/a — no host turn or CLI run yet');
|
|
85
|
+
lines.push('You cannot know Claude’s real usage from slash alone. Do not invent a dollar figure.');
|
|
86
|
+
return lines.join('\n');
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function report(opts) {
|
|
90
|
+
var state = session.show({ project: opts && opts.project });
|
|
91
|
+
return formatReport(state);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
module.exports = {
|
|
95
|
+
inferTokens: inferTokens,
|
|
96
|
+
formatFooter: formatFooter,
|
|
97
|
+
wrapPayload: wrapPayload,
|
|
98
|
+
tokensPerVerdict: tokensPerVerdict,
|
|
99
|
+
formatReport: formatReport,
|
|
100
|
+
report: report,
|
|
101
|
+
HOST_TURNS_CAP: HOST_TURNS_CAP,
|
|
102
|
+
};
|
package/dist/lib/session.js
CHANGED
|
@@ -177,8 +177,58 @@ function listProjects() {
|
|
|
177
177
|
* lightweight feedback flag the future LoRA training-pair export reads.
|
|
178
178
|
* No-ops if the persona hasn't produced an output yet.
|
|
179
179
|
*/
|
|
180
|
+
const PERSONA_IDS = ['arjun', 'meera', 'priya', 'zara', 'noor', 'anuj', 'raj', 'kavi'];
|
|
181
|
+
|
|
182
|
+
function inferLastPersona({ project } = {}) {
|
|
183
|
+
const state = show({ project: project || getProjectId() });
|
|
184
|
+
if (!state) return null;
|
|
185
|
+
const turns = (state.metrics && state.metrics.host_turns) || [];
|
|
186
|
+
for (let i = turns.length - 1; i >= 0; i--) {
|
|
187
|
+
const id = turns[i] && turns[i].persona;
|
|
188
|
+
if (id && PERSONA_IDS.indexOf(id) !== -1) return id;
|
|
189
|
+
}
|
|
190
|
+
const outputs = state.persona_outputs || {};
|
|
191
|
+
let best = null;
|
|
192
|
+
let bestAt = '';
|
|
193
|
+
Object.keys(outputs).forEach((id) => {
|
|
194
|
+
const at = (outputs[id] && outputs[id].at) || '';
|
|
195
|
+
if (at >= bestAt) {
|
|
196
|
+
bestAt = at;
|
|
197
|
+
best = id;
|
|
198
|
+
}
|
|
199
|
+
});
|
|
200
|
+
if (best) return best;
|
|
201
|
+
const experts = state.routing_decision && state.routing_decision.experts;
|
|
202
|
+
if (Array.isArray(experts) && experts[0]) return experts[0];
|
|
203
|
+
return null;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
// Slash / MCP notes often never write persona_outputs. Create a stub so keep/fix still works.
|
|
207
|
+
function ensurePersonaOutput({ project, persona, text } = {}) {
|
|
208
|
+
const projectId = project || getProjectId();
|
|
209
|
+
let state = show({ project: projectId });
|
|
210
|
+
if (!state) {
|
|
211
|
+
init({ project: projectId });
|
|
212
|
+
state = show({ project: projectId });
|
|
213
|
+
}
|
|
214
|
+
const outputs = { ...(state.persona_outputs || {}) };
|
|
215
|
+
let created = false;
|
|
216
|
+
if (!outputs[persona]) {
|
|
217
|
+
outputs[persona] = {
|
|
218
|
+
text: text || '(slash — designer marked this note; full text was in chat)',
|
|
219
|
+
at: new Date().toISOString(),
|
|
220
|
+
accepted: null,
|
|
221
|
+
source: 'slash',
|
|
222
|
+
};
|
|
223
|
+
created = true;
|
|
224
|
+
state = update({ project: projectId, patch: { persona_outputs: outputs } });
|
|
225
|
+
}
|
|
226
|
+
return { projectId, state, created };
|
|
227
|
+
}
|
|
228
|
+
|
|
180
229
|
function markAccepted({ project, persona, accepted = true } = {}) {
|
|
181
230
|
const projectId = project || getProjectId();
|
|
231
|
+
ensurePersonaOutput({ project: projectId, persona });
|
|
182
232
|
const state = show({ project: projectId });
|
|
183
233
|
if (!state || !state.persona_outputs || !state.persona_outputs[persona]) {
|
|
184
234
|
return { updated: false, reason: `No output recorded for persona "${persona}" in this session yet.` };
|
|
@@ -213,5 +263,6 @@ function logHostTurn({ project, path: turnPath, persona, inferred_in, verdicts =
|
|
|
213
263
|
}
|
|
214
264
|
|
|
215
265
|
module.exports = {
|
|
216
|
-
getProjectId, sessionPath, sessionDir, init, show, reset, update, listProjects,
|
|
266
|
+
getProjectId, sessionPath, sessionDir, init, show, reset, update, listProjects,
|
|
267
|
+
markAccepted, ensurePersonaOutput, inferLastPersona, PERSONA_IDS, logHostTurn, SESSIONS_ROOT,
|
|
217
268
|
};
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Designer share — send local corrections back to the published package.
|
|
5
|
+
* Slash /share talks in yes/no. HTTP submit if configured; else GitHub issue.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
var { spawnSync } = require('child_process');
|
|
9
|
+
var accept = require('./accept');
|
|
10
|
+
var submit = require('./feedback-submit');
|
|
11
|
+
|
|
12
|
+
var REPO = 'joshirishi/analyzthis_design';
|
|
13
|
+
var ISSUE_NEW = 'https://github.com/' + REPO + '/issues/new';
|
|
14
|
+
|
|
15
|
+
function preview(opts) {
|
|
16
|
+
opts = opts || {};
|
|
17
|
+
var cfg = submit.resolveSubmitConfig();
|
|
18
|
+
var entries = submit.collectUnsentEntries({
|
|
19
|
+
project: opts.project,
|
|
20
|
+
all: !!opts.all,
|
|
21
|
+
persona: opts.persona,
|
|
22
|
+
});
|
|
23
|
+
var rows = entries.map(function (e) {
|
|
24
|
+
var payload = submit.entryToSubmitPayload(e, cfg);
|
|
25
|
+
return {
|
|
26
|
+
id: e.id,
|
|
27
|
+
persona: payload.persona,
|
|
28
|
+
comment: payload.user_comment,
|
|
29
|
+
correction: payload.assistant_preferred,
|
|
30
|
+
};
|
|
31
|
+
});
|
|
32
|
+
return {
|
|
33
|
+
count: rows.length,
|
|
34
|
+
rows: rows,
|
|
35
|
+
hasHttp: !!(cfg.url && cfg.anonKey),
|
|
36
|
+
endpoint: cfg.url || '',
|
|
37
|
+
consent: !!(submit.loadConsent() && submit.loadConsent().opted_in),
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function formatIssueBody(rows) {
|
|
42
|
+
var lines = [
|
|
43
|
+
'Shared from `/share` (designer keep/skip). Redacted. No paths, emails, or keys.',
|
|
44
|
+
'',
|
|
45
|
+
];
|
|
46
|
+
rows.forEach(function (r, i) {
|
|
47
|
+
lines.push('### ' + (i + 1) + '. ' + r.persona);
|
|
48
|
+
if (r.comment) lines.push('**What was wrong:** ' + r.comment);
|
|
49
|
+
if (r.correction) lines.push('**What we did instead:** ' + r.correction);
|
|
50
|
+
lines.push('');
|
|
51
|
+
});
|
|
52
|
+
return lines.join('\n');
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function issueWebUrl(title, body) {
|
|
56
|
+
return ISSUE_NEW
|
|
57
|
+
+ '?labels=persona-feedback'
|
|
58
|
+
+ '&title=' + encodeURIComponent(title)
|
|
59
|
+
+ '&body=' + encodeURIComponent(body);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function tryGithubIssue(title, body) {
|
|
63
|
+
var created = spawnSync(
|
|
64
|
+
'gh',
|
|
65
|
+
['issue', 'create', '--repo', REPO, '--title', title, '--label', 'persona-feedback', '--body', body],
|
|
66
|
+
{ encoding: 'utf8', timeout: 20000 }
|
|
67
|
+
);
|
|
68
|
+
if (created.status === 0 && created.stdout) {
|
|
69
|
+
return { ok: true, url: created.stdout.trim() };
|
|
70
|
+
}
|
|
71
|
+
return { ok: false, error: (created.stderr || created.stdout || 'gh failed').trim() };
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
async function send(opts) {
|
|
75
|
+
opts = opts || {};
|
|
76
|
+
var because = String(opts.because || opts.comment || '').trim();
|
|
77
|
+
if (because) {
|
|
78
|
+
accept.fix({
|
|
79
|
+
project: opts.project,
|
|
80
|
+
persona: opts.persona,
|
|
81
|
+
because: because,
|
|
82
|
+
correction: opts.correction || because,
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
var peek = preview(opts);
|
|
87
|
+
if (!peek.count) {
|
|
88
|
+
var empty = new Error('NOTHING');
|
|
89
|
+
empty.code = 'NOTHING';
|
|
90
|
+
throw empty;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
if (peek.hasHttp) {
|
|
94
|
+
var result = await submit.submitFeedback({
|
|
95
|
+
project: opts.project,
|
|
96
|
+
all: !!opts.all,
|
|
97
|
+
persona: opts.persona,
|
|
98
|
+
yes: true,
|
|
99
|
+
});
|
|
100
|
+
return {
|
|
101
|
+
sent: result.submitted || 0,
|
|
102
|
+
via: 'http',
|
|
103
|
+
url: result.endpoint || '',
|
|
104
|
+
message: result.message,
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
var title = '[feedback] ' + peek.rows[0].persona + ': ' + (peek.rows[0].comment || 'correction').slice(0, 72);
|
|
109
|
+
var body = formatIssueBody(peek.rows);
|
|
110
|
+
var gh = tryGithubIssue(title, body);
|
|
111
|
+
if (gh.ok) {
|
|
112
|
+
submit.markEntriesSubmitted(peek.rows.map(function (r) { return r.id; }));
|
|
113
|
+
return {
|
|
114
|
+
sent: peek.count,
|
|
115
|
+
via: 'github',
|
|
116
|
+
url: gh.url,
|
|
117
|
+
message: 'Opened a GitHub issue so the package can learn.',
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
return {
|
|
122
|
+
sent: 0,
|
|
123
|
+
via: 'github-link',
|
|
124
|
+
url: issueWebUrl(title, body),
|
|
125
|
+
title: title,
|
|
126
|
+
body: body,
|
|
127
|
+
message: 'Could not open GitHub from here. Use the link — nothing secret is in it.',
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
module.exports = { preview, send, formatIssueBody, issueWebUrl, REPO };
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: accept
|
|
3
|
+
description: Keep or skip the last persona note for evolution. Designer types /accept then yes or no — no CLI flags to remember.
|
|
4
|
+
disable-model-invocation: true
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Accept — keep or skip
|
|
8
|
+
|
|
9
|
+
You help a designer mark the last persona note (Zara, Arjun, …) so the team can evolve. They should never type `npx` flags.
|
|
10
|
+
|
|
11
|
+
## What to do
|
|
12
|
+
|
|
13
|
+
1. Read the words after `/accept` (and this chat).
|
|
14
|
+
2. Decide keep vs skip:
|
|
15
|
+
- **Keep:** yes, keep, ship, good, like, 👍
|
|
16
|
+
- **Skip:** no, skip, fix, wrong, reject, 👎
|
|
17
|
+
3. If they did not say keep or skip, ask **once** in plain language:
|
|
18
|
+
|
|
19
|
+
> Keep this note? Reply **yes** (we’re taking it) or **no** plus one sentence.
|
|
20
|
+
|
|
21
|
+
4. Infer the persona from this chat (`/zara`, `/arjun`, …). If unclear, ask **once**:
|
|
22
|
+
|
|
23
|
+
> Was this Zara, Arjun, Meera, Priya, Noor, Anuj, or Raj?
|
|
24
|
+
|
|
25
|
+
5. On **skip**, you need one sentence (what was wrong, or what they did instead). If missing, ask **once**. Then stop asking.
|
|
26
|
+
6. Run the CLI yourself. Do not ask them to copy commands.
|
|
27
|
+
|
|
28
|
+
**Keep:**
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
npx analyzthis_design accept --keep --persona zara
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
**Skip:**
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
npx analyzthis_design accept --fix --persona zara --because "one sentence from the designer"
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Change `zara` to the persona they used. If they already named it in `/accept yes zara`, pass that.
|
|
41
|
+
|
|
42
|
+
7. Reply in **one or two short sentences**. Example: “Saved. Zara’s note is marked keep.” or “Saved. We logged your fix so the team can learn.” After a skip, you may mention they can type `/share` to send it to the package. No JSON. No dollar figures. No flag tutorial unless the command failed.
|
|
43
|
+
|
|
44
|
+
## If the command failed
|
|
45
|
+
|
|
46
|
+
Say what happened in plain language. If it asks which persona or for one sentence, ask the designer that — still no flags.
|
|
47
|
+
|
|
48
|
+
## Do not
|
|
49
|
+
|
|
50
|
+
- Invent a monthly cost or a verified token bill
|
|
51
|
+
- Apply evolve patches (`evolve --apply`) from this command
|
|
52
|
+
- Edit product code
|
|
@@ -36,6 +36,9 @@ This runs **Kavi** — scans your repo, builds an Obsidian vault, and syncs a **
|
|
|
36
36
|
| Set visual direction with references + team debate | `/mood-board` | Collect web/DS references, tag, deliberate, converge |
|
|
37
37
|
| Inspect the chunked execution planner | `/chunk-planner` | See how tasks are split into model-routed chunks |
|
|
38
38
|
| Run legacy single-pass orchestrator | `/run-unchunked` | Skip planner overhead for quick single-expert tasks |
|
|
39
|
+
| Keep or skip the last persona note | `/accept` | Yes or no (plus one sentence if no). Local evolution — no CLI flags. |
|
|
40
|
+
| Send a correction to the package | `/share` | Preview, then yes. Redacted. GitHub or HTTP — no CLI flags. |
|
|
41
|
+
| See inferred tokens after a critique | `/receipt` | Not a bill. Not a monthly dollar. |
|
|
39
42
|
| Make the team learn from accepted outputs | `npx analyzthis_design evolve --extract` | Harvests lessons + proposes prompt/reference/router patches |
|
|
40
43
|
| Track whether a persona's advice actually shipped | `npx analyzthis_design outcome --confirm` | Labels outcome: shipped / revised / blocked / missed |
|
|
41
44
|
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: share
|
|
3
|
+
description: Send a correction back to the analyzthis_design package. Designer types /share then yes — no CLI flags. Preview first. Redacted. Not a bill.
|
|
4
|
+
disable-model-invocation: true
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Share — send a note back to the package
|
|
8
|
+
|
|
9
|
+
You help a designer send a correction to the **published** team (npm package / GitHub). Local `/accept` stays on their machine until they share.
|
|
10
|
+
|
|
11
|
+
They should never type `npx` flags.
|
|
12
|
+
|
|
13
|
+
## What to do
|
|
14
|
+
|
|
15
|
+
1. Read the words after `/share` (and this chat).
|
|
16
|
+
2. If they gave a sentence (what was wrong / what they did instead) and have not `/accept`’d yet, treat that as the note to share.
|
|
17
|
+
3. Always **preview first** unless they already said **yes** on a preview you just showed:
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
npx analyzthis_design share
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
4. Show the preview in plain language. Example:
|
|
24
|
+
|
|
25
|
+
> Ready to send **1** note to the package (Zara): “too much motion on the daily table.”
|
|
26
|
+
> This is redacted — no folder names, emails, or keys.
|
|
27
|
+
> Send it? Reply **yes** or **no**.
|
|
28
|
+
|
|
29
|
+
5. **no** / cancel / skip → stop. Say “Not sent. It stays on your machine.”
|
|
30
|
+
6. **yes** / send / share → run:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
npx analyzthis_design share --send
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
If they included a new sentence and a persona, add `--because "..."` and `--persona zara` (change the name). Do not ask them to type those flags.
|
|
37
|
+
|
|
38
|
+
7. Reply in **one or two short sentences**. If the command printed a GitHub URL, include that link. No JSON dump. No dollar figures.
|
|
39
|
+
|
|
40
|
+
## If nothing is waiting
|
|
41
|
+
|
|
42
|
+
Say: “Nothing to send yet. After a critique, `/accept no` plus one sentence, then `/share`.”
|
|
43
|
+
If they already typed a sentence in this `/share`, run preview with that sentence recorded (the CLI `--because` path) and continue from step 4.
|
|
44
|
+
|
|
45
|
+
## If the command failed
|
|
46
|
+
|
|
47
|
+
Plain language only. If it asks which persona or for one sentence, ask that once — still no flags.
|
|
48
|
+
|
|
49
|
+
## Do not
|
|
50
|
+
|
|
51
|
+
- Send without a yes (unless they typed `/share yes` on a preview you already showed)
|
|
52
|
+
- Invent that HTTP or GitHub succeeded
|
|
53
|
+
- Apply evolve patches
|
|
54
|
+
- Edit product code
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "analyzthis_design",
|
|
3
|
-
"version": "2.4.
|
|
3
|
+
"version": "2.4.1",
|
|
4
4
|
"description": "8 AI design personas — v2.2 project-scoped knowledge bank (no cross-project vault entanglement), v2.0 chunked execution with frontier planner + free/cheap chunk models, adversarial deliberation loops, opt-in community feedback, Kavi knowledge collection, DesignSpec producer path, wireframe skills, UX critique, Agent Skills for Cursor, Claude, Codex, Grok, Windsurf. Plain source — no obfuscation, no auto-install.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cursor",
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: accept
|
|
3
|
+
description: Keep or skip the last persona note for evolution. Designer types /accept then yes or no — no CLI flags to remember.
|
|
4
|
+
disable-model-invocation: true
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Accept — keep or skip
|
|
8
|
+
|
|
9
|
+
You help a designer mark the last persona note (Zara, Arjun, …) so the team can evolve. They should never type `npx` flags.
|
|
10
|
+
|
|
11
|
+
## What to do
|
|
12
|
+
|
|
13
|
+
1. Read the words after `/accept` (and this chat).
|
|
14
|
+
2. Decide keep vs skip:
|
|
15
|
+
- **Keep:** yes, keep, ship, good, like, 👍
|
|
16
|
+
- **Skip:** no, skip, fix, wrong, reject, 👎
|
|
17
|
+
3. If they did not say keep or skip, ask **once** in plain language:
|
|
18
|
+
|
|
19
|
+
> Keep this note? Reply **yes** (we’re taking it) or **no** plus one sentence.
|
|
20
|
+
|
|
21
|
+
4. Infer the persona from this chat (`/zara`, `/arjun`, …). If unclear, ask **once**:
|
|
22
|
+
|
|
23
|
+
> Was this Zara, Arjun, Meera, Priya, Noor, Anuj, or Raj?
|
|
24
|
+
|
|
25
|
+
5. On **skip**, you need one sentence (what was wrong, or what they did instead). If missing, ask **once**. Then stop asking.
|
|
26
|
+
6. Run the CLI yourself. Do not ask them to copy commands.
|
|
27
|
+
|
|
28
|
+
**Keep:**
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
npx analyzthis_design accept --keep --persona zara
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
**Skip:**
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
npx analyzthis_design accept --fix --persona zara --because "one sentence from the designer"
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Change `zara` to the persona they used. If they already named it in `/accept yes zara`, pass that.
|
|
41
|
+
|
|
42
|
+
7. Reply in **one or two short sentences**. Example: “Saved. Zara’s note is marked keep.” or “Saved. We logged your fix so the team can learn.” After a skip, you may mention they can type `/share` to send it to the package. No JSON. No dollar figures. No flag tutorial unless the command failed.
|
|
43
|
+
|
|
44
|
+
## If the command failed
|
|
45
|
+
|
|
46
|
+
Say what happened in plain language. If it asks which persona or for one sentence, ask the designer that — still no flags.
|
|
47
|
+
|
|
48
|
+
## Do not
|
|
49
|
+
|
|
50
|
+
- Invent a monthly cost or a verified token bill
|
|
51
|
+
- Apply evolve patches (`evolve --apply`) from this command
|
|
52
|
+
- Edit product code
|
|
@@ -36,6 +36,9 @@ This runs **Kavi** — scans your repo, builds an Obsidian vault, and syncs a **
|
|
|
36
36
|
| Set visual direction with references + team debate | `/mood-board` | Collect web/DS references, tag, deliberate, converge |
|
|
37
37
|
| Inspect the chunked execution planner | `/chunk-planner` | See how tasks are split into model-routed chunks |
|
|
38
38
|
| Run legacy single-pass orchestrator | `/run-unchunked` | Skip planner overhead for quick single-expert tasks |
|
|
39
|
+
| Keep or skip the last persona note | `/accept` | Yes or no (plus one sentence if no). Local evolution — no CLI flags. |
|
|
40
|
+
| Send a correction to the package | `/share` | Preview, then yes. Redacted. GitHub or HTTP — no CLI flags. |
|
|
41
|
+
| See inferred tokens after a critique | `/receipt` | Not a bill. Not a monthly dollar. |
|
|
39
42
|
| Make the team learn from accepted outputs | `npx analyzthis_design evolve --extract` | Harvests lessons + proposes prompt/reference/router patches |
|
|
40
43
|
| Track whether a persona's advice actually shipped | `npx analyzthis_design outcome --confirm` | Labels outcome: shipped / revised / blocked / missed |
|
|
41
44
|
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: share
|
|
3
|
+
description: Send a correction back to the analyzthis_design package. Designer types /share then yes — no CLI flags. Preview first. Redacted. Not a bill.
|
|
4
|
+
disable-model-invocation: true
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Share — send a note back to the package
|
|
8
|
+
|
|
9
|
+
You help a designer send a correction to the **published** team (npm package / GitHub). Local `/accept` stays on their machine until they share.
|
|
10
|
+
|
|
11
|
+
They should never type `npx` flags.
|
|
12
|
+
|
|
13
|
+
## What to do
|
|
14
|
+
|
|
15
|
+
1. Read the words after `/share` (and this chat).
|
|
16
|
+
2. If they gave a sentence (what was wrong / what they did instead) and have not `/accept`’d yet, treat that as the note to share.
|
|
17
|
+
3. Always **preview first** unless they already said **yes** on a preview you just showed:
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
npx analyzthis_design share
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
4. Show the preview in plain language. Example:
|
|
24
|
+
|
|
25
|
+
> Ready to send **1** note to the package (Zara): “too much motion on the daily table.”
|
|
26
|
+
> This is redacted — no folder names, emails, or keys.
|
|
27
|
+
> Send it? Reply **yes** or **no**.
|
|
28
|
+
|
|
29
|
+
5. **no** / cancel / skip → stop. Say “Not sent. It stays on your machine.”
|
|
30
|
+
6. **yes** / send / share → run:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
npx analyzthis_design share --send
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
If they included a new sentence and a persona, add `--because "..."` and `--persona zara` (change the name). Do not ask them to type those flags.
|
|
37
|
+
|
|
38
|
+
7. Reply in **one or two short sentences**. If the command printed a GitHub URL, include that link. No JSON dump. No dollar figures.
|
|
39
|
+
|
|
40
|
+
## If nothing is waiting
|
|
41
|
+
|
|
42
|
+
Say: “Nothing to send yet. After a critique, `/accept no` plus one sentence, then `/share`.”
|
|
43
|
+
If they already typed a sentence in this `/share`, run preview with that sentence recorded (the CLI `--because` path) and continue from step 4.
|
|
44
|
+
|
|
45
|
+
## If the command failed
|
|
46
|
+
|
|
47
|
+
Plain language only. If it asks which persona or for one sentence, ask that once — still no flags.
|
|
48
|
+
|
|
49
|
+
## Do not
|
|
50
|
+
|
|
51
|
+
- Send without a yes (unless they typed `/share yes` on a preview you already showed)
|
|
52
|
+
- Invent that HTTP or GitHub succeeded
|
|
53
|
+
- Apply evolve patches
|
|
54
|
+
- Edit product code
|