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,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared types for cli-claw Agent Runner.
|
|
3
|
+
*
|
|
4
|
+
* These types are used across index.ts, stream-processor.ts, and mcp-tools.ts.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
// Streaming event types (canonical source: shared/stream-event.ts)
|
|
8
|
+
export type { StreamEventType, StreamEvent } from './stream-event.types.js';
|
|
9
|
+
import type { StreamEvent, StreamRuntimeIdentity } from './stream-event.types.js';
|
|
10
|
+
|
|
11
|
+
export interface ContainerInput {
|
|
12
|
+
prompt: string;
|
|
13
|
+
sessionId?: string;
|
|
14
|
+
turnId?: string;
|
|
15
|
+
groupFolder: string;
|
|
16
|
+
chatJid: string;
|
|
17
|
+
agentType?: 'claude' | 'codex';
|
|
18
|
+
model?: string | null;
|
|
19
|
+
reasoningEffort?: string | null;
|
|
20
|
+
/** @deprecated Use isHome + isAdminHome instead. Kept for backward compatibility with older host processes. */
|
|
21
|
+
isMain?: boolean;
|
|
22
|
+
/** Whether this is the user's home container (admin or member). */
|
|
23
|
+
isHome?: boolean;
|
|
24
|
+
/** Whether this is the admin's home container (full privileges). */
|
|
25
|
+
isAdminHome?: boolean;
|
|
26
|
+
isScheduledTask?: boolean;
|
|
27
|
+
images?: Array<{ data: string; mimeType?: string }>;
|
|
28
|
+
agentId?: string;
|
|
29
|
+
agentName?: string;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export interface ContainerOutput {
|
|
33
|
+
status: 'success' | 'error' | 'stream' | 'closed';
|
|
34
|
+
result: string | null;
|
|
35
|
+
newSessionId?: string;
|
|
36
|
+
error?: string;
|
|
37
|
+
alreadyStreamedError?: boolean;
|
|
38
|
+
runtimeIdentity?: StreamRuntimeIdentity | null;
|
|
39
|
+
streamEvent?: StreamEvent;
|
|
40
|
+
turnId?: string;
|
|
41
|
+
sessionId?: string;
|
|
42
|
+
sdkMessageUuid?: string;
|
|
43
|
+
sourceKind?: 'sdk_final' | 'sdk_send_message' | 'interrupt_partial' | 'overflow_partial' | 'compact_partial' | 'legacy' | 'auto_continue';
|
|
44
|
+
finalizationReason?: 'completed' | 'interrupted' | 'error';
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export interface SessionEntry {
|
|
48
|
+
sessionId: string;
|
|
49
|
+
fullPath: string;
|
|
50
|
+
summary: string;
|
|
51
|
+
firstPrompt: string;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export interface SessionsIndex {
|
|
55
|
+
entries: SessionEntry[];
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export type ImageMediaType = 'image/jpeg' | 'image/png' | 'image/gif' | 'image/webp';
|
|
59
|
+
|
|
60
|
+
export interface SDKUserMessage {
|
|
61
|
+
type: 'user';
|
|
62
|
+
message: {
|
|
63
|
+
role: 'user';
|
|
64
|
+
content:
|
|
65
|
+
| string
|
|
66
|
+
| Array<{ type: 'text'; text: string } | { type: 'image'; source: { type: 'base64'; media_type: ImageMediaType; data: string } }>;
|
|
67
|
+
};
|
|
68
|
+
parent_tool_use_id: null;
|
|
69
|
+
session_id: string;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export interface ParsedMessage {
|
|
73
|
+
role: 'user' | 'assistant';
|
|
74
|
+
content: string;
|
|
75
|
+
}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utility functions for cli-claw Agent Runner.
|
|
3
|
+
*
|
|
4
|
+
* Pure utility functions with no side effects or state dependencies.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Shorten a string to maxLen, appending "..." if truncated.
|
|
9
|
+
*/
|
|
10
|
+
export function shorten(input: string, maxLen = 180): string {
|
|
11
|
+
if (input.length <= maxLen) return input;
|
|
12
|
+
return `${input.slice(0, maxLen)}...`;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Recursively redact sensitive fields (tokens, passwords, API keys, etc.)
|
|
17
|
+
* from an object. Limits recursion depth to 3 levels.
|
|
18
|
+
*/
|
|
19
|
+
export function redactSensitive(input: unknown, depth = 0): unknown {
|
|
20
|
+
if (depth > 3) return '[truncated]';
|
|
21
|
+
if (input == null) return input;
|
|
22
|
+
if (typeof input === 'string' || typeof input === 'number' || typeof input === 'boolean') {
|
|
23
|
+
return input;
|
|
24
|
+
}
|
|
25
|
+
if (Array.isArray(input)) {
|
|
26
|
+
return input.slice(0, 10).map((item) => redactSensitive(item, depth + 1));
|
|
27
|
+
}
|
|
28
|
+
if (typeof input === 'object') {
|
|
29
|
+
const obj = input as Record<string, unknown>;
|
|
30
|
+
const out: Record<string, unknown> = {};
|
|
31
|
+
for (const [k, v] of Object.entries(obj)) {
|
|
32
|
+
if (/(token|password|secret|api[_-]?key|authorization|cookie)/iu.test(k)) {
|
|
33
|
+
out[k] = '[REDACTED]';
|
|
34
|
+
} else {
|
|
35
|
+
out[k] = redactSensitive(v, depth + 1);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return out;
|
|
39
|
+
}
|
|
40
|
+
return '[unsupported]';
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Summarize tool input for display in stream events.
|
|
45
|
+
* Extracts key fields (command, query, path, etc.) or serializes the object.
|
|
46
|
+
*/
|
|
47
|
+
export function summarizeToolInput(input: unknown): string | undefined {
|
|
48
|
+
if (input == null) return undefined;
|
|
49
|
+
|
|
50
|
+
if (typeof input === 'string') {
|
|
51
|
+
return shorten(input.trim());
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
if (typeof input === 'object') {
|
|
55
|
+
const obj = input as Record<string, unknown>;
|
|
56
|
+
const keyCandidates = ['command', 'query', 'path', 'pattern', 'prompt', 'url', 'name'];
|
|
57
|
+
for (const key of keyCandidates) {
|
|
58
|
+
const value = obj[key];
|
|
59
|
+
if (typeof value === 'string' && value.trim()) {
|
|
60
|
+
return `${key}: ${shorten(value.trim())}`;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
try {
|
|
64
|
+
const json = JSON.stringify(redactSensitive(obj));
|
|
65
|
+
// Skip empty or trivial objects (e.g. {} at content_block_start)
|
|
66
|
+
if (!json || json === '{}' || json === '[]') return undefined;
|
|
67
|
+
return shorten(json);
|
|
68
|
+
} catch {
|
|
69
|
+
return undefined;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
return undefined;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Extract a skill name from Skill tool input.
|
|
78
|
+
* Tries skillName, skill, name, command fields, then regex-matches leading slashes.
|
|
79
|
+
*/
|
|
80
|
+
export function extractSkillName(toolName: unknown, input: unknown): string | undefined {
|
|
81
|
+
if (toolName !== 'Skill') return undefined;
|
|
82
|
+
if (!input || typeof input !== 'object') return undefined;
|
|
83
|
+
const obj = input as Record<string, unknown>;
|
|
84
|
+
const raw =
|
|
85
|
+
(typeof obj.skillName === 'string' && obj.skillName) ||
|
|
86
|
+
(typeof obj.skill === 'string' && obj.skill) ||
|
|
87
|
+
(typeof obj.name === 'string' && obj.name) ||
|
|
88
|
+
(typeof obj.command === 'string' && obj.command) ||
|
|
89
|
+
'';
|
|
90
|
+
if (!raw) return undefined;
|
|
91
|
+
const matched = raw.match(/\/([A-Za-z0-9._-]+)/);
|
|
92
|
+
if (matched && matched[1]) return matched[1];
|
|
93
|
+
return raw.replace(/^\/+/, '').trim() || undefined;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Sanitize a string for use as a filename.
|
|
98
|
+
* Lowercases, replaces non-alphanumeric characters with hyphens, trims, and limits length.
|
|
99
|
+
*/
|
|
100
|
+
export function sanitizeFilename(summary: string): string {
|
|
101
|
+
return summary
|
|
102
|
+
.toLowerCase()
|
|
103
|
+
.replace(/[^\p{L}\p{N}]+/gu, '-')
|
|
104
|
+
.replace(/^-+|-+$/g, '')
|
|
105
|
+
.slice(0, 50);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Generate a fallback conversation archive filename based on current time.
|
|
110
|
+
*/
|
|
111
|
+
export function generateFallbackName(): string {
|
|
112
|
+
const time = new Date();
|
|
113
|
+
return `conversation-${time.getHours().toString().padStart(2, '0')}${time.getMinutes().toString().padStart(2, '0')}`;
|
|
114
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"lib": ["ES2022"],
|
|
5
|
+
"module": "NodeNext",
|
|
6
|
+
"moduleResolution": "NodeNext",
|
|
7
|
+
"outDir": "./dist",
|
|
8
|
+
"rootDir": "./src",
|
|
9
|
+
"strict": true,
|
|
10
|
+
"esModuleInterop": true,
|
|
11
|
+
"skipLibCheck": true,
|
|
12
|
+
"incremental": true,
|
|
13
|
+
"tsBuildInfoFile": "./dist/.tsbuildinfo"
|
|
14
|
+
},
|
|
15
|
+
"include": ["src/**/*"],
|
|
16
|
+
"exclude": ["node_modules", "dist"]
|
|
17
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Build the cli-claw agent container image
|
|
3
|
+
|
|
4
|
+
set -e
|
|
5
|
+
|
|
6
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
7
|
+
ROOT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
8
|
+
|
|
9
|
+
IMAGE_NAME="cli-claw-agent"
|
|
10
|
+
TAG="${1:-latest}"
|
|
11
|
+
|
|
12
|
+
echo "Building cli-claw agent container image..."
|
|
13
|
+
echo "Image: ${IMAGE_NAME}:${TAG}"
|
|
14
|
+
|
|
15
|
+
# Build with Docker (CACHEBUST ensures claude-code is always latest)
|
|
16
|
+
# --progress=plain ensures clean line-based output for piped log capture (WebSocket streaming)
|
|
17
|
+
docker build --progress=plain --build-arg CACHEBUST="$(date +%s)" -f "$SCRIPT_DIR/Dockerfile" -t "${IMAGE_NAME}:${TAG}" "$ROOT_DIR"
|
|
18
|
+
|
|
19
|
+
echo ""
|
|
20
|
+
echo "Build complete!"
|
|
21
|
+
echo "Image: ${IMAGE_NAME}:${TAG}"
|
|
22
|
+
|
|
23
|
+
# Touch sentinel so Makefile can detect stale image
|
|
24
|
+
touch "$ROOT_DIR/.docker-build-sentinel"
|
|
25
|
+
|
|
26
|
+
echo ""
|
|
27
|
+
echo "Test with:"
|
|
28
|
+
echo " printf '%s' '{\"prompt\":\"What is 2+2?\",\"groupFolder\":\"test\",\"chatJid\":\"test@g.us\",\"isMain\":false}' | docker run -i ${IMAGE_NAME}:${TAG}"
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
set -e
|
|
3
|
+
|
|
4
|
+
# Set permissive umask so files created by the container (node user, uid 1000)
|
|
5
|
+
# are writable by the host backend (agent user, uid 1002).
|
|
6
|
+
# Without this, the host cannot delete/modify files created by the container.
|
|
7
|
+
umask 0000
|
|
8
|
+
|
|
9
|
+
# Fix ownership on mounted volumes.
|
|
10
|
+
# Host uid may differ from container node user (uid 1000), especially in
|
|
11
|
+
# rootless podman where uid remapping causes EACCES on bind mounts.
|
|
12
|
+
# Running as root here so chown works regardless of host uid.
|
|
13
|
+
chown -R node:node /home/node/.claude 2>/dev/null || true
|
|
14
|
+
chown -R node:node /workspace/group /workspace/global /workspace/memory /workspace/ipc 2>/dev/null || true
|
|
15
|
+
|
|
16
|
+
# Source environment variables from mounted env file
|
|
17
|
+
if [ -f /workspace/env-dir/env ]; then
|
|
18
|
+
set -a
|
|
19
|
+
source /workspace/env-dir/env
|
|
20
|
+
set +a
|
|
21
|
+
fi
|
|
22
|
+
|
|
23
|
+
# Discover and link skills (builtin → project → user, higher priority overwrites)
|
|
24
|
+
# Only remove entries that conflict with mounted skills (non-symlink with same name),
|
|
25
|
+
# preserving any skills the agent created directly in .claude/skills/.
|
|
26
|
+
mkdir -p /home/node/.claude/skills
|
|
27
|
+
for dir in /opt/builtin-skills /workspace/project-skills /workspace/user-skills; do
|
|
28
|
+
if [ -d "$dir" ]; then
|
|
29
|
+
for skill in "$dir"/*/; do
|
|
30
|
+
if [ -d "$skill" ]; then
|
|
31
|
+
name=$(basename "$skill")
|
|
32
|
+
target="/home/node/.claude/skills/$name"
|
|
33
|
+
# Remove conflicting non-symlink entry (e.g. real directory from a failed agent edit)
|
|
34
|
+
if [ -e "$target" ] && [ ! -L "$target" ]; then
|
|
35
|
+
rm -rf "$target" 2>/dev/null || true
|
|
36
|
+
fi
|
|
37
|
+
ln -sfn "$skill" "$target" 2>/dev/null || true
|
|
38
|
+
fi
|
|
39
|
+
done
|
|
40
|
+
fi
|
|
41
|
+
done
|
|
42
|
+
chown -R node:node /home/node/.claude/skills 2>/dev/null || true
|
|
43
|
+
|
|
44
|
+
# Compile TypeScript (agent-runner source may be hot-mounted from host)
|
|
45
|
+
cd /app && npx tsc --outDir /tmp/dist 2>&1 >&2
|
|
46
|
+
ln -s /app/node_modules /tmp/dist/node_modules
|
|
47
|
+
ln -s /app/prompts /tmp/prompts
|
|
48
|
+
chmod -R a-w /tmp/dist
|
|
49
|
+
|
|
50
|
+
# Buffer stdin to file (container requires EOF to flush stdin pipe)
|
|
51
|
+
cat > /tmp/input.json
|
|
52
|
+
chmod 644 /tmp/input.json
|
|
53
|
+
|
|
54
|
+
# Fix permissions on exit: Claude Code creates some files with mode 0600
|
|
55
|
+
# (e.g. settings.json), which the host backend (agent user) cannot read.
|
|
56
|
+
# The trap runs as root after the node process exits.
|
|
57
|
+
cleanup() {
|
|
58
|
+
chmod -R a+rwX /home/node/.claude 2>/dev/null || true
|
|
59
|
+
chmod -R a+rwX /workspace/group 2>/dev/null || true
|
|
60
|
+
}
|
|
61
|
+
trap cleanup EXIT
|
|
62
|
+
|
|
63
|
+
# Drop privileges and execute agent-runner as node user
|
|
64
|
+
runuser -u node -- node /tmp/dist/index.js < /tmp/input.json
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: agent-browser
|
|
3
|
+
description: Browse the web for any task — research topics, read articles, interact with web apps, fill forms, take screenshots, extract data, and test web pages. Use whenever a browser would be useful, not just when the user explicitly asks.
|
|
4
|
+
allowed-tools: Bash(agent-browser:*)
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Browser Automation with agent-browser
|
|
8
|
+
|
|
9
|
+
## Quick start
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
agent-browser open <url> # Navigate to page
|
|
13
|
+
agent-browser snapshot -i # Get interactive elements with refs
|
|
14
|
+
agent-browser click @e1 # Click element by ref
|
|
15
|
+
agent-browser fill @e2 "text" # Fill input by ref
|
|
16
|
+
agent-browser close # Close browser
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Core workflow
|
|
20
|
+
|
|
21
|
+
1. Navigate: `agent-browser open <url>`
|
|
22
|
+
2. Snapshot: `agent-browser snapshot -i` (returns elements with refs like `@e1`, `@e2`)
|
|
23
|
+
3. Interact using refs from the snapshot
|
|
24
|
+
4. Re-snapshot after navigation or significant DOM changes
|
|
25
|
+
|
|
26
|
+
## Commands
|
|
27
|
+
|
|
28
|
+
### Navigation
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
agent-browser open <url> # Navigate to URL
|
|
32
|
+
agent-browser back # Go back
|
|
33
|
+
agent-browser forward # Go forward
|
|
34
|
+
agent-browser reload # Reload page
|
|
35
|
+
agent-browser close # Close browser
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
### Snapshot (page analysis)
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
agent-browser snapshot # Full accessibility tree
|
|
42
|
+
agent-browser snapshot -i # Interactive elements only (recommended)
|
|
43
|
+
agent-browser snapshot -c # Compact output
|
|
44
|
+
agent-browser snapshot -d 3 # Limit depth to 3
|
|
45
|
+
agent-browser snapshot -s "#main" # Scope to CSS selector
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### Interactions (use @refs from snapshot)
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
agent-browser click @e1 # Click
|
|
52
|
+
agent-browser dblclick @e1 # Double-click
|
|
53
|
+
agent-browser fill @e2 "text" # Clear and type
|
|
54
|
+
agent-browser type @e2 "text" # Type without clearing
|
|
55
|
+
agent-browser press Enter # Press key
|
|
56
|
+
agent-browser hover @e1 # Hover
|
|
57
|
+
agent-browser check @e1 # Check checkbox
|
|
58
|
+
agent-browser uncheck @e1 # Uncheck checkbox
|
|
59
|
+
agent-browser select @e1 "value" # Select dropdown option
|
|
60
|
+
agent-browser scroll down 500 # Scroll page
|
|
61
|
+
agent-browser upload @e1 file.pdf # Upload files
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### Get information
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
agent-browser get text @e1 # Get element text
|
|
68
|
+
agent-browser get html @e1 # Get innerHTML
|
|
69
|
+
agent-browser get value @e1 # Get input value
|
|
70
|
+
agent-browser get attr @e1 href # Get attribute
|
|
71
|
+
agent-browser get title # Get page title
|
|
72
|
+
agent-browser get url # Get current URL
|
|
73
|
+
agent-browser get count ".item" # Count matching elements
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### Screenshots & PDF
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
agent-browser screenshot # Save to temp directory
|
|
80
|
+
agent-browser screenshot path.png # Save to specific path
|
|
81
|
+
agent-browser screenshot --full # Full page
|
|
82
|
+
agent-browser pdf output.pdf # Save as PDF
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### Wait
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
agent-browser wait @e1 # Wait for element
|
|
89
|
+
agent-browser wait 2000 # Wait milliseconds
|
|
90
|
+
agent-browser wait --text "Success" # Wait for text
|
|
91
|
+
agent-browser wait --url "**/dashboard" # Wait for URL pattern
|
|
92
|
+
agent-browser wait --load networkidle # Wait for network idle
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### Semantic locators (alternative to refs)
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
agent-browser find role button click --name "Submit"
|
|
99
|
+
agent-browser find text "Sign In" click
|
|
100
|
+
agent-browser find label "Email" fill "user@test.com"
|
|
101
|
+
agent-browser find placeholder "Search" type "query"
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### Authentication with saved state
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
# Login once
|
|
108
|
+
agent-browser open https://app.example.com/login
|
|
109
|
+
agent-browser snapshot -i
|
|
110
|
+
agent-browser fill @e1 "username"
|
|
111
|
+
agent-browser fill @e2 "password"
|
|
112
|
+
agent-browser click @e3
|
|
113
|
+
agent-browser wait --url "**/dashboard"
|
|
114
|
+
agent-browser state save auth.json
|
|
115
|
+
|
|
116
|
+
# Later: load saved state
|
|
117
|
+
agent-browser state load auth.json
|
|
118
|
+
agent-browser open https://app.example.com/dashboard
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### Cookies & Storage
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
agent-browser cookies # Get all cookies
|
|
125
|
+
agent-browser cookies set name value # Set cookie
|
|
126
|
+
agent-browser cookies clear # Clear cookies
|
|
127
|
+
agent-browser storage local # Get localStorage
|
|
128
|
+
agent-browser storage local set k v # Set value
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
### JavaScript
|
|
132
|
+
|
|
133
|
+
```bash
|
|
134
|
+
agent-browser eval "document.title" # Run JavaScript
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
## Example: Form submission
|
|
138
|
+
|
|
139
|
+
```bash
|
|
140
|
+
agent-browser open https://example.com/form
|
|
141
|
+
agent-browser snapshot -i
|
|
142
|
+
# Output shows: textbox "Email" [ref=e1], textbox "Password" [ref=e2], button "Submit" [ref=e3]
|
|
143
|
+
|
|
144
|
+
agent-browser fill @e1 "user@example.com"
|
|
145
|
+
agent-browser fill @e2 "password123"
|
|
146
|
+
agent-browser click @e3
|
|
147
|
+
agent-browser wait --load networkidle
|
|
148
|
+
agent-browser snapshot -i # Check result
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
## Example: Data extraction
|
|
152
|
+
|
|
153
|
+
```bash
|
|
154
|
+
agent-browser open https://example.com/products
|
|
155
|
+
agent-browser snapshot -i
|
|
156
|
+
agent-browser get text @e1 # Get product title
|
|
157
|
+
agent-browser get attr @e2 href # Get link URL
|
|
158
|
+
agent-browser screenshot products.png
|
|
159
|
+
```
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: install-skill
|
|
3
|
+
description: >
|
|
4
|
+
When a user requests to install a new skill, this skill guides you to identify
|
|
5
|
+
the package name from various input formats and use the install_skill MCP tool.
|
|
6
|
+
Supports skills.sh URLs, GitHub URLs, owner/repo, and owner/repo@skill formats.
|
|
7
|
+
user-invocable: false
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Skill Installation Guide
|
|
11
|
+
|
|
12
|
+
When a user asks to install a skill (e.g., sends a link, mentions a skill name, or says "install xxx skill"), follow this process:
|
|
13
|
+
|
|
14
|
+
## 1. Identify the Package Name
|
|
15
|
+
|
|
16
|
+
Parse the user's input to extract the `owner/repo` or `owner/repo@skill` format:
|
|
17
|
+
|
|
18
|
+
| Input Format | Example | Extract As |
|
|
19
|
+
|---|---|---|
|
|
20
|
+
| skills.sh URL | `https://skills.sh/s/owner/repo` | `owner/repo` |
|
|
21
|
+
| skills.sh skill URL | `https://skills.sh/s/owner/repo/skill-name` | `owner/repo@skill-name` |
|
|
22
|
+
| GitHub URL | `https://github.com/owner/repo` | `owner/repo` |
|
|
23
|
+
| GitHub tree URL | `https://github.com/owner/repo/tree/main/skills/name` | `owner/repo@name` |
|
|
24
|
+
| Direct package | `owner/repo` | `owner/repo` |
|
|
25
|
+
| Package with skill | `owner/repo@skill` | `owner/repo@skill` |
|
|
26
|
+
|
|
27
|
+
## 2. Install the Skill
|
|
28
|
+
|
|
29
|
+
Call the `install_skill` MCP tool with the extracted package name:
|
|
30
|
+
|
|
31
|
+
```
|
|
32
|
+
install_skill({ "package": "owner/repo" })
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Or with a specific skill from the repo:
|
|
36
|
+
|
|
37
|
+
```
|
|
38
|
+
install_skill({ "package": "owner/repo@skill-name" })
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## 3. Handle Results
|
|
42
|
+
|
|
43
|
+
**On success:**
|
|
44
|
+
- Tell the user which skill(s) were installed (use the `installed` array from the response)
|
|
45
|
+
- Briefly describe what the skill does (if you know from context)
|
|
46
|
+
- Mention they can manage it in the Skills page
|
|
47
|
+
|
|
48
|
+
**On failure:**
|
|
49
|
+
- Check if the package name format is correct
|
|
50
|
+
- Suggest the user verify the URL or package name
|
|
51
|
+
- Common issues:
|
|
52
|
+
- Package not found: double-check the owner/repo spelling
|
|
53
|
+
- Network error: ask user to retry
|
|
54
|
+
- Invalid format: must be `owner/repo` or `owner/repo@skill`
|
|
55
|
+
|
|
56
|
+
## 4. Uninstalling
|
|
57
|
+
|
|
58
|
+
If the user wants to uninstall a skill, use the `uninstall_skill` MCP tool:
|
|
59
|
+
|
|
60
|
+
```
|
|
61
|
+
uninstall_skill({ "skill_id": "skill-name" })
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
The `skill_id` is the directory name of the installed skill.
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: post-test-cleanup
|
|
3
|
+
description: 测试完成后的扫尾清理流程。在向某个工作区发送测试指令(如长篇文章生成、耗时任务)后,用此流程彻底清除测试痕迹,防止测试消息残留在会话上下文中持续消耗 token 额度。
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# 测试后扫尾清理流程
|
|
7
|
+
|
|
8
|
+
## 何时使用
|
|
9
|
+
|
|
10
|
+
- 向某个工作区发送了耗时测试指令(如"写一篇5000字综述")后
|
|
11
|
+
- 测试完成或中断后,需要清除测试痕迹
|
|
12
|
+
- 发现某工作区残留测试消息影响 AI 上下文时
|
|
13
|
+
|
|
14
|
+
## 完整清理步骤
|
|
15
|
+
|
|
16
|
+
### 第一步:停止残留容器
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
# 查看当前运行的容器
|
|
20
|
+
docker ps --format "table {{.Names}}\t{{.Status}}\t{{.RunningFor}}"
|
|
21
|
+
|
|
22
|
+
# 确认目标容器的 folder(容器名格式:cli-claw-{folder}-{timestamp})
|
|
23
|
+
ls ~/.cli-claw/ipc/
|
|
24
|
+
|
|
25
|
+
# 发送中断信号(优雅停止)
|
|
26
|
+
touch ~/.cli-claw/ipc/{folder}/input/_interrupt
|
|
27
|
+
sleep 5
|
|
28
|
+
|
|
29
|
+
# 若容器仍在运行,发送关闭信号
|
|
30
|
+
touch ~/.cli-claw/ipc/{folder}/input/_close
|
|
31
|
+
sleep 10
|
|
32
|
+
|
|
33
|
+
# 确认容器已停止
|
|
34
|
+
docker ps --format "{{.Names}}" | grep {folder关键字}
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### 第二步:查找测试消息
|
|
38
|
+
|
|
39
|
+
```python3
|
|
40
|
+
python3 -c "
|
|
41
|
+
import os, sqlite3
|
|
42
|
+
conn = sqlite3.connect(os.path.expanduser('~/.cli-claw/db/messages.db'))
|
|
43
|
+
cur = conn.cursor()
|
|
44
|
+
|
|
45
|
+
# 先找到 folder 对应的 JID
|
|
46
|
+
cur.execute(\"SELECT jid, folder, name FROM registered_groups WHERE folder = '{folder}'\")
|
|
47
|
+
print('Group:', cur.fetchall())
|
|
48
|
+
|
|
49
|
+
# 查看最近消息,定位测试消息范围
|
|
50
|
+
cur.execute(\"\"\"
|
|
51
|
+
SELECT id, content, is_from_me, timestamp
|
|
52
|
+
FROM messages
|
|
53
|
+
WHERE chat_jid = '{jid}'
|
|
54
|
+
ORDER BY timestamp DESC LIMIT 20
|
|
55
|
+
\"\"\")
|
|
56
|
+
for r in cur.fetchall():
|
|
57
|
+
print(f'id={r[0]} from_me={r[2]} | {str(r[1])[:80]}')
|
|
58
|
+
conn.close()
|
|
59
|
+
"
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### 第三步:删除测试消息
|
|
63
|
+
|
|
64
|
+
```python3
|
|
65
|
+
python3 -c "
|
|
66
|
+
import os, sqlite3
|
|
67
|
+
conn = sqlite3.connect(os.path.expanduser('~/.cli-claw/db/messages.db'))
|
|
68
|
+
cur = conn.cursor()
|
|
69
|
+
|
|
70
|
+
# 将需要删除的消息 ID 填入列表
|
|
71
|
+
test_ids = [
|
|
72
|
+
'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx',
|
|
73
|
+
# ...
|
|
74
|
+
]
|
|
75
|
+
|
|
76
|
+
placeholders = ','.join(['?' for _ in test_ids])
|
|
77
|
+
cur.execute(f'DELETE FROM messages WHERE id IN ({placeholders})', test_ids)
|
|
78
|
+
print(f'Deleted {cur.rowcount} messages')
|
|
79
|
+
conn.commit()
|
|
80
|
+
conn.close()
|
|
81
|
+
"
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### 第四步:重置 Claude 会话(关键:清除 token 上下文)
|
|
85
|
+
|
|
86
|
+
```python3
|
|
87
|
+
python3 -c "
|
|
88
|
+
import os, sqlite3, uuid
|
|
89
|
+
conn = sqlite3.connect(os.path.expanduser('~/.cli-claw/db/messages.db'))
|
|
90
|
+
cur = conn.cursor()
|
|
91
|
+
|
|
92
|
+
# 生成新 session ID,下次启动时以空上下文开始
|
|
93
|
+
new_id = str(uuid.uuid4())
|
|
94
|
+
cur.execute(\"UPDATE sessions SET session_id = ? WHERE group_folder = '{folder}'\", (new_id,))
|
|
95
|
+
print(f'Session reset: {cur.rowcount} rows, new ID: {new_id}')
|
|
96
|
+
conn.commit()
|
|
97
|
+
conn.close()
|
|
98
|
+
"
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### 第五步:确认代码无意外修改
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
git status
|
|
105
|
+
git diff --stat
|
|
106
|
+
# 应显示 "nothing to commit, working tree clean"
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
## 注意事项
|
|
110
|
+
|
|
111
|
+
- **必须重置 session**:仅删除 DB 消息不够,Claude session 文件中仍保存着历史上下文,下次激活时依然消耗 token
|
|
112
|
+
- **容器名与 folder 的对应关系**:容器名格式为 `cli-claw-{folder}-{timestamp}`,可通过 `ls ~/.cli-claw/ipc/` 查看所有 folder
|
|
113
|
+
- **删除消息前仔细核对**:通过 `is_from_me` 和内容确认,避免误删正常业务消息
|
|
114
|
+
- **全局运行时目录的修改不影响 git**:SQLite 和 IPC 文件均在 `~/.cli-claw/` 下,不纳入版本控制
|
|
115
|
+
|
|
116
|
+
## 快速检查清单
|
|
117
|
+
|
|
118
|
+
- [ ] 无残留测试容器在运行(`docker ps`)
|
|
119
|
+
- [ ] 测试消息已从 DB 删除
|
|
120
|
+
- [ ] Claude session ID 已重置为新 UUID
|
|
121
|
+
- [ ] `git status` 显示工作区干净
|