baxian 0.1.0 → 0.2.0

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 (55) hide show
  1. package/README.md +1 -1
  2. package/dist/agent/bootstrap-poller.d.ts +6 -0
  3. package/dist/agent/bootstrap-poller.d.ts.map +1 -1
  4. package/dist/agent/bootstrap-poller.js +30 -0
  5. package/dist/agent/bootstrap-poller.js.map +1 -1
  6. package/dist/agent/bootstrap.d.ts +7 -0
  7. package/dist/agent/bootstrap.d.ts.map +1 -1
  8. package/dist/agent/bootstrap.js +104 -5
  9. package/dist/agent/bootstrap.js.map +1 -1
  10. package/dist/agent/manager.js +5 -5
  11. package/dist/agent/manager.js.map +1 -1
  12. package/dist/agent/marker-protocol.d.ts +10 -4
  13. package/dist/agent/marker-protocol.d.ts.map +1 -1
  14. package/dist/agent/marker-protocol.js +42 -34
  15. package/dist/agent/marker-protocol.js.map +1 -1
  16. package/dist/agent/post-approve-marker-watcher.d.ts.map +1 -1
  17. package/dist/agent/post-approve-marker-watcher.js +3 -7
  18. package/dist/agent/post-approve-marker-watcher.js.map +1 -1
  19. package/dist/agent/prompt.d.ts +3 -1
  20. package/dist/agent/prompt.d.ts.map +1 -1
  21. package/dist/agent/prompt.js +33 -51
  22. package/dist/agent/prompt.js.map +1 -1
  23. package/dist/agent/spec-review-marker-watcher.d.ts +3 -2
  24. package/dist/agent/spec-review-marker-watcher.d.ts.map +1 -1
  25. package/dist/agent/spec-review-marker-watcher.js +5 -7
  26. package/dist/agent/spec-review-marker-watcher.js.map +1 -1
  27. package/dist/api/config.d.ts.map +1 -1
  28. package/dist/api/config.js +16 -0
  29. package/dist/api/config.js.map +1 -1
  30. package/dist/api/projects.d.ts.map +1 -1
  31. package/dist/api/projects.js +30 -0
  32. package/dist/api/projects.js.map +1 -1
  33. package/dist/app.d.ts +2 -0
  34. package/dist/app.d.ts.map +1 -1
  35. package/dist/app.js.map +1 -1
  36. package/dist/event/handlers.js +2 -2
  37. package/dist/event/handlers.js.map +1 -1
  38. package/dist/index.d.ts.map +1 -1
  39. package/dist/index.js +32 -9
  40. package/dist/index.js.map +1 -1
  41. package/dist/shared/types.d.ts +1 -8
  42. package/dist/shared/types.d.ts.map +1 -1
  43. package/dist/state/error-record-store.d.ts +12 -0
  44. package/dist/state/error-record-store.d.ts.map +1 -1
  45. package/dist/state/error-record-store.js +130 -1
  46. package/dist/state/error-record-store.js.map +1 -1
  47. package/dist/state/snapshot.d.ts +8 -2
  48. package/dist/state/snapshot.d.ts.map +1 -1
  49. package/dist/state/snapshot.js +45 -4
  50. package/dist/state/snapshot.js.map +1 -1
  51. package/dist/web/assets/index-53CBbz4w.js +4 -0
  52. package/dist/web/assets/{index-BztIjbNF.css → index-B9D6BV08.css} +1 -1
  53. package/dist/web/index.html +2 -2
  54. package/package.json +1 -1
  55. package/dist/web/assets/index-eKI0WBRQ.js +0 -4
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/shared/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/shared/types.ts"],"names":[],"mappings":"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"}
@@ -22,6 +22,18 @@ export declare class ErrorRecordStore {
22
22
  constructor(dir: string);
23
23
  append(input: ErrorRecordInput): Promise<ErrorRecord>;
24
24
  latestForAgent(agentId: string): Promise<ErrorRecord | undefined>;
25
+ latestBootstrapForAgent(agentId: string): Promise<ErrorRecord | undefined>;
26
+ latestBootstrapByAgent(): Promise<Map<string, ErrorRecord>>;
27
+ purgeAgent(agentId: string): Promise<{
28
+ removed: number;
29
+ }>;
30
+ purgeBootstrapForAgent(agentId: string): Promise<{
31
+ removed: number;
32
+ }>;
33
+ sweepStaleBootstrapErrors(activeAgentIds: Set<string>): Promise<{
34
+ removed: number;
35
+ }>;
36
+ private rewriteFiltered;
25
37
  toSummary(record: ErrorRecord): AgentErrorSummary;
26
38
  private readAll;
27
39
  }
