oh-my-agent-web 0.7.0 → 1.0.2
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.en.md +394 -248
- package/README.md +387 -247
- package/dist/server/approval/rules.js +4 -16
- package/dist/server/approval/scope.js +3 -3
- package/dist/server/cli-config.js +3 -3
- package/dist/server/cli-info.js +9 -9
- package/dist/server/cli.js +108 -23
- package/dist/server/engine/builtin.js +64 -1
- package/dist/server/engine/catalog-probe.js +34 -0
- package/dist/server/engine/claude-map.js +296 -0
- package/dist/server/engine/claude-sessions.js +581 -0
- package/dist/server/engine/claude-transport.js +75 -0
- package/dist/server/engine/claude.js +414 -0
- package/dist/server/engine/cli-version.js +119 -0
- package/dist/server/engine/codex-map.js +19 -23
- package/dist/server/engine/codex-sessions.js +5 -5
- package/dist/server/engine/codex-subagents.js +349 -0
- package/dist/server/engine/codex.js +215 -2
- package/dist/server/engine/dsh-history.js +1 -1
- package/dist/server/engine/dsh-log.js +47 -36
- package/dist/server/engine/dsh-map.js +3 -5
- package/dist/server/engine/dsh-prompt-patch.js +48 -0
- package/dist/server/engine/dsh-sessions.js +10 -11
- package/dist/server/engine/dsh-transport.js +2 -2
- package/dist/server/engine/dsh.js +45 -2
- package/dist/server/engine/engine-versions.js +41 -0
- package/dist/server/engine/fake.js +38 -7
- package/dist/server/engine/model-registry-reload.js +1 -1
- package/dist/server/engine/opencode-map.js +2 -2
- package/dist/server/engine/opencode-projects.js +1 -1
- package/dist/server/engine/opencode-sessions.js +2 -2
- package/dist/server/engine/opencode.js +39 -1
- package/dist/server/engine/pi-events.js +4 -4
- package/dist/server/engine/pi-plugins.js +8 -6
- package/dist/server/engine/pi-sdk.js +179 -5
- package/dist/server/engine/pi-subagent-tool.js +2 -2
- package/dist/server/engine/pi-subagents.js +2 -2
- package/dist/server/engine/pi-transcript.js +1 -1
- package/dist/server/engine/registry.js +12 -2
- package/dist/server/engine/suggestion-guidance.js +22 -9
- package/dist/server/engine/wiring.js +57 -3
- package/dist/server/files/content-search.js +187 -0
- package/dist/server/files/file-search.js +3 -3
- package/dist/server/files/file-service.js +33 -15
- package/dist/server/files/files-routes.js +68 -7
- package/dist/server/files/git-info.js +51 -11
- package/dist/server/files/path-resolve.js +176 -0
- package/dist/server/files/pick-dir-routes.js +93 -0
- package/dist/server/files/pick-path-routes.js +126 -0
- package/dist/server/http/auth-routes.js +71 -4
- package/dist/server/http/auth.js +48 -30
- package/dist/server/http/aux-routes.js +20 -4
- package/dist/server/http/file-headers.js +3 -3
- package/dist/server/http/health-and-static.js +1 -1
- package/dist/server/http/live-routes.js +4 -4
- package/dist/server/http/login-page.js +128 -1
- package/dist/server/http/password-store.js +31 -0
- package/dist/server/index.js +93 -11
- package/dist/server/markers/actions.js +8 -8
- package/dist/server/mcp/codex-mcp-store.js +190 -0
- package/dist/server/mcp/json-mcp-store.js +276 -0
- package/dist/server/mcp/mcp-auth.js +1 -1
- package/dist/server/mcp/mcp-command.js +0 -2
- package/dist/server/mcp/mcp-engine-shared.js +112 -0
- package/dist/server/mcp/mcp-import.js +4 -5
- package/dist/server/mcp/mcp-market.js +2 -3
- package/dist/server/mcp/mcp-routes.js +4 -3
- package/dist/server/mcp/none-mcp-store.js +27 -0
- package/dist/server/mcp/pi-mcp-config.js +1 -1
- package/dist/server/plugins/engine-plugin-stores.js +265 -0
- package/dist/server/plugins/plugin-routes.js +4 -3
- package/dist/server/protocol-parse.js +52 -4
- package/dist/server/protocol.js +0 -1
- package/dist/server/providers/catalog-writes.js +1 -1
- package/dist/server/providers/catalog.js +2 -2
- package/dist/server/providers/codex-models.js +1 -1
- package/dist/server/providers/codex-test.js +1 -1
- package/dist/server/providers/enabled-models.js +1 -11
- package/dist/server/providers/import-routes.js +2 -2
- package/dist/server/providers/probe-routes.js +26 -0
- package/dist/server/providers/provider-handlers.js +3 -3
- package/dist/server/providers/provider-pool.js +2 -2
- package/dist/server/providers/provider-store.js +5 -2
- package/dist/server/providers/subscription-routes.js +4 -2
- package/dist/server/providers/validate.js +13 -14
- package/dist/server/push/push-routes.js +32 -3
- package/dist/server/push/push.js +43 -9
- package/dist/server/session/client-view.js +2 -2
- package/dist/server/session/close-ephemeral.js +23 -0
- package/dist/server/session/conversation-create.js +31 -9
- package/dist/server/session/delete-session.js +25 -14
- package/dist/server/session/engine-switch.js +12 -5
- package/dist/server/session/fork-session.js +38 -0
- package/dist/server/session/lock.js +4 -4
- package/dist/server/session/model-controller.js +14 -2
- package/dist/server/session/move-session.js +40 -0
- package/dist/server/session/persist-ephemeral.js +48 -0
- package/dist/server/session/pi-opener.js +2 -2
- package/dist/server/session/pi-refresh.js +1 -1
- package/dist/server/session/pi-sessions-provider.js +2 -2
- package/dist/server/session/pi-sessions.js +107 -18
- package/dist/server/session/runtime.js +144 -9
- package/dist/server/session/session-stats.js +2 -2
- package/dist/server/session/settings.js +45 -49
- package/dist/server/session/subagents.js +4 -1
- package/dist/server/session/suggest-title.js +33 -0
- package/dist/server/session/title-prompt.js +126 -0
- package/dist/server/session/turn-finish.js +2 -2
- package/dist/server/session/turn-queue.js +5 -5
- package/dist/server/session/turn-watchdog.js +2 -2
- package/dist/server/skills/skill-install.js +3 -5
- package/dist/server/skills/skill-store.js +3 -3
- package/dist/server/skills/skillhub.js +3 -4
- package/dist/server/snapshot/messages.js +2 -8
- package/dist/server/snapshot/sender.js +1 -1
- package/dist/server/snapshot/state.js +3 -5
- package/dist/server/subagents/profile-store.js +11 -9
- package/dist/server/terminal/terminal-session.js +9 -9
- package/dist/server/uploads/upload-routes.js +1 -1
- package/dist/server/uploads/upload-store.js +4 -6
- package/dist/server/util/env.js +27 -21
- package/dist/server/util/ids.js +1 -1
- package/dist/server/util/json-file.js +38 -0
- package/dist/server/util/log-file.js +3 -3
- package/dist/server/util/log.js +4 -4
- package/dist/server/util/origin.js +5 -24
- package/dist/server/util/paths.js +25 -3
- package/dist/server/util/pricing-index.js +2 -6
- package/dist/server/util/pricing.js +10 -10
- package/dist/server/util/spawn-cli.js +2 -2
- package/dist/server/util/upstream-version.js +10 -12
- package/dist/server/util/version.js +2 -2
- package/dist/server/web-proxy/proxy-routes.js +167 -0
- package/dist/server/web-proxy/proxy-url.js +60 -0
- package/dist/server/web-proxy/rewrite.js +84 -0
- package/dist/server/ws/handle-message.js +21 -2
- package/package.json +13 -14
- package/scripts/prune-prebuilds.mjs +1 -1
- package/web/dist/assets/_oh-my-agent-web-mermaid-pruned_chunk_abnfDiagram-WEYOIA3C-Dq-2fRb4.js +1 -0
- package/web/dist/assets/_oh-my-agent-web-mermaid-pruned_chunk_architectureDiagram-ZHVYKT53-Dh5CEs4k.js +1 -0
- package/web/dist/assets/_oh-my-agent-web-mermaid-pruned_chunk_c4Diagram-XDPPPE54-Cb19QmmE.js +1 -0
- package/web/dist/assets/_oh-my-agent-web-mermaid-pruned_chunk_cynefinDiagram-WF24UDRP-COk-IL9O.js +1 -0
- package/web/dist/assets/_oh-my-agent-web-mermaid-pruned_chunk_diagram-CBK3MWTC-Gp_0nfEJ.js +1 -0
- package/web/dist/assets/_oh-my-agent-web-mermaid-pruned_chunk_diagram-ODIL2UCW-rzPf_9IN.js +1 -0
- package/web/dist/assets/_oh-my-agent-web-mermaid-pruned_chunk_diagram-PFBEJUXE-B5EnLWwl.js +1 -0
- package/web/dist/assets/_oh-my-agent-web-mermaid-pruned_chunk_diagram-TYUNFSNR-DVpFKFwC.js +1 -0
- package/web/dist/assets/_oh-my-agent-web-mermaid-pruned_chunk_ebnfDiagram-V4P3TTPT-CDL1qiPY.js +1 -0
- package/web/dist/assets/_oh-my-agent-web-mermaid-pruned_chunk_ishikawaDiagram-HPEHV2GE-CSkoONzp.js +1 -0
- package/web/dist/assets/_oh-my-agent-web-mermaid-pruned_chunk_mindmap-definition-6OY57UG3-B9sdVB6_.js +1 -0
- package/web/dist/assets/_oh-my-agent-web-mermaid-pruned_chunk_pegDiagram-ECIUJNBX-B6P7baCF.js +1 -0
- package/web/dist/assets/_oh-my-agent-web-mermaid-pruned_chunk_railroadDiagram-Y72NRBL7-W_a8Vy2l.js +1 -0
- package/web/dist/assets/_oh-my-agent-web-mermaid-pruned_chunk_swimlanes-B3ENRKFQ-DvGif-RR.js +1 -0
- package/web/dist/assets/_oh-my-agent-web-mermaid-pruned_chunk_swimlanesDiagram-AYQRV4AK-D0gFG_EI.js +1 -0
- package/web/dist/assets/_oh-my-agent-web-mermaid-pruned_chunk_usecaseDiagram-WPOLBNNX-BjgUBJiR.js +1 -0
- package/web/dist/assets/_oh-my-agent-web-mermaid-pruned_chunk_vennDiagram-Q3Y3IDCW-DnVuWTpF.js +1 -0
- package/web/dist/assets/_oh-my-agent-web-mermaid-pruned_chunk_wardleyDiagram-IVAIDKWA-B2vDAqpl.js +1 -0
- package/web/dist/assets/{arc-BTAvbR16.js → arc-Df9SI9yh.js} +1 -1
- package/web/dist/assets/{architecture-WOLXFQ4H-fewLD5_7.js → architecture-WOLXFQ4H-iO49E8Y1.js} +1 -1
- package/web/dist/assets/{blockDiagram-RJAE7QA3-ClmgyxZl.js → blockDiagram-RJAE7QA3-D8d1ukIs.js} +1 -1
- package/web/dist/assets/channel-C2-OT56h.js +1 -0
- package/web/dist/assets/{chunk-55XCU76K-DdC5EhZG.js → chunk-55XCU76K-C5wOvqDb.js} +1 -1
- package/web/dist/assets/{chunk-7S6XSTFO-CgToWHK6.js → chunk-7S6XSTFO-WIrWcDbG.js} +1 -1
- package/web/dist/assets/{chunk-AQDTSKZB-D-rQMnp7.js → chunk-AQDTSKZB-OkzYqFsw.js} +1 -1
- package/web/dist/assets/{chunk-DSNLSHJZ-cuZoTGMH.js → chunk-DSNLSHJZ-CHEA9kYd.js} +2 -2
- package/web/dist/assets/{chunk-HNE4Q36P-CiKr9iSN.js → chunk-HNE4Q36P-CPsq34CI.js} +1 -1
- package/web/dist/assets/{chunk-VQ5W62QI-DbTfXAAT.js → chunk-VQ5W62QI-CamPnEuF.js} +1 -1
- package/web/dist/assets/{chunk-WQQL4CDK-DHanHfB5.js → chunk-WQQL4CDK-gNypBVAM.js} +1 -1
- package/web/dist/assets/{chunk-ZAUX2LTX-SrjFXpy2.js → chunk-ZAUX2LTX--4WyRBRV.js} +1 -1
- package/web/dist/assets/{chunk-ZCHMQSOR-7Wy8xXQ5.js → chunk-ZCHMQSOR-umv3Lkpn.js} +1 -1
- package/web/dist/assets/{classDiagram-v2-4MYWR3UA-CBe5ZDvZ.js → classDiagram-v2-4MYWR3UA-C1XldpO1.js} +1 -1
- package/web/dist/assets/{cose-bilkent-JH36ORCC-Dljdyvhw.js → cose-bilkent-JH36ORCC-BvugZzFU.js} +1 -1
- package/web/dist/assets/{cynefin-EF2NZ3EQ-CcZU7GFP.js → cynefin-EF2NZ3EQ-6qXB70s4.js} +1 -1
- package/web/dist/assets/{dagre-NK4GIZVX-Bq_6y8qp.js → dagre-NK4GIZVX-DDdlABYw.js} +1 -1
- package/web/dist/assets/{diagram-I5XIIV2D-C2lnnYVG.js → diagram-I5XIIV2D-T8oWy5CY.js} +1 -1
- package/web/dist/assets/{diagram-RJA3I4VV-Bqf8Z6wJ.js → diagram-RJA3I4VV-CkdHTtfV.js} +1 -1
- package/web/dist/assets/{elk-QONTBCTQ-Cdzq_cJ5.js → elk-QONTBCTQ-BiEUbJJX.js} +1 -1
- package/web/dist/assets/{erDiagram-KYQIGQAA-ZJLCjPFC.js → erDiagram-KYQIGQAA-q3WwhyzH.js} +1 -1
- package/web/dist/assets/{eventmodeling-K75KTNOO-DHqeIpes.js → eventmodeling-K75KTNOO-BO5gW_NC.js} +1 -1
- package/web/dist/assets/{flowDiagram-IUGLLWBU-AVgYvXKN.js → flowDiagram-IUGLLWBU-DubjP6UK.js} +1 -1
- package/web/dist/assets/{ganttDiagram-R7GPNTJY-CR1SG1M7.js → ganttDiagram-R7GPNTJY-lKNRH8CI.js} +1 -1
- package/web/dist/assets/{gitGraph-VSP46ZUC-CIZQPK0R.js → gitGraph-VSP46ZUC-Cwlv3omT.js} +1 -1
- package/web/dist/assets/{gitGraphDiagram-PDYL7XHY-BhOCWEh6.js → gitGraphDiagram-PDYL7XHY-Bo9GpFvW.js} +1 -1
- package/web/dist/assets/index-CeYhxqkk.js +113 -0
- package/web/dist/assets/index-GJgJwZ23.css +1 -0
- package/web/dist/assets/{info-OHQRW6UA-C2wuRxeQ.js → info-OHQRW6UA-g3MbTRmN.js} +1 -1
- package/web/dist/assets/{infoDiagram-MVDRKAX5-BP5doAB5.js → infoDiagram-MVDRKAX5-CmILYLoB.js} +1 -1
- package/web/dist/assets/{journeyDiagram-BOSHW7O7-BcIDRTPS.js → journeyDiagram-BOSHW7O7-Av8T0U1C.js} +1 -1
- package/web/dist/assets/{kanban-definition-FNSA4HC5-CRH_bcoT.js → kanban-definition-FNSA4HC5-B9NyWQYN.js} +1 -1
- package/web/dist/assets/{line-iA4GPA_S.js → line-BUrll1My.js} +1 -1
- package/web/dist/assets/{linear-BGUKwkTH.js → linear-DjET0phX.js} +1 -1
- package/web/dist/assets/{math-DgNW_bVP.js → math-BJAjkhlu.js} +1 -1
- package/web/dist/assets/{mermaid-parser.core-CsqmgpEv.js → mermaid-parser.core-CaTdkhkS.js} +3 -3
- package/web/dist/assets/{mermaid.core-C1yCGQK6.js → mermaid.core-Cktx937U.js} +4 -4
- package/web/dist/assets/{packet-JDAUHWVQ-2ggaoz2g.js → packet-JDAUHWVQ-DhG6l3PG.js} +1 -1
- package/web/dist/assets/{pie-XZMESJXO-h_yslQQs.js → pie-XZMESJXO-YPcOx7s0.js} +1 -1
- package/web/dist/assets/{pieDiagram-GNMPY74T-6-JZMFyk.js → pieDiagram-GNMPY74T-DesiZKUl.js} +1 -1
- package/web/dist/assets/{quadrantDiagram-D57K4MC3-K5r1HOgL.js → quadrantDiagram-D57K4MC3-Cn1kBVgu.js} +1 -1
- package/web/dist/assets/{radar-ABXABTNO-6fOJGGgq.js → radar-ABXABTNO-CtuRfYSz.js} +1 -1
- package/web/dist/assets/{railroad-I3PHUGI6-B_gUgQ3d.js → railroad-I3PHUGI6-D5Gnyy0R.js} +1 -1
- package/web/dist/assets/{railroad-abnf-LNEFI6M7-CJ_eqiXZ.js → railroad-abnf-LNEFI6M7-Kw4pmJEm.js} +1 -1
- package/web/dist/assets/{railroad-ebnf-DWYD2UWJ-BTsgjLTU.js → railroad-ebnf-DWYD2UWJ-D8Mk5dIe.js} +1 -1
- package/web/dist/assets/{railroad-peg-JR7BVNR7-D91uiLln.js → railroad-peg-JR7BVNR7-R5Jwzs8F.js} +1 -1
- package/web/dist/assets/{requirementDiagram-EQYSW5RA-uapnV_OO.js → requirementDiagram-EQYSW5RA-B9RDq-cL.js} +1 -1
- package/web/dist/assets/{sankeyDiagram-SY24JHO5-BQsbFgUb.js → sankeyDiagram-SY24JHO5-DoEatOm6.js} +1 -1
- package/web/dist/assets/{sequenceDiagram-BLEHNHQU-iRoSYX_e.js → sequenceDiagram-BLEHNHQU-DGE5Z9lT.js} +1 -1
- package/web/dist/assets/{src-BBrKcs9r.js → src-BnEL7pZw.js} +1 -1
- package/web/dist/assets/{stateDiagram-v2-A6IESKWZ-Bzj9z5KH.js → stateDiagram-v2-A6IESKWZ-_vn8W-k_.js} +1 -1
- package/web/dist/assets/{timeline-definition-JXYKGLGB-DLUUuJX0.js → timeline-definition-JXYKGLGB-BaSLTtgR.js} +1 -1
- package/web/dist/assets/{treeView-D4JQ5SDB-CphIQ3n5.js → treeView-D4JQ5SDB-DZElyFgL.js} +1 -1
- package/web/dist/assets/{treemap-SAJKECNS-DqU3insw.js → treemap-SAJKECNS-DWDO4K4G.js} +1 -1
- package/web/dist/assets/{wardley-7MLQ67FV-Ch7d8cmC.js → wardley-7MLQ67FV-DTOUsk6Q.js} +1 -1
- package/web/dist/assets/{xychartDiagram-4URNHDU4-DdxpWBeM.js → xychartDiagram-4URNHDU4-DiaCfgAB.js} +1 -1
- package/web/dist/index.html +2 -2
- package/docs/screenshots/01-chat.png +0 -0
- package/docs/screenshots/02-answer.png +0 -0
- package/docs/screenshots/03-files-diff.png +0 -0
- package/docs/screenshots/04-terminal.png +0 -0
- package/docs/screenshots/05-models.png +0 -0
- package/docs/screenshots/06-skills.png +0 -0
- package/docs/screenshots/07-skills-hub.png +0 -0
- package/docs/screenshots/08-mcp.png +0 -0
- package/docs/screenshots/09-subagents.png +0 -0
- package/docs/screenshots/10-settings.png +0 -0
- package/docs/screenshots/11-plugins.png +0 -0
- package/docs/screenshots/12-voice.png +0 -0
- package/docs/screenshots/13-push.png +0 -0
- package/docs/screenshots/README.md +0 -45
- package/web/dist/assets/_omaw-mermaid-pruned_chunk_abnfDiagram-WEYOIA3C-CvNbnJ75.js +0 -1
- package/web/dist/assets/_omaw-mermaid-pruned_chunk_architectureDiagram-ZHVYKT53-T7NZZ4ao.js +0 -1
- package/web/dist/assets/_omaw-mermaid-pruned_chunk_c4Diagram-XDPPPE54-ByuAPg39.js +0 -1
- package/web/dist/assets/_omaw-mermaid-pruned_chunk_cynefinDiagram-WF24UDRP-BY5DHttT.js +0 -1
- package/web/dist/assets/_omaw-mermaid-pruned_chunk_diagram-CBK3MWTC-D7ZYyrF7.js +0 -1
- package/web/dist/assets/_omaw-mermaid-pruned_chunk_diagram-ODIL2UCW-C6kcOZFc.js +0 -1
- package/web/dist/assets/_omaw-mermaid-pruned_chunk_diagram-PFBEJUXE-CzFPFq0D.js +0 -1
- package/web/dist/assets/_omaw-mermaid-pruned_chunk_diagram-TYUNFSNR-B4G4T8SL.js +0 -1
- package/web/dist/assets/_omaw-mermaid-pruned_chunk_ebnfDiagram-V4P3TTPT-BkQ4xwD0.js +0 -1
- package/web/dist/assets/_omaw-mermaid-pruned_chunk_ishikawaDiagram-HPEHV2GE-52xqckJv.js +0 -1
- package/web/dist/assets/_omaw-mermaid-pruned_chunk_mindmap-definition-6OY57UG3-7cQksbFn.js +0 -1
- package/web/dist/assets/_omaw-mermaid-pruned_chunk_pegDiagram-ECIUJNBX-udgtBpwv.js +0 -1
- package/web/dist/assets/_omaw-mermaid-pruned_chunk_railroadDiagram-Y72NRBL7-Cd2dcQWz.js +0 -1
- package/web/dist/assets/_omaw-mermaid-pruned_chunk_swimlanes-B3ENRKFQ-p34pL1Yk.js +0 -1
- package/web/dist/assets/_omaw-mermaid-pruned_chunk_swimlanesDiagram-AYQRV4AK-BslfPs4r.js +0 -1
- package/web/dist/assets/_omaw-mermaid-pruned_chunk_usecaseDiagram-WPOLBNNX-DJZoN9Xk.js +0 -1
- package/web/dist/assets/_omaw-mermaid-pruned_chunk_vennDiagram-Q3Y3IDCW-DPXo67cZ.js +0 -1
- package/web/dist/assets/_omaw-mermaid-pruned_chunk_wardleyDiagram-IVAIDKWA-BE6ukwkg.js +0 -1
- package/web/dist/assets/channel-DfaYIFFE.js +0 -1
- package/web/dist/assets/index-CZQjJbRg.js +0 -104
- package/web/dist/assets/index-ChDUWKZX.css +0 -1
- /package/web/dist/assets/{_omaw-mermaid-pruned_katex_katex-Zojedrce.js → _oh-my-agent-web-mermaid-pruned_katex_katex-Zojedrce.js} +0 -0
package/README.md
CHANGED
|
@@ -2,80 +2,47 @@
|
|
|
2
2
|
|
|
3
3
|
**中文** · [English](README.en.md)
|
|
4
4
|
|
|
5
|
-
一句话:**给你正在跑的那个 agent 配一个外部操作页。**
|
|
5
|
+
一句话:**给你正在跑的那个 agent 配一个外部操作页。** 引擎照旧跑在自己电脑上,你在网页里看着它干活、管它的工具和模型、随时插话纠正,需要时直接翻文件、开终端、圈出一段话让它改。
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
单用户、只听回环、**会话的事实源永远是引擎自己的落盘文件** —— 不引数据库、不建账号体系、不把会话复制一份到自己的库里。一个 `oh-my-agent-web` 进程就是一个人的工作台。
|
|
8
8
|
|
|
9
|
-

