@mmmbuto/qwen-code-termux 0.16.1-termux → 0.18.0-termux
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 +79 -109
- package/bundled/new-app/SKILL.md +22 -0
- package/bundled/qc-helper/SKILL.md +29 -24
- package/bundled/qc-helper/docs/_meta.ts +1 -0
- package/bundled/qc-helper/docs/configuration/_meta.ts +0 -3
- package/bundled/qc-helper/docs/configuration/settings.md +37 -31
- package/bundled/qc-helper/docs/configuration/themes.md +39 -0
- package/bundled/qc-helper/docs/features/_meta.ts +1 -3
- package/bundled/qc-helper/docs/features/approval-mode.md +35 -35
- package/bundled/qc-helper/docs/features/auto-mode.md +54 -9
- package/bundled/qc-helper/docs/features/channels/_meta.ts +1 -0
- package/bundled/qc-helper/docs/features/channels/feishu.md +170 -0
- package/bundled/qc-helper/docs/features/commands.md +115 -35
- package/bundled/qc-helper/docs/features/followup-suggestions.md +2 -2
- package/bundled/qc-helper/docs/features/headless.md +32 -0
- package/bundled/qc-helper/docs/features/markdown-rendering.md +21 -1
- package/bundled/qc-helper/docs/features/memory.md +22 -5
- package/bundled/qc-helper/docs/features/scheduled-tasks.md +1 -1
- package/bundled/qc-helper/docs/features/status-line.md +168 -32
- package/bundled/qc-helper/docs/features/sub-agents.md +60 -0
- package/bundled/qc-helper/docs/features/worktree.md +345 -0
- package/bundled/qc-helper/docs/overview.md +4 -4
- package/bundled/qc-helper/docs/quickstart.md +4 -4
- package/bundled/qc-helper/docs/qwen-serve-deploy-local.md +221 -0
- package/bundled/qc-helper/docs/qwen-serve.md +234 -24
- package/bundled/qc-helper/docs/reference/keyboard-shortcuts.md +16 -0
- package/bundled/qc-helper/docs/support/Uninstall.md +19 -1
- package/bundled/qc-helper/docs/support/troubleshooting.md +2 -1
- package/bundled/simplify/SKILL.md +123 -0
- package/chunks/agent-IDS4HMOX.js +56 -0
- package/chunks/agent-headless-5Q2EUSPS.js +50 -0
- package/chunks/{anthropicContentGenerator-SSGKR6DO.js → anthropicContentGenerator-2HBRNQ3B.js} +52 -9
- package/chunks/{askUserQuestion-PJWUUXKN.js → askUserQuestion-75TDJVK2.js} +45 -3
- package/chunks/{ca-UZ7BANMN.js → ca-BARBRL6N.js} +89 -5
- package/chunks/{chunk-GGNTZ2NH.js → chunk-2Y5SYSD3.js} +368 -597
- package/chunks/{chunk-2LA2TREA.js → chunk-3AA2DK35.js} +1448 -207
- package/chunks/{chunk-I2V5WXHJ.js → chunk-3AUHFMSK.js} +80 -38
- package/chunks/chunk-3DHXZ6EV.js +241 -0
- package/chunks/{chunk-PR4T27R7.js → chunk-3HTIVKZE.js} +42 -8
- package/chunks/chunk-3HX5LZ6R.js +1798 -0
- package/chunks/chunk-3PJXIDKI.js +2517 -0
- package/chunks/{chunk-MYAKAFEC.js → chunk-55ZMG67I.js} +7451 -3517
- package/chunks/{chunk-66CXYE4B.js → chunk-5IFG2VC4.js} +293 -242
- package/chunks/chunk-64WXLC72.js +98 -0
- package/chunks/{chunk-C6WMLUNB.js → chunk-72LDN5PP.js} +1 -1
- package/chunks/{chunk-F23NCRJ2.js → chunk-A7B4ISQP.js} +1 -1
- package/chunks/chunk-B7HXHOHU.js +393 -0
- package/chunks/{chunk-XEGHDASV.js → chunk-D3RHSPAS.js} +435 -540
- package/chunks/{chunk-XKS5KBFJ.js → chunk-EYENRK4D.js} +694 -384
- package/chunks/chunk-H6BD2ELD.js +36 -0
- package/chunks/{chunk-XP27SJMH.js → chunk-HR7SV7AY.js} +79 -48
- package/chunks/{chunk-D5NTAHYL.js → chunk-IDX6COTE.js} +7 -2
- package/chunks/{chunk-SHT4VJWU.js → chunk-IWKSG2AR.js} +2 -2
- package/chunks/chunk-J37FGIOA.js +1623 -0
- package/chunks/chunk-J5MDQKJL.js +2230 -0
- package/chunks/{chunk-USE2VQ5P.js → chunk-JTQAQBTV.js} +21 -0
- package/chunks/{chunk-NCTLV2NB.js → chunk-KQJMQJPI.js} +1 -1
- package/chunks/{chunk-5FBA5XC2.js → chunk-KRIHGKNA.js} +1 -1
- package/chunks/chunk-LD2XBG6Z.js +102 -0
- package/chunks/{chunk-MAY32HXD.js → chunk-M6VTDSVR.js} +3 -1
- package/chunks/chunk-MRO43B25.js +30 -0
- package/chunks/{chunk-N4WOREMD.js → chunk-NVFMZBX2.js} +43 -3
- package/chunks/chunk-OHEGWO4L.js +264 -0
- package/chunks/{chunk-K6O2NBMF.js → chunk-OQ7NJIY7.js} +4604 -6397
- package/chunks/chunk-QQDPRDVW.js +25 -0
- package/chunks/{chunk-KXZ4TJB4.js → chunk-SEGYWKIH.js} +1 -1
- package/chunks/chunk-SKBPNJEW.js +45 -0
- package/chunks/{chunk-4AOCVI6J.js → chunk-SNGELLWX.js} +52 -6
- package/chunks/{chunk-3OCRHZA3.js → chunk-TD4OPI4T.js} +56742 -44104
- package/chunks/{chunk-DQ4QTG7E.js → chunk-VV4F63BD.js} +11 -11
- package/chunks/chunk-XBY7E2FX.js +605 -0
- package/chunks/{chunk-JKMBWLFB.js → chunk-YILFYI5W.js} +48 -26
- package/chunks/chunk-YOGAOMYB.js +159 -0
- package/chunks/{chunk-QWSRH265.js → chunk-Z2Z3GUXZ.js} +777 -776
- package/chunks/{chunk-SDHRQFOS.js → chunk-ZTZ4DDQE.js} +2 -2
- package/chunks/computer-use-W2TYQNEE.js +825 -0
- package/chunks/contextCommand-6FGX3A7J.js +52 -0
- package/chunks/{cron-create-3ZBBN7WB.js → cron-create-APL5LU6I.js} +3 -3
- package/chunks/{cron-delete-NAGKKIIG.js → cron-delete-4SBJSCN4.js} +3 -3
- package/chunks/{cron-list-PAGRXNAI.js → cron-list-2AMGOMVO.js} +3 -3
- package/chunks/{de-V4IE2OOZ.js → de-YGKK2BC4.js} +89 -5
- package/chunks/{devtools-TWVXEJQB.js → devtools-FM6GJPYG.js} +2 -1
- package/chunks/{dist-4L54HRX2.js → dist-4LXD6L6X.js} +24 -5
- package/chunks/dist-H6ONXVLG.js +94146 -0
- package/chunks/{dist-XKWIWPWQ.js → dist-KAZ3SEBX.js} +1083 -3856
- package/chunks/{dist-BXDUQ2QY.js → dist-PK7DFCAW.js} +1 -1
- package/chunks/{edit-NVO3FOAK.js → edit-ZCEZC264.js} +30 -22
- package/chunks/{en-HGJ2SPLM.js → en-DHGYHIHX.js} +127 -6
- package/chunks/{enter-worktree-UEBG4WFC.js → enter-worktree-BBHCFCHG.js} +30 -20
- package/chunks/enterPlanMode-3M6KTD3B.js +158 -0
- package/chunks/{exit-worktree-UZ3MAQZN.js → exit-worktree-73YPIEQO.js} +27 -19
- package/chunks/exitPlanMode-TYZM6BAE.js +703 -0
- package/chunks/{fr-CJULI7ZX.js → fr-JXBKPJKQ.js} +89 -5
- package/chunks/{geminiContentGenerator-3UZFXGNT.js → geminiContentGenerator-7N2V3VW2.js} +8 -6
- package/chunks/{getMachineId-bsd-JXOSIJV2.js → getMachineId-bsd-4CASPIU4.js} +4 -4
- package/chunks/{getMachineId-darwin-TE4QRR42.js → getMachineId-darwin-HPQPEMZR.js} +4 -4
- package/chunks/{getMachineId-linux-S3OL52XK.js → getMachineId-linux-AUARKYHL.js} +3 -3
- package/chunks/{getMachineId-unsupported-DWUSBAPX.js → getMachineId-unsupported-S32ZDA2T.js} +3 -3
- package/chunks/{getMachineId-win-AAC5P3AP.js → getMachineId-win-4EFLHYIJ.js} +4 -4
- package/chunks/{glob-KNHSFFFG.js → glob-5XBCPQ2A.js} +27 -19
- package/chunks/{grep-LACWDZW4.js → grep-VIUU3A7X.js} +30 -19
- package/chunks/{ja-L7CHRQEW.js → ja-TGPZSP2B.js} +89 -5
- package/chunks/{keychain-token-storage-335UOLJ6.js → keychain-token-storage-6IU6ORQN.js} +3 -3
- package/chunks/{ls-AGXQOKSG.js → ls-JRGYIGLY.js} +4 -4
- package/chunks/{lsp-UDMUHNPA.js → lsp-SHMKFOAC.js} +3 -3
- package/chunks/{monitor-ETKWPJEH.js → monitor-6R4LIJL5.js} +40 -25
- package/chunks/{multipart-parser-3QWGTLK3.js → multipart-parser-AJ4WASWR.js} +2 -2
- package/chunks/{notebook-edit-QJJLPNYT.js → notebook-edit-5E7ULDVQ.js} +28 -20
- package/chunks/{openaiContentGenerator-CNNN424U.js → openaiContentGenerator-ZVHFKM3O.js} +17 -14
- package/chunks/{pt-M6JULLEQ.js → pt-TIBG6BIO.js} +89 -5
- package/chunks/{qwenContentGenerator-BOLCGK3R.js → qwenContentGenerator-B2VTVSPJ.js} +31 -23
- package/chunks/{qwenOAuth2-EEJGROP7.js → qwenOAuth2-2KCKWDCF.js} +6 -4
- package/chunks/read-file-GIT7BCDR.js +27 -0
- package/chunks/ripGrep-MWKFVYMS.js +48 -0
- package/chunks/{ru-QILM4HBC.js → ru-JBCHCK4L.js} +89 -5
- package/chunks/scheduler-5VOOYGBH.js +308 -0
- package/chunks/send-message-4QNWQJF4.js +244 -0
- package/chunks/{serve-OLSI7WSR.js → serve-MN6HZBWN.js} +14262 -7414
- package/chunks/shell-NQZQGFM2.js +56 -0
- package/chunks/{skill-D6YRHTTI.js → skill-WCFW4644.js} +145 -119
- package/chunks/{src-TMOD5X6F.js → src-7XL4G4DC.js} +88 -46
- package/chunks/{src-4QH4FZ6I.js → src-IHA6DTUV.js} +452 -62
- package/chunks/{syntheticOutput-5PVFDDJ4.js → syntheticOutput-YTYS2ZMQ.js} +4 -4
- package/chunks/task-create-MPORPYN6.js +19 -0
- package/chunks/task-list-R2YDYPZT.js +151 -0
- package/chunks/{task-stop-AJKPSR6R.js → task-stop-SYWJYBCM.js} +3 -3
- package/chunks/task-update-E4NSLKMQ.js +408 -0
- package/chunks/team-create-7R7KA5IP.js +314 -0
- package/chunks/team-delete-25OIWUPN.js +116 -0
- package/chunks/{todoWrite-VLAUG4CA.js → todoWrite-4YHMIF4X.js} +16 -5
- package/chunks/{tool-search-MZGHUUKD.js → tool-search-YBRVZCLI.js} +29 -11
- package/chunks/{tts-notification-K3X7X7MN.js → tts-notification-7SOEMQK4.js} +5 -4
- package/chunks/{web-fetch-OILB464A.js → web-fetch-MFIRHIHI.js} +5 -5
- package/chunks/workflow-5RIKVCIE.js +960 -0
- package/chunks/{write-file-BIQAA57V.js → write-file-DMQTJZOM.js} +32 -24
- package/chunks/{zh-PWL2NKY3.js → zh-7H5OQC4I.js} +135 -11
- package/chunks/{zh-TW-S3YGWICZ.js → zh-TW-P4IDHD3M.js} +128 -11
- package/cli.js +45402 -20570
- package/examples/agent/agents/diary.md +86 -0
- package/examples/agent/qwen-extension.json +5 -0
- package/examples/commands/commands/fs/grep-code.md +3 -0
- package/examples/commands/qwen-extension.json +5 -0
- package/examples/context/QWEN.md +8 -0
- package/examples/context/qwen-extension.json +5 -0
- package/examples/mcp-server/example.ts +60 -0
- package/examples/mcp-server/package.json +18 -0
- package/examples/mcp-server/qwen-extension.json +12 -0
- package/examples/mcp-server/tsconfig.json +13 -0
- package/examples/skills/qwen-extension.json +5 -0
- package/examples/skills/skills/synonyms/SKILL.md +48 -0
- 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 +118 -5
- package/locales/de.js +117 -5
- package/locales/en.js +169 -7
- package/locales/fr.js +119 -5
- package/locales/ja.js +114 -5
- package/locales/pt.js +117 -5
- package/locales/ru.js +116 -5
- package/locales/zh-TW.js +161 -12
- package/locales/zh.js +169 -12
- package/package.json +4 -2
- package/scripts/postinstall.cjs +2 -1
- package/bundled/qc-helper/docs/features/checkpointing.md +0 -77
- package/chunks/agent-7ZN3CRHR.js +0 -48
- package/chunks/chunk-6PCB2DEF.js +0 -434
- package/chunks/chunk-EM6ETG2K.js +0 -60
- package/chunks/chunk-G7YTSRES.js +0 -150
- package/chunks/contextCommand-7IBASARL.js +0 -44
- package/chunks/exitPlanMode-PZAMWIRW.js +0 -227
- package/chunks/multipart-parser-IXGBIOIN.js +0 -384
- package/chunks/read-file-CCUEUFG2.js +0 -24
- package/chunks/ripGrep-TADOH2HK.js +0 -40
- package/chunks/send-message-YL44UZFC.js +0 -151
- package/chunks/shell-7KKKC5G7.js +0 -48
- package/chunks/src-IPWIHNMI.js +0 -1406
- package/chunks/undici-F6ZOXSS5.js +0 -8
|
@@ -0,0 +1,308 @@
|
|
|
1
|
+
// Force strict mode and setup for ESM
|
|
2
|
+
"use strict";
|
|
3
|
+
import {
|
|
4
|
+
msSinceLastInteraction
|
|
5
|
+
} from "./chunk-MRO43B25.js";
|
|
6
|
+
import {
|
|
7
|
+
FILE_HISTORY_DIR
|
|
8
|
+
} from "./chunk-TD4OPI4T.js";
|
|
9
|
+
import "./chunk-K5PGHDBN.js";
|
|
10
|
+
import "./chunk-XBY7E2FX.js";
|
|
11
|
+
import "./chunk-SKBPNJEW.js";
|
|
12
|
+
import "./chunk-NVFMZBX2.js";
|
|
13
|
+
import "./chunk-O4PICXES.js";
|
|
14
|
+
import "./chunk-TW522KN6.js";
|
|
15
|
+
import "./chunk-3DHXZ6EV.js";
|
|
16
|
+
import "./chunk-J5MDQKJL.js";
|
|
17
|
+
import "./chunk-MLZQVCF3.js";
|
|
18
|
+
import "./chunk-LD2XBG6Z.js";
|
|
19
|
+
import "./chunk-OHEGWO4L.js";
|
|
20
|
+
import "./chunk-SNGELLWX.js";
|
|
21
|
+
import "./chunk-77WXWU44.js";
|
|
22
|
+
import "./chunk-A7B4ISQP.js";
|
|
23
|
+
import "./chunk-OQ7NJIY7.js";
|
|
24
|
+
import "./chunk-3PJXIDKI.js";
|
|
25
|
+
import "./chunk-UWCTAVOD.js";
|
|
26
|
+
import "./chunk-OFEVLU4C.js";
|
|
27
|
+
import "./chunk-3HTIVKZE.js";
|
|
28
|
+
import "./chunk-IDX6COTE.js";
|
|
29
|
+
import "./chunk-KQJMQJPI.js";
|
|
30
|
+
import "./chunk-D3RHSPAS.js";
|
|
31
|
+
import "./chunk-2Y5SYSD3.js";
|
|
32
|
+
import "./chunk-SEGYWKIH.js";
|
|
33
|
+
import "./chunk-64WXLC72.js";
|
|
34
|
+
import "./chunk-B7HXHOHU.js";
|
|
35
|
+
import "./chunk-EYENRK4D.js";
|
|
36
|
+
import "./chunk-M6VTDSVR.js";
|
|
37
|
+
import "./chunk-55ZMG67I.js";
|
|
38
|
+
import "./chunk-H6BD2ELD.js";
|
|
39
|
+
import "./chunk-5IFG2VC4.js";
|
|
40
|
+
import {
|
|
41
|
+
Storage,
|
|
42
|
+
createDebugLogger
|
|
43
|
+
} from "./chunk-HR7SV7AY.js";
|
|
44
|
+
import "./chunk-ZERZSAZL.js";
|
|
45
|
+
import "./chunk-QN5NZ3UQ.js";
|
|
46
|
+
import "./chunk-BR4QREVK.js";
|
|
47
|
+
import "./chunk-Z2Z3GUXZ.js";
|
|
48
|
+
import {
|
|
49
|
+
init_esbuild_shims
|
|
50
|
+
} from "./chunk-A4BMJM77.js";
|
|
51
|
+
import {
|
|
52
|
+
__name
|
|
53
|
+
} from "./chunk-J2S4EL5Y.js";
|
|
54
|
+
|
|
55
|
+
// packages/cli/src/utils/housekeeping/scheduler.ts
|
|
56
|
+
init_esbuild_shims();
|
|
57
|
+
import { stat as stat3 } from "node:fs/promises";
|
|
58
|
+
import { join as join2 } from "node:path";
|
|
59
|
+
|
|
60
|
+
// packages/cli/src/utils/housekeeping/cleanup.ts
|
|
61
|
+
init_esbuild_shims();
|
|
62
|
+
import { readdir, stat, rm, rmdir } from "node:fs/promises";
|
|
63
|
+
import { join } from "node:path";
|
|
64
|
+
var debugLogger = createDebugLogger("HOUSEKEEPING");
|
|
65
|
+
var MS_PER_DAY = 24 * 60 * 60 * 1e3;
|
|
66
|
+
var MS_PER_HOUR = 60 * 60 * 1e3;
|
|
67
|
+
var SWEEP_CONCURRENCY = 20;
|
|
68
|
+
function getCutoffDate(cleanupPeriodDays) {
|
|
69
|
+
const periodMs = cleanupPeriodDays > 0 ? cleanupPeriodDays * MS_PER_DAY : MS_PER_HOUR;
|
|
70
|
+
return new Date(Date.now() - periodMs);
|
|
71
|
+
}
|
|
72
|
+
__name(getCutoffDate, "getCutoffDate");
|
|
73
|
+
async function cleanupOldFileHistoryBackups(opts) {
|
|
74
|
+
const result = { removed: 0, errors: 0 };
|
|
75
|
+
const root = join(Storage.getGlobalQwenDir(), FILE_HISTORY_DIR);
|
|
76
|
+
const excludes = opts.excludeSessionIds ?? /* @__PURE__ */ new Set();
|
|
77
|
+
let entries;
|
|
78
|
+
try {
|
|
79
|
+
entries = await readdir(root, { withFileTypes: true });
|
|
80
|
+
} catch (e) {
|
|
81
|
+
if (isENOENT(e)) return result;
|
|
82
|
+
debugLogger.error("readdir failed", e);
|
|
83
|
+
return result;
|
|
84
|
+
}
|
|
85
|
+
const sessionDirs = entries.filter((e) => e.isDirectory() && !excludes.has(e.name)).map((e) => join(root, e.name));
|
|
86
|
+
for (let i = 0; i < sessionDirs.length; i += SWEEP_CONCURRENCY) {
|
|
87
|
+
const batch = sessionDirs.slice(i, i + SWEEP_CONCURRENCY);
|
|
88
|
+
await Promise.all(
|
|
89
|
+
batch.map(async (dir) => {
|
|
90
|
+
try {
|
|
91
|
+
const s = await stat(dir);
|
|
92
|
+
if (s.mtime < opts.cutoffDate) {
|
|
93
|
+
await rm(dir, { recursive: true, force: true });
|
|
94
|
+
result.removed++;
|
|
95
|
+
}
|
|
96
|
+
} catch (err) {
|
|
97
|
+
result.errors++;
|
|
98
|
+
debugLogger.error(`failed to sweep ${dir}`, err);
|
|
99
|
+
}
|
|
100
|
+
})
|
|
101
|
+
);
|
|
102
|
+
}
|
|
103
|
+
await rmdir(root).catch(() => {
|
|
104
|
+
});
|
|
105
|
+
return result;
|
|
106
|
+
}
|
|
107
|
+
__name(cleanupOldFileHistoryBackups, "cleanupOldFileHistoryBackups");
|
|
108
|
+
function isENOENT(e) {
|
|
109
|
+
return e?.code === "ENOENT";
|
|
110
|
+
}
|
|
111
|
+
__name(isENOENT, "isENOENT");
|
|
112
|
+
|
|
113
|
+
// packages/cli/src/utils/housekeeping/throttledOnce.ts
|
|
114
|
+
init_esbuild_shims();
|
|
115
|
+
import { mkdir, open, stat as stat2, unlink, writeFile } from "node:fs/promises";
|
|
116
|
+
import { dirname } from "node:path";
|
|
117
|
+
var debugLogger2 = createDebugLogger("HOUSEKEEPING");
|
|
118
|
+
var ONE_DAY_MS = 24 * 60 * 60 * 1e3;
|
|
119
|
+
var STALE_LOCK_MS = 60 * 60 * 1e3;
|
|
120
|
+
async function runThrottledOnce(opts, task) {
|
|
121
|
+
const minIntervalMs = opts.minIntervalMs ?? ONE_DAY_MS;
|
|
122
|
+
const staleLockMs = opts.staleLockMs ?? STALE_LOCK_MS;
|
|
123
|
+
await mkdir(dirname(opts.lockPath), { recursive: true, mode: 448 }).catch(
|
|
124
|
+
() => {
|
|
125
|
+
}
|
|
126
|
+
);
|
|
127
|
+
if (await markerIsFresh(opts.markerPath, minIntervalMs, opts.name)) {
|
|
128
|
+
return false;
|
|
129
|
+
}
|
|
130
|
+
let acquired = await tryAcquire(opts.lockPath);
|
|
131
|
+
if (!acquired) {
|
|
132
|
+
try {
|
|
133
|
+
const s = await stat2(opts.lockPath);
|
|
134
|
+
if (Date.now() - s.mtimeMs > staleLockMs) {
|
|
135
|
+
await unlink(opts.lockPath).catch(() => {
|
|
136
|
+
});
|
|
137
|
+
acquired = await tryAcquire(opts.lockPath);
|
|
138
|
+
}
|
|
139
|
+
} catch {
|
|
140
|
+
acquired = await tryAcquire(opts.lockPath);
|
|
141
|
+
}
|
|
142
|
+
if (!acquired) {
|
|
143
|
+
debugLogger2.debug(`${opts.name}: skipping, lock held`);
|
|
144
|
+
return false;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
try {
|
|
148
|
+
if (await markerIsFresh(opts.markerPath, minIntervalMs, opts.name)) {
|
|
149
|
+
return false;
|
|
150
|
+
}
|
|
151
|
+
let taskCompleted = false;
|
|
152
|
+
try {
|
|
153
|
+
await task();
|
|
154
|
+
taskCompleted = true;
|
|
155
|
+
} finally {
|
|
156
|
+
if (taskCompleted) {
|
|
157
|
+
try {
|
|
158
|
+
await writeFile(opts.markerPath, (/* @__PURE__ */ new Date()).toISOString());
|
|
159
|
+
} catch (err) {
|
|
160
|
+
debugLogger2.debug(
|
|
161
|
+
`${opts.name}: marker write failed (cleanup succeeded)`,
|
|
162
|
+
err
|
|
163
|
+
);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
return taskCompleted;
|
|
168
|
+
} finally {
|
|
169
|
+
await unlink(opts.lockPath).catch(() => {
|
|
170
|
+
debugLogger2.debug(`${opts.name}: lock unlink failed (harmless)`);
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
__name(runThrottledOnce, "runThrottledOnce");
|
|
175
|
+
async function markerIsFresh(markerPath, minIntervalMs, name) {
|
|
176
|
+
try {
|
|
177
|
+
const s = await stat2(markerPath);
|
|
178
|
+
const age = Date.now() - s.mtimeMs;
|
|
179
|
+
if (age < minIntervalMs) {
|
|
180
|
+
debugLogger2.debug(`${name}: skipping, ran ${age}ms ago`);
|
|
181
|
+
return true;
|
|
182
|
+
}
|
|
183
|
+
} catch {
|
|
184
|
+
}
|
|
185
|
+
return false;
|
|
186
|
+
}
|
|
187
|
+
__name(markerIsFresh, "markerIsFresh");
|
|
188
|
+
async function tryAcquire(lockPath) {
|
|
189
|
+
try {
|
|
190
|
+
const fh = await open(lockPath, "wx");
|
|
191
|
+
await fh.close();
|
|
192
|
+
return true;
|
|
193
|
+
} catch (e) {
|
|
194
|
+
if (e?.code === "EEXIST") {
|
|
195
|
+
return false;
|
|
196
|
+
}
|
|
197
|
+
throw e;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
__name(tryAcquire, "tryAcquire");
|
|
201
|
+
|
|
202
|
+
// packages/cli/src/utils/housekeeping/scheduler.ts
|
|
203
|
+
var debugLogger3 = createDebugLogger("HOUSEKEEPING");
|
|
204
|
+
var STARTUP_DELAY_MS = 10 * 60 * 1e3;
|
|
205
|
+
var RECURRING_INTERVAL_MS = 24 * 60 * 60 * 1e3;
|
|
206
|
+
var RECENT_INTERACTION_MS = 60 * 1e3;
|
|
207
|
+
var CATCHUP_THRESHOLD_MS = 7 * 24 * 60 * 60 * 1e3;
|
|
208
|
+
var STARTUP_DELAY_CATCHUP_MS = 60 * 1e3;
|
|
209
|
+
var FILE_HISTORY_MARKER = ".file-history-cleanup";
|
|
210
|
+
var started = false;
|
|
211
|
+
function startBackgroundHousekeeping(config, settings) {
|
|
212
|
+
if (started) return;
|
|
213
|
+
started = true;
|
|
214
|
+
void scheduleFirstPass(config, settings).catch((err) => {
|
|
215
|
+
started = false;
|
|
216
|
+
debugLogger3.error(
|
|
217
|
+
"scheduleFirstPass failed; chain will retry on next start",
|
|
218
|
+
err
|
|
219
|
+
);
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
__name(startBackgroundHousekeeping, "startBackgroundHousekeeping");
|
|
223
|
+
async function scheduleFirstPass(config, settings) {
|
|
224
|
+
const markerPath = join2(Storage.getGlobalQwenDir(), FILE_HISTORY_MARKER);
|
|
225
|
+
const delay = await needsCatchUp(markerPath) ? STARTUP_DELAY_CATCHUP_MS : STARTUP_DELAY_MS;
|
|
226
|
+
debugLogger3.debug(`first pass in ${delay / 1e3}s`);
|
|
227
|
+
setTimeout(() => scheduleNextPass(config, settings), delay).unref();
|
|
228
|
+
}
|
|
229
|
+
__name(scheduleFirstPass, "scheduleFirstPass");
|
|
230
|
+
async function needsCatchUp(markerPath) {
|
|
231
|
+
try {
|
|
232
|
+
const s = await stat3(markerPath);
|
|
233
|
+
return Date.now() - s.mtimeMs > CATCHUP_THRESHOLD_MS;
|
|
234
|
+
} catch {
|
|
235
|
+
return true;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
__name(needsCatchUp, "needsCatchUp");
|
|
239
|
+
async function runPass(config, settings) {
|
|
240
|
+
if (msSinceLastInteraction() < RECENT_INTERACTION_MS) {
|
|
241
|
+
debugLogger3.debug("user active, deferring 10 min");
|
|
242
|
+
setTimeout(
|
|
243
|
+
() => scheduleNextPass(config, settings),
|
|
244
|
+
STARTUP_DELAY_MS
|
|
245
|
+
).unref();
|
|
246
|
+
return;
|
|
247
|
+
}
|
|
248
|
+
try {
|
|
249
|
+
await runHousekeeping(config, settings);
|
|
250
|
+
} catch (err) {
|
|
251
|
+
debugLogger3.error("housekeeping pass failed; will retry next cycle", err);
|
|
252
|
+
}
|
|
253
|
+
setTimeout(
|
|
254
|
+
() => scheduleNextPass(config, settings),
|
|
255
|
+
RECURRING_INTERVAL_MS
|
|
256
|
+
).unref();
|
|
257
|
+
}
|
|
258
|
+
__name(runPass, "runPass");
|
|
259
|
+
function scheduleNextPass(config, settings) {
|
|
260
|
+
void runPass(config, settings).catch((err) => {
|
|
261
|
+
debugLogger3.error("runPass rejected unexpectedly", err);
|
|
262
|
+
});
|
|
263
|
+
}
|
|
264
|
+
__name(scheduleNextPass, "scheduleNextPass");
|
|
265
|
+
async function runHousekeeping(config, settings) {
|
|
266
|
+
const days = settings.merged.general?.cleanupPeriodDays ?? 30;
|
|
267
|
+
const cutoff = getCutoffDate(days);
|
|
268
|
+
const currentSessionId = config.getSessionId();
|
|
269
|
+
const qwenDir = Storage.getGlobalQwenDir();
|
|
270
|
+
await runThrottledOnce(
|
|
271
|
+
{
|
|
272
|
+
name: "file-history-cleanup",
|
|
273
|
+
markerPath: join2(qwenDir, FILE_HISTORY_MARKER),
|
|
274
|
+
lockPath: join2(qwenDir, FILE_HISTORY_MARKER + ".lock")
|
|
275
|
+
},
|
|
276
|
+
async () => {
|
|
277
|
+
const r = await cleanupOldFileHistoryBackups({
|
|
278
|
+
cutoffDate: cutoff,
|
|
279
|
+
excludeSessionIds: /* @__PURE__ */ new Set([currentSessionId])
|
|
280
|
+
});
|
|
281
|
+
debugLogger3.debug(
|
|
282
|
+
`file-history: removed=${r.removed} errors=${r.errors}`
|
|
283
|
+
);
|
|
284
|
+
}
|
|
285
|
+
);
|
|
286
|
+
}
|
|
287
|
+
__name(runHousekeeping, "runHousekeeping");
|
|
288
|
+
function _resetForTesting() {
|
|
289
|
+
started = false;
|
|
290
|
+
}
|
|
291
|
+
__name(_resetForTesting, "_resetForTesting");
|
|
292
|
+
var _needsCatchUpForTesting = needsCatchUp;
|
|
293
|
+
var _runHousekeepingForTesting = runHousekeeping;
|
|
294
|
+
var _runPassForTesting = runPass;
|
|
295
|
+
var _FILE_HISTORY_MARKER_FOR_TESTING = FILE_HISTORY_MARKER;
|
|
296
|
+
export {
|
|
297
|
+
_FILE_HISTORY_MARKER_FOR_TESTING,
|
|
298
|
+
_needsCatchUpForTesting,
|
|
299
|
+
_resetForTesting,
|
|
300
|
+
_runHousekeepingForTesting,
|
|
301
|
+
_runPassForTesting,
|
|
302
|
+
startBackgroundHousekeeping
|
|
303
|
+
};
|
|
304
|
+
/**
|
|
305
|
+
* @license
|
|
306
|
+
* Copyright 2025 Google LLC
|
|
307
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
308
|
+
*/
|
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
// Force strict mode and setup for ESM
|
|
2
|
+
"use strict";
|
|
3
|
+
import {
|
|
4
|
+
LEADER_NAME,
|
|
5
|
+
getAgentName,
|
|
6
|
+
isTeammate
|
|
7
|
+
} from "./chunk-LD2XBG6Z.js";
|
|
8
|
+
import {
|
|
9
|
+
BaseDeclarativeTool,
|
|
10
|
+
BaseToolInvocation,
|
|
11
|
+
ToolDisplayNames,
|
|
12
|
+
ToolNames
|
|
13
|
+
} from "./chunk-D3RHSPAS.js";
|
|
14
|
+
import "./chunk-HR7SV7AY.js";
|
|
15
|
+
import "./chunk-Z2Z3GUXZ.js";
|
|
16
|
+
import {
|
|
17
|
+
init_esbuild_shims
|
|
18
|
+
} from "./chunk-A4BMJM77.js";
|
|
19
|
+
import {
|
|
20
|
+
__name
|
|
21
|
+
} from "./chunk-J2S4EL5Y.js";
|
|
22
|
+
|
|
23
|
+
// packages/core/src/tools/send-message.ts
|
|
24
|
+
init_esbuild_shims();
|
|
25
|
+
var SendMessageInvocation = class extends BaseToolInvocation {
|
|
26
|
+
constructor(config, params) {
|
|
27
|
+
super(params);
|
|
28
|
+
this.config = config;
|
|
29
|
+
}
|
|
30
|
+
static {
|
|
31
|
+
__name(this, "SendMessageInvocation");
|
|
32
|
+
}
|
|
33
|
+
getDescription() {
|
|
34
|
+
if (this.params.task_id) {
|
|
35
|
+
return `Send message to task ${this.params.task_id}`;
|
|
36
|
+
}
|
|
37
|
+
const preview = this.params.summary ?? this.params.message.slice(0, 50);
|
|
38
|
+
return `Send to ${this.params.to}: ${preview}`;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Send-message routes free-form text into a running background task or a
|
|
42
|
+
* teammate, which will then execute it as a new instruction with full
|
|
43
|
+
* tool access. Treat it as a privileged sink — the L4 default must not be
|
|
44
|
+
* 'allow', because that would let the scheduler auto-approve in
|
|
45
|
+
* AUTO mode (where 'allow' short-circuits the classifier). 'ask' lets
|
|
46
|
+
* AUTO route through the classifier so the destination and message text
|
|
47
|
+
* can be inspected.
|
|
48
|
+
*/
|
|
49
|
+
async getDefaultPermission() {
|
|
50
|
+
return "ask";
|
|
51
|
+
}
|
|
52
|
+
async execute(_signal) {
|
|
53
|
+
if (this.params.task_id) {
|
|
54
|
+
const registry = this.config.getBackgroundTaskRegistry();
|
|
55
|
+
const entry = registry.get(this.params.task_id);
|
|
56
|
+
if (!entry) {
|
|
57
|
+
return {
|
|
58
|
+
llmContent: `Error: No background task found with ID "${this.params.task_id}".`,
|
|
59
|
+
returnDisplay: "Task not found.",
|
|
60
|
+
error: {
|
|
61
|
+
message: `Task not found: ${this.params.task_id}`,
|
|
62
|
+
type: "send_message_not_found" /* SEND_MESSAGE_NOT_FOUND */
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
if (entry.status === "paused") {
|
|
67
|
+
const resumed = await this.config.resumeBackgroundAgent(
|
|
68
|
+
this.params.task_id,
|
|
69
|
+
this.params.message
|
|
70
|
+
);
|
|
71
|
+
if (!resumed) {
|
|
72
|
+
return {
|
|
73
|
+
llmContent: `Error: Background task "${this.params.task_id}" could not be resumed.`,
|
|
74
|
+
returnDisplay: "Task could not be resumed.",
|
|
75
|
+
error: {
|
|
76
|
+
message: `Task could not be resumed: ${this.params.task_id}`,
|
|
77
|
+
type: "send_message_not_running" /* SEND_MESSAGE_NOT_RUNNING */
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
return {
|
|
82
|
+
llmContent: `Background task "${this.params.task_id}" resumed with your message as the first continuation instruction.`,
|
|
83
|
+
returnDisplay: `Resumed ${entry.description}`
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
if (entry.status !== "running") {
|
|
87
|
+
return {
|
|
88
|
+
llmContent: `Error: Background task "${this.params.task_id}" is not running (status: ${entry.status}). Cannot send messages to stopped tasks.`,
|
|
89
|
+
returnDisplay: `Task not running (${entry.status}).`,
|
|
90
|
+
error: {
|
|
91
|
+
message: `Task is ${entry.status}: ${this.params.task_id}`,
|
|
92
|
+
type: "send_message_not_running" /* SEND_MESSAGE_NOT_RUNNING */
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
registry.queueMessage(this.params.task_id, this.params.message);
|
|
97
|
+
return {
|
|
98
|
+
llmContent: `Message queued for delivery to background task "${this.params.task_id}". The task will receive it at the next tool-round boundary.`,
|
|
99
|
+
returnDisplay: `Message queued for ${entry.description}`
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
const teamManager = this.config.getTeamManager();
|
|
103
|
+
if (!teamManager) {
|
|
104
|
+
const msg = "No active team and no task_id provided. Either create a team first, or pass `task_id` to message a background task.";
|
|
105
|
+
return {
|
|
106
|
+
llmContent: msg,
|
|
107
|
+
returnDisplay: msg,
|
|
108
|
+
error: { message: msg }
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
const to = this.params.to;
|
|
112
|
+
if (!to) {
|
|
113
|
+
const msg = 'Recipient "to" is required.';
|
|
114
|
+
return {
|
|
115
|
+
llmContent: msg,
|
|
116
|
+
returnDisplay: msg,
|
|
117
|
+
error: { message: msg }
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
try {
|
|
121
|
+
if (this.params.type === "shutdown_request") {
|
|
122
|
+
if (isTeammate()) {
|
|
123
|
+
const msg3 = "Only the team leader can request shutdowns.";
|
|
124
|
+
return {
|
|
125
|
+
llmContent: msg3,
|
|
126
|
+
returnDisplay: msg3,
|
|
127
|
+
error: { message: msg3 }
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
await teamManager.requestShutdown(to);
|
|
131
|
+
const msg2 = `Shutdown requested for "${to}".`;
|
|
132
|
+
return { llmContent: msg2, returnDisplay: msg2 };
|
|
133
|
+
}
|
|
134
|
+
if (to === "*") {
|
|
135
|
+
const sender = getAgentName() ?? LEADER_NAME;
|
|
136
|
+
await teamManager.broadcast(this.params.message, sender);
|
|
137
|
+
const msg2 = "Message broadcast to all teammates.";
|
|
138
|
+
return { llmContent: msg2, returnDisplay: msg2 };
|
|
139
|
+
}
|
|
140
|
+
await teamManager.sendMessage(
|
|
141
|
+
to,
|
|
142
|
+
this.params.message,
|
|
143
|
+
getAgentName() ?? LEADER_NAME,
|
|
144
|
+
this.params.summary
|
|
145
|
+
);
|
|
146
|
+
const msg = `Message sent to "${to}".`;
|
|
147
|
+
return { llmContent: msg, returnDisplay: msg };
|
|
148
|
+
} catch (error) {
|
|
149
|
+
const errMsg = error instanceof Error ? error.message : String(error);
|
|
150
|
+
return {
|
|
151
|
+
llmContent: `Failed to send message: ${errMsg}`,
|
|
152
|
+
returnDisplay: `Failed to send message: ${errMsg}`,
|
|
153
|
+
error: { message: errMsg }
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
};
|
|
158
|
+
var SendMessageTool = class _SendMessageTool extends BaseDeclarativeTool {
|
|
159
|
+
constructor(config) {
|
|
160
|
+
super(
|
|
161
|
+
_SendMessageTool.Name,
|
|
162
|
+
ToolDisplayNames.SEND_MESSAGE,
|
|
163
|
+
'Send a message to a teammate (use "to") or to a running background task (use "task_id"). For teams, set "to" to a bare teammate name (no @) or "*" to broadcast. For background tasks, set "task_id" to the id from the launch response or a recovered paused task. Running tasks receive it at the next tool-round boundary; paused recovered tasks are resumed with the message as their first continuation instruction. Your text output is NOT visible to other agents \u2014 use this tool to communicate.',
|
|
164
|
+
"other" /* Other */,
|
|
165
|
+
{
|
|
166
|
+
type: "object",
|
|
167
|
+
properties: {
|
|
168
|
+
to: {
|
|
169
|
+
type: "string",
|
|
170
|
+
description: 'Recipient teammate name, or "*" for broadcast.'
|
|
171
|
+
},
|
|
172
|
+
task_id: {
|
|
173
|
+
type: "string",
|
|
174
|
+
description: "The ID of the background task (from the launch response or a recovered paused task)."
|
|
175
|
+
},
|
|
176
|
+
message: {
|
|
177
|
+
type: "string",
|
|
178
|
+
description: "Message text to send.",
|
|
179
|
+
// Cap message size so a teammate can't grow the
|
|
180
|
+
// recipient's inbox file unboundedly with a single send.
|
|
181
|
+
maxLength: 65536
|
|
182
|
+
},
|
|
183
|
+
summary: {
|
|
184
|
+
type: "string",
|
|
185
|
+
description: "Optional 5-10 word summary for UI display."
|
|
186
|
+
},
|
|
187
|
+
type: {
|
|
188
|
+
type: "string",
|
|
189
|
+
enum: ["shutdown_request"],
|
|
190
|
+
description: "Structured message type for control flow. When set, routes through the mailbox instead of plain text delivery."
|
|
191
|
+
}
|
|
192
|
+
},
|
|
193
|
+
required: ["message"],
|
|
194
|
+
// Either a teammate recipient (`to`) or a background-task
|
|
195
|
+
// (`task_id`) must be specified — they correspond to the
|
|
196
|
+
// two routing modes. Letting the model send `{message}`
|
|
197
|
+
// alone wastes a round-trip on the runtime "Recipient is
|
|
198
|
+
// required" error.
|
|
199
|
+
oneOf: [{ required: ["to"] }, { required: ["task_id"] }],
|
|
200
|
+
additionalProperties: false
|
|
201
|
+
},
|
|
202
|
+
true,
|
|
203
|
+
// isOutputMarkdown
|
|
204
|
+
false,
|
|
205
|
+
// canUpdateOutput
|
|
206
|
+
true,
|
|
207
|
+
// shouldDefer — sending messages is infrequent
|
|
208
|
+
false,
|
|
209
|
+
// alwaysLoad
|
|
210
|
+
"send message task teammate team communicate notify"
|
|
211
|
+
);
|
|
212
|
+
this.config = config;
|
|
213
|
+
}
|
|
214
|
+
static {
|
|
215
|
+
__name(this, "SendMessageTool");
|
|
216
|
+
}
|
|
217
|
+
static Name = ToolNames.SEND_MESSAGE;
|
|
218
|
+
createInvocation(params) {
|
|
219
|
+
return new SendMessageInvocation(this.config, params);
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Forward the routing fields and the message verbatim to the classifier —
|
|
223
|
+
* `to`/`task_id` identify the privileged sink and the `message` itself is
|
|
224
|
+
* the new instruction the recipient will execute, so the classifier needs
|
|
225
|
+
* the full text to evaluate the action's safety. `type` surfaces control
|
|
226
|
+
* messages (e.g. shutdown_request).
|
|
227
|
+
*/
|
|
228
|
+
toAutoClassifierInput(params) {
|
|
229
|
+
return {
|
|
230
|
+
to: params.to,
|
|
231
|
+
task_id: params.task_id,
|
|
232
|
+
message: params.message,
|
|
233
|
+
type: params.type
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
};
|
|
237
|
+
export {
|
|
238
|
+
SendMessageTool
|
|
239
|
+
};
|
|
240
|
+
/**
|
|
241
|
+
* @license
|
|
242
|
+
* Copyright 2025 Qwen
|
|
243
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
244
|
+
*/
|