@reconcrap/boss-recommend-mcp 1.3.35 → 1.3.36

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.
package/README.md CHANGED
@@ -239,7 +239,9 @@ node src/cli.js chat run --job "算法工程师" --start-from unread --criteria
239
239
  - `pause_boss_chat_run`
240
240
  - `resume_boss_chat_run`
241
241
  - `cancel_boss_chat_run`
242
- - vendored `boss-chat` CLI 还支持 `--data-dir <path>` 与 `BOSS_CHAT_HOME`,优先级高于兼容旧行为的 `<cwd>/.boss-chat`
242
+ - vendored `boss-chat` CLI 还支持 `--data-dir <path>` 与 `BOSS_CHAT_HOME`,默认目录为 `~/.boss-recommend-mcp/boss-chat`(若设置 `BOSS_RECOMMEND_HOME`,则默认 `<BOSS_RECOMMEND_HOME>/boss-chat`)
243
+ - 对 `/.boss-chat`、系统目录等危险运行目录会主动拒绝启动并返回 `UNSAFE_DATA_DIR`,避免在 harness 丢参时误写根目录
244
+ - `boss_chat_health_check` 与 chat run 返回结果会包含 `data_dir` 与 `data_dir_source`,便于定位是参数/环境变量/默认路径生效
243
245
 
244
246
  chat-only 交互建议:
245
247
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@reconcrap/boss-recommend-mcp",
3
- "version": "1.3.35",
3
+ "version": "1.3.36",
4
4
  "description": "Unified MCP pipeline for recommend-page filtering and screening on Boss Zhipin",
5
5
  "keywords": [
6
6
  "boss",
package/src/boss-chat.js CHANGED
@@ -97,11 +97,30 @@ function isSafeBossChatLegacyWorkspaceRoot(workspaceRoot) {
97
97
  );
98
98
  }
99
99
 
