@researai/deepscientist 1.5.14 → 1.5.16

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 (225) hide show
  1. package/README.md +336 -90
  2. package/assets/branding/logo-raster.png +0 -0
  3. package/bin/ds.js +816 -131
  4. package/docs/en/00_QUICK_START.md +36 -15
  5. package/docs/en/01_SETTINGS_REFERENCE.md +53 -4
  6. package/docs/en/02_START_RESEARCH_GUIDE.md +7 -0
  7. package/docs/en/03_QQ_CONNECTOR_GUIDE.md +19 -0
  8. package/docs/en/05_TUI_GUIDE.md +6 -0
  9. package/docs/en/06_RUNTIME_AND_CANVAS.md +4 -3
  10. package/docs/en/09_DOCTOR.md +11 -5
  11. package/docs/en/10_WEIXIN_CONNECTOR_GUIDE.md +20 -0
  12. package/docs/en/14_PROMPT_SKILLS_AND_MCP_GUIDE.md +65 -13
  13. package/docs/en/15_CODEX_PROVIDER_SETUP.md +25 -8
  14. package/docs/en/16_TELEGRAM_CONNECTOR_GUIDE.md +134 -0
  15. package/docs/en/17_WHATSAPP_CONNECTOR_GUIDE.md +126 -0
  16. package/docs/en/18_FEISHU_CONNECTOR_GUIDE.md +136 -0
  17. package/docs/en/19_EXTERNAL_CONTROLLER_GUIDE.md +226 -0
  18. package/docs/en/19_LOCAL_BROWSER_AUTH.md +70 -0
  19. package/docs/en/20_WORKSPACE_MODES_GUIDE.md +250 -0
  20. package/docs/en/README.md +24 -0
  21. package/docs/zh/00_QUICK_START.md +36 -15
  22. package/docs/zh/01_SETTINGS_REFERENCE.md +53 -4
  23. package/docs/zh/02_START_RESEARCH_GUIDE.md +7 -0
  24. package/docs/zh/03_QQ_CONNECTOR_GUIDE.md +19 -0
  25. package/docs/zh/05_TUI_GUIDE.md +6 -0
  26. package/docs/zh/09_DOCTOR.md +11 -5
  27. package/docs/zh/10_WEIXIN_CONNECTOR_GUIDE.md +20 -0
  28. package/docs/zh/14_PROMPT_SKILLS_AND_MCP_GUIDE.md +65 -13
  29. package/docs/zh/15_CODEX_PROVIDER_SETUP.md +25 -8
  30. package/docs/zh/16_TELEGRAM_CONNECTOR_GUIDE.md +134 -0
  31. package/docs/zh/17_WHATSAPP_CONNECTOR_GUIDE.md +126 -0
  32. package/docs/zh/18_FEISHU_CONNECTOR_GUIDE.md +136 -0
  33. package/docs/zh/19_EXTERNAL_CONTROLLER_GUIDE.md +226 -0
  34. package/docs/zh/19_LOCAL_BROWSER_AUTH.md +68 -0
  35. package/docs/zh/20_WORKSPACE_MODES_GUIDE.md +251 -0
  36. package/docs/zh/README.md +24 -0
  37. package/install.sh +2 -0
  38. package/package.json +1 -1
  39. package/pyproject.toml +1 -1
  40. package/src/deepscientist/__init__.py +1 -1
  41. package/src/deepscientist/acp/envelope.py +6 -0
  42. package/src/deepscientist/artifact/charts.py +567 -0
  43. package/src/deepscientist/artifact/guidance.py +50 -10
  44. package/src/deepscientist/artifact/metrics.py +228 -5
  45. package/src/deepscientist/artifact/schemas.py +3 -0
  46. package/src/deepscientist/artifact/service.py +4276 -308
  47. package/src/deepscientist/bash_exec/models.py +23 -0
  48. package/src/deepscientist/bash_exec/monitor.py +147 -67
  49. package/src/deepscientist/bash_exec/runtime.py +218 -156
  50. package/src/deepscientist/bash_exec/service.py +309 -69
  51. package/src/deepscientist/bash_exec/shells.py +87 -0
  52. package/src/deepscientist/bridges/connectors.py +51 -2
  53. package/src/deepscientist/cli.py +115 -19
  54. package/src/deepscientist/codex_cli_compat.py +232 -0
  55. package/src/deepscientist/config/models.py +8 -4
  56. package/src/deepscientist/config/service.py +38 -11
  57. package/src/deepscientist/connector/weixin_support.py +122 -1
  58. package/src/deepscientist/daemon/api/handlers.py +199 -9
  59. package/src/deepscientist/daemon/api/router.py +5 -0
  60. package/src/deepscientist/daemon/app.py +1458 -289
  61. package/src/deepscientist/doctor.py +51 -0
  62. package/src/deepscientist/file_lock.py +48 -0
  63. package/src/deepscientist/gitops/__init__.py +10 -1
  64. package/src/deepscientist/gitops/diff.py +296 -1
  65. package/src/deepscientist/gitops/service.py +4 -1
  66. package/src/deepscientist/mcp/server.py +212 -5
  67. package/src/deepscientist/process_control.py +161 -0
  68. package/src/deepscientist/prompts/builder.py +501 -453
  69. package/src/deepscientist/quest/layout.py +15 -2
  70. package/src/deepscientist/quest/service.py +2539 -195
  71. package/src/deepscientist/quest/stage_views.py +177 -1
  72. package/src/deepscientist/runners/base.py +2 -0
  73. package/src/deepscientist/runners/codex.py +169 -31
  74. package/src/deepscientist/runners/runtime_overrides.py +17 -1
  75. package/src/deepscientist/skills/__init__.py +2 -2
  76. package/src/deepscientist/skills/installer.py +196 -5
  77. package/src/deepscientist/skills/registry.py +66 -0
  78. package/src/prompts/connectors/qq.md +18 -8
  79. package/src/prompts/connectors/weixin.md +16 -6
  80. package/src/prompts/contracts/shared_interaction.md +24 -4
  81. package/src/prompts/system.md +921 -72
  82. package/src/prompts/system_copilot.md +43 -0
  83. package/src/skills/analysis-campaign/SKILL.md +32 -2
  84. package/src/skills/analysis-campaign/references/artifact-orchestration.md +1 -1
  85. package/src/skills/analysis-campaign/references/writing-facing-slice-examples.md +65 -0
  86. package/src/skills/baseline/SKILL.md +10 -0
  87. package/src/skills/decision/SKILL.md +27 -2
  88. package/src/skills/experiment/SKILL.md +16 -2
  89. package/src/skills/figure-polish/SKILL.md +1 -0
  90. package/src/skills/finalize/SKILL.md +19 -0
  91. package/src/skills/idea/SKILL.md +79 -0
  92. package/src/skills/idea/references/idea-generation-playbook.md +100 -0
  93. package/src/skills/idea/references/outline-seeding-example.md +60 -0
  94. package/src/skills/intake-audit/SKILL.md +9 -1
  95. package/src/skills/mentor/SKILL.md +217 -0
  96. package/src/skills/mentor/references/correction-rules.md +210 -0
  97. package/src/skills/mentor/references/knowledge-profile.md +91 -0
  98. package/src/skills/mentor/references/persona-profile.md +138 -0
  99. package/src/skills/mentor/references/taste-profile.md +128 -0
  100. package/src/skills/mentor/references/thought-style-profile.md +138 -0
  101. package/src/skills/mentor/references/work-profile.md +289 -0
  102. package/src/skills/mentor/references/workflow-profile.md +240 -0
  103. package/src/skills/optimize/SKILL.md +1645 -0
  104. package/src/skills/rebuttal/SKILL.md +3 -1
  105. package/src/skills/review/SKILL.md +3 -1
  106. package/src/skills/scout/SKILL.md +8 -0
  107. package/src/skills/write/SKILL.md +81 -12
  108. package/src/skills/write/references/outline-evidence-contract-example.md +107 -0
  109. package/src/tui/dist/app/AppContainer.js +22 -11
  110. package/src/tui/dist/index.js +4 -1
  111. package/src/tui/dist/lib/api.js +33 -3
  112. package/src/tui/package.json +1 -1
  113. package/src/ui/dist/assets/AiManusChatView-COFACy7V.js +204 -0
  114. package/src/ui/dist/assets/AnalysisPlugin-DnSm0GZn.js +1 -0
  115. package/src/ui/dist/assets/CliPlugin-CvwCmDQ5.js +109 -0
  116. package/src/ui/dist/assets/CodeEditorPlugin-cOqSa0xq.js +2 -0
  117. package/src/ui/dist/assets/CodeViewerPlugin-itb0tltR.js +270 -0
  118. package/src/ui/dist/assets/DocViewerPlugin-DqKkiCI6.js +7 -0
  119. package/src/ui/dist/assets/GitCommitViewerPlugin-DVgNHBCS.js +1 -0
  120. package/src/ui/dist/assets/GitDiffViewerPlugin-DxL2ezFG.js +6 -0
  121. package/src/ui/dist/assets/GitSnapshotViewer-B_RQm1YZ.js +30 -0
  122. package/src/ui/dist/assets/ImageViewerPlugin-tHqlXY3n.js +26 -0
  123. package/src/ui/dist/assets/LabCopilotPanel-ClMbq5Yu.js +14 -0
  124. package/src/ui/dist/assets/LabPlugin-L_SuE8ow.js +22 -0
  125. package/src/ui/dist/assets/LatexPlugin-B495DTXC.js +25 -0
  126. package/src/ui/dist/assets/MarkdownViewerPlugin-DG28-61B.js +128 -0
  127. package/src/ui/dist/assets/MarketplacePlugin-BiOGT-Kj.js +13 -0
  128. package/src/ui/dist/assets/{NotebookEditor-CccQYZjX.css → NotebookEditor-BHH8rdGj.css} +1 -1
  129. package/src/ui/dist/assets/NotebookEditor-BOr3x3Ej.css +1 -0
  130. package/src/ui/dist/assets/NotebookEditor-C-4Kt1p9.js +81 -0
  131. package/src/ui/dist/assets/NotebookEditor-CVsj8h_T.js +361 -0
  132. package/src/ui/dist/assets/PdfLoader-CASDQmxJ.js +16 -0
  133. package/src/ui/dist/assets/PdfLoader-Cy5jtWrr.css +1 -0
  134. package/src/ui/dist/assets/PdfMarkdownPlugin-BFhwoKsY.js +1 -0
  135. package/src/ui/dist/assets/PdfViewerPlugin-DcOzU9vd.js +17 -0
  136. package/src/ui/dist/assets/PdfViewerPlugin-nwwE-fjJ.css +1 -0
  137. package/src/ui/dist/assets/SearchPlugin-CHj7M58O.js +16 -0
  138. package/src/ui/dist/assets/SearchPlugin-DA4en4hK.css +1 -0
  139. package/src/ui/dist/assets/TextViewerPlugin-CB4DYfWO.js +54 -0
  140. package/src/ui/dist/assets/VNCViewer-CjlbyCB3.js +11 -0
  141. package/src/ui/dist/assets/bot-CFkZY-JP.js +6 -0
  142. package/src/ui/dist/assets/browser-CTB2jwNe.js +8 -0
  143. package/src/ui/dist/assets/chevron-up-Dq5ofbht.js +6 -0
  144. package/src/ui/dist/assets/code-DLC6G24T.js +6 -0
  145. package/src/ui/dist/assets/file-content-Dv4LoZec.js +1 -0
  146. package/src/ui/dist/assets/file-diff-panel-Denq-lC3.js +1 -0
  147. package/src/ui/dist/assets/file-jump-queue-DA-SdG__.js +1 -0
  148. package/src/ui/dist/assets/file-socket-Cu4Qln7Y.js +1 -0
  149. package/src/ui/dist/assets/git-commit-horizontal-BUh6G52n.js +6 -0
  150. package/src/ui/dist/assets/image-B9HUUddG.js +6 -0
  151. package/src/ui/dist/assets/index-B2B1sg-M.js +1 -0
  152. package/src/ui/dist/assets/index-Cgla8biy.css +33 -0
  153. package/src/ui/dist/assets/index-DRyx7vAc.js +1 -0
  154. package/src/ui/dist/assets/index-Gbl53BNp.js +2496 -0
  155. package/src/ui/dist/assets/index-wQ7RIIRd.js +11 -0
  156. package/src/ui/dist/assets/monaco-CiHMMNH_.js +1 -0
  157. package/src/ui/dist/assets/pdf-effect-queue-ZtnHFCAi.js +6 -0
  158. package/src/ui/dist/assets/plugin-monaco-C8UgLomw.js +19 -0
  159. package/src/ui/dist/assets/plugin-notebook-HbW2K-1c.js +169 -0
  160. package/src/ui/dist/assets/plugin-pdf-CR8hgQBV.js +357 -0
  161. package/src/ui/dist/assets/plugin-terminal-MXFIPun8.js +227 -0
  162. package/src/ui/dist/assets/popover-DL6h35vr.js +1 -0
  163. package/src/ui/dist/assets/project-sync-CsX08Qno.js +1 -0
  164. package/src/ui/dist/assets/select-DvmXt1yY.js +11 -0
  165. package/src/ui/dist/assets/sigma-7jpXazui.js +6 -0
  166. package/src/ui/dist/assets/trash-xA7kFt8i.js +11 -0
  167. package/src/ui/dist/assets/useCliAccess-DsMwDjOp.js +1 -0
  168. package/src/ui/dist/assets/useFileDiffOverlay-FuhcnKiw.js +1 -0
  169. package/src/ui/dist/assets/wrap-text-CwMn-iqb.js +11 -0
  170. package/src/ui/dist/assets/zoom-out-R-GWEhzS.js +11 -0
  171. package/src/ui/dist/index.html +5 -2
  172. package/src/ui/dist/assets/AiManusChatView-DaF9Nge_.js +0 -26597
  173. package/src/ui/dist/assets/AnalysisPlugin-BSVx6dXE.js +0 -123
  174. package/src/ui/dist/assets/CliPlugin-C9gzJX41.js +0 -5905
  175. package/src/ui/dist/assets/CodeEditorPlugin-DU9G0Tox.js +0 -427
  176. package/src/ui/dist/assets/CodeViewerPlugin-DoX_fI9l.js +0 -905
  177. package/src/ui/dist/assets/DocViewerPlugin-C4FWIXuU.js +0 -278
  178. package/src/ui/dist/assets/GitDiffViewerPlugin-BgfFMgtf.js +0 -2661
  179. package/src/ui/dist/assets/ImageViewerPlugin-tcPkfY_x.js +0 -500
  180. package/src/ui/dist/assets/LabCopilotPanel-_dKV60Bf.js +0 -4104
  181. package/src/ui/dist/assets/LabPlugin-Bje0ayoC.js +0 -2677
  182. package/src/ui/dist/assets/LatexPlugin-CVsBzAln.js +0 -1792
  183. package/src/ui/dist/assets/MarkdownViewerPlugin-xjmrqv_8.js +0 -308
  184. package/src/ui/dist/assets/MarketplacePlugin-mMM2A8wP.js +0 -413
  185. package/src/ui/dist/assets/NotebookEditor-3kVDSOBo.js +0 -4214
  186. package/src/ui/dist/assets/NotebookEditor-C3VQ7ylN.css +0 -1405
  187. package/src/ui/dist/assets/NotebookEditor-SoJ8X-MO.js +0 -84873
  188. package/src/ui/dist/assets/PdfLoader-C-Y707R3.css +0 -49
  189. package/src/ui/dist/assets/PdfLoader-DElVuHl9.js +0 -25468
  190. package/src/ui/dist/assets/PdfMarkdownPlugin-Bq88XT4G.js +0 -409
  191. package/src/ui/dist/assets/PdfViewerPlugin-CsCXMo9S.js +0 -3095
  192. package/src/ui/dist/assets/PdfViewerPlugin-DQ11QcSf.css +0 -3627
  193. package/src/ui/dist/assets/SearchPlugin-DDMrGDkh.css +0 -379
  194. package/src/ui/dist/assets/SearchPlugin-oUPvy19k.js +0 -741
  195. package/src/ui/dist/assets/TextViewerPlugin-CRkT9yNy.js +0 -472
  196. package/src/ui/dist/assets/VNCViewer-BgbuvWhR.js +0 -18821
  197. package/src/ui/dist/assets/awareness-C0NPR2Dj.js +0 -292
  198. package/src/ui/dist/assets/bot-v_RASACv.js +0 -21
  199. package/src/ui/dist/assets/browser-BAcuE0Xj.js +0 -2895
  200. package/src/ui/dist/assets/code-5hC9d0VH.js +0 -17
  201. package/src/ui/dist/assets/file-content-D1PxfOrp.js +0 -377
  202. package/src/ui/dist/assets/file-diff-panel-DG1oT_Hj.js +0 -92
  203. package/src/ui/dist/assets/file-jump-queue-r5XKgJEV.js +0 -16
  204. package/src/ui/dist/assets/file-socket-BmdFYQlk.js +0 -58
  205. package/src/ui/dist/assets/function-B5QZkkHC.js +0 -1895
  206. package/src/ui/dist/assets/image-Dqe2X2tW.js +0 -18
  207. package/src/ui/dist/assets/index-BQG-1s2o.css +0 -12553
  208. package/src/ui/dist/assets/index-DVsMKK_y.js +0 -25
  209. package/src/ui/dist/assets/index-Duvz8Ip0.js +0 -159
  210. package/src/ui/dist/assets/index-Nt9hS4ck.js +0 -244829
  211. package/src/ui/dist/assets/index-RDlNXXx1.js +0 -120
  212. package/src/ui/dist/assets/monaco-DIXge1CP.js +0 -623
  213. package/src/ui/dist/assets/pdf-effect-queue-BBTTQaO-.js +0 -47
  214. package/src/ui/dist/assets/pdf_viewer-e0g1is2C.js +0 -8206
  215. package/src/ui/dist/assets/popover-BWlolyxo.js +0 -476
  216. package/src/ui/dist/assets/project-sync-BM5PkFH4.js +0 -297
  217. package/src/ui/dist/assets/select-D4dAtrA8.js +0 -1690
  218. package/src/ui/dist/assets/sigma-CKbE5jJT.js +0 -22
  219. package/src/ui/dist/assets/square-check-big-CZNGMgiB.js +0 -17
  220. package/src/ui/dist/assets/trash-DaB37xAz.js +0 -32
  221. package/src/ui/dist/assets/useCliAccess-C2OmAcWe.js +0 -957
  222. package/src/ui/dist/assets/useFileDiffOverlay-Dowd1Ij4.js +0 -53
  223. package/src/ui/dist/assets/wrap-text-BGjAhAUq.js +0 -35
  224. package/src/ui/dist/assets/yjs-DncrqiZ8.js +0 -11243
  225. package/src/ui/dist/assets/zoom-out-dMZQMXzc.js +0 -34
