@wular/coder 0.4.2 → 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/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-DRsPpQFl.js → add-B50dIJGd.js} +1 -1
- package/dist/{add-DkpUwhtO.js → add-D7X3gxap.js} +1 -1
- package/dist/{add-C2y-mVzl.js → add-DOEUHIe7.js} +1 -1
- package/dist/{add-CLYTF_up.js → add-QExQhTzi.js} +1 -1
- package/dist/{add-json-5uPnWPoD.js → add-json-Ck4KIZrT.js} +1 -1
- package/dist/{agent-r5mMcehf.js → agent-BPtnEf1q.js} +1 -1
- package/dist/{agent-hw3zKw8y.js → agent-BlQ_dNNm.js} +2 -2
- package/dist/{alias-_0Rwf2cA.js → alias-BwQBovke.js} +1 -1
- package/dist/{app-oE8G1-bi.js → app-y6BYm2eH.js} +1 -1
- package/dist/{approvals-DbVrsxec.js → approvals-Cc9cq5T1.js} +2 -2
- package/dist/{approve-DeAhFL-m.js → approve-oO9k2fnK.js} +2 -2
- package/dist/{apps-eujHiNca.js → apps-CU2YalX8.js} +1 -1
- package/dist/{archive-BCUfymIB.js → archive-C5c_HQS1.js} +2 -2
- package/dist/{archive-DZ6vpMHb.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-BU2WVxVM.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-DWCR7iqa.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-12pK4qW7.js → config-DAE_qHYA.js} +1 -1
- package/dist/{create-D3f6q0Yq.js → create-CM8B8JxD.js} +1 -1
- package/dist/credentials-BXD4Qptk.js +1 -0
- package/dist/dash/manifest.json +949 -915
- package/dist/dash/public/assets/chunks/{agent-pills-dd0b7643e125bbf1.js → agent-pills-b6a6da91c9559d9f.js} +1 -1
- package/dist/dash/public/assets/chunks/{agent-settings-form-45ae6aeaaed2b568.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-952a457d52360d88.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-661f3b3a85f1776a.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-03ba6fb2ade7d282.js → custom-range-463e119af4681c61.js} +1 -1
- package/dist/dash/public/assets/chunks/{editor-34cb529d6d8a4b09.js → editor-804b84f4fe6539cd.js} +4 -4
- package/dist/dash/public/assets/chunks/{engines-list-2f1acee3ecc8461a.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-87b359bebd26986a.js → list-7270361464fc3c04.js} +1 -1
- package/dist/dash/public/assets/chunks/{mcp-list-b42f0d2ee463b37d.js → mcp-list-2e715d48666b54ad.js} +1 -1
- package/dist/dash/public/assets/chunks/{models-list-0669d26fd662aec3.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-c92ca3c6198a9387.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-1013702bdfb1ade4.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-f964fa864699f095.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-account-96fc41be318839fa.css → dash-account-edc56e85dbaaabe0.css} +1 -1
- 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-53b8e6a8f656fa1a.css → dash-settings-cf1997cd7f72e518.css} +1 -1
- 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-884943221f76ad93.css → dash-usage-40940b289f85e0b6.css} +1 -1
- 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-2693db10b197ade1.js → pnext-client-61db65dc4223217a.js} +1 -1
- 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-1afa4148bea69ad2.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/{default-CwQXCtoB.js → default-BMvUMTFp.js} +1 -1
- package/dist/default-B_nKaX0-.js +1 -0
- package/dist/{delete-cS01oOIb.js → delete-Bjteibld.js} +2 -2
- package/dist/{delete-BD6AnCLg.js → delete-riCIKZwj.js} +2 -2
- package/dist/{disable-BMWWeYFQ.js → disable-DQC56YFy.js} +1 -1
- package/dist/{discover-Dvr_3_Xr.js → discover-Qanr5TEO.js} +1 -1
- package/dist/{discover-Cfx5RPU7.js → discover-lgTYwoQp.js} +2 -2
- package/dist/dispatch-BsW_1m7e.js +14 -0
- package/dist/{docs-DWegDRiu.js → docs-DFs7lOJp.js} +1 -1
- package/dist/{docs-BX65z2Iu.js → docs-DKROso-4.js} +2 -2
- package/dist/{enable-Cfzeau2x.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-kAxxVOiR.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-C4tDFH4G.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-DuPqU3fk.js → list-4Uo-0v9s.js} +1 -1
- package/dist/{list-COAo7eZd.js → list-B0ujEZhd.js} +3 -3
- package/dist/{list-5Ljf9TxF.js → list-B5oa1Bhy.js} +2 -2
- package/dist/{list-vOvIpbOH.js → list-BjE_l6la.js} +1 -1
- package/dist/{list-J8d_zh-o.js → list-Ck9ibCs1.js} +1 -1
- package/dist/{list-vpyS-hv8.js → list-DhgK4Zc4.js} +1 -1
- package/dist/{list-way5oLO0.js → list-KvL7AUhD.js} +2 -2
- package/dist/{list-DzGuMkQy.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-BBw95-S3.js → login-C-ahtDKV.js} +1 -1
- package/dist/{login-CNmeRAL7.js → login-zpwke8g1.js} +1 -1
- package/dist/{logout-j0dTo_Ib.js → logout-CI6Kf-T6.js} +1 -1
- package/dist/{maintenance-DkLVtqM7.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-CsmBtlW9.js → mcp-mhXwtGQT.js} +1 -1
- package/dist/{migrate-N-85_N7J.js → migrate-Czh3TEK5.js} +1 -1
- package/dist/{migrate-D4nzYhk8.js → migrate-w7KfzUAR.js} +1 -1
- package/dist/{model-B79MFtRV.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-DbdnbZYt.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-BNzbUhaK.js → remove-C15WLaXT.js} +1 -1
- package/dist/{remove-D-QeeZQL.js → remove-CTZYjjSr.js} +1 -1
- package/dist/{remove-CLpL12Ya.js → remove-CTl-H0f0.js} +1 -1
- package/dist/{remove-CaYH9Cna.js → remove-DX2FVo5b.js} +1 -1
- package/dist/rename-D1g4TnHQ.js +1 -0
- package/dist/{result-BfTfJayl.js → result-D49VN8PM.js} +3 -3
- package/dist/result-DGWyUHYU.js +18 -0
- package/dist/{resume-aZ8yWDBh.js → resume-ywzc7z6A.js} +2 -2
- package/dist/{review-BEhDcX4b.js → review-ZC0xG8XY.js} +2 -2
- package/dist/{rotate-key-BqnKhTK8.js → rotate-key-Bf8_99ck.js} +1 -1
- package/dist/{run-BWbabvub.js → run-D7SJ-ieT.js} +2 -2
- package/dist/run-DoRQSC_K.js +2 -0
- package/dist/{run-BdPjxaZU.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-C0WC-QrV.js → serve-C1MMhM1F.js} +2 -2
- package/dist/{serve-CcObDKKQ.js → serve-DtrOHaoS.js} +2 -2
- package/dist/{serve-Ck95047c.js → serve-P9pFkEnE.js} +1 -1
- package/dist/{serve-BTeomYxW.js → serve-yjSw0B1a.js} +1 -1
- package/dist/{server-BxLFZL80.js → server-DDWTnmbx.js} +1 -1
- package/dist/{setup-host-DLd_j2Uw.js → setup-host-L6Rnn5Cz.js} +1 -1
- package/dist/{shared-BLkGRKty.js → shared-XsUX_ZZb.js} +1 -1
- package/dist/{show-DzoQIs75.js → show-CU-jqJ90.js} +1 -1
- package/dist/{show-FC3dJcD-.js → show-DVJmB2u-.js} +1 -1
- package/dist/{status-BU3DR1XU.js → status-CBydR7LE.js} +1 -1
- package/dist/{steer-P_38hRRD.js → steer-Cm_sHZqs.js} +2 -2
- package/dist/{stop-BJGDRPsp.js → stop-DJS7DAPJ.js} +1 -1
- package/dist/{stop-BWY6k6v5.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-BrSrhop9.js → test-CDKz4jY_.js} +1 -1
- package/dist/{tools-CgswhJzh.js → tools-DBFeoosk.js} +1 -1
- package/dist/{types-I5Cwtl_K.d.ts → types-DMGBYB_K.d.ts} +3 -1
- package/dist/{unalias-mMHXqok7.js → unalias-BfQFBnuK.js} +1 -1
- package/dist/{update-DbOWToPy.js → update-C4FFOie8.js} +1 -1
- package/dist/{upgrade-D6oC9HQI.js → upgrade-DLJqMnUQ.js} +2 -2
- package/dist/{usage-Cb8Dtv9V.js → usage-CSh-xwQ2.js} +1 -1
- package/dist/{usage-DMs-IIJC.js → usage-D8mc4qXK.js} +1 -1
- package/dist/{watch-BcMQXGYO.js → watch-CQu-tJKZ.js} +2 -2
- package/dist/{watch-eE2XiwsC.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-Cshghoas.js → workflow-IrouAus_.js} +1 -1
- 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 +1 -1
- 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 +11 -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.tsx +13 -3
- package/src/server/dash/app/dash/settings/[tab]/credentials-list.tsx +20 -13
- 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 +15 -4
- 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 +4 -0
- package/src/server/dash/comps/ui/select.tsx +2 -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-Cxbh8yAI.js +0 -1
- package/dist/auth-CBWTmAPA.js +0 -1
- package/dist/auth-Dmn2U7rr.js +0 -1
- package/dist/credentials-l6dsrZLL.js +0 -1
- package/dist/dash/public/assets/chunks/agents-grid-b906da80c31fc035.js +0 -1
- package/dist/dash/public/assets/chunks/composer-49f9e7c5c4dfda3b.js +0 -1
- package/dist/dash/public/assets/chunks/composer-f331d00837143aee.js +0 -1
- package/dist/dash/public/assets/chunks/credentials-list-e6177d0943517929.js +0 -2
- package/dist/dash/public/assets/chunks/format-eb03fc9d9744d960.js +0 -1
- package/dist/dash/public/assets/chunks/heads-1570a3a6db331979.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-9fffa50432c470c9.js +0 -1
- package/dist/dash/public/assets/chunks/shared-init-20e199043ff5d00f.js +0 -2
- package/dist/dash/public/assets/chunks/shared-init-88cce66bb3cfe1e5.js +0 -5
- package/dist/dash/public/assets/chunks/task-actions-a9603d520434baab.js +0 -1
- package/dist/dash/public/assets/chunks/task-fa8b82e95e771c4a.js +0 -1
- package/dist/dash/public/assets/chunks/task-view-f7039cb330bcb0b5.js +0 -3
- package/dist/dash/public/assets/chunks/tasks-list-2a905b4a0c3a9042.js +0 -1
- package/dist/dash/public/assets/dash-agents-290a7b21c7dc0c92.css +0 -1
- package/dist/dash/public/assets/dash-agents-new-a7a07bf4ebda24c2.css +0 -1
- package/dist/dash/public/assets/dash-agents-param-slug-69a72fb0bbd14cc2.css +0 -1
- package/dist/dash/public/assets/dash-agents-param-slug-edit-397bdfb2f0ca328c.css +0 -1
- package/dist/dash/public/assets/dash-agents-param-slug-platforms-a7b3b7247c27f1d2.css +0 -1
- package/dist/dash/public/assets/dash-agents-param-slug-settings-8389b7d0555e8ccf.css +0 -1
- package/dist/dash/public/assets/dash-agents-param-slug-tasks-5987b8aea5e8f30d.css +0 -1
- package/dist/dash/public/assets/dash-agents-param-slug-usage-19abc69e1d4e6b0a.css +0 -1
- package/dist/dash/public/assets/dash-settings-param-tab-ac61fdfdd6fd533f.css +0 -1
- package/dist/dash/public/assets/dash-tasks-cc0b1d32874b731c.css +0 -1
- package/dist/dash/public/assets/dash-tasks-param-id-02b8c7bd99cc1090.css +0 -1
- package/dist/dash/public/assets/pnext-client-17ba55bb57a1f4da.js +0 -1
- package/dist/dash/public/assets/pnext-client-43f52a07f8067b1b.js +0 -1
- package/dist/dash/public/assets/pnext-client-4594b693fe612835.js +0 -1
- package/dist/dash/public/assets/pnext-client-73f73e24f8141fb6.js +0 -1
- package/dist/dash/public/assets/pnext-client-7574da4651b40eae.js +0 -1
- package/dist/dash/public/assets/pnext-client-7b3a2c1092cbbb02.js +0 -1
- package/dist/dash/public/assets/pnext-client-816fe5fc96d3f768.js +0 -1
- package/dist/dash/public/assets/pnext-client-86cb956b448b0887.js +0 -1
- package/dist/dash/public/assets/pnext-client-8b64e3c030164288.js +0 -1
- package/dist/dash/public/assets/pnext-client-8f6161084c595a22.js +0 -1
- package/dist/dash/public/assets/pnext-client-9203ec11926e5d04.js +0 -1
- package/dist/dash/public/assets/pnext-client-a38b446f941d44df.js +0 -1
- package/dist/dash/public/assets/pnext-client-bd8d51aaa095e8a4.js +0 -1
- package/dist/dash/public/assets/pnext-client-e9821d1f1bdb281d.js +0 -1
- package/dist/default-De8FXiWz.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-BAgdVDhj.js +0 -5
- package/dist/integrations-D-L3uQRj.js +0 -1
- package/dist/log-view-dg0TlKLA.js +0 -1
- package/dist/models-_5LVGC3m.js +0 -1
- package/dist/queue-C9fSdE_X.js +0 -116
- package/dist/refresh-BDmap1RA.js +0 -1
- package/dist/rename-Bhcb4t9F.js +0 -1
- package/dist/result-D8DsvJDu.js +0 -15
- package/dist/run-Dqe38jX8.js +0 -2
- package/dist/runner-BPpiJvHx.js +0 -1
- package/dist/schema-CU2iFkp8.js +0 -1
- package/dist/serve-DA5I2qXj.js +0 -4
- package/dist/store-B3ZHoBJY.js +0 -8
- package/dist/store-BLi19UDE.js +0 -42
- package/dist/task-C6VAg5WU.js +0 -1
- package/dist/task-b2BK481M.js +0 -1
- package/dist/worker-CXndxmGF.js +0 -9
- package/dist/worker-DrucI22w.js +0 -1
|
@@ -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
|
}
|
|
@@ -213,6 +213,15 @@ async function ActiveCount({ count }: { count: Promise<TasksPage> }) {
|
|
|
213
213
|
) : null;
|
|
214
214
|
}
|
|
215
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
|
+
|
|
216
225
|
// `serve` opens /dash#token=…: the fragment never reaches the server, so the form posts it while the page loads, busy from first paint.
|
|
217
226
|
const TOKEN_FROM_HASH = `(() => {
|
|
218
227
|
const token = /(?:^|&)token=([^&]+)/.exec(location.hash.slice(1))?.[1];
|
|
@@ -296,10 +305,11 @@ export default function DashLayout({
|
|
|
296
305
|
const { pathname, host } = new URL(request.url);
|
|
297
306
|
const me = load(request).me();
|
|
298
307
|
const active = load(request).tasks.list({ cursor: '', limit: 1, summary: true, counts: true });
|
|
299
|
-
const
|
|
308
|
+
const side = /(?:^|; )side=(min|max)(?:;|$)/.exec(request.headers.get('cookie') ?? '')?.[1];
|
|
300
309
|
|
|
301
310
|
return (
|
|
302
|
-
<div class={
|
|
311
|
+
<div class={side === 'min' ? 'app side-min' : 'app'}>
|
|
312
|
+
{side ? null : <script dangerouslySetInnerHTML={{ __html: SIDE_AUTO }} />}
|
|
303
313
|
<header class="top">
|
|
304
314
|
<div class="top-l">
|
|
305
315
|
<Drawer />
|
|
@@ -332,7 +342,7 @@ export default function DashLayout({
|
|
|
332
342
|
)}
|
|
333
343
|
</nav>
|
|
334
344
|
<div class="side-foot">
|
|
335
|
-
<SideToggle collapsed={
|
|
345
|
+
<SideToggle collapsed={side === 'min'} />
|
|
336
346
|
<WithMe me={me}>{who => <ServerMenu me={who} host={host} />}</WithMe>
|
|
337
347
|
</div>
|
|
338
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
|
>
|
|
@@ -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('');
|
|
@@ -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;
|