duclaw-cli 1.0.0 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/bundle.js CHANGED
@@ -16339,11 +16339,11 @@ var require_commands_queue = __commonJS({
16339
16339
  return;
16340
16340
  }
16341
16341
  ;
16342
- return new Promise((resolve10) => {
16342
+ return new Promise((resolve11) => {
16343
16343
  const onEmpty = () => {
16344
16344
  if (timeoutId)
16345
16345
  clearTimeout(timeoutId);
16346
- resolve10();
16346
+ resolve11();
16347
16347
  };
16348
16348
  let timeoutId;
16349
16349
  const timeoutMs = options?.timeoutMs;
@@ -16356,7 +16356,7 @@ var require_commands_queue = __commonJS({
16356
16356
  (0, enterprise_maintenance_manager_1.dbgMaintenance)(`Flushing ${pendingCount} commands that timed out waiting for reply`);
16357
16357
  this.#flushWaitingForReply(new errors_1.TimeoutError());
16358
16358
  }
16359
- resolve10();
16359
+ resolve11();
16360
16360
  }, timeoutMs);
16361
16361
  }
16362
16362
  this.#waitingForReply.events.once("empty", onEmpty);
@@ -16368,14 +16368,14 @@ var require_commands_queue = __commonJS({
16368
16368
  } else if (options?.abortSignal?.aborted) {
16369
16369
  return Promise.reject(new errors_1.AbortError());
16370
16370
  }
16371
- return new Promise((resolve10, reject) => {
16371
+ return new Promise((resolve11, reject) => {
16372
16372
  let node;
16373
16373
  const value = {
16374
16374
  args,
16375
16375
  chainId: options?.chainId,
16376
16376
  abort: void 0,
16377
16377
  timeout: void 0,
16378
- resolve: resolve10,
16378
+ resolve: resolve11,
16379
16379
  reject,
16380
16380
  channelsCounter: void 0,
16381
16381
  typeMapping: options?.typeMapping
@@ -16410,7 +16410,7 @@ var require_commands_queue = __commonJS({
16410
16410
  });
16411
16411
  }
16412
16412
  #addPubSubCommand(command, asap = false, chainId) {
16413
- return new Promise((resolve10, reject) => {
16413
+ return new Promise((resolve11, reject) => {
16414
16414
  this.#toWrite.add({
16415
16415
  args: command.args,
16416
16416
  chainId,
@@ -16418,7 +16418,7 @@ var require_commands_queue = __commonJS({
16418
16418
  timeout: void 0,
16419
16419
  resolve() {
16420
16420
  command.resolve();
16421
- resolve10();
16421
+ resolve11();
16422
16422
  },
16423
16423
  reject(err) {
16424
16424
  command.reject?.();
@@ -16438,8 +16438,8 @@ var require_commands_queue = __commonJS({
16438
16438
  return;
16439
16439
  const firstElement = typeof reply[0] === "string" ? Buffer.from(reply[0]) : reply[0];
16440
16440
  if (PONG.equals(firstElement)) {
16441
- const { resolve: resolve10, typeMapping } = this.#waitingForReply.shift(), buffer = reply[1].length === 0 ? reply[0] : reply[1];
16442
- resolve10(typeMapping?.[decoder_1.RESP_TYPES.SIMPLE_STRING] === Buffer ? buffer : buffer.toString());
16441
+ const { resolve: resolve11, typeMapping } = this.#waitingForReply.shift(), buffer = reply[1].length === 0 ? reply[0] : reply[1];
16442
+ resolve11(typeMapping?.[decoder_1.RESP_TYPES.SIMPLE_STRING] === Buffer ? buffer : buffer.toString());
16443
16443
  return;
16444
16444
  }
16445
16445
  }
@@ -16463,12 +16463,12 @@ var require_commands_queue = __commonJS({
16463
16463
  if (!command)
16464
16464
  return;
16465
16465
  if (command && this.#respVersion === 2) {
16466
- const { resolve: resolve10 } = command;
16466
+ const { resolve: resolve11 } = command;
16467
16467
  command.resolve = () => {
16468
16468
  if (!this.#pubSub.isActive) {
16469
16469
  this.#resetDecoderCallbacks();
16470
16470
  }
16471
- resolve10();
16471
+ resolve11();
16472
16472
  };
16473
16473
  }
16474
16474
  return this.#addPubSubCommand(command);
@@ -16504,7 +16504,7 @@ var require_commands_queue = __commonJS({
16504
16504
  return this.#pubSub.listeners[type];
16505
16505
  }
16506
16506
  monitor(callback, options) {
16507
- return new Promise((resolve10, reject) => {
16507
+ return new Promise((resolve11, reject) => {
16508
16508
  const typeMapping = options?.typeMapping ?? {};
16509
16509
  this.#toWrite.add({
16510
16510
  args: ["MONITOR"],
@@ -16519,7 +16519,7 @@ var require_commands_queue = __commonJS({
16519
16519
  this.decoder.onReply = callback;
16520
16520
  }
16521
16521
  this.decoder.getTypeMapping = () => typeMapping;
16522
- resolve10();
16522
+ resolve11();
16523
16523
  },
16524
16524
  reject,
16525
16525
  channelsCounter: void 0,
@@ -16533,7 +16533,7 @@ var require_commands_queue = __commonJS({
16533
16533
  }
16534
16534
  #resetFallbackOnReply;
16535
16535
  async reset(chainId, typeMapping) {
16536
- return new Promise((resolve10, reject) => {
16536
+ return new Promise((resolve11, reject) => {
16537
16537
  this.#resetFallbackOnReply = this.decoder.onReply;
16538
16538
  this.decoder.onReply = ((reply) => {
16539
16539
  if (typeof reply === "string" && reply === "RESET" || reply instanceof Buffer && RESET.equals(reply)) {
@@ -16550,7 +16550,7 @@ var require_commands_queue = __commonJS({
16550
16550
  chainId,
16551
16551
  abort: void 0,
16552
16552
  timeout: void 0,
16553
- resolve: resolve10,
16553
+ resolve: resolve11,
16554
16554
  reject,
16555
16555
  channelsCounter: void 0,
16556
16556
  typeMapping
@@ -17870,7 +17870,7 @@ var require_pool = __commonJS({
17870
17870
  this._self.#returnClient(node);
17871
17871
  }
17872
17872
  execute(fn) {
17873
- return new Promise((resolve10, reject) => {
17873
+ return new Promise((resolve11, reject) => {
17874
17874
  const client2 = this._self.#idleClients.shift(), { tail } = this._self.#tasksQueue;
17875
17875
  if (!client2) {
17876
17876
  let timeout;
@@ -17883,7 +17883,7 @@ var require_pool = __commonJS({
17883
17883
  const task = this._self.#tasksQueue.push({
17884
17884
  timeout,
17885
17885
  // @ts-ignore
17886
- resolve: resolve10,
17886
+ resolve: resolve11,
17887
17887
  reject,
17888
17888
  fn
17889
17889
  });
@@ -17893,15 +17893,15 @@ var require_pool = __commonJS({
17893
17893
  return;
17894
17894
  }
17895
17895
  const node = this._self.#clientsInUse.push(client2);
17896
- this._self.#executeTask(node, resolve10, reject, fn);
17896
+ this._self.#executeTask(node, resolve11, reject, fn);
17897
17897
  });
17898
17898
  }
17899
- #executeTask(node, resolve10, reject, fn) {
17899
+ #executeTask(node, resolve11, reject, fn) {
17900
17900
  const result = fn(node.value);
17901
17901
  if (result instanceof Promise) {
17902
- result.then(resolve10, reject).finally(() => this.#returnClient(node));
17902
+ result.then(resolve11, reject).finally(() => this.#returnClient(node));
17903
17903
  } else {
17904
- resolve10(result);
17904
+ resolve11(result);
17905
17905
  this.#returnClient(node);
17906
17906
  }
17907
17907
  }
@@ -18948,20 +18948,20 @@ var require_client = __commonJS({
18948
18948
  * Close the client. Wait for pending commands.
18949
18949
  */
18950
18950
  close() {
18951
- return new Promise((resolve10) => {
18951
+ return new Promise((resolve11) => {
18952
18952
  clearTimeout(this._self.#pingTimer);
18953
18953
  this._self.#socket.close();
18954
18954
  this._self.#clientSideCache?.onClose();
18955
18955
  if (this._self.#queue.isEmpty()) {
18956
18956
  this._self.#socket.destroySocket();
18957
- return resolve10();
18957
+ return resolve11();
18958
18958
  }
18959
18959
  const maybeClose = () => {
18960
18960
  if (!this._self.#queue.isEmpty())
18961
18961
  return;
18962
18962
  this._self.#socket.off("data", maybeClose);
18963
18963
  this._self.#socket.destroySocket();
18964
- resolve10();
18964
+ resolve11();
18965
18965
  };
18966
18966
  this._self.#socket.on("data", maybeClose);
18967
18967
  this._self.#credentialsSubscription?.dispose();
@@ -20605,9 +20605,9 @@ var require_wait_queue = __commonJS({
20605
20605
  #list = new linked_list_1.SinglyLinkedList();
20606
20606
  #queue = new linked_list_1.SinglyLinkedList();
20607
20607
  push(value) {
20608
- const resolve10 = this.#queue.shift();
20609
- if (resolve10 !== void 0) {
20610
- resolve10(value);
20608
+ const resolve11 = this.#queue.shift();
20609
+ if (resolve11 !== void 0) {
20610
+ resolve11(value);
20611
20611
  return;
20612
20612
  }
20613
20613
  this.#list.push(value);
@@ -20616,7 +20616,7 @@ var require_wait_queue = __commonJS({
20616
20616
  return this.#list.shift();
20617
20617
  }
20618
20618
  wait() {
20619
- return new Promise((resolve10) => this.#queue.push(resolve10));
20619
+ return new Promise((resolve11) => this.#queue.push(resolve11));
20620
20620
  }
20621
20621
  };
20622
20622
  exports2.WaitQueue = WaitQueue;
@@ -28870,11 +28870,11 @@ var require_tracked_promise = __commonJS({
28870
28870
  value;
28871
28871
  constructor(executor) {
28872
28872
  this.state = "pending";
28873
- this.promise = new Promise((resolve10, reject) => {
28873
+ this.promise = new Promise((resolve11, reject) => {
28874
28874
  executor((value) => {
28875
28875
  this.state = "fulfilled";
28876
28876
  this.value = value;
28877
- resolve10(value);
28877
+ resolve11(value);
28878
28878
  }, (error) => {
28879
28879
  this.state = "rejected";
28880
28880
  this.error = error;
@@ -28978,7 +28978,7 @@ var require_runner = __commonJS({
28978
28978
  }
28979
28979
  };
28980
28980
  const runTask = (date) => {
28981
- return new Promise(async (resolve10) => {
28981
+ return new Promise(async (resolve11) => {
28982
28982
  const execution = {
28983
28983
  id: (0, create_id_1.createID)("exec"),
28984
28984
  reason: "scheduled"
@@ -29003,18 +29003,18 @@ var require_runner = __commonJS({
29003
29003
  execution.error = error;
29004
29004
  this.onError(date, error, execution);
29005
29005
  }
29006
- resolve10(true);
29006
+ resolve11(true);
29007
29007
  }, randomDelay);
29008
29008
  }
29009
29009
  });
29010
29010
  };
29011
29011
  const checkAndRun = (date) => {
29012
- return new tracked_promise_1.TrackedPromise(async (resolve10, reject) => {
29012
+ return new tracked_promise_1.TrackedPromise(async (resolve11, reject) => {
29013
29013
  try {
29014
29014
  if (this.timeMatcher.match(date)) {
29015
29015
  await runTask(date);
29016
29016
  }
29017
- resolve10(true);
29017
+ resolve11(true);
29018
29018
  } catch (err) {
29019
29019
  reject(err);
29020
29020
  }
@@ -29679,14 +29679,14 @@ var require_inline_scheduled_task = __commonJS({
29679
29679
  this.emitter.emit("task:destroyed", this.createContext(/* @__PURE__ */ new Date()));
29680
29680
  }
29681
29681
  execute() {
29682
- return new Promise((resolve10, reject) => {
29682
+ return new Promise((resolve11, reject) => {
29683
29683
  const onFail = (context) => {
29684
29684
  this.off("execution:finished", onFail);
29685
29685
  reject(context.execution?.error);
29686
29686
  };
29687
29687
  const onFinished = (context) => {
29688
29688
  this.off("execution:failed", onFail);
29689
- resolve10(context.execution?.result);
29689
+ resolve11(context.execution?.result);
29690
29690
  };
29691
29691
  this.once("execution:finished", onFinished);
29692
29692
  this.once("execution:failed", onFail);
@@ -29877,9 +29877,9 @@ var require_background_scheduled_task = __commonJS({
29877
29877
  return null;
29878
29878
  }
29879
29879
  start() {
29880
- return new Promise((resolve10, reject) => {
29880
+ return new Promise((resolve11, reject) => {
29881
29881
  if (this.forkProcess) {
29882
- return resolve10(void 0);
29882
+ return resolve11(void 0);
29883
29883
  }
29884
29884
  const timeout = setTimeout(() => {
29885
29885
  reject(new Error("Start operation timed out"));
@@ -29918,7 +29918,7 @@ var require_background_scheduled_task = __commonJS({
29918
29918
  this.once("task:started", () => {
29919
29919
  this.stateMachine.changeState("idle");
29920
29920
  clearTimeout(timeout);
29921
- resolve10(void 0);
29921
+ resolve11(void 0);
29922
29922
  });
29923
29923
  this.forkProcess.send({
29924
29924
  command: "task:start",
@@ -29932,9 +29932,9 @@ var require_background_scheduled_task = __commonJS({
29932
29932
  });
29933
29933
  }
29934
29934
  stop() {
29935
- return new Promise((resolve10, reject) => {
29935
+ return new Promise((resolve11, reject) => {
29936
29936
  if (!this.forkProcess) {
29937
- return resolve10(void 0);
29937
+ return resolve11(void 0);
29938
29938
  }
29939
29939
  const timeoutId = setTimeout(() => {
29940
29940
  clearTimeout(timeoutId);
@@ -29944,7 +29944,7 @@ var require_background_scheduled_task = __commonJS({
29944
29944
  clearTimeout(timeoutId);
29945
29945
  this.off("task:stopped", onStopped);
29946
29946
  this.forkProcess = void 0;
29947
- resolve10(void 0);
29947
+ resolve11(void 0);
29948
29948
  };
29949
29949
  const onStopped = () => {
29950
29950
  cleanupAndResolve();
@@ -29959,9 +29959,9 @@ var require_background_scheduled_task = __commonJS({
29959
29959
  return this.stateMachine.state;
29960
29960
  }
29961
29961
  destroy() {
29962
- return new Promise((resolve10, reject) => {
29962
+ return new Promise((resolve11, reject) => {
29963
29963
  if (!this.forkProcess) {
29964
- return resolve10(void 0);
29964
+ return resolve11(void 0);
29965
29965
  }
29966
29966
  const timeoutId = setTimeout(() => {
29967
29967
  clearTimeout(timeoutId);
@@ -29970,7 +29970,7 @@ var require_background_scheduled_task = __commonJS({
29970
29970
  const onDestroy = () => {
29971
29971
  clearTimeout(timeoutId);
29972
29972
  this.off("task:destroyed", onDestroy);
29973
- resolve10(void 0);
29973
+ resolve11(void 0);
29974
29974
  };
29975
29975
  this.once("task:destroyed", onDestroy);
29976
29976
  this.forkProcess.send({
@@ -29979,7 +29979,7 @@ var require_background_scheduled_task = __commonJS({
29979
29979
  });
29980
29980
  }
29981
29981
  execute() {
29982
- return new Promise((resolve10, reject) => {
29982
+ return new Promise((resolve11, reject) => {
29983
29983
  if (!this.forkProcess) {
29984
29984
  return reject(new Error("Cannot execute background task because it hasn't been started yet. Please initialize the task using the start() method before attempting to execute it."));
29985
29985
  }
@@ -29994,7 +29994,7 @@ var require_background_scheduled_task = __commonJS({
29994
29994
  };
29995
29995
  const onFinished = (context) => {
29996
29996
  cleanupListeners();
29997
- resolve10(context.execution?.result);
29997
+ resolve11(context.execution?.result);
29998
29998
  };
29999
29999
  const onFail = (context) => {
30000
30000
  cleanupListeners();
@@ -30122,69 +30122,173 @@ var require_node_cron = __commonJS({
30122
30122
  }
30123
30123
  });
30124
30124
 
30125
- // package.json
30126
- var require_package3 = __commonJS({
30127
- "package.json"(exports2, module2) {
30128
- module2.exports = {
30129
- packageManager: "pnpm@10.10.0+sha512.d615db246fe70f25dcfea6d8d73dee782ce23e2245e3c4f6f888249fb568149318637dca73c2c5c8ef2a4ca0d5657fb9567188bfab47f566d1ee6ce987815c39",
30130
- name: "dwclaw",
30131
- version: "1.0.0",
30132
- description: "AI Agent \u7BA1\u7406\u6846\u67B6 - \u652F\u6301\u98DE\u4E66 Channel\u3001\u56E2\u961F\u534F\u4F5C\u3001\u5B9A\u65F6\u4EFB\u52A1\u3001Web \u7BA1\u7406\u754C\u9762",
30133
- bin: {
30134
- dwclaw: "./dist/main.js"
30135
- },
30136
- files: [
30137
- "dist/",
30138
- "skills/",
30139
- ".claude/cron/",
30140
- "docker/Dockerfile",
30141
- "docker/docker-compose.yml",
30142
- "docker/entrypoint.sh",
30143
- "docker/agent-template.json",
30144
- "docker/.env"
30145
- ],
30146
- scripts: {
30147
- start: "npx tsx src/main.ts",
30148
- "dev:web": "cd web && pnpm dev",
30149
- build: "node build.js",
30150
- "build:tsc": "tsc",
30151
- "build:web": "cd web && pnpm build",
30152
- "build:all": "pnpm build:web && pnpm build"
30153
- },
30154
- dependencies: {
30155
- "@anthropic-ai/sdk": "^0.78.0",
30156
- "@hono/node-server": "^1.19.11",
30157
- "@larksuiteoapi/node-sdk": "^1.59.0",
30158
- "ali-oss": "^6.23.0",
30159
- "better-sqlite3": "^12.8.0",
30160
- chokidar: "^5.0.0",
30161
- dayjs: "^1.11.20",
30162
- diff: "^8.0.3",
30163
- dotenv: "^17.3.1",
30164
- hono: "^4.12.9",
30165
- "node-cron": "^4.2.1",
30166
- redis: "^5.11.0"
30167
- },
30168
- devDependencies: {
30169
- "@types/ali-oss": "^6.23.3",
30170
- "@types/better-sqlite3": "^7.6.13",
30171
- "@types/diff": "^8.0.0",
30172
- "@types/node": "^25.3.3",
30173
- "@types/node-cron": "^3.0.11",
30174
- esbuild: "^0.27.5",
30175
- "javascript-obfuscator": "^5.4.1",
30176
- tsx: "^4.21.0",
30177
- typescript: "^5.9.3",
30178
- vitest: "^4.0.18"
30179
- }
30180
- };
30125
+ // src/cli/index.ts
30126
+ var import_fs = require("fs");
30127
+ var import_path = require("path");
30128
+ var import_os = require("os");
30129
+ var DUCLAW_HOME = (0, import_path.join)((0, import_os.homedir)(), ".duclaw");
30130
+ function handleCliCommand(args) {
30131
+ const command = args[0];
30132
+ switch (command) {
30133
+ case "init":
30134
+ return handleInit(args);
30135
+ case "start":
30136
+ return handleStart();
30137
+ case "--help":
30138
+ case "-h":
30139
+ printHelp();
30140
+ return 0;
30141
+ case "--version":
30142
+ case "-v":
30143
+ printVersion();
30144
+ return 0;
30145
+ default:
30146
+ return checkAndGuideInit();
30181
30147
  }
30182
- });
30148
+ }
30149
+ function handleInit(args) {
30150
+ const targetDir = args[1] ? (0, import_path.resolve)(args[1]) : process.cwd();
30151
+ console.log(`
30152
+ duclaw-cli \u521D\u59CB\u5316
30153
+ `);
30154
+ console.log(` \u76EE\u6807\u76EE\u5F55: ${targetDir}
30155
+ `);
30156
+ if (!(0, import_fs.existsSync)(targetDir)) {
30157
+ (0, import_fs.mkdirSync)(targetDir, { recursive: true });
30158
+ }
30159
+ const configPath = (0, import_path.resolve)(targetDir, "duclaw.json");
30160
+ if ((0, import_fs.existsSync)(configPath)) {
30161
+ console.log(` [\u8DF3\u8FC7] duclaw.json \u5DF2\u5B58\u5728`);
30162
+ } else {
30163
+ const configTemplate = getDuclawTemplate();
30164
+ (0, import_fs.writeFileSync)(configPath, JSON.stringify(configTemplate, null, 4), "utf-8");
30165
+ console.log(` [\u521B\u5EFA] duclaw.json`);
30166
+ }
30167
+ const envPath = (0, import_path.resolve)(targetDir, ".env");
30168
+ if ((0, import_fs.existsSync)(envPath)) {
30169
+ console.log(` [\u8DF3\u8FC7] .env \u5DF2\u5B58\u5728`);
30170
+ } else {
30171
+ const envTemplate = getEnvTemplate();
30172
+ (0, import_fs.writeFileSync)(envPath, envTemplate, "utf-8");
30173
+ console.log(` [\u521B\u5EFA] .env`);
30174
+ }
30175
+ const skillsDir = (0, import_path.resolve)(targetDir, "skills");
30176
+ if (!(0, import_fs.existsSync)(skillsDir)) {
30177
+ (0, import_fs.mkdirSync)(skillsDir, { recursive: true });
30178
+ console.log(` [\u521B\u5EFA] skills/ \u76EE\u5F55`);
30179
+ } else {
30180
+ console.log(` [\u8DF3\u8FC7] skills/ \u76EE\u5F55\u5DF2\u5B58\u5728`);
30181
+ }
30182
+ const cronDir = (0, import_path.join)(DUCLAW_HOME, "cron");
30183
+ if (!(0, import_fs.existsSync)(cronDir)) {
30184
+ (0, import_fs.mkdirSync)(cronDir, { recursive: true });
30185
+ console.log(` [\u521B\u5EFA] ~/.duclaw/cron/ \u76EE\u5F55`);
30186
+ }
30187
+ const jobsPath = (0, import_path.join)(cronDir, "jobs.json");
30188
+ if (!(0, import_fs.existsSync)(jobsPath)) {
30189
+ (0, import_fs.writeFileSync)(jobsPath, "[]", "utf-8");
30190
+ console.log(` [\u521B\u5EFA] ~/.duclaw/cron/jobs.json`);
30191
+ }
30192
+ console.log(`
30193
+ \u521D\u59CB\u5316\u5B8C\u6210\uFF01\u63A5\u4E0B\u6765\uFF1A`);
30194
+ console.log(` 1. \u7F16\u8F91 ${configPath} \u914D\u7F6E\u4F60\u7684 Channel\uFF08\u5982\u98DE\u4E66 appId/appSecret\uFF09`);
30195
+ console.log(` 2. \u7F16\u8F91 ${envPath} \u914D\u7F6E Anthropic \u517C\u5BB9\u7684 LLM API\uFF1A`);
30196
+ console.log(` - ANTHROPIC_BASE_URL \uFF08API \u5730\u5740\uFF09`);
30197
+ console.log(` - ANTHROPIC_AUTH_TOKEN \uFF08API Key\uFF09`);
30198
+ console.log(` - ANTHROPIC_MODEL \uFF08\u6A21\u578B\u540D\u79F0\uFF09`);
30199
+ console.log(` - REDIS_URL \uFF08Redis \u8FDE\u63A5\u5730\u5740\uFF09`);
30200
+ console.log(` 3. \u8FD0\u884C duclaw-cli start \u542F\u52A8\u670D\u52A1
30201
+ `);
30202
+ return 0;
30203
+ }
30204
+ function handleStart() {
30205
+ return void 0;
30206
+ }
30207
+ function checkAndGuideInit() {
30208
+ const cwd = process.cwd();
30209
+ const configPath = (0, import_path.resolve)(cwd, "duclaw.json");
30210
+ if (!(0, import_fs.existsSync)(configPath)) {
30211
+ console.log(`
30212
+ \u672A\u627E\u5230 duclaw.json \u914D\u7F6E\u6587\u4EF6\u3002`);
30213
+ console.log(`
30214
+ \u8BF7\u5148\u8FD0\u884C\u521D\u59CB\u5316\u547D\u4EE4\uFF1A`);
30215
+ console.log(` duclaw-cli init
30216
+ `);
30217
+ return 1;
30218
+ }
30219
+ return void 0;
30220
+ }
30221
+ function printHelp() {
30222
+ console.log(`
30223
+ duclaw-cli - AI Agent \u7BA1\u7406\u6846\u67B6
30224
+
30225
+ \u547D\u4EE4:
30226
+ init [\u76EE\u5F55] \u521D\u59CB\u5316\u9879\u76EE\uFF08\u751F\u6210 duclaw.json \u548C .env \u6A21\u677F\uFF09
30227
+ start \u542F\u52A8\u670D\u52A1\uFF08\u9ED8\u8BA4\u547D\u4EE4\uFF09
30228
+ --help, -h \u663E\u793A\u5E2E\u52A9
30229
+ --version, -v \u663E\u793A\u7248\u672C
30230
+
30231
+ \u4F7F\u7528\u793A\u4F8B:
30232
+ duclaw-cli init # \u5728\u5F53\u524D\u76EE\u5F55\u521D\u59CB\u5316
30233
+ duclaw-cli init ./my-agent # \u5728\u6307\u5B9A\u76EE\u5F55\u521D\u59CB\u5316
30234
+ duclaw-cli start # \u542F\u52A8\u670D\u52A1
30235
+ duclaw-cli # \u7B49\u540C\u4E8E start
30236
+
30237
+ \u5FEB\u901F\u5F00\u59CB:
30238
+ 1. duclaw-cli init
30239
+ 2. \u7F16\u8F91 duclaw.json \u914D\u7F6E Channel
30240
+ 3. \u7F16\u8F91 .env \u914D\u7F6E Anthropic API Key \u548C Redis
30241
+ 4. duclaw-cli start
30242
+ `);
30243
+ }
30244
+ function printVersion() {
30245
+ console.log(`duclaw-cli v${true ? "1.4.0" : "unknown"}`);
30246
+ }
30247
+ function getDuclawTemplate() {
30248
+ return {
30249
+ channels: {
30250
+ feishu: {
30251
+ enabled: false,
30252
+ appId: "YOUR_FEISHU_APP_ID",
30253
+ appSecret: "YOUR_FEISHU_APP_SECRET"
30254
+ }
30255
+ }
30256
+ };
30257
+ }
30258
+ function getEnvTemplate() {
30259
+ return `# ====== LLM \u914D\u7F6E\uFF08\u5FC5\u586B\uFF09======
30260
+ # Anthropic \u517C\u5BB9\u7684 API \u914D\u7F6E
30261
+ export ANTHROPIC_BASE_URL="https://api.anthropic.com"
30262
+ export ANTHROPIC_AUTH_TOKEN="your-api-key-here"
30263
+ export ANTHROPIC_MODEL="claude-sonnet-4-20250514"
30264
+ # \u5982\u679C API \u4F7F\u7528 Bearer Token \u98CE\u683C\uFF0C\u53D6\u6D88\u4E0B\u9762\u7684\u6CE8\u91CA
30265
+ # export ANTHROPIC_AUTH_STYLE="bearer"
30266
+
30267
+ # ====== Redis \u914D\u7F6E\uFF08\u5FC5\u586B\uFF09======
30268
+ export REDIS_URL="redis://localhost:6379"
30269
+
30270
+ # ====== \u963F\u91CC\u4E91 OSS \u914D\u7F6E\uFF08\u6309\u9700\u586B\u5199\uFF0C\u7528\u4E8E\u6587\u4EF6\u5B58\u50A8\uFF09======
30271
+ # export OSS_ENDPOINT="oss-cn-shenzhen"
30272
+ # export OSS_BUCKET="your-bucket-name"
30273
+ # export OSS_ACCESS_KEY_ID="your-access-key-id"
30274
+ # export OSS_ACCESS_KEY_SECRET="your-access-key-secret"
30275
+
30276
+ # ====== \u8DEF\u5F84\u914D\u7F6E\uFF08\u9ED8\u8BA4 ~/.duclaw/\uFF0C\u901A\u5E38\u65E0\u9700\u4FEE\u6539\uFF09======
30277
+ # export JOB_PATH="~/.duclaw/cron/jobs.json"
30278
+ # export JOB_HISTORY_DIR="~/.duclaw/cron"
30279
+ # export APP_TEMP_DIR="~/.duclaw/data"
30280
+
30281
+ # ====== \u56FE\u7247\u7406\u89E3\u5DE5\u5177 LLM \u914D\u7F6E\uFF08\u6309\u9700\u586B\u5199\uFF09======
30282
+ # export TOOL_IMAGE_ANTHROPIC_AUTH_TOKEN="your-api-key"
30283
+ # export TOOL_IMAGE_ANTHROPIC_BASE_URL="https://api.anthropic.com"
30284
+ # export TOOL_IMAGE_ANTHROPIC_MODEL="claude-sonnet-4-20250514"
30285
+ `;
30286
+ }
30183
30287
 
30184
30288
  // src/config/LoadEnv.ts
30185
30289
  var import_dotenv = __toESM(require_main());
30186
- var import_fs = require("fs");
30187
- var import_path = require("path");
30290
+ var import_fs2 = require("fs");
30291
+ var import_path2 = require("path");
30188
30292
  var loadEnv = () => {
30189
30293
  const nodeEnv = process.env.NODE_ENV || "development";
30190
30294
  const isProd = nodeEnv === "production";
@@ -30197,7 +30301,7 @@ var loadEnv = () => {
30197
30301
  // 环境特定(如 .env.development)
30198
30302
  `.env.${nodeEnv}.local`
30199
30303
  // 本地环境特定(最高优先级)
30200
- ].map((file) => (0, import_path.resolve)(process.cwd(), file)).filter((file) => (0, import_fs.existsSync)(file));
30304
+ ].map((file) => (0, import_path2.resolve)(process.cwd(), file)).filter((file) => (0, import_fs2.existsSync)(file));
30201
30305
  if (isProd) {
30202
30306
  console.log("[loadEnv] Production: \u4F18\u5148\u4F7F\u7528\u7CFB\u7EDF\u73AF\u5883\u53D8\u91CF");
30203
30307
  envFiles.forEach((file) => {
@@ -30212,14 +30316,14 @@ var loadEnv = () => {
30212
30316
  };
30213
30317
 
30214
30318
  // src/config/LoadConfig.ts
30215
- var import_fs2 = require("fs");
30216
- var import_path2 = require("path");
30217
- var loadConfig = (filename = "agent-template.json", currentDir = __dirname_m) => {
30218
- const filePath = (0, import_path2.join)(currentDir, filename);
30219
- if ((0, import_fs2.existsSync)(filePath)) {
30220
- return JSON.parse((0, import_fs2.readFileSync)(filePath, "utf8"));
30319
+ var import_fs3 = require("fs");
30320
+ var import_path3 = require("path");
30321
+ var loadConfig = (filename = "duclaw.json", currentDir = process.cwd()) => {
30322
+ const filePath = (0, import_path3.join)(currentDir, filename);
30323
+ if ((0, import_fs3.existsSync)(filePath)) {
30324
+ return JSON.parse((0, import_fs3.readFileSync)(filePath, "utf8"));
30221
30325
  }
30222
- const parentDir = (0, import_path2.dirname)(currentDir);
30326
+ const parentDir = (0, import_path3.dirname)(currentDir);
30223
30327
  if (parentDir === currentDir) {
30224
30328
  throw new Error(`Config file "${filename}" not found`);
30225
30329
  }
@@ -30506,7 +30610,7 @@ var safeJSON = (text2) => {
30506
30610
  };
30507
30611
 
30508
30612
  // node_modules/.pnpm/@anthropic-ai+sdk@0.78.0_zod@4.3.6/node_modules/@anthropic-ai/sdk/internal/utils/sleep.mjs
30509
- var sleep = (ms) => new Promise((resolve10) => setTimeout(resolve10, ms));
30613
+ var sleep = (ms) => new Promise((resolve11) => setTimeout(resolve11, ms));
30510
30614
 
30511
30615
  // node_modules/.pnpm/@anthropic-ai+sdk@0.78.0_zod@4.3.6/node_modules/@anthropic-ai/sdk/version.mjs
30512
30616
  var VERSION = "0.78.0";
@@ -31205,8 +31309,8 @@ function addRequestID(value, response) {
31205
31309
  var _APIPromise_client;
31206
31310
  var APIPromise = class _APIPromise extends Promise {
31207
31311
  constructor(client2, responsePromise, parseResponse = defaultParseResponse) {
31208
- super((resolve10) => {
31209
- resolve10(null);
31312
+ super((resolve11) => {
31313
+ resolve11(null);
31210
31314
  });
31211
31315
  this.responsePromise = responsePromise;
31212
31316
  this.parseResponse = parseResponse;
@@ -32243,12 +32347,12 @@ var BetaMessageStream = class _BetaMessageStream {
32243
32347
  }
32244
32348
  return this._emit("error", new AnthropicError(String(error)));
32245
32349
  });
32246
- __classPrivateFieldSet(this, _BetaMessageStream_connectedPromise, new Promise((resolve10, reject) => {
32247
- __classPrivateFieldSet(this, _BetaMessageStream_resolveConnectedPromise, resolve10, "f");
32350
+ __classPrivateFieldSet(this, _BetaMessageStream_connectedPromise, new Promise((resolve11, reject) => {
32351
+ __classPrivateFieldSet(this, _BetaMessageStream_resolveConnectedPromise, resolve11, "f");
32248
32352
  __classPrivateFieldSet(this, _BetaMessageStream_rejectConnectedPromise, reject, "f");
32249
32353
  }), "f");
32250
- __classPrivateFieldSet(this, _BetaMessageStream_endPromise, new Promise((resolve10, reject) => {
32251
- __classPrivateFieldSet(this, _BetaMessageStream_resolveEndPromise, resolve10, "f");
32354
+ __classPrivateFieldSet(this, _BetaMessageStream_endPromise, new Promise((resolve11, reject) => {
32355
+ __classPrivateFieldSet(this, _BetaMessageStream_resolveEndPromise, resolve11, "f");
32252
32356
  __classPrivateFieldSet(this, _BetaMessageStream_rejectEndPromise, reject, "f");
32253
32357
  }), "f");
32254
32358
  __classPrivateFieldGet(this, _BetaMessageStream_connectedPromise, "f").catch(() => {
@@ -32418,11 +32522,11 @@ var BetaMessageStream = class _BetaMessageStream {
32418
32522
  * const message = await stream.emitted('message') // rejects if the stream errors
32419
32523
  */
32420
32524
  emitted(event) {
32421
- return new Promise((resolve10, reject) => {
32525
+ return new Promise((resolve11, reject) => {
32422
32526
  __classPrivateFieldSet(this, _BetaMessageStream_catchingPromiseCreated, true, "f");
32423
32527
  if (event !== "error")
32424
32528
  this.once("error", reject);
32425
- this.once(event, resolve10);
32529
+ this.once(event, resolve11);
32426
32530
  });
32427
32531
  }
32428
32532
  async done() {
@@ -32765,7 +32869,7 @@ var BetaMessageStream = class _BetaMessageStream {
32765
32869
  if (done) {
32766
32870
  return { value: void 0, done: true };
32767
32871
  }
32768
- return new Promise((resolve10, reject) => readQueue.push({ resolve: resolve10, reject })).then((chunk2) => chunk2 ? { value: chunk2, done: false } : { value: void 0, done: true });
32872
+ return new Promise((resolve11, reject) => readQueue.push({ resolve: resolve11, reject })).then((chunk2) => chunk2 ? { value: chunk2, done: false } : { value: void 0, done: true });
32769
32873
  }
32770
32874
  const chunk = pushQueue.shift();
32771
32875
  return { value: chunk, done: false };
@@ -32837,13 +32941,13 @@ var _BetaToolRunner_iterationCount;
32837
32941
  var _BetaToolRunner_checkAndCompact;
32838
32942
  var _BetaToolRunner_generateToolResponse;
32839
32943
  function promiseWithResolvers() {
32840
- let resolve10;
32944
+ let resolve11;
32841
32945
  let reject;
32842
32946
  const promise = new Promise((res, rej) => {
32843
- resolve10 = res;
32947
+ resolve11 = res;
32844
32948
  reject = rej;
32845
32949
  });
32846
- return { promise, resolve: resolve10, reject };
32950
+ return { promise, resolve: resolve11, reject };
32847
32951
  }
32848
32952
  var BetaToolRunner = class {
32849
32953
  constructor(client2, params, options) {
@@ -33861,12 +33965,12 @@ var MessageStream = class _MessageStream {
33861
33965
  }
33862
33966
  return this._emit("error", new AnthropicError(String(error)));
33863
33967
  });
33864
- __classPrivateFieldSet(this, _MessageStream_connectedPromise, new Promise((resolve10, reject) => {
33865
- __classPrivateFieldSet(this, _MessageStream_resolveConnectedPromise, resolve10, "f");
33968
+ __classPrivateFieldSet(this, _MessageStream_connectedPromise, new Promise((resolve11, reject) => {
33969
+ __classPrivateFieldSet(this, _MessageStream_resolveConnectedPromise, resolve11, "f");
33866
33970
  __classPrivateFieldSet(this, _MessageStream_rejectConnectedPromise, reject, "f");
33867
33971
  }), "f");
33868
- __classPrivateFieldSet(this, _MessageStream_endPromise, new Promise((resolve10, reject) => {
33869
- __classPrivateFieldSet(this, _MessageStream_resolveEndPromise, resolve10, "f");
33972
+ __classPrivateFieldSet(this, _MessageStream_endPromise, new Promise((resolve11, reject) => {
33973
+ __classPrivateFieldSet(this, _MessageStream_resolveEndPromise, resolve11, "f");
33870
33974
  __classPrivateFieldSet(this, _MessageStream_rejectEndPromise, reject, "f");
33871
33975
  }), "f");
33872
33976
  __classPrivateFieldGet(this, _MessageStream_connectedPromise, "f").catch(() => {
@@ -34036,11 +34140,11 @@ var MessageStream = class _MessageStream {
34036
34140
  * const message = await stream.emitted('message') // rejects if the stream errors
34037
34141
  */
34038
34142
  emitted(event) {
34039
- return new Promise((resolve10, reject) => {
34143
+ return new Promise((resolve11, reject) => {
34040
34144
  __classPrivateFieldSet(this, _MessageStream_catchingPromiseCreated, true, "f");
34041
34145
  if (event !== "error")
34042
34146
  this.once("error", reject);
34043
- this.once(event, resolve10);
34147
+ this.once(event, resolve11);
34044
34148
  });
34045
34149
  }
34046
34150
  async done() {
@@ -34358,7 +34462,7 @@ var MessageStream = class _MessageStream {
34358
34462
  if (done) {
34359
34463
  return { value: void 0, done: true };
34360
34464
  }
34361
- return new Promise((resolve10, reject) => readQueue.push({ resolve: resolve10, reject })).then((chunk2) => chunk2 ? { value: chunk2, done: false } : { value: void 0, done: true });
34465
+ return new Promise((resolve11, reject) => readQueue.push({ resolve: resolve11, reject })).then((chunk2) => chunk2 ? { value: chunk2, done: false } : { value: void 0, done: true });
34362
34466
  }
34363
34467
  const chunk = pushQueue.shift();
34364
34468
  return { value: chunk, done: false };
@@ -35531,15 +35635,15 @@ var dateTool = {
35531
35635
  var import_dayjs = __toESM(require_dayjs_min());
35532
35636
  var import_utc = __toESM(require_utc());
35533
35637
  var import_timezone = __toESM(require_timezone());
35534
- var import_fs3 = require("fs");
35535
- var import_path10 = __toESM(require("path"));
35638
+ var import_fs4 = require("fs");
35639
+ var import_path11 = __toESM(require("path"));
35536
35640
  import_dayjs.default.extend(import_utc.default);
35537
35641
  import_dayjs.default.extend(import_timezone.default);
35538
35642
  var getGoalDir = () => {
35539
- return import_path10.default.join(process.cwd(), ".tasks");
35643
+ return import_path11.default.join(process.cwd(), ".tasks");
35540
35644
  };
35541
35645
  var getGoalPath = (goalId) => {
35542
- return import_path10.default.join(getGoalDir(), `${goalId}.json`);
35646
+ return import_path11.default.join(getGoalDir(), `${goalId}.json`);
35543
35647
  };
35544
35648
  var createGoal = (subject, description) => {
35545
35649
  const goalId = generateId(subject);
@@ -35552,7 +35656,7 @@ var createGoal = (subject, description) => {
35552
35656
  createdAt: (0, import_dayjs.default)().tz("Asia/Shanghai").format("YYYY-MM-DD HH:mm:ss"),
35553
35657
  updateAt: (0, import_dayjs.default)().tz("Asia/Shanghai").format("YYYY-MM-DD HH:mm:ss")
35554
35658
  };
35555
- (0, import_fs3.writeFileSync)(`${getGoalPath(goalId)}`, JSON.stringify(goal, null, ` `), `utf-8`);
35659
+ (0, import_fs4.writeFileSync)(`${getGoalPath(goalId)}`, JSON.stringify(goal, null, ` `), `utf-8`);
35556
35660
  return goal;
35557
35661
  };
35558
35662
  var getGoalById = (id) => {
@@ -35567,11 +35671,11 @@ var getGoalBySubject = (subject) => {
35567
35671
  };
35568
35672
  var listGoal = () => {
35569
35673
  const goalDir = getGoalDir();
35570
- const files = (0, import_fs3.readdirSync)(goalDir);
35674
+ const files = (0, import_fs4.readdirSync)(goalDir);
35571
35675
  let goals = [];
35572
35676
  for (let file of files) {
35573
35677
  if (file.endsWith(`.json`)) {
35574
- const text2 = (0, import_fs3.readFileSync)(import_path10.default.join(goalDir, file), `utf-8`);
35678
+ const text2 = (0, import_fs4.readFileSync)(import_path11.default.join(goalDir, file), `utf-8`);
35575
35679
  const goal = JSON.parse(text2);
35576
35680
  goals.push(goal);
35577
35681
  }
@@ -35586,13 +35690,13 @@ var updateGoal = (id, goal) => {
35586
35690
  id
35587
35691
  // 确保 id 不被覆盖
35588
35692
  };
35589
- (0, import_fs3.writeFileSync)(getGoalPath(id), JSON.stringify(merged, null, " "), "utf-8");
35693
+ (0, import_fs4.writeFileSync)(getGoalPath(id), JSON.stringify(merged, null, " "), "utf-8");
35590
35694
  return { ...merged };
35591
35695
  };
35592
35696
  var deleteGoal = (id) => {
35593
35697
  const goalPath = getGoalPath(id);
35594
- if (!(0, import_fs3.existsSync)(goalPath)) return false;
35595
- (0, import_fs3.unlinkSync)(goalPath);
35698
+ if (!(0, import_fs4.existsSync)(goalPath)) return false;
35699
+ (0, import_fs4.unlinkSync)(goalPath);
35596
35700
  return true;
35597
35701
  };
35598
35702
  var generateId = (subject) => {
@@ -37572,29 +37676,29 @@ var sendMessage = {
37572
37676
  };
37573
37677
 
37574
37678
  // src/cron/jobs.ts
37575
- var import_fs4 = require("fs");
37679
+ var import_fs5 = require("fs");
37576
37680
  var import_crypto3 = require("crypto");
37577
- var import_path11 = __toESM(require("path"));
37681
+ var import_path12 = __toESM(require("path"));
37682
+ var import_os2 = require("os");
37683
+ var DUCLAW_HOME2 = import_path12.default.join((0, import_os2.homedir)(), ".duclaw");
37578
37684
  var getJobPath = () => {
37579
- return process.env.JOB_PATH || `/Users/duzicong/code/duzicong/agent-template-ts/.claude/cron/jobs.json`;
37685
+ return process.env.JOB_PATH || import_path12.default.join(DUCLAW_HOME2, "cron", "jobs.json");
37580
37686
  };
37581
37687
  var getJobHistoryPath = (date, title) => {
37582
- if (process.env.JOB_HISTORY_DIR) {
37583
- return import_path11.default.join(process.env.JOB_HISTORY_DIR, date, title);
37584
- }
37585
- return `/Users/duzicong/code/duzicong/agent-template-ts/cron/${date}/${title}`;
37688
+ const historyDir = process.env.JOB_HISTORY_DIR || import_path12.default.join(DUCLAW_HOME2, "cron");
37689
+ return import_path12.default.join(historyDir, date, title);
37586
37690
  };
37587
37691
  var createJob = (title, description, syntax, userRequest) => {
37588
37692
  const jsonsPath = getJobPath();
37589
- if (!(0, import_fs4.existsSync)(jsonsPath)) {
37693
+ if (!(0, import_fs5.existsSync)(jsonsPath)) {
37590
37694
  const content = `{
37591
37695
  "jobs": [
37592
37696
 
37593
37697
  ]
37594
37698
  }`;
37595
- (0, import_fs4.writeFileSync)(jsonsPath, content, `utf-8`);
37699
+ (0, import_fs5.writeFileSync)(jsonsPath, content, `utf-8`);
37596
37700
  }
37597
- const text2 = (0, import_fs4.readFileSync)(getJobPath(), `utf-8`);
37701
+ const text2 = (0, import_fs5.readFileSync)(getJobPath(), `utf-8`);
37598
37702
  const obj = JSON.parse(text2);
37599
37703
  let jobs = obj.jobs || [];
37600
37704
  const createJob2 = {
@@ -37615,7 +37719,7 @@ var createJob = (title, description, syntax, userRequest) => {
37615
37719
  ...jobs,
37616
37720
  createJob2
37617
37721
  ];
37618
- (0, import_fs4.writeFileSync)(getJobPath(), JSON.stringify({ jobs }, null, " "), `utf-8`);
37722
+ (0, import_fs5.writeFileSync)(getJobPath(), JSON.stringify({ jobs }, null, " "), `utf-8`);
37619
37723
  return { ...createJob2 };
37620
37724
  };
37621
37725
  var updateJob = (id, syntax, title, description) => {
@@ -37627,11 +37731,15 @@ var updateJob = (id, syntax, title, description) => {
37627
37731
  job.schedule.syntax = syntax;
37628
37732
  job.title = title;
37629
37733
  job.description = description;
37630
- (0, import_fs4.writeFileSync)(getJobPath(), JSON.stringify(jobs, null, " "));
37734
+ (0, import_fs5.writeFileSync)(getJobPath(), JSON.stringify(jobs, null, " "));
37631
37735
  return { ...job };
37632
37736
  };
37633
37737
  var listJobs = () => {
37634
- const text2 = (0, import_fs4.readFileSync)(getJobPath(), `utf-8`);
37738
+ const jobPath = getJobPath();
37739
+ if (!(0, import_fs5.existsSync)(jobPath)) {
37740
+ return [];
37741
+ }
37742
+ const text2 = (0, import_fs5.readFileSync)(jobPath, `utf-8`);
37635
37743
  if (!text2) {
37636
37744
  return [];
37637
37745
  }
@@ -37641,7 +37749,7 @@ var listJobs = () => {
37641
37749
  };
37642
37750
  var deleteJob = (id, title) => {
37643
37751
  const jobPath = getJobPath();
37644
- const text2 = (0, import_fs4.readFileSync)(jobPath, `utf-8`);
37752
+ const text2 = (0, import_fs5.readFileSync)(jobPath, `utf-8`);
37645
37753
  const obj = JSON.parse(text2);
37646
37754
  let jobs = obj.jobs || [];
37647
37755
  let isJobExist = false;
@@ -37663,7 +37771,7 @@ var deleteJob = (id, title) => {
37663
37771
  ;
37664
37772
  jobs = jobs.filter((j) => j.title !== title);
37665
37773
  }
37666
- (0, import_fs4.writeFileSync)(jobPath, JSON.stringify({ jobs }, null, " "), `utf-8`);
37774
+ (0, import_fs5.writeFileSync)(jobPath, JSON.stringify({ jobs }, null, " "), `utf-8`);
37667
37775
  if (targetJob) {
37668
37776
  return { ...targetJob };
37669
37777
  }
@@ -37681,7 +37789,7 @@ var getJobExecuteHistory = (id, title) => {
37681
37789
  const lastRunTime = "2026-03-17T21:00:28";
37682
37790
  const dateStr = lastRunTime.split("T")[0];
37683
37791
  const historyFilePath = getJobHistoryPath(dateStr, findJob.title);
37684
- const text2 = (0, import_fs4.readFileSync)(historyFilePath, `utf-8`);
37792
+ const text2 = (0, import_fs5.readFileSync)(historyFilePath, `utf-8`);
37685
37793
  const list = JSON.parse(text2) || [];
37686
37794
  console.log(`[jobs] \u83B7\u53D6\u5B9A\u65F6\u4EFB\u52A1\u7684\u5386\u53F2\u6267\u884C\u6D88\u606F\uFF0C\u5F53\u524D\u6267\u884C\u5386\u53F2\u5728 ${historyFilePath}`);
37687
37795
  return list;
@@ -37767,7 +37875,7 @@ var cronDelete = {
37767
37875
  };
37768
37876
 
37769
37877
  // src/cron/cron.ts
37770
- var import_fs5 = require("fs");
37878
+ var import_fs6 = require("fs");
37771
37879
 
37772
37880
  // node_modules/.pnpm/chokidar@5.0.0/node_modules/chokidar/index.js
37773
37881
  var import_node_events = require("node:events");
@@ -38640,7 +38748,7 @@ var NodeFsHandler = class {
38640
38748
  this._addToNodeFs(path9, initialAdd, wh, depth + 1);
38641
38749
  }
38642
38750
  }).on(EV.ERROR, this._boundHandleError);
38643
- return new Promise((resolve10, reject) => {
38751
+ return new Promise((resolve11, reject) => {
38644
38752
  if (!stream)
38645
38753
  return reject();
38646
38754
  stream.once(STR_END, () => {
@@ -38649,7 +38757,7 @@ var NodeFsHandler = class {
38649
38757
  return;
38650
38758
  }
38651
38759
  const wasThrottled = throttler ? throttler.clear() : false;
38652
- resolve10(void 0);
38760
+ resolve11(void 0);
38653
38761
  previous.getChildren().filter((item) => {
38654
38762
  return item !== directory && !current.has(item);
38655
38763
  }).forEach((item) => {
@@ -39590,14 +39698,14 @@ var loadAndScheduleJobs = () => {
39590
39698
  console.log(`[cron] \u5F53\u524D\u5171 ${scheduledTasks.size} \u4E2A\u6D3B\u8DC3\u4EFB\u52A1`);
39591
39699
  };
39592
39700
  var updateJobLastRunTime = (jobId) => {
39593
- const text2 = (0, import_fs5.readFileSync)(getJobPath(), `utf-8`);
39701
+ const text2 = (0, import_fs6.readFileSync)(getJobPath(), `utf-8`);
39594
39702
  const obj = JSON.parse(text2);
39595
39703
  const jobs = obj.jobs || [];
39596
39704
  const job = jobs.find((j) => j.id === jobId);
39597
39705
  if (job) {
39598
39706
  job.schedule.lastRunTime = (/* @__PURE__ */ new Date()).toLocaleString("sv-SE", { timeZone: "Asia/Shanghai" }).replace(" ", "T");
39599
39707
  suppressWatch = true;
39600
- (0, import_fs5.writeFileSync)(getJobPath(), JSON.stringify({ jobs }, null, " "), `utf-8`);
39708
+ (0, import_fs6.writeFileSync)(getJobPath(), JSON.stringify({ jobs }, null, " "), `utf-8`);
39601
39709
  }
39602
39710
  };
39603
39711
  var getCronTools = () => {
@@ -39707,6 +39815,14 @@ var executeCustomJob = async (job) => {
39707
39815
  return await handler(job);
39708
39816
  };
39709
39817
  var startScheduler = () => {
39818
+ const jobPath = getJobPath();
39819
+ const jobDir = require("path").dirname(jobPath);
39820
+ if (!(0, import_fs6.existsSync)(jobDir)) {
39821
+ (0, import_fs6.mkdirSync)(jobDir, { recursive: true });
39822
+ }
39823
+ if (!(0, import_fs6.existsSync)(jobPath)) {
39824
+ (0, import_fs6.writeFileSync)(jobPath, JSON.stringify({ jobs: [] }, null, " "), "utf-8");
39825
+ }
39710
39826
  loadAndScheduleJobs();
39711
39827
  watchJobsFile();
39712
39828
  };
@@ -39722,13 +39838,13 @@ var saveResultToFile = (job, cronResp) => {
39722
39838
  const safeTitle = sanitizeTitle(job.title);
39723
39839
  const dirPath = `./cron/${yyyyMMdd}/${safeTitle}`;
39724
39840
  const filePath = `${dirPath}/history.json`;
39725
- if (!(0, import_fs5.existsSync)(dirPath)) {
39726
- (0, import_fs5.mkdirSync)(dirPath, { recursive: true });
39841
+ if (!(0, import_fs6.existsSync)(dirPath)) {
39842
+ (0, import_fs6.mkdirSync)(dirPath, { recursive: true });
39727
39843
  }
39728
39844
  let history = [];
39729
- if ((0, import_fs5.existsSync)(filePath)) {
39845
+ if ((0, import_fs6.existsSync)(filePath)) {
39730
39846
  try {
39731
- const content = (0, import_fs5.readFileSync)(filePath, "utf-8");
39847
+ const content = (0, import_fs6.readFileSync)(filePath, "utf-8");
39732
39848
  history = JSON.parse(content);
39733
39849
  } catch {
39734
39850
  history = [];
@@ -39738,7 +39854,7 @@ var saveResultToFile = (job, cronResp) => {
39738
39854
  timestamp: now.toLocaleString("sv-SE", { timeZone: "Asia/Shanghai" }).replace(" ", "T"),
39739
39855
  result: cronResp
39740
39856
  });
39741
- (0, import_fs5.writeFileSync)(filePath, JSON.stringify(history, null, " "), "utf-8");
39857
+ (0, import_fs6.writeFileSync)(filePath, JSON.stringify(history, null, " "), "utf-8");
39742
39858
  return filePath;
39743
39859
  };
39744
39860
 
@@ -39850,8 +39966,8 @@ var cronUpdate = {
39850
39966
  };
39851
39967
 
39852
39968
  // src/tools/tools/ImageUnderstand.ts
39853
- var import_fs6 = __toESM(require("fs"));
39854
- var import_path12 = __toESM(require("path"));
39969
+ var import_fs7 = __toESM(require("fs"));
39970
+ var import_path13 = __toESM(require("path"));
39855
39971
 
39856
39972
  // src/types/builders.ts
39857
39973
  var text = (text2) => ({
@@ -39906,7 +40022,7 @@ var guessMediaTypeFromHeader = (contentType) => {
39906
40022
  return null;
39907
40023
  };
39908
40024
  var guessMediaTypeFromExt = (filePath) => {
39909
- const ext = import_path12.default.extname(filePath).toLowerCase();
40025
+ const ext = import_path13.default.extname(filePath).toLowerCase();
39910
40026
  if (ext === ".jpg" || ext === ".jpeg") return "image/jpeg";
39911
40027
  if (ext === ".png") return "image/png";
39912
40028
  if (ext === ".gif") return "image/gif";
@@ -39926,9 +40042,9 @@ var resolveImageBlock = async (input) => {
39926
40042
  return imageBase64(base64Data, mediaType2);
39927
40043
  }
39928
40044
  if (input.startsWith("/") || input.startsWith(".") || /^[A-Za-z]:[\\/]/.test(input)) {
39929
- if (!import_fs6.default.existsSync(input)) throw new Error(`[ImageUnderstand] \u672C\u5730\u6587\u4EF6\u4E0D\u5B58\u5728: ${input}`);
40045
+ if (!import_fs7.default.existsSync(input)) throw new Error(`[ImageUnderstand] \u672C\u5730\u6587\u4EF6\u4E0D\u5B58\u5728: ${input}`);
39930
40046
  console.log(`[ImageUnderstand] \u8BFB\u53D6\u672C\u5730\u6587\u4EF6: ${input}`);
39931
- const buffer = import_fs6.default.readFileSync(input);
40047
+ const buffer = import_fs7.default.readFileSync(input);
39932
40048
  const base64Data = buffer.toString("base64");
39933
40049
  const mediaType2 = guessMediaTypeFromExt(input) ?? guessMediaTypeFromData(base64Data) ?? "image/png";
39934
40050
  console.log(`[ImageUnderstand] \u63A8\u65AD\u5A92\u4F53\u7C7B\u578B: ${mediaType2}`);
@@ -39986,45 +40102,44 @@ var imageUnderstand = {
39986
40102
  };
39987
40103
 
39988
40104
  // src/skill/SkillRegistry.ts
39989
- var import_fs7 = require("fs");
39990
- var import_os = require("os");
39991
- var import_path13 = __toESM(require("path"));
40105
+ var import_fs8 = require("fs");
40106
+ var import_os3 = require("os");
40107
+ var import_path14 = __toESM(require("path"));
39992
40108
  var getSkillPaths = () => {
39993
40109
  const paths = [];
39994
40110
  let currentDir = __dirname_m;
39995
40111
  let projectRoot = "";
39996
40112
  while (currentDir !== "/") {
39997
- const claudePath = (0, import_path13.join)(currentDir, ".claude");
39998
- if ((0, import_fs7.existsSync)(claudePath) && (0, import_fs7.statSync)(claudePath).isDirectory()) {
40113
+ if ((0, import_fs8.existsSync)((0, import_path14.join)(currentDir, "duclaw.json"))) {
39999
40114
  projectRoot = currentDir;
40000
- const skillsPath = (0, import_path13.join)(claudePath, "skills");
40001
- if ((0, import_fs7.existsSync)(skillsPath)) {
40002
- paths.push(skillsPath);
40003
- }
40004
40115
  break;
40005
40116
  }
40006
- const parentDir = (0, import_path13.dirname)(currentDir);
40117
+ const parentDir = (0, import_path14.dirname)(currentDir);
40007
40118
  if (parentDir === currentDir) break;
40008
40119
  currentDir = parentDir;
40009
40120
  }
40010
40121
  if (projectRoot) {
40011
- const rootSkillsPath = (0, import_path13.join)(projectRoot, "skills");
40012
- if ((0, import_fs7.existsSync)(rootSkillsPath) && (0, import_fs7.statSync)(rootSkillsPath).isDirectory()) {
40122
+ const rootSkillsPath = (0, import_path14.join)(projectRoot, "skills");
40123
+ if ((0, import_fs8.existsSync)(rootSkillsPath) && (0, import_fs8.statSync)(rootSkillsPath).isDirectory()) {
40013
40124
  paths.push(rootSkillsPath);
40014
40125
  }
40015
40126
  }
40016
- const globalSkillsPath = (0, import_path13.join)((0, import_os.homedir)(), ".agents", "skills");
40017
- if ((0, import_fs7.existsSync)(globalSkillsPath) && (0, import_fs7.statSync)(globalSkillsPath).isDirectory()) {
40018
- paths.push(globalSkillsPath);
40127
+ const duclawSkillsPath = (0, import_path14.join)((0, import_os3.homedir)(), ".duclaw", "skills");
40128
+ if ((0, import_fs8.existsSync)(duclawSkillsPath) && (0, import_fs8.statSync)(duclawSkillsPath).isDirectory()) {
40129
+ paths.push(duclawSkillsPath);
40130
+ }
40131
+ const agentsSkillsPath = (0, import_path14.join)((0, import_os3.homedir)(), ".agents", "skills");
40132
+ if ((0, import_fs8.existsSync)(agentsSkillsPath) && (0, import_fs8.statSync)(agentsSkillsPath).isDirectory()) {
40133
+ paths.push(agentsSkillsPath);
40019
40134
  }
40020
40135
  return paths;
40021
40136
  };
40022
40137
  var getDirectories = (dirPath) => {
40023
- return (0, import_fs7.readdirSync)(dirPath).filter((name) => (0, import_fs7.statSync)((0, import_path13.join)(dirPath, name)).isDirectory());
40138
+ return (0, import_fs8.readdirSync)(dirPath).filter((name) => (0, import_fs8.statSync)((0, import_path14.join)(dirPath, name)).isDirectory());
40024
40139
  };
40025
40140
  var parseSkill = (mdPath, skillDir) => {
40026
- if (!(0, import_fs7.existsSync)(mdPath)) return null;
40027
- const raw2 = (0, import_fs7.readFileSync)(mdPath, "utf-8");
40141
+ if (!(0, import_fs8.existsSync)(mdPath)) return null;
40142
+ const raw2 = (0, import_fs8.readFileSync)(mdPath, "utf-8");
40028
40143
  let name = "";
40029
40144
  let description = "";
40030
40145
  let body = raw2;
@@ -40040,7 +40155,7 @@ var parseSkill = (mdPath, skillDir) => {
40040
40155
  }
40041
40156
  }
40042
40157
  if (!name) {
40043
- name = import_path13.default.basename(import_path13.default.dirname(mdPath));
40158
+ name = import_path14.default.basename(import_path14.default.dirname(mdPath));
40044
40159
  }
40045
40160
  if (!description && body) {
40046
40161
  description = body.split("\n")[0].replace(/^#+\s*/, "").trim();
@@ -40065,8 +40180,8 @@ var loadSkill = () => {
40065
40180
  for (const skillPath of skillPaths) {
40066
40181
  const dirs = getDirectories(skillPath);
40067
40182
  for (const skillName of dirs) {
40068
- const eachSkillPath = (0, import_path13.join)(skillPath, skillName);
40069
- const eachSkillMdPath = (0, import_path13.join)(eachSkillPath, "SKILL.md");
40183
+ const eachSkillPath = (0, import_path14.join)(skillPath, skillName);
40184
+ const eachSkillMdPath = (0, import_path14.join)(eachSkillPath, "SKILL.md");
40070
40185
  const skill = parseSkill(eachSkillMdPath, eachSkillPath);
40071
40186
  if (skill && !seen.has(skill.name)) {
40072
40187
  seen.add(skill.name);
@@ -40418,12 +40533,12 @@ var create_mailbox_table = () => {
40418
40533
  };
40419
40534
 
40420
40535
  // src/team/TeamMember.ts
40421
- var import_fs9 = require("fs");
40422
- var import_path15 = __toESM(require("path"));
40536
+ var import_fs10 = require("fs");
40537
+ var import_path16 = __toESM(require("path"));
40423
40538
 
40424
40539
  // src/team/Team.ts
40425
- var import_path14 = __toESM(require("path"));
40426
- var import_fs8 = require("fs");
40540
+ var import_path15 = __toESM(require("path"));
40541
+ var import_fs9 = require("fs");
40427
40542
  var getTeamBaseDir = () => {
40428
40543
  return `~/.duclaw/team`;
40429
40544
  };
@@ -40436,22 +40551,22 @@ var getTeamJsonPath = (teamName) => {
40436
40551
  var createTeam = (teamDefinition) => {
40437
40552
  if (!teamDefinition) throw new Error(`[createTeam] teamDefinition\u4E0D\u80FD\u4E3A\u7A7A`);
40438
40553
  const { id, name, goalId, teamMembers } = teamDefinition;
40439
- const teamPath = import_path14.default.join(getTeamWorkSpaceDir(name));
40440
- (0, import_fs8.mkdirSync)(teamPath, { recursive: true });
40441
- (0, import_fs8.writeFileSync)(`${teamPath}/team.json`, JSON.stringify(teamDefinition, null, " "), "utf-8");
40554
+ const teamPath = import_path15.default.join(getTeamWorkSpaceDir(name));
40555
+ (0, import_fs9.mkdirSync)(teamPath, { recursive: true });
40556
+ (0, import_fs9.writeFileSync)(`${teamPath}/team.json`, JSON.stringify(teamDefinition, null, " "), "utf-8");
40442
40557
  return teamDefinition;
40443
40558
  };
40444
40559
  var getTeam = (name) => {
40445
40560
  const teamJsonPath = getTeamJsonPath(name);
40446
- if (!(0, import_fs8.existsSync)(teamJsonPath)) return null;
40447
- const text2 = (0, import_fs8.readFileSync)(teamJsonPath, `utf-8`);
40561
+ if (!(0, import_fs9.existsSync)(teamJsonPath)) return null;
40562
+ const text2 = (0, import_fs9.readFileSync)(teamJsonPath, `utf-8`);
40448
40563
  const obj = JSON.parse(text2) || {};
40449
40564
  const team = obj;
40450
40565
  return team;
40451
40566
  };
40452
40567
  var listTeams = () => {
40453
40568
  const baseDir = getTeamBaseDir();
40454
- const teamnames = (0, import_fs8.readdirSync)(import_path14.default.join(baseDir, `workspace`));
40569
+ const teamnames = (0, import_fs9.readdirSync)(import_path15.default.join(baseDir, `workspace`));
40455
40570
  const teams = [];
40456
40571
  for (const teamname of teamnames) {
40457
40572
  const team = getTeam(teamname);
@@ -40468,10 +40583,10 @@ var getTeamById = (id) => {
40468
40583
  return team;
40469
40584
  };
40470
40585
  var deleteTeam = (name) => {
40471
- if (!(0, import_fs8.existsSync)(getTeamJsonPath(name))) {
40586
+ if (!(0, import_fs9.existsSync)(getTeamJsonPath(name))) {
40472
40587
  throw new Error(`[deleteTeam] \u4E0D\u5B58\u5728\u5BF9\u5E94\u7684\u56E2\u961F${name}\u7684team.json\u6587\u4EF6`);
40473
40588
  }
40474
- (0, import_fs8.rmSync)(getTeamJsonPath(name));
40589
+ (0, import_fs9.rmSync)(getTeamJsonPath(name));
40475
40590
  };
40476
40591
 
40477
40592
  // src/team/workspace/workspace.ts
@@ -40499,8 +40614,8 @@ var createTeamMember = (teamMemberDefinition) => {
40499
40614
  const { id, name, teamId, mailBoxId, workspaceId } = teamMemberDefinition;
40500
40615
  const team = getTeamById(teamMemberDefinition.teamId);
40501
40616
  if (!team) throw new Error(`[createTeamMember] \u627E\u4E0D\u5230\u5BF9\u5E94\u7684team: ${teamId}`);
40502
- const memberPath = import_path15.default.join(getTeamWorkSpaceDir(team.name), name);
40503
- (0, import_fs9.mkdirSync)(memberPath, { recursive: true });
40617
+ const memberPath = import_path16.default.join(getTeamWorkSpaceDir(team.name), name);
40618
+ (0, import_fs10.mkdirSync)(memberPath, { recursive: true });
40504
40619
  const workspace = {
40505
40620
  id: getWorkspaceId(team.name, teamMemberDefinition.name),
40506
40621
  teamName: team.name,
@@ -40512,12 +40627,12 @@ var createTeamMember = (teamMemberDefinition) => {
40512
40627
  team.teamMembers = [];
40513
40628
  }
40514
40629
  team.teamMembers.push(teamMemberDefinition);
40515
- (0, import_fs9.writeFileSync)(getTeamJsonPath(team.name), JSON.stringify(team, null, " "), "utf-8");
40630
+ (0, import_fs10.writeFileSync)(getTeamJsonPath(team.name), JSON.stringify(team, null, " "), "utf-8");
40516
40631
  return teamMemberDefinition;
40517
40632
  };
40518
40633
  var listTeamMember = (teamName) => {
40519
40634
  const teamJsonPath = getTeamJsonPath(teamName);
40520
- const text2 = (0, import_fs9.readFileSync)(teamJsonPath, `utf-8`);
40635
+ const text2 = (0, import_fs10.readFileSync)(teamJsonPath, `utf-8`);
40521
40636
  const team = JSON.parse(text2);
40522
40637
  if (!team) throw new Error(`[listTeamMember] \u627E\u4E0D\u5230\u5BF9\u5E94\u7684team: ${teamName}`);
40523
40638
  if (!team.teamMembers) return [];
@@ -40552,7 +40667,7 @@ var deleteTeamMemberById = (teamName, memberId) => {
40552
40667
  const workspaceId = team.teamMembers[memberIdx].workspaceId;
40553
40668
  let newTeamMember = team.teamMembers.filter((_, index) => index !== memberIdx);
40554
40669
  team.teamMembers = newTeamMember;
40555
- (0, import_fs9.writeFileSync)(getTeamJsonPath(teamName), JSON.stringify(team, null, ` `));
40670
+ (0, import_fs10.writeFileSync)(getTeamJsonPath(teamName), JSON.stringify(team, null, ` `));
40556
40671
  deleteWorkspace(workspaceId);
40557
40672
  };
40558
40673
 
@@ -40952,7 +41067,7 @@ var bashTool = {
40952
41067
  if (rejection) return `[bash] ${rejection}`;
40953
41068
  }
40954
41069
  const cwd = explicitCwd || getEffectiveCwd(userRequest);
40955
- return new Promise((resolve10) => {
41070
+ return new Promise((resolve11) => {
40956
41071
  const options = {
40957
41072
  timeout,
40958
41073
  maxBuffer: 1024 * 1024,
@@ -40984,7 +41099,7 @@ ${trimmed}`;
40984
41099
  if (!output) {
40985
41100
  output = "[bash] \u547D\u4EE4\u6267\u884C\u6210\u529F\uFF08\u65E0\u8F93\u51FA\uFF09";
40986
41101
  }
40987
- resolve10(output);
41102
+ resolve11(output);
40988
41103
  });
40989
41104
  });
40990
41105
  }
@@ -41285,7 +41400,7 @@ ${getSkillMeta()}
41285
41400
  const anthropicOptions = {
41286
41401
  baseURL: process.env.ANTHROPIC_BASE_URL,
41287
41402
  model: process.env.ANTHROPIC_MODEL,
41288
- apiKey: process.env.ANTHROPIC_AUTH_TOKEN || "a4fd749ac2824c55a88946fc13a50e23.VPMAm8nUNaAWWS3E",
41403
+ apiKey: process.env.ANTHROPIC_AUTH_TOKEN,
41289
41404
  authStyle: process.env.ANTHROPIC_AUTH_STYLE || void 0
41290
41405
  };
41291
41406
  const llmClient = createAnthropicAdapter(anthropicOptions);
@@ -41592,10 +41707,10 @@ var downloadMessageResource = async (messageId, fileKey, type) => {
41592
41707
  throw error;
41593
41708
  }
41594
41709
  const readable = response.getReadableStream();
41595
- return new Promise((resolve10, reject) => {
41710
+ return new Promise((resolve11, reject) => {
41596
41711
  const chunks = [];
41597
41712
  readable.on("data", (chunk) => chunks.push(chunk));
41598
- readable.on("end", () => resolve10(Buffer.concat(chunks)));
41713
+ readable.on("end", () => resolve11(Buffer.concat(chunks)));
41599
41714
  readable.on("error", reject);
41600
41715
  });
41601
41716
  };
@@ -44863,7 +44978,7 @@ var responseViaResponseObject = async (res, outgoing, options = {}) => {
44863
44978
  });
44864
44979
  if (!chunk) {
44865
44980
  if (i === 1) {
44866
- await new Promise((resolve10) => setTimeout(resolve10));
44981
+ await new Promise((resolve11) => setTimeout(resolve11));
44867
44982
  maxReadCount = 3;
44868
44983
  continue;
44869
44984
  }
@@ -45080,8 +45195,8 @@ var _baseMimes = {
45080
45195
  var baseMimes = _baseMimes;
45081
45196
 
45082
45197
  // node_modules/.pnpm/@hono+node-server@1.19.11_hono@4.12.9/node_modules/@hono/node-server/dist/serve-static.mjs
45083
- var import_fs10 = require("fs");
45084
- var import_path16 = require("path");
45198
+ var import_fs11 = require("fs");
45199
+ var import_path17 = require("path");
45085
45200
  var import_process = require("process");
45086
45201
  var import_stream2 = require("stream");
45087
45202
  var COMPRESSIBLE_CONTENT_TYPE_REGEX = /^\s*(?:text\/[^;\s]+|application\/(?:javascript|json|xml|xml-dtd|ecmascript|dart|postscript|rtf|tar|toml|vnd\.dart|vnd\.ms-fontobject|vnd\.ms-opentype|wasm|x-httpd-php|x-javascript|x-ns-proxy-autoconfig|x-sh|x-tar|x-virtualbox-hdd|x-virtualbox-ova|x-virtualbox-ovf|x-virtualbox-vbox|x-virtualbox-vdi|x-virtualbox-vhd|x-virtualbox-vmdk|x-www-form-urlencoded)|font\/(?:otf|ttf)|image\/(?:bmp|vnd\.adobe\.photoshop|vnd\.microsoft\.icon|vnd\.ms-dds|x-icon|x-ms-bmp)|message\/rfc822|model\/gltf-binary|x-shader\/x-fragment|x-shader\/x-vertex|[^;\s]+?\+(?:json|text|xml|yaml))(?:[;\s]|$)/i;
@@ -45121,7 +45236,7 @@ var createStreamBody = (stream) => {
45121
45236
  var getStats = (path9) => {
45122
45237
  let stats;
45123
45238
  try {
45124
- stats = (0, import_fs10.statSync)(path9);
45239
+ stats = (0, import_fs11.statSync)(path9);
45125
45240
  } catch {
45126
45241
  }
45127
45242
  return stats;
@@ -45143,7 +45258,7 @@ var tryDecodeURI2 = (str) => tryDecode2(str, decodeURI);
45143
45258
  var serveStatic = (options = { root: "" }) => {
45144
45259
  const root = options.root || "";
45145
45260
  const optionPath = options.path;
45146
- if (root !== "" && !(0, import_fs10.existsSync)(root)) {
45261
+ if (root !== "" && !(0, import_fs11.existsSync)(root)) {
45147
45262
  console.error(`serveStatic: root path '${root}' is not found, are you sure it's correct?`);
45148
45263
  }
45149
45264
  return async (c, next) => {
@@ -45164,14 +45279,14 @@ var serveStatic = (options = { root: "" }) => {
45164
45279
  return next();
45165
45280
  }
45166
45281
  }
45167
- let path9 = (0, import_path16.join)(
45282
+ let path9 = (0, import_path17.join)(
45168
45283
  root,
45169
45284
  !optionPath && options.rewriteRequestPath ? options.rewriteRequestPath(filename, c) : filename
45170
45285
  );
45171
45286
  let stats = getStats(path9);
45172
45287
  if (stats && stats.isDirectory()) {
45173
45288
  const indexFile = options.index ?? "index.html";
45174
- path9 = (0, import_path16.join)(path9, indexFile);
45289
+ path9 = (0, import_path17.join)(path9, indexFile);
45175
45290
  stats = getStats(path9);
45176
45291
  }
45177
45292
  if (!stats) {
@@ -45207,7 +45322,7 @@ var serveStatic = (options = { root: "" }) => {
45207
45322
  result = c.body(null);
45208
45323
  } else if (!range) {
45209
45324
  c.header("Content-Length", size.toString());
45210
- result = c.body(createStreamBody((0, import_fs10.createReadStream)(path9)), 200);
45325
+ result = c.body(createStreamBody((0, import_fs11.createReadStream)(path9)), 200);
45211
45326
  } else {
45212
45327
  c.header("Accept-Ranges", "bytes");
45213
45328
  c.header("Date", stats.birthtime.toUTCString());
@@ -45218,7 +45333,7 @@ var serveStatic = (options = { root: "" }) => {
45218
45333
  end = size - 1;
45219
45334
  }
45220
45335
  const chunksize = end - start + 1;
45221
- const stream = (0, import_fs10.createReadStream)(path9, { start, end });
45336
+ const stream = (0, import_fs11.createReadStream)(path9, { start, end });
45222
45337
  c.header("Content-Length", chunksize.toString());
45223
45338
  c.header("Content-Range", `bytes ${start}-${end}/${stats.size}`);
45224
45339
  result = c.body(createStreamBody(stream), 206);
@@ -45319,12 +45434,12 @@ var cors = (options) => {
45319
45434
  // src/git/worktree.ts
45320
45435
  var import_child_process2 = require("child_process");
45321
45436
  var import_util = require("util");
45322
- var import_path17 = __toESM(require("path"));
45323
- var import_fs11 = require("fs");
45437
+ var import_path18 = __toESM(require("path"));
45438
+ var import_fs12 = require("fs");
45324
45439
  var execFileAsync = (0, import_util.promisify)(import_child_process2.execFile);
45325
45440
  var getProjectRoot = () => process.cwd();
45326
- var getWorktreeBaseDir = () => import_path17.default.join(getProjectRoot(), ".worktrees");
45327
- var getWorktreePath = (goalId, taskId) => import_path17.default.join(getWorktreeBaseDir(), goalId, taskId);
45441
+ var getWorktreeBaseDir = () => import_path18.default.join(getProjectRoot(), ".worktrees");
45442
+ var getWorktreePath = (goalId, taskId) => import_path18.default.join(getWorktreeBaseDir(), goalId, taskId);
45328
45443
  var getBranchName = (taskId) => `task/${taskId}`;
45329
45444
  async function git(args, cwd) {
45330
45445
  const { stdout } = await execFileAsync("git", args, {
@@ -45336,14 +45451,14 @@ async function git(args, cwd) {
45336
45451
  async function createWorktree(taskId, goalId, baseBranch = "main") {
45337
45452
  const wtPath = getWorktreePath(goalId, taskId);
45338
45453
  const branch = getBranchName(taskId);
45339
- const parentDir = import_path17.default.dirname(wtPath);
45340
- if (!(0, import_fs11.existsSync)(parentDir)) {
45341
- (0, import_fs11.mkdirSync)(parentDir, { recursive: true });
45454
+ const parentDir = import_path18.default.dirname(wtPath);
45455
+ if (!(0, import_fs12.existsSync)(parentDir)) {
45456
+ (0, import_fs12.mkdirSync)(parentDir, { recursive: true });
45342
45457
  }
45343
45458
  await git(["worktree", "add", "-b", branch, wtPath, baseBranch]);
45344
45459
  return {
45345
45460
  branch,
45346
- path: import_path17.default.relative(getProjectRoot(), wtPath),
45461
+ path: import_path18.default.relative(getProjectRoot(), wtPath),
45347
45462
  baseBranch,
45348
45463
  createdAt: getDate()
45349
45464
  };
@@ -45351,7 +45466,7 @@ async function createWorktree(taskId, goalId, baseBranch = "main") {
45351
45466
  async function deleteWorktree(taskId, goalId) {
45352
45467
  const wtPath = getWorktreePath(goalId, taskId);
45353
45468
  const branch = getBranchName(taskId);
45354
- if ((0, import_fs11.existsSync)(wtPath)) {
45469
+ if ((0, import_fs12.existsSync)(wtPath)) {
45355
45470
  await git(["worktree", "remove", wtPath, "--force"]);
45356
45471
  }
45357
45472
  try {
@@ -45442,8 +45557,8 @@ async function listWorktrees() {
45442
45557
  const fullBranch = branchLine.replace("branch refs/heads/", "");
45443
45558
  if (!fullBranch.startsWith("task/")) continue;
45444
45559
  const taskId = fullBranch.replace("task/", "");
45445
- const relPath = import_path17.default.relative(getProjectRoot(), wtPath);
45446
- const parts = relPath.split(import_path17.default.sep);
45560
+ const relPath = import_path18.default.relative(getProjectRoot(), wtPath);
45561
+ const parts = relPath.split(import_path18.default.sep);
45447
45562
  const worktreeIdx = parts.indexOf(".worktrees");
45448
45563
  const goalId = worktreeIdx >= 0 && parts.length > worktreeIdx + 1 ? parts[worktreeIdx + 1] : "";
45449
45564
  worktrees.push({
@@ -46194,9 +46309,8 @@ toolRoutes.get("/skills/:name", (c) => {
46194
46309
  var systemRoutes = new Hono2();
46195
46310
  var startTime = Date.now();
46196
46311
  systemRoutes.get("/system/info", (c) => {
46197
- const pkg = require_package3();
46198
46312
  return c.json({
46199
- version: pkg.version || "unknown",
46313
+ version: true ? "1.4.0" : "unknown",
46200
46314
  uptime: Math.floor((Date.now() - startTime) / 1e3),
46201
46315
  env: process.env.NODE_ENV || "development",
46202
46316
  nodeVersion: process.version
@@ -46227,8 +46341,35 @@ function startServer(port = 3e3) {
46227
46341
  }
46228
46342
 
46229
46343
  // src/main.ts
46344
+ var cliResult = handleCliCommand(process.argv.slice(2));
46345
+ if (cliResult !== void 0) {
46346
+ process.exit(cliResult);
46347
+ }
46348
+ function validateEnv() {
46349
+ const errors = [];
46350
+ const token = process.env.ANTHROPIC_AUTH_TOKEN;
46351
+ if (!token || token === "your-api-key-here") {
46352
+ errors.push(" - ANTHROPIC_AUTH_TOKEN \u672A\u8BBE\u7F6E\u6216\u4ECD\u4E3A\u5360\u4F4D\u7B26\uFF0C\u8BF7\u5728 .env \u4E2D\u586B\u5199\u6709\u6548\u7684 API Key");
46353
+ }
46354
+ if (!process.env.ANTHROPIC_BASE_URL) {
46355
+ errors.push(" - ANTHROPIC_BASE_URL \u672A\u8BBE\u7F6E\uFF0C\u8BF7\u5728 .env \u4E2D\u586B\u5199 API \u5730\u5740");
46356
+ }
46357
+ if (!process.env.REDIS_URL) {
46358
+ errors.push(" - REDIS_URL \u672A\u8BBE\u7F6E\uFF0C\u8BF7\u5728 .env \u4E2D\u586B\u5199 Redis \u8FDE\u63A5\u5730\u5740\uFF08\u5982 redis://localhost:6379\uFF09");
46359
+ }
46360
+ if (errors.length > 0) {
46361
+ console.error(`
46362
+ [\u542F\u52A8\u5931\u8D25] \u73AF\u5883\u53D8\u91CF\u6821\u9A8C\u4E0D\u901A\u8FC7\uFF1A
46363
+ ${errors.join("\n")}
46364
+ `);
46365
+ console.error(` \u63D0\u793A\uFF1A\u8FD0\u884C duclaw-cli init \u53EF\u751F\u6210 .env \u6A21\u677F
46366
+ `);
46367
+ process.exit(1);
46368
+ }
46369
+ }
46230
46370
  async function main() {
46231
46371
  loadEnv();
46372
+ validateEnv();
46232
46373
  const cfg = loadConfig();
46233
46374
  const { registry: registry2 } = createDefaultChannels();
46234
46375
  const channels = getAllChannels(registry2);