100
- export function getBossChatDataDir() {
100
+ function isUnsafeBossChatDataDir(targetPath) {
101
+ const resolved = path.resolve(String(targetPath || ""));
102
+ return isRootDirectory(resolved) || isSystemDirectoryWorkspaceRoot(resolved);
103
+ }
104
+
105
+ function resolveBossChatDataDir() {
101
106
  if (process.env.BOSS_CHAT_HOME) {
102
- return path.resolve(process.env.BOSS_CHAT_HOME);
107
+ return {
108
+ data_dir: path.resolve(process.env.BOSS_CHAT_HOME),
109
+ data_dir_source: "env:BOSS_CHAT_HOME"
110
+ };
103
111
  }
104
- return path.join(getStateHome(), BOSS_CHAT_RUNTIME_SUBDIR);
112
+ const stateHome = getStateHome();
113
+ const source = process.env.BOSS_RECOMMEND_HOME
114
+ ? "default:env:BOSS_RECOMMEND_HOME"
115
+ : "default:user_home";
116
+ return {
117
+ data_dir: path.join(stateHome, BOSS_CHAT_RUNTIME_SUBDIR),
118
+ data_dir_source: source
119
+ };
120
+ }
121
+
122
+ export function getBossChatDataDir() {
123
+ return resolveBossChatDataDir().data_dir;
105
124
  }
106
125
 
107
126
  export function getLegacyBossChatWorkspaceDataDir(workspaceRoot) {
@@ -110,7 +129,8 @@ export function getLegacyBossChatWorkspaceDataDir(workspaceRoot) {
110
129
  }
111
130
 
112
131
  export function resolveBossChatRuntimeLayout(workspaceRoot) {
113
- const dataDir = getBossChatDataDir();
132
+ const resolvedDataDir = resolveBossChatDataDir();
133
+ const dataDir = resolvedDataDir.data_dir;
114
134
  const legacyWorkspaceDir = getLegacyBossChatWorkspaceDataDir(workspaceRoot);
115
135
  const migrationSourceDir =
116
136
  legacyWorkspaceDir && pathExists(legacyWorkspaceDir) && !pathExists(dataDir)
@@ -119,6 +139,7 @@ export function resolveBossChatRuntimeLayout(workspaceRoot) {
119
139
  return {
120
140
  workspace_root: workspaceRoot ? path.resolve(String(workspaceRoot)) : null,
121
141
  data_dir: dataDir,
142
+ data_dir_source: resolvedDataDir.data_dir_source,
122
143
  legacy_workspace_dir: legacyWorkspaceDir,
123
144
  migration_source_dir: migrationSourceDir,
124
145
  migration_pending: Boolean(migrationSourceDir),
@@ -144,6 +165,22 @@ export function ensureBossChatRuntimeReady(workspaceRoot) {
144
165
  : ""
145
166
  };
146
167
 
168
+ if (isUnsafeBossChatDataDir(runtime.data_dir)) {
169
+ return {
170
+ ...runtime,
171
+ created,
172
+ existed,
173
+ failed: [
174
+ {
175
+ path: runtime.data_dir,
176
+ message: `Refusing unsafe boss-chat runtime path: ${runtime.data_dir}. Please use BOSS_CHAT_HOME in a writable user directory.`
177
+ }
178
+ ],
179
+ migration,
180
+ blocked_reason: "UNSAFE_DATA_DIR"
181
+ };
182
+ }
183
+
147
184
  if (runtime.migration_source_dir) {
148
185
  try {
149
186
  fs.cpSync(runtime.migration_source_dir, runtime.data_dir, {
@@ -698,28 +735,39 @@ function buildBossChatCliArgs(command, input, resolvedConfig, runtimeLayout = nu
698
735
  const runId = normalizeBossChatRunId(input);
699
736
  args.push("--profile", normalizeText(input.profile) || "default");
700
737
  args.push("--run-id", runId);
701
- return args;
702
- }
703
-
738
+ return args;
739
+ }
740
+
741
+ function withRuntimeDiagnostics(payload, runtimeLayout) {
742
+ if (!payload || typeof payload !== "object") return payload;
743
+ return {
744
+ ...payload,
745
+ data_dir: runtimeLayout?.data_dir || null,
746
+ data_dir_source: runtimeLayout?.data_dir_source || null
747
+ };
748
+ }
749
+
704
750
  async function spawnBossChatCli({ workspaceRoot, command, input = {} }) {
751
+ const runtimeLayout = ensureBossChatRuntimeReady(workspaceRoot);
705
752
  const cliPath = resolveBossChatCliPath(workspaceRoot);
706
753
  if (!cliPath) {
707
- return {
754
+ return {
708
755
  ok: false,
709
756
  exitCode: -1,
710
757
  stdout: "",
711
758
  stderr: "",
712
- payload: {
713
- status: "FAILED",
714
- error: {
715
- code: "BOSS_CHAT_CLI_MISSING",
716
- message: "未找到 vendored boss-chat CLI。"
717
- }
759
+ payload: {
760
+ status: "FAILED",
761
+ error: {
762
+ code: "BOSS_CHAT_CLI_MISSING",
763
+ message: "未找到 vendored boss-chat CLI。"
764
+ },
765
+ data_dir: runtimeLayout?.data_dir || null,
766
+ data_dir_source: runtimeLayout?.data_dir_source || null
718
767
  }
719
768
  };
720
769
  }
721
770
 
722
- const runtimeLayout = ensureBossChatRuntimeReady(workspaceRoot);
723
771
  const runtimeInitFailed = runtimeLayout.failed.some((item) => item.path === runtimeLayout.data_dir)
724
772
  && !pathExists(runtimeLayout.data_dir);
725
773
  if (runtimeInitFailed) {
@@ -738,6 +786,7 @@ async function spawnBossChatCli({ workspaceRoot, command, input = {} }) {
738
786
  .join("; ") || "无法初始化 boss-chat runtime 目录。"
739
787
  },
740
788
  data_dir: runtimeLayout.data_dir,
789
+ data_dir_source: runtimeLayout.data_dir_source,
741
790
  migration: runtimeLayout.migration
742
791
  }
743
792
  };
@@ -752,12 +801,14 @@ async function spawnBossChatCli({ workspaceRoot, command, input = {} }) {
752
801
  exitCode: 1,
753
802
  stdout: "",
754
803
  stderr: "",
755
- payload: {
756
- status: "FAILED",
757
- error: configResolution.error,
758
- config_path: configResolution.config_path,
759
- config_dir: configResolution.config_dir
760
- }
804
+ payload: {
805
+ status: "FAILED",
806
+ error: configResolution.error,
807
+ config_path: configResolution.config_path,
808
+ config_dir: configResolution.config_dir,
809
+ data_dir: runtimeLayout.data_dir,
810
+ data_dir_source: runtimeLayout.data_dir_source
811
+ }
761
812
  };
762
813
  }
763
814
  }
@@ -765,12 +816,15 @@ async function spawnBossChatCli({ workspaceRoot, command, input = {} }) {
765
816
  const args = [cliPath, ...buildBossChatCliArgs(command, input, configResolution?.config || {}, runtimeLayout)];
766
817
  const cwd = path.resolve(String(workspaceRoot || process.cwd()));
767
818
  return new Promise((resolve) => {
768
- const child = spawn(process.execPath, args, {
769
- cwd,
770
- env: process.env,
771
- windowsHide: true,
772
- stdio: ["ignore", "pipe", "pipe"]
773
- });
819
+ const child = spawn(process.execPath, args, {
820
+ cwd,
821
+ env: {
822
+ ...process.env,
823
+ BOSS_CHAT_HOME: runtimeLayout.data_dir
824
+ },
825
+ windowsHide: true,
826
+ stdio: ["ignore", "pipe", "pipe"]
827
+ });
774
828
 
775
829
  let stdout = "";
776
830
  let stderr = "";
@@ -786,48 +840,53 @@ async function spawnBossChatCli({ workspaceRoot, command, input = {} }) {
786
840
  exitCode: -1,
787
841
  stdout,
788
842
  stderr,
789
- payload: {
790
- status: "FAILED",
791
- error: {
792
- code: "BOSS_CHAT_CLI_SPAWN_FAILED",
793
- message: error?.message || "无法启动 vendored boss-chat CLI。"
794
- }
795
- }
796
- });
797
- });
843
+ payload: {
844
+ status: "FAILED",
845
+ error: {
846
+ code: "BOSS_CHAT_CLI_SPAWN_FAILED",
847
+ message: error?.message || "无法启动 vendored boss-chat CLI。"
848
+ },
849
+ data_dir: runtimeLayout.data_dir,
850
+ data_dir_source: runtimeLayout.data_dir_source
851
+ }
852
+ });
853
+ });
798
854
  child.on("close", (code) => {
799
855
  const parsed = parseJsonOutput(stdout) || parseJsonOutput(stderr);
800
856
  if (parsed && typeof parsed === "object") {
801
857
  resolve({
802
858
  ok: Number(code) === 0 && String(parsed.status || "").toUpperCase() !== "FAILED",
803
- exitCode: Number.isInteger(code) ? code : 1,
804
- stdout,
805
- stderr,
806
- payload: parsed
807
- });
808
- return;
809
- }
810
- resolve({
859
+ exitCode: Number.isInteger(code) ? code : 1,
860
+ stdout,
861
+ stderr,
862
+ payload: withRuntimeDiagnostics(parsed, runtimeLayout)
863
+ });
864
+ return;
865
+ }
866
+ resolve({
811
867
  ok: Number(code) === 0,
812
868
  exitCode: Number.isInteger(code) ? code : 1,
813
869
  stdout,
814
- stderr,
815
- payload: Number(code) === 0
816
- ? {
817
- status: "OK",
818
- message: normalizeText(stdout) || `${command} 执行成功。`
819
- }
820
- : {
821
- status: "FAILED",
822
- error: {
823
- code: "BOSS_CHAT_CLI_EXECUTION_FAILED",
824
- message: normalizeText(stderr || stdout) || `${command} 执行失败。`
825
- }
826
- }
827
- });
828
- });
829
- });
830
- }
870
+ stderr,
871
+ payload: withRuntimeDiagnostics(
872
+ Number(code) === 0
873
+ ? {
874
+ status: "OK",
875
+ message: normalizeText(stdout) || `${command} 执行成功。`
876
+ }
877
+ : {
878
+ status: "FAILED",
879
+ error: {
880
+ code: "BOSS_CHAT_CLI_EXECUTION_FAILED",
881
+ message: normalizeText(stderr || stdout) || `${command} 执行失败。`
882
+ }
883
+ },
884
+ runtimeLayout
885
+ )
886
+ });
887
+ });
888
+ });
889
+ }
831
890
 
