@straiffi/archon 1.0.11 → 1.0.13
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.
- package/dist/client/assets/{index-Dgewr5ST.js → index-D3G9pPr9.js} +87 -86
- package/dist/client/index.html +1 -1
- package/dist/server/index.js +82 -14
- package/dist/server/index.js.map +1 -1
- package/dist/server/lib/chats.js +7 -1
- package/dist/server/lib/chats.js.map +1 -1
- package/dist/server/workers/chat.js +1 -1
- package/dist/server/workers/chat.js.map +1 -1
- package/package.json +1 -1
package/dist/client/index.html
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
|
6
6
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
7
7
|
<title>Archon</title>
|
|
8
|
-
<script type="module" crossorigin src="/assets/index-
|
|
8
|
+
<script type="module" crossorigin src="/assets/index-D3G9pPr9.js"></script>
|
|
9
9
|
<link rel="stylesheet" crossorigin href="/assets/index-BhQzJS4j.css">
|
|
10
10
|
</head>
|
|
11
11
|
<body>
|
package/dist/server/index.js
CHANGED
|
@@ -866,14 +866,28 @@ const getBundleReviewState = (projectId, tickets) => {
|
|
|
866
866
|
can_re_review: reviewState.can_re_review,
|
|
867
867
|
};
|
|
868
868
|
};
|
|
869
|
-
const BUNDLE_PULL_REQUEST_SYNC_TTL_MS =
|
|
869
|
+
const BUNDLE_PULL_REQUEST_SYNC_TTL_MS = 60 * 1000;
|
|
870
870
|
const BUNDLE_PULL_REQUEST_DISCOVERY_MISS_COOLDOWN_MS = 10 * 60 * 1000;
|
|
871
871
|
const BUNDLE_PULL_REQUEST_DISCOVERY_ERROR_COOLDOWN_MS = 2 * 60 * 1000;
|
|
872
|
+
const BUNDLE_PULL_REQUEST_SYNC_ERROR_COOLDOWN_MS = 2 * 60 * 1000;
|
|
873
|
+
const MAX_BACKGROUND_PULL_REQUEST_SYNCS_PER_PROJECT_REFRESH = 2;
|
|
872
874
|
// Avoid repeated open-triggered discovery hits when a bundle has no PR yet or GitHub is temporarily unavailable.
|
|
873
875
|
const bundlePullRequestDiscoveryInFlight = new Map();
|
|
874
876
|
const bundlePullRequestDiscoveryMissTimestamps = new Map();
|
|
875
877
|
const bundlePullRequestDiscoveryErrorTimestamps = new Map();
|
|
878
|
+
const bundlePullRequestSyncInFlight = new Map();
|
|
879
|
+
const bundlePullRequestSyncErrorTimestamps = new Map();
|
|
876
880
|
const getBundlePullRequestDiscoveryKey = (projectId, bundleId) => `${projectId}:${bundleId}`;
|
|
881
|
+
const startPassiveGitHubWork = (label, callback) => {
|
|
882
|
+
setImmediate(() => {
|
|
883
|
+
try {
|
|
884
|
+
callback();
|
|
885
|
+
}
|
|
886
|
+
catch (error) {
|
|
887
|
+
console.warn(`[integrations] github passive work failed ${label}`, error);
|
|
888
|
+
}
|
|
889
|
+
});
|
|
890
|
+
};
|
|
877
891
|
const isBundlePullRequestDiscoveryCoolingDown = (timestamps, key, cooldownMs) => {
|
|
878
892
|
const lastAttemptAt = timestamps.get(key);
|
|
879
893
|
if (lastAttemptAt === undefined) {
|
|
@@ -985,6 +999,7 @@ const discoverOpenBundlePullRequest = async (project, bundle) => {
|
|
|
985
999
|
};
|
|
986
1000
|
const syncTrackedBundlePullRequestIfNeeded = async (project, bundle, options = {}) => {
|
|
987
1001
|
const force = options.force ?? false;
|
|
1002
|
+
const rethrow = options.rethrow ?? false;
|
|
988
1003
|
const githubConfig = getGitHubConnectionConfig(project.id);
|
|
989
1004
|
const existingRecord = getBundlePullRequestRecord(bundle.id, project.id);
|
|
990
1005
|
if (!githubConfig || !existingRecord) {
|
|
@@ -1000,9 +1015,49 @@ const syncTrackedBundlePullRequestIfNeeded = async (project, bundle, options = {
|
|
|
1000
1015
|
}
|
|
1001
1016
|
catch (error) {
|
|
1002
1017
|
console.warn(`[integrations] github pr sync failed project=${project.id} bundle=${bundle.id} pr=${existingRecord.number}`, error);
|
|
1018
|
+
if (rethrow) {
|
|
1019
|
+
throw error;
|
|
1020
|
+
}
|
|
1003
1021
|
return existingRecord;
|
|
1004
1022
|
}
|
|
1005
1023
|
};
|
|
1024
|
+
const shouldStartTrackedBundlePullRequestSync = (project, bundle, options = {}) => {
|
|
1025
|
+
const force = options.force ?? false;
|
|
1026
|
+
const existingRecord = getBundlePullRequestRecord(bundle.id, project.id);
|
|
1027
|
+
if (!getGitHubConnectionConfig(project.id) || !existingRecord) {
|
|
1028
|
+
return false;
|
|
1029
|
+
}
|
|
1030
|
+
if (!force && !shouldSyncBundlePullRequest(existingRecord, BUNDLE_PULL_REQUEST_SYNC_TTL_MS)) {
|
|
1031
|
+
return false;
|
|
1032
|
+
}
|
|
1033
|
+
const key = getBundlePullRequestDiscoveryKey(project.id, bundle.id);
|
|
1034
|
+
if (bundlePullRequestSyncInFlight.has(key)) {
|
|
1035
|
+
return false;
|
|
1036
|
+
}
|
|
1037
|
+
return force || !isBundlePullRequestDiscoveryCoolingDown(bundlePullRequestSyncErrorTimestamps, key, BUNDLE_PULL_REQUEST_SYNC_ERROR_COOLDOWN_MS);
|
|
1038
|
+
};
|
|
1039
|
+
const startTrackedBundlePullRequestSyncIfNeeded = (project, bundle, options = {}) => {
|
|
1040
|
+
if (!shouldStartTrackedBundlePullRequestSync(project, bundle, options)) {
|
|
1041
|
+
return false;
|
|
1042
|
+
}
|
|
1043
|
+
const key = getBundlePullRequestDiscoveryKey(project.id, bundle.id);
|
|
1044
|
+
const task = (async () => {
|
|
1045
|
+
try {
|
|
1046
|
+
await syncTrackedBundlePullRequestIfNeeded(project, bundle, { ...options, rethrow: true });
|
|
1047
|
+
bundlePullRequestSyncErrorTimestamps.delete(key);
|
|
1048
|
+
reconcileBundleTicketsAfterPullRequestSync(project.id, bundle.id);
|
|
1049
|
+
}
|
|
1050
|
+
catch (error) {
|
|
1051
|
+
bundlePullRequestSyncErrorTimestamps.set(key, Date.now());
|
|
1052
|
+
console.warn(`[integrations] github pr background sync failed project=${project.id} bundle=${bundle.id}`, error);
|
|
1053
|
+
}
|
|
1054
|
+
finally {
|
|
1055
|
+
bundlePullRequestSyncInFlight.delete(key);
|
|
1056
|
+
}
|
|
1057
|
+
})();
|
|
1058
|
+
bundlePullRequestSyncInFlight.set(key, task);
|
|
1059
|
+
return true;
|
|
1060
|
+
};
|
|
1006
1061
|
const listBundleTicketIds = (projectId, bundleId) => {
|
|
1007
1062
|
const rows = db.prepare('SELECT id FROM tickets WHERE project_id = ? AND worktree_bundle_id = ? ORDER BY updated_at DESC, id DESC').all(projectId, bundleId);
|
|
1008
1063
|
return rows.map(row => row.id);
|
|
@@ -1060,11 +1115,15 @@ const reconcileBundleTicketsAfterPullRequestSync = (projectId, bundleId) => {
|
|
|
1060
1115
|
}
|
|
1061
1116
|
};
|
|
1062
1117
|
const syncProjectBundlePullRequestsIfNeeded = async (project, bundles, options = {}) => {
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1118
|
+
let startedCount = 0;
|
|
1119
|
+
for (const bundle of bundles) {
|
|
1120
|
+
if (startedCount >= MAX_BACKGROUND_PULL_REQUEST_SYNCS_PER_PROJECT_REFRESH) {
|
|
1121
|
+
return;
|
|
1122
|
+
}
|
|
1123
|
+
if (startTrackedBundlePullRequestSyncIfNeeded(project, bundle, options)) {
|
|
1124
|
+
startedCount += 1;
|
|
1125
|
+
}
|
|
1126
|
+
}
|
|
1068
1127
|
};
|
|
1069
1128
|
const startProjectBundlePullRequestSyncIfNeeded = (project, bundles, options = {}) => {
|
|
1070
1129
|
void syncProjectBundlePullRequestsIfNeeded(project, bundles, options).catch(error => {
|
|
@@ -2053,17 +2112,23 @@ app.get('/tickets/:id', async (req, res) => {
|
|
|
2053
2112
|
if (!matchesTicketProjectContext(ticket, req)) {
|
|
2054
2113
|
return res.status(404).json({ error: 'Not found' });
|
|
2055
2114
|
}
|
|
2115
|
+
let passivePullRequestContext = null;
|
|
2056
2116
|
if (ticket.project_id && ticket.worktree_bundle_id) {
|
|
2057
2117
|
const project = getProjectById(ticket.project_id);
|
|
2058
2118
|
const bundle = project ? getBundle(ticket.worktree_bundle_id, project.id) : null;
|
|
2059
2119
|
if (project && bundle) {
|
|
2060
|
-
|
|
2061
|
-
reconcileBundleTicketsAfterPullRequestSync(project.id, bundle.id);
|
|
2062
|
-
startBundlePullRequestDiscoveryIfNeeded(project, bundle);
|
|
2063
|
-
ticket = getTicket(req.params.id);
|
|
2120
|
+
passivePullRequestContext = { project, bundle };
|
|
2064
2121
|
}
|
|
2065
2122
|
}
|
|
2066
|
-
|
|
2123
|
+
res.json(ticket);
|
|
2124
|
+
if (passivePullRequestContext) {
|
|
2125
|
+
const { project, bundle } = passivePullRequestContext;
|
|
2126
|
+
startPassiveGitHubWork('ticket-open-pr-sync', () => {
|
|
2127
|
+
startTrackedBundlePullRequestSyncIfNeeded(project, bundle);
|
|
2128
|
+
startBundlePullRequestDiscoveryIfNeeded(project, bundle);
|
|
2129
|
+
});
|
|
2130
|
+
}
|
|
2131
|
+
return;
|
|
2067
2132
|
});
|
|
2068
2133
|
app.get('/tickets/:id/review-findings', (req, res) => {
|
|
2069
2134
|
const ticket = getTicketRouteContext(req.params.id);
|
|
@@ -2139,12 +2204,13 @@ app.get('/bundles', async (req, res) => {
|
|
|
2139
2204
|
timing.mark('ensure_project_root_bundle');
|
|
2140
2205
|
const bundles = listBundles(result.project.id);
|
|
2141
2206
|
timing.mark('list_bundles');
|
|
2142
|
-
startProjectBundlePullRequestSyncIfNeeded(result.project, bundles);
|
|
2143
|
-
timing.mark('start_pr_sync');
|
|
2144
2207
|
const serializedBundles = bundles.map(bundle => serializeBundleRow(result.project.id, bundle));
|
|
2145
2208
|
timing.mark('serialize_bundles');
|
|
2146
2209
|
timing.end({ count: serializedBundles.length });
|
|
2147
2210
|
res.json(serializedBundles);
|
|
2211
|
+
startPassiveGitHubWork('project-bundle-pr-sync', () => {
|
|
2212
|
+
startProjectBundlePullRequestSyncIfNeeded(result.project, bundles);
|
|
2213
|
+
});
|
|
2148
2214
|
});
|
|
2149
2215
|
app.get('/bundles/:id/details', async (req, res) => {
|
|
2150
2216
|
const result = getRequiredProject(req);
|
|
@@ -2168,9 +2234,11 @@ app.get('/bundles/:id/conversation', (req, res) => {
|
|
|
2168
2234
|
if (!bundle) {
|
|
2169
2235
|
return res.status(404).json({ error: 'Bundle not found' });
|
|
2170
2236
|
}
|
|
2171
|
-
startBundlePullRequestDiscoveryIfNeeded(result.project, bundle);
|
|
2172
2237
|
const payload = serializeBundleConversationDetails(result.project, bundle);
|
|
2173
2238
|
res.json(payload);
|
|
2239
|
+
startPassiveGitHubWork('bundle-conversation-pr-discovery', () => {
|
|
2240
|
+
startBundlePullRequestDiscoveryIfNeeded(result.project, bundle);
|
|
2241
|
+
});
|
|
2174
2242
|
});
|
|
2175
2243
|
app.get('/bundles/:id/review-findings', (req, res) => {
|
|
2176
2244
|
const result = getRequiredProject(req);
|