|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
11
|
+
> 下面所有截图都是把本仓库(0.8.0 的构建)跑起来后的真实界面 —— pi 引擎 + DeepSeek,工作区是一个 `demo-app` 演示项目。
|
|
12
|
+
> 目录、命令、`+6 −1` 的改动、token 与花费都是那次真实运行留下的,没有拼图也没有 mock。
|
|
13
|
+
> 每张图的内容、拍法与压缩方式记在 [`docs/screenshots/README.md`](docs/screenshots/README.md)。
|
|
14
14
|
|
|
15
15
|
---
|
|
16
16
|
|
|
17
|
-
##
|
|
17
|
+
## 安装
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
要求 **Node.js ≥ 22.19** 与 **npm ≥ 9**(macOS / Linux / Windows 都行)。装完就有 `oh-my-agent-web` 这个命令(短别名 `aw`、`agent-web`,完全等价)。
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
|---|---|---|
|
|
23
|
-
| **对话** | 中间 | 流式正文 + 可折叠思考块 + 工具卡(参数 / 完整命令 / 输出 / 耗时 / 成败)+ 「过程 N 步」分块 + 用量尾注(token / 缓存 / 花费)+ 改动文件 chip |
|
|
24
|
-
| **插队与排队** | 输入区 | 回合进行中可以 steer(下一条立刻生效);排队的消息可撤回;发出去的消息可折叠进过程 |
|
|
25
|
-
| **多引擎** | 顶栏「引擎」 | pi / Codex / DeepSeek Harness / opencode 各自的原生 loop(不是换皮的同一套 prompt);每个会话记住自己的引擎、模型、思考档 |
|
|
26
|
-
| **子代理** | 顶栏「子代理」+ 对话下方卡片条 | 主 agent 拿到 `Agent` 工具后可并行开多个**真实会话**;对话下方给运行卡(状态 / 耗时 / 工具次数 / token / 花费 / 就地看结果 / 单独停掉);面板里管模板:工具白名单、模型、思考档、最大轮次、并发上限(1–12) |
|
|
27
|
-
| **模型与供应商** | 顶栏「模型」 | 内置 pi 官方目录里的 41 家:**填一把 key 就能用**,不用抄 base url 与模型 id;自定义 provider 可改 api 形态(openai-completions / responses / anthropic-messages / codex / typesafe)、base url、自定义 headers;逐个勾选模型、批量测速、从 `/models` 拉清单、按勾选保存白名单;**key 不出服务端**(只回尾 4 位) |
|
|
28
|
-
| **技能** | 顶栏「技能」 | 已装列表(工具市场装了 45 个就是 45 行)+ 启停 + 看 `SKILL.md` 与目录文件;**Skill Hub** 分类搜索与一键安装(索引 20 万+)、从 Git 仓库装、手动创建;启停 = 把 `SKILL.md` 改名,不留第二份状态 |
|
|
29
|
-
| **MCP** | 顶栏「MCP」 | 全局与项目两份 `mcp.json` 可视化增删改(项目同名条目覆盖全局)、启停、exposure 四档(codemode / deferred / direct / hidden)、**测试连接**(真握手 + 列工具)、OAuth 登录、市场挑服务器 |
|
|
30
|
-
| **插件** | 顶栏「插件」 | pi package(npm / git / 本地目录)四态一览(loaded / installed / missing / disabled)、按包停用、散装 `extensions/` 单文件扩展;状态来自 pi 自己解析,装/卸/更新才动磁盘 |
|
|
31
|
-
| **文件管理** | 侧栏「文件管理」 | 目录树(可换根)、按文件名搜索、显示隐藏文件、全部收起、上传与下载、在 Finder 中显示;未提交改动在树上打点 |
|
|
32
|
-
| **查看文件** | 右栏预览(多标签) | markdown / 源码带行号 / 图片 / PDF / 音视频流;按行选中后「添加到对话」直接当上下文;可全屏、可拖宽 |
|
|
33
|
-
| **改动(diff)** | 预览页顶「改动」 | 与 HEAD 对比:`+285 −78` 概览、行级红绿高亮、可只看改动也可回到全文;从「改动过的文件」chip 点进来时直接落在 diff |
|
|
34
|
-
| **git** | 文件区顶部 | 分支标签(点开切本地分支,脏工作区先确认)、文件后面标 `M` / `U` / `D` 状态 |
|
|
35
|
-
| **终端** | 文件区 `>_`、右栏标签 | 真 PTY(`node-pty` + xterm.js),与会话共用 cwd,可自动执行初始命令;Linux 缺编译工具时会明确说装什么 |
|
|
36
|
-
| **推送** | 顶栏「推送」 | Web Push 订阅(VAPID),回合结束推一条:标题=项目名、正文=会话名、失败 ❌ / 中断 ⏹ 带前缀;多设备管理、测试推送、一键清空;需要 https 或 localhost |
|
|
37
|
-
| **语音** | 顶栏「语音」 | 四类事件提示音(开始 / 结束 / 出错 / 等待审批)可试听、音量可调;本地 TTS 播报(浏览器内置语音,不联网),可朗读最终回复、调语速与音色 |
|
|
38
|
-
| **设置** | 顶栏「设置」 | 四页:**界面**(顶栏与状态栏显示哪些块)、**通用**(快捷短语等)、**外观**(聊天字号 4 档 / 内容宽度 4 档 / 6 套色板:清亮白、暖纸、雾青、东京夜、摩卡、北境)、**语言**(中文 / English,点了立刻生效) |
|
|
39
|
-
| **会话** | 侧栏 | 按目录分组成「项目」、置顶、重命名、归档(可撤销)、删除(改名 `.deleted-<时间戳>`,文件还在);会话就是引擎自己的文件,CLI 里看到的一致 |
|
|
40
|
-
| **附件** | 输入框 | 拖拽上传、`@` 提及文件、图片粘贴;上传落在数据目录,不写进项目 |
|
|
41
|
-
| **手机** | — | 窄屏自适应:侧栏变抽屉、过程块收成三角箭头、400px 以下自动切手机布局 |
|
|
42
|
-
|
|
43
|
-
> 下面所有截图都来自**真实运行**的实例(就在本项目自己的会话上截的),不是拼的 mock。
|
|
44
|
-
|
|
45
|
-
---
|
|
21
|
+
### npm 全局安装(推荐)
|
|
46
22
|
|
|
47
|
-
|
|
23
|
+
```bash
|
|
24
|
+
npm -g install oh-my-agent-web
|
|
25
|
+
```
|
|
48
26
|
|
|
49
|
-
|
|
50
|
-
|---|---|
|
|
51
|
-
|  |  |
|
|
52
|
-
| **回答**:markdown / 表格 / 代码高亮,尾注给 token 与花费 | **改动**:与 HEAD 对比,红绿行级高亮 |
|
|
53
|
-
|  |  |
|
|
54
|
-
| **终端**:真 PTY,与会话同 cwd | **模型**:内置 41 家填 key 即用,模型勾选即生效 |
|
|
55
|
-
|  |  |
|
|
56
|
-
| **技能**:已装列表 + 启停 + 看 SKILL.md | **技能市场**:分类搜索,一键安装 |
|
|
57
|
-
|  |  |
|
|
58
|
-
| **MCP**:全局 / 项目两份配置、暴露方式、测试连接 | **子代理**:跑几个、看结果、模板与工具白名单 |
|
|
59
|
-
|  |  |
|
|
60
|
-
| **设置 → 外观**:字号、内容宽度、6 套色板 | **插件**:pi package 的加载状态与启停 |
|
|
61
|
-
|
|
62
|
-
另外两张:[语音(提示音 + 本地 TTS)](docs/screenshots/12-voice.png)、[推送(订阅与多设备)](docs/screenshots/13-push.png)。
|
|
27
|
+
不带版本号装的就是当前发行版。要钉版本或用镜像:
|
|
63
28
|
|
|
64
|
-
|
|
29
|
+
```bash
|
|
30
|
+
npm -g install oh-my-agent-web@latest
|
|
31
|
+
npm -g install oh-my-agent-web@<版本号> --registry=https://registry.npmmirror.com
|
|
32
|
+
```
|
|
65
33
|
|
|
66
|
-
|
|
34
|
+
装出来的三个命令指向同一个入口,完全等价:**`oh-my-agent-web`**(下面统一用它)、`aw`(短别名,打字省事)、`agent-web`。
|
|
67
35
|
|
|
68
|
-
|
|
36
|
+
升级与卸载:
|
|
69
37
|
|
|
70
38
|
```bash
|
|
71
|
-
|
|
72
|
-
npm
|
|
73
|
-
npm start # 前台运行;Ctrl-C 退出
|
|
39
|
+
oh-my-agent-web upgrade # 等于 npm -g install oh-my-agent-web@latest
|
|
40
|
+
npm -g uninstall oh-my-agent-web # 卸载;~/.oh-my-agent-web 里的数据不动
|
|
74
41
|
```
|
|
75
42
|
|
|
76
|
-
|
|
43
|
+
Linux 上 `node-pty`(内嵌终端)只给 macOS / Windows 带预编译产物,Linux 要就地编译:需要 `make` / `g++` / `python3`。缺工具时页面和安装脚本都会直说缺什么,装完终端才开得起来。
|
|
77
44
|
|
|
78
|
-
###
|
|
45
|
+
### 一行脚本(不想碰系统全局 npm)
|
|
79
46
|
|
|
80
47
|
macOS / Linux:
|
|
81
48
|
|
|
@@ -89,199 +56,441 @@ Windows(PowerShell):
|
|
|
89
56
|
powershell -c "irm https://raw.githubusercontent.com/duzhenxun/oh-my-agent-web/main/scripts/install.ps1 | iex"
|
|
90
57
|
```
|
|
91
58
|
|
|
92
|
-
脚本做四件事:**找一个够新的 Node**(没有就下官方包到 `~/.
|
|
93
|
-
|
|
94
|
-
|
|
59
|
+
脚本做四件事:**找一个够新的 Node**(没有就下官方包到 `~/.oh-my-agent-web/node`,校验 sha256)、**`npm install -g --prefix ~/.oh-my-agent-web`**(不写系统全局目录、不要 sudo)、**把 `aw` / `agent-web` / `oh-my-agent-web` 挂到 `~/.local/bin`**(必要时补 PATH)、**冒烟一次**(版本号 + `node-pty` 能否 require,即终端能不能开)。
|
|
60
|
+
|
|
61
|
+
装到的这个 `~/.oh-my-agent-web` 同时也是**数据目录**:装进去的 `node/`、`lib/`、`bin/` 和你的 `settings.json`、`password`、`uploads/`、`logs/` 并排放着。
|
|
95
62
|
|
|
96
63
|
| 想改的东西 | 用法(`sh` 版;PowerShell 版用环境变量) |
|
|
97
64
|
|---|---|
|
|
98
|
-
| 版本 | `
|
|
99
|
-
| 装到别处 | `
|
|
100
|
-
| 镜像源 | `
|
|
101
|
-
| 不动 PATH | `
|
|
102
|
-
| 装编译工具 | `
|
|
103
|
-
| 卸载 | `… \| sh -s -- --uninstall
|
|
104
|
-
|
|
105
|
-
Linux 上额外查一次 `make` / `g++` / `python3`:`node-pty` 只给 macOS / Windows 带预编译产物,
|
|
106
|
-
Linux 要就地编译 PTY。缺工具时脚本会说清楚装什么,或者直接 `--with-build-tools` 让它代劳。
|
|
65
|
+
| 版本 | `OH_MY_AGENT_WEB_VERSION=<版本号>`(或 `--version <版本号>`) |
|
|
66
|
+
| 装到别处 | `OH_MY_AGENT_WEB_HOME=/opt/oh-my-agent-web`(或 `--home /opt/oh-my-agent-web`) |
|
|
67
|
+
| 镜像源 | `OH_MY_AGENT_WEB_REGISTRY=https://registry.npmmirror.com`(或 `--registry …`) |
|
|
68
|
+
| 不动 PATH | `OH_MY_AGENT_WEB_NO_PATH=1`(或 `--no-modify-path`) |
|
|
69
|
+
| 装编译工具 | `OH_MY_AGENT_WEB_BUILD_TOOLS=1`(或 `--with-build-tools`) |
|
|
70
|
+
| 卸载 | `… \| sh -s -- --uninstall`(只删装进去的包与命令,`settings.json` / 密码 / 上传 / 日志不动) |
|
|
107
71
|
|
|
108
|
-
|
|
109
|
-
> 所以这时会自动改用 `<数据目录>/workspace` 并打一行提示;真想指定项目就用 `AGENT_WEB_CWD=/path/to/project`。
|
|
72
|
+
---
|
|
110
73
|
|
|
111
|
-
|
|
74
|
+
## 命令
|
|
112
75
|
|
|
113
|
-
`oh-my-agent-web`
|
|
76
|
+
三个命令完全等价,下面统一写 `oh-my-agent-web`(`aw` 是它的短别名)。
|
|
114
77
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
78
|
+
| 命令 | 作用 |
|
|
79
|
+
|---|---|
|
|
80
|
+
| `oh-my-agent-web` | **启动(默认)**:后台跑起来 + 打开浏览器,终端立刻还给你;默认工作区 = 当前目录 |
|
|
81
|
+
| `oh-my-agent-web start -f` | 前台运行,日志直接打在终端,`Ctrl-C` 退出 |
|
|
82
|
+
| `oh-my-agent-web status` | 看状态:pid / 端口 / 已运行多久 / 引擎 / 会话数 / 工作区 |
|
|
83
|
+
| `oh-my-agent-web restart` | 先停再起(默认仍后台;带 `-f` 则前台) |
|
|
84
|
+
| `oh-my-agent-web stop` | 停掉正在跑的实例(前台、后台都行 —— 读的是数据目录里的锁文件,不靠猜端口) |
|
|
85
|
+
| `oh-my-agent-web version` | 版本号(`-v` / `--version` 同义) |
|
|
86
|
+
| `oh-my-agent-web upgrade` | 升级到最新发行版(内部就是 `npm -g install oh-my-agent-web@latest`) |
|
|
87
|
+
| `oh-my-agent-web help` | 显示帮助(`-h` / `--help` 同义) |
|
|
123
88
|
|
|
124
|
-
###
|
|
89
|
+
### 参数
|
|
125
90
|
|
|
126
91
|
| 参数 | 环境变量 | 默认 | 说明 |
|
|
127
|
-
|
|
92
|
+
|---|---|---|---|
|
|
128
93
|
| `-p, --port` | `AGENT_WEB_PORT` | `25257` | 监听端口 |
|
|
129
94
|
| `-H, --host` | `AGENT_WEB_HOST` | `127.0.0.1` | 监听地址;对外访问才需要改 |
|
|
130
|
-
| `-P, --password` | `AGENT_WEB_PASSWORD` | 无 | 访问密码;不设 =
|
|
95
|
+
| `-P, --password` | `AGENT_WEB_PASSWORD` | 无 | 访问密码;不设 = 只允许本机(远程首次打开会先让你设) |
|
|
96
|
+
| `-f, --foreground` | — | 关(默认后台) | 前台运行,日志打在终端;`-d` / `--detach` 是旧写法,现在等于默认 |
|
|
97
|
+
| `--no-open` | — | 开 | 不在浏览器里打开页面 |
|
|
131
98
|
| `--allow-host` | `AGENT_WEB_ALLOWED_HOSTS` | 只认 loopback | 额外允许的域名 / 局域网 IP(可多次或逗号分隔) |
|
|
132
99
|
| `--data-dir` | `AGENT_WEB_DATA_DIR` | `~/.oh-my-agent-web` | 设置、密码、上传、日志、锁文件都放这 |
|
|
133
100
|
| — | `AGENT_WEB_CWD` | `process.cwd()` | 默认工作区(还没开会话时用) |
|
|
134
101
|
| — | `AGENT_WEB_ENGINE` | `pi` | 默认引擎 |
|
|
135
|
-
| — | `AGENT_WEB_APPROVAL_MODE` | `allow` |
|
|
102
|
+
| — | `AGENT_WEB_APPROVAL_MODE` | `allow` | 新会话默认审批模式;`ask` 则逐次确认 |
|
|
136
103
|
| — | `AGENT_WEB_TURN_TIMEOUT_MS` | 20 分钟 | 单回合看门狗超时 |
|
|
137
104
|
| — | `AGENT_WEB_LOG` | `info` | `debug` / `info` / `warn` / `error` |
|
|
138
105
|
|
|
139
|
-
|
|
106
|
+
### 常用例子
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
oh-my-agent-web # 后台起 + 打开页面(最常用)
|
|
110
|
+
oh-my-agent-web -f # 前台起,日志直接看,Ctrl-C 退出
|
|
111
|
+
oh-my-agent-web -p 25258 # 换端口(25257 被占时)
|
|
112
|
+
oh-my-agent-web status && oh-my-agent-web restart # 看完状态再重启
|
|
113
|
+
oh-my-agent-web stop # 停掉(前台/后台都行)
|
|
114
|
+
oh-my-agent-web --data-dir ~/agent-web-data # 换数据目录
|
|
115
|
+
AGENT_WEB_CWD=~/code/my-proj oh-my-agent-web # 指定默认工作区
|
|
116
|
+
oh-my-agent-web -H 0.0.0.0 --allow-host agent.example.com # 允许对外访问(首次打开会先让你设密码)
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
> **想从手机访问**:`oh-my-agent-web -H 0.0.0.0 --allow-host 你的域名`,首次在手机上打开会让你**设一个访问密码**(存到数据目录里的 `password`,之后就是输密码登录),反代 / 隧道请带上 `X-Forwarded-For`(来源校验会看它)。
|
|
120
|
+
>
|
|
121
|
+
> **在家目录直接敲 `oh-my-agent-web`** 也能用,但家目录当工作区不安全(文件树 / 搜索 / agent 的 cwd 会是整个 home),这时会自动改用 `<数据目录>/workspace` 并打一行提示;想指定项目就用 `AGENT_WEB_CWD=/path/to/project`。
|
|
122
|
+
|
|
123
|
+
各引擎还有自己的逃生阀(都有默认值,通常不用配):`AGENT_WEB_CODEX_BIN` / `_HOME`、`AGENT_WEB_DSH_BIN` / `_HOME` / `_MODEL` / `_PATCH`、`AGENT_WEB_OPENCODE_BIN` / `_ARGS` / `_MODEL`、`AGENT_WEB_CLAUDE_BIN` / `_ARGS` / `_MODEL`(默认自动探测 `claude-code-acp` / `claude-agent-acp`,没装就直说)。
|
|
124
|
+
|
|
125
|
+
---
|
|
126
|
+
|
|
127
|
+
## 它是什么,不是什么
|
|
128
|
+
|
|
129
|
+
**是**:一个把 agent 的「过程」摊开给你看的前端。思考块、工具调用、改动文件、token 与花费,都在对话流里;你能在回合中途插话、把某段话圈出来提意见、另开一条不落盘的临时对话问一句就走。
|
|
130
|
+
|
|
131
|
+
**不是**:不是新的 agent 引擎,也不是把会话搬到云上的 SaaS。它不重写 prompt、不接管工具实现 —— 你装的是 pi / Codex / Claude Code / opencode / DeepSeek Harness,工作台只是给它们配了一套能看的界面、能点的按钮和能落盘的会话列表。
|
|
132
|
+
|
|
133
|
+
三条硬纪律:
|
|
134
|
+
|
|
135
|
+
1. **不引数据库**:会话就是引擎写的 JSONL / thread,网页只读它、改它的名字、必要时删它。
|
|
136
|
+
2. **不假装**:引擎没有的能力就在界面上藏起来(能力矩阵),面板拿不到数据就说清楚,不拿别的引擎的配置冒充。
|
|
137
|
+
3. **不越界**:默认只听 `127.0.0.1`,远程暴露要显式给 `-H`、`-P`、`--allow-host` 三样。
|
|
138
|
+
|
|
139
|
+
---
|
|
140
|
+
|
|
141
|
+
## 对话
|
|
142
|
+
|
|
143
|
+
**流式正文 + 可折叠思考块 + 工具卡**。工具卡上给参数、完整命令(可复制)、输出、耗时与成败;一次回合里的思考与工具调用按「过程 N 步」分块,点开才展开。
|
|
144
|
+
|
|
145
|
+

