@ibgib/vcs-gib 0.0.30 → 0.0.32

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 (151) hide show
  1. package/dist/AUTO-GENERATED-version.d.mts +1 -1
  2. package/dist/AUTO-GENERATED-version.mjs +1 -1
  3. package/dist/bootstrap/node-bootstrap.mjs +1 -1
  4. package/dist/bootstrap/node-bootstrap.mjs.map +1 -1
  5. package/dist/cli/commands/add-cmd.d.mts +2 -3
  6. package/dist/cli/commands/add-cmd.d.mts.map +1 -1
  7. package/dist/cli/commands/add-cmd.mjs +30 -283
  8. package/dist/cli/commands/add-cmd.mjs.map +1 -1
  9. package/dist/cli/commands/branch-cmd.d.mts +8 -8
  10. package/dist/cli/commands/branch-cmd.d.mts.map +1 -1
  11. package/dist/cli/commands/branch-cmd.mjs +45 -176
  12. package/dist/cli/commands/branch-cmd.mjs.map +1 -1
  13. package/dist/cli/commands/checkout-cmd.d.mts +2 -4
  14. package/dist/cli/commands/checkout-cmd.d.mts.map +1 -1
  15. package/dist/cli/commands/checkout-cmd.mjs +31 -110
  16. package/dist/cli/commands/checkout-cmd.mjs.map +1 -1
  17. package/dist/cli/commands/commit-cmd.d.mts +7 -8
  18. package/dist/cli/commands/commit-cmd.d.mts.map +1 -1
  19. package/dist/cli/commands/commit-cmd.mjs +40 -390
  20. package/dist/cli/commands/commit-cmd.mjs.map +1 -1
  21. package/dist/cli/commands/generate-comment-cmd.d.mts.map +1 -1
  22. package/dist/cli/commands/generate-comment-cmd.mjs +5 -2
  23. package/dist/cli/commands/generate-comment-cmd.mjs.map +1 -1
  24. package/dist/cli/commands/init-cmd.d.mts +2 -2
  25. package/dist/cli/commands/init-cmd.d.mts.map +1 -1
  26. package/dist/cli/commands/init-cmd.mjs +20 -70
  27. package/dist/cli/commands/init-cmd.mjs.map +1 -1
  28. package/dist/cli/commands/log-cmd.d.mts +2 -3
  29. package/dist/cli/commands/log-cmd.d.mts.map +1 -1
  30. package/dist/cli/commands/log-cmd.mjs +42 -271
  31. package/dist/cli/commands/log-cmd.mjs.map +1 -1
  32. package/dist/cli/commands/merge-cmd.d.mts +3 -17
  33. package/dist/cli/commands/merge-cmd.d.mts.map +1 -1
  34. package/dist/cli/commands/merge-cmd.mjs +32 -218
  35. package/dist/cli/commands/merge-cmd.mjs.map +1 -1
  36. package/dist/cli/commands/reset-cmd.d.mts +1 -1
  37. package/dist/cli/commands/reset-cmd.d.mts.map +1 -1
  38. package/dist/cli/commands/reset-cmd.mjs +17 -19
  39. package/dist/cli/commands/reset-cmd.mjs.map +1 -1
  40. package/dist/cli/commands/restore-cmd.d.mts +8 -7
  41. package/dist/cli/commands/restore-cmd.d.mts.map +1 -1
  42. package/dist/cli/commands/restore-cmd.mjs +44 -62
  43. package/dist/cli/commands/restore-cmd.mjs.map +1 -1
  44. package/dist/cli/commands/status-cmd.d.mts +2 -2
  45. package/dist/cli/commands/status-cmd.d.mts.map +1 -1
  46. package/dist/cli/commands/status-cmd.mjs +63 -62
  47. package/dist/cli/commands/status-cmd.mjs.map +1 -1
  48. package/dist/cli/vcs-projection-helper.d.mts +23 -0
  49. package/dist/cli/vcs-projection-helper.d.mts.map +1 -0
  50. package/dist/cli/vcs-projection-helper.mjs +91 -0
  51. package/dist/cli/vcs-projection-helper.mjs.map +1 -0
  52. package/dist/test/test-helpers.d.mts +2 -2
  53. package/dist/test/test-helpers.d.mts.map +1 -1
  54. package/package.json +3 -3
  55. package/src/AUTO-GENERATED-version.mts +1 -1
  56. package/src/bootstrap/node-bootstrap.mts +1 -1
  57. package/src/cli/cli-e2e.respec.mts +4 -4
  58. package/src/cli/commands/add-cmd.mts +32 -347
  59. package/src/cli/commands/branch-cmd.mts +56 -225
  60. package/src/cli/commands/checkout-cmd.mts +34 -138
  61. package/src/cli/commands/commit-cmd.mts +46 -473
  62. package/src/cli/commands/commit-log-cmd.respec.mts +11 -7
  63. package/src/cli/commands/generate-comment-cmd.mts +6 -2
  64. package/src/cli/commands/init-cmd.mts +20 -73
  65. package/src/cli/commands/log-cmd.mts +41 -331
  66. package/src/cli/commands/merge-cmd.mts +32 -252
  67. package/src/cli/commands/reset-cmd.mts +17 -19
  68. package/src/cli/commands/restore-cmd.mts +52 -72
  69. package/src/cli/commands/status-add-cmd.respec.mts +3 -3
  70. package/src/cli/commands/status-cmd.mts +68 -63
  71. package/src/cli/vcs-projection-helper.mts +112 -0
  72. package/src/engine/branch/branch-space.respec.mts +5 -5
  73. package/src/engine/merge/b2tfs-sync-comments.respec.mts +4 -4
  74. package/src/test/test-helpers.mts +2 -2
  75. package/src/vcs-gib.respec.mts +11 -8
  76. package/tsconfig.test.tsbuildinfo +1 -1
  77. package/tsconfig.tsbuildinfo +1 -1
  78. package/dist/engine/branch/branch-graph-helper.d.mts +0 -28
  79. package/dist/engine/branch/branch-graph-helper.d.mts.map +0 -1
  80. package/dist/engine/branch/branch-graph-helper.mjs +0 -81
  81. package/dist/engine/branch/branch-graph-helper.mjs.map +0 -1
  82. package/dist/engine/branch/branch-helper.d.mts +0 -40
  83. package/dist/engine/branch/branch-helper.d.mts.map +0 -1
  84. package/dist/engine/branch/branch-helper.mjs +0 -78
  85. package/dist/engine/branch/branch-helper.mjs.map +0 -1
  86. package/dist/engine/branch/branch-space-helper.d.mts +0 -23
  87. package/dist/engine/branch/branch-space-helper.d.mts.map +0 -1
  88. package/dist/engine/branch/branch-space-helper.mjs +0 -78
  89. package/dist/engine/branch/branch-space-helper.mjs.map +0 -1
  90. package/dist/engine/branch/branch-types.d.mts +0 -26
  91. package/dist/engine/branch/branch-types.d.mts.map +0 -1
  92. package/dist/engine/branch/branch-types.mjs +0 -7
  93. package/dist/engine/branch/branch-types.mjs.map +0 -1
  94. package/dist/engine/diff/line-diff-helper.d.mts +0 -76
  95. package/dist/engine/diff/line-diff-helper.d.mts.map +0 -1
  96. package/dist/engine/diff/line-diff-helper.mjs +0 -144
  97. package/dist/engine/diff/line-diff-helper.mjs.map +0 -1
  98. package/dist/engine/filter/glob-helper.d.mts +0 -51
  99. package/dist/engine/filter/glob-helper.d.mts.map +0 -1
  100. package/dist/engine/filter/glob-helper.mjs +0 -132
  101. package/dist/engine/filter/glob-helper.mjs.map +0 -1
  102. package/dist/engine/index/index-helper.d.mts +0 -113
  103. package/dist/engine/index/index-helper.d.mts.map +0 -1
  104. package/dist/engine/index/index-helper.mjs +0 -533
  105. package/dist/engine/index/index-helper.mjs.map +0 -1
  106. package/dist/engine/index/index-types.d.mts +0 -63
  107. package/dist/engine/index/index-types.d.mts.map +0 -1
  108. package/dist/engine/index/index-types.mjs +0 -7
  109. package/dist/engine/index/index-types.mjs.map +0 -1
  110. package/dist/engine/item/item-atom-helper.d.mts +0 -20
  111. package/dist/engine/item/item-atom-helper.d.mts.map +0 -1
  112. package/dist/engine/item/item-atom-helper.mjs +0 -30
  113. package/dist/engine/item/item-atom-helper.mjs.map +0 -1
  114. package/dist/engine/item/item-helper.d.mts +0 -94
  115. package/dist/engine/item/item-helper.d.mts.map +0 -1
  116. package/dist/engine/item/item-helper.mjs +0 -424
  117. package/dist/engine/item/item-helper.mjs.map +0 -1
  118. package/dist/engine/item/item-types.d.mts +0 -128
  119. package/dist/engine/item/item-types.d.mts.map +0 -1
  120. package/dist/engine/item/item-types.mjs +0 -16
  121. package/dist/engine/item/item-types.mjs.map +0 -1
  122. package/dist/engine/merge/b2tfs-3way-graft-strategy.d.mts +0 -74
  123. package/dist/engine/merge/b2tfs-3way-graft-strategy.d.mts.map +0 -1
  124. package/dist/engine/merge/b2tfs-3way-graft-strategy.mjs +0 -570
  125. package/dist/engine/merge/b2tfs-3way-graft-strategy.mjs.map +0 -1
  126. package/dist/engine/merge/b2tfs-3way-graft-types.d.mts +0 -34
  127. package/dist/engine/merge/b2tfs-3way-graft-types.d.mts.map +0 -1
  128. package/dist/engine/merge/b2tfs-3way-graft-types.mjs +0 -2
  129. package/dist/engine/merge/b2tfs-3way-graft-types.mjs.map +0 -1
  130. package/dist/engine/status/status-helper.d.mts +0 -90
  131. package/dist/engine/status/status-helper.d.mts.map +0 -1
  132. package/dist/engine/status/status-helper.mjs +0 -286
  133. package/dist/engine/status/status-helper.mjs.map +0 -1
  134. package/src/engine/branch/branch-graph-helper.mts +0 -117
  135. package/src/engine/branch/branch-helper.mts +0 -112
  136. package/src/engine/branch/branch-space-helper.mts +0 -110
  137. package/src/engine/branch/branch-types.mts +0 -29
  138. package/src/engine/diff/line-diff-helper.mts +0 -210
  139. package/src/engine/diff/line-diff-helper.respec.mts +0 -84
  140. package/src/engine/filter/glob-helper.mts +0 -165
  141. package/src/engine/filter/glob-helper.respec.mts +0 -94
  142. package/src/engine/index/index-helper.mts +0 -705
  143. package/src/engine/index/index-types.mts +0 -66
  144. package/src/engine/item/item-atom-helper.mts +0 -30
  145. package/src/engine/item/item-helper.mts +0 -544
  146. package/src/engine/item/item-types.mts +0 -137
  147. package/src/engine/item/item.respec.mts +0 -92
  148. package/src/engine/merge/b2tfs-3way-graft-strategy.mts +0 -630
  149. package/src/engine/merge/b2tfs-3way-graft-strategy.respec.mts +0 -346
  150. package/src/engine/merge/b2tfs-3way-graft-types.mts +0 -34
  151. package/src/engine/status/status-helper.mts +0 -383
