@sudocode-ai/local-server 0.1.14 → 0.1.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 (74) hide show
  1. package/dist/execution/adapters/claude-adapter.d.ts.map +1 -1
  2. package/dist/execution/adapters/claude-adapter.js +1 -0
  3. package/dist/execution/adapters/claude-adapter.js.map +1 -1
  4. package/dist/execution/executors/agent-executor-wrapper.d.ts +1 -0
  5. package/dist/execution/executors/agent-executor-wrapper.d.ts.map +1 -1
  6. package/dist/execution/executors/agent-executor-wrapper.js +2 -0
  7. package/dist/execution/executors/agent-executor-wrapper.js.map +1 -1
  8. package/dist/execution/process/builders/claude.d.ts.map +1 -1
  9. package/dist/execution/process/builders/claude.js +1 -0
  10. package/dist/execution/process/builders/claude.js.map +1 -1
  11. package/dist/execution/worktree/manager.d.ts +19 -0
  12. package/dist/execution/worktree/manager.d.ts.map +1 -1
  13. package/dist/execution/worktree/manager.js +50 -0
  14. package/dist/execution/worktree/manager.js.map +1 -1
  15. package/dist/index.d.ts.map +1 -1
  16. package/dist/index.js +7 -0
  17. package/dist/index.js.map +1 -1
  18. package/dist/public/assets/index-D4AKx6EO.css +1 -0
  19. package/dist/public/assets/index-DorQqwGV.js +927 -0
  20. package/dist/public/assets/{index-3qSRtUlY.js.map → index-DorQqwGV.js.map} +1 -1
  21. package/dist/public/assets/{react-vendor-5f1Wq1qs.js → react-vendor-DoNwlLhy.js} +2 -2
  22. package/dist/public/assets/{react-vendor-5f1Wq1qs.js.map → react-vendor-DoNwlLhy.js.map} +1 -1
  23. package/dist/public/assets/{ui-vendor-BuU3mq4G.js → ui-vendor-DlxvBun1.js} +2 -2
  24. package/dist/public/assets/{ui-vendor-BuU3mq4G.js.map → ui-vendor-DlxvBun1.js.map} +1 -1
  25. package/dist/public/index.html +4 -4
  26. package/dist/routes/executions.d.ts.map +1 -1
  27. package/dist/routes/executions.js +89 -0
  28. package/dist/routes/executions.js.map +1 -1
  29. package/dist/routes/feedback.d.ts.map +1 -1
  30. package/dist/routes/feedback.js +5 -4
  31. package/dist/routes/feedback.js.map +1 -1
  32. package/dist/routes/import.d.ts +142 -0
  33. package/dist/routes/import.d.ts.map +1 -0
  34. package/dist/routes/import.js +896 -0
  35. package/dist/routes/import.js.map +1 -0
  36. package/dist/routes/issues.d.ts.map +1 -1
  37. package/dist/routes/issues.js +102 -0
  38. package/dist/routes/issues.js.map +1 -1
  39. package/dist/routes/plugins.d.ts +7 -0
  40. package/dist/routes/plugins.d.ts.map +1 -1
  41. package/dist/routes/plugins.js +110 -16
  42. package/dist/routes/plugins.js.map +1 -1
  43. package/dist/routes/projects.d.ts.map +1 -1
  44. package/dist/routes/projects.js +89 -0
  45. package/dist/routes/projects.js.map +1 -1
  46. package/dist/routes/specs.d.ts.map +1 -1
  47. package/dist/routes/specs.js +133 -5
  48. package/dist/routes/specs.js.map +1 -1
  49. package/dist/routes/update.d.ts +7 -0
  50. package/dist/routes/update.d.ts.map +1 -0
  51. package/dist/routes/update.js +194 -0
  52. package/dist/routes/update.js.map +1 -0
  53. package/dist/services/execution-changes-service.d.ts.map +1 -1
  54. package/dist/services/execution-changes-service.js +17 -7
  55. package/dist/services/execution-changes-service.js.map +1 -1
  56. package/dist/services/execution-service.d.ts +41 -0
  57. package/dist/services/execution-service.d.ts.map +1 -1
  58. package/dist/services/execution-service.js +312 -40
  59. package/dist/services/execution-service.js.map +1 -1
  60. package/dist/services/external-refresh-service.d.ts +104 -0
  61. package/dist/services/external-refresh-service.d.ts.map +1 -0
  62. package/dist/services/external-refresh-service.js +520 -0
  63. package/dist/services/external-refresh-service.js.map +1 -0
  64. package/dist/services/repo-info.d.ts +4 -0
  65. package/dist/services/repo-info.d.ts.map +1 -1
  66. package/dist/services/repo-info.js +42 -5
  67. package/dist/services/repo-info.js.map +1 -1
  68. package/dist/utils/execFileNoThrow.d.ts +43 -0
  69. package/dist/utils/execFileNoThrow.d.ts.map +1 -0
  70. package/dist/utils/execFileNoThrow.js +53 -0
  71. package/dist/utils/execFileNoThrow.js.map +1 -0
  72. package/package.json +6 -4
  73. package/dist/public/assets/index-3qSRtUlY.js +0 -844
  74. package/dist/public/assets/index-p0337DGd.css +0 -1
