cli-claw-kit 0.0.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/LICENSE +21 -0
- package/README.md +245 -0
- package/config/default-groups.json +1 -0
- package/config/global-agents-md.template.md +37 -0
- package/config/mount-allowlist.json +11 -0
- package/container/Dockerfile +160 -0
- package/container/agent-runner/dist/.tsbuildinfo +1 -0
- package/container/agent-runner/dist/agent-definitions.js +22 -0
- package/container/agent-runner/dist/channel-prefixes.js +16 -0
- package/container/agent-runner/dist/codex-config.js +29 -0
- package/container/agent-runner/dist/image-detector.js +96 -0
- package/container/agent-runner/dist/index.js +2587 -0
- package/container/agent-runner/dist/mcp-tools.js +1076 -0
- package/container/agent-runner/dist/stream-event.types.js +5 -0
- package/container/agent-runner/dist/stream-processor.js +867 -0
- package/container/agent-runner/dist/types.js +6 -0
- package/container/agent-runner/dist/utils.js +115 -0
- package/container/agent-runner/package.json +36 -0
- package/container/agent-runner/prompts/security-rules.md +31 -0
- package/container/agent-runner/src/agent-definitions.ts +27 -0
- package/container/agent-runner/src/channel-prefixes.ts +16 -0
- package/container/agent-runner/src/codex-config.ts +40 -0
- package/container/agent-runner/src/image-detector.ts +116 -0
- package/container/agent-runner/src/index.ts +3107 -0
- package/container/agent-runner/src/mcp-tools.ts +1295 -0
- package/container/agent-runner/src/stream-event.types.ts +10 -0
- package/container/agent-runner/src/stream-processor.ts +932 -0
- package/container/agent-runner/src/types.ts +75 -0
- package/container/agent-runner/src/utils.ts +114 -0
- package/container/agent-runner/tsconfig.json +17 -0
- package/container/build.sh +28 -0
- package/container/entrypoint.sh +64 -0
- package/container/skills/agent-browser/SKILL.md +159 -0
- package/container/skills/install-skill/SKILL.md +64 -0
- package/container/skills/post-test-cleanup/SKILL.md +121 -0
- package/dist/.tsbuildinfo +1 -0
- package/dist/agent-output-parser.js +459 -0
- package/dist/app-root.js +52 -0
- package/dist/assistant-meta-footer.js +1 -0
- package/dist/auth.js +91 -0
- package/dist/billing.js +694 -0
- package/dist/channel-prefixes.js +16 -0
- package/dist/cli.js +86 -0
- package/dist/commands.js +79 -0
- package/dist/config.js +120 -0
- package/dist/container-runner.js +981 -0
- package/dist/daily-summary.js +210 -0
- package/dist/db.js +3683 -0
- package/dist/dingtalk.js +1347 -0
- package/dist/feishu-markdown-style.js +97 -0
- package/dist/feishu-streaming-card.js +1875 -0
- package/dist/feishu.js +1628 -0
- package/dist/file-manager.js +270 -0
- package/dist/group-queue.js +1070 -0
- package/dist/group-runtime.js +35 -0
- package/dist/host-workspace-cwd.js +85 -0
- package/dist/im-channel.js +384 -0
- package/dist/im-command-utils.js +142 -0
- package/dist/im-downloader.js +45 -0
- package/dist/im-manager.js +527 -0
- package/dist/im-utils.js +53 -0
- package/dist/image-detector.js +96 -0
- package/dist/index.js +5828 -0
- package/dist/logger.js +22 -0
- package/dist/mcp-utils.js +66 -0
- package/dist/message-attachments.js +69 -0
- package/dist/message-notifier.js +36 -0
- package/dist/middleware/auth.js +85 -0
- package/dist/mount-security.js +315 -0
- package/dist/permissions.js +67 -0
- package/dist/project-memory.js +6 -0
- package/dist/provider-pool.js +189 -0
- package/dist/qq.js +826 -0
- package/dist/reset-admin.js +42 -0
- package/dist/routes/admin.js +543 -0
- package/dist/routes/agent-definitions.js +241 -0
- package/dist/routes/agents.js +533 -0
- package/dist/routes/auth.js +675 -0
- package/dist/routes/billing.js +490 -0
- package/dist/routes/browse.js +210 -0
- package/dist/routes/bug-report.js +387 -0
- package/dist/routes/config.js +1868 -0
- package/dist/routes/files.js +671 -0
- package/dist/routes/groups.js +1367 -0
- package/dist/routes/mcp-servers.js +320 -0
- package/dist/routes/memory.js +523 -0
- package/dist/routes/monitor.js +307 -0
- package/dist/routes/skills.js +777 -0
- package/dist/routes/tasks.js +509 -0
- package/dist/routes/usage.js +64 -0
- package/dist/routes/workspace-config.js +458 -0
- package/dist/runtime-build.js +112 -0
- package/dist/runtime-command-handler.js +189 -0
- package/dist/runtime-command-registry.js +1 -0
- package/dist/runtime-config.js +1777 -0
- package/dist/runtime-identity.js +52 -0
- package/dist/schemas.js +590 -0
- package/dist/script-runner.js +64 -0
- package/dist/sdk-query.js +82 -0
- package/dist/skill-utils.js +145 -0
- package/dist/sqlite-compat.js +19 -0
- package/dist/stream-event.types.js +5 -0
- package/dist/streaming-runtime-meta.js +29 -0
- package/dist/task-scheduler.js +695 -0
- package/dist/task-utils.js +13 -0
- package/dist/telegram-pairing.js +59 -0
- package/dist/telegram.js +897 -0
- package/dist/terminal-manager.js +307 -0
- package/dist/tool-step-display.js +1 -0
- package/dist/types.js +1 -0
- package/dist/utils.js +85 -0
- package/dist/web-context.js +161 -0
- package/dist/web.js +1377 -0
- package/dist/wechat-crypto.js +182 -0
- package/dist/wechat.js +589 -0
- package/dist/workspace-runtime-reset.js +35 -0
- package/package.json +107 -0
- package/shared/assistant-meta-footer.ts +127 -0
- package/shared/channel-prefixes.ts +16 -0
- package/shared/dist/assistant-meta-footer.d.ts +29 -0
- package/shared/dist/assistant-meta-footer.js +85 -0
- package/shared/dist/channel-prefixes.d.ts +4 -0
- package/shared/dist/channel-prefixes.js +16 -0
- package/shared/dist/image-detector.d.ts +20 -0
- package/shared/dist/image-detector.js +96 -0
- package/shared/dist/runtime-command-registry.d.ts +38 -0
- package/shared/dist/runtime-command-registry.js +185 -0
- package/shared/dist/stream-event.d.ts +65 -0
- package/shared/dist/stream-event.js +8 -0
- package/shared/dist/tool-step-display.d.ts +4 -0
- package/shared/dist/tool-step-display.js +11 -0
- package/shared/image-detector.ts +116 -0
- package/shared/runtime-command-registry.ts +252 -0
- package/shared/stream-event.ts +67 -0
- package/shared/tool-step-display.ts +21 -0
- package/shared/tsconfig.json +24 -0
- package/web/dist/assets/BillingPage-B1wBR_o-.js +52 -0
- package/web/dist/assets/ChatPage-6GBZ9nXN.css +32 -0
- package/web/dist/assets/ChatPage-BOJcXtaj.js +161 -0
- package/web/dist/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2 +0 -0
- package/web/dist/assets/KaTeX_AMS-Regular-DMm9YOAa.woff +0 -0
- package/web/dist/assets/KaTeX_AMS-Regular-DRggAlZN.ttf +0 -0
- package/web/dist/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf +0 -0
- package/web/dist/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff +0 -0
- package/web/dist/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 +0 -0
- package/web/dist/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff +0 -0
- package/web/dist/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 +0 -0
- package/web/dist/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf +0 -0
- package/web/dist/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf +0 -0
- package/web/dist/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff +0 -0
- package/web/dist/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 +0 -0
- package/web/dist/assets/KaTeX_Fraktur-Regular-CB_wures.ttf +0 -0
- package/web/dist/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 +0 -0
- package/web/dist/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff +0 -0
- package/web/dist/assets/KaTeX_Main-Bold-Cx986IdX.woff2 +0 -0
- package/web/dist/assets/KaTeX_Main-Bold-Jm3AIy58.woff +0 -0
- package/web/dist/assets/KaTeX_Main-Bold-waoOVXN0.ttf +0 -0
- package/web/dist/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 +0 -0
- package/web/dist/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf +0 -0
- package/web/dist/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff +0 -0
- package/web/dist/assets/KaTeX_Main-Italic-3WenGoN9.ttf +0 -0
- package/web/dist/assets/KaTeX_Main-Italic-BMLOBm91.woff +0 -0
- package/web/dist/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2 +0 -0
- package/web/dist/assets/KaTeX_Main-Regular-B22Nviop.woff2 +0 -0
- package/web/dist/assets/KaTeX_Main-Regular-Dr94JaBh.woff +0 -0
- package/web/dist/assets/KaTeX_Main-Regular-ypZvNtVU.ttf +0 -0
- package/web/dist/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf +0 -0
- package/web/dist/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 +0 -0
- package/web/dist/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff +0 -0
- package/web/dist/assets/KaTeX_Math-Italic-DA0__PXp.woff +0 -0
- package/web/dist/assets/KaTeX_Math-Italic-flOr_0UB.ttf +0 -0
- package/web/dist/assets/KaTeX_Math-Italic-t53AETM-.woff2 +0 -0
- package/web/dist/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf +0 -0
- package/web/dist/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 +0 -0
- package/web/dist/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff +0 -0
- package/web/dist/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 +0 -0
- package/web/dist/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff +0 -0
- package/web/dist/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf +0 -0
- package/web/dist/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf +0 -0
- package/web/dist/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff +0 -0
- package/web/dist/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 +0 -0
- package/web/dist/assets/KaTeX_Script-Regular-C5JkGWo-.ttf +0 -0
- package/web/dist/assets/KaTeX_Script-Regular-D3wIWfF6.woff2 +0 -0
- package/web/dist/assets/KaTeX_Script-Regular-D5yQViql.woff +0 -0
- package/web/dist/assets/KaTeX_Size1-Regular-C195tn64.woff +0 -0
- package/web/dist/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf +0 -0
- package/web/dist/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2 +0 -0
- package/web/dist/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf +0 -0
- package/web/dist/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2 +0 -0
- package/web/dist/assets/KaTeX_Size2-Regular-oD1tc_U0.woff +0 -0
- package/web/dist/assets/KaTeX_Size3-Regular-CTq5MqoE.woff +0 -0
- package/web/dist/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf +0 -0
- package/web/dist/assets/KaTeX_Size4-Regular-BF-4gkZK.woff +0 -0
- package/web/dist/assets/KaTeX_Size4-Regular-DWFBv043.ttf +0 -0
- package/web/dist/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2 +0 -0
- package/web/dist/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff +0 -0
- package/web/dist/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 +0 -0
- package/web/dist/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf +0 -0
- package/web/dist/assets/SettingsPage-DoY7FoZ_.js +153 -0
- package/web/dist/assets/ShareImageDialog-C1ga8b7l.js +22 -0
- package/web/dist/assets/TasksPage-CRivnNsx.js +14 -0
- package/web/dist/assets/_basePickBy-Bf-bSoS9.js +1 -0
- package/web/dist/assets/_baseUniq-zAOaCuKw.js +1 -0
- package/web/dist/assets/arc-Dm9mVQ9U.js +1 -0
- package/web/dist/assets/architectureDiagram-2XIMDMQ5-BLmzX1wr.js +36 -0
- package/web/dist/assets/band-CquvqAHh.js +1 -0
- package/web/dist/assets/blockDiagram-WCTKOSBZ-B9pcqm3j.js +132 -0
- package/web/dist/assets/c4Diagram-IC4MRINW-Cytx1q3b.js +10 -0
- package/web/dist/assets/channel-BOVj73LR.js +1 -0
- package/web/dist/assets/channel-meta-CQD0Pei-.js +41 -0
- package/web/dist/assets/chunk-4BX2VUAB-0ToDr6RE.js +1 -0
- package/web/dist/assets/chunk-55IACEB6-DQDjnXfS.js +1 -0
- package/web/dist/assets/chunk-FMBD7UC4-Di8ABm6c.js +15 -0
- package/web/dist/assets/chunk-JSJVCQXG-BZQN6rnX.js +1 -0
- package/web/dist/assets/chunk-KX2RTZJC-zBbcpaN_.js +1 -0
- package/web/dist/assets/chunk-NQ4KR5QH-BCrLoU88.js +220 -0
- package/web/dist/assets/chunk-QZHKN3VN-Bqk8juan.js +1 -0
- package/web/dist/assets/chunk-WL4C6EOR-D2YX-MHY.js +189 -0
- package/web/dist/assets/classDiagram-VBA2DB6C-DUUoMyaK.js +1 -0
- package/web/dist/assets/classDiagram-v2-RAHNMMFH-DUUoMyaK.js +1 -0
- package/web/dist/assets/clone-BmaCesfa.js +1 -0
- package/web/dist/assets/cose-bilkent-S5V4N54A-CTsv6qQA.js +1 -0
- package/web/dist/assets/cytoscape.esm-BQaXIfA_.js +331 -0
- package/web/dist/assets/dagre-KLK3FWXG-Ci4Jh9nu.js +4 -0
- package/web/dist/assets/defaultLocale-DX6XiGOO.js +1 -0
- package/web/dist/assets/diagram-E7M64L7V-BFRnfTI2.js +24 -0
- package/web/dist/assets/diagram-IFDJBPK2-B7Zhnp0b.js +43 -0
- package/web/dist/assets/diagram-P4PSJMXO-BVyP7nwq.js +24 -0
- package/web/dist/assets/erDiagram-INFDFZHY-NorKdTOF.js +70 -0
- package/web/dist/assets/error-CGD5mp5f.js +1 -0
- package/web/dist/assets/flowDiagram-PKNHOUZH-Ch97nABF.js +162 -0
- package/web/dist/assets/ganttDiagram-A5KZAMGK-BQ2pLWsy.js +292 -0
- package/web/dist/assets/gitGraphDiagram-K3NZZRJ6-bcvnBsD2.js +65 -0
- package/web/dist/assets/graph-CeAEckur.js +1 -0
- package/web/dist/assets/index-CPnL1_qC.js +768 -0
- package/web/dist/assets/index-DVevCbcO.css +10 -0
- package/web/dist/assets/infoDiagram-LFFYTUFH-CcsrFdj-.js +2 -0
- package/web/dist/assets/init-Dmth1JHB.js +1 -0
- package/web/dist/assets/ishikawaDiagram-PHBUUO56-1upyMfHN.js +70 -0
- package/web/dist/assets/journeyDiagram-4ABVD52K-CKUi-V0c.js +139 -0
- package/web/dist/assets/kanban-definition-K7BYSVSG-DOnQwXfL.js +89 -0
- package/web/dist/assets/layout-BmMMqTnJ.js +1 -0
- package/web/dist/assets/linear-DiaJloY5.js +1 -0
- package/web/dist/assets/mermaid.core-BWLV1B2v.js +254 -0
- package/web/dist/assets/mindmap-definition-YRQLILUH-BeAKHVWP.js +68 -0
- package/web/dist/assets/ordinal-DILIJJjt.js +1 -0
- package/web/dist/assets/pieDiagram-SKSYHLDU-DfiMSfWo.js +30 -0
- package/web/dist/assets/quadrantDiagram-337W2JSQ-wZxZOJxd.js +7 -0
- package/web/dist/assets/requirementDiagram-Z7DCOOCP-BK4HHm17.js +73 -0
- package/web/dist/assets/sankeyDiagram-WA2Y5GQK-BX6t2avX.js +10 -0
- package/web/dist/assets/sequenceDiagram-2WXFIKYE-BPQlkbAa.js +145 -0
- package/web/dist/assets/sheet-rI0FfB1g.js +6 -0
- package/web/dist/assets/sliders-horizontal-CuijWFNK.js +6 -0
- package/web/dist/assets/sparkles-BsMYXJoT.js +11 -0
- package/web/dist/assets/square-0CqMX1Q3.js +11 -0
- package/web/dist/assets/stateDiagram-RAJIS63D-DxkV0Vwd.js +1 -0
- package/web/dist/assets/stateDiagram-v2-FVOUBMTO-qLYoiOPe.js +1 -0
- package/web/dist/assets/step-D51IIHGA.js +1 -0
- package/web/dist/assets/tasks-D8JjBTwx.js +1 -0
- package/web/dist/assets/time-O8zIGux3.js +1 -0
- package/web/dist/assets/timeline-definition-YZTLITO2-kNp1DyFc.js +61 -0
- package/web/dist/assets/treemap-KZPCXAKY-CkrClVhk.js +162 -0
- package/web/dist/assets/utils-KGAn0XTg.js +11 -0
- package/web/dist/assets/vennDiagram-LZ73GAT5-CgdzEZz4.js +34 -0
- package/web/dist/assets/xychartDiagram-JWTSCODW-DfYGPfNB.js +7 -0
- package/web/dist/assets/zap-_hKJYy7J.js +6 -0
- package/web/dist/favicon.svg +332 -0
- package/web/dist/fonts/AlibabaPuHuiTi-3-55-Regular.woff2 +0 -0
- package/web/dist/fonts/AlibabaPuHuiTi-3-65-Medium.woff2 +0 -0
- package/web/dist/fonts/AlibabaPuHuiTi-3-75-SemiBold.woff2 +0 -0
- package/web/dist/fonts/DMSans-latin-ext.woff2 +0 -0
- package/web/dist/fonts/DMSans-latin.woff2 +0 -0
- package/web/dist/icons/README.md +20 -0
- package/web/dist/icons/apple-touch-icon-180.png +0 -0
- package/web/dist/icons/icon-128.png +0 -0
- package/web/dist/icons/icon-144.png +0 -0
- package/web/dist/icons/icon-152.png +0 -0
- package/web/dist/icons/icon-192.png +0 -0
- package/web/dist/icons/icon-192.svg +332 -0
- package/web/dist/icons/icon-384.png +0 -0
- package/web/dist/icons/icon-48.png +0 -0
- package/web/dist/icons/icon-512-maskable.png +0 -0
- package/web/dist/icons/icon-512.png +0 -0
- package/web/dist/icons/icon-512.svg +332 -0
- package/web/dist/icons/icon-72.png +0 -0
- package/web/dist/icons/icon-96.png +0 -0
- package/web/dist/icons/loading-logo.svg +332 -0
- package/web/dist/icons/logo-1024.png +0 -0
- package/web/dist/icons/logo-icon.svg +332 -0
- package/web/dist/icons/logo-text.svg +332 -0
- package/web/dist/index.html +30 -0
- package/web/dist/manifest.webmanifest +1 -0
- package/web/dist/registerSW.js +1 -0
- package/web/dist/sw.js +1 -0
- package/web/dist/workbox-08d6266a.js +1 -0
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/** IM channel type → JID prefix mapping. Shared between main server and agent-runner. */
|
|
2
|
+
export const CHANNEL_PREFIXES = {
|
|
3
|
+
feishu: 'feishu:',
|
|
4
|
+
telegram: 'telegram:',
|
|
5
|
+
qq: 'qq:',
|
|
6
|
+
wechat: 'wechat:',
|
|
7
|
+
dingtalk: 'dingtalk:',
|
|
8
|
+
};
|
|
9
|
+
/** Determine the channel type from a JID string. Returns 'web' for unrecognized prefixes. */
|
|
10
|
+
export function getChannelFromJid(jid) {
|
|
11
|
+
for (const [type, prefix] of Object.entries(CHANNEL_PREFIXES)) {
|
|
12
|
+
if (jid.startsWith(prefix))
|
|
13
|
+
return type;
|
|
14
|
+
}
|
|
15
|
+
return 'web';
|
|
16
|
+
}
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import fs from 'node:fs';
|
|
3
|
+
import { pathToFileURL } from 'node:url';
|
|
4
|
+
const HELP_TEXT = [
|
|
5
|
+
'Usage: cli-claw <command>',
|
|
6
|
+
'',
|
|
7
|
+
'Commands:',
|
|
8
|
+
' start',
|
|
9
|
+
' version',
|
|
10
|
+
' help',
|
|
11
|
+
'',
|
|
12
|
+
'Options:',
|
|
13
|
+
' -h, --help',
|
|
14
|
+
' -v, --version',
|
|
15
|
+
].join('\n');
|
|
16
|
+
function readPackageVersion() {
|
|
17
|
+
const packagePath = new URL('../package.json', import.meta.url);
|
|
18
|
+
const packageJson = JSON.parse(fs.readFileSync(packagePath, 'utf8'));
|
|
19
|
+
return packageJson.version ?? '0.0.0';
|
|
20
|
+
}
|
|
21
|
+
export function parseCliArgs(argv) {
|
|
22
|
+
const [firstArg] = argv;
|
|
23
|
+
switch (firstArg) {
|
|
24
|
+
case undefined:
|
|
25
|
+
case 'help':
|
|
26
|
+
case '-h':
|
|
27
|
+
case '--help':
|
|
28
|
+
return { command: 'help' };
|
|
29
|
+
case 'start':
|
|
30
|
+
return { command: 'start' };
|
|
31
|
+
case 'version':
|
|
32
|
+
case '-v':
|
|
33
|
+
case '--version':
|
|
34
|
+
return { command: 'version' };
|
|
35
|
+
default:
|
|
36
|
+
return { command: 'help' };
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
export function formatHelpText(_version) {
|
|
40
|
+
return HELP_TEXT;
|
|
41
|
+
}
|
|
42
|
+
async function loadBackendStart() {
|
|
43
|
+
const mod = (await import('./index.js'));
|
|
44
|
+
const candidate = mod.startCliClaw ?? mod.start ?? mod.main ?? mod.runCliClaw ?? mod.default;
|
|
45
|
+
if (typeof candidate !== 'function') {
|
|
46
|
+
throw new Error('cli-claw backend start export is unavailable; expected a callable start function from src/index.ts');
|
|
47
|
+
}
|
|
48
|
+
return candidate;
|
|
49
|
+
}
|
|
50
|
+
export async function runCli(argv, deps = {}) {
|
|
51
|
+
const parsed = parseCliArgs(argv);
|
|
52
|
+
const version = deps.version ?? readPackageVersion();
|
|
53
|
+
const stdout = deps.stdout ?? ((line) => console.log(line));
|
|
54
|
+
const stderr = deps.stderr ?? ((line) => console.error(line));
|
|
55
|
+
if (parsed.command === 'version') {
|
|
56
|
+
stdout(version);
|
|
57
|
+
return 0;
|
|
58
|
+
}
|
|
59
|
+
if (parsed.command === 'help') {
|
|
60
|
+
stdout(formatHelpText(version));
|
|
61
|
+
return 0;
|
|
62
|
+
}
|
|
63
|
+
try {
|
|
64
|
+
const start = deps.start ?? (await loadBackendStart());
|
|
65
|
+
await start();
|
|
66
|
+
return 0;
|
|
67
|
+
}
|
|
68
|
+
catch (error) {
|
|
69
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
70
|
+
stderr(message);
|
|
71
|
+
return 1;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
export async function main(argv = process.argv.slice(2)) {
|
|
75
|
+
const exitCode = await runCli(argv);
|
|
76
|
+
if (exitCode !== 0) {
|
|
77
|
+
process.exitCode = exitCode;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
if (process.argv[1] &&
|
|
81
|
+
import.meta.url === pathToFileURL(process.argv[1]).href) {
|
|
82
|
+
void main().catch((error) => {
|
|
83
|
+
console.error(error instanceof Error ? error.message : String(error));
|
|
84
|
+
process.exitCode = 1;
|
|
85
|
+
});
|
|
86
|
+
}
|
package/dist/commands.js
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Slash command handler — intercepts text commands (e.g. /clear) before they
|
|
3
|
+
* enter the normal message pipeline.
|
|
4
|
+
*/
|
|
5
|
+
import crypto from 'crypto';
|
|
6
|
+
import fs from 'fs';
|
|
7
|
+
import path from 'path';
|
|
8
|
+
import { deleteSession, getJidsByFolder, storeMessageDirect, ensureChatExists, } from './db.js';
|
|
9
|
+
import { DATA_DIR } from './config.js';
|
|
10
|
+
import { logger } from './logger.js';
|
|
11
|
+
// ─── Session file cleanup (mirrors groups.ts clearSessionJsonlFiles) ────
|
|
12
|
+
function clearSessionFiles(folder, agentId) {
|
|
13
|
+
const claudeDir = agentId
|
|
14
|
+
? path.join(DATA_DIR, 'sessions', folder, 'agents', agentId, '.claude')
|
|
15
|
+
: path.join(DATA_DIR, 'sessions', folder, '.claude');
|
|
16
|
+
if (!fs.existsSync(claudeDir))
|
|
17
|
+
return;
|
|
18
|
+
const keep = new Set(['settings.json']);
|
|
19
|
+
const entries = fs.readdirSync(claudeDir);
|
|
20
|
+
for (const entry of entries) {
|
|
21
|
+
if (keep.has(entry))
|
|
22
|
+
continue;
|
|
23
|
+
try {
|
|
24
|
+
fs.rmSync(path.join(claudeDir, entry), { recursive: true, force: true });
|
|
25
|
+
}
|
|
26
|
+
catch (err) {
|
|
27
|
+
logger.warn({ entry, folder, agentId, err }, 'Failed to remove session file, skipping');
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
// ─── Core reset ─────────────────────────────────────────────────
|
|
32
|
+
export async function executeSessionReset(baseChatJid, folder, deps, agentId) {
|
|
33
|
+
const targetJid = agentId ? `${baseChatJid}#agent:${agentId}` : baseChatJid;
|
|
34
|
+
if (agentId) {
|
|
35
|
+
// Agent-specific reset: only stop the agent's virtual JID process
|
|
36
|
+
await deps.queue.stopGroup(targetJid, { force: true });
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
// Main session reset: stop all processes for this folder
|
|
40
|
+
const siblingJids = getJidsByFolder(folder);
|
|
41
|
+
await Promise.all(siblingJids.map((j) => deps.queue.stopGroup(j, { force: true })));
|
|
42
|
+
}
|
|
43
|
+
// 2. Clear .claude/ session files (preserve settings.json)
|
|
44
|
+
clearSessionFiles(folder, agentId);
|
|
45
|
+
// 3. Delete session from DB (+ in-memory cache for main session)
|
|
46
|
+
deleteSession(folder, agentId);
|
|
47
|
+
if (!agentId) {
|
|
48
|
+
delete deps.sessions[folder];
|
|
49
|
+
}
|
|
50
|
+
// 4. Insert context_reset divider message into the correct JID
|
|
51
|
+
const dividerMessageId = crypto.randomUUID();
|
|
52
|
+
const timestamp = new Date().toISOString();
|
|
53
|
+
ensureChatExists(targetJid);
|
|
54
|
+
storeMessageDirect(dividerMessageId, targetJid, '__system__', 'system', 'context_reset', timestamp, true);
|
|
55
|
+
deps.broadcast(targetJid, {
|
|
56
|
+
id: dividerMessageId,
|
|
57
|
+
chat_jid: targetJid,
|
|
58
|
+
sender: '__system__',
|
|
59
|
+
sender_name: 'system',
|
|
60
|
+
content: 'context_reset',
|
|
61
|
+
timestamp,
|
|
62
|
+
is_from_me: true,
|
|
63
|
+
});
|
|
64
|
+
// 5. Advance lastAgentTimestamp so old messages before the reset are not
|
|
65
|
+
// re-sent to the next fresh agent session.
|
|
66
|
+
if (agentId) {
|
|
67
|
+
deps.setLastAgentTimestamp(targetJid, { timestamp, id: dividerMessageId });
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
const siblingJids = getJidsByFolder(folder);
|
|
71
|
+
for (const siblingJid of siblingJids) {
|
|
72
|
+
deps.setLastAgentTimestamp(siblingJid, {
|
|
73
|
+
timestamp,
|
|
74
|
+
id: dividerMessageId,
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
logger.info({ baseChatJid, targetJid, folder, agentId }, 'Session reset via /clear command');
|
|
79
|
+
}
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import path from 'path';
|
|
2
|
+
import fs from 'fs';
|
|
3
|
+
import crypto from 'crypto';
|
|
4
|
+
import os from 'os';
|
|
5
|
+
import { execFile } from 'node:child_process';
|
|
6
|
+
import { promisify } from 'node:util';
|
|
7
|
+
import { APP_ROOT } from './app-root.js';
|
|
8
|
+
export const ASSISTANT_NAME = process.env.ASSISTANT_NAME || 'cli-claw';
|
|
9
|
+
export const POLL_INTERVAL = 2000;
|
|
10
|
+
export const SCHEDULER_POLL_INTERVAL = 60000;
|
|
11
|
+
// Mount security: allowlist in project config/ directory
|
|
12
|
+
export const MOUNT_ALLOWLIST_PATH = path.resolve(APP_ROOT, 'config', 'mount-allowlist.json');
|
|
13
|
+
export const DATA_DIR = path.join(os.homedir(), '.cli-claw');
|
|
14
|
+
export const STORE_DIR = path.join(DATA_DIR, 'db');
|
|
15
|
+
export const GROUPS_DIR = path.join(DATA_DIR, 'groups');
|
|
16
|
+
export const MAIN_GROUP_FOLDER = 'main';
|
|
17
|
+
export const CONTAINER_IMAGE = process.env.CONTAINER_IMAGE || 'cli-claw-agent:latest';
|
|
18
|
+
// Timezone for scheduled tasks (cron expressions, etc.)
|
|
19
|
+
// Uses TZ env var with Asia/Shanghai fallback
|
|
20
|
+
export const TIMEZONE = process.env.TZ ||
|
|
21
|
+
Intl.DateTimeFormat().resolvedOptions().timeZone ||
|
|
22
|
+
'Asia/Shanghai';
|
|
23
|
+
// Web server configuration
|
|
24
|
+
export const WEB_PORT = parseInt(process.env.WEB_PORT || '3000', 10);
|
|
25
|
+
// Cookie configuration
|
|
26
|
+
// When accessed over HTTPS: use __Host- prefix (requires Secure; Path=/; no Domain)
|
|
27
|
+
// When accessed over HTTP (localhost dev or no TLS): use plain name
|
|
28
|
+
// Determined per-request via isSecureRequest(), not at startup
|
|
29
|
+
export const SESSION_COOKIE_NAME_SECURE = '__Host-cli-claw-session';
|
|
30
|
+
export const SESSION_COOKIE_NAME_PLAIN = 'cli-claw-session';
|
|
31
|
+
const SESSION_SECRET_FILE = path.join(DATA_DIR, 'config', 'session-secret.key');
|
|
32
|
+
function getOrCreateSessionSecret() {
|
|
33
|
+
// 1. Environment variable (highest priority — allows container/operator override)
|
|
34
|
+
if (process.env.WEB_SESSION_SECRET) {
|
|
35
|
+
return process.env.WEB_SESSION_SECRET;
|
|
36
|
+
}
|
|
37
|
+
// 2. File-persisted secret (survives restarts)
|
|
38
|
+
try {
|
|
39
|
+
if (fs.existsSync(SESSION_SECRET_FILE)) {
|
|
40
|
+
const stored = fs.readFileSync(SESSION_SECRET_FILE, 'utf-8').trim();
|
|
41
|
+
if (stored)
|
|
42
|
+
return stored;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
catch {
|
|
46
|
+
// ignore read errors, fall through
|
|
47
|
+
}
|
|
48
|
+
// 3. Generate and persist
|
|
49
|
+
const generated = crypto.randomBytes(32).toString('hex');
|
|
50
|
+
try {
|
|
51
|
+
fs.mkdirSync(path.dirname(SESSION_SECRET_FILE), { recursive: true });
|
|
52
|
+
fs.writeFileSync(SESSION_SECRET_FILE, generated + '\n', {
|
|
53
|
+
encoding: 'utf-8',
|
|
54
|
+
mode: 0o600,
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
catch {
|
|
58
|
+
// non-fatal: secret works for this process, just won't survive restart
|
|
59
|
+
}
|
|
60
|
+
return generated;
|
|
61
|
+
}
|
|
62
|
+
export const WEB_SESSION_SECRET = getOrCreateSessionSecret();
|
|
63
|
+
// Ensure WeChat iLink API domains bypass HTTP proxy.
|
|
64
|
+
// These Chinese domestic services are unreachable through most overseas proxies.
|
|
65
|
+
const WECHAT_NO_PROXY_DOMAINS = [
|
|
66
|
+
'ilinkai.weixin.qq.com',
|
|
67
|
+
'novac2c.cdn.weixin.qq.com',
|
|
68
|
+
];
|
|
69
|
+
/** Add or remove WeChat domains from NO_PROXY based on bypassProxy flag. */
|
|
70
|
+
export function updateWeChatNoProxy(bypassProxy) {
|
|
71
|
+
const current = process.env.NO_PROXY || process.env.no_proxy || '';
|
|
72
|
+
const existing = new Set(current
|
|
73
|
+
.split(',')
|
|
74
|
+
.map((s) => s.trim())
|
|
75
|
+
.filter(Boolean));
|
|
76
|
+
if (bypassProxy) {
|
|
77
|
+
const toAdd = WECHAT_NO_PROXY_DOMAINS.filter((d) => !existing.has(d));
|
|
78
|
+
if (toAdd.length) {
|
|
79
|
+
const updated = current
|
|
80
|
+
? `${current},${toAdd.join(',')}`
|
|
81
|
+
: toAdd.join(',');
|
|
82
|
+
process.env.NO_PROXY = updated;
|
|
83
|
+
process.env.no_proxy = updated;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
for (const d of WECHAT_NO_PROXY_DOMAINS)
|
|
88
|
+
existing.delete(d);
|
|
89
|
+
const updated = [...existing].join(',');
|
|
90
|
+
process.env.NO_PROXY = updated;
|
|
91
|
+
process.env.no_proxy = updated;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
/** Check if WeChat domains are currently in NO_PROXY. */
|
|
95
|
+
export function isWeChatBypassingProxy() {
|
|
96
|
+
const current = process.env.NO_PROXY || process.env.no_proxy || '';
|
|
97
|
+
const existing = new Set(current
|
|
98
|
+
.split(',')
|
|
99
|
+
.map((s) => s.trim())
|
|
100
|
+
.filter(Boolean));
|
|
101
|
+
return WECHAT_NO_PROXY_DOMAINS.every((d) => existing.has(d));
|
|
102
|
+
}
|
|
103
|
+
// Proxy trust configuration
|
|
104
|
+
// Set TRUST_PROXY=true when behind a reverse proxy (nginx, Cloudflare, etc.)
|
|
105
|
+
export const TRUST_PROXY = process.env.TRUST_PROXY === 'true';
|
|
106
|
+
// Docker availability check (cached for the lifetime of the process)
|
|
107
|
+
const execFileAsync = promisify(execFile);
|
|
108
|
+
let _dockerAvailable = null;
|
|
109
|
+
export async function isDockerAvailable() {
|
|
110
|
+
if (_dockerAvailable !== null)
|
|
111
|
+
return _dockerAvailable;
|
|
112
|
+
try {
|
|
113
|
+
await execFileAsync('docker', ['info'], { timeout: 10000 });
|
|
114
|
+
_dockerAvailable = true;
|
|
115
|
+
}
|
|
116
|
+
catch {
|
|
117
|
+
_dockerAvailable = false;
|
|
118
|
+
}
|
|
119
|
+
return _dockerAvailable;
|
|
120
|
+
}
|