@researai/deepscientist 1.5.15 → 1.5.17

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 (202) hide show
  1. package/README.md +385 -104
  2. package/bin/ds.js +1241 -110
  3. package/docs/en/00_QUICK_START.md +100 -19
  4. package/docs/en/01_SETTINGS_REFERENCE.md +34 -1
  5. package/docs/en/02_START_RESEARCH_GUIDE.md +7 -0
  6. package/docs/en/05_TUI_GUIDE.md +6 -0
  7. package/docs/en/06_RUNTIME_AND_CANVAS.md +4 -3
  8. package/docs/en/09_DOCTOR.md +25 -8
  9. package/docs/en/14_PROMPT_SKILLS_AND_MCP_GUIDE.md +63 -13
  10. package/docs/en/15_CODEX_PROVIDER_SETUP.md +37 -11
  11. package/docs/en/19_EXTERNAL_CONTROLLER_GUIDE.md +226 -0
  12. package/docs/en/19_LOCAL_BROWSER_AUTH.md +70 -0
  13. package/docs/en/20_WORKSPACE_MODES_GUIDE.md +250 -0
  14. package/docs/en/21_LOCAL_MODEL_BACKENDS_GUIDE.md +283 -0
  15. package/docs/en/91_DEVELOPMENT.md +237 -0
  16. package/docs/en/README.md +24 -2
  17. package/docs/zh/00_QUICK_START.md +89 -19
  18. package/docs/zh/01_SETTINGS_REFERENCE.md +34 -1
  19. package/docs/zh/02_START_RESEARCH_GUIDE.md +7 -0
  20. package/docs/zh/05_TUI_GUIDE.md +6 -0
  21. package/docs/zh/09_DOCTOR.md +26 -9
  22. package/docs/zh/14_PROMPT_SKILLS_AND_MCP_GUIDE.md +63 -13
  23. package/docs/zh/15_CODEX_PROVIDER_SETUP.md +37 -11
  24. package/docs/zh/19_EXTERNAL_CONTROLLER_GUIDE.md +226 -0
  25. package/docs/zh/19_LOCAL_BROWSER_AUTH.md +68 -0
  26. package/docs/zh/20_WORKSPACE_MODES_GUIDE.md +251 -0
  27. package/docs/zh/21_LOCAL_MODEL_BACKENDS_GUIDE.md +281 -0
  28. package/docs/zh/README.md +24 -2
  29. package/install.sh +46 -4
  30. package/package.json +2 -1
  31. package/pyproject.toml +1 -1
  32. package/src/deepscientist/__init__.py +1 -1
  33. package/src/deepscientist/acp/envelope.py +6 -0
  34. package/src/deepscientist/artifact/service.py +647 -22
  35. package/src/deepscientist/bash_exec/service.py +234 -9
  36. package/src/deepscientist/bridges/connectors.py +8 -2
  37. package/src/deepscientist/cli.py +115 -19
  38. package/src/deepscientist/codex_cli_compat.py +367 -22
  39. package/src/deepscientist/config/models.py +2 -1
  40. package/src/deepscientist/config/service.py +183 -13
  41. package/src/deepscientist/daemon/api/handlers.py +255 -31
  42. package/src/deepscientist/daemon/api/router.py +9 -0
  43. package/src/deepscientist/daemon/app.py +1146 -105
  44. package/src/deepscientist/diagnostics/__init__.py +6 -0
  45. package/src/deepscientist/diagnostics/runner_failures.py +130 -0
  46. package/src/deepscientist/doctor.py +207 -3
  47. package/src/deepscientist/gitops/__init__.py +10 -1
  48. package/src/deepscientist/gitops/diff.py +129 -0
  49. package/src/deepscientist/gitops/service.py +4 -1
  50. package/src/deepscientist/mcp/server.py +39 -0
  51. package/src/deepscientist/prompts/builder.py +275 -34
  52. package/src/deepscientist/quest/layout.py +15 -2
  53. package/src/deepscientist/quest/service.py +707 -55
  54. package/src/deepscientist/quest/stage_views.py +6 -1
  55. package/src/deepscientist/runners/codex.py +143 -43
  56. package/src/deepscientist/shared.py +19 -0
  57. package/src/deepscientist/skills/__init__.py +2 -2
  58. package/src/deepscientist/skills/installer.py +196 -5
  59. package/src/deepscientist/skills/registry.py +66 -0
  60. package/src/prompts/connectors/qq.md +18 -8
  61. package/src/prompts/connectors/weixin.md +16 -6
  62. package/src/prompts/contracts/shared_interaction.md +14 -2
  63. package/src/prompts/system.md +23 -5
  64. package/src/prompts/system_copilot.md +56 -0
  65. package/src/skills/analysis-campaign/SKILL.md +1 -0
  66. package/src/skills/baseline/SKILL.md +8 -0
  67. package/src/skills/decision/SKILL.md +8 -0
  68. package/src/skills/experiment/SKILL.md +8 -0
  69. package/src/skills/figure-polish/SKILL.md +1 -0
  70. package/src/skills/finalize/SKILL.md +1 -0
  71. package/src/skills/idea/SKILL.md +1 -0
  72. package/src/skills/intake-audit/SKILL.md +8 -0
  73. package/src/skills/mentor/SKILL.md +217 -0
  74. package/src/skills/mentor/references/correction-rules.md +210 -0
  75. package/src/skills/mentor/references/knowledge-profile.md +91 -0
  76. package/src/skills/mentor/references/persona-profile.md +138 -0
  77. package/src/skills/mentor/references/taste-profile.md +128 -0
  78. package/src/skills/mentor/references/thought-style-profile.md +138 -0
  79. package/src/skills/mentor/references/work-profile.md +289 -0
  80. package/src/skills/mentor/references/workflow-profile.md +240 -0
  81. package/src/skills/optimize/SKILL.md +1 -0
  82. package/src/skills/rebuttal/SKILL.md +1 -0
  83. package/src/skills/review/SKILL.md +1 -0
  84. package/src/skills/scout/SKILL.md +8 -0
  85. package/src/skills/write/SKILL.md +1 -0
  86. package/src/tui/dist/app/AppContainer.js +19 -11
  87. package/src/tui/dist/index.js +4 -1
  88. package/src/tui/dist/lib/api.js +33 -3
  89. package/src/tui/package.json +1 -1
  90. package/src/ui/dist/assets/AiManusChatView-Bv-Z8YpU.js +204 -0
  91. package/src/ui/dist/assets/AnalysisPlugin-BCKAfjba.js +1 -0
  92. package/src/ui/dist/assets/CliPlugin-BCKcpc35.js +109 -0
  93. package/src/ui/dist/assets/CodeEditorPlugin-DbOfSJ8K.js +2 -0
  94. package/src/ui/dist/assets/CodeViewerPlugin-CbaFRrUU.js +270 -0
  95. package/src/ui/dist/assets/DocViewerPlugin-DAjLVeQD.js +7 -0
  96. package/src/ui/dist/assets/GitCommitViewerPlugin-CIUqbUDO.js +1 -0
  97. package/src/ui/dist/assets/GitDiffViewerPlugin-CQACjoAA.js +6 -0
  98. package/src/ui/dist/assets/GitSnapshotViewer-0r4nLPke.js +30 -0
  99. package/src/ui/dist/assets/ImageViewerPlugin-nBOmI2v_.js +26 -0
  100. package/src/ui/dist/assets/LabCopilotPanel-BHxOxF4z.js +14 -0
  101. package/src/ui/dist/assets/LabPlugin-BKoZGs95.js +22 -0
  102. package/src/ui/dist/assets/LatexPlugin-ZwtV8pIp.js +25 -0
  103. package/src/ui/dist/assets/MarkdownViewerPlugin-DKqVfKyW.js +128 -0
  104. package/src/ui/dist/assets/MarketplacePlugin-BwxStZ9D.js +13 -0
  105. package/src/ui/dist/assets/NotebookEditor-BEQhaQbt.js +81 -0
  106. package/src/ui/dist/assets/{NotebookEditor-CccQYZjX.css → NotebookEditor-BHH8rdGj.css} +1 -1
  107. package/src/ui/dist/assets/NotebookEditor-BOr3x3Ej.css +1 -0
  108. package/src/ui/dist/assets/NotebookEditor-DB9N_T9q.js +361 -0
  109. package/src/ui/dist/assets/PdfLoader-Cy5jtWrr.css +1 -0
  110. package/src/ui/dist/assets/PdfLoader-eWBONbQP.js +16 -0
  111. package/src/ui/dist/assets/PdfMarkdownPlugin-D22YOZL3.js +1 -0
  112. package/src/ui/dist/assets/PdfViewerPlugin-c-RK9DLM.js +17 -0
  113. package/src/ui/dist/assets/PdfViewerPlugin-nwwE-fjJ.css +1 -0
  114. package/src/ui/dist/assets/SearchPlugin-CxF9ytAx.js +16 -0
  115. package/src/ui/dist/assets/SearchPlugin-DA4en4hK.css +1 -0
  116. package/src/ui/dist/assets/TextViewerPlugin-C5xqeeUH.js +54 -0
  117. package/src/ui/dist/assets/VNCViewer-BoLGLnHz.js +11 -0
  118. package/src/ui/dist/assets/bot-DREQOxzP.js +6 -0
  119. package/src/ui/dist/assets/browser-CTB2jwNe.js +8 -0
  120. package/src/ui/dist/assets/chevron-up-C9Qpx4DE.js +6 -0
  121. package/src/ui/dist/assets/code-WlFHE7z_.js +6 -0
  122. package/src/ui/dist/assets/file-content-BZMz3RYp.js +1 -0
  123. package/src/ui/dist/assets/file-diff-panel-CQhw0jS2.js +1 -0
  124. package/src/ui/dist/assets/file-jump-queue-DA-SdG__.js +1 -0
  125. package/src/ui/dist/assets/file-socket-CfQPKQKj.js +1 -0
  126. package/src/ui/dist/assets/git-commit-horizontal-DxZ8DCZh.js +6 -0
  127. package/src/ui/dist/assets/image-Bgl4VIyx.js +6 -0
  128. package/src/ui/dist/assets/index-BpV6lusQ.css +33 -0
  129. package/src/ui/dist/assets/index-CBNVuWcP.js +2496 -0
  130. package/src/ui/dist/assets/index-CwNu1aH4.js +11 -0
  131. package/src/ui/dist/assets/index-DrUnlf6K.js +1 -0
  132. package/src/ui/dist/assets/index-NW-h8VzN.js +1 -0
  133. package/src/ui/dist/assets/monaco-CiHMMNH_.js +1 -0
  134. package/src/ui/dist/assets/pdf-effect-queue-J8OnM0jE.js +6 -0
  135. package/src/ui/dist/assets/plugin-monaco-C8UgLomw.js +19 -0
  136. package/src/ui/dist/assets/plugin-notebook-HbW2K-1c.js +169 -0
  137. package/src/ui/dist/assets/plugin-pdf-CR8hgQBV.js +357 -0
  138. package/src/ui/dist/assets/plugin-terminal-MXFIPun8.js +227 -0
  139. package/src/ui/dist/assets/popover-CLc0pPP8.js +1 -0
  140. package/src/ui/dist/assets/project-sync-C9IdzdZW.js +1 -0
  141. package/src/ui/dist/assets/select-Cs2PmzwL.js +11 -0
  142. package/src/ui/dist/assets/sigma-ClKcHAXm.js +6 -0
  143. package/src/ui/dist/assets/trash-DwpbFr3w.js +11 -0
  144. package/src/ui/dist/assets/useCliAccess-NQ8m0Let.js +1 -0
  145. package/src/ui/dist/assets/useFileDiffOverlay-FuhcnKiw.js +1 -0
  146. package/src/ui/dist/assets/wrap-text-BC-Hltpd.js +11 -0
  147. package/src/ui/dist/assets/zoom-out-E_gaeAxL.js +11 -0
  148. package/src/ui/dist/index.html +5 -2
  149. package/src/ui/dist/assets/AiManusChatView-DDjbFnbt.js +0 -26597
  150. package/src/ui/dist/assets/AnalysisPlugin-Yb5IdmaU.js +0 -123
  151. package/src/ui/dist/assets/CliPlugin-e64sreyu.js +0 -31037
  152. package/src/ui/dist/assets/CodeEditorPlugin-C4D2TIkU.js +0 -427
  153. package/src/ui/dist/assets/CodeViewerPlugin-BVoNZIvC.js +0 -905
  154. package/src/ui/dist/assets/DocViewerPlugin-CLChbllo.js +0 -278
  155. package/src/ui/dist/assets/GitDiffViewerPlugin-C4xeFyFQ.js +0 -2661
  156. package/src/ui/dist/assets/ImageViewerPlugin-OiMUAcLi.js +0 -500
  157. package/src/ui/dist/assets/LabCopilotPanel-BjD2ThQF.js +0 -4104
  158. package/src/ui/dist/assets/LabPlugin-DQPg-NrB.js +0 -2677
  159. package/src/ui/dist/assets/LatexPlugin-CI05XAV9.js +0 -1792
  160. package/src/ui/dist/assets/MarkdownViewerPlugin-DpeBLYZf.js +0 -308
  161. package/src/ui/dist/assets/MarketplacePlugin-DolE58Q2.js +0 -413
  162. package/src/ui/dist/assets/NotebookEditor-7Qm2rSWD.js +0 -4214
  163. package/src/ui/dist/assets/NotebookEditor-C1kWaxKi.js +0 -84873
  164. package/src/ui/dist/assets/NotebookEditor-C3VQ7ylN.css +0 -1405
  165. package/src/ui/dist/assets/PdfLoader-BfOHw8Zw.js +0 -25468
  166. package/src/ui/dist/assets/PdfLoader-C-Y707R3.css +0 -49
  167. package/src/ui/dist/assets/PdfMarkdownPlugin-BulDREv1.js +0 -409
  168. package/src/ui/dist/assets/PdfViewerPlugin-C-daaOaL.js +0 -3095
  169. package/src/ui/dist/assets/PdfViewerPlugin-DQ11QcSf.css +0 -3627
  170. package/src/ui/dist/assets/SearchPlugin-CjpaiJ3A.js +0 -741
  171. package/src/ui/dist/assets/SearchPlugin-DDMrGDkh.css +0 -379
  172. package/src/ui/dist/assets/TextViewerPlugin-BxIyqPQC.js +0 -472
  173. package/src/ui/dist/assets/VNCViewer-HAg9mF7M.js +0 -18821
  174. package/src/ui/dist/assets/awareness-C0NPR2Dj.js +0 -292
  175. package/src/ui/dist/assets/bot-0DYntytV.js +0 -21
  176. package/src/ui/dist/assets/browser-BAcuE0Xj.js +0 -2895
  177. package/src/ui/dist/assets/code-B20Slj_w.js +0 -17
  178. package/src/ui/dist/assets/file-content-DT24KFma.js +0 -377
  179. package/src/ui/dist/assets/file-diff-panel-DK13YPql.js +0 -92
  180. package/src/ui/dist/assets/file-jump-queue-r5XKgJEV.js +0 -16
  181. package/src/ui/dist/assets/file-socket-B4T2o4nR.js +0 -58
  182. package/src/ui/dist/assets/function-B5QZkkHC.js +0 -1895
  183. package/src/ui/dist/assets/image-DSeR_sDS.js +0 -18
  184. package/src/ui/dist/assets/index-BrFje2Uk.js +0 -120
  185. package/src/ui/dist/assets/index-BwRJaoTl.js +0 -25
  186. package/src/ui/dist/assets/index-D_E4281X.js +0 -221322
  187. package/src/ui/dist/assets/index-DnYB3xb1.js +0 -159
  188. package/src/ui/dist/assets/index-G7AcWcMu.css +0 -12594
  189. package/src/ui/dist/assets/monaco-LExaAN3Y.js +0 -623
  190. package/src/ui/dist/assets/pdf-effect-queue-BJk5okWJ.js +0 -47
  191. package/src/ui/dist/assets/pdf_viewer-e0g1is2C.js +0 -8206
  192. package/src/ui/dist/assets/popover-D3Gg_FoV.js +0 -476
  193. package/src/ui/dist/assets/project-sync-C_ygLlVU.js +0 -297
  194. package/src/ui/dist/assets/select-CpAK6uWm.js +0 -1690
  195. package/src/ui/dist/assets/sigma-DEccaSgk.js +0 -22
  196. package/src/ui/dist/assets/square-check-big-uUfyVsbD.js +0 -17
  197. package/src/ui/dist/assets/trash-CXvwwSe8.js +0 -32
  198. package/src/ui/dist/assets/useCliAccess-Bnop4mgR.js +0 -957
  199. package/src/ui/dist/assets/useFileDiffOverlay-B8eUAX0I.js +0 -53
  200. package/src/ui/dist/assets/wrap-text-9vbOBpkW.js +0 -35
  201. package/src/ui/dist/assets/yjs-DncrqiZ8.js +0 -11243
  202. package/src/ui/dist/assets/zoom-out-BgVMmOW4.js +0 -34
@@ -1,17 +0,0 @@
1
- import { w as createLucideIcon } from './index-D_E4281X.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-D_E4281X.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-D_E4281X.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-D_E4281X.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 };