@mmnto/cli 0.6.0 → 0.8.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 (102) hide show
  1. package/dist/adapters/gh-utils.d.ts +12 -0
  2. package/dist/adapters/gh-utils.d.ts.map +1 -0
  3. package/dist/adapters/gh-utils.js +53 -0
  4. package/dist/adapters/gh-utils.js.map +1 -0
  5. package/dist/adapters/gh-utils.test.d.ts +2 -0
  6. package/dist/adapters/gh-utils.test.d.ts.map +1 -0
  7. package/dist/adapters/gh-utils.test.js +81 -0
  8. package/dist/adapters/gh-utils.test.js.map +1 -0
  9. package/dist/adapters/github-cli-pr.d.ts +10 -0
  10. package/dist/adapters/github-cli-pr.d.ts.map +1 -0
  11. package/dist/adapters/github-cli-pr.js +83 -0
  12. package/dist/adapters/github-cli-pr.js.map +1 -0
  13. package/dist/adapters/github-cli-pr.test.d.ts +2 -0
  14. package/dist/adapters/github-cli-pr.test.d.ts.map +1 -0
  15. package/dist/adapters/github-cli-pr.test.js +108 -0
  16. package/dist/adapters/github-cli-pr.test.js.map +1 -0
  17. package/dist/adapters/github-cli.d.ts +0 -1
  18. package/dist/adapters/github-cli.d.ts.map +1 -1
  19. package/dist/adapters/github-cli.js +4 -40
  20. package/dist/adapters/github-cli.js.map +1 -1
  21. package/dist/adapters/github-cli.test.d.ts +2 -0
  22. package/dist/adapters/github-cli.test.d.ts.map +1 -0
  23. package/dist/adapters/github-cli.test.js +87 -0
  24. package/dist/adapters/github-cli.test.js.map +1 -0
  25. package/dist/adapters/pr-adapter.d.ts +41 -0
  26. package/dist/adapters/pr-adapter.d.ts.map +1 -0
  27. package/dist/adapters/pr-adapter.js +6 -0
  28. package/dist/adapters/pr-adapter.js.map +1 -0
  29. package/dist/commands/anchor.d.ts.map +1 -1
  30. package/dist/commands/anchor.js +6 -4
  31. package/dist/commands/anchor.js.map +1 -1
  32. package/dist/commands/briefing.d.ts +2 -0
  33. package/dist/commands/briefing.d.ts.map +1 -1
  34. package/dist/commands/briefing.js +19 -38
  35. package/dist/commands/briefing.js.map +1 -1
  36. package/dist/commands/briefing.test.d.ts +2 -0
  37. package/dist/commands/briefing.test.d.ts.map +1 -0
  38. package/dist/commands/briefing.test.js +26 -0
  39. package/dist/commands/briefing.test.js.map +1 -0
  40. package/dist/commands/handoff.d.ts +1 -0
  41. package/dist/commands/handoff.d.ts.map +1 -1
  42. package/dist/commands/handoff.js +17 -14
  43. package/dist/commands/handoff.js.map +1 -1
  44. package/dist/commands/handoff.test.d.ts +2 -0
  45. package/dist/commands/handoff.test.d.ts.map +1 -0
  46. package/dist/commands/handoff.test.js +35 -0
  47. package/dist/commands/handoff.test.js.map +1 -0
  48. package/dist/commands/init.d.ts.map +1 -1
  49. package/dist/commands/init.js +17 -15
  50. package/dist/commands/init.js.map +1 -1
  51. package/dist/commands/learn.d.ts +12 -1
  52. package/dist/commands/learn.d.ts.map +1 -1
  53. package/dist/commands/learn.js +145 -141
  54. package/dist/commands/learn.js.map +1 -1
  55. package/dist/commands/learn.test.d.ts +2 -0
  56. package/dist/commands/learn.test.d.ts.map +1 -0
  57. package/dist/commands/learn.test.js +169 -0
  58. package/dist/commands/learn.test.js.map +1 -0
  59. package/dist/commands/search.d.ts.map +1 -1
  60. package/dist/commands/search.js +5 -4
  61. package/dist/commands/search.js.map +1 -1
  62. package/dist/commands/shield.d.ts.map +1 -1
  63. package/dist/commands/shield.js +21 -16
  64. package/dist/commands/shield.js.map +1 -1
  65. package/dist/commands/shield.test.js +4 -0
  66. package/dist/commands/shield.test.js.map +1 -1
  67. package/dist/commands/spec.d.ts +1 -1
  68. package/dist/commands/spec.d.ts.map +1 -1
  69. package/dist/commands/spec.js +56 -43
  70. package/dist/commands/spec.js.map +1 -1
  71. package/dist/commands/sync.d.ts.map +1 -1
  72. package/dist/commands/sync.js +15 -6
  73. package/dist/commands/sync.js.map +1 -1
  74. package/dist/commands/triage.d.ts +2 -0
  75. package/dist/commands/triage.d.ts.map +1 -1
  76. package/dist/commands/triage.js +15 -12
  77. package/dist/commands/triage.js.map +1 -1
  78. package/dist/commands/triage.test.d.ts +2 -0
  79. package/dist/commands/triage.test.d.ts.map +1 -0
  80. package/dist/commands/triage.test.js +33 -0
  81. package/dist/commands/triage.test.js.map +1 -0
  82. package/dist/index.js +9 -8
  83. package/dist/index.js.map +1 -1
  84. package/dist/orchestrator.test.d.ts +2 -0
  85. package/dist/orchestrator.test.d.ts.map +1 -0
  86. package/dist/orchestrator.test.js +90 -0
  87. package/dist/orchestrator.test.js.map +1 -0
  88. package/dist/ui.d.ts +26 -0
  89. package/dist/ui.d.ts.map +1 -0
  90. package/dist/ui.js +85 -0
  91. package/dist/ui.js.map +1 -0
  92. package/dist/ui.test.d.ts +2 -0
  93. package/dist/ui.test.d.ts.map +1 -0
  94. package/dist/ui.test.js +76 -0
  95. package/dist/ui.test.js.map +1 -0
  96. package/dist/utils.d.ts +16 -0
  97. package/dist/utils.d.ts.map +1 -1
  98. package/dist/utils.js +38 -9
  99. package/dist/utils.js.map +1 -1
  100. package/dist/utils.test.js +277 -2
  101. package/dist/utils.test.js.map +1 -1
  102. package/package.json +4 -2
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Generic PR adapter interface — decouples Totem commands from any
3
+ * specific code hosting platform (GitHub, GitLab, etc.).
4
+ */
5
+ export interface StandardPrListItem {
6
+ number: number;
7
+ title: string;
8
+ headRefName: string;
9
+ }
10
+ export interface StandardPrComment {
11
+ author: string;
12
+ body: string;
13
+ }
14
+ export interface StandardPrReview {
15
+ author: string;
16
+ state: string;
17
+ body: string;
18
+ }
19
+ export interface StandardPr {
20
+ number: number;
21
+ title: string;
22
+ body: string;
23
+ state: string;
24
+ comments: StandardPrComment[];
25
+ reviews: StandardPrReview[];
26
+ }
27
+ export interface StandardReviewComment {
28
+ id: number;
29
+ author: string;
30
+ body: string;
31
+ path: string;
32
+ diffHunk: string;
33
+ inReplyToId?: number;
34
+ createdAt?: string;
35
+ }
36
+ export interface PrAdapter {
37
+ fetchOpenPRs(): StandardPrListItem[];
38
+ fetchPr(prNumber: number): StandardPr;
39
+ fetchReviewComments(prNumber: number): StandardReviewComment[];
40
+ }
41
+ //# sourceMappingURL=pr-adapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pr-adapter.d.ts","sourceRoot":"","sources":["../../src/adapters/pr-adapter.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,iBAAiB,EAAE,CAAC;IAC9B,OAAO,EAAE,gBAAgB,EAAE,CAAC;CAC7B;AAED,MAAM,WAAW,qBAAqB;IACpC,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,SAAS;IACxB,YAAY,IAAI,kBAAkB,EAAE,CAAC;IACrC,OAAO,CAAC,QAAQ,EAAE,MAAM,GAAG,UAAU,CAAC;IACtC,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,qBAAqB,EAAE,CAAC;CAChE"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Generic PR adapter interface — decouples Totem commands from any
3
+ * specific code hosting platform (GitHub, GitLab, etc.).
4
+ */
5
+ export {};
6
+ //# sourceMappingURL=pr-adapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pr-adapter.js","sourceRoot":"","sources":["../../src/adapters/pr-adapter.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
@@ -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,3 +1,5 @@
1
+ import type { StandardPrListItem } from '../adapters/pr-adapter.js';
2
+ export declare function formatPRList(prs: StandardPrListItem[]): string;
1
3
  export interface BriefingOptions {
2
4
  raw?: boolean;
3
5
  out?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"briefing.d.ts","sourceRoot":"","sources":["../../src/commands/briefing.ts"],"names":[],"mappings":"AAwJA,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,CAwC7E"}
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"}
@@ -1,9 +1,9 @@
1
- import { execFileSync } from 'node:child_process';
2
1
  import * as path from 'node:path';
