ultracode 5.3.0 → 5.5.0

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 (57) hide show
  1. package/dist/chunks/analysis-tool-handlers-H2RXLDPX.js +817 -0
  2. package/dist/chunks/analysis-tool-handlers-RJZAR6VT.js +817 -0
  3. package/dist/chunks/analysis-tool-handlers-Z2RF24T7.js +13 -0
  4. package/dist/chunks/autodoc-tool-handlers-CV5JEQUA.js +1112 -0
  5. package/dist/chunks/autodoc-tool-handlers-EHTNCH6I.js +1112 -0
  6. package/dist/chunks/autodoc-tool-handlers-MECXQJ2K.js +138 -0
  7. package/dist/chunks/chaos-CO7TOBOJ.js +18 -0
  8. package/dist/chunks/chaos-VM2PXERO.js +1573 -0
  9. package/dist/chunks/chaos-W3XRVJ7K.js +1564 -0
  10. package/dist/chunks/chunk-6K37BWK5.js +439 -0
  11. package/dist/chunks/chunk-EALTCYHZ.js +10 -0
  12. package/dist/chunks/chunk-FTBE7VMY.js +316 -0
  13. package/dist/chunks/chunk-KBW6LRQP.js +322 -0
  14. package/dist/chunks/chunk-NKUHX4CU.js +5 -0
  15. package/dist/chunks/chunk-NZFF4DQ4.js +3179 -0
  16. package/dist/chunks/chunk-RGP5UVQ7.js +3179 -0
  17. package/dist/chunks/chunk-RMZXFGQZ.js +322 -0
  18. package/dist/chunks/chunk-UG44F23Y.js +316 -0
  19. package/dist/chunks/chunk-V2SCB5H5.js +4403 -0
  20. package/dist/chunks/chunk-V6JAQNM3.js +1 -0
  21. package/dist/chunks/chunk-XFGXM4CR.js +4403 -0
  22. package/dist/chunks/dev-agent-JVIGBMHQ.js +1 -0
  23. package/dist/chunks/dev-agent-TRVP5U6N.js +1624 -0
  24. package/dist/chunks/dev-agent-Y5G5WKQ4.js +1624 -0
  25. package/dist/chunks/graph-storage-factory-AYZ57YSL.js +13 -0
  26. package/dist/chunks/graph-storage-factory-GTAIJEI5.js +1 -0
  27. package/dist/chunks/graph-storage-factory-T2WO5QVG.js +13 -0
  28. package/dist/chunks/incremental-updater-KDIQGAUU.js +14 -0
  29. package/dist/chunks/incremental-updater-OJRSTO3Q.js +1 -0
  30. package/dist/chunks/incremental-updater-SBEBH7KF.js +14 -0
  31. package/dist/chunks/indexer-agent-H3QIEL3Z.js +21 -0
  32. package/dist/chunks/indexer-agent-KHF5JMV7.js +21 -0
  33. package/dist/chunks/indexer-agent-SHJD6Z77.js +1 -0
  34. package/dist/chunks/indexing-pipeline-J6Z4BHKF.js +1 -0
  35. package/dist/chunks/indexing-pipeline-OY3337QN.js +249 -0
  36. package/dist/chunks/indexing-pipeline-WCXIDMAP.js +249 -0
  37. package/dist/chunks/merge-agent-LSUBDJB2.js +2481 -0
  38. package/dist/chunks/merge-agent-MJEW3HWU.js +2481 -0
  39. package/dist/chunks/merge-agent-O45OXF33.js +11 -0
  40. package/dist/chunks/merge-tool-handlers-BDSVNQVZ.js +277 -0
  41. package/dist/chunks/merge-tool-handlers-HP7DRBXJ.js +1 -0
  42. package/dist/chunks/merge-tool-handlers-RUJAKE3D.js +277 -0
  43. package/dist/chunks/pattern-tool-handlers-L62W3CXR.js +1549 -0
  44. package/dist/chunks/pattern-tool-handlers-SAHX2CVW.js +13 -0
  45. package/dist/chunks/query-agent-3TWDFIMT.js +191 -0
  46. package/dist/chunks/query-agent-HXQ3BMMF.js +191 -0
  47. package/dist/chunks/query-agent-USMC2GNG.js +1 -0
  48. package/dist/chunks/semantic-agent-MQCAWIAB.js +6381 -0
  49. package/dist/chunks/semantic-agent-NDGR3NAK.js +6381 -0
  50. package/dist/chunks/semantic-agent-S4ZL6GZC.js +137 -0
  51. package/dist/index.js +17 -17
  52. package/dist/roslyn-addon/.build-hash +1 -1
  53. package/dist/roslyn-addon/ILGPU.Algorithms.dll +0 -0
  54. package/dist/roslyn-addon/ILGPU.dll +0 -0
  55. package/dist/roslyn-addon/UltraCode.CSharp.deps.json +35 -0
  56. package/dist/roslyn-addon/UltraCode.CSharp.dll +0 -0
  57. package/package.json +1 -1
