duclaw-cli 1.0.0 → 1.5.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,157 @@ 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.5.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
+ }
30183
30271
 
30184
30272
  // src/config/LoadEnv.ts
30185
30273
  var import_dotenv = __toESM(require_main());
30186
- var import_fs = require("fs");
30187
- var import_path = require("path");
30274
+ var import_fs2 = require("fs");
30275
+ var import_path2 = require("path");
30188
30276
  var loadEnv = () => {
30189
30277
  const nodeEnv = process.env.NODE_ENV || "development";
30190
30278
  const isProd = nodeEnv === "production";
@@ -30197,7 +30285,7 @@ var loadEnv = () => {
30197
30285
  // 环境特定(如 .env.development)
30198
30286
  `.env.${nodeEnv}.local`
30199
30287
  // 本地环境特定(最高优先级)
30200
- ].map((file) => (0, import_path.resolve)(process.cwd(), file)).filter((file) => (0, import_fs.existsSync)(file));
30288
+ ].map((file) => (0, import_path2.resolve)(process.cwd(), file)).filter((file) => (0, import_fs2.existsSync)(file));
30201
30289
  if (isProd) {
30202
30290
  console.log("[loadEnv] Production: \u4F18\u5148\u4F7F\u7528\u7CFB\u7EDF\u73AF\u5883\u53D8\u91CF");
30203
30291
  envFiles.forEach((file) => {
@@ -30212,14 +30300,14 @@ var loadEnv = () => {
30212
30300
  };
30213
30301
 
30214
30302
  // 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"));
30303
+ var import_fs3 = require("fs");
30304
+ var import_path3 = require("path");
30305
+ var loadConfig = (filename = "duclaw.json", currentDir = process.cwd()) => {
30306
+ const filePath = (0, import_path3.join)(currentDir, filename);
30307
+ if ((0, import_fs3.existsSync)(filePath)) {
30308
+ return JSON.parse((0, import_fs3.readFileSync)(filePath, "utf8"));
30221
30309
  }
30222
- const parentDir = (0, import_path2.dirname)(currentDir);
30310
+ const parentDir = (0, import_path3.dirname)(currentDir);
30223
30311
  if (parentDir === currentDir) {
30224
30312
  throw new Error(`Config file "${filename}" not found`);
30225
30313
  }
@@ -30506,7 +30594,7 @@ var safeJSON = (text2) => {
30506
30594
  };
30507
30595
 
30508
30596
  // 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));
30597
+ var sleep = (ms) => new Promise((resolve11) => setTimeout(resolve11, ms));
30510
30598
 
30511
30599
  // node_modules/.pnpm/@anthropic-ai+sdk@0.78.0_zod@4.3.6/node_modules/@anthropic-ai/sdk/version.mjs
30512
30600
  var VERSION = "0.78.0";
@@ -31205,8 +31293,8 @@ function addRequestID(value, response) {
31205
31293
  var _APIPromise_client;
31206
31294
  var APIPromise = class _APIPromise extends Promise {
31207
31295
  constructor(client2, responsePromise, parseResponse = defaultParseResponse) {
31208
- super((resolve10) => {
31209
- resolve10(null);
31296
+ super((resolve11) => {
31297
+ resolve11(null);
31210
31298
  });
31211
31299
  this.responsePromise = responsePromise;
31212
31300
  this.parseResponse = parseResponse;
@@ -32243,12 +32331,12 @@ var BetaMessageStream = class _BetaMessageStream {
32243
32331
  }
32244
32332
  return this._emit("error", new AnthropicError(String(error)));
32245
32333
  });
32246
- __classPrivateFieldSet(this, _BetaMessageStream_connectedPromise, new Promise((resolve10, reject) => {
32247
- __classPrivateFieldSet(this, _BetaMessageStream_resolveConnectedPromise, resolve10, "f");
32334
+ __classPrivateFieldSet(this, _BetaMessageStream_connectedPromise, new Promise((resolve11, reject) => {
32335
+ __classPrivateFieldSet(this, _BetaMessageStream_resolveConnectedPromise, resolve11, "f");
32248
32336
  __classPrivateFieldSet(this, _BetaMessageStream_rejectConnectedPromise, reject, "f");
32249
32337
  }), "f");
32250
- __classPrivateFieldSet(this, _BetaMessageStream_endPromise, new Promise((resolve10, reject) => {
32251
- __classPrivateFieldSet(this, _BetaMessageStream_resolveEndPromise, resolve10, "f");
32338
+ __classPrivateFieldSet(this, _BetaMessageStream_endPromise, new Promise((resolve11, reject) => {
32339
+ __classPrivateFieldSet(this, _BetaMessageStream_resolveEndPromise, resolve11, "f");
32252
32340
  __classPrivateFieldSet(this, _BetaMessageStream_rejectEndPromise, reject, "f");
32253
32341
  }), "f");
32254
32342
  __classPrivateFieldGet(this, _BetaMessageStream_connectedPromise, "f").catch(() => {
@@ -32418,11 +32506,11 @@ var BetaMessageStream = class _BetaMessageStream {
32418
32506
  * const message = await stream.emitted('message') // rejects if the stream errors
32419
32507
  */
32420
32508
  emitted(event) {
32421
- return new Promise((resolve10, reject) => {
32509
+ return new Promise((resolve11, reject) => {
32422
32510
  __classPrivateFieldSet(this, _BetaMessageStream_catchingPromiseCreated, true, "f");
32423
32511
  if (event !== "error")
32424
32512
  this.once("error", reject);
32425
- this.once(event, resolve10);
32513
+ this.once(event, resolve11);
32426
32514
  });
32427
32515
  }
32428
32516
  async done() {
@@ -32765,7 +32853,7 @@ var BetaMessageStream = class _BetaMessageStream {
32765
32853
  if (done) {
32766
32854
  return { value: void 0, done: true };
32767
32855
  }
32768
- return new Promise((resolve10, reject) => readQueue.push({ resolve: resolve10, reject })).then((chunk2) => chunk2 ? { value: chunk2, done: false } : { value: void 0, done: true });
32856
+ return new Promise((resolve11, reject) => readQueue.push({ resolve: resolve11, reject })).then((chunk2) => chunk2 ? { value: chunk2, done: false } : { value: void 0, done: true });
32769
32857
  }
32770
32858
  const chunk = pushQueue.shift();
32771
32859
  return { value: chunk, done: false };
@@ -32837,13 +32925,13 @@ var _BetaToolRunner_iterationCount;
32837
32925
  var _BetaToolRunner_checkAndCompact;
32838
32926
  var _BetaToolRunner_generateToolResponse;
32839
32927
  function promiseWithResolvers() {
32840
- let resolve10;
32928
+ let resolve11;
32841
32929
  let reject;
32842
32930
  const promise = new Promise((res, rej) => {
32843
- resolve10 = res;
32931
+ resolve11 = res;
32844
32932
  reject = rej;
32845
32933
  });
32846
- return { promise, resolve: resolve10, reject };
32934
+ return { promise, resolve: resolve11, reject };
32847
32935
  }
32848
32936
  var BetaToolRunner = class {
32849
32937
  constructor(client2, params, options) {
@@ -33861,12 +33949,12 @@ var MessageStream = class _MessageStream {
33861
33949
  }
33862
33950
  return this._emit("error", new AnthropicError(String(error)));
33863
33951
  });
33864
- __classPrivateFieldSet(this, _MessageStream_connectedPromise, new Promise((resolve10, reject) => {
33865
- __classPrivateFieldSet(this, _MessageStream_resolveConnectedPromise, resolve10, "f");
33952
+ __classPrivateFieldSet(this, _MessageStream_connectedPromise, new Promise((resolve11, reject) => {
33953
+ __classPrivateFieldSet(this, _MessageStream_resolveConnectedPromise, resolve11, "f");
33866
33954
  __classPrivateFieldSet(this, _MessageStream_rejectConnectedPromise, reject, "f");
33867
33955
  }), "f");
33868
- __classPrivateFieldSet(this, _MessageStream_endPromise, new Promise((resolve10, reject) => {
33869
- __classPrivateFieldSet(this, _MessageStream_resolveEndPromise, resolve10, "f");
33956
+ __classPrivateFieldSet(this, _MessageStream_endPromise, new Promise((resolve11, reject) => {
33957
+ __classPrivateFieldSet(this, _MessageStream_resolveEndPromise, resolve11, "f");
33870
33958
  __classPrivateFieldSet(this, _MessageStream_rejectEndPromise, reject, "f");
33871
33959
  }), "f");
33872
33960
  __classPrivateFieldGet(this, _MessageStream_connectedPromise, "f").catch(() => {
@@ -34036,11 +34124,11 @@ var MessageStream = class _MessageStream {
34036
34124
  * const message = await stream.emitted('message') // rejects if the stream errors
34037
34125
  */
34038
34126
  emitted(event) {
34039
- return new Promise((resolve10, reject) => {
34127
+ return new Promise((resolve11, reject) => {
34040
34128
  __classPrivateFieldSet(this, _MessageStream_catchingPromiseCreated, true, "f");
34041
34129
  if (event !== "error")
34042
34130
  this.once("error", reject);
34043
- this.once(event, resolve10);
34131
+ this.once(event, resolve11);
34044
34132
  });
34045
34133
  }
34046
34134
  async done() {
@@ -34358,7 +34446,7 @@ var MessageStream = class _MessageStream {
34358
34446
  if (done) {
34359
34447
  return { value: void 0, done: true };
34360
34448
  }
34361
- return new Promise((resolve10, reject) => readQueue.push({ resolve: resolve10, reject })).then((chunk2) => chunk2 ? { value: chunk2, done: false } : { value: void 0, done: true });
34449
+ return new Promise((resolve11, reject) => readQueue.push({ resolve: resolve11, reject })).then((chunk2) => chunk2 ? { value: chunk2, done: false } : { value: void 0, done: true });
34362
34450
  }
34363
34451
  const chunk = pushQueue.shift();
34364
34452
  return { value: chunk, done: false };
@@ -35531,15 +35619,15 @@ var dateTool = {
35531
35619
  var import_dayjs = __toESM(require_dayjs_min());
35532
35620
  var import_utc = __toESM(require_utc());
35533
35621
  var import_timezone = __toESM(require_timezone());
35534
- var import_fs3 = require("fs");
35535
- var import_path10 = __toESM(require("path"));
35622
+ var import_fs4 = require("fs");
35623
+ var import_path11 = __toESM(require("path"));
35536
35624
  import_dayjs.default.extend(import_utc.default);
35537
35625
  import_dayjs.default.extend(import_timezone.default);
35538
35626
  var getGoalDir = () => {
35539
- return import_path10.default.join(process.cwd(), ".tasks");
35627
+ return import_path11.default.join(process.cwd(), ".tasks");
35540
35628
  };
35541
35629
  var getGoalPath = (goalId) => {
35542
- return import_path10.default.join(getGoalDir(), `${goalId}.json`);
35630
+ return import_path11.default.join(getGoalDir(), `${goalId}.json`);
35543
35631
  };
35544
35632
  var createGoal = (subject, description) => {
35545
35633
  const goalId = generateId(subject);
@@ -35552,7 +35640,7 @@ var createGoal = (subject, description) => {
35552
35640
  createdAt: (0, import_dayjs.default)().tz("Asia/Shanghai").format("YYYY-MM-DD HH:mm:ss"),
35553
35641
  updateAt: (0, import_dayjs.default)().tz("Asia/Shanghai").format("YYYY-MM-DD HH:mm:ss")
35554
35642
  };
35555
- (0, import_fs3.writeFileSync)(`${getGoalPath(goalId)}`, JSON.stringify(goal, null, ` `), `utf-8`);
35643
+ (0, import_fs4.writeFileSync)(`${getGoalPath(goalId)}`, JSON.stringify(goal, null, ` `), `utf-8`);
35556
35644
  return goal;
35557
35645
  };
35558
35646
  var getGoalById = (id) => {
@@ -35567,11 +35655,11 @@ var getGoalBySubject = (subject) => {
35567
35655
  };
35568
35656
  var listGoal = () => {
35569
35657
  const goalDir = getGoalDir();
35570
- const files = (0, import_fs3.readdirSync)(goalDir);
35658
+ const files = (0, import_fs4.readdirSync)(goalDir);
35571
35659
  let goals = [];
35572
35660
  for (let file of files) {
35573
35661
  if (file.endsWith(`.json`)) {
35574
- const text2 = (0, import_fs3.readFileSync)(import_path10.default.join(goalDir, file), `utf-8`);
35662
+ const text2 = (0, import_fs4.readFileSync)(import_path11.default.join(goalDir, file), `utf-8`);
35575
35663
  const goal = JSON.parse(text2);
35576
35664
  goals.push(goal);
35577
35665
  }
@@ -35586,13 +35674,13 @@ var updateGoal = (id, goal) => {
35586
35674
  id
35587
35675
  // 确保 id 不被覆盖
35588
35676
  };
35589
- (0, import_fs3.writeFileSync)(getGoalPath(id), JSON.stringify(merged, null, " "), "utf-8");
35677
+ (0, import_fs4.writeFileSync)(getGoalPath(id), JSON.stringify(merged, null, " "), "utf-8");
35590
35678
  return { ...merged };
35591
35679
  };
35592
35680
  var deleteGoal = (id) => {
35593
35681
  const goalPath = getGoalPath(id);
35594
- if (!(0, import_fs3.existsSync)(goalPath)) return false;
35595
- (0, import_fs3.unlinkSync)(goalPath);
35682
+ if (!(0, import_fs4.existsSync)(goalPath)) return false;
35683
+ (0, import_fs4.unlinkSync)(goalPath);
35596
35684
  return true;
35597
35685
  };
35598
35686
  var generateId = (subject) => {
@@ -37572,29 +37660,29 @@ var sendMessage = {
37572
37660
  };
37573
37661
 
37574
37662
  // src/cron/jobs.ts
37575
- var import_fs4 = require("fs");
37663
+ var import_fs5 = require("fs");
37576
37664
  var import_crypto3 = require("crypto");
37577
- var import_path11 = __toESM(require("path"));
37665
+ var import_path12 = __toESM(require("path"));
37666
+ var import_os2 = require("os");
37667
+ var DUCLAW_HOME2 = import_path12.default.join((0, import_os2.homedir)(), ".duclaw");
37578
37668
  var getJobPath = () => {
37579
- return process.env.JOB_PATH || `/Users/duzicong/code/duzicong/agent-template-ts/.claude/cron/jobs.json`;
37669
+ return process.env.JOB_PATH || import_path12.default.join(DUCLAW_HOME2, "cron", "jobs.json");
37580
37670
  };
37581
37671
  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}`;
37672
+ const historyDir = process.env.JOB_HISTORY_DIR || import_path12.default.join(DUCLAW_HOME2, "cron");
37673
+ return import_path12.default.join(historyDir, date, title);
37586
37674
  };
37587
37675
  var createJob = (title, description, syntax, userRequest) => {
37588
37676
  const jsonsPath = getJobPath();
37589
- if (!(0, import_fs4.existsSync)(jsonsPath)) {
37677
+ if (!(0, import_fs5.existsSync)(jsonsPath)) {
37590
37678
  const content = `{
37591
37679
  "jobs": [
37592
37680
 
37593
37681
  ]
37594
37682
  }`;
37595
- (0, import_fs4.writeFileSync)(jsonsPath, content, `utf-8`);
37683
+ (0, import_fs5.writeFileSync)(jsonsPath, content, `utf-8`);
37596
37684
  }
37597
- const text2 = (0, import_fs4.readFileSync)(getJobPath(), `utf-8`);
37685
+ const text2 = (0, import_fs5.readFileSync)(getJobPath(), `utf-8`);
37598
37686
  const obj = JSON.parse(text2);
37599
37687
  let jobs = obj.jobs || [];
37600
37688
  const createJob2 = {
@@ -37615,7 +37703,7 @@ var createJob = (title, description, syntax, userRequest) => {
37615
37703
  ...jobs,
37616
37704
  createJob2
37617
37705
  ];
37618
- (0, import_fs4.writeFileSync)(getJobPath(), JSON.stringify({ jobs }, null, " "), `utf-8`);
37706
+ (0, import_fs5.writeFileSync)(getJobPath(), JSON.stringify({ jobs }, null, " "), `utf-8`);
37619
37707
  return { ...createJob2 };
37620
37708
  };
37621
37709
  var updateJob = (id, syntax, title, description) => {
@@ -37627,11 +37715,15 @@ var updateJob = (id, syntax, title, description) => {
37627
37715
  job.schedule.syntax = syntax;
37628
37716
  job.title = title;
37629
37717
  job.description = description;
37630
- (0, import_fs4.writeFileSync)(getJobPath(), JSON.stringify(jobs, null, " "));
37718
+ (0, import_fs5.writeFileSync)(getJobPath(), JSON.stringify(jobs, null, " "));
37631
37719
  return { ...job };
37632
37720
  };
37633
37721
  var listJobs = () => {
37634
- const text2 = (0, import_fs4.readFileSync)(getJobPath(), `utf-8`);
37722
+ const jobPath = getJobPath();
37723
+ if (!(0, import_fs5.existsSync)(jobPath)) {
37724
+ return [];
37725
+ }
37726
+ const text2 = (0, import_fs5.readFileSync)(jobPath, `utf-8`);
37635
37727
  if (!text2) {
37636
37728
  return [];
37637
37729
  }
@@ -37641,7 +37733,7 @@ var listJobs = () => {
37641
37733
  };
37642
37734
  var deleteJob = (id, title) => {
37643
37735
  const jobPath = getJobPath();
37644
- const text2 = (0, import_fs4.readFileSync)(jobPath, `utf-8`);
37736
+ const text2 = (0, import_fs5.readFileSync)(jobPath, `utf-8`);
37645
37737
  const obj = JSON.parse(text2);
37646
37738
  let jobs = obj.jobs || [];
37647
37739
  let isJobExist = false;
@@ -37663,7 +37755,7 @@ var deleteJob = (id, title) => {
37663
37755
  ;
37664
37756
  jobs = jobs.filter((j) => j.title !== title);
37665
37757
  }
37666
- (0, import_fs4.writeFileSync)(jobPath, JSON.stringify({ jobs }, null, " "), `utf-8`);
37758
+ (0, import_fs5.writeFileSync)(jobPath, JSON.stringify({ jobs }, null, " "), `utf-8`);
37667
37759
  if (targetJob) {
37668
37760
  return { ...targetJob };
37669
37761
  }
@@ -37681,7 +37773,7 @@ var getJobExecuteHistory = (id, title) => {
37681
37773
  const lastRunTime = "2026-03-17T21:00:28";
37682
37774
  const dateStr = lastRunTime.split("T")[0];
37683
37775
  const historyFilePath = getJobHistoryPath(dateStr, findJob.title);
37684
- const text2 = (0, import_fs4.readFileSync)(historyFilePath, `utf-8`);
37776
+ const text2 = (0, import_fs5.readFileSync)(historyFilePath, `utf-8`);
37685
37777
  const list = JSON.parse(text2) || [];
37686
37778
  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
37779
  return list;
@@ -37767,7 +37859,7 @@ var cronDelete = {
37767
37859
  };
37768
37860
 
37769
37861
  // src/cron/cron.ts
37770
- var import_fs5 = require("fs");
37862
+ var import_fs6 = require("fs");
37771
37863
 
37772
37864
  // node_modules/.pnpm/chokidar@5.0.0/node_modules/chokidar/index.js
37773
37865
  var import_node_events = require("node:events");
@@ -38640,7 +38732,7 @@ var NodeFsHandler = class {
38640
38732
  this._addToNodeFs(path9, initialAdd, wh, depth + 1);
38641
38733
  }
38642
38734
  }).on(EV.ERROR, this._boundHandleError);
38643
- return new Promise((resolve10, reject) => {
38735
+ return new Promise((resolve11, reject) => {
38644
38736
  if (!stream)
38645
38737
  return reject();
38646
38738
  stream.once(STR_END, () => {
@@ -38649,7 +38741,7 @@ var NodeFsHandler = class {
38649
38741
  return;
38650
38742
  }
38651
38743
  const wasThrottled = throttler ? throttler.clear() : false;
38652
- resolve10(void 0);
38744
+ resolve11(void 0);
38653
38745
  previous.getChildren().filter((item) => {
38654
38746
  return item !== directory && !current.has(item);
38655
38747
  }).forEach((item) => {
@@ -39590,14 +39682,14 @@ var loadAndScheduleJobs = () => {
39590
39682
  console.log(`[cron] \u5F53\u524D\u5171 ${scheduledTasks.size} \u4E2A\u6D3B\u8DC3\u4EFB\u52A1`);
39591
39683
  };
39592
39684
  var updateJobLastRunTime = (jobId) => {
39593
- const text2 = (0, import_fs5.readFileSync)(getJobPath(), `utf-8`);
39685
+ const text2 = (0, import_fs6.readFileSync)(getJobPath(), `utf-8`);
39594
39686
  const obj = JSON.parse(text2);
39595
39687
  const jobs = obj.jobs || [];
39596
39688
  const job = jobs.find((j) => j.id === jobId);
39597
39689
  if (job) {
39598
39690
  job.schedule.lastRunTime = (/* @__PURE__ */ new Date()).toLocaleString("sv-SE", { timeZone: "Asia/Shanghai" }).replace(" ", "T");
39599
39691
  suppressWatch = true;
39600
- (0, import_fs5.writeFileSync)(getJobPath(), JSON.stringify({ jobs }, null, " "), `utf-8`);
39692
+ (0, import_fs6.writeFileSync)(getJobPath(), JSON.stringify({ jobs }, null, " "), `utf-8`);
39601
39693
  }
39602
39694
  };
39603
39695
  var getCronTools = () => {
@@ -39707,6 +39799,14 @@ var executeCustomJob = async (job) => {
39707
39799
  return await handler(job);
39708
39800
  };
39709
39801
  var startScheduler = () => {
39802
+ const jobPath = getJobPath();
39803
+ const jobDir = require("path").dirname(jobPath);
39804
+ if (!(0, import_fs6.existsSync)(jobDir)) {
39805
+ (0, import_fs6.mkdirSync)(jobDir, { recursive: true });
39806
+ }
39807
+ if (!(0, import_fs6.existsSync)(jobPath)) {
39808
+ (0, import_fs6.writeFileSync)(jobPath, JSON.stringify({ jobs: [] }, null, " "), "utf-8");
39809
+ }
39710
39810
  loadAndScheduleJobs();
39711
39811
  watchJobsFile();
39712
39812
  };
@@ -39722,13 +39822,13 @@ var saveResultToFile = (job, cronResp) => {
39722
39822
  const safeTitle = sanitizeTitle(job.title);
39723
39823
  const dirPath = `./cron/${yyyyMMdd}/${safeTitle}`;
39724
39824
  const filePath = `${dirPath}/history.json`;
39725
- if (!(0, import_fs5.existsSync)(dirPath)) {
39726
- (0, import_fs5.mkdirSync)(dirPath, { recursive: true });
39825
+ if (!(0, import_fs6.existsSync)(dirPath)) {
39826
+ (0, import_fs6.mkdirSync)(dirPath, { recursive: true });
39727
39827
  }
39728
39828
  let history = [];
39729
- if ((0, import_fs5.existsSync)(filePath)) {
39829
+ if ((0, import_fs6.existsSync)(filePath)) {
39730
39830
  try {
39731
- const content = (0, import_fs5.readFileSync)(filePath, "utf-8");
39831
+ const content = (0, import_fs6.readFileSync)(filePath, "utf-8");
39732
39832
  history = JSON.parse(content);
39733
39833
  } catch {
39734
39834
  history = [];
@@ -39738,7 +39838,7 @@ var saveResultToFile = (job, cronResp) => {
39738
39838
  timestamp: now.toLocaleString("sv-SE", { timeZone: "Asia/Shanghai" }).replace(" ", "T"),
39739
39839
  result: cronResp
39740
39840
  });
39741
- (0, import_fs5.writeFileSync)(filePath, JSON.stringify(history, null, " "), "utf-8");
39841
+ (0, import_fs6.writeFileSync)(filePath, JSON.stringify(history, null, " "), "utf-8");
39742
39842
  return filePath;
39743
39843
  };
39744
39844
 
@@ -39850,8 +39950,8 @@ var cronUpdate = {
39850
39950
  };
39851
39951
 
39852
39952
  // src/tools/tools/ImageUnderstand.ts
39853
- var import_fs6 = __toESM(require("fs"));
39854
- var import_path12 = __toESM(require("path"));
39953
+ var import_fs7 = __toESM(require("fs"));
39954
+ var import_path13 = __toESM(require("path"));
39855
39955
 
39856
39956
  // src/types/builders.ts
39857
39957
  var text = (text2) => ({
@@ -39906,7 +40006,7 @@ var guessMediaTypeFromHeader = (contentType) => {
39906
40006
  return null;
39907
40007
  };
39908
40008
  var guessMediaTypeFromExt = (filePath) => {
39909
- const ext = import_path12.default.extname(filePath).toLowerCase();
40009
+ const ext = import_path13.default.extname(filePath).toLowerCase();
39910
40010
  if (ext === ".jpg" || ext === ".jpeg") return "image/jpeg";
39911
40011
  if (ext === ".png") return "image/png";
39912
40012
  if (ext === ".gif") return "image/gif";
@@ -39926,9 +40026,9 @@ var resolveImageBlock = async (input) => {
39926
40026
  return imageBase64(base64Data, mediaType2);
39927
40027
  }
39928
40028
  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}`);
40029
+ if (!import_fs7.default.existsSync(input)) throw new Error(`[ImageUnderstand] \u672C\u5730\u6587\u4EF6\u4E0D\u5B58\u5728: ${input}`);
39930
40030
  console.log(`[ImageUnderstand] \u8BFB\u53D6\u672C\u5730\u6587\u4EF6: ${input}`);
39931
- const buffer = import_fs6.default.readFileSync(input);
40031
+ const buffer = import_fs7.default.readFileSync(input);
39932
40032
  const base64Data = buffer.toString("base64");
39933
40033
  const mediaType2 = guessMediaTypeFromExt(input) ?? guessMediaTypeFromData(base64Data) ?? "image/png";
39934
40034
  console.log(`[ImageUnderstand] \u63A8\u65AD\u5A92\u4F53\u7C7B\u578B: ${mediaType2}`);
@@ -39986,45 +40086,44 @@ var imageUnderstand = {
39986
40086
  };
39987
40087
 
39988
40088
  // src/skill/SkillRegistry.ts
39989
- var import_fs7 = require("fs");
39990
- var import_os = require("os");
39991
- var import_path13 = __toESM(require("path"));
40089
+ var import_fs8 = require("fs");
40090
+ var import_os3 = require("os");
40091
+ var import_path14 = __toESM(require("path"));
39992
40092
  var getSkillPaths = () => {
39993
40093
  const paths = [];
39994
40094
  let currentDir = __dirname_m;
39995
40095
  let projectRoot = "";
39996
40096
  while (currentDir !== "/") {
39997
- const claudePath = (0, import_path13.join)(currentDir, ".claude");
39998
- if ((0, import_fs7.existsSync)(claudePath) && (0, import_fs7.statSync)(claudePath).isDirectory()) {
40097
+ if ((0, import_fs8.existsSync)((0, import_path14.join)(currentDir, "duclaw.json"))) {
39999
40098
  projectRoot = currentDir;
40000
- const skillsPath = (0, import_path13.join)(claudePath, "skills");
40001
- if ((0, import_fs7.existsSync)(skillsPath)) {
40002
- paths.push(skillsPath);
40003
- }
40004
40099
  break;
40005
40100
  }
40006
- const parentDir = (0, import_path13.dirname)(currentDir);
40101
+ const parentDir = (0, import_path14.dirname)(currentDir);
40007
40102
  if (parentDir === currentDir) break;
40008
40103
  currentDir = parentDir;
40009
40104
  }
40010
40105
  if (projectRoot) {
40011
- const rootSkillsPath = (0, import_path13.join)(projectRoot, "skills");
40012
- if ((0, import_fs7.existsSync)(rootSkillsPath) && (0, import_fs7.statSync)(rootSkillsPath).isDirectory()) {
40106
+ const rootSkillsPath = (0, import_path14.join)(projectRoot, "skills");
40107
+ if ((0, import_fs8.existsSync)(rootSkillsPath) && (0, import_fs8.statSync)(rootSkillsPath).isDirectory()) {
40013
40108
  paths.push(rootSkillsPath);
40014
40109
  }
40015
40110
  }
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);
40111
+ const duclawSkillsPath = (0, import_path14.join)((0, import_os3.homedir)(), ".duclaw", "skills");
40112
+ if ((0, import_fs8.existsSync)(duclawSkillsPath) && (0, import_fs8.statSync)(duclawSkillsPath).isDirectory()) {
40113
+ paths.push(duclawSkillsPath);
40114
+ }
40115
+ const agentsSkillsPath = (0, import_path14.join)((0, import_os3.homedir)(), ".agents", "skills");
40116
+ if ((0, import_fs8.existsSync)(agentsSkillsPath) && (0, import_fs8.statSync)(agentsSkillsPath).isDirectory()) {
40117
+ paths.push(agentsSkillsPath);
40019
40118
  }
40020
40119
  return paths;
40021
40120
  };
40022
40121
  var getDirectories = (dirPath) => {
40023
- return (0, import_fs7.readdirSync)(dirPath).filter((name) => (0, import_fs7.statSync)((0, import_path13.join)(dirPath, name)).isDirectory());
40122
+ return (0, import_fs8.readdirSync)(dirPath).filter((name) => (0, import_fs8.statSync)((0, import_path14.join)(dirPath, name)).isDirectory());
40024
40123
  };
40025
40124
  var parseSkill = (mdPath, skillDir) => {
40026
- if (!(0, import_fs7.existsSync)(mdPath)) return null;
40027
- const raw2 = (0, import_fs7.readFileSync)(mdPath, "utf-8");
40125
+ if (!(0, import_fs8.existsSync)(mdPath)) return null;
40126
+ const raw2 = (0, import_fs8.readFileSync)(mdPath, "utf-8");
40028
40127
  let name = "";
40029
40128
  let description = "";
40030
40129
  let body = raw2;
@@ -40040,7 +40139,7 @@ var parseSkill = (mdPath, skillDir) => {
40040
40139
  }
40041
40140
  }
40042
40141
  if (!name) {
40043
- name = import_path13.default.basename(import_path13.default.dirname(mdPath));
40142
+ name = import_path14.default.basename(import_path14.default.dirname(mdPath));
40044
40143
  }
40045
40144
  if (!description && body) {
40046
40145
  description = body.split("\n")[0].replace(/^#+\s*/, "").trim();
@@ -40065,8 +40164,8 @@ var loadSkill = () => {
40065
40164
  for (const skillPath of skillPaths) {
40066
40165
  const dirs = getDirectories(skillPath);
40067
40166
  for (const skillName of dirs) {
40068
- const eachSkillPath = (0, import_path13.join)(skillPath, skillName);
40069
- const eachSkillMdPath = (0, import_path13.join)(eachSkillPath, "SKILL.md");
40167
+ const eachSkillPath = (0, import_path14.join)(skillPath, skillName);
40168
+ const eachSkillMdPath = (0, import_path14.join)(eachSkillPath, "SKILL.md");
40070
40169
  const skill = parseSkill(eachSkillMdPath, eachSkillPath);
40071
40170
  if (skill && !seen.has(skill.name)) {
40072
40171
  seen.add(skill.name);
@@ -40418,12 +40517,12 @@ var create_mailbox_table = () => {
40418
40517
  };
40419
40518
 
40420
40519
  // src/team/TeamMember.ts
40421
- var import_fs9 = require("fs");
40422
- var import_path15 = __toESM(require("path"));
40520
+ var import_fs10 = require("fs");
40521
+ var import_path16 = __toESM(require("path"));
40423
40522
 
40424
40523
  // src/team/Team.ts
40425
- var import_path14 = __toESM(require("path"));
40426
- var import_fs8 = require("fs");
40524
+ var import_path15 = __toESM(require("path"));
40525
+ var import_fs9 = require("fs");
40427
40526
  var getTeamBaseDir = () => {
40428
40527
  return `~/.duclaw/team`;
40429
40528
  };
@@ -40436,22 +40535,22 @@ var getTeamJsonPath = (teamName) => {
40436
40535
  var createTeam = (teamDefinition) => {
40437
40536
  if (!teamDefinition) throw new Error(`[createTeam] teamDefinition\u4E0D\u80FD\u4E3A\u7A7A`);
40438
40537
  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");
40538
+ const teamPath = import_path15.default.join(getTeamWorkSpaceDir(name));
40539
+ (0, import_fs9.mkdirSync)(teamPath, { recursive: true });
40540
+ (0, import_fs9.writeFileSync)(`${teamPath}/team.json`, JSON.stringify(teamDefinition, null, " "), "utf-8");
40442
40541
  return teamDefinition;
40443
40542
  };
40444
40543
  var getTeam = (name) => {
40445
40544
  const teamJsonPath = getTeamJsonPath(name);
40446
- if (!(0, import_fs8.existsSync)(teamJsonPath)) return null;
40447
- const text2 = (0, import_fs8.readFileSync)(teamJsonPath, `utf-8`);
40545
+ if (!(0, import_fs9.existsSync)(teamJsonPath)) return null;
40546
+ const text2 = (0, import_fs9.readFileSync)(teamJsonPath, `utf-8`);
40448
40547
  const obj = JSON.parse(text2) || {};
40449
40548
  const team = obj;
40450
40549
  return team;
40451
40550
  };
40452
40551
  var listTeams = () => {
40453
40552
  const baseDir = getTeamBaseDir();
40454
- const teamnames = (0, import_fs8.readdirSync)(import_path14.default.join(baseDir, `workspace`));
40553
+ const teamnames = (0, import_fs9.readdirSync)(import_path15.default.join(baseDir, `workspace`));
40455
40554
  const teams = [];
40456
40555
  for (const teamname of teamnames) {
40457
40556
  const team = getTeam(teamname);
@@ -40468,10 +40567,10 @@ var getTeamById = (id) => {
40468
40567
  return team;
40469
40568
  };
40470
40569
  var deleteTeam = (name) => {
40471
- if (!(0, import_fs8.existsSync)(getTeamJsonPath(name))) {
40570
+ if (!(0, import_fs9.existsSync)(getTeamJsonPath(name))) {
40472
40571
  throw new Error(`[deleteTeam] \u4E0D\u5B58\u5728\u5BF9\u5E94\u7684\u56E2\u961F${name}\u7684team.json\u6587\u4EF6`);
40473
40572
  }
40474
- (0, import_fs8.rmSync)(getTeamJsonPath(name));
40573
+ (0, import_fs9.rmSync)(getTeamJsonPath(name));
40475
40574
  };
40476
40575
 
40477
40576
  // src/team/workspace/workspace.ts
@@ -40499,8 +40598,8 @@ var createTeamMember = (teamMemberDefinition) => {
40499
40598
  const { id, name, teamId, mailBoxId, workspaceId } = teamMemberDefinition;
40500
40599
  const team = getTeamById(teamMemberDefinition.teamId);
40501
40600
  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 });
40601
+ const memberPath = import_path16.default.join(getTeamWorkSpaceDir(team.name), name);
40602
+ (0, import_fs10.mkdirSync)(memberPath, { recursive: true });
40504
40603
  const workspace = {
40505
40604
  id: getWorkspaceId(team.name, teamMemberDefinition.name),
40506
40605
  teamName: team.name,
@@ -40512,12 +40611,12 @@ var createTeamMember = (teamMemberDefinition) => {
40512
40611
  team.teamMembers = [];
40513
40612
  }
40514
40613
  team.teamMembers.push(teamMemberDefinition);
40515
- (0, import_fs9.writeFileSync)(getTeamJsonPath(team.name), JSON.stringify(team, null, " "), "utf-8");
40614
+ (0, import_fs10.writeFileSync)(getTeamJsonPath(team.name), JSON.stringify(team, null, " "), "utf-8");
40516
40615
  return teamMemberDefinition;
40517
40616
  };
40518
40617
  var listTeamMember = (teamName) => {
40519
40618
  const teamJsonPath = getTeamJsonPath(teamName);
40520
- const text2 = (0, import_fs9.readFileSync)(teamJsonPath, `utf-8`);
40619
+ const text2 = (0, import_fs10.readFileSync)(teamJsonPath, `utf-8`);
40521
40620
  const team = JSON.parse(text2);
40522
40621
  if (!team) throw new Error(`[listTeamMember] \u627E\u4E0D\u5230\u5BF9\u5E94\u7684team: ${teamName}`);
40523
40622
  if (!team.teamMembers) return [];
@@ -40552,7 +40651,7 @@ var deleteTeamMemberById = (teamName, memberId) => {
40552
40651
  const workspaceId = team.teamMembers[memberIdx].workspaceId;
40553
40652
  let newTeamMember = team.teamMembers.filter((_, index) => index !== memberIdx);
40554
40653
  team.teamMembers = newTeamMember;
40555
- (0, import_fs9.writeFileSync)(getTeamJsonPath(teamName), JSON.stringify(team, null, ` `));
40654
+ (0, import_fs10.writeFileSync)(getTeamJsonPath(teamName), JSON.stringify(team, null, ` `));
40556
40655
  deleteWorkspace(workspaceId);
40557
40656
  };
40558
40657
 
@@ -40952,7 +41051,7 @@ var bashTool = {
40952
41051
  if (rejection) return `[bash] ${rejection}`;
40953
41052
  }
40954
41053
  const cwd = explicitCwd || getEffectiveCwd(userRequest);
40955
- return new Promise((resolve10) => {
41054
+ return new Promise((resolve11) => {
40956
41055
  const options = {
40957
41056
  timeout,
40958
41057
  maxBuffer: 1024 * 1024,
@@ -40984,7 +41083,7 @@ ${trimmed}`;
40984
41083
  if (!output) {
40985
41084
  output = "[bash] \u547D\u4EE4\u6267\u884C\u6210\u529F\uFF08\u65E0\u8F93\u51FA\uFF09";
40986
41085
  }
40987
- resolve10(output);
41086
+ resolve11(output);
40988
41087
  });
40989
41088
  });
40990
41089
  }
@@ -41285,7 +41384,7 @@ ${getSkillMeta()}
41285
41384
  const anthropicOptions = {
41286
41385
  baseURL: process.env.ANTHROPIC_BASE_URL,
41287
41386
  model: process.env.ANTHROPIC_MODEL,
41288
- apiKey: process.env.ANTHROPIC_AUTH_TOKEN || "a4fd749ac2824c55a88946fc13a50e23.VPMAm8nUNaAWWS3E",
41387
+ apiKey: process.env.ANTHROPIC_AUTH_TOKEN,
41289
41388
  authStyle: process.env.ANTHROPIC_AUTH_STYLE || void 0
41290
41389
  };
41291
41390
  const llmClient = createAnthropicAdapter(anthropicOptions);
@@ -41592,10 +41691,10 @@ var downloadMessageResource = async (messageId, fileKey, type) => {
41592
41691
  throw error;
41593
41692
  }
41594
41693
  const readable = response.getReadableStream();
41595
- return new Promise((resolve10, reject) => {
41694
+ return new Promise((resolve11, reject) => {
41596
41695
  const chunks = [];
41597
41696
  readable.on("data", (chunk) => chunks.push(chunk));
41598
- readable.on("end", () => resolve10(Buffer.concat(chunks)));
41697
+ readable.on("end", () => resolve11(Buffer.concat(chunks)));
41599
41698
  readable.on("error", reject);
41600
41699
  });
41601
41700
  };
@@ -44863,7 +44962,7 @@ var responseViaResponseObject = async (res, outgoing, options = {}) => {
44863
44962
  });
44864
44963
  if (!chunk) {
44865
44964
  if (i === 1) {
44866
- await new Promise((resolve10) => setTimeout(resolve10));
44965
+ await new Promise((resolve11) => setTimeout(resolve11));
44867
44966
  maxReadCount = 3;
44868
44967
  continue;
44869
44968
  }
@@ -45080,8 +45179,8 @@ var _baseMimes = {
45080
45179
  var baseMimes = _baseMimes;
45081
45180
 
45082
45181
  // 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");
45182
+ var import_fs11 = require("fs");
45183
+ var import_path17 = require("path");
45085
45184
  var import_process = require("process");
45086
45185
  var import_stream2 = require("stream");
45087
45186
  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 +45220,7 @@ var createStreamBody = (stream) => {
45121
45220
  var getStats = (path9) => {
45122
45221
  let stats;
45123
45222
  try {
45124
- stats = (0, import_fs10.statSync)(path9);
45223
+ stats = (0, import_fs11.statSync)(path9);
45125
45224
  } catch {
45126
45225
  }
45127
45226
  return stats;
@@ -45143,7 +45242,7 @@ var tryDecodeURI2 = (str) => tryDecode2(str, decodeURI);
45143
45242
  var serveStatic = (options = { root: "" }) => {
45144
45243
  const root = options.root || "";
45145
45244
  const optionPath = options.path;
45146
- if (root !== "" && !(0, import_fs10.existsSync)(root)) {
45245
+ if (root !== "" && !(0, import_fs11.existsSync)(root)) {
45147
45246
  console.error(`serveStatic: root path '${root}' is not found, are you sure it's correct?`);
45148
45247
  }
45149
45248
  return async (c, next) => {
@@ -45164,14 +45263,14 @@ var serveStatic = (options = { root: "" }) => {
45164
45263
  return next();
45165
45264
  }
45166
45265
  }
45167
- let path9 = (0, import_path16.join)(
45266
+ let path9 = (0, import_path17.join)(
45168
45267
  root,
45169
45268
  !optionPath && options.rewriteRequestPath ? options.rewriteRequestPath(filename, c) : filename
45170
45269
  );
45171
45270
  let stats = getStats(path9);
45172
45271
  if (stats && stats.isDirectory()) {
45173
45272
  const indexFile = options.index ?? "index.html";
45174
- path9 = (0, import_path16.join)(path9, indexFile);
45273
+ path9 = (0, import_path17.join)(path9, indexFile);
45175
45274
  stats = getStats(path9);
45176
45275
  }
45177
45276
  if (!stats) {
@@ -45207,7 +45306,7 @@ var serveStatic = (options = { root: "" }) => {
45207
45306
  result = c.body(null);
45208
45307
  } else if (!range) {
45209
45308
  c.header("Content-Length", size.toString());
45210
- result = c.body(createStreamBody((0, import_fs10.createReadStream)(path9)), 200);
45309
+ result = c.body(createStreamBody((0, import_fs11.createReadStream)(path9)), 200);
45211
45310
  } else {
45212
45311
  c.header("Accept-Ranges", "bytes");
45213
45312
  c.header("Date", stats.birthtime.toUTCString());
@@ -45218,7 +45317,7 @@ var serveStatic = (options = { root: "" }) => {
45218
45317
  end = size - 1;
45219
45318
  }
45220
45319
  const chunksize = end - start + 1;
45221
- const stream = (0, import_fs10.createReadStream)(path9, { start, end });
45320
+ const stream = (0, import_fs11.createReadStream)(path9, { start, end });
45222
45321
  c.header("Content-Length", chunksize.toString());
45223
45322
  c.header("Content-Range", `bytes ${start}-${end}/${stats.size}`);
45224
45323
  result = c.body(createStreamBody(stream), 206);
@@ -45319,12 +45418,12 @@ var cors = (options) => {
45319
45418
  // src/git/worktree.ts
45320
45419
  var import_child_process2 = require("child_process");
45321
45420
  var import_util = require("util");
45322
- var import_path17 = __toESM(require("path"));
45323
- var import_fs11 = require("fs");
45421
+ var import_path18 = __toESM(require("path"));
45422
+ var import_fs12 = require("fs");
45324
45423
  var execFileAsync = (0, import_util.promisify)(import_child_process2.execFile);
45325
45424
  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);
45425
+ var getWorktreeBaseDir = () => import_path18.default.join(getProjectRoot(), ".worktrees");
45426
+ var getWorktreePath = (goalId, taskId) => import_path18.default.join(getWorktreeBaseDir(), goalId, taskId);
45328
45427
  var getBranchName = (taskId) => `task/${taskId}`;
45329
45428
  async function git(args, cwd) {
45330
45429
  const { stdout } = await execFileAsync("git", args, {
@@ -45336,14 +45435,14 @@ async function git(args, cwd) {
45336
45435
  async function createWorktree(taskId, goalId, baseBranch = "main") {
45337
45436
  const wtPath = getWorktreePath(goalId, taskId);
45338
45437
  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 });
45438
+ const parentDir = import_path18.default.dirname(wtPath);
45439
+ if (!(0, import_fs12.existsSync)(parentDir)) {
45440
+ (0, import_fs12.mkdirSync)(parentDir, { recursive: true });
45342
45441
  }
45343
45442
  await git(["worktree", "add", "-b", branch, wtPath, baseBranch]);
45344
45443
  return {
45345
45444
  branch,
45346
- path: import_path17.default.relative(getProjectRoot(), wtPath),
45445
+ path: import_path18.default.relative(getProjectRoot(), wtPath),
45347
45446
  baseBranch,
45348
45447
  createdAt: getDate()
45349
45448
  };
@@ -45351,7 +45450,7 @@ async function createWorktree(taskId, goalId, baseBranch = "main") {
45351
45450
  async function deleteWorktree(taskId, goalId) {
45352
45451
  const wtPath = getWorktreePath(goalId, taskId);
45353
45452
  const branch = getBranchName(taskId);
45354
- if ((0, import_fs11.existsSync)(wtPath)) {
45453
+ if ((0, import_fs12.existsSync)(wtPath)) {
45355
45454
  await git(["worktree", "remove", wtPath, "--force"]);
45356
45455
  }
45357
45456
  try {
@@ -45442,8 +45541,8 @@ async function listWorktrees() {
45442
45541
  const fullBranch = branchLine.replace("branch refs/heads/", "");
45443
45542
  if (!fullBranch.startsWith("task/")) continue;
45444
45543
  const taskId = fullBranch.replace("task/", "");
45445
- const relPath = import_path17.default.relative(getProjectRoot(), wtPath);
45446
- const parts = relPath.split(import_path17.default.sep);
45544
+ const relPath = import_path18.default.relative(getProjectRoot(), wtPath);
45545
+ const parts = relPath.split(import_path18.default.sep);
45447
45546
  const worktreeIdx = parts.indexOf(".worktrees");
45448
45547
  const goalId = worktreeIdx >= 0 && parts.length > worktreeIdx + 1 ? parts[worktreeIdx + 1] : "";
45449
45548
  worktrees.push({
@@ -46194,9 +46293,8 @@ toolRoutes.get("/skills/:name", (c) => {
46194
46293
  var systemRoutes = new Hono2();
46195
46294
  var startTime = Date.now();
46196
46295
  systemRoutes.get("/system/info", (c) => {
46197
- const pkg = require_package3();
46198
46296
  return c.json({
46199
- version: pkg.version || "unknown",
46297
+ version: true ? "1.5.0" : "unknown",
46200
46298
  uptime: Math.floor((Date.now() - startTime) / 1e3),
46201
46299
  env: process.env.NODE_ENV || "development",
46202
46300
  nodeVersion: process.version
@@ -46227,8 +46325,35 @@ function startServer(port = 3e3) {
46227
46325
  }
46228
46326
 
46229
46327
  // src/main.ts
46328
+ var cliResult = handleCliCommand(process.argv.slice(2));
46329
+ if (cliResult !== void 0) {
46330
+ process.exit(cliResult);
46331
+ }
46332
+ function validateEnv() {
46333
+ const errors = [];
46334
+ const token = process.env.ANTHROPIC_AUTH_TOKEN;
46335
+ if (!token || token === "your-api-key-here") {
46336
+ 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");
46337
+ }
46338
+ if (!process.env.ANTHROPIC_BASE_URL) {
46339
+ errors.push(" - ANTHROPIC_BASE_URL \u672A\u8BBE\u7F6E\uFF0C\u8BF7\u5728 .env \u4E2D\u586B\u5199 API \u5730\u5740");
46340
+ }
46341
+ if (!process.env.REDIS_URL) {
46342
+ 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");
46343
+ }
46344
+ if (errors.length > 0) {
46345
+ console.error(`
46346
+ [\u542F\u52A8\u5931\u8D25] \u73AF\u5883\u53D8\u91CF\u6821\u9A8C\u4E0D\u901A\u8FC7\uFF1A
46347
+ ${errors.join("\n")}
46348
+ `);
46349
+ console.error(` \u63D0\u793A\uFF1A\u8FD0\u884C duclaw-cli init \u53EF\u751F\u6210 .env \u6A21\u677F
46350
+ `);
46351
+ process.exit(1);
46352
+ }
46353
+ }
46230
46354
  async function main() {
46231
46355
  loadEnv();
46356
+ validateEnv();
46232
46357
  const cfg = loadConfig();
46233
46358
  const { registry: registry2 } = createDefaultChannels();
46234
46359
  const channels = getAllChannels(registry2);