@agent-spaces/server 0.3.61 → 0.3.63
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-types.js +12 -0
- package/dist/adapters/claude-code-runtime/index.js +22 -0
- package/dist/adapters/claude-code-runtime/sdk-config.js +34 -10
- package/dist/adapters/codex-runtime.js +2 -2
- package/dist/adapters/git.js +29 -13
- package/dist/adapters/langchain-runtime.js +2 -2
- package/dist/adapters/open-agent-sdk-runtime.js +2 -2
- package/dist/agents/agent-message-parts.js +27 -3
- package/dist/agents/commit-agent.js +1 -0
- package/dist/agents/issue-agent-progress.js +4 -2
- package/dist/agents/issue-agent-runner.js +5 -5
- package/dist/agents/issue-task-controller.js +95 -14
- package/dist/app.js +74 -5
- package/dist/package.json +1 -1
- package/dist/routes/agent-sse.js +4 -2
- package/dist/routes/channel.js +21 -4
- package/dist/routes/file.js +87 -1
- package/dist/routes/hooks.js +88 -0
- package/dist/routes/issue.js +59 -1
- package/dist/routes/output-style.js +48 -0
- package/dist/routes/prompt-template.js +2 -2
- package/dist/routes/skill.js +97 -3
- package/dist/routes/task.js +13 -1
- package/dist/services/agent.js +45 -16
- package/dist/services/hook-engine.js +118 -0
- package/dist/services/issue.js +6 -0
- package/dist/services/notification-hub/bot-agent.js +1 -0
- package/dist/services/output-style.js +134 -0
- package/dist/services/persistent-agent-context.js +37 -4
- package/dist/services/prompt-template.js +2 -2
- package/dist/services/skill.js +275 -40
- package/dist/storage/hook-store.js +55 -0
- package/dist/web/404.html +1 -1
- package/dist/web/__next.__PAGE__.txt +4 -4
- package/dist/web/__next._full.txt +25 -23
- 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/0-1bfvfwifh-m.js +1 -0
- package/dist/web/_next/static/chunks/0-f~0xmwl__u5.js +1 -0
- package/dist/web/_next/static/chunks/0.n~yfwf4~6w-.js +1 -0
- package/dist/web/_next/static/chunks/002_j970b9gdx.js +1 -0
- package/dist/web/_next/static/chunks/014x2qbuiszni.js +3 -0
- package/dist/web/_next/static/chunks/01iqv28_snwus.js +1 -0
- package/dist/web/_next/static/chunks/02c22g~xd-y30.js +19 -0
- package/dist/web/_next/static/chunks/02mf61htij8g0.js +31 -0
- package/dist/web/_next/static/chunks/03scq1-0ykve3.js +1 -0
- package/dist/web/_next/static/chunks/046me66nilkff.js +1 -0
- package/dist/web/_next/static/chunks/04v-pqqs-2lvp.css +1 -0
- package/dist/web/_next/static/chunks/05f8cnmzqd5wb.js +1 -0
- package/dist/web/_next/static/chunks/{0zd1o3u04~qvo.js → 05psi2gtx~bev.js} +7 -7
- package/dist/web/_next/static/chunks/{12odetnu-lyrr.js → 06whz1~s_7pva.js} +12 -12
- package/dist/web/_next/static/chunks/06w~.izyfylap.js +1 -0
- package/dist/web/_next/static/chunks/08kfx8on9oty~.js +1 -0
- package/dist/web/_next/static/chunks/09t62a89~jesc.js +3 -0
- package/dist/web/_next/static/chunks/09y_3krccdd~u.js +1 -0
- package/dist/web/_next/static/chunks/{0njy89g5coeyi.js → 0_8dm7bxp18xo.js} +6 -6
- package/dist/web/_next/static/chunks/0_e~hmntdfop9.js +1 -0
- package/dist/web/_next/static/chunks/0_udc.6.tueey.js +1 -0
- package/dist/web/_next/static/chunks/0_vi1a~g4wx46.js +3 -0
- package/dist/web/_next/static/chunks/{05iy4.c-1cfhd.js → 0aa6bcdmtpekn.js} +1 -1
- package/dist/web/_next/static/chunks/{0tvd~rxgf0oh_.js → 0bbmx45w_h5np.js} +1 -1
- package/dist/web/_next/static/chunks/0cke33d38fnby.js +90 -0
- package/dist/web/_next/static/chunks/{0w1iudd1d46sw.js → 0ctg5qmw7uu.1.js} +2 -2
- package/dist/web/_next/static/chunks/0cyq~8xb~r5fc.js +1 -0
- package/dist/web/_next/static/chunks/0ewceguykiut5.js +1 -0
- package/dist/web/_next/static/chunks/0fxa1edqr7dve.js +1 -0
- package/dist/web/_next/static/chunks/{0202ia13sijwb.js → 0h18ej5yf974e.js} +1 -1
- package/dist/web/_next/static/chunks/0hra80eyuu37u.js +1 -0
- package/dist/web/_next/static/chunks/0i39jifmxla7q.js +1 -0
- package/dist/web/_next/static/chunks/0ie7y4k2ncvnn.js +1 -0
- package/dist/web/_next/static/chunks/0igc~uli58ncw.js +2 -0
- package/dist/web/_next/static/chunks/0kof5qdg8c2-k.js +71 -0
- package/dist/web/_next/static/chunks/{08o-zmr-40r5g.js → 0m11vvph7q94-.js} +1 -1
- package/dist/web/_next/static/chunks/0msb2mi3hiu5_.js +67 -0
- package/dist/web/_next/static/chunks/0np.d~hc1-pmh.js +4 -0
- package/dist/web/_next/static/chunks/{0qpq0~_58fe9a.js → 0oaq67r7ix.vg.js} +1 -1
- package/dist/web/_next/static/chunks/0ogpc3f3keopc.js +3 -0
- package/dist/web/_next/static/chunks/{0d_dp_4ofz0l3.css → 0ojcao3hdm36s.css} +0 -1
- package/dist/web/_next/static/chunks/0p1n8bvfnpl41.js +1 -0
- package/dist/web/_next/static/chunks/{0gig.k.rq8d0x.js → 0ppr271hz0xoq.js} +1 -1
- package/dist/web/_next/static/chunks/0s_dva~eh2yhi.js +3 -0
- package/dist/web/_next/static/chunks/0typj55ox8d5i.js +1 -0
- package/dist/web/_next/static/chunks/0w2p4ldi2aymp.js +1 -0
- package/dist/web/_next/static/chunks/{0..g0jl-8qup7.js → 0xoo17yef_b8g.js} +1 -1
- package/dist/web/_next/static/chunks/0xt-8wk21gs7g.js +1 -0
- package/dist/web/_next/static/chunks/0y09i51u6ixq5.js +1 -0
- package/dist/web/_next/static/chunks/0za1r07-6az6w.js +1 -0
- package/dist/web/_next/static/chunks/0zc0xgp5ourcn.js +1 -0
- package/dist/web/_next/static/chunks/0zmhdridea1s5.js +90 -0
- package/dist/web/_next/static/chunks/0~u.5r3-t7179.js +1 -0
- package/dist/web/_next/static/chunks/10.alq.6stmld.js +1 -0
- package/dist/web/_next/static/chunks/11-czmcci_55y.js +1 -0
- package/dist/web/_next/static/chunks/11b3zgk1etlkw.js +7 -0
- package/dist/web/_next/static/chunks/11k-.49r~1mfm.js +1 -0
- package/dist/web/_next/static/chunks/11qp8r5dotf7d.js +1 -0
- package/dist/web/_next/static/chunks/128ugqd34tr_-.js +1 -0
- package/dist/web/_next/static/chunks/12mxlicp247c8.js +1 -0
- package/dist/web/_next/static/chunks/135w27dd8c19s.js +5 -0
- package/dist/web/_next/static/chunks/13~y-b.b9rrw4.js +1 -0
- package/dist/web/_next/static/chunks/{0jokpgh485~28.js → 14hqmid8q4apf.js} +11 -11
- package/dist/web/_next/static/chunks/16sg-lflc8csx.js +1 -0
- package/dist/web/_next/static/chunks/176dc-dtokxxi.js +16 -0
- package/dist/web/_next/static/chunks/17g-0pqre.anw.js +1 -0
- package/dist/web/_next/static/chunks/17oc2l.ekcs8b.css +1 -0
- package/dist/web/_next/static/chunks/{turbopack-0lrdxynxb9-1t.js → turbopack-0ndm2zc_pdptk.js} +1 -1
- package/dist/web/_not-found/__next._full.txt +29 -30
- 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 +29 -30
- package/dist/web/icons/file_type_audio.svg +3 -1
- package/dist/web/icons/file_type_video.svg +10 -1
- package/dist/web/index.html +1 -1
- package/dist/web/index.txt +25 -23
- package/dist/web/login/__next._full.txt +30 -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 +30 -28
- package/dist/web/settings/__next._full.txt +32 -31
- 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 +35 -34
- 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 +35 -34
- package/dist/web/settings/mcps/__next._full.txt +35 -34
- 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 +35 -34
- package/dist/web/settings/models/__next._full.txt +35 -34
- 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 +35 -34
- package/dist/web/settings/output-styles/__next._full.txt +43 -0
- package/dist/web/settings/output-styles/__next._head.txt +6 -0
- package/dist/web/settings/output-styles/__next._index.txt +15 -0
- package/dist/web/settings/output-styles/__next._tree.txt +8 -0
- package/dist/web/settings/output-styles/__next.settings.output-styles.__PAGE__.txt +9 -0
- package/dist/web/settings/output-styles/__next.settings.output-styles.txt +5 -0
- package/dist/web/settings/output-styles/__next.settings.txt +7 -0
- package/dist/web/settings/output-styles.html +1 -0
- package/dist/web/settings/output-styles.txt +43 -0
- package/dist/web/settings/prompts/__next._full.txt +35 -34
- 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 +35 -34
- package/dist/web/settings/providers/__next._full.txt +35 -34
- 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 +35 -34
- package/dist/web/settings/skills/__next._full.txt +35 -34
- 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 +35 -34
- package/dist/web/settings.html +1 -1
- package/dist/web/settings.txt +32 -31
- package/dist/web/workflows/__next._full.txt +32 -30
- 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 +32 -30
- package/dist/web/workspace/_/__next._full.txt +30 -70
- 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 -17
- package/dist/web/workspace/_/__next.workspace.$d$id.__PAGE__.txt +3 -18
- 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 +30 -70
- package/dist/web/workspaces/__next._full.txt +31 -29
- 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 +31 -29
- package/dist/ws/agent-runner.js +55 -33
- package/dist/ws/message-parts.js +61 -2
- package/package.json +1 -1
- package/public/output-styles/carmack-mode.md +381 -0
- package/public/output-styles/codex-rigor-mode.md +114 -0
- package/public/output-styles/dhh-mode.md +265 -0
- package/public/output-styles/evan-you-mode.md +539 -0
- package/public/output-styles/index.json +37 -0
- package/public/output-styles/jobs-mode.md +369 -0
- package/public/output-styles/linus-mode.md +135 -0
- package/public/output-styles/uncle-bob-mode.md +221 -0
- package/public/prompt/andrej-karpathy-skills.md +65 -0
- package/public/prompt/claude-token-efficient-coding.md +35 -0
- package/public/prompt/index.json +12 -0
- package/public/skills/index.json +92 -0
- package/public/skills/planning-with-files/planning-with-files-zh/SKILL.md +243 -0
- package/public/skills/planning-with-files/planning-with-files-zh/scripts/check-complete.ps1 +44 -0
- package/public/skills/planning-with-files/planning-with-files-zh/scripts/check-complete.sh +46 -0
- package/public/skills/planning-with-files/planning-with-files-zh/scripts/init-session.ps1 +124 -0
- package/public/skills/planning-with-files/planning-with-files-zh/scripts/init-session.sh +124 -0
- package/public/skills/planning-with-files/planning-with-files-zh/scripts/session-catchup.py +438 -0
- package/public/skills/planning-with-files/planning-with-files-zh/templates/findings.md +29 -0
- package/public/skills/planning-with-files/planning-with-files-zh/templates/progress.md +40 -0
- package/public/skills/planning-with-files/planning-with-files-zh/templates/task_plan.md +58 -0
- package/public/skills/superpowers/brainstorming/SKILL.md +164 -0
- package/public/skills/superpowers/brainstorming/scripts/frame-template.html +214 -0
- package/public/skills/superpowers/brainstorming/scripts/helper.js +88 -0
- package/public/skills/superpowers/brainstorming/scripts/server.cjs +354 -0
- package/public/skills/superpowers/brainstorming/scripts/start-server.sh +148 -0
- package/public/skills/superpowers/brainstorming/scripts/stop-server.sh +56 -0
- package/public/skills/superpowers/brainstorming/spec-document-reviewer-prompt.md +49 -0
- package/public/skills/superpowers/brainstorming/visual-companion.md +287 -0
- package/public/skills/superpowers/dispatching-parallel-agents/SKILL.md +182 -0
- package/public/skills/superpowers/executing-plans/SKILL.md +70 -0
- package/public/skills/superpowers/finishing-a-development-branch/SKILL.md +251 -0
- package/public/skills/superpowers/receiving-code-review/SKILL.md +213 -0
- package/public/skills/superpowers/requesting-code-review/SKILL.md +103 -0
- package/public/skills/superpowers/requesting-code-review/code-reviewer.md +168 -0
- package/public/skills/superpowers/subagent-driven-development/SKILL.md +279 -0
- package/public/skills/superpowers/subagent-driven-development/code-quality-reviewer-prompt.md +25 -0
- package/public/skills/superpowers/subagent-driven-development/implementer-prompt.md +113 -0
- package/public/skills/superpowers/subagent-driven-development/spec-reviewer-prompt.md +61 -0
- package/public/skills/superpowers/systematic-debugging/CREATION-LOG.md +119 -0
- package/public/skills/superpowers/systematic-debugging/SKILL.md +296 -0
- package/public/skills/superpowers/systematic-debugging/condition-based-waiting-example.ts +158 -0
- package/public/skills/superpowers/systematic-debugging/condition-based-waiting.md +115 -0
- package/public/skills/superpowers/systematic-debugging/defense-in-depth.md +122 -0
- package/public/skills/superpowers/systematic-debugging/find-polluter.sh +63 -0
- package/public/skills/superpowers/systematic-debugging/root-cause-tracing.md +169 -0
- package/public/skills/superpowers/systematic-debugging/test-academic.md +14 -0
- package/public/skills/superpowers/systematic-debugging/test-pressure-1.md +58 -0
- package/public/skills/superpowers/systematic-debugging/test-pressure-2.md +68 -0
- package/public/skills/superpowers/systematic-debugging/test-pressure-3.md +69 -0
- package/public/skills/superpowers/test-driven-development/SKILL.md +371 -0
- package/public/skills/superpowers/test-driven-development/testing-anti-patterns.md +299 -0
- package/public/skills/superpowers/using-git-worktrees/SKILL.md +215 -0
- package/public/skills/superpowers/using-superpowers/SKILL.md +117 -0
- package/public/skills/superpowers/using-superpowers/references/codex-tools.md +59 -0
- package/public/skills/superpowers/using-superpowers/references/copilot-tools.md +42 -0
- package/public/skills/superpowers/using-superpowers/references/gemini-tools.md +51 -0
- package/public/skills/superpowers/verification-before-completion/SKILL.md +139 -0
- package/public/skills/superpowers/writing-plans/SKILL.md +152 -0
- package/public/skills/superpowers/writing-plans/plan-document-reviewer-prompt.md +49 -0
- package/public/skills/superpowers/writing-skills/SKILL.md +655 -0
- package/public/skills/superpowers/writing-skills/anthropic-best-practices.md +1150 -0
- package/public/skills/superpowers/writing-skills/examples/CLAUDE_MD_TESTING.md +189 -0
- package/public/skills/superpowers/writing-skills/graphviz-conventions.dot +172 -0
- package/public/skills/superpowers/writing-skills/persuasion-principles.md +187 -0
- package/public/skills/superpowers/writing-skills/render-graphs.js +168 -0
- package/public/skills/superpowers/writing-skills/testing-skills-with-subagents.md +384 -0
- package/dist/web/_next/static/chunks/0-1pn22sg~67u.js +0 -2
- package/dist/web/_next/static/chunks/01gi~q0c6ez6..js +0 -1
- package/dist/web/_next/static/chunks/03me5_ir..2ix.js +0 -1
- package/dist/web/_next/static/chunks/05eu2fdixf7c9.js +0 -1
- package/dist/web/_next/static/chunks/0_-c.y2qq4ax4.js +0 -270
- package/dist/web/_next/static/chunks/0_g3irbniww6d.js +0 -3
- package/dist/web/_next/static/chunks/0cs830n97dgjy.js +0 -1
- package/dist/web/_next/static/chunks/0g-0n6glz_z6w.js +0 -1
- package/dist/web/_next/static/chunks/0gyede80jpy3n.js +0 -4
- package/dist/web/_next/static/chunks/0hrbuvzuxrjfl.js +0 -1
- package/dist/web/_next/static/chunks/0ju52ko_nh7gi.js +0 -1
- package/dist/web/_next/static/chunks/0mny8i81aenx3.js +0 -1
- package/dist/web/_next/static/chunks/0nsu~f3voe~0i.js +0 -5
- package/dist/web/_next/static/chunks/0sz8_nijfiz0p.js +0 -1
- package/dist/web/_next/static/chunks/0u7_qd9hzqwac.js +0 -1
- package/dist/web/_next/static/chunks/0w3o.7vi.dlm6.js +0 -1
- package/dist/web/_next/static/chunks/0wv0h27jafag4.js +0 -1
- package/dist/web/_next/static/chunks/0wwvc4zc2q6bn.js +0 -1
- package/dist/web/_next/static/chunks/0x4b-a2ixww6m.js +0 -1
- package/dist/web/_next/static/chunks/0xwqf.llmm_u2.js +0 -31
- package/dist/web/_next/static/chunks/0~w6ugk9s5p-h.css +0 -1
- package/dist/web/_next/static/chunks/125nunjfj2fj0.js +0 -1
- package/dist/web/_next/static/chunks/1285yqy_oirb-.js +0 -1
- package/dist/web/_next/static/chunks/13ess~4pdmxma.js +0 -1
- package/dist/web/_next/static/chunks/14n8i2xz4_y-e.js +0 -1
- package/public/avatars/1777813826407-bea0ja-minimax.svg +0 -1
- package/public/avatars/1777813967088-3xlvd0-minimax.svg +0 -1
- package/public/avatars/1777814041714-yp0qeq-minimax.svg +0 -1
- package/public/avatars/1777904986095-rg26je-icon.png +0 -0
- package/public/avatars/1778953228323-5je54x-user.jpg +0 -0
- package/public/avatars/1778954057880-g01q6y-user.jpg +0 -0
- /package/dist/web/_next/static/{HUlYEknPhyW7dRmJ5mFdG → OoXAsPtrUWjC1l898FSvI}/_buildManifest.js +0 -0
- /package/dist/web/_next/static/{HUlYEknPhyW7dRmJ5mFdG → OoXAsPtrUWjC1l898FSvI}/_clientMiddlewareManifest.js +0 -0
- /package/dist/web/_next/static/{HUlYEknPhyW7dRmJ5mFdG → OoXAsPtrUWjC1l898FSvI}/_ssgManifest.js +0 -0
- /package/public/avatars/{1777815865622-08wp9m-user.jpg → user.jpg} +0 -0
|
@@ -1,7 +1,19 @@
|
|
|
1
|
+
import { resolveOutputStyleContent } from '../services/output-style.js';
|
|
1
2
|
export function summarizeResult(text) {
|
|
2
3
|
const normalized = text.trim().replace(/\s+/g, ' ');
|
|
3
4
|
if (!normalized)
|
|
4
5
|
return 'Completed agent execution';
|
|
5
6
|
return normalized.length > 160 ? `${normalized.slice(0, 157)}...` : normalized;
|
|
6
7
|
}
|
|
8
|
+
export function appendOutputStyleToPrompt(prompt, outputStyle) {
|
|
9
|
+
const style = resolveOutputStyleContent(outputStyle)?.trim();
|
|
10
|
+
if (!style)
|
|
11
|
+
return prompt;
|
|
12
|
+
return [
|
|
13
|
+
prompt.trimEnd(),
|
|
14
|
+
'',
|
|
15
|
+
'Output style instructions:',
|
|
16
|
+
style,
|
|
17
|
+
].join('\n');
|
|
18
|
+
}
|
|
7
19
|
//# sourceMappingURL=agent-runtime-types.js.map
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { join } from 'node:path';
|
|
2
2
|
import { query } from '@anthropic-ai/claude-agent-sdk';
|
|
3
3
|
import { summarizeResult } from '../agent-runtime-types.js';
|
|
4
|
+
import { prepareClaudeOutputStyleFile } from '../../services/output-style.js';
|
|
4
5
|
import { normalizeAdditionalDirectories, normalizePermissionMode, normalizeSkillNames, prepareConfigDir, resolveBundledClaudeExecutable, buildEnv, normalizeMcpServers } from './sdk-config.js';
|
|
5
6
|
import { startClaudeAdapterIfNeeded, getClaudeCodeModel } from './adapter-pool.js';
|
|
6
7
|
import { extractThinkingEvents, extractToolUseEvents, extractToolResultEvent, logToolDebug, formatMessage, isAskUserQuestionAutoResult, countUsageTokens, formatUsageLine, normalizeUsage } from './message-format.js';
|
|
@@ -25,6 +26,7 @@ export class ClaudeCodeRuntime {
|
|
|
25
26
|
if (configDir)
|
|
26
27
|
prepareConfigDir(configDir, agentDir);
|
|
27
28
|
const skillNames = normalizeSkillNames(options?.skills, configDir);
|
|
29
|
+
const outputStyleFile = configDir ? prepareClaudeOutputStyleFile(configDir, options?.outputStyle) : undefined;
|
|
28
30
|
const claudeExecutable = resolveBundledClaudeExecutable();
|
|
29
31
|
this.adapterRun = await startClaudeAdapterIfNeeded(this.config);
|
|
30
32
|
const baseURL = this.adapterRun?.url ?? this.config.baseURL;
|
|
@@ -46,6 +48,7 @@ export class ClaudeCodeRuntime {
|
|
|
46
48
|
tools: { type: 'preset', preset: 'claude_code' },
|
|
47
49
|
mcpServers: sdkMcpServers,
|
|
48
50
|
skills: skillNames,
|
|
51
|
+
outputStyle: outputStyleFile,
|
|
49
52
|
managedSettings: {
|
|
50
53
|
strictPluginOnlyCustomization: ['mcp'],
|
|
51
54
|
},
|
|
@@ -84,9 +87,12 @@ export class ClaudeCodeRuntime {
|
|
|
84
87
|
options?.onEvent?.({ type: 'session', sessionId });
|
|
85
88
|
}
|
|
86
89
|
const toolUses = extractToolUseEvents(message);
|
|
90
|
+
let sawAskUserQuestion = false;
|
|
87
91
|
for (const toolUse of toolUses) {
|
|
88
92
|
if (toolUse.name === 'AskUserQuestion') {
|
|
89
93
|
pendingAskUserQuestionToolIds.add(toolUse.id);
|
|
94
|
+
waitingForUserAnswer = true;
|
|
95
|
+
sawAskUserQuestion = true;
|
|
90
96
|
}
|
|
91
97
|
}
|
|
92
98
|
const toolResult = extractToolResultEvent(message);
|
|
@@ -133,8 +139,24 @@ export class ClaudeCodeRuntime {
|
|
|
133
139
|
error = message.errors.join('\n') || message.subtype;
|
|
134
140
|
}
|
|
135
141
|
}
|
|
142
|
+
if (sawAskUserQuestion)
|
|
143
|
+
break;
|
|
136
144
|
}
|
|
137
145
|
const elapsed = Date.now() - startTime;
|
|
146
|
+
if (waitingForUserAnswer) {
|
|
147
|
+
d(`waiting for user answer ${elapsed}ms | turns=${turns} tokens=${tokenCount}`);
|
|
148
|
+
if (usageLine)
|
|
149
|
+
output.push(usageLine);
|
|
150
|
+
return {
|
|
151
|
+
success: true,
|
|
152
|
+
summary: 'Waiting for user answer',
|
|
153
|
+
artifacts: [],
|
|
154
|
+
output,
|
|
155
|
+
usage,
|
|
156
|
+
costUsd,
|
|
157
|
+
sessionId,
|
|
158
|
+
};
|
|
159
|
+
}
|
|
138
160
|
if (!sawResult) {
|
|
139
161
|
const runtimeError = extractRuntimeError([...stderrLines, ...output])
|
|
140
162
|
|| 'Claude Code execution stopped before reporting a final result';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { copyFileSync, existsSync, mkdirSync, readdirSync, rmSync, statSync } from 'node:fs';
|
|
1
|
+
import { copyFileSync, cpSync, existsSync, mkdirSync, readdirSync, readFileSync, rmSync, statSync, writeFileSync } from 'node:fs';
|
|
2
2
|
import { createRequire } from 'node:module';
|
|
3
|
-
import { extname, isAbsolute, resolve } from 'node:path';
|
|
3
|
+
import { basename, extname, isAbsolute, resolve } from 'node:path';
|
|
4
4
|
import { join } from 'node:path';
|
|
5
5
|
import { createSdkMcpServer, tool } from '@anthropic-ai/claude-agent-sdk';
|
|
6
6
|
import { isAnthropicBridgeProvider } from './types.js';
|
|
@@ -125,7 +125,7 @@ export function normalizeSkillNames(skills, configDir) {
|
|
|
125
125
|
if (!Array.isArray(skills))
|
|
126
126
|
return [];
|
|
127
127
|
return skills
|
|
128
|
-
.map(
|
|
128
|
+
.map(sanitizeSkillName)
|
|
129
129
|
.filter((skill) => Boolean(skill) && hasSkillContent(skill, configDir));
|
|
130
130
|
}
|
|
131
131
|
export function prepareConfigDir(configDir, agentDir) {
|
|
@@ -138,19 +138,43 @@ export function prepareConfigDir(configDir, agentDir) {
|
|
|
138
138
|
mkdirSync(targetSkillsDir, { recursive: true });
|
|
139
139
|
if (!existsSync(sourceSkillsDir))
|
|
140
140
|
return;
|
|
141
|
-
for (const
|
|
142
|
-
|
|
141
|
+
for (const entry of readdirSync(sourceSkillsDir)) {
|
|
142
|
+
const source = join(sourceSkillsDir, entry);
|
|
143
|
+
const sourceStat = statSync(source);
|
|
144
|
+
if (sourceStat.isDirectory()) {
|
|
145
|
+
const skillName = sanitizeSkillName(entry);
|
|
146
|
+
if (!skillName)
|
|
147
|
+
continue;
|
|
148
|
+
const sourceSkillFile = join(source, 'SKILL.md');
|
|
149
|
+
const targetSkillDir = join(targetSkillsDir, skillName);
|
|
150
|
+
if (existsSync(sourceSkillFile) && statSync(sourceSkillFile).size > 0) {
|
|
151
|
+
cpSync(source, targetSkillDir, { recursive: true, force: true });
|
|
152
|
+
}
|
|
143
153
|
continue;
|
|
144
|
-
|
|
154
|
+
}
|
|
155
|
+
if (!sourceStat.isFile() || extname(entry).toLowerCase() !== '.md')
|
|
156
|
+
continue;
|
|
157
|
+
const skillName = sanitizeSkillName(entry);
|
|
158
|
+
if (!skillName || sourceStat.size === 0)
|
|
159
|
+
continue;
|
|
160
|
+
const targetSkillDir = join(targetSkillsDir, skillName);
|
|
161
|
+
mkdirSync(targetSkillDir, { recursive: true });
|
|
162
|
+
writeFileSync(join(targetSkillDir, 'SKILL.md'), readFileSync(source, 'utf-8'), 'utf-8');
|
|
163
|
+
copyFileSync(source, join(targetSkillsDir, `${skillName}.md`));
|
|
145
164
|
}
|
|
146
165
|
}
|
|
147
166
|
function hasSkillContent(skill, configDir) {
|
|
148
167
|
if (!configDir)
|
|
149
168
|
return true;
|
|
150
|
-
const skillFile = join(configDir, 'skills',
|
|
151
|
-
if (
|
|
152
|
-
return
|
|
153
|
-
|
|
169
|
+
const skillFile = join(configDir, 'skills', skill, 'SKILL.md');
|
|
170
|
+
if (existsSync(skillFile) && statSync(skillFile).size > 0)
|
|
171
|
+
return true;
|
|
172
|
+
const legacySkillFile = join(configDir, 'skills', `${skill}.md`);
|
|
173
|
+
return existsSync(legacySkillFile) && statSync(legacySkillFile).size > 0;
|
|
174
|
+
}
|
|
175
|
+
function sanitizeSkillName(name) {
|
|
176
|
+
const raw = basename(name).replace(/\.md$/i, '').trim();
|
|
177
|
+
return raw.replace(/[^a-zA-Z0-9._-]+/g, '-').replace(/^-+|-+$/g, '');
|
|
154
178
|
}
|
|
155
179
|
export function normalizePermissionMode(permissionMode) {
|
|
156
180
|
if (permissionMode === 'default' ||
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { existsSync, mkdirSync, readdirSync, readFileSync, rmSync, statSync, writeFileSync } from 'node:fs';
|
|
2
2
|
import { basename, extname, join } from 'node:path';
|
|
3
3
|
import { Codex } from '@openai/codex-sdk';
|
|
4
|
-
import { summarizeResult } from './agent-runtime-types.js';
|
|
4
|
+
import { appendOutputStyleToPrompt, summarizeResult } from './agent-runtime-types.js';
|
|
5
5
|
/**
|
|
6
6
|
* Runtime backed by OpenAI's Codex SDK.
|
|
7
7
|
* Spawns the bundled Codex CLI and consumes its structured JSONL event stream.
|
|
@@ -48,7 +48,7 @@ export class CodexRuntime {
|
|
|
48
48
|
const thread = options?.resumeSessionId
|
|
49
49
|
? codex.resumeThread(options.resumeSessionId, threadOptions)
|
|
50
50
|
: codex.startThread(threadOptions);
|
|
51
|
-
const { events } = await thread.runStreamed(prompt, {
|
|
51
|
+
const { events } = await thread.runStreamed(appendOutputStyleToPrompt(prompt, options?.outputStyle), {
|
|
52
52
|
signal: this.abortController.signal,
|
|
53
53
|
});
|
|
54
54
|
let resultText = '';
|
package/dist/adapters/git.js
CHANGED
|
@@ -3,6 +3,19 @@ import { getWorkspace } from '../storage/workspace-store.js';
|
|
|
3
3
|
import { writeFile, readFile, mkdir } from 'node:fs/promises';
|
|
4
4
|
import { existsSync } from 'node:fs';
|
|
5
5
|
import { join, basename } from 'node:path';
|
|
6
|
+
const BINARY_EXTENSIONS = new Set([
|
|
7
|
+
'png', 'jpg', 'jpeg', 'gif', 'bmp', 'ico', 'webp', 'svg', 'tiff', 'tif',
|
|
8
|
+
'mp3', 'mp4', 'wav', 'avi', 'mov', 'mkv', 'flv', 'wmv', 'webm',
|
|
9
|
+
'zip', 'tar', 'gz', 'bz2', 'xz', '7z', 'rar', 'dmg', 'iso',
|
|
10
|
+
'pdf', 'doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx',
|
|
11
|
+
'woff', 'woff2', 'ttf', 'otf', 'eot',
|
|
12
|
+
'exe', 'dll', 'so', 'dylib', 'bin', 'dat',
|
|
13
|
+
'sqlite', 'db', 'pyc', 'o', 'obj', 'class', 'jar', 'wasm',
|
|
14
|
+
]);
|
|
15
|
+
function isBinaryPath(filePath) {
|
|
16
|
+
const ext = filePath.split('.').pop()?.toLowerCase();
|
|
17
|
+
return ext ? BINARY_EXTENSIONS.has(ext) : true;
|
|
18
|
+
}
|
|
6
19
|
const gitInstances = new Map();
|
|
7
20
|
function getGitOptions() {
|
|
8
21
|
const proxy = process.env.HTTPS_PROXY || process.env.https_proxy
|
|
@@ -115,9 +128,9 @@ export async function gitDiff(workspaceId, filePath) {
|
|
|
115
128
|
const newContent = await import('node:fs/promises').then(fs => fs.readFile(`${ws.boundDirs[0]}/${filePath}`, 'utf-8')).catch(() => '');
|
|
116
129
|
diffs.push({
|
|
117
130
|
path: filePath,
|
|
118
|
-
oldContent,
|
|
119
|
-
newContent,
|
|
120
|
-
isBinary:
|
|
131
|
+
oldContent: isBinaryPath(filePath) ? '' : oldContent,
|
|
132
|
+
newContent: isBinaryPath(filePath) ? '' : newContent,
|
|
133
|
+
isBinary: isBinaryPath(filePath),
|
|
121
134
|
isNew: !oldContent,
|
|
122
135
|
isDeleted: !newContent,
|
|
123
136
|
});
|
|
@@ -126,13 +139,14 @@ export async function gitDiff(workspaceId, filePath) {
|
|
|
126
139
|
const raw = await git.diff(['--name-only']);
|
|
127
140
|
const files = raw.split('\n').filter(Boolean);
|
|
128
141
|
for (const f of files) {
|
|
129
|
-
const
|
|
130
|
-
const
|
|
142
|
+
const binary = isBinaryPath(f);
|
|
143
|
+
const oldContent = binary ? '' : await git.show([`HEAD:${f}`]).catch(() => '');
|
|
144
|
+
const newContent = binary ? '' : await import('node:fs/promises').then(fs => fs.readFile(`${ws.boundDirs[0]}/${f}`, 'utf-8')).catch(() => '');
|
|
131
145
|
diffs.push({
|
|
132
146
|
path: f,
|
|
133
147
|
oldContent,
|
|
134
148
|
newContent,
|
|
135
|
-
isBinary:
|
|
149
|
+
isBinary: binary,
|
|
136
150
|
isNew: !oldContent,
|
|
137
151
|
isDeleted: !newContent,
|
|
138
152
|
});
|
|
@@ -140,13 +154,14 @@ export async function gitDiff(workspaceId, filePath) {
|
|
|
140
154
|
// Also check untracked (staged new files)
|
|
141
155
|
const status = await git.status();
|
|
142
156
|
for (const f of status.not_added) {
|
|
143
|
-
const
|
|
144
|
-
|
|
157
|
+
const binary = isBinaryPath(f);
|
|
158
|
+
const newContent = binary ? '' : await import('node:fs/promises').then(fs => fs.readFile(`${ws.boundDirs[0]}/${f}`, 'utf-8')).catch(() => '');
|
|
159
|
+
if (newContent || binary) {
|
|
145
160
|
diffs.push({
|
|
146
161
|
path: f,
|
|
147
162
|
oldContent: '',
|
|
148
|
-
newContent,
|
|
149
|
-
isBinary:
|
|
163
|
+
newContent: binary ? '' : newContent,
|
|
164
|
+
isBinary: binary,
|
|
150
165
|
isNew: true,
|
|
151
166
|
isDeleted: false,
|
|
152
167
|
});
|
|
@@ -337,9 +352,10 @@ export async function gitCommitDiff(workspaceId, commitHash) {
|
|
|
337
352
|
const files = nameOnlyRaw.split('\n').filter(Boolean);
|
|
338
353
|
const diffs = [];
|
|
339
354
|
for (const f of files) {
|
|
340
|
-
const
|
|
341
|
-
const
|
|
342
|
-
|
|
355
|
+
const binary = isBinaryPath(f);
|
|
356
|
+
const oldContent = binary ? '' : await git.show([`${commitHash}^:${f}`]).catch(() => '');
|
|
357
|
+
const newContent = binary ? '' : await git.show([`${commitHash}:${f}`]).catch(() => '');
|
|
358
|
+
diffs.push({ path: f, oldContent, newContent, isBinary: binary, isNew: !oldContent, isDeleted: !newContent });
|
|
343
359
|
}
|
|
344
360
|
return diffs;
|
|
345
361
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createAgent, initChatModel, tool } from 'langchain';
|
|
2
2
|
import { z } from 'zod';
|
|
3
|
-
import { summarizeResult } from './agent-runtime-types.js';
|
|
3
|
+
import { appendOutputStyleToPrompt, summarizeResult } from './agent-runtime-types.js';
|
|
4
4
|
/**
|
|
5
5
|
* Runtime backed by LangChain.js.
|
|
6
6
|
* Uses LangChain's provider-neutral createAgent API and adapts Agent Spaces tools.
|
|
@@ -27,7 +27,7 @@ export class LangChainRuntime {
|
|
|
27
27
|
tools: buildLangChainTools(options?.functionTools, output, options),
|
|
28
28
|
systemPrompt: options?.systemPrompt,
|
|
29
29
|
});
|
|
30
|
-
const result = await agent.invoke({ messages: [{ role: 'user', content: prompt }] }, {
|
|
30
|
+
const result = await agent.invoke({ messages: [{ role: 'user', content: appendOutputStyleToPrompt(prompt, options?.outputStyle) }] }, {
|
|
31
31
|
signal: this.abortController?.signal,
|
|
32
32
|
recursionLimit: options?.maxTurns ? Math.max(2, options.maxTurns * 2 + 1) : undefined,
|
|
33
33
|
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { createAgent } from '@codeany/open-agent-sdk';
|
|
2
|
-
import { summarizeResult } from './agent-runtime-types.js';
|
|
2
|
+
import { appendOutputStyleToPrompt, summarizeResult } from './agent-runtime-types.js';
|
|
3
3
|
/**
|
|
4
4
|
* Runtime backed by @codeany/open-agent-sdk.
|
|
5
5
|
* Runs the agent loop in-process with the SDK's built-in tools.
|
|
@@ -35,7 +35,7 @@ export class OpenAgentSdkRuntime {
|
|
|
35
35
|
});
|
|
36
36
|
d('agent created, sending prompt...');
|
|
37
37
|
d('tool debug | open-agent-sdk runtime does not expose per-tool stream events through prompt(); only final text/usage is available here');
|
|
38
|
-
const result = await this.agent.prompt(prompt);
|
|
38
|
+
const result = await this.agent.prompt(appendOutputStyleToPrompt(prompt, options?.outputStyle));
|
|
39
39
|
const elapsed = Date.now() - startTime;
|
|
40
40
|
const inputTokens = result.usage.input_tokens;
|
|
41
41
|
const outputTokens = result.usage.output_tokens;
|
|
@@ -46,7 +46,7 @@ export function createAgentMessagePartsTracker(input) {
|
|
|
46
46
|
output.push(event.line);
|
|
47
47
|
input.onOutput?.(event.line);
|
|
48
48
|
},
|
|
49
|
-
buildParts({ sessionId, workspaceRoot, model, usage, success, error }) {
|
|
49
|
+
buildParts({ sessionId, workspaceRoot, model, usage, persistentContext, success, error }) {
|
|
50
50
|
return buildAgentMessageParts({
|
|
51
51
|
sessionId,
|
|
52
52
|
workspaceRoot,
|
|
@@ -55,6 +55,7 @@ export function createAgentMessagePartsTracker(input) {
|
|
|
55
55
|
output,
|
|
56
56
|
reasoning,
|
|
57
57
|
toolDetails,
|
|
58
|
+
persistentContext,
|
|
58
59
|
success,
|
|
59
60
|
error,
|
|
60
61
|
});
|
|
@@ -69,7 +70,7 @@ function buildAgentMessageParts(input) {
|
|
|
69
70
|
: '';
|
|
70
71
|
const usage = input.usage ?? extractUsage(lines);
|
|
71
72
|
const parts = [];
|
|
72
|
-
const chainItems = buildChainItems(lines, finalTextRange, finalText, input.workspaceRoot, input.toolDetails);
|
|
73
|
+
const chainItems = buildChainItems(lines, finalTextRange, finalText, input.workspaceRoot, input.toolDetails, input.persistentContext);
|
|
73
74
|
const reasoningText = normalizeReasoningText(input.reasoning);
|
|
74
75
|
if (reasoningText) {
|
|
75
76
|
parts.push({
|
|
@@ -181,12 +182,17 @@ function findFinalTextRange(lines) {
|
|
|
181
182
|
}
|
|
182
183
|
return { start, end };
|
|
183
184
|
}
|
|
184
|
-
function buildChainItems(lines, finalTextRange, finalText, workspaceRoot, toolDetails) {
|
|
185
|
+
function buildChainItems(lines, finalTextRange, finalText, workspaceRoot, toolDetails, persistentContext) {
|
|
185
186
|
let toolIndex = 0;
|
|
186
187
|
let messageIndex = 0;
|
|
187
188
|
const items = [];
|
|
188
189
|
const toolDetailMatchCounts = new Map();
|
|
189
190
|
let messageBuffer = [];
|
|
191
|
+
const persistentContextItem = buildPersistentContextToolItem(persistentContext);
|
|
192
|
+
if (persistentContextItem) {
|
|
193
|
+
items.push(persistentContextItem);
|
|
194
|
+
toolIndex += 1;
|
|
195
|
+
}
|
|
190
196
|
const flushMessageBuffer = () => {
|
|
191
197
|
if (messageBuffer.length === 0)
|
|
192
198
|
return;
|
|
@@ -229,6 +235,7 @@ function buildToolTodo(line, index, workspaceRoot, toolDetails, toolDetailMatchC
|
|
|
229
235
|
const detailId = findToolDetailId(line, toolDetails, toolDetailMatchCounts);
|
|
230
236
|
return {
|
|
231
237
|
id: `tool-${index}`,
|
|
238
|
+
kind: 'tool',
|
|
232
239
|
title: summary.title,
|
|
233
240
|
description: summary.description,
|
|
234
241
|
status: 'completed',
|
|
@@ -238,6 +245,23 @@ function buildToolTodo(line, index, workspaceRoot, toolDetails, toolDetailMatchC
|
|
|
238
245
|
detailId,
|
|
239
246
|
};
|
|
240
247
|
}
|
|
248
|
+
function buildPersistentContextToolItem(persistentContext) {
|
|
249
|
+
const counts = persistentContext?.counts;
|
|
250
|
+
if (!counts?.total)
|
|
251
|
+
return null;
|
|
252
|
+
const description = [
|
|
253
|
+
counts.claudeMd ? `${counts.claudeMd} claude.md` : null,
|
|
254
|
+
counts.agentsMd ? `${counts.agentsMd} AGENTS.md` : null,
|
|
255
|
+
].filter(Boolean).join(', ') || `${counts.total} instruction files`;
|
|
256
|
+
return {
|
|
257
|
+
id: 'tool-persistent-context',
|
|
258
|
+
kind: 'tool',
|
|
259
|
+
title: 'Load claude.md',
|
|
260
|
+
description,
|
|
261
|
+
status: 'completed',
|
|
262
|
+
toolName: 'LoadClaudeMd',
|
|
263
|
+
};
|
|
264
|
+
}
|
|
241
265
|
function summarizeToolLine(line, workspaceRoot) {
|
|
242
266
|
const trimmed = line.trim();
|
|
243
267
|
const toolName = extractToolName(trimmed);
|
|
@@ -42,6 +42,7 @@ export async function runCommitAgent(workspaceId) {
|
|
|
42
42
|
}), workingDir, {
|
|
43
43
|
maxTurns: 1,
|
|
44
44
|
systemPrompt,
|
|
45
|
+
outputStyle: commitAgent.outputStyle,
|
|
45
46
|
});
|
|
46
47
|
agentService.complete(workspaceId, session.id, result.success ? undefined : result.error, {
|
|
47
48
|
runtime: commitAgent.runtimeKind,
|
|
@@ -74,7 +74,9 @@ export function createIssueAgentProgress(workspaceId, issue, preset, agentSessio
|
|
|
74
74
|
return { message, comment };
|
|
75
75
|
}
|
|
76
76
|
export function completeIssueAgentProgress(workspaceId, issue, progress, summary, output, metadata) {
|
|
77
|
-
const
|
|
77
|
+
const parts = metadata.parts;
|
|
78
|
+
const finalText = [...(parts ?? [])].reverse().find((part) => part.type === 'text')?.text.trim();
|
|
79
|
+
const content = finalText || summary.trim() || output.join('\n').trim();
|
|
78
80
|
if (!content.trim())
|
|
79
81
|
return;
|
|
80
82
|
const message = messageService.updateMessage(workspaceId, issue.channelId, progress.message.id, {
|
|
@@ -88,7 +90,7 @@ export function completeIssueAgentProgress(workspaceId, issue, progress, summary
|
|
|
88
90
|
summary,
|
|
89
91
|
duration: metadata.duration,
|
|
90
92
|
},
|
|
91
|
-
parts
|
|
93
|
+
parts,
|
|
92
94
|
});
|
|
93
95
|
if (message)
|
|
94
96
|
broadcastToWorkspace(workspaceId, 'channel.message.updated', message);
|
|
@@ -9,6 +9,11 @@ export async function runIssueAutomation(workspaceId, issueId, ctx) {
|
|
|
9
9
|
console.warn(`[issue-runner] issue not found workspaceId=${workspaceId} issueId=${issueId}`);
|
|
10
10
|
return;
|
|
11
11
|
}
|
|
12
|
+
const tasks = taskService.list(workspaceId, issueId);
|
|
13
|
+
if (tasks.length > 0) {
|
|
14
|
+
await scheduleRunnableIssueTasks(workspaceId, issueId, ctx);
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
12
17
|
// Workflow template branch
|
|
13
18
|
if (issue.workflowId) {
|
|
14
19
|
const template = workflowService.getWorkflow(issue.workflowId);
|
|
@@ -29,11 +34,6 @@ export async function runIssueAutomation(workspaceId, issueId, ctx) {
|
|
|
29
34
|
return;
|
|
30
35
|
}
|
|
31
36
|
}
|
|
32
|
-
const tasks = taskService.list(workspaceId, issueId);
|
|
33
|
-
if (tasks.length > 0) {
|
|
34
|
-
await scheduleRunnableIssueTasks(workspaceId, issueId, ctx);
|
|
35
|
-
return;
|
|
36
|
-
}
|
|
37
37
|
console.warn(`[issue-runner] no workflow configured for issue workspaceId=${workspaceId} issueId=${issueId}`);
|
|
38
38
|
}
|
|
39
39
|
export function hasActiveIssueAutomation(workspaceId) {
|
|
@@ -9,7 +9,9 @@ import { createIssueFunctionTools } from '../services/builtin-tools.js';
|
|
|
9
9
|
import { getThinkingRuntimeConfig } from '../services/llm-model-config.js';
|
|
10
10
|
import { prependPersistentAgentContext } from '../services/persistent-agent-context.js';
|
|
11
11
|
import { completeIssueAgentProgress, createIssueAgentProgress, createIssueAgentProgressTracker } from './issue-agent-progress.js';
|
|
12
|
+
import { wrapOnEventWithHooks } from '../services/hook-engine.js';
|
|
12
13
|
const ACTIVE_TASK_STATUSES = ['running', 'reviewing', 'retrying', 'waiting_review'];
|
|
14
|
+
const activeIssueRuntimes = new Map();
|
|
13
15
|
export async function syncIssueTasksAfterPlanning(workspaceId, issueId, input, ctx) {
|
|
14
16
|
const issue = issueService.getById(workspaceId, issueId);
|
|
15
17
|
if (!issue) {
|
|
@@ -31,6 +33,7 @@ export async function syncIssueTasksAfterPlanning(workspaceId, issueId, input, c
|
|
|
31
33
|
ctx.broadcast('agent.output', { agentId: taskSyncAgent.id, data: `Syncing issue tasks: ${issueId}` });
|
|
32
34
|
const startTime = Date.now();
|
|
33
35
|
const taskSyncWorkingDir = resolveIssueWorkspaceRoot(workspaceId);
|
|
36
|
+
const workspace = workspaceService.getById(workspaceId);
|
|
34
37
|
const progress = createIssueAgentProgress(workspaceId, issue, taskSyncPreset, taskSyncAgent.id, {
|
|
35
38
|
runtime: taskSyncPreset.runtimeKind,
|
|
36
39
|
model: taskSyncPreset.modelId,
|
|
@@ -53,7 +56,8 @@ export async function syncIssueTasksAfterPlanning(workspaceId, issueId, input, c
|
|
|
53
56
|
skills: [],
|
|
54
57
|
configDir: agentService.getAgentConfigDir(workspaceId, taskSyncPreset),
|
|
55
58
|
sandboxDirs: taskSyncPreset.sandboxDirs,
|
|
56
|
-
|
|
59
|
+
outputStyle: taskSyncPreset.outputStyle,
|
|
60
|
+
onEvent: wrapOnEventWithHooks(taskSyncTracker.handleEvent.bind(taskSyncTracker), workspaceId, workspace?.hooksEnabled),
|
|
57
61
|
});
|
|
58
62
|
if (taskSyncTracker.output.length === 0) {
|
|
59
63
|
for (const line of result.output) {
|
|
@@ -101,7 +105,10 @@ export async function syncIssueTasksAfterPlanning(workspaceId, issueId, input, c
|
|
|
101
105
|
updateIssueStatus(workspaceId, issueId, 'in_progress', ctx);
|
|
102
106
|
await scheduleRunnableIssueTasks(workspaceId, issueId, ctx);
|
|
103
107
|
}
|
|
104
|
-
export async function scheduleRunnableIssueTasks(workspaceId, issueId, ctx) {
|
|
108
|
+
export async function scheduleRunnableIssueTasks(workspaceId, issueId, ctx, _options = {}) {
|
|
109
|
+
const issue = issueService.getById(workspaceId, issueId);
|
|
110
|
+
if (!issue)
|
|
111
|
+
return;
|
|
105
112
|
const tasks = taskService.list(workspaceId, issueId);
|
|
106
113
|
const doneIds = new Set(tasks.filter((task) => task.status === 'done').map((task) => task.id));
|
|
107
114
|
const hasActive = tasks.some((task) => ACTIVE_TASK_STATUSES.includes(task.status));
|
|
@@ -113,7 +120,8 @@ export async function scheduleRunnableIssueTasks(workspaceId, issueId, ctx) {
|
|
|
113
120
|
}
|
|
114
121
|
return;
|
|
115
122
|
}
|
|
116
|
-
|
|
123
|
+
const tasksToRun = issue.continuousRun === false ? runnable.slice(0, 1) : runnable;
|
|
124
|
+
for (const task of tasksToRun) {
|
|
117
125
|
await runIssueTask(workspaceId, issueId, task.id, ctx);
|
|
118
126
|
}
|
|
119
127
|
}
|
|
@@ -129,6 +137,8 @@ export async function runIssueTask(workspaceId, issueId, taskId, ctx) {
|
|
|
129
137
|
}
|
|
130
138
|
const taskAgentPreset = findAgentForTask(workspaceId, issue, task);
|
|
131
139
|
if (!taskAgentPreset) {
|
|
140
|
+
if (issueService.getById(workspaceId, issueId)?.status === 'error')
|
|
141
|
+
return;
|
|
132
142
|
const missingExecutorResult = {
|
|
133
143
|
success: false,
|
|
134
144
|
summary: 'No runnable agent configured in issue channel members',
|
|
@@ -161,6 +171,7 @@ export async function runIssueTask(workspaceId, issueId, taskId, ctx) {
|
|
|
161
171
|
broadcastTaskUpdate(ctx, runningTask, task.status);
|
|
162
172
|
agentService.assignTask(workspaceId, taskAgent.id, taskId);
|
|
163
173
|
const runtime = createRuntimeForPreset(taskAgentPreset);
|
|
174
|
+
registerActiveIssueRuntime(workspaceId, issueId, taskAgent.id, runtime);
|
|
164
175
|
const agentWorkingDir = resolveIssueWorkspaceRoot(workspaceId);
|
|
165
176
|
const startTime = Date.now();
|
|
166
177
|
const progress = createIssueAgentProgress(workspaceId, issue, taskAgentPreset, taskAgent.id, {
|
|
@@ -180,20 +191,40 @@ export async function runIssueTask(workspaceId, issueId, taskId, ctx) {
|
|
|
180
191
|
ctx.broadcast('task.output', { taskId, data: line });
|
|
181
192
|
},
|
|
182
193
|
});
|
|
194
|
+
const workspace = workspaceService.getById(workspaceId);
|
|
183
195
|
ctx.broadcast('agent.output', { agentId: taskAgent.id, data: `Executing task: ${runningTask.title}` });
|
|
184
196
|
ctx.broadcast('agent.output', {
|
|
185
197
|
agentId: taskAgent.id,
|
|
186
198
|
data: `[debug] workflow agentConfigId=${taskAgentPreset.id} role=${taskAgentPreset.role} taskAgentConfigId=${runningTask.agentConfigId || '(fallback)'} runtime=${taskAgentPreset.runtimeKind ?? 'open-agent-sdk'}`,
|
|
187
199
|
});
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
200
|
+
let result;
|
|
201
|
+
try {
|
|
202
|
+
result = await runtime.execute(buildIssueAgentPrompt(workspaceId, buildTaskAgentPrompt(issue, runningTask, taskAgentPreset, agentWorkingDir), agentWorkingDir, taskAgentPreset), agentWorkingDir, {
|
|
203
|
+
maxTurns: 100,
|
|
204
|
+
mcpServers: agentService.getMcpServers(taskAgentPreset.mcps),
|
|
205
|
+
functionTools: createCurrentIssueTools(workspaceId, issue, taskAgentPreset),
|
|
206
|
+
skills: agentService.getAvailableSkillNames(agentService.getAgentConfigDir(workspaceId, taskAgentPreset), taskAgentPreset.skills),
|
|
207
|
+
configDir: agentService.getAgentConfigDir(workspaceId, taskAgentPreset),
|
|
208
|
+
sandboxDirs: runningTask.sandboxDirs ?? taskAgentPreset.sandboxDirs,
|
|
209
|
+
outputStyle: taskAgentPreset.outputStyle,
|
|
210
|
+
onEvent: wrapOnEventWithHooks(agentTracker.handleEvent.bind(agentTracker), workspaceId, workspace?.hooksEnabled),
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
finally {
|
|
214
|
+
unregisterActiveIssueRuntime(workspaceId, issueId, taskAgent.id);
|
|
215
|
+
}
|
|
216
|
+
if (issueService.getById(workspaceId, issueId)?.status === 'error') {
|
|
217
|
+
const failedTask = taskService.updateStatus(workspaceId, taskId, 'failed', {
|
|
218
|
+
result: {
|
|
219
|
+
success: false,
|
|
220
|
+
summary: 'Interrupted by user',
|
|
221
|
+
artifacts: [],
|
|
222
|
+
error: 'Interrupted by user',
|
|
223
|
+
},
|
|
224
|
+
});
|
|
225
|
+
broadcastTaskUpdate(ctx, failedTask, 'running');
|
|
226
|
+
return;
|
|
227
|
+
}
|
|
197
228
|
if (agentTracker.output.length === 0) {
|
|
198
229
|
for (const line of result.output) {
|
|
199
230
|
agentTracker.output.push(line);
|
|
@@ -235,10 +266,42 @@ export async function runIssueTask(workspaceId, issueId, taskId, ctx) {
|
|
|
235
266
|
}
|
|
236
267
|
const completedTask = taskService.complete(workspaceId, taskId, result);
|
|
237
268
|
broadcastTaskUpdate(ctx, completedTask, 'running');
|
|
238
|
-
|
|
269
|
+
if (issueService.getById(workspaceId, issueId)?.continuousRun !== false) {
|
|
270
|
+
await scheduleRunnableIssueTasks(workspaceId, issueId, ctx);
|
|
271
|
+
}
|
|
239
272
|
}
|
|
240
273
|
export async function continueIssueTaskScheduling(workspaceId, issueId, ctx) {
|
|
241
|
-
await scheduleRunnableIssueTasks(workspaceId, issueId, ctx);
|
|
274
|
+
await scheduleRunnableIssueTasks(workspaceId, issueId, ctx, { force: true });
|
|
275
|
+
}
|
|
276
|
+
export function stopIssueAutomation(workspaceId, issueId, reason = 'Interrupted by user') {
|
|
277
|
+
const key = issueRunKey(workspaceId, issueId);
|
|
278
|
+
const runtimes = activeIssueRuntimes.get(key);
|
|
279
|
+
if (runtimes) {
|
|
280
|
+
for (const [agentId, runtime] of runtimes.entries()) {
|
|
281
|
+
try {
|
|
282
|
+
runtime.stop();
|
|
283
|
+
}
|
|
284
|
+
catch {
|
|
285
|
+
// Runtime may already be unwinding.
|
|
286
|
+
}
|
|
287
|
+
agentService.complete(workspaceId, agentId, reason);
|
|
288
|
+
}
|
|
289
|
+
activeIssueRuntimes.delete(key);
|
|
290
|
+
}
|
|
291
|
+
const activeTasks = taskService.list(workspaceId, issueId)
|
|
292
|
+
.filter((task) => ACTIVE_TASK_STATUSES.includes(task.status));
|
|
293
|
+
return activeTasks.map((task) => {
|
|
294
|
+
const from = task.status;
|
|
295
|
+
const failed = taskService.updateStatus(workspaceId, task.id, 'failed', {
|
|
296
|
+
result: {
|
|
297
|
+
success: false,
|
|
298
|
+
summary: reason,
|
|
299
|
+
artifacts: [],
|
|
300
|
+
error: reason,
|
|
301
|
+
},
|
|
302
|
+
});
|
|
303
|
+
return failed ? { task: failed, from } : null;
|
|
304
|
+
}).filter((item) => Boolean(item));
|
|
242
305
|
}
|
|
243
306
|
function createTaskSyncTools(workspaceId, issue, preset, ctx) {
|
|
244
307
|
return [
|
|
@@ -417,6 +480,24 @@ async function handleTaskFailure(workspaceId, issueId, taskId, result, ctx) {
|
|
|
417
480
|
ctx.broadcast('issue.status_changed', { issueId, from: issue?.status ?? 'in_progress', to: 'error' });
|
|
418
481
|
ctx.broadcast('issue.updated', updated);
|
|
419
482
|
}
|
|
483
|
+
function registerActiveIssueRuntime(workspaceId, issueId, agentId, runtime) {
|
|
484
|
+
const key = issueRunKey(workspaceId, issueId);
|
|
485
|
+
const runtimes = activeIssueRuntimes.get(key) ?? new Map();
|
|
486
|
+
runtimes.set(agentId, runtime);
|
|
487
|
+
activeIssueRuntimes.set(key, runtimes);
|
|
488
|
+
}
|
|
489
|
+
function unregisterActiveIssueRuntime(workspaceId, issueId, agentId) {
|
|
490
|
+
const key = issueRunKey(workspaceId, issueId);
|
|
491
|
+
const runtimes = activeIssueRuntimes.get(key);
|
|
492
|
+
if (!runtimes)
|
|
493
|
+
return;
|
|
494
|
+
runtimes.delete(agentId);
|
|
495
|
+
if (runtimes.size === 0)
|
|
496
|
+
activeIssueRuntimes.delete(key);
|
|
497
|
+
}
|
|
498
|
+
function issueRunKey(workspaceId, issueId) {
|
|
499
|
+
return `${workspaceId}:${issueId}`;
|
|
500
|
+
}
|
|
420
501
|
function broadcastTaskUpdate(ctx, task, from) {
|
|
421
502
|
if (!task)
|
|
422
503
|
return;
|