|
|
146
|
+
|
|
147
|
+
每条回复的尾注是**这一轮**的用量:输入(未命中缓存)/ 输出 / 缓存命中 / 花费,点「复制」可以整段带走;整段会话的累计在状态栏的上下文环里点开看(子代理是独立会话、单独计费,不算在里面)。
|
|
148
|
+
|
|
149
|
+
对话里还埋了几个能点的东西:
|
|
150
|
+
|
|
151
|
+
- **改动文件 chip**:这条回复改过哪些文件(上图底部的 `改动 1 个文件 / store.ts`),点一下直接落到右栏的 diff。
|
|
152
|
+
- **分支图标**:从这条消息「创建分支」,原对话一字不动。
|
|
153
|
+
- **文件路径**:正文里的 `web/src/App.tsx` 这类路径可直接点开预览。
|
|
154
|
+
|
|
155
|
+
### 插队、排队、停止
|
|
156
|
+
|
|
157
|
+
回合正在跑的时候,输入框不会锁死:
|
|
158
|
+
|
|
159
|
+
| 动作 | 含义 |
|
|
160
|
+
|---|---|
|
|
161
|
+
| **插队(steer)** | 立刻生效,作为下一条指令插进当前回合 |
|
|
162
|
+
| **排队** | 排在本回合结束之后,队首是谁一目了然,随时可撤回 |
|
|
163
|
+
| **停止** | 中断当前回合,保留已经产出的内容 |
|
|
164
|
+
|
|
165
|
+
插队只有 pi 引擎支持(它的 SDK 有 `streamingBehavior: "steer"`);别的引擎没有这个语义,宿主会**降级成排队**,而不是硬发第二条把活跃回合冲掉。
|
|
140
166
|
|
|
141
167
|
---
|
|
142
168
|
|
|
143
|
-
##
|
|
169
|
+
## 注释:把一段话圈出来提意见
|
|
170
|
+
|
|
171
|
+
在对话里**选中一段文字**,会浮出一个小工具条:`添加到会话` / `标注` / `在临时会话中提问`。
|
|
172
|
+
|
|
173
|
+
<table><tr>
|
|
174
|
+
<td width="50%"><img src="docs/screenshots/14-selection-toolbar.png" alt="选中一段回复后浮出的工具条"></td>
|
|
175
|
+
<td width="50%"><img src="docs/screenshots/15-annotations.png" alt="标注之后:正文里留下编号徽标,输入框里多出「1 条注释」"></td>
|
|
176
|
+
</tr></table>
|
|
177
|
+
|
|
178
|
+
「标注」给这段文字挂一条评论,正文上会留一个 **①②③ 编号徽标**,输入框里多出一个「N 条注释」的胶囊 —— 点开能逐条看、改评论、删掉,或者「放进输入框」。
|
|
179
|
+
|
|
180
|
+
发送时会自动拼成这样的块(也可以手动「放进输入框」,那就只发你自己写的话):
|
|
144
181
|
|
|
145
182
|
```
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
│ · 会话 │ · steer / 排队消息 │ · 终端 │
|
|
151
|
-
│ · 归档 │ · 子代理运行卡片条 │ · 状态栏 │
|
|
152
|
-
│ · 文件区 │ · 输入框(附件 / slash) │ │
|
|
153
|
-
└────────────┴──────────────────────────────┴──────────────────────┘
|
|
183
|
+
标注 1:
|
|
184
|
+
> 面板从 y=0 开始,但顶栏的 z-index 是 45
|
|
185
|
+
|
|
186
|
+
这里要再压缩一句
|
|
154
187
|
```
|
|
155
188
|
|
|
156
|
-
|
|
189
|
+
注释是**本地锚点**:按「原文 + 前后文」定位,所以正文重排、流式追加之后徽标仍能挂回原处;它存在当前浏览器的 `localStorage`(按会话隔离),不进服务端、不上云,换个设备看不到。
|
|
157
190
|
|
|
158
|
-
|
|
191
|
+
**文件的行引用**是另一条路:在预览里选中行(`Shift+点` 连选、`Ctrl/Cmd+点` 加选、右键出行菜单),「追加到对话」写进草稿的是 `@web/src/App.tsx:120-138` 这样的**路径 + 行号**,让 agent 自己去读。
|
|
159
192
|
|
|
160
193
|
---
|
|
161
194
|
|
|
162
|
-
##
|
|
195
|
+
## 临时对话:问一句就走
|
|
196
|
+
|
|
197
|
+

