@agent-spaces/server 0.3.62 → 0.3.64
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 +3 -0
- package/dist/adapters/claude-code-runtime/message-format.js +1 -1
- package/dist/adapters/codex-runtime.js +2 -2
- package/dist/adapters/git.js +161 -57
- package/dist/adapters/langchain-runtime.js +2 -2
- package/dist/adapters/open-agent-sdk-runtime.js +2 -2
- package/dist/agents/agent-designer.js +66 -12
- 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 +96 -15
- package/dist/app.js +123 -5
- package/dist/package.json +1 -1
- package/dist/routes/agent-commands.js +72 -0
- package/dist/routes/agent-sse.js +10 -2
- package/dist/routes/agent.js +15 -1
- package/dist/routes/database.js +345 -0
- package/dist/routes/git.js +52 -1
- package/dist/routes/hooks.js +88 -0
- package/dist/routes/issue.js +59 -1
- package/dist/routes/kanban.js +39 -0
- package/dist/routes/output-style.js +48 -0
- package/dist/routes/prompt-template.js +2 -2
- package/dist/routes/skill.js +86 -15
- package/dist/routes/task.js +13 -1
- package/dist/services/agent-commands.js +168 -0
- package/dist/services/builtin-tools/command-tools.js +117 -0
- package/dist/services/builtin-tools/database-tools.js +578 -0
- package/dist/services/builtin-tools/index.js +5 -0
- package/dist/services/builtin-tools/input-helpers.js +26 -0
- package/dist/services/builtin-tools/issue-tools.js +209 -0
- package/dist/services/builtin-tools/kanban-tools.js +277 -0
- package/dist/services/database-vector.js +244 -0
- package/dist/services/hook-engine.js +118 -0
- package/dist/services/issue.js +6 -0
- package/dist/services/kanban.js +50 -0
- package/dist/services/notification-hub/bot-agent.js +1 -0
- package/dist/services/output-style.js +134 -0
- package/dist/services/prompt-template.js +2 -2
- package/dist/services/skill.js +148 -35
- package/dist/storage/database-store.js +365 -0
- package/dist/storage/hook-store.js +55 -0
- package/dist/storage/kanban-store.js +142 -0
- package/dist/web/404.html +1 -1
- package/dist/web/__next.__PAGE__.txt +4 -4
- package/dist/web/__next._full.txt +26 -30
- package/dist/web/__next._head.txt +4 -4
- package/dist/web/__next._index.txt +14 -14
- package/dist/web/__next._tree.txt +3 -8
- package/dist/web/_next/static/chunks/0-9194nbxy_6d.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/01iqv28_snwus.js +1 -0
- package/dist/web/_next/static/chunks/01~quun6sefgl.js +1 -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/04a4vsq2wknm4.js +1 -0
- package/dist/web/_next/static/chunks/04dg4l4hv11q2.js +3 -0
- package/dist/web/_next/static/chunks/04fxddw-y20~-.js +7 -0
- package/dist/web/_next/static/chunks/04w7~5ooz_pwm.js +1 -0
- package/dist/web/_next/static/chunks/05oc21sj24wtq.js +1 -0
- package/dist/web/_next/static/chunks/{0zd1o3u04~qvo.js → 05psi2gtx~bev.js} +7 -7
- package/dist/web/_next/static/chunks/{0-oog4zg4_m~m.css → 062f9zqctzg.b.css} +0 -3
- package/dist/web/_next/static/chunks/{12odetnu-lyrr.js → 06whz1~s_7pva.js} +12 -12
- package/dist/web/_next/static/chunks/08ckpwmmwlors.js +3 -0
- package/dist/web/_next/static/chunks/08k~meqbd8d6v.js +1 -0
- package/dist/web/_next/static/chunks/099h96wjsdb25.js +2 -0
- package/dist/web/_next/static/chunks/09h23logvq65m.js +1 -0
- package/dist/web/_next/static/chunks/{0njy89g5coeyi.js → 0_8dm7bxp18xo.js} +6 -6
- package/dist/web/_next/static/chunks/0_mvduwjsm35w.js +1 -0
- package/dist/web/_next/static/chunks/0_vi1a~g4wx46.js +3 -0
- package/dist/web/_next/static/chunks/0a5y-vhf4i5id.js +3 -0
- package/dist/web/_next/static/chunks/0ake2f3x2uan4.js +24 -0
- package/dist/web/_next/static/chunks/{0tvd~rxgf0oh_.js → 0bbmx45w_h5np.js} +1 -1
- package/dist/web/_next/static/chunks/0ck8dw_9-1cdx.js +1 -0
- package/dist/web/_next/static/chunks/{07a0rktf_nr5h.js → 0ctg5qmw7uu.1.js} +2 -2
- package/dist/web/_next/static/chunks/0ewceguykiut5.js +1 -0
- package/dist/web/_next/static/chunks/0f7cb9li~3jra.js +67 -0
- package/dist/web/_next/static/chunks/0fttswpzu69qx.js +1 -0
- package/dist/web/_next/static/chunks/0ghs9on7wodrm.js +1 -0
- package/dist/web/_next/static/chunks/0ghx3j_.-gdyd.js +1 -0
- package/dist/web/_next/static/chunks/{0202ia13sijwb.js → 0h18ej5yf974e.js} +1 -1
- package/dist/web/_next/static/chunks/0h9cu-k6z5o08.js +1 -0
- package/dist/web/_next/static/chunks/0i39jifmxla7q.js +1 -0
- package/dist/web/_next/static/chunks/0iuf30t0rjsjv.js +19 -0
- package/dist/web/_next/static/chunks/0jb4~3qqkw2ps.js +1 -0
- package/dist/web/_next/static/chunks/0k4zdm72k_bfy.js +1 -0
- package/dist/web/_next/static/chunks/{08o-zmr-40r5g.js → 0m11vvph7q94-.js} +1 -1
- package/dist/web/_next/static/chunks/0n6_4so_afuwk.js +71 -0
- package/dist/web/_next/static/chunks/0nb8.iteznuvx.js +1 -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/{0d_dp_4ofz0l3.css → 0ojcao3hdm36s.css} +0 -1
- package/dist/web/_next/static/chunks/0os58q93stt7j.js +3 -0
- package/dist/web/_next/static/chunks/{0gig.k.rq8d0x.js → 0ppr271hz0xoq.js} +1 -1
- package/dist/web/_next/static/chunks/0s9lmk8iauou3.js +1 -0
- package/dist/web/_next/static/chunks/0sp_zbx~w0am7.js +1 -0
- package/dist/web/_next/static/chunks/0tel~zsv4z8l_.js +1 -0
- package/dist/web/_next/static/chunks/0twamv4wr_dbv.js +1 -0
- package/dist/web/_next/static/chunks/0uhol5wafdbl~.js +1 -0
- package/dist/web/_next/static/chunks/0v3a_x4vt42kx.js +5 -0
- package/dist/web/_next/static/chunks/{002-dxhags4dj.js → 0v6hte2z-32ca.js} +2 -2
- package/dist/web/_next/static/chunks/0v7q4mys.mnm..css +1 -0
- package/dist/web/_next/static/chunks/0vbqaynjq8ga..js +3 -0
- package/dist/web/_next/static/chunks/0xbaakj0dfc0..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/0za1r07-6az6w.js +1 -0
- package/dist/web/_next/static/chunks/0z~vqzbm_q371.js +1 -0
- package/dist/web/_next/static/chunks/0~3xm80~j9ddg.js +1 -0
- package/dist/web/_next/static/chunks/0~u.5r3-t7179.js +1 -0
- package/dist/web/_next/static/chunks/10l-9myrdo3x9.js +1 -0
- package/dist/web/_next/static/chunks/11-czmcci_55y.js +1 -0
- package/dist/web/_next/static/chunks/11k-.49r~1mfm.js +1 -0
- package/dist/web/_next/static/chunks/{0k.8qdk7oi_os.js → 128ugqd34tr_-.js} +1 -1
- package/dist/web/_next/static/chunks/12jm4gwmvq-0q.js +90 -0
- package/dist/web/_next/static/chunks/{0rke_patcovgr.js → 1442stwa0gbxe.js} +1 -1
- package/dist/web/_next/static/chunks/{0jokpgh485~28.js → 14hqmid8q4apf.js} +11 -11
- package/dist/web/_next/static/chunks/14s37n6h0_q3x.js +16 -0
- package/dist/web/_next/static/chunks/161ik5kfyuwtd.js +1 -0
- package/dist/web/_next/static/chunks/16sg-lflc8csx.js +1 -0
- package/dist/web/_next/static/chunks/17k~zbv0_4rep.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 +30 -31
- package/dist/web/_not-found/__next._head.txt +4 -4
- package/dist/web/_not-found/__next._index.txt +14 -14
- 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 +3 -3
- package/dist/web/_not-found.html +1 -1
- package/dist/web/_not-found.txt +30 -31
- package/dist/web/index.html +1 -1
- package/dist/web/index.txt +26 -30
- package/dist/web/login/__next._full.txt +32 -36
- package/dist/web/login/__next._head.txt +4 -4
- package/dist/web/login/__next._index.txt +14 -14
- package/dist/web/login/__next._tree.txt +3 -8
- 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 +32 -36
- package/dist/web/settings/__next._full.txt +29 -34
- package/dist/web/settings/__next._head.txt +4 -4
- package/dist/web/settings/__next._index.txt +14 -14
- package/dist/web/settings/__next._tree.txt +3 -8
- 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 +27 -32
- package/dist/web/settings/agents/__next._head.txt +4 -4
- package/dist/web/settings/agents/__next._index.txt +14 -14
- package/dist/web/settings/agents/__next._tree.txt +3 -8
- 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 +27 -32
- package/dist/web/settings/mcps/__next._full.txt +27 -32
- package/dist/web/settings/mcps/__next._head.txt +4 -4
- package/dist/web/settings/mcps/__next._index.txt +14 -14
- package/dist/web/settings/mcps/__next._tree.txt +3 -8
- 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 +27 -32
- package/dist/web/settings/models/__next._full.txt +27 -32
- package/dist/web/settings/models/__next._head.txt +4 -4
- package/dist/web/settings/models/__next._index.txt +14 -14
- package/dist/web/settings/models/__next._tree.txt +3 -8
- 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 +27 -32
- package/dist/web/settings/output-styles/__next._full.txt +38 -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 +3 -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 +38 -0
- package/dist/web/settings/prompts/__next._full.txt +27 -32
- package/dist/web/settings/prompts/__next._head.txt +4 -4
- package/dist/web/settings/prompts/__next._index.txt +14 -14
- package/dist/web/settings/prompts/__next._tree.txt +3 -8
- 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 +27 -32
- package/dist/web/settings/providers/__next._full.txt +27 -32
- package/dist/web/settings/providers/__next._head.txt +4 -4
- package/dist/web/settings/providers/__next._index.txt +14 -14
- package/dist/web/settings/providers/__next._tree.txt +3 -8
- 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 +27 -32
- package/dist/web/settings/skills/__next._full.txt +27 -32
- package/dist/web/settings/skills/__next._head.txt +4 -4
- package/dist/web/settings/skills/__next._index.txt +14 -14
- package/dist/web/settings/skills/__next._tree.txt +3 -8
- 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 +27 -32
- package/dist/web/settings/tools/__next._full.txt +38 -0
- package/dist/web/settings/tools/__next._head.txt +6 -0
- package/dist/web/settings/tools/__next._index.txt +15 -0
- package/dist/web/settings/tools/__next._tree.txt +3 -0
- package/dist/web/settings/tools/__next.settings.tools.__PAGE__.txt +9 -0
- package/dist/web/settings/tools/__next.settings.tools.txt +5 -0
- package/dist/web/settings/tools/__next.settings.txt +7 -0
- package/dist/web/settings/tools.html +1 -0
- package/dist/web/settings/tools.txt +38 -0
- package/dist/web/settings.html +1 -1
- package/dist/web/settings.txt +29 -34
- package/dist/web/workflows/__next._full.txt +34 -37
- package/dist/web/workflows/__next._head.txt +4 -4
- package/dist/web/workflows/__next._index.txt +14 -14
- package/dist/web/workflows/__next._tree.txt +3 -8
- 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 +34 -37
- package/dist/web/workspace/_/__next._full.txt +32 -77
- package/dist/web/workspace/_/__next._head.txt +4 -4
- package/dist/web/workspace/_/__next._index.txt +14 -14
- package/dist/web/workspace/_/__next._tree.txt +4 -23
- 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 +32 -77
- package/dist/web/workspaces/__next._full.txt +32 -38
- package/dist/web/workspaces/__next._head.txt +4 -4
- package/dist/web/workspaces/__next._index.txt +14 -14
- package/dist/web/workspaces/__next._tree.txt +3 -8
- 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 +32 -38
- package/dist/ws/agent-prompt.js +45 -8
- package/dist/ws/agent-runner.js +10 -6
- package/package.json +11 -10
- 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-81wi7xr2nd-.js +0 -270
- package/dist/web/_next/static/chunks/00lca9lsasdm7.js +0 -1
- package/dist/web/_next/static/chunks/01gi~q0c6ez6..js +0 -1
- package/dist/web/_next/static/chunks/02shswpmybici.js +0 -1
- package/dist/web/_next/static/chunks/05tx6hzdtkgi9.js +0 -2
- package/dist/web/_next/static/chunks/07nbyndvzftr1.js +0 -3
- package/dist/web/_next/static/chunks/0bn~onkv~9xza.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/0i51q.5s_-.vh.css +0 -1
- package/dist/web/_next/static/chunks/0qf163pbrwy4z.js +0 -1
- package/dist/web/_next/static/chunks/0rnt-f3pjxb-d.js +0 -5
- package/dist/web/_next/static/chunks/0tgbcgsca9mrg.js +0 -1
- package/dist/web/_next/static/chunks/0tyhv6.y7~yxd.js +0 -1
- package/dist/web/_next/static/chunks/0u7_qd9hzqwac.js +0 -1
- package/dist/web/_next/static/chunks/0vuvql8rloda5.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/0xmmk3vebw8xs.js +0 -1
- package/dist/web/_next/static/chunks/0xwqf.llmm_u2.js +0 -31
- package/dist/web/_next/static/chunks/0yo22_w53mo~5.js +0 -1
- package/dist/web/_next/static/chunks/12c0jp0qvlr1t.js +0 -1
- package/dist/web/_next/static/chunks/12pg1nn3v~~5k.js +0 -1
- package/dist/web/_next/static/chunks/16cyr8ilpx1nn.js +0 -1
- package/dist/web/_next/static/media/0a7740363b4d4863-s.1110aazvokzp..woff2 +0 -0
- package/dist/web/_next/static/media/0da9c7f357bd9d4d-s.0ek5sshv8wk3m.woff2 +0 -0
- package/dist/web/_next/static/media/1b99372b3eaef0c8-s.p.0gx2haw2tmll8.woff2 +0 -0
- package/dist/web/_next/static/media/41e95f694c5c4549-s.0r1jrq7neqdsq.woff2 +0 -0
- package/dist/web/_next/static/media/5c285b27cdda1fe8-s.p.0yo6-5yoeeudq.woff2 +0 -0
- package/dist/web/_next/static/media/5f9d24ebef5d5292-s.0esuu2f5si~v8.woff2 +0 -0
- package/dist/web/_next/static/media/6c55a692938ebbbc-s.0g6rbszwfgn9y.woff2 +0 -0
- package/dist/web/_next/static/media/8e6fa89aa22d24ec-s.p.0uvzar8hswo3p.woff2 +0 -0
- package/dist/web/_next/static/media/a218039a3287bcfd-s.p.17-1enzs_j91b.woff2 +0 -0
- package/dist/web/_next/static/media/b2ea385cb5ae8625-s.0kjod.kaq1k69.woff2 +0 -0
- package/dist/web/_next/static/media/bdc7e24a509eb931-s.0apt5mko2.qn3.woff2 +0 -0
- package/dist/web/_next/static/media/c3cb240f9c892514-s.163v2i5cux7-c.woff2 +0 -0
- package/dist/web/_next/static/media/e2334d715941921e-s.p.12skym0rqknxy.woff2 +0 -0
- 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/{GS3b40oeaeLxm7i9-ibaj → e8w3vd9Eov_LDYWj_0zsE}/_buildManifest.js +0 -0
- /package/dist/web/_next/static/{GS3b40oeaeLxm7i9-ibaj → e8w3vd9Eov_LDYWj_0zsE}/_clientMiddlewareManifest.js +0 -0
- /package/dist/web/_next/static/{GS3b40oeaeLxm7i9-ibaj → e8w3vd9Eov_LDYWj_0zsE}/_ssgManifest.js +0 -0
- /package/public/avatars/{1777815865622-08wp9m-user.jpg → user.jpg} +0 -0
|
@@ -5,11 +5,13 @@ import * as issueService from '../services/issue.js';
|
|
|
5
5
|
import * as taskService from '../services/task.js';
|
|
6
6
|
import * as workspaceService from '../services/workspace.js';
|
|
7
7
|
import { mapWorkflowToTaskDrafts, validateWorkflowForRun } from '../services/workflow.js';
|
|
8
|
-
import { createIssueFunctionTools } from '../services/builtin-tools.js';
|
|
8
|
+
import { createIssueFunctionTools } from '../services/builtin-tools/index.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;
|
package/dist/app.js
CHANGED
|
@@ -5,9 +5,9 @@ import express from 'express';
|
|
|
5
5
|
import cors from 'cors';
|
|
6
6
|
import { createServer } from 'node:http';
|
|
7
7
|
import { WebSocketServer } from 'ws';
|
|
8
|
-
import { existsSync, mkdirSync } from 'node:fs';
|
|
8
|
+
import { existsSync, mkdirSync, readFileSync, readdirSync, writeFileSync } from 'node:fs';
|
|
9
9
|
import { writeFile } from 'node:fs/promises';
|
|
10
|
-
import { join, dirname } from 'node:path';
|
|
10
|
+
import { join, dirname, extname, basename } from 'node:path';
|
|
11
11
|
import { fileURLToPath } from 'node:url';
|
|
12
12
|
import workspaceRouter from './routes/workspace.js';
|
|
13
13
|
import fileRouter from './routes/file.js';
|
|
@@ -22,14 +22,19 @@ import authRouter from './routes/auth.js';
|
|
|
22
22
|
import folderRouter from './routes/folder.js';
|
|
23
23
|
import commandRouter from './routes/command.js';
|
|
24
24
|
import codeFavoritesRouter from './routes/code-favorites.js';
|
|
25
|
+
import hooksRouter from './routes/hooks.js';
|
|
25
26
|
import skillRouter from './routes/skill.js';
|
|
26
27
|
import promptTemplateRouter from './routes/prompt-template.js';
|
|
28
|
+
import outputStyleRouter from './routes/output-style.js';
|
|
27
29
|
import mcpRouter from './routes/mcp.js';
|
|
28
30
|
import subscriptionRouter from './routes/subscription.js';
|
|
29
31
|
import agentSseRouter from './routes/agent-sse.js';
|
|
30
32
|
import searchRouter from './routes/search.js';
|
|
31
33
|
import notificationRouter from './routes/notification.js';
|
|
34
|
+
import databaseRouter from './routes/database.js';
|
|
35
|
+
import kanbanRouter from './routes/kanban.js';
|
|
32
36
|
import speechRecognitionRouter, { handleSpeechStream } from './routes/speech-recognition.js';
|
|
37
|
+
import agentCommandsRouter from './routes/agent-commands.js';
|
|
33
38
|
import { getUserSettings, setUserAvatarUrl, removeUserAvatarUrl } from './storage/user-settings-store.js';
|
|
34
39
|
import { authMiddleware, verifyToken } from './middleware/auth.js';
|
|
35
40
|
import { handleConnection } from './ws/handler.js';
|
|
@@ -65,6 +70,73 @@ app.use('/api', authMiddleware);
|
|
|
65
70
|
// Serve static files from public/
|
|
66
71
|
const publicDir = resolveRuntimeDir('public');
|
|
67
72
|
app.use('/public', express.static(publicDir));
|
|
73
|
+
// Scan public/prompt/ and generate index.json for the prompt store
|
|
74
|
+
function scanPromptStore() {
|
|
75
|
+
const promptDir = join(publicDir, 'prompt');
|
|
76
|
+
if (!existsSync(promptDir))
|
|
77
|
+
return;
|
|
78
|
+
const files = readdirSync(promptDir).filter((f) => f.endsWith('.md'));
|
|
79
|
+
const index = files.map((filename) => {
|
|
80
|
+
const id = basename(filename, '.md');
|
|
81
|
+
const content = readFileSync(join(promptDir, filename), 'utf-8');
|
|
82
|
+
const firstHeading = content.split('\n').find((l) => /^#\s+/.test(l));
|
|
83
|
+
const name = firstHeading ? firstHeading.replace(/^#\s+/, '').trim() : id.replace(/[-_]/g, ' ');
|
|
84
|
+
return { id, name, filename };
|
|
85
|
+
});
|
|
86
|
+
writeFileSync(join(promptDir, 'index.json'), JSON.stringify(index, null, 2), 'utf-8');
|
|
87
|
+
console.log(`[prompt-store] scanned ${index.length} templates`);
|
|
88
|
+
}
|
|
89
|
+
scanPromptStore();
|
|
90
|
+
// Scan public/output-styles/ and generate index.json
|
|
91
|
+
function scanOutputStyleStore() {
|
|
92
|
+
const dir = join(publicDir, 'output-styles');
|
|
93
|
+
if (!existsSync(dir))
|
|
94
|
+
return;
|
|
95
|
+
const files = readdirSync(dir).filter((f) => f.endsWith('.md'));
|
|
96
|
+
const index = files.map((filename) => {
|
|
97
|
+
const id = basename(filename, '.md');
|
|
98
|
+
const content = readFileSync(join(dir, filename), 'utf-8');
|
|
99
|
+
const firstHeading = content.split('\n').find((l) => /^#\s+/.test(l));
|
|
100
|
+
const name = firstHeading ? firstHeading.replace(/^#\s+/, '').trim() : id.replace(/[-_]/g, ' ');
|
|
101
|
+
return { id, name, filename };
|
|
102
|
+
});
|
|
103
|
+
writeFileSync(join(dir, 'index.json'), JSON.stringify(index, null, 2), 'utf-8');
|
|
104
|
+
console.log(`[output-style-store] scanned ${index.length} templates`);
|
|
105
|
+
}
|
|
106
|
+
scanOutputStyleStore();
|
|
107
|
+
// Scan public/skills/{group}/{skill-name}/SKILL.md and generate index.json
|
|
108
|
+
function scanSkillStore() {
|
|
109
|
+
const dir = join(publicDir, 'skills');
|
|
110
|
+
if (!existsSync(dir))
|
|
111
|
+
return;
|
|
112
|
+
const index = [];
|
|
113
|
+
for (const groupEntry of readdirSync(dir, { withFileTypes: true })) {
|
|
114
|
+
if (!groupEntry.isDirectory())
|
|
115
|
+
continue;
|
|
116
|
+
const group = groupEntry.name;
|
|
117
|
+
const groupDir = join(dir, group);
|
|
118
|
+
for (const skillEntry of readdirSync(groupDir, { withFileTypes: true })) {
|
|
119
|
+
if (!skillEntry.isDirectory())
|
|
120
|
+
continue;
|
|
121
|
+
const skillName = skillEntry.name;
|
|
122
|
+
const skillFile = join(groupDir, skillName, 'SKILL.md');
|
|
123
|
+
if (!existsSync(skillFile))
|
|
124
|
+
continue;
|
|
125
|
+
const content = readFileSync(skillFile, 'utf-8');
|
|
126
|
+
const fm = content.match(/^---\r?\n([\s\S]*?)\r?\n---/);
|
|
127
|
+
let name = skillName;
|
|
128
|
+
if (fm) {
|
|
129
|
+
const nameLine = fm[1].split(/\r?\n/).find((l) => /^\s*name\s*:/i.test(l));
|
|
130
|
+
if (nameLine)
|
|
131
|
+
name = nameLine.split(':', 2)[1].trim() || skillName;
|
|
132
|
+
}
|
|
133
|
+
index.push({ id: skillName, name, group, path: `${group}/${skillName}` });
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
writeFileSync(join(dir, 'index.json'), JSON.stringify(index, null, 2), 'utf-8');
|
|
137
|
+
console.log(`[skill-store] scanned ${index.length} skills`);
|
|
138
|
+
}
|
|
139
|
+
scanSkillStore();
|
|
68
140
|
app.get('/api/health', (_req, res) => {
|
|
69
141
|
res.json({ status: 'ok', timestamp: new Date().toISOString(), platform: process.platform });
|
|
70
142
|
});
|
|
@@ -82,15 +154,56 @@ app.post('/api/upload/avatar', async (req, res) => {
|
|
|
82
154
|
return;
|
|
83
155
|
}
|
|
84
156
|
const [, mime, base64] = match;
|
|
85
|
-
const
|
|
86
|
-
const id = `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
|
|
87
|
-
const name = filename ? `${id}-${filename.replace(/[^a-zA-Z0-9._-]/g, '_')}` : `${id}.${ext}`;
|
|
157
|
+
const name = 'user.jpg';
|
|
88
158
|
const avatarsDir = join(publicDir, 'avatars');
|
|
89
159
|
if (!existsSync(avatarsDir))
|
|
90
160
|
mkdirSync(avatarsDir, { recursive: true });
|
|
91
161
|
await writeFile(join(avatarsDir, name), Buffer.from(base64, 'base64'));
|
|
92
162
|
res.json({ url: `/static/avatars/${name}` });
|
|
93
163
|
});
|
|
164
|
+
// Font upload
|
|
165
|
+
const FONT_EXTS = new Set(['.ttf', '.otf', '.woff', '.woff2']);
|
|
166
|
+
const fontsDir = join(publicDir, 'fonts');
|
|
167
|
+
if (!existsSync(fontsDir))
|
|
168
|
+
mkdirSync(fontsDir, { recursive: true });
|
|
169
|
+
app.get('/api/fonts', (_req, res) => {
|
|
170
|
+
if (!existsSync(fontsDir)) {
|
|
171
|
+
res.json([]);
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
const fonts = readdirSync(fontsDir).filter(f => FONT_EXTS.has(extname(f).toLowerCase()));
|
|
175
|
+
res.json(fonts.map(f => ({ name: f, url: `/static/fonts/${f}` })));
|
|
176
|
+
});
|
|
177
|
+
app.post('/api/fonts/upload', async (req, res) => {
|
|
178
|
+
const { name, content } = req.body;
|
|
179
|
+
if (!name || !content) {
|
|
180
|
+
res.status(400).json({ error: 'name and content are required' });
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
const ext = extname(name).toLowerCase();
|
|
184
|
+
if (!FONT_EXTS.has(ext)) {
|
|
185
|
+
res.status(400).json({ error: 'Unsupported font format' });
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
188
|
+
const safeName = basename(name).replace(/[^a-zA-Z0-9._-]/g, '_');
|
|
189
|
+
await writeFile(join(fontsDir, safeName), Buffer.from(content, 'base64'));
|
|
190
|
+
res.json({ name: safeName, url: `/static/fonts/${safeName}` });
|
|
191
|
+
});
|
|
192
|
+
app.delete('/api/fonts/:name', (req, res) => {
|
|
193
|
+
const name = basename(req.params.name);
|
|
194
|
+
const ext = extname(name).toLowerCase();
|
|
195
|
+
if (!FONT_EXTS.has(ext)) {
|
|
196
|
+
res.status(400).json({ error: 'Invalid font file' });
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
const filePath = join(fontsDir, name);
|
|
200
|
+
if (!existsSync(filePath)) {
|
|
201
|
+
res.status(404).json({ error: 'Font not found' });
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
import('node:fs').then(fs => fs.unlinkSync(filePath));
|
|
205
|
+
res.json({ ok: true });
|
|
206
|
+
});
|
|
94
207
|
// User settings
|
|
95
208
|
app.get('/api/user/settings', (_req, res) => {
|
|
96
209
|
const settings = getUserSettings();
|
|
@@ -113,6 +226,7 @@ app.use('/api/workspaces/:id/issues', issueRouter);
|
|
|
113
226
|
app.use('/api/workflows', workflowRouter);
|
|
114
227
|
app.use('/api/workspaces/:id/commands', commandRouter);
|
|
115
228
|
app.use('/api/workspaces/:id/code-favorites', codeFavoritesRouter);
|
|
229
|
+
app.use('/api/workspaces/:id/hooks', hooksRouter);
|
|
116
230
|
app.use('/api/workspaces/:id/agents', agentRouter);
|
|
117
231
|
app.use('/api/workspaces/:id/tasks', taskRouter);
|
|
118
232
|
app.use('/api/workspaces/:id/git', gitRouter);
|
|
@@ -138,15 +252,19 @@ app.post('/api/git-config', async (req, res) => {
|
|
|
138
252
|
}
|
|
139
253
|
});
|
|
140
254
|
app.use('/api/workspaces/:id/search', searchRouter);
|
|
255
|
+
app.use('/api/workspaces/:id/database', databaseRouter);
|
|
256
|
+
app.use('/api/workspaces/:id/kanban', kanbanRouter);
|
|
141
257
|
app.use('/api/workspaces/:id/notifications', notificationRouter);
|
|
142
258
|
app.use('/api/agents', agentRouter);
|
|
143
259
|
app.use('/api', llmRouter);
|
|
144
260
|
app.use('/api/folder', folderRouter);
|
|
145
261
|
app.use('/api/skills', skillRouter);
|
|
146
262
|
app.use('/api/prompt-templates', promptTemplateRouter);
|
|
263
|
+
app.use('/api/output-styles', outputStyleRouter);
|
|
147
264
|
app.use('/api/mcps', mcpRouter);
|
|
148
265
|
app.use('/api/subscriptions', subscriptionRouter);
|
|
149
266
|
app.use('/api/speech-recognition', speechRecognitionRouter);
|
|
267
|
+
app.use('/api/agent-commands', agentCommandsRouter);
|
|
150
268
|
// Serve static web frontend in production (after API routes, before catch-all)
|
|
151
269
|
const webDir = resolveRuntimeDir('web');
|
|
152
270
|
if (existsSync(webDir)) {
|
package/dist/package.json
CHANGED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { Router } from 'express';
|
|
2
|
+
import { listAgentsWithCommands, listAllCommands, listCommands, getCommand, createCommand, updateCommand, deleteCommand, applyCommandToAgents, } from '../services/agent-commands.js';
|
|
3
|
+
const router = Router();
|
|
4
|
+
router.get('/agents', (_req, res) => {
|
|
5
|
+
res.json(listAgentsWithCommands());
|
|
6
|
+
});
|
|
7
|
+
router.get('/all', (_req, res) => {
|
|
8
|
+
res.json(listAllCommands());
|
|
9
|
+
});
|
|
10
|
+
router.get('/:agentId', (req, res) => {
|
|
11
|
+
const agentId = typeof req.params.agentId === 'string' ? req.params.agentId : req.params.agentId[0];
|
|
12
|
+
res.json(listCommands(agentId));
|
|
13
|
+
});
|
|
14
|
+
router.get('/:agentId/:name', (req, res) => {
|
|
15
|
+
const agentId = typeof req.params.agentId === 'string' ? req.params.agentId : req.params.agentId[0];
|
|
16
|
+
const name = typeof req.params.name === 'string' ? req.params.name : req.params.name[0];
|
|
17
|
+
const group = req.query.group;
|
|
18
|
+
const cmd = getCommand(agentId, name, group);
|
|
19
|
+
if (!cmd) {
|
|
20
|
+
res.status(404).json({ error: 'Command not found' });
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
res.json(cmd);
|
|
24
|
+
});
|
|
25
|
+
router.post('/:agentId', (req, res) => {
|
|
26
|
+
const agentId = typeof req.params.agentId === 'string' ? req.params.agentId : req.params.agentId[0];
|
|
27
|
+
const { name, content, group } = req.body;
|
|
28
|
+
if (!name || !content) {
|
|
29
|
+
res.status(400).json({ error: 'name and content required' });
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
res.json(createCommand(agentId, name, content, group));
|
|
33
|
+
});
|
|
34
|
+
router.put('/:agentId/:name', (req, res) => {
|
|
35
|
+
const agentId = typeof req.params.agentId === 'string' ? req.params.agentId : req.params.agentId[0];
|
|
36
|
+
const name = typeof req.params.name === 'string' ? req.params.name : req.params.name[0];
|
|
37
|
+
const { content, group } = req.body;
|
|
38
|
+
if (!content) {
|
|
39
|
+
res.status(400).json({ error: 'content required' });
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
const cmd = updateCommand(agentId, name, content, group);
|
|
43
|
+
if (!cmd) {
|
|
44
|
+
res.status(404).json({ error: 'Command not found' });
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
res.json(cmd);
|
|
48
|
+
});
|
|
49
|
+
router.delete('/:agentId/:name', (req, res) => {
|
|
50
|
+
const agentId = typeof req.params.agentId === 'string' ? req.params.agentId : req.params.agentId[0];
|
|
51
|
+
const name = typeof req.params.name === 'string' ? req.params.name : req.params.name[0];
|
|
52
|
+
const group = req.query.group;
|
|
53
|
+
const ok = deleteCommand(agentId, name, group);
|
|
54
|
+
if (!ok) {
|
|
55
|
+
res.status(404).json({ error: 'Command not found' });
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
res.json({ success: true });
|
|
59
|
+
});
|
|
60
|
+
router.post('/:agentId/:name/apply', (req, res) => {
|
|
61
|
+
const agentId = typeof req.params.agentId === 'string' ? req.params.agentId : req.params.agentId[0];
|
|
62
|
+
const name = typeof req.params.name === 'string' ? req.params.name : req.params.name[0];
|
|
63
|
+
const { group, agentIds } = req.body;
|
|
64
|
+
if (!Array.isArray(agentIds) || agentIds.length === 0) {
|
|
65
|
+
res.status(400).json({ error: 'agentIds required' });
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
const applied = applyCommandToAgents(agentId, name, group || '', agentIds);
|
|
69
|
+
res.json({ applied });
|
|
70
|
+
});
|
|
71
|
+
export default router;
|
|
72
|
+
//# sourceMappingURL=agent-commands.js.map
|
package/dist/routes/agent-sse.js
CHANGED
|
@@ -5,6 +5,7 @@ import * as agentService from '../services/agent.js';
|
|
|
5
5
|
import * as workspaceService from '../services/workspace.js';
|
|
6
6
|
import { getThinkingRuntimeConfig } from '../services/llm-model-config.js';
|
|
7
7
|
import { buildAgentPrompt } from '../ws/agent-prompt.js';
|
|
8
|
+
import { wrapOnEventWithHooks } from '../services/hook-engine.js';
|
|
8
9
|
const router = Router();
|
|
9
10
|
router.post('/run', async (req, res) => {
|
|
10
11
|
const body = req.body;
|
|
@@ -78,11 +79,12 @@ router.post('/run', async (req, res) => {
|
|
|
78
79
|
skills,
|
|
79
80
|
configDir,
|
|
80
81
|
sandboxDirs: preset.sandboxDirs,
|
|
81
|
-
|
|
82
|
+
outputStyle: body.outputStyle ?? preset.outputStyle,
|
|
83
|
+
onEvent: wrapOnEventWithHooks((event) => {
|
|
82
84
|
if (event.type === 'output')
|
|
83
85
|
output.push(event.line);
|
|
84
86
|
writeSse(res, event.type, serializeRuntimeEvent(event));
|
|
85
|
-
},
|
|
87
|
+
}, workspaceId, workspace?.hooksEnabled),
|
|
86
88
|
});
|
|
87
89
|
completed = true;
|
|
88
90
|
const displayOutput = output.length ? output : result.output;
|
|
@@ -141,11 +143,17 @@ function prepareSse(res) {
|
|
|
141
143
|
res.setHeader('Content-Type', 'text/event-stream; charset=utf-8');
|
|
142
144
|
res.setHeader('Cache-Control', 'no-cache, no-transform');
|
|
143
145
|
res.setHeader('Connection', 'keep-alive');
|
|
146
|
+
res.setHeader('X-Accel-Buffering', 'no');
|
|
144
147
|
res.flushHeaders?.();
|
|
148
|
+
res.socket?.setNoDelay?.(true);
|
|
145
149
|
}
|
|
146
150
|
function writeSse(res, event, data) {
|
|
147
151
|
res.write(`event: ${event}\n`);
|
|
148
152
|
res.write(`data: ${JSON.stringify(data)}\n\n`);
|
|
153
|
+
// Force flush — compression middleware and some proxies buffer small writes
|
|
154
|
+
const flushable = res;
|
|
155
|
+
if (typeof flushable.flush === 'function')
|
|
156
|
+
flushable.flush();
|
|
149
157
|
}
|
|
150
158
|
function resolveUserPrompt(body) {
|
|
151
159
|
const direct = body.prompt ?? body.message;
|
package/dist/routes/agent.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Router } from 'express';
|
|
2
2
|
import * as agentService from '../services/agent.js';
|
|
3
|
-
import { generateAgentDesign } from '../agents/agent-designer.js';
|
|
3
|
+
import { generateAgentDesign, optimizeAgentPrompt } from '../agents/agent-designer.js';
|
|
4
4
|
const router = Router({ mergeParams: true });
|
|
5
5
|
router.get('/usage/dashboard', (req, res) => {
|
|
6
6
|
const days = Number(req.query.days ?? 30);
|
|
@@ -36,6 +36,20 @@ router.post('/presets/generate', async (req, res) => {
|
|
|
36
36
|
res.status(400).json({ error: err instanceof Error ? err.message : 'agent generation failed' });
|
|
37
37
|
}
|
|
38
38
|
});
|
|
39
|
+
router.post('/presets/optimize-prompt', async (req, res) => {
|
|
40
|
+
const { prompt, currentPrompt } = req.body;
|
|
41
|
+
if (!prompt?.trim()) {
|
|
42
|
+
res.status(400).json({ error: 'prompt is required' });
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
try {
|
|
46
|
+
res.json(await optimizeAgentPrompt(prompt, currentPrompt ?? ''));
|
|
47
|
+
}
|
|
48
|
+
catch (err) {
|
|
49
|
+
console.error('[agent-designer] optimize failed', err);
|
|
50
|
+
res.status(400).json({ error: err instanceof Error ? err.message : 'prompt optimization failed' });
|
|
51
|
+
}
|
|
52
|
+
});
|
|
39
53
|
router.post('/presets/test-connection', async (req, res) => {
|
|
40
54
|
const workspaceId = req.params.id;
|
|
41
55
|
const data = req.body;
|