@@ -0,0 +1,322 @@
1
+ import { init_logging, log } from './chunk-VCCBEJQ5.js';
2
+
3
+ // src/core/di-container.ts
4
+ init_logging();
5
+ var DIContainer = class _DIContainer {
6
+ services = /* @__PURE__ */ new Map();
7
+ resolutionStack = /* @__PURE__ */ new Set();
8
+ disposed = false;
9
+ constructor() {
10
+ this.registerInstance("DIContainer", this);
11
+ }
12
+ /**
13
+ * Register a service with factory function
14
+ */
15
+ register(name, factory, lifetime = "singleton" /* SINGLETON */, dependencies = []) {
16
+ this.ensureNotDisposed();
17
+ if (this.services.has(name)) {
18
+ throw new Error(`Service '${name}' is already registered`);
19
+ }
20
+ const descriptor = {
21
+ name,
22
+ factory,
23
+ lifetime,
24
+ dependencies
25
+ };
26
+ this.services.set(name, descriptor);
27
+ log.i("DICONTAINER", "svc_registered", { name, lifetime });
28
+ }
29
+ /**
30
+ * Register a singleton service (convenience method)
31
+ */
32
+ registerSingleton(name, factory, dependencies = []) {
33
+ this.register(name, factory, "singleton" /* SINGLETON */, dependencies);
34
+ }
35
+ /**
36
+ * Register a transient service (convenience method)
37
+ */
38
+ registerTransient(name, factory, dependencies = []) {
39
+ this.register(name, factory, "transient" /* TRANSIENT */, dependencies);
40
+ }
41
+ /**
42
+ * Register an existing instance as singleton
43
+ */
44
+ registerInstance(name, instance) {
45
+ this.ensureNotDisposed();
46
+ if (this.services.has(name)) {
47
+ throw new Error(`Service '${name}' is already registered`);
48
+ }
49
+ const descriptor = {
50
+ name,
51
+ factory: () => instance,
52
+ lifetime: "singleton" /* SINGLETON */,
53
+ instance
54
+ };
55
+ this.services.set(name, descriptor);
56
+ log.i("DICONTAINER", "inst_registered", { name });
57
+ }
58
+ /**
59
+ * Update an existing singleton instance (useful for project context switches)
60
+ */
61
+ updateInstance(name, instance) {
62
+ this.ensureNotDisposed();
63
+ const descriptor = this.services.get(name);
64
+ if (!descriptor) {
65
+ this.registerInstance(name, instance);
66
+ return;
67
+ }
68
+ if (descriptor.lifetime !== "singleton" /* SINGLETON */) {
69
+ throw new Error(`Cannot update non-singleton service '${name}'`);
70
+ }
71
+ descriptor.instance = instance;
72
+ descriptor.factory = () => instance;
73
+ log.i("DICONTAINER", "inst_updated", { name });
74
+ }
75
+ /**
76
+ * Register an agent factory
77
+ */
78
+ registerAgent(agentType, factory, dependencies = []) {
79
+ const serviceName = `Agent:${agentType}`;
80
+ this.register(serviceName, factory, "singleton" /* SINGLETON */, dependencies);
81
+ }
82
+ /**
83
+ * Resolve a service by name with circular dependency detection
84
+ */
85
+ async resolve(name) {
86
+ this.ensureNotDisposed();
87
+ const descriptor = this.services.get(name);
88
+ if (!descriptor) {
89
+ throw new Error(`Service '${name}' is not registered`);
90
+ }
91
+ if (this.resolutionStack.has(name)) {
92
+ const cycle = Array.from(this.resolutionStack).join(" -> ");
93
+ throw new Error(`Circular dependency detected: ${cycle} -> ${name}`);
94
+ }
95
+ if (descriptor.lifetime === "singleton" /* SINGLETON */ && descriptor.instance !== void 0) {
96
+ return descriptor.instance;
97
+ }
98
+ this.resolutionStack.add(name);
99
+ try {
100
+ const instance = await descriptor.factory(this);
101
+ if (descriptor.lifetime === "singleton" /* SINGLETON */) {
102
+ descriptor.instance = instance;
103
+ }
104
+ return instance;
105
+ } finally {
106
+ this.resolutionStack.delete(name);
107
+ }
108
+ }
109
+ /**
110
+ * Resolve an agent by type
111
+ */
112
+ async resolveAgent(agentType) {
113
+ const serviceName = `Agent:${agentType}`;
114
+ return this.resolve(serviceName);
115
+ }
116
+ /**
117
+ * Check if service is registered
118
+ */
119
+ has(name) {
120
+ return this.services.has(name);
121
+ }
122
+ /**
123
+ * Check if agent is registered
124
+ */
125
+ hasAgent(agentType) {
126
+ return this.has(`Agent:${agentType}`);
127
+ }
128
+ /**
129
+ * Get all registered service names
130
+ */
131
+ getServiceNames() {
132
+ return Array.from(this.services.keys());
133
+ }
134
+ /**
135
+ * Get all registered agent types
136
+ */
137
+ getAgentTypes() {
138
+ const agentTypes = [];
139
+ for (const name of this.services.keys()) {
140
+ if (name.startsWith("Agent:")) {
141
+ agentTypes.push(name.slice(6));
142
+ }
143
+ }
144
+ return agentTypes;
145
+ }
146
+ /**
147
+ * Get dependency graph for a service
148
+ */
149
+ getDependencyGraph(name) {
150
+ const descriptor = this.services.get(name);
151
+ if (!descriptor) {
152
+ return [];
153
+ }
154
+ return descriptor.dependencies || [];
155
+ }
156
+ /**
157
+ * Clear all transient instances (keep singletons)
158
+ */
159
+ clearTransients() {
160
+ for (const descriptor of this.services.values()) {
161
+ if (descriptor.lifetime === "transient" /* TRANSIENT */) {
162
+ delete descriptor.instance;
163
+ }
164
+ }
165
+ log.i("DICONTAINER", "transients_cleared");
166
+ }
167
+ /**
168
+ * Clear cached agent instances (to force recreation with new context)
169
+ * Used when project context switches and agents need new SQLiteManager
170
+ */
171
+ clearAgentInstances() {
172
+ let cleared = 0;
173
+ for (const [name, descriptor] of this.services) {
174
+ if (name.startsWith("Agent:") && descriptor.instance !== void 0) {
175
+ delete descriptor.instance;
176
+ cleared++;
177
+ }
178
+ }
179
+ log.i("DICONTAINER", "agents_cleared", { count: cleared });
180
+ }
181
+ /**
182
+ * Clear all registrations (useful for testing)
183
+ */
184
+ clear() {
185
+ this.services.clear();
186
+ this.resolutionStack.clear();
187
+ this.disposed = false;
188
+ log.i("DICONTAINER", "container_cleared");
189
+ }
190
+ /**
191
+ * Dispose all services and clear container
192
+ */
193
+ async dispose() {
194
+ if (this.disposed) {
195
+ return;
196
+ }
197
+ log.i("DICONTAINER", "disposing");
198
+ this.disposed = true;
199
+ const descriptors = Array.from(this.services.values()).reverse();
200
+ for (const descriptor of descriptors) {
201
+ if (descriptor.instance && this.isDisposable(descriptor.instance)) {
202
+ try {
203
+ await descriptor.instance.dispose();
204
+ log.i("DICONTAINER", "disposed_svc", { name: descriptor.name });
205
+ } catch (error) {
206
+ log.w("DICONTAINER", "dispose_fail", { name: descriptor.name, err: String(error) });
207
+ }
208
+ }
209
+ }
210
+ this.services.clear();
211
+ this.resolutionStack.clear();
212
+ log.i("DICONTAINER", "disposed");
213
+ }
214
+ /**
215
+ * Check if object implements Disposable interface
216
+ */
217
+ isDisposable(obj) {
218
+ return obj !== null && typeof obj === "object" && "dispose" in obj && typeof obj.dispose === "function";
219
+ }
220
+ /**
221
+ * Ensure container is not disposed
222
+ */
223
+ ensureNotDisposed() {
224
+ if (this.disposed) {
225
+ throw new Error("DIContainer has been disposed");
226
+ }
227
+ }
228
+ /**
229
+ * Create a child container (scoped)
230
+ */
231
+ createScope() {
232
+ const scope = new _DIContainer();
233
+ for (const [name, descriptor] of this.services) {
234
+ if (descriptor.lifetime === "singleton" /* SINGLETON */) {
235
+ scope.services.set(name, { ...descriptor, instance: void 0 });
236
+ }
237
+ }
238
+ return scope;
239
+ }
240
+ };
241
+ var globalContainer = null;
242
+ function getGlobalContainer() {
243
+ if (!globalContainer) {
244
+ globalContainer = new DIContainer();
245
+ }
246
+ return globalContainer;
247
+ }
248
+
249
+ // src/core/agent-registry.ts
250
+ init_logging();
251
+ async function registerAllAgents(container) {
252
+ log.i("AGENTREG", "registering_all");
253
+ container.registerAgent("dev" /* DEV */, async (_c) => {
254
+ const { DevAgent } = await import('./dev-agent-Y5G5WKQ4.js');
255
+ return new DevAgent();
256
+ });
257
+ container.registerAgent("semantic" /* SEMANTIC */, async (_c) => {
258
+ const { SemanticAgent } = await import('./semantic-agent-NDGR3NAK.js');
259
+ return new SemanticAgent();
260
+ });
261
+ container.registerAgent("dora" /* DORA */, async (_c) => {
262
+ const { DoraAgent } = await import('./dora-agent-NNYRSIBQ.js');
263
+ return new DoraAgent();
264
+ });
265
+ container.registerAgent("parser" /* PARSER */, async (_c) => {
266
+ const { ParserAgent } = await import('./parser-agent-FCJ2YDLD.js');
267
+ return new ParserAgent();
268
+ });
269
+ container.registerAgent("indexer" /* INDEXER */, async (_c) => {
270
+ const { IndexerAgent } = await import('./indexer-agent-KHF5JMV7.js');
271
+ const agent = new IndexerAgent();
272
+ await agent.initialize();
273
+ return agent;
274
+ });
275
+ container.registerAgent("query" /* QUERY */, async (_c) => {
276
+ const { QueryAgent } = await import('./query-agent-HXQ3BMMF.js');
277
+ return new QueryAgent();
278
+ });
279
+ container.registerAgent("merge" /* MERGE */, async (_c) => {
280
+ const { MergeAgent } = await import('./merge-agent-LSUBDJB2.js');
281
+ let repoPath = process.cwd();
282
+ let branchManager;
283
+ try {
284
+ const config = await _c.resolve("Config");
285
+ if (config?.directory) {
286
+ repoPath = config.directory;
287
+ }
288
+ } catch {
289
+ }
290
+ try {
291
+ branchManager = await _c.resolve("BranchManager");
292
+ } catch {
293
+ }
294
+ return new MergeAgent({
295
+ repoPath,
296
+ fastPathEnabled: true,
297
+ semanticMatchingEnabled: true,
298
+ semanticThreshold: 0.7,
299
+ autoResolveConflicts: false,
300
+ branchManager
301
+ });
302
+ });
303
+ log.i("AGENTREG", "all_registered");
304
+ }
305
+ async function getOrCreateAgent(container, conductor, agentType) {
306
+ const existing = conductor.getAgentsByType(agentType);
307
+ if (existing.length > 0) {
308
+ return existing[0];
309
+ }
310
+ if (!container.hasAgent(agentType)) {
311
+ throw new Error(`Agent ${agentType} is not registered in DI container`);
312
+ }
313
+ const agent = await container.resolveAgent(agentType);
314
+ await agent.initialize();
315
+ log.i("AGENTREG", "agent_init", { type: agentType });
316
+ conductor.register(agent);
317
+ return agent;
318
+ }
319
+
320
+ export { getGlobalContainer, getOrCreateAgent, registerAllAgents };
321
+ //# sourceMappingURL=chunk-RMZXFGQZ.js.map
322
+ //# sourceMappingURL=chunk-RMZXFGQZ.js.map
@@ -0,0 +1,316 @@
1
+ import { getGraphStorage } from './chunk-XFGXM4CR.js';
2
+ import { existsSync, readFileSync, writeFileSync } from 'fs';
3
+ import path from 'path';
4
+
5
+ function extractReferences(content) {
6
+ const refs = [];
7
+ const fileLinePattern = /(?:`([^`]+\.(?:ts|js|tsx|jsx|py|go|rs|java|kt|swift|cpp|c|h)):(\d+)`|([a-zA-Z0-9_\-/.]+\.(?:ts|js|tsx|jsx|py|go|rs|java|kt|swift|cpp|c|h)):(\d+))/g;
8
+ let match;
9
+ while ((match = fileLinePattern.exec(content)) !== null) {
10
+ const filePath = match[1] || match[3];
11
+ const lineNum = match[2] || match[4];
12
+ if (filePath && lineNum) {
13
+ refs.push({
14
+ original: match[0],
15
+ filePath,
16
+ lineNumber: parseInt(lineNum, 10),
17
+ startIndex: match.index,
18
+ endIndex: match.index + match[0].length
19
+ });
20
+ }
21
+ }
22
+ const mdLinkPattern = /\[([^\]]+)\]\(([^)]+\.(?:ts|js|tsx|jsx|py|go|rs|java|kt|swift|cpp|c|h))(?:#L(\d+))?\)/g;
23
+ while ((match = mdLinkPattern.exec(content)) !== null) {
24
+ const mdFilePath = match[2];
25
+ if (mdFilePath) {
26
+ refs.push({
27
+ original: match[0],
28
+ filePath: mdFilePath,
29
+ lineNumber: match[3] ? parseInt(match[3], 10) : void 0,
30
+ startIndex: match.index,
31
+ endIndex: match.index + match[0].length
32
+ });
33
+ }
34
+ }
35
+ return refs;
36
+ }
37
+ function extractSections(content) {
38
+ const lines = content.split("\n");
39
+ const sections = [];
40
+ let currentSection = null;
41
+ let contentLines = [];
42
+ for (let i = 0; i < lines.length; i++) {
43
+ const line = lines[i] ?? "";
44
+ const headerMatch = line.match(/^(#{1,6})\s+(.+)$/);
45
+ if (headerMatch?.[2]) {
46
+ if (currentSection) {
47
+ currentSection.content = contentLines.join("\n");
48
+ currentSection.endLine = i - 1;
49
+ sections.push(currentSection);
50
+ }
51
+ currentSection = {
52
+ title: headerMatch[2],
53
+ content: "",
54
+ startLine: i,
55
+ endLine: i,
56
+ relatedEntities: []
57
+ };
58
+ contentLines = [];
59
+ } else if (currentSection) {
60
+ contentLines.push(line);
61
+ const entityRefs = line.match(/`([A-Z][a-zA-Z0-9_]+)`/g);
62
+ if (entityRefs) {
63
+ for (const ref of entityRefs) {
64
+ const name = ref.slice(1, -1);
65
+ if (!currentSection.relatedEntities.includes(name)) {
66
+ currentSection.relatedEntities.push(name);
67
+ }
68
+ }
69
+ }
70
+ }
71
+ }
72
+ if (currentSection) {
73
+ currentSection.content = contentLines.join("\n");
74
+ currentSection.endLine = lines.length - 1;
75
+ sections.push(currentSection);
76
+ }
77
+ return sections;
78
+ }
79
+ async function detectChanges(modulePath, existingDoc, currentEntities) {
80
+ const changes = [];
81
+ const refs = extractReferences(existingDoc);
82
+ const sections = extractSections(existingDoc);
83
+ const documentedEntities = /* @__PURE__ */ new Set();
84
+ for (const section of sections) {
85
+ for (const entity of section.relatedEntities) {
86
+ documentedEntities.add(entity);
87
+ }
88
+ }
89
+ const entityPattern = /`([A-Z][a-zA-Z0-9_]+)`/g;
90
+ let match;
91
+ while ((match = entityPattern.exec(existingDoc)) !== null) {
92
+ if (match[1]) {
93
+ documentedEntities.add(match[1]);
94
+ }
95
+ }
96
+ for (const entity of currentEntities) {
97
+ if (!documentedEntities.has(entity.name)) {
98
+ changes.push({
99
+ type: "added",
100
+ entityId: entity.id,
101
+ entityName: entity.name,
102
+ entityType: entity.type,
103
+ filePath: entity.filePath,
104
+ newLineNumber: entity.location?.start?.line,
105
+ timestamp: /* @__PURE__ */ new Date()
106
+ });
107
+ }
108
+ }
109
+ const currentEntityNames = new Set(currentEntities.map((e) => e.name));
110
+ for (const docEntity of documentedEntities) {
111
+ if (!currentEntityNames.has(docEntity)) {
112
+ changes.push({
113
+ type: "deleted",
114
+ entityName: docEntity,
115
+ entityType: "unknown",
116
+ filePath: modulePath,
117
+ timestamp: /* @__PURE__ */ new Date()
118
+ });
119
+ }
120
+ }
121
+ for (const ref of refs) {
122
+ if (ref.lineNumber && ref.entityName) {
123
+ const entity = currentEntities.find((e) => e.name === ref.entityName);
124
+ if (entity && entity.location?.start?.line !== ref.lineNumber) {
125
+ changes.push({
126
+ type: "moved",
127
+ entityId: entity.id,
128
+ entityName: entity.name,
129
+ entityType: entity.type,
130
+ filePath: entity.filePath,
131
+ oldLineNumber: ref.lineNumber,
132
+ newLineNumber: entity.location?.start?.line,
133
+ timestamp: /* @__PURE__ */ new Date()
134
+ });
135
+ }
136
+ }
137
+ }
138
+ return changes;
139
+ }
140
+ function updateReferences(content, changes) {
141
+ let updated = content;
142
+ const lineUpdates = /* @__PURE__ */ new Map();
143
+ for (const change of changes) {
144
+ if (change.type === "moved" && change.oldLineNumber && change.newLineNumber) {
145
+ const key = `${change.filePath}:${change.oldLineNumber}`;
146
+ lineUpdates.set(key, { old: change.oldLineNumber, new: change.newLineNumber });
147
+ }
148
+ }
149
+ const fileLinePattern = /(`[^`]+\.(?:ts|js|tsx|jsx)):(\d+)`/g;
150
+ updated = updated.replace(fileLinePattern, (match, filePart, lineNum) => {
151
+ const line = parseInt(lineNum, 10);
152
+ for (const [key, update] of lineUpdates) {
153
+ if (key.endsWith(`:${line}`)) {
154
+ return `${filePart}:${update.new}\``;
155
+ }
156
+ }
157
+ return match;
158
+ });
159
+ const mdLinkPattern = /(\[[^\]]+\]\([^)]+\.(?:ts|js|tsx|jsx))#L(\d+)\)/g;
160
+ updated = updated.replace(mdLinkPattern, (match, linkPart, lineNum) => {
161
+ const line = parseInt(lineNum, 10);
162
+ for (const [key, update] of lineUpdates) {
163
+ if (key.endsWith(`:${line}`)) {
164
+ return `${linkPart}#L${update.new})`;
165
+ }
166
+ }
167
+ return match;
168
+ });
169
+ return updated;
170
+ }
171
+ function mergeWithExisting(existingContent, newContent, changes) {
172
+ const existingSections = extractSections(existingContent);
173
+ const newSections = extractSections(newContent);
174
+ const result = [];
175
+ const processedNewSections = /* @__PURE__ */ new Set();
176
+ for (const existingSection of existingSections) {
177
+ const newSection = newSections.find((s) => s.title === existingSection.title);
178
+ if (newSection) {
179
+ processedNewSections.add(newSection.title);
180
+ const addedEntities = changes.filter((c) => c.type === "added").map((c) => c.entityName);
181
+ if (addedEntities.length > 0 && existingSection.title.toLowerCase().includes("export")) {
182
+ result.push(`## ${existingSection.title}`);
183
+ result.push(existingSection.content);
184
+ result.push("");
185
+ result.push("### Added");
186
+ result.push("");
187
+ for (const entity of addedEntities) {
188
+ result.push(`- \`${entity}\` *(added ${(/* @__PURE__ */ new Date()).toISOString().split("T")[0]})*`);
189
+ }
190
+ result.push("");
191
+ } else {
192
+ result.push(`## ${existingSection.title}`);
193
+ result.push(existingSection.content);
194
+ }
195
+ } else {
196
+ result.push(`## ${existingSection.title}`);
197
+ result.push(existingSection.content);
198
+ }
199
+ }
200
+ for (const newSection of newSections) {
201
+ if (!processedNewSections.has(newSection.title)) {
202
+ const existsInOriginal = existingSections.some((s) => s.title === newSection.title);
203
+ if (!existsInOriginal) {
204
+ result.push("");
205
+ result.push(`## ${newSection.title}`);
206
+ result.push(newSection.content);
207
+ }
208
+ }
209
+ }
210
+ return result.join("\n");
211
+ }
212
+ function markDeleted(content, deletedEntities) {
213
+ if (deletedEntities.length === 0) return content;
214
+ let updated = content;
215
+ if (!updated.includes("## Deprecated") && !updated.includes("## Deleted")) {
216
+ const timestamp = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
217
+ const deletedSection = ["", "## Deleted", "", "*The following items were removed from the codebase:*", ""];
218
+ for (const deleted of deletedEntities) {
219
+ deletedSection.push(`- ~~\`${deleted.entityName}\`~~ *(removed ${timestamp})*`);
220
+ }
221
+ deletedSection.push("");
222
+ updated += deletedSection.join("\n");
223
+ } else {
224
+ const timestamp = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
225
+ const insertPoint = updated.indexOf("## Deleted");
226
+ if (insertPoint !== -1) {
227
+ const afterHeader = updated.indexOf("\n\n", insertPoint) + 2;
228
+ const newItems = deletedEntities.map((d) => `- ~~\`${d.entityName}\`~~ *(removed ${timestamp})*`).join("\n");
229
+ updated = updated.slice(0, afterHeader) + newItems + "\n" + updated.slice(afterHeader);
230
+ }
231
+ }
232
+ for (const deleted of deletedEntities) {
233
+ const pattern = new RegExp(`\`${deleted.entityName}\`(?![^~]*~~)`, "g");
234
+ updated = updated.replace(pattern, `~~\`${deleted.entityName}\`~~`);
235
+ }
236
+ return updated;
237
+ }
238
+ async function updateModuleDoc(modulePath, docPath, newContent, options = {}) {
239
+ const result = {
240
+ docPath,
241
+ updated: false,
242
+ changes: []
243
+ };
244
+ const docExists = existsSync(docPath);
245
+ if (!docExists) {
246
+ result.updated = true;
247
+ result.newContent = newContent;
248
+ result.changes.push({
249
+ type: "created_new",
250
+ description: "Created new documentation file"
251
+ });
252
+ return result;
253
+ }
254
+ const existingContent = readFileSync(docPath, "utf-8");
255
+ const storage = await getGraphStorage();
256
+ const currentEntities = await storage.searchEntitiesInDirectory(modulePath);
257
+ const changes = await detectChanges(modulePath, existingContent, currentEntities);
258
+ if (changes.length === 0) {
259
+ return result;
260
+ }
261
+ let updatedContent = existingContent;
262
+ const movedChanges = changes.filter((c) => c.type === "moved");
263
+ if (movedChanges.length > 0) {
264
+ updatedContent = updateReferences(updatedContent, movedChanges);
265
+ result.changes.push({
266
+ type: "reference_updated",
267
+ description: `Updated ${movedChanges.length} line/file references`
268
+ });
269
+ }
270
+ const addedChanges = changes.filter((c) => c.type === "added");
271
+ if (addedChanges.length > 0) {
272
+ updatedContent = mergeWithExisting(updatedContent, newContent, addedChanges);
273
+ result.changes.push({
274
+ type: "content_added",
275
+ description: `Added documentation for ${addedChanges.length} new entities: ${addedChanges.map((c) => c.entityName).join(", ")}`
276
+ });
277
+ }
278
+ const deletedChanges = changes.filter((c) => c.type === "deleted");
279
+ if (deletedChanges.length > 0) {
280
+ updatedContent = markDeleted(updatedContent, deletedChanges);
281
+ result.changes.push({
282
+ type: "content_marked_deleted",
283
+ description: `Marked ${deletedChanges.length} deleted entities: ${deletedChanges.map((c) => c.entityName).join(", ")}`
284
+ });
285
+ }
286
+ if (options.useLlm && options.llmEnhancer && addedChanges.length > 0) {
287
+ updatedContent = await options.llmEnhancer(updatedContent, addedChanges);
288
+ }
289
+ if (updatedContent !== existingContent) {
290
+ result.updated = true;
291
+ result.newContent = updatedContent;
292
+ }
293
+ return result;
294
+ }
295
+ async function updateAllModuleDocs(rootDir, options = {}) {
296
+ const results = [];
297
+ const { scanModules, generateModuleReadme } = await import('./doc-generator-RMUSNK3G.js');
298
+ const modules = await scanModules(rootDir);
299
+ for (const mod of modules) {
300
+ const docPath = path.join(mod.path, "AUTODOC.md");
301
+ const newContent = generateModuleReadme(mod);
302
+ const result = await updateModuleDoc(mod.path, docPath, newContent, {
303
+ useLlm: options.useLlm,
304
+ llmEnhancer: options.llmEnhancer
305
+ });
306
+ if (result.updated && !options.preview && result.newContent) {
307
+ writeFileSync(docPath, result.newContent, "utf-8");
308
+ }
309
+ results.push(result);
310
+ }
311
+ return results;
312
+ }
313
+
314
+ export { detectChanges, extractReferences, extractSections, markDeleted, mergeWithExisting, updateAllModuleDocs, updateModuleDoc, updateReferences };
315
+ //# sourceMappingURL=chunk-UG44F23Y.js.map
316
+ //# sourceMappingURL=chunk-UG44F23Y.js.map