@mmnto/cli 0.7.0 → 0.9.0

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/dist/commands/anchor.d.ts.map +1 -1
  2. package/dist/commands/anchor.js +6 -4
  3. package/dist/commands/anchor.js.map +1 -1
  4. package/dist/commands/briefing.d.ts.map +1 -1
  5. package/dist/commands/briefing.js +15 -12
  6. package/dist/commands/briefing.js.map +1 -1
  7. package/dist/commands/handoff.d.ts.map +1 -1
  8. package/dist/commands/handoff.js +16 -13
  9. package/dist/commands/handoff.js.map +1 -1
  10. package/dist/commands/init.d.ts +21 -0
  11. package/dist/commands/init.d.ts.map +1 -1
  12. package/dist/commands/init.js +210 -15
  13. package/dist/commands/init.js.map +1 -1
  14. package/dist/commands/init.test.js +160 -1
  15. package/dist/commands/init.test.js.map +1 -1
  16. package/dist/commands/learn.d.ts +12 -1
  17. package/dist/commands/learn.d.ts.map +1 -1
  18. package/dist/commands/learn.js +137 -59
  19. package/dist/commands/learn.js.map +1 -1
  20. package/dist/commands/learn.test.js +59 -1
  21. package/dist/commands/learn.test.js.map +1 -1
  22. package/dist/commands/search.d.ts.map +1 -1
  23. package/dist/commands/search.js +5 -4
  24. package/dist/commands/search.js.map +1 -1
  25. package/dist/commands/shield.d.ts.map +1 -1
  26. package/dist/commands/shield.js +19 -14
  27. package/dist/commands/shield.js.map +1 -1
  28. package/dist/commands/spec.d.ts +1 -1
  29. package/dist/commands/spec.d.ts.map +1 -1
  30. package/dist/commands/spec.js +56 -43
  31. package/dist/commands/spec.js.map +1 -1
  32. package/dist/commands/sync.d.ts.map +1 -1
  33. package/dist/commands/sync.js +15 -6
  34. package/dist/commands/sync.js.map +1 -1
  35. package/dist/commands/triage.d.ts.map +1 -1
  36. package/dist/commands/triage.js +14 -11
  37. package/dist/commands/triage.js.map +1 -1
  38. package/dist/index.js +9 -8
  39. package/dist/index.js.map +1 -1
  40. package/dist/ui.d.ts +26 -0
  41. package/dist/ui.d.ts.map +1 -0
  42. package/dist/ui.js +85 -0
  43. package/dist/ui.js.map +1 -0
  44. package/dist/ui.test.d.ts +2 -0
  45. package/dist/ui.test.d.ts.map +1 -0
  46. package/dist/ui.test.js +76 -0
  47. package/dist/ui.test.js.map +1 -0
  48. package/dist/utils.d.ts +6 -0
  49. package/dist/utils.d.ts.map +1 -1
  50. package/dist/utils.js +37 -8
  51. package/dist/utils.js.map +1 -1
  52. package/dist/utils.test.js +70 -1
  53. package/dist/utils.test.js.map +1 -1
  54. package/package.json +4 -2
@@ -1 +1 @@
1
- {"version":3,"file":"anchor.d.ts","sourceRoot":"","sources":["../../src/commands/anchor.ts"],"names":[],"mappings":"AAkBA,wBAAsB,aAAa,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA0ErE"}
1
+ {"version":3,"file":"anchor.d.ts","sourceRoot":"","sources":["../../src/commands/anchor.ts"],"names":[],"mappings":"AAmBA,wBAAsB,aAAa,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA2ErE"}
@@ -3,6 +3,7 @@ import * as fs from 'node:fs';
3
3
  import * as path from 'node:path';
4
4
  import { stdin as input, stdout as output } from 'node:process';
5
5
  import * as readline from 'node:readline/promises';
6
+ import { log } from '../ui.js';
6
7
  import { IS_WIN, loadConfig, loadEnv, resolveConfigPath } from '../utils.js';