@@ -1 +1 @@
1
- {"version":3,"file":"error-record-store.d.ts","sourceRoot":"","sources":["../../src/state/error-record-store.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAE5D,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACtC,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,WAAY,SAAQ,QAAQ,CAAC,IAAI,CAAC,gBAAgB,EAAE,QAAQ,GAAG,aAAa,GAAG,gBAAgB,CAAC,CAAC;IAChH,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACtC,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,qBAAa,gBAAgB;IAGf,OAAO,CAAC,GAAG;IAFvB,OAAO,CAAC,KAAK,CAAuC;gBAEhC,GAAG,EAAE,MAAM;IAEzB,MAAM,CAAC,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAAC,WAAW,CAAC;IAsBrD,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,SAAS,CAAC;IAOvE,SAAS,CAAC,MAAM,EAAE,WAAW,GAAG,iBAAiB;YAUnC,OAAO;CAwBtB"}
1
+ {"version":3,"file":"error-record-store.d.ts","sourceRoot":"","sources":["../../src/state/error-record-store.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAE5D,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACtC,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,WAAY,SAAQ,QAAQ,CAAC,IAAI,CAAC,gBAAgB,EAAE,QAAQ,GAAG,aAAa,GAAG,gBAAgB,CAAC,CAAC;IAChH,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACtC,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,qBAAa,gBAAgB;IAGf,OAAO,CAAC,GAAG;IAFvB,OAAO,CAAC,KAAK,CAAuC;gBAEhC,GAAG,EAAE,MAAM;IAEzB,MAAM,CAAC,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAAC,WAAW,CAAC;IAsBrD,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,SAAS,CAAC;IAOjE,uBAAuB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,SAAS,CAAC;IAS1E,sBAAsB,IAAI,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IAgB3D,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAWzD,sBAAsB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAiBrE,yBAAyB,CAAC,cAAc,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAa1F,OAAO,CAAC,eAAe;IA8DvB,SAAS,CAAC,MAAM,EAAE,WAAW,GAAG,iBAAiB;YAUnC,OAAO;CAwBtB"}
@@ -1,4 +1,4 @@
1
- import { appendFile, readFile, readdir } from 'node:fs/promises';
1
+ import { appendFile, readFile, readdir, rename, unlink, writeFile } from 'node:fs/promises';
2
2
  import { join } from 'node:path';
3
3
  import { randomUUID } from 'node:crypto';
4
4
  export class ErrorRecordStore {
@@ -34,6 +34,135 @@ export class ErrorRecordStore {
34
34
  .filter(record => record.agentId === agentId)
35
35
  .sort((a, b) => b.occurredAt.localeCompare(a.occurredAt))[0];
36
36
  }
37
+ async latestBootstrapForAgent(agentId) {
38
+ const records = await this.readAll();
39
+ return records
40
+ .filter(record => record.agentId === agentId && record.operation === 'bootstrap')
41
+ .sort((a, b) => b.occurredAt.localeCompare(a.occurredAt))[0];
42
+ }
43
+ // Batched variant for buildAllAgentSnapshots — one readAll() per snapshot pass instead of
44
+ // N (agent count) × full-history scan. Returns the most recent bootstrap record per agentId.
45
+ async latestBootstrapByAgent() {
46
+ const records = await this.readAll();
47
+ const latest = new Map();
48
+ for (const record of records) {
49
+ if (record.operation !== 'bootstrap')
50
+ continue;
51
+ const prev = latest.get(record.agentId);
52
+ if (!prev || record.occurredAt > prev.occurredAt) {
53
+ latest.set(record.agentId, record);
54
+ }
55
+ }
56
+ return latest;
57
+ }
58
+ // Drops every record for an agentId by rewriting each affected jsonl. Called from
59
+ // agent-delete so an id reused later (delete + recreate) doesn't inherit stale bootstrap
60
+ // errors from the previous incarnation. Best-effort; partial failures are logged not thrown.
61
+ async purgeAgent(agentId) {
62
+ const idMarker = `"agentId":${JSON.stringify(agentId)}`;
63
+ return this.rewriteFiltered({
64
+ mayMatch: content => content.includes(idMarker),
65
+ shouldDrop: record => record.agentId === agentId,
66
+ });
67
+ }
68
+ // Narrower variant: drops only bootstrap-operation records for one agent, called from
69
+ // runSingleTarget's success path on EVERY tick. Hot path — quickCheck must be cheap and
70
+ // truly short-circuit (read alone, no parse, no rewrite) in the common no-stale case.
71
+ async purgeBootstrapForAgent(agentId) {
72
+ const idMarker = `"agentId":${JSON.stringify(agentId)}`;
73
+ const opMarker = '"operation":"bootstrap"';
74
+ return this.rewriteFiltered({
75
+ mayMatch: content => content.includes(idMarker) && content.includes(opMarker),
76
+ shouldDrop: record => record.agentId === agentId && record.operation === 'bootstrap',
77
+ });
78
+ }
79
+ // One-shot sweep on startup / config-replace: drop bootstrap-operation records for every
80
+ // agent NOT currently in the auto-bootstrap set. Covers:
81
+ // (a) agent transitioned from auto-mode to explicit workdir (id stays, leaves bootstrap)
82
+ // (b) agent deleted while server was down
83
+ // (c) PATCH /config saved then restartRequired — old poller appended a fresh stale record
84
+ // in the window before restart; sweep on next startup clears it
85
+ // Done in a single rewriteFiltered pass — one full-history scan per startup rather than
86
+ // N (stale agents) × full scans.
87
+ async sweepStaleBootstrapErrors(activeAgentIds) {
88
+ return this.rewriteFiltered({
89
+ mayMatch: content => content.includes('"operation":"bootstrap"'),
90
+ shouldDrop: record => record.operation === 'bootstrap' && !activeAgentIds.has(record.agentId),
91
+ });
92
+ }
93
+ // Shared rewrite-with-filter helper. shouldDrop returns true for records to remove.
94
+ // Uses tmp file + atomic rename per jsonl to survive crash/disk-full mid-rewrite
95
+ // (in-place writeFile would otherwise truncate the file and lose unrelated history).
96
+ // mayMatch lets callers short-circuit per file BEFORE the parse loop — without it, every
97
+ // call still parses the whole history even when nothing matches, defeating the rewrite skip.
98
+ rewriteFiltered(opts) {
99
+ const result = this.chain.then(async () => {
100
+ let files;
101
+ try {
102
+ files = await readdir(this.dir);
103
+ }
104
+ catch {
105
+ return { removed: 0 };
106
+ }
107
+ let removed = 0;
108
+ for (const file of files.filter(f => f.endsWith('.jsonl'))) {
109
+ const path = join(this.dir, file);
110
+ let content;
111
+ try {
112
+ content = await readFile(path, 'utf-8');
113
+ }
114
+ catch (err) {
115
+ console.warn(`[ErrorRecordStore] rewriteFiltered: skipping unreadable ${file}:`, err);
116
+ continue;
117
+ }
118
+ if (!opts.mayMatch(content))
119
+ continue;
120
+ const lines = content.split('\n');
121
+ const kept = [];
122
+ let fileRemoved = 0;
123
+ for (const line of lines) {
124
+ if (!line)
125
+ continue;
126
+ let record;
127
+ try {
128
+ record = JSON.parse(line);
129
+ }
130
+ catch {
131
+ kept.push(line);
132
+ continue;
133
+ }
134
+ if (opts.shouldDrop(record)) {
135
+ fileRemoved++;
136
+ continue;
137
+ }
138
+ kept.push(line);
139
+ }
140
+ if (fileRemoved === 0)
141
+ continue;
142
+ const tmp = `${path}.${process.pid}.${Date.now()}.tmp`;
143
+ try {
144
+ await writeFile(tmp, kept.length > 0 ? kept.join('\n') + '\n' : '');
145
+ await rename(tmp, path);
146
+ // Only count records as removed after the atomic rename succeeds. If writeFile or
147
+ // rename fails the original file is untouched, and callers (bootstrap.ts uses
148
+ // removed > 0 as a state-change signal) must not be misled into publishing a
149
+ // "stale error cleared" event for a purge that didn't actually happen.
150
+ removed += fileRemoved;
151
+ }
152
+ catch (err) {
153
+ console.warn(`[ErrorRecordStore] rewriteFiltered: atomic rewrite failed for ${file}:`, err);
154
+ // Best-effort tmp cleanup so a partial write doesn't accumulate orphan .tmp files.
155
+ try {
156
+ await unlink(tmp);
157
+ }
158
+ catch { /* ignore — tmp may not exist if writeFile failed early */ }
159
+ }
160
+ }
161
+ return { removed };
162
+ });
163
+ this.chain = result.catch(() => undefined);
164
+ return result;
165
+ }
37
166
  toSummary(record) {
38
167
  return {
39
168
  id: record.id,
@@ -1 +1 @@
1
- {"version":3,"file":"error-record-store.js","sourceRoot":"","sources":["../../src/state/error-record-store.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"error-record-store.js","sourceRoot":"","sources":["../../src/state/error-record-store.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,6 @@
1
- import type { AgentBindingFacts, AgentRuntimeStatus, AgentSnapshot, TaskState } from '../shared/index.js';
1
+ import type { AgentBindingFacts, AgentErrorSummary, AgentRuntimeStatus, AgentSnapshot, TaskState } from '../shared/index.js';
2
2
  import type { TmuxSessionObservation } from '../agent/tmux-probe-poller.js';
3
+ import type { ErrorRecord } from './error-record-store.js';
3
4
  export interface AgentSnapshotCtx {
4
5
  agentManager: {
5
6
  listAgents: () => Array<{
@@ -21,11 +22,16 @@ export interface AgentSnapshotCtx {
21
22
  tmuxSessionStatusStore: {
22
23
  get: (id: string) => TmuxSessionObservation;
23
24
  };
25
+ errorRecordStore?: {
26
+ latestBootstrapForAgent: (agentId: string) => Promise<ErrorRecord | undefined>;
27
+ latestBootstrapByAgent: () => Promise<Map<string, ErrorRecord>>;
28
+ toSummary: (record: ErrorRecord) => AgentErrorSummary;
29
+ };
24
30
  }
25
31
  export declare function agentSnapshot(configured: {
26
32
  id: string;
27
33
  projectId: string;
28
- }, binding: AgentBindingFacts | undefined, tmuxObservation: TmuxSessionObservation, task: TaskState | undefined): AgentSnapshot;
34
+ }, binding: AgentBindingFacts | undefined, tmuxObservation: TmuxSessionObservation, task: TaskState | undefined, latestBootstrapError?: AgentErrorSummary): AgentSnapshot;
29
35
  export declare function deriveRuntimeStatus(binding: AgentBindingFacts | undefined, tmuxObservation: TmuxSessionObservation, task: TaskState | undefined): AgentRuntimeStatus;
30
36
  export declare function buildAllAgentSnapshots(ctx: AgentSnapshotCtx): Promise<AgentSnapshot[]>;
31
37
  export declare function buildAgentSnapshotById(ctx: AgentSnapshotCtx, id: string): Promise<AgentSnapshot | null>;
@@ -1 +1 @@
1
- {"version":3,"file":"snapshot.d.ts","sourceRoot":"","sources":["../../src/state/snapshot.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,iBAAiB,EACjB,kBAAkB,EAClB,aAAa,EACb,SAAS,EACV,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AAE5E,MAAM,WAAW,gBAAgB;IAC/B,YAAY,EAAE;QACZ,UAAU,EAAE,MAAM,KAAK,CAAC;YAAE,EAAE,EAAE,MAAM,CAAC;YAAC,SAAS,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;QAC3D,cAAc,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK;YAAE,EAAE,EAAE,MAAM,CAAC;YAAC,SAAS,EAAE,MAAM,CAAA;SAAE,GAAG,SAAS,CAAC;KAC/E,CAAC;IACF,UAAU,EAAE;QAAE,IAAI,EAAE,MAAM,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAAC;QAAC,GAAG,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC,CAAA;KAAE,CAAC;IACjH,SAAS,EAAE;QAAE,GAAG,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CAAA;KAAE,CAAC;IAC9D,sBAAsB,EAAE;QAAE,GAAG,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,sBAAsB,CAAA;KAAE,CAAC;CACzE;AAOD,wBAAgB,aAAa,CAC3B,UAAU,EAAE;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,EAC7C,OAAO,EAAE,iBAAiB,GAAG,SAAS,EACtC,eAAe,EAAE,sBAAsB,EACvC,IAAI,EAAE,SAAS,GAAG,SAAS,GAC1B,aAAa,CAkBf;AAED,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,iBAAiB,GAAG,SAAS,EACtC,eAAe,EAAE,sBAAsB,EACvC,IAAI,EAAE,SAAS,GAAG,SAAS,GAC1B,kBAAkB,CAiBpB;AA8BD,wBAAsB,sBAAsB,CAAC,GAAG,EAAE,gBAAgB,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC,CAa5F;AAED,wBAAsB,sBAAsB,CAC1C,GAAG,EAAE,gBAAgB,EACrB,EAAE,EAAE,MAAM,GACT,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CAW/B"}
1
+ {"version":3,"file":"snapshot.d.ts","sourceRoot":"","sources":["../../src/state/snapshot.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,iBAAiB,EACjB,iBAAiB,EACjB,kBAAkB,EAClB,aAAa,EACb,SAAS,EACV,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AAC5E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAE3D,MAAM,WAAW,gBAAgB;IAC/B,YAAY,EAAE;QACZ,UAAU,EAAE,MAAM,KAAK,CAAC;YAAE,EAAE,EAAE,MAAM,CAAC;YAAC,SAAS,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;QAC3D,cAAc,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK;YAAE,EAAE,EAAE,MAAM,CAAC;YAAC,SAAS,EAAE,MAAM,CAAA;SAAE,GAAG,SAAS,CAAC;KAC/E,CAAC;IACF,UAAU,EAAE;QAAE,IAAI,EAAE,MAAM,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAAC;QAAC,GAAG,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC,CAAA;KAAE,CAAC;IACjH,SAAS,EAAE;QAAE,GAAG,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CAAA;KAAE,CAAC;IAC9D,sBAAsB,EAAE;QAAE,GAAG,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,sBAAsB,CAAA;KAAE,CAAC;IAGxE,gBAAgB,CAAC,EAAE;QACjB,uBAAuB,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,WAAW,GAAG,SAAS,CAAC,CAAC;QAC/E,sBAAsB,EAAE,MAAM,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC;QAChE,SAAS,EAAE,CAAC,MAAM,EAAE,WAAW,KAAK,iBAAiB,CAAC;KACvD,CAAC;CACH;AAOD,wBAAgB,aAAa,CAC3B,UAAU,EAAE;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,EAC7C,OAAO,EAAE,iBAAiB,GAAG,SAAS,EACtC,eAAe,EAAE,sBAAsB,EACvC,IAAI,EAAE,SAAS,GAAG,SAAS,EAC3B,oBAAoB,CAAC,EAAE,iBAAiB,GACvC,aAAa,CA2Bf;AAED,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,iBAAiB,GAAG,SAAS,EACtC,eAAe,EAAE,sBAAsB,EACvC,IAAI,EAAE,SAAS,GAAG,SAAS,GAC1B,kBAAkB,CAiBpB;AA6DD,wBAAsB,sBAAsB,CAAC,GAAG,EAAE,gBAAgB,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC,CAiB5F;AAED,wBAAsB,sBAAsB,CAC1C,GAAG,EAAE,gBAAgB,EACrB,EAAE,EAAE,MAAM,GACT,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CAa/B"}
@@ -2,12 +2,20 @@ const WORKING_TASK_STATUSES = new Set(['in_progress', 'fixing']);
2
2
  const WAITING_TASK_STATUSES = new Set(['review', 'approved']);
3
3
  const ERROR_TASK_STATUSES = new Set(['failed', 'max_rounds']);
4
4
  const UNREACHABLE_ACTIVE_TASK_GRACE_MS = 30_000;
5
- export function agentSnapshot(configured, binding, tmuxObservation, task) {
5
+ export function agentSnapshot(configured, binding, tmuxObservation, task, latestBootstrapError) {
6
6
  const runtimeStatus = deriveRuntimeStatus(binding, tmuxObservation, task);
7
7
  // When PENDING_IDLE is gated by task status, also hide the matching error card / reason /
8
8
  // message — otherwise the UI keeps a red "waiting on user input" banner that points operators
9
9
  // at a terminal they shouldn't touch (the task is on GitHub now, not in the dev's pane).
10
10
  const suppressPendingIdle = shouldGatePendingIdle(tmuxObservation, task);
11
+ // Bootstrap error visibility is gated by errorRecordStore presence, not by binding.repoPath:
12
+ // (a) never-dispatched agents never get a binding (runSingleTarget skips AgentStore.update on
13
+ // existing=undefined), so repoPath-based suppression keeps showing stale errors forever;
14
+ // (b) once binding.repoPath is set by an early success, a later failure would be SUPPRESSED
15
+ // and the user can't see the new regression.
16
+ // Truth source is now "is there a current bootstrap error record?" — successful bootstraps
17
+ // purge their agent's bootstrap records (see ErrorRecordStore.purgeBootstrapForAgent).
18
+ const showBootstrapError = !!latestBootstrapError;
11
19
  return {
12
20
  id: configured.id,
13
21
  projectId: configured.projectId,
@@ -17,6 +25,7 @@ export function agentSnapshot(configured, binding, tmuxObservation, task) {
17
25
  ...(tmuxObservation.observedAt ? { observedAt: tmuxObservation.observedAt } : {}),
18
26
  ...(binding ? { binding } : {}),
19
27
  ...(!suppressPendingIdle && tmuxObservation.latestError ? { latestError: tmuxObservation.latestError } : {}),
28
+ ...(showBootstrapError ? { latestBootstrapError } : {}),
20
29
  ...(!suppressPendingIdle && tmuxObservation.reason ? { reason: tmuxObservation.reason } : {}),
21
30
  ...(!suppressPendingIdle && tmuxObservation.message ? { message: tmuxObservation.message } : {}),
22
31
  };
@@ -73,13 +82,44 @@ function isRecentPresentObservation(tmuxObservation) {
73
82
  return false;
74
83
  return observedAt - lastPresentAt <= UNREACHABLE_ACTIVE_TASK_GRACE_MS;
75
84
  }
85
+ async function loadLatestBootstrapError(ctx, agentId) {
86
+ if (!ctx.errorRecordStore)
87
+ return undefined;
88
+ try {
89
+ const record = await ctx.errorRecordStore.latestBootstrapForAgent(agentId);
90
+ return record ? ctx.errorRecordStore.toSummary(record) : undefined;
91
+ }
92
+ catch (err) {
93
+ console.warn(`[snapshot] failed to load bootstrap error for ${agentId}:`, err);
94
+ return undefined;
95
+ }
96
+ }
97
+ async function loadLatestBootstrapByAgent(ctx) {
98
+ if (!ctx.errorRecordStore)
99
+ return new Map();
100
+ try {
101
+ const records = await ctx.errorRecordStore.latestBootstrapByAgent();
102
+ const summaries = new Map();
103
+ for (const [agentId, record] of records) {
104
+ summaries.set(agentId, ctx.errorRecordStore.toSummary(record));
105
+ }
106
+ return summaries;
107
+ }
108
+ catch (err) {
109
+ console.warn('[snapshot] failed to batch-load bootstrap errors:', err);
110
+ return new Map();
111
+ }
112
+ }
76
113
  export async function buildAllAgentSnapshots(ctx) {
77
- const bindings = await ctx.agentStore.list();
114
+ const [bindings, bootstrapErrorsByAgent] = await Promise.all([
115
+ ctx.agentStore.list(),
116
+ loadLatestBootstrapByAgent(ctx),
117
+ ]);
78
118
  const bindingByAgentId = new Map(bindings.map((s) => [s.id, s]));
79
119
  return Promise.all(ctx.agentManager.listAgents().map(async (configured) => {
80
120
  const binding = bindingByAgentId.get(configured.id);
81
121
  const task = binding?.taskId ? await ctx.taskStore.get(binding.taskId) : null;
82
- return agentSnapshot(configured, binding, ctx.tmuxSessionStatusStore.get(configured.id), task ?? undefined);
122
+ return agentSnapshot(configured, binding, ctx.tmuxSessionStatusStore.get(configured.id), task ?? undefined, bootstrapErrorsByAgent.get(configured.id));
83
123
  }));
84
124
  }
85
125
  export async function buildAgentSnapshotById(ctx, id) {
@@ -88,6 +128,7 @@ export async function buildAgentSnapshotById(ctx, id) {
88
128
  return null;
89
129
  const binding = await ctx.agentStore.get(id);
90
130
  const task = binding?.taskId ? await ctx.taskStore.get(binding.taskId) : null;
91
- return agentSnapshot(configured, binding ?? undefined, ctx.tmuxSessionStatusStore.get(id), task ?? undefined);
131
+ const latestBootstrapError = await loadLatestBootstrapError(ctx, id);
132
+ return agentSnapshot(configured, binding ?? undefined, ctx.tmuxSessionStatusStore.get(id), task ?? undefined, latestBootstrapError);
92
133
  }
93
134
  //# sourceMappingURL=snapshot.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"snapshot.js","sourceRoot":"","sources":["../../src/state/snapshot.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"snapshot.js","sourceRoot":"","sources":["../../src/state/snapshot.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ var Je=Object.defineProperty;var Ve=(s,t,n)=>t in s?Je(s,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):s[t]=n;var L=(s,t,n)=>Ve(s,typeof t!="symbol"?t+"":t,n);import{r as a,j as e,c as Ke}from"./react-BG4Iuztk.js";import{x as Ye,a as Ze}from"./xterm-D5X2JljJ.js";import{L as ee,u as ve,a as Se,B as Xe,R as et,b as ae}from"./router-B_Nv0oRz.js";(function(){const t=document.createElement("link").relList;if(t&&t.supports&&t.supports("modulepreload"))return;for(const r of document.querySelectorAll('link[rel="modulepreload"]'))o(r);new MutationObserver(r=>{for(const i of r)if(i.type==="childList")for(const c of i.addedNodes)c.tagName==="LINK"&&c.rel==="modulepreload"&&o(c)}).observe(document,{childList:!0,subtree:!0});function n(r){const i={};return r.integrity&&(i.integrity=r.integrity),r.referrerPolicy&&(i.referrerPolicy=r.referrerPolicy),r.crossOrigin==="use-credentials"?i.credentials="include":r.crossOrigin==="anonymous"?i.credentials="omit":i.credentials="same-origin",i}function o(r){if(r.ep)return;r.ep=!0;const i=n(r);fetch(r.href,i)}})();const me="/api",ke="baxian.token",ye="baxian:unauthorized";function Ne(){try{return typeof localStorage<"u"?localStorage.getItem(ke):null}catch{return null}}function tt(s){try{localStorage.setItem(ke,s)}catch(t){console.error("Failed to save auth token to localStorage",t)}}function st(){try{localStorage.removeItem(ke)}catch(s){console.error("Failed to clear auth token from localStorage",s)}}function ie(s){const t=Ne();return{...s??{},...t?{Authorization:`Bearer ${t}`}:{}}}class de extends Error{constructor(t,n,o){super(n),this.status=t,this.details=o,this.name="ApiError"}}async function oe(s){const t=await s.text();let n=t||`HTTP ${s.status}`,o;try{const r=JSON.parse(t);typeof r.error=="string"&&(n=r.error),Array.isArray(r.details)&&(o=r.details)}catch{}throw s.status===401&&typeof window<"u"&&window.dispatchEvent(new CustomEvent(ye)),new de(s.status,n,o)}async function se(s){const t=await fetch(`${me}${s}`,{headers:ie()});return t.ok||await oe(t),t.json()}async function rt(){const s=await fetch("/health");return s.ok||await oe(s),s.json()}async function Z(s,t,n){const o=t!==void 0,r=await fetch(`${me}${s}`,{method:"POST",headers:o?ie({"Content-Type":"application/json"}):ie(),body:o?JSON.stringify(t):void 0,signal:n==null?void 0:n.signal});return r.ok||await oe(r),r.json()}async function nt(s,t,n){const o=await fetch(`${me}${s}`,{method:"PATCH",headers:ie({"Content-Type":"application/json"}),body:t?JSON.stringify(t):void 0,signal:n==null?void 0:n.signal});if(o.ok||await oe(o),o.status===204)return;const r=await o.text();if(r)return JSON.parse(r)}async function Te(s){const t=await fetch(`${me}${s}`,{method:"DELETE",headers:ie()});if(t.ok||await oe(t),t.status===204)return;const n=await t.text();if(n)return JSON.parse(n)}const W=encodeURIComponent,O={agents:{list:()=>se("/agents"),get:s=>se(`/agents/${W(s)}`),stop:s=>Te(`/agents/${W(s)}/session`),probe:(s,t,n)=>Z("/agents/probe",{mode:s,host:t},n)},tasks:{list:s=>se(`/tasks${s?`?projectId=${W(s)}`:""}`),get:s=>se(`/tasks/${W(s)}`),create:s=>Z("/tasks",s),update:(s,t)=>nt(`/tasks/${W(s)}`,t),retry:s=>Z(`/tasks/${W(s)}/retry`),review:s=>Z(`/tasks/${W(s)}/review`)},projects:{list:()=>se("/projects"),get:s=>se(`/projects/${W(s)}`),create:s=>Z("/projects",s),addAgent:(s,t)=>Z(`/projects/${W(s)}/agents`,t),deleteAgent:(s,t)=>Te(`/projects/${W(s)}/agents/${W(t)}`),resumeAgent:(s,t)=>Z(`/projects/${W(s)}/agents/${W(t)}/resume`),bootstrap:s=>Z(`/projects/${W(s)}/bootstrap`)},config:{get:()=>se("/config")},health:{get:rt},server:{restart:()=>Z("/restart")}},Fe=a.createContext(null),at={success:"bg-green-50 border-green-200 text-green-900",warn:"bg-amber-50 border-amber-200 text-amber-900",error:"bg-red-50 border-red-200 text-red-900"},it={success:"✅",warn:"⚠️",error:"❌"};let ot=1;function lt({children:s}){const[t,n]=a.useState([]),o=a.useCallback(i=>{n(c=>c.filter(m=>m.id!==i))},[]),r=a.useCallback(i=>{const c=ot++,m=i.durationMs??3e3;n(p=>[...p,{...i,id:c}]),setTimeout(()=>o(c),m)},[o]);return e.jsxs(Fe.Provider,{value:{show:r},children:[s,e.jsx("div",{className:"fixed top-4 right-4 z-[60] flex flex-col gap-2 pointer-events-none",children:t.map(i=>e.jsx("div",{className:`pointer-events-auto px-4 py-3 rounded shadow-lg border w-80 ${at[i.kind]}`,role:"status",children:e.jsxs("div",{className:"flex items-start gap-2",children:[e.jsx("span",{"aria-hidden":!0,children:it[i.kind]}),e.jsxs("div",{className:"flex-1",children:[e.jsx("div",{className:"font-semibold",children:i.title}),i.body&&e.jsx("div",{className:"text-sm mt-1 whitespace-pre-line",children:i.body})]}),e.jsx("button",{type:"button",onClick:()=>o(i.id),className:"text-current opacity-50 hover:opacity-100","aria-label":"Dismiss",children:"✕"})]})},i.id))})]})}function le(){const s=a.useContext(Fe);if(!s)throw new Error("useToast must be inside <ToastProvider>");return s}const ue="baxian.pendingRestart",ct=500,dt=3e4,ze=a.createContext(null);function ut(){try{const s=localStorage.getItem(ue);if(!s)return{count:0,baselineStartedAt:null};const t=JSON.parse(s);return{count:typeof t.count=="number"?t.count:0,baselineStartedAt:typeof t.baselineStartedAt=="string"?t.baselineStartedAt:null}}catch{return{count:0,baselineStartedAt:null}}}function ht(s){try{s.count<=0?localStorage.removeItem(ue):localStorage.setItem(ue,JSON.stringify(s))}catch{}}function mt({children:s}){const t=ut(),[n,o]=a.useState(t.count),[r,i]=a.useState(t.baselineStartedAt),[c,m]=a.useState(t.count>0?"pending":"idle"),[p,b]=a.useState(),u=a.useRef(t.count),h=a.useRef(t.count>0?"pending":"idle"),f=a.useRef(0),x=a.useCallback(S=>{u.current=S,o(S)},[]),d=a.useCallback(S=>{o(A=>{const g=S(A);return u.current=g,g})},[]),j=a.useCallback(S=>{h.current=S,m(S)},[]);a.useEffect(()=>{ht({count:n,baselineStartedAt:r})},[n,r]),a.useEffect(()=>{let S=!1;(async()=>{try{const g=await O.health.get();if(S)return;i(R=>R!==null&&g.startedAt!==R?(x(0),j("idle"),null):R)}catch{}})();const A=g=>{if(g.key===ue){if(g.newValue===null){if(h.current==="restarting"&&f.current>0){x(f.current),i(null);return}x(0),i(null),h.current!=="restarting"&&j("idle");return}try{const R=JSON.parse(g.newValue);typeof R.count=="number"&&(h.current==="restarting"&&R.count>u.current&&(f.current+=R.count-u.current),x(R.count),h.current!=="restarting"&&j(R.count>0?"pending":"idle")),typeof R.baselineStartedAt=="string"?i(R.baselineStartedAt):R.baselineStartedAt===null&&i(null)}catch{}}};return window.addEventListener("storage",A),()=>{S=!0,window.removeEventListener("storage",A)}},[x,j]);const l=a.useRef(!1),T=a.useCallback(()=>{d(S=>S+1),h.current==="restarting"?f.current+=1:j("pending"),i(S=>(S!==null||l.current||(l.current=!0,(async()=>{try{const A=await O.health.get();i(g=>g??A.startedAt)}catch{}finally{l.current=!1}})()),S))},[j,d]),$=a.useCallback(async()=>{f.current=0,b(void 0),j("restarting");let S;try{S=(await O.health.get()).startedAt}catch(g){j("failed"),b(`获取重启前 startedAt 失败: ${g instanceof Error?g.message:String(g)}`);return}try{await O.server.restart()}catch(g){if(!(g instanceof de&&g.status===409)){j("failed"),b(`触发重启失败: ${g instanceof Error?g.message:String(g)}`);return}}const A=Date.now();for(;Date.now()-A<dt;){await new Promise(g=>setTimeout(g,ct));try{const g=await O.health.get();if(g.startedAt!==S){const R=f.current;f.current=0,i(R>0?g.startedAt:null),x(R),j(R>0?"pending":"idle");return}}catch{}}j("failed"),b("重启超时(30s 未恢复)。请检查日志或手动 baxian start -c <path>")},[x,j]);return e.jsx(ze.Provider,{value:{phase:c,count:n,error:p,flagDirty:T,triggerRestart:$},children:s})}function xe(){const s=a.useContext(ze);if(!s)throw new Error("usePendingRestart must be used inside PendingRestartProvider");return s}const xt=[500,1e3,2e3,4e3,8e3,15e3,3e4];class Me{constructor(t){L(this,"attempts",0);L(this,"timer",null);L(this,"delaysMs");this.opts=t,this.delaysMs=t.delaysMs??xt}schedule(){if(this.timer||!this.shouldReconnect())return;const t=this.delaysMs[Math.min(this.attempts,this.delaysMs.length-1)];this.attempts+=1,this.timer=setTimeout(()=>{this.timer=null,this.shouldReconnect()&&this.opts.reconnect()},t)}cancel(){this.timer&&(clearTimeout(this.timer),this.timer=null)}reset(){this.attempts=0}shouldReconnect(){return this.opts.shouldReconnect?this.opts.shouldReconnect():!0}}let Ie=0;function ft(){Ie++;const s=Math.random().toString(36).slice(2,8);return`sub-${Date.now().toString(36)}-${Ie}-${s}`}function bt(s){return Array.from(new TextEncoder().encode(s)).map(t=>t.toString(16).padStart(2,"0")).join("")}function pt(){return`${location.protocol==="https:"?"wss":"ws"}://${location.host}/api/stream`}const gt=(s,t)=>t&&t.length>0?new WebSocket(s,t):new WebSocket(s);class yt{constructor(t={}){L(this,"wsUrl");L(this,"wsFactory");L(this,"tokenProvider");L(this,"ws",null);L(this,"subs",new Map);L(this,"snapshotPending",new Set);L(this,"preSubscribeQueue",new Map);L(this,"outbox",[]);L(this,"reconnectScheduler");L(this,"explicitlyClosed",!1);this.wsUrl=t.wsUrl??pt(),this.wsFactory=t.wsFactory??gt,this.tokenProvider=t.tokenProvider??Ne,this.reconnectScheduler=new Me({reconnect:()=>this.openSocket(),shouldReconnect:()=>!this.explicitlyClosed&&this.subs.size>0})}subscribe(t){const n=ft(),o={subscriberId:n,agentId:t.agentId,mode:t.mode,onSnapshot:t.onSnapshot,onData:t.onData,onError:t.onError,onSessionGone:t.onSessionGone};return this.subs.set(n,o),this.snapshotPending.add(n),this.preSubscribeQueue.set(n,[]),this.ensureSocket(),this.wsSendOrQueue({op:"subscribe",subscriberId:n,agentId:t.agentId,mode:t.mode}),{subscriberId:n,unsubscribe:()=>this.unsubscribe(n)}}send(t,n){if(this.subs.has(t)){if(this.snapshotPending.has(t)){this.outbox.push({op:"input",subscriberId:t,data:n});return}this.wsSendOrQueue({op:"input",subscriberId:t,data:n})}}resize(t,n,o){const r=this.subs.get(t);r&&(r.lastSize={cols:n,rows:o},!this.snapshotPending.has(t)&&this.wsSendOrQueue({op:"resize",subscriberId:t,cols:n,rows:o}))}ping(){this.wsSendOrQueue({op:"ping"})}close(){if(this.explicitlyClosed=!0,this.reconnectScheduler.cancel(),this.reconnectScheduler.reset(),this.ws){try{this.ws.close()}catch{}this.ws=null}this.subs.clear(),this.snapshotPending.clear(),this.preSubscribeQueue.clear(),this.outbox=[]}unsubscribe(t){this.subs.has(t)&&(this.subs.delete(t),this.snapshotPending.delete(t),this.preSubscribeQueue.delete(t),this.wsSendOrQueue({op:"unsubscribe",subscriberId:t}),this.subs.size===0&&this.teardownSocket())}teardownSocket(){if(this.reconnectScheduler.cancel(),this.reconnectScheduler.reset(),this.outbox=[],this.ws){try{this.ws.close()}catch{}this.ws=null}}ensureSocket(){this.explicitlyClosed||this.ws&&(this.ws.readyState===WebSocket.OPEN||this.ws.readyState===WebSocket.CONNECTING)||this.openSocket()}openSocket(){if(this.explicitlyClosed)return;this.reconnectScheduler.cancel();const t=this.tokenProvider(),n=t?[`baxian.token.${bt(t)}`]:void 0;let o;try{o=this.wsFactory(this.wsUrl,n)}catch(r){console.warn("[pane-stream] WebSocket constructor threw:",r),this.scheduleReconnect();return}this.ws=o,o.onopen=()=>{if(o!==this.ws)return;this.reconnectScheduler.reset();for(const i of this.subs.values()){this.snapshotPending.add(i.subscriberId),this.preSubscribeQueue.set(i.subscriberId,[]),i.snapshotSeq=void 0;try{o.send(JSON.stringify({op:"subscribe",subscriberId:i.subscriberId,agentId:i.agentId,mode:i.mode}))}catch(c){console.warn("[pane-stream] resubscribe send failed:",c)}}const r=this.outbox;this.outbox=[];for(const i of r)if(i.op!=="subscribe"){if("subscriberId"in i&&i.subscriberId){if(!this.subs.has(i.subscriberId))continue;if(this.snapshotPending.has(i.subscriberId)&&i.op!=="unsubscribe"){this.outbox.push(i);continue}}try{o.send(JSON.stringify(i))}catch(c){console.warn("[pane-stream] outbox flush failed:",c)}}},o.onmessage=r=>{if(o!==this.ws)return;let i;try{const c=typeof r.data=="string"?r.data:String(r.data);i=JSON.parse(c)}catch{return}this.handleMessage(i)},o.onclose=()=>{o===this.ws&&(this.ws=null,!this.explicitlyClosed&&this.subs.size!==0&&this.scheduleReconnect())},o.onerror=()=>{}}scheduleReconnect(){this.reconnectScheduler.schedule()}wsSendOrQueue(t){if(this.ws&&this.ws.readyState===WebSocket.OPEN)try{this.ws.send(JSON.stringify(t));return}catch(n){console.warn("[pane-stream] send failed, will queue:",n)}this.outbox.push(t)}handleMessage(t){var n,o;switch(t.type){case"snapshot":this.handleSnapshot(t);break;case"subscribed":this.handleSubscribed(t);break;case"data":this.dispatch(t);break;case"session_gone":for(const r of[...this.subs.values()])r.agentId===t.agentId&&((n=r.onSessionGone)==null||n.call(r));break;case"error":{if(t.subscriberId){const r=this.subs.get(t.subscriberId);(o=r==null?void 0:r.onError)==null||o.call(r,{code:t.code,message:t.message})}else console.warn("[pane-stream] connection-level error:",t.code,t.message);break}}}handleSnapshot(t){const n=this.subs.get(t.subscriberId);n&&n.onSnapshot({cols:t.cols,rows:t.rows,data:t.data})}handleSubscribed(t){const n=this.subs.get(t.subscriberId);if(!n)return;n.snapshotSeq=t.snapshotSeq,n.lastSize||(n.lastSize={cols:t.cols,rows:t.rows}),this.snapshotPending.delete(t.subscriberId);const o=this.preSubscribeQueue.get(t.subscriberId);if(this.preSubscribeQueue.delete(t.subscriberId),o)for(const r of o)r.seq>t.snapshotSeq&&n.onData(r.data);n.mode==="full"&&n.lastSize&&this.wsSendOrQueue({op:"resize",subscriberId:n.subscriberId,cols:n.lastSize.cols,rows:n.lastSize.rows}),this.flushOutboxForSub(t.subscriberId)}flushOutboxForSub(t){if(this.outbox.length===0||!this.ws||this.ws.readyState!==WebSocket.OPEN)return;const n=[];for(const o of this.outbox)if("subscriberId"in o&&o.subscriberId===t&&o.op!=="subscribe")try{this.ws.send(JSON.stringify(o))}catch(r){console.warn("[pane-stream] flushOutboxForSub send failed:",r)}else n.push(o);this.outbox=n}dispatch(t){for(const n of this.subs.values())if(n.agentId===t.agentId)if(this.snapshotPending.has(n.subscriberId)){const o=this.preSubscribeQueue.get(n.subscriberId);o&&o.push({seq:t.seq,data:t.data})}else n.onData(t.data)}}let be=null;function pe(){return be||(be=new yt),be}function jt(s){const{agentId:t,mode:n}=s,o=a.useRef(null),r=a.useRef({onSnapshot:s.onSnapshot,onData:s.onData,onError:s.onError,onSessionGone:s.onSessionGone});r.current={onSnapshot:s.onSnapshot,onData:s.onData,onError:s.onError,onSessionGone:s.onSessionGone},a.useEffect(()=>{const p=pe().subscribe({agentId:t,mode:n,onSnapshot:b=>r.current.onSnapshot(b),onData:b=>r.current.onData(b),onError:b=>{var u,h;return(h=(u=r.current).onError)==null?void 0:h.call(u,b)},onSessionGone:()=>{var b,u;return(u=(b=r.current).onSessionGone)==null?void 0:u.call(b)}});return o.current=p.subscriberId,()=>{o.current=null,p.unsubscribe()}},[t,n]);const i=a.useCallback(m=>{const p=o.current;p&&pe().send(p,m)},[]),c=a.useCallback((m,p)=>{const b=o.current;b&&pe().resize(b,m,p)},[]);return{send:i,resize:c}}const wt=18,vt=250,St=256*1024,he="#e1e2e7",kt={background:he,foreground:"#3760bf",cursor:"#3760bf",cursorAccent:he,selectionBackground:"#b7c1e3",selectionForeground:"#3760bf",black:"#b4b5b9",red:"#f52a65",green:"#587539",yellow:"#8c6c3e",blue:"#2e7de9",magenta:"#9854f1",cyan:"#007197",white:"#6172b0",brightBlack:"#a1a6c5",brightRed:"#ff4774",brightGreen:"#5c8524",brightYellow:"#a27629",brightBlue:"#358aff",brightMagenta:"#a463ff",brightCyan:"#007ea8",brightWhite:"#3760bf"},Nt=/\x1b\[(?:\?[\d;]*c|>[\d;]*c|\??\d+;\d+R|\d+n)/g;function Et(s){return s.replace(Nt,"")}function je({agentId:s,mode:t,interactive:n=!1,maxLines:o,className:r,autoFocus:i=!0,deferFullUntilFocus:c=!1}){const m=a.useRef(null),p=a.useRef(null),b=a.useRef(null),u=a.useRef(!1),h=a.useRef(""),f=a.useRef([]),x=a.useRef(0),d=a.useRef(null),j=a.useRef(null),l=a.useRef(Promise.resolve()),T=a.useRef(0),[$,S]=a.useState(null),[A,g]=a.useState(!1),R=`${s}\0${t}\0${c?"1":"0"}`,[k,P]=a.useState({key:R,active:!1}),N=k.key===R&&k.active,D=t==="full"&&c,F=D&&!N?"preview":t,I=n&&F==="full",M=(y,_)=>_.length===0?Promise.resolve():new Promise(C=>{try{y.write(_,()=>C())}catch(w){console.warn("[pane-terminal] write failed:",w),C()}}),Q=(y,_)=>{l.current=l.current.then(async()=>{const C=p.current;if(!(!C||_!==T.current))try{await y(C)}catch(w){console.warn("[pane-terminal] terminal task failed:",w)}}).catch(C=>{console.warn("[pane-terminal] write chain failed:",C)})},U=(y,_)=>{Q(C=>M(C,y),_)},J=()=>{d.current!==null&&(cancelAnimationFrame(d.current),d.current=null),j.current!==null&&(clearTimeout(j.current),j.current=null)},Y=()=>{J(),f.current=[],x.current=0},H=()=>{J();const y=f.current;y.length!==0&&(f.current=[],x.current=0,U(y.join(""),T.current))},V=y=>{if(y.length!==0){if(f.current.push(y),x.current+=y.length,x.current>=St){H();return}d.current===null&&(d.current=requestAnimationFrame(H)),j.current===null&&(j.current=setTimeout(H,vt))}},{send:K,resize:te}=jt({agentId:s,mode:F,onSnapshot:({cols:y,rows:_,data:C})=>{if(p.current)try{const v=T.current+1;T.current=v,Y(),Q(async q=>{q.reset(),y>0&&_>0&&q.resize(y,_),await M(q,C)},v)}catch(v){console.warn("[pane-terminal] snapshot write failed:",v)}},onData:y=>{V(y)},onError:y=>S(`${y.code}: ${y.message}`),onSessionGone:()=>g(!0)});a.useEffect(()=>{S(null),g(!1)},[s,F]),a.useEffect(()=>{h.current=""},[R]),a.useEffect(()=>{if(F!=="full")return;const y=h.current;y.length!==0&&(h.current="",K(y))},[K,F]);const G=a.useCallback(()=>{!n||!D||N||(u.current=!0,P({key:R,active:!0}))},[R,N,n,D]);a.useEffect(()=>{const y=m.current;if(!y)return;let _=!1;const C=new Ye.Terminal({cursorBlink:n,disableStdin:!n,theme:kt,scrollback:F==="full"?5e3:1e3}),w=new Ze.FitAddon;if(C.loadAddon(w),C.open(y),p.current=C,b.current=w,n&&(i||u.current)){u.current=!1;try{C.focus()}catch{}}n&&C.onData(re=>{const ne=Et(re);if(ne.length!==0){if(D&&!N){h.current+=ne,G();return}K(ne)}});const v=()=>y.clientWidth>0&&y.clientHeight>0,q=(re=!1)=>{if(!v())return!1;const ne=C.cols,He=C.rows;try{w.fit()}catch{return!1}return C.cols>0&&C.rows>0&&(re||C.cols!==ne||C.rows!==He)&&te(C.cols,C.rows),!0};let B=null,X=null,ce=null,Ge=0;const Ae=()=>{B||(B=new ResizeObserver(()=>{X&&clearTimeout(X),X=setTimeout(()=>{X=null,q()},100)}),B.observe(y))},Ce=()=>{ce=requestAnimationFrame(()=>{if(ce=null,!(_||!I)){if(q(!0)){Ae();return}if(Ge++<5){Ce();return}Ae()}})};return Ce(),()=>{_=!0,ce!==null&&cancelAnimationFrame(ce),d.current!==null&&(cancelAnimationFrame(d.current),d.current=null),j.current!==null&&(clearTimeout(j.current),j.current=null),T.current++,f.current=[],x.current=0,l.current=Promise.resolve(),X&&clearTimeout(X),B==null||B.disconnect(),p.current=null,b.current=null;try{C.dispose()}catch(re){console.warn("[pane-terminal] dispose failed:",re)}}},[G,s,i,I,N,n,K,D,F,te]);const E=()=>{var y;if(n){G();try{(y=p.current)==null||y.focus()}catch{}}},z=o&&o>0?{maxHeight:`${o*wt}px`}:void 0;return e.jsxs("div",{className:r??"flex flex-col h-full w-full min-h-0 bg-[#e1e2e7]",children:[($||A)&&e.jsx("div",{className:"px-3 py-1 text-[11px] font-mono text-red-300 bg-red-950/40 border-b border-red-900/60",children:A?"session ended":$}),e.jsx("div",{ref:m,className:"flex-1 min-h-0 overflow-hidden px-2 py-1.5",style:z,onMouseDown:E})]})}const Rt={unknown:{label:"Unknown",cls:"bg-slate-100 text-slate-700"},idle:{label:"Idle",cls:"bg-gray-100 text-gray-700"},pending:{label:"Pending user",cls:"bg-amber-200 text-amber-900"},working:{label:"Working",cls:"bg-green-100 text-green-800"},waiting:{label:"Waiting",cls:"bg-blue-100 text-blue-800"},error:{label:"Error",cls:"bg-red-100 text-red-800"}},At={present:{label:"Session present",cls:"bg-emerald-100 text-emerald-800"},absent:{label:"No session",cls:"bg-gray-100 text-gray-700"},unreachable:{label:"Host unreachable",cls:"bg-amber-100 text-amber-800"},unknown:{label:"Session unknown",cls:"bg-slate-100 text-slate-600"}};function Ct({agent:s,projectId:t,role:n,onDeleted:o,pendingRestart:r=!1,terminalLoading:i=!1,showTaskBinding:c=!0,terminalMode:m="activity-preview"}){var G,E,z,y,_,C,w;const[p,b]=a.useState(!1),[u,h]=a.useState(null),{show:f}=le(),{flagDirty:x}=xe(),[d,j]=a.useState(!1),[l,T]=a.useState(null),[$,S]=a.useState(!1),[A,g]=a.useState(!1),[R,k]=a.useState(!1),P=(G=s.binding)==null?void 0:G.taskId,N=((E=s.binding)==null?void 0:E.status)==="awaiting_human",D=!!((z=s.binding)!=null&&z.creationToken)&&!((y=s.binding)!=null&&y.paneId)&&!N&&s.reason!=="PENDING_HUMAN",F=D?{label:"Starting",cls:"bg-sky-100 text-sky-800"}:Rt[s.runtimeStatus],I=D?{label:"Starting session",cls:"bg-sky-100 text-sky-800"}:At[s.tmuxSessionStatus],M=m==="activity-preview"&&!D&&(s.runtimeStatus==="working"||s.runtimeStatus==="pending"),Q=m==="embedded-full",U=i||r||D,J=i?"Agent 状态加载中":r?"重启 baxian server 后可用":"Agent 正在启动",Y=async()=>{b(!0),h(null);try{await O.agents.stop(s.id)}catch(v){h(v instanceof Error?v.message:String(v))}finally{b(!1)}},H=async()=>{if(P&&window.confirm(`请 QA 对 task ${P} 重审?这会让 QA agent 立即开始新一轮 review(reviewRound +1)。`)){S(!0);try{const v=await O.tasks.review(P);f({kind:"success",title:`已派 QA 重审 (round ${v.reviewRound})`})}catch(v){f({kind:"error",title:"Review 派发失败",body:v instanceof Error?v.message:String(v)})}finally{S(!1)}}},V=async()=>{k(!0);try{(await O.projects.bootstrap(t)).ok?f({kind:"success",title:"Bootstrap retry 完成",body:"agent 状态将在下一次刷新生效。"}):f({kind:"warn",title:"Bootstrap retry 仍失败",body:"看一下红色错误卡的最新原因,按提示修复后再试。"})}catch(v){f({kind:"error",title:"Bootstrap retry 失败",body:v instanceof Error?v.message:String(v)})}finally{k(!1)}},K=async()=>{if(window.confirm(`确认 Resume Agent ${s.id}?baxian 会清除 awaiting_human 状态,agent 重新可派遣。`)){g(!0);try{const v=await O.projects.resumeAgent(t,s.id);f({kind:"success",title:`Agent ${s.id} 已 Resume`,body:v.releasedBinding?"原任务已释放,agent 可接新任务。":"保留绑定(原任务仍 active)。"})}catch(v){f({kind:"error",title:"Resume 失败",body:v instanceof Error?v.message:String(v)})}finally{g(!1)}}},te=async()=>{if(window.confirm(`确认删除 Agent ${s.id}?此操作不可撤销`)){j(!0),T(null);try{const v=await O.projects.deleteAgent(t,s.id);v!=null&&v.restartRequired&&x();const q=(v==null?void 0:v.removed)??[s.id];if(q.length>1){const B=q.filter(X=>X!==s.id).join(", ");f({kind:"warn",title:`已删除 Agent ${s.id}`,body:`配对的 QA Agent ${B} 也被一并移除。`})}else f({kind:"success",title:`Agent ${s.id} 已删除`});o==null||o()}catch(v){T(v instanceof Error?v.message:String(v))}finally{j(!1)}}};return e.jsxs("div",{className:"bg-white rounded-lg border p-4 min-w-0 h-full flex flex-col",children:[e.jsxs("div",{className:"flex items-start justify-between gap-2 mb-2",children:[e.jsx("span",{className:"font-mono font-bold",children:s.id}),e.jsxs("div",{className:"flex flex-wrap justify-end gap-1",children:[N&&e.jsx("span",{className:"px-2 py-0.5 rounded text-xs font-medium bg-amber-200 text-amber-900",title:((_=s.binding)==null?void 0:_.awaitingReason)??"需人工处理",children:"Held"}),e.jsx("span",{className:`px-2 py-0.5 rounded text-xs font-medium ${F.cls}`,children:F.label}),e.jsx("span",{className:`px-2 py-0.5 rounded text-xs font-medium ${I.cls}`,children:I.label}),s.stale&&e.jsx("span",{className:"px-2 py-0.5 rounded text-xs font-medium bg-orange-100 text-orange-800",title:s.observedAt?`Last observed at ${s.observedAt}`:void 0,children:"Stale"})]})]}),D&&e.jsx("div",{className:"text-xs text-sky-900 mb-2 bg-sky-50 border border-sky-200 px-2 py-2 rounded",children:"Agent 正在启动,终端可用后会自动刷新。"}),N&&e.jsxs("div",{className:"text-xs text-amber-900 mb-2 bg-amber-50 border border-amber-200 px-2 py-2 rounded",children:[e.jsx("span",{className:"font-mono",children:(C=s.binding)==null?void 0:C.awaitingPhase}),((w=s.binding)==null?void 0:w.awaitingReason)&&e.jsxs("span",{children:[" · ",s.binding.awaitingReason]})]}),!D&&s.runtimeStatus==="pending"&&e.jsxs("div",{className:"text-xs text-amber-900 mb-2 bg-amber-50 border border-amber-200 px-2 py-2 rounded space-y-1",children:[e.jsx("div",{className:"font-medium",children:"等待人工介入"}),e.jsxs("div",{children:["Agent 正在等待人工输入。请打开 ",e.jsx(ee,{to:`/terminal/${s.id}`,className:"text-blue-700 underline",children:"Terminal"})," 处理; 处理完后状态会随下一次观测刷新。"]})]}),s.latestError&&e.jsxs("div",{className:"text-xs text-red-700 mb-2 bg-red-50 border border-red-200 px-2 py-2 rounded space-y-1",children:[e.jsx("div",{className:"font-medium break-words",children:s.latestError.message}),e.jsxs("div",{className:"text-[11px] text-red-600",children:[s.latestError.reason," · ",s.latestError.occurredAt]})]}),s.latestBootstrapError&&e.jsxs("div",{className:"text-xs text-red-700 mb-2 bg-red-50 border border-red-200 px-2 py-2 rounded space-y-1",children:[e.jsx("div",{className:"font-medium break-words",children:s.latestBootstrapError.message}),s.latestBootstrapError.recommendation&&e.jsx("div",{className:"break-words",children:s.latestBootstrapError.recommendation}),e.jsxs("div",{className:"flex items-center justify-between gap-2",children:[e.jsxs("div",{className:"text-[11px] text-red-600 truncate",children:[s.latestBootstrapError.reason," · ",s.latestBootstrapError.occurredAt]}),e.jsx("button",{type:"button",onClick:V,disabled:R,className:"text-[11px] px-2 py-1 rounded border border-red-300 bg-white text-red-700 hover:bg-red-100 disabled:opacity-50 disabled:cursor-not-allowed shrink-0",children:R?"Retrying…":"Retry bootstrap"})]})]}),c&&P&&e.jsxs("div",{className:"text-sm text-gray-500 mb-2",children:["Task: ",P]}),M&&e.jsx("div",{className:"mb-2 border border-zinc-800",style:{backgroundColor:he},children:e.jsx(je,{agentId:s.id,mode:"preview",maxLines:6,interactive:!1})}),Q&&e.jsx("div",{className:"mt-3 mb-2 h-80 min-h-0 overflow-hidden border border-zinc-800",style:{backgroundColor:he},children:U?e.jsx("div",{className:"flex h-full items-center justify-center px-3 text-sm text-gray-600",children:J}):e.jsx(je,{agentId:s.id,mode:"full",interactive:!0,autoFocus:!1,deferFullUntilFocus:!0})}),r&&e.jsx("div",{className:"text-xs text-amber-700 mb-2 bg-amber-50 px-2 py-1 rounded",children:"⚠️ 重启 baxian server 后生效"}),e.jsxs("div",{className:"mt-3 flex flex-wrap gap-x-3 gap-y-2 items-center",children:[U?e.jsx("span",{className:"text-sm text-gray-400 cursor-not-allowed",title:J,children:"Terminal"}):e.jsx(ee,{to:`/terminal/${s.id}`,className:"text-sm text-blue-600 hover:underline",children:"Terminal"}),!r&&s.runtimeStatus==="working"&&e.jsx("button",{onClick:Y,disabled:p,className:"text-sm text-red-600 hover:underline disabled:opacity-50",children:p?"Stopping…":"Stop"}),u&&e.jsx("span",{className:"text-xs text-red-500",children:u}),N&&e.jsx("button",{type:"button",onClick:K,disabled:A,title:"清除 awaiting_human 状态,让 agent 重新可派遣",className:"text-sm text-amber-700 hover:underline disabled:opacity-50",children:A?"Resuming…":"Resume"}),!r&&P&&n==="dev"&&e.jsx("button",{type:"button",onClick:H,disabled:$,title:`让 QA 立即对 task ${P} 跑一轮 review(需要该 task 已有 PR)`,className:"text-sm text-purple-700 hover:underline disabled:opacity-50",children:$?"Dispatching…":"Request QA review"}),e.jsx("button",{type:"button",onClick:te,disabled:d,className:"text-sm text-red-600 hover:underline disabled:opacity-50 ml-auto","aria-label":`Delete agent ${s.id}`,children:d?"删除中…":"🗑"}),l&&e.jsx("span",{className:"text-xs text-red-500",children:l})]})]})}const Tt=new Set(["in_progress","review","fixing","approved"]);function Be({group:s,projectId:t,agentsById:n,agentsLoaded:o,agentsError:r=!1,tasks:i,onDeleted:c,terminalMode:m="activity-preview"}){const p=s.find(x=>x.role==="dev")??s[0],b=s.find(x=>x.role==="qa"),u=i.filter(x=>It(x,p==null?void 0:p.id,b==null?void 0:b.id)),h=`Agent group ${s.map(x=>x.id).join(" / ")}`,f=m==="embedded-full"?s.length<=1?"lg:grid-cols-1":s.length===2?"lg:grid-cols-2":s.length===3?"lg:grid-cols-3":"lg:grid-cols-4":"sm:grid-cols-2";return e.jsxs("div",{role:"group","aria-label":h,className:"min-w-0",children:[u.length>0?e.jsx("div",{className:"mb-2 max-h-28 overflow-y-auto rounded border bg-white divide-y",children:u.map(x=>{const d=x.phase==="spec"?x.specReviewRound??0:x.reviewRound;return e.jsxs(ee,{to:`/task/${x.id}`,className:"flex items-center gap-3 px-3 py-2 text-sm hover:bg-gray-50",children:[e.jsxs("div",{className:"min-w-0 flex-1 flex items-center gap-2",children:[e.jsx("span",{className:"font-mono text-xs text-blue-700 shrink-0",children:x.id}),e.jsx("span",{className:"truncate font-medium text-gray-900",children:x.title})]}),e.jsxs("div",{className:"flex items-center gap-2 shrink-0",children:[e.jsx("span",{className:"text-xs px-2 py-0.5 rounded bg-gray-100 text-gray-700",children:x.status}),e.jsxs("span",{"aria-label":`Round ${d}`,className:"text-xs font-semibold px-2 py-0.5 rounded bg-blue-100 text-blue-700",children:["Round ",d]})]})]},x.id)})}):e.jsx("div",{className:"mb-2 rounded border border-dashed bg-white px-3 py-2 text-sm text-gray-400","aria-label":`${h} no active task`,children:"暂无任务"}),e.jsx("div",{className:`grid grid-cols-1 ${f} gap-4`,children:s.map(x=>{const d=n.get(x.id),j=d??{id:x.id,projectId:t,runtimeStatus:"unknown",tmuxSessionStatus:"unknown",stale:!0};return e.jsx(Ct,{agent:j,projectId:t,role:x.role,pendingRestart:o&&!d,terminalLoading:!o&&!d&&!r,onDeleted:c,showTaskBinding:!1,terminalMode:m},x.id)})})]})}function It(s,t,n){return!(!t||!Tt.has(s.status)||!(s.agentId===t||s.preferredAgentId===t)||n&&s.qaAgentId&&s.qaAgentId!==n)}const Pt={sm:"max-w-md",md:"max-w-lg",lg:"max-w-2xl"},Pe='input:not([disabled]), select:not([disabled]), textarea:not([disabled]), button:not([disabled]), [href], [tabindex]:not([tabindex="-1"])';function fe({open:s,onClose:t,title:n,children:o,size:r="md"}){const i=a.useRef(null),c=a.useRef(null),m=a.useRef(t);return a.useEffect(()=>{m.current=t},[t]),a.useEffect(()=>{if(!s)return;c.current=document.activeElement;const p=h=>{if(h.key==="Escape"){m.current();return}if(h.key!=="Tab")return;const f=i.current;if(!f)return;const x=Array.from(f.querySelectorAll(Pe)).filter(T=>T.offsetParent!==null||T===document.activeElement);if(x.length===0){h.preventDefault();return}const d=x[0],j=x[x.length-1],l=document.activeElement;h.shiftKey&&(l===d||!f.contains(l))?(h.preventDefault(),j.focus()):!h.shiftKey&&(l===j||!f.contains(l))&&(h.preventDefault(),d.focus())};document.addEventListener("keydown",p);const b=document.body.style.overflow;document.body.style.overflow="hidden";const u=i.current;if(u){const h=u.querySelector(Pe);h==null||h.focus()}return()=>{var h,f;document.removeEventListener("keydown",p),document.body.style.overflow=b,(f=(h=c.current)==null?void 0:h.focus)==null||f.call(h)}},[s]),s?e.jsx("div",{className:"fixed inset-0 z-50 flex items-center justify-center bg-black/40 px-3 sm:px-4",onClick:()=>m.current(),role:"presentation",children:e.jsxs("div",{ref:i,className:`bg-white rounded-lg shadow-xl w-full ${Pt[r]} max-h-[90vh] overflow-auto`,onClick:p=>p.stopPropagation(),role:"dialog","aria-modal":"true","aria-label":n,children:[e.jsxs("div",{className:"flex items-center justify-between px-6 py-4 border-b",children:[e.jsx("h2",{className:"text-lg font-semibold",children:n}),e.jsx("button",{type:"button",onClick:()=>m.current(),className:"text-gray-400 hover:text-gray-600","aria-label":"Close",children:"✕"})]}),e.jsx("div",{className:"px-6 py-4",children:o})]})}):null}const $t=/^[a-z][a-z0-9-]{1,31}$/,Dt=/^[A-Za-z0-9_-][A-Za-z0-9._-]*\/[A-Za-z0-9_-][A-Za-z0-9._-]*$/;function Ot({open:s,onClose:t,onCreated:n}){const[o,r]=a.useState(""),[i,c]=a.useState(""),[m,p]=a.useState(null),[b,u]=a.useState(!1),[h,f]=a.useState(null),[x,d]=a.useState({}),[j,l]=a.useState(new Set),T=a.useRef(0),{show:$}=le(),{flagDirty:S}=xe();a.useEffect(()=>{if(!s)return;T.current+=1;const k=T.current;r(""),c(""),p(null),f(null),d({}),l(new Set),O.config.get().then(P=>{k===T.current&&l(new Set(P.project.map(N=>N.id)))}).catch(()=>{})},[s]);const A=()=>{b||t()},g=()=>{const k={};return o?$t.test(o)?j.has(o)&&(k.id="该 id 已被占用"):k.id="小写字母开头,只含 a-z 0-9 -,长度 2-32":k.id="必填",i?Dt.test(i)||(k.repo="需为 owner/repo 形式"):k.repo="必填",d(k),Object.keys(k).length===0},R=async k=>{if(k.preventDefault(),!!g()){u(!0),f(null);try{const P=await O.projects.create({id:o,repo:i,merge:m});P.restartRequired&&S(),$({kind:"success",title:`项目 ${P.project.id} 已创建`}),n(P.project.id)}catch(P){f(P instanceof Error?P.message:String(P))}finally{u(!1)}}};return e.jsx(fe,{open:s,onClose:A,title:"新建项目",size:"md",children:e.jsxs("form",{onSubmit:R,className:"space-y-4",children:[h&&e.jsx("div",{className:"bg-red-50 border border-red-200 text-red-800 px-3 py-2 rounded text-sm",children:h}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-sm font-medium mb-1",htmlFor:"proj-id",children:"项目 ID"}),e.jsx("input",{id:"proj-id",type:"text",value:o,onChange:k=>r(k.target.value),className:"w-full border rounded px-3 py-2",placeholder:"kongkong",disabled:b}),x.id&&e.jsx("div",{className:"text-xs text-red-600 mt-1",children:x.id})]}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-sm font-medium mb-1",htmlFor:"proj-repo",children:"GitHub 仓库"}),e.jsx("input",{id:"proj-repo",type:"text",value:i,onChange:k=>c(k.target.value),className:"w-full border rounded px-3 py-2",placeholder:"rockdai/baxian",disabled:b}),x.repo&&e.jsx("div",{className:"text-xs text-red-600 mt-1",children:x.repo})]}),e.jsxs("div",{children:[e.jsx("span",{className:"block text-sm font-medium mb-1",children:"合并策略"}),e.jsxs("label",{className:"flex items-center gap-2 mb-1",children:[e.jsx("input",{type:"radio",name:"merge",checked:m===null,onChange:()=>p(null),disabled:b}),e.jsx("span",{className:"text-sm",children:"人类合并(默认)"})]}),e.jsxs("label",{className:"flex items-center gap-2",children:[e.jsx("input",{type:"radio",name:"merge",checked:m==="auto",onChange:()=>p("auto"),disabled:b}),e.jsx("span",{className:"text-sm",children:"QA Approve 后自动合并"})]})]}),e.jsxs("div",{className:"flex justify-end gap-2 pt-4 border-t",children:[e.jsx("button",{type:"button",onClick:A,disabled:b,className:"px-4 py-2 border rounded text-sm hover:bg-gray-50 disabled:opacity-50",children:"取消"}),e.jsx("button",{type:"submit",disabled:b,className:"px-4 py-2 bg-blue-600 text-white rounded text-sm hover:bg-blue-700 disabled:opacity-50",children:b?"创建中…":"创建"})]})]})})}const $e=/^[a-z][a-z0-9-]{1,31}$/,_t=500,De={id:"",role:"dev",pairWith:"",mode:"local",hostname:"",user:"",runtime:"",workdir:"",yolo:!0,model:"",addDirs:""};function Qe({open:s,onClose:t,projectId:n,onCreated:o}){var G;const[r,i]=a.useState(De),[c,m]=a.useState(null),[p,b]=a.useState(new Set),[u,h]=a.useState(null),[f,x]=a.useState(!1),[d,j]=a.useState(!1),[l,T]=a.useState(null),$=a.useRef(null),S=a.useRef(null),A=a.useRef(0),{show:g}=le(),{flagDirty:R}=xe();a.useEffect(()=>{if(!s)return;A.current+=1;const E=A.current;i(De),m(null),b(new Set),h(null),x(!1),T(null),O.config.get().then(z=>{if(E!==A.current)return;const y=z.project.find(C=>C.id===n)??null;m(y);const _=new Set;z.project.forEach(C=>C.agent.forEach(w=>w.forEach(v=>_.add(v.id)))),b(_)}).catch(()=>{})},[s,n]);const k=()=>{d||t()},P=a.useCallback(()=>{$.current&&$.current.abort();const E=new AbortController;$.current=E,x(!0),T(null);const z=r.mode==="remote"?{hostname:r.hostname,user:r.user||void 0}:void 0;O.agents.probe(r.mode,z,{signal:E.signal}).then(y=>{E.signal.aborted||(h(y),T(null))}).catch(y=>{E.signal.aborted||(h(null),T(y instanceof Error?y.message:String(y)))}).finally(()=>{$.current===E&&x(!1)})},[r.mode,r.hostname,r.user]);a.useEffect(()=>{if(s&&(h(null),$.current&&$.current.abort(),!(r.mode==="remote"&&!r.hostname)))return S.current&&clearTimeout(S.current),S.current=setTimeout(P,_t),()=>{S.current&&clearTimeout(S.current)}},[s,r.mode,r.hostname,r.user,P]),a.useEffect(()=>{s||$.current&&$.current.abort()},[s]),a.useEffect(()=>()=>{$.current&&$.current.abort(),S.current&&clearTimeout(S.current)},[]);const N=(c==null?void 0:c.agent.filter(E=>E.length===1&&E[0].role==="dev").map(E=>E[0]))??[],D=N.length>0,F=$e.test(r.id)&&!p.has(r.id),I=r.mode==="local"||r.mode==="remote"&&r.hostname.length>0,M=r.runtime!==""&&(r.runtime==="claude-code"?!!(u!=null&&u.runtimes["claude-code"].ok):!!(u!=null&&u.runtimes.codex.ok)),Q=!!(u!=null&&u.tmux.ok),U=r.mode==="local"||!!((G=u==null?void 0:u.ssh)!=null&&G.ok),J=r.role==="dev"||r.role==="qa"&&r.pairWith!=="",Y=!d&&F&&I&&J&&M&&Q&&U,H=async E=>{if(E.preventDefault(),!!Y){j(!0),T(null);try{const z=r.addDirs.split(`
2
+ `).map(C=>C.trim()).filter(C=>C.length>0),y={id:r.id,role:r.role,runtime:r.runtime,mode:r.mode,...r.mode==="remote"?{host:{hostname:r.hostname,...r.user?{user:r.user}:{}}}:{},...r.workdir?{workdir:r.workdir}:{},yolo:r.yolo,...r.model.trim()?{model:r.model.trim()}:{},...z.length>0?{addDirs:z}:{},...r.role==="qa"?{pairWith:r.pairWith}:{}},_=await O.projects.addAgent(n,y);_.restartRequired&&R(),g({kind:"success",title:`Agent ${_.agent.id} 已添加到 ${n}`}),o(),t()}catch(z){T(z instanceof Error?z.message:String(z))}finally{j(!1)}}},V=({rt:E})=>{if(r.mode==="remote"&&!r.hostname)return e.jsx("span",{className:"text-xs text-gray-400 ml-2",children:"(请先填写 hostname)"});if(f)return e.jsx("span",{className:"text-xs text-gray-400 ml-2",children:"…探测中"});if(!u)return e.jsx("span",{className:"text-xs text-gray-400 ml-2",children:"?"});const y=u.runtimes[E];return y.ok?e.jsxs("span",{className:"text-xs text-green-600 ml-2",children:["✓ ",y.path??""]}):e.jsxs("span",{className:"text-xs text-red-500 ml-2",title:y.message,children:["⨯ ",y.message]})},K=()=>r.mode==="remote"&&!r.hostname?null:f?e.jsx("div",{className:"text-xs text-gray-400",children:"tmux: …探测中"}):u?u.tmux.ok?e.jsxs("div",{className:"text-xs text-green-600",children:["tmux: ✓ ",u.tmux.path??""]}):e.jsxs("div",{className:"text-xs text-red-500",children:["tmux: ⨯ ",u.tmux.message]}):null,te=()=>r.mode!=="remote"||!r.hostname||!(u!=null&&u.ssh)?null:u.ssh.ok?e.jsxs("div",{className:"text-xs text-green-600",children:["SSH: ✓ ",u.ssh.message]}):e.jsxs("div",{className:"text-xs text-red-500",children:["SSH: ⨯ ",u.ssh.message]});return e.jsx(fe,{open:s,onClose:k,title:`添加 Agent 到 ${n}`,size:"lg",children:e.jsxs("form",{onSubmit:H,className:"space-y-4",children:[l&&e.jsx("div",{className:"bg-red-50 border border-red-200 text-red-800 px-3 py-2 rounded text-sm",children:l}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-sm font-medium mb-1",htmlFor:"agent-id",children:"Agent ID"}),e.jsx("input",{id:"agent-id",type:"text",value:r.id,onChange:E=>i({...r,id:E.target.value}),className:"w-full border rounded px-3 py-2",placeholder:"kk-cc",disabled:d}),r.id&&!$e.test(r.id)&&e.jsx("div",{className:"text-xs text-red-600 mt-1",children:"小写字母开头,只含 a-z 0-9 -,长度 2-32"}),r.id&&p.has(r.id)&&e.jsx("div",{className:"text-xs text-red-600 mt-1",children:"该 id 已被占用(全局唯一)"})]}),e.jsxs("div",{children:[e.jsx("span",{className:"block text-sm font-medium mb-1",children:"角色"}),e.jsxs("label",{className:"inline-flex items-center gap-2 mr-4",children:[e.jsx("input",{type:"radio",name:"role",checked:r.role==="dev",onChange:()=>i({...r,role:"dev",pairWith:""}),disabled:d}),e.jsx("span",{className:"text-sm",children:"Dev"})]}),e.jsxs("label",{className:"inline-flex items-center gap-2",title:D?"":"请先创建一个 Dev Agent",children:[e.jsx("input",{type:"radio",name:"role",checked:r.role==="qa",onChange:()=>i({...r,role:"qa"}),disabled:d||!D}),e.jsx("span",{className:`text-sm ${D?"":"text-gray-400"}`,children:"QA"})]})]}),r.role==="qa"&&e.jsxs("div",{children:[e.jsx("label",{className:"block text-sm font-medium mb-1",htmlFor:"pair-with",children:"配对 Dev Agent"}),e.jsxs("select",{id:"pair-with",value:r.pairWith,onChange:E=>i({...r,pairWith:E.target.value}),className:"w-full border rounded px-3 py-2",disabled:d,children:[e.jsx("option",{value:"",children:"请选择"}),N.map(E=>e.jsxs("option",{value:E.id,children:[E.id," (dev, ",E.mode,")"]},E.id))]})]}),e.jsxs("div",{children:[e.jsx("span",{className:"block text-sm font-medium mb-1",children:"运行模式"}),e.jsxs("label",{className:"inline-flex items-center gap-2 mr-4",children:[e.jsx("input",{type:"radio",name:"mode",checked:r.mode==="local",onChange:()=>i({...r,mode:"local",hostname:"",user:""}),disabled:d}),e.jsx("span",{className:"text-sm",children:"本机"})]}),e.jsxs("label",{className:"inline-flex items-center gap-2",children:[e.jsx("input",{type:"radio",name:"mode",checked:r.mode==="remote",onChange:()=>i({...r,mode:"remote"}),disabled:d}),e.jsx("span",{className:"text-sm",children:"远程 (SSH)"})]})]}),r.mode==="remote"&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{children:[e.jsx("label",{className:"block text-sm font-medium mb-1",htmlFor:"hostname",children:"Hostname"}),e.jsx("input",{id:"hostname",type:"text",value:r.hostname,onChange:E=>i({...r,hostname:E.target.value}),className:"w-full border rounded px-3 py-2",placeholder:"macmini-2026",disabled:d}),e.jsx("div",{className:"text-xs text-gray-500 mt-1",children:"端口/私钥/跳板机请配 ~/.ssh/config"})]}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-sm font-medium mb-1",htmlFor:"user",children:"User(可选)"}),e.jsx("input",{id:"user",type:"text",value:r.user,onChange:E=>i({...r,user:E.target.value}),className:"w-full border rounded px-3 py-2",placeholder:"留空则读 ~/.ssh/config 的 User",disabled:d})]})]}),e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center justify-between mb-1",children:[e.jsx("span",{className:"block text-sm font-medium",children:"运行时"}),e.jsx("button",{type:"button",onClick:P,className:"text-xs text-blue-600 hover:underline disabled:opacity-50 disabled:no-underline disabled:cursor-not-allowed",disabled:d||f||r.mode==="remote"&&!r.hostname,children:"↻ 重新探测"})]}),e.jsxs("label",{className:"flex items-center gap-2",children:[e.jsx("input",{type:"radio",name:"runtime",checked:r.runtime==="claude-code",onChange:()=>i({...r,runtime:"claude-code"}),disabled:d||(u?!u.runtimes["claude-code"].ok:!1)}),e.jsx("span",{className:"text-sm",children:"Claude Code"}),e.jsx(V,{rt:"claude-code"})]}),e.jsxs("label",{className:"flex items-center gap-2 mt-1",children:[e.jsx("input",{type:"radio",name:"runtime",checked:r.runtime==="codex",onChange:()=>i({...r,runtime:"codex"}),disabled:d||(u?!u.runtimes.codex.ok:!1)}),e.jsx("span",{className:"text-sm",children:"Codex"}),e.jsx(V,{rt:"codex"})]}),e.jsx("div",{className:"mt-2",children:e.jsx(K,{})}),e.jsx("div",{children:e.jsx(te,{})})]}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-sm font-medium mb-1",htmlFor:"workdir",children:"Workdir(可选)"}),e.jsx("input",{id:"workdir",type:"text",value:r.workdir,onChange:E=>i({...r,workdir:E.target.value}),className:"w-full border rounded px-3 py-2",placeholder:"留空时自动 clone 到 ~/.baxian/repos/<owner>/<repo>",disabled:d})]}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-sm font-medium mb-1",htmlFor:"model",children:"Model(可选)"}),e.jsx("input",{id:"model",type:"text",value:r.model,onChange:E=>i({...r,model:E.target.value}),className:"w-full border rounded px-3 py-2",placeholder:r.runtime==="codex"?"例: o3 / gpt-4o(留空走 default)":"例: sonnet / opus / claude-sonnet-4-6(留空走 default)",disabled:d}),e.jsx("div",{className:"text-xs text-gray-500 mt-1",children:"透传到 launch 命令的 --model 参数;留空跟随 CLI 默认。"})]}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-sm font-medium mb-1",htmlFor:"addDirs",children:"Additional Dirs(可选)"}),e.jsx("textarea",{id:"addDirs",value:r.addDirs,onChange:E=>i({...r,addDirs:E.target.value}),className:"w-full border rounded px-3 py-2 font-mono text-xs",rows:3,placeholder:`每行一个绝对路径,例:
3
+ /Users/me/shared-libs
4
+ /Users/me/extra-repo`,disabled:d}),e.jsx("div",{className:"text-xs text-gray-500 mt-1",children:"透传到 --add-dir。当前 YOLO 模式下不影响权限拦截,主要用于让 CLI 把额外目录纳入工作根。"})]}),e.jsx("div",{className:"bg-amber-50 border border-amber-200 px-3 py-2 rounded",children:e.jsxs("label",{className:"flex items-start gap-2 cursor-pointer",children:[e.jsx("input",{type:"checkbox",className:"mt-1",checked:r.yolo,onChange:E=>i({...r,yolo:E.target.checked}),disabled:d}),e.jsxs("div",{className:"text-sm",children:[e.jsx("div",{className:"font-medium",children:"YOLO 模式(推荐开启)"}),e.jsxs("div",{className:"text-xs text-amber-900 mt-1",children:["Agent 自主执行所有命令、文件改动,无需逐条确认。开启后体验更顺滑, 但",e.jsx("strong",{children:"请确认在受控环境(容器、隔离 worktree)中运行"}),"。"]})]})]})}),e.jsxs("div",{className:"flex justify-end gap-2 pt-4 border-t",children:[e.jsx("button",{type:"button",onClick:k,disabled:d,className:"px-4 py-2 border rounded text-sm hover:bg-gray-50 disabled:opacity-50",children:"取消"}),e.jsx("button",{type:"submit",disabled:!Y,className:"px-4 py-2 bg-blue-600 text-white rounded text-sm hover:bg-blue-700 disabled:opacity-50",children:d?"添加中…":"添加 Agent"})]})]})})}const Oe=200,_e=16e3;function Ee(s){const t=s.mode==="edit",n=ve(),{show:o}=le(),r=t?s.task.projectId:s.projectId,i=t?s.task.title:"",c=t?s.task.description:"",m=t?s.task.preferredAgentId:"",[p,b]=a.useState([]),[u,h]=a.useState([]),[f,x]=a.useState(r??""),[d,j]=a.useState(m),[l,T]=a.useState(i),[$,S]=a.useState(c),[A,g]=a.useState(!1),[R,k]=a.useState(null),P=a.useRef(0);a.useEffect(()=>{if(!s.open)return;P.current+=1;const w=P.current;b([]),h([]),x(r??""),j(m),T(i),S(c),k(null),g(!1),Promise.all([O.projects.list(),O.agents.list()]).then(([v,q])=>{w===P.current&&(b(v),h(q))}).catch(v=>{w===P.current&&k(v instanceof Error?v.message:String(v))})},[s.open,r,i,c,m]);const N=a.useMemo(()=>p.find(w=>w.id===f)??null,[p,f]),D=a.useMemo(()=>N?N.agent.flat().filter(w=>w.role==="dev"):[],[N]),F=a.useMemo(()=>new Set(u.map(w=>w.id)),[u]),I=a.useMemo(()=>D.filter(w=>F.has(w.id)),[D,F]),M=a.useMemo(()=>D.filter(w=>!F.has(w.id)),[D,F]);a.useEffect(()=>{if(!t){if(I.length===0){d!==""&&j("");return}I.find(w=>w.id===d)||j(I[0].id)}},[I,d,t]);const Q=!t||I.find(w=>w.id===d),U=t&&!Q&&!!d,J=U&&M.some(w=>w.id===d),Y=J?`当前 dev "${d}" 在 baxian.json 中存在但 runtime 未加载,可能是手动编辑过配置文件;重启 server 可拉起`:U?`当前 dev "${d}" 不在 runtime(可能已从 project 配置移除);保存可能失败,请确认或选择新 dev`:!f||I.length>0?null:M.length>0?"baxian.json 里有 dev agent 但 runtime 未加载(可能是手动编辑过配置);重启 server 后生效":"请先为项目添加 dev agent",H=l.trim(),V=$.trim(),K=I.length>0||U,G=!!f&&K&&!!d&&H.length>0&&V.length>0&&!A,E=()=>{A||s.onClose()},z=async w=>{var v,q;if(w.preventDefault(),!!G){g(!0),k(null);try{if(s.mode==="edit"){const B=await O.tasks.update(s.task.id,{title:H,description:V,preferredAgentId:d});o({kind:"success",title:"任务已更新"}),(v=s.onUpdated)==null||v.call(s,B),s.onClose()}else{const B=await O.tasks.create({projectId:f,title:H,description:V,preferredAgentId:d});o({kind:"success",title:"任务已创建"}),(q=s.onCreated)==null||q.call(s,B),s.onClose(),n(`/task/${B.id}`)}}catch(B){k(B instanceof Error?B.message:String(B))}finally{g(!1)}}},y=t?"编辑 Task":"新建 Task",_=t?A?"保存中…":"保存":A?"创建中…":"创建",C=!t&&!r;return e.jsx(fe,{open:s.open,onClose:E,title:y,size:"md",children:e.jsxs("form",{onSubmit:z,className:"space-y-4",children:[R&&e.jsx("div",{className:"bg-red-50 border border-red-200 text-red-800 px-3 py-2 rounded text-sm",children:R}),C&&e.jsxs("div",{children:[e.jsx("label",{className:"block text-sm font-medium mb-1",htmlFor:"task-project",children:"Project"}),e.jsxs("select",{id:"task-project",value:f,onChange:w=>x(w.target.value),className:"w-full border rounded px-3 py-2 disabled:bg-gray-50",disabled:A,required:!0,children:[e.jsx("option",{value:"",disabled:!0,children:"选择项目"}),p.map(w=>e.jsx("option",{value:w.id,children:w.id},w.id))]})]}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-sm font-medium mb-1",htmlFor:"task-dev",children:"Dev Agent"}),e.jsxs("select",{id:"task-dev",value:d,onChange:w=>j(w.target.value),className:"w-full border rounded px-3 py-2 disabled:bg-gray-50",disabled:A||I.length===0&&!U||I.length===1&&I[0].id===d&&!U,required:!0,children:[I.length===0&&!U&&e.jsx("option",{value:"",disabled:!0,children:"无可用 dev"}),U&&e.jsxs("option",{value:d,children:[d," ",J?"(待重启)":"(不在 runtime)"]}),I.map(w=>e.jsx("option",{value:w.id,children:w.id},w.id))]}),Y&&e.jsx("div",{className:"text-xs text-amber-700 mt-1",children:Y})]}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-sm font-medium mb-1",htmlFor:"task-title",children:"Title"}),e.jsx("input",{id:"task-title",type:"text",value:l,onChange:w=>T(w.target.value),maxLength:Oe,className:"w-full border rounded px-3 py-2",placeholder:"一句话描述要做什么",disabled:A,required:!0}),e.jsxs("div",{className:"text-xs text-gray-500 mt-1 text-right",children:[l.length," / ",Oe]})]}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-sm font-medium mb-1",htmlFor:"task-description",children:"Description"}),e.jsx("textarea",{id:"task-description",value:$,onChange:w=>S(w.target.value),maxLength:_e,rows:8,className:"w-full border rounded px-3 py-2 font-mono text-sm",placeholder:"详细描述任务,支持 markdown",disabled:A,required:!0}),e.jsxs("div",{className:"text-xs text-gray-500 mt-1 text-right",children:[$.length," / ",_e]})]}),e.jsxs("div",{className:"flex justify-end gap-2 pt-4 border-t",children:[e.jsx("button",{type:"button",onClick:E,disabled:A,className:"px-4 py-2 border rounded text-sm hover:bg-gray-50 disabled:opacity-50",children:"取消"}),e.jsx("button",{type:"submit",disabled:!G,className:"px-4 py-2 bg-blue-600 text-white rounded text-sm hover:bg-blue-700 disabled:opacity-50",children:_})]})]})})}function Lt(s){return Array.from(new TextEncoder().encode(s)).map(t=>t.toString(16).padStart(2,"0")).join("")}function Ft(){return`${location.protocol==="https:"?"wss":"ws"}://${location.host}/api/realtime`}const zt=(s,t)=>t&&t.length>0?new WebSocket(s,t):new WebSocket(s);class Mt{constructor(t={}){L(this,"wsUrl");L(this,"wsFactory");L(this,"tokenProvider");L(this,"ws",null);L(this,"topics",new Map);L(this,"cache",new Map);L(this,"outbox",[]);L(this,"reconnectScheduler");L(this,"explicitlyClosed",!1);this.wsUrl=t.wsUrl??Ft(),this.wsFactory=t.wsFactory??zt,this.tokenProvider=t.tokenProvider??Ne,this.reconnectScheduler=new Me({reconnect:()=>this.openSocket(),shouldReconnect:()=>!this.explicitlyClosed&&this.topics.size>0})}subscribe(t,n,o){let r=this.topics.get(t);const i=!r;return r||(r={data:new Set,error:new Set},this.topics.set(t,r)),r.data.add(n),o&&r.error.add(o),i?(this.ensureSocket(),this.wsSendOrQueue({op:"subscribe",topic:t})):this.cache.has(t)&&queueMicrotask(()=>{var c;(c=this.topics.get(t))!=null&&c.data.has(n)&&this.cache.has(t)&&n(this.cache.get(t))}),()=>this.unsubscribe(t,n,o)}close(){if(this.explicitlyClosed=!0,this.reconnectScheduler.cancel(),this.reconnectScheduler.reset(),this.ws){try{this.ws.close()}catch{}this.ws=null}this.topics.clear(),this.cache.clear(),this.outbox=[]}unsubscribe(t,n,o){const r=this.topics.get(t);r&&(r.data.delete(n),o&&r.error.delete(o),r.data.size===0&&r.error.size===0&&(this.topics.delete(t),this.cache.delete(t),this.wsSendOrQueue({op:"unsubscribe",topic:t}),this.topics.size===0&&this.teardownSocket()))}teardownSocket(){if(this.reconnectScheduler.cancel(),this.reconnectScheduler.reset(),this.outbox=[],this.ws){try{this.ws.close()}catch{}this.ws=null}}ensureSocket(){this.explicitlyClosed||this.ws&&(this.ws.readyState===WebSocket.OPEN||this.ws.readyState===WebSocket.CONNECTING)||this.openSocket()}openSocket(){if(this.explicitlyClosed)return;this.reconnectScheduler.cancel();const t=this.tokenProvider(),n=t?[`baxian.token.${Lt(t)}`]:void 0;let o;try{o=this.wsFactory(this.wsUrl,n)}catch(i){console.warn("[events-client] WebSocket constructor threw:",i),this.broadcastConnectionError({code:"connection_failed",message:i instanceof Error?i.message:"WebSocket constructor threw"}),this.scheduleReconnect();return}this.ws=o;let r=!1;o.onopen=()=>{if(o!==this.ws)return;r=!0,this.reconnectScheduler.reset();for(const c of this.topics.keys())try{o.send(JSON.stringify({op:"subscribe",topic:c}))}catch(m){console.warn("[events-client] resubscribe send failed:",m)}const i=this.outbox;this.outbox=[];for(const c of i)if(!(c.op==="subscribe"||c.op==="unsubscribe"))try{o.send(JSON.stringify(c))}catch(m){console.warn("[events-client] outbox flush failed:",m)}},o.onmessage=i=>{if(o!==this.ws)return;let c;try{const m=typeof i.data=="string"?i.data:String(i.data);c=JSON.parse(m)}catch{return}this.handleMessage(c)},o.onclose=()=>{o===this.ws&&(this.ws=null,!this.explicitlyClosed&&(r||this.broadcastConnectionError({code:"connection_failed",message:"WebSocket failed to connect (auth, network, or proxy issue)"}),this.topics.size!==0&&this.scheduleReconnect()))},o.onerror=()=>{}}scheduleReconnect(){this.reconnectScheduler.schedule()}broadcastConnectionError(t){for(const n of this.topics.values())for(const o of[...n.error])try{o(t)}catch(r){console.error("[events-client] error handler threw on connection error:",r)}}wsSendOrQueue(t){if(this.ws&&this.ws.readyState===WebSocket.OPEN)try{this.ws.send(JSON.stringify(t));return}catch(n){console.warn("[events-client] send failed, will queue:",n)}this.outbox.push(t)}handleMessage(t){switch(t.type){case"data":{const n=this.topics.get(t.topic);if(this.cache.set(t.topic,t.data),!n)return;for(const o of[...n.data])try{o(t.data)}catch(r){console.error(`[events-client] handler threw on ${t.topic}:`,r)}break}case"error":{const n={code:t.code,message:t.message};if(t.topic){const o=this.topics.get(t.topic);if(o)for(const r of[...o.error])try{r(n)}catch(i){console.error(`[events-client] error handler threw on ${t.topic}:`,i)}}else console.warn("[events-client] connection-level error:",t.code,t.message);break}}}}let ge=null;function Re(){return ge||(ge=new Mt),ge}function Ue(){const[s,t]=a.useState(null),[n,o]=a.useState(!1),[r,i]=a.useState(null);return a.useEffect(()=>Re().subscribe("agents",m=>{i(null),t(m),o(!0)},m=>i(m)),[]),{data:s,loaded:n,error:r}}function Bt(s){const[t,n]=a.useState(null),[o,r]=a.useState(!1),[i,c]=a.useState(null);return a.useEffect(()=>(n(null),r(!1),c(null),Re().subscribe(`task:${s}`,p=>{c(null),n(p),r(!0)},p=>c(p))),[s]),{data:t,loaded:o,error:i}}function Qt(s){const[t,n]=a.useState(null),[o,r]=a.useState(!1),[i,c]=a.useState(null);return a.useEffect(()=>{if(!s){n(null),r(!1),c(null);return}n(null),r(!1),c(null);let m=!1,p=!1,b=!1;const u=Re().subscribe(`project-tasks:${s}`,h=>{m||(p=!0,c(null),n(h),r(!0))},h=>{m||(c(h),!(p||b)&&(b=!0,O.tasks.list(s).then(f=>{m||p||(n(f),r(!0))},f=>{console.warn(`[useProjectTasks] REST fallback failed for ${s}:`,f)})))});return()=>{m=!0,u()}},[s]),{data:t,loaded:o,error:i}}function Ut(){const[s,t]=a.useState([]),[n,o]=a.useState([]),[r,i]=a.useState(!1),[c,m]=a.useState(null),[p,b]=a.useState(null),[u,h]=a.useState(!1),[f,x]=a.useState(!1),[d,j]=a.useState({kind:"closed"}),l=a.useRef(0),{data:T,loaded:$,error:S}=Ue(),A=(S==null?void 0:S.message)??null,g=new Map((T??[]).map(N=>[N.id,N])),R=c??A??p,k=async()=>{const N=++l.current;try{const D=await O.projects.list();if(N!==l.current)return;t(D),m(null)}catch(D){if(N!==l.current)return;m(D instanceof Error?D.message:String(D))}finally{N===l.current&&i(!0)}},P=async()=>{try{const N=await O.tasks.list();o(N),b(null)}catch(N){b(N instanceof Error?N.message:String(N))}};return a.useEffect(()=>{k(),P()},[]),e.jsxs("div",{children:[e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-3 mb-6",children:[e.jsx("h1",{className:"text-xl sm:text-2xl font-bold",children:"Dashboard"}),e.jsxs("div",{className:"flex flex-wrap gap-2",children:[e.jsx("button",{onClick:()=>h(!0),className:"px-4 py-2 bg-blue-600 text-white rounded text-sm hover:bg-blue-700",children:"+ 新建项目"}),e.jsx("button",{onClick:()=>x(!0),disabled:s.length===0,"aria-describedby":s.length===0?"create-task-hint":void 0,className:"px-4 py-2 bg-blue-600 text-white rounded text-sm hover:bg-blue-700 disabled:bg-gray-300 disabled:cursor-not-allowed",children:"+ 新建 Task"}),s.length===0&&e.jsx("span",{id:"create-task-hint",className:"text-xs text-gray-500 self-center",children:"请先创建项目"})]})]}),R&&e.jsxs("div",{className:"mb-4 text-sm text-red-600",children:["Error: ",R]}),r&&s.length===0&&!c&&e.jsx("div",{className:"text-gray-500 text-sm py-12 text-center border-2 border-dashed rounded",children:'还没有项目。点击右上角"+ 新建项目"开始。'}),s.map(N=>e.jsxs("div",{className:"mb-8",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-x-3 gap-y-1 mb-4",children:[e.jsx("h2",{className:"text-lg font-semibold",children:N.id}),e.jsx("span",{className:"text-sm text-gray-500 break-words min-w-0",children:N.repo}),e.jsx(ee,{to:`/project/${N.id}`,className:"text-sm text-blue-600 hover:underline ml-auto",children:"Details"})]}),N.agent.flat().length===0?e.jsx("div",{className:"text-gray-400 text-sm py-6 text-center border border-dashed rounded",children:"还没有 Agent。进入 Details 添加。"}):e.jsx("div",{className:"grid grid-cols-1 xl:grid-cols-2 gap-4",children:N.agent.map((D,F)=>e.jsx(Be,{group:D,projectId:N.id,agentsById:g,agentsLoaded:$,agentsError:!!S,tasks:n.filter(I=>I.projectId===N.id),onDeleted:()=>{k(),P()}},D.map(I=>I.id).join(":")||F))})]},N.id)),e.jsx(Ot,{open:u,onClose:()=>h(!1),onCreated:N=>{h(!1),k(),j({kind:"asking",projectId:N})}}),e.jsx(fe,{open:d.kind==="asking",onClose:()=>j({kind:"closed"}),title:"项目已创建",size:"sm",children:e.jsxs("div",{className:"space-y-4",children:[e.jsx("p",{className:"text-sm",children:"现在添加第一个 Agent,还是稍后再加?"}),e.jsxs("div",{className:"flex justify-end gap-2",children:[e.jsx("button",{type:"button",onClick:()=>j({kind:"closed"}),className:"px-4 py-2 border rounded text-sm hover:bg-gray-50",children:"稍后再加"}),e.jsx("button",{type:"button",onClick:()=>{d.kind==="asking"&&j({kind:"addingAgent",projectId:d.projectId})},className:"px-4 py-2 bg-blue-600 text-white rounded text-sm hover:bg-blue-700",children:"继续添加 Agent"})]})]})}),d.kind==="addingAgent"&&e.jsx(Qe,{open:!0,projectId:d.projectId,onClose:()=>j({kind:"closed"}),onCreated:()=>{k()}}),e.jsx(Ee,{open:f,onClose:()=>x(!1),onCreated:()=>{P()}})]})}function qe({tasks:s}){const t=ve();return s.length===0?e.jsx("div",{className:"text-gray-400 text-sm",children:"No tasks"}):e.jsx("div",{className:"overflow-x-auto",children:e.jsxs("table",{className:"w-full text-sm",children:[e.jsx("thead",{children:e.jsxs("tr",{className:"text-left border-b text-xs text-gray-500",children:[e.jsx("th",{className:"py-2 pr-4 font-medium",children:"ID"}),e.jsx("th",{className:"py-2 pr-4 font-medium",children:"Title"}),e.jsx("th",{className:"py-2 pr-4 font-medium hidden sm:table-cell",children:"Agent"}),e.jsx("th",{className:"py-2 pr-4 font-medium",children:"Status"}),e.jsx("th",{className:"py-2 font-medium hidden sm:table-cell",children:"Round"})]})}),e.jsx("tbody",{children:s.map(n=>e.jsxs("tr",{className:"border-b hover:bg-gray-50 cursor-pointer",onClick:()=>t(`/task/${n.id}`),children:[e.jsx("td",{className:"py-2 pr-4 font-mono whitespace-nowrap",children:e.jsx(ee,{to:`/task/${n.id}`,className:"text-blue-600 hover:underline",onClick:o=>o.stopPropagation(),children:n.id})}),e.jsx("td",{className:"py-2 pr-4 break-words",children:n.title}),e.jsx("td",{className:"py-2 pr-4 font-mono text-xs hidden sm:table-cell",children:n.agentId?n.agentId:n.preferredAgentId?e.jsx("span",{className:"italic text-gray-500",children:n.preferredAgentId}):"-"}),e.jsxs("td",{className:"py-2 pr-4 whitespace-nowrap",children:[e.jsx("span",{className:"text-xs px-2 py-0.5 rounded bg-gray-100",children:n.status}),n.phase==="spec"&&e.jsx("span",{className:"ml-1 text-xs px-2 py-0.5 rounded bg-indigo-100 text-indigo-800",children:"spec"})]}),e.jsx("td",{className:"py-2 text-xs text-gray-500 hidden sm:table-cell",children:n.phase==="spec"?n.specReviewRound??0:n.reviewRound})]},n.id))})]})})}function qt(){const{id:s}=Se(),[t,n]=a.useState(null),[o,r]=a.useState(null),[i,c]=a.useState(!1),[m,p]=a.useState(!1),b=a.useRef(0),{data:u,loaded:h,error:f}=Ue(),{data:x,error:d}=Qt(s),j=(f==null?void 0:f.message)??null,l=(d==null?void 0:d.message)??null,T=x??[],$=new Map((u??[]).map(g=>[g.id,g])),S=o??j??l,A=a.useCallback(async g=>{const R=++b.current;try{const k=await O.projects.get(g);if(R!==b.current)return;n(k),r(null)}catch(k){if(R!==b.current)return;r(k instanceof Error?k.message:String(k))}},[]);return a.useEffect(()=>{s&&(n(null),r(null),A(s))},[s,A]),t?e.jsxs("div",{children:[S&&e.jsxs("div",{className:"mb-4 text-sm text-red-600",children:["Error: ",S]}),e.jsx("h1",{className:"text-xl sm:text-2xl font-bold mb-2 break-words",children:t.id}),e.jsx("p",{className:"text-gray-500 mb-6 break-words",children:t.repo}),e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-2 mb-3",children:[e.jsx("h2",{className:"text-lg font-semibold",children:"Agents"}),e.jsx("button",{onClick:()=>c(!0),className:"px-3 py-1.5 bg-blue-600 text-white rounded text-sm hover:bg-blue-700",children:"+ 添加 Agent"})]}),t.agent.flat().length===0?e.jsx("div",{className:"text-gray-400 text-sm py-6 text-center border border-dashed rounded mb-8",children:"还没有 Agent,点击右上角添加。"}):e.jsx("div",{className:"space-y-5 mb-8",children:t.agent.map((g,R)=>e.jsx(Be,{group:g,projectId:t.id,agentsById:$,agentsLoaded:h,agentsError:!!f,tasks:T,onDeleted:()=>{A(t.id)},terminalMode:"embedded-full"},g.map(k=>k.id).join(":")||R))}),e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-2 mb-3",children:[e.jsx("h2",{className:"text-lg font-semibold",children:"Tasks"}),e.jsx("button",{onClick:()=>p(!0),className:"px-3 py-1.5 bg-blue-600 text-white rounded text-sm hover:bg-blue-700",children:"+ 新建 Task"})]}),e.jsx(qe,{tasks:T}),e.jsx(Qe,{open:i,projectId:t.id,onClose:()=>c(!1),onCreated:()=>{A(t.id)}}),e.jsx(Ee,{open:m,projectId:t.id,onClose:()=>p(!1)})]}):o?e.jsxs("div",{className:"text-red-600",children:["Error: ",o]}):e.jsx("div",{children:"Loading..."})}function Wt(){const{agentId:s}=Se();return s?e.jsxs("div",{className:"flex-1 min-h-0 flex flex-col border border-zinc-800 bg-[#e1e2e7] shadow-sm",children:[e.jsx("div",{className:"flex items-center gap-3 h-8 px-3 bg-zinc-900 border-b border-zinc-800 text-[11px] font-mono select-none",children:e.jsxs("div",{className:"flex items-center gap-1.5",children:[e.jsx("span",{className:"h-2 w-2 rounded-full bg-emerald-500","aria-hidden":!0}),e.jsx("span",{className:"text-zinc-200",children:s})]})}),e.jsx("div",{className:"flex-1 min-h-0",children:e.jsx(je,{agentId:s,mode:"full",interactive:!0})})]}):e.jsx("div",{children:"No agent specified"})}function Gt(){const[s,t]=a.useState([]),[n,o]=a.useState(null);return a.useEffect(()=>{let r=!1;return(async()=>{try{const i=await O.tasks.list();r||t(i)}catch(i){r||o(i instanceof Error?i.message:String(i))}})(),()=>{r=!0}},[]),e.jsxs("div",{children:[e.jsx("h1",{className:"text-xl sm:text-2xl font-bold mb-6",children:"Tasks"}),n&&e.jsxs("div",{className:"mb-4 text-sm text-red-600",children:["Error: ",n]}),e.jsx(qe,{tasks:s})]})}const We=new Set(["merged","failed","max_rounds","cancelled"]),Le=We,Ht={pending:"bg-gray-200 text-gray-800",in_progress:"bg-blue-200 text-blue-800",review:"bg-purple-200 text-purple-800",fixing:"bg-orange-200 text-orange-800",approved:"bg-green-100 text-green-800",merged:"bg-green-300 text-green-900",failed:"bg-red-200 text-red-800",max_rounds:"bg-red-200 text-red-800",cancelled:"bg-gray-400 text-gray-100"};function Jt(){const{id:s}=Se(),t=ve(),{show:n}=le(),[o,r]=a.useState(!1),[i,c]=a.useState(!1),[m,p]=a.useState(!1),[b,u]=a.useState(!1),[h,f]=a.useState(null),{data:x,loaded:d,error:j}=Bt(s??""),l=h??x,T=(j==null?void 0:j.message)??null;a.useEffect(()=>{f(null)},[s]),a.useEffect(()=>{h&&x&&x.updatedAt>=h.updatedAt&&f(null)},[h,x]);const $=I=>{f(I)};if(!s)return e.jsx("div",{className:"text-red-600",children:"Task ID required"});if(T&&!l)return e.jsxs("div",{className:"text-red-600",children:["Error: ",T]});if(d&&!l)return e.jsxs("div",{className:"text-red-600",children:["Task not found: ",s]});if(!l)return e.jsx("div",{children:"Loading..."});const S=l.status==="pending",A=l.status==="pending"||l.status==="in_progress",g=Le.has(l.status)&&!!l.preferredAgentId,R=!!l.prNumber,k=l.preferredAgentId==="",P=l.status==="approved"&&l.prNumber!==void 0,N=async()=>{if(confirm(`确定取消 task ${l.id}?`)){c(!0);try{const I=await O.tasks.update(l.id,{status:"cancelled"});$(I),n({kind:"success",title:"任务已取消"})}catch(I){n({kind:"error",title:"取消失败",body:I instanceof Error?I.message:String(I)})}finally{c(!1)}}},D=async()=>{const M=We.has(l.status)?`task ${l.id} 已是 ${l.status} 状态。手动请 QA 重审会再跑一轮 review,但状态机不会把 QA 结果带回主流程。继续?`:`请 QA 重审 task ${l.id}?这会让 QA agent 立即开始新一轮 review(reviewRound +1)。`;if(confirm(M)){u(!0);try{const Q=await O.tasks.review(l.id);$(Q),n({kind:"success",title:`已派 QA 重审 (round ${Q.reviewRound})`})}catch(Q){n({kind:"error",title:"Review 派发失败",body:Q instanceof Error?Q.message:String(Q)})}finally{u(!1)}}},F=async()=>{const I=l.status==="merged"?`task ${l.id} 已 merged。Retry 会用同样的标题/描述新建一个 task 从头跑,确定继续?`:`Retry task ${l.id}?这会新建一个 task 从头开始,旧 task 保留为历史。`;if(confirm(I)){p(!0);try{const M=await O.tasks.retry(l.id);n({kind:"success",title:`已新建 task ${M.id}`}),t(`/task/${M.id}`)}catch(M){n({kind:"error",title:"Retry 失败",body:M instanceof Error?M.message:String(M)})}finally{p(!1)}}};return e.jsxs("div",{className:"max-w-4xl mx-auto",children:[T&&e.jsxs("div",{className:"mb-4 text-sm text-red-600",children:["Error: ",T]}),k&&e.jsx("div",{className:"mb-4 p-3 bg-amber-100 border-l-4 border-amber-500 text-amber-800 text-sm",children:l.status==="pending"?e.jsxs(e.Fragment,{children:["This task has no preferred dev (legacy). Click ",e.jsx("b",{children:"Edit"})," to assign one."]}):e.jsxs(e.Fragment,{children:["This is a legacy task with no preferred dev (read-only in status ",e.jsx("b",{children:l.status}),")."]})}),e.jsxs("div",{className:"flex flex-wrap items-center gap-3 mb-2",children:[e.jsx("span",{className:"font-mono text-sm font-bold",children:l.id}),e.jsx("span",{className:`px-2 py-1 rounded text-xs font-medium ${Ht[l.status]}`,children:l.status}),l.phase==="spec"&&e.jsx("span",{className:"px-2 py-1 rounded text-xs font-medium bg-indigo-100 text-indigo-800",children:"spec phase"}),e.jsxs("span",{className:"text-xs text-gray-500",children:["created ",l.createdAt]}),e.jsxs("span",{className:"text-xs text-gray-500",children:["updated ",l.updatedAt]})]}),e.jsx("h1",{className:"text-xl sm:text-2xl font-bold mb-4 break-words",children:l.title}),P&&e.jsxs("div",{className:"mb-4 rounded border border-green-200 bg-green-50 p-4 text-sm text-green-900",children:[e.jsx("div",{className:"font-semibold",children:"QA approved · awaiting PR merge"}),e.jsx("div",{className:"mt-1",children:"Dev keeps the task reserved while it checks whether all human or agent feedback has been handled."}),l.prUrl&&e.jsxs("a",{href:l.prUrl,target:"_blank",rel:"noopener noreferrer",className:"mt-3 inline-flex rounded border border-green-300 bg-white px-3 py-1.5 text-sm font-medium text-green-800 hover:bg-green-100",children:["Open PR #",l.prNumber]})]}),e.jsx("pre",{className:"whitespace-pre-wrap font-sans bg-gray-50 border rounded p-4 mb-6 text-sm",children:l.description}),e.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-x-6 gap-y-2 text-sm mb-6",children:[e.jsxs("div",{children:["Project: ",e.jsx("span",{className:"font-mono",children:l.projectId})]}),e.jsxs("div",{children:["Dev: ",e.jsx("span",{className:"font-mono",children:l.agentId||"-"})]}),e.jsxs("div",{children:["Preferred: ",e.jsx("span",{className:"font-mono",children:l.preferredAgentId||"-"})]}),e.jsxs("div",{children:["QA: ",e.jsx("span",{className:"font-mono",children:l.qaAgentId||"-"})]}),e.jsxs("div",{children:["PR:"," ",l.prNumber?l.prUrl?e.jsxs("a",{href:l.prUrl,target:"_blank",rel:"noopener noreferrer",className:"text-blue-600 hover:underline",children:["#",l.prNumber]}):e.jsxs("span",{children:["#",l.prNumber]}):e.jsx("span",{children:"-"})]}),e.jsxs("div",{children:["Branch: ",e.jsx("span",{className:"font-mono",children:l.branch||"-"})]}),e.jsxs("div",{children:["Round: ",l.reviewRound,l.specReviewRound!==void 0&&l.specReviewRound>0&&e.jsxs("span",{className:"ml-2 text-xs text-indigo-700",children:["spec: ",l.specReviewRound]})]})]}),e.jsxs("div",{className:"flex flex-wrap gap-2",children:[e.jsx("button",{type:"button",disabled:!S,onClick:()=>r(!0),className:"px-4 py-2 border rounded text-sm hover:bg-gray-50 disabled:opacity-50 disabled:cursor-not-allowed",children:"Edit"}),e.jsx("button",{type:"button",disabled:!A||i,onClick:N,className:"px-4 py-2 border border-red-300 text-red-700 rounded text-sm hover:bg-red-50 disabled:opacity-50 disabled:cursor-not-allowed",children:i?"Cancelling...":"Cancel"}),e.jsx("button",{type:"button",disabled:!g||m,onClick:F,title:Le.has(l.status)?k?"Legacy task has no preferred dev to retry against":"新建一个 task 从头跑,丢弃当前 worktree/branch":`Cannot retry in status ${l.status}`,className:"px-4 py-2 border border-blue-300 text-blue-700 rounded text-sm hover:bg-blue-50 disabled:opacity-50 disabled:cursor-not-allowed",children:m?"Retrying...":"Retry"}),e.jsx("button",{type:"button",disabled:!R||b,onClick:D,title:l.prNumber?"让 QA agent 立即开始新一轮 review(reviewRound +1)":"该 task 还没有 PR,无法派 review",className:"px-4 py-2 border border-purple-300 text-purple-700 rounded text-sm hover:bg-purple-50 disabled:opacity-50 disabled:cursor-not-allowed",children:b?"Dispatching...":"Request QA review"})]}),e.jsx(Ee,{mode:"edit",open:o,onClose:()=>r(!1),task:l,onUpdated:$})]})}function Vt(){const{phase:s,count:t,error:n,triggerRestart:o}=xe();return s==="idle"?null:s==="failed"?e.jsxs("div",{className:"bg-red-50 border-b border-red-200 px-4 py-2 flex items-center justify-between",children:[e.jsxs("div",{className:"text-sm text-red-800",children:["❌ 重启失败:",n]}),e.jsx("button",{onClick:()=>{o()},className:"text-sm text-red-700 hover:underline font-medium",children:"重试"})]}):s==="restarting"?e.jsx("div",{className:"bg-blue-50 border-b border-blue-200 px-4 py-2 text-sm text-blue-800",children:"🔄 重启中…"}):e.jsxs("div",{className:"bg-amber-50 border-b border-amber-200 px-4 py-2 flex items-center justify-between",children:[e.jsxs("div",{className:"text-sm text-amber-900",children:["⚠️ 有 ",t," 项配置变更待重启 baxian server 才生效"]}),e.jsx("button",{onClick:()=>{o()},className:"px-3 py-1 bg-amber-600 text-white text-sm rounded hover:bg-amber-700",children:"现在重启"})]})}function Kt(){return e.jsx(Xe,{children:e.jsxs("div",{className:"h-screen flex flex-col bg-gray-50",children:[e.jsxs("nav",{className:"bg-white border-b px-4 py-3 sm:px-6 flex flex-wrap items-center gap-x-4 gap-y-2 sm:gap-x-6 flex-none",children:[e.jsx(ee,{to:"/",className:"font-bold text-lg",children:"baxian"}),e.jsx(ee,{to:"/",className:"text-gray-600 hover:text-black",children:"Dashboard"}),e.jsx(ee,{to:"/tasks",className:"text-gray-600 hover:text-black",children:"Tasks"})]}),e.jsx(Vt,{}),e.jsx("main",{className:"flex-1 min-h-0 overflow-y-auto flex flex-col p-3 sm:p-6",children:e.jsxs(et,{children:[e.jsx(ae,{path:"/",element:e.jsx(Ut,{})}),e.jsx(ae,{path:"/project/:id",element:e.jsx(qt,{})}),e.jsx(ae,{path:"/terminal/:agentId",element:e.jsx(Wt,{})}),e.jsx(ae,{path:"/tasks",element:e.jsx(Gt,{})}),e.jsx(ae,{path:"/task/:id",element:e.jsx(Jt,{})})]})})]})})}function Yt({children:s}){const[t,n]=a.useState({kind:"probing"}),o=a.useRef(t);a.useEffect(()=>{o.current=t},[t]);const r=a.useCallback(async()=>{n({kind:"probing"});try{await O.config.get(),n({kind:"authorized"})}catch(i){if(i instanceof de&&i.status===401){n({kind:"unauthorized"});return}const c=i instanceof Error?i.message:"无法连接服务器";n({kind:"error",message:c})}},[]);return a.useEffect(()=>{r()},[r]),a.useEffect(()=>{const i=()=>{o.current.kind!=="probing"&&n({kind:"unauthorized",message:"登录已失效,请重新输入令牌"})};return window.addEventListener(ye,i),()=>window.removeEventListener(ye,i)},[]),t.kind==="authorized"?e.jsx(e.Fragment,{children:s}):t.kind==="error"?e.jsxs(we,{title:"无法连接服务器",children:[e.jsx("p",{className:"text-sm text-gray-600",children:t.message}),e.jsx("button",{type:"button",onClick:()=>{r()},className:"mt-4 w-full px-3 py-2 bg-blue-600 text-white text-sm font-medium rounded hover:bg-blue-700",children:"重试"})]}):t.kind==="probing"?e.jsx(we,{title:"加载中",children:e.jsx("p",{className:"text-sm text-gray-500",children:"正在检查登录状态…"})}):e.jsx(Zt,{message:t.message,onSubmit:async i=>{tt(i);try{await O.config.get(),n({kind:"authorized"})}catch(c){if(st(),c instanceof de&&c.status===401){n({kind:"unauthorized",message:"令牌无效,请重试"});return}const m=c instanceof Error?c.message:"登录失败";n({kind:"error",message:m})}}})}function we({title:s,children:t}){return e.jsx("div",{className:"min-h-screen flex items-center justify-center bg-gray-50 px-4",children:e.jsxs("div",{className:"w-full max-w-sm bg-white border rounded-lg shadow-sm px-6 py-6",children:[e.jsx("h1",{className:"text-lg font-semibold mb-3",children:s}),t]})})}function Zt({message:s,onSubmit:t}){const[n,o]=a.useState(""),[r,i]=a.useState(!1),[c,m]=a.useState(void 0),p=async u=>{u.preventDefault();const h=n.trim();if(!h){m("请输入访问令牌");return}m(void 0),i(!0);try{await t(h)}finally{i(!1)}},b=c??s;return e.jsxs(we,{title:"登录 baxian",children:[e.jsx("p",{className:"text-sm text-gray-600 mb-4",children:"服务器开启了访问鉴权,请输入访问令牌继续。"}),e.jsxs("form",{onSubmit:u=>{p(u)},children:[e.jsx("label",{className:"block text-sm font-medium text-gray-700 mb-1",htmlFor:"baxian-token",children:"访问令牌"}),e.jsx("input",{id:"baxian-token",type:"password",autoComplete:"current-password",autoFocus:!0,value:n,onChange:u=>o(u.target.value),className:"w-full px-3 py-2 border rounded text-sm font-mono focus:outline-none focus:ring-2 focus:ring-blue-500",placeholder:"请输入服务器配置的 token",disabled:r}),b&&e.jsx("p",{role:"alert",className:"mt-2 text-sm text-red-600",children:b}),e.jsx("button",{type:"submit",disabled:r,className:"mt-4 w-full px-3 py-2 bg-blue-600 text-white text-sm font-medium rounded hover:bg-blue-700 disabled:opacity-60 disabled:cursor-not-allowed",children:r?"登录中…":"登录"})]})]})}Ke.createRoot(document.getElementById("root")).render(e.jsx(a.StrictMode,{children:e.jsx(mt,{children:e.jsx(lt,{children:e.jsx(Yt,{children:e.jsx(Kt,{})})})})}));