@agent-spaces/server 0.3.64 → 0.3.67
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/dist/adapters/agent-runtime.js +4 -0
- package/dist/adapters/claude-code-runtime/index.js +68 -2
- package/dist/adapters/claude-code-runtime/message-format.js +26 -0
- package/dist/adapters/claude-code-runtime/sdk-config.js +12 -0
- package/dist/adapters/codex-function-tool-bridge.js +144 -0
- package/dist/adapters/codex-runtime.js +23 -4
- package/dist/adapters/git.js +25 -7
- package/dist/adapters/hermes-runtime.js +210 -0
- package/dist/agents/agent-message-parts.js +1 -1
- package/dist/agents/commit-agent.js +4 -2
- package/dist/agents/issue-task-controller.js +75 -4
- package/dist/agents/pull-request-agent.js +115 -0
- package/dist/agents/scheduler-agent.js +1 -1
- package/dist/app.js +12 -70
- package/dist/middleware/auth.js +1 -1
- package/dist/package.json +2 -1
- package/dist/routes/agent-sse.js +2 -0
- package/dist/routes/agent.js +3 -0
- package/dist/routes/database.js +1 -0
- package/dist/routes/git.js +197 -317
- package/dist/routes/issue.js +1 -1
- package/dist/routes/notification.js +10 -0
- package/dist/routes/robot-account.js +68 -0
- package/dist/routes/version.js +94 -0
- package/dist/routes/worktree.js +93 -0
- package/dist/services/agent.js +37 -3
- package/dist/services/builtin-tools/kanban-tools.js +4 -0
- package/dist/services/git-operation-log.js +40 -0
- package/dist/services/global-wechat-qr.js +72 -0
- package/dist/services/hook-engine.js +175 -17
- package/dist/services/notification-center.js +9 -0
- package/dist/services/notification-hub/bot-agent.js +3 -1
- package/dist/services/notification-hub/service.js +12 -2
- package/dist/services/robot-account.js +34 -0
- package/dist/services/version.js +59 -0
- package/dist/services/workflow-command-runner.js +23 -0
- package/dist/services/workflow.js +25 -8
- package/dist/services/workspace.js +25 -1
- package/dist/services/worktree.js +207 -0
- package/dist/storage/robot-account-store.js +39 -0
- package/dist/storage/worktree-store.js +33 -0
- package/dist/web/404.html +1 -1
- package/dist/web/__next.__PAGE__.txt +4 -4
- package/dist/web/__next._full.txt +23 -25
- package/dist/web/__next._head.txt +4 -4
- package/dist/web/__next._index.txt +13 -13
- package/dist/web/__next._tree.txt +2 -2
- package/dist/web/_next/static/chunks/{0n6_4so_afuwk.js → 0-92u-tiuy40a.js} +4 -4
- package/dist/web/_next/static/chunks/{0vbqaynjq8ga..js → 0-yizd8osmas2.js} +1 -1
- package/dist/web/_next/static/chunks/0.ln~3mnv8.69.js +1 -0
- package/dist/web/_next/static/chunks/{0iuf30t0rjsjv.js → 01y3e9pemva7b.js} +10 -10
- package/dist/web/_next/static/chunks/02802taez976w.js +67 -0
- package/dist/web/_next/static/chunks/02l~tmzrgny.~.js +1 -0
- package/dist/web/_next/static/chunks/033.awk90g6eh.js +1 -0
- package/dist/web/_next/static/chunks/03f1bwuynjdmk.js +1 -0
- package/dist/web/_next/static/chunks/04cb4kc9r2pd1.js +1 -0
- package/dist/web/_next/static/chunks/04de6ha5_e3pp.js +1 -0
- package/dist/web/_next/static/chunks/06.kdsa9rr2h1.js +1 -0
- package/dist/web/_next/static/chunks/09he0p79ov1rn.js +1 -0
- package/dist/web/_next/static/chunks/09vpocs4zuc8h.js +1 -0
- package/dist/web/_next/static/chunks/0_o2exgr0e_nh.js +1 -0
- package/dist/web/_next/static/chunks/{0xbaakj0dfc0..js → 0_y9nskc-xt2k.js} +1 -1
- package/dist/web/_next/static/chunks/0clnj-1fi6u8j.js +3 -0
- package/dist/web/_next/static/chunks/0gv40by0zzxs_.js +1 -0
- package/dist/web/_next/static/chunks/0iusr8y88.kjg.js +1 -0
- package/dist/web/_next/static/chunks/{04a4vsq2wknm4.js → 0j-8418fxvkd1.js} +1 -1
- package/dist/web/_next/static/chunks/0j-l7l_k9jt45.js +1 -0
- package/dist/web/_next/static/chunks/0j.wxxyoclma5.js +1 -0
- package/dist/web/_next/static/chunks/0jq.16sozqik..js +3 -0
- package/dist/web/_next/static/chunks/0jw8xdk_fpnp0.css +1 -0
- package/dist/web/_next/static/chunks/0l1lkd-wcotma.js +1 -0
- package/dist/web/_next/static/chunks/0ncxf_zr4n839.js +1 -0
- package/dist/web/_next/static/chunks/0ndo7um~v7vco.js +1 -0
- package/dist/web/_next/static/chunks/0ngk.~kan8wq_.js +1 -0
- package/dist/web/_next/static/chunks/0p3h-h3zj5ujg.js +30 -0
- package/dist/web/_next/static/chunks/0pm-un~-sy3rl.js +1 -0
- package/dist/web/_next/static/chunks/0rt9bofnn6qvn.js +1 -0
- package/dist/web/_next/static/chunks/0t64.9jd00hio.js +3 -0
- package/dist/web/_next/static/chunks/0taui9--5n6-5.js +1 -0
- package/dist/web/_next/static/chunks/0ty39169lh~z3.js +1 -0
- package/dist/web/_next/static/chunks/0uxzi~9b~k4mn.js +31 -0
- package/dist/web/_next/static/chunks/0v8nof~waedlu.js +1 -0
- package/dist/web/_next/static/chunks/{0ctg5qmw7uu.1.js → 0vcfoagnpf.aw.js} +3 -3
- package/dist/web/_next/static/chunks/{08ckpwmmwlors.js → 0wwwq.gyyz0vg.js} +3 -3
- package/dist/web/_next/static/chunks/0x5lak8yz7pm7.js +1 -0
- package/dist/web/_next/static/chunks/0xon_.4-o0_zq.js +7 -0
- package/dist/web/_next/static/chunks/0zjnrbt7inime.js +1 -0
- package/dist/web/_next/static/chunks/0zncg76rgtbm-.js +1 -0
- package/dist/web/_next/static/chunks/0zwebpitvpuv1.js +1 -0
- package/dist/web/_next/static/chunks/0~02o4g-o6n~m.js +1 -0
- package/dist/web/_next/static/chunks/{10l-9myrdo3x9.js → 0~fjezp.k4qk3.js} +1 -1
- package/dist/web/_next/static/chunks/0~sh93re1-_rp.js +1 -0
- package/dist/web/_next/static/chunks/10_niiq0k6o-p.js +5 -0
- package/dist/web/_next/static/chunks/12tjr0_2ccrtq.js +2 -0
- package/dist/web/_next/static/chunks/12x5.go_x9mfk.js +1 -0
- package/dist/web/_next/static/chunks/{1442stwa0gbxe.js → 12~5dk9i9d16t.js} +2 -2
- package/dist/web/_next/static/chunks/13iye4rv5p31b.js +1 -0
- package/dist/web/_next/static/chunks/{01~quun6sefgl.js → 13~y-b.b9rrw4.js} +1 -1
- package/dist/web/_next/static/chunks/151wzhb5q0lo5.js +1 -0
- package/dist/web/_next/static/chunks/18c7g84y01mj0.js +1 -0
- package/dist/web/_next/static/chunks/{turbopack-0ndm2zc_pdptk.js → turbopack-11qjwlynmfc-n.js} +1 -1
- package/dist/web/_not-found/__next._full.txt +30 -29
- package/dist/web/_not-found/__next._head.txt +4 -4
- package/dist/web/_not-found/__next._index.txt +13 -13
- package/dist/web/_not-found/__next._not-found.__PAGE__.txt +2 -2
- package/dist/web/_not-found/__next._not-found.txt +3 -3
- package/dist/web/_not-found/__next._tree.txt +2 -2
- package/dist/web/_not-found.html +1 -1
- package/dist/web/_not-found.txt +30 -29
- package/dist/web/index.html +1 -1
- package/dist/web/index.txt +23 -25
- package/dist/web/login/__next._full.txt +28 -28
- package/dist/web/login/__next._head.txt +4 -4
- package/dist/web/login/__next._index.txt +13 -13
- package/dist/web/login/__next._tree.txt +2 -2
- package/dist/web/login/__next.login.__PAGE__.txt +4 -4
- package/dist/web/login/__next.login.txt +3 -3
- package/dist/web/login.html +1 -1
- package/dist/web/login.txt +28 -28
- package/dist/web/settings/__next._full.txt +33 -32
- package/dist/web/settings/__next._head.txt +4 -4
- package/dist/web/settings/__next._index.txt +13 -13
- package/dist/web/settings/__next._tree.txt +2 -2
- package/dist/web/settings/__next.settings.__PAGE__.txt +4 -4
- package/dist/web/settings/__next.settings.txt +5 -5
- package/dist/web/settings/agents/__next._full.txt +24 -24
- package/dist/web/settings/agents/__next._head.txt +4 -4
- package/dist/web/settings/agents/__next._index.txt +13 -13
- package/dist/web/settings/agents/__next._tree.txt +2 -2
- package/dist/web/settings/agents/__next.settings.agents.__PAGE__.txt +4 -4
- package/dist/web/settings/agents/__next.settings.agents.txt +3 -3
- package/dist/web/settings/agents/__next.settings.txt +5 -5
- package/dist/web/settings/agents.html +1 -1
- package/dist/web/settings/agents.txt +24 -24
- package/dist/web/settings/mcps/__next._full.txt +24 -24
- package/dist/web/settings/mcps/__next._head.txt +4 -4
- package/dist/web/settings/mcps/__next._index.txt +13 -13
- package/dist/web/settings/mcps/__next._tree.txt +2 -2
- package/dist/web/settings/mcps/__next.settings.mcps.__PAGE__.txt +4 -4
- package/dist/web/settings/mcps/__next.settings.mcps.txt +3 -3
- package/dist/web/settings/mcps/__next.settings.txt +5 -5
- package/dist/web/settings/mcps.html +1 -1
- package/dist/web/settings/mcps.txt +24 -24
- package/dist/web/settings/models/__next._full.txt +24 -24
- package/dist/web/settings/models/__next._head.txt +4 -4
- package/dist/web/settings/models/__next._index.txt +13 -13
- package/dist/web/settings/models/__next._tree.txt +2 -2
- package/dist/web/settings/models/__next.settings.models.__PAGE__.txt +4 -4
- package/dist/web/settings/models/__next.settings.models.txt +3 -3
- package/dist/web/settings/models/__next.settings.txt +5 -5
- package/dist/web/settings/models.html +1 -1
- package/dist/web/settings/models.txt +24 -24
- package/dist/web/settings/output-styles/__next._full.txt +24 -24
- package/dist/web/settings/output-styles/__next._head.txt +4 -4
- package/dist/web/settings/output-styles/__next._index.txt +13 -13
- package/dist/web/settings/output-styles/__next._tree.txt +2 -2
- package/dist/web/settings/output-styles/__next.settings.output-styles.__PAGE__.txt +4 -4
- package/dist/web/settings/output-styles/__next.settings.output-styles.txt +3 -3
- package/dist/web/settings/output-styles/__next.settings.txt +5 -5
- package/dist/web/settings/output-styles.html +1 -1
- package/dist/web/settings/output-styles.txt +24 -24
- package/dist/web/settings/prompts/__next._full.txt +24 -24
- package/dist/web/settings/prompts/__next._head.txt +4 -4
- package/dist/web/settings/prompts/__next._index.txt +13 -13
- package/dist/web/settings/prompts/__next._tree.txt +2 -2
- package/dist/web/settings/prompts/__next.settings.prompts.__PAGE__.txt +4 -4
- package/dist/web/settings/prompts/__next.settings.prompts.txt +3 -3
- package/dist/web/settings/prompts/__next.settings.txt +5 -5
- package/dist/web/settings/prompts.html +1 -1
- package/dist/web/settings/prompts.txt +24 -24
- package/dist/web/settings/providers/__next._full.txt +24 -24
- package/dist/web/settings/providers/__next._head.txt +4 -4
- package/dist/web/settings/providers/__next._index.txt +13 -13
- package/dist/web/settings/providers/__next._tree.txt +2 -2
- package/dist/web/settings/providers/__next.settings.providers.__PAGE__.txt +4 -4
- package/dist/web/settings/providers/__next.settings.providers.txt +3 -3
- package/dist/web/settings/providers/__next.settings.txt +5 -5
- package/dist/web/settings/providers.html +1 -1
- package/dist/web/settings/providers.txt +24 -24
- package/dist/web/settings/skills/__next._full.txt +24 -24
- package/dist/web/settings/skills/__next._head.txt +4 -4
- package/dist/web/settings/skills/__next._index.txt +13 -13
- package/dist/web/settings/skills/__next._tree.txt +2 -2
- package/dist/web/settings/skills/__next.settings.skills.__PAGE__.txt +4 -4
- package/dist/web/settings/skills/__next.settings.skills.txt +3 -3
- package/dist/web/settings/skills/__next.settings.txt +5 -5
- package/dist/web/settings/skills.html +1 -1
- package/dist/web/settings/skills.txt +24 -24
- package/dist/web/settings/tools/__next._full.txt +24 -24
- package/dist/web/settings/tools/__next._head.txt +4 -4
- package/dist/web/settings/tools/__next._index.txt +13 -13
- package/dist/web/settings/tools/__next._tree.txt +2 -2
- package/dist/web/settings/tools/__next.settings.tools.__PAGE__.txt +4 -4
- package/dist/web/settings/tools/__next.settings.tools.txt +3 -3
- package/dist/web/settings/tools/__next.settings.txt +5 -5
- package/dist/web/settings/tools.html +1 -1
- package/dist/web/settings/tools.txt +24 -24
- package/dist/web/settings.html +1 -1
- package/dist/web/settings.txt +33 -32
- package/dist/web/workflows/__next._full.txt +31 -33
- package/dist/web/workflows/__next._head.txt +4 -4
- package/dist/web/workflows/__next._index.txt +13 -13
- package/dist/web/workflows/__next._tree.txt +2 -2
- package/dist/web/workflows/__next.workflows.__PAGE__.txt +4 -4
- package/dist/web/workflows/__next.workflows.txt +3 -3
- package/dist/web/workflows.html +1 -1
- package/dist/web/workflows.txt +31 -33
- package/dist/web/workspace/_/__next._full.txt +28 -29
- package/dist/web/workspace/_/__next._head.txt +4 -4
- package/dist/web/workspace/_/__next._index.txt +13 -13
- package/dist/web/workspace/_/__next._tree.txt +2 -2
- package/dist/web/workspace/_/__next.workspace.$d$id.__PAGE__.txt +3 -3
- package/dist/web/workspace/_/__next.workspace.$d$id.txt +3 -3
- package/dist/web/workspace/_/__next.workspace.txt +3 -3
- package/dist/web/workspace/_.html +1 -1
- package/dist/web/workspace/_.txt +28 -29
- package/dist/web/workspaces/__next._full.txt +29 -31
- package/dist/web/workspaces/__next._head.txt +4 -4
- package/dist/web/workspaces/__next._index.txt +13 -13
- package/dist/web/workspaces/__next._tree.txt +2 -2
- package/dist/web/workspaces/__next.workspaces.__PAGE__.txt +4 -4
- package/dist/web/workspaces/__next.workspaces.txt +3 -3
- package/dist/web/workspaces.html +1 -1
- package/dist/web/workspaces.txt +29 -31
- package/dist/ws/agent-prompt.js +32 -3
- package/dist/ws/agent-runner.js +83 -6
- package/package.json +11 -11
- package/dist/web/_next/static/chunks/0-9194nbxy_6d.js +0 -1
- package/dist/web/_next/static/chunks/0.n~yfwf4~6w-.js +0 -1
- package/dist/web/_next/static/chunks/02mf61htij8g0.js +0 -31
- package/dist/web/_next/static/chunks/04dg4l4hv11q2.js +0 -3
- package/dist/web/_next/static/chunks/04fxddw-y20~-.js +0 -7
- package/dist/web/_next/static/chunks/04w7~5ooz_pwm.js +0 -1
- package/dist/web/_next/static/chunks/05oc21sj24wtq.js +0 -1
- package/dist/web/_next/static/chunks/08kfx8on9oty~.js +0 -1
- package/dist/web/_next/static/chunks/08k~meqbd8d6v.js +0 -1
- package/dist/web/_next/static/chunks/099h96wjsdb25.js +0 -2
- package/dist/web/_next/static/chunks/09h23logvq65m.js +0 -1
- package/dist/web/_next/static/chunks/0a5y-vhf4i5id.js +0 -3
- package/dist/web/_next/static/chunks/0ake2f3x2uan4.js +0 -24
- package/dist/web/_next/static/chunks/0ck8dw_9-1cdx.js +0 -1
- package/dist/web/_next/static/chunks/0ewceguykiut5.js +0 -1
- package/dist/web/_next/static/chunks/0f7cb9li~3jra.js +0 -67
- package/dist/web/_next/static/chunks/0ghs9on7wodrm.js +0 -1
- package/dist/web/_next/static/chunks/0ghx3j_.-gdyd.js +0 -1
- package/dist/web/_next/static/chunks/0h9cu-k6z5o08.js +0 -1
- package/dist/web/_next/static/chunks/0jb4~3qqkw2ps.js +0 -1
- package/dist/web/_next/static/chunks/0nb8.iteznuvx.js +0 -1
- package/dist/web/_next/static/chunks/0os58q93stt7j.js +0 -3
- package/dist/web/_next/static/chunks/0s9lmk8iauou3.js +0 -1
- package/dist/web/_next/static/chunks/0sp_zbx~w0am7.js +0 -1
- package/dist/web/_next/static/chunks/0tel~zsv4z8l_.js +0 -1
- package/dist/web/_next/static/chunks/0twamv4wr_dbv.js +0 -1
- package/dist/web/_next/static/chunks/0uhol5wafdbl~.js +0 -1
- package/dist/web/_next/static/chunks/0v3a_x4vt42kx.js +0 -5
- package/dist/web/_next/static/chunks/0v7q4mys.mnm..css +0 -1
- package/dist/web/_next/static/chunks/0xt-8wk21gs7g.js +0 -1
- package/dist/web/_next/static/chunks/0z~vqzbm_q371.js +0 -1
- package/dist/web/_next/static/chunks/0~3xm80~j9ddg.js +0 -1
- package/dist/web/_next/static/chunks/14s37n6h0_q3x.js +0 -16
- package/dist/web/_next/static/chunks/161ik5kfyuwtd.js +0 -1
- package/dist/web/_next/static/chunks/17k~zbv0_4rep.js +0 -1
- package/public/output-styles/carmack-mode.md +0 -381
- package/public/output-styles/codex-rigor-mode.md +0 -114
- package/public/output-styles/dhh-mode.md +0 -265
- package/public/output-styles/evan-you-mode.md +0 -539
- package/public/output-styles/index.json +0 -37
- package/public/output-styles/jobs-mode.md +0 -369
- package/public/output-styles/linus-mode.md +0 -135
- package/public/output-styles/uncle-bob-mode.md +0 -221
- package/public/prompt/andrej-karpathy-skills.md +0 -65
- package/public/prompt/claude-token-efficient-coding.md +0 -35
- package/public/prompt/index.json +0 -12
- package/public/skills/index.json +0 -92
- package/public/skills/planning-with-files/planning-with-files-zh/SKILL.md +0 -243
- package/public/skills/planning-with-files/planning-with-files-zh/scripts/check-complete.ps1 +0 -44
- package/public/skills/planning-with-files/planning-with-files-zh/scripts/check-complete.sh +0 -46
- package/public/skills/planning-with-files/planning-with-files-zh/scripts/init-session.ps1 +0 -124
- package/public/skills/planning-with-files/planning-with-files-zh/scripts/init-session.sh +0 -124
- package/public/skills/planning-with-files/planning-with-files-zh/scripts/session-catchup.py +0 -438
- package/public/skills/planning-with-files/planning-with-files-zh/templates/findings.md +0 -29
- package/public/skills/planning-with-files/planning-with-files-zh/templates/progress.md +0 -40
- package/public/skills/planning-with-files/planning-with-files-zh/templates/task_plan.md +0 -58
- package/public/skills/superpowers/brainstorming/SKILL.md +0 -164
- package/public/skills/superpowers/brainstorming/scripts/frame-template.html +0 -214
- package/public/skills/superpowers/brainstorming/scripts/helper.js +0 -88
- package/public/skills/superpowers/brainstorming/scripts/server.cjs +0 -354
- package/public/skills/superpowers/brainstorming/scripts/start-server.sh +0 -148
- package/public/skills/superpowers/brainstorming/scripts/stop-server.sh +0 -56
- package/public/skills/superpowers/brainstorming/spec-document-reviewer-prompt.md +0 -49
- package/public/skills/superpowers/brainstorming/visual-companion.md +0 -287
- package/public/skills/superpowers/dispatching-parallel-agents/SKILL.md +0 -182
- package/public/skills/superpowers/executing-plans/SKILL.md +0 -70
- package/public/skills/superpowers/finishing-a-development-branch/SKILL.md +0 -251
- package/public/skills/superpowers/receiving-code-review/SKILL.md +0 -213
- package/public/skills/superpowers/requesting-code-review/SKILL.md +0 -103
- package/public/skills/superpowers/requesting-code-review/code-reviewer.md +0 -168
- package/public/skills/superpowers/subagent-driven-development/SKILL.md +0 -279
- package/public/skills/superpowers/subagent-driven-development/code-quality-reviewer-prompt.md +0 -25
- package/public/skills/superpowers/subagent-driven-development/implementer-prompt.md +0 -113
- package/public/skills/superpowers/subagent-driven-development/spec-reviewer-prompt.md +0 -61
- package/public/skills/superpowers/systematic-debugging/CREATION-LOG.md +0 -119
- package/public/skills/superpowers/systematic-debugging/SKILL.md +0 -296
- package/public/skills/superpowers/systematic-debugging/condition-based-waiting-example.ts +0 -158
- package/public/skills/superpowers/systematic-debugging/condition-based-waiting.md +0 -115
- package/public/skills/superpowers/systematic-debugging/defense-in-depth.md +0 -122
- package/public/skills/superpowers/systematic-debugging/find-polluter.sh +0 -63
- package/public/skills/superpowers/systematic-debugging/root-cause-tracing.md +0 -169
- package/public/skills/superpowers/systematic-debugging/test-academic.md +0 -14
- package/public/skills/superpowers/systematic-debugging/test-pressure-1.md +0 -58
- package/public/skills/superpowers/systematic-debugging/test-pressure-2.md +0 -68
- package/public/skills/superpowers/systematic-debugging/test-pressure-3.md +0 -69
- package/public/skills/superpowers/test-driven-development/SKILL.md +0 -371
- package/public/skills/superpowers/test-driven-development/testing-anti-patterns.md +0 -299
- package/public/skills/superpowers/using-git-worktrees/SKILL.md +0 -215
- package/public/skills/superpowers/using-superpowers/SKILL.md +0 -117
- package/public/skills/superpowers/using-superpowers/references/codex-tools.md +0 -59
- package/public/skills/superpowers/using-superpowers/references/copilot-tools.md +0 -42
- package/public/skills/superpowers/using-superpowers/references/gemini-tools.md +0 -51
- package/public/skills/superpowers/verification-before-completion/SKILL.md +0 -139
- package/public/skills/superpowers/writing-plans/SKILL.md +0 -152
- package/public/skills/superpowers/writing-plans/plan-document-reviewer-prompt.md +0 -49
- package/public/skills/superpowers/writing-skills/SKILL.md +0 -655
- package/public/skills/superpowers/writing-skills/anthropic-best-practices.md +0 -1150
- package/public/skills/superpowers/writing-skills/examples/CLAUDE_MD_TESTING.md +0 -189
- package/public/skills/superpowers/writing-skills/graphviz-conventions.dot +0 -172
- package/public/skills/superpowers/writing-skills/persuasion-principles.md +0 -187
- package/public/skills/superpowers/writing-skills/render-graphs.js +0 -168
- package/public/skills/superpowers/writing-skills/testing-skills-with-subagents.md +0 -384
- /package/dist/web/_next/static/{e8w3vd9Eov_LDYWj_0zsE → rGXyAK8rgod1NjF3bLZAY}/_buildManifest.js +0 -0
- /package/dist/web/_next/static/{e8w3vd9Eov_LDYWj_0zsE → rGXyAK8rgod1NjF3bLZAY}/_clientMiddlewareManifest.js +0 -0
- /package/dist/web/_next/static/{e8w3vd9Eov_LDYWj_0zsE → rGXyAK8rgod1NjF3bLZAY}/_ssgManifest.js +0 -0
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
import { exec } from 'node:child_process';
|
|
2
2
|
import { listHooks } from '../storage/hook-store.js';
|
|
3
|
+
function logDebug(message, details) {
|
|
4
|
+
if (details) {
|
|
5
|
+
console.debug(`[HookEngine] ${message}`, details);
|
|
6
|
+
return;
|
|
7
|
+
}
|
|
8
|
+
console.debug(`[HookEngine] ${message}`);
|
|
9
|
+
}
|
|
3
10
|
function matchToolName(matcher, toolName) {
|
|
4
11
|
if (matcher === '*')
|
|
5
12
|
return true;
|
|
@@ -8,7 +15,12 @@ function matchToolName(matcher, toolName) {
|
|
|
8
15
|
const regex = new RegExp(matcher.slice(1, -1));
|
|
9
16
|
return regex.test(toolName);
|
|
10
17
|
}
|
|
11
|
-
catch {
|
|
18
|
+
catch (error) {
|
|
19
|
+
console.warn(`[HookEngine] invalid matcher regex, falling back to exact match`, {
|
|
20
|
+
matcher,
|
|
21
|
+
toolName,
|
|
22
|
+
error: error.message,
|
|
23
|
+
});
|
|
12
24
|
return matcher === toolName;
|
|
13
25
|
}
|
|
14
26
|
}
|
|
@@ -16,7 +28,8 @@ function matchToolName(matcher, toolName) {
|
|
|
16
28
|
}
|
|
17
29
|
function executeCommand(command, env, timeout) {
|
|
18
30
|
return new Promise((resolve) => {
|
|
19
|
-
|
|
31
|
+
const cappedTimeout = Math.min(timeout, 30000);
|
|
32
|
+
exec(command, { env: { ...process.env, ...env }, timeout: cappedTimeout }, (error) => {
|
|
20
33
|
if (error)
|
|
21
34
|
console.warn(`[HookEngine] command error: ${error.message}`);
|
|
22
35
|
resolve();
|
|
@@ -26,43 +39,101 @@ function executeCommand(command, env, timeout) {
|
|
|
26
39
|
async function executeWebhook(url, body, timeout) {
|
|
27
40
|
try {
|
|
28
41
|
const controller = new AbortController();
|
|
29
|
-
const
|
|
30
|
-
|
|
42
|
+
const cappedTimeout = Math.min(timeout, 30000);
|
|
43
|
+
const timer = setTimeout(() => controller.abort(), cappedTimeout);
|
|
44
|
+
const response = await fetch(url, {
|
|
31
45
|
method: 'POST',
|
|
32
46
|
headers: { 'Content-Type': 'application/json' },
|
|
33
47
|
body: JSON.stringify(body),
|
|
34
48
|
signal: controller.signal,
|
|
35
49
|
});
|
|
36
50
|
clearTimeout(timer);
|
|
51
|
+
if (!response.ok) {
|
|
52
|
+
console.warn(`[HookEngine] webhook non-2xx response`, {
|
|
53
|
+
url,
|
|
54
|
+
status: response.status,
|
|
55
|
+
statusText: response.statusText,
|
|
56
|
+
});
|
|
57
|
+
}
|
|
37
58
|
}
|
|
38
59
|
catch (error) {
|
|
39
60
|
console.warn(`[HookEngine] webhook error: ${error.message}`);
|
|
40
61
|
}
|
|
41
62
|
}
|
|
42
|
-
async function executeRule(rule, phase,
|
|
63
|
+
async function executeRule(rule, phase, matcherValue, workspaceId, context, hookName) {
|
|
43
64
|
const timeout = rule.timeout ?? 10000;
|
|
65
|
+
const startedAt = Date.now();
|
|
66
|
+
logDebug('rule start', {
|
|
67
|
+
workspaceId,
|
|
68
|
+
phase,
|
|
69
|
+
hookName,
|
|
70
|
+
matcherValue,
|
|
71
|
+
matcher: rule.matcher,
|
|
72
|
+
type: rule.type,
|
|
73
|
+
timeout,
|
|
74
|
+
});
|
|
44
75
|
if (rule.type === 'command' && rule.command) {
|
|
45
76
|
await executeCommand(rule.command, {
|
|
46
|
-
|
|
77
|
+
HOOK_NAME: hookName ?? '',
|
|
78
|
+
HOOK_RULE_MATCHER: rule.matcher,
|
|
79
|
+
HOOK_RULE_TYPE: rule.type,
|
|
80
|
+
HOOK_RULE_TIMEOUT: String(timeout),
|
|
81
|
+
HOOK_EVENT_NAME: context.eventName ?? phase,
|
|
82
|
+
HOOK_EVENT_PAYLOAD: JSON.stringify(context.eventPayload ?? {}),
|
|
83
|
+
HOOK_MATCHER_VALUE: matcherValue,
|
|
84
|
+
HOOK_TOOL_NAME: matcherValue,
|
|
85
|
+
HOOK_TOOL_USE_ID: context.toolUseId ?? '',
|
|
47
86
|
HOOK_TOOL_INPUT: JSON.stringify(context.toolInput ?? {}),
|
|
48
87
|
HOOK_TOOL_RESULT: JSON.stringify(context.toolResult ?? ''),
|
|
49
88
|
HOOK_WORKSPACE_ID: workspaceId,
|
|
50
89
|
HOOK_PHASE: phase,
|
|
90
|
+
HOOK_TRIGGER_CHECKED_RULES: String(context.checkedRules ?? ''),
|
|
91
|
+
HOOK_TRIGGER_MATCHED_RULES: String(context.matchedRules ?? ''),
|
|
92
|
+
HOOK_TRIGGERED_AT: new Date().toISOString(),
|
|
51
93
|
}, timeout);
|
|
52
94
|
}
|
|
53
95
|
else if (rule.type === 'webhook' && rule.url) {
|
|
54
96
|
await executeWebhook(rule.url, {
|
|
55
97
|
event: phase,
|
|
56
|
-
toolName,
|
|
98
|
+
toolName: matcherValue,
|
|
99
|
+
matcherValue,
|
|
57
100
|
toolInput: context.toolInput,
|
|
58
101
|
toolResult: context.toolResult ?? undefined,
|
|
102
|
+
payload: context.eventPayload,
|
|
59
103
|
timestamp: new Date().toISOString(),
|
|
60
104
|
workspaceId,
|
|
61
105
|
}, timeout);
|
|
62
106
|
}
|
|
63
107
|
else if (rule.type === 'script') {
|
|
64
|
-
console.warn(`[HookEngine] script type not implemented, skipping rule
|
|
108
|
+
console.warn(`[HookEngine] script type not implemented, skipping rule`, {
|
|
109
|
+
workspaceId,
|
|
110
|
+
phase,
|
|
111
|
+
hookName,
|
|
112
|
+
matcherValue,
|
|
113
|
+
matcher: rule.matcher,
|
|
114
|
+
});
|
|
65
115
|
}
|
|
116
|
+
else {
|
|
117
|
+
console.warn(`[HookEngine] invalid rule configuration, skipping rule`, {
|
|
118
|
+
workspaceId,
|
|
119
|
+
phase,
|
|
120
|
+
hookName,
|
|
121
|
+
matcherValue,
|
|
122
|
+
matcher: rule.matcher,
|
|
123
|
+
type: rule.type,
|
|
124
|
+
hasCommand: Boolean(rule.command),
|
|
125
|
+
hasUrl: Boolean(rule.url),
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
logDebug('rule finished', {
|
|
129
|
+
workspaceId,
|
|
130
|
+
phase,
|
|
131
|
+
hookName,
|
|
132
|
+
matcherValue,
|
|
133
|
+
matcher: rule.matcher,
|
|
134
|
+
type: rule.type,
|
|
135
|
+
durationMs: Date.now() - startedAt,
|
|
136
|
+
});
|
|
66
137
|
}
|
|
67
138
|
export class HookEngine {
|
|
68
139
|
hooks = [];
|
|
@@ -72,6 +143,12 @@ export class HookEngine {
|
|
|
72
143
|
}
|
|
73
144
|
load() {
|
|
74
145
|
this.hooks = listHooks(this.workspaceId);
|
|
146
|
+
logDebug('loaded hooks', {
|
|
147
|
+
workspaceId: this.workspaceId,
|
|
148
|
+
totalHooks: this.hooks.length,
|
|
149
|
+
enabledHooks: this.hooks.filter(h => h.enabled).length,
|
|
150
|
+
hookNames: this.hooks.map(h => h.name),
|
|
151
|
+
});
|
|
75
152
|
}
|
|
76
153
|
reload() {
|
|
77
154
|
this.load();
|
|
@@ -79,40 +156,121 @@ export class HookEngine {
|
|
|
79
156
|
getHooks() {
|
|
80
157
|
return this.hooks;
|
|
81
158
|
}
|
|
82
|
-
async executeHooks(phase,
|
|
159
|
+
async executeHooks(phase, matcherValue, context) {
|
|
83
160
|
const enabledHooks = this.hooks.filter(h => h.enabled);
|
|
84
161
|
const promises = [];
|
|
162
|
+
const matchedRuleEntries = [];
|
|
163
|
+
let checkedRules = 0;
|
|
164
|
+
let matchedRules = 0;
|
|
165
|
+
logDebug('trigger received', {
|
|
166
|
+
workspaceId: this.workspaceId,
|
|
167
|
+
phase,
|
|
168
|
+
matcherValue,
|
|
169
|
+
totalHooks: this.hooks.length,
|
|
170
|
+
enabledHooks: enabledHooks.length,
|
|
171
|
+
hasToolInput: context.toolInput !== undefined,
|
|
172
|
+
hasToolResult: context.toolResult !== undefined,
|
|
173
|
+
});
|
|
85
174
|
for (const hook of enabledHooks) {
|
|
86
175
|
const rules = hook.hooks[phase];
|
|
87
176
|
if (!rules)
|
|
88
177
|
continue;
|
|
89
178
|
for (const rule of rules) {
|
|
90
|
-
|
|
91
|
-
|
|
179
|
+
checkedRules += 1;
|
|
180
|
+
if (matchToolName(rule.matcher, matcherValue)) {
|
|
181
|
+
matchedRules += 1;
|
|
182
|
+
logDebug('rule matched', {
|
|
183
|
+
workspaceId: this.workspaceId,
|
|
184
|
+
phase,
|
|
185
|
+
hookName: hook.name,
|
|
186
|
+
matcherValue,
|
|
187
|
+
matcher: rule.matcher,
|
|
188
|
+
type: rule.type,
|
|
189
|
+
});
|
|
190
|
+
matchedRuleEntries.push({ hookName: hook.name, rule });
|
|
92
191
|
}
|
|
93
192
|
}
|
|
94
193
|
}
|
|
95
|
-
|
|
194
|
+
for (const { hookName, rule } of matchedRuleEntries) {
|
|
195
|
+
promises.push(executeRule(rule, phase, matcherValue, this.workspaceId, {
|
|
196
|
+
...context,
|
|
197
|
+
checkedRules,
|
|
198
|
+
matchedRules,
|
|
199
|
+
}, hookName));
|
|
200
|
+
}
|
|
201
|
+
const results = await Promise.allSettled(promises);
|
|
202
|
+
const rejectedRules = results.filter(result => result.status === 'rejected').length;
|
|
203
|
+
logDebug('trigger finished', {
|
|
204
|
+
workspaceId: this.workspaceId,
|
|
205
|
+
phase,
|
|
206
|
+
matcherValue,
|
|
207
|
+
checkedRules,
|
|
208
|
+
matchedRules,
|
|
209
|
+
rejectedRules,
|
|
210
|
+
});
|
|
96
211
|
}
|
|
97
212
|
}
|
|
98
213
|
export function wrapOnEventWithHooks(onEvent, workspaceId, hooksEnabled) {
|
|
99
|
-
if (!hooksEnabled)
|
|
214
|
+
if (!hooksEnabled) {
|
|
215
|
+
logDebug('hooks disabled for workspace', { workspaceId });
|
|
100
216
|
return onEvent;
|
|
217
|
+
}
|
|
101
218
|
const engine = new HookEngine(workspaceId);
|
|
102
219
|
engine.load();
|
|
103
220
|
const toolNameById = new Map();
|
|
221
|
+
let lastToolUse = null;
|
|
104
222
|
return (event) => {
|
|
105
|
-
|
|
223
|
+
if (event.type !== 'hook_event')
|
|
224
|
+
onEvent(event);
|
|
106
225
|
if (event.type === 'tool_use') {
|
|
107
226
|
toolNameById.set(event.id, event.name);
|
|
108
|
-
|
|
227
|
+
lastToolUse = { id: event.id, name: event.name };
|
|
228
|
+
logDebug('tool_use event mapped', {
|
|
229
|
+
workspaceId,
|
|
230
|
+
toolUseId: event.id,
|
|
231
|
+
toolName: event.name,
|
|
232
|
+
});
|
|
233
|
+
engine.executeHooks('PreToolUse', event.name, { toolInput: event.input, toolUseId: event.id });
|
|
109
234
|
}
|
|
110
235
|
if (event.type === 'tool_result') {
|
|
111
|
-
const
|
|
236
|
+
const resolvedToolUseId = event.toolUseId || lastToolUse?.id;
|
|
237
|
+
const toolName = resolvedToolUseId ? (toolNameById.get(resolvedToolUseId) ?? '') : '';
|
|
112
238
|
if (toolName) {
|
|
113
|
-
|
|
239
|
+
logDebug('tool_result event resolved', {
|
|
240
|
+
workspaceId,
|
|
241
|
+
toolUseId: resolvedToolUseId,
|
|
242
|
+
originalToolUseId: event.toolUseId,
|
|
243
|
+
toolName,
|
|
244
|
+
});
|
|
245
|
+
engine.executeHooks('PostToolUse', toolName, { toolResult: event.result, toolUseId: resolvedToolUseId });
|
|
246
|
+
if (isToolFailureResult(event.result)) {
|
|
247
|
+
engine.executeHooks('PostToolUseFailure', toolName, { toolResult: event.result, toolUseId: resolvedToolUseId });
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
else {
|
|
251
|
+
logDebug('tool_result event skipped without matching tool_use', {
|
|
252
|
+
workspaceId,
|
|
253
|
+
toolUseId: event.toolUseId,
|
|
254
|
+
});
|
|
114
255
|
}
|
|
115
256
|
}
|
|
257
|
+
if (event.type === 'hook_event') {
|
|
258
|
+
logDebug('hook_event received', {
|
|
259
|
+
workspaceId,
|
|
260
|
+
event: event.event,
|
|
261
|
+
matcher: event.matcher ?? '*',
|
|
262
|
+
});
|
|
263
|
+
engine.executeHooks(event.event, event.matcher ?? '*', {
|
|
264
|
+
eventName: event.event,
|
|
265
|
+
eventPayload: event.payload,
|
|
266
|
+
});
|
|
267
|
+
}
|
|
116
268
|
};
|
|
117
269
|
}
|
|
270
|
+
function isToolFailureResult(result) {
|
|
271
|
+
if (!result || typeof result !== 'object')
|
|
272
|
+
return false;
|
|
273
|
+
const record = result;
|
|
274
|
+
return record.error !== undefined || record.is_error === true || record.success === false;
|
|
275
|
+
}
|
|
118
276
|
//# sourceMappingURL=hook-engine.js.map
|
|
@@ -46,6 +46,15 @@ export function clearAll(workspaceId) {
|
|
|
46
46
|
writeAll(workspaceId, []);
|
|
47
47
|
broadcastToWorkspace(workspaceId, 'notification.cleared', null);
|
|
48
48
|
}
|
|
49
|
+
export function removeNotification(workspaceId, notificationId) {
|
|
50
|
+
const all = readAll(workspaceId);
|
|
51
|
+
const idx = all.findIndex((n) => n.id === notificationId);
|
|
52
|
+
if (idx === -1)
|
|
53
|
+
return null;
|
|
54
|
+
const [removed] = all.splice(idx, 1);
|
|
55
|
+
writeAll(workspaceId, all);
|
|
56
|
+
return removed;
|
|
57
|
+
}
|
|
49
58
|
export function unreadCount(workspaceId) {
|
|
50
59
|
return readAll(workspaceId).filter((n) => !n.read).length;
|
|
51
60
|
}
|
|
@@ -28,7 +28,8 @@ export async function runBotAgent(workspaceId, preset, message) {
|
|
|
28
28
|
const workingDir = agentService.resolveWorkingDir(workspaceId, preset);
|
|
29
29
|
const workspace = workspaceService.getById(workspaceId);
|
|
30
30
|
try {
|
|
31
|
-
const
|
|
31
|
+
const userPrompt = buildBotPrompt(message);
|
|
32
|
+
const result = await runtime.execute(prependPersistentAgentContext(userPrompt, {
|
|
32
33
|
workspaceId,
|
|
33
34
|
workingDir,
|
|
34
35
|
boundDirs: workspace?.boundDirs,
|
|
@@ -36,6 +37,7 @@ export async function runBotAgent(workspaceId, preset, message) {
|
|
|
36
37
|
excludeNativeClaudeMd: preset.runtimeKind === 'claude-code',
|
|
37
38
|
}), workingDir, {
|
|
38
39
|
maxTurns: 20,
|
|
40
|
+
userPrompt,
|
|
39
41
|
mcpServers: agentService.getMcpServers(preset.mcps),
|
|
40
42
|
skills: agentService.getAvailableSkillNames(agentService.getAgentConfigDir(workspaceId, preset), preset.skills),
|
|
41
43
|
configDir: agentService.getAgentConfigDir(workspaceId, preset),
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import * as workspaceService from '../workspace.js';
|
|
2
|
+
import { resolveCredentials } from '../robot-account.js';
|
|
2
3
|
import { adapters } from './types.js';
|
|
3
4
|
import { persistServiceRunning } from './helpers.js';
|
|
4
5
|
import { WeChatNotificationAdapter } from './wechat-adapter.js';
|
|
@@ -9,15 +10,24 @@ export async function startWorkspaceNotificationService(workspaceId) {
|
|
|
9
10
|
if (!workspace || !settings?.enabled)
|
|
10
11
|
return { started: false };
|
|
11
12
|
await stopWorkspaceNotificationService(workspaceId);
|
|
13
|
+
const credentials = resolveCredentials(settings);
|
|
12
14
|
if (settings.provider === 'lark') {
|
|
13
|
-
|
|
15
|
+
if (!credentials || credentials.type !== 'lark') {
|
|
16
|
+
throw new Error('Lark credentials not found. Link a Robot Account or configure appId/appSecret.');
|
|
17
|
+
}
|
|
18
|
+
const mergedSettings = { ...settings, lark: { ...settings.lark, appId: credentials.appId, appSecret: credentials.appSecret } };
|
|
19
|
+
const adapter = new LarkNotificationAdapter(workspace, mergedSettings);
|
|
14
20
|
await adapter.start();
|
|
15
21
|
adapters.set(workspaceId, adapter);
|
|
16
22
|
persistServiceRunning(workspaceId, true);
|
|
17
23
|
return { started: true, provider: 'lark' };
|
|
18
24
|
}
|
|
19
25
|
if (settings.provider === 'wechat') {
|
|
20
|
-
|
|
26
|
+
if (!credentials || credentials.type !== 'wechat') {
|
|
27
|
+
throw new Error('WeChat credentials not found. Link a Robot Account or scan QR code first.');
|
|
28
|
+
}
|
|
29
|
+
const mergedSettings = { ...settings, wechat: { ...settings.wechat, token: credentials.token, baseUrl: credentials.baseUrl, accountId: credentials.accountId, userId: credentials.userId } };
|
|
30
|
+
const adapter = new WeChatNotificationAdapter(workspace, mergedSettings);
|
|
21
31
|
await adapter.start();
|
|
22
32
|
adapters.set(workspaceId, adapter);
|
|
23
33
|
persistServiceRunning(workspaceId, true);
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { v4 as uuid } from 'uuid';
|
|
2
|
+
import { listRobotAccounts, getRobotAccount, createRobotAccount, updateRobotAccount, deleteRobotAccount } from '../storage/robot-account-store.js';
|
|
3
|
+
export { listRobotAccounts, getRobotAccount, deleteRobotAccount };
|
|
4
|
+
export function createAccount(input) {
|
|
5
|
+
const now = new Date().toISOString();
|
|
6
|
+
const account = { id: uuid(), name: input.name, type: input.type, lark: input.lark, wechat: input.wechat, createdAt: now, updatedAt: now };
|
|
7
|
+
createRobotAccount(account);
|
|
8
|
+
return account;
|
|
9
|
+
}
|
|
10
|
+
export function updateAccount(id, patch) {
|
|
11
|
+
return updateRobotAccount(id, patch);
|
|
12
|
+
}
|
|
13
|
+
export function resolveCredentials(settings) {
|
|
14
|
+
if (settings.robotAccountId) {
|
|
15
|
+
const account = getRobotAccount(settings.robotAccountId);
|
|
16
|
+
if (account) {
|
|
17
|
+
if (account.type === 'lark' && account.lark) {
|
|
18
|
+
return { type: 'lark', appId: account.lark.appId, appSecret: account.lark.appSecret };
|
|
19
|
+
}
|
|
20
|
+
if (account.type === 'wechat' && account.wechat) {
|
|
21
|
+
return { type: 'wechat', token: account.wechat.token, baseUrl: account.wechat.baseUrl || 'https://qyapi.weixin.qq.com', accountId: account.wechat.accountId, userId: account.wechat.userId };
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
// fallback to inline credentials
|
|
26
|
+
if (settings.provider === 'lark' && settings.lark?.appId && settings.lark?.appSecret) {
|
|
27
|
+
return { type: 'lark', appId: settings.lark.appId, appSecret: settings.lark.appSecret };
|
|
28
|
+
}
|
|
29
|
+
if (settings.provider === 'wechat' && settings.wechat?.token && settings.wechat?.accountId) {
|
|
30
|
+
return { type: 'wechat', token: settings.wechat.token, baseUrl: settings.wechat.baseUrl || 'https://qyapi.weixin.qq.com', accountId: settings.wechat.accountId, userId: settings.wechat.userId };
|
|
31
|
+
}
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=robot-account.js.map
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs';
|
|
2
|
+
import { join, dirname } from 'node:path';
|
|
3
|
+
import { fileURLToPath } from 'node:url';
|
|
4
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
5
|
+
let localVersion = '';
|
|
6
|
+
let cachedLatest = null;
|
|
7
|
+
const CACHE_TTL = 3600_000; // 1 hour
|
|
8
|
+
export function getLocalVersion() {
|
|
9
|
+
if (localVersion !== '')
|
|
10
|
+
return localVersion;
|
|
11
|
+
try {
|
|
12
|
+
const pkg = JSON.parse(readFileSync(join(__dirname, '..', 'package.json'), 'utf-8'));
|
|
13
|
+
localVersion = pkg.version || '0.0.0';
|
|
14
|
+
}
|
|
15
|
+
catch {
|
|
16
|
+
localVersion = '0.0.0';
|
|
17
|
+
}
|
|
18
|
+
return localVersion;
|
|
19
|
+
}
|
|
20
|
+
export function getCachedLatest() {
|
|
21
|
+
if (cachedLatest && Date.now() - cachedLatest.ts < CACHE_TTL) {
|
|
22
|
+
return cachedLatest.version;
|
|
23
|
+
}
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
export async function fetchLatestVersion(forceRefresh = false) {
|
|
27
|
+
if (!forceRefresh && cachedLatest && Date.now() - cachedLatest.ts < CACHE_TTL) {
|
|
28
|
+
return cachedLatest.version;
|
|
29
|
+
}
|
|
30
|
+
try {
|
|
31
|
+
const res = await fetch('https://registry.npmjs.org/@agent-spaces/server', {
|
|
32
|
+
signal: AbortSignal.timeout(8000),
|
|
33
|
+
});
|
|
34
|
+
if (!res.ok)
|
|
35
|
+
return cachedLatest?.version ?? null;
|
|
36
|
+
const data = await res.json();
|
|
37
|
+
const latest = data?.['dist-tags']?.latest;
|
|
38
|
+
if (latest) {
|
|
39
|
+
cachedLatest = { version: latest, ts: Date.now() };
|
|
40
|
+
}
|
|
41
|
+
return latest ?? cachedLatest?.version ?? null;
|
|
42
|
+
}
|
|
43
|
+
catch {
|
|
44
|
+
return cachedLatest?.version ?? null;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
export function isNewerVersion(latest, local) {
|
|
48
|
+
const parse = (v) => v.replace(/^v/, '').split('.').map(Number);
|
|
49
|
+
const a = parse(latest);
|
|
50
|
+
const b = parse(local);
|
|
51
|
+
for (let i = 0; i < 3; i++) {
|
|
52
|
+
if ((a[i] || 0) > (b[i] || 0))
|
|
53
|
+
return true;
|
|
54
|
+
if ((a[i] || 0) < (b[i] || 0))
|
|
55
|
+
return false;
|
|
56
|
+
}
|
|
57
|
+
return false;
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=version.js.map
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { exec } from 'child_process';
|
|
2
|
+
import { getWorkspace } from '../storage/workspace-store.js';
|
|
3
|
+
export async function executeCommandNode(workspaceId, node) {
|
|
4
|
+
const workspace = getWorkspace(workspaceId);
|
|
5
|
+
const cwd = node.data.cwd || workspace?.boundDirs?.[0] || process.cwd();
|
|
6
|
+
return new Promise((resolve) => {
|
|
7
|
+
exec(node.data.script, {
|
|
8
|
+
cwd,
|
|
9
|
+
env: { ...process.env, ...node.data.env },
|
|
10
|
+
shell: node.data.shell || undefined,
|
|
11
|
+
timeout: 300_000,
|
|
12
|
+
maxBuffer: 10 * 1024 * 1024,
|
|
13
|
+
}, (error, stdout, stderr) => {
|
|
14
|
+
resolve({
|
|
15
|
+
success: !error,
|
|
16
|
+
exitCode: error ? (typeof error.code === 'number' ? error.code : 1) : 0,
|
|
17
|
+
stdout: stdout || '',
|
|
18
|
+
stderr: stderr || '',
|
|
19
|
+
});
|
|
20
|
+
});
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=workflow-command-runner.js.map
|
|
@@ -72,6 +72,8 @@ function resolveStaleRoles(nodes) {
|
|
|
72
72
|
const agentMap = new Map(listTemplates().map(a => [a.id, a]));
|
|
73
73
|
const invalidIds = [];
|
|
74
74
|
const resolved = nodes.map(node => {
|
|
75
|
+
if (node.type === 'command')
|
|
76
|
+
return node;
|
|
75
77
|
const agent = agentMap.get(node.data.agentConfigId);
|
|
76
78
|
if (!agent) {
|
|
77
79
|
invalidIds.push(node.id);
|
|
@@ -177,19 +179,34 @@ export function mapWorkflowToTaskDrafts(template) {
|
|
|
177
179
|
for (const edge of template.edges) {
|
|
178
180
|
dependsOn.get(edge.target)?.push(edge.source);
|
|
179
181
|
}
|
|
180
|
-
return template.nodes.map(node =>
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
182
|
+
return template.nodes.map(node => {
|
|
183
|
+
if (node.type === 'command') {
|
|
184
|
+
return {
|
|
185
|
+
key: node.id,
|
|
186
|
+
title: node.data.label,
|
|
187
|
+
description: `Run command: ${node.data.label}`,
|
|
188
|
+
agentConfigId: undefined,
|
|
189
|
+
dependsOnKeys: dependsOn.get(node.id)?.length ? dependsOn.get(node.id) : undefined,
|
|
190
|
+
sandboxDirs: undefined,
|
|
191
|
+
commandNode: node,
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
return {
|
|
195
|
+
key: node.id,
|
|
196
|
+
title: node.data.taskTitleTemplate || node.data.label,
|
|
197
|
+
description: node.data.taskDescriptionTemplate || `Task assigned to ${node.data.label} (${node.data.role})`,
|
|
198
|
+
agentConfigId: node.data.agentConfigId,
|
|
199
|
+
dependsOnKeys: dependsOn.get(node.id)?.length ? dependsOn.get(node.id) : undefined,
|
|
200
|
+
sandboxDirs: undefined,
|
|
201
|
+
};
|
|
202
|
+
});
|
|
188
203
|
}
|
|
189
204
|
// --- Run-time Validation ---
|
|
190
205
|
export function validateWorkflowForRun(_workspaceId, template, memberAgentIds) {
|
|
191
206
|
const agentMap = new Map(listTemplates().map((a) => [a.id, a]));
|
|
192
207
|
for (const node of template.nodes) {
|
|
208
|
+
if (node.type === 'command')
|
|
209
|
+
continue;
|
|
193
210
|
const agent = agentMap.get(node.data.agentConfigId);
|
|
194
211
|
if (!agent)
|
|
195
212
|
return `Agent "${node.data.label}" (${node.data.agentConfigId}) no longer exists`;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { v4 as uuid } from 'uuid';
|
|
2
2
|
import { listWorkspaces, getWorkspace, createWorkspace, updateWorkspace, deleteWorkspace } from '../storage/workspace-store.js';
|
|
3
|
+
import { listWorktrees } from '../storage/worktree-store.js';
|
|
3
4
|
import { ensureDir } from '../storage/json-store.js';
|
|
4
5
|
import { join } from 'node:path';
|
|
5
6
|
import { existsSync, writeFileSync } from 'node:fs';
|
|
@@ -21,7 +22,14 @@ function initAgentspace(agentspaceDir) {
|
|
|
21
22
|
}
|
|
22
23
|
}
|
|
23
24
|
export function getAll() {
|
|
24
|
-
|
|
25
|
+
const workspaces = listWorkspaces();
|
|
26
|
+
const workspaceIds = new Set(workspaces.map((workspace) => workspace.id));
|
|
27
|
+
const worktreeWorkspaces = workspaces
|
|
28
|
+
.filter((workspace) => !workspace.isWorktree)
|
|
29
|
+
.flatMap((workspace) => listWorktrees(workspace.id)
|
|
30
|
+
.filter((worktree) => worktree.status === 'active' && !workspaceIds.has(worktree.id))
|
|
31
|
+
.map(worktreeToWorkspace));
|
|
32
|
+
return [...workspaces, ...worktreeWorkspaces];
|
|
25
33
|
}
|
|
26
34
|
export function getById(id) {
|
|
27
35
|
return getWorkspace(id);
|
|
@@ -59,6 +67,8 @@ export function update(id, data) {
|
|
|
59
67
|
allowed.autoProcessIssues = data.autoProcessIssues;
|
|
60
68
|
if (Object.hasOwn(data, 'notificationSettings'))
|
|
61
69
|
allowed.notificationSettings = data.notificationSettings;
|
|
70
|
+
if (Object.hasOwn(data, 'hooksEnabled'))
|
|
71
|
+
allowed.hooksEnabled = data.hooksEnabled;
|
|
62
72
|
Object.assign(ws, allowed, { updatedAt: new Date().toISOString() });
|
|
63
73
|
updateWorkspace(ws);
|
|
64
74
|
return ws;
|
|
@@ -70,4 +80,18 @@ export function remove(id) {
|
|
|
70
80
|
deleteWorkspace(id);
|
|
71
81
|
return true;
|
|
72
82
|
}
|
|
83
|
+
function worktreeToWorkspace(worktree) {
|
|
84
|
+
return {
|
|
85
|
+
id: worktree.id,
|
|
86
|
+
name: `${worktree.name} (Worktree)`,
|
|
87
|
+
boundDirs: [worktree.path],
|
|
88
|
+
agentspaceDir: join(worktree.path, '.agentspace'),
|
|
89
|
+
isWorktree: true,
|
|
90
|
+
parentWorkspaceId: worktree.workspaceId,
|
|
91
|
+
createdAt: worktree.createdAt,
|
|
92
|
+
updatedAt: worktree.updatedAt,
|
|
93
|
+
activeChannels: [],
|
|
94
|
+
activeIssues: [],
|
|
95
|
+
};
|
|
96
|
+
}
|
|
73
97
|
//# sourceMappingURL=workspace.js.map
|