@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
|
@@ -0,0 +1,336 @@
|
|
|
1
|
+
import './filter.css';
|
|
2
|
+
import { Fragment, type ComponentChildren } from 'preact';
|
|
3
|
+
import { useEffect, useRef, useState } from 'preact/hooks';
|
|
4
|
+
|
|
5
|
+
import { FILTER_ROWS } from '@/utils/paged';
|
|
6
|
+
import { iLeft, iRight, iSearch, iX } from './icons';
|
|
7
|
+
import { Icon } from './icon';
|
|
8
|
+
import { Menu, MenuRadio } from './menu';
|
|
9
|
+
import type { Option } from './select';
|
|
10
|
+
|
|
11
|
+
const RECENT = 'coder:filters';
|
|
12
|
+
|
|
13
|
+
/** From this many options a facet's full list gets a find box. */
|
|
14
|
+
const FIND = 5;
|
|
15
|
+
|
|
16
|
+
/** One thing a list filters by; an empty value is its default and shows no chip. */
|
|
17
|
+
export interface Facet<K extends string = string> {
|
|
18
|
+
key: K;
|
|
19
|
+
label: string;
|
|
20
|
+
/** The picks shown before typing. */
|
|
21
|
+
options: Option[];
|
|
22
|
+
/** A fixed list, always in the menu with its default as a row; its chip is its pick alone. */
|
|
23
|
+
inline?: boolean;
|
|
24
|
+
/** Each pick's icon: an icon path or a ready element. */
|
|
25
|
+
icon?: (value: string) => string | ComponentChildren;
|
|
26
|
+
/** Finds picks on the server once something is typed, at most `limit`. */
|
|
27
|
+
search?: (q: string, limit: number) => Promise<Option[]>;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/** How many of a facet's picks the menu lists before "More". */
|
|
31
|
+
const SHOWN = 5;
|
|
32
|
+
|
|
33
|
+
/** The picks the menu lists for a facet: the first few, keeping the current pick in view. */
|
|
34
|
+
export function inlineRows(picks: Option[], value: string) {
|
|
35
|
+
if (picks.length <= SHOWN) return picks;
|
|
36
|
+
const shown = picks.slice(0, SHOWN);
|
|
37
|
+
const current = picks.find(([key]) => key === value);
|
|
38
|
+
|
|
39
|
+
return current && !shown.includes(current) ? [...shown.slice(0, SHOWN - 1), current] : shown;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/** Whether a facet's own list needs a find box. */
|
|
43
|
+
const findable = (facet: Facet) => facet.options.filter(([value]) => value).length >= FIND;
|
|
44
|
+
|
|
45
|
+
/** What a facet's value reads as; "Any" for its default. */
|
|
46
|
+
export function valueLabel<K extends string>(
|
|
47
|
+
facet: Facet<K>,
|
|
48
|
+
value: string,
|
|
49
|
+
seen: Record<string, string> = {},
|
|
50
|
+
) {
|
|
51
|
+
if (!value) return 'Any';
|
|
52
|
+
|
|
53
|
+
return (
|
|
54
|
+
facet.options.find(([key]) => key === value)?.[1] ?? seen[`${facet.key}:${value}`] ?? value
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/** The filters that are on, one chip each in facet order. */
|
|
59
|
+
export function filterChips<K extends string>(
|
|
60
|
+
facets: Facet<K>[],
|
|
61
|
+
values: Record<K, string>,
|
|
62
|
+
seen: Record<string, string> = {},
|
|
63
|
+
) {
|
|
64
|
+
return facets
|
|
65
|
+
.filter(facet => values[facet.key])
|
|
66
|
+
.map(facet => {
|
|
67
|
+
const label = valueLabel(facet, values[facet.key], seen);
|
|
68
|
+
|
|
69
|
+
return { key: facet.key, text: facet.inline ? label : `${facet.label}: ${label}` };
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/** A facet list's rows: recent picks that match first, then the rest, at most FILTER_ROWS. */
|
|
74
|
+
export function listRows(rows: Option[], recent: Option[], q: string) {
|
|
75
|
+
const needle = q.trim().toLowerCase();
|
|
76
|
+
const first = recent.filter(([, label]) => label.toLowerCase().includes(needle));
|
|
77
|
+
const all = [...first, ...rows.filter(([value]) => !first.some(([kept]) => kept === value))];
|
|
78
|
+
|
|
79
|
+
return { shown: all.slice(0, FILTER_ROWS), more: all.length > FILTER_ROWS };
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function readRecent(): Record<string, Option[]> {
|
|
83
|
+
try {
|
|
84
|
+
return JSON.parse(localStorage.getItem(RECENT) ?? '{}') ?? {};
|
|
85
|
+
} catch {
|
|
86
|
+
return {};
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function keepRecent(list: string, pick: Option) {
|
|
91
|
+
const all = readRecent();
|
|
92
|
+
all[list] = [pick, ...(all[list] ?? []).filter(([value]) => value !== pick[0])].slice(0, 5);
|
|
93
|
+
localStorage.setItem(RECENT, JSON.stringify(all));
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/** One Filter button over every facet, and a removable chip for each filter that is on; `name` keeps each list's recent picks apart. */
|
|
97
|
+
export function Filter<K extends string>({
|
|
98
|
+
name,
|
|
99
|
+
facets,
|
|
100
|
+
values,
|
|
101
|
+
onChange,
|
|
102
|
+
}: {
|
|
103
|
+
name: string;
|
|
104
|
+
facets: Facet<K>[];
|
|
105
|
+
values: Record<K, string>;
|
|
106
|
+
onChange: (key: K, value: string) => void;
|
|
107
|
+
}) {
|
|
108
|
+
// Labels of picks the options lack, so a chip names an agent found by search.
|
|
109
|
+
const [seen, setSeen] = useState<Record<string, string>>({});
|
|
110
|
+
const remember = (key: K, rows: Option[]) =>
|
|
111
|
+
setSeen(current => ({
|
|
112
|
+
...current,
|
|
113
|
+
...Object.fromEntries(rows.map(([value, label]) => [`${key}:${value}`, label])),
|
|
114
|
+
}));
|
|
115
|
+
useEffect(() => {
|
|
116
|
+
const recent = readRecent();
|
|
117
|
+
for (const facet of facets) remember(facet.key, recent[`${name}:${facet.key}`] ?? []);
|
|
118
|
+
}, []);
|
|
119
|
+
const chips = filterChips(facets, values, seen);
|
|
120
|
+
|
|
121
|
+
return (
|
|
122
|
+
<>
|
|
123
|
+
<Menu
|
|
124
|
+
class="filter-more"
|
|
125
|
+
summaryClass={`field-btn${chips.length ? ' on' : ''}`}
|
|
126
|
+
summary={chips.length ? `Filter · ${chips.length}` : 'Filter'}
|
|
127
|
+
>
|
|
128
|
+
<FilterPanel
|
|
129
|
+
name={name}
|
|
130
|
+
facets={facets}
|
|
131
|
+
values={values}
|
|
132
|
+
seen={seen}
|
|
133
|
+
onFound={remember}
|
|
134
|
+
onPick={(facet, [value, label]) => {
|
|
135
|
+
if (!facet.inline && value !== values[facet.key]) {
|
|
136
|
+
keepRecent(`${name}:${facet.key}`, [value, label]);
|
|
137
|
+
remember(facet.key, [[value, label]]);
|
|
138
|
+
}
|
|
139
|
+
onChange(facet.key, facet.inline || value !== values[facet.key] ? value : '');
|
|
140
|
+
}}
|
|
141
|
+
/>
|
|
142
|
+
</Menu>
|
|
143
|
+
<span class="filter-chips">
|
|
144
|
+
{chips.map(chip => (
|
|
145
|
+
<button
|
|
146
|
+
key={chip.key}
|
|
147
|
+
type="button"
|
|
148
|
+
class="chip"
|
|
149
|
+
title={chip.text}
|
|
150
|
+
aria-label={`Clear ${chip.text}`}
|
|
151
|
+
onClick={() => onChange(chip.key, '')}
|
|
152
|
+
>
|
|
153
|
+
<span class="grow">{chip.text}</span>
|
|
154
|
+
<Icon d={iX} />
|
|
155
|
+
</button>
|
|
156
|
+
))}
|
|
157
|
+
</span>
|
|
158
|
+
</>
|
|
159
|
+
);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/** The menu's facets; a long facet opens its own list in place, and Escape steps back out of it. */
|
|
163
|
+
function FilterPanel<K extends string>({
|
|
164
|
+
name,
|
|
165
|
+
facets,
|
|
166
|
+
values,
|
|
167
|
+
seen,
|
|
168
|
+
onFound,
|
|
169
|
+
onPick,
|
|
170
|
+
}: {
|
|
171
|
+
name: string;
|
|
172
|
+
facets: Facet<K>[];
|
|
173
|
+
values: Record<K, string>;
|
|
174
|
+
seen: Record<string, string>;
|
|
175
|
+
onFound: (key: K, rows: Option[]) => void;
|
|
176
|
+
onPick: (facet: Facet<K>, pick: Option) => void;
|
|
177
|
+
}) {
|
|
178
|
+
const root = useRef<HTMLDivElement>(null);
|
|
179
|
+
const [open, setOpen] = useState<Facet<K>>();
|
|
180
|
+
const [q, setQ] = useState('');
|
|
181
|
+
const [found, setFound] = useState<Option[]>();
|
|
182
|
+
const asked = useRef(0);
|
|
183
|
+
const from = useRef<K>();
|
|
184
|
+
const typed = q.trim();
|
|
185
|
+
|
|
186
|
+
const focus = (selector: string) => root.current?.querySelector<HTMLElement>(selector)?.focus();
|
|
187
|
+
const show = (facet?: Facet<K>) => {
|
|
188
|
+
if (facet) from.current = facet.key;
|
|
189
|
+
setOpen(facet);
|
|
190
|
+
setQ('');
|
|
191
|
+
setFound(undefined);
|
|
192
|
+
};
|
|
193
|
+
|
|
194
|
+
useEffect(() => {
|
|
195
|
+
const pop = root.current!.closest<HTMLElement>('[popover]')!;
|
|
196
|
+
const toggle = (event: Event) => {
|
|
197
|
+
if ((event as ToggleEvent).newState === 'open') focus('.pop-item');
|
|
198
|
+
else show();
|
|
199
|
+
};
|
|
200
|
+
pop.addEventListener('toggle', toggle);
|
|
201
|
+
return () => pop.removeEventListener('toggle', toggle);
|
|
202
|
+
}, []);
|
|
203
|
+
|
|
204
|
+
useEffect(() => {
|
|
205
|
+
if (!root.current?.closest(':popover-open')) return;
|
|
206
|
+
focus(open ? 'input' : `[data-facet="${from.current}"]`);
|
|
207
|
+
}, [open]);
|
|
208
|
+
|
|
209
|
+
useEffect(() => {
|
|
210
|
+
if (!open?.search || !typed) return;
|
|
211
|
+
const ask = ++asked.current;
|
|
212
|
+
const timer = setTimeout(
|
|
213
|
+
() =>
|
|
214
|
+
void open.search!(typed, FILTER_ROWS + 1).then(
|
|
215
|
+
rows => {
|
|
216
|
+
if (asked.current !== ask) return;
|
|
217
|
+
setFound(rows);
|
|
218
|
+
onFound(open.key, rows);
|
|
219
|
+
},
|
|
220
|
+
() => asked.current === ask && setFound([]),
|
|
221
|
+
),
|
|
222
|
+
200,
|
|
223
|
+
);
|
|
224
|
+
return () => clearTimeout(timer);
|
|
225
|
+
}, [open, typed]);
|
|
226
|
+
|
|
227
|
+
const rows = open
|
|
228
|
+
? open.search && typed
|
|
229
|
+
? (found ?? [])
|
|
230
|
+
: open.options.filter(
|
|
231
|
+
([value, label]) => value && label.toLowerCase().includes(typed.toLowerCase()),
|
|
232
|
+
)
|
|
233
|
+
: [];
|
|
234
|
+
const list = open
|
|
235
|
+
? listRows(rows, readRecent()[`${name}:${open.key}`] ?? [], typed)
|
|
236
|
+
: { shown: [], more: false };
|
|
237
|
+
const searching = Boolean(open?.search && typed && !found);
|
|
238
|
+
|
|
239
|
+
const onKeyDown = (event: KeyboardEvent) => {
|
|
240
|
+
const items = [...root.current!.querySelectorAll<HTMLElement>('input, .pop-item')];
|
|
241
|
+
const at = items.indexOf(document.activeElement as HTMLElement);
|
|
242
|
+
const target = event.target as HTMLElement;
|
|
243
|
+
const key = event.key;
|
|
244
|
+
if (key === 'ArrowDown') items[(at + 1) % items.length]?.focus();
|
|
245
|
+
else if (key === 'ArrowUp') items[(at - 1 + items.length) % items.length]?.focus();
|
|
246
|
+
else if (key === 'ArrowRight' && target.dataset.facet) target.click();
|
|
247
|
+
else if (key === 'ArrowLeft' && open && target.tagName !== 'INPUT') show();
|
|
248
|
+
else if (key === 'Enter' && target.tagName === 'INPUT') focus('[role=menuitemradio]');
|
|
249
|
+
else if (key === 'Escape' && open) {
|
|
250
|
+
event.stopPropagation();
|
|
251
|
+
show();
|
|
252
|
+
} else return;
|
|
253
|
+
event.preventDefault();
|
|
254
|
+
};
|
|
255
|
+
|
|
256
|
+
return (
|
|
257
|
+
<div ref={root} class="filter-panel" onKeyDown={onKeyDown}>
|
|
258
|
+
{open ? (
|
|
259
|
+
<>
|
|
260
|
+
<button type="button" class="pop-item" data-keep onClick={() => show()}>
|
|
261
|
+
<Icon d={iLeft} />
|
|
262
|
+
<span class="grow">{open.label}</span>
|
|
263
|
+
</button>
|
|
264
|
+
{findable(open) ? (
|
|
265
|
+
<label class="search">
|
|
266
|
+
<Icon d={iSearch} />
|
|
267
|
+
<input
|
|
268
|
+
type="search"
|
|
269
|
+
value={q}
|
|
270
|
+
placeholder={`Find ${open.label.toLowerCase()}`}
|
|
271
|
+
aria-label={`Find ${open.label.toLowerCase()}`}
|
|
272
|
+
autocomplete="off"
|
|
273
|
+
onInput={event => setQ(event.currentTarget.value)}
|
|
274
|
+
/>
|
|
275
|
+
</label>
|
|
276
|
+
) : null}
|
|
277
|
+
<div role="group" aria-label={open.label} aria-busy={searching}>
|
|
278
|
+
{list.shown.map(([value, label]) => (
|
|
279
|
+
<MenuRadio
|
|
280
|
+
key={value}
|
|
281
|
+
icon={open.icon?.(value)}
|
|
282
|
+
on={values[open.key] === value}
|
|
283
|
+
onPick={() => onPick(open, [value, label])}
|
|
284
|
+
>
|
|
285
|
+
{label}
|
|
286
|
+
</MenuRadio>
|
|
287
|
+
))}
|
|
288
|
+
</div>
|
|
289
|
+
{list.more ? (
|
|
290
|
+
<p class="pop-note">Type to find more.</p>
|
|
291
|
+
) : !list.shown.length && !searching ? (
|
|
292
|
+
<p class="pop-note">Nothing matches.</p>
|
|
293
|
+
) : null}
|
|
294
|
+
</>
|
|
295
|
+
) : (
|
|
296
|
+
facets.map(facet => {
|
|
297
|
+
const picks = facet.options.filter(([value]) => facet.inline || value);
|
|
298
|
+
if (!picks.length) return null;
|
|
299
|
+
const shown = inlineRows(picks, values[facet.key]);
|
|
300
|
+
|
|
301
|
+
return (
|
|
302
|
+
<Fragment key={facet.key}>
|
|
303
|
+
<p class="pop-label">{facet.label}</p>
|
|
304
|
+
<div role="group" aria-label={facet.label}>
|
|
305
|
+
{shown.map(([value, label]) => (
|
|
306
|
+
<MenuRadio
|
|
307
|
+
key={value}
|
|
308
|
+
icon={facet.icon?.(value)}
|
|
309
|
+
on={values[facet.key] === value}
|
|
310
|
+
onPick={() => onPick(facet, [value, label])}
|
|
311
|
+
>
|
|
312
|
+
{label}
|
|
313
|
+
</MenuRadio>
|
|
314
|
+
))}
|
|
315
|
+
</div>
|
|
316
|
+
{picks.length > shown.length ? (
|
|
317
|
+
<button
|
|
318
|
+
type="button"
|
|
319
|
+
class="pop-item"
|
|
320
|
+
data-keep
|
|
321
|
+
data-facet={facet.key}
|
|
322
|
+
aria-haspopup="true"
|
|
323
|
+
onClick={() => show(facet)}
|
|
324
|
+
>
|
|
325
|
+
<span class="grow">More</span>
|
|
326
|
+
<span class="muted">{picks.length - shown.length}</span>
|
|
327
|
+
<Icon d={iRight} />
|
|
328
|
+
</button>
|
|
329
|
+
) : null}
|
|
330
|
+
</Fragment>
|
|
331
|
+
);
|
|
332
|
+
})
|
|
333
|
+
)}
|
|
334
|
+
</div>
|
|
335
|
+
);
|
|
336
|
+
}
|
|
@@ -38,6 +38,8 @@ export const iSearch = 'M4 11a7 7 0 1 0 14 0a7 7 0 1 0 -14 0M20 20l-3.5-3.5';
|
|
|
38
38
|
export const iAlert =
|
|
39
39
|
'm21.7 18-8-14a2 2 0 0 0-3.4 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.7-3M12 9v4M12 17h.01';
|
|
40
40
|
export const iTerminal = 'm4 17 6-6-6-6M12 19h8';
|
|
41
|
+
export const iFolder =
|
|
42
|
+
'M4 20h16a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.9a2 2 0 0 1-1.7-.9l-.8-1.2A2 2 0 0 0 7.9 3H4a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2Z';
|
|
41
43
|
export const iClock = 'M12 7v5l3 2M3 12a9 9 0 1 0 18 0a9 9 0 1 0 -18 0';
|
|
42
44
|
export const iPlug = 'M9 2v6M15 2v6M6 8h12v4a6 6 0 0 1-12 0ZM12 18v4';
|
|
43
45
|
export const iCopy = 'M9 9h11v11H9ZM5 15H4V4h11v1';
|
|
@@ -13,6 +13,7 @@ export function Menu({
|
|
|
13
13
|
summary,
|
|
14
14
|
summaryClass,
|
|
15
15
|
label,
|
|
16
|
+
tip,
|
|
16
17
|
align = 'right',
|
|
17
18
|
wide,
|
|
18
19
|
class: cls,
|
|
@@ -21,6 +22,8 @@ export function Menu({
|
|
|
21
22
|
summary: ComponentChildren;
|
|
22
23
|
summaryClass?: string;
|
|
23
24
|
label?: string;
|
|
25
|
+
/** A styled tooltip in place of the native title, where the layout shows one. */
|
|
26
|
+
tip?: string;
|
|
24
27
|
align?: 'right' | 'up' | 'left';
|
|
25
28
|
wide?: boolean;
|
|
26
29
|
class?: string;
|
|
@@ -34,7 +37,8 @@ export function Menu({
|
|
|
34
37
|
type="button"
|
|
35
38
|
class={summaryClass}
|
|
36
39
|
aria-label={label}
|
|
37
|
-
title={label}
|
|
40
|
+
title={tip ? undefined : label}
|
|
41
|
+
data-tip={tip}
|
|
38
42
|
>
|
|
39
43
|
{summary}
|
|
40
44
|
</button>
|
|
@@ -131,10 +135,13 @@ export function MoreList({ label, children }: { label: string; children: Compone
|
|
|
131
135
|
export function MenuRadio({
|
|
132
136
|
on,
|
|
133
137
|
onPick,
|
|
138
|
+
icon,
|
|
134
139
|
children,
|
|
135
140
|
}: {
|
|
136
141
|
on: boolean;
|
|
137
142
|
onPick: () => void;
|
|
143
|
+
/** An icon path or a ready element. */
|
|
144
|
+
icon?: string | ComponentChildren;
|
|
138
145
|
children: ComponentChildren;
|
|
139
146
|
}) {
|
|
140
147
|
return (
|
|
@@ -145,6 +152,7 @@ export function MenuRadio({
|
|
|
145
152
|
class={on ? 'pop-item on' : 'pop-item'}
|
|
146
153
|
onClick={onPick}
|
|
147
154
|
>
|
|
155
|
+
{typeof icon === 'string' ? <Icon d={icon} /> : icon}
|
|
148
156
|
<span class="grow">{children}</span>
|
|
149
157
|
{on ? <Icon d={iCheck} /> : null}
|
|
150
158
|
</button>
|
|
@@ -135,8 +135,8 @@ export function Select({
|
|
|
135
135
|
setPlace(
|
|
136
136
|
`left:${Math.round(Math.min(box.left, innerWidth - menu.offsetWidth - 8))}px;min-width:${Math.round(box.width)}px;` +
|
|
137
137
|
(up
|
|
138
|
-
? `bottom:${Math.round(innerHeight - box.top + 4)}px;max-height:${Math.round(Math.min(
|
|
139
|
-
: `top:${Math.round(box.bottom + 4)}px;max-height:${Math.round(Math.min(
|
|
138
|
+
? `bottom:${Math.round(innerHeight - box.top + 4)}px;max-height:${Math.round(Math.min(560, box.top - 12))}px`
|
|
139
|
+
: `top:${Math.round(box.bottom + 4)}px;max-height:${Math.round(Math.min(560, below))}px`),
|
|
140
140
|
);
|
|
141
141
|
};
|
|
142
142
|
position();
|
|
@@ -15,8 +15,9 @@
|
|
|
15
15
|
.toast {
|
|
16
16
|
position: relative;
|
|
17
17
|
display: grid;
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
grid-template-columns: minmax(0, 1fr);
|
|
19
|
+
gap: 6px;
|
|
20
|
+
padding: 14px 16px;
|
|
20
21
|
border: 1px solid var(--line2);
|
|
21
22
|
background: var(--tile);
|
|
22
23
|
box-shadow: 0 12px 32px rgba(0, 0, 0, 0.18);
|
|
@@ -24,6 +24,20 @@
|
|
|
24
24
|
grid-row: 1;
|
|
25
25
|
grid-column: 3;
|
|
26
26
|
}
|
|
27
|
+
.page {
|
|
28
|
+
container-type: inline-size;
|
|
29
|
+
}
|
|
30
|
+
/* with a primary action, the filters drop under the title before they would wrap */
|
|
31
|
+
@container (max-width: 720px) {
|
|
32
|
+
.head.tools:has(> .actions) > .filters {
|
|
33
|
+
grid-row: auto;
|
|
34
|
+
grid-column: 1 / -1;
|
|
35
|
+
justify-content: flex-start;
|
|
36
|
+
}
|
|
37
|
+
.head.tools:has(> .actions) .search {
|
|
38
|
+
max-width: none;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
27
41
|
|
|
28
42
|
/* lists: filters above, rows load on scroll */
|
|
29
43
|
.filters {
|
|
@@ -17,3 +17,24 @@ export async function signOut(): Promise<void> {
|
|
|
17
17
|
const { url } = await client.signOut();
|
|
18
18
|
location.href = url ?? '/?signed_out=1';
|
|
19
19
|
}
|
|
20
|
+
|
|
21
|
+
/** Runs `work` every `ms` once the last run settles, skipping while the tab is hidden; returns its stop. */
|
|
22
|
+
export function poll(work: () => Promise<unknown>, ms: number): () => void {
|
|
23
|
+
let timer: ReturnType<typeof setTimeout>;
|
|
24
|
+
let stopped = false;
|
|
25
|
+
const next = () => {
|
|
26
|
+
if (!stopped) timer = setTimeout(run, ms);
|
|
27
|
+
};
|
|
28
|
+
const run = () => {
|
|
29
|
+
if (document.visibilityState === 'hidden') return next();
|
|
30
|
+
void work()
|
|
31
|
+
.catch(() => {})
|
|
32
|
+
.finally(next);
|
|
33
|
+
};
|
|
34
|
+
next();
|
|
35
|
+
|
|
36
|
+
return () => {
|
|
37
|
+
stopped = true;
|
|
38
|
+
clearTimeout(timer);
|
|
39
|
+
};
|
|
40
|
+
}
|
|
@@ -19,17 +19,25 @@ const parts = (value: number, tz: string, options: Intl.DateTimeFormatOptions) =
|
|
|
19
19
|
);
|
|
20
20
|
|
|
21
21
|
// Built from parts, so every ICU version, on the server or in the browser, prints the same text.
|
|
22
|
-
|
|
22
|
+
/** `short` prints only the time today and leaves out this year. */
|
|
23
|
+
export function formatDate(value: number | undefined, tz: string, short?: boolean) {
|
|
23
24
|
if (!value) return 'Not available';
|
|
24
|
-
const
|
|
25
|
+
const options: Intl.DateTimeFormatOptions = {
|
|
25
26
|
month: 'short',
|
|
26
27
|
day: 'numeric',
|
|
27
28
|
year: 'numeric',
|
|
28
29
|
hour: 'numeric',
|
|
29
30
|
minute: '2-digit',
|
|
30
31
|
hour12: true,
|
|
31
|
-
}
|
|
32
|
-
|
|
32
|
+
};
|
|
33
|
+
const p = parts(value, tz, options);
|
|
34
|
+
const time = `${p.hour}:${p.minute} ${p.dayPeriod}`;
|
|
35
|
+
if (!short) return `${p.month} ${p.day}, ${p.year}, ${time}`;
|
|
36
|
+
|
|
37
|
+
const now = parts(Date.now(), tz, options);
|
|
38
|
+
if (p.year !== now.year) return `${p.month} ${p.day}, ${p.year}, ${time}`;
|
|
39
|
+
|
|
40
|
+
return p.month === now.month && p.day === now.day ? time : `${p.month} ${p.day}, ${time}`;
|
|
33
41
|
}
|
|
34
42
|
|
|
35
43
|
/** The time of day as `formatDate` prints it, with seconds. */
|
|
@@ -61,13 +61,15 @@ export function usePaged<T>({
|
|
|
61
61
|
const sentinel = useRef<HTMLElement>(null);
|
|
62
62
|
const live = useRef(state);
|
|
63
63
|
live.current = state;
|
|
64
|
-
|
|
64
|
+
// The load in flight; each is its own object, so an answer to an older load for the same page never passes.
|
|
65
|
+
const loading = useRef<{ key: string } | undefined>(undefined);
|
|
65
66
|
const failed = useRef<(() => void) | undefined>(undefined);
|
|
66
67
|
|
|
67
68
|
const load = (cursor: string, forQuery: string, append: boolean) => {
|
|
68
69
|
const key = `${forQuery}|${cursor}`;
|
|
69
|
-
if (loading.current === key) return;
|
|
70
|
-
|
|
70
|
+
if (loading.current?.key === key) return;
|
|
71
|
+
const request = { key };
|
|
72
|
+
loading.current = request;
|
|
71
73
|
setError('');
|
|
72
74
|
setBusy(true);
|
|
73
75
|
const since = performance.now();
|
|
@@ -77,7 +79,7 @@ export function usePaged<T>({
|
|
|
77
79
|
void fetchPage(cursor)
|
|
78
80
|
.then(held(since))
|
|
79
81
|
.then(page => {
|
|
80
|
-
if (loading.current !==
|
|
82
|
+
if (loading.current !== request) return;
|
|
81
83
|
if (!append) firstPages.current.set(forQuery, { page, at: Date.now() });
|
|
82
84
|
setError('');
|
|
83
85
|
failed.current = undefined;
|
|
@@ -95,12 +97,12 @@ export function usePaged<T>({
|
|
|
95
97
|
});
|
|
96
98
|
})
|
|
97
99
|
.catch(reason => {
|
|
98
|
-
if (loading.current !==
|
|
100
|
+
if (loading.current !== request) return;
|
|
99
101
|
failed.current = () => load(cursor, forQuery, append);
|
|
100
102
|
setError(reason instanceof Error ? reason.message : String(reason));
|
|
101
103
|
})
|
|
102
104
|
.finally(() => {
|
|
103
|
-
if (loading.current !==
|
|
105
|
+
if (loading.current !== request) return;
|
|
104
106
|
loading.current = undefined;
|
|
105
107
|
setBusy(false);
|
|
106
108
|
});
|
|
@@ -118,6 +120,9 @@ export function usePaged<T>({
|
|
|
118
120
|
useEffect(() => {
|
|
119
121
|
if (seen.current === first) return;
|
|
120
122
|
seen.current = first;
|
|
123
|
+
// A page still loading belongs to the rows this replaces.
|
|
124
|
+
loading.current = undefined;
|
|
125
|
+
setBusy(false);
|
|
121
126
|
firstPages.current.set(initial, { page: first, at: Date.now() });
|
|
122
127
|
setState(fromPage(initial, first));
|
|
123
128
|
}, [first]);
|
|
@@ -182,3 +187,6 @@ export function readQuery(keys: string[]): Record<string, string> {
|
|
|
182
187
|
|
|
183
188
|
/** Rows a list loads per page; more load as it scrolls. */
|
|
184
189
|
export const LIST_PAGE = 20;
|
|
190
|
+
|
|
191
|
+
/** Rows a filter's list shows; typing finds the rest. */
|
|
192
|
+
export const FILTER_ROWS = 20;
|
package/dist/actions-Mk3FSlpJ.js
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import{t as e}from"./rolldown-runtime-DT7IzrpZ.js";import{Bt as t,Cn as n,Et as r,Gt as i,Lt as a,M as o,Mt as s,N as c,O as l,P as u,Qt as d,Rt as f,Tt as p,Wt as m,an as h,cn as g,d as ee,ft as _,j as v,jt as y,k as b,ln as x,mt as S,nn as C,nt as te,sn as w,tn as T,tt as E,un as D,vn as O,wt as k,x as A,xt as ne,z as j,zt as M}from"./dispatch-BKeAch9E.js";import{t as re}from"./chat-bridge-BS9WtP3X.js";import N from"node:path";import P from"node:process";import F from"node:fs";import{spawn as I}from"node:child_process";import L from"node:os";function R(){let e=process.env.CLAUDE_CONFIG_DIR||N.join(L.homedir(),`.claude`);return N.join(e,`projects`)}function z(e){if(!e)return!1;let t=R(),n=!1;try{for(let r of F.readdirSync(t)){let i=N.join(t,r,`${e}.jsonl`);F.existsSync(i)&&(F.rmSync(i,{force:!0}),n=!0)}}catch{}return n}var B=e({archiveFlagged:()=>ie,askTask:()=>q,claudeAskOptions:()=>K,collectPending:()=>J,collectTasks:()=>Y,deleteTask:()=>$,sidecarPrompt:()=>G,spawnArchiveSweep:()=>Q,steerTask:()=>H,stopTask:()=>Z,streamTask:()=>X});async function V(e,t,n,r,i={}){if(t.status!==`running`)return null;let a=t.engine===`claude`?await(i.claude??b)(t.steerEndpoint,n,void 0,r):await(i.codex??c)(e,{endpoint:t.steerEndpoint,threadId:t.threadId,turnId:t.turnId,text:n,command:r});if(a.steered)return p(e,t.id,{kind:`steer`,message:`Steer accepted live:\n${n}`}),{taskId:t.id,steered:`live`};if(!a.retryable)throw p(e,t.id,{kind:`error`,message:`Live steer failed: ${a.detail}`}),Error(`Could not steer running task ${t.id}: ${a.detail}`);let o=M(e,t.id)??t;return g.includes(o.status)?(y(e,o.id,n),p(e,o.id,{kind:`steer`,message:`Steer queued for the next turn:\n${n}`}),{taskId:o.id,steered:`queued`}):null}async function H(e,t,n,r={},i={}){if(!t.threadId)throw new ne(`invalid-option`,`Task ${t.id} has no thread to steer yet (status: ${t.status}).`,{hint:`Wait for it to start: coder task watch ${t.id}`});let a=await V(e,t,n,r.command,i);if(a){let n=M(e,t.id)??t;return n.archived&&h(e,n),a}return U(e,t,n,r),{taskId:t.id,steered:`resumed`}}function U(e,t,n,r){t.archived&&h(e,t),w(e,t.id,{status:`queued`,resumedAt:new Date().toISOString(),currentPrompt:n,...r.outputSchema?{outputSchema:r.outputSchema}:{},resumeThreadId:t.threadId,steerEndpoint:null,model:r.model??t.model??null,effort:r.effort??t.effort??null,permissions:r.permissions??t.permissions,error:void 0}),p(e,t.id,{kind:`steer`,message:`Resuming with steer:\n${n}`}),ee(t.cwd??e,t.id)}const W=[`Read`,`Glob`,`Grep`];function G(e,t,n){return`You are a read-only sidecar answering a question ABOUT a coder task.
|
|
2
|
-
You are not the task. Never continue, redo, or fix its work. Only answer the question. The task never sees this question or your answer.
|
|
3
|
-
|
|
4
|
-
Task metadata:
|
|
5
|
-
${[`id: ${e.id}`,...e.name?[`name: ${e.name}`]:[],`status: ${e.status}`,`engine: ${e.engine}${e.model?`/${e.model}`:``}${e.effort?`/${e.effort}`:``}`,...e.cwd?[`workspace: ${e.cwd}`]:[],...e.createdAt?[`created: ${e.createdAt}`]:[],...e.completedAt?[`finished: ${e.completedAt}`]:[]].join(`
|
|
6
|
-
`)}
|
|
7
|
-
|
|
8
|
-
Task prompt:
|
|
9
|
-
${e.prompt??`(unknown)`}
|
|
10
|
-
|
|
11
|
-
Inspect as needed (grep/read selectively; events can be large):
|
|
12
|
-
- progress log (jsonl, one event per line): ${N.join(t,`log.jsonl`)}
|
|
13
|
-
- final result: ${N.join(t,`result.json`)}
|
|
14
|
-
- worker output: ${N.join(t,`worker.log`)}
|
|
15
|
-
${e.cwd?`- the task's workspace (its code and changes): ${e.cwd}`:``}
|
|
16
|
-
|
|
17
|
-
Question: ${n}
|
|
18
|
-
|
|
19
|
-
Answer the question directly and concisely.`}function K(e,t,n,r){return{prompt:n,model:r.model??e.model,effort:r.effort,permissions:`read-only`,additionalDirectories:[t],taskRoot:t,readOnlyAllowedTools:W}}async function q(e,t,n,r={}){let i=d(e,t.id),a=G(t,i,n)+(r.command?`\n\nCoder command ${j(r.command)}`:``),s=r.command?e=>{let t=N.join(i,`inbox-control`);F.mkdirSync(t,{recursive:!0}),F.appendFileSync(N.join(t,`${j(r.command)}.transcript.jsonl`),JSON.stringify({command:r.command,result:e.finalMessage??e.error?.message??``})+`
|
|
20
|
-
`)}:void 0,c=r.effort??t.effort??null;if(t.engine===`claude`)return l(t.cwd??e,{...K(t,i,a,{model:r.model,effort:c}),command:r.command,onResult:s});let u=te(e),f=r.model??t.model,p=f?u.models?.[f]:void 0,m=p&&E(p)?p:void 0;if(m?.envKey&&!P.env[m.envKey])throw Error(`Missing environment variable: \`${m.envKey}\`.`);let h=m?await re(m,m.wireApi??`chat`):null,g=S(u,f,h??void 0);try{return await o(t.cwd??e,{prompt:a,model:g?.model??_(f??null),modelProvider:g?.modelProvider??null,configOverrides:g?.configOverrides??null,effort:c,sandbox:`read-only`,approvalPolicy:`never`,ephemeral:!0,onResult:s})}finally{await h?.close()}}function J(e){return f(e).filter(e=>g.includes(e.status)).flatMap(t=>A(d(e,t.id)).filter(e=>!e.response).map(e=>({taskId:t.id,id:e.id,summary:String(e.summary??``),createdAt:e.createdAt?String(e.createdAt):void 0})))}function Y(e,n={}){let r=n.limit===`all`?void 0:n.limit,i=e=>x.includes(e.status),o=[],s=f(e).filter(n=>{if(!i(n))return!0;let r=n.completedAt??n.updatedAt??n.createdAt;return k(r)<=6e5||(t(e,n),o.push(n.id),!1)});if(Q(e,o),n.archived?s=a(e):n.running?s=s.filter(e=>g.includes(e.status)):n.stopped&&(s=s.filter(i)),n.dir){let e=T(N.resolve(String(n.dir))),t=new Map;s=s.filter(n=>n.cwd?(t.has(n.cwd)||t.set(n.cwd,T(n.cwd)),t.get(n.cwd)===e):!1)}if(!n.archived&&!n.running&&!n.stopped){let e=e=>e.status===`failed`?0:g.includes(e.status)?1:e.status===`completed`?3:2;s=[...s].sort((t,n)=>e(t)-e(n))}let c=r===void 0?0:Math.max(0,s.length-r);return r!==void 0&&(s=s.slice(0,r)),{tasks:s,clipped:c}}async function*X(e,t,r={}){let i=new Set([`completed`,`failed`,`cancelled`]),a=M(e,t);if(!a)throw Error(`No task found for "${t}".`);let o=r.tail??1,s=n(N.join(d(e,t),`log.jsonl`)),c=!0,l=()=>{let e=s().map(e=>{try{return JSON.parse(e)}catch{return{message:e}}});return c?(c=!1,o===`all`?e:C(e,o)):e};for(yield*l();!i.has(a.status);)await new Promise(e=>setTimeout(e,400)),a=m(e,M(e,t)??a),yield*l();yield*l()}async function Z(e,t,n={}){let r=t.engine===`claude`?{detail:`claude worker terminated`}:await(n.interrupt??v)(e,{endpoint:t.steerEndpoint,threadId:t.threadId,turnId:t.turnId});if(t.engine!==`claude`&&u(t.steerEndpoint),t.pid&&t.status===`running`)try{P.kill(t.pid,`SIGTERM`)}catch{}return w(e,t.id,{status:`cancelled`,steerEndpoint:null,completedAt:new Date().toISOString()}),{taskId:t.id,status:`cancelled`,interrupt:r.detail}}function Q(e,t,n={}){if(t.length)try{I(P.execPath,[O,`task`,`archive-sweep`,`--cwd`,e,...n.flows?[`--flows`]:[],...t],{detached:!0,stdio:`ignore`}).unref()}catch{}}function $(e,t){return t.threadId&&(t.engine===`claude`?z(t.threadId):D(e,t.threadId)),i(e,t.id)}function ie(e,t){for(let n of t){let t=s(e,n);t&&x.includes(t.status)&&r(e,t)}}export{$ as a,Z as c,Y as i,X as l,q as n,Q as o,J as r,H as s,B as t};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{i as e}from"./cli-BilSDkvE.js";import{n as t,s as n}from"./args-BOEEdpWk.js";const r=e({name:`task archive-sweep`,options:{cwd:n,flows:t},args:1/0,run:async({options:e,args:t,cwd:n})=>{let{archiveFlagged:r}=await import(`./actions-Mk3FSlpJ.js`).then(e=>e.t),{archiveFlaggedRuns:i}=await import(`./executor-BvAA7Cgw.js`).then(e=>e.y);return e.flows?i(t):r(n,t)}});export{r as commandArchiveSweep};
|
package/dist/auth-BFny--17.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{i as e,l as t}from"./http-Bkg_OQ6r.js";import{Ft as n,dn as r,un as i}from"./store-DzqXS2wT.js";import{c as a}from"./schema-CU2iFkp8.js";import{a as o,i as s,o as c}from"./serve-CQKZxzFE.js";import{createECDH as l,hkdfSync as u}from"node:crypto";import*as d from"openid-client";import{and as f,eq as p}from"drizzle-orm";import{EncryptJWT as m,calculateJwkThumbprint as h,createRemoteJWKSet as g,jwtDecrypt as _,jwtVerify as v}from"jose";const y=(e,t)=>new Uint8Array(u(`sha256`,e,``,t,32));async function b(e){let t=y(e,`coder oidc client key`),n=l(`prime256v1`);n.setPrivateKey(t);let r=n.getPublicKey(),i={kty:`EC`,crv:`P-256`,x:Buffer.from(r.subarray(1,33)).toString(`base64url`),y:Buffer.from(r.subarray(33)).toString(`base64url`)},a=await crypto.subtle.importKey(`jwk`,{...i,d:Buffer.from(t).toString(`base64url`)},{name:`ECDSA`,namedCurve:`P-256`},!1,[`sign`]),o=await h(i);return{key:a,kid:o,jwk:{...i,kid:o,alg:`ES256`,use:`sig`}}}async function x(e){let t=[e.encryptionKey,e.previousEncryptionKey].filter(e=>!!e),n=await Promise.all(t.map(b));return{cookie:t.map(e=>y(e,`coder session cookie`)),client:n[0],jwks:{keys:n.map(e=>e.jwk)}}}const S=`${i}.session`,C=`${i}.oidc`,w=3800,T=2592e3,E=()=>Math.floor(Date.now()/1e3);function D(e){let t=new Map;for(let n of(e.get(`cookie`)??``).split(/;\s*/)){let e=n.indexOf(`=`);e>0&&t.set(n.slice(0,e),n.slice(e+1))}return t}function O(e){let t=[];for(;e.has(`${S}.${t.length}`);)t.push(`${S}.${t.length}`);return t}function k(e){let t=D(e);return t.get(S)??(O(t).map(e=>t.get(e)).join(``)||void 0)}function A(e){return Array.isArray(e)?e.flatMap(e=>typeof e?.id==`string`&&typeof e.role==`string`?[{id:e.id,slug:String(e.slug??e.id),name:String(e.name??e.slug??e.id),role:e.role}]:[]):[]}function j(e,t,n){let r=e.get(`x-coder-organization`),i=r?t.organizations.find(e=>e.slug===r||e.id===r):t.organizations.find(e=>e.id===n)??t.organizations[0];return i?{...t,organizationId:i.id,role:i.role}:r?{...t,organizationDenied:!0}:t}async function M(i,l){let u=l.auth.wular.url,h=l.publicUrl,y=new URL(h).origin,b=h.startsWith(`https:`),M=await x(l),N=`${h}${s}`,P=(e,t,n)=>`${e}=${t}; Path=/; HttpOnly; SameSite=Lax; Max-Age=${n}${b?`; Secure`:``}`,F=(e,t)=>new m(e).setProtectedHeader({alg:`dir`,enc:`A256GCM`}).setIssuedAt().setExpirationTime(`${t}s`).encrypt(M.cookie[0]);async function I(e){if(e)for(let t of M.cookie)try{return(await _(e,t)).payload}catch{}}async function L(e,t){let n=await F(t,T),r=O(D(e));if(n.length<=w)return[P(S,n,T),...r.map(e=>P(e,``,0))];let i=n.match(RegExp(`.{1,${w}}`,`g`));return[P(S,``,0),...i.map((e,t)=>P(`${S}.${t}`,e,T)),...r.slice(i.length).map(e=>P(e,``,0))]}let R=e=>[S,...O(D(e))].map(e=>P(e,``,0)),z,B=()=>z??=d.discovery(new URL(u),`${h}${c}`,void 0,d.PrivateKeyJwt(M.client),new URL(u).protocol===`http:`?{execute:[d.allowInsecureRequests]}:void 0).catch(e=>{throw z=void 0,e}),V,H=async()=>V??=g(new URL((await B()).serverMetadata().jwks_uri));function U(e,t){let n=e.claims();if(!n)throw Error(`Wular Auth returned no ID token`);let r=A(n.organizations);return{sub:n.sub,name:typeof n.name==`string`?n.name:``,email:typeof n.email==`string`?n.email:``,orgs:r,org:r.some(e=>e.id===t?.org)?t.org:r[0]?.id,exp_at:E()+(e.expires_in??600),at:E(),rt:e.refresh_token??t?.rt,idt:e.id_token??t?.idt}}let W=new Map;function G(e){let t=e.rt;if(!t)return Promise.resolve(void 0);let n=W.get(t);return n||(n=B().then(e=>d.refreshTokenGrant(e,t)).then(t=>U(t,e)).catch(()=>{W.delete(t)}),W.set(t,n),setTimeout(()=>W.delete(t),6e4).unref?.()),n}async function K(e,t,n){let r=(await H().then(t=>v(e,t,{issuer:u,audience:y,typ:`at+jwt`})).catch(()=>void 0))?.payload;if(!r?.sub)return;let i={user:{id:r.sub,name:``,email:``},organizations:A(r.organizations)};return n&&E()-(r.iat??0)>60?{...i,stale:!0}:j(t,i)}async function q(e){let t=await B().catch(()=>void 0);if(!t)return Response.redirect(`${h}/login?error=unavailable`,302);let n={verifier:d.randomPKCECodeVerifier(),state:d.randomState(),nonce:d.randomNonce(),return:r(e.searchParams.get(`return`),y)},i=d.buildAuthorizationUrl(t,{redirect_uri:N,scope:o,code_challenge:await d.calculatePKCECodeChallenge(n.verifier),code_challenge_method:`S256`,state:n.state,nonce:n.nonce});return new Response(null,{status:302,headers:{location:i.href,"set-cookie":P(C,await F(n,600),600)}})}async function J(e,t){let n=e=>{let t=new Headers({location:`/login?error=${encodeURIComponent(e)}`});return t.append(`set-cookie`,P(C,``,0)),new Response(null,{status:302,headers:t})},r=await I(D(e.headers).get(C));if(!r)return n(`expired`);let i=t.searchParams.get(`error`);if(i)return n(i);let a;try{a=U(await d.authorizationCodeGrant(await B(),new URL(`${N}${t.search}`),{pkceCodeVerifier:r.verifier,expectedState:r.state,expectedNonce:r.nonce,idTokenExpected:!0}))}catch{return n(`sign_in_failed`)}let o=new Headers({location:r.return});o.append(`set-cookie`,P(C,``,0));for(let t of await L(e.headers,a))o.append(`set-cookie`,t);return new Response(null,{status:302,headers:o})}async function Y(t){if(!n(t,h))return e();let r=await I(k(t.headers)),i=await B().catch(()=>void 0),a=`${h}/?signed_out=1`,o=i?.serverMetadata().end_session_endpoint&&r?.idt?d.buildEndSessionUrl(i,{id_token_hint:r.idt,post_logout_redirect_uri:a}).href:a,s=Response.json({url:o});for(let e of R(t.headers))s.headers.append(`set-cookie`,e);return s}return{issuer:u,jwks:M.jwks,handler(e){let n=new URL(e.url);return n.pathname===`/api/auth/sign-in`&&e.method===`GET`?q(n):n.pathname===`/api/auth/callback`&&e.method===`GET`?J(e,n):n.pathname===`/api/auth/sign-out`&&e.method===`POST`?Y(e):Promise.resolve(t())},async session(e,t=!1){let n=e.get(`authorization`);if(n?.startsWith(`Bearer `))return K(n.slice(7),e,t);let r=await I(k(e));if(!r)return;let i;if(r.exp_at<=E()||t&&E()-r.at>60){if(r=await G(r),!r)return;i=await L(e,r)}return j(e,{user:{id:r.sub,name:r.name,email:r.email},organizations:r.orgs,...i?{cookies:i}:{}},r.org)},async setOrganization(e,t){let n=await I(k(e)),r=n?.orgs.find(e=>e.slug===t);if(!(!n||!r))return{...r,cookies:await L(e,{...n,org:r.id})}},async link(e,t,n,r={}){let o={name:e.name,email:e.email,...r.organizations?{organizations:r.organizations}:{},...r.token?{token:r.token}:{}};await i.insert(a).values({platform:t,platformUserId:n,userId:e.id,...o}).onConflictDoUpdate({target:[a.platform,a.platformUserId],set:o,setWhere:p(a.userId,e.id)});let[s]=await i.select({userId:a.userId}).from(a).where(f(p(a.platform,t),p(a.platformUserId,n)));return s?.userId===e.id?`linked`:`taken`},async linkedUser(e,t){let[n]=await i.select({id:a.userId,name:a.name,email:a.email,organizations:a.organizations,token:a.token}).from(a).where(f(p(a.platform,e),p(a.platformUserId,t)));return n&&{id:n.id,name:n.name,email:n.email,...n.organizations?{organizations:n.organizations}:{},...n.token?{token:n.token}:{}}}}}export{M as createAuth};
|
package/dist/auth-DWHIzqbA.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{s as e}from"./cli-BilSDkvE.js";const t=e(`auth`,{login:async()=>(await import(`./login-BFxX4jJy.js`)).commandLogin,logout:async()=>(await import(`./logout-BHAtw4Z8.js`)).commandLogout,status:async()=>(await import(`./status-D26U--p8.js`)).commandStatus},{menu:[{usage:`login`,blurb:`sign in through the browser`},{usage:`logout`,blurb:`sign out and forget the saved session`},{usage:`status`,blurb:`show where you are signed in`}],description:[`Sign in to Coder and manage saved server sessions.`],exampleCommand:`auth login`});export{t as commandAuth};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{s as e}from"./cli-BilSDkvE.js";const t=e(`credentials`,{list:async()=>(await import(`./list-BxEywhHU.js`)).commandCredentialsList,add:async()=>(await import(`./add-ej0X9e3a.js`)).commandCredentialsAdd,login:async()=>(await import(`./login-DkkslfBx.js`)).commandCredentialsLogin,remove:async()=>(await import(`./remove-eQ8y5C5p.js`)).commandCredentialsRemove,default:async()=>(await import(`./default-vYPT26DR.js`)).commandCredentialsDefault},void 0,{help:{usage:`coder credentials [list|add|login|remove|default] ...`,summary:`Manage engine credentials. Your personal ones are yours alone; workspace ones serve every member, and only owners and admins change them. A task runs on its requester's default for the engine, else the workspace's.`}});export{t as commandCredentials};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use client";import{a as h,b,c as k}from"./agent-pills-c9c4ac4d4a10df83.js";import{a as C}from"./tail-7c27aab8ba268bd9.js";import{a as w,b as A,c as v,d as P}from"./toolbar-a75d2570f07cbb70.js";import{b as y}from"./paged-bc6fa0c2b9d52ed7.js";import"./badge-676b01e0c615bf7b.js";import{b as u}from"./card-e0901d68b79dfa93.js";import{f}from"./format-eb03fc9d9744d960.js";import"./sentinel-c972a33dc69a5135.js";import{$2a as p}from"./shared-init-ffb3397e494137c9.js";import"./shared-init-ffb3397e494137c9.js";import{$4a as g,$4d as l}from"./shared-init-ffb3397e494137c9.js";import"./shared-init-ffb3397e494137c9.js";import"./shared-init-88cce66bb3cfe1e5.js";import{$0b as c}from"./shared-init-88cce66bb3cfe1e5.js";import{$2a as a}from"./shared-init-88cce66bb3cfe1e5.js";import{$1c as d}from"./shared-init-8f2ac936c95a7f7b.js";function I(){return a(p,{class:"btn",href:"/dash/agents/new",children:"New agent"})}function S({agent:t,catalog:m}){return a("li",{class:"agent-card",children:[a("div",{class:"bc-head",children:[a("span",{class:"mark",children:f(t.name)}),a("div",{class:"grow",children:[a("h3",{children:a(p,{class:"cover",href:"/dash/agents/[slug]",params:{slug:t.id},children:t.name})}),a("span",{class:"pills",children:a(k,{agent:t})})]})]}),a("div",{class:"lead-clamp",children:a("span",{children:t.description??"No description yet."})}),t.platforms.length?a("span",{class:"pfs",children:t.platforms.map(o=>a(b,{id:o.id,info:m.find(s=>s.id===o.id),state:o.state},o.id))}):a("span",{class:"pfs muted",children:"Listens nowhere yet"})]})}var K=[["","All agents"],["dashboard","Dashboard agents"],["repository","Repository agents"],["builtin","Built-in"]];function X({first:t,limit:m,filters:o,catalog:s,head:R,children:M}){let{values:n,set:i,query:N}=A(o),r=y({name:"agents",fetchPage:e=>c.agents.list({cursor:e,limit:m,...n}),query:N,first:t,initial:w(o)});return a(d,{children:[a(P,{head:R,action:a(I,{}),children:[a(v,{value:n.q,label:"Search agents",onInput:e=>i("q",e,250)}),a(g,{class:"filter-more",label:"More filters",summaryClass:`field-btn${n.platform||n.type?" on":""}`,summary:"Filter",children:[a("p",{class:"pop-label",children:"Platform"}),a("div",{role:"group","aria-label":"Platform",children:[a(l,{on:!n.platform,onPick:()=>i("platform",""),children:"All platforms"}),s.map(e=>a(l,{on:n.platform===e.id,onPick:()=>i("platform",e.id),children:a("span",{class:"pf",children:[a(h,{brand:e.brand}),e.name]})},e.id))]}),a("p",{class:"pop-label",children:"Source"}),a("div",{role:"group","aria-label":"Source",children:K.map(([e,q])=>a(l,{on:n.type===e,onPick:()=>i("type",e),children:q},e))})]})]}),M,r.rows.length?a("ul",{class:"agent-grid","aria-busy":r.stale,children:r.rows.map(e=>a(S,{agent:e,catalog:s},e.id))}):r.stale?null:a(u,{title:"No agents match",children:"Try another search or filter."}),a(C,{noun:"agents",...r})]})}export{X as AgentsGrid,K as KINDS};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use client";import{a,b,c,d}from"./composer-d10d4b1d54c4f751.js";import"./connect-repositories-5389ec8701a3deac.js";import"./composer-data-6f7608fed13f3dd7.js";import"./model-options-15c53331a2f28a4f.js";import"./select-7ae25fd8a7d6c338.js";import"./task-fa8b82e95e771c4a.js";import"./card-e0901d68b79dfa93.js";import"./field-901f1f35c18c39c9.js";import"./format-eb03fc9d9744d960.js";import"./shared-init-ffb3397e494137c9.js";import"./shared-init-ffb3397e494137c9.js";import"./wular-pnext-246221e985d863e5-0.js";import"./shared-init-ffb3397e494137c9.js";import"./shared-init-ffb3397e494137c9.js";import"./shared-init-ffb3397e494137c9.js";import"./shared-init-ffb3397e494137c9.js";import"./shared-init-88cce66bb3cfe1e5.js";import"./shared-init-88cce66bb3cfe1e5.js";import"./shared-init-88cce66bb3cfe1e5.js";import"./shared-init-246221e985d863e5-2.js";import"./shared-init-246221e985d863e5-2.js";import"./shared-init-8f2ac936c95a7f7b.js";export{b as Composer,c as LoadingComposer,a as NeedsCredential,d as NewTaskButton};
|