@@ -1,17 +0,0 @@
1
- import { w as createLucideIcon } from './index-Nt9hS4ck.js';
2
-
3
- /**
4
- * @license lucide-react v0.511.0 - ISC
5
- *
6
- * This source code is licensed under the ISC license.
7
- * See the LICENSE file in the root directory of this source tree.
8
- */
9
-
10
-
11
- const __iconNode = [
12
- ["path", { d: "m16 18 6-6-6-6", key: "eg8j8" }],
13
- ["path", { d: "m8 6-6 6 6 6", key: "ppft3o" }]
14
- ];
15
- const Code = createLucideIcon("code", __iconNode);
16
-
17
- export { Code as C };
@@ -1,377 +0,0 @@
1
- import { Q as create, U as updateFileContent, V as getFileContent } from './index-Nt9hS4ck.js';
2
-
3
- function openDb({ dbName, version, storeName }) {
4
- return new Promise((resolve, reject) => {
5
- const request = indexedDB.open(dbName, version);
6
- request.onupgradeneeded = () => {
7
- const db = request.result;
8
- if (!db.objectStoreNames.contains(storeName)) {
9
- db.createObjectStore(storeName);
10
- }
11
- };
12
- request.onsuccess = () => resolve(request.result);
13
- request.onerror = () => reject(request.error ?? new Error("Failed to open IndexedDB"));
14
- });
15
- }
16
- function requestToPromise(request) {
17
- return new Promise((resolve, reject) => {
18
- request.onsuccess = () => resolve(request.result);
19
- request.onerror = () => reject(request.error ?? new Error("IndexedDB request failed"));
20
- });
21
- }
22
- function createIdbStore(options) {
23
- let dbPromise = null;
24
- const getDb = () => {
25
- if (!dbPromise) dbPromise = openDb(options);
26
- return dbPromise;
27
- };
28
- const withStore = async (mode, fn) => {
29
- const db = await getDb();
30
- return await new Promise((resolve, reject) => {
31
- const tx = db.transaction(options.storeName, mode);
32
- const store = tx.objectStore(options.storeName);
33
- Promise.resolve(fn(store)).then((reqOrValue) => {
34
- if (reqOrValue instanceof IDBRequest) {
35
- requestToPromise(reqOrValue).then(resolve).catch(reject);
36
- } else {
37
- resolve(reqOrValue);
38
- }
39
- }).catch(reject);
40
- tx.onabort = () => reject(tx.error ?? new Error("IndexedDB transaction aborted"));
41
- });
42
- };
43
- return {
44
- async get(key) {
45
- return await withStore("readonly", (store) => store.get(key));
46
- },
47
- async set(key, value) {
48
- await withStore("readwrite", (store) => store.put(value, key));
49
- },
50
- async del(key) {
51
- await withStore("readwrite", (store) => store.delete(key));
52
- },
53
- async keys() {
54
- const db = await getDb();
55
- const tx = db.transaction(options.storeName, "readonly");
56
- const store = tx.objectStore(options.storeName);
57
- const keys = await requestToPromise(store.getAllKeys());
58
- return keys.map(String);
59
- }
60
- };
61
- }
62
-
63
- const PERSIST_MAX_BYTES = 1 * 1024 * 1024;
64
- const MEMORY_MAX_BYTES = 20 * 1024 * 1024;
65
- function makeKey(projectId, fileId) {
66
- return `${projectId}:${fileId}`;
67
- }
68
- function getByteSize(text) {
69
- try {
70
- return new TextEncoder().encode(text).byteLength;
71
- } catch {
72
- return text.length;
73
- }
74
- }
75
- function shouldPersist(entry) {
76
- const bytes = entry.sizeBytes ?? getByteSize(entry.content);
77
- return bytes <= PERSIST_MAX_BYTES;
78
- }
79
- const idb = createIdbStore({ dbName: "ds-file-cache", version: 1, storeName: "files" });
80
- const useFileContentStore = create((set, get) => ({
81
- entries: {},
82
- totalBytes: 0,
83
- loadingKeys: {},
84
- getKey: makeKey,
85
- getEntry: (projectId, fileId) => get().entries[makeKey(projectId, fileId)],
86
- ensureLoaded: async ({ projectId, fileId, updatedAt, mimeType, sizeBytes }) => {
87
- const key = makeKey(projectId, fileId);
88
- const existing = get().entries[key];
89
- const setLoading = (loading) => set((s) => ({ loadingKeys: { ...s.loadingKeys, [key]: loading } }));
90
- const upsert = (incoming) => {
91
- set((s) => {
92
- const prev = s.entries[key];
93
- const prevBytes = prev ? prev.sizeBytes ?? getByteSize(prev.content) : 0;
94
- const nextBytes = incoming.sizeBytes ?? getByteSize(incoming.content);
95
- return {
96
- entries: { ...s.entries, [key]: { ...incoming, key } },
97
- totalBytes: Math.max(0, s.totalBytes - prevBytes + nextBytes)
98
- };
99
- });
100
- get().evictIfNeeded();
101
- return get().entries[key];
102
- };
103
- if (existing) {
104
- if (existing.isDirty) {
105
- get().touch({ projectId, fileId });
106
- return existing;
107
- }
108
- if (existing.updatedAt && updatedAt && existing.updatedAt !== updatedAt) ; else {
109
- get().touch({ projectId, fileId });
110
- return existing;
111
- }
112
- }
113
- setLoading(true);
114
- try {
115
- const persisted = await idb.get(key);
116
- if (persisted) {
117
- const entry = {
118
- key,
119
- projectId: persisted.projectId,
120
- fileId: persisted.fileId,
121
- mimeType: persisted.mimeType,
122
- sizeBytes: persisted.sizeBytes ?? getByteSize(persisted.content),
123
- updatedAt: persisted.updatedAt,
124
- content: persisted.content,
125
- isDirty: persisted.isDirty,
126
- saveState: "idle",
127
- conflict: void 0,
128
- lastAccessedAt: Date.now(),
129
- lastSavedAt: persisted.lastSavedAt,
130
- saveError: void 0
131
- };
132
- if (updatedAt && entry.updatedAt && entry.updatedAt !== updatedAt && !entry.isDirty) {
133
- } else {
134
- return upsert(entry);
135
- }
136
- }
137
- const text = await getFileContent(fileId);
138
- const bytes = sizeBytes ?? getByteSize(text);
139
- const created = upsert({
140
- projectId,
141
- fileId,
142
- mimeType,
143
- sizeBytes: bytes,
144
- updatedAt,
145
- content: text,
146
- isDirty: false,
147
- saveState: "idle",
148
- saveError: void 0,
149
- conflict: void 0,
150
- lastAccessedAt: Date.now(),
151
- lastSavedAt: void 0
152
- });
153
- if (shouldPersist(created)) {
154
- const persistedEntry = {
155
- v: 1,
156
- projectId,
157
- fileId,
158
- mimeType,
159
- sizeBytes: created.sizeBytes,
160
- updatedAt: created.updatedAt,
161
- content: created.content,
162
- isDirty: created.isDirty,
163
- lastAccessedAt: created.lastAccessedAt,
164
- lastSavedAt: created.lastSavedAt,
165
- conflict: created.conflict
166
- };
167
- await idb.set(key, persistedEntry);
168
- }
169
- return created;
170
- } finally {
171
- setLoading(false);
172
- }
173
- },
174
- reload: async ({ projectId, fileId, updatedAt, mimeType, sizeBytes, ignoreDirty }) => {
175
- const key = makeKey(projectId, fileId);
176
- const existing = get().entries[key];
177
- if (existing?.isDirty && !ignoreDirty) {
178
- get().touch({ projectId, fileId });
179
- return existing;
180
- }
181
- const setLoading = (loading) => set((s) => ({ loadingKeys: { ...s.loadingKeys, [key]: loading } }));
182
- setLoading(true);
183
- try {
184
- const text = await getFileContent(fileId);
185
- const bytes = sizeBytes ?? getByteSize(text);
186
- get().applyServerSnapshot({
187
- projectId,
188
- fileId,
189
- content: text,
190
- updatedAt,
191
- sizeBytes: bytes,
192
- mimeType
193
- });
194
- return get().entries[key];
195
- } finally {
196
- setLoading(false);
197
- }
198
- },
199
- setContent: ({ projectId, fileId, content }) => {
200
- const key = makeKey(projectId, fileId);
201
- const now = Date.now();
202
- set((s) => {
203
- const prev = s.entries[key];
204
- const nextBytes = getByteSize(content);
205
- const prevBytes = prev ? prev.sizeBytes ?? getByteSize(prev.content) : 0;
206
- const next = {
207
- key,
208
- projectId,
209
- fileId,
210
- mimeType: prev?.mimeType,
211
- sizeBytes: nextBytes,
212
- updatedAt: prev?.updatedAt,
213
- content,
214
- isDirty: true,
215
- saveState: prev?.saveState ?? "idle",
216
- saveError: void 0,
217
- conflict: prev?.conflict,
218
- lastAccessedAt: now,
219
- lastSavedAt: prev?.lastSavedAt
220
- };
221
- return {
222
- entries: { ...s.entries, [key]: next },
223
- totalBytes: Math.max(0, s.totalBytes - prevBytes + nextBytes)
224
- };
225
- });
226
- const entry = get().entries[key];
227
- if (entry && shouldPersist(entry)) {
228
- const persistedEntry = {
229
- v: 1,
230
- projectId,
231
- fileId,
232
- mimeType: entry.mimeType,
233
- sizeBytes: entry.sizeBytes,
234
- updatedAt: entry.updatedAt,
235
- content: entry.content,
236
- isDirty: entry.isDirty,
237
- lastAccessedAt: entry.lastAccessedAt,
238
- lastSavedAt: entry.lastSavedAt,
239
- conflict: entry.conflict
240
- };
241
- idb.set(key, persistedEntry).catch(() => {
242
- });
243
- }
244
- },
245
- touch: ({ projectId, fileId }) => {
246
- const key = makeKey(projectId, fileId);
247
- set((s) => {
248
- const entry = s.entries[key];
249
- if (!entry) return s;
250
- return { entries: { ...s.entries, [key]: { ...entry, lastAccessedAt: Date.now() } } };
251
- });
252
- },
253
- save: async ({ projectId, fileId }) => {
254
- const key = makeKey(projectId, fileId);
255
- const entry = get().entries[key];
256
- if (!entry) {
257
- return await get().ensureLoaded({ projectId, fileId });
258
- }
259
- set((s) => ({
260
- entries: {
261
- ...s.entries,
262
- [key]: { ...s.entries[key], saveState: "saving", saveError: void 0 }
263
- }
264
- }));
265
- try {
266
- const result = await updateFileContent(fileId, entry.content);
267
- const updatedAt = result.updated_at;
268
- const next = {
269
- ...get().entries[key],
270
- isDirty: false,
271
- saveState: "idle",
272
- updatedAt,
273
- lastSavedAt: Date.now(),
274
- saveError: void 0,
275
- conflict: void 0
276
- };
277
- set((s) => ({
278
- entries: { ...s.entries, [key]: next }
279
- }));
280
- if (shouldPersist(next)) {
281
- const persistedEntry = {
282
- v: 1,
283
- projectId,
284
- fileId,
285
- mimeType: next.mimeType,
286
- sizeBytes: next.sizeBytes,
287
- updatedAt: next.updatedAt,
288
- content: next.content,
289
- isDirty: next.isDirty,
290
- lastAccessedAt: next.lastAccessedAt,
291
- lastSavedAt: next.lastSavedAt,
292
- conflict: next.conflict
293
- };
294
- await idb.set(key, persistedEntry);
295
- }
296
- return next;
297
- } catch (err) {
298
- const message = err instanceof Error ? err.message : "Save failed";
299
- set((s) => ({
300
- entries: {
301
- ...s.entries,
302
- [key]: { ...s.entries[key], saveState: "error", saveError: message }
303
- }
304
- }));
305
- return get().entries[key];
306
- }
307
- },
308
- applyServerSnapshot: ({ projectId, fileId, content, updatedAt, sizeBytes, mimeType, keepDirty }) => {
309
- const key = makeKey(projectId, fileId);
310
- const now = Date.now();
311
- set((s) => {
312
- const prev = s.entries[key];
313
- const prevBytes = prev ? prev.sizeBytes ?? getByteSize(prev.content) : 0;
314
- const nextBytes = sizeBytes ?? getByteSize(content);
315
- const next = {
316
- key,
317
- projectId,
318
- fileId,
319
- mimeType: mimeType ?? prev?.mimeType,
320
- sizeBytes: nextBytes,
321
- updatedAt: updatedAt ?? prev?.updatedAt,
322
- content,
323
- isDirty: keepDirty ? !!prev?.isDirty : false,
324
- saveState: "idle",
325
- saveError: void 0,
326
- conflict: void 0,
327
- lastAccessedAt: now,
328
- lastSavedAt: keepDirty ? prev?.lastSavedAt : now
329
- };
330
- return {
331
- entries: { ...s.entries, [key]: next },
332
- totalBytes: Math.max(0, s.totalBytes - prevBytes + nextBytes)
333
- };
334
- });
335
- const entry = get().entries[key];
336
- if (entry && shouldPersist(entry)) {
337
- const persistedEntry = {
338
- v: 1,
339
- projectId,
340
- fileId,
341
- mimeType: entry.mimeType,
342
- sizeBytes: entry.sizeBytes,
343
- updatedAt: entry.updatedAt,
344
- content: entry.content,
345
- isDirty: entry.isDirty,
346
- lastAccessedAt: entry.lastAccessedAt,
347
- lastSavedAt: entry.lastSavedAt,
348
- conflict: void 0
349
- };
350
- idb.set(key, persistedEntry).catch(() => {
351
- });
352
- }
353
- },
354
- evictIfNeeded: () => {
355
- const { totalBytes, entries } = get();
356
- if (totalBytes <= MEMORY_MAX_BYTES) return;
357
- const list = Object.values(entries).slice().sort((a, b) => a.lastAccessedAt - b.lastAccessedAt);
358
- let bytes = totalBytes;
359
- const nextEntries = { ...entries };
360
- for (const entry of list) {
361
- if (bytes <= MEMORY_MAX_BYTES) break;
362
- if (entry.isDirty) continue;
363
- const entryBytes = entry.sizeBytes ?? getByteSize(entry.content);
364
- delete nextEntries[entry.key];
365
- bytes -= entryBytes;
366
- }
367
- if (bytes !== totalBytes) {
368
- set({ entries: nextEntries, totalBytes: Math.max(0, bytes) });
369
- }
370
- }
371
- }));
372
- function useFileContentLoading(projectId, fileId) {
373
- const key = projectId && fileId ? makeKey(projectId, fileId) : null;
374
- return useFileContentStore((s) => key ? !!s.loadingKeys[key] : false);
375
- }
376
-
377
- export { useFileContentLoading as a, useFileContentStore as u };
@@ -1,92 +0,0 @@
1
- import { r as reactExports, j as jsxRuntimeExports, X, b as cn } from './index-Nt9hS4ck.js';
2
-
3
- const CHANGE_LABELS = {
4
- create: "Created",
5
- update: "Updated",
6
- delete: "Deleted"
7
- };
8
- function getDiffLineMeta(line) {
9
- const isHunk = line.startsWith("@@");
10
- const isAdd = line.startsWith("+") && !line.startsWith("+++");
11
- const isDel = line.startsWith("-") && !line.startsWith("---");
12
- const isContext = !isHunk && !isAdd && !isDel;
13
- const prefix = isHunk ? "@@" : isAdd ? "+" : isDel ? "-" : " ";
14
- const text = isHunk ? line.slice(2).trimStart() : line.slice(1);
15
- return { isHunk, isAdd, isDel, isContext, prefix, text };
16
- }
17
- function countDiffLines(lines) {
18
- let added = 0;
19
- let removed = 0;
20
- lines.forEach((line) => {
21
- if (line.startsWith("+") && !line.startsWith("+++")) added += 1;
22
- if (line.startsWith("-") && !line.startsWith("---")) removed += 1;
23
- });
24
- return { added, removed };
25
- }
26
- function FileDiffPanel({
27
- diff,
28
- changeType,
29
- title,
30
- subtitle,
31
- compact,
32
- showHeader = true,
33
- onClose,
34
- className
35
- }) {
36
- const counts = reactExports.useMemo(() => countDiffLines(diff.lines), [diff.lines]);
37
- const added = diff.added ?? counts.added;
38
- const removed = diff.removed ?? counts.removed;
39
- const label = changeType ? CHANGE_LABELS[changeType] ?? "Updated" : "Updated";
40
- return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: cn("ds-file-diff-panel", compact && "is-compact", className), children: [
41
- showHeader ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ds-file-diff-header", children: [
42
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ds-file-diff-header-text", children: [
43
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "ds-file-diff-title", children: title ?? "AI Change" }),
44
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ds-file-diff-subtitle", children: [
45
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "ds-file-diff-tag", children: label }),
46
- /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "ds-file-diff-meta", children: [
47
- "+",
48
- added
49
- ] }),
50
- /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "ds-file-diff-meta", children: [
51
- "-",
52
- removed
53
- ] }),
54
- subtitle ? /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "ds-file-diff-muted", children: subtitle }) : null
55
- ] })
56
- ] }),
57
- onClose ? /* @__PURE__ */ jsxRuntimeExports.jsx(
58
- "button",
59
- {
60
- type: "button",
61
- className: "ds-file-diff-close",
62
- onClick: onClose,
63
- "aria-label": "Dismiss diff",
64
- children: /* @__PURE__ */ jsxRuntimeExports.jsx(X, { size: 14 })
65
- }
66
- ) : null
67
- ] }) : null,
68
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "ds-file-diff-body", children: diff.lines.map((line, index) => {
69
- const { isHunk, isAdd, isDel, isContext, prefix, text } = getDiffLineMeta(line);
70
- return /* @__PURE__ */ jsxRuntimeExports.jsxs(
71
- "div",
72
- {
73
- className: cn(
74
- "ds-file-diff-line",
75
- isHunk && "is-hunk",
76
- isAdd && "is-add",
77
- isDel && "is-del",
78
- isContext && "is-context"
79
- ),
80
- children: [
81
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "ds-file-diff-prefix", children: prefix }),
82
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "ds-file-diff-text", children: text })
83
- ]
84
- },
85
- `${prefix}-${index}`
86
- );
87
- }) }),
88
- diff.truncated ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "ds-file-diff-footer", children: "Diff truncated. Open file for full details." }) : null
89
- ] });
90
- }
91
-
92
- export { FileDiffPanel as F };
@@ -1,16 +0,0 @@
1
- const pendingEffects = /* @__PURE__ */ new Map();
2
- function queueFileJumpEffect(effect) {
3
- const fileId = effect.data?.fileId;
4
- if (!fileId) return;
5
- const existing = pendingEffects.get(fileId) ?? [];
6
- existing.push(effect);
7
- pendingEffects.set(fileId, existing);
8
- }
9
- function consumeFileJumpEffects(fileId) {
10
- const existing = pendingEffects.get(fileId);
11
- if (!existing || existing.length === 0) return [];
12
- pendingEffects.delete(fileId);
13
- return existing;
14
- }
15
-
16
- export { consumeFileJumpEffects as c, queueFileJumpEffect as q };
@@ -1,58 +0,0 @@
1
- import { x as supportsSocketIo, y as lookup, z as useAuthStore, D as resolveApiBaseUrl } from './index-Nt9hS4ck.js';
2
-
3
- const getApiBaseUrl = resolveApiBaseUrl;
4
- const SOCKET_CACHE = /* @__PURE__ */ new Map();
5
- function createNoopFileSocket() {
6
- const socket = {
7
- connected: false,
8
- connect: () => socket,
9
- disconnect: () => socket,
10
- on: () => socket,
11
- off: () => socket,
12
- emit: () => true,
13
- emitWithAck: async () => ({ data: void 0 })
14
- };
15
- return socket;
16
- }
17
- function acquireFileSocket() {
18
- if (!supportsSocketIo()) {
19
- return {
20
- socket: createNoopFileSocket(),
21
- release: () => {
22
- }
23
- };
24
- }
25
- const endpoint = getApiBaseUrl();
26
- let entry = SOCKET_CACHE.get(endpoint);
27
- if (!entry) {
28
- const socket = lookup(endpoint, {
29
- path: "/ws/socket.io",
30
- autoConnect: false,
31
- transports: ["websocket", "polling"],
32
- auth: (cb) => {
33
- const token = useAuthStore.getState().accessToken || (typeof window !== "undefined" ? window.localStorage.getItem("ds_access_token") : null);
34
- cb({ token });
35
- }
36
- });
37
- entry = { socket, refCount: 0 };
38
- SOCKET_CACHE.set(endpoint, entry);
39
- }
40
- entry.refCount += 1;
41
- if (!entry.socket.connected) {
42
- entry.socket.connect();
43
- }
44
- return {
45
- socket: entry.socket,
46
- release: () => {
47
- const cur = SOCKET_CACHE.get(endpoint);
48
- if (!cur) return;
49
- cur.refCount -= 1;
50
- if (cur.refCount <= 0) {
51
- cur.socket.disconnect();
52
- SOCKET_CACHE.delete(endpoint);
53
- }
54
- }
55
- };
56
- }
57
-
58
- export { acquireFileSocket as a };