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/README.md +121 -23
- package/dist/bundle.js +381 -240
- package/dist/main.js +1 -1
- package/package.json +4 -10
- package/.claude/cron/jobs.json +0 -3
- package/docker/.env +0 -31
- package/docker/Dockerfile +0 -61
- package/docker/agent-template.json +0 -9
- package/docker/docker-compose.yml +0 -43
- package/docker/entrypoint.sh +0 -27
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((
|
|
16342
|
+
return new Promise((resolve11) => {
|
|
16343
16343
|
const onEmpty = () => {
|
|
16344
16344
|
if (timeoutId)
|
|
16345
16345
|
clearTimeout(timeoutId);
|
|
16346
|
-
|
|
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
|
-
|
|
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((
|
|
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:
|
|
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((
|
|
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
|
-
|
|
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:
|
|
16442
|
-
|
|
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:
|
|
16466
|
+
const { resolve: resolve11 } = command;
|
|
16467
16467
|
command.resolve = () => {
|
|
16468
16468
|
if (!this.#pubSub.isActive) {
|
|
16469
16469
|
this.#resetDecoderCallbacks();
|
|
16470
16470
|
}
|
|
16471
|
-
|
|
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((
|
|
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
|
-
|
|
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((
|
|
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:
|
|
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((
|
|
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:
|
|
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,
|
|
17896
|
+
this._self.#executeTask(node, resolve11, reject, fn);
|
|
17897
17897
|
});
|
|
17898
17898
|
}
|
|
17899
|
-
#executeTask(node,
|
|
17899
|
+
#executeTask(node, resolve11, reject, fn) {
|
|
17900
17900
|
const result = fn(node.value);
|
|
17901
17901
|
if (result instanceof Promise) {
|
|
17902
|
-
result.then(
|
|
17902
|
+
result.then(resolve11, reject).finally(() => this.#returnClient(node));
|
|
17903
17903
|
} else {
|
|
17904
|
-
|
|
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((
|
|
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
|
|
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
|
-
|
|
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
|
|
20609
|
-
if (
|
|
20610
|
-
|
|
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((
|
|
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((
|
|
28873
|
+
this.promise = new Promise((resolve11, reject) => {
|
|
28874
28874
|
executor((value) => {
|
|
28875
28875
|
this.state = "fulfilled";
|
|
28876
28876
|
this.value = value;
|
|
28877
|
-
|
|
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 (
|
|
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
|
-
|
|
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 (
|
|
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
|
-
|
|
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((
|
|
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
|
-
|
|
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((
|
|
29880
|
+
return new Promise((resolve11, reject) => {
|
|
29881
29881
|
if (this.forkProcess) {
|
|
29882
|
-
return
|
|
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
|
-
|
|
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((
|
|
29935
|
+
return new Promise((resolve11, reject) => {
|
|
29936
29936
|
if (!this.forkProcess) {
|
|
29937
|
-
return
|
|
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
|
-
|
|
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((
|
|
29962
|
+
return new Promise((resolve11, reject) => {
|
|
29963
29963
|
if (!this.forkProcess) {
|
|
29964
|
-
return
|
|
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
|
-
|
|
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((
|
|
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
|
-
|
|
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
|
-
//
|
|
30126
|
-
var
|
|
30127
|
-
|
|
30128
|
-
|
|
30129
|
-
|
|
30130
|
-
|
|
30131
|
-
|
|
30132
|
-
|
|
30133
|
-
|
|
30134
|
-
|
|
30135
|
-
|
|
30136
|
-
|
|
30137
|
-
|
|
30138
|
-
|
|
30139
|
-
|
|
30140
|
-
|
|
30141
|
-
|
|
30142
|
-
|
|
30143
|
-
|
|
30144
|
-
|
|
30145
|
-
|
|
30146
|
-
|
|
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
|
|
30187
|
-
var
|
|
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,
|
|
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
|
|
30216
|
-
var
|
|
30217
|
-
var loadConfig = (filename = "
|
|
30218
|
-
const filePath = (0,
|
|
30219
|
-
if ((0,
|
|
30220
|
-
return JSON.parse((0,
|
|
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,
|
|
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((
|
|
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((
|
|
31209
|
-
|
|
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((
|
|
32247
|
-
__classPrivateFieldSet(this, _BetaMessageStream_resolveConnectedPromise,
|
|
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((
|
|
32251
|
-
__classPrivateFieldSet(this, _BetaMessageStream_resolveEndPromise,
|
|
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((
|
|
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,
|
|
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((
|
|
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
|
|
32944
|
+
let resolve11;
|
|
32841
32945
|
let reject;
|
|
32842
32946
|
const promise = new Promise((res, rej) => {
|
|
32843
|
-
|
|
32947
|
+
resolve11 = res;
|
|
32844
32948
|
reject = rej;
|
|
32845
32949
|
});
|
|
32846
|
-
return { promise, resolve:
|
|
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((
|
|
33865
|
-
__classPrivateFieldSet(this, _MessageStream_resolveConnectedPromise,
|
|
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((
|
|
33869
|
-
__classPrivateFieldSet(this, _MessageStream_resolveEndPromise,
|
|
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((
|
|
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,
|
|
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((
|
|
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
|
|
35535
|
-
var
|
|
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
|
|
35643
|
+
return import_path11.default.join(process.cwd(), ".tasks");
|
|
35540
35644
|
};
|
|
35541
35645
|
var getGoalPath = (goalId) => {
|
|
35542
|
-
return
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
35595
|
-
(0,
|
|
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
|
|
37679
|
+
var import_fs5 = require("fs");
|
|
37576
37680
|
var import_crypto3 = require("crypto");
|
|
37577
|
-
var
|
|
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 ||
|
|
37685
|
+
return process.env.JOB_PATH || import_path12.default.join(DUCLAW_HOME2, "cron", "jobs.json");
|
|
37580
37686
|
};
|
|
37581
37687
|
var getJobHistoryPath = (date, title) => {
|
|
37582
|
-
|
|
37583
|
-
|
|
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,
|
|
37693
|
+
if (!(0, import_fs5.existsSync)(jsonsPath)) {
|
|
37590
37694
|
const content = `{
|
|
37591
37695
|
"jobs": [
|
|
37592
37696
|
|
|
37593
37697
|
]
|
|
37594
37698
|
}`;
|
|
37595
|
-
(0,
|
|
37699
|
+
(0, import_fs5.writeFileSync)(jsonsPath, content, `utf-8`);
|
|
37596
37700
|
}
|
|
37597
|
-
const text2 = (0,
|
|
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,
|
|
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,
|
|
37734
|
+
(0, import_fs5.writeFileSync)(getJobPath(), JSON.stringify(jobs, null, " "));
|
|
37631
37735
|
return { ...job };
|
|
37632
37736
|
};
|
|
37633
37737
|
var listJobs = () => {
|
|
37634
|
-
const
|
|
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,
|
|
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,
|
|
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,
|
|
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
|
|
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((
|
|
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
|
-
|
|
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,
|
|
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,
|
|
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,
|
|
39726
|
-
(0,
|
|
39841
|
+
if (!(0, import_fs6.existsSync)(dirPath)) {
|
|
39842
|
+
(0, import_fs6.mkdirSync)(dirPath, { recursive: true });
|
|
39727
39843
|
}
|
|
39728
39844
|
let history = [];
|
|
39729
|
-
if ((0,
|
|
39845
|
+
if ((0, import_fs6.existsSync)(filePath)) {
|
|
39730
39846
|
try {
|
|
39731
|
-
const content = (0,
|
|
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,
|
|
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
|
|
39854
|
-
var
|
|
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 =
|
|
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 (!
|
|
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 =
|
|
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
|
|
39990
|
-
var
|
|
39991
|
-
var
|
|
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
|
-
|
|
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,
|
|
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,
|
|
40012
|
-
if ((0,
|
|
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
|
|
40017
|
-
if ((0,
|
|
40018
|
-
paths.push(
|
|
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,
|
|
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,
|
|
40027
|
-
const raw2 = (0,
|
|
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 =
|
|
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,
|
|
40069
|
-
const eachSkillMdPath = (0,
|
|
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
|
|
40422
|
-
var
|
|
40536
|
+
var import_fs10 = require("fs");
|
|
40537
|
+
var import_path16 = __toESM(require("path"));
|
|
40423
40538
|
|
|
40424
40539
|
// src/team/Team.ts
|
|
40425
|
-
var
|
|
40426
|
-
var
|
|
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 =
|
|
40440
|
-
(0,
|
|
40441
|
-
(0,
|
|
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,
|
|
40447
|
-
const text2 = (0,
|
|
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,
|
|
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,
|
|
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,
|
|
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 =
|
|
40503
|
-
(0,
|
|
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,
|
|
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,
|
|
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,
|
|
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((
|
|
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
|
-
|
|
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
|
|
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((
|
|
41710
|
+
return new Promise((resolve11, reject) => {
|
|
41596
41711
|
const chunks = [];
|
|
41597
41712
|
readable.on("data", (chunk) => chunks.push(chunk));
|
|
41598
|
-
readable.on("end", () =>
|
|
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((
|
|
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
|
|
45084
|
-
var
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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
|
|
45323
|
-
var
|
|
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 = () =>
|
|
45327
|
-
var getWorktreePath = (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 =
|
|
45340
|
-
if (!(0,
|
|
45341
|
-
(0,
|
|
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:
|
|
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,
|
|
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 =
|
|
45446
|
-
const parts = relPath.split(
|
|
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:
|
|
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);
|