|
|
198
|
+
|
|
199
|
+
顶栏那颗「临时会话」(或右栏工作区落地页的第一张卡)会在**右栏**另开一条聊天:
|
|
200
|
+
|
|
201
|
+
- **不落盘**:会话只存在内存里,关掉标签就销毁,不进侧栏、不留文件;
|
|
202
|
+
- 主对话照旧跑,两边互不打断;
|
|
203
|
+
- 想留下就点 `保存为正式对话`,此时才写出会话文件(临时会话没有的历史也能保住);
|
|
204
|
+
- 可以同时开多条,每条一个独立通道、独立标签。
|
|
205
|
+
|
|
206
|
+
> 该能力依赖引擎的「内存会话」:pi 支持;Codex 的 thread 本身就在它自己的库里,所以没有「保存」按钮。它不是「换皮的新会话」,也不等于子代理 —— **临时对话是人开的窗口,子代理是 agent 派出去的子任务**。
|
|
207
|
+
|
|
208
|
+
---
|
|
209
|
+
|
|
210
|
+
## 文件、改动、git、搜索
|
|
211
|
+
|
|
212
|
+
文件区在侧栏底部,也能在右栏当标签用。**网页端是只读的**:看、比、引用、搜,都能做;原地改文件并保存不在这一层 —— 改文件交给 agent 的工具或终端,这里用 diff 复核。
|
|
213
|
+
|
|
214
|
+
| 能力 | 说明 |
|
|
215
|
+
|---|---|
|
|
216
|
+
| 目录树 | 可换根(跟随会话 / 指定项目)、懒加载、单目录最多 500 项、默认不列 `node_modules`/`.git`/`dist`,可「显示隐藏文件」看 `.env` 之类 |
|
|
217
|
+
| 按文件名搜 | 只匹配名字,不读内容,防抖 250ms,最多 200 条 |
|
|
218
|
+
| 预览 | markdown(表格 / 代码高亮 / mermaid)、源码带行号、图片、PDF、音视频流;多标签、拖拽换序、右键关闭左/右/全部、可铺开占满 |
|
|
219
|
+
| 行引用 | 选中行 → 「追加到对话」写 `@path:行号`;拖选文字还能「复制选中的文字」 |
|
|
220
|
+
| 在 Finder 中显示 | macOS `open -R`、Windows `explorer.exe /select,`、Linux 打开父目录 |
|
|
221
|
+
| 未提交改动 | 文件树上的状态点、文件后面的 `M` / `U` / `D` |
|
|
163
222
|
|
|
164
|
-
|
|
165
|
-
| --- | --- |
|
|
166
|
-
| **pi**(默认) | 完整的插件 / 技能生态、工具延迟加载、审批门禁、目标模式与子代理;模型与 provider 由本工作台管理 |
|
|
167
|
-
| **Codex** | codex 官方 agent(app-server JSON-RPC),独立 loop 与沙箱,会话与 Codex Desktop / CLI 共用;审批是命令 / 文件级的 |
|
|
168
|
-
| **DeepSeek Harness** | DeepSeek 官方 agent(ACP),模型与思考档可切,权限逐次确认 |
|
|
169
|
-
| **opencode** | opencode 官方 agent(ACP),自带工具 / MCP / 插件生态;会话与 opencode CLI / TUI 共用。**审批取决于 opencode 自身的 `permission` 配置**(配成全局 allow 时不会询问) |
|
|
170
|
-
| **fake** | 零 token 的脚本化引擎,只用来验证协议 / 工具 / 审批流程(`AGENT_WEB_ENGINE=fake`,默认不进切换面板) |
|
|
223
|
+
### 改动(diff)
|
|
171
224
|
|
|
172
|
-
|
|
225
|
+

