repowisestage 0.0.79 → 0.0.81
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/bin/repowise.js +131 -72
- package/package.json +1 -1
package/dist/bin/repowise.js
CHANGED
|
@@ -3172,6 +3172,8 @@ init_config_dir();
|
|
|
3172
3172
|
import { readFile as readFile14, writeFile as writeFile16, mkdir as mkdir16, stat as fsStat } from "fs/promises";
|
|
3173
3173
|
import { join as join42, dirname as dirname18 } from "path";
|
|
3174
3174
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
3175
|
+
import { execFile as execFile9 } from "child_process";
|
|
3176
|
+
import { promisify as promisify7 } from "util";
|
|
3175
3177
|
import lockfile5 from "proper-lockfile";
|
|
3176
3178
|
|
|
3177
3179
|
// ../../packages/shared/dist/lib/ai-tools.js
|
|
@@ -6040,6 +6042,16 @@ function createGraphCache(options = {}) {
|
|
|
6040
6042
|
clearTimeout(entry.evictTimer);
|
|
6041
6043
|
delete entry.evictTimer;
|
|
6042
6044
|
}
|
|
6045
|
+
if (entry.sessionCount > 0) {
|
|
6046
|
+
void loadFromDisk(repoId).then((fresh) => {
|
|
6047
|
+
if (entries.get(repoId) === entry) {
|
|
6048
|
+
entry.graph = fresh.graph;
|
|
6049
|
+
entry.loadedMtime = fresh.loadedMtime;
|
|
6050
|
+
}
|
|
6051
|
+
}, () => {
|
|
6052
|
+
});
|
|
6053
|
+
return;
|
|
6054
|
+
}
|
|
6043
6055
|
entries.delete(repoId);
|
|
6044
6056
|
},
|
|
6045
6057
|
stats() {
|
|
@@ -10976,6 +10988,7 @@ async function fetchProducerGraph(apiUrl, authToken, repoId, fetchImpl = fetch)
|
|
|
10976
10988
|
// ../listener/dist/typed-resolution/hooks.js
|
|
10977
10989
|
function buildTypedResolutionHooks(options) {
|
|
10978
10990
|
const producer = options.producer ?? "repowise-listener/0.0.0";
|
|
10991
|
+
const inFlightProducers = /* @__PURE__ */ new Set();
|
|
10979
10992
|
async function resolveToken() {
|
|
10980
10993
|
try {
|
|
10981
10994
|
return await options.getAuthToken();
|
|
@@ -11030,85 +11043,93 @@ function buildTypedResolutionHooks(options) {
|
|
|
11030
11043
|
}
|
|
11031
11044
|
},
|
|
11032
11045
|
async onGraphReady(repoId, commitSha, localPath) {
|
|
11033
|
-
const
|
|
11034
|
-
if (
|
|
11035
|
-
return;
|
|
11036
|
-
const token = await resolveToken();
|
|
11037
|
-
if (!token)
|
|
11046
|
+
const inFlightKey = `${repoId} ${commitSha}`;
|
|
11047
|
+
if (inFlightProducers.has(inFlightKey))
|
|
11038
11048
|
return;
|
|
11039
|
-
|
|
11040
|
-
const shaMatches = graph !== null && (graph.commitSha === commitSha || graph.commitSha.startsWith(commitSha) || commitSha.startsWith(graph.commitSha));
|
|
11041
|
-
if (!graph || !shaMatches) {
|
|
11042
|
-
console.warn(`[typed-resolution] graph.ready for ${repoId}@${commitSha.slice(0, 12)} but fetched graph is ${graph ? `at ${graph.commitSha.slice(0, 12)}` : "missing"} \u2014 skipping`);
|
|
11043
|
-
return;
|
|
11044
|
-
}
|
|
11045
|
-
const receivers = graph.unresolvedReceivers ?? [];
|
|
11046
|
-
const snapshot = {
|
|
11047
|
-
resolvedCount: 0,
|
|
11048
|
-
remainingReceivers: receivers.length,
|
|
11049
|
-
// Until the first receiver completes, session spawn + server
|
|
11050
|
-
// indexing is the activity signal that keeps the wait alive.
|
|
11051
|
-
indexingActive: true
|
|
11052
|
-
};
|
|
11053
|
-
const reporter = createStatusReporter({
|
|
11054
|
-
apiUrl,
|
|
11055
|
-
repoId,
|
|
11056
|
-
commitSha: graph.commitSha,
|
|
11057
|
-
getAuthToken: options.getAuthToken,
|
|
11058
|
-
...options.getAuthTokenForceRefresh ? { getAuthTokenForceRefresh: options.getAuthTokenForceRefresh } : {},
|
|
11059
|
-
getSnapshot: () => ({ ...snapshot })
|
|
11060
|
-
});
|
|
11061
|
-
reporter.start();
|
|
11062
|
-
let prepared = null;
|
|
11049
|
+
inFlightProducers.add(inFlightKey);
|
|
11063
11050
|
try {
|
|
11064
|
-
|
|
11065
|
-
|
|
11051
|
+
const apiUrl = options.repoApiUrls.get(repoId);
|
|
11052
|
+
if (!apiUrl)
|
|
11066
11053
|
return;
|
|
11067
|
-
|
|
11068
|
-
|
|
11069
|
-
|
|
11070
|
-
|
|
11054
|
+
const token = await resolveToken();
|
|
11055
|
+
if (!token)
|
|
11056
|
+
return;
|
|
11057
|
+
const graph = await fetchProducerGraph(apiUrl, token, repoId);
|
|
11058
|
+
const shaMatches = graph !== null && (graph.commitSha === commitSha || graph.commitSha.startsWith(commitSha) || commitSha.startsWith(graph.commitSha));
|
|
11059
|
+
if (!graph || !shaMatches) {
|
|
11060
|
+
console.warn(`[typed-resolution] graph.ready for ${repoId}@${commitSha.slice(0, 12)} but fetched graph is ${graph ? `at ${graph.commitSha.slice(0, 12)}` : "missing"} \u2014 skipping`);
|
|
11071
11061
|
return;
|
|
11072
11062
|
}
|
|
11073
|
-
const
|
|
11074
|
-
|
|
11075
|
-
|
|
11076
|
-
|
|
11077
|
-
|
|
11078
|
-
|
|
11079
|
-
|
|
11080
|
-
}
|
|
11081
|
-
const
|
|
11082
|
-
const result = await runProducerCycle({
|
|
11063
|
+
const receivers = graph.unresolvedReceivers ?? [];
|
|
11064
|
+
const snapshot = {
|
|
11065
|
+
resolvedCount: 0,
|
|
11066
|
+
remainingReceivers: receivers.length,
|
|
11067
|
+
// Until the first receiver completes, session spawn + server
|
|
11068
|
+
// indexing is the activity signal that keeps the wait alive.
|
|
11069
|
+
indexingActive: true
|
|
11070
|
+
};
|
|
11071
|
+
const reporter = createStatusReporter({
|
|
11083
11072
|
apiUrl,
|
|
11084
|
-
authToken: token,
|
|
11085
11073
|
repoId,
|
|
11086
|
-
|
|
11087
|
-
|
|
11088
|
-
|
|
11089
|
-
|
|
11090
|
-
...lspOverrides ? { lspOverrides } : {},
|
|
11091
|
-
onReceiverProcessed: (processed, total, resolvedCount) => {
|
|
11092
|
-
snapshot.resolvedCount = resolvedCount;
|
|
11093
|
-
snapshot.remainingReceivers = Math.max(0, total - processed);
|
|
11094
|
-
snapshot.indexingActive = false;
|
|
11095
|
-
}
|
|
11074
|
+
commitSha: graph.commitSha,
|
|
11075
|
+
getAuthToken: options.getAuthToken,
|
|
11076
|
+
...options.getAuthTokenForceRefresh ? { getAuthTokenForceRefresh: options.getAuthTokenForceRefresh } : {},
|
|
11077
|
+
getSnapshot: () => ({ ...snapshot })
|
|
11096
11078
|
});
|
|
11097
|
-
|
|
11098
|
-
|
|
11099
|
-
|
|
11100
|
-
|
|
11101
|
-
|
|
11102
|
-
|
|
11103
|
-
|
|
11104
|
-
|
|
11105
|
-
|
|
11106
|
-
|
|
11107
|
-
|
|
11108
|
-
|
|
11109
|
-
|
|
11079
|
+
reporter.start();
|
|
11080
|
+
let prepared = null;
|
|
11081
|
+
try {
|
|
11082
|
+
if (receivers.length === 0) {
|
|
11083
|
+
await reporter.reportCompleted();
|
|
11084
|
+
return;
|
|
11085
|
+
}
|
|
11086
|
+
prepared = await prepareCommittedTree(localPath, graph.commitSha);
|
|
11087
|
+
if (!prepared) {
|
|
11088
|
+
await reporter.reportCrashed();
|
|
11089
|
+
return;
|
|
11090
|
+
}
|
|
11091
|
+
const buildResult = await ensureIndexable(prepared.indexRoot, "swift", {
|
|
11092
|
+
onActivity: () => {
|
|
11093
|
+
snapshot.indexingActive = true;
|
|
11094
|
+
}
|
|
11095
|
+
});
|
|
11096
|
+
if (!buildResult.ready) {
|
|
11097
|
+
console.warn(`[typed-resolution] swift build unavailable for ${repoId}: ${buildResult.reason ?? "unknown"} \u2014 continuing without it`);
|
|
11098
|
+
}
|
|
11099
|
+
const lspOverrides = options.getLspOverrides?.();
|
|
11100
|
+
const result = await runProducerCycle({
|
|
11101
|
+
apiUrl,
|
|
11102
|
+
authToken: token,
|
|
11103
|
+
repoId,
|
|
11104
|
+
repoRoot: prepared.indexRoot,
|
|
11105
|
+
graph,
|
|
11106
|
+
workspaces: options.workspaces,
|
|
11107
|
+
producer,
|
|
11108
|
+
...lspOverrides ? { lspOverrides } : {},
|
|
11109
|
+
onReceiverProcessed: (processed, total, resolvedCount) => {
|
|
11110
|
+
snapshot.resolvedCount = resolvedCount;
|
|
11111
|
+
snapshot.remainingReceivers = Math.max(0, total - processed);
|
|
11112
|
+
snapshot.indexingActive = false;
|
|
11113
|
+
}
|
|
11110
11114
|
});
|
|
11115
|
+
if (result) {
|
|
11116
|
+
await reporter.reportCompleted();
|
|
11117
|
+
} else {
|
|
11118
|
+
await reporter.reportCrashed();
|
|
11119
|
+
}
|
|
11120
|
+
} catch (err) {
|
|
11121
|
+
console.warn(`[typed-resolution] graph.ready producer failed for ${repoId}: ${err instanceof Error ? err.message : String(err)}`);
|
|
11122
|
+
await reporter.reportCrashed().catch(() => void 0);
|
|
11123
|
+
} finally {
|
|
11124
|
+
reporter.stop();
|
|
11125
|
+
if (prepared) {
|
|
11126
|
+
await prepared.cleanup().catch((cleanupErr) => {
|
|
11127
|
+
console.warn(`[typed-resolution] worktree cleanup failed: ${cleanupErr instanceof Error ? cleanupErr.message : String(cleanupErr)}`);
|
|
11128
|
+
});
|
|
11129
|
+
}
|
|
11111
11130
|
}
|
|
11131
|
+
} finally {
|
|
11132
|
+
inFlightProducers.delete(inFlightKey);
|
|
11112
11133
|
}
|
|
11113
11134
|
},
|
|
11114
11135
|
async onSidecarMerged(repoId, commitSha) {
|
|
@@ -11132,6 +11153,16 @@ function buildTypedResolutionHooks(options) {
|
|
|
11132
11153
|
|
|
11133
11154
|
// ../listener/dist/main.js
|
|
11134
11155
|
var TWENTY_FOUR_HOURS_MS = 24 * 60 * 60 * 1e3;
|
|
11156
|
+
var execFileAsync4 = promisify7(execFile9);
|
|
11157
|
+
async function resolveHeadSha(localPath) {
|
|
11158
|
+
try {
|
|
11159
|
+
const { stdout } = await execFileAsync4("git", ["-C", localPath, "rev-parse", "HEAD"]);
|
|
11160
|
+
const sha = stdout.trim();
|
|
11161
|
+
return /^[0-9a-f]{7,40}$/.test(sha) ? sha : null;
|
|
11162
|
+
} catch {
|
|
11163
|
+
return null;
|
|
11164
|
+
}
|
|
11165
|
+
}
|
|
11135
11166
|
var STALE_CHECK_COOLDOWN_MS = 60 * 60 * 1e3;
|
|
11136
11167
|
var CRASH_LOOP_WINDOW_MS = 3e4;
|
|
11137
11168
|
var CRASH_LOOP_THRESHOLD = 3;
|
|
@@ -11526,16 +11557,24 @@ async function handleCatchUp(offlineState, pollClient, repoIds, state, repoLocal
|
|
|
11526
11557
|
lastSyncCommitSha: null
|
|
11527
11558
|
// unknown from catch-up, but timestamp prevents re-download
|
|
11528
11559
|
};
|
|
11560
|
+
const onGraphReady = typedResolutionHooks?.onGraphReady;
|
|
11561
|
+
if (onGraphReady) {
|
|
11562
|
+
void resolveHeadSha(localPath).then((headSha) => headSha ? onGraphReady(repoId, headSha, localPath) : void 0).catch((err) => {
|
|
11563
|
+
console.warn(`[catch-up] typed-resolution producer failed for ${repoId}: ${err instanceof Error ? err.message : String(err)}`);
|
|
11564
|
+
});
|
|
11565
|
+
}
|
|
11529
11566
|
}
|
|
11530
11567
|
}
|
|
11531
11568
|
await saveState(state);
|
|
11532
|
-
|
|
11569
|
+
if (!offlineState.fromRestart)
|
|
11570
|
+
notifyBackOnline(syncCount);
|
|
11533
11571
|
} else {
|
|
11534
11572
|
const sinceTimestamp = offlineState.offlineSince;
|
|
11535
11573
|
const response = await pollClient.poll(repoIds, sinceTimestamp);
|
|
11536
11574
|
const updateCount = await processNotifications(response.notifications, state, repoLocalPaths, apiUrl, lspWorkspaces, typedResolutionHooks);
|
|
11537
11575
|
await saveState(state);
|
|
11538
|
-
|
|
11576
|
+
if (!offlineState.fromRestart)
|
|
11577
|
+
notifyBackOnline(updateCount);
|
|
11539
11578
|
}
|
|
11540
11579
|
}
|
|
11541
11580
|
async function checkStaleContext(repos, state, groups) {
|
|
@@ -11798,13 +11837,20 @@ async function startListener() {
|
|
|
11798
11837
|
const apiUrl = repo.apiUrl ?? config2.defaultApiUrl;
|
|
11799
11838
|
let group = groupMap.get(apiUrl);
|
|
11800
11839
|
if (!group) {
|
|
11840
|
+
const persistedOfflineSince = state.offlineCursors?.[apiUrl] ?? null;
|
|
11801
11841
|
group = {
|
|
11802
11842
|
apiUrl,
|
|
11803
11843
|
pollClient: new PollClient(apiUrl),
|
|
11804
11844
|
backoff: new BackoffCalculator(),
|
|
11805
11845
|
repoIds: [],
|
|
11806
11846
|
repoLocalPaths: /* @__PURE__ */ new Map(),
|
|
11807
|
-
offline: {
|
|
11847
|
+
offline: {
|
|
11848
|
+
isOffline: persistedOfflineSince !== null,
|
|
11849
|
+
offlineSince: persistedOfflineSince,
|
|
11850
|
+
attemptCount: 0,
|
|
11851
|
+
nextRetryAt: 0,
|
|
11852
|
+
fromRestart: persistedOfflineSince !== null
|
|
11853
|
+
}
|
|
11808
11854
|
};
|
|
11809
11855
|
groupMap.set(apiUrl, group);
|
|
11810
11856
|
}
|
|
@@ -12223,7 +12269,12 @@ async function startListener() {
|
|
|
12223
12269
|
group.offline.offlineSince = null;
|
|
12224
12270
|
group.offline.attemptCount = 0;
|
|
12225
12271
|
group.offline.nextRetryAt = 0;
|
|
12272
|
+
group.offline.fromRestart = false;
|
|
12226
12273
|
group.backoff.reset();
|
|
12274
|
+
if (state.offlineCursors?.[group.apiUrl]) {
|
|
12275
|
+
delete state.offlineCursors[group.apiUrl];
|
|
12276
|
+
await saveState(state);
|
|
12277
|
+
}
|
|
12227
12278
|
} else if (response.notifications.length > 0) {
|
|
12228
12279
|
await processNotifications(response.notifications, state, group.repoLocalPaths, group.apiUrl, mcpRuntime?.lspWorkspaces, typedResolutionHooks);
|
|
12229
12280
|
await saveState(state);
|
|
@@ -12264,11 +12315,19 @@ async function startListener() {
|
|
|
12264
12315
|
group.offline.isOffline = true;
|
|
12265
12316
|
group.offline.offlineSince = (/* @__PURE__ */ new Date()).toISOString();
|
|
12266
12317
|
group.offline.attemptCount = 0;
|
|
12318
|
+
group.offline.fromRestart = false;
|
|
12267
12319
|
if (!connectionLostNotified) {
|
|
12268
12320
|
notifyConnectionLost();
|
|
12269
12321
|
connectionLostNotified = true;
|
|
12270
12322
|
}
|
|
12271
12323
|
}
|
|
12324
|
+
if (group.offline.offlineSince) {
|
|
12325
|
+
state.offlineCursors = {
|
|
12326
|
+
...state.offlineCursors,
|
|
12327
|
+
[group.apiUrl]: group.offline.offlineSince
|
|
12328
|
+
};
|
|
12329
|
+
await saveState(state);
|
|
12330
|
+
}
|
|
12272
12331
|
group.offline.attemptCount++;
|
|
12273
12332
|
const delay3 = group.backoff.nextDelay();
|
|
12274
12333
|
group.offline.nextRetryAt = Date.now() + delay3;
|