7
8
  function detectSyncCommand(cwd) {
8
9
  if (fs.existsSync(path.join(cwd, 'pnpm-lock.yaml'))) {
@@ -53,16 +54,16 @@ export async function anchorCommand(lessonArg) {
53
54
  }
54
55
  }
55
56
  if (!lessonText || !lessonText.trim()) {
56
- console.error('[Totem Error] Lesson text cannot be empty.');
57
+ log.error('Totem', 'Lesson text cannot be empty.');
57
58
  return;
58
59
  }
59
60
  const timestamp = new Date().toISOString();
60
61
  const tagString = tags.length > 0 ? tags.join(', ') : 'manual';
61
62
  const entry = `\n## Lesson — ${timestamp}\n\n**Tags:** ${tagString}\n\n${lessonText.trim()}\n`;
62
63
  fs.appendFileSync(lessonsPath, entry, 'utf-8');
63
- console.log(`\n[Totem] Lesson saved to ${config.totemDir}/lessons.md`);
64
+ log.success('Totem', `Lesson saved to ${config.totemDir}/lessons.md`);
64
65
  const logPath = path.join(totemDir, 'mcp-sync.log');
65
- console.log('[Totem] Triggering background re-index...');
66
+ log.dim('Totem', 'Triggering background re-index...');
66
67
  try {
67
68
  const { cmd, args } = detectSyncCommand(cwd);
68
69
  const logFd = fs.openSync(logPath, 'a');
@@ -76,7 +77,8 @@ export async function anchorCommand(lessonArg) {
76
77
  child.unref();
77
78
  }
78
79
  catch (err) {
79
- console.error('[Totem Warning] Failed to trigger background sync:', err);
80
+ const message = err instanceof Error ? err.message : String(err);
81
+ log.warn('Totem', `Failed to trigger background sync: ${message}`);
80
82
  }
81
83
  }
82
84
  //# sourceMappingURL=anchor.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"anchor.js","sourceRoot":"","sources":["../../src/commands/anchor.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"anchor.js","sourceRoot":"","sources":["../../src/commands/anchor.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"briefing.d.ts","sourceRoot":"","sources":["../../src/commands/briefing.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAyEpE,wBAAgB,YAAY,CAAC,GAAG,EAAE,kBAAkB,EAAE,GAAG,MAAM,CAG9D;AAoCD,MAAM,WAAW,eAAe;IAC9B,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,wBAAsB,eAAe,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAyC7E"}
1
+ {"version":3,"file":"briefing.d.ts","sourceRoot":"","sources":["../../src/commands/briefing.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AA2EpE,wBAAgB,YAAY,CAAC,GAAG,EAAE,kBAAkB,EAAE,GAAG,MAAM,CAG9D;AAqCD,MAAM,WAAW,eAAe;IAC9B,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,wBAAsB,eAAe,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CA0C7E"}
@@ -2,7 +2,8 @@ import * as path from 'node:path';
2
2
  import { createEmbedder, LanceStore } from '@mmnto/totem';
3
3
  import { GitHubCliPrAdapter } from '../adapters/github-cli-pr.js';
4
4
  import { getGitBranch, getGitStatus } from '../git.js';
5
- import { formatResults, loadConfig, loadEnv, resolveConfigPath, runOrchestrator, wrapXml, writeOutput, } from '../utils.js';
5
+ import { log } from '../ui.js';
6
+ import { formatResults, getSystemPrompt, loadConfig, loadEnv, resolveConfigPath, runOrchestrator, wrapXml, writeOutput, } from '../utils.js';
6
7
  // ─── Constants ──────────────────────────────────────────
7
8
  const TAG = 'Briefing';
8
9
  const MAX_SPEC_RESULTS = 5;
@@ -53,8 +54,8 @@ export function formatPRList(prs) {
53
54
  return '(none)';
54
55
  return prs.map((pr) => `- #${pr.number} — ${pr.title} (branch: ${pr.headRefName})`).join('\n');
55
56
  }
56
- function assemblePrompt(branch, status, prs, context) {
57
- const sections = [SYSTEM_PROMPT];
57
+ function assemblePrompt(branch, status, prs, context, systemPrompt) {
58
+ const sections = [systemPrompt];
58
59
  // Git state
59
60
  sections.push('=== GIT STATE ===');
60
61
  sections.push(`Branch: ${branch}`);
@@ -80,33 +81,35 @@ export async function briefingCommand(options) {
80
81
  loadEnv(cwd);
81
82
  const config = await loadConfig(configPath);
82
83
  // Gather git state
83
- console.error(`[${TAG}] Gathering git state...`);
84
+ log.info(TAG, 'Gathering git state...');
84
85
  const branch = getGitBranch(cwd);
85
86
  const status = getGitStatus(cwd);
86
- console.error(`[${TAG}] Branch: ${branch}`);
87
+ log.info(TAG, `Branch: ${branch}`);
87
88
  // Fetch open PRs
88
- console.error(`[${TAG}] Fetching open PRs...`);
89
+ log.info(TAG, 'Fetching open PRs...');
89
90
  const adapter = new GitHubCliPrAdapter(cwd);
90
91
  const prs = adapter.fetchOpenPRs();
91
- console.error(`[${TAG}] Found ${prs.length} open PRs.`);
92
+ log.info(TAG, `Found ${prs.length} open PRs.`);
92
93
  // Connect to LanceDB
93
94
  const embedder = createEmbedder(config.embedding);
94
95
  const store = new LanceStore(path.join(cwd, config.lanceDir), embedder);
95
96
  await store.connect();
96
97
  // Retrieve context from LanceDB
97
98
  const query = `${branch} active work session priorities`;
98
- console.error(`[${TAG}] Querying Totem index...`);
99
+ log.info(TAG, 'Querying Totem index...');
99
100
  const context = await retrieveContext(query, store);
100
101
  const totalResults = context.specs.length + context.sessions.length;
101
- console.error(`[${TAG}] Found: ${context.specs.length} specs, ${context.sessions.length} sessions`);
102
+ log.info(TAG, `Found: ${context.specs.length} specs, ${context.sessions.length} sessions`);
103
+ // Resolve system prompt (allow .totem/prompts/briefing.md override)
104
+ const systemPrompt = getSystemPrompt('briefing', SYSTEM_PROMPT, cwd, config.totemDir);
102
105
  // Assemble prompt
103
- const prompt = assemblePrompt(branch, status, prs, context);
104
- console.error(`[${TAG}] Prompt: ${(prompt.length / 1024).toFixed(0)}KB`);
106
+ const prompt = assemblePrompt(branch, status, prs, context, systemPrompt);
107
+ log.dim(TAG, `Prompt: ${(prompt.length / 1024).toFixed(0)}KB`);
105
108
  const content = runOrchestrator({ prompt, tag: TAG, options, config, cwd, totalResults });
106
109
  if (content != null) {
107
110
  writeOutput(content, options.out);
108
111
  if (options.out)
109
- console.error(`[${TAG}] Written to ${options.out}`);
112
+ log.success(TAG, `Written to ${options.out}`);
110
113
  }
111
114
  }
112
115
  //# sourceMappingURL=briefing.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"briefing.js","sourceRoot":"","sources":["../../src/commands/briefing.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"briefing.js","sourceRoot":"","sources":["../../src/commands/briefing.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"handoff.d.ts","sourceRoot":"","sources":["../../src/commands/handoff.ts"],"names":[],"mappings":"AA0DA,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAUvE;AAgDD,MAAM,WAAW,cAAc;IAC7B,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,wBAAsB,cAAc,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAuC3E"}
1
+ {"version":3,"file":"handoff.d.ts","sourceRoot":"","sources":["../../src/commands/handoff.ts"],"names":[],"mappings":"AA4DA,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAUvE;AAiDD,MAAM,WAAW,cAAc;IAC7B,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,wBAAsB,cAAc,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAwC3E"}
@@ -1,7 +1,8 @@
1
1
  import * as fs from 'node:fs';
2
2
  import * as path from 'node:path';
3
3
  import { getGitBranch, getGitDiff, getGitDiffStat, getGitStatus } from '../git.js';
4
- import { loadConfig, loadEnv, resolveConfigPath, runOrchestrator, wrapXml, writeOutput, } from '../utils.js';
4
+ import { log } from '../ui.js';
5
+ import { getSystemPrompt, loadConfig, loadEnv, resolveConfigPath, runOrchestrator, wrapXml, writeOutput, } from '../utils.js';
5
6
  // ─── Constants ──────────────────────────────────────────
6
7
  const TAG = 'Handoff';
7
8
  const MAX_DIFF_CHARS = 50_000;
@@ -53,8 +54,8 @@ export function readRecentLessons(cwd, totemDir) {
53
54
  return lines.slice(-LESSONS_TAIL_LINES).join('\n').trim();
54
55
  }
55
56
  // ─── Prompt assembly ────────────────────────────────────
56
- function assemblePrompt(branch, status, diff, diffStat, lessons) {
57
- const sections = [SYSTEM_PROMPT];
57
+ function assemblePrompt(branch, status, diff, diffStat, lessons, systemPrompt) {
58
+ const sections = [systemPrompt];
58
59
  // Git state
59
60
  sections.push('=== GIT STATE ===');
60
61
  sections.push(`Branch: ${branch}`);
@@ -87,32 +88,34 @@ export async function handoffCommand(options) {
87
88
  loadEnv(cwd);
88
89
  const config = await loadConfig(configPath);
89
90
  // Gather git state
90
- console.error(`[${TAG}] Gathering git state...`);
91
+ log.info(TAG, 'Gathering git state...');
91
92
  const branch = getGitBranch(cwd);
92
93
  const status = getGitStatus(cwd);
93
- console.error(`[${TAG}] Branch: ${branch}`);
94
+ log.info(TAG, `Branch: ${branch}`);
94
95
  // Get diff
95
- console.error(`[${TAG}] Getting uncommitted diff...`);
96
+ log.info(TAG, 'Getting uncommitted diff...');
96
97
  const diff = getGitDiff('all', cwd);
97
98
  const diffStat = diff.trim() ? getGitDiffStat(cwd) : '';
98
99
  if (diff.trim()) {
99
- console.error(`[${TAG}] Diff: ${(diff.length / 1024).toFixed(0)}KB`);
100
+ log.info(TAG, `Diff: ${(diff.length / 1024).toFixed(0)}KB`);
100
101
  }
101
102
  else {
102
- console.error(`[${TAG}] Working tree is clean.`);
103
+ log.dim(TAG, 'Working tree is clean.');
103
104
  }
104
105
  // Read recent lessons
105
- console.error(`[${TAG}] Reading recent lessons...`);
106
+ log.info(TAG, 'Reading recent lessons...');
106
107
  const lessons = readRecentLessons(cwd, config.totemDir);
107
- console.error(`[${TAG}] Lessons: ${lessons ? `${lessons.split('\n').length} lines` : 'none found'}`);
108
+ log.info(TAG, `Lessons: ${lessons ? `${lessons.split('\n').length} lines` : 'none found'}`);
109
+ // Resolve system prompt (allow .totem/prompts/handoff.md override)
110
+ const systemPrompt = getSystemPrompt('handoff', SYSTEM_PROMPT, cwd, config.totemDir);
108
111
  // Assemble prompt
109
- const prompt = assemblePrompt(branch, status, diff, diffStat, lessons);
110
- console.error(`[${TAG}] Prompt: ${(prompt.length / 1024).toFixed(0)}KB`);
112
+ const prompt = assemblePrompt(branch, status, diff, diffStat, lessons, systemPrompt);
113
+ log.dim(TAG, `Prompt: ${(prompt.length / 1024).toFixed(0)}KB`);
111
114
  const content = runOrchestrator({ prompt, tag: TAG, options, config, cwd });
112
115
  if (content != null) {
113
116
  writeOutput(content, options.out);
114
117
  if (options.out)
115
- console.error(`[${TAG}] Written to ${options.out}`);
118
+ log.success(TAG, `Written to ${options.out}`);
116
119
  }
117
120
  }
118
121
  //# sourceMappingURL=handoff.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"handoff.js","sourceRoot":"","sources":["../../src/commands/handoff.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"handoff.js","sourceRoot":"","sources":["../../src/commands/handoff.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,28 @@
1
+ export interface HookInstallerResult {
2
+ file: string;
3
+ action: 'created' | 'exists' | 'skipped' | 'merged';
4
+ err?: string;
5
+ }
1
6
  export declare function buildNpxCommand(isWin: boolean): {
2
7
  command: string;
3
8
  args: string[];
4
9
  };
10
+ /**
11
+ * Scaffold a file with idempotency — skips if the marker is already present.
12
+ * Creates parent directories as needed.
13
+ */
14
+ export declare function scaffoldFile(filePath: string, content: string, marker?: string): {
15
+ action: 'created' | 'exists' | 'skipped';
16
+ err?: string;
17
+ };
18
+ /**
19
+ * Merge Totem hooks into .claude/settings.local.json without overwriting
20
+ * existing user-defined hooks.
21
+ */
22
+ export declare function scaffoldClaudeHooks(filePath: string): {
23
+ action: 'created' | 'merged' | 'skipped';
24
+ err?: string;
25
+ };
5
26
  export declare function scaffoldMcpConfig(filePath: string, serverEntry: Record<string, unknown>): {
6
27
  action: 'created' | 'merged' | 'skipped';
7
28
  err?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAoDA,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,EAAE,CAAA;CAAE,CAInF;AA0CD,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACnC;IAAE,MAAM,EAAE,SAAS,GAAG,QAAQ,GAAG,SAAS,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,CAoD5D;AAmID,wBAAsB,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CAgLjD"}
1
+ {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAqDA,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,SAAS,GAAG,QAAQ,GAAG,SAAS,GAAG,QAAQ,CAAC;IACpD,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAUD,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,EAAE,CAAA;CAAE,CAInF;AAID;;;GAGG;AACH,wBAAgB,YAAY,CAC1B,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,MAAM,GAAE,MAA0B,GACjC;IAAE,MAAM,EAAE,SAAS,GAAG,QAAQ,GAAG,SAAS,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,CAqB5D;AAqFD;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG;IACrD,MAAM,EAAE,SAAS,GAAG,QAAQ,GAAG,SAAS,CAAC;IACzC,GAAG,CAAC,EAAE,MAAM,CAAC;CACd,CAkEA;AAiDD,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACnC;IAAE,MAAM,EAAE,SAAS,GAAG,QAAQ,GAAG,SAAS,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,CAoD5D;AAmID,wBAAsB,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CAmMjD"}
@@ -2,6 +2,7 @@ import * as fs from 'node:fs';
2
2
  import * as path from 'node:path';
3
3
  import { stdin as input, stdout as output } from 'node:process';
4
4
  import * as readline from 'node:readline/promises';
5
+ import { bold, brand, dim, log, printBanner, success } from '../ui.js';
5
6
  import { IS_WIN } from '../utils.js';
6
7
  import { installPostMergeHook } from './install-hooks.js';
7
8
  const AI_PROMPT_BLOCK = `
@@ -26,25 +27,198 @@ Totem provides CLI commands that map to your development lifecycle. Use them at
26
27
  2. **Before Implementation:** Run \`totem spec <issue-url-or-topic>\` to generate an architectural plan and review related context before writing code.
27
28
  3. **Before PR/Push:** Run \`totem shield\` to analyze uncommitted changes against project knowledge — catches architectural drift and pattern violations.
28
29
  4. **End of Session:** Run \`totem handoff\` to generate a snapshot for the next agent session with current progress and open threads.
30
+
31
+ ### Cloud / PR Review Bots
32
+ [FOR CLOUD BOTS ONLY — e.g., Gemini Code Assist, GitHub Copilot PR Review]
33
+ You do NOT have access to the local CLI. Instead, use the Totem MCP tools directly:
34
+ 1. **Before reviewing a PR:** Call \`search_knowledge\` with queries about the files and patterns being changed to check for known traps and architectural constraints.
35
+ 2. **Before suggesting changes:** Call \`search_knowledge\` to verify your suggestion aligns with established project patterns and past lessons.
36
+ 3. **When you spot a recurring issue:** Call \`add_lesson\` to persist the trap so future reviews catch it automatically.
29
37
  `;
30
38
  export function buildNpxCommand(isWin) {
31
39
  return isWin
32
40
  ? { command: 'cmd', args: ['/c', 'npx', '-y', '@mmnto/mcp'] }
33
41
  : { command: 'npx', args: ['-y', '@mmnto/mcp'] };
34
42
  }
43
+ const TOTEM_FILE_MARKER = '// [totem] auto-generated';
44
+ /**
45
+ * Scaffold a file with idempotency — skips if the marker is already present.
46
+ * Creates parent directories as needed.
47
+ */
48
+ export function scaffoldFile(filePath, content, marker = TOTEM_FILE_MARKER) {
49
+ try {
50
+ if (fs.existsSync(filePath)) {
51
+ const existing = fs.readFileSync(filePath, 'utf-8');
52
+ if (existing.includes(marker)) {
53
+ return { action: 'exists' };
54
+ }
55
+ return { action: 'skipped' };
56
+ }
57
+ const dir = path.dirname(filePath);
58
+ if (!fs.existsSync(dir)) {
59
+ fs.mkdirSync(dir, { recursive: true });
60
+ }
61
+ fs.writeFileSync(filePath, content, 'utf-8');
62
+ return { action: 'created' };
63
+ }
64
+ catch (err) {
65
+ const message = err instanceof Error ? err.message : String(err);
66
+ return { action: 'skipped', err: `[Totem Error] ${message}` };
67
+ }
68
+ }
35
69
  const { command: npxCmd, args: npxArgs } = buildNpxCommand(IS_WIN);
70
+ // --- Gemini CLI hook templates ---
71
+ const GEMINI_SESSION_START = `// [totem] auto-generated — Gemini CLI SessionStart hook
72
+ // Runs \`totem briefing\` at the start of every Gemini CLI session.
73
+ const { execSync } = require('child_process');
74
+
75
+ try {
76
+ const output = execSync('totem briefing', {
77
+ encoding: 'utf-8',
78
+ timeout: 30000,
79
+ stdio: ['ignore', 'pipe', 'pipe'],
80
+ });
81
+ process.stderr.write(output);
82
+ } catch (err) {
83
+ process.stderr.write('[Totem Error] Briefing unavailable: ' + (err instanceof Error ? err.message : String(err)) + '\\n');
84
+ }
85
+ `;
86
+ const GEMINI_BEFORE_TOOL = `// [totem] auto-generated — Gemini CLI BeforeTool hook
87
+ // Intercepts git push/commit to run \`totem shield\` before proceeding.
88
+ const { execSync } = require('child_process');
89
+
90
+ module.exports = function beforeTool(toolName, toolInput) {
91
+ if (toolName !== 'run_shell_command') return;
92
+ const cmd = typeof toolInput === 'string' ? toolInput : JSON.stringify(toolInput);
93
+ if (!/git\\s+(push|commit)/.test(cmd) && !/["']git["'].*["'](push|commit)["']/.test(cmd)) return;
94
+
95
+ try {
96
+ execSync('totem shield', { encoding: 'utf-8', timeout: 60000, stdio: 'inherit' });
97
+ } catch (err) {
98
+ throw new Error('[Totem Error] Shield check failed. Fix violations before pushing.\\n' + err.message);
99
+ }
100
+ };
101
+ `;
102
+ const GEMINI_SKILL = `<!-- [totem] auto-generated — Totem Architect skill -->
103
+ # Totem Architect
104
+
105
+ Before designing, planning, or implementing features, query the project's memory index for relevant context:
106
+
107
+ 1. Use the \`search_knowledge\` MCP tool with a query describing what you're about to build.
108
+ 2. Review returned lessons, specs, and code patterns before writing any code.
109
+ 3. If you discover a trap or architectural constraint, factor it into your design.
110
+
111
+ This ensures you build on existing knowledge rather than repeating past mistakes.
112
+ `;
113
+ async function installGeminiHooks(cwd) {
114
+ const results = [];
115
+ const files = [
116
+ {
117
+ rel: '.gemini/hooks/SessionStart.js',
118
+ content: GEMINI_SESSION_START,
119
+ marker: TOTEM_FILE_MARKER,
120
+ },
121
+ { rel: '.gemini/hooks/BeforeTool.js', content: GEMINI_BEFORE_TOOL, marker: TOTEM_FILE_MARKER },
122
+ {
123
+ rel: '.gemini/skills/totem.md',
124
+ content: GEMINI_SKILL,
125
+ marker: '<!-- [totem] auto-generated — Totem Architect skill -->',
126
+ },
127
+ ];
128
+ for (const { rel, content, marker } of files) {
129
+ const filePath = path.join(cwd, rel);
130
+ const result = scaffoldFile(filePath, content, marker);
131
+ results.push({ file: rel, ...result });
132
+ }
133
+ return results;
134
+ }
135
+ // --- Claude Code hook installer ---
136
+ const CLAUDE_PRETOOLUSE_ENTRY = {
137
+ matcher: 'Bash',
138
+ hooks: [
139
+ 'if printf "%s" "$TOOL_INPUT" | grep -q "git" && printf "%s" "$TOOL_INPUT" | grep -qE "(push|commit)"; then totem shield; fi',
140
+ ],
141
+ };
142
+ /**
143
+ * Merge Totem hooks into .claude/settings.local.json without overwriting
144
+ * existing user-defined hooks.
145
+ */
146
+ export function scaffoldClaudeHooks(filePath) {
147
+ try {
148
+ const dir = path.dirname(filePath);
149
+ if (!fs.existsSync(dir)) {
150
+ fs.mkdirSync(dir, { recursive: true });
151
+ }
152
+ const fullConfig = { hooks: { PreToolUse: [CLAUDE_PRETOOLUSE_ENTRY] } };
153
+ if (!fs.existsSync(filePath)) {
154
+ fs.writeFileSync(filePath, JSON.stringify(fullConfig, null, 2) + '\n', 'utf-8');
155
+ return { action: 'created' };
156
+ }
157
+ const raw = fs.readFileSync(filePath, 'utf-8');
158
+ let parsed;
159
+ try {
160
+ parsed = JSON.parse(raw);
161
+ }
162
+ catch (err) {
163
+ const message = err instanceof Error ? err.message : String(err);
164
+ return {
165
+ action: 'skipped',
166
+ err: `[Totem Error] Could not parse settings.local.json (invalid JSON): ${message}`,
167
+ };
168
+ }
169
+ // Deep merge: check if PreToolUse already has a totem entry
170
+ const hooksUntyped = parsed.hooks;
171
+ if (hooksUntyped !== undefined &&
172
+ (typeof hooksUntyped !== 'object' || hooksUntyped === null || Array.isArray(hooksUntyped))) {
173
+ return {
174
+ action: 'skipped',
175
+ err: '[Totem Error] Could not merge config: "hooks" in settings.local.json must be an object.',
176
+ };
177
+ }
178
+ const hooks = (hooksUntyped ?? {});
179
+ if (hooks.PreToolUse !== undefined && !Array.isArray(hooks.PreToolUse)) {
180
+ return {
181
+ action: 'skipped',
182
+ err: '[Totem Error] Could not merge config: "hooks.PreToolUse" in settings.local.json must be an array.',
183
+ };
184
+ }
185
+ const preToolUse = (hooks.PreToolUse ?? []);
186
+ if (preToolUse.some((h) => h &&
187
+ h.matcher === 'Bash' &&
188
+ Array.isArray(h.hooks) &&
189
+ h.hooks.some((cmd) => typeof cmd === 'string' && cmd.includes('totem shield')))) {
190
+ return { action: 'skipped' };
191
+ }
192
+ hooks.PreToolUse = [...preToolUse, CLAUDE_PRETOOLUSE_ENTRY];
193
+ parsed.hooks = hooks;
194
+ fs.writeFileSync(filePath, JSON.stringify(parsed, null, 2) + '\n', 'utf-8');
195
+ return { action: 'merged' };
196
+ }
197
+ catch (err) {
198
+ const message = err instanceof Error ? err.message : String(err);
199
+ return { action: 'skipped', err: `[Totem Error] ${message}` };
200
+ }
201
+ }
202
+ async function installClaudeHooks(cwd) {
203
+ const rel = '.claude/settings.local.json';
204
+ const filePath = path.join(cwd, rel);
205
+ const result = scaffoldClaudeHooks(filePath);
206
+ return [{ file: rel, ...result }];
207
+ }
36
208
  const AI_TOOLS = [
37
209
  {
38
210
  name: 'Claude Code',
39
211
  mcpPath: '.mcp.json',
40
212
  reflexFile: 'CLAUDE.md',
41
213
  serverEntry: { type: 'stdio', command: npxCmd, args: npxArgs },
214
+ hookInstaller: installClaudeHooks,
42
215
  },
43
216
  {
44
217
  name: 'Gemini CLI',
45
218
  mcpPath: '.gemini/settings.json',
46
219
  reflexFile: '.gemini/gemini.md',
47
220
  serverEntry: { command: npxCmd, args: npxArgs },
221
+ hookInstaller: installGeminiHooks,
48
222
  },
49
223
  {
50
224
  name: 'Cursor',
@@ -223,9 +397,10 @@ export async function initCommand() {
223
397
  const rl = readline.createInterface({ input, output });
224
398
  const summary = [];
225
399
  try {
400
+ printBanner();
226
401
  if (!configExists) {
227
402
  // --- Fresh install: generate config ---
228
- console.log('[Totem] Scanning project...');
403
+ log.info('Totem', 'Scanning project...');
229
404
  const detected = detectProject(cwd);
230
405
  const detections = [];
231
406
  if (detected.hasTypeScript)
@@ -241,10 +416,10 @@ export async function initCommand() {
241
416
  if (detected.hasSessions)
242
417
  detections.push('session logs');
243
418
  if (detections.length > 0) {
244
- console.log(`[Totem] Detected: ${detections.join(', ')}`);
419
+ log.info('Totem', `Detected: ${bold(detections.join(', '))}`);
245
420
  }
246
421
  else {
247
- console.log('[Totem] No specific project structure detected. Using markdown defaults.');
422
+ log.dim('Totem', 'No specific project structure detected. Using markdown defaults.');
248
423
  }
249
424
  const targets = buildTargets(detected);
250
425
  let provider = 'openai';
@@ -252,7 +427,7 @@ export async function initCommand() {
252
427
  const apiKey = answer.trim().replace(/[\r\n]/g, '');
253
428
  if (apiKey) {
254
429
  if (!/^sk-[a-zA-Z0-9_-]+$/.test(apiKey)) {
255
- console.error('[Totem] Warning: API key does not look like a valid OpenAI key (expected sk-...). Skipping.');
430
+ log.warn('Totem', 'API key does not look like a valid OpenAI key (expected sk-...). Skipping.');
256
431
  provider = 'ollama';
257
432
  }
258
433
  else {
@@ -273,14 +448,14 @@ export async function initCommand() {
273
448
  }
274
449
  else {
275
450
  provider = 'ollama';
276
- console.log('[Totem] Configured for Ollama. Make sure it is running locally.');
451
+ log.info('Totem', 'Configured for Ollama. Make sure it is running locally.');
277
452
  }
278
453
  const configContent = generateConfig(targets, provider);
279
454
  fs.writeFileSync(configPath, configContent, 'utf-8');
280
455
  summary.push({ file: 'totem.config.ts', action: 'Created with auto-detected targets' });
281
456
  }
282
457
  else {
283
- console.log('[Totem] totem.config.ts already exists. Checking reflexes and hooks...');
458
+ log.dim('Totem', 'totem.config.ts already exists. Checking reflexes and hooks...');
284
459
  }
285
460
  // --- Always run: .totem/ directory ---
286
461
  if (!fs.existsSync(totemDir)) {
@@ -295,7 +470,7 @@ export async function initCommand() {
295
470
  const detectedTools = detectAiTools(cwd);
296
471
  if (detectedTools.length > 0) {
297
472
  const toolNames = detectedTools.map((t) => t.name).join(', ');
298
- console.log(`\n[Totem] Detected AI tools: ${toolNames}`);
473
+ log.info('Totem', `Detected AI tools: ${bold(toolNames)}`);
299
474
  const toolAnswer = await rl.question('Which tools should Totem configure? [all/none/select] (default: all): ');
300
475
  let selectedTools;
301
476
  const trimmed = toolAnswer.trim().toLowerCase();
@@ -320,9 +495,9 @@ export async function initCommand() {
320
495
  const filePath = path.join(cwd, tool.mcpPath);
321
496
  const result = scaffoldMcpConfig(filePath, tool.serverEntry);
322
497
  if (result.err) {
323
- console.error(`\n[Totem Error] ${result.err}`);
324
- console.log(`To fix this, add the following manually to your ${tool.mcpPath} under "mcpServers":\n`);
325
- console.log(` "totem": ${JSON.stringify(tool.serverEntry, null, 2)}\n`);
498
+ log.error('Totem', result.err);
499
+ console.error(`To fix this, add the following manually to your ${tool.mcpPath} under "mcpServers":\n`);
500
+ console.error(` "totem": ${JSON.stringify(tool.serverEntry, null, 2)}\n`);
326
501
  }
327
502
  else if (result.action === 'created') {
328
503
  summary.push({ file: tool.mcpPath, action: `Created with Totem MCP server` });
@@ -344,7 +519,27 @@ export async function initCommand() {
344
519
  }
345
520
  catch (err) {
346
521
  const message = err instanceof Error ? err.message : String(err);
347
- console.error(`\n[Totem Error] Failed to inject reflexes into ${tool.reflexFile}: ${message}`);
522
+ log.error('Totem', `Failed to inject reflexes into ${tool.reflexFile}: ${message}`);
523
+ }
524
+ }
525
+ // --- Hook installation for selected tools ---
526
+ for (const tool of selectedTools) {
527
+ if (!tool.hookInstaller)
528
+ continue;
529
+ const results = await tool.hookInstaller(cwd);
530
+ for (const result of results) {
531
+ if (result.err) {
532
+ log.error('Totem', `Hook scaffolding failed for ${result.file}: ${result.err}`);
533
+ }
534
+ else if (result.action === 'created') {
535
+ summary.push({ file: result.file, action: `Scaffolded ${tool.name} hook` });
536
+ }
537
+ else if (result.action === 'merged') {
538
+ summary.push({
539
+ file: result.file,
540
+ action: `Merged ${tool.name} hook into existing config`,
541
+ });
542
+ }
348
543
  }
349
544
  }
350
545
  }
@@ -361,13 +556,13 @@ export async function initCommand() {
361
556
  }
362
557
  // --- Print summary ---
363
558
  if (summary.length > 0) {
364
- console.log('\n--- Totem Init Summary ---');
559
+ console.error(`\n${brand('--- Totem Init Summary ---')}`);
365
560
  for (const entry of summary) {
366
- console.log(` [OK] ${entry.file} — ${entry.action}`);
561
+ console.error(` ${success('OK')} ${dim(entry.file)} — ${entry.action}`);
367
562
  }
368
- console.log('--------------------------');
563
+ console.error(brand('--------------------------'));
369
564
  }
370
- console.log('\n[Totem] Init complete. Run `totem sync` to index your project.');
565
+ log.success('Totem', 'Init complete. Run `totem sync` to index your project.');
371
566
  }
372
567
  finally {
373
568
  rl.close();