@wular/coder 0.4.1 → 0.4.3
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/README.md +69 -70
- package/dist/actions-FzDNxMFf.js +20 -0
- package/dist/{adapter-BKVzTDnn.js → adapter-7SEiVsmp.js} +1 -1
- package/dist/{adapter-B0oYCI0S.js → adapter-BLEfUqoQ.js} +1 -1
- package/dist/{adapter-DPInwbJG.js → adapter-H4GlcKQz.js} +1 -1
- package/dist/{add-CE-70LFs.js → add-B50dIJGd.js} +1 -1
- package/dist/{add-BxpLHnvD.js → add-D7X3gxap.js} +1 -1
- package/dist/{add-ej0X9e3a.js → add-DOEUHIe7.js} +1 -1
- package/dist/{add-U-pty9qJ.js → add-QExQhTzi.js} +1 -1
- package/dist/{add-json-CEa-6luW.js → add-json-Ck4KIZrT.js} +1 -1
- package/dist/{agent-JdtZozvP.js → agent-BPtnEf1q.js} +1 -1
- package/dist/{agent-BsYx3Odz.js → agent-BlQ_dNNm.js} +2 -2
- package/dist/{alias-DX-Bm86x.js → alias-BwQBovke.js} +1 -1
- package/dist/{app-BT5f7zL5.js → app-y6BYm2eH.js} +1 -1
- package/dist/{approvals-C-AvFt6s.js → approvals-Cc9cq5T1.js} +2 -2
- package/dist/{approve-DOmpQRNd.js → approve-oO9k2fnK.js} +2 -2
- package/dist/{apps-CjfrZyM5.js → apps-CU2YalX8.js} +1 -1
- package/dist/{archive-BziJ1rQ-.js → archive-C5c_HQS1.js} +2 -2
- package/dist/{archive-BUB8gFKD.js → archive-CemlWlVY.js} +2 -2
- package/dist/archive-sweep-ehg-fWIt.js +1 -0
- package/dist/{args-BOEEdpWk.js → args-DcBCtXhz.js} +1 -1
- package/dist/{ask-dE3U3ss2.js → ask-Chu7Twu_.js} +2 -2
- package/dist/auth-BOyXPOtu.js +1 -0
- package/dist/auth-XbqKSbcD.js +1 -0
- package/dist/{chat-bridge-BS9WtP3X.js → chat-bridge-DXgZItGP.js} +1 -1
- package/dist/{chat-B_yhNTo0.js → chat-cknlIhVh.js} +1 -1
- package/dist/{cli-BilSDkvE.js → cli-B1ObVrL4.js} +5 -5
- package/dist/cli.d.ts +1 -1
- package/dist/cli.js +1 -1
- package/dist/{client-D9IoAuDD.js → client-31YzOj-i.js} +1 -1
- package/dist/{config-Da_cwoxI.js → config-DAE_qHYA.js} +1 -1
- package/dist/{create-C_iMJV4Y.js → create-CM8B8JxD.js} +1 -1
- package/dist/credentials-BXD4Qptk.js +1 -0
- package/dist/dash/manifest.json +934 -1014
- package/dist/dash/public/assets/chunks/{agent-pills-c9c4ac4d4a10df83.js → agent-pills-b6a6da91c9559d9f.js} +1 -1
- package/dist/dash/public/assets/chunks/{agent-settings-form-8be2ddab074aba6d.js → agent-settings-form-b615c677046cd6f2.js} +1 -1
- package/dist/dash/public/assets/chunks/agents-grid-f2e7b4ff9e11b6e3.js +1 -0
- package/dist/dash/public/assets/chunks/{badge-676b01e0c615bf7b.js → badge-215c7b2631dafc69.js} +1 -1
- package/dist/dash/public/assets/chunks/{card-e0901d68b79dfa93.js → card-e86dcc81326d2b14.js} +1 -1
- package/dist/dash/public/assets/chunks/{combo-41234c24668b1db1.js → combo-09e246dc9a517fa8.js} +1 -1
- package/dist/dash/public/assets/chunks/composer-417166b029f48c47.js +1 -0
- package/dist/dash/public/assets/chunks/composer-645ae8fa97a35280.js +1 -0
- package/dist/dash/public/assets/chunks/{confirm-f2fe4ba9905a89c6.js → confirm-5ae484241ad888fd.js} +1 -1
- package/dist/dash/public/assets/chunks/{connect-apps-aa2a3d82e48ed8c3.js → connect-apps-4147c45f45fde2b1.js} +1 -1
- package/dist/dash/public/assets/chunks/{connect-repositories-5389ec8701a3deac.js → connect-repositories-77591110836bdf03.js} +1 -1
- package/dist/dash/public/assets/chunks/credentials-list-e005a0783ec93465.js +2 -0
- package/dist/dash/public/assets/chunks/{custom-range-4761ab14f05149df.js → custom-range-463e119af4681c61.js} +1 -1
- package/dist/dash/public/assets/chunks/{editor-bfe8cd854f8001be.js → editor-804b84f4fe6539cd.js} +4 -4
- package/dist/dash/public/assets/chunks/{engines-list-f1191390f5715b39.js → engines-list-ceab51f13c690e8c.js} +1 -1
- package/dist/dash/public/assets/chunks/{field-901f1f35c18c39c9.js → field-aa0a4b98a976781e.js} +1 -1
- package/dist/dash/public/assets/chunks/filter-91144ac2eec6297f.js +1 -0
- package/dist/dash/public/assets/chunks/format-105c706345987fb2.js +1 -0
- package/dist/dash/public/assets/chunks/heads-a42817b32d2d7f08.js +1 -0
- package/dist/dash/public/assets/chunks/{instructions-052fa45a9daf6db6.js → instructions-3a1dcaff2d868aa5.js} +1 -1
- package/dist/dash/public/assets/chunks/instructions-6c6f981fffaa31e4.js +1 -0
- package/dist/dash/public/assets/chunks/{list-1d259660d7612c5f.js → list-7270361464fc3c04.js} +1 -1
- package/dist/dash/public/assets/chunks/{mcp-list-e3bebbbe831393b8.js → mcp-list-2e715d48666b54ad.js} +1 -1
- package/dist/dash/public/assets/chunks/{models-list-44f857a469ca04d5.js → models-list-d3c40f94c761a6e5.js} +1 -1
- package/dist/dash/public/assets/chunks/paged-3ddb6077bef42752.js +1 -0
- package/dist/dash/public/assets/chunks/{platform-actions-d1426602049926d2.js → platform-actions-271ec3b99a64280b.js} +1 -1
- package/dist/dash/public/assets/chunks/runners-list-767e49c7d0ec833a.js +1 -0
- package/dist/dash/public/assets/chunks/{segmented-358ff2b4992b8384.js → segmented-de4386ccaac7304d.js} +1 -1
- package/dist/dash/public/assets/chunks/{select-7ae25fd8a7d6c338.js → select-a90307706cffa6e0.js} +1 -1
- package/dist/dash/public/assets/chunks/{sentinel-c972a33dc69a5135.js → sentinel-b5e032b38604dfd3.js} +1 -1
- package/dist/dash/public/assets/chunks/shared-init-7f81ae7bc8c82438.js +2 -0
- package/dist/dash/public/assets/chunks/shared-init-933c7f9ee85be766.js +5 -0
- package/dist/dash/public/assets/chunks/{tail-7c27aab8ba268bd9.js → tail-4891e727ee526792.js} +1 -1
- package/dist/dash/public/assets/chunks/task-actions-ce854925a2dc78fd.js +1 -0
- package/dist/dash/public/assets/chunks/task-ddfddeaf07fb684c.js +1 -0
- package/dist/dash/public/assets/chunks/task-view-c37dcee08f21a279.js +5 -0
- package/dist/dash/public/assets/chunks/tasks-list-baef587999f322d8.js +1 -0
- package/dist/dash/public/assets/chunks/{toolbar-a75d2570f07cbb70.js → toolbar-8d98313606ad8a2d.js} +1 -1
- package/dist/dash/public/assets/chunks/{versions-list-fc2e0d2a7382e049.js → versions-list-532690efd9f1b0ea.js} +1 -1
- package/dist/dash/public/assets/dash-49ca85b59ac65c20.css +1 -0
- package/dist/dash/public/assets/dash-account-edc56e85dbaaabe0.css +1 -0
- package/dist/dash/public/assets/dash-agents-edba57b67e4005d0.css +1 -0
- package/dist/dash/public/assets/dash-agents-new-fe22253fbada2fbf.css +1 -0
- package/dist/dash/public/assets/dash-agents-param-slug-adf52e9dacb2d825.css +1 -0
- package/dist/dash/public/assets/dash-agents-param-slug-edit-a2937a347689ef29.css +1 -0
- package/dist/dash/public/assets/dash-agents-param-slug-platforms-265ba13db32a460d.css +1 -0
- package/dist/dash/public/assets/dash-agents-param-slug-settings-8afc52eb0372bc4b.css +1 -0
- package/dist/dash/public/assets/dash-agents-param-slug-tasks-6193e646be68dbd2.css +1 -0
- package/dist/dash/public/assets/dash-agents-param-slug-usage-ceadb3a1c911c402.css +1 -0
- package/dist/dash/public/assets/dash-settings-cf1997cd7f72e518.css +1 -0
- package/dist/dash/public/assets/dash-settings-param-tab-b44dac8e79a560e6.css +1 -0
- package/dist/dash/public/assets/dash-tasks-916c7100a8058aa3.css +1 -0
- package/dist/dash/public/assets/dash-tasks-param-id-194a6ffc20e872f2.css +1 -0
- package/dist/dash/public/assets/dash-usage-40940b289f85e0b6.css +1 -0
- package/dist/dash/public/assets/pnext-client-13aee92bef5c9e3f.js +1 -0
- package/dist/dash/public/assets/pnext-client-1f2686b2044f0df6.js +1 -0
- package/dist/dash/public/assets/pnext-client-26130234ebad7067.js +1 -0
- package/dist/dash/public/assets/pnext-client-311e35b0076bf406.js +1 -0
- package/dist/dash/public/assets/pnext-client-4ade1bf75c9c3d87.js +1 -0
- package/dist/dash/public/assets/pnext-client-61cd31b687ede1da.js +1 -0
- package/dist/dash/public/assets/pnext-client-61db65dc4223217a.js +1 -0
- package/dist/dash/public/assets/pnext-client-6ea656e7705e3f2a.js +1 -0
- package/dist/dash/public/assets/pnext-client-7fd0f793f0322cb9.js +1 -0
- package/dist/dash/public/assets/pnext-client-88159c0840fcfa4a.js +1 -0
- package/dist/dash/public/assets/pnext-client-b03f0c47c066b4f3.js +1 -0
- package/dist/dash/public/assets/{pnext-client-1b9ab0963a8ff77b.js → pnext-client-d6478835f543f901.js} +1 -1
- package/dist/dash/public/assets/pnext-client-dadb8359021ed590.js +1 -0
- package/dist/dash/public/assets/pnext-client-de07532d6aaebf2c.js +1 -0
- package/dist/dash/public/assets/pnext-client-f87a31890c8ff224.js +1 -0
- package/dist/dash/public/assets/pnext-client-ffe1c123a8e2a350.js +1 -0
- package/dist/dash/server/bundle-0.1.6-b29ec45cb963d47f/entry.js +2 -0
- package/dist/{default-vYPT26DR.js → default-BMvUMTFp.js} +1 -1
- package/dist/default-B_nKaX0-.js +1 -0
- package/dist/{delete-D8gEwoOj.js → delete-Bjteibld.js} +2 -2
- package/dist/{delete-z1_86nf6.js → delete-riCIKZwj.js} +2 -2
- package/dist/{disable-DVKd-0Xb.js → disable-DQC56YFy.js} +1 -1
- package/dist/{discover-Dvr_3_Xr.js → discover-Qanr5TEO.js} +1 -1
- package/dist/{discover-Df-a8K4R.js → discover-lgTYwoQp.js} +2 -2
- package/dist/dispatch-BsW_1m7e.js +14 -0
- package/dist/{docs-DKJnqZqt.js → docs-DFs7lOJp.js} +1 -1
- package/dist/{docs-BX65z2Iu.js → docs-DKROso-4.js} +2 -2
- package/dist/{enable-C8Zf_wpN.js → enable-D2DqZvcU.js} +1 -1
- package/dist/{env-CRf6wkM2.js → env-YRY3I60r.js} +1 -1
- package/dist/exec-DuUkLMqg.js +11 -0
- package/dist/executor-vMppVLB6.js +10 -0
- package/dist/flow/builtin/review.js +1 -1
- package/dist/flow/index.d.ts +1 -1
- package/dist/flow/index.js +1 -1
- package/dist/{flow-17k25MHt.js → flow-DmERAnR8.js} +1 -1
- package/dist/{github-actions-DwUzm4hC.js → github-actions-C_NkHVJq.js} +1 -1
- package/dist/http-D01Udu4u.js +1 -0
- package/dist/{index-CZjFX5zV.d.ts → index-B1L4zXZH.d.ts} +2 -1
- package/dist/{init-CoMfFxbG.js → init-Bd6JHzBc.js} +1 -1
- package/dist/integrations-B2CavXR1.js +5 -0
- package/dist/integrations-D1Dwy1kt.js +1 -0
- package/dist/lib/broker.js +2 -2
- package/dist/{list-DX-z3SBp.js → list-4Uo-0v9s.js} +1 -1
- package/dist/{list-BAKvxSbh.js → list-B0ujEZhd.js} +3 -3
- package/dist/{list-BYiG8Zav.js → list-B5oa1Bhy.js} +2 -2
- package/dist/{list-BxEywhHU.js → list-BjE_l6la.js} +1 -1
- package/dist/{list-VToARh3C.js → list-Ck9ibCs1.js} +1 -1
- package/dist/{list-CIW2joV1.js → list-DhgK4Zc4.js} +1 -1
- package/dist/{list-DpCf4G-H.js → list-KvL7AUhD.js} +2 -2
- package/dist/{list-C5w01-8q.js → list-byYLBl1U.js} +1 -1
- package/dist/{load-BpEsAn51.js → load-SnZd7xG1.js} +1 -1
- package/dist/{local-H3uvqEbq.js → local-BRy1EUq2.js} +1 -1
- package/dist/log-view-DeJstSkw.js +3 -0
- package/dist/{login-DkkslfBx.js → login-C-ahtDKV.js} +1 -1
- package/dist/{login-BFxX4jJy.js → login-zpwke8g1.js} +1 -1
- package/dist/{logout-BHAtw4Z8.js → logout-CI6Kf-T6.js} +1 -1
- package/dist/{maintenance-C5FklUw3.js → maintenance-BAzr9Jlr.js} +1 -1
- package/dist/{match-CXAjDhg7.js → match-DxV1d49D.js} +1 -1
- package/dist/{mcp-BgKb2Cdk.js → mcp-CmcL1MCG.js} +1 -1
- package/dist/{mcp-CCZOAo06.js → mcp-mhXwtGQT.js} +1 -1
- package/dist/{migrate-N-85_N7J.js → migrate-Czh3TEK5.js} +1 -1
- package/dist/{migrate-C4vM7DQN.js → migrate-w7KfzUAR.js} +1 -1
- package/dist/{model-Bs1StDo3.js → model-JRoTH9QK.js} +1 -1
- package/dist/models-C-S7HqSb.js +1 -0
- package/dist/{prompt-CEuBMNhk.js → prompt-CMXmt2l9.js} +4 -4
- package/dist/{push-CUC55Bqd.js → push-B8BhTyZs.js} +1 -1
- package/dist/queue-CirjEskI.js +117 -0
- package/dist/refresh-Bmy2r1Ee.js +1 -0
- package/dist/{remote-miQNTVRa.js → remote-CxFnEjZl.js} +1 -1
- package/dist/{remove-B93LNkZI.js → remove-C15WLaXT.js} +1 -1
- package/dist/{remove-C5_xggx7.js → remove-CTZYjjSr.js} +1 -1
- package/dist/{remove-eQ8y5C5p.js → remove-CTl-H0f0.js} +1 -1
- package/dist/{remove-CuH8a3L9.js → remove-DX2FVo5b.js} +1 -1
- package/dist/rename-D1g4TnHQ.js +1 -0
- package/dist/{result-BEtQZHaY.js → result-D49VN8PM.js} +3 -3
- package/dist/result-DGWyUHYU.js +18 -0
- package/dist/{resume-DYzKvyEw.js → resume-ywzc7z6A.js} +2 -2
- package/dist/{review-oIBeECZE.js → review-ZC0xG8XY.js} +2 -2
- package/dist/{rotate-key-IdMYH7gg.js → rotate-key-Bf8_99ck.js} +1 -1
- package/dist/{run-CTtd0Znc.js → run-D7SJ-ieT.js} +2 -2
- package/dist/run-DoRQSC_K.js +2 -0
- package/dist/{run-CawRGnOg.js → run-ukCf2Mdy.js} +1 -1
- package/dist/runner-D-REfOUe.js +1 -0
- package/dist/{runner-sUpWJ_k0.js → runner-wDYhkVsM.js} +1 -1
- package/dist/schema-DoNO0dPh.js +1 -0
- package/dist/sdk.d.ts +4 -2
- package/dist/sdk.js +1 -1
- package/dist/serve-BJ_Mbm2m.js +8 -0
- package/dist/{serve-CPnmrKyf.js → serve-C1MMhM1F.js} +2 -2
- package/dist/{serve-GmRO89s5.js → serve-DtrOHaoS.js} +2 -2
- package/dist/{serve-CE8YV2e9.js → serve-P9pFkEnE.js} +1 -1
- package/dist/{serve-BTeomYxW.js → serve-yjSw0B1a.js} +1 -1
- package/dist/{server-Kb22cWfF.js → server-DDWTnmbx.js} +1 -1
- package/dist/{setup-host-GFTUzzZJ.js → setup-host-L6Rnn5Cz.js} +1 -1
- package/dist/{shared-DVtzWhUT.js → shared-XsUX_ZZb.js} +1 -1
- package/dist/{show-COTZEYgc.js → show-CU-jqJ90.js} +1 -1
- package/dist/{show-CMUg8SJu.js → show-DVJmB2u-.js} +1 -1
- package/dist/{status-D26U--p8.js → status-CBydR7LE.js} +1 -1
- package/dist/{steer-C6uARLp5.js → steer-Cm_sHZqs.js} +2 -2
- package/dist/{stop-BrGI3hSS.js → stop-DJS7DAPJ.js} +1 -1
- package/dist/{stop-ByCAlbmN.js → stop-TrebIIuv.js} +2 -2
- package/dist/store-BrNMqJgk.js +42 -0
- package/dist/store-j8icrG0v.js +19 -0
- package/dist/task-C8lmcNsf.js +1 -0
- package/dist/{task-DeglY79z.js → task-CpUI19o2.js} +4 -4
- package/dist/task-CvSqiwxo.js +1 -0
- package/dist/{test-NEbhlxvo.js → test-CDKz4jY_.js} +1 -1
- package/dist/{tools-D0Zfs8Hx.js → tools-DBFeoosk.js} +1 -1
- package/dist/{types-I5Cwtl_K.d.ts → types-DMGBYB_K.d.ts} +3 -1
- package/dist/{unalias-C9NqmSDq.js → unalias-BfQFBnuK.js} +1 -1
- package/dist/{update-BTxYQj7Z.js → update-C4FFOie8.js} +1 -1
- package/dist/{upgrade-hA0yWBvx.js → upgrade-DLJqMnUQ.js} +2 -2
- package/dist/{usage-BhqoCjvE.js → usage-CSh-xwQ2.js} +1 -1
- package/dist/{usage-C4d9X2Uq.js → usage-D8mc4qXK.js} +1 -1
- package/dist/{watch-DtRuC0Wc.js → watch-CQu-tJKZ.js} +2 -2
- package/dist/{watch-CSdj24ct.js → watch-DmwaEvoi.js} +2 -2
- package/dist/{wire-BeT1Axeo.js → wire-DzGLZ3-O.js} +1 -1
- package/dist/worker-BLKTMLqa.js +1 -0
- package/dist/worker-nHemduM_.js +9 -0
- package/dist/{workflow-Dcmdooi8.js → workflow-IrouAus_.js} +1 -1
- package/docs/cli.md +145 -0
- package/docs/mcp.md +1 -1
- package/migrations/0000_initial.sql +8 -0
- package/migrations/meta/0000_snapshot.json +75 -1
- package/migrations/meta/_journal.json +1 -1
- package/package.json +3 -2
- package/plugins/agents/skills/coder/SKILL.md +1 -0
- package/plugins/claude/.claude-plugin/plugin.json +1 -1
- package/plugins/claude/skills/dispatch/SKILL.md +1 -1
- package/plugins/cursor/.cursor-plugin/plugin.json +1 -1
- package/plugins/cursor/skills/coder/SKILL.md +1 -0
- package/src/client/index.ts +10 -2
- package/src/client/types.ts +18 -0
- package/src/core/defaults.ts +36 -0
- package/src/core/task/log-view.ts +120 -6
- package/src/server/dash/app/dash/agents/(list)/agent-menu.tsx +4 -0
- package/src/server/dash/app/dash/agents/(list)/agents-grid.tsx +18 -35
- package/src/server/dash/app/dash/agents/(list)/loading.tsx +7 -1
- package/src/server/dash/app/dash/agents/[slug]/(tabs)/layout.tsx +2 -1
- package/src/server/dash/app/dash/layout.css +58 -1
- package/src/server/dash/app/dash/layout.tsx +29 -7
- package/src/server/dash/app/dash/settings/[tab]/credentials-list.tsx +20 -13
- package/src/server/dash/app/dash/settings/[tab]/page.tsx +1 -1
- package/src/server/dash/app/dash/settings/[tab]/runners-list.tsx +13 -12
- package/src/server/dash/app/dash/tasks/[id]/activity.tsx +49 -4
- package/src/server/dash/app/dash/tasks/[id]/task-actions.tsx +43 -6
- package/src/server/dash/app/dash/tasks/[id]/task-view.css +52 -31
- package/src/server/dash/app/dash/tasks/[id]/task-view.tsx +143 -51
- package/src/server/dash/app/dash/tasks/composer.css +4 -0
- package/src/server/dash/app/dash/tasks/composer.tsx +6 -5
- package/src/server/dash/app/dash/tasks/list/task.ts +29 -1
- package/src/server/dash/app/dash/tasks/list/tasks-list.css +20 -7
- package/src/server/dash/app/dash/tasks/list/tasks-list.tsx +256 -109
- package/src/server/dash/app/dash/tasks/list/tasks-section.tsx +9 -13
- package/src/server/dash/app/dash/tasks/page.tsx +3 -35
- package/src/server/dash/comps/frame/loading-card.tsx +4 -3
- package/src/server/dash/comps/frame/page-head.css +10 -0
- package/src/server/dash/comps/frame/page-head.tsx +3 -2
- package/src/server/dash/comps/frame/task-toasts.tsx +196 -50
- package/src/server/dash/comps/nav/side-toggle.tsx +16 -5
- package/src/server/dash/comps/ui/card.css +1 -0
- package/src/server/dash/comps/ui/filter.css +64 -0
- package/src/server/dash/comps/ui/filter.tsx +336 -0
- package/src/server/dash/comps/ui/icons.ts +2 -0
- package/src/server/dash/comps/ui/menu.tsx +9 -1
- package/src/server/dash/comps/ui/select.tsx +2 -2
- package/src/server/dash/comps/ui/toast.css +3 -2
- package/src/server/dash/comps/ui/toolbar.css +14 -0
- package/src/server/dash/utils/client.ts +21 -0
- package/src/server/dash/utils/format.ts +12 -4
- package/src/server/dash/utils/paged.ts +14 -6
- package/dist/actions-Mk3FSlpJ.js +0 -20
- package/dist/archive-sweep-CtBcARgN.js +0 -1
- package/dist/auth-BFny--17.js +0 -1
- package/dist/auth-DWHIzqbA.js +0 -1
- package/dist/credentials-B1jv6dkg.js +0 -1
- package/dist/dash/public/assets/chunks/agents-grid-951584b6f4c4314e.js +0 -1
- package/dist/dash/public/assets/chunks/composer-5534be50bc12385e.js +0 -1
- package/dist/dash/public/assets/chunks/composer-d10d4b1d54c4f751.js +0 -1
- package/dist/dash/public/assets/chunks/credentials-list-bc5bfcab058176c5.js +0 -2
- package/dist/dash/public/assets/chunks/format-eb03fc9d9744d960.js +0 -1
- package/dist/dash/public/assets/chunks/heads-f3bcd289663d48fa.js +0 -1
- package/dist/dash/public/assets/chunks/instructions-d0a4b0d95009c262.js +0 -1
- package/dist/dash/public/assets/chunks/paged-bc6fa0c2b9d52ed7.js +0 -1
- package/dist/dash/public/assets/chunks/runners-list-1901af8a5dea1f09.js +0 -1
- package/dist/dash/public/assets/chunks/shared-init-88cce66bb3cfe1e5.js +0 -5
- package/dist/dash/public/assets/chunks/shared-init-ffb3397e494137c9.js +0 -2
- package/dist/dash/public/assets/chunks/task-actions-8e1d93c788d001df.js +0 -1
- package/dist/dash/public/assets/chunks/task-fa8b82e95e771c4a.js +0 -1
- package/dist/dash/public/assets/chunks/task-view-6d7618d2820a5cb4.js +0 -3
- package/dist/dash/public/assets/chunks/tasks-list-f4784e5cbd0ed785.js +0 -1
- package/dist/dash/public/assets/dash-9e02d5d1a6d42ee3.css +0 -1
- package/dist/dash/public/assets/dash-account-04859899c1838ada.css +0 -1
- package/dist/dash/public/assets/dash-agents-9e678137267dec07.css +0 -1
- package/dist/dash/public/assets/dash-agents-new-26fa27b17ef9b8d8.css +0 -1
- package/dist/dash/public/assets/dash-agents-param-slug-b975c48f8abf3444.css +0 -1
- package/dist/dash/public/assets/dash-agents-param-slug-edit-e13fda599bb04843.css +0 -1
- package/dist/dash/public/assets/dash-agents-param-slug-platforms-70292932cb27bc96.css +0 -1
- package/dist/dash/public/assets/dash-agents-param-slug-settings-71f9a86251723fcc.css +0 -1
- package/dist/dash/public/assets/dash-agents-param-slug-tasks-fb8eb2ed71006601.css +0 -1
- package/dist/dash/public/assets/dash-agents-param-slug-usage-7c8740f1cdd52c71.css +0 -1
- package/dist/dash/public/assets/dash-settings-8eb818da462227e8.css +0 -1
- package/dist/dash/public/assets/dash-settings-param-tab-849a1a9542e273f5.css +0 -1
- package/dist/dash/public/assets/dash-tasks-81e510e0b6931b42.css +0 -1
- package/dist/dash/public/assets/dash-tasks-param-id-bbd2a83342f2ec10.css +0 -1
- package/dist/dash/public/assets/dash-usage-8e0259e03eaed1bd.css +0 -1
- package/dist/dash/public/assets/pnext-client-03b03b254e525e82.js +0 -1
- package/dist/dash/public/assets/pnext-client-1c7859bb888f4ef0.js +0 -1
- package/dist/dash/public/assets/pnext-client-3c748afe963fb05d.js +0 -1
- package/dist/dash/public/assets/pnext-client-4f47c2cae220f107.js +0 -1
- package/dist/dash/public/assets/pnext-client-6ab9fd9b53b794d2.js +0 -1
- package/dist/dash/public/assets/pnext-client-6c241786342498e4.js +0 -1
- package/dist/dash/public/assets/pnext-client-80b56d420f02b808.js +0 -1
- package/dist/dash/public/assets/pnext-client-83135c17bae850a3.js +0 -1
- package/dist/dash/public/assets/pnext-client-8e6fa4302ae0396f.js +0 -1
- package/dist/dash/public/assets/pnext-client-932c9d8cc0717fc8.js +0 -1
- package/dist/dash/public/assets/pnext-client-a42ae63d4de113f9.js +0 -1
- package/dist/dash/public/assets/pnext-client-d2ee6f8c1e337032.js +0 -1
- package/dist/dash/public/assets/pnext-client-d513f65ec23b7f20.js +0 -1
- package/dist/dash/public/assets/pnext-client-ecb88e2a8a109954.js +0 -1
- package/dist/dash/public/assets/pnext-client-f1545ee6270bbf9a.js +0 -1
- package/dist/dash/server/bundle-0.1.5-1508b6c99c0d1e68/boot-B2MFTRO2.js +0 -30
- package/dist/dash/server/bundle-0.1.5-1508b6c99c0d1e68/build-tier-XJJSL5FR.js +0 -2704
- package/dist/dash/server/bundle-0.1.5-1508b6c99c0d1e68/chunk-2HFY3DQT.js +0 -208
- package/dist/dash/server/bundle-0.1.5-1508b6c99c0d1e68/chunk-2ICEVELW.js +0 -834
- package/dist/dash/server/bundle-0.1.5-1508b6c99c0d1e68/chunk-3UPROT2C.js +0 -35
- package/dist/dash/server/bundle-0.1.5-1508b6c99c0d1e68/chunk-4P5CMIYT.js +0 -1582
- package/dist/dash/server/bundle-0.1.5-1508b6c99c0d1e68/chunk-4TKZKZ3Q.js +0 -131
- package/dist/dash/server/bundle-0.1.5-1508b6c99c0d1e68/chunk-5RDEILQB.js +0 -437
- package/dist/dash/server/bundle-0.1.5-1508b6c99c0d1e68/chunk-62KEQM43.js +0 -25
- package/dist/dash/server/bundle-0.1.5-1508b6c99c0d1e68/chunk-6KQSWT6D.js +0 -831
- package/dist/dash/server/bundle-0.1.5-1508b6c99c0d1e68/chunk-7DCNCW6O.js +0 -724
- package/dist/dash/server/bundle-0.1.5-1508b6c99c0d1e68/chunk-B4THCTQP.js +0 -22
- package/dist/dash/server/bundle-0.1.5-1508b6c99c0d1e68/chunk-C2LIV2MM.js +0 -172
- package/dist/dash/server/bundle-0.1.5-1508b6c99c0d1e68/chunk-CCATPVTW.js +0 -378
- package/dist/dash/server/bundle-0.1.5-1508b6c99c0d1e68/chunk-COXJAPTU.js +0 -89
- package/dist/dash/server/bundle-0.1.5-1508b6c99c0d1e68/chunk-E6IXL2NJ.js +0 -6270
- package/dist/dash/server/bundle-0.1.5-1508b6c99c0d1e68/chunk-FLGRBFAH.js +0 -1198
- package/dist/dash/server/bundle-0.1.5-1508b6c99c0d1e68/chunk-FTJVHFWD.js +0 -61
- package/dist/dash/server/bundle-0.1.5-1508b6c99c0d1e68/chunk-H523KSIH.js +0 -5151
- package/dist/dash/server/bundle-0.1.5-1508b6c99c0d1e68/chunk-HT6KKX6A.js +0 -20
- package/dist/dash/server/bundle-0.1.5-1508b6c99c0d1e68/chunk-JESFYECC.js +0 -438
- package/dist/dash/server/bundle-0.1.5-1508b6c99c0d1e68/chunk-JRPJM2XY.js +0 -17
- package/dist/dash/server/bundle-0.1.5-1508b6c99c0d1e68/chunk-L2IWDUXG.js +0 -107
- package/dist/dash/server/bundle-0.1.5-1508b6c99c0d1e68/chunk-L5P4Y4UC.js +0 -183
- package/dist/dash/server/bundle-0.1.5-1508b6c99c0d1e68/chunk-NQE46AZN.js +0 -647
- package/dist/dash/server/bundle-0.1.5-1508b6c99c0d1e68/chunk-PA4QEARJ.js +0 -129
- package/dist/dash/server/bundle-0.1.5-1508b6c99c0d1e68/chunk-PZ5AXOLW.js +0 -7146
- package/dist/dash/server/bundle-0.1.5-1508b6c99c0d1e68/chunk-SNVPTULL.js +0 -2397
- package/dist/dash/server/bundle-0.1.5-1508b6c99c0d1e68/chunk-T3QZT3PG.js +0 -220
- package/dist/dash/server/bundle-0.1.5-1508b6c99c0d1e68/chunk-VC5O2SDP.js +0 -72
- package/dist/dash/server/bundle-0.1.5-1508b6c99c0d1e68/chunk-WZX4V6CM.js +0 -231
- package/dist/dash/server/bundle-0.1.5-1508b6c99c0d1e68/chunk-XUUIDXY5.js +0 -627
- package/dist/dash/server/bundle-0.1.5-1508b6c99c0d1e68/chunk-ZHFDO3PR.js +0 -265
- package/dist/dash/server/bundle-0.1.5-1508b6c99c0d1e68/compile-CE2DN7ZA.js +0 -18
- package/dist/dash/server/bundle-0.1.5-1508b6c99c0d1e68/config-UREY7XJT.js +0 -16
- package/dist/dash/server/bundle-0.1.5-1508b6c99c0d1e68/config-loader-UI2XE3PZ.js +0 -17
- package/dist/dash/server/bundle-0.1.5-1508b6c99c0d1e68/entry.js +0 -219
- package/dist/dash/server/bundle-0.1.5-1508b6c99c0d1e68/generate-I2PPTDFD.js +0 -16
- package/dist/dash/server/bundle-0.1.5-1508b6c99c0d1e68/modules-UVOCE4C2.js +0 -48
- package/dist/dash/server/bundle-0.1.5-1508b6c99c0d1e68/pipeline-UW47K537.js +0 -963
- package/dist/dash/server/bundle-0.1.5-1508b6c99c0d1e68/proxy-ITGOVJBW.js +0 -26
- package/dist/dash/server/bundle-0.1.5-1508b6c99c0d1e68/register-4SA55SWT.js +0 -12579
- package/dist/dash/server/bundle-0.1.5-1508b6c99c0d1e68/router-JNKHLBCZ.js +0 -505
- package/dist/dash/server/bundle-0.1.5-1508b6c99c0d1e68/routes-PD6J2NXW.js +0 -54
- package/dist/dash/server/bundle-0.1.5-1508b6c99c0d1e68/tsconfig-defaults-ZXEH7RQK.js +0 -15
- package/dist/default-Bobztoxf.js +0 -1
- package/dist/dispatch-BKeAch9E.js +0 -14
- package/dist/exec-RZFLclKX.js +0 -11
- package/dist/executor-BvAA7Cgw.js +0 -10
- package/dist/http-Bkg_OQ6r.js +0 -1
- package/dist/integrations-5xCaXSd-.js +0 -1
- package/dist/integrations-BAgdVDhj.js +0 -5
- package/dist/log-view-dg0TlKLA.js +0 -1
- package/dist/models-_5LVGC3m.js +0 -1
- package/dist/queue-6io_NOP3.js +0 -116
- package/dist/refresh-BIrmrWYq.js +0 -1
- package/dist/rename-CYfy03FE.js +0 -1
- package/dist/result-BzaM3inj.js +0 -15
- package/dist/run-BDYl0CKl.js +0 -2
- package/dist/runner-D7ScbIHJ.js +0 -1
- package/dist/schema-CU2iFkp8.js +0 -1
- package/dist/serve-CQKZxzFE.js +0 -4
- package/dist/store-B94tSate.js +0 -42
- package/dist/store-DzqXS2wT.js +0 -8
- package/dist/task-C6VAg5WU.js +0 -1
- package/dist/task-CgOKgkEG.js +0 -1
- package/dist/worker-CXndxmGF.js +0 -9
- package/dist/worker-DX7P9kWl.js +0 -1
- package/src/server/dash/app/dash/token-from-hash.tsx +0 -17
|
@@ -40,7 +40,7 @@ const ICONS: Record<TaskDisplayRow['kind'], string> = {
|
|
|
40
40
|
|
|
41
41
|
/** Rows long enough to fold to one line. */
|
|
42
42
|
const foldable = (row: TaskDisplayRow) =>
|
|
43
|
-
Boolean(row.detail) || row.title.length > 120 || row.title.includes('\n');
|
|
43
|
+
Boolean(row.detail || row.result?.detail) || row.title.length > 120 || row.title.includes('\n');
|
|
44
44
|
|
|
45
45
|
const atEnd = () => innerHeight + scrollY >= document.documentElement.scrollHeight - 48;
|
|
46
46
|
|
|
@@ -65,15 +65,43 @@ function useWindowVirtualizer(count: number, list: { current: HTMLElement | null
|
|
|
65
65
|
return virtual;
|
|
66
66
|
}
|
|
67
67
|
|
|
68
|
+
/** A call's or approval's outcome on the right: a spinner and the time so far, then ✓ or ✗ and how long it took. */
|
|
69
|
+
function CallState({ row, running }: { row: TaskDisplayRow; running: boolean }) {
|
|
70
|
+
const [, tick] = useReducer((n: number) => n + 1, 0);
|
|
71
|
+
useEffect(() => {
|
|
72
|
+
if (!running) return;
|
|
73
|
+
const timer = setInterval(() => tick(0), 1000);
|
|
74
|
+
return () => clearInterval(timer);
|
|
75
|
+
}, [running]);
|
|
76
|
+
const result = row.result;
|
|
77
|
+
const took = running ? Math.max(0, Date.now() - row.at) : result?.durationMs;
|
|
78
|
+
const text = [
|
|
79
|
+
row.state,
|
|
80
|
+
result && !result.ok && result.exitCode !== undefined ? `exit ${result.exitCode}` : '',
|
|
81
|
+
took ? formatDuration(took) : '',
|
|
82
|
+
]
|
|
83
|
+
.filter(Boolean)
|
|
84
|
+
.join(' · ');
|
|
85
|
+
|
|
86
|
+
return (
|
|
87
|
+
<span class={`act-state${result && !result.ok ? ' bad' : ''}`}>
|
|
88
|
+
{running ? <i class="spin" /> : result ? <Icon d={result.ok ? iCheck : iX} /> : null}
|
|
89
|
+
{text}
|
|
90
|
+
</span>
|
|
91
|
+
);
|
|
92
|
+
}
|
|
93
|
+
|
|
68
94
|
function Row({
|
|
69
95
|
row,
|
|
70
96
|
tz,
|
|
71
97
|
open,
|
|
98
|
+
running,
|
|
72
99
|
onToggle,
|
|
73
100
|
}: {
|
|
74
101
|
row: TaskDisplayRow;
|
|
75
102
|
tz: string;
|
|
76
103
|
open: boolean;
|
|
104
|
+
running: boolean;
|
|
77
105
|
onToggle: () => void;
|
|
78
106
|
}) {
|
|
79
107
|
const title = useRef<HTMLSpanElement>(null);
|
|
@@ -83,6 +111,7 @@ function Row({
|
|
|
83
111
|
}, [row.title]);
|
|
84
112
|
const fold = open || clipped || foldable(row);
|
|
85
113
|
const failed = row.tone === 'error';
|
|
114
|
+
const timed = row.kind === 'tool' || row.state !== undefined;
|
|
86
115
|
const extra =
|
|
87
116
|
row.kind === 'tool-result'
|
|
88
117
|
? [
|
|
@@ -100,7 +129,7 @@ function Row({
|
|
|
100
129
|
return (
|
|
101
130
|
<Tag
|
|
102
131
|
type={fold ? 'button' : undefined}
|
|
103
|
-
class={`act ${row.kind}${row.tone ? ` ${row.tone}` : ''}${row.separated ? ' sep' : ''}${open ? ' open' : ''}`}
|
|
132
|
+
class={`act ${row.kind}${row.tone ? ` ${row.tone}` : ''}${row.separated ? ' sep' : ''}${timed ? ' timed' : ''}${open ? ' open' : ''}`}
|
|
104
133
|
aria-expanded={fold ? open : undefined}
|
|
105
134
|
onClick={fold ? onToggle : undefined}
|
|
106
135
|
>
|
|
@@ -108,11 +137,20 @@ function Row({
|
|
|
108
137
|
<Icon d={row.kind === 'tool-result' && failed ? iX : ICONS[row.kind]} />
|
|
109
138
|
<span class="act-text">
|
|
110
139
|
<span class="act-title" ref={title}>
|
|
111
|
-
{row.title}
|
|
140
|
+
{row.kind === 'tool' && row.tool && row.title.startsWith(`${row.tool} `) ? (
|
|
141
|
+
<>
|
|
142
|
+
<span class="act-tool">{row.tool}</span>
|
|
143
|
+
{row.title.slice(row.tool.length)}
|
|
144
|
+
</>
|
|
145
|
+
) : (
|
|
146
|
+
row.title
|
|
147
|
+
)}
|
|
112
148
|
</span>
|
|
113
149
|
{extra ? <span class="act-detail">{extra}</span> : null}
|
|
114
|
-
{row.detail ? <span class="act-detail">{row.detail}</span> : null}
|
|
150
|
+
{row.detail && (open || !row.state) ? <span class="act-detail">{row.detail}</span> : null}
|
|
151
|
+
{open && row.result?.detail ? <span class="act-detail">{row.result.detail}</span> : null}
|
|
115
152
|
</span>
|
|
153
|
+
{timed ? <CallState row={row} running={running} /> : null}
|
|
116
154
|
{fold ? <Icon d={iDown} class="act-chev" /> : null}
|
|
117
155
|
</Tag>
|
|
118
156
|
);
|
|
@@ -132,6 +170,8 @@ export function Activity({
|
|
|
132
170
|
const [open, setOpen] = useState<Set<number>>(new Set());
|
|
133
171
|
const [follow, setFollow] = useState(live);
|
|
134
172
|
const virtual = useWindowVirtualizer(rows.length, list);
|
|
173
|
+
// Calls the agent has moved on from without a result are not still running.
|
|
174
|
+
const settled = rows.findLastIndex(row => row.kind === 'assistant' || row.kind === 'reasoning');
|
|
135
175
|
|
|
136
176
|
useEffect(() => {
|
|
137
177
|
const onScroll = () => setFollow(atEnd());
|
|
@@ -173,6 +213,11 @@ export function Activity({
|
|
|
173
213
|
row={row}
|
|
174
214
|
tz={tz}
|
|
175
215
|
open={open.has(row.seq)}
|
|
216
|
+
running={
|
|
217
|
+
live &&
|
|
218
|
+
!row.result &&
|
|
219
|
+
(row.state !== undefined || (row.kind === 'tool' && item.index > settled))
|
|
220
|
+
}
|
|
176
221
|
onToggle={() =>
|
|
177
222
|
setOpen(value => {
|
|
178
223
|
const next = new Set(value);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
|
-
import { useState } from 'preact/hooks';
|
|
3
|
+
import { useEffect, useState } from 'preact/hooks';
|
|
4
4
|
|
|
5
5
|
import { client } from '@/utils/client';
|
|
6
6
|
import { useRouter } from '@wular/pnext/navigation/client';
|
|
@@ -12,6 +12,7 @@ import { ConfirmDialog } from '@/comps/ui/confirm';
|
|
|
12
12
|
import { Menu, MenuItem } from '@/comps/ui/menu';
|
|
13
13
|
import { Icon } from '@/comps/ui/icon';
|
|
14
14
|
import { iDots } from '@/comps/ui/icons';
|
|
15
|
+
import { showToast, toastError } from '@/comps/frame/task-toasts';
|
|
15
16
|
|
|
16
17
|
export function approvalParts(approval: unknown): {
|
|
17
18
|
id?: string;
|
|
@@ -114,6 +115,14 @@ export function TaskActions({ task, live }: { task: TaskRow; live: boolean }) {
|
|
|
114
115
|
)}
|
|
115
116
|
<Menu summary={<Icon d={iDots} />} summaryClass="icon-btn" label="More actions">
|
|
116
117
|
{live && !archived ? <MenuItem title="Archive" onClick={archive} /> : null}
|
|
118
|
+
<MenuItem
|
|
119
|
+
title="Copy task id"
|
|
120
|
+
onClick={() =>
|
|
121
|
+
void navigator.clipboard
|
|
122
|
+
.writeText(task.task.id)
|
|
123
|
+
.then(() => showToast('Copied', task.task.id))
|
|
124
|
+
}
|
|
125
|
+
/>
|
|
117
126
|
<MenuItem title="Delete" danger onClick={() => setDeleting('ask')} />
|
|
118
127
|
</Menu>
|
|
119
128
|
<ConfirmDialog
|
|
@@ -131,9 +140,26 @@ export function TaskActions({ task, live }: { task: TaskRow; live: boolean }) {
|
|
|
131
140
|
|
|
132
141
|
export function Approval({ task }: { task: TaskRow }) {
|
|
133
142
|
const action = useAction(task.task.id);
|
|
143
|
+
const [busy, setBusy] = useState<'accept' | 'decline'>();
|
|
144
|
+
// A sent decision hides its card at once; the events stream catches up after.
|
|
145
|
+
const [decided, setDecided] = useState<string>();
|
|
134
146
|
const { id, action: tool, reason } = approvalParts(task.approval);
|
|
135
|
-
|
|
136
|
-
|
|
147
|
+
|
|
148
|
+
const decide = async (decision: 'accept' | 'decline') => {
|
|
149
|
+
setBusy(decision);
|
|
150
|
+
const ok = await action.run('approve', { approvalId: id, decision });
|
|
151
|
+
setBusy(undefined);
|
|
152
|
+
if (!ok) return;
|
|
153
|
+
setDecided(id);
|
|
154
|
+
showToast(decision === 'accept' ? 'Allowed' : 'Denied', 'The task continues.');
|
|
155
|
+
};
|
|
156
|
+
|
|
157
|
+
useEffect(() => {
|
|
158
|
+
if (action.error) toastError('Not sent', action.error);
|
|
159
|
+
}, [action.error]);
|
|
160
|
+
|
|
161
|
+
if (id && decided === id) return null;
|
|
162
|
+
|
|
137
163
|
return (
|
|
138
164
|
<Card
|
|
139
165
|
tone="accent"
|
|
@@ -141,11 +167,22 @@ export function Approval({ task }: { task: TaskRow }) {
|
|
|
141
167
|
actions={
|
|
142
168
|
task.task.flow === 'default' ? (
|
|
143
169
|
<>
|
|
144
|
-
<
|
|
145
|
-
|
|
170
|
+
<button
|
|
171
|
+
type="button"
|
|
172
|
+
class="btn outline sm"
|
|
173
|
+
disabled={Boolean(busy)}
|
|
174
|
+
aria-busy={busy === 'decline'}
|
|
175
|
+
onClick={() => void decide('decline')}
|
|
176
|
+
>
|
|
146
177
|
Deny
|
|
147
178
|
</button>
|
|
148
|
-
<button
|
|
179
|
+
<button
|
|
180
|
+
type="button"
|
|
181
|
+
class="btn sm"
|
|
182
|
+
disabled={Boolean(busy)}
|
|
183
|
+
aria-busy={busy === 'accept'}
|
|
184
|
+
onClick={() => void decide('accept')}
|
|
185
|
+
>
|
|
149
186
|
Allow
|
|
150
187
|
</button>
|
|
151
188
|
</>
|
|
@@ -1,60 +1,52 @@
|
|
|
1
|
-
/* task head: the
|
|
2
|
-
.head .lead:has(.
|
|
1
|
+
/* task head: the facts line under the title */
|
|
2
|
+
.head .lead:has(.fact) {
|
|
3
3
|
display: flex;
|
|
4
4
|
align-items: center;
|
|
5
|
-
gap:
|
|
6
|
-
}
|
|
7
|
-
.head.stuck .lead:has(.task-id) {
|
|
8
|
-
display: none;
|
|
9
|
-
}
|
|
10
|
-
.task-id {
|
|
5
|
+
gap: 16px;
|
|
11
6
|
font-size: 12px;
|
|
12
|
-
overflow: hidden;
|
|
13
|
-
text-overflow: ellipsis;
|
|
14
7
|
}
|
|
15
|
-
.
|
|
16
|
-
display: inline-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
8
|
+
.fact {
|
|
9
|
+
display: inline-flex;
|
|
10
|
+
align-items: center;
|
|
11
|
+
gap: 5px;
|
|
12
|
+
white-space: nowrap;
|
|
13
|
+
}
|
|
14
|
+
.fact .ic {
|
|
15
|
+
width: 12px;
|
|
16
|
+
height: 12px;
|
|
23
17
|
color: var(--dim);
|
|
24
|
-
cursor: pointer;
|
|
25
18
|
}
|
|
26
|
-
.
|
|
27
|
-
color: var(--
|
|
19
|
+
.fact-dim {
|
|
20
|
+
color: var(--dim);
|
|
28
21
|
}
|
|
29
|
-
.head
|
|
30
|
-
|
|
31
|
-
height: 13px;
|
|
22
|
+
.head.stuck .lead:has(.fact) {
|
|
23
|
+
display: none;
|
|
32
24
|
}
|
|
33
25
|
/* phones: the actions sit on the back link's row, the title gets the full width under it */
|
|
34
26
|
@media (max-width: 760px) {
|
|
35
|
-
.head:has(.
|
|
27
|
+
.head:has(.fact) .back {
|
|
36
28
|
height: 34px;
|
|
37
29
|
}
|
|
38
|
-
.head:has(.
|
|
30
|
+
.head:has(.fact) .title-row > h1 {
|
|
39
31
|
flex-basis: 100%;
|
|
40
32
|
}
|
|
41
|
-
.head:has(.
|
|
33
|
+
.head:has(.fact) .actions {
|
|
42
34
|
position: absolute;
|
|
43
35
|
top: 0;
|
|
44
36
|
right: 16px;
|
|
45
37
|
width: auto;
|
|
46
38
|
flex-wrap: nowrap;
|
|
47
39
|
}
|
|
48
|
-
.head.stuck:has(.
|
|
40
|
+
.head.stuck:has(.fact) .actions {
|
|
49
41
|
position: static;
|
|
50
42
|
}
|
|
51
|
-
.head.stuck:has(.
|
|
43
|
+
.head.stuck:has(.fact) .actions > .menu {
|
|
52
44
|
display: inline;
|
|
53
45
|
}
|
|
54
|
-
.head.stuck:has(.
|
|
46
|
+
.head.stuck:has(.fact) .title-row > h1 {
|
|
55
47
|
flex-basis: auto;
|
|
56
48
|
}
|
|
57
|
-
.head.stuck:has(.
|
|
49
|
+
.head.stuck:has(.fact) .meta {
|
|
58
50
|
display: none;
|
|
59
51
|
}
|
|
60
52
|
}
|
|
@@ -196,6 +188,9 @@ button.act:hover {
|
|
|
196
188
|
flex: 1 1 0;
|
|
197
189
|
color: var(--dim);
|
|
198
190
|
}
|
|
191
|
+
.act-tool {
|
|
192
|
+
color: var(--fg);
|
|
193
|
+
}
|
|
199
194
|
.act.open .act-text {
|
|
200
195
|
display: grid;
|
|
201
196
|
gap: 2px;
|
|
@@ -228,6 +223,32 @@ button.act:hover {
|
|
|
228
223
|
.act.error :is(.act-title, .ic) {
|
|
229
224
|
color: var(--bad);
|
|
230
225
|
}
|
|
226
|
+
.act.timed {
|
|
227
|
+
grid-template-columns: 76px 16px minmax(0, 1fr) auto 14px;
|
|
228
|
+
}
|
|
229
|
+
.act-state {
|
|
230
|
+
color: var(--dim);
|
|
231
|
+
font-size: 11px;
|
|
232
|
+
font-variant-numeric: tabular-nums;
|
|
233
|
+
white-space: nowrap;
|
|
234
|
+
}
|
|
235
|
+
.act-state.bad,
|
|
236
|
+
.act-state.bad .ic {
|
|
237
|
+
color: var(--bad);
|
|
238
|
+
}
|
|
239
|
+
.act-state :is(.ic, .spin) {
|
|
240
|
+
display: inline-block;
|
|
241
|
+
width: 11px;
|
|
242
|
+
height: 11px;
|
|
243
|
+
margin: 0 6px 0 0;
|
|
244
|
+
vertical-align: -1px;
|
|
245
|
+
}
|
|
246
|
+
.act-state .spin {
|
|
247
|
+
border: 1.5px solid currentColor;
|
|
248
|
+
border-top-color: transparent;
|
|
249
|
+
border-radius: 50%;
|
|
250
|
+
animation: spin 0.8s linear infinite;
|
|
251
|
+
}
|
|
231
252
|
.act-empty {
|
|
232
253
|
padding: 24px 0;
|
|
233
254
|
text-align: center;
|
|
@@ -12,7 +12,7 @@ import { formatDate, formatDuration, reasonText } from '@/utils/format';
|
|
|
12
12
|
import { Link } from '@wular/pnext/link';
|
|
13
13
|
import { useSearchParams } from '@wular/pnext/navigation/client';
|
|
14
14
|
import type { TaskLog, TaskRow } from '@coder/client/types';
|
|
15
|
-
import { iAgent, iCheck,
|
|
15
|
+
import { iAgent, iCheck, iClock, iDown, iFolder, iPlug, iTerminal } from '@/comps/ui/icons';
|
|
16
16
|
import { Badge } from '@/comps/ui/badge';
|
|
17
17
|
import { Card, Loading } from '@/comps/ui/card';
|
|
18
18
|
import { Collapse } from '@/comps/ui/collapse';
|
|
@@ -25,7 +25,7 @@ import { Status } from '@/app/dash/tasks/list/status';
|
|
|
25
25
|
import { folderName, sourceLabel, taskActive, taskTitle } from '@/app/dash/tasks/list/task';
|
|
26
26
|
import { Approval, TaskActions, useAction } from './task-actions';
|
|
27
27
|
import { Activity } from './activity';
|
|
28
|
-
import { toastError, watchTask } from '@/comps/frame/task-toasts';
|
|
28
|
+
import { toastError, useTaskEvents, watchTask } from '@/comps/frame/task-toasts';
|
|
29
29
|
|
|
30
30
|
const TABS = ['Conversation', 'Activity'];
|
|
31
31
|
|
|
@@ -104,30 +104,10 @@ function TaskBack() {
|
|
|
104
104
|
);
|
|
105
105
|
}
|
|
106
106
|
|
|
107
|
-
|
|
108
|
-
const [copied, setCopied] = useState(false);
|
|
109
|
-
const label = copied ? 'Copied' : 'Copy task id';
|
|
110
|
-
useEffect(() => {
|
|
111
|
-
if (!copied) return;
|
|
112
|
-
const timer = setTimeout(() => setCopied(false), 1500);
|
|
113
|
-
return () => clearTimeout(timer);
|
|
114
|
-
}, [copied]);
|
|
115
|
-
return (
|
|
116
|
-
<button
|
|
117
|
-
type="button"
|
|
118
|
-
class={copied ? 'copy copied' : 'copy'}
|
|
119
|
-
aria-label={label}
|
|
120
|
-
title={label}
|
|
121
|
-
onClick={() => void navigator.clipboard.writeText(id).then(() => setCopied(true))}
|
|
122
|
-
>
|
|
123
|
-
<Icon d={copied ? iCheck : iCopy} />
|
|
124
|
-
</button>
|
|
125
|
-
);
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
/** The task's one-row head: back, title, status, source and agent, its actions, and a muted line with id, created time and duration. */
|
|
107
|
+
/** The task's one-row head: back, title, status, source and agent, its actions, and a muted line with created time, source, folder, and the agent with its model. */
|
|
129
108
|
function TaskHead({ task, tz }: { task: TaskRow; tz: string }) {
|
|
130
109
|
const live = taskActive(task);
|
|
110
|
+
const { engine, model, effort } = { ...task.task.definition, ...task.task.usage };
|
|
131
111
|
const source = task.task.event?.integration ?? task.task.source;
|
|
132
112
|
const kind = task.task.event?.type ?? (task.task.flow !== 'default' ? task.task.flow : undefined);
|
|
133
113
|
|
|
@@ -143,23 +123,39 @@ function TaskHead({ task, tz }: { task: TaskRow; tz: string }) {
|
|
|
143
123
|
}
|
|
144
124
|
lead={
|
|
145
125
|
<>
|
|
146
|
-
<span class="
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
126
|
+
<span class="fact" title={`Created ${formatDate(task.createdAt, tz)}`}>
|
|
127
|
+
<Icon d={iClock} />
|
|
128
|
+
{formatDate(task.createdAt, tz, true)}
|
|
129
|
+
{task.startedAt && task.finishedAt
|
|
130
|
+
? `, ran ${formatDuration(task.finishedAt - task.startedAt)}`
|
|
131
|
+
: null}
|
|
132
|
+
</span>
|
|
133
|
+
<span class="fact" title="Source">
|
|
134
|
+
<Icon d={task.task.event ? iPlug : iTerminal} />
|
|
135
|
+
{kind ? `${sourceLabel(source)} ${kind}` : sourceLabel(source)}
|
|
136
|
+
</span>
|
|
137
|
+
{task.task.cwd ? (
|
|
138
|
+
<span class="fact" title={task.task.cwd}>
|
|
139
|
+
<Icon d={iFolder} />
|
|
140
|
+
{folderName(task.task.cwd)}
|
|
141
|
+
</span>
|
|
151
142
|
) : null}
|
|
152
|
-
<span
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
143
|
+
<span class="fact">
|
|
144
|
+
<Link
|
|
145
|
+
class="agent-link"
|
|
146
|
+
href="/dash/agents/[slug]"
|
|
147
|
+
params={{ slug: task.task.agent }}
|
|
148
|
+
search={{ from: `/dash/tasks/${task.task.id}` }}
|
|
149
|
+
>
|
|
150
|
+
<Icon d={iAgent} />
|
|
151
|
+
{task.task.agent}
|
|
152
|
+
</Link>
|
|
153
|
+
{engine ? (
|
|
154
|
+
<span class="fact-dim" title="Engine, model and effort">
|
|
155
|
+
{[engine, model, effort].filter(Boolean).join('/')}
|
|
156
|
+
</span>
|
|
157
|
+
) : null}
|
|
158
|
+
</span>
|
|
163
159
|
</>
|
|
164
160
|
}
|
|
165
161
|
actions={<TaskActions task={task} live={live} />}
|
|
@@ -167,12 +163,16 @@ function TaskHead({ task, tz }: { task: TaskRow; tz: string }) {
|
|
|
167
163
|
);
|
|
168
164
|
}
|
|
169
165
|
|
|
170
|
-
/** Display rows for the lines so far; new lines
|
|
166
|
+
/** Display rows for the lines so far; new lines extend them or complete an earlier call. */
|
|
171
167
|
function useDisplayRows(lines: TaskLog[]) {
|
|
172
168
|
const view = useRef<{ log: LogView; rows: TaskDisplayRow[]; seen: number }>();
|
|
173
169
|
return useMemo(() => {
|
|
174
170
|
const state = (view.current ??= { log: new LogView(), rows: [], seen: 0 });
|
|
175
|
-
for (const line of lines.slice(state.seen))
|
|
171
|
+
for (const line of lines.slice(state.seen))
|
|
172
|
+
for (const row of state.log.reduce(line)) {
|
|
173
|
+
if (row.seq > (state.rows.at(-1)?.seq ?? -1)) state.rows.push(row);
|
|
174
|
+
else state.rows[state.rows.findLastIndex(({ seq }) => seq === row.seq)] = row;
|
|
175
|
+
}
|
|
176
176
|
state.seen = lines.length;
|
|
177
177
|
return [...state.rows];
|
|
178
178
|
}, [lines]);
|
|
@@ -214,17 +214,107 @@ export function TaskView({ initial, tz }: { initial: TaskRow; tz: string }) {
|
|
|
214
214
|
if (action.error) toastError('Not sent', action.error);
|
|
215
215
|
}, [action.error]);
|
|
216
216
|
|
|
217
|
+
const pending = useRef<TaskLog[]>([]);
|
|
217
218
|
const append = (more: TaskLog[]) => {
|
|
218
219
|
const fresh = more.filter(line => line.seq > after.current);
|
|
219
220
|
if (!fresh.length) return;
|
|
220
221
|
after.current = fresh.at(-1)!.seq;
|
|
221
|
-
|
|
222
|
+
// Lines that land together render once.
|
|
223
|
+
if (pending.current.push(...fresh) === fresh.length)
|
|
224
|
+
setTimeout(() => {
|
|
225
|
+
const batch = pending.current.splice(0);
|
|
226
|
+
setLines(value => [...value, ...batch]);
|
|
227
|
+
});
|
|
222
228
|
};
|
|
223
229
|
|
|
224
230
|
useEffect(() => {
|
|
225
231
|
if (live && replies) input.current?.focus();
|
|
226
232
|
}, []);
|
|
227
233
|
|
|
234
|
+
const [visible, setVisible] = useState(true);
|
|
235
|
+
useEffect(() => {
|
|
236
|
+
const sync = () => setVisible(document.visibilityState === 'visible');
|
|
237
|
+
sync();
|
|
238
|
+
addEventListener('visibilitychange', sync);
|
|
239
|
+
return () => removeEventListener('visibilitychange', sync);
|
|
240
|
+
}, []);
|
|
241
|
+
|
|
242
|
+
// Logs stream from when the task runs until the stream ends them, which waits for logs still arriving.
|
|
243
|
+
const [streaming, setStreaming] = useState(live);
|
|
244
|
+
useEffect(() => {
|
|
245
|
+
if (live) setStreaming(true);
|
|
246
|
+
}, [live]);
|
|
247
|
+
|
|
248
|
+
// Each turn's reads apply to it alone: a continue, here or from elsewhere, starts the next.
|
|
249
|
+
const [round, setRound] = useState(0);
|
|
250
|
+
const roundNow = useRef(0);
|
|
251
|
+
roundNow.current = round;
|
|
252
|
+
|
|
253
|
+
const reload = () => {
|
|
254
|
+
const started = roundNow.current;
|
|
255
|
+
void client.tasks
|
|
256
|
+
.get(task.task.id)
|
|
257
|
+
.then(({ logs: _logs, ...full }) => {
|
|
258
|
+
if (roundNow.current === started) setTask(full);
|
|
259
|
+
})
|
|
260
|
+
.catch(reason => setStatus(reasonText(reason)));
|
|
261
|
+
};
|
|
262
|
+
|
|
263
|
+
// A running stream follows its own cursor; a stopped page fetches the lines it missed.
|
|
264
|
+
const catchUp = () => {
|
|
265
|
+
reload();
|
|
266
|
+
if (!streaming) setComplete(false);
|
|
267
|
+
};
|
|
268
|
+
|
|
269
|
+
// A new turn's prompt, from this page or elsewhere; its state comes from the events stream.
|
|
270
|
+
useEffect(() => {
|
|
271
|
+
if (!round) return;
|
|
272
|
+
void client.tasks
|
|
273
|
+
.get(task.task.id)
|
|
274
|
+
.then(({ turns }) => {
|
|
275
|
+
if (roundNow.current === round)
|
|
276
|
+
setTask(current => (taskActive(current) ? { ...current, turns } : current));
|
|
277
|
+
})
|
|
278
|
+
.catch(() => {});
|
|
279
|
+
}, [round]);
|
|
280
|
+
|
|
281
|
+
// The head follows the browser's events stream; a finish brings the full task.
|
|
282
|
+
useTaskEvents(
|
|
283
|
+
event => {
|
|
284
|
+
if (event.id !== task.task.id || event.deleted) return;
|
|
285
|
+
if (live && !taskActive(event)) reload();
|
|
286
|
+
// A new run, even one that finished and was continued between two events.
|
|
287
|
+
const rerun = live && task.startedAt !== undefined && event.startedAt !== task.startedAt;
|
|
288
|
+
if (taskActive(event) && (!live || rerun)) {
|
|
289
|
+
setRound(value => value + 1);
|
|
290
|
+
setStreaming(true);
|
|
291
|
+
}
|
|
292
|
+
// A turn continued and finished elsewhere while this page heard nothing of it.
|
|
293
|
+
if (!live && !taskActive(event) && event.finishedAt !== task.finishedAt) {
|
|
294
|
+
reload();
|
|
295
|
+
setComplete(false);
|
|
296
|
+
}
|
|
297
|
+
setTask(current => ({
|
|
298
|
+
...current,
|
|
299
|
+
status: event.status,
|
|
300
|
+
approval: event.approval ?? undefined,
|
|
301
|
+
archivedAt: event.archivedAt,
|
|
302
|
+
startedAt: event.startedAt,
|
|
303
|
+
finishedAt: event.finishedAt,
|
|
304
|
+
...(event.result === undefined
|
|
305
|
+
? {}
|
|
306
|
+
: {
|
|
307
|
+
result: event.result ?? undefined,
|
|
308
|
+
error: event.error ?? undefined,
|
|
309
|
+
answer: event.answer ?? undefined,
|
|
310
|
+
}),
|
|
311
|
+
}));
|
|
312
|
+
},
|
|
313
|
+
// Missed events: refetch the task and catch up its logs from the cursor.
|
|
314
|
+
catchUp,
|
|
315
|
+
() => document.visibilityState === 'visible' && catchUp(),
|
|
316
|
+
);
|
|
317
|
+
|
|
228
318
|
// Older lines a chunk at a time, then the stream follows the run.
|
|
229
319
|
useEffect(() => {
|
|
230
320
|
if (complete) return;
|
|
@@ -237,8 +327,9 @@ export function TaskView({ initial, tz }: { initial: TaskRow; tz: string }) {
|
|
|
237
327
|
.catch(reason => setStatus(reasonText(reason)));
|
|
238
328
|
}, [complete, lines.length]);
|
|
239
329
|
|
|
330
|
+
// A hidden tab holds no log stream and resumes from its cursor.
|
|
240
331
|
useEffect(() => {
|
|
241
|
-
if (!complete || !
|
|
332
|
+
if (!complete || !streaming || !visible) return;
|
|
242
333
|
const abort = new AbortController();
|
|
243
334
|
const follow = async () => {
|
|
244
335
|
while (!abort.signal.aborted) {
|
|
@@ -250,10 +341,9 @@ export function TaskView({ initial, tz }: { initial: TaskRow; tz: string }) {
|
|
|
250
341
|
}
|
|
251
342
|
setStatus('');
|
|
252
343
|
for await (const event of serverEvents(response.body)) {
|
|
344
|
+
if (abort.signal.aborted) return;
|
|
253
345
|
if (event.event === 'log') append([JSON.parse(event.data)]);
|
|
254
|
-
else if (event.event === '
|
|
255
|
-
setTask(current => ({ ...current, ...JSON.parse(event.data) }));
|
|
256
|
-
else if (event.event === 'end') return;
|
|
346
|
+
else if (event.event === 'end') return setStreaming(false);
|
|
257
347
|
}
|
|
258
348
|
} catch {
|
|
259
349
|
if (abort.signal.aborted) return;
|
|
@@ -264,7 +354,7 @@ export function TaskView({ initial, tz }: { initial: TaskRow; tz: string }) {
|
|
|
264
354
|
};
|
|
265
355
|
void follow();
|
|
266
356
|
return () => abort.abort();
|
|
267
|
-
}, [complete,
|
|
357
|
+
}, [complete, streaming, visible, round]);
|
|
268
358
|
|
|
269
359
|
const turns = task.turns ?? [
|
|
270
360
|
{
|
|
@@ -295,12 +385,14 @@ export function TaskView({ initial, tz }: { initial: TaskRow; tz: string }) {
|
|
|
295
385
|
const ok = await action.run(kind, { text }).finally(() => setSending(false));
|
|
296
386
|
if (!ok) return;
|
|
297
387
|
input.current!.value = '';
|
|
298
|
-
if (kind === 'continue')
|
|
388
|
+
if (kind === 'continue') {
|
|
389
|
+
setRound(value => value + 1);
|
|
299
390
|
setTask(current => ({
|
|
300
391
|
...current,
|
|
301
392
|
status: 'queued',
|
|
302
393
|
result: undefined,
|
|
303
394
|
error: undefined,
|
|
395
|
+
startedAt: undefined,
|
|
304
396
|
finishedAt: undefined,
|
|
305
397
|
turns: [
|
|
306
398
|
...turns.map((turn, index) =>
|
|
@@ -311,7 +403,7 @@ export function TaskView({ initial, tz }: { initial: TaskRow; tz: string }) {
|
|
|
311
403
|
{ prompt: text },
|
|
312
404
|
],
|
|
313
405
|
}));
|
|
314
|
-
else {
|
|
406
|
+
} else {
|
|
315
407
|
setSent(value => [...value, { kind, text, turn: turns.length - 1 }]);
|
|
316
408
|
setTab('activity');
|
|
317
409
|
}
|
|
@@ -332,6 +424,7 @@ export function TaskView({ initial, tz }: { initial: TaskRow; tz: string }) {
|
|
|
332
424
|
{fallback.engine} was unavailable. {fallback.detail} This task is using {fallback.next}.
|
|
333
425
|
</p>
|
|
334
426
|
))}
|
|
427
|
+
{task.approval ? <Approval task={task} /> : null}
|
|
335
428
|
<nav class="tabs" role="tablist" aria-label="Task">
|
|
336
429
|
{TABS.map(label => {
|
|
337
430
|
const key = label.toLowerCase() as Tab;
|
|
@@ -366,7 +459,6 @@ export function TaskView({ initial, tz }: { initial: TaskRow; tz: string }) {
|
|
|
366
459
|
<p class="who">Prompt</p>
|
|
367
460
|
<Collapse class="prose">{turn.prompt}</Collapse>
|
|
368
461
|
</div>
|
|
369
|
-
{last && task.approval ? <Approval task={task} /> : null}
|
|
370
462
|
{last
|
|
371
463
|
? (task.answer ?? []).slice(0, knownAnswers.current).map((answer, index) => (
|
|
372
464
|
<div key={`a${index}`} class="turn answer">
|
|
@@ -216,6 +216,10 @@ dialog.compose-dialog::backdrop {
|
|
|
216
216
|
height: 30px;
|
|
217
217
|
margin-left: auto;
|
|
218
218
|
}
|
|
219
|
+
/* the dialog's prompt grows to 20 lines, short of the dialog's own scroll */
|
|
220
|
+
.compose-dialog .composer textarea {
|
|
221
|
+
max-height: min(20lh, max(4lh, calc(86dvh - 180px)));
|
|
222
|
+
}
|
|
219
223
|
.compose-dialog .composer,
|
|
220
224
|
.compose-dialog > .loading,
|
|
221
225
|
.compose-dialog > .flash,
|
|
@@ -823,8 +823,8 @@ export function LoadingComposer() {
|
|
|
823
823
|
);
|
|
824
824
|
}
|
|
825
825
|
|
|
826
|
-
/** Opens the composer in a dialog with `agent` picked; starting a task opens it. */
|
|
827
|
-
export function NewTaskButton({ agent }: { agent
|
|
826
|
+
/** Opens the composer in a dialog, with `agent` picked when given; starting a task opens it. */
|
|
827
|
+
export function NewTaskButton({ agent }: { agent?: string }) {
|
|
828
828
|
const dialog = useRef<HTMLDialogElement>(null);
|
|
829
829
|
const [setup, setSetup] = useState<Awaited<ReturnType<typeof loadComposer>>>();
|
|
830
830
|
const [error, setError] = useState('');
|
|
@@ -852,18 +852,19 @@ export function NewTaskButton({ agent }: { agent: string }) {
|
|
|
852
852
|
onPointerEnter={prepare}
|
|
853
853
|
onFocus={prepare}
|
|
854
854
|
>
|
|
855
|
+
<Icon d={iPlus} />
|
|
855
856
|
New task
|
|
856
857
|
</button>
|
|
857
858
|
<dialog
|
|
858
859
|
ref={dialog}
|
|
859
860
|
class="compose-dialog"
|
|
860
|
-
aria-label={`New task for ${agent}`}
|
|
861
|
+
aria-label={agent ? `New task for ${agent}` : 'New task'}
|
|
861
862
|
onClose={() => setShown(false)}
|
|
862
863
|
onClick={event => event.target === event.currentTarget && dialog.current?.close()}
|
|
863
864
|
>
|
|
864
865
|
<header>
|
|
865
866
|
<h2>New task</h2>
|
|
866
|
-
<span class="sub">{agent}</span>
|
|
867
|
+
{agent ? <span class="sub">{agent}</span> : null}
|
|
867
868
|
<button
|
|
868
869
|
type="button"
|
|
869
870
|
class="icon-btn"
|
|
@@ -876,7 +877,7 @@ export function NewTaskButton({ agent }: { agent: string }) {
|
|
|
876
877
|
{!shown ? null : setup ? (
|
|
877
878
|
<Composer
|
|
878
879
|
{...setup}
|
|
879
|
-
initial={{ ...savedChoice(document.cookie), agent }}
|
|
880
|
+
initial={{ ...savedChoice(document.cookie), ...(agent ? { agent } : {}) }}
|
|
880
881
|
tz={Intl.DateTimeFormat().resolvedOptions().timeZone}
|
|
881
882
|
/>
|
|
882
883
|
) : error ? (
|