helixmind 0.2.10 → 0.2.12

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.
@@ -1 +1 @@
1
- {"version":3,"file":"chat.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/chat.ts"],"names":[],"mappings":"AAwDA,UAAU,WAAW;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAkLD,wBAAsB,WAAW,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAyzDrE"}
1
+ {"version":3,"file":"chat.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/chat.ts"],"names":[],"mappings":"AAwDA,UAAU,WAAW;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAkLD,wBAAsB,WAAW,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAi3DrE"}
@@ -323,16 +323,55 @@ export async function chatCommand(options) {
323
323
  let sessionToolCalls = 0;
324
324
  let roundToolCalls = 0;
325
325
  // Brain scope: project-local if .helixmind/ exists, else global
326
- // Auto-create .helixmind/ for new projects (opt-in for local brain)
326
+ // Requires directory trust before creating .helixmind/
327
327
  const { detectBrainScope, resolveDataDir: resolveSpiralDir, loadConfig: loadSpiralConfig } = await import('../../utils/config.js');
328
328
  const { mkdirSync, existsSync } = await import('node:fs');
329
+ const { isSystemDirectory, isDirectoryTrusted, trustDirectory } = await import('../config/trust.js');
329
330
  let brainScope = detectBrainScope(process.cwd());
330
- // Auto-create .helixmind/ if it doesn't exist (local brain by default for projects)
331
- const helixDir = join(process.cwd(), '.helixmind');
331
+ // Determine if we can create .helixmind/ in this directory
332
+ const cwd = process.cwd();
333
+ const helixDir = join(cwd, '.helixmind');
332
334
  if (!existsSync(helixDir)) {
333
- mkdirSync(helixDir, { recursive: true });
334
- renderInfo(chalk.dim(' Created .helixmind/ directory for local brain'));
335
- brainScope = 'project';
335
+ if (isSystemDirectory(cwd)) {
336
+ // System directory — never create .helixmind/, use global brain silently
337
+ brainScope = 'global';
338
+ }
339
+ else if (isDirectoryTrusted(cwd)) {
340
+ // Already trusted — create .helixmind/
341
+ try {
342
+ mkdirSync(helixDir, { recursive: true });
343
+ renderInfo(chalk.dim(' Created .helixmind/ directory for local brain'));
344
+ brainScope = 'project';
345
+ }
346
+ catch {
347
+ // Permission error — fall back to global brain
348
+ brainScope = 'global';
349
+ }
350
+ }
351
+ else {
352
+ // New directory — ask for trust
353
+ const { confirmMenu } = await import('../ui/select-menu.js');
354
+ process.stdout.write('\n');
355
+ renderInfo(chalk.hex('#ff6600').bold(' New directory detected'));
356
+ renderInfo(chalk.dim(` ${cwd}`));
357
+ const trusted = await confirmMenu(`Do you trust this directory? ${chalk.dim('(HelixMind will create .helixmind/ for local brain data)')}`, false);
358
+ if (trusted) {
359
+ trustDirectory(cwd);
360
+ try {
361
+ mkdirSync(helixDir, { recursive: true });
362
+ renderInfo(chalk.dim(' Created .helixmind/ directory for local brain'));
363
+ brainScope = 'project';
364
+ }
365
+ catch {
366
+ renderInfo(chalk.yellow(' Could not create .helixmind/ — using global brain'));
367
+ brainScope = 'global';
368
+ }
369
+ }
370
+ else {
371
+ renderInfo(chalk.dim(' Using global brain (no local data)'));
372
+ brainScope = 'global';
373
+ }
374
+ }
336
375
  }
337
376
  let spiralEngine = null;
338
377
  async function initSpiralEngine(scope) {
@@ -1010,9 +1049,19 @@ export async function chatCommand(options) {
1010
1049
  if (newScope === 'project') {
1011
1050
  const { mkdirSync, existsSync } = await import('node:fs');
1012
1051
  const { join } = await import('node:path');
1013
- const helixDir = join(process.cwd(), '.helixmind');
1014
- if (!existsSync(helixDir))
1015
- mkdirSync(helixDir, { recursive: true });
1052
+ const { isSystemDirectory: isSysDir } = await import('../config/trust.js');
1053
+ const hlxDir = join(process.cwd(), '.helixmind');
1054
+ if (!existsSync(hlxDir)) {
1055
+ if (isSysDir(process.cwd())) {
1056
+ throw new Error('Cannot create .helixmind/ in system directory');
1057
+ }
1058
+ try {
1059
+ mkdirSync(hlxDir, { recursive: true });
1060
+ }
1061
+ catch {
1062
+ throw new Error('Cannot create .helixmind/ — permission denied');
1063
+ }
1064
+ }
1016
1065
  }
1017
1066
  spiralEngine = await initSpiralEngine(newScope);
1018
1067
  const { exportBrainData } = await import('../brain/exporter.js');
@@ -1307,10 +1356,23 @@ export async function chatCommand(options) {
1307
1356
  // Create .helixmind/ dir if switching to project and it doesn't exist
1308
1357
  if (newScope === 'project') {
1309
1358
  const { mkdirSync, existsSync } = await import('node:fs');
1359
+ const { isSystemDirectory: isSysDir2 } = await import('../config/trust.js');
1310
1360
  const projDir = join(process.cwd(), '.helixmind');
1311
1361
  if (!existsSync(projDir)) {
1312
- mkdirSync(projDir, { recursive: true });
1313
- renderInfo(chalk.dim(' Created .helixmind/ directory'));
1362
+ if (isSysDir2(process.cwd())) {
1363
+ renderInfo(chalk.yellow(' Cannot create .helixmind/ in system directory'));
1364
+ brainScope = 'global';
1365
+ }
1366
+ else {
1367
+ try {
1368
+ mkdirSync(projDir, { recursive: true });
1369
+ renderInfo(chalk.dim(' Created .helixmind/ directory'));
1370
+ }
1371
+ catch {
1372
+ renderInfo(chalk.yellow(' Could not create .helixmind/ — using global brain'));
1373
+ brainScope = 'global';
1374
+ }
1375
+ }
1314
1376
  }
1315
1377
  }
1316
1378
  spiralEngine = await initSpiralEngine(newScope);
@@ -2021,6 +2083,7 @@ async function sendAgentMessage(input, agentHistory, provider, project, spiralEn
2021
2083
  // Track assistant response in session buffer
2022
2084
  if (result.text) {
2023
2085
  sessionBuffer.addAssistantSummary(result.text);
2086
+ sessionBuffer.addTopicFromResponse(result.text);
2024
2087
  }
2025
2088
  // Create checkpoint for agent response
2026
2089
  if (result.text) {
@@ -2242,14 +2305,19 @@ async function handleSlashCommand(input, messages, agentHistory, config, spiralE
2242
2305
  case '/helixlocal':
2243
2306
  // Always use local brain for /helix and /helixlocal
2244
2307
  if (onBrainSwitch && currentBrainScope !== 'project') {
2245
- await onBrainSwitch('project');
2246
- renderInfo(chalk.cyan('\u{1F4C1} Switched to project-local brain (.helixmind/)'));
2247
2308
  try {
2248
- const { pushScopeChange, isBrainServerRunning } = await import('../brain/generator.js');
2249
- if (isBrainServerRunning())
2250
- pushScopeChange('project');
2309
+ await onBrainSwitch('project');
2310
+ renderInfo(chalk.cyan('\u{1F4C1} Switched to project-local brain (.helixmind/)'));
2311
+ try {
2312
+ const { pushScopeChange, isBrainServerRunning } = await import('../brain/generator.js');
2313
+ if (isBrainServerRunning())
2314
+ pushScopeChange('project');
2315
+ }
2316
+ catch { /* optional */ }
2317
+ }
2318
+ catch {
2319
+ renderInfo(chalk.yellow(' Cannot use local brain here — using global'));
2251
2320
  }
2252
- catch { /* optional */ }
2253
2321
  }
2254
2322
  // Auto-start brain visualization
2255
2323
  if (spiralEngine) {
@@ -2323,15 +2391,20 @@ async function handleSlashCommand(input, messages, agentHistory, config, spiralE
2323
2391
  renderInfo('Already using project-local brain.');
2324
2392
  }
2325
2393
  else if (onBrainSwitch) {
2326
- await onBrainSwitch('project');
2327
- renderInfo(chalk.cyan('\u{1F4C1} Switched to project-local brain (.helixmind/)'));
2328
- // Update browser if open
2329
2394
  try {
2330
- const { pushScopeChange, isBrainServerRunning } = await import('../brain/generator.js');
2331
- if (isBrainServerRunning())
2332
- pushScopeChange('project');
2395
+ await onBrainSwitch('project');
2396
+ renderInfo(chalk.cyan('\u{1F4C1} Switched to project-local brain (.helixmind/)'));
2397
+ // Update browser if open
2398
+ try {
2399
+ const { pushScopeChange, isBrainServerRunning } = await import('../brain/generator.js');
2400
+ if (isBrainServerRunning())
2401
+ pushScopeChange('project');
2402
+ }
2403
+ catch { /* optional */ }
2404
+ }
2405
+ catch {
2406
+ renderInfo(chalk.yellow(' Cannot use local brain here — using global'));
2333
2407
  }
2334
- catch { /* optional */ }
2335
2408
  }
2336
2409
  break;
2337
2410
  }