832
891
  export function getBossChatHealthCheck(workspaceRoot, input = {}) {
833
892
  const cliDir = resolveBossChatCliDir(workspaceRoot);
@@ -844,6 +903,7 @@ export function getBossChatHealthCheck(workspaceRoot, input = {}) {
844
903
  message: "未找到 vendored boss-chat CLI。"
845
904
  },
846
905
  data_dir: runtimeLayout.data_dir,
906
+ data_dir_source: runtimeLayout.data_dir_source,
847
907
  legacy_workspace_dir: runtimeLayout.legacy_workspace_dir,
848
908
  migration_pending: runtimeLayout.migration_pending
849
909
  };
@@ -857,6 +917,7 @@ export function getBossChatHealthCheck(workspaceRoot, input = {}) {
857
917
  cli_dir: cliDir,
858
918
  cli_path: cliPath,
859
919
  data_dir: runtimeLayout.data_dir,
920
+ data_dir_source: runtimeLayout.data_dir_source,
860
921
  legacy_workspace_dir: runtimeLayout.legacy_workspace_dir,
861
922
  migration_pending: runtimeLayout.migration_pending
862
923
  };
@@ -870,6 +931,7 @@ export function getBossChatHealthCheck(workspaceRoot, input = {}) {
870
931
  debug_port: resolvedPort,
871
932
  shared_llm_config: true,
872
933
  data_dir: runtimeLayout.data_dir,
934
+ data_dir_source: runtimeLayout.data_dir_source,
873
935
  legacy_workspace_dir: runtimeLayout.legacy_workspace_dir,
874
936
  migration_source_dir: runtimeLayout.migration_source_dir,
875
937
  migration_pending: runtimeLayout.migration_pending
@@ -244,6 +244,7 @@ async function testBossChatAdapterShouldResolveSharedConfigAndInvokeLocalCli() {
244
244
  assert.equal(health.status, "OK");
245
245
  assert.equal(health.shared_llm_config, true);
246
246
  assert.equal(health.debug_port, 9666);
247
+ assert.equal(health.data_dir_source, "env:BOSS_CHAT_HOME");
247
248
  assert.equal(health.data_dir, getTestChatDataDir(workspaceRoot));
248
249
  assert.equal(health.legacy_workspace_dir, path.join(workspaceRoot, ".boss-chat"));
249
250
  assert.equal(health.migration_pending, false);
@@ -526,18 +527,45 @@ function testVendorBossChatCliShouldResolveExplicitDataDir() {
526
527
  const cwd = path.join(path.parse(process.cwd()).root, "workspace");
527
528
  const args = vendorCliTestables.parseArgs(["start-run", "--data-dir", "/tmp/boss-chat-data"]);
528
529
  assert.equal(args.dataDir, "/tmp/boss-chat-data");
530
+ const explicitResolved = vendorCliTestables.resolveDataDirDetails(args, { BOSS_CHAT_HOME: "/tmp/ignored" }, cwd);
531
+ assert.equal(explicitResolved.source, "arg:data-dir");
532
+ assert.equal(explicitResolved.path, path.resolve("/tmp/boss-chat-data"));
529
533
  assert.equal(
530
534
  vendorCliTestables.resolveDataDir(args, { BOSS_CHAT_HOME: "/tmp/ignored" }, cwd),
531
535
  path.resolve("/tmp/boss-chat-data")
532
536
  );
537
+ const envResolved = vendorCliTestables.resolveDataDirDetails({}, { BOSS_CHAT_HOME: "/tmp/from-env" }, cwd);
538
+ assert.equal(envResolved.source, "env:BOSS_CHAT_HOME");
539
+ assert.equal(envResolved.path, path.resolve("/tmp/from-env"));
533
540
  assert.equal(
534
541
  vendorCliTestables.resolveDataDir({}, { BOSS_CHAT_HOME: "/tmp/from-env" }, cwd),
535
542
  path.resolve("/tmp/from-env")
536
543
  );
544
+ const defaultResolved = vendorCliTestables.resolveDataDirDetails({}, {}, cwd);
545
+ assert.equal(defaultResolved.source, "default:user_home");
546
+ assert.equal(defaultResolved.path, path.join(os.homedir(), ".boss-recommend-mcp", "boss-chat"));
537
547
  assert.equal(
538
548
  vendorCliTestables.resolveDataDir({}, {}, cwd),
539
- path.join(path.resolve(cwd), ".boss-chat")
549
+ path.join(os.homedir(), ".boss-recommend-mcp", "boss-chat")
540
550
  );
551
+
552
+ const unsafeRoot = vendorCliTestables.validateDataDir(path.parse(process.cwd()).root);
553
+ assert.equal(unsafeRoot.ok, false);
554
+ assert.equal(unsafeRoot.code, "UNSAFE_DATA_DIR");
555
+ assert.equal(unsafeRoot.message.includes("Refusing unsafe boss-chat data dir"), true);
556
+
557
+ const safePath = vendorCliTestables.validateDataDir(path.join(os.homedir(), ".boss-recommend-mcp", "boss-chat"));
558
+ assert.equal(safePath.ok, true);
559
+ }
560
+
561
+ function testVendorBossChatCliShouldUseRecommendHomeForDefaultDataDir() {
562
+ const resolved = vendorCliTestables.resolveDataDirDetails(
563
+ {},
564
+ { BOSS_RECOMMEND_HOME: "/tmp/recommend-home" },
565
+ path.join(path.parse(process.cwd()).root, "workspace")
566
+ );
567
+ assert.equal(resolved.source, "default:env:BOSS_RECOMMEND_HOME");
568
+ assert.equal(resolved.path, path.resolve("/tmp/recommend-home/boss-chat"));
541
569
  }
542
570
 
543
571
  async function testBossChatPageShouldTreatBlankChatShellAsOnChatPage() {
@@ -3019,6 +3047,7 @@ async function main() {
3019
3047
  await testBossChatMcpToolsShouldValidateAndRoute();
3020
3048
  await testBossChatCliShouldSupportRunAndFollowUpParsing();
3021
3049
  testVendorBossChatCliShouldResolveExplicitDataDir();
3050
+ testVendorBossChatCliShouldUseRecommendHomeForDefaultDataDir();
3022
3051
  await testVendorBossChatCliShouldWaitForHydratedChatShell();
3023
3052
  await testVendorBossChatCliShouldRetryJobListDuringPromptRunProfile();
3024
3053
  testCliShouldPinInstalledPackageVersionInGeneratedMcpConfig();
@@ -1,8 +1,9 @@
1
- #!/usr/bin/env node
2
- import { spawn } from 'node:child_process';
3
- import { appendFile, mkdir } from 'node:fs/promises';
4
- import path from 'node:path';
5
- import process from 'node:process';
1
+ #!/usr/bin/env node
2
+ import { spawn } from 'node:child_process';
3
+ import { appendFile, mkdir } from 'node:fs/promises';
4
+ import os from 'node:os';
5
+ import path from 'node:path';
6
+ import process from 'node:process';
6
7
  import * as readlineCore from 'node:readline';
7
8
  import readline from 'node:readline/promises';
8
9
  import util from 'node:util';
@@ -301,12 +302,82 @@ function parseArgs(argv) {
301
302
  return args;
302
303
  }
303
304
 
304
- function resolveDataDir(args = {}, env = process.env, cwd = process.cwd()) {
305
+ function isRootDirectory(targetPath) {
306
+ const resolved = path.resolve(String(targetPath || ''));
307
+ const parsed = path.parse(resolved);
308
+ return resolved.toLowerCase() === String(parsed.root || '').toLowerCase();
309
+ }
310
+
311
+ function isSystemDirectoryPath(targetPath) {
312
+ const resolved = path.resolve(String(targetPath || ''));
313
+ const normalized = resolved.replace(/\\/g, '/').toLowerCase();
314
+ if (process.platform === 'win32') {
315
+ return (
316
+ normalized.endsWith('/windows')
317
+ || normalized.endsWith('/windows/system32')
318
+ || normalized.endsWith('/windows/syswow64')
319
+ || normalized.endsWith('/program files')
320
+ || normalized.endsWith('/program files (x86)')
321
+ );
322
+ }
323
+ return (
324
+ normalized === '/system'
325
+ || normalized.startsWith('/system/')
326
+ || normalized === '/usr'
327
+ || normalized.startsWith('/usr/')
328
+ || normalized === '/bin'
329
+ || normalized.startsWith('/bin/')
330
+ || normalized === '/sbin'
331
+ || normalized.startsWith('/sbin/')
332
+ );
333
+ }
334
+
335
+ function resolveDefaultDataDir(env = process.env) {
336
+ const stateHomeRaw = String(env?.BOSS_RECOMMEND_HOME || '').trim();
337
+ const stateHome = stateHomeRaw
338
+ ? path.resolve(stateHomeRaw)
339
+ : path.join(os.homedir(), '.boss-recommend-mcp');
340
+ const source = stateHomeRaw
341
+ ? 'default:env:BOSS_RECOMMEND_HOME'
342
+ : 'default:user_home';
343
+ return {
344
+ path: path.join(stateHome, 'boss-chat'),
345
+ source,
346
+ };
347
+ }
348
+
349
+ function resolveDataDirDetails(args = {}, env = process.env, cwd = process.cwd()) {
305
350
  const explicit = String(args?.dataDir || '').trim();
306
- if (explicit) return path.resolve(explicit);
351
+ if (explicit) {
352
+ return {
353
+ path: path.resolve(explicit),
354
+ source: 'arg:data-dir',
355
+ };
356
+ }
307
357
  const fromEnv = String(env?.BOSS_CHAT_HOME || '').trim();
308
- if (fromEnv) return path.resolve(fromEnv);
309
- return path.join(path.resolve(String(cwd || process.cwd())), '.boss-chat');
358
+ if (fromEnv) {
359
+ return {
360
+ path: path.resolve(fromEnv),
361
+ source: 'env:BOSS_CHAT_HOME',
362
+ };
363
+ }
364
+ return resolveDefaultDataDir(env);
365
+ }
366
+
367
+ function resolveDataDir(args = {}, env = process.env, cwd = process.cwd()) {
368
+ return resolveDataDirDetails(args, env, cwd).path;
369
+ }
370
+
371
+ function validateDataDir(targetPath) {
372
+ const resolved = path.resolve(String(targetPath || ''));
373
+ if (isRootDirectory(resolved) || isSystemDirectoryPath(resolved)) {
374
+ return {
375
+ ok: false,
376
+ code: 'UNSAFE_DATA_DIR',
377
+ message: `Refusing unsafe boss-chat data dir: ${resolved}. Please use --data-dir or BOSS_CHAT_HOME to a writable user directory.`,
378
+ };
379
+ }
380
+ return { ok: true };
310
381
  }
311
382
 
312
383
  function printUsage() {
@@ -323,7 +394,7 @@ function printUsage() {
323
394
  console.log('');
324
395
  console.log('Common options:');
325
396
  console.log(' --profile <name> Profile name (default: default)');
326
- console.log(' --data-dir <path> Runtime data dir (default: $BOSS_CHAT_HOME or <cwd>/.boss-chat)');
397
+ console.log(' --data-dir <path> Runtime data dir (default: $BOSS_CHAT_HOME or ~/.boss-recommend-mcp/boss-chat)');
327
398
  console.log(' --json JSON output for agent integration');
328
399
  console.log(' --run-id <id> Target async run_id (for get/pause/resume/cancel)');
329
400
  console.log('');
@@ -1527,7 +1598,27 @@ async function executeRunCommand(args, dataDir) {
1527
1598
 
1528
1599
  async function main() {
1529
1600
  const args = parseArgs(process.argv.slice(2));
1530
- const dataDir = resolveDataDir(args);
1601
+ const resolvedDataDir = resolveDataDirDetails(args);
1602
+ const dataDir = resolvedDataDir.path;
1603
+ const dataDirValidation = validateDataDir(dataDir);
1604
+ if (!dataDirValidation.ok) {
1605
+ const failedPayload = {
1606
+ status: 'FAILED',
1607
+ error: {
1608
+ code: dataDirValidation.code,
1609
+ message: dataDirValidation.message,
1610
+ },
1611
+ data_dir: dataDir,
1612
+ data_dir_source: resolvedDataDir.source,
1613
+ };
1614
+ if (args.json) {
1615
+ console.log(JSON.stringify(failedPayload));
1616
+ } else {
1617
+ console.error(failedPayload.error.message);
1618
+ }
1619
+ process.exitCode = 1;
1620
+ return;
1621
+ }
1531
1622
  await mkdir(dataDir, { recursive: true });
1532
1623
 
1533
1624
  if (args.command === 'help') {
@@ -1562,19 +1653,28 @@ async function main() {
1562
1653
  break;
1563
1654
  default:
1564
1655
  printUsage();
1565
- process.exitCode = 1;
1566
- return;
1567
- }
1568
-
1569
- outputCommandResult(args, payload);
1570
- if (payload?.status === 'FAILED') {
1571
- process.exitCode = 1;
1572
- }
1573
- }
1656
+ process.exitCode = 1;
1657
+ return;
1658
+ }
1659
+
1660
+ if (payload && typeof payload === 'object') {
1661
+ payload = {
1662
+ ...payload,
1663
+ data_dir: dataDir,
1664
+ data_dir_source: resolvedDataDir.source,
1665
+ };
1666
+ }
1667
+ outputCommandResult(args, payload);
1668
+ if (payload?.status === 'FAILED') {
1669
+ process.exitCode = 1;
1670
+ }
1671
+ }
1574
1672
 
1575
1673
  export const __testables = {
1576
1674
  parseArgs,
1675
+ resolveDataDirDetails,
1577
1676
  resolveDataDir,
1677
+ validateDataDir,
1578
1678
  connectBossChatPage,
1579
1679
  hasHydratedChatShell,
1580
1680
  promptRunProfile,