@qwen-code/qwen-code 0.18.0-preview.2 → 0.18.1
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/bundled/loop/SKILL.md +2 -1
- package/bundled/qc-helper/docs/_meta.ts +1 -0
- package/bundled/qc-helper/docs/configuration/auth.md +1 -1
- package/bundled/qc-helper/docs/configuration/model-providers.md +12 -5
- package/bundled/qc-helper/docs/configuration/settings.md +33 -32
- package/bundled/qc-helper/docs/features/approval-mode.md +10 -14
- package/bundled/qc-helper/docs/features/commands.md +33 -11
- package/bundled/qc-helper/docs/features/dual-output.md +37 -3
- package/bundled/qc-helper/docs/features/followup-suggestions.md +2 -2
- package/bundled/qc-helper/docs/features/skills.md +29 -3
- package/bundled/qc-helper/docs/features/sub-agents.md +34 -12
- package/bundled/qc-helper/docs/qwen-serve-deploy-local.md +221 -0
- package/bundled/qc-helper/docs/qwen-serve.md +246 -28
- package/chunks/{agent-QB7TZ4HW.js → agent-XT7NHZ5H.js} +25 -24
- package/chunks/agent-headless-LNRE63ZL.js +51 -0
- package/chunks/{anthropicContentGenerator-M45EVVRM.js → anthropicContentGenerator-DCI26OQF.js} +7 -7
- package/chunks/{askUserQuestion-WM2KHM3K.js → askUserQuestion-ITYUTWLR.js} +45 -3
- package/chunks/{ca-BARBRL6N.js → ca-RK4QPLIX.js} +18 -1
- package/chunks/{chunk-CWV3SJZS.js → chunk-3NRO6NHX.js} +2 -2
- package/chunks/{chunk-BNESGOSJ.js → chunk-55ZMG67I.js} +1 -1
- package/chunks/{chunk-QCG6KPNM.js → chunk-6T7Y7USE.js} +18017 -11621
- package/chunks/{chunk-CNHFPN7T.js → chunk-7KPZFE5A.js} +1 -1
- package/chunks/{chunk-2ZTWI7KH.js → chunk-A2ZIEEGJ.js} +30 -22
- package/chunks/{chunk-JUGRPQAB.js → chunk-B4ZF2KSI.js} +1 -1
- package/chunks/chunk-BJ5HQ23U.js +178 -0
- package/chunks/{chunk-HXJE7VOG.js → chunk-BXYRCW2C.js} +1074 -144
- package/chunks/{chunk-ICOI4E4S.js → chunk-CPVI5J2L.js} +101 -23
- package/chunks/{chunk-HV3ZZ7G4.js → chunk-DHZREJTG.js} +2 -2
- package/chunks/{chunk-GX7VH5JQ.js → chunk-FIQECJTQ.js} +1 -1
- package/chunks/{chunk-SZOEIL6S.js → chunk-H6BD2ELD.js} +1 -0
- package/chunks/{chunk-JXAZUMDW.js → chunk-HA2UEYZP.js} +7 -4
- package/chunks/{chunk-USE2VQ5P.js → chunk-HED55F43.js} +26 -1
- package/chunks/{chunk-PAEBHDIO.js → chunk-HQUWWSSP.js} +1 -1
- package/chunks/{chunk-MVIVIPCU.js → chunk-IDYDPBBN.js} +361 -583
- package/chunks/{chunk-JVQOQ3OU.js → chunk-IQHSD7K5.js} +1 -1
- package/chunks/{chunk-NW5QBUYO.js → chunk-IS7UA4W3.js} +14 -14
- package/chunks/{chunk-UAMOBVVW.js → chunk-LXYWINWF.js} +1 -1
- package/chunks/{chunk-P4J26VDS.js → chunk-LYRSMKLS.js} +2 -2
- package/chunks/{chunk-Y7R6H6FT.js → chunk-LYSND7KR.js} +9 -4
- package/chunks/{chunk-LR62TEET.js → chunk-NNIYWQIS.js} +1 -1
- package/chunks/chunk-OMX7CUOE.js +356 -0
- package/chunks/{chunk-CNSMKPK6.js → chunk-QILTEBWS.js} +1 -1
- package/chunks/chunk-QQDPRDVW.js +25 -0
- package/chunks/{chunk-ZK4AMNIU.js → chunk-RON7LFNH.js} +1294 -314
- package/chunks/chunk-SFRV6BGY.js +243 -0
- package/chunks/{chunk-AVW55ZCO.js → chunk-WJ3SND6W.js} +37 -16
- package/chunks/{chunk-HGJPQK33.js → chunk-WPTCDQN6.js} +188 -534
- package/chunks/{chunk-7YKXFA3D.js → chunk-XZTNBSMW.js} +11 -11
- package/chunks/{chunk-C6WMLUNB.js → chunk-Y7KMDUEP.js} +1 -1
- package/chunks/{chunk-WFVXF3OM.js → chunk-Z2Z3GUXZ.js} +1 -0
- package/chunks/{chunk-KC6ZMJ5X.js → chunk-ZMIBJS45.js} +1 -1
- package/chunks/chunk-ZOFNJQNJ.js +607 -0
- package/chunks/computer-use-4YX3JGBV.js +2052 -0
- package/chunks/contextCommand-KS2H7MW5.js +53 -0
- package/chunks/cron-create-CAPUKK7I.js +184 -0
- package/chunks/{cron-delete-ZGUXWBTG.js → cron-delete-G3KAR26Q.js} +28 -5
- package/chunks/{cron-list-QNNZGMN3.js → cron-list-ZA4ZIUS5.js} +40 -7
- package/chunks/{de-YGKK2BC4.js → de-FGPM4KW5.js} +18 -1
- package/chunks/{devtools-IXE4UP72.js → devtools-FM6GJPYG.js} +1 -1
- package/chunks/{dist-ZMQ4TXD5.js → dist-7YWFWOCJ.js} +2 -2
- package/chunks/{dist-R2SXPG74.js → dist-VEGFONCF.js} +2 -2
- package/chunks/{dist-TE5QKMGR.js → dist-X4EXN7W6.js} +1 -1
- package/chunks/{dist-BXDUQ2QY.js → dist-YLS6NI7H.js} +1 -1
- package/chunks/{edit-6UBTS2J5.js → edit-2ARPEO4B.js} +26 -25
- package/chunks/{en-HSQQNQUB.js → en-VP6XPGEC.js} +9 -2
- package/chunks/{enter-worktree-NN7LIXCM.js → enter-worktree-IXNXNAW5.js} +25 -24
- package/chunks/enterPlanMode-TAKAGAYP.js +159 -0
- package/chunks/{exit-worktree-GGSS5KIE.js → exit-worktree-LHTRV7ML.js} +25 -24
- package/chunks/exitPlanMode-MK5UAITL.js +743 -0
- package/chunks/{fr-JXBKPJKQ.js → fr-ATYBVCLT.js} +18 -1
- package/chunks/{geminiContentGenerator-I4H2NLJG.js → geminiContentGenerator-HFJIGO77.js} +7 -7
- package/chunks/{getMachineId-bsd-F7GNPTER.js → getMachineId-bsd-4CASPIU4.js} +1 -1
- package/chunks/{getMachineId-darwin-T73DJL27.js → getMachineId-darwin-HPQPEMZR.js} +1 -1
- package/chunks/{getMachineId-linux-MKQTFPQM.js → getMachineId-linux-AUARKYHL.js} +1 -1
- package/chunks/{getMachineId-unsupported-MUR5KOQE.js → getMachineId-unsupported-S32ZDA2T.js} +1 -1
- package/chunks/{getMachineId-win-CDYFC6ZM.js → getMachineId-win-4EFLHYIJ.js} +1 -1
- package/chunks/{glob-OLCX57MD.js → glob-I2USLUSC.js} +25 -24
- package/chunks/{grep-7HXIMDOW.js → grep-WBIF7THR.js} +37 -30
- package/chunks/{ja-TGPZSP2B.js → ja-W2QEA2OI.js} +18 -1
- package/chunks/{keychain-token-storage-LB46DAEK.js → keychain-token-storage-QSTRHKKL.js} +3 -3
- package/chunks/{ls-6PEZUK6O.js → ls-2R5RHLX5.js} +4 -4
- package/chunks/{lsp-JZSJOVT7.js → lsp-XKH6ZIAN.js} +3 -3
- package/chunks/{monitor-SQO7MVAV.js → monitor-WU7UFATU.js} +25 -24
- package/chunks/{notebook-edit-72L3EBAL.js → notebook-edit-KUHYPXEM.js} +26 -25
- package/chunks/{openaiContentGenerator-FTR7CDWF.js → openaiContentGenerator-5PLHYJQL.js} +15 -15
- package/chunks/{pt-TIBG6BIO.js → pt-ZKEWJFBW.js} +18 -1
- package/chunks/{qwenContentGenerator-U5UFQ566.js → qwenContentGenerator-TSKW73KY.js} +27 -26
- package/chunks/{qwenOAuth2-EFSECGHF.js → qwenOAuth2-KK433U33.js} +6 -5
- package/chunks/{read-file-UA64EEQC.js → read-file-VIPF2PS6.js} +11 -11
- package/chunks/ripGrep-XLIZTYE7.js +49 -0
- package/chunks/{ru-JBCHCK4L.js → ru-VEKTPJ74.js} +18 -1
- package/chunks/{scheduler-VBASHOCA.js → scheduler-O66SLJGU.js} +25 -24
- package/chunks/{send-message-OYJZ5TPG.js → send-message-CTME7DXD.js} +3 -3
- package/chunks/{serve-A7E2OJDR.js → serve-BWOLYT62.js} +13164 -3840
- package/chunks/{shell-3NFOT6F5.js → shell-XE7UYKOO.js} +25 -24
- package/chunks/{skill-RA5YUREY.js → skill-RZWM6XMC.js} +64 -113
- package/chunks/{src-NFCMARMT.js → src-L5P7K4MH.js} +176 -44
- package/chunks/{syntheticOutput-DETQ2YM6.js → syntheticOutput-ZJGSU7OQ.js} +4 -4
- package/chunks/{task-create-Y3ZKTJIG.js → task-create-EE6JEM7G.js} +8 -7
- package/chunks/{task-list-ONXJ3I3A.js → task-list-EESYAC65.js} +7 -6
- package/chunks/{task-stop-UHDC4N5B.js → task-stop-XZVCFFYY.js} +3 -3
- package/chunks/{task-update-TCNOU3P5.js → task-update-EIO4HNE3.js} +21 -9
- package/chunks/{team-create-6SR4OVRG.js → team-create-R2H7Y3SG.js} +28 -26
- package/chunks/{team-delete-EJ4U4DDP.js → team-delete-A7LXPGV7.js} +9 -6
- package/chunks/{todoWrite-TEYDRS5L.js → todoWrite-VRKSGAWM.js} +5 -5
- package/chunks/{tool-search-OD435A3X.js → tool-search-USSQMTMS.js} +11 -11
- package/chunks/{web-fetch-6W67H5PO.js → web-fetch-GHAZUA54.js} +5 -5
- package/chunks/workflow-5LNNLNUR.js +1414 -0
- package/chunks/{write-file-475L5OPP.js → write-file-2I7HP24C.js} +26 -25
- package/chunks/{zh-VCLWO26Y.js → zh-OIXDDQHB.js} +10 -3
- package/chunks/{zh-TW-G3HFHVVT.js → zh-TW-6YFNCKTA.js} +10 -3
- package/cli-entry.js +19 -0
- package/cli.js +11064 -6628
- package/examples/starter/QWEN.md +30 -0
- package/examples/starter/README.md +59 -0
- package/examples/starter/agents/diary.md +86 -0
- package/examples/starter/commands/writing/polish.md +13 -0
- package/examples/starter/example.ts +64 -0
- package/examples/starter/package.json +18 -0
- package/examples/starter/qwen-extension.json +12 -0
- package/examples/starter/skills/synonyms/SKILL.md +48 -0
- package/examples/starter/tsconfig.json +13 -0
- package/fzfWorker.js +1083 -0
- package/locales/ca.js +20 -2
- package/locales/de.js +21 -2
- package/locales/en.js +13 -4
- package/locales/fr.js +22 -2
- package/locales/ja.js +22 -2
- package/locales/pt.js +21 -2
- package/locales/ru.js +20 -2
- package/locales/zh-TW.js +11 -4
- package/locales/zh.js +11 -4
- package/package.json +5 -3
- package/chunks/agent-headless-APVHH7QM.js +0 -50
- package/chunks/chunk-AJIR24J2.js +0 -59
- package/chunks/chunk-SKBPNJEW.js +0 -45
- package/chunks/chunk-XBFVXFB2.js +0 -216
- package/chunks/computer-use-B7VIUI7F.js +0 -825
- package/chunks/contextCommand-63RZ3O5R.js +0 -52
- package/chunks/cron-create-FI5LJVUS.js +0 -140
- package/chunks/exitPlanMode-H323NHB2.js +0 -235
- package/chunks/ripGrep-WSYCWZVK.js +0 -48
- package/chunks/workflow-62DHH4EO.js +0 -708
|
@@ -1,23 +1,27 @@
|
|
|
1
1
|
// Force strict mode and setup for ESM
|
|
2
2
|
"use strict";
|
|
3
3
|
import {
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
INBOXES_DIR,
|
|
5
|
+
LEADER_NAME,
|
|
6
|
+
TASKS_DIR,
|
|
7
|
+
TEAMMATE_COLORS,
|
|
8
|
+
TEAMS_DIR,
|
|
9
|
+
TEAM_CONFIG_FILENAME
|
|
10
|
+
} from "./chunk-LD2XBG6Z.js";
|
|
6
11
|
import {
|
|
7
12
|
atomicWriteJSON
|
|
8
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-LXYWINWF.js";
|
|
9
14
|
import {
|
|
10
|
-
|
|
15
|
+
Storage,
|
|
11
16
|
isNodeError
|
|
12
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-HA2UEYZP.js";
|
|
13
18
|
import {
|
|
14
19
|
init_esbuild_shims
|
|
15
20
|
} from "./chunk-A4BMJM77.js";
|
|
16
21
|
import {
|
|
17
22
|
__commonJS,
|
|
18
23
|
__name,
|
|
19
|
-
__require
|
|
20
|
-
__toESM
|
|
24
|
+
__require
|
|
21
25
|
} from "./chunk-J2S4EL5Y.js";
|
|
22
26
|
|
|
23
27
|
// node_modules/graceful-fs/polyfills.js
|
|
@@ -88,7 +92,7 @@ var require_polyfills = __commonJS({
|
|
|
88
92
|
}
|
|
89
93
|
if (platform === "win32") {
|
|
90
94
|
fs2.rename = typeof fs2.rename !== "function" ? fs2.rename : function(fs$rename) {
|
|
91
|
-
function
|
|
95
|
+
function rename(from, to, cb) {
|
|
92
96
|
var start = Date.now();
|
|
93
97
|
var backoff = 0;
|
|
94
98
|
fs$rename(from, to, /* @__PURE__ */ __name(function CB(er) {
|
|
@@ -108,9 +112,9 @@ var require_polyfills = __commonJS({
|
|
|
108
112
|
if (cb) cb(er);
|
|
109
113
|
}, "CB"));
|
|
110
114
|
}
|
|
111
|
-
__name(
|
|
112
|
-
if (Object.setPrototypeOf) Object.setPrototypeOf(
|
|
113
|
-
return
|
|
115
|
+
__name(rename, "rename");
|
|
116
|
+
if (Object.setPrototypeOf) Object.setPrototypeOf(rename, fs$rename);
|
|
117
|
+
return rename;
|
|
114
118
|
}(fs2.rename);
|
|
115
119
|
}
|
|
116
120
|
fs2.read = typeof fs2.read !== "function" ? fs2.read : function(fs$read) {
|
|
@@ -476,11 +480,11 @@ var require_graceful_fs = __commonJS({
|
|
|
476
480
|
});
|
|
477
481
|
}
|
|
478
482
|
__name(publishQueue, "publishQueue");
|
|
479
|
-
var
|
|
483
|
+
var debug = noop;
|
|
480
484
|
if (util.debuglog)
|
|
481
|
-
|
|
485
|
+
debug = util.debuglog("gfs4");
|
|
482
486
|
else if (/\bgfs4\b/i.test(process.env.NODE_DEBUG || ""))
|
|
483
|
-
|
|
487
|
+
debug = /* @__PURE__ */ __name(function() {
|
|
484
488
|
var m = util.format.apply(util, arguments);
|
|
485
489
|
m = "GFS4: " + m.split(/\n/).join("\nGFS4: ");
|
|
486
490
|
console.error(m);
|
|
@@ -517,7 +521,7 @@ var require_graceful_fs = __commonJS({
|
|
|
517
521
|
}(fs2.closeSync);
|
|
518
522
|
if (/\bgfs4\b/i.test(process.env.NODE_DEBUG || "")) {
|
|
519
523
|
process.on("exit", function() {
|
|
520
|
-
|
|
524
|
+
debug(fs2[gracefulQueue]);
|
|
521
525
|
__require("assert").equal(fs2[gracefulQueue].length, 0);
|
|
522
526
|
});
|
|
523
527
|
}
|
|
@@ -556,8 +560,8 @@ var require_graceful_fs = __commonJS({
|
|
|
556
560
|
}
|
|
557
561
|
__name(readFile2, "readFile");
|
|
558
562
|
var fs$writeFile = fs3.writeFile;
|
|
559
|
-
fs3.writeFile =
|
|
560
|
-
function
|
|
563
|
+
fs3.writeFile = writeFile2;
|
|
564
|
+
function writeFile2(path2, data, options, cb) {
|
|
561
565
|
if (typeof options === "function")
|
|
562
566
|
cb = options, options = null;
|
|
563
567
|
return go$writeFile(path2, data, options, cb);
|
|
@@ -573,7 +577,7 @@ var require_graceful_fs = __commonJS({
|
|
|
573
577
|
}
|
|
574
578
|
__name(go$writeFile, "go$writeFile");
|
|
575
579
|
}
|
|
576
|
-
__name(
|
|
580
|
+
__name(writeFile2, "writeFile");
|
|
577
581
|
var fs$appendFile = fs3.appendFile;
|
|
578
582
|
if (fs$appendFile)
|
|
579
583
|
fs3.appendFile = appendFile;
|
|
@@ -725,7 +729,7 @@ var require_graceful_fs = __commonJS({
|
|
|
725
729
|
__name(ReadStream, "ReadStream");
|
|
726
730
|
function ReadStream$open() {
|
|
727
731
|
var that = this;
|
|
728
|
-
|
|
732
|
+
open(that.path, that.flags, that.mode, function(err, fd) {
|
|
729
733
|
if (err) {
|
|
730
734
|
if (that.autoClose)
|
|
731
735
|
that.destroy();
|
|
@@ -747,7 +751,7 @@ var require_graceful_fs = __commonJS({
|
|
|
747
751
|
__name(WriteStream, "WriteStream");
|
|
748
752
|
function WriteStream$open() {
|
|
749
753
|
var that = this;
|
|
750
|
-
|
|
754
|
+
open(that.path, that.flags, that.mode, function(err, fd) {
|
|
751
755
|
if (err) {
|
|
752
756
|
that.destroy();
|
|
753
757
|
that.emit("error", err);
|
|
@@ -767,8 +771,8 @@ var require_graceful_fs = __commonJS({
|
|
|
767
771
|
}
|
|
768
772
|
__name(createWriteStream, "createWriteStream");
|
|
769
773
|
var fs$open = fs3.open;
|
|
770
|
-
fs3.open =
|
|
771
|
-
function
|
|
774
|
+
fs3.open = open;
|
|
775
|
+
function open(path2, flags, mode, cb) {
|
|
772
776
|
if (typeof mode === "function")
|
|
773
777
|
cb = mode, mode = null;
|
|
774
778
|
return go$open(path2, flags, mode, cb);
|
|
@@ -784,12 +788,12 @@ var require_graceful_fs = __commonJS({
|
|
|
784
788
|
}
|
|
785
789
|
__name(go$open, "go$open");
|
|
786
790
|
}
|
|
787
|
-
__name(
|
|
791
|
+
__name(open, "open");
|
|
788
792
|
return fs3;
|
|
789
793
|
}
|
|
790
794
|
__name(patch, "patch");
|
|
791
795
|
function enqueue(elem) {
|
|
792
|
-
|
|
796
|
+
debug("ENQUEUE", elem[0].name, elem[1]);
|
|
793
797
|
fs2[gracefulQueue].push(elem);
|
|
794
798
|
retry();
|
|
795
799
|
}
|
|
@@ -818,10 +822,10 @@ var require_graceful_fs = __commonJS({
|
|
|
818
822
|
var startTime = elem[3];
|
|
819
823
|
var lastTime = elem[4];
|
|
820
824
|
if (startTime === void 0) {
|
|
821
|
-
|
|
825
|
+
debug("RETRY", fn.name, args);
|
|
822
826
|
fn.apply(null, args);
|
|
823
827
|
} else if (Date.now() - startTime >= 6e4) {
|
|
824
|
-
|
|
828
|
+
debug("TIMEOUT", fn.name, args);
|
|
825
829
|
var cb = args.pop();
|
|
826
830
|
if (typeof cb === "function")
|
|
827
831
|
cb.call(null, err);
|
|
@@ -830,7 +834,7 @@ var require_graceful_fs = __commonJS({
|
|
|
830
834
|
var sinceStart = Math.max(lastTime - startTime, 1);
|
|
831
835
|
var desiredDelay = Math.min(sinceStart * 1.2, 100);
|
|
832
836
|
if (sinceAttempt >= desiredDelay) {
|
|
833
|
-
|
|
837
|
+
debug("RETRY", fn.name, args);
|
|
834
838
|
fn.apply(null, args.concat([startTime]));
|
|
835
839
|
} else {
|
|
836
840
|
fs2[gracefulQueue].push(elem);
|
|
@@ -1193,8 +1197,8 @@ var require_signal_exit = __commonJS({
|
|
|
1193
1197
|
if (!processOk(globalThis.process)) {
|
|
1194
1198
|
return;
|
|
1195
1199
|
}
|
|
1196
|
-
var
|
|
1197
|
-
if (
|
|
1200
|
+
var listeners = process2.listeners(sig);
|
|
1201
|
+
if (listeners.length === emitter.count) {
|
|
1198
1202
|
unload();
|
|
1199
1203
|
emit("exit", null, sig);
|
|
1200
1204
|
emit("afterexit", null, sig);
|
|
@@ -1639,32 +1643,32 @@ var require_proper_lockfile = __commonJS({
|
|
|
1639
1643
|
"node_modules/proper-lockfile/index.js"(exports, module) {
|
|
1640
1644
|
"use strict";
|
|
1641
1645
|
init_esbuild_shims();
|
|
1642
|
-
var
|
|
1646
|
+
var lockfile = require_lockfile();
|
|
1643
1647
|
var { toPromise, toSync, toSyncOptions } = require_adapter();
|
|
1644
1648
|
async function lock(file, options) {
|
|
1645
|
-
const release = await toPromise(
|
|
1649
|
+
const release = await toPromise(lockfile.lock)(file, options);
|
|
1646
1650
|
return toPromise(release);
|
|
1647
1651
|
}
|
|
1648
1652
|
__name(lock, "lock");
|
|
1649
1653
|
function lockSync(file, options) {
|
|
1650
|
-
const release = toSync(
|
|
1654
|
+
const release = toSync(lockfile.lock)(file, toSyncOptions(options));
|
|
1651
1655
|
return toSync(release);
|
|
1652
1656
|
}
|
|
1653
1657
|
__name(lockSync, "lockSync");
|
|
1654
1658
|
function unlock(file, options) {
|
|
1655
|
-
return toPromise(
|
|
1659
|
+
return toPromise(lockfile.unlock)(file, options);
|
|
1656
1660
|
}
|
|
1657
1661
|
__name(unlock, "unlock");
|
|
1658
1662
|
function unlockSync(file, options) {
|
|
1659
|
-
return toSync(
|
|
1663
|
+
return toSync(lockfile.unlock)(file, toSyncOptions(options));
|
|
1660
1664
|
}
|
|
1661
1665
|
__name(unlockSync, "unlockSync");
|
|
1662
1666
|
function check(file, options) {
|
|
1663
|
-
return toPromise(
|
|
1667
|
+
return toPromise(lockfile.check)(file, options);
|
|
1664
1668
|
}
|
|
1665
1669
|
__name(check, "check");
|
|
1666
1670
|
function checkSync(file, options) {
|
|
1667
|
-
return toSync(
|
|
1671
|
+
return toSync(lockfile.check)(file, toSyncOptions(options));
|
|
1668
1672
|
}
|
|
1669
1673
|
__name(checkSync, "checkSync");
|
|
1670
1674
|
module.exports = lock;
|
|
@@ -1677,552 +1681,202 @@ var require_proper_lockfile = __commonJS({
|
|
|
1677
1681
|
}
|
|
1678
1682
|
});
|
|
1679
1683
|
|
|
1680
|
-
// packages/core/src/agents/team/
|
|
1684
|
+
// packages/core/src/agents/team/teamHelpers.ts
|
|
1681
1685
|
init_esbuild_shims();
|
|
1682
|
-
var import_proper_lockfile = __toESM(require_proper_lockfile(), 1);
|
|
1683
1686
|
import * as fs from "node:fs/promises";
|
|
1684
|
-
import { constants as fsConstants } from "node:fs";
|
|
1685
1687
|
import * as path from "node:path";
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
var MAX_PARALLEL_TASK_READS = 16;
|
|
1689
|
-
function assertMetadataWithinLimit(metadata) {
|
|
1690
|
-
if (!metadata) return;
|
|
1691
|
-
const size = Buffer.byteLength(JSON.stringify(metadata), "utf-8");
|
|
1692
|
-
if (size > MAX_METADATA_BYTES) {
|
|
1693
|
-
throw new Error(
|
|
1694
|
-
`Task metadata is too large (${size} bytes; max ${MAX_METADATA_BYTES}). Trim the payload or store the bulk content elsewhere.`
|
|
1695
|
-
);
|
|
1696
|
-
}
|
|
1688
|
+
function getTeamsRootDir() {
|
|
1689
|
+
return path.join(Storage.getGlobalQwenDir(), TEAMS_DIR);
|
|
1697
1690
|
}
|
|
1698
|
-
__name(
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
retries: 30,
|
|
1702
|
-
minTimeout: 5,
|
|
1703
|
-
maxTimeout: 100,
|
|
1704
|
-
factor: 2
|
|
1705
|
-
},
|
|
1706
|
-
stale: 5e3,
|
|
1707
|
-
onCompromised: /* @__PURE__ */ __name((err) => {
|
|
1708
|
-
debug.warn("task lock compromised:", err?.message ?? err);
|
|
1709
|
-
}, "onCompromised")
|
|
1710
|
-
};
|
|
1711
|
-
function assertValidTaskId(taskId) {
|
|
1712
|
-
if (!/^[1-9]\d*$/.test(taskId)) {
|
|
1713
|
-
throw new Error(
|
|
1714
|
-
`Invalid task ID "${taskId}". Task IDs must be positive integers.`
|
|
1715
|
-
);
|
|
1716
|
-
}
|
|
1691
|
+
__name(getTeamsRootDir, "getTeamsRootDir");
|
|
1692
|
+
function getTeamDir(teamName) {
|
|
1693
|
+
return path.join(getTeamsRootDir(), teamName);
|
|
1717
1694
|
}
|
|
1718
|
-
__name(
|
|
1719
|
-
function
|
|
1720
|
-
|
|
1721
|
-
return path.join(getTasksDir(teamName), `${taskId}.json`);
|
|
1695
|
+
__name(getTeamDir, "getTeamDir");
|
|
1696
|
+
function getTeamFilePath(teamName) {
|
|
1697
|
+
return path.join(getTeamDir(teamName), TEAM_CONFIG_FILENAME);
|
|
1722
1698
|
}
|
|
1723
|
-
__name(
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
listeners.add(listener);
|
|
1727
|
-
return () => {
|
|
1728
|
-
listeners.delete(listener);
|
|
1729
|
-
};
|
|
1699
|
+
__name(getTeamFilePath, "getTeamFilePath");
|
|
1700
|
+
function getInboxesDir(teamName) {
|
|
1701
|
+
return path.join(getTeamDir(teamName), INBOXES_DIR);
|
|
1730
1702
|
}
|
|
1731
|
-
__name(
|
|
1732
|
-
function
|
|
1733
|
-
|
|
1734
|
-
try {
|
|
1735
|
-
listener(teamName);
|
|
1736
|
-
} catch (err) {
|
|
1737
|
-
debug.warn(`task update listener failed: ${err}`);
|
|
1738
|
-
}
|
|
1739
|
-
}
|
|
1703
|
+
__name(getInboxesDir, "getInboxesDir");
|
|
1704
|
+
function getTasksDir(teamName) {
|
|
1705
|
+
return path.join(Storage.getGlobalQwenDir(), TASKS_DIR, teamName);
|
|
1740
1706
|
}
|
|
1741
|
-
__name(
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
const dir = getTasksDir(teamName);
|
|
1745
|
-
await fs.mkdir(dir, { recursive: true });
|
|
1746
|
-
const MAX_RETRIES = 15;
|
|
1747
|
-
for (let attempt = 0; attempt < MAX_RETRIES; attempt++) {
|
|
1748
|
-
const nextId = await getNextTaskId(dir);
|
|
1749
|
-
const task = {
|
|
1750
|
-
id: nextId,
|
|
1751
|
-
subject: opts.subject,
|
|
1752
|
-
description: opts.description,
|
|
1753
|
-
activeForm: opts.activeForm,
|
|
1754
|
-
owner: opts.owner,
|
|
1755
|
-
status: "pending",
|
|
1756
|
-
blocks: [],
|
|
1757
|
-
blockedBy: [],
|
|
1758
|
-
metadata: opts.metadata
|
|
1759
|
-
};
|
|
1760
|
-
const taskPath = path.join(dir, `${nextId}.json`);
|
|
1761
|
-
try {
|
|
1762
|
-
const handle = await fs.open(
|
|
1763
|
-
taskPath,
|
|
1764
|
-
fsConstants.O_WRONLY | fsConstants.O_CREAT | fsConstants.O_EXCL
|
|
1765
|
-
);
|
|
1766
|
-
await handle.close();
|
|
1767
|
-
} catch (err) {
|
|
1768
|
-
if (isNodeError(err) && err.code === "EEXIST") {
|
|
1769
|
-
continue;
|
|
1770
|
-
}
|
|
1771
|
-
throw err;
|
|
1772
|
-
}
|
|
1773
|
-
try {
|
|
1774
|
-
await atomicWriteJSON(taskPath, task);
|
|
1775
|
-
} catch (err) {
|
|
1776
|
-
await fs.unlink(taskPath).catch(() => {
|
|
1777
|
-
});
|
|
1778
|
-
throw err;
|
|
1779
|
-
}
|
|
1780
|
-
notifyTasksUpdated(teamName);
|
|
1781
|
-
return task;
|
|
1782
|
-
}
|
|
1783
|
-
throw new Error(
|
|
1784
|
-
`Failed to create task after ${MAX_RETRIES} attempts (ID contention).`
|
|
1785
|
-
);
|
|
1707
|
+
__name(getTasksDir, "getTasksDir");
|
|
1708
|
+
function sanitizeName(name) {
|
|
1709
|
+
return name.toLowerCase().replace(/[^a-z0-9-]/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "");
|
|
1786
1710
|
}
|
|
1787
|
-
__name(
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
try {
|
|
1791
|
-
const raw = await fs.readFile(taskPath, "utf-8");
|
|
1792
|
-
return JSON.parse(raw);
|
|
1793
|
-
} catch (err) {
|
|
1794
|
-
if (isNodeError(err) && err.code === "ENOENT") return void 0;
|
|
1795
|
-
throw err;
|
|
1796
|
-
}
|
|
1711
|
+
__name(sanitizeName, "sanitizeName");
|
|
1712
|
+
function formatAgentId(name, teamName) {
|
|
1713
|
+
return `${sanitizeName(name)}@${sanitizeName(teamName)}`;
|
|
1797
1714
|
}
|
|
1798
|
-
__name(
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1715
|
+
__name(formatAgentId, "formatAgentId");
|
|
1716
|
+
function generateUniqueTeammateName(baseName, existingMembers) {
|
|
1717
|
+
const sanitized = sanitizeName(baseName);
|
|
1718
|
+
if (!sanitized) {
|
|
1719
|
+
throw new Error(
|
|
1720
|
+
`Teammate name "${baseName}" sanitizes to an empty string. Choose a name with at least one alphanumeric character.`
|
|
1803
1721
|
);
|
|
1804
|
-
this.taskId = taskId;
|
|
1805
|
-
this.callerName = callerName;
|
|
1806
|
-
this.actualOwner = actualOwner;
|
|
1807
|
-
this.name = "TaskOwnershipError";
|
|
1808
1722
|
}
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
async function updateTask(teamName, taskId, updates, opts) {
|
|
1814
|
-
const taskPath = getTaskPath(teamName, taskId);
|
|
1815
|
-
let release;
|
|
1816
|
-
try {
|
|
1817
|
-
release = await import_proper_lockfile.default.lock(taskPath, LOCK_OPTIONS);
|
|
1818
|
-
} catch (err) {
|
|
1819
|
-
if (isNodeError(err) && err.code === "ENOENT") return void 0;
|
|
1820
|
-
throw err;
|
|
1723
|
+
if (sanitized === LEADER_NAME) {
|
|
1724
|
+
throw new Error(
|
|
1725
|
+
`"${LEADER_NAME}" is reserved for the team leader. Choose a different teammate name.`
|
|
1726
|
+
);
|
|
1821
1727
|
}
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
throw err;
|
|
1829
|
-
}
|
|
1830
|
-
const task = JSON.parse(raw);
|
|
1831
|
-
if (opts?.callerName !== void 0) {
|
|
1832
|
-
const restrictsOwnership = updates.status !== void 0 || updates.owner !== void 0 || updates.subject !== void 0 || updates.description !== void 0 || (updates.addBlocks?.length ?? 0) > 0 || (updates.addBlockedBy?.length ?? 0) > 0;
|
|
1833
|
-
if (restrictsOwnership && task.owner && task.owner !== opts.callerName) {
|
|
1834
|
-
throw new TaskOwnershipError(taskId, opts.callerName, task.owner);
|
|
1835
|
-
}
|
|
1836
|
-
}
|
|
1837
|
-
if (updates.addBlocks?.length) {
|
|
1838
|
-
const blockSet = new Set(task.blocks);
|
|
1839
|
-
for (const id of updates.addBlocks) blockSet.add(id);
|
|
1840
|
-
task.blocks = Array.from(blockSet);
|
|
1841
|
-
}
|
|
1842
|
-
if (updates.addBlockedBy?.length) {
|
|
1843
|
-
const blockedBySet = new Set(task.blockedBy);
|
|
1844
|
-
for (const id of updates.addBlockedBy) blockedBySet.add(id);
|
|
1845
|
-
task.blockedBy = Array.from(blockedBySet);
|
|
1846
|
-
}
|
|
1847
|
-
if (updates.status !== void 0) {
|
|
1848
|
-
task.status = updates.status;
|
|
1849
|
-
if (updates.status === "completed" && task.blocks.length > 0) {
|
|
1850
|
-
await unblockDependents(teamName, taskId, task.blocks);
|
|
1851
|
-
}
|
|
1852
|
-
}
|
|
1853
|
-
if (updates.owner !== void 0) {
|
|
1854
|
-
task.owner = updates.owner ? updates.owner : void 0;
|
|
1855
|
-
}
|
|
1856
|
-
if (updates.subject !== void 0) {
|
|
1857
|
-
task.subject = updates.subject;
|
|
1858
|
-
}
|
|
1859
|
-
if (updates.description !== void 0) {
|
|
1860
|
-
task.description = updates.description;
|
|
1861
|
-
}
|
|
1862
|
-
if (updates.activeForm !== void 0) {
|
|
1863
|
-
task.activeForm = updates.activeForm ?? void 0;
|
|
1864
|
-
}
|
|
1865
|
-
if (updates.metadata !== void 0) {
|
|
1866
|
-
task.metadata = task.metadata ?? {};
|
|
1867
|
-
for (const [key, value] of Object.entries(updates.metadata)) {
|
|
1868
|
-
if (key === "__proto__" || key === "constructor" || key === "prototype") {
|
|
1869
|
-
continue;
|
|
1870
|
-
}
|
|
1871
|
-
if (value === null) {
|
|
1872
|
-
delete task.metadata[key];
|
|
1873
|
-
} else {
|
|
1874
|
-
task.metadata[key] = value;
|
|
1875
|
-
}
|
|
1876
|
-
}
|
|
1877
|
-
if (Object.keys(task.metadata).length === 0) {
|
|
1878
|
-
task.metadata = void 0;
|
|
1879
|
-
}
|
|
1880
|
-
assertMetadataWithinLimit(task.metadata);
|
|
1881
|
-
}
|
|
1882
|
-
await atomicWriteJSON(taskPath, task);
|
|
1883
|
-
notifyTasksUpdated(teamName);
|
|
1884
|
-
return task;
|
|
1885
|
-
} finally {
|
|
1886
|
-
await release?.();
|
|
1728
|
+
const existingNames = new Set(existingMembers.map((m) => m.name));
|
|
1729
|
+
if (existingNames.has(sanitized)) {
|
|
1730
|
+
const existingList = [...existingNames].join(", ") || "<none>";
|
|
1731
|
+
throw new Error(
|
|
1732
|
+
`A teammate named "${sanitized}" already exists in this team (existing: ${existingList}). Choose a different name.`
|
|
1733
|
+
);
|
|
1887
1734
|
}
|
|
1735
|
+
return sanitized;
|
|
1888
1736
|
}
|
|
1889
|
-
__name(
|
|
1890
|
-
|
|
1891
|
-
const
|
|
1892
|
-
|
|
1893
|
-
try {
|
|
1894
|
-
release = await import_proper_lockfile.default.lock(taskPath, LOCK_OPTIONS);
|
|
1895
|
-
} catch (err) {
|
|
1896
|
-
if (isNodeError(err) && err.code === "ENOENT") return false;
|
|
1897
|
-
throw err;
|
|
1898
|
-
}
|
|
1899
|
-
let dependentIds = /* @__PURE__ */ new Set();
|
|
1900
|
-
try {
|
|
1901
|
-
let task;
|
|
1902
|
-
try {
|
|
1903
|
-
const raw = await fs.readFile(taskPath, "utf-8");
|
|
1904
|
-
task = JSON.parse(raw);
|
|
1905
|
-
} catch (err) {
|
|
1906
|
-
if (isNodeError(err) && err.code === "ENOENT") return false;
|
|
1907
|
-
throw err;
|
|
1908
|
-
}
|
|
1909
|
-
if (opts?.callerName !== void 0 && task.owner && task.owner !== opts.callerName) {
|
|
1910
|
-
throw new TaskOwnershipError(taskId, opts.callerName, task.owner);
|
|
1911
|
-
}
|
|
1912
|
-
dependentIds = /* @__PURE__ */ new Set([...task.blocks, ...task.blockedBy]);
|
|
1913
|
-
dependentIds.delete(taskId);
|
|
1914
|
-
try {
|
|
1915
|
-
await fs.unlink(taskPath);
|
|
1916
|
-
} catch (err) {
|
|
1917
|
-
if (isNodeError(err) && err.code === "ENOENT") return false;
|
|
1918
|
-
throw err;
|
|
1919
|
-
}
|
|
1920
|
-
} finally {
|
|
1921
|
-
await release();
|
|
1922
|
-
}
|
|
1923
|
-
const results = await Promise.allSettled(
|
|
1924
|
-
Array.from(dependentIds).map(
|
|
1925
|
-
(depId) => removeEdgesReferencing(teamName, depId, taskId)
|
|
1926
|
-
)
|
|
1737
|
+
__name(generateUniqueTeammateName, "generateUniqueTeammateName");
|
|
1738
|
+
function assignTeammateColor(existingMembers) {
|
|
1739
|
+
const usedColors = new Set(
|
|
1740
|
+
existingMembers.map((m) => m.color).filter((c) => c !== void 0)
|
|
1927
1741
|
);
|
|
1928
|
-
for (const
|
|
1929
|
-
if (
|
|
1930
|
-
|
|
1931
|
-
}
|
|
1932
|
-
}
|
|
1933
|
-
notifyTasksUpdated(teamName);
|
|
1934
|
-
return true;
|
|
1935
|
-
}
|
|
1936
|
-
__name(deleteTask, "deleteTask");
|
|
1937
|
-
async function removeEdgesReferencing(teamName, targetId, referencedId) {
|
|
1938
|
-
const depPath = getTaskPath(teamName, targetId);
|
|
1939
|
-
let release;
|
|
1940
|
-
try {
|
|
1941
|
-
release = await import_proper_lockfile.default.lock(depPath, LOCK_OPTIONS);
|
|
1942
|
-
} catch (err) {
|
|
1943
|
-
if (isNodeError(err) && err.code === "ENOENT") return;
|
|
1944
|
-
throw err;
|
|
1945
|
-
}
|
|
1946
|
-
try {
|
|
1947
|
-
const raw = await fs.readFile(depPath, "utf-8");
|
|
1948
|
-
const task = JSON.parse(raw);
|
|
1949
|
-
const beforeBlocks = task.blocks.length;
|
|
1950
|
-
const beforeBlockedBy = task.blockedBy.length;
|
|
1951
|
-
task.blocks = task.blocks.filter((id) => id !== referencedId);
|
|
1952
|
-
task.blockedBy = task.blockedBy.filter((id) => id !== referencedId);
|
|
1953
|
-
if (task.blocks.length === beforeBlocks && task.blockedBy.length === beforeBlockedBy) {
|
|
1954
|
-
return;
|
|
1742
|
+
for (const color of TEAMMATE_COLORS) {
|
|
1743
|
+
if (!usedColors.has(color)) {
|
|
1744
|
+
return color;
|
|
1955
1745
|
}
|
|
1956
|
-
await atomicWriteJSON(depPath, task);
|
|
1957
|
-
} catch (err) {
|
|
1958
|
-
if (isNodeError(err) && err.code === "ENOENT") return;
|
|
1959
|
-
throw err;
|
|
1960
|
-
} finally {
|
|
1961
|
-
await release?.();
|
|
1962
1746
|
}
|
|
1747
|
+
return TEAMMATE_COLORS[existingMembers.length % TEAMMATE_COLORS.length];
|
|
1963
1748
|
}
|
|
1964
|
-
__name(
|
|
1965
|
-
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
entries = await fs.readdir(dir);
|
|
1970
|
-
} catch (err) {
|
|
1971
|
-
if (isNodeError(err) && err.code === "ENOENT") return [];
|
|
1972
|
-
const errMsg = err instanceof Error ? err.message : String(err);
|
|
1973
|
-
debug.warn(`Failed to list tasks dir ${dir}: ${errMsg}`);
|
|
1974
|
-
throw err instanceof Error ? err : new Error(errMsg);
|
|
1975
|
-
}
|
|
1976
|
-
const jsonEntries = entries.filter((e) => e.endsWith(".json"));
|
|
1977
|
-
const reads = [];
|
|
1978
|
-
for (let i = 0; i < jsonEntries.length; i += MAX_PARALLEL_TASK_READS) {
|
|
1979
|
-
const batch = jsonEntries.slice(i, i + MAX_PARALLEL_TASK_READS);
|
|
1980
|
-
const batchReads = await Promise.all(
|
|
1981
|
-
batch.map(async (entry) => {
|
|
1982
|
-
const filePath = path.join(dir, entry);
|
|
1983
|
-
let raw;
|
|
1984
|
-
try {
|
|
1985
|
-
raw = await fs.readFile(filePath, "utf-8");
|
|
1986
|
-
} catch (err) {
|
|
1987
|
-
if (isNodeError(err) && err.code === "ENOENT") return void 0;
|
|
1988
|
-
const errMsg = err instanceof Error ? err.message : String(err);
|
|
1989
|
-
debug.warn(`Failed to read task file ${filePath}: ${errMsg}`);
|
|
1990
|
-
return void 0;
|
|
1991
|
-
}
|
|
1992
|
-
if (raw.trim() === "") {
|
|
1993
|
-
return void 0;
|
|
1994
|
-
}
|
|
1995
|
-
try {
|
|
1996
|
-
return JSON.parse(raw);
|
|
1997
|
-
} catch (err) {
|
|
1998
|
-
const errMsg = err instanceof Error ? err.message : String(err);
|
|
1999
|
-
debug.warn(`Quarantining corrupt task file ${filePath}: ${errMsg}`);
|
|
2000
|
-
const quarantined = `${filePath}.corrupt-${Date.now()}`;
|
|
2001
|
-
try {
|
|
2002
|
-
await fs.rename(filePath, quarantined);
|
|
2003
|
-
} catch (renameErr) {
|
|
2004
|
-
const renameMsg = renameErr instanceof Error ? renameErr.message : String(renameErr);
|
|
2005
|
-
debug.warn(`Failed to quarantine ${filePath}: ${renameMsg}`);
|
|
2006
|
-
}
|
|
2007
|
-
return void 0;
|
|
2008
|
-
}
|
|
2009
|
-
})
|
|
2010
|
-
);
|
|
2011
|
-
reads.push(...batchReads);
|
|
2012
|
-
}
|
|
2013
|
-
const tasks = reads.filter((t) => t !== void 0);
|
|
2014
|
-
tasks.sort((a, b) => Number(a.id) - Number(b.id));
|
|
2015
|
-
if (!filters) return tasks;
|
|
2016
|
-
return tasks.filter((t) => {
|
|
2017
|
-
if (filters.status !== void 0 && t.status !== filters.status) {
|
|
2018
|
-
return false;
|
|
2019
|
-
}
|
|
2020
|
-
if (filters.owner !== void 0 && t.owner !== filters.owner) {
|
|
2021
|
-
return false;
|
|
2022
|
-
}
|
|
2023
|
-
if (filters.blockedBy !== void 0 && !t.blockedBy.includes(filters.blockedBy)) {
|
|
2024
|
-
return false;
|
|
2025
|
-
}
|
|
2026
|
-
return true;
|
|
1749
|
+
__name(assignTeammateColor, "assignTeammateColor");
|
|
1750
|
+
function clearTeammateColors(members) {
|
|
1751
|
+
return members.map((m) => {
|
|
1752
|
+
const { color: _, ...rest } = m;
|
|
1753
|
+
return rest;
|
|
2027
1754
|
});
|
|
2028
1755
|
}
|
|
2029
|
-
__name(
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
await fs.rm(dir, { recursive: true, force: true });
|
|
2033
|
-
notifyTasksUpdated(teamName);
|
|
1756
|
+
__name(clearTeammateColors, "clearTeammateColors");
|
|
1757
|
+
function setMemberActive(members, agentId, isActive) {
|
|
1758
|
+
return members.map((m) => m.agentId === agentId ? { ...m, isActive } : m);
|
|
2034
1759
|
}
|
|
2035
|
-
__name(
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
dependentIds.map(async (depId) => {
|
|
2039
|
-
const depPath = getTaskPath(teamName, depId);
|
|
2040
|
-
let release;
|
|
2041
|
-
try {
|
|
2042
|
-
release = await import_proper_lockfile.default.lock(depPath, LOCK_OPTIONS);
|
|
2043
|
-
} catch (err) {
|
|
2044
|
-
if (isNodeError(err) && err.code === "ENOENT") return;
|
|
2045
|
-
throw err;
|
|
2046
|
-
}
|
|
2047
|
-
try {
|
|
2048
|
-
const raw = await fs.readFile(depPath, "utf-8");
|
|
2049
|
-
const task = JSON.parse(raw);
|
|
2050
|
-
const before = task.blockedBy.length;
|
|
2051
|
-
task.blockedBy = task.blockedBy.filter((id) => id !== completedId);
|
|
2052
|
-
if (task.blockedBy.length === before) return;
|
|
2053
|
-
await atomicWriteJSON(depPath, task);
|
|
2054
|
-
} finally {
|
|
2055
|
-
await release?.();
|
|
2056
|
-
}
|
|
2057
|
-
})
|
|
2058
|
-
);
|
|
2059
|
-
for (const r of results) {
|
|
2060
|
-
if (r.status === "rejected") {
|
|
2061
|
-
debug.warn(`unblockDependents(${completedId}): ${r.reason}`);
|
|
2062
|
-
}
|
|
2063
|
-
}
|
|
2064
|
-
notifyTasksUpdated(teamName);
|
|
1760
|
+
__name(setMemberActive, "setMemberActive");
|
|
1761
|
+
function findMemberById(members, agentId) {
|
|
1762
|
+
return members.find((m) => m.agentId === agentId);
|
|
2065
1763
|
}
|
|
2066
|
-
__name(
|
|
2067
|
-
|
|
2068
|
-
|
|
2069
|
-
|
|
1764
|
+
__name(findMemberById, "findMemberById");
|
|
1765
|
+
function findMemberByName(members, name) {
|
|
1766
|
+
const sanitized = sanitizeName(name);
|
|
1767
|
+
return members.find((m) => m.name === sanitized);
|
|
2070
1768
|
}
|
|
2071
|
-
__name(
|
|
2072
|
-
|
|
2073
|
-
|
|
2074
|
-
|
|
2075
|
-
|
|
2076
|
-
|
|
2077
|
-
|
|
2078
|
-
|
|
1769
|
+
__name(findMemberByName, "findMemberByName");
|
|
1770
|
+
function classifyShutdownResponse(message) {
|
|
1771
|
+
const trimmed = message.trimStart();
|
|
1772
|
+
if (/^shutdown_approved\b/i.test(trimmed)) return "shutdown_approved";
|
|
1773
|
+
if (/^shutdown_rejected\b/i.test(trimmed)) return "shutdown_rejected";
|
|
1774
|
+
return void 0;
|
|
1775
|
+
}
|
|
1776
|
+
__name(classifyShutdownResponse, "classifyShutdownResponse");
|
|
1777
|
+
async function readTeamFile(teamName) {
|
|
1778
|
+
const filePath = getTeamFilePath(teamName);
|
|
2079
1779
|
try {
|
|
2080
|
-
|
|
1780
|
+
const raw = await fs.readFile(filePath, "utf-8");
|
|
1781
|
+
return JSON.parse(raw);
|
|
2081
1782
|
} catch (err) {
|
|
2082
|
-
if (isNodeError(err) && err.code === "ENOENT")
|
|
2083
|
-
|
|
2084
|
-
}
|
|
2085
|
-
try {
|
|
2086
|
-
let raw;
|
|
2087
|
-
try {
|
|
2088
|
-
raw = await fs.readFile(taskPath, "utf-8");
|
|
2089
|
-
} catch (err) {
|
|
2090
|
-
if (isNodeError(err) && err.code === "ENOENT") return void 0;
|
|
2091
|
-
throw err;
|
|
1783
|
+
if (isNodeError(err) && err.code === "ENOENT") {
|
|
1784
|
+
return void 0;
|
|
2092
1785
|
}
|
|
2093
|
-
|
|
2094
|
-
if (task.status !== "pending") return void 0;
|
|
2095
|
-
if (task.owner) return void 0;
|
|
2096
|
-
task.owner = opts?.ownerName ?? agentId;
|
|
2097
|
-
task.status = "in_progress";
|
|
2098
|
-
await atomicWriteJSON(taskPath, task);
|
|
2099
|
-
notifyTasksUpdated(teamName);
|
|
2100
|
-
return task;
|
|
2101
|
-
} finally {
|
|
2102
|
-
await release?.();
|
|
1786
|
+
throw err;
|
|
2103
1787
|
}
|
|
2104
1788
|
}
|
|
2105
|
-
__name(
|
|
2106
|
-
async function
|
|
2107
|
-
const
|
|
2108
|
-
|
|
1789
|
+
__name(readTeamFile, "readTeamFile");
|
|
1790
|
+
async function writeTeamFile(teamName, teamFile) {
|
|
1791
|
+
const filePath = getTeamFilePath(teamName);
|
|
1792
|
+
await fs.mkdir(path.dirname(filePath), { recursive: true });
|
|
1793
|
+
await atomicWriteJSON(filePath, teamFile);
|
|
1794
|
+
}
|
|
1795
|
+
__name(writeTeamFile, "writeTeamFile");
|
|
1796
|
+
async function createTeamFile(teamName, teamFile) {
|
|
1797
|
+
const filePath = getTeamFilePath(teamName);
|
|
1798
|
+
await fs.mkdir(path.dirname(filePath), { recursive: true });
|
|
1799
|
+
await fs.writeFile(filePath, JSON.stringify(teamFile, null, 2) + "\n", {
|
|
1800
|
+
encoding: "utf-8",
|
|
1801
|
+
flag: "wx"
|
|
2109
1802
|
});
|
|
2110
|
-
const bareName = agentId.split("@")[0];
|
|
2111
|
-
return inProgress.some((t) => t.owner === agentId || t.owner === bareName);
|
|
2112
1803
|
}
|
|
2113
|
-
__name(
|
|
2114
|
-
|
|
2115
|
-
const taskPath = getTaskPath(teamName, taskId);
|
|
2116
|
-
let release;
|
|
1804
|
+
__name(createTeamFile, "createTeamFile");
|
|
1805
|
+
function isPidAlive(pid) {
|
|
2117
1806
|
try {
|
|
2118
|
-
|
|
1807
|
+
process.kill(pid, 0);
|
|
1808
|
+
return true;
|
|
2119
1809
|
} catch (err) {
|
|
2120
|
-
|
|
2121
|
-
throw err;
|
|
1810
|
+
return isNodeError(err) && err.code === "EPERM";
|
|
2122
1811
|
}
|
|
1812
|
+
}
|
|
1813
|
+
__name(isPidAlive, "isPidAlive");
|
|
1814
|
+
async function tryReclaimStaleTeam(teamName) {
|
|
1815
|
+
let existing;
|
|
2123
1816
|
try {
|
|
2124
|
-
|
|
2125
|
-
|
|
2126
|
-
|
|
2127
|
-
|
|
2128
|
-
|
|
2129
|
-
|
|
2130
|
-
}
|
|
2131
|
-
const task = JSON.parse(raw);
|
|
2132
|
-
if (task.status !== "in_progress") return false;
|
|
2133
|
-
if (task.owner !== expectedOwner) return false;
|
|
2134
|
-
task.owner = void 0;
|
|
2135
|
-
task.status = "pending";
|
|
2136
|
-
await atomicWriteJSON(taskPath, task);
|
|
1817
|
+
existing = await readTeamFile(teamName);
|
|
1818
|
+
} catch {
|
|
1819
|
+
return false;
|
|
1820
|
+
}
|
|
1821
|
+
if (!existing) {
|
|
1822
|
+
await deleteTeamDirs(teamName);
|
|
2137
1823
|
return true;
|
|
2138
|
-
} finally {
|
|
2139
|
-
await release?.();
|
|
2140
1824
|
}
|
|
2141
|
-
|
|
2142
|
-
|
|
2143
|
-
async function unassignTeammateTasks(teamName, agentId) {
|
|
2144
|
-
const bareName = agentId.split("@")[0];
|
|
2145
|
-
const inProgress = await listTasks(teamName, {
|
|
2146
|
-
status: "in_progress"
|
|
2147
|
-
});
|
|
2148
|
-
const owned = inProgress.filter(
|
|
2149
|
-
(task) => task.owner === agentId || task.owner === bareName
|
|
2150
|
-
);
|
|
2151
|
-
const results = await Promise.allSettled(
|
|
2152
|
-
owned.map((task) => releaseOwnedTask(teamName, task.id, task.owner))
|
|
2153
|
-
);
|
|
2154
|
-
const failed = results.filter((r) => r.status === "rejected");
|
|
2155
|
-
if (failed.length > 0) {
|
|
2156
|
-
debug.warn(
|
|
2157
|
-
`unassignTeammateTasks: ${failed.length}/${owned.length} task(s) failed to unassign for ${agentId}`
|
|
2158
|
-
);
|
|
1825
|
+
if (typeof existing.leadPid !== "number" || existing.leadPid <= 0) {
|
|
1826
|
+
return false;
|
|
2159
1827
|
}
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
).length;
|
|
2163
|
-
if (released > 0) {
|
|
2164
|
-
notifyTasksUpdated(teamName);
|
|
1828
|
+
if (existing.leadPid !== process.pid && isPidAlive(existing.leadPid)) {
|
|
1829
|
+
return false;
|
|
2165
1830
|
}
|
|
2166
|
-
|
|
1831
|
+
await deleteTeamDirs(teamName);
|
|
1832
|
+
return true;
|
|
2167
1833
|
}
|
|
2168
|
-
__name(
|
|
2169
|
-
async function
|
|
2170
|
-
const
|
|
2171
|
-
const
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
completed: 0
|
|
2177
|
-
};
|
|
2178
|
-
if (task.status === "in_progress") {
|
|
2179
|
-
entry.inProgress++;
|
|
2180
|
-
} else if (task.status === "completed") {
|
|
2181
|
-
entry.completed++;
|
|
2182
|
-
}
|
|
2183
|
-
statuses.set(task.owner, entry);
|
|
2184
|
-
}
|
|
2185
|
-
return statuses;
|
|
1834
|
+
__name(tryReclaimStaleTeam, "tryReclaimStaleTeam");
|
|
1835
|
+
async function deleteTeamDirs(teamName) {
|
|
1836
|
+
const teamDir = getTeamDir(teamName);
|
|
1837
|
+
const tasksDir = getTasksDir(teamName);
|
|
1838
|
+
await Promise.allSettled([
|
|
1839
|
+
fs.rm(teamDir, { recursive: true, force: true }),
|
|
1840
|
+
fs.rm(tasksDir, { recursive: true, force: true })
|
|
1841
|
+
]);
|
|
2186
1842
|
}
|
|
2187
|
-
__name(
|
|
2188
|
-
async function
|
|
2189
|
-
|
|
1843
|
+
__name(deleteTeamDirs, "deleteTeamDirs");
|
|
1844
|
+
async function listTeamNames() {
|
|
1845
|
+
const teamsRoot = getTeamsRootDir();
|
|
2190
1846
|
try {
|
|
2191
|
-
entries = await fs.readdir(
|
|
1847
|
+
const entries = await fs.readdir(teamsRoot, {
|
|
1848
|
+
withFileTypes: true
|
|
1849
|
+
});
|
|
1850
|
+
return entries.filter((e) => e.isDirectory()).map((e) => e.name);
|
|
2192
1851
|
} catch {
|
|
2193
|
-
return
|
|
2194
|
-
}
|
|
2195
|
-
let maxId = 0;
|
|
2196
|
-
for (const entry of entries) {
|
|
2197
|
-
if (!entry.endsWith(".json")) continue;
|
|
2198
|
-
const num = parseInt(entry.replace(".json", ""), 10);
|
|
2199
|
-
if (!isNaN(num) && num > maxId) {
|
|
2200
|
-
maxId = num;
|
|
2201
|
-
}
|
|
1852
|
+
return [];
|
|
2202
1853
|
}
|
|
2203
|
-
return String(maxId + 1);
|
|
2204
1854
|
}
|
|
2205
|
-
__name(
|
|
1855
|
+
__name(listTeamNames, "listTeamNames");
|
|
2206
1856
|
|
|
2207
1857
|
export {
|
|
1858
|
+
getTeamsRootDir,
|
|
1859
|
+
getTeamDir,
|
|
1860
|
+
getTeamFilePath,
|
|
1861
|
+
getInboxesDir,
|
|
1862
|
+
getTasksDir,
|
|
1863
|
+
sanitizeName,
|
|
1864
|
+
formatAgentId,
|
|
1865
|
+
generateUniqueTeammateName,
|
|
1866
|
+
assignTeammateColor,
|
|
1867
|
+
clearTeammateColors,
|
|
1868
|
+
setMemberActive,
|
|
1869
|
+
findMemberById,
|
|
1870
|
+
findMemberByName,
|
|
1871
|
+
classifyShutdownResponse,
|
|
1872
|
+
readTeamFile,
|
|
1873
|
+
writeTeamFile,
|
|
1874
|
+
createTeamFile,
|
|
1875
|
+
tryReclaimStaleTeam,
|
|
1876
|
+
deleteTeamDirs,
|
|
1877
|
+
listTeamNames,
|
|
2208
1878
|
require_graceful_fs,
|
|
2209
|
-
require_proper_lockfile
|
|
2210
|
-
assertValidTaskId,
|
|
2211
|
-
getTaskPath,
|
|
2212
|
-
onTasksUpdated,
|
|
2213
|
-
notifyTasksUpdated,
|
|
2214
|
-
createTask,
|
|
2215
|
-
getTask,
|
|
2216
|
-
TaskOwnershipError,
|
|
2217
|
-
updateTask,
|
|
2218
|
-
deleteTask,
|
|
2219
|
-
listTasks,
|
|
2220
|
-
resetTaskList,
|
|
2221
|
-
blockTask,
|
|
2222
|
-
claimTask,
|
|
2223
|
-
releaseOwnedTask,
|
|
2224
|
-
unassignTeammateTasks,
|
|
2225
|
-
getAgentStatuses
|
|
1879
|
+
require_proper_lockfile
|
|
2226
1880
|
};
|
|
2227
1881
|
/**
|
|
2228
1882
|
* @license
|