@@ -1,383 +0,0 @@
1
- /**
2
- * @module status-helper
3
- *
4
- * Pure status inspection helpers and pending `.ib.*.md` comment metadata detection.
5
- */
6
-
7
- import path from 'node:path';
8
- import fs from 'node:fs/promises';
9
- import { Dirent } from 'node:fs';
10
- import crypto from 'node:crypto';
11
-
12
- import { B2tFSItemIbGib_V1, B2TFS_CHILD_ITEM_REL8N_NAME } from '../item/item-types.mjs';
13
- import { getIbGibWithMetaspaceFallback } from '../item/item-helper.mjs';
14
- import { B2tFSBranchIbGib_V1 } from '../branch/branch-types.mjs';
15
- import { isPathFiltered, parseFilterFileContent } from '../filter/glob-helper.mjs';
16
- import { getB2tFSIndexIbGib } from '../index/index-helper.mjs';
17
- import { B2tFSStagedItemRecord } from '../index/index-types.mjs';
18
- import { getOrCreateBranchSpace } from '../branch/branch-space-helper.mjs';
19
- import { resolveContextualBranchName } from '../branch/branch-helper.mjs';
20
-
21
- export interface VcsStatusItem {
22
- path: string;
23
- fsType: 'file' | 'folder';
24
- status: 'untracked' | 'modified' | 'deleted' | 'staged';
25
- }
26
-
27
- export interface PendingCommentInfo {
28
- /** Relative path of the companion file, e.g. "src/.ib.index.mts.md" or ".ib.architecture.md" */
29
- commentRelPath: string;
30
- /** Full disk path of the companion file */
31
- commentFullPath: string;
32
- /** Target relative path this comment attaches to, e.g. "src/index.mts" or "src" (folder) or "" (root) */
33
- targetRelPath: string;
34
- /** 'file' if .ib.<filename>.md matches a file, or 'folder' */
35
- targetType: 'file' | 'folder';
36
- /** The topic name (the * in .ib.*.md) or filename */
37
- topicName: string;
38
- /** Raw text content of the markdown comment file */
39
- content: string;
40
- }
41
-
42
- export interface RepoStatusResult {
43
- branchName: string;
44
- activeWorktreeDir: string;
45
- staged: VcsStatusItem[];
46
- modified: VcsStatusItem[];
47
- deleted: VcsStatusItem[];
48
- untracked: VcsStatusItem[];
49
- pendingComments: PendingCommentInfo[];
50
- }
51
-
52
- /**
53
- * Returns true if filename is a `.ib.*.md` comment metadata file.
54
- */
55
- export function isCommentMetadataFilename(filename: string): boolean {
56
- return filename.startsWith('.ib.') && filename.endsWith('.md') && filename.length > '.ib..md'.length;
57
- }
58
-
59
- /**
60
- * Extracts the inner topic / filename from `.ib.<topic>.md`.
61
- */
62
- export function extractCommentTopicName(filename: string): string {
63
- if (!isCommentMetadataFilename(filename)) { return ''; }
64
- return filename.slice(4, -3); // strips leading '.ib.' and trailing '.md'
65
- }
66
-
67
- /**
68
- * Pure helper to walk the branch graph items.
69
- */
70
- export async function walkBranchGraph({
71
- item,
72
- space,
73
- metaspace,
74
- currentRelPath,
75
- outMap,
76
- }: {
77
- item: B2tFSItemIbGib_V1;
78
- space: any;
79
- metaspace?: any;
80
- currentRelPath: string;
81
- outMap: Map<string, { relPath: string; fileHash?: string; fsType: 'file' | 'folder' }>;
82
- }): Promise<void> {
83
- if (!item || !item.data) { return; }
84
-
85
- const { fsType, fileHash } = item.data;
86
- if (currentRelPath) {
87
- outMap.set(currentRelPath, { relPath: currentRelPath, fileHash, fsType });
88
- }
89
-
90
- if (fsType === 'folder') {
91
- const childAddrs = item.rel8ns?.[B2TFS_CHILD_ITEM_REL8N_NAME] || [];
92
- for (const childAddr of childAddrs) {
93
- const childItem = await getIbGibWithMetaspaceFallback({
94
- addr: childAddr,
95
- space,
96
- metaspace,
97
- }) as B2tFSItemIbGib_V1;
98
- if (childItem && childItem.data) {
99
- const childRelPath = currentRelPath
100
- ? `${currentRelPath}/${childItem.data.name}`
101
- : childItem.data.name;
102
- await walkBranchGraph({
103
- item: childItem,
104
- space,
105
- metaspace,
106
- currentRelPath: childRelPath,
107
- outMap,
108
- });
109
- }
110
- }
111
- }
112
- }
113
-
114
- /**
115
- * Pure helper to scan physical workspace, separating source files from `.ib.*.md` comment files.
116
- */
117
- export async function scanPhysicalWorkspace({
118
- dirPath,
119
- baseDir,
120
- vcsFolderName,
121
- filterPatterns,
122
- outSourceMap,
123
- outCommentFiles,
124
- }: {
125
- dirPath: string;
126
- baseDir: string;
127
- vcsFolderName: string;
128
- filterPatterns: string[];
129
- outSourceMap: Map<string, { relPath: string; fullPath: string; isDirectory: boolean; fileHash?: string }>;
130
- outCommentFiles: Array<{ relPath: string; fullPath: string; parentRelPath: string; filename: string }>;
131
- }): Promise<void> {
132
- let entries: Dirent[] = [];
133
- try {
134
- entries = await fs.readdir(dirPath, { withFileTypes: true });
135
- } catch {
136
- return;
137
- }
138
-
139
- for (const entry of entries) {
140
- const fullEntryPath = path.join(dirPath, entry.name);
141
- const relPath = path.relative(baseDir, fullEntryPath).replace(/\\/g, '/');
142
-
143
- // Ignore vcs storage folder, .git, and worktrees folder b
144
- if (
145
- relPath === vcsFolderName || relPath.startsWith(vcsFolderName + '/') ||
146
- relPath === '.git' || relPath.startsWith('.git/') ||
147
- relPath === 'b' || relPath.startsWith('b/')
148
- ) {
149
- continue;
150
- }
151
-
152
- if (isPathFiltered({ relativePath: relPath, isDirectory: entry.isDirectory(), filterPatterns })) {
153
- continue;
154
- }
155
-
156
- if (entry.isDirectory()) {
157
- outSourceMap.set(relPath, { relPath, fullPath: fullEntryPath, isDirectory: true });
158
- await scanPhysicalWorkspace({
159
- dirPath: fullEntryPath,
160
- baseDir,
161
- vcsFolderName,
162
- filterPatterns,
163
- outSourceMap,
164
- outCommentFiles,
165
- });
166
- } else if (entry.isFile()) {
167
- if (isCommentMetadataFilename(entry.name)) {
168
- const parentRelPath = path.relative(baseDir, dirPath).replace(/\\/g, '/');
169
- outCommentFiles.push({
170
- relPath,
171
- fullPath: fullEntryPath,
172
- parentRelPath: parentRelPath === '.' ? '' : parentRelPath,
173
- filename: entry.name,
174
- });
175
- } else {
176
- let fileHash: string | undefined;
177
- try {
178
- const fileData = await fs.readFile(fullEntryPath);
179
- fileHash = crypto.createHash('sha256').update(fileData).digest('hex');
180
- } catch {
181
- // File unreadable
182
- }
183
- outSourceMap.set(relPath, { relPath, fullPath: fullEntryPath, isDirectory: false, fileHash });
184
- }
185
- }
186
- }
187
- }
188
-
189
- /**
190
- * Computes complete repository status, including staged, modified, deleted, untracked,
191
- * and mapped pending `.ib.*.md` comment files.
192
- */
193
- export async function getRepoStatus({
194
- metaspace,
195
- localSpace,
196
- vcsPath,
197
- repoRoot,
198
- targetDir = repoRoot,
199
- vcsFolderName = '.vcsgib',
200
- }: {
201
- metaspace: any;
202
- localSpace: any;
203
- vcsPath: string;
204
- repoRoot: string;
205
- targetDir?: string;
206
- vcsFolderName?: string;
207
- }): Promise<RepoStatusResult> {
208
- const indexIbGib = await getB2tFSIndexIbGib({ space: localSpace, vcsPath });
209
- const branchName = resolveContextualBranchName({ targetDir, repoRoot, indexIbGib });
210
- const activeWorktreeDir = branchName === 'main' ? repoRoot : path.join(repoRoot, 'b', branchName);
211
-
212
- const { space: activeBranchSpace } = await getOrCreateBranchSpace({
213
- metaspace,
214
- vcsPath,
215
- branchName,
216
- });
217
-
218
- const stagedMap = new Map<string, B2tFSStagedItemRecord>();
219
- const indexStagedPaths = indexIbGib?.data?.stagedPaths || {};
220
- for (const [relPath, itemRec] of Object.entries(indexStagedPaths)) {
221
- stagedMap.set(relPath, itemRec);
222
- }
223
-
224
- let rootItemAddr: string | undefined;
225
- const branchAddrs = [
226
- ...(indexIbGib?.rel8ns?.branch || []),
227
- ...(indexIbGib?.rel8ns?.branch_tjp || []),
228
- ];
229
-
230
- if (branchAddrs.length > 0) {
231
- let branchIbGibs: B2tFSBranchIbGib_V1[] = [];
232
- for (const bAddr of branchAddrs) {
233
- const bIbGib = await getIbGibWithMetaspaceFallback({
234
- addr: bAddr,
235
- space: activeBranchSpace,
236
- metaspace,
237
- });
238
- if (bIbGib) {
239
- branchIbGibs.push(bIbGib as B2tFSBranchIbGib_V1);
240
- }
241
- }
242
-
243
- const activeBranchIbGib = branchIbGibs.find(
244
- (b) => (b as B2tFSBranchIbGib_V1)?.data?.name === branchName,
245
- ) as B2tFSBranchIbGib_V1 || (branchIbGibs.at(0) as B2tFSBranchIbGib_V1);
246
-
247
- rootItemAddr = activeBranchIbGib?.rel8ns?.b2tFS_item?.at(0) || activeBranchIbGib?.rel8ns?.b2tfs_item?.at(0);
248
- }
249
-
250
- let filterPatterns: string[] = [];
251
- const ignorePath = path.join(activeWorktreeDir, '.ibgibignore');
252
- try {
253
- const ignoreContent = await fs.readFile(ignorePath, 'utf8');
254
- filterPatterns = parseFilterFileContent(ignoreContent);
255
- } catch {
256
- // Ignore file missing is fine
257
- }
258
-
259
- const branchItemsMap = new Map<string, { relPath: string; fileHash?: string; fsType: 'file' | 'folder' }>();
260
- if (rootItemAddr) {
261
- const rootItem = await getIbGibWithMetaspaceFallback({
262
- addr: rootItemAddr,
263
- space: activeBranchSpace,
264
- metaspace,
265
- }) as B2tFSItemIbGib_V1;
266
-
267
- if (rootItem) {
268
- await walkBranchGraph({
269
- item: rootItem,
270
- space: activeBranchSpace,
271
- metaspace,
272
- currentRelPath: '',
273
- outMap: branchItemsMap,
274
- });
275
- }
276
- }
277
-
278
- const physicalItemsMap = new Map<string, { relPath: string; fullPath: string; isDirectory: boolean; fileHash?: string }>();
279
- const rawCommentFiles: Array<{ relPath: string; fullPath: string; parentRelPath: string; filename: string }> = [];
280
-
281
- await scanPhysicalWorkspace({
282
- dirPath: activeWorktreeDir,
283
- baseDir: activeWorktreeDir,
284
- vcsFolderName,
285
- filterPatterns,
286
- outSourceMap: physicalItemsMap,
287
- outCommentFiles: rawCommentFiles,
288
- });
289
-
290
- const staged: VcsStatusItem[] = [];
291
- const modified: VcsStatusItem[] = [];
292
- const deleted: VcsStatusItem[] = [];
293
- const untracked: VcsStatusItem[] = [];
294
-
295
- for (const [relPath, stagedRec] of stagedMap.entries()) {
296
- staged.push({
297
- path: relPath,
298
- fsType: stagedRec.fsType || 'file',
299
- status: 'staged',
300
- });
301
- }
302
-
303
- for (const [relPath, physItem] of physicalItemsMap.entries()) {
304
- if (stagedMap.has(relPath)) {
305
- continue;
306
- }
307
-
308
- const branchItem = branchItemsMap.get(relPath);
309
- if (!branchItem) {
310
- untracked.push({
311
- path: relPath,
312
- fsType: physItem.isDirectory ? 'folder' : 'file',
313
- status: 'untracked',
314
- });
315
- } else {
316
- if (!physItem.isDirectory && physItem.fileHash && branchItem.fileHash && physItem.fileHash !== branchItem.fileHash) {
317
- modified.push({
318
- path: relPath,
319
- fsType: 'file',
320
- status: 'modified',
321
- });
322
- }
323
- }
324
- }
325
-
326
- for (const [relPath, branchItem] of branchItemsMap.entries()) {
327
- if (!relPath || relPath === '.' || relPath === '') { continue; }
328
- if (!physicalItemsMap.has(relPath) && !stagedMap.has(relPath)) {
329
- deleted.push({
330
- path: relPath,
331
- fsType: branchItem.fsType,
332
- status: 'deleted',
333
- });
334
- }
335
- }
336
-
337
- // Map raw comment files to targets (file or folder)
338
- const pendingComments: PendingCommentInfo[] = [];
339
- for (const raw of rawCommentFiles) {
340
- const topicName = extractCommentTopicName(raw.filename);
341
- const candidateFileRelPath = raw.parentRelPath ? `${raw.parentRelPath}/${topicName}` : topicName;
342
-
343
- let targetType: 'file' | 'folder' = 'folder';
344
- let targetRelPath = raw.parentRelPath;
345
-
346
- if (physicalItemsMap.has(candidateFileRelPath) && !physicalItemsMap.get(candidateFileRelPath)?.isDirectory) {
347
- targetType = 'file';
348
- targetRelPath = candidateFileRelPath;
349
- } else if (branchItemsMap.has(candidateFileRelPath) && branchItemsMap.get(candidateFileRelPath)?.fsType === 'file') {
350
- targetType = 'file';
351
- targetRelPath = candidateFileRelPath;
352
- } else if (stagedMap.has(candidateFileRelPath)) {
353
- targetType = 'file';
354
- targetRelPath = candidateFileRelPath;
355
- }
356
-
357
- let content = '';
358
- try {
359
- content = await fs.readFile(raw.fullPath, 'utf8');
360
- } catch {
361
- // Unreadable comment file
362
- }
363
-
364
- pendingComments.push({
365
- commentRelPath: raw.relPath,
366
- commentFullPath: raw.fullPath,
367
- targetRelPath,
368
- targetType,
369
- topicName,
370
- content,
371
- });
372
- }
373
-
374
- return {
375
- branchName,
376
- activeWorktreeDir,
377
- staged,
378
- modified,
379
- deleted,
380
- untracked,
381
- pendingComments,
382
- };
383
- }