@henlii/pidance 0.2.36 → 0.2.39
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/.next/BUILD_ID +1 -1
- package/.next/app-path-routes-manifest.json +13 -10
- package/.next/build-manifest.json +6 -6
- package/.next/prerender-manifest.json +18 -3
- package/.next/required-server-files.json +29 -9
- package/.next/routes-manifest.json +20 -0
- package/.next/server/app/_global-error/page.js +2 -3
- package/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
- package/.next/server/app/_global-error.html +1 -1
- package/.next/server/app/_global-error.meta +16 -5
- package/.next/server/app/_global-error.rsc +3 -3
- package/.next/server/app/_global-error.segments/_full.segment.rsc +3 -3
- package/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +16 -1
- package/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/_not-found/page.js +1 -2
- package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/.next/server/app/_not-found.html +1 -1
- package/.next/server/app/_not-found.meta +16 -5
- package/.next/server/app/_not-found.rsc +7 -7
- package/.next/server/app/_not-found.segments/_full.segment.rsc +7 -7
- package/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +20 -1
- package/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/api/about/route.js +1 -1
- package/.next/server/app/api/agent/[id]/bash-output/route.js +1 -1
- package/.next/server/app/api/agent/[id]/events/route.js +2 -2
- package/.next/server/app/api/agent/[id]/route.js +1 -1
- package/.next/server/app/api/agent/new/route.js +1 -1
- package/.next/server/app/api/agent/running/events/route.js +2 -2
- package/.next/server/app/api/agent/running/route.js +1 -1
- package/.next/server/app/api/agent/submissions/[submissionId]/route.js +1 -1
- package/.next/server/app/api/agent-settings/route.js +2 -2
- package/.next/server/app/api/attachments/route.js +1 -1
- package/.next/server/app/api/auth/all-providers/route.js +1 -1
- package/.next/server/app/api/auth/api-key/[provider]/route.js +1 -1
- package/.next/server/app/api/auth/login/[provider]/route.js +2 -2
- package/.next/server/app/api/auth/logout/[provider]/route.js +1 -1
- package/.next/server/app/api/auth/providers/route.js +1 -1
- package/.next/server/app/api/auth/ui-session/route.js +1 -1
- package/.next/server/app/api/auth/ui-sessions/[id]/route.js +1 -1
- package/.next/server/app/api/auth/ui-sessions/route.js +1 -1
- package/.next/server/app/api/cwd/browse/route.js +1 -1
- package/.next/server/app/api/cwd/create/route.js +1 -1
- package/.next/server/app/api/cwd/validate/route.js +1 -1
- package/.next/server/app/api/default-cwd/route.js +1 -1
- package/.next/server/app/api/file-index/route.js +1 -1
- package/.next/server/app/api/files/[...path]/route.js +3 -3
- package/.next/server/app/api/files/save-as/route.js +1 -1
- package/.next/server/app/api/git/diff/route.js +1 -1
- package/.next/server/app/api/git/status/route.js +1 -1
- package/.next/server/app/api/home/route.js +1 -1
- package/.next/server/app/api/message-media/route.js +1 -1
- package/.next/server/app/api/models/enabled/route.js +1 -0
- package/.next/server/app/api/models/enabled/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/models/refresh/route.js +1 -0
- package/.next/server/app/api/models/refresh/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/models/route.js +1 -1
- package/.next/server/app/api/models-config/raw/route.js +1 -1
- package/.next/server/app/api/models-config/route.js +1 -1
- package/.next/server/app/api/models-config/test/route.js +1 -1
- package/.next/server/app/api/plugins/route.js +1 -1
- package/.next/server/app/api/plugins/search/route.js +1 -1
- package/.next/server/app/api/plugins/updates/route.js +1 -1
- package/.next/server/app/api/preferences/route.js +1 -1
- package/.next/server/app/api/project-assets/route.js +2 -2
- package/.next/server/app/api/prompts/route.js +1 -1
- package/.next/server/app/api/pty/route.js +2 -2
- package/.next/server/app/api/sessions/[id]/archive/route.js +1 -1
- package/.next/server/app/api/sessions/[id]/auto-name/route.js +1 -1
- package/.next/server/app/api/sessions/[id]/command-entry/route.js +1 -1
- package/.next/server/app/api/sessions/[id]/context/route.js +1 -1
- package/.next/server/app/api/sessions/[id]/entries/[entryId]/thinking/route.js +1 -1
- package/.next/server/app/api/sessions/[id]/export/route.js +1 -1
- package/.next/server/app/api/sessions/[id]/info/route.js +1 -1
- package/.next/server/app/api/sessions/[id]/lock/route.js +1 -0
- package/.next/server/app/api/sessions/[id]/lock/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/sessions/[id]/outline/route.js +1 -1
- package/.next/server/app/api/sessions/[id]/route.js +1 -1
- package/.next/server/app/api/sessions/[id]/state/route.js +1 -1
- package/.next/server/app/api/sessions/[id]/tool-results/[toolCallId]/route.js +1 -1
- package/.next/server/app/api/sessions/route.js +1 -1
- package/.next/server/app/api/sessions/search/route.js +1 -1
- package/.next/server/app/api/settings/raw/route.js +2 -2
- package/.next/server/app/api/settings/remote/route.js +1 -1
- package/.next/server/app/api/skills/check/route.js +1 -1
- package/.next/server/app/api/skills/install/route.js +1 -1
- package/.next/server/app/api/skills/route.js +2 -2
- package/.next/server/app/api/skills/search/route.js +1 -1
- package/.next/server/app/api/skills/update/route.js +1 -1
- package/.next/server/app/api/subagent-runs/route.js +1 -1
- package/.next/server/app/api/update/apply/route.js +2 -2
- package/.next/server/app/api/update/check/route.js +1 -1
- package/.next/server/app/icon.png/route.js +1 -1
- package/.next/server/app/index.html +1 -1
- package/.next/server/app/index.meta +11 -4
- package/.next/server/app/index.rsc +5 -5
- package/.next/server/app/index.segments/__PAGE__.segment.rsc +19 -3
- package/.next/server/app/index.segments/_full.segment.rsc +5 -5
- package/.next/server/app/index.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/page.js +13 -14
- package/.next/server/app/page_client-reference-manifest.js +1 -1
- package/.next/server/app-paths-manifest.json +13 -10
- package/.next/server/chunks/1069.js +1 -1
- package/.next/server/chunks/1207.js +2 -2
- package/.next/server/chunks/1813.js +1 -1
- package/.next/server/chunks/2325.js +2 -2
- package/.next/server/chunks/2430.js +193 -0
- package/.next/server/chunks/329.js +1 -1
- package/.next/server/chunks/3379.js +1 -1
- package/.next/server/chunks/3960.js +1 -1
- package/.next/server/chunks/42.js +1 -0
- package/.next/server/chunks/4367.js +1 -1
- package/.next/server/chunks/4674.js +1 -1
- package/.next/server/chunks/4741.js +152 -7
- package/.next/server/chunks/4980.js +1 -1
- package/.next/server/chunks/5274.js +1 -1
- package/.next/server/chunks/5304.js +2 -2
- package/.next/server/chunks/5318.js +1 -1
- package/.next/server/chunks/5420.js +1 -0
- package/.next/server/chunks/5726.js +1 -1
- package/.next/server/chunks/7307.js +1 -1
- package/.next/server/chunks/7594.js +11 -10
- package/.next/server/chunks/7818.js +1 -0
- package/.next/server/chunks/8359.js +1 -1
- package/.next/server/chunks/8443.js +1 -0
- package/.next/server/chunks/8645.js +1 -1
- package/.next/server/chunks/9280.js +3 -3
- package/.next/server/chunks/940.js +1 -1
- package/.next/server/chunks/981.js +1 -1
- package/.next/server/chunks/9935.js +1 -1
- package/.next/server/instrumentation.js +1 -1
- package/.next/server/middleware-build-manifest.js +1 -1
- package/.next/server/middleware-react-loadable-manifest.js +1 -1
- package/.next/server/middleware.js +151 -6
- package/.next/server/pages/404.html +1 -1
- package/.next/server/pages/500.html +1 -1
- package/.next/server/prefetch-hints.json +39 -1
- package/.next/server/server-reference-manifest.json +1 -1
- package/.next/static/chunks/{1377.e883e13864574c26.js → 1377.540f9477711dcf8f.js} +1 -1
- package/.next/static/chunks/{3308.23eadd1744bb967c.js → 3308.c0a1a01bfd826d65.js} +2 -2
- package/.next/static/chunks/{370.57cfa27da8567918.js → 370.8e8f3cf8eb0e29dd.js} +1 -1
- package/.next/static/chunks/3794-0a1186eb85c3950f.js +52 -0
- package/.next/static/chunks/4bd1b696-8a4ab4fdf0ae305a.js +1 -0
- package/.next/static/chunks/6121.eb9023b1cbc78ee2.js +1 -0
- package/.next/static/chunks/{5519-9fb47277a49697d8.js → 7444-80a846a8795bf6f4.js} +1 -1
- package/.next/static/chunks/{776.fe8e64ab3669a915.js → 776.4d418d68f76336c7.js} +1 -1
- package/.next/static/chunks/{8233.a465d18b04719c6d.js → 8233.e3b47a59bd72a3b3.js} +1 -1
- package/.next/static/chunks/{90542734.b75ad0df50bf68f5.js → 90542734.ae439f2382f58c51.js} +1 -1
- package/.next/static/chunks/9780-864f35ace9287b0b.js +1 -0
- package/.next/static/chunks/app/_global-error/page-8f70dda1817cd20c.js +1 -0
- package/.next/static/chunks/app/api/about/route-8f70dda1817cd20c.js +1 -0
- package/.next/static/chunks/app/api/agent/[id]/bash-output/route-8f70dda1817cd20c.js +1 -0
- package/.next/static/chunks/app/api/agent/[id]/events/route-8f70dda1817cd20c.js +1 -0
- package/.next/static/chunks/app/api/agent/[id]/route-8f70dda1817cd20c.js +1 -0
- package/.next/static/chunks/app/api/agent/new/route-8f70dda1817cd20c.js +1 -0
- package/.next/static/chunks/app/api/agent/running/events/route-8f70dda1817cd20c.js +1 -0
- package/.next/static/chunks/app/api/agent/running/route-8f70dda1817cd20c.js +1 -0
- package/.next/static/chunks/app/api/agent/submissions/[submissionId]/route-8f70dda1817cd20c.js +1 -0
- package/.next/static/chunks/app/api/agent-settings/route-8f70dda1817cd20c.js +1 -0
- package/.next/static/chunks/app/api/attachments/route-8f70dda1817cd20c.js +1 -0
- package/.next/static/chunks/app/api/auth/all-providers/route-8f70dda1817cd20c.js +1 -0
- package/.next/static/chunks/app/api/auth/api-key/[provider]/route-8f70dda1817cd20c.js +1 -0
- package/.next/static/chunks/app/api/auth/login/[provider]/route-8f70dda1817cd20c.js +1 -0
- package/.next/static/chunks/app/api/auth/logout/[provider]/route-8f70dda1817cd20c.js +1 -0
- package/.next/static/chunks/app/api/auth/providers/route-8f70dda1817cd20c.js +1 -0
- package/.next/static/chunks/app/api/auth/ui-session/route-8f70dda1817cd20c.js +1 -0
- package/.next/static/chunks/app/api/auth/ui-sessions/[id]/route-8f70dda1817cd20c.js +1 -0
- package/.next/static/chunks/app/api/auth/ui-sessions/route-8f70dda1817cd20c.js +1 -0
- package/.next/static/chunks/app/api/cwd/browse/route-8f70dda1817cd20c.js +1 -0
- package/.next/static/chunks/app/api/cwd/create/route-8f70dda1817cd20c.js +1 -0
- package/.next/static/chunks/app/api/cwd/validate/route-8f70dda1817cd20c.js +1 -0
- package/.next/static/chunks/app/api/default-cwd/route-8f70dda1817cd20c.js +1 -0
- package/.next/static/chunks/app/api/file-index/route-8f70dda1817cd20c.js +1 -0
- package/.next/static/chunks/app/api/files/[...path]/route-8f70dda1817cd20c.js +1 -0
- package/.next/static/chunks/app/api/files/save-as/route-8f70dda1817cd20c.js +1 -0
- package/.next/static/chunks/app/api/git/diff/route-8f70dda1817cd20c.js +1 -0
- package/.next/static/chunks/app/api/git/status/route-8f70dda1817cd20c.js +1 -0
- package/.next/static/chunks/app/api/home/route-8f70dda1817cd20c.js +1 -0
- package/.next/static/chunks/app/api/message-media/route-8f70dda1817cd20c.js +1 -0
- package/.next/static/chunks/app/api/models/enabled/route-8f70dda1817cd20c.js +1 -0
- package/.next/static/chunks/app/api/models/refresh/route-8f70dda1817cd20c.js +1 -0
- package/.next/static/chunks/app/api/models/route-8f70dda1817cd20c.js +1 -0
- package/.next/static/chunks/app/api/models-config/raw/route-8f70dda1817cd20c.js +1 -0
- package/.next/static/chunks/app/api/models-config/route-8f70dda1817cd20c.js +1 -0
- package/.next/static/chunks/app/api/models-config/test/route-8f70dda1817cd20c.js +1 -0
- package/.next/static/chunks/app/api/plugins/route-8f70dda1817cd20c.js +1 -0
- package/.next/static/chunks/app/api/plugins/search/route-8f70dda1817cd20c.js +1 -0
- package/.next/static/chunks/app/api/plugins/updates/route-8f70dda1817cd20c.js +1 -0
- package/.next/static/chunks/app/api/preferences/route-8f70dda1817cd20c.js +1 -0
- package/.next/static/chunks/app/api/project-assets/route-8f70dda1817cd20c.js +1 -0
- package/.next/static/chunks/app/api/prompts/route-8f70dda1817cd20c.js +1 -0
- package/.next/static/chunks/app/api/pty/route-8f70dda1817cd20c.js +1 -0
- package/.next/static/chunks/app/api/sessions/[id]/archive/route-8f70dda1817cd20c.js +1 -0
- package/.next/static/chunks/app/api/sessions/[id]/auto-name/route-8f70dda1817cd20c.js +1 -0
- package/.next/static/chunks/app/api/sessions/[id]/command-entry/route-8f70dda1817cd20c.js +1 -0
- package/.next/static/chunks/app/api/sessions/[id]/context/route-8f70dda1817cd20c.js +1 -0
- package/.next/static/chunks/app/api/sessions/[id]/entries/[entryId]/thinking/route-8f70dda1817cd20c.js +1 -0
- package/.next/static/chunks/app/api/sessions/[id]/export/route-8f70dda1817cd20c.js +1 -0
- package/.next/static/chunks/app/api/sessions/[id]/info/route-8f70dda1817cd20c.js +1 -0
- package/.next/static/chunks/app/api/sessions/[id]/lock/route-8f70dda1817cd20c.js +1 -0
- package/.next/static/chunks/app/api/sessions/[id]/outline/route-8f70dda1817cd20c.js +1 -0
- package/.next/static/chunks/app/api/sessions/[id]/route-8f70dda1817cd20c.js +1 -0
- package/.next/static/chunks/app/api/sessions/[id]/state/route-8f70dda1817cd20c.js +1 -0
- package/.next/static/chunks/app/api/sessions/[id]/tool-results/[toolCallId]/route-8f70dda1817cd20c.js +1 -0
- package/.next/static/chunks/app/api/sessions/route-8f70dda1817cd20c.js +1 -0
- package/.next/static/chunks/app/api/sessions/search/route-8f70dda1817cd20c.js +1 -0
- package/.next/static/chunks/app/api/settings/raw/route-8f70dda1817cd20c.js +1 -0
- package/.next/static/chunks/app/api/settings/remote/route-8f70dda1817cd20c.js +1 -0
- package/.next/static/chunks/app/api/skills/check/route-8f70dda1817cd20c.js +1 -0
- package/.next/static/chunks/app/api/skills/install/route-8f70dda1817cd20c.js +1 -0
- package/.next/static/chunks/app/api/skills/route-8f70dda1817cd20c.js +1 -0
- package/.next/static/chunks/app/api/skills/search/route-8f70dda1817cd20c.js +1 -0
- package/.next/static/chunks/app/api/skills/update/route-8f70dda1817cd20c.js +1 -0
- package/.next/static/chunks/app/api/subagent-runs/route-8f70dda1817cd20c.js +1 -0
- package/.next/static/chunks/app/api/update/apply/route-8f70dda1817cd20c.js +1 -0
- package/.next/static/chunks/app/api/update/check/route-8f70dda1817cd20c.js +1 -0
- package/.next/static/chunks/app/page-5f78e55ff0d87ec7.js +24 -0
- package/.next/static/chunks/{da12927c.00775c0e4542fd3e.js → da12927c.476aa688a637649c.js} +2 -2
- package/.next/static/chunks/{e868780c-16e43c5968ccf2bf.js → e868780c-1584512c612787d7.js} +1 -1
- package/.next/static/chunks/framework-b33a8f5d57cd8d87.js +1 -0
- package/.next/static/chunks/main-1b407bf74905d84a.js +5 -0
- package/.next/static/chunks/{main-app-06b2b50b226e40d1.js → main-app-d353053e6467499a.js} +1 -1
- package/.next/static/chunks/next/dist/client/components/builtin/app-error-8f70dda1817cd20c.js +1 -0
- package/.next/static/chunks/next/dist/client/components/builtin/forbidden-8f70dda1817cd20c.js +1 -0
- package/.next/static/chunks/next/dist/client/components/builtin/not-found-8f70dda1817cd20c.js +1 -0
- package/.next/static/chunks/next/dist/client/components/builtin/unauthorized-8f70dda1817cd20c.js +1 -0
- package/.next/static/chunks/{webpack-d2379fd13c5c78c6.js → webpack-2423c4442766d244.js} +1 -1
- package/.next/static/css/ea117138d33e0b37.css +1 -0
- package/.next/static/vD56I5OFkAr4Y9TsF1L7c/_buildManifest.js +1 -0
- package/README.en.md +10 -1
- package/README.md +10 -1
- package/bin/pidance-auth-gate.js +41 -11
- package/bin/pidance-http-server.js +7 -0
- package/bin/pidance.js +5 -1
- package/bin/pty-ws.js +126 -3
- package/package.json +6 -4
- package/.next/server/app/_global-error.segments/_global-error.segment.rsc +0 -5
- package/.next/server/app/_global-error.segments/_head.segment.rsc +0 -5
- package/.next/server/app/_global-error.segments/_index.segment.rsc +0 -5
- package/.next/server/app/_not-found.segments/_head.segment.rsc +0 -6
- package/.next/server/app/_not-found.segments/_index.segment.rsc +0 -7
- package/.next/server/app/_not-found.segments/_not-found.segment.rsc +0 -5
- package/.next/server/app/index.segments/_head.segment.rsc +0 -6
- package/.next/server/app/index.segments/_index.segment.rsc +0 -7
- package/.next/server/chunks/188.js +0 -1
- package/.next/server/chunks/319.js +0 -45
- package/.next/server/chunks/6953.js +0 -1
- package/.next/static/9m7dmaudtohXTam6OFJrW/_buildManifest.js +0 -1
- package/.next/static/chunks/3794-907785a527d8128b.js +0 -32
- package/.next/static/chunks/4bd1b696-e356ca5ba0218e27.js +0 -1
- package/.next/static/chunks/6121.5b8cb3199531d194.js +0 -1
- package/.next/static/chunks/9780-190981a7d5f4799b.js +0 -1
- package/.next/static/chunks/app/_global-error/page-7c63ab7d3880fba7.js +0 -1
- package/.next/static/chunks/app/api/about/route-7c63ab7d3880fba7.js +0 -1
- package/.next/static/chunks/app/api/agent/[id]/bash-output/route-7c63ab7d3880fba7.js +0 -1
- package/.next/static/chunks/app/api/agent/[id]/events/route-7c63ab7d3880fba7.js +0 -1
- package/.next/static/chunks/app/api/agent/[id]/route-7c63ab7d3880fba7.js +0 -1
- package/.next/static/chunks/app/api/agent/new/route-7c63ab7d3880fba7.js +0 -1
- package/.next/static/chunks/app/api/agent/running/events/route-7c63ab7d3880fba7.js +0 -1
- package/.next/static/chunks/app/api/agent/running/route-7c63ab7d3880fba7.js +0 -1
- package/.next/static/chunks/app/api/agent/submissions/[submissionId]/route-7c63ab7d3880fba7.js +0 -1
- package/.next/static/chunks/app/api/agent-settings/route-7c63ab7d3880fba7.js +0 -1
- package/.next/static/chunks/app/api/attachments/route-7c63ab7d3880fba7.js +0 -1
- package/.next/static/chunks/app/api/auth/all-providers/route-7c63ab7d3880fba7.js +0 -1
- package/.next/static/chunks/app/api/auth/api-key/[provider]/route-7c63ab7d3880fba7.js +0 -1
- package/.next/static/chunks/app/api/auth/login/[provider]/route-7c63ab7d3880fba7.js +0 -1
- package/.next/static/chunks/app/api/auth/logout/[provider]/route-7c63ab7d3880fba7.js +0 -1
- package/.next/static/chunks/app/api/auth/providers/route-7c63ab7d3880fba7.js +0 -1
- package/.next/static/chunks/app/api/auth/ui-session/route-7c63ab7d3880fba7.js +0 -1
- package/.next/static/chunks/app/api/auth/ui-sessions/[id]/route-7c63ab7d3880fba7.js +0 -1
- package/.next/static/chunks/app/api/auth/ui-sessions/route-7c63ab7d3880fba7.js +0 -1
- package/.next/static/chunks/app/api/cwd/browse/route-7c63ab7d3880fba7.js +0 -1
- package/.next/static/chunks/app/api/cwd/create/route-7c63ab7d3880fba7.js +0 -1
- package/.next/static/chunks/app/api/cwd/validate/route-7c63ab7d3880fba7.js +0 -1
- package/.next/static/chunks/app/api/default-cwd/route-7c63ab7d3880fba7.js +0 -1
- package/.next/static/chunks/app/api/file-index/route-7c63ab7d3880fba7.js +0 -1
- package/.next/static/chunks/app/api/files/[...path]/route-7c63ab7d3880fba7.js +0 -1
- package/.next/static/chunks/app/api/files/save-as/route-7c63ab7d3880fba7.js +0 -1
- package/.next/static/chunks/app/api/git/diff/route-7c63ab7d3880fba7.js +0 -1
- package/.next/static/chunks/app/api/git/status/route-7c63ab7d3880fba7.js +0 -1
- package/.next/static/chunks/app/api/home/route-7c63ab7d3880fba7.js +0 -1
- package/.next/static/chunks/app/api/message-media/route-7c63ab7d3880fba7.js +0 -1
- package/.next/static/chunks/app/api/models/route-7c63ab7d3880fba7.js +0 -1
- package/.next/static/chunks/app/api/models-config/raw/route-7c63ab7d3880fba7.js +0 -1
- package/.next/static/chunks/app/api/models-config/route-7c63ab7d3880fba7.js +0 -1
- package/.next/static/chunks/app/api/models-config/test/route-7c63ab7d3880fba7.js +0 -1
- package/.next/static/chunks/app/api/plugins/route-7c63ab7d3880fba7.js +0 -1
- package/.next/static/chunks/app/api/plugins/search/route-7c63ab7d3880fba7.js +0 -1
- package/.next/static/chunks/app/api/plugins/updates/route-7c63ab7d3880fba7.js +0 -1
- package/.next/static/chunks/app/api/preferences/route-7c63ab7d3880fba7.js +0 -1
- package/.next/static/chunks/app/api/project-assets/route-7c63ab7d3880fba7.js +0 -1
- package/.next/static/chunks/app/api/prompts/route-7c63ab7d3880fba7.js +0 -1
- package/.next/static/chunks/app/api/pty/route-7c63ab7d3880fba7.js +0 -1
- package/.next/static/chunks/app/api/sessions/[id]/archive/route-7c63ab7d3880fba7.js +0 -1
- package/.next/static/chunks/app/api/sessions/[id]/auto-name/route-7c63ab7d3880fba7.js +0 -1
- package/.next/static/chunks/app/api/sessions/[id]/command-entry/route-7c63ab7d3880fba7.js +0 -1
- package/.next/static/chunks/app/api/sessions/[id]/context/route-7c63ab7d3880fba7.js +0 -1
- package/.next/static/chunks/app/api/sessions/[id]/entries/[entryId]/thinking/route-7c63ab7d3880fba7.js +0 -1
- package/.next/static/chunks/app/api/sessions/[id]/export/route-7c63ab7d3880fba7.js +0 -1
- package/.next/static/chunks/app/api/sessions/[id]/info/route-7c63ab7d3880fba7.js +0 -1
- package/.next/static/chunks/app/api/sessions/[id]/outline/route-7c63ab7d3880fba7.js +0 -1
- package/.next/static/chunks/app/api/sessions/[id]/route-7c63ab7d3880fba7.js +0 -1
- package/.next/static/chunks/app/api/sessions/[id]/state/route-7c63ab7d3880fba7.js +0 -1
- package/.next/static/chunks/app/api/sessions/[id]/tool-results/[toolCallId]/route-7c63ab7d3880fba7.js +0 -1
- package/.next/static/chunks/app/api/sessions/route-7c63ab7d3880fba7.js +0 -1
- package/.next/static/chunks/app/api/sessions/search/route-7c63ab7d3880fba7.js +0 -1
- package/.next/static/chunks/app/api/settings/raw/route-7c63ab7d3880fba7.js +0 -1
- package/.next/static/chunks/app/api/settings/remote/route-7c63ab7d3880fba7.js +0 -1
- package/.next/static/chunks/app/api/skills/check/route-7c63ab7d3880fba7.js +0 -1
- package/.next/static/chunks/app/api/skills/install/route-7c63ab7d3880fba7.js +0 -1
- package/.next/static/chunks/app/api/skills/route-7c63ab7d3880fba7.js +0 -1
- package/.next/static/chunks/app/api/skills/search/route-7c63ab7d3880fba7.js +0 -1
- package/.next/static/chunks/app/api/skills/update/route-7c63ab7d3880fba7.js +0 -1
- package/.next/static/chunks/app/api/subagent-runs/route-7c63ab7d3880fba7.js +0 -1
- package/.next/static/chunks/app/api/update/apply/route-7c63ab7d3880fba7.js +0 -1
- package/.next/static/chunks/app/api/update/check/route-7c63ab7d3880fba7.js +0 -1
- package/.next/static/chunks/app/page-a67f4b63843f6c4b.js +0 -24
- package/.next/static/chunks/framework-711ef29bc66f648c.js +0 -1
- package/.next/static/chunks/main-8e7ef001ea9dd641.js +0 -5
- package/.next/static/chunks/next/dist/client/components/builtin/app-error-7c63ab7d3880fba7.js +0 -1
- package/.next/static/chunks/next/dist/client/components/builtin/forbidden-7c63ab7d3880fba7.js +0 -1
- package/.next/static/chunks/next/dist/client/components/builtin/not-found-7c63ab7d3880fba7.js +0 -1
- package/.next/static/chunks/next/dist/client/components/builtin/unauthorized-7c63ab7d3880fba7.js +0 -1
- package/.next/static/css/82b378f5d9cf6c9d.css +0 -1
- /package/.next/static/{9m7dmaudtohXTam6OFJrW → vD56I5OFkAr4Y9TsF1L7c}/_ssgManifest.js +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
self.__BUILD_MANIFEST={__rewrites:{afterFiles:[],beforeFiles:[],fallback:[]},__routerFilterStatic:{numItems:49,errorRate:1e-4,numBits:940,numHashes:14,bitArray:[1,0,1,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,1,1,0,1,1,0,1,0,1,0,0,0,1,1,1,1,0,1,0,1,0,1,0,0,0,1,0,0,1,1,0,0,1,0,1,0,1,0,1,1,1,0,0,1,1,1,0,0,0,0,1,0,0,1,1,1,0,1,1,1,1,0,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,0,1,0,0,1,1,0,1,0,0,1,0,0,0,0,0,0,1,0,1,1,1,1,1,0,0,1,1,0,1,1,1,1,0,0,1,0,1,0,0,1,0,1,1,1,0,1,0,1,1,0,0,0,0,0,1,1,1,1,0,1,0,0,0,1,1,1,0,1,1,1,0,0,0,0,0,1,1,1,0,1,1,1,1,0,1,1,0,0,0,1,1,1,1,1,1,0,0,0,0,0,1,1,1,0,0,1,0,1,0,1,0,0,1,0,1,1,1,0,1,0,0,1,0,0,0,0,1,1,0,1,0,0,0,0,0,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,0,1,1,1,1,1,1,1,1,1,0,1,1,1,1,0,1,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,1,0,1,1,1,0,1,1,0,0,1,0,0,1,0,1,1,0,0,1,0,1,0,1,1,0,0,1,0,1,0,1,1,1,0,1,0,1,0,0,0,1,1,1,0,0,0,1,0,1,1,0,1,1,0,1,0,0,0,1,1,1,1,0,1,1,0,0,0,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,0,1,1,1,0,0,0,1,1,1,0,1,1,0,0,0,1,0,0,1,0,0,0,0,1,0,0,1,0,0,1,0,0,0,1,1,0,0,0,0,0,1,0,0,1,0,0,1,1,1,1,0,0,0,0,0,0,1,1,0,0,1,0,0,1,1,1,0,0,0,1,0,0,1,1,1,0,1,0,0,1,1,1,0,1,1,1,1,1,1,1,1,0,0,1,0,1,0,1,0,0,0,1,0,1,0,0,1,0,1,1,1,0,0,0,1,0,0,1,1,1,1,1,0,1,0,1,0,1,0,1,1,0,0,1,1,1,0,1,0,0,0,0,0,1,1,1,0,0,0,0,0,1,1,0,1,1,1,0,1,1,0,1,0,0,1,1,1,0,0,1,0,0,1,1,1,0,1,0,0,1,0,0,1,1,0,0,1,0,0,0,1,1,1,1,0,1,1,0,1,1,1,0,1,1,0,0,1,0,0,0,1,0,0,1,1,1,0,0,0,0,0,1,0,0,1,0,0,1,1,1,0,0,1,0,1,1,0,1,1,1,1,0,1,1,1,1,1,1,0,0,0,1,1,0,1,1,0,0,0,1,1,1,1,0,1,1,1,0,1,0,1,1,0,1,1,0,0,0,0,1,0,0,0,1,1,0,1,0,1,1,1,0,0,0,1,1,1,1,1,1,0,1,0,1,1,1,1,0,0,1,1,1,1,0,1,1,1,0,0,0,1,0,0,1,1,0,0,0,0,1,1,0,0,1,1,0,0,0,1,0,1,0,0,1,0,0,0,1,1,1,0,0,0,1,1,1,0,1,0,1,0,1,1,1,0,1,1,0,0,1,0,0,1,1,0,1,1,0,0,0,0,0,1,0,1,1,0,0,0,0,0,1,0,1,0,0,0,1,0,1,1,0,1,0,0,1,1,1,1,0,1,0,0,0,0,1,1,0,1,1,1,0,1,0,1,1,0,0,1,0,0,0,0,0,0,1,0,1,0,1,0,0,1,1,1,1,0,1,0,1,0,1,1,0,0,0,0,0,1,1,1,0,1,0,0,1,0,0,0,0,1,0,0,1,0,0,0,1,0,1,0,0,1,0,1,0,0,0,0,1,0,1,0,1,1,0,0,1,0,1,0,0,1,0,1,0,1,0,1,0,0,1,0,1,1,0,1,1,1,1,1,0,0,0,1,1,1,1,0,0,1,1,0,0,1,0,0,0,1,1,1,1,0,1,1,1,0,0,0,1]},__routerFilterDynamic:{numItems:8,errorRate:1e-4,numBits:154,numHashes:14,bitArray:[1,0,0,0,1,1,1,0,1,0,1,1,1,1,1,1,1,1,0,1,0,0,1,0,1,0,0,1,1,0,0,0,1,1,0,1,0,1,1,0,1,1,1,1,0,1,1,1,1,0,1,0,0,0,0,1,0,0,1,1,0,1,0,1,0,1,1,1,1,1,0,1,1,0,0,1,1,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,1,0,0,1,1,1,0,1,0,1,0,0,1,1,1,1,0,0,0,0,0,1,1,1,1,0,0,0,1,1,0,0,1,1,1,1,1,1,1,1,0,1,1,0,1,0,1,0,0,1,0,0,0,0,1,1,1,0,0,0,1,0]},sortedPages:["/_app"]},self.__BUILD_MANIFEST_CB&&self.__BUILD_MANIFEST_CB();
|
package/README.en.md
CHANGED
|
@@ -10,7 +10,16 @@
|
|
|
10
10
|
|
|
11
11
|
Pidance is an open-source web client for the [Pi](https://github.com/badlogic/pi-mono) coding agent. It reads local Pi session files directly and preserves Pi SDK session and runtime semantics, bringing live chat, project files, Git, subagents, and configuration into one browser workspace. Pi remains the source of truth for data and execution semantics; Pidance provides a clearer and more complete interface.
|
|
12
12
|
|
|
13
|
-
> Current version: `0.2.
|
|
13
|
+
> Current version: `0.2.39` · npm package: `@henlii/pidance` · CLI: `pidance`
|
|
14
|
+
|
|
15
|
+
## Design principles
|
|
16
|
+
|
|
17
|
+
**Compatibility first, then general display improvements on top of it.**
|
|
18
|
+
|
|
19
|
+
1. **Content completeness comes first.** Pidance aims to let you experience what a native TUI session shows — **including extension (plugin) custom UI** — in the browser. Anything the native TUI can display, Pidance should display too; prefer showing it as-is over hiding it because it “looks off on the web”.
|
|
20
|
+
2. **Compatibility outranks looks.** Content a plugin expresses through the TUI extension API (self-drawn components, overlays, widgets, status lines, dialogs) must always have a landing spot. When a capability is missing, degrade **visibly** — notify or return an explicit value, never drop it silently (silence makes plugin authors think it worked).
|
|
21
|
+
3. **Improvements must be general.** Display-layer work (layout, collapsing, card shells, titles, accessibility) goes through mechanisms shared by every plugin — no per-plugin special cases. Plugin-specific code is allowed only in the compatibility layer: parsing a plugin's private payloads, or bridging TUI semantics to the web.
|
|
22
|
+
4. **Pi stays the source of truth.** Session files, tool execution, compaction and branch semantics are decided by the Pi SDK; Pidance only projects and presents them. See [`docs/ui-vs-tui.md`](./docs/ui-vs-tui.md) for the surface-by-surface mapping.
|
|
14
23
|
|
|
15
24
|
## Preview
|
|
16
25
|
|
package/README.md
CHANGED
|
@@ -10,7 +10,16 @@
|
|
|
10
10
|
|
|
11
11
|
Pidance 是面向 [Pi](https://github.com/badlogic/pi-mono) coding agent 的开源 Web 客户端。它直接读取本机 Pi 会话文件,并沿用 Pi SDK 的会话与运行时语义,把实时对话、项目文件、Git、工作树、子代理和配置管理汇集到一个浏览器工作区。Pi 仍是数据与执行语义的事实来源;Pidance 负责提供更清晰、更完整的操作界面。
|
|
12
12
|
|
|
13
|
-
> 当前版本:`0.2.
|
|
13
|
+
> 当前版本:`0.2.39` · npm 包:`@henlii/pidance` · CLI:`pidance`
|
|
14
|
+
|
|
15
|
+
## 设计原则
|
|
16
|
+
|
|
17
|
+
**兼容优先,然后在兼容之上做通用的显示优化。**
|
|
18
|
+
|
|
19
|
+
1. **内容完整优先**:Pidance 的目标是在浏览器里体验原生 TUI 会话的内容,**包括扩展(插件)自定义的界面**。原生 TUI 里能显示的东西,Pidance 都要能显示;宁可先原样呈现,也不要因为「Web 里不好看」而少显示。
|
|
20
|
+
2. **兼容高于观感**:插件用 TUI 扩展 API 表达的内容(自绘组件、overlay、widget、状态条、对话框)都必须有落点。暂不具备的能力按**可见方式**降级——给出提示或明确返回值,不静默丢弃(静默会让插件作者以为生效了)。
|
|
21
|
+
3. **优化必须通用**:显示层的改进(排版、折叠、卡片壳、标题、无障碍)要走所有插件共用的机制,不为个别插件写特例。插件专属代码只允许出现在兼容层:解析它发的私有载荷、把 TUI 语义桥到 Web。
|
|
22
|
+
4. **Pi 仍是事实来源**:会话文件、工具执行、压缩与分支语义由 Pi SDK 决定;Pidance 不复制、不覆盖这些语义,只负责投影与呈现。界面分区对照见 [`docs/ui-vs-tui.md`](./docs/ui-vs-tui.md)。
|
|
14
23
|
|
|
15
24
|
## 界面预览
|
|
16
25
|
|
package/bin/pidance-auth-gate.js
CHANGED
|
@@ -2,11 +2,50 @@
|
|
|
2
2
|
|
|
3
3
|
// 启动认证门禁纯逻辑(CLI 门禁用;与 lib/request-guard.ts 的 isLoopbackHost 语义保持一致):
|
|
4
4
|
// 监听非回环地址且未设置认证密码 → 拒绝启动(fail-closed,发布阻断 P0)。
|
|
5
|
-
//
|
|
5
|
+
// 密码来源:启动缓存(已搬走)→ PIDANCE_PASSWORD(产品名)→ 旧变量 PI_WEB_PASSWORD。
|
|
6
6
|
|
|
7
7
|
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
8
8
|
const { isIP } = require("net");
|
|
9
9
|
|
|
10
|
+
/**
|
|
11
|
+
* 进程内密码缓存键,与 lib/request-guard.ts 的 __piAuthPassword 同形。
|
|
12
|
+
*
|
|
13
|
+
* 同进程共享:middleware / route / CLI 共用 globalThis(Next 的 Node middleware 是
|
|
14
|
+
* require 进同进程的),所以 CLI 写、服务端读。
|
|
15
|
+
*/
|
|
16
|
+
const AUTH_PASSWORD_CACHE_KEY = "__piAuthPassword";
|
|
17
|
+
|
|
18
|
+
function readPasswordFromEnv(env) {
|
|
19
|
+
const p =
|
|
20
|
+
env && env.PIDANCE_PASSWORD && env.PIDANCE_PASSWORD.length > 0
|
|
21
|
+
? env.PIDANCE_PASSWORD
|
|
22
|
+
: env && env.PI_WEB_PASSWORD;
|
|
23
|
+
return typeof p === "string" && p.length > 0 ? p : null;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/** 解析认证密码:启动缓存优先,否则读 env。 */
|
|
27
|
+
function resolvePassword(env) {
|
|
28
|
+
const cached = globalThis[AUTH_PASSWORD_CACHE_KEY];
|
|
29
|
+
if (cached) return cached.value;
|
|
30
|
+
return readPasswordFromEnv(env);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* 把 env 里的密码搬进进程内缓存,并从 process.env 删掉两个变量名。
|
|
35
|
+
*
|
|
36
|
+
* 为什么必须搬:主 agent 的 SDK bash 工具用 `{ ...process.env }` 构造命令环境,
|
|
37
|
+
* 密码留在 env 里会被 agent 一条 `env` 打进会话并永久落盘。删掉后命令环境拿不到,
|
|
38
|
+
* 认证改读缓存(只删不搬会让 resolvePassword fail-open)。
|
|
39
|
+
* 缓存不写盘。
|
|
40
|
+
*/
|
|
41
|
+
function primeAndScrubPassword(env = process.env) {
|
|
42
|
+
const value = readPasswordFromEnv(env);
|
|
43
|
+
globalThis[AUTH_PASSWORD_CACHE_KEY] = { value };
|
|
44
|
+
delete env.PIDANCE_PASSWORD;
|
|
45
|
+
delete env.PI_WEB_PASSWORD;
|
|
46
|
+
return value;
|
|
47
|
+
}
|
|
48
|
+
|
|
10
49
|
/** host 是否为回环(localhost / *.localhost / IPv4 127.x / IPv6 ::1)。 */
|
|
11
50
|
function isLoopbackHost(host) {
|
|
12
51
|
if (typeof host !== "string" || host.length === 0) return false; // 未指定 → Pidance 默认绑定 127.0.0.1
|
|
@@ -19,15 +58,6 @@ function isLoopbackHost(host) {
|
|
|
19
58
|
return false;
|
|
20
59
|
}
|
|
21
60
|
|
|
22
|
-
/** 解析认证密码:PIDANCE_PASSWORD 优先(产品名,空/缺失时回退),兼容旧变量 PI_WEB_PASSWORD。 */
|
|
23
|
-
function resolvePassword(env) {
|
|
24
|
-
const p =
|
|
25
|
-
env && env.PIDANCE_PASSWORD && env.PIDANCE_PASSWORD.length > 0
|
|
26
|
-
? env.PIDANCE_PASSWORD
|
|
27
|
-
: env && env.PI_WEB_PASSWORD;
|
|
28
|
-
return typeof p === "string" && p.length > 0 ? p : null;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
61
|
/**
|
|
32
62
|
* 是否需要强制认证:非回环监听地址 + 未设置密码(env 明文或设置 → 通用 保存的服务端密码)。
|
|
33
63
|
* serverConfig 来自 bin/pidance-server-config.js 的 { passwordSet, remoteEnabled } 投影。
|
|
@@ -44,4 +74,4 @@ function describeHost(host) {
|
|
|
44
74
|
return typeof host === "string" && host.length > 0 ? host : "127.0.0.1(默认本机绑定)";
|
|
45
75
|
}
|
|
46
76
|
|
|
47
|
-
module.exports = { isLoopbackHost, resolvePassword, shouldRequireAuth, describeHost };
|
|
77
|
+
module.exports = { isLoopbackHost, resolvePassword, primeAndScrubPassword, shouldRequireAuth, describeHost };
|
|
@@ -58,6 +58,13 @@ async function startPidanceHttpServer(options) {
|
|
|
58
58
|
const handle = app.getRequestHandler();
|
|
59
59
|
const server = createHttpServer((req, res) => {
|
|
60
60
|
installUpgradeHandler();
|
|
61
|
+
// 对端地址是我们唯一可信的客户端身份来源:先删掉客户端自带的同名头,
|
|
62
|
+
// 再写入 socket 地址。限流分桶读它(middleware 里读不到 socket)。
|
|
63
|
+
if (req.headers) {
|
|
64
|
+
delete req.headers["x-pidance-peer-ip"];
|
|
65
|
+
const address = req.socket?.remoteAddress;
|
|
66
|
+
if (address) req.headers["x-pidance-peer-ip"] = address;
|
|
67
|
+
}
|
|
61
68
|
// Next 的 compress 只在它自己的内置服务器(router-server)里生效;
|
|
62
69
|
// 自管 server 必须自己压缩,否则 JSON/HTML 明文下发。
|
|
63
70
|
// 见 bin/pidance-compression.js。
|
package/bin/pidance.js
CHANGED
|
@@ -12,7 +12,7 @@ const { parseLaunchOptions } = require("./pidance-options");
|
|
|
12
12
|
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
13
13
|
const { loadServerConfig } = require("./pidance-server-config");
|
|
14
14
|
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
15
|
-
const { shouldRequireAuth, resolvePassword, describeHost } = require("./pidance-auth-gate");
|
|
15
|
+
const { shouldRequireAuth, resolvePassword, primeAndScrubPassword, describeHost } = require("./pidance-auth-gate");
|
|
16
16
|
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
17
17
|
const { startPidanceHttpServer } = require("./pidance-http-server");
|
|
18
18
|
|
|
@@ -39,6 +39,10 @@ if (!nodeMeetsMin(process.versions.node)) {
|
|
|
39
39
|
|
|
40
40
|
const { port: explicitPort, hostname: explicitHostname, openBrowser } = parseLaunchOptions();
|
|
41
41
|
const serverConfig = loadServerConfig();
|
|
42
|
+
// 密码只活在进程内缓存里:把 env 里的密码搬进缓存、再删掉两个变量名。
|
|
43
|
+
// 必须在启动 Next 之前做——middleware / route / SDK bash 都在同一进程,读的是 globalThis
|
|
44
|
+
// 缓存;env 里留着的密码会被 agent 的 bash 一条 `env` 打进会话并永久落盘。
|
|
45
|
+
primeAndScrubPassword(process.env);
|
|
42
46
|
// 默认绑定:设置 → 通用 开启远程服务 → 0.0.0.0;否则仅本机 127.0.0.1(免密码)。
|
|
43
47
|
// 显式 --hostname / -H / HOSTNAME env 优先;显式 0.0.0.0 仍走密码门禁。
|
|
44
48
|
const hostname = explicitHostname ?? (serverConfig.remoteEnabled ? "0.0.0.0" : "127.0.0.1");
|
package/bin/pty-ws.js
CHANGED
|
@@ -69,6 +69,10 @@ function isLoopbackHost(hostHeader) {
|
|
|
69
69
|
const UI_SESSION_COOKIE_NAME = "pidance_ui_session";
|
|
70
70
|
|
|
71
71
|
function resolvePassword(env) {
|
|
72
|
+
// 启动时密码已搬进同进程 globalThis 缓存(bin/pidance-auth-gate.js 的
|
|
73
|
+
// primeAndScrubPassword),env 里不再有明文;两条来源同形,缺一不可。
|
|
74
|
+
const cached = globalThis.__piAuthPassword;
|
|
75
|
+
if (cached) return cached.value;
|
|
72
76
|
const p =
|
|
73
77
|
env && env.PIDANCE_PASSWORD && env.PIDANCE_PASSWORD.length > 0
|
|
74
78
|
? env.PIDANCE_PASSWORD
|
|
@@ -215,15 +219,22 @@ function ptyGuardHeaders(req) {
|
|
|
215
219
|
secFetchUser: header(req, "sec-fetch-user"),
|
|
216
220
|
authorization: header(req, "authorization"),
|
|
217
221
|
cookie: header(req, "cookie"),
|
|
222
|
+
xForwardedFor: header(req, "x-forwarded-for"),
|
|
218
223
|
method: "GET",
|
|
219
224
|
url,
|
|
220
225
|
pathname,
|
|
221
226
|
};
|
|
222
227
|
}
|
|
223
228
|
|
|
224
|
-
function reject(socket, status, message) {
|
|
229
|
+
function reject(socket, status, message, extraHeaders) {
|
|
230
|
+
const headers = {
|
|
231
|
+
Connection: "close",
|
|
232
|
+
"Content-Length": 0,
|
|
233
|
+
...(extraHeaders || {}),
|
|
234
|
+
};
|
|
235
|
+
const lines = Object.keys(headers).map((name) => `${name}: ${headers[name]}\r\n`).join("");
|
|
225
236
|
try {
|
|
226
|
-
socket.write(`HTTP/1.1 ${status} ${message}\r\
|
|
237
|
+
socket.write(`HTTP/1.1 ${status} ${message}\r\n${lines}\r\n`);
|
|
227
238
|
} catch {
|
|
228
239
|
// ignore
|
|
229
240
|
}
|
|
@@ -234,6 +245,99 @@ function reject(socket, status, message) {
|
|
|
234
245
|
}
|
|
235
246
|
}
|
|
236
247
|
|
|
248
|
+
// ── 密码尝试限流(与 lib/auth-throttle.ts 同桶)──────────────────────────
|
|
249
|
+
//
|
|
250
|
+
// WebSocket 升级不经过 Next middleware,所以这里必须自己挡一次:否则 /api/pty
|
|
251
|
+
// 就是一条不限速的密码预言机(Basic 可全速猜)。状态放在与 lib/auth-throttle.ts
|
|
252
|
+
// 相同的 globalThis 键、相同结构上,两条入口在同进程里共用同一个桶。
|
|
253
|
+
//
|
|
254
|
+
// bin/ 是自包含发布物(见文件头注释,不依赖 lib/ 源码树),所以退避公式与常量
|
|
255
|
+
// 在内联实现里保持语义一致;bin/pty-ws.test.mjs 有一条与 lib/auth-throttle.ts
|
|
256
|
+
// 的 parity 断言,改一边不改另一边会红。
|
|
257
|
+
|
|
258
|
+
const AUTH_THROTTLE_GLOBAL_KEY = "__piAuthThrottle";
|
|
259
|
+
const AUTH_THROTTLE_BASE_DELAY_MS = 1000;
|
|
260
|
+
const AUTH_THROTTLE_MAX_DELAY_MS = 60000;
|
|
261
|
+
const AUTH_THROTTLE_RESET_AFTER_MS = 5 * 60 * 1000;
|
|
262
|
+
const AUTH_THROTTLE_MAX_BUCKETS = 256;
|
|
263
|
+
|
|
264
|
+
function authThrottleStore() {
|
|
265
|
+
if (!globalThis[AUTH_THROTTLE_GLOBAL_KEY]) globalThis[AUTH_THROTTLE_GLOBAL_KEY] = new Map();
|
|
266
|
+
return globalThis[AUTH_THROTTLE_GLOBAL_KEY];
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
function backoffDelayMs(failures) {
|
|
270
|
+
if (failures <= 0) return 0;
|
|
271
|
+
const exponent = Math.min(failures - 1, 31);
|
|
272
|
+
return Math.min(AUTH_THROTTLE_BASE_DELAY_MS * 2 ** exponent, AUTH_THROTTLE_MAX_DELAY_MS);
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
function expireIfStale(state, now) {
|
|
276
|
+
if (state.failures > 0 && now - state.lastFailureAt >= AUTH_THROTTLE_RESET_AFTER_MS) {
|
|
277
|
+
state.failures = 0;
|
|
278
|
+
state.lastFailureAt = 0;
|
|
279
|
+
state.blockedUntil = 0;
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
/** 该桶还需等多久(毫秒);0 表示可以尝试。 */
|
|
284
|
+
function getAuthRetryAfterMs(key, now = Date.now()) {
|
|
285
|
+
const state = authThrottleStore().get(key);
|
|
286
|
+
if (!state) return 0;
|
|
287
|
+
expireIfStale(state, now);
|
|
288
|
+
return Math.max(0, state.blockedUntil - now);
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
function pruneAuthThrottle(now) {
|
|
292
|
+
const map = authThrottleStore();
|
|
293
|
+
if (map.size <= AUTH_THROTTLE_MAX_BUCKETS) return;
|
|
294
|
+
for (const [key, state] of map) {
|
|
295
|
+
if (state.failures === 0 || now - state.lastFailureAt >= AUTH_THROTTLE_RESET_AFTER_MS) map.delete(key);
|
|
296
|
+
}
|
|
297
|
+
while (map.size > AUTH_THROTTLE_MAX_BUCKETS) {
|
|
298
|
+
const oldest = [...map.entries()].sort((a, b) => a[1].lastFailureAt - b[1].lastFailureAt)[0];
|
|
299
|
+
if (!oldest) break;
|
|
300
|
+
map.delete(oldest[0]);
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
/** 记一次失败并返回施加的退避(毫秒)。 */
|
|
305
|
+
function recordAuthFailure(key, now = Date.now()) {
|
|
306
|
+
const map = authThrottleStore();
|
|
307
|
+
let state = map.get(key);
|
|
308
|
+
if (!state) {
|
|
309
|
+
state = { failures: 0, lastFailureAt: 0, blockedUntil: 0 };
|
|
310
|
+
map.set(key, state);
|
|
311
|
+
}
|
|
312
|
+
expireIfStale(state, now);
|
|
313
|
+
state.failures += 1;
|
|
314
|
+
state.lastFailureAt = now;
|
|
315
|
+
state.blockedUntil = now + backoffDelayMs(state.failures);
|
|
316
|
+
pruneAuthThrottle(now);
|
|
317
|
+
return backoffDelayMs(state.failures);
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
/**
|
|
321
|
+
* 限流分桶的身份,与 lib/request-guard.ts 的 `authIdentity` 同规则:
|
|
322
|
+
* 只在显式 `PIDANCE_TRUST_PROXY` 时信 `x-forwarded-for`,否则用对端地址;
|
|
323
|
+
* 都拿不到时退回固定全局桶(宁可误伤也不放行)。
|
|
324
|
+
*/
|
|
325
|
+
function authThrottleKey(socket, headers, env) {
|
|
326
|
+
const trustProxy = env.PIDANCE_TRUST_PROXY === "1" || env.PIDANCE_TRUST_PROXY === "true";
|
|
327
|
+
if (trustProxy) {
|
|
328
|
+
const first = (headers.xForwardedFor || "").split(",")[0];
|
|
329
|
+
const trimmed = first ? first.trim() : "";
|
|
330
|
+
if (trimmed) return trimmed.replace(/^::ffff:/, "");
|
|
331
|
+
}
|
|
332
|
+
const peer = typeof socket?.remoteAddress === "string" ? socket.remoteAddress.trim() : "";
|
|
333
|
+
if (peer) return peer.replace(/^::ffff:/, "");
|
|
334
|
+
return "unknown";
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
function retryAfterSeconds(retryAfterMs) {
|
|
338
|
+
return Math.max(1, Math.ceil(retryAfterMs / 1000));
|
|
339
|
+
}
|
|
340
|
+
|
|
237
341
|
async function handlePtyUpgrade(req, socket, head) {
|
|
238
342
|
if (!tryLoadNodePty()) {
|
|
239
343
|
reject(socket, 503, "PTY Unavailable");
|
|
@@ -251,10 +355,20 @@ async function handlePtyUpgrade(req, socket, head) {
|
|
|
251
355
|
return;
|
|
252
356
|
}
|
|
253
357
|
if (passwordEnabled(process.env)) {
|
|
358
|
+
// 与 middleware / 登录表单共用同一个桶:封锁期内密码正确也不放行,
|
|
359
|
+
// 否则升级路径就是一条不限速的密码预言机。
|
|
360
|
+
const throttleKey = authThrottleKey(socket, guardHeaders, process.env);
|
|
361
|
+
const retryAfterMs = getAuthRetryAfterMs(throttleKey);
|
|
362
|
+
if (retryAfterMs > 0) {
|
|
363
|
+
reject(socket, 429, "Too Many Requests", { "Retry-After": retryAfterSeconds(retryAfterMs) });
|
|
364
|
+
return;
|
|
365
|
+
}
|
|
254
366
|
if (!checkAuthenticated(guardHeaders, process.env)) {
|
|
367
|
+
recordAuthFailure(throttleKey);
|
|
255
368
|
reject(socket, 401, "auth-required");
|
|
256
369
|
return;
|
|
257
370
|
}
|
|
371
|
+
// 成功不回退计数:Basic 每个请求都带,复位会让穿插猜测回到基准延迟。
|
|
258
372
|
} else if (!isLoopbackHost(guardHeaders.host)) {
|
|
259
373
|
// fail-closed 兜底:未设密码时仅放行回环请求(与 middleware 一致)。
|
|
260
374
|
reject(socket, 401, "auth-required");
|
|
@@ -268,4 +382,13 @@ async function handlePtyUpgrade(req, socket, head) {
|
|
|
268
382
|
completePtyUpgrade(req, socket, head, cwd);
|
|
269
383
|
}
|
|
270
384
|
|
|
271
|
-
module.exports = {
|
|
385
|
+
module.exports = {
|
|
386
|
+
handlePtyUpgrade,
|
|
387
|
+
ptyGuardHeaders,
|
|
388
|
+
// 导出限流内联实现:bin/pty-ws.test.mjs 用它断言与 lib/auth-throttle.ts 的
|
|
389
|
+
// 退避公式一致、且两条入口共用同一个桶。
|
|
390
|
+
authThrottleKey,
|
|
391
|
+
backoffDelayMs,
|
|
392
|
+
getAuthRetryAfterMs,
|
|
393
|
+
recordAuthFailure,
|
|
394
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@henlii/pidance",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.39",
|
|
4
4
|
"description": "Pidance:面向 Pi coding agent 的开源 Web 客户端",
|
|
5
5
|
"homepage": "https://github.com/henlii/pidance#readme",
|
|
6
6
|
"repository": {
|
|
@@ -55,20 +55,22 @@
|
|
|
55
55
|
"check": "npm run typecheck && npm run lint && npm run test",
|
|
56
56
|
"release:audit": "node scripts/audit-release-package.mjs --pre",
|
|
57
57
|
"release:audit:tgz": "node scripts/audit-release-package.mjs --tgz",
|
|
58
|
+
"release:desktop-check": "node scripts/check-desktop-lockfile.mjs",
|
|
58
59
|
"package:candidate": "node scripts/make-candidate-package.mjs",
|
|
59
60
|
"release:check": "npm run check && npm run build && npm run release:audit",
|
|
60
61
|
"test:browser:sse": "node --test scripts/sse-recording-replay.test.mjs"
|
|
61
62
|
},
|
|
62
63
|
"dependencies": {
|
|
63
|
-
"@earendil-works/pi-coding-agent": "0.
|
|
64
|
+
"@earendil-works/pi-coding-agent": "0.87.0",
|
|
65
|
+
"@earendil-works/pi-tui": "0.87.0",
|
|
64
66
|
"@xterm/addon-fit": "^0.11.0",
|
|
65
67
|
"@xterm/xterm": "^6.0.0",
|
|
66
68
|
"jiti": "^2.7.0",
|
|
67
69
|
"lucide-react": "^0.562.0",
|
|
68
|
-
"next": "16.
|
|
70
|
+
"next": "16.3.6",
|
|
69
71
|
"react": "^19.2.4",
|
|
70
72
|
"react-dom": "^19.2.4",
|
|
71
|
-
"undici": "8.
|
|
73
|
+
"undici": "8.11.0",
|
|
72
74
|
"ws": "^8.21.3"
|
|
73
75
|
},
|
|
74
76
|
"devDependencies": {
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
1:"$Sreact.fragment"
|
|
2
|
-
2:I[57121,[],""]
|
|
3
|
-
3:I[74581,[],""]
|
|
4
|
-
4:[]
|
|
5
|
-
0:{"rsc":["$","$1","c",{"children":[null,["$","$L2",null,{"parallelRouterKey":"children","template":["$","$L3",null,{}]}]]}],"isPartial":false,"staleTime":300,"varyParams":"$W4","buildId":"9m7dmaudtohXTam6OFJrW"}
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
1:"$Sreact.fragment"
|
|
2
|
-
2:I[90484,[],"ViewportBoundary"]
|
|
3
|
-
3:I[90484,[],"MetadataBoundary"]
|
|
4
|
-
4:"$Sreact.suspense"
|
|
5
|
-
0:{"rsc":["$","$1","h",{"children":[null,["$","$L2",null,{"children":[["$","meta","0",{"charSet":"utf-8"}],["$","meta","1",{"name":"viewport","content":"width=device-width, initial-scale=1"}]]}],["$","div",null,{"hidden":true,"children":["$","$L3",null,{"children":["$","$4",null,{"name":"Next.Metadata","children":[]}]}]}],["$","meta",null,{"name":"next-size-adjust","content":""}]]}],"isPartial":false,"staleTime":300,"varyParams":null,"buildId":"9m7dmaudtohXTam6OFJrW"}
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
1:"$Sreact.fragment"
|
|
2
|
-
2:I[57121,[],""]
|
|
3
|
-
3:I[74581,[],""]
|
|
4
|
-
4:[]
|
|
5
|
-
0:{"rsc":["$","$1","c",{"children":[null,["$","$L2",null,{"parallelRouterKey":"children","template":["$","$L3",null,{}]}]]}],"isPartial":false,"staleTime":300,"varyParams":"$W4","buildId":"9m7dmaudtohXTam6OFJrW"}
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
1:"$Sreact.fragment"
|
|
2
|
-
2:I[90484,[],"ViewportBoundary"]
|
|
3
|
-
3:I[90484,[],"MetadataBoundary"]
|
|
4
|
-
4:"$Sreact.suspense"
|
|
5
|
-
5:I[86869,[],"IconMark"]
|
|
6
|
-
0:{"rsc":["$","$1","h",{"children":[["$","meta",null,{"name":"robots","content":"noindex"}],["$","$L2",null,{"children":[["$","meta","0",{"charSet":"utf-8"}],["$","meta","1",{"name":"viewport","content":"width=device-width, initial-scale=1"}]]}],["$","div",null,{"hidden":true,"children":["$","$L3",null,{"children":["$","$4",null,{"name":"Next.Metadata","children":[["$","title","0",{"children":"Pidance"}],["$","meta","1",{"name":"description","content":"Open-source web client for the Pi coding agent"}],["$","link","2",{"rel":"icon","href":"/brand/pidance-logo.png"}],["$","link","3",{"rel":"apple-touch-icon","href":"/brand/pidance-logo.png"}],["$","$L5","4",{}]]}]}]}],["$","meta",null,{"name":"next-size-adjust","content":""}]]}],"isPartial":false,"staleTime":300,"varyParams":null,"buildId":"9m7dmaudtohXTam6OFJrW"}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
1:"$Sreact.fragment"
|
|
2
|
-
2:I[99780,["9780","static/chunks/9780-190981a7d5f4799b.js","7177","static/chunks/app/layout-88764b4be2728d3f.js"],"I18nProvider"]
|
|
3
|
-
3:I[57121,[],""]
|
|
4
|
-
4:I[74581,[],""]
|
|
5
|
-
:HL["/_next/static/css/88714c00e109ce28.css","style"]
|
|
6
|
-
:HL["/_next/static/css/82b378f5d9cf6c9d.css","style"]
|
|
7
|
-
0:{"rsc":["$","$1","c",{"children":[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/css/88714c00e109ce28.css","precedence":"next"}],["$","link","1",{"rel":"stylesheet","href":"/_next/static/css/82b378f5d9cf6c9d.css","precedence":"next"}]],["$","html",null,{"lang":"en","translate":"no","className":"__variable_66b8ca notranslate","suppressHydrationWarning":true,"children":[["$","head",null,{"children":[["$","meta",null,{"name":"google","content":"notranslate"}],["$","script",null,{"dangerouslySetInnerHTML":{"__html":"(function(){try{var r=document.documentElement,m=localStorage.getItem(\"pi-theme\"),s=localStorage.getItem(\"pi-theme-style\");if(m!==\"light\"&&m!==\"dark\"&&m!==\"system\")m=\"light\";if(s!==\"fusion\"&&s!==\"chamber\")s=\"chamber\";var d=m===\"dark\"||(m===\"system\"&&matchMedia(\"(prefers-color-scheme: dark)\").matches);r.classList.toggle(\"dark\",d);r.dataset.themeMode=m;r.dataset.themeStyle=s}catch(e){}})();"}}]]}],["$","body",null,{"translate":"no","className":"notranslate","style":{"height":"100dvh","display":"flex","flexDirection":"column"},"children":["$","$L2",null,{"children":["$","$L3",null,{"parallelRouterKey":"children","template":["$","$L4",null,{}]}]}]}]]}]]}],"isPartial":false,"staleTime":300,"varyParams":null,"buildId":"9m7dmaudtohXTam6OFJrW"}
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
1:"$Sreact.fragment"
|
|
2
|
-
2:I[57121,[],""]
|
|
3
|
-
3:I[74581,[],""]
|
|
4
|
-
4:[]
|
|
5
|
-
0:{"rsc":["$","$1","c",{"children":[null,["$","$L2",null,{"parallelRouterKey":"children","template":["$","$L3",null,{}]}]]}],"isPartial":false,"staleTime":300,"varyParams":"$W4","buildId":"9m7dmaudtohXTam6OFJrW"}
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
1:"$Sreact.fragment"
|
|
2
|
-
2:I[90484,[],"ViewportBoundary"]
|
|
3
|
-
3:I[90484,[],"MetadataBoundary"]
|
|
4
|
-
4:"$Sreact.suspense"
|
|
5
|
-
5:I[86869,[],"IconMark"]
|
|
6
|
-
0:{"rsc":["$","$1","h",{"children":[null,["$","$L2",null,{"children":[["$","meta","0",{"charSet":"utf-8"}],["$","meta","1",{"name":"viewport","content":"width=device-width, initial-scale=1"}]]}],["$","div",null,{"hidden":true,"children":["$","$L3",null,{"children":["$","$4",null,{"name":"Next.Metadata","children":[["$","title","0",{"children":"Pidance"}],["$","meta","1",{"name":"description","content":"Open-source web client for the Pi coding agent"}],["$","link","2",{"rel":"icon","href":"/brand/pidance-logo.png"}],["$","link","3",{"rel":"apple-touch-icon","href":"/brand/pidance-logo.png"}],["$","$L5","4",{}]]}]}]}],["$","meta",null,{"name":"next-size-adjust","content":""}]]}],"isPartial":false,"staleTime":300,"varyParams":null,"buildId":"9m7dmaudtohXTam6OFJrW"}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
1:"$Sreact.fragment"
|
|
2
|
-
2:I[99780,["9780","static/chunks/9780-190981a7d5f4799b.js","7177","static/chunks/app/layout-88764b4be2728d3f.js"],"I18nProvider"]
|
|
3
|
-
3:I[57121,[],""]
|
|
4
|
-
4:I[74581,[],""]
|
|
5
|
-
:HL["/_next/static/css/88714c00e109ce28.css","style"]
|
|
6
|
-
:HL["/_next/static/css/82b378f5d9cf6c9d.css","style"]
|
|
7
|
-
0:{"rsc":["$","$1","c",{"children":[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/css/88714c00e109ce28.css","precedence":"next"}],["$","link","1",{"rel":"stylesheet","href":"/_next/static/css/82b378f5d9cf6c9d.css","precedence":"next"}]],["$","html",null,{"lang":"en","translate":"no","className":"__variable_66b8ca notranslate","suppressHydrationWarning":true,"children":[["$","head",null,{"children":[["$","meta",null,{"name":"google","content":"notranslate"}],["$","script",null,{"dangerouslySetInnerHTML":{"__html":"(function(){try{var r=document.documentElement,m=localStorage.getItem(\"pi-theme\"),s=localStorage.getItem(\"pi-theme-style\");if(m!==\"light\"&&m!==\"dark\"&&m!==\"system\")m=\"light\";if(s!==\"fusion\"&&s!==\"chamber\")s=\"chamber\";var d=m===\"dark\"||(m===\"system\"&&matchMedia(\"(prefers-color-scheme: dark)\").matches);r.classList.toggle(\"dark\",d);r.dataset.themeMode=m;r.dataset.themeStyle=s}catch(e){}})();"}}]]}],["$","body",null,{"translate":"no","className":"notranslate","style":{"height":"100dvh","display":"flex","flexDirection":"column"},"children":["$","$L2",null,{"children":["$","$L3",null,{"parallelRouterKey":"children","template":["$","$L4",null,{}],"notFound":[[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":404}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],[]]}]}]}]]}]]}],"isPartial":false,"staleTime":300,"varyParams":null,"buildId":"9m7dmaudtohXTam6OFJrW"}
|