openclaw-node-harness 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +184 -0
- package/bin/discord-read.js +228 -0
- package/bin/fleet-deploy.js +365 -0
- package/bin/lane-watchdog.js +232 -0
- package/bin/mesh-agent.js +714 -0
- package/bin/mesh-bridge.js +535 -0
- package/bin/mesh-deploy-listener.js +322 -0
- package/bin/mesh-deploy.js +1048 -0
- package/bin/mesh-health-publisher.js +247 -0
- package/bin/mesh-task-daemon.js +451 -0
- package/bin/mesh-tool-discord.js +293 -0
- package/bin/mesh.js +649 -0
- package/boot/manifest.yaml +187 -0
- package/cli.js +35 -0
- package/config/daemon.json.template +16 -0
- package/config/obsidian-sync.json.template +39 -0
- package/config/openclaw.json.template +124 -0
- package/config/transcript-sources.json.template +22 -0
- package/identity/AGENTS.md +201 -0
- package/identity/CLAUDE.md +64 -0
- package/identity/DELEGATION.md +304 -0
- package/identity/HEARTBEAT.md +163 -0
- package/identity/MEMORY_SPEC.md +368 -0
- package/identity/PRINCIPLES.md +81 -0
- package/identity/SOUL.md +48 -0
- package/identity/TOOLS.md +47 -0
- package/install.sh +895 -0
- package/lib/agent-activity.js +390 -0
- package/lib/kanban-io.js +352 -0
- package/lib/mesh-registry.js +194 -0
- package/lib/mesh-roles.js +13 -0
- package/lib/mesh-tasks.js +306 -0
- package/lib/nats-resolve.js +108 -0
- package/mission-control/README.md +36 -0
- package/mission-control/drizzle/0000_simple_silhouette.sql +62 -0
- package/mission-control/drizzle/meta/0000_snapshot.json +413 -0
- package/mission-control/drizzle/meta/_journal.json +13 -0
- package/mission-control/drizzle.config.ts +13 -0
- package/mission-control/eslint.config.mjs +18 -0
- package/mission-control/next.config.ts +7 -0
- package/mission-control/package-lock.json +10518 -0
- package/mission-control/package.json +49 -0
- package/mission-control/postcss.config.mjs +7 -0
- package/mission-control/public/file.svg +1 -0
- package/mission-control/public/globe.svg +1 -0
- package/mission-control/public/next.svg +1 -0
- package/mission-control/public/vercel.svg +1 -0
- package/mission-control/public/window.svg +1 -0
- package/mission-control/scripts/enrich-descriptions.js +193 -0
- package/mission-control/scripts/gen-chronology.js +102 -0
- package/mission-control/scripts/import-pipeline-v2.js +523 -0
- package/mission-control/scripts/import-pipeline.js +295 -0
- package/mission-control/src/app/api/activity/live/route.ts +27 -0
- package/mission-control/src/app/api/activity/route.ts +47 -0
- package/mission-control/src/app/api/burndown/route.ts +112 -0
- package/mission-control/src/app/api/critical-path/route.ts +159 -0
- package/mission-control/src/app/api/dependencies/route.ts +176 -0
- package/mission-control/src/app/api/memory/categories/route.ts +93 -0
- package/mission-control/src/app/api/memory/consolidate/route.ts +107 -0
- package/mission-control/src/app/api/memory/doc/route.ts +89 -0
- package/mission-control/src/app/api/memory/flush/route.ts +129 -0
- package/mission-control/src/app/api/memory/graph/route.ts +105 -0
- package/mission-control/src/app/api/memory/items/route.ts +86 -0
- package/mission-control/src/app/api/memory/list/route.ts +48 -0
- package/mission-control/src/app/api/memory/retrieve/route.ts +51 -0
- package/mission-control/src/app/api/memory/search/route.ts +143 -0
- package/mission-control/src/app/api/memory/sync/route.ts +23 -0
- package/mission-control/src/app/api/memory/wikilinks/route.ts +75 -0
- package/mission-control/src/app/api/mesh/events/route.ts +67 -0
- package/mission-control/src/app/api/mesh/nodes/route.ts +221 -0
- package/mission-control/src/app/api/mesh/tokens/route.ts +133 -0
- package/mission-control/src/app/api/projects/route.ts +102 -0
- package/mission-control/src/app/api/resolve-path/route.ts +92 -0
- package/mission-control/src/app/api/scheduler/tick/route.ts +38 -0
- package/mission-control/src/app/api/scheduler/waves/route.ts +54 -0
- package/mission-control/src/app/api/screenshot/route.ts +127 -0
- package/mission-control/src/app/api/settings/gateway/route.ts +92 -0
- package/mission-control/src/app/api/skills/[id]/health/route.ts +57 -0
- package/mission-control/src/app/api/skills/list/route.ts +41 -0
- package/mission-control/src/app/api/souls/[id]/evolution/route.ts +253 -0
- package/mission-control/src/app/api/souls/[id]/prompt/route.ts +205 -0
- package/mission-control/src/app/api/souls/[id]/propagate/route.ts +146 -0
- package/mission-control/src/app/api/souls/route.ts +174 -0
- package/mission-control/src/app/api/tasks/[id]/handoff/route.ts +115 -0
- package/mission-control/src/app/api/tasks/[id]/route.ts +266 -0
- package/mission-control/src/app/api/tasks/[id]/tree/route.ts +94 -0
- package/mission-control/src/app/api/tasks/route.ts +253 -0
- package/mission-control/src/app/api/tts/route.ts +47 -0
- package/mission-control/src/app/api/workspace/files/route.ts +88 -0
- package/mission-control/src/app/api/workspace/read/route.ts +73 -0
- package/mission-control/src/app/burndown/page.tsx +309 -0
- package/mission-control/src/app/calendar/page.tsx +839 -0
- package/mission-control/src/app/favicon.ico +0 -0
- package/mission-control/src/app/globals.css +67 -0
- package/mission-control/src/app/graph/page.tsx +352 -0
- package/mission-control/src/app/layout.tsx +35 -0
- package/mission-control/src/app/live/page.tsx +232 -0
- package/mission-control/src/app/memory/page.tsx +154 -0
- package/mission-control/src/app/mesh/page.tsx +457 -0
- package/mission-control/src/app/obsidian/page.tsx +252 -0
- package/mission-control/src/app/page.tsx +70 -0
- package/mission-control/src/app/roadmap/page.tsx +1757 -0
- package/mission-control/src/app/settings/page.tsx +260 -0
- package/mission-control/src/app/souls/page.tsx +573 -0
- package/mission-control/src/components/board/activity-timeline.tsx +96 -0
- package/mission-control/src/components/board/daily-board.tsx +373 -0
- package/mission-control/src/components/board/kanban-board.tsx +364 -0
- package/mission-control/src/components/board/kanban-column.tsx +105 -0
- package/mission-control/src/components/board/live-stream.tsx +116 -0
- package/mission-control/src/components/board/skill-health-card.tsx +128 -0
- package/mission-control/src/components/board/status-banner.tsx +124 -0
- package/mission-control/src/components/board/task-card.tsx +454 -0
- package/mission-control/src/components/board/unified-task-dialog.tsx +1043 -0
- package/mission-control/src/components/layout/resizable-layout.tsx +68 -0
- package/mission-control/src/components/layout/sidebar.tsx +90 -0
- package/mission-control/src/components/live/audio-spectrum.tsx +106 -0
- package/mission-control/src/components/live/chat-bubble.tsx +52 -0
- package/mission-control/src/components/live/chat-input.tsx +92 -0
- package/mission-control/src/components/memory/doc-reader.tsx +172 -0
- package/mission-control/src/components/memory/memory-list.tsx +169 -0
- package/mission-control/src/components/memory/search-bar.tsx +67 -0
- package/mission-control/src/components/memory/search-results.tsx +149 -0
- package/mission-control/src/components/obsidian/backlinks-panel.tsx +52 -0
- package/mission-control/src/components/obsidian/file-tree.tsx +186 -0
- package/mission-control/src/components/obsidian/local-graph.tsx +107 -0
- package/mission-control/src/components/obsidian/obsidian-graph.tsx +192 -0
- package/mission-control/src/components/obsidian/obsidian-reader.tsx +246 -0
- package/mission-control/src/lib/activity.ts +29 -0
- package/mission-control/src/lib/config.ts +21 -0
- package/mission-control/src/lib/db/index.ts +429 -0
- package/mission-control/src/lib/db/schema.ts +218 -0
- package/mission-control/src/lib/gateway-notify.ts +113 -0
- package/mission-control/src/lib/hooks.ts +536 -0
- package/mission-control/src/lib/memory/categories.ts +125 -0
- package/mission-control/src/lib/memory/entities.ts +482 -0
- package/mission-control/src/lib/memory/extract.ts +369 -0
- package/mission-control/src/lib/memory/retrieval.ts +281 -0
- package/mission-control/src/lib/memory/wikilinks.ts +147 -0
- package/mission-control/src/lib/nats.ts +126 -0
- package/mission-control/src/lib/parsers/clawvault-doc.ts +98 -0
- package/mission-control/src/lib/parsers/daily-log.ts +73 -0
- package/mission-control/src/lib/parsers/memory-md.ts +81 -0
- package/mission-control/src/lib/parsers/task-markdown.ts +459 -0
- package/mission-control/src/lib/parsers/transcript.ts +209 -0
- package/mission-control/src/lib/scheduler.ts +394 -0
- package/mission-control/src/lib/speech/use-speech-pipeline.ts +176 -0
- package/mission-control/src/lib/sync/memory.ts +224 -0
- package/mission-control/src/lib/sync/tasks.ts +271 -0
- package/mission-control/src/lib/tts/edge.ts +31 -0
- package/mission-control/src/lib/tts/google.ts +78 -0
- package/mission-control/src/lib/tts/index.ts +39 -0
- package/mission-control/src/lib/tts/types.ts +18 -0
- package/mission-control/tsconfig.json +42 -0
- package/obsidian-vault/.obsidian/app.json +10 -0
- package/obsidian-vault/.obsidian/community-plugins.json +8 -0
- package/obsidian-vault/.obsidian/graph.json +40 -0
- package/obsidian-vault/.obsidian/plugins/obsidian-local-rest-api/main.js +58769 -0
- package/obsidian-vault/.obsidian/plugins/obsidian-local-rest-api/manifest.json +10 -0
- package/obsidian-vault/.obsidian/plugins/obsidian-local-rest-api/styles.css +47 -0
- package/obsidian-vault/00-meta/.gitkeep +0 -0
- package/obsidian-vault/01-architecture/.gitkeep +0 -0
- package/obsidian-vault/02-smart-contracts/.gitkeep +0 -0
- package/obsidian-vault/03-backend/.gitkeep +0 -0
- package/obsidian-vault/04-mobile/.gitkeep +0 -0
- package/obsidian-vault/05-ar-mapping/.gitkeep +0 -0
- package/obsidian-vault/06-3d-assets/.gitkeep +0 -0
- package/obsidian-vault/07-sound-music/.gitkeep +0 -0
- package/obsidian-vault/08-lore/.gitkeep +0 -0
- package/obsidian-vault/09-quests-playthrough/.gitkeep +0 -0
- package/obsidian-vault/10-economy/.gitkeep +0 -0
- package/obsidian-vault/11-nft-assets/.gitkeep +0 -0
- package/obsidian-vault/12-nft-mechanics/.gitkeep +0 -0
- package/obsidian-vault/13-dao-guild-social/.gitkeep +0 -0
- package/obsidian-vault/14-game-progression/.gitkeep +0 -0
- package/obsidian-vault/15-analytics/.gitkeep +0 -0
- package/obsidian-vault/16-security/.gitkeep +0 -0
- package/obsidian-vault/17-devops/.gitkeep +0 -0
- package/obsidian-vault/18-marketplace/.gitkeep +0 -0
- package/obsidian-vault/19-decisions/.gitkeep +0 -0
- package/obsidian-vault/20-business-strategy/.gitkeep +0 -0
- package/obsidian-vault/21-legal-regulatory/.gitkeep +0 -0
- package/obsidian-vault/nodes/.gitkeep +0 -0
- package/openclaw.env.example +17 -0
- package/package.json +45 -0
- package/services/launchd/ai.openclaw.gateway.plist +59 -0
- package/services/launchd/ai.openclaw.lane-watchdog.plist +32 -0
- package/services/launchd/ai.openclaw.log-rotate.plist +28 -0
- package/services/launchd/ai.openclaw.memory-daemon.plist +36 -0
- package/services/launchd/ai.openclaw.mesh-agent.plist +38 -0
- package/services/launchd/ai.openclaw.mesh-bridge.plist +36 -0
- package/services/launchd/ai.openclaw.mesh-deploy-listener.plist +33 -0
- package/services/launchd/ai.openclaw.mesh-health-publisher.plist +29 -0
- package/services/launchd/ai.openclaw.mesh-task-daemon.plist +36 -0
- package/services/launchd/ai.openclaw.mesh-tool-discord.plist +36 -0
- package/services/launchd/ai.openclaw.mission-control.plist +41 -0
- package/services/service-manifest.json +13 -0
- package/services/systemd/openclaw-gateway.service +21 -0
- package/services/systemd/openclaw-lane-watchdog.service +21 -0
- package/services/systemd/openclaw-log-rotate.service +13 -0
- package/services/systemd/openclaw-log-rotate.timer +9 -0
- package/services/systemd/openclaw-memory-daemon.service +21 -0
- package/services/systemd/openclaw-mesh-agent.service +19 -0
- package/services/systemd/openclaw-mesh-bridge.service +21 -0
- package/services/systemd/openclaw-mesh-deploy-listener.service +23 -0
- package/services/systemd/openclaw-mesh-health-publisher.service +21 -0
- package/services/systemd/openclaw-mesh-task-daemon.service +21 -0
- package/services/systemd/openclaw-mesh-tool-discord.service +21 -0
- package/services/systemd/openclaw-mission-control.service +22 -0
- package/skills/1password/.clawhub/origin.json +7 -0
- package/skills/1password/SKILL.md +63 -0
- package/skills/1password/references/cli-examples.md +29 -0
- package/skills/1password/references/get-started.md +17 -0
- package/skills/acquisition-channel-advisor/SKILL.md +643 -0
- package/skills/acquisition-channel-advisor/examples/conversation-flow.md +531 -0
- package/skills/agent-browser/.clawhub/origin.json +7 -0
- package/skills/agent-browser/CONTRIBUTING.md +63 -0
- package/skills/agent-browser/SKILL.md +338 -0
- package/skills/agentic-compass/.clawhub/origin.json +7 -0
- package/skills/agentic-compass/README.md +96 -0
- package/skills/agentic-compass/SKILL.md +112 -0
- package/skills/agentic-compass/references/README.md +5 -0
- package/skills/agentic-compass/scripts/agentic-compass.py +196 -0
- package/skills/arcane-dev-ops/SKILL.md +61 -0
- package/skills/arcane-dev-ops/references/checklist.md +22 -0
- package/skills/arcane-dev-ops/references/validation-cases.md +11 -0
- package/skills/arcane-dev-ops/scripts/prepush_check.sh +41 -0
- package/skills/auto-updater/.clawhub/origin.json +7 -0
- package/skills/auto-updater/SKILL.md +158 -0
- package/skills/auto-updater/references/agent-guide.md +152 -0
- package/skills/auto-updater/references/summary-examples.md +109 -0
- package/skills/business-health-diagnostic/SKILL.md +782 -0
- package/skills/byterover/.clawhub/origin.json +7 -0
- package/skills/byterover/SKILL.md +105 -0
- package/skills/byterover/TROUBLESHOOTING.md +50 -0
- package/skills/byterover/WORKFLOWS.md +229 -0
- package/skills/capability-evolver/.clawhub/origin.json +7 -0
- package/skills/capability-evolver/CONTRIBUTING.md +11 -0
- package/skills/capability-evolver/README.md +157 -0
- package/skills/capability-evolver/README.zh-CN.md +112 -0
- package/skills/capability-evolver/SKILL.md +93 -0
- package/skills/capability-evolver/assets/gep/capsules.json +5 -0
- package/skills/capability-evolver/assets/gep/genes.json +104 -0
- package/skills/capability-evolver/index.js +59 -0
- package/skills/capability-evolver/package.json +22 -0
- package/skills/capability-evolver/scripts/analyze_by_skill.js +121 -0
- package/skills/capability-evolver/scripts/build_public.js +350 -0
- package/skills/capability-evolver/scripts/export_history.js +98 -0
- package/skills/capability-evolver/scripts/extract_log.js +85 -0
- package/skills/capability-evolver/scripts/generate_history.js +75 -0
- package/skills/capability-evolver/scripts/human_report.js +147 -0
- package/skills/capability-evolver/scripts/publish_public.js +516 -0
- package/skills/capability-evolver/scripts/suggest_version.js +89 -0
- package/skills/capability-evolver/src/evolve.js +594 -0
- package/skills/capability-evolver/src/gep/assetStore.js +204 -0
- package/skills/capability-evolver/src/gep/candidates.js +134 -0
- package/skills/capability-evolver/src/gep/paths.js +23 -0
- package/skills/capability-evolver/src/gep/prompt.js +254 -0
- package/skills/capability-evolver/src/gep/selector.js +89 -0
- package/skills/capability-evolver/src/gep/signals.js +27 -0
- package/skills/cc-godmode/.clawhub/origin.json +7 -0
- package/skills/cc-godmode/CHANGELOG.md +66 -0
- package/skills/cc-godmode/README.md +293 -0
- package/skills/cc-godmode/SKILL.md +242 -0
- package/skills/cc-godmode/docs/AGENTS.md +332 -0
- package/skills/cc-godmode/docs/MIGRATION.md +206 -0
- package/skills/cc-godmode/docs/TROUBLESHOOTING.md +357 -0
- package/skills/cc-godmode/docs/WORKFLOWS.md +329 -0
- package/skills/cc-godmode/references/agents.md +433 -0
- package/skills/cc-godmode/scripts/build-skill.js +232 -0
- package/skills/clawdbot-filesystem/.clawhub/origin.json +7 -0
- package/skills/clawdbot-filesystem/LICENSE.md +21 -0
- package/skills/clawdbot-filesystem/README.md +322 -0
- package/skills/clawdbot-filesystem/SKILL.md +219 -0
- package/skills/clawdbot-filesystem/config.json +41 -0
- package/skills/clawdbot-filesystem/package.json +69 -0
- package/skills/clawdbot-security-check/.clawhub/origin.json +7 -0
- package/skills/clawdbot-security-check/README.md +168 -0
- package/skills/clawdbot-security-check/SKILL.md +145 -0
- package/skills/clawdbot-security-check/references/audit-checks.md +521 -0
- package/skills/clawdbot-security-check/skill.json +42 -0
- package/skills/clawddocs/.clawhub/origin.json +7 -0
- package/skills/clawddocs/SKILL.md +176 -0
- package/skills/clawddocs/package.json +9 -0
- package/skills/clawddocs/scripts/build-index.sh +17 -0
- package/skills/clawddocs/scripts/cache.sh +13 -0
- package/skills/clawddocs/scripts/fetch-doc.sh +7 -0
- package/skills/clawddocs/scripts/recent.sh +5 -0
- package/skills/clawddocs/scripts/search.sh +8 -0
- package/skills/clawddocs/scripts/sitemap.sh +23 -0
- package/skills/clawddocs/scripts/track-changes.sh +16 -0
- package/skills/clawddocs/snippets/common-configs.md +69 -0
- package/skills/clawguard/.clawhub/origin.json +7 -0
- package/skills/clawguard/SKILL.md +137 -0
- package/skills/company-research/SKILL.md +393 -0
- package/skills/company-research/examples/sample.md +164 -0
- package/skills/company-research/template.md +60 -0
- package/skills/crypto-price/.clawhub/origin.json +7 -0
- package/skills/crypto-price/ARCHITECTURE.md +437 -0
- package/skills/crypto-price/README.md +194 -0
- package/skills/crypto-price/SKILL.md +61 -0
- package/skills/crypto-price/requirements.txt +1 -0
- package/skills/crypto-price/scripts/get_price_chart.py +988 -0
- package/skills/customer-journey-map/SKILL.md +343 -0
- package/skills/customer-journey-map/examples/sample.md +33 -0
- package/skills/customer-journey-map/template.md +28 -0
- package/skills/customer-journey-mapping-workshop/SKILL.md +522 -0
- package/skills/deep-research/.clawhub/origin.json +7 -0
- package/skills/deep-research/SKILL.md +93 -0
- package/skills/deep-research/rules/logic.md +32 -0
- package/skills/discord-telegram-triage/SKILL.md +59 -0
- package/skills/discord-telegram-triage/references/discord-runbook.md +28 -0
- package/skills/discord-telegram-triage/references/validation-cases.md +11 -0
- package/skills/discord-telegram-triage/scripts/triage_snapshot.sh +23 -0
- package/skills/discovery-interview-prep/SKILL.md +408 -0
- package/skills/discovery-process/SKILL.md +503 -0
- package/skills/discovery-process/examples/sample.md +60 -0
- package/skills/discovery-process/template.md +39 -0
- package/skills/dist/arcane-dev-ops.skill +0 -0
- package/skills/dist/discord-telegram-triage.skill +0 -0
- package/skills/dist/founder-brief-summarizer.skill +0 -0
- package/skills/epic-breakdown-advisor/SKILL.md +664 -0
- package/skills/epic-hypothesis/SKILL.md +285 -0
- package/skills/epic-hypothesis/examples/sample.md +104 -0
- package/skills/epic-hypothesis/template.md +30 -0
- package/skills/excel/.clawhub/origin.json +7 -0
- package/skills/excel/SKILL.md +332 -0
- package/skills/excel/scripts/excel.py +1120 -0
- package/skills/fast-browser-use/.clawhub/origin.json +7 -0
- package/skills/fast-browser-use/CODEBUDDY.md +142 -0
- package/skills/fast-browser-use/Cargo.toml +77 -0
- package/skills/fast-browser-use/README.md +62 -0
- package/skills/fast-browser-use/SKILL.md +217 -0
- package/skills/fast-browser-use/package-lock.json +28 -0
- package/skills/fast-browser-use/package.json +8 -0
- package/skills/fast-browser-use/rustfmt.toml +10 -0
- package/skills/fast-browser-use/src/bin/cli.rs +373 -0
- package/skills/fast-browser-use/src/bin/mcp_server.rs +203 -0
- package/skills/fast-browser-use/src/browser/config.rs +136 -0
- package/skills/fast-browser-use/src/browser/debug.rs +16 -0
- package/skills/fast-browser-use/src/browser/mod.rs +61 -0
- package/skills/fast-browser-use/src/browser/session.rs +478 -0
- package/skills/fast-browser-use/src/dom/element.rs +442 -0
- package/skills/fast-browser-use/src/dom/extract_dom.js +849 -0
- package/skills/fast-browser-use/src/dom/mod.rs +14 -0
- package/skills/fast-browser-use/src/dom/tree.rs +296 -0
- package/skills/fast-browser-use/src/dom/yaml.rs +149 -0
- package/skills/fast-browser-use/src/error.rs +115 -0
- package/skills/fast-browser-use/src/lib.rs +17 -0
- package/skills/fast-browser-use/src/mcp/handler.rs +63 -0
- package/skills/fast-browser-use/src/mcp/mod.rs +81 -0
- package/skills/fast-browser-use/src/tools/Readability.min.js +1480 -0
- package/skills/fast-browser-use/src/tools/annotate.rs +165 -0
- package/skills/fast-browser-use/src/tools/click.rs +84 -0
- package/skills/fast-browser-use/src/tools/close.rs +35 -0
- package/skills/fast-browser-use/src/tools/close_tab.rs +45 -0
- package/skills/fast-browser-use/src/tools/convert_to_markdown.js +117 -0
- package/skills/fast-browser-use/src/tools/cookies.rs +58 -0
- package/skills/fast-browser-use/src/tools/debug.rs +44 -0
- package/skills/fast-browser-use/src/tools/evaluate.rs +40 -0
- package/skills/fast-browser-use/src/tools/extract.rs +66 -0
- package/skills/fast-browser-use/src/tools/go_back.rs +35 -0
- package/skills/fast-browser-use/src/tools/go_forward.rs +35 -0
- package/skills/fast-browser-use/src/tools/hover.js +33 -0
- package/skills/fast-browser-use/src/tools/hover.rs +97 -0
- package/skills/fast-browser-use/src/tools/html_to_markdown.rs +99 -0
- package/skills/fast-browser-use/src/tools/input.rs +93 -0
- package/skills/fast-browser-use/src/tools/local_storage.rs +159 -0
- package/skills/fast-browser-use/src/tools/markdown.rs +181 -0
- package/skills/fast-browser-use/src/tools/mod.rs +326 -0
- package/skills/fast-browser-use/src/tools/navigate.rs +55 -0
- package/skills/fast-browser-use/src/tools/new_tab.rs +60 -0
- package/skills/fast-browser-use/src/tools/press_key.rs +78 -0
- package/skills/fast-browser-use/src/tools/read_links.rs +59 -0
- package/skills/fast-browser-use/src/tools/readability_script.rs +8 -0
- package/skills/fast-browser-use/src/tools/screenshot.rs +47 -0
- package/skills/fast-browser-use/src/tools/scroll.js +22 -0
- package/skills/fast-browser-use/src/tools/scroll.rs +95 -0
- package/skills/fast-browser-use/src/tools/select.js +23 -0
- package/skills/fast-browser-use/src/tools/select.rs +129 -0
- package/skills/fast-browser-use/src/tools/sitemap.rs +426 -0
- package/skills/fast-browser-use/src/tools/snapshot.rs +324 -0
- package/skills/fast-browser-use/src/tools/switch_tab.rs +69 -0
- package/skills/fast-browser-use/src/tools/tab_list.rs +76 -0
- package/skills/fast-browser-use/src/tools/utils.rs +92 -0
- package/skills/fast-browser-use/src/tools/wait.rs +53 -0
- package/skills/fast-browser-use/test_auth.json +3 -0
- package/skills/fast-browser-use/test_state.json +6 -0
- package/skills/fast-browser-use/tests/browser_tools_integration.rs +233 -0
- package/skills/fast-browser-use/tests/cli_recipes_integration.rs +112 -0
- package/skills/fast-browser-use/tests/cookies_integration.rs +56 -0
- package/skills/fast-browser-use/tests/debug_integration.rs +83 -0
- package/skills/fast-browser-use/tests/dom_integration.rs +170 -0
- package/skills/fast-browser-use/tests/local_storage_integration.rs +75 -0
- package/skills/fast-browser-use/tests/markdown_integration.rs +448 -0
- package/skills/fast-browser-use/tests/navigation_integration.rs +241 -0
- package/skills/fast-browser-use/tests/sitemap_integration.rs +326 -0
- package/skills/fast-browser-use/tests/tab_management_integration.rs +300 -0
- package/skills/feature-investment-advisor/SKILL.md +639 -0
- package/skills/feature-investment-advisor/examples/conversation-flow.md +538 -0
- package/skills/finance-based-pricing-advisor/SKILL.md +763 -0
- package/skills/finance-metrics-quickref/SKILL.md +309 -0
- package/skills/find-skills/.clawhub/origin.json +7 -0
- package/skills/find-skills/SKILL.md +143 -0
- package/skills/flavor-text-writer/SKILL.md +27 -0
- package/skills/founder-brief-summarizer/SKILL.md +52 -0
- package/skills/founder-brief-summarizer/references/response-templates.md +15 -0
- package/skills/founder-brief-summarizer/references/validation-cases.md +11 -0
- package/skills/founder-brief-summarizer/scripts/brief_template.sh +28 -0
- package/skills/frontend-design/.clawhub/origin.json +7 -0
- package/skills/frontend-design/LICENSE.txt +190 -0
- package/skills/frontend-design/SKILL.md +53 -0
- package/skills/gemini/.clawhub/origin.json +7 -0
- package/skills/gemini/SKILL.md +33 -0
- package/skills/gemini-deep-research/.clawhub/origin.json +7 -0
- package/skills/gemini-deep-research/SKILL.md +78 -0
- package/skills/gemini-deep-research/scripts/deep_research.py +176 -0
- package/skills/git-essentials/.clawhub/origin.json +7 -0
- package/skills/git-essentials/SKILL.md +239 -0
- package/skills/git-essentials/references/advanced.md +211 -0
- package/skills/github/.clawhub/origin.json +7 -0
- package/skills/github/SKILL.md +57 -0
- package/skills/google-drive/.clawhub/origin.json +7 -0
- package/skills/google-drive/LICENSE.txt +21 -0
- package/skills/google-drive/SKILL.md +320 -0
- package/skills/growth-loop/SKILL.md +270 -0
- package/skills/growth-loop/_meta.json +9 -0
- package/skills/growth-loop/references/diagnosis-framework.md +84 -0
- package/skills/growth-loop/references/platform-benchmarks.md +79 -0
- package/skills/growth-loop/scripts/init-campaign.sh +274 -0
- package/skills/humanize-ai-text/.clawhub/origin.json +7 -0
- package/skills/humanize-ai-text/SKILL.md +192 -0
- package/skills/humanize-ai-text/scripts/compare.py +58 -0
- package/skills/humanize-ai-text/scripts/detect.py +160 -0
- package/skills/humanize-ai-text/scripts/patterns.json +191 -0
- package/skills/humanize-ai-text/scripts/transform.py +127 -0
- package/skills/humanizer/.clawhub/origin.json +7 -0
- package/skills/humanizer/README.md +82 -0
- package/skills/humanizer/SKILL.md +443 -0
- package/skills/jobs-to-be-done/SKILL.md +378 -0
- package/skills/jobs-to-be-done/examples/sample.md +80 -0
- package/skills/jobs-to-be-done/template.md +65 -0
- package/skills/lean-ux-canvas/SKILL.md +561 -0
- package/skills/lean-ux-canvas/examples/sample.md +88 -0
- package/skills/lean-ux-canvas/template.md +32 -0
- package/skills/markdown-formatter/.clawhub/origin.json +7 -0
- package/skills/markdown-formatter/README.md +137 -0
- package/skills/markdown-formatter/SKILL.md +369 -0
- package/skills/markdown-formatter/config.json +20 -0
- package/skills/markdown-formatter/index.js +439 -0
- package/skills/markdown-formatter/package.json +23 -0
- package/skills/markdown-formatter/test.js +23 -0
- package/skills/marketing-mode/.clawhub/origin.json +7 -0
- package/skills/marketing-mode/README.md +49 -0
- package/skills/marketing-mode/SKILL.md +703 -0
- package/skills/marketing-mode/mode-prompt.md +39 -0
- package/skills/marketing-mode/skill.json +51 -0
- package/skills/memory-hygiene/.clawhub/origin.json +7 -0
- package/skills/memory-hygiene/SKILL.md +91 -0
- package/skills/memory-setup/.clawhub/origin.json +7 -0
- package/skills/memory-setup/SKILL.md +180 -0
- package/skills/memorylayer/.clawhub/origin.json +7 -0
- package/skills/memorylayer/README.md +197 -0
- package/skills/memorylayer/SKILL.md +227 -0
- package/skills/memorylayer/examples/agent-integration.js +145 -0
- package/skills/memorylayer/examples/basic-usage.js +87 -0
- package/skills/memorylayer/examples/token-savings-demo.js +183 -0
- package/skills/memorylayer/index.js +115 -0
- package/skills/memorylayer/package-lock.json +295 -0
- package/skills/memorylayer/package.json +27 -0
- package/skills/memorylayer/python/memorylayer_skill.py +230 -0
- package/skills/memorylayer/python/requirements.txt +7 -0
- package/skills/mesh/SKILL.md +184 -0
- package/skills/model-usage/.clawhub/origin.json +7 -0
- package/skills/model-usage/SKILL.md +54 -0
- package/skills/model-usage/references/codexbar-cli.md +28 -0
- package/skills/model-usage/scripts/model_usage.py +310 -0
- package/skills/moltbook-interact/.clawhub/origin.json +7 -0
- package/skills/moltbook-interact/INSTALL.md +139 -0
- package/skills/moltbook-interact/README.md +198 -0
- package/skills/moltbook-interact/SKILL.md +72 -0
- package/skills/moltbook-interact/references/api.md +106 -0
- package/skills/moltbook-interact/scripts/moltbook.sh +142 -0
- package/skills/moltbook-registry/.clawhub/origin.json +7 -0
- package/skills/moltbook-registry/README.md +26 -0
- package/skills/moltbook-registry/SKILL.md +82 -0
- package/skills/moltbook-registry/index.js +180 -0
- package/skills/moltbook-registry/package.json +11 -0
- package/skills/mythril-scanner/SKILL.md +27 -0
- package/skills/n8n/.clawhub/origin.json +7 -0
- package/skills/n8n/SKILL.md +141 -0
- package/skills/n8n/references/api.md +156 -0
- package/skills/n8n/scripts/n8n_api.py +158 -0
- package/skills/n8n-workflow-automation/.clawhub/origin.json +7 -0
- package/skills/n8n-workflow-automation/SKILL.md +103 -0
- package/skills/n8n-workflow-automation/assets/runbook-template.md +32 -0
- package/skills/narrative-designer/SKILL.md +27 -0
- package/skills/ontology/.clawhub/origin.json +7 -0
- package/skills/ontology/SKILL.md +236 -0
- package/skills/ontology/references/queries.md +211 -0
- package/skills/ontology/references/schema.md +322 -0
- package/skills/ontology/scripts/ontology.py +374 -0
- package/skills/openai-image-gen/.clawhub/origin.json +7 -0
- package/skills/openai-image-gen/SKILL.md +45 -0
- package/skills/openai-image-gen/scripts/gen.py +227 -0
- package/skills/openclaw-agent-optimize/.clawhub/origin.json +7 -0
- package/skills/openclaw-agent-optimize/SKILL.md +33 -0
- package/skills/openclaw-agent-optimize/references/agent-orchestration.md +20 -0
- package/skills/openclaw-agent-optimize/references/context-management.md +15 -0
- package/skills/openclaw-agent-optimize/references/continuous-learning.md +14 -0
- package/skills/openclaw-agent-optimize/references/cron-optimization.md +16 -0
- package/skills/openclaw-agent-optimize/references/memory-patterns.md +14 -0
- package/skills/openclaw-agent-optimize/references/model-selection.md +18 -0
- package/skills/openclaw-skill-scanner/.clawhub/origin.json +7 -0
- package/skills/openclaw-skill-scanner/SKILL.md +88 -0
- package/skills/openclaw-skill-scanner/install-hook.sh +294 -0
- package/skills/openclaw-skill-scanner/report-template.md +53 -0
- package/skills/openclaw-skill-scanner/scanner.py +929 -0
- package/skills/openclaw-skill-scanner/whitelist.json +18 -0
- package/skills/opportunity-solution-tree/SKILL.md +428 -0
- package/skills/opportunity-solution-tree/examples/sample.md +104 -0
- package/skills/opportunity-solution-tree/template.md +33 -0
- package/skills/pdf/.clawhub/origin.json +7 -0
- package/skills/pdf/SKILL.md +304 -0
- package/skills/pestel-analysis/SKILL.md +384 -0
- package/skills/pestel-analysis/examples/sample.md +143 -0
- package/skills/pestel-analysis/template.md +53 -0
- package/skills/pol-probe/SKILL.md +217 -0
- package/skills/pol-probe/examples/sample.md +136 -0
- package/skills/pol-probe/template.md +59 -0
- package/skills/pol-probe-advisor/SKILL.md +492 -0
- package/skills/positioning-statement/SKILL.md +229 -0
- package/skills/positioning-statement/examples/sample.md +51 -0
- package/skills/positioning-statement/template.md +25 -0
- package/skills/positioning-workshop/SKILL.md +424 -0
- package/skills/prd-development/SKILL.md +654 -0
- package/skills/prd-development/examples/sample.md +43 -0
- package/skills/prd-development/template.md +55 -0
- package/skills/press-release/SKILL.md +277 -0
- package/skills/press-release/examples/sample.md +73 -0
- package/skills/press-release/template.md +39 -0
- package/skills/prioritization-advisor/SKILL.md +451 -0
- package/skills/proactive-messages/.clawhub/origin.json +7 -0
- package/skills/proactive-messages/SKILL.md +91 -0
- package/skills/problem-framing-canvas/SKILL.md +466 -0
- package/skills/problem-framing-canvas/examples/sample.md +58 -0
- package/skills/problem-framing-canvas/template.md +22 -0
- package/skills/problem-statement/SKILL.md +255 -0
- package/skills/problem-statement/examples/sample.md +82 -0
- package/skills/problem-statement/template.md +37 -0
- package/skills/product-strategy-session/SKILL.md +434 -0
- package/skills/product-strategy-session/examples/sample.md +67 -0
- package/skills/product-strategy-session/template.md +38 -0
- package/skills/prompt-guard/.clawhub/origin.json +7 -0
- package/skills/prompt-guard/ARCHITECTURE.md +364 -0
- package/skills/prompt-guard/CHANGELOG.md +200 -0
- package/skills/prompt-guard/README.md +215 -0
- package/skills/prompt-guard/SECURITY.md +66 -0
- package/skills/prompt-guard/SKILL.md +174 -0
- package/skills/prompt-guard/blog/how-i-secured-my-ai-agent.md +185 -0
- package/skills/prompt-guard/config.example.yaml +56 -0
- package/skills/prompt-guard/references/detection-patterns.md +298 -0
- package/skills/prompt-guard/requirements.txt +1 -0
- package/skills/prompt-guard/scripts/analyze_log.py +224 -0
- package/skills/prompt-guard/scripts/audit.py +344 -0
- package/skills/prompt-guard/scripts/detect.py +1587 -0
- package/skills/prompt-guard/scripts/hivefence.py +345 -0
- package/skills/proto-persona/SKILL.md +336 -0
- package/skills/proto-persona/examples/sample.md +97 -0
- package/skills/proto-persona/template.md +45 -0
- package/skills/recommendation-canvas/SKILL.md +382 -0
- package/skills/recommendation-canvas/examples/sample.md +94 -0
- package/skills/recommendation-canvas/template.md +86 -0
- package/skills/refactor-suggest/.clawhub/origin.json +7 -0
- package/skills/refactor-suggest/SKILL.md +94 -0
- package/skills/roadmap-planning/SKILL.md +506 -0
- package/skills/roadmap-planning/examples/sample.md +62 -0
- package/skills/roadmap-planning/template.md +30 -0
- package/skills/saas-economics-efficiency-metrics/SKILL.md +694 -0
- package/skills/saas-economics-efficiency-metrics/examples/cash-trap.md +365 -0
- package/skills/saas-economics-efficiency-metrics/examples/healthy-unit-economics.md +279 -0
- package/skills/saas-economics-efficiency-metrics/template.md +263 -0
- package/skills/saas-revenue-growth-metrics/SKILL.md +629 -0
- package/skills/saas-revenue-growth-metrics/examples/healthy-saas.md +131 -0
- package/skills/saas-revenue-growth-metrics/examples/warning-signs.md +229 -0
- package/skills/saas-revenue-growth-metrics/template.md +192 -0
- package/skills/save-money/.clawhub/origin.json +7 -0
- package/skills/save-money/SKILL.md +173 -0
- package/skills/scripts/golden_skills_v3.sh +32 -0
- package/skills/search/.clawhub/origin.json +7 -0
- package/skills/search/SKILL.md +18 -0
- package/skills/search/skill.json +1 -0
- package/skills/second-brain/.clawhub/origin.json +7 -0
- package/skills/second-brain/SKILL.md +278 -0
- package/skills/second-brain/scripts/ensue-api.sh +37 -0
- package/skills/self-improving-agent/.clawhub/origin.json +7 -0
- package/skills/self-improving-agent/.learnings/ERRORS.md +5 -0
- package/skills/self-improving-agent/.learnings/FEATURE_REQUESTS.md +5 -0
- package/skills/self-improving-agent/.learnings/LEARNINGS.md +5 -0
- package/skills/self-improving-agent/SKILL.md +130 -0
- package/skills/self-improving-agent/assets/LEARNINGS.md +45 -0
- package/skills/self-improving-agent/assets/SKILL-TEMPLATE.md +177 -0
- package/skills/self-improving-agent/hooks/openclaw/HOOK.md +23 -0
- package/skills/self-improving-agent/hooks/openclaw/handler.js +56 -0
- package/skills/self-improving-agent/hooks/openclaw/handler.ts +62 -0
- package/skills/self-improving-agent/references/examples.md +374 -0
- package/skills/self-improving-agent/references/hooks-setup.md +223 -0
- package/skills/self-improving-agent/references/openclaw-integration.md +248 -0
- package/skills/self-improving-agent/references/templates.md +480 -0
- package/skills/self-improving-agent/scripts/activator.sh +20 -0
- package/skills/self-improving-agent/scripts/error-detector.sh +55 -0
- package/skills/self-improving-agent/scripts/extract-skill.sh +203 -0
- package/skills/self-improving-agent-1-0-2/.clawhub/origin.json +7 -0
- package/skills/self-improving-agent-1-0-2/SKILL.md +562 -0
- package/skills/self-improving-agent-1-0-2/assets/LEARNINGS.md +45 -0
- package/skills/self-improving-agent-1-0-2/assets/SKILL-TEMPLATE.md +182 -0
- package/skills/self-improving-agent-1-0-2/references/clawdbot-integration.md +311 -0
- package/skills/self-improving-agent-1-0-2/references/examples.md +374 -0
- package/skills/self-improving-agent-1-0-2/references/hooks-setup.md +223 -0
- package/skills/self-improving-agent-1-0-2/scripts/activator.sh +20 -0
- package/skills/self-improving-agent-1-0-2/scripts/error-detector.sh +55 -0
- package/skills/self-improving-agent-1-0-2/scripts/extract-skill.sh +203 -0
- package/skills/self-love-confidence/.clawhub/origin.json +7 -0
- package/skills/self-love-confidence/SKILL.md +79 -0
- package/skills/self-reflection/.clawhub/origin.json +7 -0
- package/skills/self-reflection/README.md +292 -0
- package/skills/self-reflection/SKILL.md +110 -0
- package/skills/self-reflection/self-reflection.example.json +6 -0
- package/skills/slither-analyzer/SKILL.md +27 -0
- package/skills/solidity-audit/SKILL.md +27 -0
- package/skills/soulcraft/.clawhub/origin.json +7 -0
- package/skills/soulcraft/README.md +123 -0
- package/skills/soulcraft/SKILL.md +340 -0
- package/skills/soulcraft/references/question-bank.md +154 -0
- package/skills/soulcraft/references/soul-examples.md +207 -0
- package/skills/soulcraft/research/RESEARCH_REPORT.md +317 -0
- package/skills/spotify-player/.clawhub/origin.json +7 -0
- package/skills/spotify-player/SKILL.md +44 -0
- package/skills/storyboard/SKILL.md +259 -0
- package/skills/storyboard/examples/sample.md +71 -0
- package/skills/storyboard/template.md +41 -0
- package/skills/summarize/.clawhub/origin.json +7 -0
- package/skills/summarize/SKILL.md +59 -0
- package/skills/superdesign/.clawhub/origin.json +7 -0
- package/skills/superdesign/SKILL.md +224 -0
- package/skills/tam-sam-som-calculator/SKILL.md +399 -0
- package/skills/tam-sam-som-calculator/examples/sample.md +142 -0
- package/skills/tam-sam-som-calculator/scripts/market-sizing.py +95 -0
- package/skills/tam-sam-som-calculator/template.md +35 -0
- package/skills/tavily-search/.clawhub/origin.json +7 -0
- package/skills/tavily-search/SKILL.md +49 -0
- package/skills/tavily-search/scripts/extract.mjs +59 -0
- package/skills/tavily-search/scripts/search.mjs +101 -0
- package/skills/twitter/SKILL.md +74 -0
- package/skills/twitter/_meta.json +9 -0
- package/skills/twitter/references/validation-cases.md +53 -0
- package/skills/twitter/scripts/twitter.sh +421 -0
- package/skills/ui-ux-pro-max/.clawhub/origin.json +7 -0
- package/skills/ui-ux-pro-max/SKILL.md +54 -0
- package/skills/ui-ux-pro-max/assets/data/charts.csv +26 -0
- package/skills/ui-ux-pro-max/assets/data/colors.csv +97 -0
- package/skills/ui-ux-pro-max/assets/data/icons.csv +101 -0
- package/skills/ui-ux-pro-max/assets/data/landing.csv +31 -0
- package/skills/ui-ux-pro-max/assets/data/products.csv +97 -0
- package/skills/ui-ux-pro-max/assets/data/react-performance.csv +45 -0
- package/skills/ui-ux-pro-max/assets/data/stacks/astro.csv +54 -0
- package/skills/ui-ux-pro-max/assets/data/stacks/flutter.csv +53 -0
- package/skills/ui-ux-pro-max/assets/data/stacks/html-tailwind.csv +56 -0
- package/skills/ui-ux-pro-max/assets/data/stacks/jetpack-compose.csv +53 -0
- package/skills/ui-ux-pro-max/assets/data/stacks/nextjs.csv +53 -0
- package/skills/ui-ux-pro-max/assets/data/stacks/nuxt-ui.csv +51 -0
- package/skills/ui-ux-pro-max/assets/data/stacks/nuxtjs.csv +59 -0
- package/skills/ui-ux-pro-max/assets/data/stacks/react-native.csv +52 -0
- package/skills/ui-ux-pro-max/assets/data/stacks/react.csv +54 -0
- package/skills/ui-ux-pro-max/assets/data/stacks/shadcn.csv +61 -0
- package/skills/ui-ux-pro-max/assets/data/stacks/svelte.csv +54 -0
- package/skills/ui-ux-pro-max/assets/data/stacks/swiftui.csv +51 -0
- package/skills/ui-ux-pro-max/assets/data/stacks/vue.csv +50 -0
- package/skills/ui-ux-pro-max/assets/data/styles.csv +68 -0
- package/skills/ui-ux-pro-max/assets/data/typography.csv +58 -0
- package/skills/ui-ux-pro-max/assets/data/ui-reasoning.csv +101 -0
- package/skills/ui-ux-pro-max/assets/data/ux-guidelines.csv +100 -0
- package/skills/ui-ux-pro-max/assets/data/web-interface.csv +31 -0
- package/skills/ui-ux-pro-max/references/upstream-README.md +488 -0
- package/skills/ui-ux-pro-max/references/upstream-skill-content.md +288 -0
- package/skills/ui-ux-pro-max/scripts/__init__.py +0 -0
- package/skills/ui-ux-pro-max/scripts/core.py +253 -0
- package/skills/ui-ux-pro-max/scripts/design_system.py +1071 -0
- package/skills/ui-ux-pro-max/scripts/search.py +111 -0
- package/skills/user-story/SKILL.md +272 -0
- package/skills/user-story/examples/sample.md +110 -0
- package/skills/user-story/scripts/user-story-template.py +65 -0
- package/skills/user-story/template.md +32 -0
- package/skills/user-story-mapping/SKILL.md +296 -0
- package/skills/user-story-mapping/examples/sample.md +77 -0
- package/skills/user-story-mapping/template.md +41 -0
- package/skills/user-story-mapping-workshop/SKILL.md +485 -0
- package/skills/user-story-mapping-workshop/template.md +28 -0
- package/skills/user-story-splitting/SKILL.md +313 -0
- package/skills/user-story-splitting/examples/sample.md +147 -0
- package/skills/user-story-splitting/template.md +37 -0
- package/skills/wacli/.clawhub/origin.json +7 -0
- package/skills/wacli/SKILL.md +53 -0
- package/skills/web-search/.clawhub/origin.json +7 -0
- package/skills/web-search/SKILL.md +151 -0
- package/skills/web-search/references/api-details.md +207 -0
- package/skills/web-search/scripts/search.py +576 -0
- package/skills/workshop-facilitation/SKILL.md +88 -0
- package/skills/world-builder/SKILL.md +27 -0
- package/souls/blockchain-auditor/PRINCIPLES.md +75 -0
- package/souls/blockchain-auditor/SOUL.md +56 -0
- package/souls/blockchain-auditor/capabilities.json +33 -0
- package/souls/blockchain-auditor/evolution/capsules.json +4 -0
- package/souls/blockchain-auditor/evolution/events.jsonl +1 -0
- package/souls/blockchain-auditor/evolution/genes.json +62 -0
- package/souls/daedalus/PRINCIPLES.md +78 -0
- package/souls/daedalus/SOUL.md +48 -0
- package/souls/daedalus/capabilities.json +46 -0
- package/souls/identity-architect/PRINCIPLES.md +83 -0
- package/souls/identity-architect/SOUL.md +66 -0
- package/souls/identity-architect/capabilities.json +38 -0
- package/souls/identity-architect/evolution/capsules.json +4 -0
- package/souls/identity-architect/evolution/events.jsonl +0 -0
- package/souls/identity-architect/evolution/genes.json +4 -0
- package/souls/infra-ops/PRINCIPLES.md +77 -0
- package/souls/infra-ops/SOUL.md +56 -0
- package/souls/infra-ops/capabilities.json +33 -0
- package/souls/infra-ops/evolution/capsules.json +4 -0
- package/souls/infra-ops/evolution/events.jsonl +0 -0
- package/souls/infra-ops/evolution/genes.json +4 -0
- package/souls/lore-writer/PRINCIPLES.md +74 -0
- package/souls/lore-writer/SOUL.md +54 -0
- package/souls/lore-writer/capabilities.json +37 -0
- package/souls/lore-writer/evolution/capsules.json +4 -0
- package/souls/lore-writer/evolution/events.jsonl +0 -0
- package/souls/lore-writer/evolution/genes.json +4 -0
- package/souls/qa-evidence/PRINCIPLES.md +97 -0
- package/souls/qa-evidence/SOUL.md +66 -0
- package/souls/qa-evidence/capabilities.json +32 -0
- package/souls/qa-evidence/evolution/capsules.json +4 -0
- package/souls/qa-evidence/evolution/events.jsonl +0 -0
- package/souls/qa-evidence/evolution/genes.json +4 -0
- package/souls/registry.json +211 -0
- package/souls/sync-registry.js +65 -0
- package/uninstall.sh +102 -0
- package/workspace-bin/auto-checkpoint +60 -0
- package/workspace-bin/clawvault-access-control +65 -0
- package/workspace-bin/clawvault-local +28 -0
- package/workspace-bin/compile-boot +494 -0
- package/workspace-bin/daily-log-writer.mjs +251 -0
- package/workspace-bin/evolve +540 -0
- package/workspace-bin/fitness_score.py +395 -0
- package/workspace-bin/hooks/pre-commit +80 -0
- package/workspace-bin/install-daemon +299 -0
- package/workspace-bin/lane-watchdog.js +232 -0
- package/workspace-bin/lib/__init__.py +0 -0
- package/workspace-bin/lib/frontmatter.py +114 -0
- package/workspace-bin/memory-daemon.mjs +879 -0
- package/workspace-bin/memory-maintenance.mjs +531 -0
- package/workspace-bin/mesh-bridge.mjs +154 -0
- package/workspace-bin/multi-review +130 -0
- package/workspace-bin/obsidian +125 -0
- package/workspace-bin/obsidian-sync.mjs +888 -0
- package/workspace-bin/openclaw-register-source +102 -0
- package/workspace-bin/proactive-scan +147 -0
- package/workspace-bin/quality-gate +175 -0
- package/workspace-bin/screenshot +96 -0
- package/workspace-bin/session-recap +453 -0
- package/workspace-bin/skill-audit +494 -0
- package/workspace-bin/skill-quality-check +134 -0
- package/workspace-bin/skill-routing-eval +599 -0
- package/workspace-bin/soul-prompt +251 -0
- package/workspace-bin/subagent-audit.mjs +267 -0
- package/workspace-bin/test-multi-soul-workflow +130 -0
- package/workspace-bin/trust-registry +465 -0
- package/workspace-docs/AGENTS.md +201 -0
- package/workspace-docs/CLAUDE.md +64 -0
- package/workspace-docs/PRINCIPLES.md +81 -0
- package/workspace-docs/SOUL.md +48 -0
|
@@ -0,0 +1,714 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* mesh-agent.js — Mesh worker agent for OpenClaw.
|
|
5
|
+
*
|
|
6
|
+
* Option A architecture: external wrapper around Claude Code CLI.
|
|
7
|
+
* The outer loop is mechanical Node.js code. The inner loop is the LLM.
|
|
8
|
+
* The LLM has no awareness of the mesh — it gets a clean task prompt.
|
|
9
|
+
*
|
|
10
|
+
* Flow:
|
|
11
|
+
* 1. Connect to NATS
|
|
12
|
+
* 2. Claim next available task from mesh-task-daemon
|
|
13
|
+
* 3. Construct prompt from task schema
|
|
14
|
+
* 4. Run `claude -p` (non-interactive)
|
|
15
|
+
* 5. Evaluate metric (if defined)
|
|
16
|
+
* 6. If metric fails → log attempt, retry with failure context
|
|
17
|
+
* 7. If metric passes or no metric → report completion
|
|
18
|
+
* 8. If budget exhausted → report failure
|
|
19
|
+
* 9. Loop back to step 2
|
|
20
|
+
*
|
|
21
|
+
* The Karpathy pattern: try → measure → keep/discard → retry.
|
|
22
|
+
* The outer loop is deterministic. The LLM owns the problem-solving.
|
|
23
|
+
*
|
|
24
|
+
* Usage:
|
|
25
|
+
* node mesh-agent.js # run worker
|
|
26
|
+
* node mesh-agent.js --once # claim one task, execute, exit
|
|
27
|
+
* node mesh-agent.js --model sonnet # override model
|
|
28
|
+
* node mesh-agent.js --dry-run # claim + build prompt, don't execute
|
|
29
|
+
*/
|
|
30
|
+
|
|
31
|
+
const { connect, StringCodec } = require('nats');
|
|
32
|
+
const { spawn, execSync } = require('child_process');
|
|
33
|
+
const os = require('os');
|
|
34
|
+
const path = require('path');
|
|
35
|
+
const fs = require('fs');
|
|
36
|
+
const { getActivityState, getSessionInfo } = require('../lib/agent-activity');
|
|
37
|
+
|
|
38
|
+
const sc = StringCodec();
|
|
39
|
+
const { NATS_URL, natsConnectOpts } = require('../lib/nats-resolve');
|
|
40
|
+
const NODE_ID = process.env.MESH_NODE_ID || os.hostname().toLowerCase().replace(/[^a-z0-9-]/g, '-');
|
|
41
|
+
const POLL_INTERVAL = parseInt(process.env.MESH_POLL_INTERVAL || '15000'); // 15s between polls
|
|
42
|
+
const MAX_ATTEMPTS = parseInt(process.env.MESH_MAX_ATTEMPTS || '3');
|
|
43
|
+
const HEARTBEAT_INTERVAL = parseInt(process.env.MESH_HEARTBEAT_INTERVAL || '60000'); // 60s heartbeat
|
|
44
|
+
const CLAUDE_PATH = process.env.CLAUDE_PATH || '/usr/local/bin/claude';
|
|
45
|
+
const WORKSPACE = process.env.MESH_WORKSPACE || path.join(process.env.HOME, '.openclaw', 'workspace');
|
|
46
|
+
|
|
47
|
+
// ── CLI args ──────────────────────────────────────────
|
|
48
|
+
|
|
49
|
+
const args = process.argv.slice(2);
|
|
50
|
+
const ONCE = args.includes('--once');
|
|
51
|
+
const DRY_RUN = args.includes('--dry-run');
|
|
52
|
+
const MODEL = (() => {
|
|
53
|
+
const idx = args.indexOf('--model');
|
|
54
|
+
return idx >= 0 && args[idx + 1] ? args[idx + 1] : 'sonnet';
|
|
55
|
+
})();
|
|
56
|
+
|
|
57
|
+
let nc;
|
|
58
|
+
let running = true;
|
|
59
|
+
let currentTaskId = null; // tracks active task for alive-check responses
|
|
60
|
+
|
|
61
|
+
// ── Agent State File (read by mesh-health-publisher) ──
|
|
62
|
+
const AGENT_STATE_PATH = path.join(os.homedir(), '.openclaw', '.tmp', 'agent-state.json');
|
|
63
|
+
|
|
64
|
+
function writeAgentState(status, taskId) {
|
|
65
|
+
try {
|
|
66
|
+
fs.writeFileSync(AGENT_STATE_PATH, JSON.stringify({
|
|
67
|
+
status, taskId: taskId || null,
|
|
68
|
+
llm: status === 'working' ? 'claude' : null,
|
|
69
|
+
model: status === 'working' ? MODEL : null,
|
|
70
|
+
}));
|
|
71
|
+
} catch { /* best-effort */ }
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// ── Logging ───────────────────────────────────────────
|
|
75
|
+
|
|
76
|
+
function log(msg) {
|
|
77
|
+
const ts = new Date().toISOString();
|
|
78
|
+
console.log(`[${ts}] [mesh-agent:${NODE_ID}] ${msg}`);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// ── NATS Helpers ──────────────────────────────────────
|
|
82
|
+
|
|
83
|
+
async function natsRequest(subject, payload, timeoutMs = 10000) {
|
|
84
|
+
const msg = await nc.request(subject, sc.encode(JSON.stringify(payload)), { timeout: timeoutMs });
|
|
85
|
+
const response = JSON.parse(sc.decode(msg.data));
|
|
86
|
+
if (!response.ok) throw new Error(response.error);
|
|
87
|
+
return response.data;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// ── Prompt Construction ───────────────────────────────
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Build the initial prompt from a task.
|
|
94
|
+
* The LLM gets: what to do, what files to touch, how to verify success.
|
|
95
|
+
* It does NOT get: NATS subjects, mesh protocol, budget deadlines.
|
|
96
|
+
*/
|
|
97
|
+
function buildInitialPrompt(task) {
|
|
98
|
+
const parts = [];
|
|
99
|
+
|
|
100
|
+
parts.push(`# Task: ${task.title}`);
|
|
101
|
+
parts.push('');
|
|
102
|
+
|
|
103
|
+
if (task.description) {
|
|
104
|
+
parts.push(task.description);
|
|
105
|
+
parts.push('');
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
if (task.success_criteria.length > 0) {
|
|
109
|
+
parts.push('## Success Criteria');
|
|
110
|
+
for (const c of task.success_criteria) {
|
|
111
|
+
parts.push(`- ${c}`);
|
|
112
|
+
}
|
|
113
|
+
parts.push('');
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
if (task.metric) {
|
|
117
|
+
parts.push(`## Verification`);
|
|
118
|
+
parts.push(`Run this command to check your work: \`${task.metric}\``);
|
|
119
|
+
parts.push(`Your changes are only accepted if this command exits with code 0.`);
|
|
120
|
+
parts.push('');
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
if (task.scope.length > 0) {
|
|
124
|
+
parts.push('## Scope');
|
|
125
|
+
parts.push('Only modify these files/paths:');
|
|
126
|
+
for (const s of task.scope) {
|
|
127
|
+
parts.push(`- ${s}`);
|
|
128
|
+
}
|
|
129
|
+
parts.push('');
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
parts.push('## Instructions');
|
|
133
|
+
parts.push('- Read the relevant files before making changes.');
|
|
134
|
+
parts.push('- Make minimal, focused changes. Do not add scope beyond what is asked.');
|
|
135
|
+
parts.push('- If you hit a blocker you cannot resolve, explain what is blocking you clearly.');
|
|
136
|
+
if (task.metric) {
|
|
137
|
+
parts.push(`- After making changes, run \`${task.metric}\` to verify.`);
|
|
138
|
+
parts.push('- If verification fails, analyze the failure and iterate on your approach.');
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
return parts.join('\n');
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Build a retry prompt after a failed attempt.
|
|
146
|
+
* Includes: what was tried, why it failed, what to try differently.
|
|
147
|
+
*/
|
|
148
|
+
function buildRetryPrompt(task, previousAttempts, attemptNumber) {
|
|
149
|
+
const parts = [];
|
|
150
|
+
|
|
151
|
+
parts.push(`# Task: ${task.title} (Attempt ${attemptNumber}/${MAX_ATTEMPTS})`);
|
|
152
|
+
parts.push('');
|
|
153
|
+
parts.push('Previous attempts have not passed verification. Review what was tried and take a different approach.');
|
|
154
|
+
if (attemptNumber >= 3) {
|
|
155
|
+
parts.push('');
|
|
156
|
+
parts.push('**This is attempt 3+. Previous approaches did not work. Try a fundamentally different strategy.**');
|
|
157
|
+
parts.push('Do not iterate on the same idea — rethink the problem from scratch.');
|
|
158
|
+
}
|
|
159
|
+
parts.push('');
|
|
160
|
+
|
|
161
|
+
if (task.description) {
|
|
162
|
+
parts.push(task.description);
|
|
163
|
+
parts.push('');
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
parts.push('## Previous Attempts');
|
|
167
|
+
for (let i = 0; i < previousAttempts.length; i++) {
|
|
168
|
+
const a = previousAttempts[i];
|
|
169
|
+
parts.push(`### Attempt ${i + 1}`);
|
|
170
|
+
parts.push(`- Approach: ${a.approach || 'unknown'}`);
|
|
171
|
+
parts.push(`- Result: ${a.result || 'unknown'}`);
|
|
172
|
+
parts.push(`- Kept: ${a.keep ? 'yes' : 'no (reverted)'}`);
|
|
173
|
+
parts.push('');
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
if (task.metric) {
|
|
177
|
+
parts.push(`## Verification`);
|
|
178
|
+
parts.push(`Run: \`${task.metric}\``);
|
|
179
|
+
parts.push(`Must exit code 0.`);
|
|
180
|
+
parts.push('');
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
if (task.scope.length > 0) {
|
|
184
|
+
parts.push('## Scope');
|
|
185
|
+
for (const s of task.scope) {
|
|
186
|
+
parts.push(`- ${s}`);
|
|
187
|
+
}
|
|
188
|
+
parts.push('');
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
parts.push('## Instructions');
|
|
192
|
+
parts.push('- Do NOT repeat a failed approach. Try something different.');
|
|
193
|
+
parts.push('- Read the relevant files before making changes.');
|
|
194
|
+
parts.push('- Make minimal, focused changes.');
|
|
195
|
+
if (task.metric) {
|
|
196
|
+
parts.push(`- Run \`${task.metric}\` to verify before finishing.`);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
return parts.join('\n');
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
// ── Worktree Isolation ────────────────────────────────
|
|
203
|
+
|
|
204
|
+
const WORKTREE_BASE = process.env.MESH_WORKTREE_BASE || path.join(process.env.HOME, '.openclaw', 'worktrees');
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* Create a git worktree for a task. Returns the worktree path.
|
|
208
|
+
* Each task gets an isolated branch and working directory.
|
|
209
|
+
* On failure, returns null (falls back to shared workspace).
|
|
210
|
+
*/
|
|
211
|
+
function createWorktree(taskId) {
|
|
212
|
+
const worktreePath = path.join(WORKTREE_BASE, taskId);
|
|
213
|
+
const branch = `mesh/${taskId}`;
|
|
214
|
+
|
|
215
|
+
try {
|
|
216
|
+
fs.mkdirSync(WORKTREE_BASE, { recursive: true });
|
|
217
|
+
|
|
218
|
+
// Clean up stale worktree if it exists from a previous crashed attempt
|
|
219
|
+
if (fs.existsSync(worktreePath)) {
|
|
220
|
+
log(`Cleaning stale worktree: ${worktreePath}`);
|
|
221
|
+
try {
|
|
222
|
+
execSync(`git worktree remove --force "${worktreePath}"`, { cwd: WORKSPACE, timeout: 10000 });
|
|
223
|
+
} catch {
|
|
224
|
+
// If git worktree remove fails, manually clean up
|
|
225
|
+
fs.rmSync(worktreePath, { recursive: true, force: true });
|
|
226
|
+
}
|
|
227
|
+
// Also clean up the branch if it exists
|
|
228
|
+
try {
|
|
229
|
+
execSync(`git branch -D "${branch}"`, { cwd: WORKSPACE, timeout: 5000, stdio: 'ignore' });
|
|
230
|
+
} catch { /* branch may not exist */ }
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
// Create new worktree branched off HEAD
|
|
234
|
+
execSync(`git worktree add -b "${branch}" "${worktreePath}" HEAD`, {
|
|
235
|
+
cwd: WORKSPACE,
|
|
236
|
+
timeout: 30000,
|
|
237
|
+
stdio: 'pipe',
|
|
238
|
+
});
|
|
239
|
+
|
|
240
|
+
log(`Worktree created: ${worktreePath} (branch: ${branch})`);
|
|
241
|
+
return worktreePath;
|
|
242
|
+
} catch (err) {
|
|
243
|
+
log(`WORKTREE FAILED: ${err.message} — falling back to shared workspace`);
|
|
244
|
+
return null;
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* Clean up a worktree after task completion or failure.
|
|
250
|
+
* @param {string} worktreePath
|
|
251
|
+
* @param {boolean} keep - If true, leave the branch for manual review
|
|
252
|
+
*/
|
|
253
|
+
/**
|
|
254
|
+
* Commit any changes in the worktree and merge to main.
|
|
255
|
+
* Returns { committed, merged, sha } or null if nothing to commit.
|
|
256
|
+
*/
|
|
257
|
+
function commitAndMergeWorktree(worktreePath, taskId, summary) {
|
|
258
|
+
if (!worktreePath) return null;
|
|
259
|
+
const branch = `mesh/${taskId}`;
|
|
260
|
+
|
|
261
|
+
try {
|
|
262
|
+
// Check for changes
|
|
263
|
+
const status = execSync('git status --porcelain', {
|
|
264
|
+
cwd: worktreePath, timeout: 5000, encoding: 'utf-8',
|
|
265
|
+
}).trim();
|
|
266
|
+
|
|
267
|
+
if (!status) {
|
|
268
|
+
log(`Worktree has no changes to commit (${taskId})`);
|
|
269
|
+
return null;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
// Stage and commit all changes
|
|
273
|
+
execSync('git add -A', { cwd: worktreePath, timeout: 10000, stdio: 'pipe' });
|
|
274
|
+
const commitMsg = `mesh(${taskId}): ${(summary || 'task completed').slice(0, 72)}`;
|
|
275
|
+
const { spawnSync } = require('child_process');
|
|
276
|
+
const commitResult = spawnSync('git', ['commit', '-m', commitMsg], {
|
|
277
|
+
cwd: worktreePath, timeout: 10000, stdio: 'pipe',
|
|
278
|
+
});
|
|
279
|
+
if (commitResult.status !== 0) {
|
|
280
|
+
throw new Error(`git commit failed: ${commitResult.stderr?.toString() || 'unknown error'}`);
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
const sha = execSync('git rev-parse --short HEAD', {
|
|
284
|
+
cwd: worktreePath, timeout: 5000, encoding: 'utf-8',
|
|
285
|
+
}).trim();
|
|
286
|
+
|
|
287
|
+
log(`Committed ${sha} on ${branch}: ${commitMsg}`);
|
|
288
|
+
|
|
289
|
+
// Merge into main (from workspace)
|
|
290
|
+
try {
|
|
291
|
+
execSync(`git merge --no-ff "${branch}" -m "Merge ${branch}: ${taskId}"`, {
|
|
292
|
+
cwd: WORKSPACE, timeout: 30000, stdio: 'pipe',
|
|
293
|
+
});
|
|
294
|
+
log(`Merged ${branch} into main`);
|
|
295
|
+
return { committed: true, merged: true, sha };
|
|
296
|
+
} catch (mergeErr) {
|
|
297
|
+
// Merge conflict — abort and keep branch for human resolution
|
|
298
|
+
execSync('git merge --abort', { cwd: WORKSPACE, timeout: 5000, stdio: 'ignore' });
|
|
299
|
+
log(`MERGE CONFLICT on ${branch} — branch kept for manual resolution`);
|
|
300
|
+
return { committed: true, merged: false, sha };
|
|
301
|
+
}
|
|
302
|
+
} catch (err) {
|
|
303
|
+
log(`Commit/merge warning: ${err.message}`);
|
|
304
|
+
return null;
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
/**
|
|
309
|
+
* Clean up a worktree after task completion or failure.
|
|
310
|
+
* @param {string} worktreePath
|
|
311
|
+
* @param {boolean} keep - If true, leave the branch for manual review
|
|
312
|
+
*/
|
|
313
|
+
function cleanupWorktree(worktreePath, keep = false) {
|
|
314
|
+
if (!worktreePath || !worktreePath.startsWith(WORKTREE_BASE)) return;
|
|
315
|
+
|
|
316
|
+
const taskId = path.basename(worktreePath);
|
|
317
|
+
const branch = `mesh/${taskId}`;
|
|
318
|
+
|
|
319
|
+
try {
|
|
320
|
+
execSync(`git worktree remove --force "${worktreePath}"`, {
|
|
321
|
+
cwd: WORKSPACE,
|
|
322
|
+
timeout: 10000,
|
|
323
|
+
stdio: 'pipe',
|
|
324
|
+
});
|
|
325
|
+
if (!keep) {
|
|
326
|
+
execSync(`git branch -D "${branch}"`, {
|
|
327
|
+
cwd: WORKSPACE,
|
|
328
|
+
timeout: 5000,
|
|
329
|
+
stdio: 'ignore',
|
|
330
|
+
});
|
|
331
|
+
}
|
|
332
|
+
log(`Worktree cleaned: ${worktreePath} (branch ${keep ? 'kept' : 'deleted'})`);
|
|
333
|
+
} catch (err) {
|
|
334
|
+
log(`Worktree cleanup warning: ${err.message}`);
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
// ── Claude Execution ──────────────────────────────────
|
|
339
|
+
|
|
340
|
+
/**
|
|
341
|
+
* Run Claude Code CLI with a prompt. Returns { exitCode, stdout, stderr, cwd }.
|
|
342
|
+
* Sends heartbeats to the daemon every HEARTBEAT_INTERVAL to prevent stall detection.
|
|
343
|
+
*
|
|
344
|
+
* @param {string} prompt
|
|
345
|
+
* @param {object} task
|
|
346
|
+
* @param {string|null} worktreePath - If set, Claude accesses this worktree instead of WORKSPACE
|
|
347
|
+
*/
|
|
348
|
+
function runClaude(prompt, task, worktreePath) {
|
|
349
|
+
return new Promise((resolve) => {
|
|
350
|
+
const args = [
|
|
351
|
+
'-p', prompt,
|
|
352
|
+
'--output-format', 'text',
|
|
353
|
+
'--model', MODEL,
|
|
354
|
+
'--permission-mode', 'bypassPermissions',
|
|
355
|
+
// SECURITY NOTE: bypassPermissions is intentional for mesh agents.
|
|
356
|
+
// Tasks run in isolated worktrees with no interactive terminal.
|
|
357
|
+
// The agent needs autonomous execution without permission prompts.
|
|
358
|
+
// Safety is enforced at the mesh level: budget limits, scope restrictions,
|
|
359
|
+
// and human review of all results before merge to main.
|
|
360
|
+
// Note: --no-session-persistence removed to enable JSONL activity tracking
|
|
361
|
+
// Claude writes session files to ~/.claude/projects/{encoded-cwd}/
|
|
362
|
+
// which agent-activity.js reads for cost, summary, and activity state
|
|
363
|
+
];
|
|
364
|
+
|
|
365
|
+
// Use worktree if available, otherwise fall back to workspace
|
|
366
|
+
const targetDir = worktreePath || WORKSPACE;
|
|
367
|
+
args.push('--add-dir', targetDir);
|
|
368
|
+
|
|
369
|
+
// When using a worktree, also give read access to the workspace
|
|
370
|
+
// (scope files may be untracked and absent from worktree)
|
|
371
|
+
if (worktreePath) {
|
|
372
|
+
args.push('--add-dir', WORKSPACE);
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
// Add scope directories if specified (with path traversal validation)
|
|
376
|
+
if (task.scope.length > 0) {
|
|
377
|
+
const addedDirs = new Set([targetDir, WORKSPACE]);
|
|
378
|
+
for (const s of task.scope) {
|
|
379
|
+
// Resolve against both workspace and worktree
|
|
380
|
+
for (const base of [targetDir, WORKSPACE]) {
|
|
381
|
+
const resolved = path.resolve(base, s);
|
|
382
|
+
const resolvedDir = path.dirname(resolved);
|
|
383
|
+
if (!resolved.startsWith(base) && !resolved.startsWith('/tmp/')) continue;
|
|
384
|
+
if (addedDirs.has(resolvedDir)) continue;
|
|
385
|
+
addedDirs.add(resolvedDir);
|
|
386
|
+
args.push('--add-dir', resolvedDir);
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
log(`Spawning: claude ${args.slice(0, 6).join(' ')} ... (target: ${worktreePath ? 'worktree' : 'workspace'})`);
|
|
392
|
+
|
|
393
|
+
// Use a clean temp directory as cwd to avoid loading workspace CLAUDE.md
|
|
394
|
+
// (which triggers the full Daedalus boot sequence and eats the entire budget)
|
|
395
|
+
const cleanCwd = path.join(os.tmpdir(), 'mesh-agent-work');
|
|
396
|
+
if (!fs.existsSync(cleanCwd)) fs.mkdirSync(cleanCwd, { recursive: true });
|
|
397
|
+
|
|
398
|
+
// Strip CLAUDECODE env var to allow nested sessions
|
|
399
|
+
const cleanEnv = { ...process.env };
|
|
400
|
+
delete cleanEnv.CLAUDECODE;
|
|
401
|
+
|
|
402
|
+
const child = spawn(CLAUDE_PATH, args, {
|
|
403
|
+
cwd: cleanCwd,
|
|
404
|
+
env: cleanEnv,
|
|
405
|
+
stdio: ['ignore', 'pipe', 'pipe'], // stdin must be 'ignore' — 'pipe' causes Claude to block
|
|
406
|
+
timeout: (task.budget_minutes || 30) * 60 * 1000, // kill if exceeds budget
|
|
407
|
+
});
|
|
408
|
+
|
|
409
|
+
// Heartbeat: signal daemon with JSONL-enriched activity state
|
|
410
|
+
const heartbeatTimer = setInterval(async () => {
|
|
411
|
+
try {
|
|
412
|
+
// Read Claude's JSONL session file for real activity state (zero token cost)
|
|
413
|
+
// KNOWN LIMITATION: If Claude transitions working→ready→working within one
|
|
414
|
+
// heartbeat interval (60s), the ready state is missed. Acceptable for V1
|
|
415
|
+
// (used for visibility only, not triggering reactions). Revisit if reactions
|
|
416
|
+
// depend on seeing transient states.
|
|
417
|
+
const activity = await getActivityState(cleanCwd);
|
|
418
|
+
const payload = { task_id: task.task_id };
|
|
419
|
+
if (activity) {
|
|
420
|
+
payload.activity_state = activity.state; // starting|active|ready|idle|waiting_input|blocked
|
|
421
|
+
payload.activity_timestamp = activity.timestamp?.toISOString();
|
|
422
|
+
}
|
|
423
|
+
await natsRequest('mesh.tasks.heartbeat', payload);
|
|
424
|
+
} catch {
|
|
425
|
+
// fire-and-forget, don't crash on NATS hiccup or JSONL read failure
|
|
426
|
+
}
|
|
427
|
+
}, HEARTBEAT_INTERVAL);
|
|
428
|
+
|
|
429
|
+
let stdout = '';
|
|
430
|
+
let stderr = '';
|
|
431
|
+
|
|
432
|
+
child.stdout.on('data', (d) => { stdout += d.toString(); });
|
|
433
|
+
child.stderr.on('data', (d) => { stderr += d.toString(); });
|
|
434
|
+
|
|
435
|
+
child.on('close', (code) => {
|
|
436
|
+
clearInterval(heartbeatTimer);
|
|
437
|
+
resolve({ exitCode: code, stdout, stderr });
|
|
438
|
+
});
|
|
439
|
+
|
|
440
|
+
child.on('error', (err) => {
|
|
441
|
+
clearInterval(heartbeatTimer);
|
|
442
|
+
resolve({ exitCode: 1, stdout: '', stderr: err.message });
|
|
443
|
+
});
|
|
444
|
+
});
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
// ── Metric Evaluation ─────────────────────────────────
|
|
448
|
+
|
|
449
|
+
/**
|
|
450
|
+
* Run the task's metric command. Returns { passed, output }.
|
|
451
|
+
*/
|
|
452
|
+
function evaluateMetric(metric, cwd) {
|
|
453
|
+
return new Promise((resolve) => {
|
|
454
|
+
const child = spawn('bash', ['-c', metric], {
|
|
455
|
+
cwd: cwd || WORKSPACE,
|
|
456
|
+
env: process.env,
|
|
457
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
458
|
+
timeout: 60000, // 60s max for metric evaluation
|
|
459
|
+
});
|
|
460
|
+
|
|
461
|
+
let output = '';
|
|
462
|
+
child.stdout.on('data', (d) => { output += d.toString(); });
|
|
463
|
+
child.stderr.on('data', (d) => { output += d.toString(); });
|
|
464
|
+
|
|
465
|
+
child.on('close', (code) => {
|
|
466
|
+
resolve({ passed: code === 0, output: output.slice(-2000) }); // last 2K chars
|
|
467
|
+
});
|
|
468
|
+
|
|
469
|
+
child.on('error', (err) => {
|
|
470
|
+
resolve({ passed: false, output: err.message });
|
|
471
|
+
});
|
|
472
|
+
});
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
// ── Task Execution ────────────────────────────────────
|
|
476
|
+
|
|
477
|
+
/**
|
|
478
|
+
* Execute a task with the Karpathy iteration pattern.
|
|
479
|
+
* Try → measure → keep/discard → retry.
|
|
480
|
+
*/
|
|
481
|
+
async function executeTask(task) {
|
|
482
|
+
log(`EXECUTING: ${task.task_id} "${task.title}" (budget: ${task.budget_minutes}m, metric: ${task.metric || 'none'}, max attempts: ${MAX_ATTEMPTS})`);
|
|
483
|
+
|
|
484
|
+
// Create isolated worktree for this task (falls back to shared workspace on failure)
|
|
485
|
+
const worktreePath = createWorktree(task.task_id);
|
|
486
|
+
const taskDir = worktreePath || WORKSPACE;
|
|
487
|
+
|
|
488
|
+
// Signal start
|
|
489
|
+
await natsRequest('mesh.tasks.start', { task_id: task.task_id });
|
|
490
|
+
writeAgentState('working', task.task_id);
|
|
491
|
+
log(`Started: ${task.task_id} (dir: ${worktreePath ? 'worktree' : 'workspace'})`);
|
|
492
|
+
|
|
493
|
+
const attempts = [];
|
|
494
|
+
|
|
495
|
+
for (let attempt = 1; attempt <= MAX_ATTEMPTS; attempt++) {
|
|
496
|
+
// Check budget before each attempt
|
|
497
|
+
const budgetDeadline = new Date(task.budget_deadline);
|
|
498
|
+
const remaining = (budgetDeadline - Date.now()) / 60000;
|
|
499
|
+
if (remaining <= 0) {
|
|
500
|
+
log(`Budget exhausted before attempt ${attempt}`);
|
|
501
|
+
break;
|
|
502
|
+
}
|
|
503
|
+
log(`Attempt ${attempt}/${MAX_ATTEMPTS} (${remaining.toFixed(1)}m remaining)`);
|
|
504
|
+
|
|
505
|
+
// Build prompt — attempt number injected as discrete integer for strategy branching
|
|
506
|
+
const prompt = attempt === 1
|
|
507
|
+
? buildInitialPrompt(task)
|
|
508
|
+
: buildRetryPrompt(task, attempts, attempt);
|
|
509
|
+
|
|
510
|
+
if (DRY_RUN) {
|
|
511
|
+
log(`[DRY RUN] Prompt:\n${prompt}`);
|
|
512
|
+
// Release the task so it doesn't stay stuck in "running" state
|
|
513
|
+
await natsRequest('mesh.tasks.release', { task_id: task.task_id, node_id: NODE_ID }).catch(() => {});
|
|
514
|
+
return;
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
// Run Claude (with worktree isolation if available)
|
|
518
|
+
const claudeResult = await runClaude(prompt, task, worktreePath);
|
|
519
|
+
const summary = claudeResult.stdout.slice(-500) || '(no output)';
|
|
520
|
+
|
|
521
|
+
log(`Claude exited with code ${claudeResult.exitCode}`);
|
|
522
|
+
|
|
523
|
+
// Extract cost + summary from JSONL session file (zero-cost observability)
|
|
524
|
+
const cleanCwd = path.join(os.tmpdir(), 'mesh-agent-work');
|
|
525
|
+
const sessionInfo = await getSessionInfo(cleanCwd).catch(() => null);
|
|
526
|
+
if (sessionInfo?.cost) {
|
|
527
|
+
log(`Cost: $${sessionInfo.cost.estimatedCostUsd.toFixed(4)} (${sessionInfo.cost.inputTokens} in / ${sessionInfo.cost.outputTokens} out)`);
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
if (claudeResult.exitCode !== 0) {
|
|
531
|
+
const attemptRecord = {
|
|
532
|
+
approach: `Attempt ${attempt}: Claude exited with error (code ${claudeResult.exitCode})`,
|
|
533
|
+
result: claudeResult.stderr.slice(-500) || 'unknown error',
|
|
534
|
+
keep: false,
|
|
535
|
+
};
|
|
536
|
+
attempts.push(attemptRecord);
|
|
537
|
+
await natsRequest('mesh.tasks.attempt', { task_id: task.task_id, ...attemptRecord });
|
|
538
|
+
|
|
539
|
+
// Two-tier retry: abnormal exit → exponential backoff (agent crash, OOM, etc.)
|
|
540
|
+
const backoffMs = Math.min(1000 * Math.pow(2, attempt - 1), 30000); // 1s, 2s, 4s... max 30s
|
|
541
|
+
log(`Attempt ${attempt} failed (Claude error, code ${claudeResult.exitCode}). Backoff ${backoffMs}ms before retry.`);
|
|
542
|
+
await new Promise(r => setTimeout(r, backoffMs));
|
|
543
|
+
continue;
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
// If no metric, trust Claude's output and complete
|
|
547
|
+
if (!task.metric) {
|
|
548
|
+
const attemptRecord = {
|
|
549
|
+
approach: `Attempt ${attempt}: executed without metric`,
|
|
550
|
+
result: summary,
|
|
551
|
+
keep: true,
|
|
552
|
+
};
|
|
553
|
+
attempts.push(attemptRecord);
|
|
554
|
+
await natsRequest('mesh.tasks.attempt', { task_id: task.task_id, ...attemptRecord });
|
|
555
|
+
|
|
556
|
+
// Commit changes and merge to main before cleanup
|
|
557
|
+
const mergeResult = commitAndMergeWorktree(worktreePath, task.task_id, summary);
|
|
558
|
+
const keepBranch = mergeResult && !mergeResult.merged; // keep on merge conflict
|
|
559
|
+
|
|
560
|
+
await natsRequest('mesh.tasks.complete', {
|
|
561
|
+
task_id: task.task_id,
|
|
562
|
+
result: {
|
|
563
|
+
success: true, summary, artifacts: [],
|
|
564
|
+
cost: sessionInfo?.cost || null,
|
|
565
|
+
sha: mergeResult?.sha || null,
|
|
566
|
+
merged: mergeResult?.merged ?? null,
|
|
567
|
+
},
|
|
568
|
+
});
|
|
569
|
+
cleanupWorktree(worktreePath, keepBranch);
|
|
570
|
+
writeAgentState('idle', null);
|
|
571
|
+
log(`COMPLETED: ${task.task_id} (no metric, attempt ${attempt})`);
|
|
572
|
+
return;
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
// Evaluate metric (run in worktree if available)
|
|
576
|
+
log(`Evaluating metric: ${task.metric} (in ${worktreePath ? 'worktree' : 'workspace'})`);
|
|
577
|
+
const metricResult = await evaluateMetric(task.metric, taskDir);
|
|
578
|
+
|
|
579
|
+
if (metricResult.passed) {
|
|
580
|
+
const attemptRecord = {
|
|
581
|
+
approach: `Attempt ${attempt}: metric passed`,
|
|
582
|
+
result: metricResult.output.slice(-300),
|
|
583
|
+
keep: true,
|
|
584
|
+
};
|
|
585
|
+
attempts.push(attemptRecord);
|
|
586
|
+
await natsRequest('mesh.tasks.attempt', { task_id: task.task_id, ...attemptRecord });
|
|
587
|
+
|
|
588
|
+
// Commit changes and merge to main before cleanup
|
|
589
|
+
const mergeResult = commitAndMergeWorktree(worktreePath, task.task_id, summary);
|
|
590
|
+
const keepBranch = mergeResult && !mergeResult.merged;
|
|
591
|
+
|
|
592
|
+
await natsRequest('mesh.tasks.complete', {
|
|
593
|
+
task_id: task.task_id,
|
|
594
|
+
result: {
|
|
595
|
+
success: true,
|
|
596
|
+
summary: `Metric passed on attempt ${attempt}. ${summary.slice(0, 200)}`,
|
|
597
|
+
artifacts: [],
|
|
598
|
+
cost: sessionInfo?.cost || null,
|
|
599
|
+
sha: mergeResult?.sha || null,
|
|
600
|
+
merged: mergeResult?.merged ?? null,
|
|
601
|
+
},
|
|
602
|
+
});
|
|
603
|
+
cleanupWorktree(worktreePath, keepBranch);
|
|
604
|
+
writeAgentState('idle', null);
|
|
605
|
+
log(`COMPLETED: ${task.task_id} (metric passed, attempt ${attempt})`);
|
|
606
|
+
return;
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
// Metric failed — log attempt, quick continuation (normal exit, just didn't pass)
|
|
610
|
+
const attemptRecord = {
|
|
611
|
+
approach: `Attempt ${attempt}: metric failed`,
|
|
612
|
+
result: metricResult.output.slice(-500),
|
|
613
|
+
keep: false,
|
|
614
|
+
};
|
|
615
|
+
attempts.push(attemptRecord);
|
|
616
|
+
await natsRequest('mesh.tasks.attempt', { task_id: task.task_id, ...attemptRecord });
|
|
617
|
+
log(`Attempt ${attempt}: metric failed. Quick retry (1s). Output: ${metricResult.output.slice(0, 200)}`);
|
|
618
|
+
await new Promise(r => setTimeout(r, 1000)); // two-tier: normal exit → 1s continuation
|
|
619
|
+
}
|
|
620
|
+
|
|
621
|
+
// All attempts exhausted or budget exceeded → RELEASE (not fail)
|
|
622
|
+
// "Released" = automation tried everything, human must triage.
|
|
623
|
+
// "Failed" = a single attempt failed (used by daemon for budget/stall).
|
|
624
|
+
// Commit whatever partial work exists — preserve for post-mortem
|
|
625
|
+
const partialResult = commitAndMergeWorktree(worktreePath, task.task_id, 'partial: released after exhausting attempts');
|
|
626
|
+
|
|
627
|
+
const reason = `Exhausted ${attempts.length}/${MAX_ATTEMPTS} attempts. Last: ${attempts[attempts.length - 1]?.result?.slice(0, 200) || 'unknown'}`;
|
|
628
|
+
await natsRequest('mesh.tasks.release', {
|
|
629
|
+
task_id: task.task_id,
|
|
630
|
+
reason,
|
|
631
|
+
attempts,
|
|
632
|
+
});
|
|
633
|
+
// Keep worktree branch on release for post-mortem debugging (don't merge partial work)
|
|
634
|
+
cleanupWorktree(worktreePath, true);
|
|
635
|
+
writeAgentState('idle', null);
|
|
636
|
+
log(`RELEASED: ${task.task_id} — ${reason}`);
|
|
637
|
+
}
|
|
638
|
+
|
|
639
|
+
// ── Main Loop ─────────────────────────────────────────
|
|
640
|
+
|
|
641
|
+
async function main() {
|
|
642
|
+
log(`Starting mesh agent worker`);
|
|
643
|
+
log(` Node ID: ${NODE_ID}`);
|
|
644
|
+
log(` NATS: ${NATS_URL}`);
|
|
645
|
+
log(` Model: ${MODEL}`);
|
|
646
|
+
log(` Workspace: ${WORKSPACE}`);
|
|
647
|
+
log(` Max attempts: ${MAX_ATTEMPTS}`);
|
|
648
|
+
log(` Poll interval: ${POLL_INTERVAL / 1000}s`);
|
|
649
|
+
log(` Mode: ${ONCE ? 'single task' : 'continuous'} ${DRY_RUN ? '(dry run)' : ''}`);
|
|
650
|
+
|
|
651
|
+
nc = await connect(natsConnectOpts({ timeout: 5000, reconnect: true, maxReconnectAttempts: -1, reconnectTimeWait: 5000 }));
|
|
652
|
+
log(`Connected to NATS`);
|
|
653
|
+
|
|
654
|
+
// Subscribe to alive-check requests from the daemon's stall detector
|
|
655
|
+
const aliveSub = nc.subscribe(`mesh.agent.${NODE_ID}.alive`);
|
|
656
|
+
(async () => {
|
|
657
|
+
for await (const msg of aliveSub) {
|
|
658
|
+
try {
|
|
659
|
+
const { task_id } = JSON.parse(sc.decode(msg.data));
|
|
660
|
+
const alive = currentTaskId != null && (task_id === currentTaskId || !task_id);
|
|
661
|
+
msg.respond(sc.encode(JSON.stringify({ alive, task_id: currentTaskId })));
|
|
662
|
+
log(`ALIVE CHECK: responded ${alive} (asked about ${task_id}, working on ${currentTaskId})`);
|
|
663
|
+
} catch {
|
|
664
|
+
msg.respond(sc.encode(JSON.stringify({ alive: currentTaskId != null, task_id: currentTaskId })));
|
|
665
|
+
}
|
|
666
|
+
}
|
|
667
|
+
})();
|
|
668
|
+
log(` Listening: mesh.agent.${NODE_ID}.alive`);
|
|
669
|
+
|
|
670
|
+
while (running) {
|
|
671
|
+
try {
|
|
672
|
+
// Claim next available task (longer timeout — KV operations on remote NATS can be slow)
|
|
673
|
+
const task = await natsRequest('mesh.tasks.claim', { node_id: NODE_ID }, 60000);
|
|
674
|
+
|
|
675
|
+
if (!task) {
|
|
676
|
+
if (ONCE) {
|
|
677
|
+
log('No tasks available. Exiting (--once mode).');
|
|
678
|
+
break;
|
|
679
|
+
}
|
|
680
|
+
// Wait and retry
|
|
681
|
+
await new Promise(r => setTimeout(r, POLL_INTERVAL));
|
|
682
|
+
continue;
|
|
683
|
+
}
|
|
684
|
+
|
|
685
|
+
log(`CLAIMED: ${task.task_id} "${task.title}"`);
|
|
686
|
+
|
|
687
|
+
// Execute the task
|
|
688
|
+
currentTaskId = task.task_id;
|
|
689
|
+
await executeTask(task);
|
|
690
|
+
currentTaskId = null;
|
|
691
|
+
|
|
692
|
+
} catch (err) {
|
|
693
|
+
log(`ERROR: ${err.message}`);
|
|
694
|
+
// Don't crash the loop — wait and retry
|
|
695
|
+
await new Promise(r => setTimeout(r, POLL_INTERVAL));
|
|
696
|
+
}
|
|
697
|
+
|
|
698
|
+
if (ONCE) break;
|
|
699
|
+
}
|
|
700
|
+
|
|
701
|
+
aliveSub.unsubscribe();
|
|
702
|
+
await nc.drain();
|
|
703
|
+
log('Agent worker stopped.');
|
|
704
|
+
}
|
|
705
|
+
|
|
706
|
+
// ── Shutdown ──────────────────────────────────────────
|
|
707
|
+
|
|
708
|
+
process.on('SIGINT', () => { running = false; log('Received SIGINT, finishing current task...'); });
|
|
709
|
+
process.on('SIGTERM', () => { running = false; log('Received SIGTERM, finishing current task...'); });
|
|
710
|
+
|
|
711
|
+
main().catch(err => {
|
|
712
|
+
console.error(`[mesh-agent] Fatal: ${err.message}`);
|
|
713
|
+
process.exit(1);
|
|
714
|
+
});
|