@contextium/cli 1.0.31 → 1.0.33

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/dist/index.js CHANGED
@@ -27,6 +27,7 @@ import { deleteFileCommand } from './commands/delete-file.js';
27
27
  import { updateLibraryCommand } from './commands/update-library.js';
28
28
  import { versionsCommand } from './commands/versions.js';
29
29
  import { structureCommand } from './commands/structure.js';
30
+ import { recordCommand, maybeShowReviewPrompt } from './lib/review-prompt.js';
30
31
  import { createRequire } from 'module';
31
32
  const require = createRequire(import.meta.url);
32
33
  const pkg = require('../package.json');
@@ -106,6 +107,15 @@ program.addCommand(deleteFileCommand);
106
107
  program.addCommand(updateLibraryCommand);
107
108
  program.addCommand(versionsCommand);
108
109
  program.addCommand(structureCommand);
110
+ // Skip review prompt for auth/meta commands
111
+ const SKIP_REVIEW_COMMANDS = new Set(['login', 'logout', 'whoami', 'setup', 'setup-claude']);
112
+ program.hook('postAction', async (thisCommand) => {
113
+ const name = thisCommand.name();
114
+ if (!SKIP_REVIEW_COMMANDS.has(name)) {
115
+ await recordCommand();
116
+ await maybeShowReviewPrompt();
117
+ }
118
+ });
109
119
  // Parse command line
110
120
  program.parse();
