@stackmemoryai/stackmemory 0.5.21 → 0.5.23

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.
@@ -11,12 +11,18 @@ import { program } from "commander";
11
11
  import { v4 as uuidv4 } from "uuid";
12
12
  import chalk from "chalk";
13
13
  import { initializeTracing, trace } from "../core/trace/index.js";
14
+ import {
15
+ generateSessionSummary,
16
+ formatSummaryMessage
17
+ } from "../hooks/session-summary.js";
18
+ import { sendNotification } from "../hooks/sms-notify.js";
14
19
  const DEFAULT_SM_CONFIG = {
15
20
  defaultWorktree: false,
16
21
  defaultSandbox: false,
17
22
  defaultChrome: false,
18
23
  defaultTracing: true,
19
- defaultRemote: false
24
+ defaultRemote: false,
25
+ defaultNotifyOnDone: true
20
26
  };
21
27
  function getConfigPath() {
22
28
  return path.join(os.homedir(), ".stackmemory", "claude-sm.json");
@@ -54,9 +60,11 @@ class ClaudeSM {
54
60
  useChrome: this.smConfig.defaultChrome,
55
61
  useWorktree: this.smConfig.defaultWorktree,
56
62
  useRemote: this.smConfig.defaultRemote,
63
+ notifyOnDone: this.smConfig.defaultNotifyOnDone,
57
64
  contextEnabled: true,
58
65
  tracingEnabled: this.smConfig.defaultTracing,
59
- verboseTracing: false
66
+ verboseTracing: false,
67
+ sessionStartTime: Date.now()
60
68
  };
61
69
  this.stackmemoryPath = this.findStackMemory();
62
70
  this.worktreeScriptPath = path.join(
@@ -192,18 +200,15 @@ class ClaudeSM {
192
200
  if (!this.config.contextEnabled) return;
193
201
  try {
194
202
  console.log(chalk.blue("\u{1F4DA} Loading previous context..."));
195
- const cmd = `${this.stackmemoryPath} context list --limit 5 --format json`;
196
- const output = execSync(cmd, { encoding: "utf8" });
197
- const contexts = JSON.parse(output);
198
- if (contexts.length > 0) {
199
- console.log(chalk.gray("Recent context loaded:"));
200
- contexts.forEach(
201
- (ctx) => {
202
- console.log(
203
- chalk.gray(` - ${ctx.message} (${ctx.metadata?.timestamp})`)
204
- );
205
- }
206
- );
203
+ const cmd = `${this.stackmemoryPath} context show`;
204
+ const output = execSync(cmd, {
205
+ encoding: "utf8",
206
+ stdio: ["pipe", "pipe", "pipe"]
207
+ // Capture stderr to suppress errors
208
+ });
209
+ const lines = output.trim().split("\n").filter((l) => l.trim());
210
+ if (lines.length > 3) {
211
+ console.log(chalk.gray("Context stack loaded"));
207
212
  }
208
213
  } catch {
209
214
  }
@@ -238,6 +243,48 @@ class ClaudeSM {
238
243
  );
239
244
  }
240
245
  }
246
+ async sendDoneNotification(exitCode) {
247
+ try {
248
+ const context = {
249
+ instanceId: this.config.instanceId,
250
+ exitCode,
251
+ sessionStartTime: this.config.sessionStartTime,
252
+ worktreePath: this.config.worktreePath,
253
+ branch: this.config.branch,
254
+ task: this.config.task
255
+ };
256
+ const summary = await generateSessionSummary(context);
257
+ const message = formatSummaryMessage(summary);
258
+ console.log(chalk.cyan("\nSending session summary via WhatsApp..."));
259
+ const options = summary.suggestions.slice(0, 4).map((s) => ({
260
+ key: s.key,
261
+ label: s.label,
262
+ action: s.action
263
+ }));
264
+ const result = await sendNotification({
265
+ type: "task_complete",
266
+ title: "Claude Session Complete",
267
+ message,
268
+ prompt: options.length > 0 ? {
269
+ type: "options",
270
+ options
271
+ } : void 0
272
+ });
273
+ if (result.success) {
274
+ console.log(chalk.green("Notification sent successfully"));
275
+ } else {
276
+ console.log(
277
+ chalk.yellow(`Notification not sent: ${result.error || "unknown"}`)
278
+ );
279
+ }
280
+ } catch (error) {
281
+ console.log(
282
+ chalk.yellow(
283
+ `Could not send notification: ${error instanceof Error ? error.message : "unknown"}`
284
+ )
285
+ );
286
+ }
287
+ }
241
288
  async run(args) {
242
289
  const claudeArgs = [];
243
290
  let i = 0;
@@ -259,6 +306,13 @@ class ClaudeSM {
259
306
  case "--no-remote":
260
307
  this.config.useRemote = false;
261
308
  break;
309
+ case "--notify-done":
310
+ case "-n":
311
+ this.config.notifyOnDone = true;
312
+ break;
313
+ case "--no-notify-done":
314
+ this.config.notifyOnDone = false;
315
+ break;
262
316
  case "--sandbox":
263
317
  case "-s":
264
318
  this.config.useSandbox = true;
@@ -421,7 +475,7 @@ class ClaudeSM {
421
475
  }
422
476
  process.exit(1);
423
477
  });
424
- claude.on("exit", (code) => {
478
+ claude.on("exit", async (code) => {
425
479
  this.saveContext("Claude session ended", {
426
480
  action: "session_end",
427
481
  exitCode: code
@@ -433,6 +487,9 @@ class ClaudeSM {
433
487
  console.log(chalk.blue("Debug Trace Summary:"));
434
488
  console.log(chalk.gray(summary));
435
489
  }
490
+ if (this.config.notifyOnDone || this.config.useRemote) {
491
+ await this.sendDoneNotification(code);
492
+ }
436
493
  if (this.config.worktreePath) {
437
494
  console.log();
438
495
  console.log(chalk.gray("\u2500".repeat(42)));
@@ -478,6 +535,9 @@ configCmd.command("show").description("Show current default settings").action(()
478
535
  console.log(
479
536
  ` defaultRemote: ${config.defaultRemote ? chalk.green("true") : chalk.gray("false")}`
480
537
  );
538
+ console.log(
539
+ ` defaultNotifyOnDone: ${config.defaultNotifyOnDone ? chalk.green("true") : chalk.gray("false")}`
540
+ );
481
541
  console.log(chalk.gray(`
482
542
  Config: ${getConfigPath()}`));
483
543
  });
@@ -489,13 +549,17 @@ configCmd.command("set <key> <value>").description("Set a default (e.g., set wor
489
549
  sandbox: "defaultSandbox",
490
550
  chrome: "defaultChrome",
491
551
  tracing: "defaultTracing",
492
- remote: "defaultRemote"
552
+ remote: "defaultRemote",
553
+ "notify-done": "defaultNotifyOnDone",
554
+ notifyondone: "defaultNotifyOnDone"
493
555
  };
494
556
  const configKey = keyMap[key];
495
557
  if (!configKey) {
496
558
  console.log(chalk.red(`Unknown key: ${key}`));
497
559
  console.log(
498
- chalk.gray("Valid keys: worktree, sandbox, chrome, tracing, remote")
560
+ chalk.gray(
561
+ "Valid keys: worktree, sandbox, chrome, tracing, remote, notify-done"
562
+ )
499
563
  );
500
564
  process.exit(1);
501
565
  }
@@ -527,7 +591,19 @@ configCmd.command("remote-off").description("Disable remote mode by default").ac
527
591
  saveSMConfig(config);
528
592
  console.log(chalk.green("Remote mode disabled by default"));
529
593
  });
530
- program.option("-w, --worktree", "Create isolated worktree for this instance").option("-W, --no-worktree", "Disable worktree (override default)").option("-r, --remote", "Enable remote mode (WhatsApp for all questions)").option("--no-remote", "Disable remote mode (override default)").option("-s, --sandbox", "Enable sandbox mode (file/network restrictions)").option("-c, --chrome", "Enable Chrome automation").option("-a, --auto", "Automatically detect and apply best settings").option("-b, --branch <name>", "Specify branch name for worktree").option("-t, --task <desc>", "Task description for context").option("--claude-bin <path>", "Path to claude CLI (or use CLAUDE_BIN)").option("--no-context", "Disable StackMemory context integration").option("--no-trace", "Disable debug tracing (enabled by default)").option("--verbose-trace", "Enable verbose debug tracing with full details").helpOption("-h, --help", "Display help").allowUnknownOption(true).action(async (_options) => {
594
+ configCmd.command("notify-done-on").description("Enable WhatsApp notification when session ends (default)").action(() => {
595
+ const config = loadSMConfig();
596
+ config.defaultNotifyOnDone = true;
597
+ saveSMConfig(config);
598
+ console.log(chalk.green("Notify-on-done enabled by default"));
599
+ });
600
+ configCmd.command("notify-done-off").description("Disable notification when session ends").action(() => {
601
+ const config = loadSMConfig();
602
+ config.defaultNotifyOnDone = false;
603
+ saveSMConfig(config);
604
+ console.log(chalk.green("Notify-on-done disabled by default"));
605
+ });
606
+ program.option("-w, --worktree", "Create isolated worktree for this instance").option("-W, --no-worktree", "Disable worktree (override default)").option("-r, --remote", "Enable remote mode (WhatsApp for all questions)").option("--no-remote", "Disable remote mode (override default)").option("-n, --notify-done", "Send WhatsApp notification when session ends").option("--no-notify-done", "Disable notification when session ends").option("-s, --sandbox", "Enable sandbox mode (file/network restrictions)").option("-c, --chrome", "Enable Chrome automation").option("-a, --auto", "Automatically detect and apply best settings").option("-b, --branch <name>", "Specify branch name for worktree").option("-t, --task <desc>", "Task description for context").option("--claude-bin <path>", "Path to claude CLI (or use CLAUDE_BIN)").option("--no-context", "Disable StackMemory context integration").option("--no-trace", "Disable debug tracing (enabled by default)").option("--verbose-trace", "Enable verbose debug tracing with full details").helpOption("-h, --help", "Display help").allowUnknownOption(true).action(async (_options) => {
531
607
  const claudeSM = new ClaudeSM();
532
608
  const args = process.argv.slice(2);
533
609
  await claudeSM.run(args);
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/cli/claude-sm.ts"],
4
- "sourcesContent": ["#!/usr/bin/env node\n\n/**\n * claude-sm: Claude wrapper with StackMemory and worktree integration\n * Automatically manages context persistence and instance isolation\n */\n\nimport { spawn, execSync, execFileSync } from 'child_process';\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport * as os from 'os';\nimport { program } from 'commander';\nimport { v4 as uuidv4 } from 'uuid';\nimport chalk from 'chalk';\nimport { initializeTracing, trace } from '../core/trace/index.js';\n\n// __filename and __dirname are provided by esbuild banner for ESM compatibility\n\ninterface ClaudeSMConfig {\n defaultWorktree: boolean;\n defaultSandbox: boolean;\n defaultChrome: boolean;\n defaultTracing: boolean;\n defaultRemote: boolean;\n}\n\ninterface ClaudeConfig {\n instanceId: string;\n worktreePath?: string;\n useSandbox: boolean;\n useChrome: boolean;\n useWorktree: boolean;\n useRemote: boolean;\n contextEnabled: boolean;\n branch?: string;\n task?: string;\n tracingEnabled: boolean;\n verboseTracing: boolean;\n claudeBin?: string;\n}\n\nconst DEFAULT_SM_CONFIG: ClaudeSMConfig = {\n defaultWorktree: false,\n defaultSandbox: false,\n defaultChrome: false,\n defaultTracing: true,\n defaultRemote: false,\n};\n\nfunction getConfigPath(): string {\n return path.join(os.homedir(), '.stackmemory', 'claude-sm.json');\n}\n\nfunction loadSMConfig(): ClaudeSMConfig {\n try {\n const configPath = getConfigPath();\n if (fs.existsSync(configPath)) {\n const content = fs.readFileSync(configPath, 'utf8');\n return { ...DEFAULT_SM_CONFIG, ...JSON.parse(content) };\n }\n } catch {\n // Ignore errors, use defaults\n }\n return { ...DEFAULT_SM_CONFIG };\n}\n\nfunction saveSMConfig(config: ClaudeSMConfig): void {\n const configPath = getConfigPath();\n const dir = path.dirname(configPath);\n if (!fs.existsSync(dir)) {\n fs.mkdirSync(dir, { recursive: true });\n }\n fs.writeFileSync(configPath, JSON.stringify(config, null, 2));\n}\n\nclass ClaudeSM {\n private config: ClaudeConfig;\n private stackmemoryPath: string;\n private worktreeScriptPath: string;\n private claudeConfigDir: string;\n private smConfig: ClaudeSMConfig;\n\n constructor() {\n // Load persistent defaults\n this.smConfig = loadSMConfig();\n\n this.config = {\n instanceId: this.generateInstanceId(),\n useSandbox: this.smConfig.defaultSandbox,\n useChrome: this.smConfig.defaultChrome,\n useWorktree: this.smConfig.defaultWorktree,\n useRemote: this.smConfig.defaultRemote,\n contextEnabled: true,\n tracingEnabled: this.smConfig.defaultTracing,\n verboseTracing: false,\n };\n\n this.stackmemoryPath = this.findStackMemory();\n this.worktreeScriptPath = path.join(\n __dirname,\n '../../scripts/claude-worktree-manager.sh'\n );\n this.claudeConfigDir = path.join(os.homedir(), '.claude');\n\n // Ensure config directory exists\n if (!fs.existsSync(this.claudeConfigDir)) {\n fs.mkdirSync(this.claudeConfigDir, { recursive: true });\n }\n }\n\n private generateInstanceId(): string {\n return uuidv4().substring(0, 8);\n }\n\n private findStackMemory(): string {\n // Check multiple possible locations\n const possiblePaths = [\n path.join(os.homedir(), '.stackmemory', 'bin', 'stackmemory'),\n '/usr/local/bin/stackmemory',\n '/opt/homebrew/bin/stackmemory',\n 'stackmemory', // Rely on PATH\n ];\n\n for (const smPath of possiblePaths) {\n try {\n execFileSync('which', [smPath], { stdio: 'ignore' });\n return smPath;\n } catch {\n // Continue searching\n }\n }\n\n return 'stackmemory'; // Fallback to PATH\n }\n\n private isGitRepo(): boolean {\n try {\n execSync('git rev-parse --git-dir', { stdio: 'ignore' });\n return true;\n } catch {\n return false;\n }\n }\n\n private getCurrentBranch(): string {\n try {\n return execSync('git rev-parse --abbrev-ref HEAD', {\n encoding: 'utf8',\n }).trim();\n } catch {\n return 'main';\n }\n }\n\n private hasUncommittedChanges(): boolean {\n try {\n const status = execSync('git status --porcelain', { encoding: 'utf8' });\n return status.length > 0;\n } catch {\n return false;\n }\n }\n\n private resolveClaudeBin(): string | null {\n // 1) CLI-specified\n if (this.config.claudeBin && this.config.claudeBin.trim()) {\n return this.config.claudeBin.trim();\n }\n // 2) Env override\n const envBin = process.env['CLAUDE_BIN'];\n if (envBin && envBin.trim()) return envBin.trim();\n // 3) PATH detection\n try {\n execSync('which claude', { stdio: 'ignore' });\n return 'claude';\n } catch {}\n return null;\n }\n\n private setupWorktree(): string | null {\n if (!this.config.useWorktree || !this.isGitRepo()) {\n return null;\n }\n\n console.log(chalk.blue('\uD83C\uDF33 Setting up isolated worktree...'));\n\n const timestamp = new Date()\n .toISOString()\n .replace(/[:.]/g, '-')\n .substring(0, 19);\n const branch =\n this.config.branch ||\n `claude-${this.config.task || 'work'}-${timestamp}-${this.config.instanceId}`;\n const repoName = path.basename(process.cwd());\n const worktreePath = path.join(\n path.dirname(process.cwd()),\n `${repoName}--${branch}`\n );\n\n try {\n // Create worktree\n const flags = [];\n if (this.config.useSandbox) flags.push('--sandbox');\n if (this.config.useChrome) flags.push('--chrome');\n\n const cmd = `git worktree add -b \"${branch}\" \"${worktreePath}\"`;\n execSync(cmd, { stdio: 'inherit' });\n\n console.log(chalk.green(`\u2705 Worktree created: ${worktreePath}`));\n console.log(chalk.gray(` Branch: ${branch}`));\n\n // Save worktree config\n const configPath = path.join(worktreePath, '.claude-instance.json');\n const configData = {\n instanceId: this.config.instanceId,\n worktreePath,\n branch,\n task: this.config.task,\n sandboxEnabled: this.config.useSandbox,\n chromeEnabled: this.config.useChrome,\n created: new Date().toISOString(),\n parentRepo: process.cwd(),\n };\n fs.writeFileSync(configPath, JSON.stringify(configData, null, 2));\n\n // Copy environment files\n const envFiles = ['.env', '.env.local', '.mise.toml', '.tool-versions'];\n for (const file of envFiles) {\n const srcPath = path.join(process.cwd(), file);\n if (fs.existsSync(srcPath)) {\n fs.copyFileSync(srcPath, path.join(worktreePath, file));\n }\n }\n\n return worktreePath;\n } catch (err: unknown) {\n console.error(chalk.red('\u274C Failed to create worktree:'), err);\n return null;\n }\n }\n\n private saveContext(\n message: string,\n metadata: Record<string, unknown> = {}\n ): void {\n if (!this.config.contextEnabled) return;\n\n try {\n const contextData = {\n message,\n metadata: {\n ...metadata,\n instanceId: this.config.instanceId,\n worktree: this.config.worktreePath,\n timestamp: new Date().toISOString(),\n },\n };\n\n const cmd = `${this.stackmemoryPath} context save --json '${JSON.stringify(contextData)}'`;\n execSync(cmd, { stdio: 'ignore' });\n } catch {\n // Silently fail - don't interrupt Claude\n }\n }\n\n private loadContext(): void {\n if (!this.config.contextEnabled) return;\n\n try {\n console.log(chalk.blue('\uD83D\uDCDA Loading previous context...'));\n\n const cmd = `${this.stackmemoryPath} context list --limit 5 --format json`;\n const output = execSync(cmd, { encoding: 'utf8' });\n const contexts = JSON.parse(output);\n\n if (contexts.length > 0) {\n console.log(chalk.gray('Recent context loaded:'));\n contexts.forEach(\n (ctx: { message: string; metadata?: { timestamp?: string } }) => {\n console.log(\n chalk.gray(` - ${ctx.message} (${ctx.metadata?.timestamp})`)\n );\n }\n );\n }\n } catch {\n // Silently continue\n }\n }\n\n private detectMultipleInstances(): boolean {\n try {\n const lockDir = path.join(process.cwd(), '.claude-worktree-locks');\n if (!fs.existsSync(lockDir)) return false;\n\n const locks = fs.readdirSync(lockDir).filter((f) => f.endsWith('.lock'));\n const activeLocks = locks.filter((lockFile) => {\n const lockPath = path.join(lockDir, lockFile);\n const lockData = JSON.parse(fs.readFileSync(lockPath, 'utf8'));\n const lockAge = Date.now() - new Date(lockData.created).getTime();\n return lockAge < 24 * 60 * 60 * 1000; // Less than 24 hours old\n });\n\n return activeLocks.length > 0;\n } catch {\n return false;\n }\n }\n\n private suggestWorktreeMode(): void {\n if (this.hasUncommittedChanges()) {\n console.log(chalk.yellow('\u26A0\uFE0F Uncommitted changes detected'));\n console.log(\n chalk.gray(' Consider using --worktree to work in isolation')\n );\n }\n\n if (this.detectMultipleInstances()) {\n console.log(chalk.yellow('\u26A0\uFE0F Other Claude instances detected'));\n console.log(\n chalk.gray(' Using --worktree is recommended to avoid conflicts')\n );\n }\n }\n\n public async run(args: string[]): Promise<void> {\n // Parse arguments\n const claudeArgs: string[] = [];\n let i = 0;\n\n while (i < args.length) {\n const arg = args[i];\n\n switch (arg) {\n case '--worktree':\n case '-w':\n this.config.useWorktree = true;\n break;\n case '--no-worktree':\n case '-W':\n this.config.useWorktree = false;\n break;\n case '--remote':\n case '-r':\n this.config.useRemote = true;\n break;\n case '--no-remote':\n this.config.useRemote = false;\n break;\n case '--sandbox':\n case '-s':\n this.config.useSandbox = true;\n claudeArgs.push('--sandbox');\n break;\n case '--chrome':\n case '-c':\n this.config.useChrome = true;\n claudeArgs.push('--chrome');\n break;\n case '--no-context':\n this.config.contextEnabled = false;\n break;\n case '--no-trace':\n this.config.tracingEnabled = false;\n break;\n case '--verbose-trace':\n this.config.verboseTracing = true;\n break;\n case '--branch':\n case '-b':\n i++;\n this.config.branch = args[i];\n break;\n case '--task':\n case '-t':\n i++;\n this.config.task = args[i];\n break;\n case '--claude-bin':\n i++;\n this.config.claudeBin = args[i];\n process.env['CLAUDE_BIN'] = this.config.claudeBin;\n break;\n case '--auto':\n case '-a':\n // Auto mode: detect and apply best settings\n if (this.isGitRepo()) {\n this.config.useWorktree =\n this.hasUncommittedChanges() || this.detectMultipleInstances();\n }\n break;\n default:\n claudeArgs.push(arg);\n }\n i++;\n }\n\n // Initialize tracing system if enabled\n if (this.config.tracingEnabled) {\n // Set up environment for tracing\n process.env['DEBUG_TRACE'] = 'true';\n process.env['STACKMEMORY_DEBUG'] = 'true';\n process.env['TRACE_OUTPUT'] = 'file'; // Write to file to not clutter Claude output\n process.env['TRACE_MASK_SENSITIVE'] = 'true'; // Always mask sensitive data\n\n if (this.config.verboseTracing) {\n process.env['TRACE_VERBOSITY'] = 'full';\n process.env['TRACE_PARAMS'] = 'true';\n process.env['TRACE_RESULTS'] = 'true';\n process.env['TRACE_MEMORY'] = 'true';\n } else {\n process.env['TRACE_VERBOSITY'] = 'summary';\n process.env['TRACE_PARAMS'] = 'true';\n process.env['TRACE_RESULTS'] = 'false';\n }\n\n // Initialize the tracing system\n initializeTracing();\n\n // Start tracing this Claude session\n trace.command(\n 'claude-sm',\n {\n instanceId: this.config.instanceId,\n worktree: this.config.useWorktree,\n sandbox: this.config.useSandbox,\n task: this.config.task,\n },\n async () => {\n // Session tracing will wrap the entire Claude execution\n }\n );\n }\n\n // Show header\n console.log(chalk.blue('\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557'));\n console.log(chalk.blue('\u2551 Claude + StackMemory + Worktree \u2551'));\n console.log(chalk.blue('\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D'));\n console.log();\n\n // Check Git repo status\n if (this.isGitRepo()) {\n const branch = this.getCurrentBranch();\n console.log(chalk.gray(`\uD83D\uDCCD Current branch: ${branch}`));\n\n if (!this.config.useWorktree) {\n this.suggestWorktreeMode();\n }\n }\n\n // Setup worktree if requested\n if (this.config.useWorktree) {\n const worktreePath = this.setupWorktree();\n if (worktreePath) {\n this.config.worktreePath = worktreePath;\n process.chdir(worktreePath);\n\n // Save context about worktree creation\n this.saveContext('Created worktree for Claude instance', {\n action: 'worktree_created',\n path: worktreePath,\n branch: this.config.branch,\n });\n }\n }\n\n // Load previous context\n this.loadContext();\n\n // Setup environment\n process.env['CLAUDE_INSTANCE_ID'] = this.config.instanceId;\n if (this.config.worktreePath) {\n process.env['CLAUDE_WORKTREE_PATH'] = this.config.worktreePath;\n }\n if (this.config.useRemote) {\n process.env['CLAUDE_REMOTE'] = '1';\n }\n\n console.log(chalk.gray(`\uD83E\uDD16 Instance ID: ${this.config.instanceId}`));\n console.log(chalk.gray(`\uD83D\uDCC1 Working in: ${process.cwd()}`));\n\n if (this.config.useSandbox) {\n console.log(chalk.yellow('\uD83D\uDD12 Sandbox mode enabled'));\n }\n if (this.config.useRemote) {\n console.log(\n chalk.cyan('\uD83D\uDCF1 Remote mode: WhatsApp notifications for all questions')\n );\n }\n if (this.config.useChrome) {\n console.log(chalk.yellow('\uD83C\uDF10 Chrome automation enabled'));\n }\n if (this.config.tracingEnabled) {\n console.log(\n chalk.gray(`\uD83D\uDD0D Debug tracing enabled (logs to ~/.stackmemory/traces/)`)\n );\n if (this.config.verboseTracing) {\n console.log(\n chalk.gray(` Verbose mode: capturing all execution details`)\n );\n }\n }\n\n console.log();\n console.log(chalk.gray('Starting Claude...'));\n console.log(chalk.gray('\u2500'.repeat(42)));\n\n const claudeBin = this.resolveClaudeBin();\n if (!claudeBin) {\n console.error(chalk.red('\u274C Claude CLI not found.'));\n console.log(\n chalk.gray(\n ' Install Claude CLI or set an override:\\n' +\n ' export CLAUDE_BIN=/path/to/claude\\n' +\n ' claude-sm --help\\n\\n' +\n ' Ensure PATH includes npm global bin (npm bin -g).'\n )\n );\n process.exit(1);\n return;\n }\n\n // Launch Claude\n const claude = spawn(claudeBin, claudeArgs, {\n stdio: 'inherit',\n env: process.env,\n });\n\n claude.on('error', (err: NodeJS.ErrnoException) => {\n console.error(chalk.red('\u274C Failed to launch Claude CLI.'));\n if (err.code === 'ENOENT') {\n console.error(\n chalk.gray(' Not found. Set CLAUDE_BIN or install claude on PATH.')\n );\n } else if (err.code === 'EPERM' || err.code === 'EACCES') {\n console.error(\n chalk.gray(\n ' Permission/sandbox issue. Try outside a sandbox or set CLAUDE_BIN.'\n )\n );\n } else {\n console.error(chalk.gray(` ${err.message}`));\n }\n process.exit(1);\n });\n\n // Handle exit\n claude.on('exit', (code) => {\n // Save final context\n this.saveContext('Claude session ended', {\n action: 'session_end',\n exitCode: code,\n });\n\n // End tracing and show summary if enabled\n if (this.config.tracingEnabled) {\n const summary = trace.getExecutionSummary();\n console.log();\n console.log(chalk.gray('\u2500'.repeat(42)));\n console.log(chalk.blue('Debug Trace Summary:'));\n console.log(chalk.gray(summary));\n }\n\n // Offer to clean up worktree\n if (this.config.worktreePath) {\n console.log();\n console.log(chalk.gray('\u2500'.repeat(42)));\n console.log(chalk.blue('Session ended in worktree:'));\n console.log(chalk.gray(` ${this.config.worktreePath}`));\n console.log();\n console.log(chalk.gray('To remove worktree: gd_claude'));\n console.log(chalk.gray('To merge to main: cwm'));\n }\n\n process.exit(code || 0);\n });\n\n // Handle signals\n process.on('SIGINT', () => {\n this.saveContext('Claude session interrupted', {\n action: 'session_interrupt',\n });\n claude.kill('SIGINT');\n });\n\n process.on('SIGTERM', () => {\n this.saveContext('Claude session terminated', {\n action: 'session_terminate',\n });\n claude.kill('SIGTERM');\n });\n }\n}\n\n// CLI interface\nprogram\n .name('claude-sm')\n .description('Claude with StackMemory context and worktree isolation')\n .version('1.0.0');\n\n// Config subcommand\nconst configCmd = program\n .command('config')\n .description('Manage claude-sm defaults');\n\nconfigCmd\n .command('show')\n .description('Show current default settings')\n .action(() => {\n const config = loadSMConfig();\n console.log(chalk.blue('claude-sm defaults:'));\n console.log(\n ` defaultWorktree: ${config.defaultWorktree ? chalk.green('true') : chalk.gray('false')}`\n );\n console.log(\n ` defaultSandbox: ${config.defaultSandbox ? chalk.green('true') : chalk.gray('false')}`\n );\n console.log(\n ` defaultChrome: ${config.defaultChrome ? chalk.green('true') : chalk.gray('false')}`\n );\n console.log(\n ` defaultTracing: ${config.defaultTracing ? chalk.green('true') : chalk.gray('false')}`\n );\n console.log(\n ` defaultRemote: ${config.defaultRemote ? chalk.green('true') : chalk.gray('false')}`\n );\n console.log(chalk.gray(`\\nConfig: ${getConfigPath()}`));\n });\n\nconfigCmd\n .command('set <key> <value>')\n .description('Set a default (e.g., set worktree true)')\n .action((key: string, value: string) => {\n const config = loadSMConfig();\n const boolValue = value === 'true' || value === '1' || value === 'on';\n\n const keyMap: Record<string, keyof ClaudeSMConfig> = {\n worktree: 'defaultWorktree',\n sandbox: 'defaultSandbox',\n chrome: 'defaultChrome',\n tracing: 'defaultTracing',\n remote: 'defaultRemote',\n };\n\n const configKey = keyMap[key];\n if (!configKey) {\n console.log(chalk.red(`Unknown key: ${key}`));\n console.log(\n chalk.gray('Valid keys: worktree, sandbox, chrome, tracing, remote')\n );\n process.exit(1);\n }\n\n config[configKey] = boolValue;\n saveSMConfig(config);\n console.log(chalk.green(`Set ${key} = ${boolValue}`));\n });\n\nconfigCmd\n .command('worktree-on')\n .description('Enable worktree mode by default')\n .action(() => {\n const config = loadSMConfig();\n config.defaultWorktree = true;\n saveSMConfig(config);\n console.log(chalk.green('Worktree mode enabled by default'));\n });\n\nconfigCmd\n .command('worktree-off')\n .description('Disable worktree mode by default')\n .action(() => {\n const config = loadSMConfig();\n config.defaultWorktree = false;\n saveSMConfig(config);\n console.log(chalk.green('Worktree mode disabled by default'));\n });\n\nconfigCmd\n .command('remote-on')\n .description('Enable remote mode by default (WhatsApp for all questions)')\n .action(() => {\n const config = loadSMConfig();\n config.defaultRemote = true;\n saveSMConfig(config);\n console.log(chalk.green('Remote mode enabled by default'));\n });\n\nconfigCmd\n .command('remote-off')\n .description('Disable remote mode by default')\n .action(() => {\n const config = loadSMConfig();\n config.defaultRemote = false;\n saveSMConfig(config);\n console.log(chalk.green('Remote mode disabled by default'));\n });\n\n// Main command (default action when no subcommand)\nprogram\n .option('-w, --worktree', 'Create isolated worktree for this instance')\n .option('-W, --no-worktree', 'Disable worktree (override default)')\n .option('-r, --remote', 'Enable remote mode (WhatsApp for all questions)')\n .option('--no-remote', 'Disable remote mode (override default)')\n .option('-s, --sandbox', 'Enable sandbox mode (file/network restrictions)')\n .option('-c, --chrome', 'Enable Chrome automation')\n .option('-a, --auto', 'Automatically detect and apply best settings')\n .option('-b, --branch <name>', 'Specify branch name for worktree')\n .option('-t, --task <desc>', 'Task description for context')\n .option('--claude-bin <path>', 'Path to claude CLI (or use CLAUDE_BIN)')\n .option('--no-context', 'Disable StackMemory context integration')\n .option('--no-trace', 'Disable debug tracing (enabled by default)')\n .option('--verbose-trace', 'Enable verbose debug tracing with full details')\n .helpOption('-h, --help', 'Display help')\n .allowUnknownOption(true)\n .action(async (_options) => {\n const claudeSM = new ClaudeSM();\n const args = process.argv.slice(2);\n await claudeSM.run(args);\n });\n\n// Handle direct execution\n// ESM-safe CLI entry\nprogram.parse(process.argv);\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["#!/usr/bin/env node\n\n/**\n * claude-sm: Claude wrapper with StackMemory and worktree integration\n * Automatically manages context persistence and instance isolation\n */\n\nimport { spawn, execSync, execFileSync } from 'child_process';\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport * as os from 'os';\nimport { program } from 'commander';\nimport { v4 as uuidv4 } from 'uuid';\nimport chalk from 'chalk';\nimport { initializeTracing, trace } from '../core/trace/index.js';\nimport {\n generateSessionSummary,\n formatSummaryMessage,\n SessionContext,\n} from '../hooks/session-summary.js';\nimport { sendNotification } from '../hooks/sms-notify.js';\n\n// __filename and __dirname are provided by esbuild banner for ESM compatibility\n\ninterface ClaudeSMConfig {\n defaultWorktree: boolean;\n defaultSandbox: boolean;\n defaultChrome: boolean;\n defaultTracing: boolean;\n defaultRemote: boolean;\n defaultNotifyOnDone: boolean;\n}\n\ninterface ClaudeConfig {\n instanceId: string;\n worktreePath?: string;\n useSandbox: boolean;\n useChrome: boolean;\n useWorktree: boolean;\n useRemote: boolean;\n notifyOnDone: boolean;\n contextEnabled: boolean;\n branch?: string;\n task?: string;\n tracingEnabled: boolean;\n verboseTracing: boolean;\n claudeBin?: string;\n sessionStartTime: number;\n}\n\nconst DEFAULT_SM_CONFIG: ClaudeSMConfig = {\n defaultWorktree: false,\n defaultSandbox: false,\n defaultChrome: false,\n defaultTracing: true,\n defaultRemote: false,\n defaultNotifyOnDone: true,\n};\n\nfunction getConfigPath(): string {\n return path.join(os.homedir(), '.stackmemory', 'claude-sm.json');\n}\n\nfunction loadSMConfig(): ClaudeSMConfig {\n try {\n const configPath = getConfigPath();\n if (fs.existsSync(configPath)) {\n const content = fs.readFileSync(configPath, 'utf8');\n return { ...DEFAULT_SM_CONFIG, ...JSON.parse(content) };\n }\n } catch {\n // Ignore errors, use defaults\n }\n return { ...DEFAULT_SM_CONFIG };\n}\n\nfunction saveSMConfig(config: ClaudeSMConfig): void {\n const configPath = getConfigPath();\n const dir = path.dirname(configPath);\n if (!fs.existsSync(dir)) {\n fs.mkdirSync(dir, { recursive: true });\n }\n fs.writeFileSync(configPath, JSON.stringify(config, null, 2));\n}\n\nclass ClaudeSM {\n private config: ClaudeConfig;\n private stackmemoryPath: string;\n private worktreeScriptPath: string;\n private claudeConfigDir: string;\n private smConfig: ClaudeSMConfig;\n\n constructor() {\n // Load persistent defaults\n this.smConfig = loadSMConfig();\n\n this.config = {\n instanceId: this.generateInstanceId(),\n useSandbox: this.smConfig.defaultSandbox,\n useChrome: this.smConfig.defaultChrome,\n useWorktree: this.smConfig.defaultWorktree,\n useRemote: this.smConfig.defaultRemote,\n notifyOnDone: this.smConfig.defaultNotifyOnDone,\n contextEnabled: true,\n tracingEnabled: this.smConfig.defaultTracing,\n verboseTracing: false,\n sessionStartTime: Date.now(),\n };\n\n this.stackmemoryPath = this.findStackMemory();\n this.worktreeScriptPath = path.join(\n __dirname,\n '../../scripts/claude-worktree-manager.sh'\n );\n this.claudeConfigDir = path.join(os.homedir(), '.claude');\n\n // Ensure config directory exists\n if (!fs.existsSync(this.claudeConfigDir)) {\n fs.mkdirSync(this.claudeConfigDir, { recursive: true });\n }\n }\n\n private generateInstanceId(): string {\n return uuidv4().substring(0, 8);\n }\n\n private findStackMemory(): string {\n // Check multiple possible locations\n const possiblePaths = [\n path.join(os.homedir(), '.stackmemory', 'bin', 'stackmemory'),\n '/usr/local/bin/stackmemory',\n '/opt/homebrew/bin/stackmemory',\n 'stackmemory', // Rely on PATH\n ];\n\n for (const smPath of possiblePaths) {\n try {\n execFileSync('which', [smPath], { stdio: 'ignore' });\n return smPath;\n } catch {\n // Continue searching\n }\n }\n\n return 'stackmemory'; // Fallback to PATH\n }\n\n private isGitRepo(): boolean {\n try {\n execSync('git rev-parse --git-dir', { stdio: 'ignore' });\n return true;\n } catch {\n return false;\n }\n }\n\n private getCurrentBranch(): string {\n try {\n return execSync('git rev-parse --abbrev-ref HEAD', {\n encoding: 'utf8',\n }).trim();\n } catch {\n return 'main';\n }\n }\n\n private hasUncommittedChanges(): boolean {\n try {\n const status = execSync('git status --porcelain', { encoding: 'utf8' });\n return status.length > 0;\n } catch {\n return false;\n }\n }\n\n private resolveClaudeBin(): string | null {\n // 1) CLI-specified\n if (this.config.claudeBin && this.config.claudeBin.trim()) {\n return this.config.claudeBin.trim();\n }\n // 2) Env override\n const envBin = process.env['CLAUDE_BIN'];\n if (envBin && envBin.trim()) return envBin.trim();\n // 3) PATH detection\n try {\n execSync('which claude', { stdio: 'ignore' });\n return 'claude';\n } catch {}\n return null;\n }\n\n private setupWorktree(): string | null {\n if (!this.config.useWorktree || !this.isGitRepo()) {\n return null;\n }\n\n console.log(chalk.blue('\uD83C\uDF33 Setting up isolated worktree...'));\n\n const timestamp = new Date()\n .toISOString()\n .replace(/[:.]/g, '-')\n .substring(0, 19);\n const branch =\n this.config.branch ||\n `claude-${this.config.task || 'work'}-${timestamp}-${this.config.instanceId}`;\n const repoName = path.basename(process.cwd());\n const worktreePath = path.join(\n path.dirname(process.cwd()),\n `${repoName}--${branch}`\n );\n\n try {\n // Create worktree\n const flags = [];\n if (this.config.useSandbox) flags.push('--sandbox');\n if (this.config.useChrome) flags.push('--chrome');\n\n const cmd = `git worktree add -b \"${branch}\" \"${worktreePath}\"`;\n execSync(cmd, { stdio: 'inherit' });\n\n console.log(chalk.green(`\u2705 Worktree created: ${worktreePath}`));\n console.log(chalk.gray(` Branch: ${branch}`));\n\n // Save worktree config\n const configPath = path.join(worktreePath, '.claude-instance.json');\n const configData = {\n instanceId: this.config.instanceId,\n worktreePath,\n branch,\n task: this.config.task,\n sandboxEnabled: this.config.useSandbox,\n chromeEnabled: this.config.useChrome,\n created: new Date().toISOString(),\n parentRepo: process.cwd(),\n };\n fs.writeFileSync(configPath, JSON.stringify(configData, null, 2));\n\n // Copy environment files\n const envFiles = ['.env', '.env.local', '.mise.toml', '.tool-versions'];\n for (const file of envFiles) {\n const srcPath = path.join(process.cwd(), file);\n if (fs.existsSync(srcPath)) {\n fs.copyFileSync(srcPath, path.join(worktreePath, file));\n }\n }\n\n return worktreePath;\n } catch (err: unknown) {\n console.error(chalk.red('\u274C Failed to create worktree:'), err);\n return null;\n }\n }\n\n private saveContext(\n message: string,\n metadata: Record<string, unknown> = {}\n ): void {\n if (!this.config.contextEnabled) return;\n\n try {\n const contextData = {\n message,\n metadata: {\n ...metadata,\n instanceId: this.config.instanceId,\n worktree: this.config.worktreePath,\n timestamp: new Date().toISOString(),\n },\n };\n\n const cmd = `${this.stackmemoryPath} context save --json '${JSON.stringify(contextData)}'`;\n execSync(cmd, { stdio: 'ignore' });\n } catch {\n // Silently fail - don't interrupt Claude\n }\n }\n\n private loadContext(): void {\n if (!this.config.contextEnabled) return;\n\n try {\n console.log(chalk.blue('\uD83D\uDCDA Loading previous context...'));\n\n // Use 'context show' command which outputs the current context stack\n const cmd = `${this.stackmemoryPath} context show`;\n const output = execSync(cmd, {\n encoding: 'utf8',\n stdio: ['pipe', 'pipe', 'pipe'], // Capture stderr to suppress errors\n });\n\n // Check if we got meaningful output (not empty or just headers)\n const lines = output\n .trim()\n .split('\\n')\n .filter((l) => l.trim());\n if (lines.length > 3) {\n // Has content beyond headers\n console.log(chalk.gray('Context stack loaded'));\n }\n } catch {\n // Silently continue - context loading is optional\n }\n }\n\n private detectMultipleInstances(): boolean {\n try {\n const lockDir = path.join(process.cwd(), '.claude-worktree-locks');\n if (!fs.existsSync(lockDir)) return false;\n\n const locks = fs.readdirSync(lockDir).filter((f) => f.endsWith('.lock'));\n const activeLocks = locks.filter((lockFile) => {\n const lockPath = path.join(lockDir, lockFile);\n const lockData = JSON.parse(fs.readFileSync(lockPath, 'utf8'));\n const lockAge = Date.now() - new Date(lockData.created).getTime();\n return lockAge < 24 * 60 * 60 * 1000; // Less than 24 hours old\n });\n\n return activeLocks.length > 0;\n } catch {\n return false;\n }\n }\n\n private suggestWorktreeMode(): void {\n if (this.hasUncommittedChanges()) {\n console.log(chalk.yellow('\u26A0\uFE0F Uncommitted changes detected'));\n console.log(\n chalk.gray(' Consider using --worktree to work in isolation')\n );\n }\n\n if (this.detectMultipleInstances()) {\n console.log(chalk.yellow('\u26A0\uFE0F Other Claude instances detected'));\n console.log(\n chalk.gray(' Using --worktree is recommended to avoid conflicts')\n );\n }\n }\n\n private async sendDoneNotification(exitCode: number | null): Promise<void> {\n try {\n const context: SessionContext = {\n instanceId: this.config.instanceId,\n exitCode,\n sessionStartTime: this.config.sessionStartTime,\n worktreePath: this.config.worktreePath,\n branch: this.config.branch,\n task: this.config.task,\n };\n\n const summary = await generateSessionSummary(context);\n const message = formatSummaryMessage(summary);\n\n console.log(chalk.cyan('\\nSending session summary via WhatsApp...'));\n\n // Build options from suggestions for interactive response\n const options = summary.suggestions.slice(0, 4).map((s) => ({\n key: s.key,\n label: s.label,\n action: s.action,\n }));\n\n const result = await sendNotification({\n type: 'task_complete',\n title: 'Claude Session Complete',\n message,\n prompt:\n options.length > 0\n ? {\n type: 'options',\n options,\n }\n : undefined,\n });\n\n if (result.success) {\n console.log(chalk.green('Notification sent successfully'));\n } else {\n console.log(\n chalk.yellow(`Notification not sent: ${result.error || 'unknown'}`)\n );\n }\n } catch (error) {\n console.log(\n chalk.yellow(\n `Could not send notification: ${error instanceof Error ? error.message : 'unknown'}`\n )\n );\n }\n }\n\n public async run(args: string[]): Promise<void> {\n // Parse arguments\n const claudeArgs: string[] = [];\n let i = 0;\n\n while (i < args.length) {\n const arg = args[i];\n\n switch (arg) {\n case '--worktree':\n case '-w':\n this.config.useWorktree = true;\n break;\n case '--no-worktree':\n case '-W':\n this.config.useWorktree = false;\n break;\n case '--remote':\n case '-r':\n this.config.useRemote = true;\n break;\n case '--no-remote':\n this.config.useRemote = false;\n break;\n case '--notify-done':\n case '-n':\n this.config.notifyOnDone = true;\n break;\n case '--no-notify-done':\n this.config.notifyOnDone = false;\n break;\n case '--sandbox':\n case '-s':\n this.config.useSandbox = true;\n claudeArgs.push('--sandbox');\n break;\n case '--chrome':\n case '-c':\n this.config.useChrome = true;\n claudeArgs.push('--chrome');\n break;\n case '--no-context':\n this.config.contextEnabled = false;\n break;\n case '--no-trace':\n this.config.tracingEnabled = false;\n break;\n case '--verbose-trace':\n this.config.verboseTracing = true;\n break;\n case '--branch':\n case '-b':\n i++;\n this.config.branch = args[i];\n break;\n case '--task':\n case '-t':\n i++;\n this.config.task = args[i];\n break;\n case '--claude-bin':\n i++;\n this.config.claudeBin = args[i];\n process.env['CLAUDE_BIN'] = this.config.claudeBin;\n break;\n case '--auto':\n case '-a':\n // Auto mode: detect and apply best settings\n if (this.isGitRepo()) {\n this.config.useWorktree =\n this.hasUncommittedChanges() || this.detectMultipleInstances();\n }\n break;\n default:\n claudeArgs.push(arg);\n }\n i++;\n }\n\n // Initialize tracing system if enabled\n if (this.config.tracingEnabled) {\n // Set up environment for tracing\n process.env['DEBUG_TRACE'] = 'true';\n process.env['STACKMEMORY_DEBUG'] = 'true';\n process.env['TRACE_OUTPUT'] = 'file'; // Write to file to not clutter Claude output\n process.env['TRACE_MASK_SENSITIVE'] = 'true'; // Always mask sensitive data\n\n if (this.config.verboseTracing) {\n process.env['TRACE_VERBOSITY'] = 'full';\n process.env['TRACE_PARAMS'] = 'true';\n process.env['TRACE_RESULTS'] = 'true';\n process.env['TRACE_MEMORY'] = 'true';\n } else {\n process.env['TRACE_VERBOSITY'] = 'summary';\n process.env['TRACE_PARAMS'] = 'true';\n process.env['TRACE_RESULTS'] = 'false';\n }\n\n // Initialize the tracing system\n initializeTracing();\n\n // Start tracing this Claude session\n trace.command(\n 'claude-sm',\n {\n instanceId: this.config.instanceId,\n worktree: this.config.useWorktree,\n sandbox: this.config.useSandbox,\n task: this.config.task,\n },\n async () => {\n // Session tracing will wrap the entire Claude execution\n }\n );\n }\n\n // Show header\n console.log(chalk.blue('\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557'));\n console.log(chalk.blue('\u2551 Claude + StackMemory + Worktree \u2551'));\n console.log(chalk.blue('\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D'));\n console.log();\n\n // Check Git repo status\n if (this.isGitRepo()) {\n const branch = this.getCurrentBranch();\n console.log(chalk.gray(`\uD83D\uDCCD Current branch: ${branch}`));\n\n if (!this.config.useWorktree) {\n this.suggestWorktreeMode();\n }\n }\n\n // Setup worktree if requested\n if (this.config.useWorktree) {\n const worktreePath = this.setupWorktree();\n if (worktreePath) {\n this.config.worktreePath = worktreePath;\n process.chdir(worktreePath);\n\n // Save context about worktree creation\n this.saveContext('Created worktree for Claude instance', {\n action: 'worktree_created',\n path: worktreePath,\n branch: this.config.branch,\n });\n }\n }\n\n // Load previous context\n this.loadContext();\n\n // Setup environment\n process.env['CLAUDE_INSTANCE_ID'] = this.config.instanceId;\n if (this.config.worktreePath) {\n process.env['CLAUDE_WORKTREE_PATH'] = this.config.worktreePath;\n }\n if (this.config.useRemote) {\n process.env['CLAUDE_REMOTE'] = '1';\n }\n\n console.log(chalk.gray(`\uD83E\uDD16 Instance ID: ${this.config.instanceId}`));\n console.log(chalk.gray(`\uD83D\uDCC1 Working in: ${process.cwd()}`));\n\n if (this.config.useSandbox) {\n console.log(chalk.yellow('\uD83D\uDD12 Sandbox mode enabled'));\n }\n if (this.config.useRemote) {\n console.log(\n chalk.cyan('\uD83D\uDCF1 Remote mode: WhatsApp notifications for all questions')\n );\n }\n if (this.config.useChrome) {\n console.log(chalk.yellow('\uD83C\uDF10 Chrome automation enabled'));\n }\n if (this.config.tracingEnabled) {\n console.log(\n chalk.gray(`\uD83D\uDD0D Debug tracing enabled (logs to ~/.stackmemory/traces/)`)\n );\n if (this.config.verboseTracing) {\n console.log(\n chalk.gray(` Verbose mode: capturing all execution details`)\n );\n }\n }\n\n console.log();\n console.log(chalk.gray('Starting Claude...'));\n console.log(chalk.gray('\u2500'.repeat(42)));\n\n const claudeBin = this.resolveClaudeBin();\n if (!claudeBin) {\n console.error(chalk.red('\u274C Claude CLI not found.'));\n console.log(\n chalk.gray(\n ' Install Claude CLI or set an override:\\n' +\n ' export CLAUDE_BIN=/path/to/claude\\n' +\n ' claude-sm --help\\n\\n' +\n ' Ensure PATH includes npm global bin (npm bin -g).'\n )\n );\n process.exit(1);\n return;\n }\n\n // Launch Claude\n const claude = spawn(claudeBin, claudeArgs, {\n stdio: 'inherit',\n env: process.env,\n });\n\n claude.on('error', (err: NodeJS.ErrnoException) => {\n console.error(chalk.red('\u274C Failed to launch Claude CLI.'));\n if (err.code === 'ENOENT') {\n console.error(\n chalk.gray(' Not found. Set CLAUDE_BIN or install claude on PATH.')\n );\n } else if (err.code === 'EPERM' || err.code === 'EACCES') {\n console.error(\n chalk.gray(\n ' Permission/sandbox issue. Try outside a sandbox or set CLAUDE_BIN.'\n )\n );\n } else {\n console.error(chalk.gray(` ${err.message}`));\n }\n process.exit(1);\n });\n\n // Handle exit\n claude.on('exit', async (code) => {\n // Save final context\n this.saveContext('Claude session ended', {\n action: 'session_end',\n exitCode: code,\n });\n\n // End tracing and show summary if enabled\n if (this.config.tracingEnabled) {\n const summary = trace.getExecutionSummary();\n console.log();\n console.log(chalk.gray('\u2500'.repeat(42)));\n console.log(chalk.blue('Debug Trace Summary:'));\n console.log(chalk.gray(summary));\n }\n\n // Send notification when done (if enabled)\n if (this.config.notifyOnDone || this.config.useRemote) {\n await this.sendDoneNotification(code);\n }\n\n // Offer to clean up worktree\n if (this.config.worktreePath) {\n console.log();\n console.log(chalk.gray('\u2500'.repeat(42)));\n console.log(chalk.blue('Session ended in worktree:'));\n console.log(chalk.gray(` ${this.config.worktreePath}`));\n console.log();\n console.log(chalk.gray('To remove worktree: gd_claude'));\n console.log(chalk.gray('To merge to main: cwm'));\n }\n\n process.exit(code || 0);\n });\n\n // Handle signals\n process.on('SIGINT', () => {\n this.saveContext('Claude session interrupted', {\n action: 'session_interrupt',\n });\n claude.kill('SIGINT');\n });\n\n process.on('SIGTERM', () => {\n this.saveContext('Claude session terminated', {\n action: 'session_terminate',\n });\n claude.kill('SIGTERM');\n });\n }\n}\n\n// CLI interface\nprogram\n .name('claude-sm')\n .description('Claude with StackMemory context and worktree isolation')\n .version('1.0.0');\n\n// Config subcommand\nconst configCmd = program\n .command('config')\n .description('Manage claude-sm defaults');\n\nconfigCmd\n .command('show')\n .description('Show current default settings')\n .action(() => {\n const config = loadSMConfig();\n console.log(chalk.blue('claude-sm defaults:'));\n console.log(\n ` defaultWorktree: ${config.defaultWorktree ? chalk.green('true') : chalk.gray('false')}`\n );\n console.log(\n ` defaultSandbox: ${config.defaultSandbox ? chalk.green('true') : chalk.gray('false')}`\n );\n console.log(\n ` defaultChrome: ${config.defaultChrome ? chalk.green('true') : chalk.gray('false')}`\n );\n console.log(\n ` defaultTracing: ${config.defaultTracing ? chalk.green('true') : chalk.gray('false')}`\n );\n console.log(\n ` defaultRemote: ${config.defaultRemote ? chalk.green('true') : chalk.gray('false')}`\n );\n console.log(\n ` defaultNotifyOnDone: ${config.defaultNotifyOnDone ? chalk.green('true') : chalk.gray('false')}`\n );\n console.log(chalk.gray(`\\nConfig: ${getConfigPath()}`));\n });\n\nconfigCmd\n .command('set <key> <value>')\n .description('Set a default (e.g., set worktree true)')\n .action((key: string, value: string) => {\n const config = loadSMConfig();\n const boolValue = value === 'true' || value === '1' || value === 'on';\n\n const keyMap: Record<string, keyof ClaudeSMConfig> = {\n worktree: 'defaultWorktree',\n sandbox: 'defaultSandbox',\n chrome: 'defaultChrome',\n tracing: 'defaultTracing',\n remote: 'defaultRemote',\n 'notify-done': 'defaultNotifyOnDone',\n notifyondone: 'defaultNotifyOnDone',\n };\n\n const configKey = keyMap[key];\n if (!configKey) {\n console.log(chalk.red(`Unknown key: ${key}`));\n console.log(\n chalk.gray(\n 'Valid keys: worktree, sandbox, chrome, tracing, remote, notify-done'\n )\n );\n process.exit(1);\n }\n\n config[configKey] = boolValue;\n saveSMConfig(config);\n console.log(chalk.green(`Set ${key} = ${boolValue}`));\n });\n\nconfigCmd\n .command('worktree-on')\n .description('Enable worktree mode by default')\n .action(() => {\n const config = loadSMConfig();\n config.defaultWorktree = true;\n saveSMConfig(config);\n console.log(chalk.green('Worktree mode enabled by default'));\n });\n\nconfigCmd\n .command('worktree-off')\n .description('Disable worktree mode by default')\n .action(() => {\n const config = loadSMConfig();\n config.defaultWorktree = false;\n saveSMConfig(config);\n console.log(chalk.green('Worktree mode disabled by default'));\n });\n\nconfigCmd\n .command('remote-on')\n .description('Enable remote mode by default (WhatsApp for all questions)')\n .action(() => {\n const config = loadSMConfig();\n config.defaultRemote = true;\n saveSMConfig(config);\n console.log(chalk.green('Remote mode enabled by default'));\n });\n\nconfigCmd\n .command('remote-off')\n .description('Disable remote mode by default')\n .action(() => {\n const config = loadSMConfig();\n config.defaultRemote = false;\n saveSMConfig(config);\n console.log(chalk.green('Remote mode disabled by default'));\n });\n\nconfigCmd\n .command('notify-done-on')\n .description('Enable WhatsApp notification when session ends (default)')\n .action(() => {\n const config = loadSMConfig();\n config.defaultNotifyOnDone = true;\n saveSMConfig(config);\n console.log(chalk.green('Notify-on-done enabled by default'));\n });\n\nconfigCmd\n .command('notify-done-off')\n .description('Disable notification when session ends')\n .action(() => {\n const config = loadSMConfig();\n config.defaultNotifyOnDone = false;\n saveSMConfig(config);\n console.log(chalk.green('Notify-on-done disabled by default'));\n });\n\n// Main command (default action when no subcommand)\nprogram\n .option('-w, --worktree', 'Create isolated worktree for this instance')\n .option('-W, --no-worktree', 'Disable worktree (override default)')\n .option('-r, --remote', 'Enable remote mode (WhatsApp for all questions)')\n .option('--no-remote', 'Disable remote mode (override default)')\n .option('-n, --notify-done', 'Send WhatsApp notification when session ends')\n .option('--no-notify-done', 'Disable notification when session ends')\n .option('-s, --sandbox', 'Enable sandbox mode (file/network restrictions)')\n .option('-c, --chrome', 'Enable Chrome automation')\n .option('-a, --auto', 'Automatically detect and apply best settings')\n .option('-b, --branch <name>', 'Specify branch name for worktree')\n .option('-t, --task <desc>', 'Task description for context')\n .option('--claude-bin <path>', 'Path to claude CLI (or use CLAUDE_BIN)')\n .option('--no-context', 'Disable StackMemory context integration')\n .option('--no-trace', 'Disable debug tracing (enabled by default)')\n .option('--verbose-trace', 'Enable verbose debug tracing with full details')\n .helpOption('-h, --help', 'Display help')\n .allowUnknownOption(true)\n .action(async (_options) => {\n const claudeSM = new ClaudeSM();\n const args = process.argv.slice(2);\n await claudeSM.run(args);\n });\n\n// Handle direct execution\n// ESM-safe CLI entry\nprogram.parse(process.argv);\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -0,0 +1,248 @@
1
+ import { fileURLToPath as __fileURLToPath } from 'url';
2
+ import { dirname as __pathDirname } from 'path';
3
+ const __filename = __fileURLToPath(import.meta.url);
4
+ const __dirname = __pathDirname(__filename);
5
+ import { Command } from "commander";
6
+ import Database from "better-sqlite3";
7
+ import { join } from "path";
8
+ import { existsSync } from "fs";
9
+ import chalk from "chalk";
10
+ import { RetrievalAuditStore } from "../../core/retrieval/retrieval-audit.js";
11
+ function createRetrievalCommands() {
12
+ const retrieval = new Command("retrieval").alias("ret").description("Manage LLM-driven context retrieval");
13
+ retrieval.command("audit").description("View retrieval audit log").option("-l, --limit <n>", "Number of entries to show", "10").option("-q, --query <text>", "Filter by query text").option("-v, --verbose", "Show full details").action(async (options) => {
14
+ const projectRoot = process.cwd();
15
+ const dbPath = join(projectRoot, ".stackmemory", "context.db");
16
+ if (!existsSync(dbPath)) {
17
+ console.log(
18
+ chalk.red("StackMemory not initialized in this directory.")
19
+ );
20
+ console.log(chalk.gray('Run "stackmemory init" first.'));
21
+ return;
22
+ }
23
+ const db = new Database(dbPath);
24
+ try {
25
+ let projectId = "default";
26
+ try {
27
+ const row = db.prepare(`SELECT value FROM metadata WHERE key = 'project_id'`).get();
28
+ if (row?.value) projectId = row.value;
29
+ } catch {
30
+ }
31
+ const auditStore = new RetrievalAuditStore(db, projectId);
32
+ let entries;
33
+ if (options.query) {
34
+ entries = auditStore.searchByQuery(
35
+ options.query,
36
+ parseInt(options.limit)
37
+ );
38
+ console.log(
39
+ chalk.blue(
40
+ `
41
+ Retrieval audit entries matching "${options.query}":
42
+ `
43
+ )
44
+ );
45
+ } else {
46
+ entries = auditStore.getRecent(parseInt(options.limit));
47
+ console.log(chalk.blue("\nRecent retrieval audit entries:\n"));
48
+ }
49
+ if (entries.length === 0) {
50
+ console.log(chalk.gray("No audit entries found."));
51
+ console.log(
52
+ chalk.gray(
53
+ "\nRetrieval audit records decisions made by the LLM-driven"
54
+ )
55
+ );
56
+ console.log(
57
+ chalk.gray(
58
+ "context retrieval system. Run some queries to generate entries."
59
+ )
60
+ );
61
+ return;
62
+ }
63
+ for (const entry of entries) {
64
+ const date = new Date(entry.timestamp).toLocaleString();
65
+ const providerIcon = entry.provider === "anthropic" ? chalk.green("LLM") : entry.provider === "cached" ? chalk.yellow("CACHE") : chalk.gray("HEUR");
66
+ console.log(
67
+ `${chalk.cyan(entry.id.slice(0, 8))} ${chalk.gray(date)} [${providerIcon}]`
68
+ );
69
+ console.log(
70
+ ` Query: ${chalk.white(entry.query.slice(0, 60))}${entry.query.length > 60 ? "..." : ""}`
71
+ );
72
+ console.log(
73
+ ` Confidence: ${formatConfidence(entry.confidenceScore)} | Tokens: ${entry.tokensUsed}/${entry.tokenBudget} | Time: ${entry.analysisTimeMs}ms | Complexity: ${entry.queryComplexity}`
74
+ );
75
+ if (options.verbose) {
76
+ console.log(
77
+ ` Frames: ${entry.framesRetrieved.join(", ") || "none"}`
78
+ );
79
+ console.log(
80
+ ` Reasoning: ${chalk.gray(entry.reasoning.slice(0, 200))}${entry.reasoning.length > 200 ? "..." : ""}`
81
+ );
82
+ }
83
+ console.log("");
84
+ }
85
+ } finally {
86
+ db.close();
87
+ }
88
+ });
89
+ retrieval.command("stats").description("Show retrieval statistics").action(async () => {
90
+ const projectRoot = process.cwd();
91
+ const dbPath = join(projectRoot, ".stackmemory", "context.db");
92
+ if (!existsSync(dbPath)) {
93
+ console.log(
94
+ chalk.red("StackMemory not initialized in this directory.")
95
+ );
96
+ return;
97
+ }
98
+ const db = new Database(dbPath);
99
+ try {
100
+ let projectId = "default";
101
+ try {
102
+ const row = db.prepare(`SELECT value FROM metadata WHERE key = 'project_id'`).get();
103
+ if (row?.value) projectId = row.value;
104
+ } catch {
105
+ }
106
+ const auditStore = new RetrievalAuditStore(db, projectId);
107
+ const stats = auditStore.getStats();
108
+ console.log(chalk.blue("\nRetrieval Statistics\n"));
109
+ console.log(`Total retrievals: ${chalk.white(stats.totalRetrievals)}`);
110
+ console.log(
111
+ `Average confidence: ${formatConfidence(stats.avgConfidence)}`
112
+ );
113
+ console.log(
114
+ `Average tokens used: ${chalk.white(Math.round(stats.avgTokensUsed))}`
115
+ );
116
+ console.log(
117
+ `Average analysis time: ${chalk.white(Math.round(stats.avgAnalysisTime))}ms`
118
+ );
119
+ console.log("\nProvider breakdown:");
120
+ for (const [provider, count] of Object.entries(
121
+ stats.providerBreakdown
122
+ )) {
123
+ const pct = stats.totalRetrievals > 0 ? (count / stats.totalRetrievals * 100).toFixed(1) : "0";
124
+ const icon = provider === "anthropic" ? chalk.green("LLM") : provider === "cached" ? chalk.yellow("CACHE") : chalk.gray("HEUR");
125
+ console.log(` ${icon}: ${count} (${pct}%)`);
126
+ }
127
+ console.log("");
128
+ } finally {
129
+ db.close();
130
+ }
131
+ });
132
+ retrieval.command("reasoning <id>").description("Show detailed reasoning for a retrieval decision").action(async (id) => {
133
+ const projectRoot = process.cwd();
134
+ const dbPath = join(projectRoot, ".stackmemory", "context.db");
135
+ if (!existsSync(dbPath)) {
136
+ console.log(
137
+ chalk.red("StackMemory not initialized in this directory.")
138
+ );
139
+ return;
140
+ }
141
+ const db = new Database(dbPath);
142
+ try {
143
+ let projectId = "default";
144
+ try {
145
+ const row = db.prepare(`SELECT value FROM metadata WHERE key = 'project_id'`).get();
146
+ if (row?.value) projectId = row.value;
147
+ } catch {
148
+ }
149
+ const auditStore = new RetrievalAuditStore(db, projectId);
150
+ const entries = auditStore.getRecent(100);
151
+ const entry = entries.find((e) => e.id.startsWith(id));
152
+ if (!entry) {
153
+ console.log(
154
+ chalk.red(`No audit entry found with ID starting with "${id}"`)
155
+ );
156
+ return;
157
+ }
158
+ console.log(chalk.blue("\nRetrieval Decision Details\n"));
159
+ console.log(`ID: ${chalk.white(entry.id)}`);
160
+ console.log(
161
+ `Time: ${chalk.white(new Date(entry.timestamp).toLocaleString())}`
162
+ );
163
+ console.log(`Provider: ${chalk.white(entry.provider)}`);
164
+ console.log(`Query: ${chalk.white(entry.query)}`);
165
+ console.log(`Complexity: ${chalk.white(entry.queryComplexity)}`);
166
+ console.log(`Confidence: ${formatConfidence(entry.confidenceScore)}`);
167
+ console.log(
168
+ `Tokens: ${chalk.white(`${entry.tokensUsed}/${entry.tokenBudget}`)}`
169
+ );
170
+ console.log(
171
+ `Analysis Time: ${chalk.white(`${entry.analysisTimeMs}ms`)}`
172
+ );
173
+ console.log(chalk.blue("\nReasoning:"));
174
+ console.log(entry.reasoning);
175
+ console.log(chalk.blue("\nFrames Retrieved:"));
176
+ if (entry.framesRetrieved.length === 0) {
177
+ console.log(chalk.gray(" (none)"));
178
+ } else {
179
+ for (const frameId of entry.framesRetrieved) {
180
+ console.log(` - ${frameId}`);
181
+ }
182
+ }
183
+ console.log("");
184
+ } finally {
185
+ db.close();
186
+ }
187
+ });
188
+ retrieval.command("cleanup").description("Remove old audit entries").option("-d, --days <n>", "Keep entries from last N days", "7").action(async (options) => {
189
+ const projectRoot = process.cwd();
190
+ const dbPath = join(projectRoot, ".stackmemory", "context.db");
191
+ if (!existsSync(dbPath)) {
192
+ console.log(
193
+ chalk.red("StackMemory not initialized in this directory.")
194
+ );
195
+ return;
196
+ }
197
+ const db = new Database(dbPath);
198
+ try {
199
+ let projectId = "default";
200
+ try {
201
+ const row = db.prepare(`SELECT value FROM metadata WHERE key = 'project_id'`).get();
202
+ if (row?.value) projectId = row.value;
203
+ } catch {
204
+ }
205
+ const auditStore = new RetrievalAuditStore(db, projectId);
206
+ const days = parseInt(options.days);
207
+ const maxAgeMs = days * 24 * 60 * 60 * 1e3;
208
+ const deleted = auditStore.cleanup(maxAgeMs);
209
+ console.log(
210
+ chalk.green(
211
+ `Cleaned up ${deleted} old audit entries (older than ${days} days)`
212
+ )
213
+ );
214
+ } finally {
215
+ db.close();
216
+ }
217
+ });
218
+ retrieval.command("status").description("Show current retrieval system status").action(async () => {
219
+ const hasApiKey = !!process.env["ANTHROPIC_API_KEY"];
220
+ const model = process.env["ANTHROPIC_MODEL"] || "claude-3-haiku-20240307";
221
+ console.log(chalk.blue("\nRetrieval System Status\n"));
222
+ if (hasApiKey) {
223
+ console.log(`LLM Provider: ${chalk.green("Anthropic (active)")}`);
224
+ console.log(`Model: ${chalk.white(model)}`);
225
+ } else {
226
+ console.log(
227
+ `LLM Provider: ${chalk.yellow("Heuristic fallback (no API key)")}`
228
+ );
229
+ console.log(
230
+ chalk.gray("Set ANTHROPIC_API_KEY to enable LLM-driven retrieval")
231
+ );
232
+ }
233
+ console.log(`Default Token Budget: ${chalk.white("8000")}`);
234
+ console.log(`Confidence Threshold: ${chalk.white("0.6")}`);
235
+ console.log(`Cache TTL: ${chalk.white("5 minutes")}`);
236
+ console.log("");
237
+ });
238
+ return retrieval;
239
+ }
240
+ function formatConfidence(score) {
241
+ if (score >= 0.8) return chalk.green(`${(score * 100).toFixed(0)}%`);
242
+ if (score >= 0.6) return chalk.yellow(`${(score * 100).toFixed(0)}%`);
243
+ return chalk.red(`${(score * 100).toFixed(0)}%`);
244
+ }
245
+ export {
246
+ createRetrievalCommands
247
+ };
248
+ //# sourceMappingURL=retrieval.js.map