@teammy/server 0.1.5 → 0.1.6

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 (155) hide show
  1. package/dist/main.js +9835 -6799
  2. package/dist/native-pi-entry.js +14 -1
  3. package/dist/project-pi-entry.js +46 -8
  4. package/dist/runtime/workflows/task-bootstrap/prompt.md +2 -0
  5. package/dist/web/assets/{Assistant-B3h2yQF3.css → Assistant-4yZWjYm-.css} +1 -1
  6. package/dist/web/assets/Assistant-BNVXOHQZ.js +1 -0
  7. package/dist/web/assets/Dashboard-zKTK6EZD.js +1 -0
  8. package/dist/web/assets/Files-DI98WkdW.js +1 -0
  9. package/dist/web/assets/{Markdown-oZagG-wy.js → Markdown-D3cU0ani.js} +4 -4
  10. package/dist/web/assets/Materials-CK-mbNmo.css +1 -0
  11. package/dist/web/assets/Materials-CWptgAHz.js +6 -0
  12. package/dist/web/assets/Sessions-DiDwqXLI.js +1 -0
  13. package/dist/web/assets/WorkspaceTree-DeAA1QtV.js +1 -0
  14. package/dist/web/assets/{file-links-CD346_jf.js → file-links-GfCXWkEh.js} +1 -1
  15. package/dist/web/assets/index-BwEl1PIa.js +66 -0
  16. package/dist/web/assets/{index-Be5hGscJ.css → index-CTIAGUGG.css} +1 -1
  17. package/dist/web/downloads/teammy-skill.zip +0 -0
  18. package/dist/web/index.html +2 -2
  19. package/node_modules/@isaacs/nonrecursive-glob-match/LICENSE.md +55 -0
  20. package/node_modules/@isaacs/nonrecursive-glob-match/README.md +333 -0
  21. package/node_modules/@isaacs/nonrecursive-glob-match/dist/commonjs/index.d.ts +114 -0
  22. package/node_modules/@isaacs/nonrecursive-glob-match/dist/commonjs/index.d.ts.map +1 -0
  23. package/node_modules/@isaacs/nonrecursive-glob-match/dist/commonjs/index.js +762 -0
  24. package/node_modules/@isaacs/nonrecursive-glob-match/dist/commonjs/index.js.map +1 -0
  25. package/node_modules/@isaacs/nonrecursive-glob-match/dist/commonjs/index.min.js +3 -0
  26. package/node_modules/@isaacs/nonrecursive-glob-match/dist/commonjs/index.min.js.map +7 -0
  27. package/node_modules/@isaacs/nonrecursive-glob-match/dist/commonjs/package.json +3 -0
  28. package/node_modules/@isaacs/nonrecursive-glob-match/dist/commonjs/parse-class.d.ts +4 -0
  29. package/node_modules/@isaacs/nonrecursive-glob-match/dist/commonjs/parse-class.d.ts.map +1 -0
  30. package/node_modules/@isaacs/nonrecursive-glob-match/dist/commonjs/parse-class.js +142 -0
  31. package/node_modules/@isaacs/nonrecursive-glob-match/dist/commonjs/parse-class.js.map +1 -0
  32. package/node_modules/@isaacs/nonrecursive-glob-match/dist/esm/index.d.ts +114 -0
  33. package/node_modules/@isaacs/nonrecursive-glob-match/dist/esm/index.d.ts.map +1 -0
  34. package/node_modules/@isaacs/nonrecursive-glob-match/dist/esm/index.js +758 -0
  35. package/node_modules/@isaacs/nonrecursive-glob-match/dist/esm/index.js.map +1 -0
  36. package/node_modules/@isaacs/nonrecursive-glob-match/dist/esm/index.min.js +3 -0
  37. package/node_modules/@isaacs/nonrecursive-glob-match/dist/esm/index.min.js.map +7 -0
  38. package/node_modules/@isaacs/nonrecursive-glob-match/dist/esm/package.json +3 -0
  39. package/node_modules/@isaacs/nonrecursive-glob-match/dist/esm/parse-class.d.ts +4 -0
  40. package/node_modules/@isaacs/nonrecursive-glob-match/dist/esm/parse-class.d.ts.map +1 -0
  41. package/node_modules/@isaacs/nonrecursive-glob-match/dist/esm/parse-class.js +138 -0
  42. package/node_modules/@isaacs/nonrecursive-glob-match/dist/esm/parse-class.js.map +1 -0
  43. package/node_modules/@isaacs/nonrecursive-glob-match/package.json +56 -0
  44. package/node_modules/@isaacs/nonrecursive-glob-match/src/index.ts +900 -0
  45. package/node_modules/@isaacs/nonrecursive-glob-match/src/parse-class.ts +158 -0
  46. package/node_modules/glob/README.md +388 -214
  47. package/node_modules/glob/dist/commonjs/glob.d.ts +20 -11
  48. package/node_modules/glob/dist/commonjs/glob.d.ts.map +1 -1
  49. package/node_modules/glob/dist/commonjs/glob.js +22 -29
  50. package/node_modules/glob/dist/commonjs/glob.js.map +1 -1
  51. package/node_modules/glob/dist/commonjs/has-magic.d.ts +1 -1
  52. package/node_modules/glob/dist/commonjs/has-magic.d.ts.map +1 -1
  53. package/node_modules/glob/dist/commonjs/has-magic.js +1 -4
  54. package/node_modules/glob/dist/commonjs/has-magic.js.map +1 -1
  55. package/node_modules/glob/dist/commonjs/ignore.d.ts +16 -4
  56. package/node_modules/glob/dist/commonjs/ignore.d.ts.map +1 -1
  57. package/node_modules/glob/dist/commonjs/ignore.js +24 -4
  58. package/node_modules/glob/dist/commonjs/ignore.js.map +1 -1
  59. package/node_modules/glob/dist/commonjs/index.d.ts +3 -2
  60. package/node_modules/glob/dist/commonjs/index.d.ts.map +1 -1
  61. package/node_modules/glob/dist/commonjs/index.js.map +1 -1
  62. package/node_modules/glob/dist/commonjs/index.min.js +2 -3
  63. package/node_modules/glob/dist/commonjs/index.min.js.map +4 -4
  64. package/node_modules/glob/dist/commonjs/pattern.d.ts +10 -3
  65. package/node_modules/glob/dist/commonjs/pattern.d.ts.map +1 -1
  66. package/node_modules/glob/dist/commonjs/pattern.js +27 -15
  67. package/node_modules/glob/dist/commonjs/pattern.js.map +1 -1
  68. package/node_modules/glob/dist/commonjs/processor.d.ts +23 -10
  69. package/node_modules/glob/dist/commonjs/processor.d.ts.map +1 -1
  70. package/node_modules/glob/dist/commonjs/processor.js +36 -23
  71. package/node_modules/glob/dist/commonjs/processor.js.map +1 -1
  72. package/node_modules/glob/dist/commonjs/walker.d.ts +19 -17
  73. package/node_modules/glob/dist/commonjs/walker.d.ts.map +1 -1
  74. package/node_modules/glob/dist/commonjs/walker.js +50 -35
  75. package/node_modules/glob/dist/commonjs/walker.js.map +1 -1
  76. package/node_modules/glob/dist/esm/glob.d.ts +20 -11
  77. package/node_modules/glob/dist/esm/glob.d.ts.map +1 -1
  78. package/node_modules/glob/dist/esm/glob.js +22 -29
  79. package/node_modules/glob/dist/esm/glob.js.map +1 -1
  80. package/node_modules/glob/dist/esm/has-magic.d.ts +1 -1
  81. package/node_modules/glob/dist/esm/has-magic.d.ts.map +1 -1
  82. package/node_modules/glob/dist/esm/has-magic.js +1 -4
  83. package/node_modules/glob/dist/esm/has-magic.js.map +1 -1
  84. package/node_modules/glob/dist/esm/ignore.d.ts +16 -4
  85. package/node_modules/glob/dist/esm/ignore.d.ts.map +1 -1
  86. package/node_modules/glob/dist/esm/ignore.js +25 -5
  87. package/node_modules/glob/dist/esm/ignore.js.map +1 -1
  88. package/node_modules/glob/dist/esm/index.d.ts +3 -2
  89. package/node_modules/glob/dist/esm/index.d.ts.map +1 -1
  90. package/node_modules/glob/dist/esm/index.js.map +1 -1
  91. package/node_modules/glob/dist/esm/index.min.js +2 -3
  92. package/node_modules/glob/dist/esm/index.min.js.map +4 -4
  93. package/node_modules/glob/dist/esm/pattern.d.ts +10 -3
  94. package/node_modules/glob/dist/esm/pattern.d.ts.map +1 -1
  95. package/node_modules/glob/dist/esm/pattern.js +27 -15
  96. package/node_modules/glob/dist/esm/pattern.js.map +1 -1
  97. package/node_modules/glob/dist/esm/processor.d.ts +23 -10
  98. package/node_modules/glob/dist/esm/processor.d.ts.map +1 -1
  99. package/node_modules/glob/dist/esm/processor.js +36 -23
  100. package/node_modules/glob/dist/esm/processor.js.map +1 -1
  101. package/node_modules/glob/dist/esm/walker.d.ts +19 -17
  102. package/node_modules/glob/dist/esm/walker.d.ts.map +1 -1
  103. package/node_modules/glob/dist/esm/walker.js +51 -36
  104. package/node_modules/glob/dist/esm/walker.js.map +1 -1
  105. package/node_modules/glob/package.json +28 -12
  106. package/node_modules/glob/src/glob.ts +655 -0
  107. package/node_modules/glob/src/has-magic.ts +23 -0
  108. package/node_modules/glob/src/ignore.ts +162 -0
  109. package/node_modules/glob/src/index.ts +225 -0
  110. package/node_modules/glob/src/pattern.ts +286 -0
  111. package/node_modules/glob/src/processor.ts +333 -0
  112. package/node_modules/glob/src/walker.ts +523 -0
  113. package/node_modules/minimatch/README.md +125 -107
  114. package/node_modules/minimatch/dist/commonjs/index.d.ts +49 -38
  115. package/node_modules/minimatch/dist/commonjs/index.d.ts.map +1 -1
  116. package/node_modules/minimatch/dist/commonjs/index.js +782 -359
  117. package/node_modules/minimatch/dist/commonjs/index.js.map +1 -1
  118. package/node_modules/minimatch/dist/esm/index.d.ts +49 -38
  119. package/node_modules/minimatch/dist/esm/index.d.ts.map +1 -1
  120. package/node_modules/minimatch/dist/esm/index.js +781 -356
  121. package/node_modules/minimatch/dist/esm/index.js.map +1 -1
  122. package/node_modules/minimatch/package.json +5 -4
  123. package/node_modules/path-scurry/README.md +0 -1
  124. package/node_modules/path-scurry/dist/commonjs/index.d.ts +7 -0
  125. package/node_modules/path-scurry/dist/commonjs/index.d.ts.map +1 -1
  126. package/node_modules/path-scurry/dist/commonjs/index.js +59 -21
  127. package/node_modules/path-scurry/dist/commonjs/index.js.map +1 -1
  128. package/node_modules/path-scurry/dist/esm/index.d.ts +7 -0
  129. package/node_modules/path-scurry/dist/esm/index.d.ts.map +1 -1
  130. package/node_modules/path-scurry/dist/esm/index.js +42 -14
  131. package/node_modules/path-scurry/dist/esm/index.js.map +1 -1
  132. package/node_modules/path-scurry/package.json +4 -4
  133. package/package.json +2 -1
  134. package/dist/web/assets/Assistant-Dm_p8EZl.js +0 -1
  135. package/dist/web/assets/Dashboard-fwW9NxcC.js +0 -1
  136. package/dist/web/assets/Files-D-KCDWmO.js +0 -1
  137. package/dist/web/assets/Sessions-BQhGiLvz.js +0 -1
  138. package/dist/web/assets/WorkspaceTree-B9733pV3.js +0 -1
  139. package/dist/web/assets/index-BiiPuwDi.js +0 -66
  140. package/node_modules/minimatch/dist/commonjs/ast.d.ts +0 -22
  141. package/node_modules/minimatch/dist/commonjs/ast.d.ts.map +0 -1
  142. package/node_modules/minimatch/dist/commonjs/ast.js +0 -845
  143. package/node_modules/minimatch/dist/commonjs/ast.js.map +0 -1
  144. package/node_modules/minimatch/dist/commonjs/brace-expressions.d.ts +0 -8
  145. package/node_modules/minimatch/dist/commonjs/brace-expressions.d.ts.map +0 -1
  146. package/node_modules/minimatch/dist/commonjs/brace-expressions.js +0 -150
  147. package/node_modules/minimatch/dist/commonjs/brace-expressions.js.map +0 -1
  148. package/node_modules/minimatch/dist/esm/ast.d.ts +0 -22
  149. package/node_modules/minimatch/dist/esm/ast.d.ts.map +0 -1
  150. package/node_modules/minimatch/dist/esm/ast.js +0 -841
  151. package/node_modules/minimatch/dist/esm/ast.js.map +0 -1
  152. package/node_modules/minimatch/dist/esm/brace-expressions.d.ts +0 -8
  153. package/node_modules/minimatch/dist/esm/brace-expressions.d.ts.map +0 -1
  154. package/node_modules/minimatch/dist/esm/brace-expressions.js +0 -146
  155. package/node_modules/minimatch/dist/esm/brace-expressions.js.map +0 -1
