@researai/deepscientist 1.5.15 → 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 (193) hide show
  1. package/README.md +336 -98
  2. package/bin/ds.js +691 -91
  3. package/docs/en/00_QUICK_START.md +36 -15
  4. package/docs/en/01_SETTINGS_REFERENCE.md +33 -0
  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 +11 -5
  9. package/docs/en/14_PROMPT_SKILLS_AND_MCP_GUIDE.md +63 -13
  10. package/docs/en/15_CODEX_PROVIDER_SETUP.md +25 -8
  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/README.md +18 -0
  15. package/docs/zh/00_QUICK_START.md +36 -15
  16. package/docs/zh/01_SETTINGS_REFERENCE.md +33 -0
  17. package/docs/zh/02_START_RESEARCH_GUIDE.md +7 -0
  18. package/docs/zh/05_TUI_GUIDE.md +6 -0
  19. package/docs/zh/09_DOCTOR.md +11 -5
  20. package/docs/zh/14_PROMPT_SKILLS_AND_MCP_GUIDE.md +63 -13
  21. package/docs/zh/15_CODEX_PROVIDER_SETUP.md +25 -8
  22. package/docs/zh/19_EXTERNAL_CONTROLLER_GUIDE.md +226 -0
  23. package/docs/zh/19_LOCAL_BROWSER_AUTH.md +68 -0
  24. package/docs/zh/20_WORKSPACE_MODES_GUIDE.md +251 -0
  25. package/docs/zh/README.md +18 -0
  26. package/package.json +1 -1
  27. package/pyproject.toml +1 -1
  28. package/src/deepscientist/__init__.py +1 -1
  29. package/src/deepscientist/acp/envelope.py +6 -0
  30. package/src/deepscientist/artifact/service.py +647 -22
  31. package/src/deepscientist/bash_exec/service.py +234 -9
  32. package/src/deepscientist/cli.py +115 -19
  33. package/src/deepscientist/codex_cli_compat.py +232 -0
  34. package/src/deepscientist/config/models.py +2 -1
  35. package/src/deepscientist/config/service.py +31 -9
  36. package/src/deepscientist/daemon/api/handlers.py +125 -6
  37. package/src/deepscientist/daemon/api/router.py +4 -0
  38. package/src/deepscientist/daemon/app.py +715 -98
  39. package/src/deepscientist/gitops/__init__.py +10 -1
  40. package/src/deepscientist/gitops/diff.py +129 -0
  41. package/src/deepscientist/gitops/service.py +4 -1
  42. package/src/deepscientist/mcp/server.py +39 -0
  43. package/src/deepscientist/prompts/builder.py +255 -32
  44. package/src/deepscientist/quest/layout.py +15 -2
  45. package/src/deepscientist/quest/service.py +295 -43
  46. package/src/deepscientist/quest/stage_views.py +6 -1
  47. package/src/deepscientist/runners/codex.py +86 -31
  48. package/src/deepscientist/skills/__init__.py +2 -2
  49. package/src/deepscientist/skills/installer.py +196 -5
  50. package/src/deepscientist/skills/registry.py +66 -0
  51. package/src/prompts/connectors/qq.md +18 -8
  52. package/src/prompts/connectors/weixin.md +16 -6
  53. package/src/prompts/contracts/shared_interaction.md +12 -1
  54. package/src/prompts/system.md +10 -5
  55. package/src/prompts/system_copilot.md +43 -0
  56. package/src/skills/analysis-campaign/SKILL.md +1 -0
  57. package/src/skills/baseline/SKILL.md +8 -0
  58. package/src/skills/decision/SKILL.md +8 -0
  59. package/src/skills/experiment/SKILL.md +8 -0
  60. package/src/skills/figure-polish/SKILL.md +1 -0
  61. package/src/skills/finalize/SKILL.md +1 -0
  62. package/src/skills/idea/SKILL.md +1 -0
  63. package/src/skills/intake-audit/SKILL.md +8 -0
  64. package/src/skills/mentor/SKILL.md +217 -0
  65. package/src/skills/mentor/references/correction-rules.md +210 -0
  66. package/src/skills/mentor/references/knowledge-profile.md +91 -0
  67. package/src/skills/mentor/references/persona-profile.md +138 -0
  68. package/src/skills/mentor/references/taste-profile.md +128 -0
  69. package/src/skills/mentor/references/thought-style-profile.md +138 -0
  70. package/src/skills/mentor/references/work-profile.md +289 -0
  71. package/src/skills/mentor/references/workflow-profile.md +240 -0
  72. package/src/skills/optimize/SKILL.md +1 -0
  73. package/src/skills/rebuttal/SKILL.md +1 -0
  74. package/src/skills/review/SKILL.md +1 -0
  75. package/src/skills/scout/SKILL.md +8 -0
  76. package/src/skills/write/SKILL.md +1 -0
  77. package/src/tui/dist/app/AppContainer.js +19 -11
  78. package/src/tui/dist/index.js +4 -1
  79. package/src/tui/dist/lib/api.js +33 -3
  80. package/src/tui/package.json +1 -1
  81. package/src/ui/dist/assets/AiManusChatView-COFACy7V.js +204 -0
  82. package/src/ui/dist/assets/AnalysisPlugin-DnSm0GZn.js +1 -0
  83. package/src/ui/dist/assets/CliPlugin-CvwCmDQ5.js +109 -0
  84. package/src/ui/dist/assets/CodeEditorPlugin-cOqSa0xq.js +2 -0
  85. package/src/ui/dist/assets/CodeViewerPlugin-itb0tltR.js +270 -0
  86. package/src/ui/dist/assets/DocViewerPlugin-DqKkiCI6.js +7 -0
  87. package/src/ui/dist/assets/GitCommitViewerPlugin-DVgNHBCS.js +1 -0
  88. package/src/ui/dist/assets/GitDiffViewerPlugin-DxL2ezFG.js +6 -0
  89. package/src/ui/dist/assets/GitSnapshotViewer-B_RQm1YZ.js +30 -0
  90. package/src/ui/dist/assets/ImageViewerPlugin-tHqlXY3n.js +26 -0
  91. package/src/ui/dist/assets/LabCopilotPanel-ClMbq5Yu.js +14 -0
  92. package/src/ui/dist/assets/LabPlugin-L_SuE8ow.js +22 -0
  93. package/src/ui/dist/assets/LatexPlugin-B495DTXC.js +25 -0
  94. package/src/ui/dist/assets/MarkdownViewerPlugin-DG28-61B.js +128 -0
  95. package/src/ui/dist/assets/MarketplacePlugin-BiOGT-Kj.js +13 -0
  96. package/src/ui/dist/assets/{NotebookEditor-CccQYZjX.css → NotebookEditor-BHH8rdGj.css} +1 -1
  97. package/src/ui/dist/assets/NotebookEditor-BOr3x3Ej.css +1 -0
  98. package/src/ui/dist/assets/NotebookEditor-C-4Kt1p9.js +81 -0
  99. package/src/ui/dist/assets/NotebookEditor-CVsj8h_T.js +361 -0
  100. package/src/ui/dist/assets/PdfLoader-CASDQmxJ.js +16 -0
  101. package/src/ui/dist/assets/PdfLoader-Cy5jtWrr.css +1 -0
  102. package/src/ui/dist/assets/PdfMarkdownPlugin-BFhwoKsY.js +1 -0
  103. package/src/ui/dist/assets/PdfViewerPlugin-DcOzU9vd.js +17 -0
  104. package/src/ui/dist/assets/PdfViewerPlugin-nwwE-fjJ.css +1 -0
  105. package/src/ui/dist/assets/SearchPlugin-CHj7M58O.js +16 -0
  106. package/src/ui/dist/assets/SearchPlugin-DA4en4hK.css +1 -0
  107. package/src/ui/dist/assets/TextViewerPlugin-CB4DYfWO.js +54 -0
  108. package/src/ui/dist/assets/VNCViewer-CjlbyCB3.js +11 -0
  109. package/src/ui/dist/assets/bot-CFkZY-JP.js +6 -0
  110. package/src/ui/dist/assets/browser-CTB2jwNe.js +8 -0
  111. package/src/ui/dist/assets/chevron-up-Dq5ofbht.js +6 -0
  112. package/src/ui/dist/assets/code-DLC6G24T.js +6 -0
  113. package/src/ui/dist/assets/file-content-Dv4LoZec.js +1 -0
  114. package/src/ui/dist/assets/file-diff-panel-Denq-lC3.js +1 -0
  115. package/src/ui/dist/assets/file-jump-queue-DA-SdG__.js +1 -0
  116. package/src/ui/dist/assets/file-socket-Cu4Qln7Y.js +1 -0
  117. package/src/ui/dist/assets/git-commit-horizontal-BUh6G52n.js +6 -0
  118. package/src/ui/dist/assets/image-B9HUUddG.js +6 -0
  119. package/src/ui/dist/assets/index-B2B1sg-M.js +1 -0
  120. package/src/ui/dist/assets/index-Cgla8biy.css +33 -0
  121. package/src/ui/dist/assets/index-DRyx7vAc.js +1 -0
  122. package/src/ui/dist/assets/index-Gbl53BNp.js +2496 -0
  123. package/src/ui/dist/assets/index-wQ7RIIRd.js +11 -0
  124. package/src/ui/dist/assets/monaco-CiHMMNH_.js +1 -0
  125. package/src/ui/dist/assets/pdf-effect-queue-ZtnHFCAi.js +6 -0
  126. package/src/ui/dist/assets/plugin-monaco-C8UgLomw.js +19 -0
  127. package/src/ui/dist/assets/plugin-notebook-HbW2K-1c.js +169 -0
  128. package/src/ui/dist/assets/plugin-pdf-CR8hgQBV.js +357 -0
  129. package/src/ui/dist/assets/plugin-terminal-MXFIPun8.js +227 -0
  130. package/src/ui/dist/assets/popover-DL6h35vr.js +1 -0
  131. package/src/ui/dist/assets/project-sync-CsX08Qno.js +1 -0
  132. package/src/ui/dist/assets/select-DvmXt1yY.js +11 -0
  133. package/src/ui/dist/assets/sigma-7jpXazui.js +6 -0
  134. package/src/ui/dist/assets/trash-xA7kFt8i.js +11 -0
  135. package/src/ui/dist/assets/useCliAccess-DsMwDjOp.js +1 -0
  136. package/src/ui/dist/assets/useFileDiffOverlay-FuhcnKiw.js +1 -0
  137. package/src/ui/dist/assets/wrap-text-CwMn-iqb.js +11 -0
  138. package/src/ui/dist/assets/zoom-out-R-GWEhzS.js +11 -0
  139. package/src/ui/dist/index.html +5 -2
  140. package/src/ui/dist/assets/AiManusChatView-DDjbFnbt.js +0 -26597
  141. package/src/ui/dist/assets/AnalysisPlugin-Yb5IdmaU.js +0 -123
  142. package/src/ui/dist/assets/CliPlugin-e64sreyu.js +0 -31037
  143. package/src/ui/dist/assets/CodeEditorPlugin-C4D2TIkU.js +0 -427
  144. package/src/ui/dist/assets/CodeViewerPlugin-BVoNZIvC.js +0 -905
  145. package/src/ui/dist/assets/DocViewerPlugin-CLChbllo.js +0 -278
  146. package/src/ui/dist/assets/GitDiffViewerPlugin-C4xeFyFQ.js +0 -2661
  147. package/src/ui/dist/assets/ImageViewerPlugin-OiMUAcLi.js +0 -500
  148. package/src/ui/dist/assets/LabCopilotPanel-BjD2ThQF.js +0 -4104
  149. package/src/ui/dist/assets/LabPlugin-DQPg-NrB.js +0 -2677
  150. package/src/ui/dist/assets/LatexPlugin-CI05XAV9.js +0 -1792
  151. package/src/ui/dist/assets/MarkdownViewerPlugin-DpeBLYZf.js +0 -308
  152. package/src/ui/dist/assets/MarketplacePlugin-DolE58Q2.js +0 -413
  153. package/src/ui/dist/assets/NotebookEditor-7Qm2rSWD.js +0 -4214
  154. package/src/ui/dist/assets/NotebookEditor-C1kWaxKi.js +0 -84873
  155. package/src/ui/dist/assets/NotebookEditor-C3VQ7ylN.css +0 -1405
  156. package/src/ui/dist/assets/PdfLoader-BfOHw8Zw.js +0 -25468
  157. package/src/ui/dist/assets/PdfLoader-C-Y707R3.css +0 -49
  158. package/src/ui/dist/assets/PdfMarkdownPlugin-BulDREv1.js +0 -409
  159. package/src/ui/dist/assets/PdfViewerPlugin-C-daaOaL.js +0 -3095
  160. package/src/ui/dist/assets/PdfViewerPlugin-DQ11QcSf.css +0 -3627
  161. package/src/ui/dist/assets/SearchPlugin-CjpaiJ3A.js +0 -741
  162. package/src/ui/dist/assets/SearchPlugin-DDMrGDkh.css +0 -379
  163. package/src/ui/dist/assets/TextViewerPlugin-BxIyqPQC.js +0 -472
  164. package/src/ui/dist/assets/VNCViewer-HAg9mF7M.js +0 -18821
  165. package/src/ui/dist/assets/awareness-C0NPR2Dj.js +0 -292
  166. package/src/ui/dist/assets/bot-0DYntytV.js +0 -21
  167. package/src/ui/dist/assets/browser-BAcuE0Xj.js +0 -2895
  168. package/src/ui/dist/assets/code-B20Slj_w.js +0 -17
  169. package/src/ui/dist/assets/file-content-DT24KFma.js +0 -377
  170. package/src/ui/dist/assets/file-diff-panel-DK13YPql.js +0 -92
  171. package/src/ui/dist/assets/file-jump-queue-r5XKgJEV.js +0 -16
  172. package/src/ui/dist/assets/file-socket-B4T2o4nR.js +0 -58
  173. package/src/ui/dist/assets/function-B5QZkkHC.js +0 -1895
  174. package/src/ui/dist/assets/image-DSeR_sDS.js +0 -18
  175. package/src/ui/dist/assets/index-BrFje2Uk.js +0 -120
  176. package/src/ui/dist/assets/index-BwRJaoTl.js +0 -25
  177. package/src/ui/dist/assets/index-D_E4281X.js +0 -221322
  178. package/src/ui/dist/assets/index-DnYB3xb1.js +0 -159
  179. package/src/ui/dist/assets/index-G7AcWcMu.css +0 -12594
  180. package/src/ui/dist/assets/monaco-LExaAN3Y.js +0 -623
  181. package/src/ui/dist/assets/pdf-effect-queue-BJk5okWJ.js +0 -47
  182. package/src/ui/dist/assets/pdf_viewer-e0g1is2C.js +0 -8206
  183. package/src/ui/dist/assets/popover-D3Gg_FoV.js +0 -476
  184. package/src/ui/dist/assets/project-sync-C_ygLlVU.js +0 -297
  185. package/src/ui/dist/assets/select-CpAK6uWm.js +0 -1690
  186. package/src/ui/dist/assets/sigma-DEccaSgk.js +0 -22
  187. package/src/ui/dist/assets/square-check-big-uUfyVsbD.js +0 -17
  188. package/src/ui/dist/assets/trash-CXvwwSe8.js +0 -32
  189. package/src/ui/dist/assets/useCliAccess-Bnop4mgR.js +0 -957
  190. package/src/ui/dist/assets/useFileDiffOverlay-B8eUAX0I.js +0 -53
  191. package/src/ui/dist/assets/wrap-text-9vbOBpkW.js +0 -35
  192. package/src/ui/dist/assets/yjs-DncrqiZ8.js +0 -11243
  193. 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 };