3
- import { z } from 'zod';
4
2
  import { createEmbedder, LanceStore } from '@mmnto/totem';
3
+ import { GitHubCliPrAdapter } from '../adapters/github-cli-pr.js';
5
4
  import { getGitBranch, getGitStatus } from '../git.js';
6
- import { formatResults, GH_TIMEOUT_MS, IS_WIN, 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';
7
7
  // ─── Constants ──────────────────────────────────────────
8
8
  const TAG = 'Briefing';
9
9
  const MAX_SPEC_RESULTS = 5;
@@ -40,28 +40,6 @@ Respond with ONLY the sections below. No preamble, no closing remarks.
40
40
  ### Recommended First Action
41
41
  [Single clear recommendation for what the developer should do first in this session. Consider: uncommitted work to commit/continue, PRs to review/merge, next issue to pick up.]
42
42
  `;
43
- // ─── GitHub helpers ─────────────────────────────────────
44
- const GhPrListItemSchema = z.object({
45
- number: z.number(),
46
- title: z.string(),
47
- headRefName: z.string(),
48
- });
49
- function fetchOpenPRs(cwd) {
50
- try {
51
- const result = execFileSync('gh', ['pr', 'list', '--state', 'open', '--json', 'number,title,headRefName'], { cwd, encoding: 'utf-8', timeout: GH_TIMEOUT_MS, shell: IS_WIN });
52
- return z.array(GhPrListItemSchema).parse(JSON.parse(result));
53
- }
54
- catch (err) {
55
- if (err instanceof z.ZodError) {
56
- throw new Error(`[Totem Error] Failed to parse GitHub PR list response: ${err.message}`);
57
- }
58
- const msg = err instanceof Error ? err.message : String(err);
59
- if (msg.includes('ENOENT') || msg.includes('not found')) {
60
- throw new Error(`[Totem Error] GitHub CLI (gh) is required for PR fetching. Install: https://cli.github.com`);
61
- }
62
- throw new Error(`[Totem Error] Failed to fetch open PRs: ${msg}`);
63
- }
64
- }
65
43
  async function retrieveContext(query, store) {
66
44
  const search = (typeFilter, maxResults) => store.search({ query, typeFilter, maxResults });
67
45
  const [specs, sessions] = await Promise.all([
@@ -71,13 +49,13 @@ async function retrieveContext(query, store) {
71
49
  return { specs, sessions };
72
50
  }
73
51
  // ─── Prompt assembly ────────────────────────────────────
74
- function formatPRList(prs) {
52
+ export function formatPRList(prs) {
75
53
  if (prs.length === 0)
76
54
  return '(none)';
77
55
  return prs.map((pr) => `- #${pr.number} — ${pr.title} (branch: ${pr.headRefName})`).join('\n');
78
56
  }
79
- function assemblePrompt(branch, status, prs, context) {
80
- const sections = [SYSTEM_PROMPT];
57
+ function assemblePrompt(branch, status, prs, context, systemPrompt) {
58
+ const sections = [systemPrompt];
81
59
  // Git state
82
60
  sections.push('=== GIT STATE ===');
83
61
  sections.push(`Branch: ${branch}`);
@@ -103,32 +81,35 @@ export async function briefingCommand(options) {
103
81
  loadEnv(cwd);
104
82
  const config = await loadConfig(configPath);
105
83
  // Gather git state
106
- console.error(`[${TAG}] Gathering git state...`);
84
+ log.info(TAG, 'Gathering git state...');
107
85
  const branch = getGitBranch(cwd);
108
86
  const status = getGitStatus(cwd);
109
- console.error(`[${TAG}] Branch: ${branch}`);
87
+ log.info(TAG, `Branch: ${branch}`);
110
88
  // Fetch open PRs
111
- console.error(`[${TAG}] Fetching open PRs...`);
112
- const prs = fetchOpenPRs(cwd);
113
- console.error(`[${TAG}] Found ${prs.length} open PRs.`);
89
+ log.info(TAG, 'Fetching open PRs...');
90
+ const adapter = new GitHubCliPrAdapter(cwd);
91
+ const prs = adapter.fetchOpenPRs();
92
+ log.info(TAG, `Found ${prs.length} open PRs.`);
114
93
  // Connect to LanceDB
115
94
  const embedder = createEmbedder(config.embedding);
116
95
  const store = new LanceStore(path.join(cwd, config.lanceDir), embedder);
117
96
  await store.connect();
118
97
  // Retrieve context from LanceDB
119
98
  const query = `${branch} active work session priorities`;
120
- console.error(`[${TAG}] Querying Totem index...`);
99
+ log.info(TAG, 'Querying Totem index...');
121
100
  const context = await retrieveContext(query, store);
122
101
  const totalResults = context.specs.length + context.sessions.length;
123
- 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);
124
105
  // Assemble prompt
125
- const prompt = assemblePrompt(branch, status, prs, context);
126
- 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`);
127
108
  const content = runOrchestrator({ prompt, tag: TAG, options, config, cwd, totalResults });
128
109
  if (content != null) {
129
110
  writeOutput(content, options.out);
130
111
  if (options.out)
131
- console.error(`[${TAG}] Written to ${options.out}`);
112
+ log.success(TAG, `Written to ${options.out}`);
132
113
  }
133
114
  }
134
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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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=briefing.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"briefing.test.d.ts","sourceRoot":"","sources":["../../src/commands/briefing.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,26 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import { formatPRList } from './briefing.js';
3
+ describe('formatPRList', () => {
4
+ it('returns (none) for empty PR list', () => {
5
+ expect(formatPRList([])).toBe('(none)');
6
+ });
7
+ it('formats a single PR with number, title, and branch', () => {
8
+ const prs = [
9
+ { number: 42, title: 'Add widget', headRefName: 'feat/widget' },
10
+ ];
11
+ const output = formatPRList(prs);
12
+ expect(output).toBe('- #42 — Add widget (branch: feat/widget)');
13
+ });
14
+ it('formats multiple PRs as a bulleted list', () => {
15
+ const prs = [
16
+ { number: 1, title: 'First', headRefName: 'feat/first' },
17
+ { number: 2, title: 'Second', headRefName: 'feat/second' },
18
+ ];
19
+ const output = formatPRList(prs);
20
+ const lines = output.split('\n');
21
+ expect(lines).toHaveLength(2);
22
+ expect(lines[0]).toContain('#1');
23
+ expect(lines[1]).toContain('#2');
24
+ });
25
+ });
26
+ //# sourceMappingURL=briefing.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"briefing.test.js","sourceRoot":"","sources":["../../src/commands/briefing.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAG9C,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAE7C,QAAQ,CAAC,cAAc,EAAE,GAAG,EAAE;IAC5B,EAAE,CAAC,kCAAkC,EAAE,GAAG,EAAE;QAC1C,MAAM,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC1C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oDAAoD,EAAE,GAAG,EAAE;QAC5D,MAAM,GAAG,GAAyB;YAChC,EAAE,MAAM,EAAE,EAAE,EAAE,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,aAAa,EAAE;SAChE,CAAC;QACF,MAAM,MAAM,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC;QACjC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,0CAA0C,CAAC,CAAC;IAClE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,yCAAyC,EAAE,GAAG,EAAE;QACjD,MAAM,GAAG,GAAyB;YAChC,EAAE,MAAM,EAAE,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE;YACxD,EAAE,MAAM,EAAE,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,aAAa,EAAE;SAC3D,CAAC;QACF,MAAM,MAAM,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC;QACjC,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACjC,MAAM,CAAC,KAAK,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QAC9B,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;QACjC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IACnC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -1,3 +1,4 @@
1
+ export declare function readRecentLessons(cwd: string, totemDir: string): string;
1
2
  export interface HandoffOptions {
2
3
  raw?: boolean;
3
4
  out?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"handoff.d.ts","sourceRoot":"","sources":["../../src/commands/handoff.ts"],"names":[],"mappings":"AAoHA,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;
@@ -42,7 +43,7 @@ Respond with ONLY the sections below. No preamble, no closing remarks.
42
43
  [Clear, ordered list of what the next session should do first. Be specific — not "continue working" but "finish implementing X in file Y, then run tests."]
43
44
  `;
44
45
  // ─── Lessons file reader ────────────────────────────────
45
- function readRecentLessons(cwd, totemDir) {
46
+ export function readRecentLessons(cwd, totemDir) {
46
47
  const lessonsPath = path.join(cwd, totemDir, 'lessons.md');
47
48
  if (!fs.existsSync(lessonsPath))
48
49
  return '';
@@ -53,8 +54,8 @@ 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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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=handoff.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"handoff.test.d.ts","sourceRoot":"","sources":["../../src/commands/handoff.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,35 @@
1
+ import * as fs from 'node:fs';
2
+ import * as os from 'node:os';
3
+ import * as path from 'node:path';
4
+ import { afterEach, beforeEach, describe, expect, it } from 'vitest';
5
+ import { readRecentLessons } from './handoff.js';
6
+ describe('readRecentLessons', () => {
7
+ let tmpDir;
8
+ const totemDir = '.totem';
9
+ beforeEach(() => {
10
+ tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'totem-handoff-'));
11
+ });
12
+ afterEach(() => {
13
+ fs.rmSync(tmpDir, { recursive: true, force: true });
14
+ });
15
+ it('returns empty string when lessons.md does not exist', () => {
16
+ expect(readRecentLessons(tmpDir, totemDir)).toBe('');
17
+ });
18
+ it('returns full content when file is short', () => {
19
+ const lessonsDir = path.join(tmpDir, totemDir);
20
+ fs.mkdirSync(lessonsDir, { recursive: true });
21
+ fs.writeFileSync(path.join(lessonsDir, 'lessons.md'), '## Lesson\nSome content', 'utf-8');
22
+ expect(readRecentLessons(tmpDir, totemDir)).toBe('## Lesson\nSome content');
23
+ });
24
+ it('returns only the last 100 lines for long files', () => {
25
+ const lessonsDir = path.join(tmpDir, totemDir);
26
+ fs.mkdirSync(lessonsDir, { recursive: true });
27
+ const lines = Array.from({ length: 200 }, (_, i) => `Line ${i + 1}`);
28
+ fs.writeFileSync(path.join(lessonsDir, 'lessons.md'), lines.join('\n'), 'utf-8');
29
+ const result = readRecentLessons(tmpDir, totemDir);
30
+ expect(result).toContain('Line 200');
31
+ expect(result).toContain('Line 101');
32
+ expect(result).not.toContain('Line 100\n');
33
+ });
34
+ });
35
+ //# sourceMappingURL=handoff.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"handoff.test.js","sourceRoot":"","sources":["../../src/commands/handoff.test.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAElC,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAErE,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAEjD,QAAQ,CAAC,mBAAmB,EAAE,GAAG,EAAE;IACjC,IAAI,MAAc,CAAC;IACnB,MAAM,QAAQ,GAAG,QAAQ,CAAC;IAE1B,UAAU,CAAC,GAAG,EAAE;QACd,MAAM,GAAG,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,gBAAgB,CAAC,CAAC,CAAC;IACpE,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,GAAG,EAAE;QACb,EAAE,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IACtD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qDAAqD,EAAE,GAAG,EAAE;QAC7D,MAAM,CAAC,iBAAiB,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACvD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,yCAAyC,EAAE,GAAG,EAAE;QACjD,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;QAC/C,EAAE,CAAC,SAAS,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC9C,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,YAAY,CAAC,EAAE,yBAAyB,EAAE,OAAO,CAAC,CAAC;QAC1F,MAAM,CAAC,iBAAiB,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC;IAC9E,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gDAAgD,EAAE,GAAG,EAAE;QACxD,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;QAC/C,EAAE,CAAC,SAAS,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC9C,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACrE,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,YAAY,CAAC,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC,CAAC;QAEjF,MAAM,MAAM,GAAG,iBAAiB,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;QACnD,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;QACrC,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;QACrC,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;IAC7C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -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,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,CAiLjD"}
@@ -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 = `
@@ -223,9 +224,10 @@ export async function initCommand() {
223
224
  const rl = readline.createInterface({ input, output });
224
225
  const summary = [];
225
226
  try {
227
+ printBanner();
226
228
  if (!configExists) {
227
229
  // --- Fresh install: generate config ---
228
- console.log('[Totem] Scanning project...');
230
+ log.info('Totem', 'Scanning project...');
229
231
  const detected = detectProject(cwd);
230
232
  const detections = [];
231
233
  if (detected.hasTypeScript)
@@ -241,10 +243,10 @@ export async function initCommand() {
241
243
  if (detected.hasSessions)
242
244
  detections.push('session logs');
243
245
  if (detections.length > 0) {
244
- console.log(`[Totem] Detected: ${detections.join(', ')}`);
246
+ log.info('Totem', `Detected: ${bold(detections.join(', '))}`);
245
247
  }
246
248
  else {
247
- console.log('[Totem] No specific project structure detected. Using markdown defaults.');
249
+ log.dim('Totem', 'No specific project structure detected. Using markdown defaults.');
248
250
  }
249
251
  const targets = buildTargets(detected);
250
252
  let provider = 'openai';
@@ -252,7 +254,7 @@ export async function initCommand() {
252
254
  const apiKey = answer.trim().replace(/[\r\n]/g, '');
253
255
  if (apiKey) {
254
256
  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.');
257
+ log.warn('Totem', 'API key does not look like a valid OpenAI key (expected sk-...). Skipping.');
256
258
  provider = 'ollama';
257
259
  }
258
260
  else {
@@ -273,14 +275,14 @@ export async function initCommand() {
273
275
  }
274
276
  else {
275
277
  provider = 'ollama';
276
- console.log('[Totem] Configured for Ollama. Make sure it is running locally.');
278
+ log.info('Totem', 'Configured for Ollama. Make sure it is running locally.');
277
279
  }
278
280
  const configContent = generateConfig(targets, provider);
279
281
  fs.writeFileSync(configPath, configContent, 'utf-8');
280
282
  summary.push({ file: 'totem.config.ts', action: 'Created with auto-detected targets' });
281
283
  }
282
284
  else {
283
- console.log('[Totem] totem.config.ts already exists. Checking reflexes and hooks...');
285
+ log.dim('Totem', 'totem.config.ts already exists. Checking reflexes and hooks...');
284
286
  }
285
287
  // --- Always run: .totem/ directory ---
286
288
  if (!fs.existsSync(totemDir)) {
@@ -295,7 +297,7 @@ export async function initCommand() {
295
297
  const detectedTools = detectAiTools(cwd);
296
298
  if (detectedTools.length > 0) {
297
299
  const toolNames = detectedTools.map((t) => t.name).join(', ');
298
- console.log(`\n[Totem] Detected AI tools: ${toolNames}`);
300
+ log.info('Totem', `Detected AI tools: ${bold(toolNames)}`);
299
301
  const toolAnswer = await rl.question('Which tools should Totem configure? [all/none/select] (default: all): ');
300
302
  let selectedTools;
301
303
  const trimmed = toolAnswer.trim().toLowerCase();
@@ -320,9 +322,9 @@ export async function initCommand() {
320
322
  const filePath = path.join(cwd, tool.mcpPath);
321
323
  const result = scaffoldMcpConfig(filePath, tool.serverEntry);
322
324
  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`);
325
+ log.error('Totem', result.err);
326
+ console.error(`To fix this, add the following manually to your ${tool.mcpPath} under "mcpServers":\n`);
327
+ console.error(` "totem": ${JSON.stringify(tool.serverEntry, null, 2)}\n`);
326
328
  }
327
329
  else if (result.action === 'created') {
328
330
  summary.push({ file: tool.mcpPath, action: `Created with Totem MCP server` });
@@ -344,7 +346,7 @@ export async function initCommand() {
344
346
  }
345
347
  catch (err) {
346
348
  const message = err instanceof Error ? err.message : String(err);
347
- console.error(`\n[Totem Error] Failed to inject reflexes into ${tool.reflexFile}: ${message}`);
349
+ log.error('Totem', `Failed to inject reflexes into ${tool.reflexFile}: ${message}`);
348
350
  }
349
351
  }
350
352
  }
@@ -361,13 +363,13 @@ export async function initCommand() {
361
363
  }
362
364
  // --- Print summary ---
363
365
  if (summary.length > 0) {
364
- console.log('\n--- Totem Init Summary ---');
366
+ console.error(`\n${brand('--- Totem Init Summary ---')}`);
365
367
  for (const entry of summary) {
366
- console.log(` [OK] ${entry.file} — ${entry.action}`);
368
+ console.error(` ${success('OK')} ${dim(entry.file)} — ${entry.action}`);
367
369
  }
368
- console.log('--------------------------');
370
+ console.error(brand('--------------------------'));
369
371
  }
370
- console.log('\n[Totem] Init complete. Run `totem sync` to index your project.');
372
+ log.success('Totem', 'Init complete. Run `totem sync` to index your project.');
371
373
  }
372
374
  finally {
373
375
  rl.close();