@bike4mind/cli 0.2.34 → 0.2.35-feat-6781-headless-mode.20009

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.
@@ -19,7 +19,7 @@ process.on('warning', (warning) => {
19
19
 
20
20
  import { createRequire } from 'module';
21
21
  import { fileURLToPath } from 'url';
22
- import { dirname, join } from 'path';
22
+ import { dirname, join, resolve } from 'path';
23
23
  import { existsSync } from 'fs';
24
24
  import yargs from 'yargs';
25
25
  import { hideBin } from 'yargs/helpers';
@@ -46,6 +46,27 @@ const argv = await yargs(hideBin(process.argv))
46
46
  description: 'Disable loading project-specific configuration (.bike4mind/)',
47
47
  default: false,
48
48
  })
49
+ .option('add-dir', {
50
+ type: 'array',
51
+ description: 'Add additional directories for file access (can be used multiple times)',
52
+ string: true,
53
+ })
54
+ .option('prompt', {
55
+ alias: 'p',
56
+ type: 'string',
57
+ description: 'Run a single query in headless/non-interactive mode and exit',
58
+ })
59
+ .option('output-format', {
60
+ type: 'string',
61
+ description: 'Output format when using -p: text (default), json, stream-json (NDJSON)',
62
+ choices: ['text', 'json', 'stream-json'],
63
+ default: 'text',
64
+ })
65
+ .option('dangerously-skip-permissions', {
66
+ type: 'boolean',
67
+ description: 'When using -p, auto-allow all tool permission prompts (use with caution in CI/CD)',
68
+ default: false,
69
+ })
49
70
  .command('mcp', 'Manage MCP (Model Context Protocol) servers', (yargs) => {
50
71
  return yargs
51
72
  .command('list', 'List configured MCP servers', {}, async () => {
@@ -109,6 +130,11 @@ if (argv['debug-stream']) {
109
130
  if (argv['no-project-config']) {
110
131
  process.env.B4M_NO_PROJECT_CONFIG = '1';
111
132
  }
133
+ if (argv['add-dir'] && argv['add-dir'].length > 0) {
134
+ // Resolve paths to absolute and pass via environment variable
135
+ const resolvedDirs = argv['add-dir'].map(d => resolve(d));
136
+ process.env.B4M_ADDITIONAL_DIRS = JSON.stringify(resolvedDirs);
137
+ }
112
138
 
113
139
  // Auto-detect environment: prefer production mode when dist exists
114
140
  const distPath = join(__dirname, '../dist/index.js');
@@ -123,6 +149,40 @@ const hasDist = existsSync(distPath);
123
149
  const isDev = process.env.NODE_ENV === 'development' ||
124
150
  (!hasDist && hasSource);
125
151
 
152
+ // Handle headless mode (-p / --prompt flag)
153
+ // Must be done after isDev detection to use correct import path
154
+ if (argv.prompt !== undefined) {
155
+ const outputFormat = argv['output-format'] || 'text';
156
+ const rawAddDirs = argv['add-dir'] || [];
157
+
158
+ try {
159
+ let handleHeadlessCommand;
160
+
161
+ if (isDev) {
162
+ const { register } = require('tsx/esm/api');
163
+ register();
164
+ const module = await import('../src/commands/headlessCommand.ts');
165
+ handleHeadlessCommand = module.handleHeadlessCommand;
166
+ } else {
167
+ const module = await import('../dist/commands/headlessCommand.js');
168
+ handleHeadlessCommand = module.handleHeadlessCommand;
169
+ }
170
+
171
+ await handleHeadlessCommand({
172
+ prompt: argv.prompt,
173
+ outputFormat,
174
+ dangerouslySkipPermissions: argv['dangerously-skip-permissions'] || false,
175
+ verbose: argv.verbose || false,
176
+ addDirs: rawAddDirs.map(d => resolve(d)),
177
+ });
178
+ // handleHeadlessCommand calls process.exit internally, but handle the case it doesn't
179
+ process.exit(0);
180
+ } catch (error) {
181
+ console.error('Error:', error.message);
182
+ process.exit(1);
183
+ }
184
+ }
185
+
126
186
  // Handle MCP subcommands (external commands)
127
187
  // Must be done after mode detection to use correct import path
128
188
  if (argv._[0] === 'mcp') {
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ ProxyManager
4
+ } from "./chunk-G4ZGEQFT.js";
5
+ export {
6
+ ProxyManager
7
+ };
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ SandboxOrchestrator
4
+ } from "./chunk-KQAMBXAW.js";
5
+ import "./chunk-4BIBE3J7.js";
6
+ export {
7
+ SandboxOrchestrator
8
+ };
@@ -6,7 +6,7 @@ import {
6
6
  getSettingsByNames,
7
7
  obfuscateApiKey,
8
8
  secureParameters
9
- } from "./chunk-USW6NZC2.js";
9
+ } from "./chunk-LMGKNYB3.js";
10
10
  import {
11
11
  ApiKeyType,
12
12
  MementoTier,
@@ -3,7 +3,7 @@
3
3
  // package.json
4
4
  var package_default = {
5
5
  name: "@bike4mind/cli",
6
- version: "0.2.34",
6
+ version: "0.2.35-feat-6781-headless-mode.20009+62963ec5e",
7
7
  type: "module",
8
8
  description: "Interactive CLI tool for Bike4Mind with ReAct agents",
9
9
  license: "UNLICENSED",
@@ -114,10 +114,10 @@ var package_default = {
114
114
  },
115
115
  devDependencies: {
116
116
  "@bike4mind/agents": "0.1.0",
117
- "@bike4mind/common": "2.56.0",
118
- "@bike4mind/mcp": "1.32.3",
119
- "@bike4mind/services": "2.53.0",
120
- "@bike4mind/utils": "2.9.1",
117
+ "@bike4mind/common": "2.56.1-feat-6781-headless-mode.20009+62963ec5e",
118
+ "@bike4mind/mcp": "1.32.4-feat-6781-headless-mode.20009+62963ec5e",
119
+ "@bike4mind/services": "2.53.1-feat-6781-headless-mode.20009+62963ec5e",
120
+ "@bike4mind/utils": "2.9.2-feat-6781-headless-mode.20009+62963ec5e",
121
121
  "@types/better-sqlite3": "^7.6.13",
122
122
  "@types/diff": "^5.0.9",
123
123
  "@types/jsonwebtoken": "^9.0.4",
@@ -138,7 +138,7 @@ var package_default = {
138
138
  optionalDependencies: {
139
139
  "@vscode/ripgrep": "^1.17.0"
140
140
  },
141
- gitHead: "541fa130ab03ae992ac54caef18c0aa5858ccc16"
141
+ gitHead: "62963ec5e23803e9536066c9bc1478b97ea2b1fd"
142
142
  };
143
143
 
144
144
  // src/utils/updateChecker.ts
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  BadRequestError,
4
4
  secureParameters
5
- } from "./chunk-USW6NZC2.js";
5
+ } from "./chunk-LMGKNYB3.js";
6
6
  import {
7
7
  CompletionApiUsageTransaction,
8
8
  GenericCreditDeductTransaction,
@@ -244,6 +244,7 @@ var ProxyManager = class {
244
244
  return () => this.eventHandlers.delete(handler);
245
245
  }
246
246
  };
247
+
247
248
  export {
248
249
  ProxyManager
249
250
  };
@@ -157,6 +157,7 @@ var SandboxOrchestrator = class {
157
157
  return this.config.excludedCommands.some((excluded) => baseCommand === excluded);
158
158
  }
159
159
  };
160
+
160
161
  export {
161
162
  SandboxOrchestrator
162
163
  };
@@ -7,7 +7,7 @@ import {
7
7
  getSettingsMap,
8
8
  getSettingsValue,
9
9
  secureParameters
10
- } from "./chunk-USW6NZC2.js";
10
+ } from "./chunk-LMGKNYB3.js";
11
11
  import {
12
12
  KnowledgeType,
13
13
  SupportedFabFileMimeTypes
@@ -398,7 +398,8 @@ var CliConfigSchema = z.object({
398
398
  config: z.record(z.string(), z.any())
399
399
  }),
400
400
  trustedTools: z.array(z.string()).optional().prefault([]),
401
- sandbox: SandboxConfigSchema.optional()
401
+ sandbox: SandboxConfigSchema.optional(),
402
+ additionalDirectories: z.array(z.string()).optional().prefault([])
402
403
  });
403
404
  var ProjectConfigSchema = z.object({
404
405
  tools: z.object({
@@ -418,7 +419,8 @@ var ProjectConfigSchema = z.object({
418
419
  enableSkillTool: z.boolean().optional(),
419
420
  enableDynamicAgentCreation: z.boolean().optional()
420
421
  }).optional(),
421
- sandbox: PartialSandboxConfigSchema
422
+ sandbox: PartialSandboxConfigSchema,
423
+ additionalDirectories: z.array(z.string()).optional()
422
424
  });
423
425
  var ProjectLocalConfigSchema = z.object({
424
426
  trustedTools: z.array(z.string()).optional(),
@@ -465,8 +467,10 @@ var DEFAULT_CONFIG = {
465
467
  // Web-only tools
466
468
  config: {}
467
469
  },
468
- trustedTools: []
470
+ trustedTools: [],
469
471
  // No tools trusted by default
472
+ additionalDirectories: []
473
+ // No additional directories by default
470
474
  };
471
475
  function findProjectConfigDir(startDir = process.cwd()) {
472
476
  let currentDir = startDir;
@@ -1017,6 +1021,53 @@ ${entryToAdd}
1017
1021
  }
1018
1022
  return loadProjectLocalConfig(this.projectConfigDir);
1019
1023
  }
1024
+ /**
1025
+ * Add a directory to the allowed directories list
1026
+ * Persists to global config
1027
+ */
1028
+ async addDirectory(dirPath) {
1029
+ const config = await this.load();
1030
+ if (!config.additionalDirectories) {
1031
+ config.additionalDirectories = [];
1032
+ }
1033
+ const resolvedPath = path2.resolve(dirPath);
1034
+ if (!config.additionalDirectories.includes(resolvedPath)) {
1035
+ config.additionalDirectories.push(resolvedPath);
1036
+ await this.save(config);
1037
+ }
1038
+ }
1039
+ /**
1040
+ * Remove a directory from the allowed directories list
1041
+ */
1042
+ async removeDirectory(dirPath) {
1043
+ const config = await this.load();
1044
+ if (config.additionalDirectories) {
1045
+ const resolvedPath = path2.resolve(dirPath);
1046
+ config.additionalDirectories = config.additionalDirectories.filter((d) => path2.resolve(d) !== resolvedPath);
1047
+ await this.save(config);
1048
+ }
1049
+ }
1050
+ /**
1051
+ * Get all additional directories (merged from global + project configs)
1052
+ * Returns resolved absolute paths
1053
+ */
1054
+ async getAdditionalDirectories() {
1055
+ const config = await this.load();
1056
+ const dirs = /* @__PURE__ */ new Set();
1057
+ if (config.additionalDirectories) {
1058
+ for (const dir of config.additionalDirectories) {
1059
+ dirs.add(path2.resolve(dir));
1060
+ }
1061
+ }
1062
+ const projectConfig = await this.loadRawProjectConfig();
1063
+ if (projectConfig?.additionalDirectories) {
1064
+ const projectRoot = this.projectConfigDir || process.cwd();
1065
+ for (const dir of projectConfig.additionalDirectories) {
1066
+ dirs.add(path2.resolve(projectRoot, dir));
1067
+ }
1068
+ }
1069
+ return Array.from(dirs);
1070
+ }
1020
1071
  };
1021
1072
 
1022
1073
  export {