@orion-agents/orion-code 0.3.1 → 0.3.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/CHANGELOG.md +43 -0
- package/README.md +39 -28
- package/README.zh-CN.md +32 -25
- package/dist/commands/model-command-handlers.d.ts.map +1 -1
- package/dist/commands/model-command-handlers.js +59 -14
- package/dist/commands/model-command-handlers.js.map +1 -1
- package/dist/commands/types.d.ts +6 -0
- package/dist/commands/types.d.ts.map +1 -1
- package/dist/commands/types.js.map +1 -1
- package/dist/commands/workflow-command-handlers.d.ts +1 -1
- package/dist/commands/workflow-command-handlers.d.ts.map +1 -1
- package/dist/commands/workflow-command-handlers.js +42 -3
- package/dist/commands/workflow-command-handlers.js.map +1 -1
- package/dist/commands/workflow-commands.d.ts.map +1 -1
- package/dist/commands/workflow-commands.js +2 -2
- package/dist/commands/workflow-commands.js.map +1 -1
- package/dist/runtime/agent-runtime-controller.d.ts +16 -2
- package/dist/runtime/agent-runtime-controller.d.ts.map +1 -1
- package/dist/runtime/agent-runtime-controller.js +115 -6
- package/dist/runtime/agent-runtime-controller.js.map +1 -1
- package/dist/runtime/agent-runtime-protocol.d.ts +3 -0
- package/dist/runtime/agent-runtime-protocol.d.ts.map +1 -1
- package/dist/runtime/agent-runtime-protocol.js.map +1 -1
- package/dist/runtime/agent-runtime-runner.d.ts +8 -0
- package/dist/runtime/agent-runtime-runner.d.ts.map +1 -1
- package/dist/runtime/orion-session-runner.d.ts +4 -0
- package/dist/runtime/orion-session-runner.d.ts.map +1 -1
- package/dist/runtime/orion-session-runner.js +15 -0
- package/dist/runtime/orion-session-runner.js.map +1 -1
- package/dist/runtime/plan-review.d.ts +38 -0
- package/dist/runtime/plan-review.d.ts.map +1 -0
- package/dist/runtime/plan-review.js +173 -0
- package/dist/runtime/plan-review.js.map +1 -0
- package/dist/runtime/product-bootstrap.d.ts.map +1 -1
- package/dist/runtime/product-bootstrap.js +28 -6
- package/dist/runtime/product-bootstrap.js.map +1 -1
- package/dist/runtime/product-orion-runtime.d.ts.map +1 -1
- package/dist/runtime/product-orion-runtime.js +14 -35
- package/dist/runtime/product-orion-runtime.js.map +1 -1
- package/dist/runtime/protocol/runtime-protocol-v1.d.ts +73 -0
- package/dist/runtime/protocol/runtime-protocol-v1.d.ts.map +1 -1
- package/dist/runtime/protocol/runtime-protocol-v1.js +37 -0
- package/dist/runtime/protocol/runtime-protocol-v1.js.map +1 -1
- package/dist/runtime/release-receipts.d.ts +5 -3
- package/dist/runtime/release-receipts.d.ts.map +1 -1
- package/dist/runtime/release-receipts.js +42 -1
- package/dist/runtime/release-receipts.js.map +1 -1
- package/dist/runtime/session-composer-control.d.ts +136 -0
- package/dist/runtime/session-composer-control.d.ts.map +1 -0
- package/dist/runtime/session-composer-control.js +532 -0
- package/dist/runtime/session-composer-control.js.map +1 -0
- package/dist/runtime/thread-projection.d.ts +17 -0
- package/dist/runtime/thread-projection.d.ts.map +1 -1
- package/dist/runtime/thread-projection.js +87 -0
- package/dist/runtime/thread-projection.js.map +1 -1
- package/dist/runtime/ui-events.d.ts +6 -1
- package/dist/runtime/ui-events.d.ts.map +1 -1
- package/dist/runtime/ui-events.js.map +1 -1
- package/dist/services/session-storage.d.ts +36 -0
- package/dist/services/session-storage.d.ts.map +1 -1
- package/dist/services/session-storage.js +77 -1
- package/dist/services/session-storage.js.map +1 -1
- package/dist/web/event-hub.js +10 -0
- package/dist/web/event-hub.js.map +1 -1
- package/dist/web/file-read-service.d.ts +9 -0
- package/dist/web/file-read-service.d.ts.map +1 -1
- package/dist/web/file-read-service.js +17 -7
- package/dist/web/file-read-service.js.map +1 -1
- package/dist/web/git-read-model-service.d.ts +8 -0
- package/dist/web/git-read-model-service.d.ts.map +1 -1
- package/dist/web/git-read-model-service.js +28 -2
- package/dist/web/git-read-model-service.js.map +1 -1
- package/dist/web/protocol.d.ts +142 -0
- package/dist/web/protocol.d.ts.map +1 -1
- package/dist/web/protocol.js +207 -0
- package/dist/web/protocol.js.map +1 -1
- package/dist/web/server.d.ts.map +1 -1
- package/dist/web/server.js +45 -8
- package/dist/web/server.js.map +1 -1
- package/dist/web/terminal-manager.d.ts +1 -0
- package/dist/web/terminal-manager.d.ts.map +1 -1
- package/dist/web/terminal-manager.js +41 -9
- package/dist/web/terminal-manager.js.map +1 -1
- package/dist/web/workbench-controller.d.ts +26 -9
- package/dist/web/workbench-controller.d.ts.map +1 -1
- package/dist/web/workbench-controller.js +545 -29
- package/dist/web/workbench-controller.js.map +1 -1
- package/dist/web-client/assets/{DiffViewer-DpKoD07C.js → DiffViewer-eaQNsnCh.js} +1 -1
- package/dist/web-client/assets/FilesPanel-DYs1MhoM.js +2 -0
- package/dist/web-client/assets/{GitPanel-D20StcdG.js → GitPanel-CnU4XVr7.js} +1 -1
- package/dist/web-client/assets/{ReviewPanel-3MVWbMQV.js → ReviewPanel-BDxG670T.js} +1 -1
- package/dist/web-client/assets/{TerminalPanel-BLQ592Fb.js → TerminalPanel-Q5mSSsoK.js} +15 -13
- package/dist/web-client/assets/index-BWV5sIvw.css +1 -0
- package/dist/web-client/assets/index-VVUKj6FE.js +17 -0
- package/dist/web-client/index.html +2 -2
- package/docs/architecture/agent-mode-permission-contract.md +87 -0
- package/docs/architecture/v0.3.1-web-api.yaml +53 -5
- package/docs/architecture/v0.3.2-web-api.yaml +3029 -0
- package/docs/migration/v0.3.1-to-v0.3.2.md +94 -0
- package/docs/plan/v0.3.1-web-workbench-professional-shell-plan.md +1 -1
- package/docs/plan/v0.3.2-web-workbench-layout-and-composer-plan.md +869 -0
- package/docs/readme.md +12 -2
- package/docs/test/v0.3.1-web-workbench-e2e-plan.md +1 -1
- package/docs/test/v0.3.2-web-workbench-e2e-plan.md +100 -0
- package/npm-shrinkwrap.json +2 -2
- package/package.json +6 -1
- package/dist/web-client/assets/FilesPanel-BkoLmgjR.js +0 -2
- package/dist/web-client/assets/index-BkIDl_xk.js +0 -16
- package/dist/web-client/assets/index-DXMpnWE8.css +0 -1
package/docs/readme.md
CHANGED
|
@@ -18,6 +18,17 @@ The repository release history is canonical in [`CHANGELOG.md`](../CHANGELOG.md)
|
|
|
18
18
|
link into the archive, but historical evidence is not moved back into `plan/` merely to satisfy an
|
|
19
19
|
old relative path.
|
|
20
20
|
|
|
21
|
+
## v0.3.2 candidate release set
|
|
22
|
+
|
|
23
|
+
- [Resizable Workbench and Composer Control Center plan](plan/v0.3.2-web-workbench-layout-and-composer-plan.md)
|
|
24
|
+
- [v0.3.2 Web API contract](architecture/v0.3.2-web-api.yaml)
|
|
25
|
+
- [Agent mode and permission contract](architecture/agent-mode-permission-contract.md)
|
|
26
|
+
- [v0.3.2 real Web E2E qualification plan](test/v0.3.2-web-workbench-e2e-plan.md)
|
|
27
|
+
- [v0.3.1 to v0.3.2 migration and rollback](migration/v0.3.1-to-v0.3.2.md)
|
|
28
|
+
|
|
29
|
+
Candidate plans and contracts describe required behavior; they are not release evidence. A v0.3.2
|
|
30
|
+
GO still requires the source-clean exact-tarball receipts described by the E2E plan.
|
|
31
|
+
|
|
21
32
|
## v0.3.1 candidate release set
|
|
22
33
|
|
|
23
34
|
- [Professional Web Workbench plan](plan/v0.3.1-web-workbench-professional-shell-plan.md)
|
|
@@ -25,8 +36,7 @@ old relative path.
|
|
|
25
36
|
- [v0.3.1 real Web E2E qualification plan](test/v0.3.1-web-workbench-e2e-plan.md)
|
|
26
37
|
- [v0.3.0 to v0.3.1 migration and rollback](migration/v0.3.0-to-v0.3.1.md)
|
|
27
38
|
|
|
28
|
-
|
|
29
|
-
GO still requires the source-clean exact-tarball receipts described by the E2E plan.
|
|
39
|
+
This remains the v0.3.2 baseline and historical qualification contract.
|
|
30
40
|
|
|
31
41
|
## v0.3.0 release set
|
|
32
42
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Orion Code v0.3.1 Web Workbench E2E 资格计划
|
|
2
2
|
|
|
3
3
|
- 目标版本:`0.3.1`
|
|
4
|
-
-
|
|
4
|
+
- 状态:合同已冻结;真实 release evidence 由组装器生成,本文不手工复制易漂移的 run ID
|
|
5
5
|
- 权威场景目录:`src/runtime/release-receipts.ts`
|
|
6
6
|
- 证据组装器:`scripts/e2e/assemble-web-e2e-receipt.ts`
|
|
7
7
|
- 产品方案:[`v0.3.1 Web Workbench 专业工作台计划`](../plan/v0.3.1-web-workbench-professional-shell-plan.md)
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
# Orion Code v0.3.2 Web Workbench E2E 资格计划
|
|
2
|
+
|
|
3
|
+
- 目标版本:`0.3.2`
|
|
4
|
+
- 状态:合同冻结;本地开发 run 只用于修复,不是 release evidence
|
|
5
|
+
- 权威场景目录:`src/runtime/release-receipts.ts`
|
|
6
|
+
- required facts:`tests/e2e/scenarios.ts::WEB32_REQUIRED_EVIDENCE_FACTS_V1`
|
|
7
|
+
- 证据组装器:`scripts/e2e/assemble-web-e2e-receipt.ts`
|
|
8
|
+
- 产品方案:[`v0.3.2 Workbench 与 Composer 计划`](../plan/v0.3.2-web-workbench-layout-and-composer-plan.md)
|
|
9
|
+
- API 合同:[`v0.3.2 Local Web API`](../architecture/v0.3.2-web-api.yaml)
|
|
10
|
+
|
|
11
|
+
## 1. GO 边界
|
|
12
|
+
|
|
13
|
+
源码 build、单元测试、开发 Host 或历史 0.3.1 receipt 都不是 v0.3.2 发布证明。GO 必须同时满足:
|
|
14
|
+
|
|
15
|
+
1. source-clean checkout 只构建一次 `@orion-agents/orion-code@0.3.2` tgz;
|
|
16
|
+
2. 三次 fresh primary run 与 Node 22.12.0、24.0.0、26.0.0 runtime run 安装同一
|
|
17
|
+
`tarballSha256`,且 `installedTargetDigest` 相同;
|
|
18
|
+
3. 使用真实 Chrome、打包后的 `bin/orion`、真实 Host/Runtime/ToolGateway/Thread store;
|
|
19
|
+
4. primary 精确执行既有 E2E/SET/WEB31 加 WEB32-P0-01..12;runtime 精确执行冻结 critical 集;
|
|
20
|
+
5. 无 skip、expected-fail、自动 retry、源码 fallback 或 DOM 注入伪造状态;
|
|
21
|
+
6. console error/warning、page error、HTTP 5xx、secret finding、dropped event、orphan 均为 0;
|
|
22
|
+
7. 每个 WEB32 场景的 structured facts 和 PNG 都通过安全校验并绑定 manifest digest;
|
|
23
|
+
8. runner、Chrome、Node/npm/platform/arch、artifact receipt 与 installed target identity 写入 receipt。
|
|
24
|
+
|
|
25
|
+
## 2. WEB32 场景
|
|
26
|
+
|
|
27
|
+
| ID | 真实旅程 | 关键权威证据 |
|
|
28
|
+
| ----------- | --------------------------------------------------------------------------------- | ------------------------------------------------- |
|
|
29
|
+
| WEB32-P0-01 | 左栏鼠标拖至 240/280/480、双击复位、48px rail、刷新恢复 | pointer facts、实际 bounding box、PNG |
|
|
30
|
+
| WEB32-P0-02 | 左右栏同时最大,right concession 后 center 仍 ≥560;视口恢复时桌面偏好恢复 | center/right 实测宽度与 preference |
|
|
31
|
+
| WEB32-P0-03 | 320/390/760/1024/1180/1440 drawer、互斥、focus return、无水平溢出 | viewport matrix、focus、overflow=0 |
|
|
32
|
+
| WEB32-P0-04 | BUILD/PLAN/AUTO 下拉、immediate/deferred、AUTO risk;模式与权限独立 | Host snapshot、provider request mode |
|
|
33
|
+
| WEB32-P0-05 | default/Ask/Allow/Deny、Allow confirm、显式 Deny、真实 ToolGateway | 文件副作用、durable authorization receipt |
|
|
34
|
+
| WEB32-P0-06 | 双模型 catalog+Effort、切小窗口真实 compact、失败 rollback | provider model/usage、compact receipt、metadata |
|
|
35
|
+
| WEB32-P0-07 | provider/estimated Context、阈值、capacity reset、自动/手动 compact | Runtime context projection 与 provider request |
|
|
36
|
+
| WEB32-P0-08 | file/folder/review/session/skill 引用、stale/forbidden、prompt manifest、secret=0 | Host prompt manifest/digest、negative probes |
|
|
37
|
+
| WEB32-P0-09 | PLAN 不执行;approve/continue/cancel;refresh/restart;stale digest 409 | durable Thread facts、provider sequence、零副作用 |
|
|
38
|
+
| WEB32-P0-10 | queue edit/move/remove、Steer CAS、Session draft 切换/刷新、无串线 | queue/item revisions、sessionStorage scope |
|
|
39
|
+
| WEB32-P0-11 | 双 tab CAS、Host restart、replay reset、matching snapshot 前 Composer disabled | exact 409、SSE frames、snapshot barrier |
|
|
40
|
+
| WEB32-P0-12 | normal CSP、axe、light/dark/reduced-motion/200% zoom、错误/secret/dropped 全 0 | headers、axe JSON、browser counters、PNG |
|
|
41
|
+
|
|
42
|
+
每个 Playwright 标题必须且只能包含一个 scenario ID。完整 fact key、类型与阈值以代码目录为准;
|
|
43
|
+
组装器拒绝缺失、额外、错误类型、错误 PNG、绝对路径、symlink 或不满足阈值的证据。
|
|
44
|
+
|
|
45
|
+
## 3. Critical 子集
|
|
46
|
+
|
|
47
|
+
Node 22.12/24/26 使用同一 tgz 执行既有 critical 集并新增:
|
|
48
|
+
|
|
49
|
+
```text
|
|
50
|
+
WEB32-P0-01, WEB32-P0-04, WEB32-P0-05, WEB32-P0-06,
|
|
51
|
+
WEB32-P0-09, WEB32-P0-11, WEB32-P0-12
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
它覆盖 packaged layout、模式/权限/模型/Context、durable Plan review、多标签 CAS、恢复屏障与
|
|
55
|
+
normal-CSP accessibility/security。其他 WEB32 场景仍必须在三次 full primary run 中执行。
|
|
56
|
+
|
|
57
|
+
## 4. 运行规则
|
|
58
|
+
|
|
59
|
+
- deterministic loopback provider 至少提供大/小两个 context window 和多个 Effort;
|
|
60
|
+
- 权限场景必须进入真实 ToolGateway,以 durable receipt 和文件副作用核验;
|
|
61
|
+
- PLAN 场景必须读取真实 Thread journal;HTTP 202 或 UI 文案不是完成证据;
|
|
62
|
+
- recovery 使用真实同端口 Host restart、EventSource cursor/replay reset 和 matching snapshot;
|
|
63
|
+
- 核心旅程使用 normal CSP;axe 注入不能通过全页 `bypassCSP` 弱化产品约束;
|
|
64
|
+
- Context/文件安全 negative probe 可用 installed Host fetch,避免预期 4xx 变成浏览器 console 噪音;
|
|
65
|
+
- network failure 只能在场景内精确采集 method/path/error 后逐项登记;不得给固定宽限;
|
|
66
|
+
- 截图只裁产品表面,禁止绝对路径、用户名、凭据、真实项目内容、terminal ticket 或外部账号信息。
|
|
67
|
+
|
|
68
|
+
## 5. 构建与 receipt
|
|
69
|
+
|
|
70
|
+
等价本地入口如下,实际 tgz 文件名从 artifact receipt 读取:
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
npm run release:artifact -- \
|
|
74
|
+
--out-dir .release/package \
|
|
75
|
+
--receipt .release/package/artifact.json
|
|
76
|
+
|
|
77
|
+
npm run test:web-e2e:primary -- \
|
|
78
|
+
--tarball .release/package/orion-agents-orion-code-0.3.2.tgz \
|
|
79
|
+
--receipt .release/package/artifact.json \
|
|
80
|
+
--chrome /absolute/path/to/google-chrome
|
|
81
|
+
|
|
82
|
+
npm run test:web-e2e:matrix -- \
|
|
83
|
+
--tarball .release/package/orion-agents-orion-code-0.3.2.tgz \
|
|
84
|
+
--receipt .release/package/artifact.json \
|
|
85
|
+
--chrome /absolute/path/to/google-chrome \
|
|
86
|
+
--node22 /absolute/path/to/node-22.12.0 \
|
|
87
|
+
--node24 /absolute/path/to/node-24.0.0 \
|
|
88
|
+
--node26 /absolute/path/to/node-26.0.0
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
三个 primary manifests、三个 runtime manifests 和 artifact receipt 交给
|
|
92
|
+
`npm run release:web-e2e-receipt`。最终 release receipt 必须强绑定 Web receipt digest。
|
|
93
|
+
|
|
94
|
+
## 6. 失败处理
|
|
95
|
+
|
|
96
|
+
- 任一 ID 缺失/重复/额外、fact/PNG 缺失、artifact identity 不一致:NO_GO;
|
|
97
|
+
- 任一 Node clean install/native dependency/Chrome journey 失败:NO_GO;
|
|
98
|
+
- stale mutation 有副作用、Plan 自动执行、敏感内容泄漏、snapshot 前 Composer 可提交:NO_GO;
|
|
99
|
+
- 修复产品或测试后,从同一 source-clean commit 重建新 tgz,旧 artifact 与旧 run 全部失效;
|
|
100
|
+
- 开发态逐场景 GO 只能证明修复方向,不能复制成正式发布结论。
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@orion-agents/orion-code",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.2",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@orion-agents/orion-code",
|
|
9
|
-
"version": "0.3.
|
|
9
|
+
"version": "0.3.2",
|
|
10
10
|
"license": "MIT",
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"@clack/prompts": "^0.7.0",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@orion-agents/orion-code",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.2",
|
|
4
4
|
"description": "Orion Code - local-first goal-driven coding agent for terminal and Web.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -18,15 +18,20 @@
|
|
|
18
18
|
"docs/migration/v0.2.2-to-v0.3.0.md",
|
|
19
19
|
"docs/migration/v0.2.2-to-v0.3.0-settings.md",
|
|
20
20
|
"docs/migration/v0.3.0-to-v0.3.1.md",
|
|
21
|
+
"docs/migration/v0.3.1-to-v0.3.2.md",
|
|
21
22
|
"docs/plan/v0.2.0-dsh-harness-redesign-plan.md",
|
|
22
23
|
"docs/plan/v0.2.0-release-checklist.md",
|
|
23
24
|
"docs/plan/v0.3.0-web-workbench-plan.md",
|
|
24
25
|
"docs/plan/v0.3.0-settings-integration-plan.md",
|
|
25
26
|
"docs/plan/v0.3.0-node-runtime-compatibility-plan.md",
|
|
26
27
|
"docs/plan/v0.3.1-web-workbench-professional-shell-plan.md",
|
|
28
|
+
"docs/plan/v0.3.2-web-workbench-layout-and-composer-plan.md",
|
|
27
29
|
"docs/test/v0.3.1-web-workbench-e2e-plan.md",
|
|
30
|
+
"docs/test/v0.3.2-web-workbench-e2e-plan.md",
|
|
28
31
|
"docs/architecture/v0.3.0-web-api.yaml",
|
|
29
32
|
"docs/architecture/v0.3.1-web-api.yaml",
|
|
33
|
+
"docs/architecture/v0.3.2-web-api.yaml",
|
|
34
|
+
"docs/architecture/agent-mode-permission-contract.md",
|
|
30
35
|
"LICENSE",
|
|
31
36
|
"README.md",
|
|
32
37
|
"README.zh-CN.md",
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{r as l,j as e,I as k,s as H,W as J}from"./index-BkIDl_xk.js";function se({workspaceId:t,refreshEpoch:c,actions:a}){const[i,d]=l.useState({}),[p,x]=l.useState(new Set(["workspace-root"])),[o,f]=l.useState(null),[m,y]=l.useState(""),[L,S]=l.useState(null),[P,$]=l.useState(!1),[E,R]=l.useState(""),[T,N]=l.useState(""),[F,Q]=l.useState(""),[B,V]=l.useState(!1),[z,q]=l.useState("1"),D=l.useRef(null),u=l.useRef(0),g=l.useRef(0),C=async(s,r=!1,b=u.current)=>{if(b!==u.current)return;const h=i[s],v=r?h?.nextCursor:void 0;if(!(r&&!v)){d(n=>({...n,[s]:{items:h?.items??[],nextCursor:h?.nextCursor??null,revision:h?.revision??"",loading:!0}}));try{const n=await a.listFiles(s,v??void 0);if(b!==u.current)return;d(j=>({...j,[s]:{items:r?X(j[s]?.items??[],n.items):n.items,nextCursor:n.nextCursor,revision:n.revision,loading:!1}}))}catch(n){if(b!==u.current)return;if(r&&K(n)){N("目录已变化,已重新载入第一页。"),C(s,!1,b);return}d(j=>({...j,[s]:{items:j[s]?.items??[],nextCursor:j[s]?.nextCursor??null,revision:j[s]?.revision??"",loading:!1,error:_(n)}}))}}};l.useEffect(()=>{const s=u.current+1;u.current=s,g.current+=1,d({}),x(new Set(["workspace-root"])),f(null),y(""),S(null),$(!1),R(""),N(""),t&&C("workspace-root",!1,s)},[c,t]);const w=async(s,r=!1,b=!1,h=u.current,v=g.current+1)=>{if(h===u.current&&!(!s.readable||s.sensitive||s.kind==="directory")){g.current=v,f(s),R(""),r||(y(""),S(null),$(!1)),b||N("");try{const n=await a.readFileContent(s.id,r?L??void 0:void 0);if(h!==u.current||v!==g.current)return;$(n.binary),y(j=>r?`${j}${n.content??""}`:n.content??""),S(n.nextCursor),b&&N("文件已变化,已从第一页重新载入。")}catch(n){if(h!==u.current||v!==g.current)return;if(r&&K(n)){await w(s,!1,!0,h,v);return}R(_(n))}}},M=s=>{const r=new Set(p);r.has(s)?r.delete(s):(r.add(s),i[s]||C(s)),x(r)},G=l.useMemo(()=>Object.values(i).flatMap(s=>s.items),[i]),W=F.trim()?G.filter(s=>s.name.toLocaleLowerCase().includes(F.toLocaleLowerCase())):null;return e.jsxs("div",{className:"work-resource-panel files-panel",children:[e.jsxs("div",{className:"resource-toolbar",children:[e.jsxs("label",{className:"resource-search",children:[e.jsx("span",{className:"sr-only",children:"搜索已加载文件"}),e.jsx(k,{name:"search",size:14}),e.jsx("input",{type:"search",value:F,onChange:s=>Q(s.target.value),placeholder:"搜索已加载文件"})]}),e.jsx("button",{type:"button",className:"icon-button","aria-label":"刷新文件树",onClick:()=>{C("workspace-root")},children:e.jsx(k,{name:"refresh",size:15})})]}),e.jsxs("div",{className:"files-layout",children:[e.jsx("section",{className:"file-tree","aria-label":"工作区文件",children:W?e.jsxs(e.Fragment,{children:[e.jsx("p",{className:"resource-hint",children:"搜索仅覆盖已加载的目录和文件。"}),e.jsx("ul",{role:"list",className:"file-node-list search-results",children:W.map(s=>e.jsx(O,{node:s,depth:0,expanded:!1,selected:o?.id===s.id,onToggle:M,onSelect:r=>{w(r)}},s.id))})]}):e.jsx(A,{parentId:"workspace-root",depth:0,directories:i,expanded:p,selectedId:o?.id,onToggle:M,onSelect:s=>{w(s)},onLoadMore:s=>{C(s,!0)}})}),e.jsxs("section",{className:"file-preview","aria-label":"文件预览",children:[T?e.jsx("p",{className:"resource-notice",role:"status",children:T}):null,o?e.jsxs(e.Fragment,{children:[e.jsxs("header",{children:[e.jsx("strong",{children:o.name}),e.jsx("span",{children:Y(o.sizeBytes??0)})]}),E?e.jsx("p",{className:"resource-error",role:"alert",children:E}):P?e.jsxs("div",{className:"resource-empty",children:[e.jsx(k,{name:"code"}),e.jsx("strong",{children:"二进制文件"}),e.jsx("p",{children:"出于安全和性能考虑,只显示元数据。"})]}):e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"file-preview-actions",children:[e.jsxs("label",{children:[e.jsx("span",{className:"sr-only",children:"跳到行"}),e.jsx("input",{type:"number",min:"1",value:z,"aria-label":"跳到行",onChange:s=>q(s.target.value)})]}),e.jsx("button",{type:"button",className:"text-button",onClick:()=>Z(D.current,z),children:"跳转"}),e.jsx("button",{type:"button",className:"text-button",onClick:()=>{I(m,N)},children:"复制"}),e.jsx("button",{type:"button",className:"text-button","aria-pressed":B,onClick:()=>V(s=>!s),children:"自动换行"})]}),e.jsx("pre",{ref:D,tabIndex:0,className:`file-code-view ${B?"wrap":""}`,"aria-label":`文件内容 ${o.name}`,children:H(m).split(`
|
|
2
|
-
`).map((s,r)=>e.jsxs("span",{className:"file-code-line","data-line":r+1,children:[e.jsx("span",{className:"file-line-number","aria-hidden":"true",children:r+1}),e.jsx("span",{className:"file-line-content",children:s||" "})]},r))})]}),L?e.jsx("button",{type:"button",className:"secondary-button",onClick:()=>{w(o,!0)},children:"加载更多内容"}):null]}):e.jsxs("div",{className:"resource-empty",children:[e.jsx(k,{name:"workspace"}),e.jsx("strong",{children:"选择文件预览"}),e.jsx("p",{children:"敏感文件、工作区外链接和二进制正文不会返回浏览器。"})]})]})]})]})}function A({parentId:t,depth:c,directories:a,expanded:i,selectedId:d,onToggle:p,onSelect:x,onLoadMore:o}){const f=a[t];return f?f.error?e.jsx("p",{className:"resource-error",role:"alert",children:f.error}):e.jsxs("ul",{role:"list",className:"file-node-list",children:[f.items.map(m=>{const y=i.has(m.id);return e.jsxs("li",{children:[e.jsx(O,{node:m,depth:c,expanded:y,selected:d===m.id,onToggle:p,onSelect:x}),m.kind==="directory"&&y?e.jsx(A,{parentId:m.id,depth:c+1,directories:a,expanded:i,selectedId:d,onToggle:p,onSelect:x,onLoadMore:o}):null]},m.id)}),f.loading?e.jsx("li",{className:"resource-loading",children:"正在读取…"}):null,f.nextCursor?e.jsx("li",{children:e.jsx("button",{type:"button",className:"text-button",onClick:()=>o(t),children:"加载更多"})}):null]}):e.jsx("p",{className:"resource-loading",children:"正在读取…"})}function O({node:t,depth:c,expanded:a,selected:i,onToggle:d,onSelect:p}){const x=t.sensitive||!t.readable;return e.jsxs("button",{type:"button",className:`file-node ${i?"selected":""} ${x?"blocked":""}`,style:{paddingInlineStart:`${8+c*15}px`},"aria-expanded":t.kind==="directory"?a:void 0,"aria-label":`${U(t.kind)} ${t.name}${x?",不可读取":""}`,onClick:()=>t.kind==="directory"?d(t.id):p(t),disabled:x,children:[e.jsx(k,{name:t.kind==="directory"?"workspace":"code",size:14}),e.jsx("span",{children:t.name}),t.kind==="symlink"?e.jsx("small",{children:"链接"}):null,t.sensitive?e.jsx("small",{children:"敏感"}):null]})}function U(t){return t==="directory"?"目录":t==="symlink"?"符号链接":"文件"}function X(t,c){const a=new Map(t.map(i=>[i.id,i]));for(const i of c)a.set(i.id,i);return[...a.values()]}function Y(t){return t<1024?`${t} B`:t<1048576?`${(t/1024).toFixed(1)} KB`:`${(t/1048576).toFixed(1)} MB`}function K(t){return t instanceof J&&t.code==="file_revision_conflict"}function Z(t,c){const a=Number(c);!t||!Number.isSafeInteger(a)||a<1||(t.querySelector(`[data-line="${a}"]`)?.scrollIntoView({block:"center"}),t.focus())}async function I(t,c){try{await navigator.clipboard.writeText(t),c("已复制当前加载的文件内容。")}catch{c("浏览器未允许复制,请手动选择文本。")}}function _(t){return t instanceof Error?t.message:"文件请求失败。"}export{se as FilesPanel};
|