|
|
173
226
|
|
|
174
|
-
|
|
175
|
-
| --- | :-: | :-: | :-: | :-: |
|
|
176
|
-
| 审批 | ✅ | ✅ | ✅ | 看配置 |
|
|
177
|
-
| 模型 / 思考档 | ✅ | ✅ | ✅ | ✅ |
|
|
178
|
-
| 恢复历史会话 | ✅ | ✅ | ✅ | ✅ |
|
|
179
|
-
| 插队(steer) | ✅ | — | — | — |
|
|
180
|
-
| 子代理面板 | ✅ | — | — | — |
|
|
181
|
-
| 本工作台管 provider | ✅ | — | — | — |
|
|
227
|
+
预览页顶部切「改动」就是与 `HEAD` 的对比:`+285 −78` 概览、行级红绿高亮、可「只看改动」也可回到全文。从回答里的「改动文件」chip 点进来会直接落在 diff。
|
|
182
228
|
|
|
183
|
-
|
|
229
|
+
### git
|
|
184
230
|
|
|
185
|
-
|
|
231
|
+
文件区顶部有分支标签,点开切本地分支(工作区脏会先要确认)。它只调 `git` 命令做读与切分支,不做提交 —— 提交还是交给 agent 或你自己在终端里做。
|
|
186
232
|
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
| `AGENT_WEB_DSH_BIN` / `_HOME` / `_MODEL` / `_PATCH` | DSH 可执行文件、数据目录、模型、补丁开关 |
|
|
191
|
-
| `AGENT_WEB_CODEX_BIN` / `_HOME` | codex 可执行文件与数据目录 |
|
|
233
|
+
### 内容搜索
|
|
234
|
+
|
|
235
|
+
工具栏的「搜文件内容」是全文检索:可以加**路径掩码**(如 `web/src/**`)收窄范围,结果显示 `文件:行号` + 原文片段,点一下跳到那行;命中太多时按上限截断并明说。
|
|
192
236
|
|
|
193
237
|
---
|
|
194
238
|
|
|
195
|
-
##
|
|
239
|
+
## 终端
|
|
196
240
|
|
|
197
|
-
|
|
241
|
+

|
|
198
242
|
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
| Codex 会话 | Codex 自己的 thread 存储(走 `thread/list \| resume \| delete`) |
|
|
203
|
-
| opencode / DSH 会话 | 各自的数据目录(opencode 按 cwd `session/list`;DSH 读 `~/.dsh` 的 workspace 投影) |
|
|
204
|
-
| 会话标题 | pi 取首条 user 消息(只读头 60 行);改名 = 往 jsonl 末尾追加 `session_info.name` |
|
|
205
|
-
| 工作台状态 | `<dataDir>/settings.json`、`approval-rules.json`、`server.lock`、`logs/`、`uploads/`、`push-subscriptions.json`、`vapid-keys.json` |
|
|
243
|
+
右栏的终端是**真 PTY**(`node-pty` + xterm.js):vim / top / Ctrl-C / 颜色 / 行编辑都正常,cwd 与会话所在项目一致,可带一条初始命令(升级流程就用它)。
|
|
244
|
+
|
|
245
|
+
刷新页面不会恢复终端会话(PTY 随页面卸载退出),切标签则不会断。Linux 上 `node-pty` 需要就地编译,缺工具时界面会直接说装什么。
|
|
206
246
|
|
|
207
|
-
|
|
247
|
+
### 内置网页
|
|
248
|
+
|
|
249
|
+
右栏还能开网页:输入网址在 iframe 里看,请求走**本机代理**(`/web/p/<url>`)—— 把文档取回来、去掉 `X-Frame-Options` / CSP 的嵌入限制,所以百度这类站点也能开。代理有边界:只代理 HTML/CSS 文档、**不带 cookie 过去也不带回**、上游 12MB 上限、iframe 沙箱不含 `allow-same-origin`。需要登录或重 JS 的站点点 `⧉` 跳系统浏览器。
|
|
250
|
+
|
|
251
|
+
---
|
|
252
|
+
|
|
253
|
+
## 多引擎:各跑各的原生 loop
|
|
254
|
+
|
|
255
|
+
引擎不是「同一个 prompt 换个皮」,每个都是官方 agent 自己的循环:
|
|
256
|
+
|
|
257
|
+
| 引擎 | 接入方式 | 说明 |
|
|
258
|
+
|---|---|---|
|
|
259
|
+
| **pi**(默认) | 原生 SDK | 完整插件 / 技能生态、工具延迟加载、审批门禁、子代理、插队;模型与 provider 由本工作台管理 |
|
|
260
|
+
| **Codex** | app-server(JSON-RPC) | 独立 loop 与沙箱,会话与 Codex Desktop / CLI 共用;审批是命令 / 文件级的 |
|
|
261
|
+
| **DeepSeek Harness** | ACP | 模型与思考档可切,权限逐次确认 |
|
|
262
|
+
| **opencode** | ACP | 自带工具 / MCP / 插件生态,会话与 opencode CLI / TUI 共用;审批取决于 opencode 自己的 `permission` 配置 |
|
|
263
|
+
| **Claude Code** | ACP(`claude-code-acp` 适配器) | 模型可切、工具逐次确认,会话与 `claude` CLI 共用;这套 ACP 面不暴露思考档与子代理 |
|
|
264
|
+
| **fake** | 内置脚本化引擎 | 零 token,只用来验证协议 / 工具 / 审批流程(默认不出现在切换面板) |
|
|
265
|
+
|
|
266
|
+
能力差异(`server/engine/registry.ts` 的能力矩阵,界面据此隐藏按钮):
|
|
267
|
+
|
|
268
|
+
| 能力 | pi | codex | dsh | opencode | claude |
|
|
269
|
+
|---|:-:|:-:|:-:|:-:|:-:|
|
|
270
|
+
| 审批 | ✅ | ✅ | ✅ | 看配置 | ✅ |
|
|
271
|
+
| 模型 / 思考档 | ✅ | ✅ | ✅ | ✅ | 模型可切 / 无档位 |
|
|
272
|
+
| 恢复历史会话 | ✅ | ✅ | ✅ | ✅ | ✅ |
|
|
273
|
+
| 插队(steer) | ✅ | — | — | — | — |
|
|
274
|
+
| 子代理面板 | ✅ | — | — | — | — |
|
|
275
|
+
| 本工作台管 provider | ✅ | — | — | — | — |
|
|
276
|
+
| 临时会话(内存) | ✅ | — | — | — | — |
|
|
277
|
+
|
|
278
|
+
**模型 / 插件 / MCP 三块跟着当前引擎走**:切到 Codex,面板读的就是 Codex 自己的东西(`model/list`、`plugin/list`、`config/read`);claude 读 `~/.claude.json` 与 `~/.claude/settings.json`;opencode 读 `opencode.json`。没接的面板会直说,不拿 pi 的配置冒充。
|
|
279
|
+
|
|
280
|
+
引擎在**底部状态栏**切换(不是顶栏),每个会话各自记住自己的引擎、模型与思考档。
|
|
208
281
|
|
|
209
282
|
---
|
|
210
283
|
|
|
211
284
|
## 模型与供应商
|
|
212
285
|
|
|
213
|
-
|
|
286
|
+

