@tom2012/cc-web 2026.5.24-e → 2026.5.24-g

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.
Files changed (27) hide show
  1. package/README.md +1 -1
  2. package/backend/dist/__tests__/browser-chrome-e2e.test.js +50 -0
  3. package/backend/dist/__tests__/browser-chrome-e2e.test.js.map +1 -1
  4. package/backend/dist/browser-chrome/session-manager.d.ts +20 -1
  5. package/backend/dist/browser-chrome/session-manager.d.ts.map +1 -1
  6. package/backend/dist/browser-chrome/session-manager.js +61 -4
  7. package/backend/dist/browser-chrome/session-manager.js.map +1 -1
  8. package/backend/dist/routes/browser-chrome.d.ts.map +1 -1
  9. package/backend/dist/routes/browser-chrome.js +4 -0
  10. package/backend/dist/routes/browser-chrome.js.map +1 -1
  11. package/frontend/dist/assets/{ChatOverlay-V7DBSoaF.js → ChatOverlay-DNblGgsD.js} +1 -1
  12. package/frontend/dist/assets/{GraphPreview-BxBsGYE9.js → GraphPreview-DZuX6HrU.js} +1 -1
  13. package/frontend/dist/assets/{MobilePage-BwIfpmZA.js → MobilePage-BlwBG-sh.js} +3 -3
  14. package/frontend/dist/assets/{OfficePreview-CWiJpp9Z.js → OfficePreview-CWYidYK8.js} +2 -2
  15. package/frontend/dist/assets/{PdfPreview-2DcKEMbR.js → PdfPreview-_uFda2zI.js} +1 -1
  16. package/frontend/dist/assets/{ProjectPage-CKm1NIEx.js → ProjectPage-C8W6Jx8Z.js} +4 -4
  17. package/frontend/dist/assets/{SettingsPage-CRPl_mVj.js → SettingsPage-CbTTZOeF.js} +1 -1
  18. package/frontend/dist/assets/{SkillHubPage-DsF2j49l.js → SkillHubPage-D5yrAZ66.js} +1 -1
  19. package/frontend/dist/assets/{chevron-down-DSuYI8m-.js → chevron-down-DGJ1q8HL.js} +1 -1
  20. package/frontend/dist/assets/{index-CPROAFio.js → index-DsEIMlTx.js} +1 -1
  21. package/frontend/dist/assets/{index-DLIf9Yfa.js → index-M_4VnkuM.js} +1 -1
  22. package/frontend/dist/assets/{index-YwIvszwO.js → index-P6fKDTgI.js} +2 -2
  23. package/frontend/dist/assets/{jszip.min-C_jYnhtJ.js → jszip.min-2wuC33Uk.js} +1 -1
  24. package/frontend/dist/assets/{search-CaBUM8S-.js → search-BSUk1egC.js} +1 -1
  25. package/frontend/dist/assets/{select-BUvVYFSc.js → select-d9YUOMJ7.js} +1 -1
  26. package/frontend/dist/index.html +1 -1
  27. package/package.json +1 -1
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  A self-hosted web application (distributed as npm package) that provides a browser-based interface for [Claude Code](https://docs.anthropic.com/en/docs/claude-code) CLI sessions. Create projects, each with a persistent terminal running Claude Code, and interact with them through a real-time terminal UI.
4
4
 
5
- **Current version**: v2026.5.24-e | [GitHub](https://github.com/zbc0315/cc-web) | MIT License
5
+ **Current version**: v2026.5.24-g | [GitHub](https://github.com/zbc0315/cc-web) | MIT License
6
6
 
7
7
  ## Features
8
8
 
@@ -141,6 +141,56 @@ vitest_1.describe.skipIf(!chromiumAvailable)('browser-chrome e2e (real chromium)
141
141
  (0, vitest_1.expect)(await session.page.$eval('#x', (el) => el.value)).toBe('ellX');
142
142
  void port;
143
143
  }, 30000);
144
+ (0, vitest_1.it)('isolates pages between users and enforces SessionLimitError at the 4th user', async () => {
145
+ // Earlier tests leave 'e2e-user' + 'reuse-user' alive at the time this
146
+ // runs. Drop everything to a clean slate so we can deterministically
147
+ // verify the cap, then re-establish 'e2e-user' afterwards.
148
+ await session_manager_1.browserChromeSessions.destroyAll(2000);
149
+ const { SessionLimitError } = await Promise.resolve().then(() => __importStar(require('../browser-chrome/session-manager')));
150
+ const userA = await session_manager_1.browserChromeSessions.getOrCreate('user-a');
151
+ const userB = await session_manager_1.browserChromeSessions.getOrCreate('user-b');
152
+ const userC = await session_manager_1.browserChromeSessions.getOrCreate('user-c');
153
+ (0, vitest_1.expect)(userA.sid).toBeTruthy();
154
+ // user-b and user-c distinct from each other and from e2e-user.
155
+ const sidSet = new Set([userB.sid, userC.sid]);
156
+ (0, vitest_1.expect)(sidSet.size).toBe(2);
157
+ // Set distinct content per session and confirm pages don't share state.
158
+ await userB.page.setContent('<title>B-PAGE</title><body>BBB</body>');
159
+ await userC.page.setContent('<title>C-PAGE</title><body>CCC</body>');
160
+ (0, vitest_1.expect)(await userB.page.title()).toBe('B-PAGE');
161
+ (0, vitest_1.expect)(await userC.page.title()).toBe('C-PAGE');
162
+ // 4th distinct user hits the cap.
163
+ let caught = null;
164
+ try {
165
+ await session_manager_1.browserChromeSessions.getOrCreate('user-d');
166
+ }
167
+ catch (err) {
168
+ caught = err;
169
+ }
170
+ (0, vitest_1.expect)(caught).toBeInstanceOf(SessionLimitError);
171
+ // Reusing an existing user still works even at the cap.
172
+ const userBAgain = await session_manager_1.browserChromeSessions.getOrCreate('user-b');
173
+ (0, vitest_1.expect)(userBAgain.sid).toBe(userB.sid);
174
+ // Cleanup: free everyone so the next test starts under the cap.
175
+ await session_manager_1.browserChromeSessions.destroy(userA.sid);
176
+ await session_manager_1.browserChromeSessions.destroy(userB.sid);
177
+ await session_manager_1.browserChromeSessions.destroy(userC.sid);
178
+ }, 60000);
179
+ (0, vitest_1.it)('forwards IME-committed CJK text via type msg', async () => {
180
+ const session = await session_manager_1.browserChromeSessions.getOrCreate('e2e-user');
181
+ await session.page.setContent(`<!doctype html><html><body>
182
+ <input id="cn" autofocus style="width:400px;font-size:24px"/>
183
+ </body></html>`);
184
+ await session.page.focus('#cn');
185
+ const { handleInput } = await Promise.resolve().then(() => __importStar(require('../browser-chrome/input-forwarder')));
186
+ // Simulates what the frontend sends on compositionend: the final composed
187
+ // CJK string as a single 'type' msg (rather than per-keystroke 'key').
188
+ await handleInput(session, { type: 'type', text: '你好世界' });
189
+ (0, vitest_1.expect)(await session.page.$eval('#cn', (el) => el.value)).toBe('你好世界');
190
+ // Mix CJK + ASCII as IME often does (user types '你好' then ASCII 'foo').
191
+ await handleInput(session, { type: 'type', text: 'foo' });
192
+ (0, vitest_1.expect)(await session.page.$eval('#cn', (el) => el.value)).toBe('你好世界foo');
193
+ }, 30000);
144
194
  (0, vitest_1.it)('resize updates viewport and persists on session', async () => {
145
195
  const session = await session_manager_1.browserChromeSessions.getOrCreate('e2e-user');
146
196
  const { handleInput } = await Promise.resolve().then(() => __importStar(require('../browser-chrome/input-forwarder')));
@@ -1 +1 @@
1
- {"version":3,"file":"browser-chrome-e2e.test.js","sourceRoot":"","sources":["../../src/__tests__/browser-chrome-e2e.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"browser-chrome-e2e.test.js","sourceRoot":"","sources":["../../src/__tests__/browser-chrome-e2e.test.ts"],"names":[],"mappings":"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"}
@@ -15,17 +15,36 @@ export interface Session {
15
15
  };
16
16
  url: string;
17
17
  }
18
+ /**
19
+ * Thrown by `getOrCreate` when the global session cap is reached. Routes
20
+ * map this to HTTP 429 so the frontend can surface a friendly "too many
21
+ * concurrent browser sessions, try again later" instead of a generic 500.
22
+ */
23
+ export declare class SessionLimitError extends Error {
24
+ readonly limit: number;
25
+ constructor(limit: number);
26
+ }
18
27
  declare class SessionManager extends EventEmitter {
19
28
  private sessions;
20
29
  private idleTimer;
30
+ private memoryTimer;
21
31
  private started;
22
32
  start(): void;
23
33
  /** Return existing session for this user (reuse) or create a new one. */
24
34
  getOrCreate(username: string): Promise<Session>;
25
35
  get(sid: string, username: string): Session | null;
26
36
  destroy(sid: string): Promise<void>;
27
- destroyAll(): Promise<void>;
37
+ /**
38
+ * Tear down every session within `gracefulMs`. Playwright doesn't expose
39
+ * the chromium child process via public API (only puppeteer does), so we
40
+ * rely on `browser.close()` to be polite. Anything stuck past the grace
41
+ * window is logged loudly — the daemon's force-exit timeout (process.exit
42
+ * 5s later) will SIGKILL the parent and OS propagates SIGHUP to children.
43
+ * Residual zombie chromium handling deferred to Phase 5.
44
+ */
45
+ destroyAll(gracefulMs?: number): Promise<void>;
28
46
  size(): number;
47
+ private sampleMemory;
29
48
  private sweepIdle;
30
49
  }
31
50
  export declare const browserChromeSessions: SessionManager;
@@ -1 +1 @@
1
- {"version":3,"file":"session-manager.d.ts","sourceRoot":"","sources":["../../src/browser-chrome/session-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAY,KAAK,OAAO,EAAE,KAAK,cAAc,EAAE,KAAK,IAAI,EAAE,KAAK,UAAU,EAAE,MAAM,YAAY,CAAC;AAErG,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAOtC,MAAM,WAAW,OAAO;IACtB,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,cAAc,CAAC;IACxB,IAAI,EAAE,IAAI,CAAC;IACX,GAAG,EAAE,UAAU,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,QAAQ,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACnC,GAAG,EAAE,MAAM,CAAC;CACb;AAMD,cAAM,cAAe,SAAQ,YAAY;IACvC,OAAO,CAAC,QAAQ,CAA8B;IAC9C,OAAO,CAAC,SAAS,CAA+B;IAChD,OAAO,CAAC,OAAO,CAAS;IAExB,KAAK,IAAI,IAAI;IAMb,yEAAyE;IACnE,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAiDrD,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,GAAG,IAAI;IAQ5C,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAanC,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAQjC,IAAI,IAAI,MAAM;IAId,OAAO,CAAC,SAAS;CASlB;AAED,eAAO,MAAM,qBAAqB,gBAAuB,CAAC;AAO1D,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAOtE;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAU1F"}
1
+ {"version":3,"file":"session-manager.d.ts","sourceRoot":"","sources":["../../src/browser-chrome/session-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAY,KAAK,OAAO,EAAE,KAAK,cAAc,EAAE,KAAK,IAAI,EAAE,KAAK,UAAU,EAAE,MAAM,YAAY,CAAC;AAErG,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAOtC,MAAM,WAAW,OAAO;IACtB,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,cAAc,CAAC;IACxB,IAAI,EAAE,IAAI,CAAC;IACX,GAAG,EAAE,UAAU,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,QAAQ,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACnC,GAAG,EAAE,MAAM,CAAC;CACb;AAUD;;;;GAIG;AACH,qBAAa,iBAAkB,SAAQ,KAAK;IAC1C,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;gBACX,KAAK,EAAE,MAAM;CAK1B;AAED,cAAM,cAAe,SAAQ,YAAY;IACvC,OAAO,CAAC,QAAQ,CAA8B;IAC9C,OAAO,CAAC,SAAS,CAA+B;IAChD,OAAO,CAAC,WAAW,CAA+B;IAClD,OAAO,CAAC,OAAO,CAAS;IAExB,KAAK,IAAI,IAAI;IAOb,yEAAyE;IACnE,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAiDrD,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,GAAG,IAAI;IAQ5C,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAazC;;;;;;;OAOG;IACG,UAAU,CAAC,UAAU,GAAE,MAA0B,GAAG,OAAO,CAAC,IAAI,CAAC;IAqBvE,IAAI,IAAI,MAAM;YAIA,YAAY;IAmB1B,OAAO,CAAC,SAAS;CASlB;AAED,eAAO,MAAM,qBAAqB,gBAAuB,CAAC;AAO1D,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAOtE;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAU1F"}
@@ -33,7 +33,7 @@ var __importStar = (this && this.__importStar) || (function () {
33
33
  };
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.browserChromeSessions = void 0;
36
+ exports.browserChromeSessions = exports.SessionLimitError = void 0;
37
37
  exports.mintSessionToken = mintSessionToken;
38
38
  exports.verifySessionToken = verifySessionToken;
39
39
  const playwright_1 = require("playwright");
@@ -46,11 +46,29 @@ const log = (0, logger_1.modLogger)('browser-chrome');
46
46
  const MAX_SESSIONS = 3;
47
47
  const IDLE_TIMEOUT_MS = 5 * 60 * 1000;
48
48
  const DEFAULT_VIEWPORT = { w: 1280, h: 800 };
49
+ const MEMORY_SAMPLE_INTERVAL_MS = 30 * 1000;
50
+ const MEMORY_WARN_BYTES = 500 * 1024 * 1024; // log warn at 500MB JS heap
51
+ const MEMORY_HARD_LIMIT_BYTES = 1024 * 1024 * 1024; // force destroy at 1GB
52
+ const SHUTDOWN_GRACE_MS = 5000;
53
+ /**
54
+ * Thrown by `getOrCreate` when the global session cap is reached. Routes
55
+ * map this to HTTP 429 so the frontend can surface a friendly "too many
56
+ * concurrent browser sessions, try again later" instead of a generic 500.
57
+ */
58
+ class SessionLimitError extends Error {
59
+ constructor(limit) {
60
+ super(`Max ${limit} browser sessions reached`);
61
+ this.name = 'SessionLimitError';
62
+ this.limit = limit;
63
+ }
64
+ }
65
+ exports.SessionLimitError = SessionLimitError;
49
66
  class SessionManager extends events_1.EventEmitter {
50
67
  constructor() {
51
68
  super(...arguments);
52
69
  this.sessions = new Map();
53
70
  this.idleTimer = null;
71
+ this.memoryTimer = null;
54
72
  this.started = false;
55
73
  }
56
74
  start() {
@@ -58,6 +76,7 @@ class SessionManager extends events_1.EventEmitter {
58
76
  return;
59
77
  this.started = true;
60
78
  this.idleTimer = setInterval(() => this.sweepIdle(), 30 * 1000);
79
+ this.memoryTimer = setInterval(() => { void this.sampleMemory(); }, MEMORY_SAMPLE_INTERVAL_MS);
61
80
  }
62
81
  /** Return existing session for this user (reuse) or create a new one. */
63
82
  async getOrCreate(username) {
@@ -69,7 +88,7 @@ class SessionManager extends events_1.EventEmitter {
69
88
  }
70
89
  }
71
90
  if (this.sessions.size >= MAX_SESSIONS) {
72
- throw new Error(`Max ${MAX_SESSIONS} browser sessions reached`);
91
+ throw new SessionLimitError(MAX_SESSIONS);
73
92
  }
74
93
  const sid = (0, uuid_1.v4)();
75
94
  let browser;
@@ -128,17 +147,55 @@ class SessionManager extends events_1.EventEmitter {
128
147
  }
129
148
  log.info({ sid, count: this.sessions.size }, 'session destroyed');
130
149
  }
131
- async destroyAll() {
150
+ /**
151
+ * Tear down every session within `gracefulMs`. Playwright doesn't expose
152
+ * the chromium child process via public API (only puppeteer does), so we
153
+ * rely on `browser.close()` to be polite. Anything stuck past the grace
154
+ * window is logged loudly — the daemon's force-exit timeout (process.exit
155
+ * 5s later) will SIGKILL the parent and OS propagates SIGHUP to children.
156
+ * Residual zombie chromium handling deferred to Phase 5.
157
+ */
158
+ async destroyAll(gracefulMs = SHUTDOWN_GRACE_MS) {
132
159
  const sids = Array.from(this.sessions.keys());
133
- await Promise.all(sids.map(sid => this.destroy(sid)));
134
160
  if (this.idleTimer)
135
161
  clearInterval(this.idleTimer);
162
+ if (this.memoryTimer)
163
+ clearInterval(this.memoryTimer);
136
164
  this.idleTimer = null;
165
+ this.memoryTimer = null;
137
166
  this.started = false;
167
+ await Promise.race([
168
+ Promise.all(sids.map(sid => this.destroy(sid))),
169
+ new Promise(r => setTimeout(r, gracefulMs)),
170
+ ]);
171
+ if (this.sessions.size > 0) {
172
+ log.warn({ remaining: Array.from(this.sessions.keys()) }, `${this.sessions.size} chromium session(s) did not close within ${gracefulMs}ms — relying on OS cleanup`);
173
+ }
138
174
  }
139
175
  size() {
140
176
  return this.sessions.size;
141
177
  }
178
+ async sampleMemory() {
179
+ for (const [sid, s] of this.sessions) {
180
+ try {
181
+ const metrics = await s.cdp.send('Performance.getMetrics');
182
+ const heap = metrics.metrics.find(m => m.name === 'JSHeapUsedSize');
183
+ if (!heap)
184
+ continue;
185
+ const bytes = heap.value;
186
+ if (bytes > MEMORY_HARD_LIMIT_BYTES) {
187
+ log.error({ sid, username: s.username, bytes }, 'chromium memory hard-limit exceeded — force destroy');
188
+ void this.destroy(sid);
189
+ }
190
+ else if (bytes > MEMORY_WARN_BYTES) {
191
+ log.warn({ sid, username: s.username, bytes }, 'chromium memory above soft warn threshold');
192
+ }
193
+ }
194
+ catch {
195
+ // CDP detached during the sample window — sweepIdle will tidy up.
196
+ }
197
+ }
198
+ }
142
199
  sweepIdle() {
143
200
  const now = Date.now();
144
201
  for (const [sid, s] of this.sessions) {
@@ -1 +1 @@
1
- {"version":3,"file":"session-manager.js","sourceRoot":"","sources":["../../src/browser-chrome/session-manager.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA0IA,4CAOC;AAED,gDAUC;AA7JD,2CAAqG;AACrG,+BAAoC;AACpC,mCAAsC;AACtC,kDAAoC;AACpC,sCAAsC;AACtC,sCAAsC;AAEtC,MAAM,GAAG,GAAG,IAAA,kBAAS,EAAC,gBAAgB,CAAC,CAAC;AAexC,MAAM,YAAY,GAAG,CAAC,CAAC;AACvB,MAAM,eAAe,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC;AACtC,MAAM,gBAAgB,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC;AAE7C,MAAM,cAAe,SAAQ,qBAAY;IAAzC;;QACU,aAAQ,GAAG,IAAI,GAAG,EAAmB,CAAC;QACtC,cAAS,GAA0B,IAAI,CAAC;QACxC,YAAO,GAAG,KAAK,CAAC;IAoG1B,CAAC;IAlGC,KAAK;QACH,IAAI,IAAI,CAAC,OAAO;YAAE,OAAO;QACzB,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;QACpB,IAAI,CAAC,SAAS,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,SAAS,EAAE,EAAE,EAAE,GAAG,IAAI,CAAC,CAAC;IAClE,CAAC;IAED,yEAAyE;IACzE,KAAK,CAAC,WAAW,CAAC,QAAgB;QAChC,IAAI,CAAC,KAAK,EAAE,CAAC;QACb,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,EAAE,CAAC;YACvC,IAAI,CAAC,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;gBAC5B,CAAC,CAAC,cAAc,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;gBAC9B,OAAO,CAAC,CAAC;YACX,CAAC;QACH,CAAC;QACD,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,IAAI,YAAY,EAAE,CAAC;YACvC,MAAM,IAAI,KAAK,CAAC,OAAO,YAAY,2BAA2B,CAAC,CAAC;QAClE,CAAC;QAED,MAAM,GAAG,GAAG,IAAA,SAAM,GAAE,CAAC;QACrB,IAAI,OAAgB,CAAC;QACrB,IAAI,CAAC;YACH,OAAO,GAAG,MAAM,qBAAQ,CAAC,MAAM,CAAC;gBAC9B,QAAQ,EAAE,IAAI;gBACd,IAAI,EAAE,CAAC,yBAAyB,EAAE,cAAc,EAAE,eAAe,CAAC;aACnE,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,GAAG,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,EAAE,qEAAqE,CAAC,CAAC;YAC1F,MAAM,IAAI,KAAK,CAAC,+DAA+D,CAAC,CAAC;QACnF,CAAC;QACD,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,UAAU,CAAC;YACvC,QAAQ,EAAE,EAAE,KAAK,EAAE,gBAAgB,CAAC,CAAC,EAAE,MAAM,EAAE,gBAAgB,CAAC,CAAC,EAAE;YACnE,SAAS,EAAE,0BAA0B;SACtC,CAAC,CAAC;QACH,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,OAAO,EAAE,CAAC;QACrC,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;QAE9C,MAAM,OAAO,GAAY;YACvB,GAAG,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG;YAC1C,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;YACrB,cAAc,EAAE,IAAI,CAAC,GAAG,EAAE;YAC1B,QAAQ,EAAE,EAAE,GAAG,gBAAgB,EAAE;YACjC,GAAG,EAAE,aAAa;SACnB,CAAC;QACF,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;QAChC,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,QAAQ,EAAE,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,EAAE,iBAAiB,CAAC,CAAC;QAE1E,+DAA+D;QAC/D,OAAO,CAAC,IAAI,CAAC,cAAc,EAAE,GAAG,EAAE;YAChC,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,EAAE,mCAAmC,CAAC,CAAC;YACvD,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAC5B,CAAC,CAAC,CAAC;QAEH,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,GAAG,CAAC,GAAW,EAAE,QAAgB;QAC/B,MAAM,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACjC,IAAI,CAAC,CAAC;YAAE,OAAO,IAAI,CAAC;QACpB,IAAI,CAAC,CAAC,QAAQ,KAAK,QAAQ;YAAE,OAAO,IAAI,CAAC;QACzC,CAAC,CAAC,cAAc,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC9B,OAAO,CAAC,CAAC;IACX,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,GAAW;QACvB,MAAM,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACjC,IAAI,CAAC,CAAC;YAAE,OAAO;QACf,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAC1B,IAAI,CAAC;YACH,MAAM,CAAC,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;YACrC,MAAM,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;QAC1B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,sBAAsB,CAAC,CAAC;QACjD,CAAC;QACD,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,EAAE,mBAAmB,CAAC,CAAC;IACpE,CAAC;IAED,KAAK,CAAC,UAAU;QACd,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;QAC9C,MAAM,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QACtD,IAAI,IAAI,CAAC,SAAS;YAAE,aAAa,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAClD,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;QACtB,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC;IACvB,CAAC;IAED,IAAI;QACF,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;IAC5B,CAAC;IAEO,SAAS;QACf,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,KAAK,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YACrC,IAAI,GAAG,GAAG,CAAC,CAAC,cAAc,GAAG,eAAe,EAAE,CAAC;gBAC7C,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,GAAG,CAAC,CAAC,cAAc,EAAE,EAAE,cAAc,CAAC,CAAC;gBAClE,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,qBAAqB,CAAC,CAAC,CAAC;YAChF,CAAC;QACH,CAAC;IACH,CAAC;CACF;AAEY,QAAA,qBAAqB,GAAG,IAAI,cAAc,EAAE,CAAC;AAE1D,8EAA8E;AAC9E,6EAA6E;AAC7E,8EAA8E;AAC9E,2DAA2D;AAE3D,SAAgB,gBAAgB,CAAC,GAAW,EAAE,QAAgB;IAC5D,MAAM,MAAM,GAAG,IAAA,kBAAS,GAAE,CAAC;IAC3B,OAAO,GAAG,CAAC,IAAI,CACb,EAAE,GAAG,EAAE,QAAQ,EAAE,GAAG,EAAE,gBAAgB,EAAE,EACxC,MAAM,CAAC,SAAS,EAChB,EAAE,SAAS,EAAE,IAAI,EAAE,CACpB,CAAC;AACJ,CAAC;AAED,SAAgB,kBAAkB,CAAC,KAAa;IAC9C,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAA,kBAAS,GAAE,CAAC;QAC3B,MAAM,OAAO,GAAG,GAAG,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,SAAS,CAAmB,CAAC;QACtE,IAAI,OAAO,CAAC,GAAG,KAAK,gBAAgB;YAAE,OAAO,IAAI,CAAC;QAClD,IAAI,OAAO,OAAO,CAAC,GAAG,KAAK,QAAQ,IAAI,OAAO,OAAO,CAAC,QAAQ,KAAK,QAAQ;YAAE,OAAO,IAAI,CAAC;QACzF,OAAO,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAAE,CAAC;IAC1D,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"session-manager.js","sourceRoot":"","sources":["../../src/browser-chrome/session-manager.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"browser-chrome.d.ts","sourceRoot":"","sources":["../../src/routes/browser-chrome.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAA0B,MAAM,SAAS,CAAC;AAQzD,QAAA,MAAM,MAAM,EAAE,MAAiB,CAAC;AAkGhC,eAAe,MAAM,CAAC"}
1
+ {"version":3,"file":"browser-chrome.d.ts","sourceRoot":"","sources":["../../src/routes/browser-chrome.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAA0B,MAAM,SAAS,CAAC;AAQzD,QAAA,MAAM,MAAM,EAAE,MAAiB,CAAC;AAsGhC,eAAe,MAAM,CAAC"}
@@ -39,6 +39,10 @@ router.post('/_session', requireBearerAdmin, async (req, res) => {
39
39
  });
40
40
  }
41
41
  catch (err) {
42
+ if (err instanceof session_manager_1.SessionLimitError) {
43
+ res.status(429).json({ error: err.message, limit: err.limit });
44
+ return;
45
+ }
42
46
  log.warn({ err }, 'create session failed');
43
47
  const msg = err instanceof Error ? err.message : 'Session create failed';
44
48
  res.status(500).json({ error: msg });
@@ -1 +1 @@
1
- {"version":3,"file":"browser-chrome.js","sourceRoot":"","sources":["../../src/routes/browser-chrome.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"browser-chrome.js","sourceRoot":"","sources":["../../src/routes/browser-chrome.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import{bH as e,bI as t,r as n,bJ as r,c as a,h as i,bK as o,aX as s,j as l,R as c,d as u,U as d,bL as p,t as m,b2 as g,B as h,A as f,q as b,bM as y,a as E,a8 as v,aa as S,a6 as w,a5 as k,a9 as x,a4 as T,bk as A,aH as _,bz as I,bA as N,bB as R,i as C,bN as O,bO as L,s as D,bP as M,bQ as P,bC as F,bR as B,bE as U,bF as z,S as $,l as G,p as j}from"./index-YwIvszwO.js";import{C as H}from"./chevron-down-DSuYI8m-.js";import{a as q,C as V,u as W,c as Y}from"./index-DLIf9Yfa.js";function K(){!e.current&&t();const[a]=n.useState(r.current);return a}
1
+ import{bH as e,bI as t,r as n,bJ as r,c as a,h as i,bK as o,aX as s,j as l,R as c,d as u,U as d,bL as p,t as m,b2 as g,B as h,A as f,q as b,bM as y,a as E,a8 as v,aa as S,a6 as w,a5 as k,a9 as x,a4 as T,bk as A,aH as _,bz as I,bA as N,bB as R,i as C,bN as O,bO as L,s as D,bP as M,bQ as P,bC as F,bR as B,bE as U,bF as z,S as $,l as G,p as j}from"./index-P6fKDTgI.js";import{C as H}from"./chevron-down-DGJ1q8HL.js";import{a as q,C as V,u as W,c as Y}from"./index-M_4VnkuM.js";function K(){!e.current&&t();const[a]=n.useState(r.current);return a}
2
2
  /**
3
3
  * @license lucide-react v0.309.0 - ISC
4
4
  *
@@ -1,4 +1,4 @@
1
- import{c as e,r as t,b as n,j as i,U as r,B as o,m as a}from"./index-YwIvszwO.js";import{Z as l,a as s}from"./ProjectPage-CKm1NIEx.js";import"./purify.es-CgRAQgUo.js";import"./ChatOverlay-V7DBSoaF.js";import"./chevron-down-DSuYI8m-.js";import"./index-DLIf9Yfa.js";import"./select-BUvVYFSc.js";import"./search-CaBUM8S-.js";
1
+ import{c as e,r as t,b as n,j as i,U as r,B as o,m as a}from"./index-P6fKDTgI.js";import{Z as l,a as s}from"./ProjectPage-C8W6Jx8Z.js";import"./purify.es-CgRAQgUo.js";import"./ChatOverlay-DNblGgsD.js";import"./chevron-down-DGJ1q8HL.js";import"./index-M_4VnkuM.js";import"./select-d9YUOMJ7.js";import"./search-BSUk1egC.js";
2
2
  /**
3
3
  * @license lucide-react v0.309.0 - ISC
4
4
  *
@@ -1,5 +1,5 @@
1
- const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/OfficePreview-CWiJpp9Z.js","assets/index-YwIvszwO.js","assets/index-DB7vdaUN.css","assets/purify.es-CgRAQgUo.js"])))=>i.map(i=>d[i]);
2
- import{c as e,aI as t,br as s,aK as a,r as n,bs as r,bt as l,j as o,bu as c,m as i,d,bv as u,bw as x,bx as m,by as h,bz as p,bA as f,bB as g,ak as b,aj as j,bC as v,bD as y,t as N,ai as w,aD as k,bE as C,U as S,bF as I,a as P,b as z,g as M,D as U,h as T,R as A,_ as E,l as D,X as $,p as L,aV as R,bG as _,C as F,A as H,q as O}from"./index-YwIvszwO.js";import{A as q,g as W,i as B,T as V,j as K,k as G,G as J,M as Q,r as X,a as Y,b as Z,c as ee,e as te,h as se,o as ae,d as ne,I as re,F as le}from"./ChatOverlay-V7DBSoaF.js";import{a as oe}from"./index-DLIf9Yfa.js";import{C as ce}from"./chevron-down-DSuYI8m-.js";
1
+ const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/OfficePreview-CWYidYK8.js","assets/index-P6fKDTgI.js","assets/index-DB7vdaUN.css","assets/purify.es-CgRAQgUo.js"])))=>i.map(i=>d[i]);
2
+ import{c as e,aI as t,br as s,aK as a,r as n,bs as r,bt as l,j as o,bu as c,m as i,d,bv as u,bw as x,bx as m,by as h,bz as p,bA as f,bB as g,ak as b,aj as j,bC as v,bD as y,t as N,ai as w,aD as k,bE as C,U as S,bF as I,a as P,b as z,g as M,D as U,h as T,R as A,_ as E,l as D,X as $,p as L,aV as R,bG as _,C as F,A as H,q as O}from"./index-P6fKDTgI.js";import{A as q,g as W,i as B,T as V,j as K,k as G,G as J,M as Q,r as X,a as Y,b as Z,c as ee,e as te,h as se,o as ae,d as ne,I as re,F as le}from"./ChatOverlay-DNblGgsD.js";import{a as oe}from"./index-M_4VnkuM.js";import{C as ce}from"./chevron-down-DGJ1q8HL.js";
3
3
  /**
4
4
  * @license lucide-react v0.309.0 - ISC
5
5
  *
@@ -11,4 +11,4 @@ import{c as e,aI as t,br as s,aK as a,r as n,bs as r,bt as l,j as o,bu as c,m as
11
11
  *
12
12
  * This source code is licensed under the ISC license.
13
13
  * See the LICENSE file in the root directory of this source tree.
14
- */function he({onSelectProject:e}){const h=t(),p=s(e=>e.clearToken),{projects:f,fetchProjects:g,hasFetched:b,loading:j}=a(),v=n.useCallback(()=>{a.getState().setProjects([]),p(),h("/login")},[p,h]),[y,N]=n.useState(new Map),[w,k]=n.useState(new Set),[C,S]=n.useState(!1);n.useEffect(()=>{g()},[g]);const I=n.useCallback(e=>{e.status&&N(t=>{const s=new Map(t);return s.set(e.projectId,e.status),s}),void 0!==e.active&&k(t=>{const s=new Set(t);return e.active?s.add(e.projectId):s.delete(e.projectId),s})},[]);r({onActivityUpdate:I});const{applyOrder:P}=l(),z=P(f.filter(e=>!e.archived));return o.jsxs("div",{className:"flex flex-col h-full",children:[o.jsxs("div",{className:"flex items-center gap-3 px-4 h-12 border-b border-border shrink-0",children:[o.jsx("span",{className:"font-semibold text-base flex-1",children:"CC Web"}),o.jsx(c,{}),o.jsx("button",{onClick:()=>{(async()=>{S(!0);try{await g()}finally{S(!1)}})()},className:"text-muted-foreground active:text-foreground",disabled:C,"aria-label":"Refresh",children:o.jsx(i,{className:d("h-4 w-4",C&&"animate-spin")})}),o.jsx("button",{onClick:()=>h("/settings"),className:"text-muted-foreground active:text-foreground","aria-label":"Settings",children:o.jsx(u,{className:"h-4 w-4"})}),o.jsx("button",{onClick:v,className:"text-muted-foreground active:text-foreground","aria-label":"Logout",children:o.jsx(x,{className:"h-4 w-4"})}),!me&&o.jsx("button",{onClick:()=>h("/"),className:"text-muted-foreground active:text-foreground","aria-label":"Desktop mode",children:o.jsx(m,{className:"h-4 w-4"})})]}),o.jsxs("div",{className:"flex-1 overflow-y-auto px-3 py-3",children:[j&&!b&&o.jsx("div",{className:"text-center text-muted-foreground text-sm py-12",children:"加载中..."}),b&&0===z.length&&o.jsx("div",{className:"text-center text-muted-foreground text-sm py-12",children:"暂无项目"}),o.jsx("div",{className:"grid grid-cols-2 gap-2",children:z.map(t=>{var s;const a="running"===(s=t,y.get(s.id)??s.status??"stopped"),n=w.has(t.id),r=o.jsxs("button",{onClick:()=>e(t.id),className:d("w-full text-left rounded-xl border bg-card p-2.5 active:bg-accent transition-colors",n?"border-transparent":"border-border"),children:[o.jsxs("div",{className:"flex items-center gap-1.5 mb-1",children:[o.jsx("span",{className:d("w-2 h-2 rounded-full shrink-0",a?"bg-green-500":"bg-zinc-400")}),o.jsx("span",{className:"font-medium text-sm truncate flex-1",children:t.name})]}),o.jsx("div",{className:"text-[10px] text-muted-foreground font-mono truncate",children:t.cliTool??"claude"})]});return o.jsx("div",{className:n?"card-active-glow rounded-xl":void 0,children:r},t.id)})})]})]})}function pe(e){if(!e.phase)return null;if("thinking"===e.phase)return"思考中";if("tool_result"===e.phase)return"处理结果";if("tool_use"===e.phase){const t=(e.detail||"").toLowerCase();return"bash"===t?"执行命令":"read"===t?"读取文件":"edit"===t||"multiedit"===t?"编辑文件":"write"===t?"写入文件":"grep"===t?"搜索内容":"glob"===t?"匹配文件":"webfetch"===t||"websearch"===t?"访问网络":"task"===t?"调度子任务":"todowrite"===t?"更新任务列表":"notebookedit"===t?"编辑 Notebook":e.detail?`调用 ${e.detail}`:"调用工具"}return null}function fe({project:e,onBack:t,onOpenPanel:s,onContextUpdate:a}){const[r,l]=n.useState(""),c=n.useRef(null),i=n.useRef(null),[u,x]=n.useState([]),m=n.useCallback(e=>{x(t=>{const s=[...t,e];return s.length>200?s.slice(-200):s})},[]),P=n.useRef(null),z=n.useCallback(e=>{var t;"stopped"===e&&(null==(t=P.current)||t.call(P,"stopped"))},[]),[M,U]=n.useState(null);n.useEffect(()=>{const t=t=>{const s=t.detail;s&&s.projectId===e.id&&("cli_prompt_detected"===s.type?U({kind:s.kind,label:s.label,detectedAt:s.detectedAt,options:s.options}):"cli_prompt_dismissed"===s.type&&U(e=>(null==e?void 0:e.kind)===s.kind?null:e))};return window.addEventListener("ccweb:cli-prompt-msg",t),()=>window.removeEventListener("ccweb:cli-prompt-msg",t)},[e.id]);const[T,A]=n.useState([]),E=n.useRef(new Set),D=n.useCallback(e=>{E.current.has(e.toolUseId)||A(t=>t.some(t=>t.toolUseId===e.toolUseId)?t:[...t,{projectId:e.projectId,toolUseId:e.toolUseId,toolName:e.toolName,toolInput:e.toolInput,sessionId:e.sessionId,createdAt:e.createdAt}])},[]),$=n.useCallback(e=>{E.current.add(e.toolUseId),A(t=>t.filter(t=>t.toolUseId!==e.toolUseId))},[]),L=n.useCallback(e=>{E.current.add(e),A(t=>t.filter(t=>t.toolUseId!==e))},[]),[R,_]=n.useState(null),F=n.useRef(0),H=n.useCallback(e=>{var t,s,a;if(!e.active)return void _(null);if("text"===(null==(t=e.semantic)?void 0:t.phase))return void _(null);const n=null==(s=e.semantic)?void 0:s.phase,r=null==(a=e.semantic)?void 0:a.detail;_(e=>e?e.phase===n&&e.detail===r?e:{...e,phase:n,detail:r}:{id:"mab"+ ++F.current,phase:n,detail:r})},[]),{sendInput:O,connected:Q}=h({projectId:e.id,enabled:!0,onChatMessage:m,onStatusChange:z,onContextUpdate:a,onApprovalRequest:D,onApprovalResolved:$,onSemanticUpdate:H});n.useEffect(()=>{let t=!1;if(U(null),Q)return p(e.id).then(e=>{!t&&e.active&&U({kind:e.active.kind,label:e.active.label,detectedAt:e.active.detectedAt,options:e.active.options})}).catch(()=>{}),()=>{t=!0}},[e.id,Q]),n.useEffect(()=>{if(!Q)return;if("claude"!==e.cliTool)return;let t=!1;return f(e.id).then(e=>{if(t)return;const s=e.pending.filter(e=>!E.current.has(e.toolUseId));A(e=>{const t=new Map;for(const a of s)t.set(a.toolUseId,a);for(const s of e)t.has(s.toolUseId)||E.current.has(s.toolUseId)||t.set(s.toolUseId,s);return[...t.values()]})}).catch(()=>{}),()=>{t=!0}},[e.id,e.cliTool,Q]);const{state:X,setState:Y,messages:Z,hasMoreHistory:ee,loadMoreHistory:te,sendMessage:se,isWaking:ae}=g({project:e,liveMessages:u,ws:{send:O,connected:Q},historyLimit:20});P.current=Y;const ne=n.useRef(Q);n.useEffect(()=>{!ne.current&&Q&&x([]),ne.current=Q},[Q]);const re=(()=>{for(let e=Z.length-1;e>=0;e--)if("assistant"===Z[e].role)return e;return-1})(),[le,de]=n.useState([]),[ue,me]=n.useState([]),[he,fe]=n.useState(null),[ge,be]=n.useState(null),je=n.useRef(!1);n.useEffect(()=>{b().then(de).catch(()=>{}),j(e.id).then(me).catch(()=>{})},[e.id]);const ve=n.useCallback(e=>{const t=i.current;if(!t)return void l(t=>t+e);const s=t.selectionStart??r.length,a=t.selectionEnd??r.length,n=r.slice(0,s)+e+r.slice(a);l(n),requestAnimationFrame(()=>{t.focus();const a=s+e.length;t.setSelectionRange(a,a),t.style.height="auto",t.style.height=Math.min(t.scrollHeight,128)+"px"})},[r]),ye=n.useCallback(e=>{fe(null),ve(e+" ")},[ve]),Ne=n.useCallback(t=>{const s=e.folderPath;let a=t;s&&(t===s||t.startsWith(s+"/")||t.startsWith(s+"\\"))&&(a=t.slice(s.length).replace(/^[/\\]+/,"")),fe(null),ve(`@${a} `)},[e.folderPath,ve]),we=n.useCallback(async()=>{if("skills"!==he){if(!je.current){je.current=!0;try{const t=await v(e.cliTool??"claude",e.id);be(t)}catch{be({builtin:[],custom:[],plugins:[],mcp:[]})}finally{je.current=!1}}fe("skills")}else fe(null)},[he,e.cliTool,e.id]),ke=n.useCallback(async()=>{const e=c.current,t=(null==e?void 0:e.scrollHeight)??0;await te(),requestAnimationFrame(()=>{e&&(e.scrollTop+=e.scrollHeight-t)})},[te]),Ce=n.useRef(0);n.useEffect(()=>{const e=c.current;if(!e)return;const t=Z.length>Ce.current,s=0===Ce.current&&Z.length>0;Ce.current=Z.length,s?e.scrollTo({top:e.scrollHeight}):t&&e.scrollTo({top:e.scrollHeight,behavior:"smooth"})},[Z,T.length]);const[Se,Ie]=n.useState(!1),Pe=n.useCallback(async()=>{const e=r.trim();if(!e||Se)return;Ie(!0);const t=await se(e);Ie(!1),"delivered"===t&&(l(""),i.current&&(i.current.style.height="auto"))},[r,Se,se]),ze=y(Pe,"shift"),Me=n.useCallback(async(t,s)=>{fe(null);try{"failed"===await se(t.command)?N.error("快捷命令未送达,请重试或检查会话"):"project"===s&&w(e.id,t.id,!0).catch(e=>{console.error("Failed to mark shortcut used:",e)})}catch(a){console.error("Shortcut send error:",a),N.error("快捷命令发送失败")}},[se,e.id]),Ue="live"===X;return o.jsxs("div",{className:"flex flex-col h-full bg-background",children:[o.jsxs("div",{className:"flex items-center gap-2 px-3 h-12 border-b border-border shrink-0",children:[o.jsx("button",{onClick:t,className:"text-muted-foreground active:text-foreground p-1",children:o.jsx(k,{className:"h-5 w-5"})}),o.jsxs("div",{className:"flex items-center gap-1.5 flex-1 min-w-0",children:[o.jsx("span",{className:"font-medium text-sm truncate",children:e.name}),o.jsx("span",{className:d("w-2 h-2 rounded-full shrink-0",Ue?"bg-green-500":ae?"bg-yellow-400 animate-pulse":"bg-zinc-400")})]}),o.jsx("button",{onClick:s,className:"text-muted-foreground active:text-foreground p-1",children:o.jsx(xe,{className:"h-5 w-5"})})]}),o.jsxs("div",{ref:c,className:"flex-1 overflow-y-auto px-3 py-3 space-y-3 min-h-0",children:[ee&&o.jsx("div",{className:"flex justify-center pb-1",children:o.jsxs("button",{onClick:()=>{ke()},className:"flex items-center gap-1 px-3 py-1.5 rounded-full text-xs text-muted-foreground border border-border active:bg-accent transition-colors",children:[o.jsx(oe,{className:"h-3 w-3"}),"加载更早消息"]})}),Z.map((e,t)=>{const s="user"===e.role;return o.jsx("div",{className:d("flex",s?"justify-end":"justify-start"),children:o.jsx("div",{className:d("max-w-[85%] rounded-xl px-3 py-2 break-words text-sm leading-relaxed",s?"bg-blue-500/15 text-foreground border border-blue-500/20 rounded-br-sm whitespace-pre-wrap":"bg-secondary text-secondary-foreground border border-border rounded-bl-sm"),children:s?e.content:o.jsx(q,{content:e.content,blocks:e.blocks,isLatest:t===re})})},e.id)}),T.map(e=>o.jsx(W,{approval:e,onResolved:L},e.toolUseId)),M&&o.jsx(B,{prompt:M,onSelect:async t=>{await C(e.id,t)}}),R&&0===T.length&&o.jsx("div",{className:"flex justify-start",children:o.jsxs("div",{className:"rounded-2xl rounded-bl-md px-3 py-1.5 bg-black/5 dark:bg-white/10 border border-black/10 dark:border-white/15 flex items-center gap-2 text-xs text-muted-foreground",children:[o.jsx(V,{}),pe(R)&&o.jsx("span",{children:pe(R)})]})},R.id),0===Z.length&&0===T.length&&!R&&"stopped"===X&&o.jsx("div",{className:"flex items-center justify-center h-full text-muted-foreground/40 text-sm",children:"暂无对话记录"}),ae&&o.jsx("div",{className:"flex items-center justify-center py-4 text-yellow-400 text-sm animate-pulse",children:"启动中..."})]}),"global"===he||"project"===he?o.jsx("div",{className:"border-t border-border max-h-48 overflow-y-auto shrink-0",children:o.jsxs("div",{className:"px-3 py-2 space-y-1",children:[("global"===he?le:ue).map(e=>o.jsxs("button",{onClick:()=>Me(e,he),disabled:ae,className:d("w-full text-left rounded-md px-2.5 py-2 text-sm active:bg-accent transition-colors border border-border/50",ae&&"opacity-50 cursor-not-allowed"),children:[o.jsx("div",{className:"font-medium text-xs",children:e.label}),o.jsx("div",{className:"text-[11px] text-muted-foreground font-mono truncate",children:e.command})]},e.id)),0===("global"===he?le:ue).length&&o.jsx("div",{className:"text-center text-muted-foreground text-xs py-3",children:"暂无快捷 Prompts"})]})}):"skills"===he&&ge?o.jsx("div",{className:"border-t border-border shrink-0",children:o.jsx(K,{data:ge,onCommand:ye})}):"files"===he&&e.folderPath?o.jsx("div",{className:"border-t border-border shrink-0",children:o.jsx(G,{projectPath:e.folderPath,onSelect:Ne})}):null,o.jsxs("div",{className:"flex items-center gap-1.5 px-3 py-1.5 border-t border-border shrink-0",children:[o.jsx("button",{onClick:()=>{we()},title:"斜杠命令",className:d("flex items-center justify-center w-7 h-7 rounded font-mono text-base transition-colors","skills"===he?"bg-accent text-foreground font-medium":"text-muted-foreground active:bg-accent"),children:"/"}),o.jsx("button",{onClick:()=>fe(e=>"files"===e?null:"files"),disabled:!e.folderPath,title:"引用文件",className:d("flex items-center justify-center w-7 h-7 rounded font-mono text-base transition-colors","files"===he?"bg-accent text-foreground font-medium":e.folderPath?"text-muted-foreground active:bg-accent":"text-muted-foreground/30 cursor-not-allowed"),children:"@"}),le.length>0&&o.jsxs("button",{onClick:()=>fe(e=>"global"===e?null:"global"),className:d("flex items-center gap-1 px-2 py-1 rounded-md text-xs transition-colors","global"===he?"bg-accent text-foreground font-medium":"text-muted-foreground active:bg-accent"),children:[o.jsx(J,{className:"h-3 w-3"}),"全局","global"===he&&o.jsx(ce,{className:"h-3 w-3"})]}),ue.length>0&&o.jsxs("button",{onClick:()=>fe(e=>"project"===e?null:"project"),className:d("flex items-center gap-1 px-2 py-1 rounded-md text-xs transition-colors","project"===he?"bg-accent text-foreground font-medium":"text-muted-foreground active:bg-accent"),children:[o.jsx(ie,{className:"h-3 w-3"}),"项目","project"===he&&o.jsx(ce,{className:"h-3 w-3"})]})]}),o.jsx("div",{className:"border-t border-border px-3 py-2 shrink-0",style:{paddingBottom:"max(0.5rem, env(safe-area-inset-bottom))"},children:o.jsxs("div",{className:"flex items-end gap-2",children:[o.jsx("textarea",{ref:i,value:r,onChange:e=>l(e.target.value),onKeyDown:ze,disabled:ae||Se,placeholder:ae?"启动中...":Se?"发送中…":"stopped"===X?"输入消息(自动启动)...":"输入消息...",rows:1,className:d("flex-1 resize-none rounded-md border border-input bg-transparent px-3 py-2 text-sm outline-none","focus:ring-1 focus:ring-ring placeholder:text-muted-foreground/50","max-h-32 overflow-y-auto",(ae||Se)&&"opacity-50 cursor-not-allowed"),style:{minHeight:"2.5rem"},onInput:e=>{const t=e.currentTarget;t.style.height="auto",t.style.height=Math.min(t.scrollHeight,128)+"px"}}),o.jsx("button",{onClick:Pe,disabled:ae||Se||!r.trim(),className:d("shrink-0 p-2 rounded-md transition-colors",r.trim()&&!Se?"text-blue-500 active:bg-blue-500/10":"text-muted-foreground/30"),children:Se?o.jsx(S,{className:"h-5 w-5 animate-spin"}):o.jsx(I,{className:"h-5 w-5"})})]})})]})}const ge=A.lazy(()=>E(()=>import("./OfficePreview-CWiJpp9Z.js"),__vite__mapDeps([0,1,2,3])).then(e=>({default:e.OfficePreview}))),be=new Set(["png","jpg","jpeg","gif","webp","svg","bmp","ico","avif"]),je=new Set(["docx","xlsx","xls","pptx"]),ve={js:"javascript",jsx:"jsx",ts:"typescript",tsx:"tsx",py:"python",rb:"ruby",go:"go",rs:"rust",java:"java",kt:"kotlin",swift:"swift",c:"c",cpp:"cpp",h:"c",cs:"csharp",php:"php",sh:"bash",bash:"bash",zsh:"bash",yaml:"yaml",yml:"yaml",json:"json",toml:"toml",html:"html",htm:"html",xml:"xml",svg:"xml",css:"css",scss:"scss",less:"less",sql:"sql",graphql:"graphql",gql:"graphql",dockerfile:"docker",makefile:"makefile",r:"r",lua:"lua",dart:"dart",zig:"zig"};function ye(e){return e.split("/").pop()??e}function Ne({filePath:e,onBack:t}){const[s,a]=n.useState(null),[r,l]=n.useState(!0),[c,i]=n.useState(null),{resolved:d}=P(),u=function(e){const t=e.split("/").pop()??"",s=t.toLowerCase();if("dockerfile"===s)return"dockerfile";if("makefile"===s)return"makefile";const a=t.lastIndexOf(".");return a>=0?t.slice(a+1).toLowerCase():""}(e),x=be.has(u),m=je.has(u),h=ve[u],p="dark"===d;n.useEffect(()=>{x||m?l(!1):(l(!0),i(null),z(e).then(a).catch(e=>i(e instanceof Error?e.message:"Failed to load")).finally(()=>l(!1)))},[e,x,m]);const f=T(e),g=n.useMemo(()=>{const e=M();return e?`${f}&token=${encodeURIComponent(e)}`:f},[f]),b=n.useMemo(()=>x?`${g}&t=${Date.now()}`:"",[g,x]);return o.jsxs("div",{className:"flex flex-col h-full",children:[o.jsxs("div",{className:"flex items-center gap-2 px-3 h-12 border-b border-border shrink-0",children:[o.jsx("button",{onClick:t,className:"text-muted-foreground active:text-foreground p-1",children:o.jsx(k,{className:"h-5 w-5"})}),o.jsx("span",{className:"flex-1 text-sm font-medium truncate",children:ye(e)}),o.jsx("a",{href:g,download:!0,className:"text-muted-foreground active:text-foreground p-1",onClick:e=>e.stopPropagation(),children:o.jsx(U,{className:"h-4 w-4"})})]}),o.jsxs("div",{className:"flex-1 overflow-auto min-h-0",children:[r&&o.jsx("div",{className:"flex items-center justify-center py-12",children:o.jsx(S,{className:"h-5 w-5 animate-spin text-muted-foreground"})}),c&&o.jsx("div",{className:"text-center text-destructive text-sm py-12 px-4",children:c}),x&&o.jsx("div",{className:"flex items-center justify-center p-4 h-full",children:o.jsx("img",{src:b,alt:ye(e),className:"max-w-full max-h-full object-contain rounded",style:{touchAction:"pinch-zoom"}})}),m&&o.jsx(n.Suspense,{fallback:o.jsx("div",{className:"flex items-center justify-center py-12",children:o.jsx(S,{className:"h-5 w-5 animate-spin text-muted-foreground"})}),children:o.jsx(ge,{filePath:e,ext:u,zoom:100})}),s&&(s.binary||s.tooLarge)&&o.jsxs("div",{className:"text-center py-12 px-4 space-y-3",children:[o.jsxs("p",{className:"text-muted-foreground text-sm",children:[s.binary?"二进制文件":"文件过大",s.size>0&&` (${j=s.size,j<1024?`${j} B`:j<1048576?`${(j/1024).toFixed(1)} KB`:`${(j/1048576).toFixed(1)} MB`})`]}),o.jsxs("a",{href:g,download:!0,className:"inline-flex items-center gap-1.5 text-sm text-blue-500 active:text-blue-400",children:[o.jsx(U,{className:"h-4 w-4"}),"下载文件"]})]}),s&&!s.binary&&!s.tooLarge&&null!=s.content&&o.jsxs(o.Fragment,{children:["md"===u&&o.jsx("div",{className:"prose prose-sm dark:prose-invert max-w-none px-4 py-3",children:o.jsx(Q,{remarkPlugins:[Y,Z],rehypePlugins:[X],urlTransform:(e,t,s)=>"src"===t&&"img"===s.tagName?e:te(e),components:{img:({src:t,alt:s,...a})=>o.jsx("img",{...a,src:ee(e,t,M()),alt:s??"",loading:"lazy",style:{maxWidth:"100%",height:"auto"}})},children:s.content})}),"md"!==u&&h&&o.jsx(se,{language:h,style:p?ae:ne,customStyle:{margin:0,fontSize:"12px",borderRadius:0},showLineNumbers:!0,children:s.content}),"md"!==u&&!h&&o.jsx("pre",{className:"p-4 text-xs font-mono whitespace-pre-wrap break-words",children:s.content})]})]})]});var j}const we=new Set(["png","jpg","jpeg","gif","webp","svg","bmp","ico","avif"]),ke=new Set(["js","jsx","ts","tsx","py","rb","go","rs","java","c","cpp","h","swift","kt","cs","php","sh","bash","zsh","r","lua","dart","zig","css","scss","less","html","htm","xml","sql"]),Ce=new Set(["json","yaml","yml","toml","csv","tsv"]);function Se({entry:e}){if("dir"===e.type)return o.jsx(L,{className:"h-8 w-8 text-blue-400"});const t=function(e){const t=e.lastIndexOf(".");return t>=0?e.slice(t+1).toLowerCase():""}(e.name);return we.has(t)?o.jsx(re,{className:"h-8 w-8 text-emerald-400"}):ke.has(t)?o.jsx(de,{className:"h-8 w-8 text-orange-400"}):Ce.has(t)?o.jsx(ue,{className:"h-8 w-8 text-yellow-400"}):"md"===t?o.jsx(le,{className:"h-8 w-8 text-sky-400"}):o.jsx(R,{className:"h-8 w-8 text-muted-foreground"})}function Ie({rootPath:e,onClose:t}){const[s,a]=n.useState(e),[r,l]=n.useState([]),[c,i]=n.useState(!0),[d,u]=n.useState(null),x=n.useCallback(async e=>{i(!0);try{const t=[...(await D(e)).entries].sort((e,t)=>e.type!==t.type?"dir"===e.type?-1:1:e.name.localeCompare(t.name));l(t),a(e)}catch{l([])}finally{i(!1)}},[]);n.useEffect(()=>{x(e)},[e,x]);const m=s!==e,h=s.startsWith(e)?s.slice(e.length)||"/":s;return d?o.jsx(Ne,{filePath:d,onBack:()=>u(null)}):o.jsxs("div",{className:"flex flex-col h-full",children:[o.jsxs("div",{className:"flex items-center gap-2 px-3 h-12 border-b border-border shrink-0",children:[o.jsx("button",{onClick:t,className:"text-muted-foreground active:text-foreground p-1",children:o.jsx($,{className:"h-5 w-5"})}),o.jsxs("div",{className:"flex items-center gap-1 flex-1 min-w-0 text-sm",children:[m&&o.jsx("button",{onClick:()=>{if(s===e)return;const t=s.replace(/\/[^/]+$/,"")||"/";t.startsWith(e)&&x(t)},className:"text-muted-foreground active:text-foreground p-0.5 shrink-0",children:o.jsx(k,{className:"h-4 w-4"})}),o.jsx("span",{className:"truncate text-muted-foreground font-mono text-xs",children:h})]})]}),o.jsxs("div",{className:"flex-1 overflow-y-auto px-3 py-3",children:[c&&o.jsx("div",{className:"flex items-center justify-center py-12",children:o.jsx(S,{className:"h-5 w-5 animate-spin text-muted-foreground"})}),!c&&0===r.length&&o.jsx("div",{className:"text-center text-muted-foreground text-sm py-12",children:"空目录"}),!c&&o.jsx("div",{className:"grid grid-cols-3 gap-1",children:r.map(e=>o.jsxs("button",{onClick:()=>(e=>{"dir"===e.type?x(e.path):u(e.path)})(e),className:"flex flex-col items-center gap-1 p-2 rounded-md active:bg-accent transition-colors",children:[o.jsx(Se,{entry:e}),o.jsx("span",{className:"text-[11px] text-center leading-tight w-full line-clamp-2 break-all",children:e.name})]},e.path))})]})]})}function Pe(e){return e<50?"text-green-400":e<80?"text-yellow-400":"text-red-400"}function ze(e){return e<50?"bg-green-500":e<80?"bg-yellow-500":"bg-red-500"}function Me({projectName:e,cliTool:t,folderPath:s,contextData:a,onClose:r}){const[l,c]=n.useState(new Set(["context","usage","files"])),[u,x]=n.useState(null),[m,h]=n.useState(!1),p=e=>{c(t=>{const s=new Set(t);return s.has(e)?s.delete(e):s.add(e),s})};n.useEffect(()=>{h(!0),_(t).then(x).catch(()=>x(null)).finally(()=>h(!1))},[t]);const f=a?Math.round(a.usedPercentage):null;return o.jsxs("div",{className:"flex flex-col h-full",children:[o.jsxs("div",{className:"flex items-center gap-2 px-3 h-12 border-b border-border shrink-0",children:[o.jsx("button",{onClick:r,className:"text-muted-foreground active:text-foreground p-1",children:o.jsx($,{className:"h-5 w-5"})}),o.jsx("span",{className:"flex-1 font-medium text-sm truncate",children:e})]}),o.jsxs("div",{className:"flex-1 overflow-y-auto",children:[o.jsxs("button",{onClick:()=>p("context"),className:"w-full flex items-center gap-2 px-4 py-2.5 border-b border-border/50 active:bg-accent",children:[l.has("context")?o.jsx(ce,{className:"h-3.5 w-3.5 text-muted-foreground"}):o.jsx(F,{className:"h-3.5 w-3.5 text-muted-foreground"}),o.jsx("span",{className:"text-sm font-medium",children:"上下文"}),null!==f&&o.jsxs("span",{className:d("text-xs font-mono ml-auto",Pe(f)),children:[f,"%"]})]}),l.has("context")&&o.jsx("div",{className:"px-4 py-3 border-b border-border/50",children:null!==f&&a?o.jsxs("div",{className:"space-y-2",children:[o.jsxs("div",{className:"flex items-center gap-2",children:[o.jsx("div",{className:"flex-1 h-2 bg-secondary rounded-full overflow-hidden",children:o.jsx("div",{className:d("h-full rounded-full transition-all",ze(f)),style:{width:`${Math.min(f,100)}%`}})}),o.jsxs("span",{className:d("text-xs font-mono w-10 text-right",Pe(f)),children:[f,"%"]})]}),o.jsxs("div",{className:"grid grid-cols-2 gap-x-4 gap-y-1 text-[11px] text-muted-foreground",children:[o.jsx("span",{children:"窗口大小"}),o.jsx("span",{className:"text-right font-mono",children:a.contextWindowSize>=1e6?`${(a.contextWindowSize/1e6).toFixed(1)}M`:`${Math.round(a.contextWindowSize/1e3)}K`}),o.jsx("span",{children:"输入 tokens"}),o.jsx("span",{className:"text-right font-mono",children:a.inputTokens.toLocaleString()}),o.jsx("span",{children:"输出 tokens"}),o.jsx("span",{className:"text-right font-mono",children:a.outputTokens.toLocaleString()})]})]}):o.jsx("div",{className:"text-xs text-muted-foreground/50 text-center py-2",children:"暂无数据"})}),o.jsxs("div",{className:"w-full flex items-center gap-2 px-4 py-2.5 border-b border-border/50 cursor-pointer",role:"button",tabIndex:0,onClick:()=>p("usage"),onKeyDown:e=>{"Enter"!==e.key&&" "!==e.key||p("usage")},children:[l.has("usage")?o.jsx(ce,{className:"h-3.5 w-3.5 text-muted-foreground"}):o.jsx(F,{className:"h-3.5 w-3.5 text-muted-foreground"}),o.jsx("span",{className:"text-sm font-medium",children:"用量"}),o.jsx("button",{onClick:e=>{e.stopPropagation(),(async()=>{h(!0);try{const{refreshUsage:e}=await E(async()=>{const{refreshUsage:e}=await import("./index-YwIvszwO.js").then(e=>e.bU);return{refreshUsage:e}},__vite__mapDeps([1,2]));x(await e(t))}catch{}finally{h(!1)}})()},className:"ml-auto text-muted-foreground active:text-foreground",children:o.jsx(i,{className:d("h-3 w-3",m&&"animate-spin")})})]}),l.has("usage")&&o.jsx("div",{className:"px-4 py-3 border-b border-border/50",children:u?o.jsxs("div",{className:"space-y-2",children:[u.planName&&o.jsxs("div",{className:"text-[11px] text-muted-foreground",children:["Plan: ",o.jsx("span",{className:"font-medium text-foreground",children:u.planName})]}),o.jsx(Ue,{label:"5h",bucket:u.fiveHour}),o.jsx(Ue,{label:"7d",bucket:u.sevenDay}),u.sevenDaySonnet&&o.jsx(Ue,{label:"7d Sonnet",bucket:u.sevenDaySonnet}),u.sevenDayOpus&&o.jsx(Ue,{label:"7d Opus",bucket:u.sevenDayOpus}),!u.fiveHour&&!u.sevenDay&&o.jsx("div",{className:"text-xs text-muted-foreground/50 text-center",children:"暂无数据"})]}):o.jsx("div",{className:"text-xs text-muted-foreground/50 text-center py-2",children:m?"加载中...":"暂无数据"})}),o.jsxs("button",{onClick:()=>p("files"),className:"w-full flex items-center gap-2 px-4 py-2.5 border-b border-border/50 active:bg-accent",children:[l.has("files")?o.jsx(ce,{className:"h-3.5 w-3.5 text-muted-foreground"}):o.jsx(F,{className:"h-3.5 w-3.5 text-muted-foreground"}),o.jsx("span",{className:"text-sm font-medium",children:"文件"})]}),l.has("files")&&o.jsx("div",{className:"h-[60vh]",children:o.jsx(Ie,{rootPath:s,onClose:()=>p("files")})})]})]})}function Ue({label:e,bucket:t}){if(!t||void 0===t.utilization)return null;const s=t.utilization,a=function(e){if(!e)return"";const t=new Date(e).getTime()-Date.now();if(t<=0)return"即将重置";const s=Math.floor(t/36e5),a=Math.floor(t%36e5/6e4);return s>0?`${s}h${a}m`:`${a}m`}(t.resetAt);return o.jsxs("div",{className:"flex items-center gap-2",children:[o.jsx("span",{className:"text-xs text-muted-foreground w-16",children:e}),o.jsx("div",{className:"flex-1 h-1.5 bg-secondary rounded-full overflow-hidden",children:o.jsx("div",{className:d("h-full rounded-full",ze(s)),style:{width:`${Math.min(s,100)}%`}})}),o.jsxs("span",{className:d("text-xs font-mono w-8 text-right",Pe(s)),children:[s,"%"]}),a&&o.jsx("span",{className:"text-[10px] text-muted-foreground/60",children:a})]})}function Te(){n.useEffect(()=>{const e=document.querySelector('meta[name="viewport"]');if(!e)return;const t=e.getAttribute("content")??"";return e.setAttribute("content","width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover"),()=>{e.setAttribute("content",t)}},[]);const[e,t]=n.useState({screen:"list"}),[s,r]=n.useState(null),l=a(e=>e.projects),c=n.useCallback(e=>{t({screen:"chat",projectId:e}),r(null)},[]),i=n.useCallback(e=>{t({screen:"panel",projectId:e})},[]),d=n.useCallback(()=>{t(e=>"panel"===e.screen?{screen:"chat",projectId:e.projectId}:{screen:"list"})},[]),u="list"!==e.screen?l.find(t=>t.id===e.projectId):void 0;return o.jsxs("div",{className:"fixed inset-0 bg-background overflow-hidden",children:[o.jsxs(H,{mode:"wait",children:["list"===e.screen&&o.jsx(O.div,{className:"absolute inset-0",initial:{opacity:0},animate:{opacity:1},exit:{x:"-30%",opacity:0},transition:{duration:.2},style:{paddingTop:"env(safe-area-inset-top)"},children:o.jsx(he,{onSelectProject:c})},"list"),"chat"===e.screen&&u&&o.jsx(O.div,{className:"absolute inset-0",initial:{x:"100%"},animate:{x:0},exit:{x:"100%"},transition:{type:"tween",duration:.25},style:{paddingTop:"env(safe-area-inset-top)"},children:o.jsx(fe,{project:u,onBack:d,onOpenPanel:()=>i(e.projectId),onContextUpdate:r})},`chat-${e.projectId}`)]}),o.jsx(H,{children:"panel"===e.screen&&u&&o.jsx(O.div,{className:"absolute inset-0 z-50 bg-background",initial:{x:"100%"},animate:{x:0},exit:{x:"100%"},transition:{type:"tween",duration:.25},style:{paddingTop:"env(safe-area-inset-top)"},children:o.jsx(Me,{projectName:u.name,cliTool:u.cliTool??"claude",folderPath:u.folderPath,contextData:s,onClose:d})},"panel")})]})}export{Te as MobilePage};
14
+ */function he({onSelectProject:e}){const h=t(),p=s(e=>e.clearToken),{projects:f,fetchProjects:g,hasFetched:b,loading:j}=a(),v=n.useCallback(()=>{a.getState().setProjects([]),p(),h("/login")},[p,h]),[y,N]=n.useState(new Map),[w,k]=n.useState(new Set),[C,S]=n.useState(!1);n.useEffect(()=>{g()},[g]);const I=n.useCallback(e=>{e.status&&N(t=>{const s=new Map(t);return s.set(e.projectId,e.status),s}),void 0!==e.active&&k(t=>{const s=new Set(t);return e.active?s.add(e.projectId):s.delete(e.projectId),s})},[]);r({onActivityUpdate:I});const{applyOrder:P}=l(),z=P(f.filter(e=>!e.archived));return o.jsxs("div",{className:"flex flex-col h-full",children:[o.jsxs("div",{className:"flex items-center gap-3 px-4 h-12 border-b border-border shrink-0",children:[o.jsx("span",{className:"font-semibold text-base flex-1",children:"CC Web"}),o.jsx(c,{}),o.jsx("button",{onClick:()=>{(async()=>{S(!0);try{await g()}finally{S(!1)}})()},className:"text-muted-foreground active:text-foreground",disabled:C,"aria-label":"Refresh",children:o.jsx(i,{className:d("h-4 w-4",C&&"animate-spin")})}),o.jsx("button",{onClick:()=>h("/settings"),className:"text-muted-foreground active:text-foreground","aria-label":"Settings",children:o.jsx(u,{className:"h-4 w-4"})}),o.jsx("button",{onClick:v,className:"text-muted-foreground active:text-foreground","aria-label":"Logout",children:o.jsx(x,{className:"h-4 w-4"})}),!me&&o.jsx("button",{onClick:()=>h("/"),className:"text-muted-foreground active:text-foreground","aria-label":"Desktop mode",children:o.jsx(m,{className:"h-4 w-4"})})]}),o.jsxs("div",{className:"flex-1 overflow-y-auto px-3 py-3",children:[j&&!b&&o.jsx("div",{className:"text-center text-muted-foreground text-sm py-12",children:"加载中..."}),b&&0===z.length&&o.jsx("div",{className:"text-center text-muted-foreground text-sm py-12",children:"暂无项目"}),o.jsx("div",{className:"grid grid-cols-2 gap-2",children:z.map(t=>{var s;const a="running"===(s=t,y.get(s.id)??s.status??"stopped"),n=w.has(t.id),r=o.jsxs("button",{onClick:()=>e(t.id),className:d("w-full text-left rounded-xl border bg-card p-2.5 active:bg-accent transition-colors",n?"border-transparent":"border-border"),children:[o.jsxs("div",{className:"flex items-center gap-1.5 mb-1",children:[o.jsx("span",{className:d("w-2 h-2 rounded-full shrink-0",a?"bg-green-500":"bg-zinc-400")}),o.jsx("span",{className:"font-medium text-sm truncate flex-1",children:t.name})]}),o.jsx("div",{className:"text-[10px] text-muted-foreground font-mono truncate",children:t.cliTool??"claude"})]});return o.jsx("div",{className:n?"card-active-glow rounded-xl":void 0,children:r},t.id)})})]})]})}function pe(e){if(!e.phase)return null;if("thinking"===e.phase)return"思考中";if("tool_result"===e.phase)return"处理结果";if("tool_use"===e.phase){const t=(e.detail||"").toLowerCase();return"bash"===t?"执行命令":"read"===t?"读取文件":"edit"===t||"multiedit"===t?"编辑文件":"write"===t?"写入文件":"grep"===t?"搜索内容":"glob"===t?"匹配文件":"webfetch"===t||"websearch"===t?"访问网络":"task"===t?"调度子任务":"todowrite"===t?"更新任务列表":"notebookedit"===t?"编辑 Notebook":e.detail?`调用 ${e.detail}`:"调用工具"}return null}function fe({project:e,onBack:t,onOpenPanel:s,onContextUpdate:a}){const[r,l]=n.useState(""),c=n.useRef(null),i=n.useRef(null),[u,x]=n.useState([]),m=n.useCallback(e=>{x(t=>{const s=[...t,e];return s.length>200?s.slice(-200):s})},[]),P=n.useRef(null),z=n.useCallback(e=>{var t;"stopped"===e&&(null==(t=P.current)||t.call(P,"stopped"))},[]),[M,U]=n.useState(null);n.useEffect(()=>{const t=t=>{const s=t.detail;s&&s.projectId===e.id&&("cli_prompt_detected"===s.type?U({kind:s.kind,label:s.label,detectedAt:s.detectedAt,options:s.options}):"cli_prompt_dismissed"===s.type&&U(e=>(null==e?void 0:e.kind)===s.kind?null:e))};return window.addEventListener("ccweb:cli-prompt-msg",t),()=>window.removeEventListener("ccweb:cli-prompt-msg",t)},[e.id]);const[T,A]=n.useState([]),E=n.useRef(new Set),D=n.useCallback(e=>{E.current.has(e.toolUseId)||A(t=>t.some(t=>t.toolUseId===e.toolUseId)?t:[...t,{projectId:e.projectId,toolUseId:e.toolUseId,toolName:e.toolName,toolInput:e.toolInput,sessionId:e.sessionId,createdAt:e.createdAt}])},[]),$=n.useCallback(e=>{E.current.add(e.toolUseId),A(t=>t.filter(t=>t.toolUseId!==e.toolUseId))},[]),L=n.useCallback(e=>{E.current.add(e),A(t=>t.filter(t=>t.toolUseId!==e))},[]),[R,_]=n.useState(null),F=n.useRef(0),H=n.useCallback(e=>{var t,s,a;if(!e.active)return void _(null);if("text"===(null==(t=e.semantic)?void 0:t.phase))return void _(null);const n=null==(s=e.semantic)?void 0:s.phase,r=null==(a=e.semantic)?void 0:a.detail;_(e=>e?e.phase===n&&e.detail===r?e:{...e,phase:n,detail:r}:{id:"mab"+ ++F.current,phase:n,detail:r})},[]),{sendInput:O,connected:Q}=h({projectId:e.id,enabled:!0,onChatMessage:m,onStatusChange:z,onContextUpdate:a,onApprovalRequest:D,onApprovalResolved:$,onSemanticUpdate:H});n.useEffect(()=>{let t=!1;if(U(null),Q)return p(e.id).then(e=>{!t&&e.active&&U({kind:e.active.kind,label:e.active.label,detectedAt:e.active.detectedAt,options:e.active.options})}).catch(()=>{}),()=>{t=!0}},[e.id,Q]),n.useEffect(()=>{if(!Q)return;if("claude"!==e.cliTool)return;let t=!1;return f(e.id).then(e=>{if(t)return;const s=e.pending.filter(e=>!E.current.has(e.toolUseId));A(e=>{const t=new Map;for(const a of s)t.set(a.toolUseId,a);for(const s of e)t.has(s.toolUseId)||E.current.has(s.toolUseId)||t.set(s.toolUseId,s);return[...t.values()]})}).catch(()=>{}),()=>{t=!0}},[e.id,e.cliTool,Q]);const{state:X,setState:Y,messages:Z,hasMoreHistory:ee,loadMoreHistory:te,sendMessage:se,isWaking:ae}=g({project:e,liveMessages:u,ws:{send:O,connected:Q},historyLimit:20});P.current=Y;const ne=n.useRef(Q);n.useEffect(()=>{!ne.current&&Q&&x([]),ne.current=Q},[Q]);const re=(()=>{for(let e=Z.length-1;e>=0;e--)if("assistant"===Z[e].role)return e;return-1})(),[le,de]=n.useState([]),[ue,me]=n.useState([]),[he,fe]=n.useState(null),[ge,be]=n.useState(null),je=n.useRef(!1);n.useEffect(()=>{b().then(de).catch(()=>{}),j(e.id).then(me).catch(()=>{})},[e.id]);const ve=n.useCallback(e=>{const t=i.current;if(!t)return void l(t=>t+e);const s=t.selectionStart??r.length,a=t.selectionEnd??r.length,n=r.slice(0,s)+e+r.slice(a);l(n),requestAnimationFrame(()=>{t.focus();const a=s+e.length;t.setSelectionRange(a,a),t.style.height="auto",t.style.height=Math.min(t.scrollHeight,128)+"px"})},[r]),ye=n.useCallback(e=>{fe(null),ve(e+" ")},[ve]),Ne=n.useCallback(t=>{const s=e.folderPath;let a=t;s&&(t===s||t.startsWith(s+"/")||t.startsWith(s+"\\"))&&(a=t.slice(s.length).replace(/^[/\\]+/,"")),fe(null),ve(`@${a} `)},[e.folderPath,ve]),we=n.useCallback(async()=>{if("skills"!==he){if(!je.current){je.current=!0;try{const t=await v(e.cliTool??"claude",e.id);be(t)}catch{be({builtin:[],custom:[],plugins:[],mcp:[]})}finally{je.current=!1}}fe("skills")}else fe(null)},[he,e.cliTool,e.id]),ke=n.useCallback(async()=>{const e=c.current,t=(null==e?void 0:e.scrollHeight)??0;await te(),requestAnimationFrame(()=>{e&&(e.scrollTop+=e.scrollHeight-t)})},[te]),Ce=n.useRef(0);n.useEffect(()=>{const e=c.current;if(!e)return;const t=Z.length>Ce.current,s=0===Ce.current&&Z.length>0;Ce.current=Z.length,s?e.scrollTo({top:e.scrollHeight}):t&&e.scrollTo({top:e.scrollHeight,behavior:"smooth"})},[Z,T.length]);const[Se,Ie]=n.useState(!1),Pe=n.useCallback(async()=>{const e=r.trim();if(!e||Se)return;Ie(!0);const t=await se(e);Ie(!1),"delivered"===t&&(l(""),i.current&&(i.current.style.height="auto"))},[r,Se,se]),ze=y(Pe,"shift"),Me=n.useCallback(async(t,s)=>{fe(null);try{"failed"===await se(t.command)?N.error("快捷命令未送达,请重试或检查会话"):"project"===s&&w(e.id,t.id,!0).catch(e=>{console.error("Failed to mark shortcut used:",e)})}catch(a){console.error("Shortcut send error:",a),N.error("快捷命令发送失败")}},[se,e.id]),Ue="live"===X;return o.jsxs("div",{className:"flex flex-col h-full bg-background",children:[o.jsxs("div",{className:"flex items-center gap-2 px-3 h-12 border-b border-border shrink-0",children:[o.jsx("button",{onClick:t,className:"text-muted-foreground active:text-foreground p-1",children:o.jsx(k,{className:"h-5 w-5"})}),o.jsxs("div",{className:"flex items-center gap-1.5 flex-1 min-w-0",children:[o.jsx("span",{className:"font-medium text-sm truncate",children:e.name}),o.jsx("span",{className:d("w-2 h-2 rounded-full shrink-0",Ue?"bg-green-500":ae?"bg-yellow-400 animate-pulse":"bg-zinc-400")})]}),o.jsx("button",{onClick:s,className:"text-muted-foreground active:text-foreground p-1",children:o.jsx(xe,{className:"h-5 w-5"})})]}),o.jsxs("div",{ref:c,className:"flex-1 overflow-y-auto px-3 py-3 space-y-3 min-h-0",children:[ee&&o.jsx("div",{className:"flex justify-center pb-1",children:o.jsxs("button",{onClick:()=>{ke()},className:"flex items-center gap-1 px-3 py-1.5 rounded-full text-xs text-muted-foreground border border-border active:bg-accent transition-colors",children:[o.jsx(oe,{className:"h-3 w-3"}),"加载更早消息"]})}),Z.map((e,t)=>{const s="user"===e.role;return o.jsx("div",{className:d("flex",s?"justify-end":"justify-start"),children:o.jsx("div",{className:d("max-w-[85%] rounded-xl px-3 py-2 break-words text-sm leading-relaxed",s?"bg-blue-500/15 text-foreground border border-blue-500/20 rounded-br-sm whitespace-pre-wrap":"bg-secondary text-secondary-foreground border border-border rounded-bl-sm"),children:s?e.content:o.jsx(q,{content:e.content,blocks:e.blocks,isLatest:t===re})})},e.id)}),T.map(e=>o.jsx(W,{approval:e,onResolved:L},e.toolUseId)),M&&o.jsx(B,{prompt:M,onSelect:async t=>{await C(e.id,t)}}),R&&0===T.length&&o.jsx("div",{className:"flex justify-start",children:o.jsxs("div",{className:"rounded-2xl rounded-bl-md px-3 py-1.5 bg-black/5 dark:bg-white/10 border border-black/10 dark:border-white/15 flex items-center gap-2 text-xs text-muted-foreground",children:[o.jsx(V,{}),pe(R)&&o.jsx("span",{children:pe(R)})]})},R.id),0===Z.length&&0===T.length&&!R&&"stopped"===X&&o.jsx("div",{className:"flex items-center justify-center h-full text-muted-foreground/40 text-sm",children:"暂无对话记录"}),ae&&o.jsx("div",{className:"flex items-center justify-center py-4 text-yellow-400 text-sm animate-pulse",children:"启动中..."})]}),"global"===he||"project"===he?o.jsx("div",{className:"border-t border-border max-h-48 overflow-y-auto shrink-0",children:o.jsxs("div",{className:"px-3 py-2 space-y-1",children:[("global"===he?le:ue).map(e=>o.jsxs("button",{onClick:()=>Me(e,he),disabled:ae,className:d("w-full text-left rounded-md px-2.5 py-2 text-sm active:bg-accent transition-colors border border-border/50",ae&&"opacity-50 cursor-not-allowed"),children:[o.jsx("div",{className:"font-medium text-xs",children:e.label}),o.jsx("div",{className:"text-[11px] text-muted-foreground font-mono truncate",children:e.command})]},e.id)),0===("global"===he?le:ue).length&&o.jsx("div",{className:"text-center text-muted-foreground text-xs py-3",children:"暂无快捷 Prompts"})]})}):"skills"===he&&ge?o.jsx("div",{className:"border-t border-border shrink-0",children:o.jsx(K,{data:ge,onCommand:ye})}):"files"===he&&e.folderPath?o.jsx("div",{className:"border-t border-border shrink-0",children:o.jsx(G,{projectPath:e.folderPath,onSelect:Ne})}):null,o.jsxs("div",{className:"flex items-center gap-1.5 px-3 py-1.5 border-t border-border shrink-0",children:[o.jsx("button",{onClick:()=>{we()},title:"斜杠命令",className:d("flex items-center justify-center w-7 h-7 rounded font-mono text-base transition-colors","skills"===he?"bg-accent text-foreground font-medium":"text-muted-foreground active:bg-accent"),children:"/"}),o.jsx("button",{onClick:()=>fe(e=>"files"===e?null:"files"),disabled:!e.folderPath,title:"引用文件",className:d("flex items-center justify-center w-7 h-7 rounded font-mono text-base transition-colors","files"===he?"bg-accent text-foreground font-medium":e.folderPath?"text-muted-foreground active:bg-accent":"text-muted-foreground/30 cursor-not-allowed"),children:"@"}),le.length>0&&o.jsxs("button",{onClick:()=>fe(e=>"global"===e?null:"global"),className:d("flex items-center gap-1 px-2 py-1 rounded-md text-xs transition-colors","global"===he?"bg-accent text-foreground font-medium":"text-muted-foreground active:bg-accent"),children:[o.jsx(J,{className:"h-3 w-3"}),"全局","global"===he&&o.jsx(ce,{className:"h-3 w-3"})]}),ue.length>0&&o.jsxs("button",{onClick:()=>fe(e=>"project"===e?null:"project"),className:d("flex items-center gap-1 px-2 py-1 rounded-md text-xs transition-colors","project"===he?"bg-accent text-foreground font-medium":"text-muted-foreground active:bg-accent"),children:[o.jsx(ie,{className:"h-3 w-3"}),"项目","project"===he&&o.jsx(ce,{className:"h-3 w-3"})]})]}),o.jsx("div",{className:"border-t border-border px-3 py-2 shrink-0",style:{paddingBottom:"max(0.5rem, env(safe-area-inset-bottom))"},children:o.jsxs("div",{className:"flex items-end gap-2",children:[o.jsx("textarea",{ref:i,value:r,onChange:e=>l(e.target.value),onKeyDown:ze,disabled:ae||Se,placeholder:ae?"启动中...":Se?"发送中…":"stopped"===X?"输入消息(自动启动)...":"输入消息...",rows:1,className:d("flex-1 resize-none rounded-md border border-input bg-transparent px-3 py-2 text-sm outline-none","focus:ring-1 focus:ring-ring placeholder:text-muted-foreground/50","max-h-32 overflow-y-auto",(ae||Se)&&"opacity-50 cursor-not-allowed"),style:{minHeight:"2.5rem"},onInput:e=>{const t=e.currentTarget;t.style.height="auto",t.style.height=Math.min(t.scrollHeight,128)+"px"}}),o.jsx("button",{onClick:Pe,disabled:ae||Se||!r.trim(),className:d("shrink-0 p-2 rounded-md transition-colors",r.trim()&&!Se?"text-blue-500 active:bg-blue-500/10":"text-muted-foreground/30"),children:Se?o.jsx(S,{className:"h-5 w-5 animate-spin"}):o.jsx(I,{className:"h-5 w-5"})})]})})]})}const ge=A.lazy(()=>E(()=>import("./OfficePreview-CWYidYK8.js"),__vite__mapDeps([0,1,2,3])).then(e=>({default:e.OfficePreview}))),be=new Set(["png","jpg","jpeg","gif","webp","svg","bmp","ico","avif"]),je=new Set(["docx","xlsx","xls","pptx"]),ve={js:"javascript",jsx:"jsx",ts:"typescript",tsx:"tsx",py:"python",rb:"ruby",go:"go",rs:"rust",java:"java",kt:"kotlin",swift:"swift",c:"c",cpp:"cpp",h:"c",cs:"csharp",php:"php",sh:"bash",bash:"bash",zsh:"bash",yaml:"yaml",yml:"yaml",json:"json",toml:"toml",html:"html",htm:"html",xml:"xml",svg:"xml",css:"css",scss:"scss",less:"less",sql:"sql",graphql:"graphql",gql:"graphql",dockerfile:"docker",makefile:"makefile",r:"r",lua:"lua",dart:"dart",zig:"zig"};function ye(e){return e.split("/").pop()??e}function Ne({filePath:e,onBack:t}){const[s,a]=n.useState(null),[r,l]=n.useState(!0),[c,i]=n.useState(null),{resolved:d}=P(),u=function(e){const t=e.split("/").pop()??"",s=t.toLowerCase();if("dockerfile"===s)return"dockerfile";if("makefile"===s)return"makefile";const a=t.lastIndexOf(".");return a>=0?t.slice(a+1).toLowerCase():""}(e),x=be.has(u),m=je.has(u),h=ve[u],p="dark"===d;n.useEffect(()=>{x||m?l(!1):(l(!0),i(null),z(e).then(a).catch(e=>i(e instanceof Error?e.message:"Failed to load")).finally(()=>l(!1)))},[e,x,m]);const f=T(e),g=n.useMemo(()=>{const e=M();return e?`${f}&token=${encodeURIComponent(e)}`:f},[f]),b=n.useMemo(()=>x?`${g}&t=${Date.now()}`:"",[g,x]);return o.jsxs("div",{className:"flex flex-col h-full",children:[o.jsxs("div",{className:"flex items-center gap-2 px-3 h-12 border-b border-border shrink-0",children:[o.jsx("button",{onClick:t,className:"text-muted-foreground active:text-foreground p-1",children:o.jsx(k,{className:"h-5 w-5"})}),o.jsx("span",{className:"flex-1 text-sm font-medium truncate",children:ye(e)}),o.jsx("a",{href:g,download:!0,className:"text-muted-foreground active:text-foreground p-1",onClick:e=>e.stopPropagation(),children:o.jsx(U,{className:"h-4 w-4"})})]}),o.jsxs("div",{className:"flex-1 overflow-auto min-h-0",children:[r&&o.jsx("div",{className:"flex items-center justify-center py-12",children:o.jsx(S,{className:"h-5 w-5 animate-spin text-muted-foreground"})}),c&&o.jsx("div",{className:"text-center text-destructive text-sm py-12 px-4",children:c}),x&&o.jsx("div",{className:"flex items-center justify-center p-4 h-full",children:o.jsx("img",{src:b,alt:ye(e),className:"max-w-full max-h-full object-contain rounded",style:{touchAction:"pinch-zoom"}})}),m&&o.jsx(n.Suspense,{fallback:o.jsx("div",{className:"flex items-center justify-center py-12",children:o.jsx(S,{className:"h-5 w-5 animate-spin text-muted-foreground"})}),children:o.jsx(ge,{filePath:e,ext:u,zoom:100})}),s&&(s.binary||s.tooLarge)&&o.jsxs("div",{className:"text-center py-12 px-4 space-y-3",children:[o.jsxs("p",{className:"text-muted-foreground text-sm",children:[s.binary?"二进制文件":"文件过大",s.size>0&&` (${j=s.size,j<1024?`${j} B`:j<1048576?`${(j/1024).toFixed(1)} KB`:`${(j/1048576).toFixed(1)} MB`})`]}),o.jsxs("a",{href:g,download:!0,className:"inline-flex items-center gap-1.5 text-sm text-blue-500 active:text-blue-400",children:[o.jsx(U,{className:"h-4 w-4"}),"下载文件"]})]}),s&&!s.binary&&!s.tooLarge&&null!=s.content&&o.jsxs(o.Fragment,{children:["md"===u&&o.jsx("div",{className:"prose prose-sm dark:prose-invert max-w-none px-4 py-3",children:o.jsx(Q,{remarkPlugins:[Y,Z],rehypePlugins:[X],urlTransform:(e,t,s)=>"src"===t&&"img"===s.tagName?e:te(e),components:{img:({src:t,alt:s,...a})=>o.jsx("img",{...a,src:ee(e,t,M()),alt:s??"",loading:"lazy",style:{maxWidth:"100%",height:"auto"}})},children:s.content})}),"md"!==u&&h&&o.jsx(se,{language:h,style:p?ae:ne,customStyle:{margin:0,fontSize:"12px",borderRadius:0},showLineNumbers:!0,children:s.content}),"md"!==u&&!h&&o.jsx("pre",{className:"p-4 text-xs font-mono whitespace-pre-wrap break-words",children:s.content})]})]})]});var j}const we=new Set(["png","jpg","jpeg","gif","webp","svg","bmp","ico","avif"]),ke=new Set(["js","jsx","ts","tsx","py","rb","go","rs","java","c","cpp","h","swift","kt","cs","php","sh","bash","zsh","r","lua","dart","zig","css","scss","less","html","htm","xml","sql"]),Ce=new Set(["json","yaml","yml","toml","csv","tsv"]);function Se({entry:e}){if("dir"===e.type)return o.jsx(L,{className:"h-8 w-8 text-blue-400"});const t=function(e){const t=e.lastIndexOf(".");return t>=0?e.slice(t+1).toLowerCase():""}(e.name);return we.has(t)?o.jsx(re,{className:"h-8 w-8 text-emerald-400"}):ke.has(t)?o.jsx(de,{className:"h-8 w-8 text-orange-400"}):Ce.has(t)?o.jsx(ue,{className:"h-8 w-8 text-yellow-400"}):"md"===t?o.jsx(le,{className:"h-8 w-8 text-sky-400"}):o.jsx(R,{className:"h-8 w-8 text-muted-foreground"})}function Ie({rootPath:e,onClose:t}){const[s,a]=n.useState(e),[r,l]=n.useState([]),[c,i]=n.useState(!0),[d,u]=n.useState(null),x=n.useCallback(async e=>{i(!0);try{const t=[...(await D(e)).entries].sort((e,t)=>e.type!==t.type?"dir"===e.type?-1:1:e.name.localeCompare(t.name));l(t),a(e)}catch{l([])}finally{i(!1)}},[]);n.useEffect(()=>{x(e)},[e,x]);const m=s!==e,h=s.startsWith(e)?s.slice(e.length)||"/":s;return d?o.jsx(Ne,{filePath:d,onBack:()=>u(null)}):o.jsxs("div",{className:"flex flex-col h-full",children:[o.jsxs("div",{className:"flex items-center gap-2 px-3 h-12 border-b border-border shrink-0",children:[o.jsx("button",{onClick:t,className:"text-muted-foreground active:text-foreground p-1",children:o.jsx($,{className:"h-5 w-5"})}),o.jsxs("div",{className:"flex items-center gap-1 flex-1 min-w-0 text-sm",children:[m&&o.jsx("button",{onClick:()=>{if(s===e)return;const t=s.replace(/\/[^/]+$/,"")||"/";t.startsWith(e)&&x(t)},className:"text-muted-foreground active:text-foreground p-0.5 shrink-0",children:o.jsx(k,{className:"h-4 w-4"})}),o.jsx("span",{className:"truncate text-muted-foreground font-mono text-xs",children:h})]})]}),o.jsxs("div",{className:"flex-1 overflow-y-auto px-3 py-3",children:[c&&o.jsx("div",{className:"flex items-center justify-center py-12",children:o.jsx(S,{className:"h-5 w-5 animate-spin text-muted-foreground"})}),!c&&0===r.length&&o.jsx("div",{className:"text-center text-muted-foreground text-sm py-12",children:"空目录"}),!c&&o.jsx("div",{className:"grid grid-cols-3 gap-1",children:r.map(e=>o.jsxs("button",{onClick:()=>(e=>{"dir"===e.type?x(e.path):u(e.path)})(e),className:"flex flex-col items-center gap-1 p-2 rounded-md active:bg-accent transition-colors",children:[o.jsx(Se,{entry:e}),o.jsx("span",{className:"text-[11px] text-center leading-tight w-full line-clamp-2 break-all",children:e.name})]},e.path))})]})]})}function Pe(e){return e<50?"text-green-400":e<80?"text-yellow-400":"text-red-400"}function ze(e){return e<50?"bg-green-500":e<80?"bg-yellow-500":"bg-red-500"}function Me({projectName:e,cliTool:t,folderPath:s,contextData:a,onClose:r}){const[l,c]=n.useState(new Set(["context","usage","files"])),[u,x]=n.useState(null),[m,h]=n.useState(!1),p=e=>{c(t=>{const s=new Set(t);return s.has(e)?s.delete(e):s.add(e),s})};n.useEffect(()=>{h(!0),_(t).then(x).catch(()=>x(null)).finally(()=>h(!1))},[t]);const f=a?Math.round(a.usedPercentage):null;return o.jsxs("div",{className:"flex flex-col h-full",children:[o.jsxs("div",{className:"flex items-center gap-2 px-3 h-12 border-b border-border shrink-0",children:[o.jsx("button",{onClick:r,className:"text-muted-foreground active:text-foreground p-1",children:o.jsx($,{className:"h-5 w-5"})}),o.jsx("span",{className:"flex-1 font-medium text-sm truncate",children:e})]}),o.jsxs("div",{className:"flex-1 overflow-y-auto",children:[o.jsxs("button",{onClick:()=>p("context"),className:"w-full flex items-center gap-2 px-4 py-2.5 border-b border-border/50 active:bg-accent",children:[l.has("context")?o.jsx(ce,{className:"h-3.5 w-3.5 text-muted-foreground"}):o.jsx(F,{className:"h-3.5 w-3.5 text-muted-foreground"}),o.jsx("span",{className:"text-sm font-medium",children:"上下文"}),null!==f&&o.jsxs("span",{className:d("text-xs font-mono ml-auto",Pe(f)),children:[f,"%"]})]}),l.has("context")&&o.jsx("div",{className:"px-4 py-3 border-b border-border/50",children:null!==f&&a?o.jsxs("div",{className:"space-y-2",children:[o.jsxs("div",{className:"flex items-center gap-2",children:[o.jsx("div",{className:"flex-1 h-2 bg-secondary rounded-full overflow-hidden",children:o.jsx("div",{className:d("h-full rounded-full transition-all",ze(f)),style:{width:`${Math.min(f,100)}%`}})}),o.jsxs("span",{className:d("text-xs font-mono w-10 text-right",Pe(f)),children:[f,"%"]})]}),o.jsxs("div",{className:"grid grid-cols-2 gap-x-4 gap-y-1 text-[11px] text-muted-foreground",children:[o.jsx("span",{children:"窗口大小"}),o.jsx("span",{className:"text-right font-mono",children:a.contextWindowSize>=1e6?`${(a.contextWindowSize/1e6).toFixed(1)}M`:`${Math.round(a.contextWindowSize/1e3)}K`}),o.jsx("span",{children:"输入 tokens"}),o.jsx("span",{className:"text-right font-mono",children:a.inputTokens.toLocaleString()}),o.jsx("span",{children:"输出 tokens"}),o.jsx("span",{className:"text-right font-mono",children:a.outputTokens.toLocaleString()})]})]}):o.jsx("div",{className:"text-xs text-muted-foreground/50 text-center py-2",children:"暂无数据"})}),o.jsxs("div",{className:"w-full flex items-center gap-2 px-4 py-2.5 border-b border-border/50 cursor-pointer",role:"button",tabIndex:0,onClick:()=>p("usage"),onKeyDown:e=>{"Enter"!==e.key&&" "!==e.key||p("usage")},children:[l.has("usage")?o.jsx(ce,{className:"h-3.5 w-3.5 text-muted-foreground"}):o.jsx(F,{className:"h-3.5 w-3.5 text-muted-foreground"}),o.jsx("span",{className:"text-sm font-medium",children:"用量"}),o.jsx("button",{onClick:e=>{e.stopPropagation(),(async()=>{h(!0);try{const{refreshUsage:e}=await E(async()=>{const{refreshUsage:e}=await import("./index-P6fKDTgI.js").then(e=>e.bU);return{refreshUsage:e}},__vite__mapDeps([1,2]));x(await e(t))}catch{}finally{h(!1)}})()},className:"ml-auto text-muted-foreground active:text-foreground",children:o.jsx(i,{className:d("h-3 w-3",m&&"animate-spin")})})]}),l.has("usage")&&o.jsx("div",{className:"px-4 py-3 border-b border-border/50",children:u?o.jsxs("div",{className:"space-y-2",children:[u.planName&&o.jsxs("div",{className:"text-[11px] text-muted-foreground",children:["Plan: ",o.jsx("span",{className:"font-medium text-foreground",children:u.planName})]}),o.jsx(Ue,{label:"5h",bucket:u.fiveHour}),o.jsx(Ue,{label:"7d",bucket:u.sevenDay}),u.sevenDaySonnet&&o.jsx(Ue,{label:"7d Sonnet",bucket:u.sevenDaySonnet}),u.sevenDayOpus&&o.jsx(Ue,{label:"7d Opus",bucket:u.sevenDayOpus}),!u.fiveHour&&!u.sevenDay&&o.jsx("div",{className:"text-xs text-muted-foreground/50 text-center",children:"暂无数据"})]}):o.jsx("div",{className:"text-xs text-muted-foreground/50 text-center py-2",children:m?"加载中...":"暂无数据"})}),o.jsxs("button",{onClick:()=>p("files"),className:"w-full flex items-center gap-2 px-4 py-2.5 border-b border-border/50 active:bg-accent",children:[l.has("files")?o.jsx(ce,{className:"h-3.5 w-3.5 text-muted-foreground"}):o.jsx(F,{className:"h-3.5 w-3.5 text-muted-foreground"}),o.jsx("span",{className:"text-sm font-medium",children:"文件"})]}),l.has("files")&&o.jsx("div",{className:"h-[60vh]",children:o.jsx(Ie,{rootPath:s,onClose:()=>p("files")})})]})]})}function Ue({label:e,bucket:t}){if(!t||void 0===t.utilization)return null;const s=t.utilization,a=function(e){if(!e)return"";const t=new Date(e).getTime()-Date.now();if(t<=0)return"即将重置";const s=Math.floor(t/36e5),a=Math.floor(t%36e5/6e4);return s>0?`${s}h${a}m`:`${a}m`}(t.resetAt);return o.jsxs("div",{className:"flex items-center gap-2",children:[o.jsx("span",{className:"text-xs text-muted-foreground w-16",children:e}),o.jsx("div",{className:"flex-1 h-1.5 bg-secondary rounded-full overflow-hidden",children:o.jsx("div",{className:d("h-full rounded-full",ze(s)),style:{width:`${Math.min(s,100)}%`}})}),o.jsxs("span",{className:d("text-xs font-mono w-8 text-right",Pe(s)),children:[s,"%"]}),a&&o.jsx("span",{className:"text-[10px] text-muted-foreground/60",children:a})]})}function Te(){n.useEffect(()=>{const e=document.querySelector('meta[name="viewport"]');if(!e)return;const t=e.getAttribute("content")??"";return e.setAttribute("content","width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover"),()=>{e.setAttribute("content",t)}},[]);const[e,t]=n.useState({screen:"list"}),[s,r]=n.useState(null),l=a(e=>e.projects),c=n.useCallback(e=>{t({screen:"chat",projectId:e}),r(null)},[]),i=n.useCallback(e=>{t({screen:"panel",projectId:e})},[]),d=n.useCallback(()=>{t(e=>"panel"===e.screen?{screen:"chat",projectId:e.projectId}:{screen:"list"})},[]),u="list"!==e.screen?l.find(t=>t.id===e.projectId):void 0;return o.jsxs("div",{className:"fixed inset-0 bg-background overflow-hidden",children:[o.jsxs(H,{mode:"wait",children:["list"===e.screen&&o.jsx(O.div,{className:"absolute inset-0",initial:{opacity:0},animate:{opacity:1},exit:{x:"-30%",opacity:0},transition:{duration:.2},style:{paddingTop:"env(safe-area-inset-top)"},children:o.jsx(he,{onSelectProject:c})},"list"),"chat"===e.screen&&u&&o.jsx(O.div,{className:"absolute inset-0",initial:{x:"100%"},animate:{x:0},exit:{x:"100%"},transition:{type:"tween",duration:.25},style:{paddingTop:"env(safe-area-inset-top)"},children:o.jsx(fe,{project:u,onBack:d,onOpenPanel:()=>i(e.projectId),onContextUpdate:r})},`chat-${e.projectId}`)]}),o.jsx(H,{children:"panel"===e.screen&&u&&o.jsx(O.div,{className:"absolute inset-0 z-50 bg-background",initial:{x:"100%"},animate:{x:0},exit:{x:"100%"},transition:{type:"tween",duration:.25},style:{paddingTop:"env(safe-area-inset-top)"},children:o.jsx(Me,{projectName:u.name,cliTool:u.cliTool??"claude",folderPath:u.folderPath,contextData:s,onClose:d})},"panel")})]})}export{Te as MobilePage};
@@ -1,2 +1,2 @@
1
- const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/index-CPROAFio.js","assets/index-YwIvszwO.js","assets/index-DB7vdaUN.css","assets/jszip.min-C_jYnhtJ.js"])))=>i.map(i=>d[i]);
2
- import{j as e,r as t,_ as s,g as r,h as a}from"./index-YwIvszwO.js";import{p as n}from"./purify.es-CgRAQgUo.js";async function l(e){let t=a(e);const s=r();s&&(t+=`${t.includes("?")?"&":"?"}token=${encodeURIComponent(s)}`);const n=await fetch(t);if(!n.ok)throw new Error(`Failed to fetch file: ${n.status}`);return n.arrayBuffer()}function o({filePath:r,zoom:a}){const[o,i]=t.useState(""),[d,c]=t.useState(null),[x,u]=t.useState(!0);return t.useEffect(()=>{let e=!1;return u(!0),c(null),(async()=>{try{const t=await s(()=>import("./index-CPROAFio.js").then(e=>e.i),__vite__mapDeps([0,1,2,3])),a=await l(r),n=await t.convertToHtml({arrayBuffer:a});e||i(n.value)}catch(t){e||c(t instanceof Error?t.message:"Failed to render docx")}finally{e||u(!1)}})(),()=>{e=!0}},[r]),x?e.jsx("p",{className:"text-sm text-muted-foreground p-4",children:"加载 Word 文档中..."}):d?e.jsx("p",{className:"text-sm text-destructive p-4",children:d}):e.jsx("div",{className:"p-6 prose dark:prose-invert max-w-none",style:{fontSize:12*a/100+"px"},dangerouslySetInnerHTML:{__html:n.sanitize(o)}})}function i({filePath:r,zoom:a}){var o;const[i,d]=t.useState([]),[c,x]=t.useState(0),[u,p]=t.useState(null),[m,f]=t.useState(!0);return t.useEffect(()=>{let e=!1;return f(!0),p(null),(async()=>{try{const t=await s(()=>import("./xlsx-DfDjAMCE.js"),[]),a=await l(r),n=t.read(a,{type:"array"}),o=n.SheetNames.map(e=>({name:e,html:t.utils.sheet_to_html(n.Sheets[e],{editable:!1})}));e||(d(o),x(0))}catch(t){e||p(t instanceof Error?t.message:"Failed to render xlsx")}finally{e||f(!1)}})(),()=>{e=!0}},[r]),m?e.jsx("p",{className:"text-sm text-muted-foreground p-4",children:"加载 Excel 文件中..."}):u?e.jsx("p",{className:"text-sm text-destructive p-4",children:u}):0===i.length?e.jsx("p",{className:"text-sm text-muted-foreground p-4",children:"空文件"}):e.jsxs("div",{className:"flex flex-col h-full",children:[i.length>1&&e.jsx("div",{className:"flex gap-0.5 px-3 py-1.5 border-b border-border bg-muted/30 flex-shrink-0 overflow-x-auto",children:i.map((t,s)=>e.jsx("button",{onClick:()=>x(s),className:"px-3 py-1 text-xs rounded-t transition-colors whitespace-nowrap "+(s===c?"bg-background text-foreground border border-b-0 border-border":"text-muted-foreground hover:text-foreground"),children:t.name},s))}),e.jsx("div",{className:"flex-1 overflow-auto p-2 xlsx-preview",style:{fontSize:12*a/100+"px"},dangerouslySetInnerHTML:{__html:n.sanitize((null==(o=i[c])?void 0:o.html)??"")}}),e.jsx("style",{children:"\n .xlsx-preview table { border-collapse: collapse; width: auto; min-width: 100%; }\n .xlsx-preview td, .xlsx-preview th {\n border: 1px solid hsl(var(--border));\n padding: 4px 8px;\n text-align: left;\n white-space: nowrap;\n font-size: inherit;\n }\n .xlsx-preview th { background: hsl(var(--muted)); font-weight: 600; }\n .xlsx-preview tr:hover td { background: hsl(var(--accent) / 0.3); }\n "})]})}function d({filePath:r,zoom:a}){const[n,o]=t.useState([]),[i,d]=t.useState(null),[c,x]=t.useState(!0);return t.useEffect(()=>{let e=!1;return x(!0),d(null),(async()=>{try{const t=await l(r),a=await async function(e){const{default:t}=await s(async()=>{const{default:e}=await import("./jszip.min-C_jYnhtJ.js").then(e=>e.j);return{default:e}},__vite__mapDeps([3,1,2])),r=await t.loadAsync(e),a=[],n=Object.keys(r.files).filter(e=>/^ppt\/slides\/slide\d+\.xml$/i.test(e)).sort((e,t)=>{var s,r;return parseInt((null==(s=e.match(/slide(\d+)/))?void 0:s[1])??"0")-parseInt((null==(r=t.match(/slide(\d+)/))?void 0:r[1])??"0")});for(let s=0;s<n.length;s++){const e=await r.file(n[s]).async("text"),t=[],l=/<a:t[^>]*>([\s\S]*?)<\/a:t>/g;let o;for(;null!==(o=l.exec(e));){const e=o[1].replace(/&amp;/g,"&").replace(/&lt;/g,"<").replace(/&gt;/g,">").replace(/&quot;/g,'"').trim();e&&t.push(e)}a.push({index:s+1,texts:t})}return a}(t);e||o(a)}catch(t){e||d(t instanceof Error?t.message:"Failed to render pptx")}finally{e||x(!1)}})(),()=>{e=!0}},[r]),c?e.jsx("p",{className:"text-sm text-muted-foreground p-4",children:"加载 PPT 文件中..."}):i?e.jsx("p",{className:"text-sm text-destructive p-4",children:i}):0===n.length?e.jsx("p",{className:"text-sm text-muted-foreground p-4",children:"空文件"}):e.jsx("div",{className:"p-4 space-y-4",style:{fontSize:12*a/100+"px"},children:n.map(t=>e.jsxs("div",{className:"border border-border rounded-xl p-5 bg-muted/20",children:[e.jsxs("div",{className:"text-xs text-muted-foreground mb-2 font-medium",children:["Slide ",t.index]}),t.texts.length>0?e.jsx("div",{className:"space-y-1.5",children:t.texts.map((t,s)=>e.jsx("p",{className:"text-foreground leading-relaxed",style:{fontSize:"inherit"},children:t},s))}):e.jsx("p",{className:"text-muted-foreground text-sm italic",children:"(无文本内容)"})]},t.index))})}const c=new Set(["docx","xlsx","xls","pptx"]);function x({filePath:t,ext:s,zoom:r}){return"docx"===s?e.jsx(o,{filePath:t,zoom:r}):"xlsx"===s||"xls"===s?e.jsx(i,{filePath:t,zoom:r}):"pptx"===s?e.jsx(d,{filePath:t,zoom:r}):null}export{c as OFFICE_EXTS,x as OfficePreview};
1
+ const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/index-DsEIMlTx.js","assets/index-P6fKDTgI.js","assets/index-DB7vdaUN.css","assets/jszip.min-2wuC33Uk.js"])))=>i.map(i=>d[i]);
2
+ import{j as e,r as t,_ as s,g as r,h as a}from"./index-P6fKDTgI.js";import{p as n}from"./purify.es-CgRAQgUo.js";async function l(e){let t=a(e);const s=r();s&&(t+=`${t.includes("?")?"&":"?"}token=${encodeURIComponent(s)}`);const n=await fetch(t);if(!n.ok)throw new Error(`Failed to fetch file: ${n.status}`);return n.arrayBuffer()}function o({filePath:r,zoom:a}){const[o,i]=t.useState(""),[d,c]=t.useState(null),[x,u]=t.useState(!0);return t.useEffect(()=>{let e=!1;return u(!0),c(null),(async()=>{try{const t=await s(()=>import("./index-DsEIMlTx.js").then(e=>e.i),__vite__mapDeps([0,1,2,3])),a=await l(r),n=await t.convertToHtml({arrayBuffer:a});e||i(n.value)}catch(t){e||c(t instanceof Error?t.message:"Failed to render docx")}finally{e||u(!1)}})(),()=>{e=!0}},[r]),x?e.jsx("p",{className:"text-sm text-muted-foreground p-4",children:"加载 Word 文档中..."}):d?e.jsx("p",{className:"text-sm text-destructive p-4",children:d}):e.jsx("div",{className:"p-6 prose dark:prose-invert max-w-none",style:{fontSize:12*a/100+"px"},dangerouslySetInnerHTML:{__html:n.sanitize(o)}})}function i({filePath:r,zoom:a}){var o;const[i,d]=t.useState([]),[c,x]=t.useState(0),[u,p]=t.useState(null),[m,f]=t.useState(!0);return t.useEffect(()=>{let e=!1;return f(!0),p(null),(async()=>{try{const t=await s(()=>import("./xlsx-DfDjAMCE.js"),[]),a=await l(r),n=t.read(a,{type:"array"}),o=n.SheetNames.map(e=>({name:e,html:t.utils.sheet_to_html(n.Sheets[e],{editable:!1})}));e||(d(o),x(0))}catch(t){e||p(t instanceof Error?t.message:"Failed to render xlsx")}finally{e||f(!1)}})(),()=>{e=!0}},[r]),m?e.jsx("p",{className:"text-sm text-muted-foreground p-4",children:"加载 Excel 文件中..."}):u?e.jsx("p",{className:"text-sm text-destructive p-4",children:u}):0===i.length?e.jsx("p",{className:"text-sm text-muted-foreground p-4",children:"空文件"}):e.jsxs("div",{className:"flex flex-col h-full",children:[i.length>1&&e.jsx("div",{className:"flex gap-0.5 px-3 py-1.5 border-b border-border bg-muted/30 flex-shrink-0 overflow-x-auto",children:i.map((t,s)=>e.jsx("button",{onClick:()=>x(s),className:"px-3 py-1 text-xs rounded-t transition-colors whitespace-nowrap "+(s===c?"bg-background text-foreground border border-b-0 border-border":"text-muted-foreground hover:text-foreground"),children:t.name},s))}),e.jsx("div",{className:"flex-1 overflow-auto p-2 xlsx-preview",style:{fontSize:12*a/100+"px"},dangerouslySetInnerHTML:{__html:n.sanitize((null==(o=i[c])?void 0:o.html)??"")}}),e.jsx("style",{children:"\n .xlsx-preview table { border-collapse: collapse; width: auto; min-width: 100%; }\n .xlsx-preview td, .xlsx-preview th {\n border: 1px solid hsl(var(--border));\n padding: 4px 8px;\n text-align: left;\n white-space: nowrap;\n font-size: inherit;\n }\n .xlsx-preview th { background: hsl(var(--muted)); font-weight: 600; }\n .xlsx-preview tr:hover td { background: hsl(var(--accent) / 0.3); }\n "})]})}function d({filePath:r,zoom:a}){const[n,o]=t.useState([]),[i,d]=t.useState(null),[c,x]=t.useState(!0);return t.useEffect(()=>{let e=!1;return x(!0),d(null),(async()=>{try{const t=await l(r),a=await async function(e){const{default:t}=await s(async()=>{const{default:e}=await import("./jszip.min-2wuC33Uk.js").then(e=>e.j);return{default:e}},__vite__mapDeps([3,1,2])),r=await t.loadAsync(e),a=[],n=Object.keys(r.files).filter(e=>/^ppt\/slides\/slide\d+\.xml$/i.test(e)).sort((e,t)=>{var s,r;return parseInt((null==(s=e.match(/slide(\d+)/))?void 0:s[1])??"0")-parseInt((null==(r=t.match(/slide(\d+)/))?void 0:r[1])??"0")});for(let s=0;s<n.length;s++){const e=await r.file(n[s]).async("text"),t=[],l=/<a:t[^>]*>([\s\S]*?)<\/a:t>/g;let o;for(;null!==(o=l.exec(e));){const e=o[1].replace(/&amp;/g,"&").replace(/&lt;/g,"<").replace(/&gt;/g,">").replace(/&quot;/g,'"').trim();e&&t.push(e)}a.push({index:s+1,texts:t})}return a}(t);e||o(a)}catch(t){e||d(t instanceof Error?t.message:"Failed to render pptx")}finally{e||x(!1)}})(),()=>{e=!0}},[r]),c?e.jsx("p",{className:"text-sm text-muted-foreground p-4",children:"加载 PPT 文件中..."}):i?e.jsx("p",{className:"text-sm text-destructive p-4",children:i}):0===n.length?e.jsx("p",{className:"text-sm text-muted-foreground p-4",children:"空文件"}):e.jsx("div",{className:"p-4 space-y-4",style:{fontSize:12*a/100+"px"},children:n.map(t=>e.jsxs("div",{className:"border border-border rounded-xl p-5 bg-muted/20",children:[e.jsxs("div",{className:"text-xs text-muted-foreground mb-2 font-medium",children:["Slide ",t.index]}),t.texts.length>0?e.jsx("div",{className:"space-y-1.5",children:t.texts.map((t,s)=>e.jsx("p",{className:"text-foreground leading-relaxed",style:{fontSize:"inherit"},children:t},s))}):e.jsx("p",{className:"text-muted-foreground text-sm italic",children:"(无文本内容)"})]},t.index))})}const c=new Set(["docx","xlsx","xls","pptx"]);function x({filePath:t,ext:s,zoom:r}){return"docx"===s?e.jsx(o,{filePath:t,zoom:r}):"xlsx"===s||"xls"===s?e.jsx(i,{filePath:t,zoom:r}):"pptx"===s?e.jsx(d,{filePath:t,zoom:r}):null}export{c as OFFICE_EXTS,x as OfficePreview};