111
121
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACnC,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAA;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;AACpD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAChD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAChD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAC9C,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;AACpD,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAA;AAC5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAA;AACzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAA;AAC1D,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAA;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAA;AAClD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAChD,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAA;AAC/D,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAA;AAClD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;AACpD,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAA;AAC9D,OAAO,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAA;AACnE,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAA;AACvD,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAA;AACzD,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAA;AAC7D,OAAO,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAA;AACnE,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAA;AACxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAA;AAC1D,OAAO,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAA;AACtC,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;AAC9C,MAAM,GAAG,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAA;AAEtC,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAA;AAE7B,OAAO;KACJ,IAAI,CAAC,YAAY,CAAC;KAClB,WAAW,CAAC,0HAA0H,CAAC;KAEvI,OAAO,CAAC,GAAG,CAAC,OAAO,EAAE,eAAe,CAAC;KACrC,WAAW,CAAC,OAAO,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAwCvB,CAAC,CAAA;AAEF,gBAAgB;AAChB,OAAO,CAAC,UAAU,CAAC,YAAY,CAAC,CAAA;AAChC,OAAO,CAAC,UAAU,CAAC,aAAa,CAAC,CAAA;AACjC,OAAO,CAAC,UAAU,CAAC,aAAa,CAAC,CAAA;AAEjC,iBAAiB;AACjB,OAAO,CAAC,UAAU,CAAC,YAAY,CAAC,CAAA;AAChC,OAAO,CAAC,UAAU,CAAC,WAAW,CAAC,CAAA;AAC/B,OAAO,CAAC,UAAU,CAAC,kBAAkB,CAAC,CAAA;AAEtC,gBAAgB;AAChB,OAAO,CAAC,UAAU,CAAC,iBAAiB,CAAC,CAAA;AACrC,OAAO,CAAC,UAAU,CAAC,gBAAgB,CAAC,CAAA;AACpC,OAAO,CAAC,UAAU,CAAC,eAAe,CAAC,CAAA;AACnC,OAAO,CAAC,UAAU,CAAC,gBAAgB,CAAC,CAAA;AACpC,OAAO,CAAC,UAAU,CAAC,YAAY,CAAC,CAAA;AAChC,OAAO,CAAC,UAAU,CAAC,WAAW,CAAC,CAAA;AAC/B,OAAO,CAAC,UAAU,CAAC,WAAW,CAAC,CAAA;AAC/B,OAAO,CAAC,UAAU,CAAC,UAAU,CAAC,CAAA;AAC9B,OAAO,CAAC,UAAU,CAAC,aAAa,CAAC,CAAA;AACjC,OAAO,CAAC,UAAU,CAAC,aAAa,CAAC,CAAA;AACjC,OAAO,CAAC,UAAU,CAAC,WAAW,CAAC,CAAA;AAC/B,OAAO,CAAC,UAAU,CAAC,aAAa,CAAC,CAAA;AACjC,OAAO,CAAC,UAAU,CAAC,aAAa,CAAC,CAAA;AACjC,OAAO,CAAC,UAAU,CAAC,kBAAkB,CAAC,CAAA;AACtC,OAAO,CAAC,UAAU,CAAC,oBAAoB,CAAC,CAAA;AACxC,OAAO,CAAC,UAAU,CAAC,cAAc,CAAC,CAAA;AAClC,OAAO,CAAC,UAAU,CAAC,eAAe,CAAC,CAAA;AACnC,OAAO,CAAC,UAAU,CAAC,iBAAiB,CAAC,CAAA;AACrC,OAAO,CAAC,UAAU,CAAC,oBAAoB,CAAC,CAAA;AACxC,OAAO,CAAC,UAAU,CAAC,eAAe,CAAC,CAAA;AACnC,OAAO,CAAC,UAAU,CAAC,gBAAgB,CAAC,CAAA;AAEpC,qBAAqB;AACrB,OAAO,CAAC,KAAK,EAAE,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export declare function recordCommand(): Promise<void>;
2
+ export declare function maybeShowReviewPrompt(): Promise<void>;
3
+ //# sourceMappingURL=review-prompt.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"review-prompt.d.ts","sourceRoot":"","sources":["../../src/lib/review-prompt.ts"],"names":[],"mappings":"AA2CA,wBAAsB,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC,CAInD;AA+DD,wBAAsB,qBAAqB,IAAI,OAAO,CAAC,IAAI,CAAC,CAyD3D"}
@@ -0,0 +1,149 @@
1
+ import fs from 'fs/promises';
2
+ import path from 'path';
3
+ import os from 'os';
4
+ import readline from 'readline';
5
+ import { chalk } from './output.js';
6
+ import { getAccessToken } from './msal.js';
7
+ const STATE_DIR = path.join(os.homedir(), '.contextium');
8
+ const STATE_PATH = path.join(STATE_DIR, 'review-state.json');
9
+ const API_URL = 'https://api.contextium.io/api/v1';
10
+ // Show after this many commands (then every 30 after that, server enforces 90-day cooldown)
11
+ const FIRST_PROMPT_AT = 15;
12
+ const REPEAT_EVERY = 30;
13
+ // Must have been using the CLI for at least this many days before prompting
14
+ const MIN_DAYS_BEFORE_FIRST = 2;
15
+ async function loadState() {
16
+ try {
17
+ const raw = await fs.readFile(STATE_PATH, 'utf-8');
18
+ return JSON.parse(raw);
19
+ }
20
+ catch {
21
+ return {
22
+ commandCount: 0,
23
+ firstRunAt: new Date().toISOString(),
24
+ lastPromptedAt: null,
25
+ neverAsk: false,
26
+ };
27
+ }
28
+ }
29
+ async function saveState(state) {
30
+ await fs.mkdir(STATE_DIR, { recursive: true });
31
+ await fs.writeFile(STATE_PATH, JSON.stringify(state, null, 2), 'utf-8');
32
+ }
33
+ export async function recordCommand() {
34
+ const state = await loadState();
35
+ state.commandCount += 1;
36
+ await saveState(state);
37
+ }
38
+ function shouldShow(state) {
39
+ if (state.neverAsk)
40
+ return false;
41
+ if (!process.stdout.isTTY)
42
+ return false;
43
+ const daysSinceFirst = (Date.now() - new Date(state.firstRunAt).getTime()) / (1000 * 60 * 60 * 24);
44
+ if (daysSinceFirst < MIN_DAYS_BEFORE_FIRST)
45
+ return false;
46
+ const count = state.commandCount;
47
+ if (count < FIRST_PROMPT_AT)
48
+ return false;
49
+ // First trigger
50
+ if (count === FIRST_PROMPT_AT)
51
+ return true;
52
+ // Subsequent triggers at intervals above the first threshold
53
+ return (count - FIRST_PROMPT_AT) % REPEAT_EVERY === 0;
54
+ }
55
+ async function checkEligibility(token) {
56
+ try {
57
+ const res = await fetch(`${API_URL}/reviews/eligibility`, {
58
+ headers: { Authorization: `Bearer ${token}` },
59
+ });
60
+ if (!res.ok)
61
+ return false;
62
+ const body = await res.json();
63
+ return body?.data?.eligible === true;
64
+ }
65
+ catch {
66
+ return false;
67
+ }
68
+ }
69
+ async function submitReview(token, score) {
70
+ try {
71
+ const res = await fetch(`${API_URL}/reviews`, {
72
+ method: 'POST',
73
+ headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
74
+ body: JSON.stringify({ score, platform: 'cli' }),
75
+ });
76
+ if (!res.ok)
77
+ return null;
78
+ const body = await res.json();
79
+ return body?.data?.id ?? null;
80
+ }
81
+ catch {
82
+ return null;
83
+ }
84
+ }
85
+ async function submitComment(token, reviewId, comment) {
86
+ try {
87
+ await fetch(`${API_URL}/reviews/${reviewId}/comment`, {
88
+ method: 'PATCH',
89
+ headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
90
+ body: JSON.stringify({ comment }),
91
+ });
92
+ }
93
+ catch {
94
+ // best-effort
95
+ }
96
+ }
97
+ function ask(rl, question) {
98
+ return new Promise((resolve) => rl.question(question, resolve));
99
+ }
100
+ export async function maybeShowReviewPrompt() {
101
+ try {
102
+ const state = await loadState();
103
+ if (!shouldShow(state))
104
+ return;
105
+ const token = await getAccessToken();
106
+ if (!token)
107
+ return;
108
+ const eligible = await checkEligibility(token);
109
+ if (!eligible)
110
+ return;
111
+ const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
112
+ console.log();
113
+ console.log(chalk.dim('─'.repeat(50)));
114
+ console.log();
115
+ console.log(` ${chalk.bold('Quick question about Contextium')} ${chalk.dim('(takes 10 seconds)')}`);
116
+ console.log();
117
+ console.log(` ${chalk.dim('How are you finding it so far?')}`);
118
+ console.log();
119
+ console.log(` ${chalk.yellow('1')} ★ ${chalk.yellow('2')} ★★ ${chalk.yellow('3')} ★★★ ${chalk.yellow('4')} ★★★★ ${chalk.yellow('5')} ★★★★★`);
120
+ console.log();
121
+ const ratingRaw = await ask(rl, ` Rating ${chalk.dim('(1–5, or Enter to skip)')}: `);
122
+ const rating = parseInt(ratingRaw.trim(), 10);
123
+ if (!ratingRaw.trim() || isNaN(rating) || rating < 1 || rating > 5) {
124
+ rl.close();
125
+ console.log();
126
+ return;
127
+ }
128
+ console.log();
129
+ const reviewId = await submitReview(token, rating);
130
+ const wantFeedback = await ask(rl, ` Any feedback to share? ${chalk.dim('(y/n)')}: `);
131
+ if (wantFeedback.trim().toLowerCase() === 'y' && reviewId) {
132
+ console.log();
133
+ const comment = await ask(rl, ` What's on your mind? `);
134
+ if (comment.trim()) {
135
+ await submitComment(token, reviewId, comment.trim());
136
+ }
137
+ }
138
+ rl.close();
139
+ console.log();
140
+ console.log(` ${chalk.green('✓')} Thanks for the feedback!`);
141
+ console.log();
142
+ state.lastPromptedAt = new Date().toISOString();
143
+ await saveState(state);
144
+ }
145
+ catch {
146
+ // Never block the CLI
147
+ }
148
+ }
149
+ //# sourceMappingURL=review-prompt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"review-prompt.js","sourceRoot":"","sources":["../../src/lib/review-prompt.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contextium/cli",
3
- "version": "1.0.31",
3
+ "version": "1.0.33",
4
4
  "description": "Command-line tool for managing Contextium documentation, agents, skills, and workflows — pipe context to AI coding assistants",