|
|
287
|
+
|
|
288
|
+
- **订阅服务**:OAuth 登录(9 家),登录后直接能用,不用手抄 key。
|
|
289
|
+
- **官方内置**:pi 目录里带模型的那批,**填一把 key 就能用**,端点与模型表由目录提供。
|
|
290
|
+
- **自己输入**:可改 API 形态(openai-completions / responses / anthropic-messages / codex / typesafe)、base url、自定义 headers,逐个加模型。
|
|
291
|
+
- 逐个勾选模型(只保存勾上的)、批量试连、从 `/models` 拉清单、按勾选保存白名单。
|
|
214
292
|
|
|
215
|
-
|
|
216
|
-
- 自定义可以逐个加模型、改 base url、从别的客户端**导入**(实际是拉 `GET {baseUrl}/models` 勾选写回)、逐个**试连**。
|
|
217
|
-
- **key 不出服务端**:接口只返回 `hasKey` 与尾 4 位;写操作在进程内串行化,避免并发写坏文件。
|
|
293
|
+
**key 不出服务端**:接口只返回 `hasKey` 与尾 4 位;写操作在进程内串行化,避免并发写坏文件。
|
|
218
294
|
|
|
219
|
-
|
|
220
|
-
`models-store.json`(历史位置)、`auth.json`(`api_key` 或 oauth 订阅凭据),白名单在 `settings.json.enabledModels`。
|
|
295
|
+
配置真相分散在 `~/.pi/agent/models.json`(provider 目录)、`models-store.json`(历史位置)、`auth.json`(`api_key` 或 OAuth 凭据),白名单在 `settings.json.enabledModels`。
|
|
221
296
|
|
|
222
297
|
---
|
|
223
298
|
|
|
224
|
-
##
|
|
299
|
+
## 技能
|
|
225
300
|
|
|
226
|
-
|
|
227
|
-
- 身份判定:对端是回环 **且** Host 是回环 → 放行;未设密码时远程一律 403;设了密码则走 cookie(`agent-web-auth`,7 天 HttpOnly)或 HTTP Basic;登录失败按 20 次 / 10 分钟节流。
|
|
228
|
-
- 工具与命令走审批:**只读工具**(read / grep / find / ls)与只读命令自动放行,其余按 `scopeKey`(工具 + 可执行名或目标目录)询问;点「总是允许」就把规则写进 `approval-rules.json`(原子写,坏文件当空)。
|
|
229
|
-
- 会话回合结束时清掉该会话所有悬置审批,不会挂在那等下一个人点。
|
|
230
|
-
- 上传的临时文件、会话缓存都在数据目录里,不写进你的项目目录。
|
|
301
|
+

|
|
231
302
|
|
|
232
|
-
|
|
303
|
+
读 `~/.agents/skills/<目录>/SKILL.md`,列表只解析 frontmatter(不引 yaml 依赖)。**启停 = 把 `SKILL.md` 改名成 `.SKILL.md.disabled`**,没有第二份状态文件 —— 所以在 CLI 里看到的一致。
|
|
304
|
+
|
|
305
|
+
**Skill Hub**:分类搜索 + 一键安装(索引 20 万+),也能从 Git 仓库装指定 `skills/<name>`,或手动建一个。
|
|
233
306
|
|
|
234
307
|
---
|
|
235
308
|
|
|
236
|
-
##
|
|
309
|
+
## MCP
|
|
237
310
|
|
|
238
|
-
|
|
311
|
+

|
|
239
312
|
|
|
240
|
-
|
|
241
|
-
- **在哪看**:运行卡片在对话下方(输入区上方那条「子代理」卡片条):状态、耗时、工具次数、token 与花费,点开原地展开结果原文与会话文件路径,随时停掉某一个;切会话自动换成本会话的那批。顶栏徽标保留一眼概览。
|
|
242
|
-
- **怎么管**:面板里管的是**模板**(内置 explore / general-purpose / plan,可停用;可新建 / 编辑 / 删除)。模板落 `~/.pi/agent/agents/*.md`,frontmatter 写 `name / display_name / description / tools / model / thinking / max_turns`,正文就是系统指令 —— 与 pi 的 agent 文件同一套格式,可读可改可进 git。
|
|
243
|
-
- **并发**:面板可设上限(1–12,默认 4),超出的排队;总开关关掉后模型不再看到 `Agent` 工具。
|
|
244
|
-
- **隔离**:子代理默认不加载技能 / 插件 / 主题 / 上下文文件(快、可预期);模型不跟随父会话时沿用父会话的模型。有的模型由扩展注册 provider,这类模型在子代理里会失败并提示「在模板里指定模型」。
|
|
313
|
+
读写两份配置:`~/.pi/agent/mcp.json`(全局)与 `<workspace>/.pi/mcp.json`(项目),**项目同名条目覆盖全局**,写回保留缩进与 CRLF。
|
|
245
314
|
|
|
246
|
-
|
|
315
|
+
- exposure 四档:**代码模式(默认)/ 搜索后声明 / 直接声明 / 不暴露**;
|
|
316
|
+
- **测试连接**:真握手 + `tools/list` 后即断,报连接状态与工具数;
|
|
317
|
+
- OAuth 登录、市场挑服务器、粘贴命令 / URL / JSON 自动解析;
|
|
318
|
+
- **配置即真相**:pi 会话启动时自己连,改完对**新会话**生效。
|
|
247
319
|
|
|
248
320
|
---
|
|
249
321
|
|
|
250
|
-
##
|
|
322
|
+
## 插件
|
|
251
323
|
|
|
252
|
-
|
|
253
|
-
exposure 四档 `codemode | deferred | direct | hidden`,工具命名空间 `mcp__<name>`。
|
|
254
|
-
**配置即真相** —— pi 会话启动时自行连接,面板改完对**新会话**生效。测试连接走 `@earendil-works/pi-mcp` 真实握手 + `tools/list` 后即断;
|
|
255
|
-
OAuth 走 `pi mcp login`。另有市场入口(registry / smithery / github)与「粘贴命令 / URL / JSON 自动解析」。
|
|
324
|
+

|
|
256
325
|
|
|
257
|
-
|
|
258
|
-
状态由 pi SDK 的 `resolve()` 决定(查询**不**触发 npm install),四态 `loaded / installed / missing / disabled`;停用写 `autoload:false`,不删文件。
|
|
326
|
+
插件就是 pi package:`settings.json` 里的 `packages`(npm / git / 本地目录)+ 散装 `~/.pi/agent/extensions/`、`<ws>/.pi/extensions/`。
|
|
259
327
|
|
|
260
|
-
|
|
261
|
-
**启停 = 把 `SKILL.md` 改名成 `.SKILL.md.disabled`**,没有第二份状态文件。Skill Hub 支持分类搜索 + zip 安装,也支持 git clone 指定 `skills/<name>`。
|
|
328
|
+
状态由 pi SDK 的 `resolve()` 决定(**查询不会触发 npm install**),四态 `loaded / installed / missing / disabled`;按包停用写 `autoload:false`,不删文件。
|
|
262
329
|
|
|
263
330
|
---
|
|
264
331
|
|
|
265
|
-
##
|
|
332
|
+
## 子代理:并行开,逐个管
|
|
333
|
+
|
|
334
|
+

|
|
335
|
+
|
|
336
|
+
主 agent 拿到 `Agent` 工具后,可以一次并行开好几个子代理,每个都是**一个真实的会话**(自己的上下文、会话文件、工具白名单)。
|
|
337
|
+
|
|
338
|
+
- **看**:输入框上方那条「子代理」卡片条 —— 状态、耗时、工具次数、token、花费,点「查看结果」原地展开结果原文与会话文件路径,可以单独停掉某一个;标题里给一眼概览(`2 个在跑` / `8 个已结束`)。
|
|
339
|
+
- **管**:顶栏「子代理」面板管的是**模板**(内置 explore / general-purpose / plan,可停用;也能新建、编辑、删除):`name / display_name / description / tools / model / thinking / max_turns`,落 `~/.pi/agent/agents/*.md`,与 pi 的 agent 文件同一套格式,可读可改可进 git。
|
|
340
|
+
- **并发**:1–12(默认 4),超出的排队;关掉总开关后模型不再看到 `Agent` 工具。
|
|
341
|
+
- **隔离**:子代理默认不加载技能 / 插件 / 主题 / 上下文文件(快、可预期);模型不跟随父会话时沿用父会话的模型。
|
|
342
|
+
|
|
343
|
+
子代理的会话文件紧挨着父会话归档(`<父会话目录>/<父会话名>/subagents/`),不进侧栏项目清单。
|
|
344
|
+
|
|
345
|
+
---
|
|
346
|
+
|
|
347
|
+
## 推送与语音
|
|
348
|
+
|
|
349
|
+
<table><tr>
|
|
350
|
+
<td width="50%"><img src="docs/screenshots/11-push.png" alt="推送:本机推送状态、目标设备、测试推送"></td>
|
|
351
|
+
<td width="50%"><img src="docs/screenshots/10-voice.png" alt="语音:四类事件提示音 + 本地 TTS"></td>
|
|
352
|
+
</tr></table>
|
|
353
|
+
|
|
354
|
+
**推送**:Web Push(VAPID)订阅,回合结束推一条 —— 标题=项目名、正文=会话名,失败 ❌ / 中断 ⏹ 带前缀;多设备管理、测试推送、一键清空。需要 https 或 localhost。
|
|
355
|
+
|
|
356
|
+
**语音**:四类事件提示音(开始 / 结束 / 出错 / 等待审批)可试听、音量可调;本地 TTS 用浏览器内置语音播报最终回复,可调语速与音色,不联网。
|
|
357
|
+
|
|
358
|
+
---
|
|
359
|
+
|
|
360
|
+
## 设置
|
|
361
|
+
|
|
362
|
+

