@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
|
@@ -37,12 +37,16 @@ export interface TaskDisplayRow {
|
|
|
37
37
|
tool?: string;
|
|
38
38
|
exitCode?: number;
|
|
39
39
|
tokens?: TokenUsage;
|
|
40
|
+
result?: { ok: boolean; exitCode?: number; durationMs: number; detail: string };
|
|
41
|
+
state?: string;
|
|
40
42
|
}
|
|
41
43
|
|
|
42
44
|
export const isApproval = (kind: string) =>
|
|
43
45
|
kind.includes('approval') || kind === 'sidecar-decision' || kind === 'auto-review';
|
|
44
46
|
|
|
45
|
-
|
|
47
|
+
const ANSI = /\x1b\[[0-9;?]*[ -/]*[@-~]|\x1b\][^\x07\x1b]*(?:\x07|\x1b\\)/g;
|
|
48
|
+
|
|
49
|
+
export function stripCwd(text: string, cwd?: string): string {
|
|
46
50
|
return cwd ? text.split(`${cwd}/`).join('').split(cwd).join('.') : text;
|
|
47
51
|
}
|
|
48
52
|
|
|
@@ -70,19 +74,38 @@ export function logEntry(line: string): TaskLogEntry | undefined {
|
|
|
70
74
|
export class LogView {
|
|
71
75
|
private prevKind: string | null = null;
|
|
72
76
|
private lastAssistant = '';
|
|
73
|
-
private lastTool: string | null = null;
|
|
74
77
|
private lastToolText = '';
|
|
78
|
+
private openCalls: TaskDisplayRow[] = [];
|
|
79
|
+
// Engine invocation ids, so concurrent calls of one tool close with their own results.
|
|
80
|
+
private callIds = new WeakMap<TaskDisplayRow, string>();
|
|
81
|
+
private approval: TaskDisplayRow | undefined;
|
|
82
|
+
private approvals = new Map<string, TaskDisplayRow>();
|
|
75
83
|
private lastUsageTotal = 0;
|
|
76
84
|
|
|
77
|
-
constructor(
|
|
85
|
+
constructor(
|
|
86
|
+
private readonly cwd?: string,
|
|
87
|
+
private readonly opts: { keepAnsi?: boolean } = {},
|
|
88
|
+
) {}
|
|
78
89
|
|
|
79
90
|
get lastAssistantMessage(): string {
|
|
80
91
|
return this.lastAssistant;
|
|
81
92
|
}
|
|
82
93
|
|
|
94
|
+
/** A result or verdict that completes an earlier call or approval returns that row again, keyed by its seq. */
|
|
83
95
|
reduce(record: TaskLog): TaskDisplayRow[] {
|
|
84
96
|
const entry = record.entry;
|
|
85
97
|
const sourceKind = entry ? String(entry.kind ?? 'status') : 'line';
|
|
98
|
+
const earlier = !entry
|
|
99
|
+
? undefined
|
|
100
|
+
: sourceKind === 'tool-result'
|
|
101
|
+
? this.close(record, entry)
|
|
102
|
+
: isApproval(sourceKind)
|
|
103
|
+
? this.decide(record, entry, sourceKind)
|
|
104
|
+
: undefined;
|
|
105
|
+
if (earlier) {
|
|
106
|
+
this.prevKind = sourceKind;
|
|
107
|
+
return [earlier];
|
|
108
|
+
}
|
|
86
109
|
const row: TaskDisplayRow = {
|
|
87
110
|
seq: record.seq,
|
|
88
111
|
at: record.at,
|
|
@@ -109,6 +132,25 @@ export class LogView {
|
|
|
109
132
|
row.kind = 'usage';
|
|
110
133
|
row.tokens = tokens;
|
|
111
134
|
row.title = `ctx ${tokenCount(tokens.input + tokens.cachedInput)} · out ${tokenCount(tokens.output)}`;
|
|
135
|
+
} else if (
|
|
136
|
+
(sourceKind === 'approval-decision' && entry.decision === 'escalate') ||
|
|
137
|
+
sourceKind === 'approval-escalated'
|
|
138
|
+
) {
|
|
139
|
+
const summary = stripCwd(entry.summary ? String(entry.summary) : '', this.cwd);
|
|
140
|
+
const target =
|
|
141
|
+
/^(?:run command: |Run command\. |Apply file changes\. |\w+: )?([\s\S]*)$/.exec(
|
|
142
|
+
summary,
|
|
143
|
+
)![1]!;
|
|
144
|
+
const method = String(entry.method ?? '');
|
|
145
|
+
const name = method && !method.includes('/') ? method : this.openCalls.at(-1)?.tool;
|
|
146
|
+
const word = target.startsWith('{') ? '' : target.split(/\s+/)[0];
|
|
147
|
+
const reason = stripCwd(entry.reason ? String(entry.reason) : '', this.cwd);
|
|
148
|
+
row.kind = 'approval';
|
|
149
|
+
row.title = ['Approval', [name, word].filter(Boolean).join(' ')].filter(Boolean).join(' · ');
|
|
150
|
+
row.detail = [target, reason && `Policy · ${reason}`].filter(Boolean).join('\n');
|
|
151
|
+
row.state = sourceKind === 'approval-escalated' ? 'waiting' : 'escalated';
|
|
152
|
+
if (sourceKind === 'approval-escalated') this.approvals.set(String(entry.approvalId), row);
|
|
153
|
+
else this.approval = row;
|
|
112
154
|
} else if (isApproval(sourceKind) && (entry.decision || !entry.message)) {
|
|
113
155
|
row.kind = 'approval';
|
|
114
156
|
const label =
|
|
@@ -141,18 +183,20 @@ export class LogView {
|
|
|
141
183
|
row.durationMs = typeof entry.durationMs === 'number' ? entry.durationMs : 0;
|
|
142
184
|
} else if (sourceKind === 'tool') {
|
|
143
185
|
row.kind = 'tool';
|
|
144
|
-
|
|
186
|
+
if (entry.tool) row.tool = String(entry.tool);
|
|
145
187
|
this.lastToolText = row.title;
|
|
188
|
+
if (entry.callId) this.callIds.set(row, String(entry.callId));
|
|
189
|
+
this.openCalls.push(row);
|
|
146
190
|
} else if (sourceKind === 'tool-result') {
|
|
147
191
|
row.kind = 'tool-result';
|
|
192
|
+
row.title = this.output(raw);
|
|
148
193
|
row.exitCode = typeof entry.exitCode === 'number' ? entry.exitCode : undefined;
|
|
149
194
|
row.tone =
|
|
150
195
|
(row.exitCode !== undefined && row.exitCode !== 0) || entry.isError === true
|
|
151
196
|
? 'error'
|
|
152
197
|
: 'muted';
|
|
153
198
|
row.durationMs = typeof entry.durationMs === 'number' ? entry.durationMs : 0;
|
|
154
|
-
|
|
155
|
-
if (tool && tool !== this.lastTool) row.tool = tool;
|
|
199
|
+
if (entry.tool) row.tool = String(entry.tool);
|
|
156
200
|
}
|
|
157
201
|
}
|
|
158
202
|
if (this.prevKind !== null) {
|
|
@@ -164,6 +208,76 @@ export class LogView {
|
|
|
164
208
|
this.prevKind = sourceKind;
|
|
165
209
|
return [row];
|
|
166
210
|
}
|
|
211
|
+
|
|
212
|
+
// A result closes the call with its invocation id; without one, the oldest open call of its tool, or the latest call.
|
|
213
|
+
private close(record: TaskLog, entry: TaskLogEntry): TaskDisplayRow | undefined {
|
|
214
|
+
const tool = entry.tool ? String(entry.tool) : undefined;
|
|
215
|
+
const byId = entry.callId
|
|
216
|
+
? this.openCalls.findIndex(call => this.callIds.get(call) === String(entry.callId))
|
|
217
|
+
: -1;
|
|
218
|
+
const index =
|
|
219
|
+
byId >= 0
|
|
220
|
+
? byId
|
|
221
|
+
: tool
|
|
222
|
+
? this.openCalls.findIndex(call => call.tool === tool)
|
|
223
|
+
: this.openCalls.length - 1;
|
|
224
|
+
if (index < 0) return undefined;
|
|
225
|
+
|
|
226
|
+
const [call] = this.openCalls.splice(index, 1);
|
|
227
|
+
const exitCode = typeof entry.exitCode === 'number' ? entry.exitCode : undefined;
|
|
228
|
+
const durationMs =
|
|
229
|
+
typeof entry.durationMs === 'number' ? entry.durationMs : record.at - call!.at || 0;
|
|
230
|
+
return {
|
|
231
|
+
...call!,
|
|
232
|
+
result: {
|
|
233
|
+
ok: !exitCode && entry.isError !== true,
|
|
234
|
+
exitCode,
|
|
235
|
+
durationMs: Math.max(0, durationMs),
|
|
236
|
+
detail: this.output(entry.message ? String(entry.message) : ''),
|
|
237
|
+
},
|
|
238
|
+
};
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
// Sidecar verdicts and escalations follow the policy verdict before them; answers carry the approval id.
|
|
242
|
+
private decide(record: TaskLog, entry: TaskLogEntry, kind: string): TaskDisplayRow | undefined {
|
|
243
|
+
const id = String(entry.approvalId ?? '');
|
|
244
|
+
const accepted = entry.decision === 'accept';
|
|
245
|
+
if (kind === 'sidecar-decision' && this.approval) {
|
|
246
|
+
const reason = stripCwd(entry.reason ? String(entry.reason) : '', this.cwd);
|
|
247
|
+
const row = {
|
|
248
|
+
...this.approval,
|
|
249
|
+
detail: [this.approval.detail, reason && `Sidecar · ${reason}`].filter(Boolean).join('\n'),
|
|
250
|
+
};
|
|
251
|
+
if (entry.decision === 'escalate') return (this.approval = row);
|
|
252
|
+
this.approval = undefined;
|
|
253
|
+
return settle(row, record, `${accepted ? 'accepted' : 'denied'} by sidecar`, accepted);
|
|
254
|
+
}
|
|
255
|
+
if (kind === 'approval-escalated' && this.approval) {
|
|
256
|
+
const row = { ...this.approval, state: 'waiting' };
|
|
257
|
+
this.approval = undefined;
|
|
258
|
+
this.approvals.set(id, row);
|
|
259
|
+
return row;
|
|
260
|
+
}
|
|
261
|
+
const open = this.approvals.get(id);
|
|
262
|
+
if (!open || (kind !== 'approval-answered' && kind !== 'approval-timeout')) return undefined;
|
|
263
|
+
|
|
264
|
+
this.approvals.delete(id);
|
|
265
|
+
return kind === 'approval-timeout'
|
|
266
|
+
? settle(open, record, 'timed out', false)
|
|
267
|
+
: settle(open, record, `${accepted ? 'accepted' : 'denied'} by reviewer`, accepted);
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
private output(text: string): string {
|
|
271
|
+
return stripCwd(this.opts.keepAnsi ? text : text.replace(ANSI, ''), this.cwd);
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
function settle(row: TaskDisplayRow, record: TaskLog, state: string, ok: boolean): TaskDisplayRow {
|
|
276
|
+
return {
|
|
277
|
+
...row,
|
|
278
|
+
state,
|
|
279
|
+
result: { ok, durationMs: Math.max(0, record.at - row.at || 0), detail: '' },
|
|
280
|
+
};
|
|
167
281
|
}
|
|
168
282
|
|
|
169
283
|
function tokenCount(n: number): string {
|
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
import { Link } from '@wular/pnext/link';
|
|
2
2
|
|
|
3
|
+
import { iAgent } from '@/comps/ui/icons';
|
|
4
|
+
import { Icon } from '@/comps/ui/icon';
|
|
5
|
+
|
|
3
6
|
/** Make a dashboard agent; importing from a repository starts from the same page. */
|
|
4
7
|
export function NewAgentMenu() {
|
|
5
8
|
return (
|
|
6
9
|
<Link class="btn" href="/dash/agents/new">
|
|
10
|
+
<Icon d={iAgent} />
|
|
7
11
|
New agent
|
|
8
12
|
</Link>
|
|
9
13
|
);
|
|
@@ -9,8 +9,7 @@ import type { AgentCardRow, IntegrationInfo, Paged } from '@coder/client/types';
|
|
|
9
9
|
import { Empty } from '@/comps/ui/card';
|
|
10
10
|
import { initial } from '@/utils/format';
|
|
11
11
|
import { AgentPills, BrandIcon, Platform } from '@/app/dash/agents/agent/agent-pills';
|
|
12
|
-
import {
|
|
13
|
-
import { Icon } from '@/comps/ui/icon';
|
|
12
|
+
import { Filter } from '@/comps/ui/filter';
|
|
14
13
|
import { NewAgentMenu } from './agent-menu';
|
|
15
14
|
import { Search, Toolbar, queryOf, useFilters } from '@/comps/ui/toolbar';
|
|
16
15
|
import { Tail } from '@/comps/ui/tail';
|
|
@@ -93,39 +92,23 @@ export function AgentsGrid({
|
|
|
93
92
|
<>
|
|
94
93
|
<Toolbar head={head} action={<NewAgentMenu />}>
|
|
95
94
|
<Search value={values.q} label="Search agents" onInput={value => set('q', value, 250)} />
|
|
96
|
-
<
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
<span class="pf">
|
|
114
|
-
<BrandIcon brand={entry.brand} />
|
|
115
|
-
{entry.name}
|
|
116
|
-
</span>
|
|
117
|
-
</MenuRadio>
|
|
118
|
-
))}
|
|
119
|
-
</div>
|
|
120
|
-
<p class="pop-label">Source</p>
|
|
121
|
-
<div role="group" aria-label="Source">
|
|
122
|
-
{KINDS.map(([value, label]) => (
|
|
123
|
-
<MenuRadio key={value} on={values.type === value} onPick={() => set('type', value)}>
|
|
124
|
-
{label}
|
|
125
|
-
</MenuRadio>
|
|
126
|
-
))}
|
|
127
|
-
</div>
|
|
128
|
-
</Menu>
|
|
95
|
+
<Filter
|
|
96
|
+
name="agents"
|
|
97
|
+
facets={[
|
|
98
|
+
{
|
|
99
|
+
key: 'platform',
|
|
100
|
+
label: 'Platform',
|
|
101
|
+
options: catalog.map((entry): [string, string] => [entry.id, entry.name]),
|
|
102
|
+
icon: value => {
|
|
103
|
+
const entry = catalog.find(item => item.id === value);
|
|
104
|
+
return entry ? <BrandIcon brand={entry.brand} /> : undefined;
|
|
105
|
+
},
|
|
106
|
+
},
|
|
107
|
+
{ key: 'type', label: 'Source', options: KINDS },
|
|
108
|
+
]}
|
|
109
|
+
values={values}
|
|
110
|
+
onChange={set}
|
|
111
|
+
/>
|
|
129
112
|
</Toolbar>
|
|
130
113
|
{children}
|
|
131
114
|
{list.rows.length ? (
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { HEADS } from '@/comps/frame/heads';
|
|
2
|
+
import { iAgent } from '@/comps/ui/icons';
|
|
2
3
|
import { Page } from '@/comps/frame/page-head';
|
|
3
4
|
import { LoadingToolbar } from '@/comps/frame/loading-card';
|
|
4
5
|
import { Loading } from '@/comps/ui/card';
|
|
@@ -7,7 +8,12 @@ import { Loading } from '@/comps/ui/card';
|
|
|
7
8
|
export default function AgentsLoading() {
|
|
8
9
|
return (
|
|
9
10
|
<Page>
|
|
10
|
-
<LoadingToolbar
|
|
11
|
+
<LoadingToolbar
|
|
12
|
+
head={HEADS.agents}
|
|
13
|
+
search="Search agents"
|
|
14
|
+
more
|
|
15
|
+
action={{ label: 'New agent', icon: iAgent }}
|
|
16
|
+
/>
|
|
11
17
|
<Loading label="Loading agents" />
|
|
12
18
|
</Page>
|
|
13
19
|
);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { ComponentChildren } from 'preact';
|
|
2
2
|
import { dynamic } from '@wular/pnext/dynamic';
|
|
3
3
|
|
|
4
|
-
import { iGit, iPencil } from '@/comps/ui/icons';
|
|
4
|
+
import { iGit, iPencil, iPlus } from '@/comps/ui/icons';
|
|
5
5
|
import { Link } from '@wular/pnext/link';
|
|
6
6
|
import { load } from '@/api/load';
|
|
7
7
|
import type { AgentRow, TasksPage } from '@coder/client/types';
|
|
@@ -56,6 +56,7 @@ function LoadingAgentHead({ back }: { back: ComponentChildren }) {
|
|
|
56
56
|
back={back}
|
|
57
57
|
actions={
|
|
58
58
|
<button type="button" class="btn" disabled>
|
|
59
|
+
<Icon d={iPlus} />
|
|
59
60
|
New task
|
|
60
61
|
</button>
|
|
61
62
|
}
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
.side {
|
|
41
41
|
position: sticky;
|
|
42
42
|
top: 56px;
|
|
43
|
-
z-index:
|
|
43
|
+
z-index: 12;
|
|
44
44
|
height: calc(100vh - 56px);
|
|
45
45
|
display: flex;
|
|
46
46
|
flex-direction: column;
|
|
@@ -248,6 +248,63 @@
|
|
|
248
248
|
.side-min .side nav .n {
|
|
249
249
|
display: none;
|
|
250
250
|
}
|
|
251
|
+
/* collapsed icons and the sidebar toggle name themselves on hover and keyboard focus */
|
|
252
|
+
.side-min .side [data-tip],
|
|
253
|
+
.side-toggle {
|
|
254
|
+
position: relative;
|
|
255
|
+
}
|
|
256
|
+
.side-min .side [data-tip]::after,
|
|
257
|
+
.side-toggle::after {
|
|
258
|
+
content: attr(data-tip) / '';
|
|
259
|
+
position: absolute;
|
|
260
|
+
top: 50%;
|
|
261
|
+
left: calc(100% + 12px);
|
|
262
|
+
z-index: 30;
|
|
263
|
+
padding: 6px 10px;
|
|
264
|
+
border: 1px solid var(--line2);
|
|
265
|
+
background: var(--tile);
|
|
266
|
+
box-shadow: 0 12px 32px rgba(0, 0, 0, 0.18);
|
|
267
|
+
color: var(--fg);
|
|
268
|
+
font-size: 12px;
|
|
269
|
+
letter-spacing: normal;
|
|
270
|
+
white-space: nowrap;
|
|
271
|
+
transform: translateY(-50%);
|
|
272
|
+
pointer-events: none;
|
|
273
|
+
opacity: 0;
|
|
274
|
+
transition: opacity 0.1s;
|
|
275
|
+
}
|
|
276
|
+
/* a small arrow on the tooltip's edge, pointing back at the icon */
|
|
277
|
+
.side-min .side [data-tip]::before,
|
|
278
|
+
.side-toggle::before {
|
|
279
|
+
content: '';
|
|
280
|
+
position: absolute;
|
|
281
|
+
top: 50%;
|
|
282
|
+
left: calc(100% + 8px);
|
|
283
|
+
z-index: 31;
|
|
284
|
+
width: 8px;
|
|
285
|
+
height: 8px;
|
|
286
|
+
border-bottom: 1px solid var(--line2);
|
|
287
|
+
border-left: 1px solid var(--line2);
|
|
288
|
+
background: var(--tile);
|
|
289
|
+
transform: translateY(-50%) rotate(45deg);
|
|
290
|
+
pointer-events: none;
|
|
291
|
+
opacity: 0;
|
|
292
|
+
transition: opacity 0.1s;
|
|
293
|
+
}
|
|
294
|
+
.side-min .side [data-tip]:is(:hover, :focus-visible)::before,
|
|
295
|
+
.side-min .side [data-tip]:is(:hover, :focus-visible)::after,
|
|
296
|
+
.side-toggle:is(:hover, :focus-visible)::before,
|
|
297
|
+
.side-toggle:is(:hover, :focus-visible)::after {
|
|
298
|
+
opacity: 1;
|
|
299
|
+
}
|
|
300
|
+
.side-toggle:is(:hover, :focus-visible)::before,
|
|
301
|
+
.side-toggle:is(:hover, :focus-visible)::after {
|
|
302
|
+
transition-delay: 0.7s;
|
|
303
|
+
}
|
|
304
|
+
.side-min .menu:has(:popover-open) > [data-tip]::before,
|
|
305
|
+
.side-min .menu:has(:popover-open) > [data-tip]::after {
|
|
306
|
+
opacity: 0;
|
|
307
|
+
}
|
|
251
308
|
.side-min .server > button {
|
|
252
309
|
justify-content: center;
|
|
253
310
|
padding: 10px 0;
|
|
@@ -31,7 +31,6 @@ import { Drawer } from '@/comps/frame/drawer';
|
|
|
31
31
|
import { SignOut } from '@/app/dash/account/sign-out';
|
|
32
32
|
import { CurrentLink } from '@/comps/nav/current-link';
|
|
33
33
|
import { SideToggle } from '@/comps/nav/side-toggle';
|
|
34
|
-
import { TokenFromHash } from './token-from-hash';
|
|
35
34
|
import type { To } from '@/comps/nav/to';
|
|
36
35
|
import { Menu } from '@/comps/ui/menu';
|
|
37
36
|
import { TaskToasts } from '@/comps/frame/task-toasts';
|
|
@@ -170,17 +169,19 @@ function ServerMenu({ me, host }: { me?: Me; host: string }) {
|
|
|
170
169
|
const memory = !me?.user;
|
|
171
170
|
const local = me?.mode === 'local';
|
|
172
171
|
const url = me?.server?.url ?? `https://${host}`;
|
|
172
|
+
const name = local ? 'Local server' : memory ? 'Memory server' : 'Cloud server';
|
|
173
173
|
|
|
174
174
|
return (
|
|
175
175
|
<Menu
|
|
176
176
|
class="server"
|
|
177
177
|
align="up"
|
|
178
178
|
label="Server"
|
|
179
|
+
tip={name}
|
|
179
180
|
summary={
|
|
180
181
|
<>
|
|
181
182
|
<i class={memory && !local ? 'dot' : 'dot ok'} />
|
|
182
183
|
<span class="grow" title={`${me?.server?.name ?? 'Coder'} · ${new URL(url).host}`}>
|
|
183
|
-
{
|
|
184
|
+
{name}
|
|
184
185
|
</span>
|
|
185
186
|
<Icon d={iUpdown} />
|
|
186
187
|
</>
|
|
@@ -212,6 +213,26 @@ async function ActiveCount({ count }: { count: Promise<TasksPage> }) {
|
|
|
212
213
|
) : null;
|
|
213
214
|
}
|
|
214
215
|
|
|
216
|
+
// Without a saved choice, mid-width screens start with the sidebar collapsed, before first paint.
|
|
217
|
+
const SIDE_AUTO = `(() => {
|
|
218
|
+
const app = document.currentScript.parentElement;
|
|
219
|
+
const mid = matchMedia('(min-width: 761px) and (max-width: 1279px)');
|
|
220
|
+
const sync = () => /(?:^|; )side=/.test(document.cookie) || app.classList.toggle('side-min', mid.matches);
|
|
221
|
+
sync();
|
|
222
|
+
mid.addEventListener('change', sync);
|
|
223
|
+
})()`;
|
|
224
|
+
|
|
225
|
+
// `serve` opens /dash#token=…: the fragment never reaches the server, so the form posts it while the page loads, busy from first paint.
|
|
226
|
+
const TOKEN_FROM_HASH = `(() => {
|
|
227
|
+
const token = /(?:^|&)token=([^&]+)/.exec(location.hash.slice(1))?.[1];
|
|
228
|
+
if (!token) return;
|
|
229
|
+
history.replaceState(null, '', location.pathname + location.search);
|
|
230
|
+
const form = document.getElementById('token-form');
|
|
231
|
+
form.elements.token.value = decodeURIComponent(token);
|
|
232
|
+
form.querySelector('button').setAttribute('aria-busy', 'true');
|
|
233
|
+
form.submit();
|
|
234
|
+
})();`;
|
|
235
|
+
|
|
215
236
|
function TokenPage({ request }: { request: Request }) {
|
|
216
237
|
const url = new URL(request.url);
|
|
217
238
|
const rejected = url.searchParams.get('token') === 'rejected';
|
|
@@ -238,7 +259,7 @@ function TokenPage({ request }: { request: Request }) {
|
|
|
238
259
|
</p>
|
|
239
260
|
) : null}
|
|
240
261
|
</form>
|
|
241
|
-
<
|
|
262
|
+
<script dangerouslySetInnerHTML={{ __html: TOKEN_FROM_HASH }} />
|
|
242
263
|
</AuthPanel>
|
|
243
264
|
);
|
|
244
265
|
}
|
|
@@ -284,10 +305,11 @@ export default function DashLayout({
|
|
|
284
305
|
const { pathname, host } = new URL(request.url);
|
|
285
306
|
const me = load(request).me();
|
|
286
307
|
const active = load(request).tasks.list({ cursor: '', limit: 1, summary: true, counts: true });
|
|
287
|
-
const
|
|
308
|
+
const side = /(?:^|; )side=(min|max)(?:;|$)/.exec(request.headers.get('cookie') ?? '')?.[1];
|
|
288
309
|
|
|
289
310
|
return (
|
|
290
|
-
<div class={
|
|
311
|
+
<div class={side === 'min' ? 'app side-min' : 'app'}>
|
|
312
|
+
{side ? null : <script dangerouslySetInnerHTML={{ __html: SIDE_AUTO }} />}
|
|
291
313
|
<header class="top">
|
|
292
314
|
<div class="top-l">
|
|
293
315
|
<Drawer />
|
|
@@ -307,7 +329,7 @@ export default function DashLayout({
|
|
|
307
329
|
<nav aria-label="Dashboard">
|
|
308
330
|
{navFor(request.headers.get('x-coder-mode') === 'local').map(
|
|
309
331
|
({ within, label, icon, ...to }) => (
|
|
310
|
-
<CurrentLink key={within} {...to} within={within}
|
|
332
|
+
<CurrentLink key={within} {...to} within={within} data-tip={label}>
|
|
311
333
|
<Icon d={icon} />
|
|
312
334
|
{label}
|
|
313
335
|
{label === 'Tasks' ? (
|
|
@@ -320,7 +342,7 @@ export default function DashLayout({
|
|
|
320
342
|
)}
|
|
321
343
|
</nav>
|
|
322
344
|
<div class="side-foot">
|
|
323
|
-
<SideToggle collapsed={
|
|
345
|
+
<SideToggle collapsed={side === 'min'} />
|
|
324
346
|
<WithMe me={me}>{who => <ServerMenu me={who} host={host} />}</WithMe>
|
|
325
347
|
</div>
|
|
326
348
|
</aside>
|
|
@@ -4,7 +4,7 @@ import './credentials-list.css';
|
|
|
4
4
|
|
|
5
5
|
import { useEffect, useRef, useState } from 'preact/hooks';
|
|
6
6
|
|
|
7
|
-
import { client } from '@/utils/client';
|
|
7
|
+
import { client, poll } from '@/utils/client';
|
|
8
8
|
import { iCheck, iCopy, iDots } from '@/comps/ui/icons';
|
|
9
9
|
import { useRouter } from '@wular/pnext/navigation/client';
|
|
10
10
|
import type { CredentialRow, EngineStatus, Me } from '@coder/client/types';
|
|
@@ -336,23 +336,30 @@ export function EngineLogins({ status: initial }: { status: EngineStatus }) {
|
|
|
336
336
|
const [status, setStatus] = useState(initial);
|
|
337
337
|
const [busy, setBusy] = useState('');
|
|
338
338
|
const [error, setError] = useState('');
|
|
339
|
-
const waiting = useRef<
|
|
339
|
+
const waiting = useRef<() => void>();
|
|
340
340
|
|
|
341
341
|
// A sign-in finishes in the browser the engine opened; the status says when.
|
|
342
342
|
const watch = (engine: string) => {
|
|
343
|
-
|
|
343
|
+
waiting.current?.();
|
|
344
344
|
const until = Date.now() + 5 * 60_000;
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
345
|
+
// A status read from a sign-in already stopped never stops the next one.
|
|
346
|
+
let current = true;
|
|
347
|
+
const stopPoll = poll(async () => {
|
|
348
|
+
const next = await client.engines.status();
|
|
349
|
+
if (!current) return;
|
|
350
|
+
setStatus(next);
|
|
351
|
+
if (next[engine as 'claude' | 'codex']?.signedIn || Date.now() > until) {
|
|
352
|
+
stop();
|
|
353
|
+
setBusy('');
|
|
354
|
+
}
|
|
353
355
|
}, 2000);
|
|
356
|
+
const stop = () => {
|
|
357
|
+
current = false;
|
|
358
|
+
stopPoll();
|
|
359
|
+
};
|
|
360
|
+
waiting.current = stop;
|
|
354
361
|
};
|
|
355
|
-
useEffect(() => () =>
|
|
362
|
+
useEffect(() => () => waiting.current?.(), []);
|
|
356
363
|
const act = (engine: string, action: 'login' | 'logout') => {
|
|
357
364
|
setBusy(`${engine}:${action}`);
|
|
358
365
|
setError('');
|
|
@@ -413,7 +420,7 @@ export function EngineLogins({ status: initial }: { status: EngineStatus }) {
|
|
|
413
420
|
type="button"
|
|
414
421
|
class="btn ghost sm"
|
|
415
422
|
onClick={() => {
|
|
416
|
-
|
|
423
|
+
waiting.current?.();
|
|
417
424
|
setBusy('');
|
|
418
425
|
}}
|
|
419
426
|
>
|
|
@@ -5,7 +5,7 @@ import './credentials-list.css';
|
|
|
5
5
|
import './list.css';
|
|
6
6
|
import { dynamic } from '@wular/pnext/dynamic';
|
|
7
7
|
import { notFound } from '@wular/pnext/navigation';
|
|
8
|
-
import { DEFAULT_CONFIG } from '@coder/core/
|
|
8
|
+
import { DEFAULT_CONFIG } from '@coder/core/defaults';
|
|
9
9
|
|
|
10
10
|
import { load } from '@/api/load';
|
|
11
11
|
import { Settle, Stream } from '@/comps/frame/stream';
|
|
@@ -4,7 +4,7 @@ import './runners-list.css';
|
|
|
4
4
|
|
|
5
5
|
import { useEffect, useRef, useState } from 'preact/hooks';
|
|
6
6
|
|
|
7
|
-
import { client } from '@/utils/client';
|
|
7
|
+
import { client, poll } from '@/utils/client';
|
|
8
8
|
import {
|
|
9
9
|
iCheck,
|
|
10
10
|
iCopy,
|
|
@@ -246,15 +246,19 @@ function AddRunner({
|
|
|
246
246
|
useEffect(() => {
|
|
247
247
|
if (!pairing) return;
|
|
248
248
|
const until = Math.min(pairing.expiresAt, Date.now() + 15 * 60_000);
|
|
249
|
-
|
|
249
|
+
// A list read from a pairing already gone never ends the next one.
|
|
250
|
+
let current = true;
|
|
251
|
+
const stop = poll(async () => {
|
|
250
252
|
if (Date.now() > until) return cancel();
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
});
|
|
253
|
+
const rows = await client.runners.list();
|
|
254
|
+
if (!current || !rows.items.some(row => !known.includes(row.id))) return;
|
|
255
|
+
onAdded(rows);
|
|
256
|
+
cancel();
|
|
256
257
|
}, 2000);
|
|
257
|
-
return () =>
|
|
258
|
+
return () => {
|
|
259
|
+
current = false;
|
|
260
|
+
stop();
|
|
261
|
+
};
|
|
258
262
|
}, [pairing]);
|
|
259
263
|
|
|
260
264
|
const cancel = () => {
|
|
@@ -411,10 +415,7 @@ export function RunnersList({ first, me }: { first: Runners; me: Me }) {
|
|
|
411
415
|
const items = sortedRunners(rows.items);
|
|
412
416
|
|
|
413
417
|
// Online dots stay fresh while the tab is open.
|
|
414
|
-
useEffect(() =>
|
|
415
|
-
const timer = setInterval(() => void client.runners.list().then(setRows, () => {}), 30_000);
|
|
416
|
-
return () => clearInterval(timer);
|
|
417
|
-
}, []);
|
|
418
|
+
useEffect(() => poll(() => client.runners.list().then(setRows), 30_000), []);
|
|
418
419
|
|
|
419
420
|
const change = async (act: () => Promise<unknown>) => {
|
|
420
421
|
setError('');
|