5
5
  "keywords": [
6
6
  "contextium",
@@ -281,51 +281,81 @@ Infer sensible phases from the project description. Title the file `project-stat
281
281
  If no: set `planner_planned = false` and continue.
282
282
  </step>
283
283
 
284
- <step name="regression_agent_question">
285
- Ask the user:
286
-
287
- "Would you like a regression testing agent for this project? It will write E2E tests alongside every new feature so nothing you've built ever breaks silently."
288
-
289
- Use AskUserQuestion:
290
- - "Yes, add a regression testing agent"
284
+ <step name="quality_agent_question">
285
+ Before asking this question, classify the project type from the description provided in `project_description`. Choose exactly one from:
286
+
287
+ - **development** software, apps, APIs, code, engineering, features, bug fixes
288
+ - **research** — investigation, analysis, literature review, market research, competitive analysis, feasibility studies
289
+ - **writing** — papers, reports, essays, documentation, articles, books, whitepapers
290
+ - **pitch/presentation** — pitch decks, slide decks, investor materials, presentations, proposals
291
+ - **marketing/content** — campaigns, copy, brand materials, social content, creative briefs
292
+ - **data/finance** — financial models, data analysis, forecasts, reports, spreadsheets
293
+ - **design** — UX, UI, design systems, wireframes, prototypes
294
+ - **other** — anything that doesn't clearly fit the above
295
+
296
+ Store this as `project_type`.
297
+
298
+ Based on `project_type`, determine whether a quality/review agent is relevant and what kind:
299
+
300
+ | Project type | Relevant? | Agent name pattern | What it does |
301
+ |---|---|---|---|
302
+ | development | Yes | "[Project Name] Regression Tester" | Writes E2E tests alongside every feature so nothing breaks silently |
303
+ | research | Yes | "[Project Name] Fact Checker" | Validates claims against sources, flags unsupported assertions, checks citations |
304
+ | writing | Yes | "[Project Name] Proofreader" | Reviews drafts for clarity, consistency, grammar, and tone before finalising |
305
+ | pitch/presentation | Yes | "[Project Name] Deck Reviewer" | Reviews pitch decks for clarity, narrative flow, and persuasive strength |
306
+ | marketing/content | Yes | "[Project Name] Copy Reviewer" | Reviews copy for brand voice, clarity, and effectiveness before publishing |
307
+ | data/finance | Yes | "[Project Name] Data Validator" | Checks calculations, flags assumptions, and validates data sources |
308
+ | design | No | — | Skip this step entirely |
309
+ | other | No | — | Skip this step entirely |
310
+
311
+ If `project_type` is `design` or `other`, skip this step entirely — do not ask the question.
312
+
313
+ Otherwise, ask the user the question tailored to their project type. Use natural language that fits the domain — do not use the word "regression" for non-development projects. Examples:
314
+
315
+ - development: "Would you like a regression testing agent? It will write E2E tests alongside every new feature so nothing you've built ever breaks silently."
316
+ - research: "Would you like a fact-checking agent? It can review your findings against sources, flag unsupported claims, and validate citations as you build out your research."
317
+ - writing: "Would you like a proofreader agent? It can review drafts for clarity, consistency, and tone before you finalise anything."
318
+ - pitch/presentation: "Would you like a deck reviewer agent? It can review your pitch for narrative flow, clarity, and persuasive strength before you present it."
319
+ - marketing/content: "Would you like a copy reviewer agent? It can check copy for brand voice, clarity, and effectiveness before it goes out."
320
+ - data/finance: "Would you like a data validator agent? It can check your calculations, flag assumptions, and verify your data sources."
321
+
322
+ Use AskUserQuestion with:
323
+ - "Yes, add a [agent name]"
291
324
  - "No, skip"
292
325
 
293
326
  If yes:
294
- 1. Add a "**[Project Name] Regression Tester**" agent to the creation plan. Its system prompt should:
295
- - Know that every feature must include an E2E Playwright test as a required deliverable
296
- - Know the test suite lives in `apps/web/e2e/` and tests run against `https://staging.contextium.io`
297
- - Know the rule: a feature is not complete until its E2E test is written and the full regression suite passes on staging
298
- - Be instructed to write focused, realistic tests using existing page selectors and routes — not generic placeholder tests
299
- 2. Store as `regression_agent_planned = true`.
300
-
301
- 3. Check if Playwright is already installed by running silently:
302
- ```bash
303
- cd apps/web && npx playwright --version 2>/dev/null | grep -q "Version" && echo "installed" || echo "not-installed"
304
- ```
327
+ 1. Add the agent to the creation plan. Write a system prompt tailored to the project's specific domain — not a generic description. The prompt should describe:
328
+ - What the agent reviews and what quality bar it holds to
329
+ - What a "complete" deliverable looks like from its perspective (e.g. for development: all features have passing E2E tests; for research: all claims are cited and verified; for writing: no draft goes out without a proofread pass)
330
+ - Any project-specific context inferred from the description (tone, audience, tech stack, subject matter)
331
+ 2. Store as `quality_agent_planned = true`, `quality_agent_type = <type>`.
305
332
 
306
- If not installed, ask:
333
+ **For development projects only** — additionally check if Playwright is installed:
334
+ ```bash
335
+ cd apps/web && npx playwright --version 2>/dev/null | grep -q "Version" && echo "installed" || echo "not-installed"
336
+ ```
307
337
 
308
- "Playwright is required to run E2E tests. Would you like me to install it now?"
338
+ If not installed, ask: "Playwright is required to run E2E tests. Would you like me to install it now?"
309
339
 
310
- Use AskUserQuestion:
311
- - "Yes, install Playwright"
312
- - "No, I'll install it later"
340
+ Use AskUserQuestion:
341
+ - "Yes, install Playwright"
342
+ - "No, I'll install it later"
313
343
 
314
- If yes — install silently:
315
- ```bash
316
- cd apps/web && npm install -D @playwright/test && npx playwright install chromium
317
- ```
318
- Show `✓ Playwright installed` when done.
344
+ If yes — install silently:
345
+ ```bash
346
+ cd apps/web && npm install -D @playwright/test && npx playwright install chromium
347
+ ```
348
+ Show `✓ Playwright installed` when done.
319
349
 
320
- If no — store `playwright_install_pending = true` and add a note to the final summary:
321
- `⚠ Playwright not installed — run the following before running E2E tests:`
322
- ` cd apps/web && npm install -D @playwright/test && npx playwright install chromium`
350
+ If no — store `playwright_install_pending = true` and add a note to the final summary:
351
+ `⚠ Playwright not installed — run the following before running E2E tests:`
352
+ ` cd apps/web && npm install -D @playwright/test && npx playwright install chromium`
323
353
 
324
- If no: set `regression_agent_planned = false` and continue.
354
+ If no to the quality agent question: set `quality_agent_planned = false` and continue.
325
355
  </step>
326
356
 
327
357
  <step name="create_resources">
328
- Only create what the user confirmed across all steps. Create in this order: tag types → tags → libraries → skills → agents (including research, planner, and regression agents if confirmed).
358
+ Only create what the user confirmed across all steps. Create in this order: tag types → tags → libraries → skills → agents (including research, planner, and quality agents if confirmed).
329
359
 
330
360
  Do NOT create a workflow in this step.
331
361