|
|
363
|
+
|
|
364
|
+
顶栏那一排就是全部面板入口,**可以在「设置 → 界面」里逐项隐藏**(设置与分栏两颗不参与隐藏 —— 它们是恢复其它入口的唯一入口);侧栏、右栏也都能拖宽、收起,宽度记在本机 `localStorage`。
|
|
365
|
+
|
|
366
|
+
顶栏「设置」分五页:
|
|
367
|
+
|
|
368
|
+
| 页 | 内容 |
|
|
369
|
+
|---|---|
|
|
370
|
+
| **界面** | 外框:顶栏显示哪些入口(文案 / 图标分开勾)、状态栏里显示哪些块(排队 / 工作中 / 上下文用量)、侧栏、对话里图片的最大宽度 |
|
|
371
|
+
| **对话** | 对话区自己长什么样:输入框上方显示哪些块(模板 / 想想 / 快捷指令)、快捷短语的内容、想想(思考档)的默认值(这两项走服务端保存、多设备一致)、对话里是否显示花费、思考块与工具卡默认是否展开 |
|
|
372
|
+
| **外观** | 只管尺寸:三处字号(聊天正文 / 侧栏项目名 / 侧栏会话名,滑杆 2–20px)、内容宽度 4 档(720 / 900 / 1100 / 满宽)、顶栏高度、顶栏名称与 logo(可隐藏、可改成自己的名字) |
|
|
373
|
+
| **主题** | 6 套色板(清亮白、暖纸、雾青、东京夜、摩卡、北境),点一下立刻生效 |
|
|
374
|
+
| **语言** | 中文 / English,点了立刻生效 |
|
|
375
|
+
| **快捷键** | 11 个动作可改键、可清空、可恢复默认,另有速查表 |
|
|
376
|
+
|
|
377
|
+
外观、主题、界面、语言这些偏好只存本机(`localStorage`,`agent-web.` 前缀),手机、平板、桌面各一份;「通用」里的快捷短语才多设备一致。
|
|
378
|
+
|
|
379
|
+
---
|
|
380
|
+
|
|
381
|
+
## 手机
|
|
382
|
+
|
|
383
|
+
<table><tr>
|
|
384
|
+
<td width="34%"><img src="docs/screenshots/16-mobile.png" alt="手机单栏:顶栏入口只留图标、输入框 18px"></td>
|
|
385
|
+
<td width="34%"><img src="docs/screenshots/17-mobile-drawer.png" alt="手机上的项目侧栏是覆盖式抽屉"></td>
|
|
386
|
+
</tr></table>
|
|
387
|
+
|
|
388
|
+
窄屏(手机 UA 或 ≤400px)自动切成单栏:
|
|
389
|
+
|
|
390
|
+
- 侧栏变覆盖式抽屉(宽度 `clamp(260px, 76vw, 340px)`,点遮罩关闭,点会话后自动收起);
|
|
391
|
+
- 顶栏允许换行、入口只留图标、可横向滑动;
|
|
392
|
+
- 右栏工作区变成整屏第二页,用 `100dvh` 从顶栏下方开始(避开 iOS 工具栏);
|
|
393
|
+
- 输入框字号 18px,免得 iOS 聚焦时自动放大;模型菜单变底部抽屉;
|
|
394
|
+
- 状态栏横向可滚,上下文用量浮层变整宽弹层。
|
|
395
|
+
|
|
396
|
+
---
|
|
397
|
+
|
|
398
|
+
## 会话:置顶、归档、分叉、换项目
|
|
399
|
+
|
|
400
|
+
侧栏按目录把会话分组「项目」:
|
|
401
|
+
|
|
402
|
+
| 动作 | 行为 |
|
|
403
|
+
|---|---|
|
|
404
|
+
| 置顶 | 会话或项目提到最上面 |
|
|
405
|
+
| 重命名 | pi 会话 = 往 jsonl 末尾追加 `session_info.name` |
|
|
406
|
+
| 归档 | 收进「已归档」,可撤销 |
|
|
407
|
+
| 删除 | 改名成 `.deleted-<时间戳>`(引擎有原生删除接口时优先用它),**文件还在磁盘上** |
|
|
408
|
+
| 分叉 | 从某条消息派生新会话(标题 `分支 · …`),原会话一字不动 |
|
|
409
|
+
| 换项目 | 把会话行拖到另一个项目上,会话 id 与历史不变,只改文件头部的 `cwd` 并搬目录 |
|
|
410
|
+
|
|
411
|
+
排序上有一个刻意的选择:**组内按创建时间倒序** —— 新会话在最上面,而更新一个旧会话不会让它跳位置(按最后活动排的话,在一个老会话里说一句话它就窜到顶,整个列表跟着挪)。
|
|
412
|
+
|
|
413
|
+
---
|
|
414
|
+
|
|
415
|
+
## 快捷键与斜杠指令
|
|
416
|
+
|
|
417
|
+
**快捷键**都可以在「设置 → 快捷键」里改(必须带 `Mod`/`Alt`,不收裸字母)。macOS 上 `Mod` = ⌘,其它平台 = Ctrl。
|
|
418
|
+
|
|
419
|
+
| 动作 | 默认键 | 动作 | 默认键 |
|
|
420
|
+
|---|---|---|---|
|
|
421
|
+
| 新会话 | `Mod+K` | 打开右侧边栏 | `Mod+Alt+O` |
|
|
422
|
+
| 新项目 | `Mod+M` | 收起右侧边栏 | `Mod+Alt+W` |
|
|
423
|
+
| 临时会话 | `Mod+Shift+K` | 收起 / 展开左侧栏 | `Mod+Alt+L` |
|
|
424
|
+
| 设置 | `Mod+Alt+S` | 文件管理 | `Mod+Alt+F` |
|
|
425
|
+
| 新建终端 | `Mod+Alt+T` | 搜索文件内容 | `Mod+Shift+F` |
|
|
426
|
+
| 快捷键速查表 | `Mod+/` | | |
|
|
266
427
|
|
|
267
|
-
|
|
428
|
+
**斜杠指令**在输入框里打 `/` 弹出,分两类 —— `本地` 由工作台自己执行,`发给 Agent` 原样作为消息交给引擎:
|
|
429
|
+
|
|
430
|
+
| 指令 | 类型 | 作用 |
|
|
431
|
+
|---|---|---|
|
|
432
|
+
| `/new [首条消息]` | 本地 | 新建对话,可带上第一条消息 |
|
|
433
|
+
| `/name <名称>` | 本地 | 重命名当前会话 |
|
|
434
|
+
| `/model <名称>` | 本地 | 切模型(按 id 或显示名模糊匹配) |
|
|
435
|
+
| `/thinking <档位>` | 本地 | 设思考强度(off / low / … / max) |
|
|
436
|
+
| `/copy` | 本地 | 复制最后一条助手消息 |
|
|
437
|
+
| `/session` | 本地 | 会话消息数 / token / 费用统计 |
|
|
438
|
+
| `/resume` | 本地 | 刷新会话列表(别的终端刚开的会话) |
|
|
439
|
+
| `/skill <技能名>` | 发给 Agent | 用某个技能(面板会列出已装的) |
|
|
440
|
+
| `/compact [说明]` | 发给 Agent | 压缩上下文 |
|
|
441
|
+
| `/plan [on\|off]` | 发给 Agent | 开关计划模式 |
|
|
442
|
+
| `/cwd <路径>` | 发给 Agent | 切换工作目录 |
|
|
443
|
+
|
|
444
|
+
---
|
|
445
|
+
|
|
446
|
+
## 架构:SSE + RPC,没有 WebSocket
|
|
268
447
|
|
|
269
448
|
```
|
|
270
|
-
浏览器 ──GET /api/events(SSE)──▶ 服务端
|
|
271
|
-
──POST /api/rpc (JSON)──▶
|
|
449
|
+
浏览器 ──GET /api/events(SSE)──▶ 服务端 首帧快照 · 其后只推增量
|
|
450
|
+
──POST /api/rpc (JSON)──▶ ClientRequest → { reply } 就地消费
|
|
272
451
|
```
|
|
273
452
|
|
|
274
|
-
- **下行**:首帧一份完整快照,其后只推增量。正文走 `message_delta` 逐块追加;工具卡、错误、状态这类结构性变化推快照(60ms 窗口合并,快照可丢、事件不可丢)。SSE 25s
|
|
275
|
-
- **上行**:`send_message
|
|
276
|
-
- **协议单源**在 `server/protocol.ts
|
|
277
|
-
-
|
|
453
|
+
- **下行**:首帧一份完整快照,其后只推增量。正文走 `message_delta` 逐块追加;工具卡、错误、状态这类结构性变化推快照(60ms 窗口合并,快照可丢、事件不可丢)。SSE 25s 心跳。
|
|
454
|
+
- **上行**:`send_message`、`interrupt`、`approve`、`new_chat`(可带 `ephemeral`)、`switch_conversation`、`set_engine` / `set_model` / `set_thinking_level` / `set_approval_mode`、`persist_conversation`、`close_ephemeral`、`fork_session`、`move_session`、`cancel_queued`、`rename_session` 等。
|
|
455
|
+
- **协议单源**在 `server/protocol.ts`,前端复用类型,两端共用一份定义。
|
|
456
|
+
- **快照是唯一事实源**:`store.ts` 用 `useSyncExternalStore`,快照一到整体替换;本地只留 `preview` / `draft` / `pendingActive` 这类乐观态。
|
|
457
|
+
- **每个客户端各看各的会话**(ADR-0033):同一个服务端,两台设备可以停在不同会话上;会话清单这类大块数据只在该客户端需要时下发。
|
|
458
|
+
|
|
459
|
+
进程模型:`cli.ts` 解析参数 → `session/lock.ts` 抢 `<dataDir>/server.lock`(pid 活则拒绝启动、pid 死则接管陈旧锁)→ `runtime.init()` → `listen`。`SIGINT` / `SIGTERM` / `/api/shutdown` 走同一个优雅退出(flush、断开引擎、释放锁)。
|
|
460
|
+
|
|
461
|
+
---
|
|
462
|
+
|
|
463
|
+
## 数据落在哪
|
|
464
|
+
|
|
465
|
+
| 内容 | 位置 |
|
|
466
|
+
|---|---|
|
|
467
|
+
| pi 会话 | `~/.pi/agent/sessions/<编码后的 cwd>/<ISO>_<uuid>.jsonl`(首行 `{type:"session",id,timestamp,cwd}`) |
|
|
468
|
+
| Codex 会话 | Codex 自己的 thread 存储(`thread/list \| resume \| delete`) |
|
|
469
|
+
| opencode / DSH / claude 会话 | 各自的数据目录(opencode 按 cwd `session/list`;DSH 读 `~/.dsh`;claude 读 `~/.claude`) |
|
|
470
|
+
| 会话标题 | pi 取首条 user 消息(只读头 60 行);改名 = 追加 `session_info.name` |
|
|
471
|
+
| 工作台状态 | `<dataDir>/settings.json`、`approval-rules.json`、`server.lock`、`logs/`、`uploads/`、`push-subscriptions.json`、`vapid-keys.json` |
|
|
472
|
+
| 技能 / 子代理模板 / MCP | `~/.agents/skills/`、`~/.pi/agent/agents/`、`~/.pi/agent/mcp.json` |
|
|
473
|
+
| 本机界面偏好 | 浏览器 `localStorage`(`agent-web.` 前缀:主题、字号、宽度、快捷键、注释、标签页) |
|
|
474
|
+
|
|
475
|
+
---
|
|
476
|
+
|
|
477
|
+
## 安全模型
|
|
478
|
+
|
|
479
|
+
- 默认只听 `127.0.0.1`,并校验 `Origin` / `Host`(含 `AGENT_WEB_ALLOWED_HOSTS` 白名单、vite 端口、局域网地址)。
|
|
480
|
+
- 身份判定:对端是回环**且** Host 是回环 → 放行;未设密码时远程一律 403;设了密码则走 cookie(`agent-web-auth`,7 天 HttpOnly)或 HTTP Basic;登录失败按 20 次 / 10 分钟节流。
|
|
481
|
+
- 工具与命令走审批:**只读工具**(read / grep / find / ls)与只读命令自动放行,其余按 `scopeKey`(工具 + 可执行名或目标目录)询问;点「总是允许」把规则写进 `approval-rules.json`(原子写,坏文件当空)。
|
|
482
|
+
- 回合结束时清掉该会话所有悬置审批,不会挂在那等下一个人点。
|
|
483
|
+
- 上传的临时文件、会话缓存都在数据目录里,不写进你的项目。
|
|
484
|
+
- 内置网页的代理不带 cookie、iframe 沙箱不含 `allow-same-origin`(否则远端 JS 能摸到 localStorage 与 RPC)。
|
|
278
485
|
|
|
279
|
-
|
|
486
|
+
> 远程暴露是显式操作:必须同时给 `-H`、`-P`、`--allow-host`,缺一个都不通。
|
|
280
487
|
|
|
281
488
|
---
|
|
282
489
|
|
|
283
490
|
## 开发
|
|
284
491
|
|
|
492
|
+
在仓库根目录先 `npm install`,然后:
|
|
493
|
+
|
|
285
494
|
```bash
|
|
286
495
|
npm run dev # 一条命令起两个进程
|
|
287
496
|
```
|
|
@@ -291,8 +500,7 @@ npm run dev # 一条命令起两个进程
|
|
|
291
500
|
- 手机调试:`npm run dev -- --host 0.0.0.0`。
|
|
292
501
|
|
|
293
502
|
| 命令 | 作用 |
|
|
294
|
-
|
|
295
|
-
| `npm test` | `node --test` 跑 `tests/unit/*.test.ts`(22 个文件,零额外依赖) |
|
|
503
|
+
|---|---|
|
|
296
504
|
| `npm run typecheck` | 服务端 + 前端两套 `tsc --noEmit` |
|
|
297
505
|
| `npm run lint` | oxlint(`server` / `web/src` / `scripts`) |
|
|
298
506
|
| `npm run format` | prettier 全仓格式化(`format:check` 只检查;`*.md` 故意跳过) |
|
|
@@ -301,88 +509,20 @@ npm run dev # 一条命令起两个进程
|
|
|
301
509
|
|
|
302
510
|
CI(`.github/workflows/ci.yml`):`npm ci` → typecheck → lint → test → build,跑在 ubuntu + Node 22。
|
|
303
511
|
|
|
304
|
-
### 目录结构
|
|
305
|
-
|
|
306
|
-
```
|
|
307
|
-
oh-my-agent-web/
|
|
308
|
-
├─ server/ 后端(Express 5,TypeScript ESM)
|
|
309
|
-
│ ├─ cli.ts 命令入口:start / stop / restart / status / version / upgrade
|
|
310
|
-
│ ├─ index.ts 进程装配:中间件、路由、静态产物、优雅退出
|
|
311
|
-
│ ├─ protocol.ts 协议单源(前端复用类型)
|
|
312
|
-
│ ├─ engine/ 引擎适配层:pi(原生 SDK)/ codex / dsh / opencode(ACP)/ fake
|
|
313
|
-
│ │ + 能力矩阵 registry、catalog、wiring、pi-plugins
|
|
314
|
-
│ ├─ session/ 运行时:runtime、turn-*、审批桥、改名删除、锁、settings
|
|
315
|
-
│ ├─ sessions/ 会话删除的 HTTP 路由(扫描逻辑在 session/pi-sessions.ts)
|
|
316
|
-
│ ├─ snapshot/ 服务端状态快照:state、buildSnapshot、fan-out、60ms 合并
|
|
317
|
-
│ ├─ http/ auth、live-routes(SSE + RPC)、aux-routes、压缩、文件响应头
|
|
318
|
-
│ ├─ files/ 文件树、预览、搜索、媒体流、git 分支
|
|
319
|
-
│ ├─ terminal/ PTY 会话与 SSE 流
|
|
320
|
-
│ ├─ approval/ 审批作用域与规则
|
|
321
|
-
│ ├─ providers/ 供应商 / 模型清单 / 试连 / 导入 / 订阅 OAuth
|
|
322
|
-
│ ├─ mcp/ mcp.json 读写、连通性探测、OAuth、市场
|
|
323
|
-
│ ├─ skills/ 技能发现、启停、Hub 安装
|
|
324
|
-
│ ├─ subagents/ 子代理模板存储(`~/.pi/agent/agents/*.md`)
|
|
325
|
-
│ ├─ plugins/ 插件包 HTTP 路由
|
|
326
|
-
│ ├─ push/ Web Push(VAPID)
|
|
327
|
-
│ ├─ markers/ `[[action:suggest:…]]` 标记的解析与流式过滤
|
|
328
|
-
│ └─ util/ env、paths、spawn-cli(跨平台)、origin 等
|
|
329
|
-
├─ web/ 前端(React 19 + Vite + TypeScript)
|
|
330
|
-
│ ├─ src/components/ ~70 个组件:侧栏、消息流、输入框、文件树、终端、各类面板
|
|
331
|
-
│ ├─ src/styles/ ~45 个分区 CSS + 6 套主题变量(无 CSS 框架)
|
|
332
|
-
│ ├─ src/ws.ts SSE + RPC 客户端(名字是历史遗留)
|
|
333
|
-
│ └─ src/store.ts 快照 store(useSyncExternalStore)
|
|
334
|
-
├─ scripts/ dev 双进程、安装脚本、prebuild 裁剪、图标生成
|
|
335
|
-
├─ tests/unit/ node:test 单测
|
|
336
|
-
├─ docs/adr/README.md ADR 索引
|
|
337
|
-
└─ docs/screenshots/ README 用的真实截图(PNG 256 色,~1.4MB)
|
|
338
|
-
```
|
|
339
|
-
|
|
340
|
-
### 代码约定
|
|
341
|
-
|
|
342
|
-
- prettier:**Tab 缩进**、`printWidth 120`;oxlint 用默认规则集。
|
|
343
|
-
- 单文件 400 行是护栏,超了就拆(`cli-info.ts`、`snapshot/*` 都是这么来的)。
|
|
344
|
-
- **ADR 正文写在它约束的那段代码的文件头注释里**,不在 `docs/` 单独立文 —— 改代码的人一定会读到;`docs/adr/README.md` 只是按编号索引到文件的表。改代码时顺手更新那张表。
|
|
345
|
-
|
|
346
|
-
---
|
|
347
|
-
|
|
348
|
-
## 安装体积:按场景选命令
|
|
349
|
-
|
|
350
|
-
依赖树里大头都在**前端构建期**(`mermaid` 121MB、react 等)与**只给本机用的构建工具**,服务器真正运行时只需要
|
|
351
|
-
`express` / `web-push` / `node-pty` / `@earendil-works/pi-*` 这几样 —— 浏览器那一半已经打进 `web/dist` 了。
|
|
352
|
-
所以 `react` / `mermaid` / `xterm` / `highlight.js` 这类包全部放在 `devDependencies`:
|
|
353
|
-
|
|
354
|
-
| 场景 | 命令 | 包数 | 磁盘 |
|
|
355
|
-
|---|---|---|---|
|
|
356
|
-
| 开发 / 要自己构建 | `npm ci` | 456 | 547 MB |
|
|
357
|
-
| 已有构建产物,只想跑 | `npm ci --omit=dev` | 192 | **158 MB**(~3 秒) |
|
|
358
|
-
| 构建完顺手瘦身 | `npm ci && npm run build && npm prune --omit=dev` | 192 | **158 MB** |
|
|
359
|
-
| 分发给另一台机器 | `npm pack` → `npm i -g ./oh-my-agent-web-*.tgz` | 193 | 223 MB(tarball 3.1 MB,含截图) |
|
|
360
|
-
|
|
361
|
-
两个自动瘦身动作已经在 `postinstall` 里(`scripts/prune-prebuilds.mjs`):
|
|
362
|
-
|
|
363
|
-
- **只留当前平台的 `node-pty` 预编译产物**:它默认带四个平台的二进制,其中 Windows 那两份就占 58MB。macOS / Linux 上剪掉后 62MB → 5MB;`npm ci` 会原样装回来。
|
|
364
|
-
- 修 `spawn-helper` 的可执行位。
|
|
365
|
-
|
|
366
|
-
> 剩下的 158MB 里,基本全是 pi 的模型层:各家 provider 的官方 SDK(`openai` 17.6MB、`@google/genai` 10.8MB、`@anthropic-ai/sdk` 9.1MB、`@aws-sdk/*` + `@smithy/*` 5.2MB)——
|
|
367
|
-
> 这些都是 `@earendil-works/pi-ai` 的硬依赖,不做供应商裁剪就绕不开。
|
|
368
|
-
|
|
369
512
|
---
|
|
370
513
|
|
|
371
514
|
## 排错
|
|
372
515
|
|
|
373
|
-
> **为什么用 `npm ci` 而不是 `npm install
|
|
374
|
-
> `npm install` 会拿 `package.json` 里的版本范围去 registry 重新解析,一旦用的镜像源(公司 Nexus、npmmirror 等)还没同步到那些版本,就会报 `npm error notarget No matching version found for …`。
|
|
375
|
-
> `npm ci` 直接用锁文件里的精确版本,完全不走这一步。
|
|
376
|
-
|
|
377
|
-
按这个顺序排查:
|
|
516
|
+
> **为什么用 `npm ci` 而不是 `npm install`**:直接依赖普遍很新,`npm install` 会拿版本范围去 registry 重新解析,镜像源(公司 Nexus、npmmirror 等)没同步到那些版本就报 `npm error notarget`。`npm ci` 直接用锁文件里的精确版本。
|
|
378
517
|
|
|
379
|
-
1. `npm error notarget No matching version found` → 镜像没同步。先 `npm config get registry
|
|
380
|
-
2. `EBADENGINE` /
|
|
381
|
-
3. `node-pty` 编译失败(多见于 Linux)→
|
|
382
|
-
4. 起不来但 `
|
|
383
|
-
5. 端口被占 → `
|
|
518
|
+
1. `npm error notarget No matching version found` → 镜像没同步。先 `npm config get registry`,再临时用官方源:`npm -g install oh-my-agent-web --registry=https://registry.npmjs.org/`。
|
|
519
|
+
2. `EBADENGINE` / 启动即报 Node 版本 → 需要 Node ≥ 22.19(`node -v` 确认)。
|
|
520
|
+
3. `node-pty` 编译失败(多见于 Linux)→ 先装 `python3` / `make` / `g++` 再 `npm -g install`,或用一行脚本的 `--with-build-tools` 让脚本代劳。
|
|
521
|
+
4. 起不来但 `oh-my-agent-web status` 说「陈旧锁」→ 之前进程没退干净,下次 `start` 会自动接管;确实僵着就删 `<dataDir>/server.lock`。
|
|
522
|
+
5. 端口被占 → `oh-my-agent-web -p 25258`,或先 `oh-my-agent-web stop`。
|
|
523
|
+
6. 内置网页一片空白 → 该站点重登录 / 重脚本,代理不隧道 cookie;点 `⧉` 用系统浏览器。
|
|
384
524
|
|
|
385
|
-
Windows
|
|
525
|
+
Windows 上的 shell 解析、进程树回收、路径判断、权限与 CRLF 差异已全部收口在三个模块里:`server/util/spawn-cli.ts`(PATH/PATHEXT、`.cmd` 走 `cmd.exe`、`killTree`)、`server/util/paths.ts` 与 `web/src/path-utils.ts`(分隔符与绝对路径)、`server/util/file-mode.ts`(Windows 走 `icacls`)。改跨平台相关的代码先看这三个文件头。
|
|
386
526
|
|
|
387
527
|
---
|
|
388
528
|
|