@@ -97,6 +97,18 @@ function modelAccess(profile, key, reasoning = false) {
97
97
  return { models, model };
98
98
  }
99
99
 
100
+ // apps/server/agent-skills.ts
101
+ import { existsSync } from "node:fs";
102
+ import { loadSkillsFromDir } from "@earendil-works/pi-coding-agent";
103
+
104
+ // apps/server/agent-resources.ts
105
+ var agentResourcesPath = "/opt/teammy-resources";
106
+
107
+ // apps/server/agent-skills.ts
108
+ function loadAgentSkills(directory = `${agentResourcesPath}/skills`) {
109
+ return existsSync(directory) ? loadSkillsFromDir({ dir: directory, source: "teammy-deployment" }) : { skills: [], diagnostics: [] };
110
+ }
111
+
100
112
  // apps/server/ai/native-pi-entry.ts
101
113
  var channel = new AgentChannel(process.stdin, process.stdout);
102
114
  var sequence = 0;
@@ -131,9 +143,10 @@ async function run(config) {
131
143
  model.reasoning
132
144
  );
133
145
  modelRuntime.registerNativeProvider(bridge.models.getProvider(model.provider));
146
+ const skills = loadAgentSkills();
134
147
  const loader = {
135
148
  getExtensions: () => ({ extensions: [], errors: [], runtime: createExtensionRuntime() }),
136
- getSkills: () => ({ skills: [], diagnostics: [] }),
149
+ getSkills: () => skills,
137
150
  getPrompts: () => ({ prompts: [], diagnostics: [] }),
138
151
  getThemes: () => ({ themes: [], diagnostics: [] }),
139
152
  getAgentsFiles: () => ({ agentsFiles: [] }),
@@ -1,8 +1,8 @@
1
1
  // apps/server/agents/pi-entry.ts
2
2
  import { spawn } from "node:child_process";
3
- import { existsSync } from "node:fs";
4
- import { mkdir } from "node:fs/promises";
5
- import { join } from "node:path";
3
+ import { existsSync as existsSync2 } from "node:fs";
4
+ import { mkdir, readFile } from "node:fs/promises";
5
+ import { join, basename } from "node:path";
6
6
  import { InMemoryCredentialStore, InMemoryModelsStore, Type as Type2 } from "@earendil-works/pi-ai";
7
7
  import { createAssistantMessageEventStream } from "@earendil-works/pi-ai/utils/event-stream";
8
8
  import {
@@ -91,6 +91,18 @@ function modelAccess(profile, key, reasoning = false) {
91
91
  return { models, model };
92
92
  }
93
93
 
94
+ // apps/server/agent-skills.ts
95
+ import { existsSync } from "node:fs";
96
+ import { loadSkillsFromDir } from "@earendil-works/pi-coding-agent";
97
+
98
+ // apps/server/agent-resources.ts
99
+ var agentResourcesPath = "/opt/teammy-resources";
100
+
101
+ // apps/server/agent-skills.ts
102
+ function loadAgentSkills(directory = `${agentResourcesPath}/skills`) {
103
+ return existsSync(directory) ? loadSkillsFromDir({ dir: directory, source: "teammy-deployment" }) : { skills: [], diagnostics: [] };
104
+ }
105
+
94
106
  // apps/server/agents/pi-entry.ts
95
107
  async function piChild() {
96
108
  const channel = new AgentChannel(process.stdin, process.stdout);
@@ -106,6 +118,7 @@ async function piChild() {
106
118
  };
107
119
  async function open(input) {
108
120
  const key = JSON.stringify([
121
+ input.cwd,
109
122
  input.model,
110
123
  input.compactAt,
111
124
  input.prompt,
@@ -115,7 +128,7 @@ async function piChild() {
115
128
  if (session && key === configKey) return;
116
129
  session?.dispose();
117
130
  await mkdir(input.sessionDir, { recursive: true });
118
- manager = input.sessionFile && existsSync(input.sessionFile) ? SessionManager.open(input.sessionFile, input.sessionDir, "/project") : SessionManager.create("/project", input.sessionDir);
131
+ manager = input.sessionFile && existsSync2(input.sessionFile) ? SessionManager.open(input.sessionFile, input.sessionDir, input.cwd ?? "/project") : SessionManager.create(input.cwd ?? "/project", input.sessionDir);
119
132
  const modelRuntime = await ModelRuntime.create({
120
133
  credentials: new InMemoryCredentialStore(),
121
134
  modelsStore: new InMemoryModelsStore(),
@@ -140,9 +153,10 @@ async function piChild() {
140
153
  getModels: () => [input.model],
141
154
  getAllModels: () => [input.model]
142
155
  });
156
+ const skills = loadAgentSkills();
143
157
  const loader = {
144
158
  getExtensions: () => ({ extensions: [], errors: [], runtime: createExtensionRuntime() }),
145
- getSkills: () => ({ skills: [], diagnostics: [] }),
159
+ getSkills: () => skills,
146
160
  getPrompts: () => ({ prompts: [], diagnostics: [] }),
147
161
  getThemes: () => ({ themes: [], diagnostics: [] }),
148
162
  getAgentsFiles: () => ({ agentsFiles: [] }),
@@ -161,12 +175,28 @@ async function piChild() {
161
175
  description: tool.description,
162
176
  parameters: Type2.Unsafe(tool.schema),
163
177
  execute: async (_id, params) => {
164
- const value = await rpc(tool.name, params);
178
+ let input2 = params;
179
+ if (tool.name === "save_material") {
180
+ const source = params;
181
+ input2 = {
182
+ ...source,
183
+ ...source.contentFile ? { _content: await readFile(source.contentFile, "utf8") } : {},
184
+ ...source.originals ? {
185
+ _files: await Promise.all(
186
+ source.originals.map(async (file) => ({
187
+ name: file.name ?? basename(file.path),
188
+ base64: (await readFile(file.path)).toString("base64")
189
+ }))
190
+ )
191
+ } : {}
192
+ };
193
+ }
194
+ const value = await rpc(tool.name, input2);
165
195
  return { content: [{ type: "text", text: JSON.stringify(value) }], details: value };
166
196
  }
167
197
  }));
168
198
  const created = await createAgentSession({
169
- cwd: "/project",
199
+ cwd: input.cwd ?? "/project",
170
200
  agentDir: join(input.sessionDir, "agent"),
171
201
  modelRuntime,
172
202
  model: input.model,
@@ -178,7 +208,15 @@ async function piChild() {
178
208
  retry: { enabled: false, maxRetries: 0 },
179
209
  cacheWarming: "off"
180
210
  }),
181
- tools: ["read", "bash", "grep", "find", "ls", ...input.tools.map((tool) => tool.name)],
211
+ tools: [
212
+ "read",
213
+ "bash",
214
+ "grep",
215
+ "find",
216
+ "ls",
217
+ ...input.cwd === "/work" ? ["write", "edit"] : [],
218
+ ...input.tools.map((tool) => tool.name)
219
+ ],
182
220
  customTools
183
221
  });
184
222
  session = created.session;
@@ -42,6 +42,8 @@
42
42
 
43
43
  更新关注任务表达和来源的实质变化,无需为了措辞或附带统计的变化重写任务。
44
44
 
45
+ 已有任务也可能由成员确认创建(origin 为 confirmed),来源中的 material 表示项目资料,不在本轮成员目录内。结合已有任务避免重复;不能因成员文件缺少对应记录而撤下这类任务。人工确认的字段由系统保留,本轮只补充工作区中的实际变化。
46
+
45
47
  ## 分析范围与复核
46
48
 
47
49
  工作区和基线只读,`/tmp` 可用于临时分析。公共资料用于理解约定,本轮只维护指定成员的任务。
@@ -1 +1 @@
1
- main#main[data-page=assistant]{height:100dvh;padding:0}.assistant-layout{grid-template-columns:var(--pane-width) minmax(0, 1fr);height:100%;min-height:0}.assistant-list{border-right:1px solid var(--color-line);background:var(--color-surface);flex-direction:column;min-height:0;display:flex}.assistant-list-heading,.assistant-thread-heading{border-bottom:1px solid var(--color-line);flex:0 0 76px;justify-content:space-between;align-items:center;padding:0 24px;display:flex}.assistant-list-heading h1{margin:0;font-size:20px}.assistant-thread-heading h2{text-overflow:ellipsis;white-space:nowrap;margin:0;font-size:17px;overflow:hidden}.assistant-message-scroll{flex:1;min-height:0;overflow-y:auto}.assistant-list-status{color:var(--color-muted);font-size:var(--text-sm);margin:20px 24px}.assistant-message-item{border:0;border-bottom:1px solid var(--color-line);text-align:left;width:100%;color:var(--color-text);background:0 0;border-radius:0;align-items:center;gap:12px;padding:20px 24px;display:flex}.assistant-message-item:hover{background:var(--color-hover)}.assistant-message-item.selected{background:var(--color-soft)}.assistant-message-item.archived{color:var(--color-muted)}.assistant-message-item.archived strong{font-weight:400}.assistant-new-chat{width:32px;height:32px;min-height:32px;color:var(--brand-orange);background:var(--color-accent-soft);padding:6px}.assistant-new-chat .icon{width:20px;height:20px}.assistant-new-chat:after{top:calc(100% + 6px);bottom:auto}.assistant-message-copy{flex-direction:column;flex:1;gap:6px;min-width:0;display:flex}.assistant-message-copy>.selection-content{width:fit-content;max-width:100%;color:var(--color-text);margin:-5px -8px;padding:5px 8px;display:block;overflow:visible}.assistant-message-item.archived .selection-content{color:inherit}.assistant-message-copy .selection-inner{min-width:0;display:block}.assistant-message-copy .selection-inner strong{display:block}.assistant-message-copy strong,.assistant-message-copy>span{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.assistant-message-copy strong{font-size:var(--text-base);font-weight:600}.assistant-message-copy>span,.assistant-message-copy time{font-size:var(--text-xs);color:var(--color-muted)}.assistant-message-dot{border-radius:50%;flex:0 0 7px;width:7px;height:7px}.assistant-message-dot.unread{background:var(--brand-orange)}.assistant-thread{background:var(--color-canvas);flex-direction:column;min-width:0;min-height:0;display:flex}.assistant-transcript{flex:1;min-height:0;padding:28px clamp(20px,4vw,64px);overflow-y:auto}.assistant-bubble-row{margin:0 0 24px;display:flex}.assistant-bubble-row.mine{justify-content:flex-end}.assistant-bubble{border-radius:4px var(--radius-lg) var(--radius-lg);background:var(--color-soft);overflow-wrap:anywhere;min-width:100px;max-width:min(88%,800px);padding:14px 18px}.assistant-bubble-row.mine .assistant-bubble{background:var(--color-accent-soft);border-radius:var(--radius-lg) 4px var(--radius-lg) var(--radius-lg)}.assistant-bubble-meta{font-size:var(--text-xs);color:var(--color-muted);align-items:baseline;gap:16px;margin-bottom:8px;display:flex}.assistant-debug-reply{font-size:var(--text-xs);background:var(--color-surface);margin-top:12px;padding:4px 10px}.assistant-bubble .markdown>:first-child{margin-top:0}.assistant-bubble .markdown>:last-child{margin-bottom:0}.assistant-bubble .markdown{font-size:var(--text-base);line-height:1.75}.assistant-bubble .markdown h1,.assistant-bubble .markdown h2{font-size:18px}.assistant-bubble .markdown h3,.assistant-bubble .markdown h4,.assistant-bubble .markdown h5,.assistant-bubble .markdown h6{font-size:var(--text-base)}.assistant-bubble .markdown :is(h1,h2,h3,h4,h5,h6){margin:18px 0 8px;line-height:1.5}.assistant-bubble .markdown :is(p,ul,ol){margin:10px 0}.assistant-bubble .markdown :is(ul,ol){padding-left:1.5em}.assistant-bubble .markdown li+li{margin-top:4px}.assistant-bubble .markdown li>:is(ul,ol){margin:4px 0}.assistant-bubble pre{max-width:100%;overflow-x:auto}.assistant-composer{background:var(--color-surface);border:1px solid var(--color-line);border-radius:var(--radius-lg);align-items:flex-end;gap:12px;margin:0 28px 28px;padding:12px;display:flex}.assistant-reply-hint{font-size:var(--text-xs);color:var(--color-muted);margin:0 28px 10px;line-height:1.7}.assistant-composer:focus-within{border-color:var(--color-muted)}.assistant-composer textarea{box-shadow:none;resize:vertical;background:0 0;border:0;flex:1;min-height:56px;max-height:220px;padding:8px}.assistant-composer textarea:focus{box-shadow:none;outline:none}.assistant-send{flex:0 0 40px;place-items:center;width:40px;height:40px;padding:0;display:grid}.assistant-empty{height:100%;min-height:240px;color:var(--color-muted);flex-direction:column;justify-content:center;align-items:center;gap:20px;display:flex}.assistant-empty .mascot{width:96px;height:144px}.assistant-empty p{margin:0}.assistant-archived{color:var(--color-muted);font-size:var(--text-sm);justify-content:center;align-items:center;gap:8px;padding:24px;display:flex}.assistant-thread>.notice{margin:0 28px 12px}.assistant-typing{gap:5px;padding:8px 0;display:inline-flex}.assistant-typing i{background:var(--color-muted);border-radius:50%;width:5px;height:5px;animation:1.4s infinite assistant-pulse}.assistant-typing i:nth-child(2){animation-delay:.15s}.assistant-typing i:nth-child(3){animation-delay:.3s}@keyframes assistant-pulse{0%,70%,to{opacity:.35}35%{opacity:1}}@media (prefers-reduced-motion:reduce){.assistant-typing i{animation:none}}@media (width<=900px){.assistant-layout{grid-template-columns:240px minmax(0,1fr)}.assistant-message-item{padding:16px}.assistant-composer{margin:0 16px 16px}.assistant-reply-hint{margin:0 16px 10px}.assistant-bubble{max-width:96%}}@media (width<=600px){.assistant-layout{grid-template-columns:150px minmax(0,1fr)}.assistant-list-heading,.assistant-thread-heading{padding:0 12px}.assistant-transcript{padding:16px 10px}.assistant-composer{gap:4px;margin:0 8px 12px;padding:6px}.assistant-reply-hint{margin:0 8px 10px}}
1
+ main#main[data-page=assistant]{height:100dvh;padding:0}.assistant-layout{grid-template-columns:var(--pane-width) minmax(0, 1fr);height:100%;min-height:0}.assistant-list{border-right:1px solid var(--color-line);background:var(--color-surface);flex-direction:column;min-height:0;display:flex}.assistant-list-heading,.assistant-thread-heading{border-bottom:1px solid var(--color-line);flex:0 0 76px;justify-content:space-between;align-items:center;padding:0 24px;display:flex}.assistant-list-heading h1{margin:0;font-size:20px}.assistant-thread-heading h2{text-overflow:ellipsis;white-space:nowrap;margin:0;font-size:17px;overflow:hidden}.assistant-message-scroll{flex:1;min-height:0;overflow-y:auto}.assistant-list-status{color:var(--color-muted);font-size:var(--text-sm);margin:20px 24px}.assistant-message-item{border:0;border-bottom:1px solid var(--color-line);text-align:left;width:100%;color:var(--color-text);background:0 0;border-radius:0;align-items:center;gap:12px;padding:20px 24px;display:flex}.assistant-message-item:hover{background:var(--color-hover)}.assistant-message-item.selected{background:var(--color-soft)}.assistant-message-item.archived{color:var(--color-muted)}.assistant-message-item.archived strong{font-weight:400}.assistant-new-chat{width:32px;height:32px;min-height:32px;color:var(--brand-orange);background:var(--color-accent-soft);padding:6px}.assistant-new-chat .icon{width:20px;height:20px}.assistant-new-chat:after{top:calc(100% + 6px);bottom:auto}.assistant-message-copy{flex-direction:column;flex:1;gap:6px;min-width:0;display:flex}.assistant-message-copy>.selection-content{width:fit-content;max-width:100%;color:var(--color-text);margin:-5px -8px;padding:5px 8px;display:block;overflow:visible}.assistant-message-item.archived .selection-content{color:inherit}.assistant-message-copy .selection-inner{min-width:0;display:block}.assistant-message-copy .selection-inner strong{display:block}.assistant-message-copy strong,.assistant-message-copy>span{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.assistant-message-copy strong{font-size:var(--text-base);font-weight:600}.assistant-message-copy>span,.assistant-message-copy time{font-size:var(--text-xs);color:var(--color-muted)}.assistant-message-dot{border-radius:50%;flex:0 0 7px;width:7px;height:7px}.assistant-message-dot.unread{background:var(--brand-orange)}.assistant-thread{background:var(--color-canvas);flex-direction:column;min-width:0;min-height:0;display:flex}.assistant-transcript{flex:1;min-height:0;padding:28px clamp(20px,4vw,64px);overflow-y:auto}.assistant-bubble-row{margin:0 0 24px;display:flex}.assistant-bubble-row.mine{justify-content:flex-end}.assistant-bubble{border-radius:4px var(--radius-lg) var(--radius-lg);background:var(--color-soft);overflow-wrap:anywhere;min-width:100px;max-width:min(88%,800px);padding:14px 18px}.assistant-bubble-row.mine .assistant-bubble{background:var(--color-accent-soft);border-radius:var(--radius-lg) 4px var(--radius-lg) var(--radius-lg)}.assistant-bubble-meta{font-size:var(--text-xs);color:var(--color-muted);align-items:baseline;gap:16px;margin-bottom:8px;display:flex}.assistant-debug-reply{font-size:var(--text-xs);background:var(--color-surface);margin-top:12px;padding:4px 10px}.assistant-bubble .markdown>:first-child{margin-top:0}.assistant-bubble .markdown>:last-child{margin-bottom:0}.assistant-bubble .markdown{font-size:var(--text-base);line-height:1.75}.assistant-bubble .markdown h1,.assistant-bubble .markdown h2{font-size:18px}.assistant-bubble .markdown h3,.assistant-bubble .markdown h4,.assistant-bubble .markdown h5,.assistant-bubble .markdown h6{font-size:var(--text-base)}.assistant-bubble .markdown :is(h1,h2,h3,h4,h5,h6){margin:18px 0 8px;line-height:1.5}.assistant-bubble .markdown :is(p,ul,ol){margin:10px 0}.assistant-bubble .markdown :is(ul,ol){padding-left:1.5em}.assistant-bubble .markdown li+li{margin-top:4px}.assistant-bubble .markdown li>:is(ul,ol){margin:4px 0}.assistant-bubble pre{max-width:100%;overflow-x:auto}.assistant-composer{background:var(--color-surface);border:1px solid var(--color-line);border-radius:var(--radius-lg);align-items:flex-end;gap:12px;margin:0 28px 28px;padding:12px;display:flex}.assistant-reply-hint{font-size:var(--text-xs);color:var(--color-muted);margin:0 28px 10px;line-height:1.7}.assistant-composer:focus-within{border-color:var(--color-muted)}.assistant-composer textarea{box-shadow:none;resize:vertical;background:0 0;border:0;flex:1;min-height:56px;max-height:220px;padding:8px}.assistant-composer textarea:focus{box-shadow:none;outline:none}.assistant-send{flex:0 0 40px;place-items:center;width:40px;height:40px;padding:0;display:grid}.assistant-empty{height:100%;min-height:240px;color:var(--color-muted);flex-direction:column;justify-content:center;align-items:center;gap:20px;display:flex}.assistant-empty .mascot{width:96px;height:144px}.assistant-empty p{margin:0}.assistant-archived{color:var(--color-muted);font-size:var(--text-sm);justify-content:center;align-items:center;gap:8px;padding:24px;display:flex}.assistant-thread>.notice{margin:0 28px 12px}.assistant-typing{gap:5px;padding:8px 0;display:inline-flex}.assistant-typing i{background:var(--color-muted);border-radius:50%;width:5px;height:5px;animation:1.4s infinite assistant-pulse}.assistant-typing i:nth-child(2){animation-delay:.15s}.assistant-typing i:nth-child(3){animation-delay:.3s}@keyframes assistant-pulse{0%,70%,to{opacity:.35}35%{opacity:1}}@media (prefers-reduced-motion:reduce){.assistant-typing i{animation:none}}@media (width<=900px){.assistant-layout{grid-template-columns:240px minmax(0,1fr)}.assistant-message-item{padding:16px}.assistant-composer{margin:0 16px 16px}.assistant-reply-hint{margin:0 16px 10px}.assistant-bubble{max-width:96%}}@media (width<=600px){.assistant-layout{grid-template-columns:150px minmax(0,1fr)}.assistant-list-heading,.assistant-thread-heading{padding:0 12px}.assistant-transcript{padding:16px 10px}.assistant-composer{gap:4px;margin:0 8px 12px;padding:6px}.assistant-reply-hint{margin:0 8px 10px}}.assistant-participants{text-overflow:ellipsis;white-space:nowrap;min-width:0;max-width:45%;color:var(--color-muted);font-size:var(--text-sm);margin-left:16px;overflow:hidden}
@@ -0,0 +1 @@
1
+ import{$ as e,D as t,E as n,G as r,K as i,O as ee,Q as a,U as te,_ as o,a as s,d as c,i as ne,j as l,k as u,l as re,n as d,r as f,t as ie,v as ae,x as p,y as m}from"./index-BwEl1PIa.js";import{t as h}from"./Markdown-D3cU0ani.js";var g=a(),_=u(),v=e=>new Date(e).toLocaleTimeString([],{hour:`2-digit`,minute:`2-digit`}),y=e=>e.replace(/[#*_`>]/g,``).replace(/\s+/g,` `).trim();function b({mine:e=!1,author:t,time:n,children:r}){return(0,_.jsx)(`div`,{className:`assistant-bubble-row ${e?`mine`:``}`,children:(0,_.jsxs)(`div`,{className:`assistant-bubble`,children:[(0,_.jsxs)(`div`,{className:`assistant-bubble-meta`,children:[(0,_.jsx)(`span`,{children:t}),(0,_.jsx)(`time`,{dateTime:n,children:v(n)})]}),r]})})}function x({me:a}){let{projectId:u,request:x}=re(),C=ee(),w=t(u,a,`assistant-selection`),T=t(u,a,`assistant-drafts`),oe=(0,g.useCallback)(e=>x(`agents/outbox`,ne,{signal:e}),[x]),E=n(oe,3e3,t(u,a,`outbox`)),se=(0,g.useCallback)(e=>x(`agents/chats`,ie,{signal:e}),[x]),D=n(se,3e3,t(u,a,`chats`)),[O,ce]=(0,g.useState)(()=>{let e=new URLSearchParams(location.search),t=e.get(`chat`);return t?`chat:${t}`:e.get(`message`)??C?.get(w)??``}),k=O.startsWith(`chat:`)?O.slice(5):``,A=!O||!!k,[j,M]=(0,g.useState)(()=>C?.get(t(u,a,`chat`,k))),N=j?.id===k?j:C?.get(t(u,a,`chat`,k)),le=D.data?.chats.find(e=>e.id===k),[ue,P]=(0,g.useState)(),[F,de]=(0,g.useState)(()=>C?.get(T)??{}),I=F[O]??``,L=e=>de(t=>({...t,[O]:e})),[R,z]=(0,g.useState)(!1),[B,V]=(0,g.useState)(!1),[fe,H]=(0,g.useState)(``),[U,W]=(0,g.useState)(``),G=(0,g.useRef)(null),K=(0,g.useRef)(!0),q=(0,g.useRef)(O);q.current=O,(0,g.useEffect)(()=>{j&&C?.set(t(u,a,`chat`,j.id),j)},[C,u,a,j]),(0,g.useEffect)(()=>{C?.set(T,F)},[C,T,F]);function J(e){q.current=e,ce(e),C?.set(w,e);let t=new URL(location.href);e.startsWith(`chat:`)?t.searchParams.set(`chat`,e.slice(5)):t.searchParams.delete(`chat`),e&&!e.startsWith(`chat:`)&&e!==`debug`?t.searchParams.set(`message`,e):t.searchParams.delete(`message`),history.replaceState(history.state,``,t)}(0,g.useEffect)(()=>{!O&&D.data?.chats.length&&J(`chat:${D.data.chats[0].id}`)},[O,D.data]);let Y=(E.data?.messages??[]).filter(e=>e.box===`debug`).reverse(),X=E.data?.messages.find(e=>e.id===(O===`debug`?ue:O)),Z=Y.filter(e=>!e.readAt).map(e=>e.id).join(`,`);(0,g.useEffect)(()=>{X&&!X.readAt&&O!==`debug`&&x(`agents/outbox/${X.id}/read`,s,{method:`POST`}).then(()=>{window.dispatchEvent(new Event(`teammy:outbox`)),E.reload()}).catch(e=>H(l(e)))},[X?.id,X?.readAt,O,x,E.reload]),(0,g.useEffect)(()=>{O===`debug`&&Z&&Promise.all(Z.split(`,`).map(e=>x(`agents/outbox/${e}/read`,s,{method:`POST`}))).then(()=>{window.dispatchEvent(new Event(`teammy:outbox`)),E.reload()}).catch(e=>H(l(e)))},[O,Z,x,E.reload]),(0,g.useEffect)(()=>{if(W(``),!k)return;let t=!0,n=new EventSource(e(`/api/v1/projects/${encodeURIComponent(u)}/agents/chats/${encodeURIComponent(k)}/events`));n.addEventListener(`snapshot`,e=>{if(t)try{M(d.parse(JSON.parse(e.data))),W(``)}catch(e){W(l(e))}}),n.onerror=()=>{t&&W(`对话连接中断,正在重新连接…`)},n.addEventListener(`run`,e=>{if(!t)return;let n=f.parse(JSON.parse(e.data));M(t=>t&&{...t,cursor:Math.max(t.cursor,Number(e.lastEventId)||0),runs:t.runs.some(e=>e.id===n.id)?t.runs:[...t.runs,n]})});for(let e of[`delta`,`reset`,`state`])n.addEventListener(e,n=>{if(!t)return;let r=JSON.parse(n.data);M(t=>t&&{...t,cursor:Math.max(t.cursor,Number(n.lastEventId)||0),runs:t.runs.map(t=>t.id===r.id?{...t,answer:e===`delta`?t.answer+(r.text??``):e===`reset`?``:r.answer??t.answer,state:r.state??t.state,error:r.error===void 0?t.error:r.error}:t)})});return()=>{t=!1,n.close()}},[u,k]),(0,g.useEffect)(()=>{if(N?.kind!==`matter`||N.id!==k)return;let e=()=>{document.visibilityState===`visible`&&x(`agents/chats/${k}/read`,i({ok:te()}),{method:`POST`,body:{cursor:N.cursor}}).then(()=>{D.reload(),window.dispatchEvent(new Event(`teammy:outbox`))}).catch(e=>H(l(e)))},t=setTimeout(e,300);return document.addEventListener(`visibilitychange`,e),()=>{clearTimeout(t),document.removeEventListener(`visibilitychange`,e)}},[k,N?.cursor,N?.kind,x]),(0,g.useEffect)(()=>{K.current&&G.current?.scrollIntoView({block:`end`})},[O,j?.runs,X?.recipients,Y.length]);function Q(){window.dispatchEvent(new Event(`teammy:outbox`)),E.reload()}async function $(e){if(K.current=!0,J(e),H(``),P(void 0),!(e.startsWith(`chat:`)||e===`debug`))try{await x(`agents/outbox/${e}/read`,s,{method:`POST`}),Q()}catch(e){H(l(e))}}async function pe(){if(!B){V(!0),H(``);try{let e=await x(`agents/chats`,d,{method:`POST`});M(e),await $(`chat:${e.id}`),D.reload()}catch(e){H(l(e))}finally{V(!1)}}}async function me(e){e.preventDefault();let t=I.trim();if(t&&!R){z(!0),H(``);try{if(A){let e=k;if(!e){let t=await x(`agents/chats`,d,{method:`POST`});e=t.id,q.current===O&&(M(t),J(`chat:${e}`))}let n=await x(`agents/chats/${e}`,f,{method:`POST`,body:{text:t}});M(t=>t?.id===e?{...t,runs:t.runs.some(e=>e.id===n.id)?t.runs:[...t.runs,n]}:t),D.reload()}else await x(`agents/outbox/${X.id}/reply`,i({taskId:r()}),{method:`POST`,body:{body:t}}),Q(),P(void 0);L(``)}catch(e){H(l(e))}finally{z(!1)}}}let he=A||!!X&&!X.archivedAt&&!X.recipients.find(e=>e.userId===a)?.reply,ge=A&&!N&&(!!k||!D.data);return(0,_.jsxs)(`div`,{className:`split-layout assistant-layout`,"data-testid":`assistant-page`,children:[(0,_.jsxs)(`aside`,{className:`assistant-list`,"aria-label":`消息列表`,children:[(0,_.jsxs)(`header`,{className:`assistant-list-heading`,children:[(0,_.jsx)(`h1`,{children:`消息`}),(0,_.jsx)(ae,{className:`assistant-new-chat`,icon:`plus`,label:`新建对话`,disabled:B,onClick:()=>void pe(),"data-testid":`assistant-launcher`})]}),(0,_.jsxs)(`div`,{className:`assistant-message-scroll`,children:[D.loading&&!D.data&&(0,_.jsx)(`p`,{className:`assistant-list-status`,role:`status`,children:`加载中…`}),D.data?.chats.map(e=>(0,_.jsxs)(`button`,{type:`button`,"data-testid":`assistant-chat-${e.id}`,className:`assistant-message-item assistant-chat-item ${k===e.id?`selected`:``}`,"aria-pressed":k===e.id,onClick:()=>void $(`chat:${e.id}`),children:[(0,_.jsx)(`span`,{className:`assistant-message-dot ${e.unread||e.state===`running`||e.state===`queued`?`unread`:``}`}),(0,_.jsxs)(`span`,{className:`assistant-message-copy`,children:[(0,_.jsx)(c,{selected:k===e.id,children:(0,_.jsx)(`strong`,{children:e.title})}),(0,_.jsxs)(`time`,{dateTime:e.updatedAt,children:[new Date(e.updatedAt).toLocaleDateString([],{month:`numeric`,day:`numeric`}),` `,v(e.updatedAt)]})]})]},e.id)),!!Y.length&&(0,_.jsxs)(`button`,{type:`button`,"data-testid":`debug-outbox`,className:`assistant-message-item ${O===`debug`?`selected`:``}`,onClick:()=>void $(`debug`),children:[(0,_.jsx)(`span`,{className:`assistant-message-dot ${Z?`unread`:``}`}),(0,_.jsxs)(`span`,{className:`assistant-message-copy`,children:[(0,_.jsx)(c,{selected:O===`debug`,children:(0,_.jsx)(`strong`,{children:`运行提醒`})}),(0,_.jsx)(`span`,{children:y(Y.at(-1).body)})]})]}),E.data?.messages.filter(e=>e.box!==`debug`).sort((e,t)=>Number(!!e.archivedAt)-Number(!!t.archivedAt)).map(e=>(0,_.jsxs)(`button`,{type:`button`,"data-testid":`outbox-${e.id}`,className:`assistant-message-item ${e.archivedAt?`archived`:``} ${O===e.id?`selected`:``}`,onClick:()=>void $(e.id),children:[(0,_.jsx)(`span`,{className:`assistant-message-dot ${e.readAt?``:`unread`}`}),(0,_.jsxs)(`span`,{className:`assistant-message-copy`,children:[(0,_.jsx)(c,{selected:O===e.id,children:(0,_.jsx)(`strong`,{children:y(e.body)})}),(0,_.jsxs)(`time`,{dateTime:e.createdAt,children:[new Date(e.createdAt).toLocaleDateString([],{month:`numeric`,day:`numeric`}),` `,v(e.createdAt)]})]})]},e.id))]}),(0,_.jsx)(p,{error:!0,children:E.error||D.error})]}),(0,_.jsxs)(`section`,{className:`assistant-thread`,"aria-label":A?`提百事对话`:`消息内容`,children:[(0,_.jsxs)(`header`,{className:`assistant-thread-heading`,children:[(0,_.jsx)(`h2`,{children:A?le?.title??N?.title??(k?`无标题`:`提百事`):O===`debug`?`运行提醒`:`项目消息`}),N?.kind===`matter`&&(0,_.jsxs)(`span`,{className:`assistant-participants`,title:N.participants?.join(`、`),children:[N.visibility===`project`?`项目共享 · `:``,N.participants?.join(`、`)]})]}),(0,_.jsxs)(`div`,{className:`assistant-transcript`,role:`log`,"aria-live":`polite`,"data-testid":`assistant-transcript`,onScroll:e=>{let t=e.currentTarget;K.current=t.scrollHeight-t.scrollTop-t.clientHeight<100},children:[A?ge?(0,_.jsxs)(`div`,{className:`assistant-empty`,"data-testid":`assistant-loading`,children:[(0,_.jsx)(m,{}),(0,_.jsx)(`p`,{role:`status`,children:U||D.error?`暂时无法加载对话`:`加载中…`})]}):N?.runs.length?N.runs.map(e=>(0,_.jsxs)(`div`,{className:`assistant-turn`,children:[(0,_.jsx)(b,{mine:e.author===void 0||e.author===a,author:`${e.author===void 0?a:e.author||`提百事`}${e.source===`wecom`?` · 企业微信`:``}`,time:e.createdAt,children:(0,_.jsx)(`div`,{className:`markdown`,children:(0,_.jsx)(h,{children:e.text})})}),(0,_.jsxs)(b,{author:`提百事`,time:e.createdAt,children:[e.answer&&(0,_.jsx)(`div`,{className:`markdown`,children:(0,_.jsx)(h,{children:e.answer})}),[`queued`,`running`].includes(e.state)&&(0,_.jsxs)(`span`,{className:`assistant-typing`,"aria-label":`正在回答`,children:[(0,_.jsx)(`i`,{}),(0,_.jsx)(`i`,{}),(0,_.jsx)(`i`,{})]}),e.state===`failed`&&(0,_.jsx)(p,{error:!0,children:e.error||`本次回答未完成。`})]})]},e.id)):(0,_.jsxs)(`div`,{className:`assistant-empty`,children:[(0,_.jsx)(m,{}),(0,_.jsx)(`p`,{children:`有什么项目问题想聊聊?`})]}):!E.data&&E.loading?(0,_.jsx)(`div`,{className:`assistant-empty`,children:(0,_.jsx)(`p`,{role:`status`,children:`加载中…`})}):O===`debug`?Y.map(e=>(0,_.jsx)(S,{item:e,me:a,onReply:!e.archivedAt&&!e.recipients.find(e=>e.userId===a)?.reply?()=>{P(e.id),L(``),H(``)}:void 0},e.id)):X&&(0,_.jsx)(S,{item:X,me:a}),(0,_.jsx)(`div`,{ref:G})]}),(0,_.jsx)(p,{error:!0,children:fe||(A?U:``)}),he&&!A&&(0,_.jsx)(`p`,{className:`assistant-reply-hint`,id:`assistant-reply-hint`,children:O===`debug`?`回复运行提醒:${y(X.body).split(`诊断码`)[0]}。发送后将作为新的后台输入。`:`回应「提百事」的问题。注意:只能发送一条消息,「提百事」收到后会继续工作。如果有新的问题,「提百事」会继续发消息来问你。`}),he?(0,_.jsxs)(`form`,{className:`assistant-composer`,onSubmit:e=>void me(e),children:[(0,_.jsx)(`textarea`,{value:I,onChange:e=>L(e.target.value),"aria-label":A?`向提百事提问`:`回复消息`,"aria-describedby":A?void 0:`assistant-reply-hint`,placeholder:A?`问问提百事…`:`回复…`,rows:2,onKeyDown:e=>{e.key===`Enter`&&!e.shiftKey&&!e.nativeEvent.isComposing&&(e.preventDefault(),e.currentTarget.form?.requestSubmit())}}),(0,_.jsx)(`button`,{className:`primary assistant-send`,type:`submit`,disabled:R||ge||!I.trim(),"aria-label":`发送`,children:(0,_.jsx)(o,{name:`send`})})]}):O!==`debug`&&X&&(0,_.jsxs)(`div`,{className:`assistant-archived`,children:[(0,_.jsx)(o,{name:`archive`}),`已归档`]})]})]})}function S({item:e,me:t,onReply:n}){return(0,_.jsxs)(`div`,{"data-testid":`outbox-thread-${e.id}`,children:[(0,_.jsxs)(b,{author:e.box===`debug`?`运行提醒`:`提百事`,time:e.createdAt,children:[(0,_.jsx)(`div`,{className:`markdown`,children:(0,_.jsx)(h,{children:e.body})}),n&&(0,_.jsx)(`button`,{type:`button`,className:`assistant-debug-reply`,onClick:n,children:`回复`})]}),[...e.recipients].filter(e=>e.reply).sort((e,t)=>e.reply.createdAt.localeCompare(t.reply.createdAt)).map(e=>(0,_.jsx)(b,{mine:e.userId===t,author:e.userId,time:e.reply.createdAt,children:(0,_.jsx)(`div`,{className:`markdown`,children:(0,_.jsx)(h,{children:e.reply.body})})},e.userId))]})}export{x as Assistant};
@@ -0,0 +1 @@
1
+ import{$ as e,D as t,E as n,Q as r,S as i,T as a,_ as o,b as s,f as c,g as l,j as u,k as d,l as f,m as p,p as m,v as h,w as g,x as _}from"./index-BwEl1PIa.js";import{t as v}from"./project-links-XbF78Bal.js";import"./file-links-GfCXWkEh.js";var y=r(),b=d(),x=[{status:`planned`,label:`计划`},{status:`in_progress`,label:`进行中`},{status:`in_review`,label:`待验收`},{status:`completed`,label:`已完成`},{status:null,label:`未明确`}];function S({members:e,project:r}){let{request:a,projectId:o}=f(),s=(0,y.useCallback)(e=>a(`tasks`,c,{signal:e}),[a]),l=n(s,3e3,t(o,`tasks`)),[u,d]=(0,y.useState)(),m=l.data,h=new Map(e.map(e=>[e.id,e.displayName||e.id]));return(0,b.jsxs)(`div`,{className:`task-board`,children:[(0,b.jsx)(i,{title:r?.projectName.trim()?`${r.projectName.trim()}|工作看板`:`工作看板`,description:r?.description.trim()||``}),(0,b.jsx)(_,{error:!0,children:l.error}),(0,b.jsx)(`section`,{className:`task-board-lanes`,"aria-label":`任务进度`,"data-testid":`progress-board`,children:x.filter(e=>e.status!==null||m?.tasks.some(e=>e.status===null)).map(e=>{let t=m?.tasks.filter(t=>t.status===e.status)??[];return(0,b.jsxs)(`section`,{className:`task-lane`,"aria-label":e.label,"data-stage":e.status??`unknown`,children:[(0,b.jsxs)(`h2`,{children:[(0,b.jsx)(`span`,{className:`lane-dot`}),e.label,(0,b.jsx)(p,{children:m?t.length:`—`})]}),(0,b.jsx)(`div`,{className:`task-lane-content`,children:t.length?t.map(e=>(0,b.jsx)(C,{task:e,names:h,onEdit:()=>d(e),onSaved:()=>void l.reload()},e.id)):(0,b.jsx)(`p`,{className:`task-lane-empty`,children:l.error&&!m?`读取失败`:m?`暂无任务`:`读取中…`})})]},e.label)})}),u&&(0,b.jsx)(T,{task:u,onClose:()=>d(void 0),onSaved:()=>{d(void 0),l.reload()}},u.id)]})}function C({task:t,names:n,onEdit:r,onSaved:i}){let{projectId:s,request:c}=f(),l=a(),[d,p]=(0,y.useState)(!1),[x,S]=(0,y.useState)(``);async function C(){if(!d){p(!0),S(``);try{await c(`tasks/${t.id}/correction`,m,{method:`PATCH`,signal:l,body:{needsConfirmation:!1,expectedRevision:t.revision}}),l.aborted||i()}catch(e){l.aborted||S(u(e))}finally{p(!1)}}}return(0,b.jsxs)(`details`,{className:`task-card`,"data-testid":`task-card`,"data-task-id":t.id,"data-owner":t.owner,"data-status":t.status??`unknown`,children:[(0,b.jsxs)(`summary`,{className:`task-card-heading`,"data-testid":`task-toggle`,children:[(0,b.jsx)(`h3`,{children:t.title}),(0,b.jsxs)(`span`,{className:`task-card-meta`,children:[(0,b.jsx)(`small`,{children:n.get(t.owner)??t.owner}),t.needsConfirmation&&(0,b.jsxs)(`span`,{className:`task-confirmation`,"data-testid":`task-confirmation`,children:[(0,b.jsx)(o,{name:`attention`,size:`small`}),`需要确认`]})]})]}),(0,b.jsx)(h,{icon:`edit`,className:`task-card-edit`,label:`纠正任务:${t.title}`,"data-testid":`task-correct`,disabled:d,onClick:r}),(0,b.jsxs)(`div`,{className:`task-card-details`,children:[t.corrected&&!t.needsConfirmation&&(0,b.jsx)(`small`,{children:`已确认`}),t.needsReview&&(0,b.jsx)(`p`,{children:`本次整理未能明确对应,请核对来源。`}),(0,b.jsx)(`h4`,{children:`目标`}),(0,b.jsx)(`p`,{children:t.goal?(0,b.jsx)(w,{value:t.goal,names:n}):`目标未明确`}),(0,b.jsx)(`h4`,{children:`当前进展`}),(0,b.jsx)(`p`,{className:`task-progress`,children:(0,b.jsx)(w,{value:t.progress,names:n})}),(0,b.jsx)(`div`,{className:`task-card-sources`,children:t.sources.map(n=>(0,b.jsxs)(`a`,{"data-testid":`task-source`,href:e(n.kind===`material`?`/projects/${s}/materials?id=${n.materialId}&revision=${n.revision}`:v(s,t.owner,n.path)),children:[(0,b.jsx)(o,{name:`file`,size:`small`}),(0,b.jsx)(`span`,{children:n.path})]},n.path))}),t.syncedAt&&(0,b.jsxs)(`small`,{children:[`资料同步于 `,(0,b.jsx)(g,{value:t.syncedAt})]}),t.needsConfirmation&&(0,b.jsxs)(`div`,{className:`task-card-confirm`,children:[(0,b.jsx)(_,{error:!0,children:x}),(0,b.jsx)(`button`,{className:`primary`,"data-testid":`task-confirm-save`,disabled:d,onClick:()=>void C(),children:d?`正在保存…`:`保存`})]})]})]})}function w({value:e,names:t}){return e.split(/(@[a-z][a-z0-9_-]*)/gi).map((e,n)=>e.startsWith(`@`)&&t.has(e.slice(1))?(0,b.jsx)(`mark`,{className:`task-mention`,children:e},n):e)}function T({task:e,onClose:t,onSaved:n}){let{request:r}=f(),i=a(),[o,c]=(0,y.useState)(e.title),[d,p]=(0,y.useState)(e.status??``),[h,g]=(0,y.useState)(e.goal??``),[v,S]=(0,y.useState)(e.progress),[C,w]=(0,y.useState)(!1),[T,E]=(0,y.useState)(``),D={...o===e.title?{}:{title:o},...d===(e.status??``)?{}:{status:d||null},...h===(e.goal??``)?{}:{goal:h||null},...v===e.progress?{}:{progress:v},...e.needsConfirmation?{needsConfirmation:!1}:{}};async function O(t=!1){if(!(C||!t&&!Object.keys(D).length)){w(!0),E(``);try{await r(`tasks/${e.id}/correction`,m,{method:t?`DELETE`:`PATCH`,signal:i,...t?{}:{body:{...D,expectedRevision:e.revision}}}),i.aborted||n()}catch(e){i.aborted||E(u(e))}finally{w(!1)}}}return(0,b.jsx)(s,{id:`task-correction`,title:`纠正任务`,onClose:t,children:(0,b.jsxs)(`form`,{className:`stack`,"aria-busy":C,onSubmit:e=>{e.preventDefault(),O()},children:[(0,b.jsx)(l,{id:`task-title`,label:`标题`,children:(0,b.jsx)(`input`,{value:o,required:!0,onChange:e=>c(e.target.value)})}),(0,b.jsxs)(`fieldset`,{className:`task-status-field`,disabled:C,children:[(0,b.jsx)(`legend`,{children:`状态`}),(0,b.jsx)(`div`,{className:`task-status-options`,"data-testid":`task-status`,children:x.filter(e=>e.status!==null).map(e=>(0,b.jsxs)(`label`,{className:`task-status-choice`,children:[(0,b.jsx)(`input`,{type:`radio`,name:`task-status`,value:e.status,checked:d===e.status,onChange:()=>p(e.status)}),(0,b.jsx)(`span`,{children:e.label})]},e.status))})]}),(0,b.jsx)(l,{id:`task-goal`,label:`目标`,children:(0,b.jsx)(`textarea`,{value:h,onChange:e=>g(e.target.value)})}),(0,b.jsx)(l,{id:`task-progress`,label:`当前进展`,children:(0,b.jsx)(`textarea`,{value:v,onChange:e=>S(e.target.value)})}),(0,b.jsx)(_,{error:!0,children:T}),(0,b.jsxs)(`div`,{className:`row wrap`,children:[(0,b.jsx)(`button`,{type:`submit`,className:`primary`,disabled:C||!Object.keys(D).length,"data-testid":`task-correction-save`,children:`保存`}),e.corrected&&e.jobId&&(0,b.jsx)(`button`,{type:`button`,disabled:C,"data-testid":`task-correction-reset`,onClick:()=>void O(!0),children:`恢复自动结果`})]})]})})}function E({members:e,config:t}){return(0,b.jsx)(S,{members:e,project:t})}export{E as Dashboard};
@@ -0,0 +1 @@
1
+ import{$ as e,A as t,C as n,D as r,E as i,I as a,P as o,Q as s,_ as c,c as l,h as u,k as d,l as f,o as p,s as m,v as h,x as g}from"./index-BwEl1PIa.js";import{t as _}from"./Markdown-D3cU0ani.js";import{t as v}from"./project-links-XbF78Bal.js";import{t as y}from"./file-links-GfCXWkEh.js";import{n as b,t as x}from"./WorkspaceTree-DeAA1QtV.js";var S=s(),C=d();function w(e,t){let n=t.split(`/`).slice(0,-1);return n.map((t,r)=>b(e,n.slice(0,r+1).join(`/`))).concat(b(e,``))}function T({members:n,me:r,onRefresh:s}){let{api:c,projectId:d}=f(),[_,T]=(0,S.useState)(()=>{let e=new URLSearchParams(location.search),t=e.get(`owner`),r=a.safeParse(e.get(`path`));return t&&(t===`_project`||n.some(e=>e.id===t))&&r.success&&!m(r.data)?{owner:t,path:r.data}:void 0}),[D,O]=(0,S.useState)(()=>new Set(_?w(_.owner,_.path):[b(r,``)])),[k,A]=(0,S.useState)(()=>_?{..._,kind:`file`}:void 0),[j,M]=(0,S.useState)(0),[N,P]=(0,S.useState)(()=>{let e=new URLSearchParams(location.search);return!_&&(e.has(`owner`)||e.has(`path`))?`文件链接不完整或目标已不可用。`:``}),F=(0,S.useCallback)(async e=>{if(_)try{return{owner:_.owner,...await c.file(_.owner,_.path,void 0,e)}}catch(e){throw e instanceof t&&e.code===`FILE_NOT_FOUND`?Error(`找不到这个文件,可能已被删除或移动。`):e}},[_?.owner,_?.path,j]),I=i(F),L=I.data?.owner===_?.owner&&I.data?.file.path===_?.path?I.data:void 0;function R(e,t){let n=t.split(`/`).filter(Boolean);O(t=>{let r=new Set(t);for(let t=0;t<=n.length;t++)r.add(b(e,n.slice(0,t).join(`/`)));return r})}function z(t,n){P(``),R(t,n.split(`/`).slice(0,-1).join(`/`)),T({owner:t,path:n}),A({owner:t,path:n,kind:`file`}),history.replaceState(null,``,e(v(d,t,n)))}function B(e){if(!_)return!1;let t=y(_.owner===`_project`?_.path:`${_.owner}/${_.path}`,e);if(!t)return!/^[a-z][a-z0-9+.-]*:/i.test(e)&&!e.startsWith(`//`)&&(P(`该链接超出工作区,请在原仓库查看。`),!0);if(m(t.path))return P(`配置文件不在文件浏览中显示。`),!0;let[r,...i]=t.path.split(`/`),a=n.some(e=>e.id===r),o=a?r:p,s=a?i.join(`/`):t.path;return P(``),t.directory?(R(o,s),A({owner:o,path:s,kind:`directory`})):o===_.owner&&s===_.path?t.anchor&&[...document.querySelectorAll(`.markdown h1,.markdown h2,.markdown h3,.markdown h4`)].find(e=>e.textContent?.trim().toLowerCase().replace(/\s+/g,`-`)===t.anchor.toLowerCase())?.scrollIntoView({block:`center`}):z(o,s),!0}return(0,C.jsxs)(`div`,{className:`split-layout file-explorer`,"data-testid":`file-browser`,children:[(0,C.jsxs)(`aside`,{className:`file-tree-pane`,"aria-label":`文件资源管理器`,children:[(0,C.jsx)(l,{title:`工作区`,icon:`files`,children:(0,C.jsx)(h,{icon:`refresh`,label:`刷新文件`,"data-testid":`files-refresh`,onClick:()=>{P(``),M(e=>e+1),s()}})}),(0,C.jsx)(x,{members:n,expanded:D,selected:k,revealed:!I.loading&&!I.error&&L?{owner:L.owner,path:L.file.path,file:L.file}:void 0,onSelect:z,onToggle:(e,t)=>{A({owner:e,path:t,kind:`directory`}),O(n=>{let r=new Set(n),i=b(e,t);return r.has(i)?r.delete(i):r.add(i),r})}},j)]}),(0,C.jsx)(`section`,{className:`file-detail`,"data-testid":`file-preview`,"data-owner-id":_?.owner,"data-file-path":_?.path,"aria-label":o.filePreview,children:_?(0,C.jsxs)(C.Fragment,{children:[(0,C.jsx)(g,{error:!0,children:N||!I.loading&&I.error}),I.error&&(0,C.jsx)(`button`,{className:`file-entry-retry`,"data-testid":`files-retry`,onClick:()=>void I.reload(),children:o.retry}),I.loading?(0,C.jsx)(`p`,{className:`preview-body`,role:`status`,children:o.loading}):!I.error&&L&&(0,C.jsx)(E,{owner:L.owner,file:L.file,onLink:B},`${L.owner}:${L.file.path}:${L.file.sha256}`)]}):N?(0,C.jsx)(g,{error:!0,children:N}):(0,C.jsx)(u,{mascot:!0,title:`从一份资料开始`,description:o.pickFile})})]})}function E({owner:e,file:t,onLink:a}){let{readTextBlob:s,blobUrl:l,projectId:u}=f(),[d,p]=(0,S.useState)(!1),m=t.size>524288,v=/\.(md|markdown)$/i.test(t.path),y=(0,S.useCallback)(e=>m?Promise.resolve(void 0):s(t,e),[t.sha256,t.size,m]),b=i(y,!1,r(u,`file-body`,t.sha256));return(0,C.jsxs)(C.Fragment,{children:[(0,C.jsxs)(`header`,{className:`file-detail-header`,children:[(0,C.jsxs)(`span`,{className:`file-detail-path`,title:`${e===`_project`?`workspaces`:e}/${t.path}`,children:[(0,C.jsxs)(`span`,{children:[e===`_project`?`workspaces`:e,` / `]}),t.path]}),(0,C.jsxs)(n,{label:`文件操作`,children:[v&&(0,C.jsx)(h,{icon:d?`preview`:`code`,label:d?`切换为预览`:`切换为原文`,"data-testid":`file-toggle-raw`,"aria-pressed":d,onClick:()=>p(!d)}),(0,C.jsx)(`a`,{className:`icon-button`,"data-testid":`file-download`,"aria-label":o.download,title:o.download,href:l(t.sha256),download:t.path.split(`/`).at(-1),children:(0,C.jsx)(c,{name:`download`})})]})]}),m?(0,C.jsx)(`div`,{className:`empty`,children:(0,C.jsx)(`p`,{children:o.previewLarge})}):b.error?(0,C.jsxs)(`div`,{className:`preview-body`,children:[(0,C.jsx)(g,{error:!0,children:b.error}),(0,C.jsx)(`button`,{"data-testid":`file-preview-retry`,onClick:()=>void b.reload(),children:o.retry})]}):b.loading?(0,C.jsx)(`p`,{className:`preview-body`,role:`status`,children:o.loading}):(0,C.jsx)(`div`,{className:`preview-body`,children:v&&!d?(0,C.jsx)(`article`,{className:`markdown`,"data-testid":`file-content`,"data-format":`markdown`,children:(0,C.jsx)(_,{onLink:a,children:b.data??``})}):(0,C.jsx)(`pre`,{className:`raw`,"data-testid":`file-content`,"data-format":`text`,children:b.data})})]})}export{T as Files};