@@ -0,0 +1,104 @@
1
+ /**
2
+ * Refresh Service - handles refreshing entities from external sources
3
+ *
4
+ * Provides change detection via content_hash comparison and refresh logic
5
+ * for syncing entities with their external sources.
6
+ */
7
+ import type Database from "better-sqlite3";
8
+ import type { Spec, Issue } from "@sudocode-ai/types";
9
+ /**
10
+ * Change between local and remote values for a field
11
+ */
12
+ export interface FieldChange {
13
+ field: string;
14
+ localValue: string;
15
+ remoteValue: string;
16
+ }
17
+ /**
18
+ * Result of refreshing a single entity
19
+ */
20
+ export interface RefreshResult {
21
+ updated: boolean;
22
+ hasLocalChanges: boolean;
23
+ changes?: FieldChange[];
24
+ entity?: Spec | Issue;
25
+ stale?: boolean;
26
+ error?: string;
27
+ }
28
+ /**
29
+ * Status of a bulk refresh operation for a single entity
30
+ */
31
+ export type BulkRefreshStatus = "updated" | "skipped" | "failed" | "stale";
32
+ /**
33
+ * Result for a single entity in bulk refresh
34
+ */
35
+ export interface BulkRefreshEntityResult {
36
+ entityId: string;
37
+ status: BulkRefreshStatus;
38
+ error?: string;
39
+ }
40
+ /**
41
+ * Result of bulk refresh operation
42
+ */
43
+ export interface BulkRefreshResult {
44
+ refreshed: number;
45
+ skipped: number;
46
+ failed: number;
47
+ stale: number;
48
+ results: BulkRefreshEntityResult[];
49
+ }
50
+ /**
51
+ * Compute SHA256 hash of content for change detection
52
+ * Matches the implementation in import.ts
53
+ */
54
+ export declare function computeContentHash(title: string, content: string): string;
55
+ /**
56
+ * Detect local changes by comparing current content hash with stored hash
57
+ *
58
+ * @param title - Current entity title
59
+ * @param content - Current entity content
60
+ * @param storedHash - Hash stored in external_link.content_hash
61
+ * @returns true if local changes were detected
62
+ */
63
+ export declare function detectLocalChanges(title: string, content: string, storedHash: string | undefined): boolean;
64
+ /**
65
+ * Compute field-level changes between local entity and remote entity
66
+ */
67
+ export declare function computeFieldChanges(localTitle: string, localContent: string, remoteTitle: string, remoteContent: string): FieldChange[];
68
+ /**
69
+ * Refresh a spec from its external source
70
+ *
71
+ * @param db - Database instance
72
+ * @param sudocodeDir - Path to .sudocode directory
73
+ * @param projectPath - Path to project root
74
+ * @param specId - ID of spec to refresh
75
+ * @param force - If true, skip conflict check and overwrite local changes
76
+ * @returns Refresh result
77
+ */
78
+ export declare function refreshSpec(db: Database.Database, sudocodeDir: string, projectPath: string, specId: string, force?: boolean): Promise<RefreshResult>;
79
+ /**
80
+ * Refresh an issue from its external source
81
+ *
82
+ * @param db - Database instance
83
+ * @param sudocodeDir - Path to .sudocode directory
84
+ * @param projectPath - Path to project root
85
+ * @param issueId - ID of issue to refresh
86
+ * @param force - If true, skip conflict check and overwrite local changes
87
+ * @returns Refresh result
88
+ */
89
+ export declare function refreshIssue(db: Database.Database, sudocodeDir: string, projectPath: string, issueId: string, force?: boolean): Promise<RefreshResult>;
90
+ /**
91
+ * Refresh multiple entities from their external sources
92
+ *
93
+ * @param db - Database instance
94
+ * @param sudocodeDir - Path to .sudocode directory
95
+ * @param projectPath - Path to project root
96
+ * @param options - Filter options for bulk refresh
97
+ * @returns Bulk refresh result
98
+ */
99
+ export declare function bulkRefresh(db: Database.Database, sudocodeDir: string, projectPath: string, options?: {
100
+ provider?: string;
101
+ entityIds?: string[];
102
+ force?: boolean;
103
+ }): Promise<BulkRefreshResult>;
104
+ //# sourceMappingURL=external-refresh-service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"external-refresh-service.d.ts","sourceRoot":"","sources":["../../src/services/external-refresh-service.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAC3C,OAAO,KAAK,EAGV,IAAI,EACJ,KAAK,EACN,MAAM,oBAAoB,CAAC;AAkB5B;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,OAAO,CAAC;IACjB,eAAe,EAAE,OAAO,CAAC;IACzB,OAAO,CAAC,EAAE,WAAW,EAAE,CAAC;IACxB,MAAM,CAAC,EAAE,IAAI,GAAG,KAAK,CAAC;IACtB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,MAAM,iBAAiB,GAAG,SAAS,GAAG,SAAS,GAAG,QAAQ,GAAG,OAAO,CAAC;AAE3E;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,iBAAiB,CAAC;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,uBAAuB,EAAE,CAAC;CACpC;AAMD;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAKzE;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,GAAG,SAAS,GAC7B,OAAO,CAOT;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,MAAM,EACpB,WAAW,EAAE,MAAM,EACnB,aAAa,EAAE,MAAM,GACpB,WAAW,EAAE,CAoBf;AAwGD;;;;;;;;;GASG;AACH,wBAAsB,WAAW,CAC/B,EAAE,EAAE,QAAQ,CAAC,QAAQ,EACrB,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,MAAM,EACd,KAAK,GAAE,OAAe,GACrB,OAAO,CAAC,aAAa,CAAC,CA6JxB;AAED;;;;;;;;;GASG;AACH,wBAAsB,YAAY,CAChC,EAAE,EAAE,QAAQ,CAAC,QAAQ,EACrB,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,EACf,KAAK,GAAE,OAAe,GACrB,OAAO,CAAC,aAAa,CAAC,CA6JxB;AAED;;;;;;;;GAQG;AACH,wBAAsB,WAAW,CAC/B,EAAE,EAAE,QAAQ,CAAC,QAAQ,EACrB,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,EACnB,OAAO,GAAE;IACP,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,KAAK,CAAC,EAAE,OAAO,CAAC;CACZ,GACL,OAAO,CAAC,iBAAiB,CAAC,CAqI5B"}
@@ -0,0 +1,520 @@
1
+ /**
2
+ * Refresh Service - handles refreshing entities from external sources
3
+ *
4
+ * Provides change detection via content_hash comparison and refresh logic
5
+ * for syncing entities with their external sources.
6
+ */
7
+ import { createHash } from "crypto";
8
+ import { getSpecFromJsonl, getIssueFromJsonl, } from "@sudocode-ai/cli/dist/operations/external-links.js";
9
+ import { loadPlugin, getFirstPartyPlugins, } from "@sudocode-ai/cli/dist/integrations/index.js";
10
+ import { updateExistingSpec } from "./specs.js";
11
+ import { updateExistingIssue } from "./issues.js";
12
+ import { readJSONLSync, writeJSONLSync } from "@sudocode-ai/cli/dist/jsonl.js";
13
+ import * as path from "path";
14
+ // =============================================================================
15
+ // Content Hash Utilities
16
+ // =============================================================================
17
+ /**
18
+ * Compute SHA256 hash of content for change detection
19
+ * Matches the implementation in import.ts
20
+ */
21
+ export function computeContentHash(title, content) {
22
+ const hash = createHash("sha256");
23
+ hash.update(title);
24
+ hash.update(content || "");
25
+ return hash.digest("hex");
26
+ }
27
+ /**
28
+ * Detect local changes by comparing current content hash with stored hash
29
+ *
30
+ * @param title - Current entity title
31
+ * @param content - Current entity content
32
+ * @param storedHash - Hash stored in external_link.content_hash
33
+ * @returns true if local changes were detected
34
+ */
35
+ export function detectLocalChanges(title, content, storedHash) {
36
+ if (!storedHash) {
37
+ // No stored hash means we can't detect changes - assume no local changes
38
+ return false;
39
+ }
40
+ const currentHash = computeContentHash(title, content);
41
+ return currentHash !== storedHash;
42
+ }
43
+ /**
44
+ * Compute field-level changes between local entity and remote entity
45
+ */
46
+ export function computeFieldChanges(localTitle, localContent, remoteTitle, remoteContent) {
47
+ const changes = [];
48
+ if (localTitle !== remoteTitle) {
49
+ changes.push({
50
+ field: "title",
51
+ localValue: localTitle,
52
+ remoteValue: remoteTitle,
53
+ });
54
+ }
55
+ if (localContent !== (remoteContent || "")) {
56
+ changes.push({
57
+ field: "content",
58
+ localValue: localContent,
59
+ remoteValue: remoteContent || "",
60
+ });
61
+ }
62
+ return changes;
63
+ }
64
+ // =============================================================================
65
+ // External Link Update Utilities
66
+ // =============================================================================
67
+ /**
68
+ * Update an external link on a spec in JSONL
69
+ */
70
+ function updateSpecExternalLink(sudocodeDir, specId, externalId, updates) {
71
+ const specsPath = path.join(sudocodeDir, "specs.jsonl");
72
+ const specs = readJSONLSync(specsPath, { skipErrors: true });
73
+ const specIndex = specs.findIndex((s) => s.id === specId);
74
+ if (specIndex === -1) {
75
+ throw new Error(`Spec not found: ${specId}`);
76
+ }
77
+ const spec = specs[specIndex];
78
+ const links = spec.external_links || [];
79
+ const linkIndex = links.findIndex((l) => l.external_id === externalId);
80
+ if (linkIndex === -1) {
81
+ throw new Error(`External link not found: ${externalId}`);
82
+ }
83
+ links[linkIndex] = { ...links[linkIndex], ...updates };
84
+ spec.external_links = links;
85
+ spec.updated_at = new Date().toISOString();
86
+ specs[specIndex] = spec;
87
+ writeJSONLSync(specsPath, specs);
88
+ }
89
+ /**
90
+ * Update an external link on an issue in JSONL
91
+ */
92
+ function updateIssueExternalLink(sudocodeDir, issueId, externalId, updates) {
93
+ const issuesPath = path.join(sudocodeDir, "issues.jsonl");
94
+ const issues = readJSONLSync(issuesPath, { skipErrors: true });
95
+ const issueIndex = issues.findIndex((i) => i.id === issueId);
96
+ if (issueIndex === -1) {
97
+ throw new Error(`Issue not found: ${issueId}`);
98
+ }
99
+ const issue = issues[issueIndex];
100
+ const links = issue.external_links || [];
101
+ const linkIndex = links.findIndex((l) => l.external_id === externalId);
102
+ if (linkIndex === -1) {
103
+ throw new Error(`External link not found: ${externalId}`);
104
+ }
105
+ links[linkIndex] = { ...links[linkIndex], ...updates };
106
+ issue.external_links = links;
107
+ issue.updated_at = new Date().toISOString();
108
+ issues[issueIndex] = issue;
109
+ writeJSONLSync(issuesPath, issues);
110
+ }
111
+ // =============================================================================
112
+ // Refresh Logic
113
+ // =============================================================================
114
+ /**
115
+ * Get a provider instance for the given provider name
116
+ */
117
+ async function getProvider(providerName, projectPath) {
118
+ const firstPartyPlugins = getFirstPartyPlugins();
119
+ // Try first-party plugins
120
+ for (const p of firstPartyPlugins) {
121
+ if (p.name === providerName) {
122
+ const plugin = await loadPlugin(p.name);
123
+ if (plugin) {
124
+ return plugin.createProvider({}, projectPath);
125
+ }
126
+ }
127
+ }
128
+ // Try loading as custom plugin
129
+ const plugin = await loadPlugin(providerName);
130
+ if (plugin) {
131
+ return plugin.createProvider({}, projectPath);
132
+ }
133
+ return null;
134
+ }
135
+ /**
136
+ * Refresh a spec from its external source
137
+ *
138
+ * @param db - Database instance
139
+ * @param sudocodeDir - Path to .sudocode directory
140
+ * @param projectPath - Path to project root
141
+ * @param specId - ID of spec to refresh
142
+ * @param force - If true, skip conflict check and overwrite local changes
143
+ * @returns Refresh result
144
+ */
145
+ export async function refreshSpec(db, sudocodeDir, projectPath, specId, force = false) {
146
+ // Get spec from JSONL (includes external_links)
147
+ const spec = getSpecFromJsonl(sudocodeDir, specId);
148
+ if (!spec) {
149
+ return {
150
+ updated: false,
151
+ hasLocalChanges: false,
152
+ error: `Spec not found: ${specId}`,
153
+ };
154
+ }
155
+ // Check for external links
156
+ const externalLinks = spec.external_links || [];
157
+ if (externalLinks.length === 0) {
158
+ return {
159
+ updated: false,
160
+ hasLocalChanges: false,
161
+ error: "Spec has no external links",
162
+ };
163
+ }
164
+ // Use the first sync-enabled inbound link
165
+ const link = externalLinks.find((l) => l.sync_enabled &&
166
+ (l.sync_direction === "inbound" || l.sync_direction === "bidirectional"));
167
+ if (!link) {
168
+ return {
169
+ updated: false,
170
+ hasLocalChanges: false,
171
+ error: "No sync-enabled inbound external link found",
172
+ };
173
+ }
174
+ // Get provider
175
+ const provider = await getProvider(link.provider, projectPath);
176
+ if (!provider) {
177
+ return {
178
+ updated: false,
179
+ hasLocalChanges: false,
180
+ error: `Provider not found: ${link.provider}`,
181
+ };
182
+ }
183
+ try {
184
+ await provider.initialize();
185
+ // Fetch fresh entity from provider
186
+ const remoteEntity = await provider.fetchEntity(link.external_id);
187
+ // Handle stale/deleted entity
188
+ if (!remoteEntity) {
189
+ // Mark link as stale but don't delete local entity
190
+ updateSpecExternalLink(sudocodeDir, specId, link.external_id, {
191
+ sync_enabled: false,
192
+ metadata: {
193
+ ...link.metadata,
194
+ stale: true,
195
+ stale_reason: "external_entity_not_found",
196
+ stale_at: new Date().toISOString(),
197
+ },
198
+ });
199
+ return {
200
+ updated: false,
201
+ hasLocalChanges: false,
202
+ stale: true,
203
+ error: "External entity no longer exists",
204
+ };
205
+ }
206
+ // Check for local changes
207
+ const hasLocalChanges = detectLocalChanges(spec.title, spec.content || "", link.content_hash);
208
+ // If local changes exist and not forcing, return preview
209
+ if (hasLocalChanges && !force) {
210
+ const changes = computeFieldChanges(spec.title, spec.content || "", remoteEntity.title, remoteEntity.description || "");
211
+ return {
212
+ updated: false,
213
+ hasLocalChanges: true,
214
+ changes,
215
+ };
216
+ }
217
+ // Update spec with remote data
218
+ const newContentHash = computeContentHash(remoteEntity.title, remoteEntity.description || "");
219
+ const now = new Date().toISOString();
220
+ // Update in database
221
+ const updatedSpec = updateExistingSpec(db, specId, {
222
+ title: remoteEntity.title,
223
+ content: remoteEntity.description || "",
224
+ });
225
+ // Update external link metadata in JSONL
226
+ updateSpecExternalLink(sudocodeDir, specId, link.external_id, {
227
+ content_hash: newContentHash,
228
+ last_synced_at: now,
229
+ external_updated_at: remoteEntity.updated_at,
230
+ });
231
+ return {
232
+ updated: true,
233
+ hasLocalChanges: false,
234
+ entity: updatedSpec,
235
+ };
236
+ }
237
+ catch (error) {
238
+ const errorMessage = error instanceof Error ? error.message : String(error);
239
+ // Check for 404-like errors indicating stale entity
240
+ if (errorMessage.includes("404") ||
241
+ errorMessage.includes("not found") ||
242
+ errorMessage.includes("Not Found")) {
243
+ updateSpecExternalLink(sudocodeDir, specId, link.external_id, {
244
+ sync_enabled: false,
245
+ metadata: {
246
+ ...link.metadata,
247
+ stale: true,
248
+ stale_reason: "fetch_failed_404",
249
+ stale_at: new Date().toISOString(),
250
+ },
251
+ });
252
+ return {
253
+ updated: false,
254
+ hasLocalChanges: false,
255
+ stale: true,
256
+ error: "External entity no longer exists",
257
+ };
258
+ }
259
+ return {
260
+ updated: false,
261
+ hasLocalChanges: false,
262
+ error: `Refresh failed: ${errorMessage}`,
263
+ };
264
+ }
265
+ finally {
266
+ await provider.dispose();
267
+ }
268
+ }
269
+ /**
270
+ * Refresh an issue from its external source
271
+ *
272
+ * @param db - Database instance
273
+ * @param sudocodeDir - Path to .sudocode directory
274
+ * @param projectPath - Path to project root
275
+ * @param issueId - ID of issue to refresh
276
+ * @param force - If true, skip conflict check and overwrite local changes
277
+ * @returns Refresh result
278
+ */
279
+ export async function refreshIssue(db, sudocodeDir, projectPath, issueId, force = false) {
280
+ // Get issue from JSONL (includes external_links)
281
+ const issue = getIssueFromJsonl(sudocodeDir, issueId);
282
+ if (!issue) {
283
+ return {
284
+ updated: false,
285
+ hasLocalChanges: false,
286
+ error: `Issue not found: ${issueId}`,
287
+ };
288
+ }
289
+ // Check for external links
290
+ const externalLinks = issue.external_links || [];
291
+ if (externalLinks.length === 0) {
292
+ return {
293
+ updated: false,
294
+ hasLocalChanges: false,
295
+ error: "Issue has no external links",
296
+ };
297
+ }
298
+ // Use the first sync-enabled inbound link
299
+ const link = externalLinks.find((l) => l.sync_enabled &&
300
+ (l.sync_direction === "inbound" || l.sync_direction === "bidirectional"));
301
+ if (!link) {
302
+ return {
303
+ updated: false,
304
+ hasLocalChanges: false,
305
+ error: "No sync-enabled inbound external link found",
306
+ };
307
+ }
308
+ // Get provider
309
+ const provider = await getProvider(link.provider, projectPath);
310
+ if (!provider) {
311
+ return {
312
+ updated: false,
313
+ hasLocalChanges: false,
314
+ error: `Provider not found: ${link.provider}`,
315
+ };
316
+ }
317
+ try {
318
+ await provider.initialize();
319
+ // Fetch fresh entity from provider
320
+ const remoteEntity = await provider.fetchEntity(link.external_id);
321
+ // Handle stale/deleted entity
322
+ if (!remoteEntity) {
323
+ // Mark link as stale but don't delete local entity
324
+ updateIssueExternalLink(sudocodeDir, issueId, link.external_id, {
325
+ sync_enabled: false,
326
+ metadata: {
327
+ ...link.metadata,
328
+ stale: true,
329
+ stale_reason: "external_entity_not_found",
330
+ stale_at: new Date().toISOString(),
331
+ },
332
+ });
333
+ return {
334
+ updated: false,
335
+ hasLocalChanges: false,
336
+ stale: true,
337
+ error: "External entity no longer exists",
338
+ };
339
+ }
340
+ // Check for local changes
341
+ const hasLocalChanges = detectLocalChanges(issue.title, issue.content || "", link.content_hash);
342
+ // If local changes exist and not forcing, return preview
343
+ if (hasLocalChanges && !force) {
344
+ const changes = computeFieldChanges(issue.title, issue.content || "", remoteEntity.title, remoteEntity.description || "");
345
+ return {
346
+ updated: false,
347
+ hasLocalChanges: true,
348
+ changes,
349
+ };
350
+ }
351
+ // Update issue with remote data
352
+ const newContentHash = computeContentHash(remoteEntity.title, remoteEntity.description || "");
353
+ const now = new Date().toISOString();
354
+ // Update in database
355
+ const updatedIssue = updateExistingIssue(db, issueId, {
356
+ title: remoteEntity.title,
357
+ content: remoteEntity.description || "",
358
+ });
359
+ // Update external link metadata in JSONL
360
+ updateIssueExternalLink(sudocodeDir, issueId, link.external_id, {
361
+ content_hash: newContentHash,
362
+ last_synced_at: now,
363
+ external_updated_at: remoteEntity.updated_at,
364
+ });
365
+ return {
366
+ updated: true,
367
+ hasLocalChanges: false,
368
+ entity: updatedIssue,
369
+ };
370
+ }
371
+ catch (error) {
372
+ const errorMessage = error instanceof Error ? error.message : String(error);
373
+ // Check for 404-like errors indicating stale entity
374
+ if (errorMessage.includes("404") ||
375
+ errorMessage.includes("not found") ||
376
+ errorMessage.includes("Not Found")) {
377
+ updateIssueExternalLink(sudocodeDir, issueId, link.external_id, {
378
+ sync_enabled: false,
379
+ metadata: {
380
+ ...link.metadata,
381
+ stale: true,
382
+ stale_reason: "fetch_failed_404",
383
+ stale_at: new Date().toISOString(),
384
+ },
385
+ });
386
+ return {
387
+ updated: false,
388
+ hasLocalChanges: false,
389
+ stale: true,
390
+ error: "External entity no longer exists",
391
+ };
392
+ }
393
+ return {
394
+ updated: false,
395
+ hasLocalChanges: false,
396
+ error: `Refresh failed: ${errorMessage}`,
397
+ };
398
+ }
399
+ finally {
400
+ await provider.dispose();
401
+ }
402
+ }
403
+ /**
404
+ * Refresh multiple entities from their external sources
405
+ *
406
+ * @param db - Database instance
407
+ * @param sudocodeDir - Path to .sudocode directory
408
+ * @param projectPath - Path to project root
409
+ * @param options - Filter options for bulk refresh
410
+ * @returns Bulk refresh result
411
+ */
412
+ export async function bulkRefresh(db, sudocodeDir, projectPath, options = {}) {
413
+ const { provider: providerFilter, entityIds, force = false } = options;
414
+ const results = [];
415
+ let refreshed = 0;
416
+ let skipped = 0;
417
+ let failed = 0;
418
+ let stale = 0;
419
+ // Collect entities to refresh
420
+ const entitiesToRefresh = [];
421
+ // Read specs and issues from JSONL
422
+ const specsPath = path.join(sudocodeDir, "specs.jsonl");
423
+ const issuesPath = path.join(sudocodeDir, "issues.jsonl");
424
+ const specs = readJSONLSync(specsPath, { skipErrors: true });
425
+ const issues = readJSONLSync(issuesPath, { skipErrors: true });
426
+ // Filter specs
427
+ for (const spec of specs) {
428
+ if (entityIds && !entityIds.includes(spec.id))
429
+ continue;
430
+ const links = spec.external_links || [];
431
+ const hasMatchingLink = links.some((l) => l.sync_enabled &&
432
+ (l.sync_direction === "inbound" ||
433
+ l.sync_direction === "bidirectional") &&
434
+ (!providerFilter || l.provider === providerFilter));
435
+ if (hasMatchingLink) {
436
+ entitiesToRefresh.push({ id: spec.id, type: "spec" });
437
+ }
438
+ }
439
+ // Filter issues
440
+ for (const issue of issues) {
441
+ if (entityIds && !entityIds.includes(issue.id))
442
+ continue;
443
+ const links = issue.external_links || [];
444
+ const hasMatchingLink = links.some((l) => l.sync_enabled &&
445
+ (l.sync_direction === "inbound" ||
446
+ l.sync_direction === "bidirectional") &&
447
+ (!providerFilter || l.provider === providerFilter));
448
+ if (hasMatchingLink) {
449
+ entitiesToRefresh.push({ id: issue.id, type: "issue" });
450
+ }
451
+ }
452
+ // Refresh each entity
453
+ for (const entity of entitiesToRefresh) {
454
+ try {
455
+ let result;
456
+ if (entity.type === "spec") {
457
+ result = await refreshSpec(db, sudocodeDir, projectPath, entity.id, force);
458
+ }
459
+ else {
460
+ result = await refreshIssue(db, sudocodeDir, projectPath, entity.id, force);
461
+ }
462
+ if (result.stale) {
463
+ stale++;
464
+ results.push({
465
+ entityId: entity.id,
466
+ status: "stale",
467
+ error: result.error,
468
+ });
469
+ }
470
+ else if (result.error) {
471
+ failed++;
472
+ results.push({
473
+ entityId: entity.id,
474
+ status: "failed",
475
+ error: result.error,
476
+ });
477
+ }
478
+ else if (result.updated) {
479
+ refreshed++;
480
+ results.push({
481
+ entityId: entity.id,
482
+ status: "updated",
483
+ });
484
+ }
485
+ else if (result.hasLocalChanges) {
486
+ // Skipped due to local changes (and not forcing)
487
+ skipped++;
488
+ results.push({
489
+ entityId: entity.id,
490
+ status: "skipped",
491
+ error: "Local changes detected - use force=true to overwrite",
492
+ });
493
+ }
494
+ else {
495
+ // No changes needed
496
+ skipped++;
497
+ results.push({
498
+ entityId: entity.id,
499
+ status: "skipped",
500
+ });
501
+ }
502
+ }
503
+ catch (error) {
504
+ failed++;
505
+ results.push({
506
+ entityId: entity.id,
507
+ status: "failed",
508
+ error: error instanceof Error ? error.message : String(error),
509
+ });
510
+ }
511
+ }
512
+ return {
513
+ refreshed,
514
+ skipped,
515
+ failed,
516
+ stale,
517
+ results,
518
+ };
519
+ }
520
+ //# sourceMappingURL=external-refresh-service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"external-refresh-service.js","sourceRoot":"","sources":["../../src/services/external-refresh-service.ts"],"names":[],"mappings":"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"}
@@ -5,6 +5,10 @@ export interface RepositoryInfo {
5
5
  name: string;
6
6
  branch: string;
7
7
  path: string;
8
+ /** Full owner/repo identifier from git remote (e.g., "anthropic/sudocode") */
9
+ ownerRepo?: string;
10
+ /** Git hosting provider (e.g., "github", "gitlab", "bitbucket") */
11
+ gitProvider?: string;
8
12
  }
9
13
  export interface BranchInfo {
10
14
  current: string;
@@ -1 +1 @@
1
- {"version":3,"file":"repo-info.d.ts","sourceRoot":"","sources":["../../src/services/repo-info.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED;;;;;;GAMG;AACH,wBAAsB,iBAAiB,CACrC,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,cAAc,CAAC,CAgDzB;AAED;;;;;;GAMG;AACH,wBAAsB,qBAAqB,CACzC,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,UAAU,CAAC,CA8CrB"}
1
+ {"version":3,"file":"repo-info.d.ts","sourceRoot":"","sources":["../../src/services/repo-info.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,8EAA8E;IAC9E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,mEAAmE;IACnE,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED;;;;;;GAMG;AACH,wBAAsB,iBAAiB,CACrC,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,cAAc,CAAC,CAqFzB;AAED;;;;;;GAMG;AACH,wBAAsB,qBAAqB,CACzC,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,UAAU,CAAC,CA8CrB"}