pi-minimal 0.4.0 → 0.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.
- package/CHANGELOG.md +46 -0
- package/CONTEXT.md +83 -0
- package/README.md +3 -3
- package/dist/config.js +2 -1
- package/dist/edit-diff.js +74 -0
- package/dist/footer-contribution-events.js +5 -3
- package/dist/footer-contributions.js +15 -13
- package/dist/git-state.js +31 -11
- package/dist/index.js +24 -208
- package/dist/reclaim.js +0 -3
- package/dist/session.js +155 -0
- package/dist/tools.js +213 -374
- package/dist/tracker.js +2 -2
- package/dist/working-status.js +2 -1
- package/doc/archive/README.md +3 -0
- package/doc/footer-contributions.md +7 -7
- package/package.json +1 -1
- package/release-notes.md +46 -12
- package/src/config.ts +2 -1
- package/src/edit-diff.ts +73 -0
- package/src/footer-contribution-events.ts +7 -4
- package/src/footer-contributions.ts +15 -13
- package/src/git-state.ts +29 -10
- package/src/index.ts +26 -201
- package/src/reclaim.ts +0 -4
- package/src/session.ts +159 -0
- package/src/tools.ts +261 -389
- package/src/tracker.ts +11 -5
- package/src/working-status.ts +2 -1
- package/test/config.test.ts +2 -2
- package/test/footer-contribution-events.test.ts +15 -0
- package/test/git-state.test.ts +35 -0
- package/test/index.test.ts +45 -3
- package/test/tools.test.ts +36 -3
- package/test/working-status.test.ts +53 -0
- /package/doc/{plans/2026-09-22-pi-minimal-package.md → archive/2026-09-22-plan-pi-minimal-package.md} +0 -0
- /package/doc/{specs/2026-09-22-pi-minimal-package.md → archive/2026-09-22-spec-pi-minimal-package.md} +0 -0
package/dist/index.js
CHANGED
|
@@ -1,231 +1,47 @@
|
|
|
1
|
-
import { getAgentDir } from "@earendil-works/pi-coding-agent";
|
|
2
|
-
import { loadPiMinimalConfig } from "./config.js";
|
|
3
|
-
import { installHeader } from "./header.js";
|
|
4
|
-
import { installFooter } from "./footer.js";
|
|
5
|
-
import { createFooterContributions } from "./footer-contributions.js";
|
|
6
|
-
import { bindFooterContributionEvents } from "./footer-contribution-events.js";
|
|
7
|
-
import { installCwd } from "./cwd.js";
|
|
8
|
-
import { listSiblings, parseAgentList, parseTabList } from "./herdr.js";
|
|
9
|
-
import { hideGauntletWidgets } from "./tracker.js";
|
|
10
|
-
import { installToolRenderers, setEditDiffMode, stopLiveWatch } from "./tools.js";
|
|
11
|
-
import { setSessionCwd } from "./tool-rows.js";
|
|
12
|
-
import { applyReclaim, reclaimPolicy } from "./reclaim.js";
|
|
13
|
-
import { installWorkingStatus } from "./working-status.js";
|
|
14
|
-
import { installTurnRule } from "./turn-rule.js";
|
|
15
|
-
import { installTranscript } from "./transcript.js";
|
|
16
|
-
import { createGitState } from "./git-state.js";
|
|
17
1
|
import { installCodeBox } from "./code-box.js";
|
|
18
|
-
import {
|
|
19
|
-
import {
|
|
2
|
+
import { createSession } from "./session.js";
|
|
3
|
+
import { installToolRenderers, stopLiveWatch } from "./tools.js";
|
|
4
|
+
import { installTranscript } from "./transcript.js";
|
|
5
|
+
import { installTurnRule } from "./turn-rule.js";
|
|
6
|
+
import { installWorkingStatus } from "./working-status.js";
|
|
7
|
+
/**
|
|
8
|
+
* Process-wide hooks are installed once at load (renderers, transformers, the code-box patch);
|
|
9
|
+
* everything else lives on a `Session` created at session_start and disposed at session_shutdown
|
|
10
|
+
* or when the next session starts.
|
|
11
|
+
*/
|
|
20
12
|
export default function piMinimalExtension(pi) {
|
|
21
13
|
const stopWorkingStatus = installWorkingStatus(pi);
|
|
22
14
|
const stopTurnRule = installTurnRule(pi);
|
|
23
15
|
installToolRenderers(pi);
|
|
24
16
|
installTranscript(pi);
|
|
25
17
|
installCodeBox();
|
|
26
|
-
|
|
27
|
-
let stopFooter = () => { };
|
|
28
|
-
let stopContributionEvents = () => { };
|
|
29
|
-
let sessionActive = false;
|
|
30
|
-
let fastTimer;
|
|
31
|
-
let slowTimer;
|
|
32
|
-
let stealTimer;
|
|
33
|
-
let inFlight;
|
|
34
|
-
let siblings;
|
|
35
|
-
let generation = 0;
|
|
36
|
-
let hideWidgets = true;
|
|
18
|
+
let active;
|
|
37
19
|
let busy = false;
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
if (fastTimer)
|
|
42
|
-
clearInterval(fastTimer);
|
|
43
|
-
if (slowTimer)
|
|
44
|
-
clearInterval(slowTimer);
|
|
45
|
-
if (stealTimer)
|
|
46
|
-
clearInterval(stealTimer);
|
|
47
|
-
fastTimer = undefined;
|
|
48
|
-
slowTimer = undefined;
|
|
49
|
-
stealTimer = undefined;
|
|
50
|
-
inFlight?.abort();
|
|
51
|
-
inFlight = undefined;
|
|
52
|
-
};
|
|
53
|
-
const scheduleFast = (ctx) => {
|
|
54
|
-
if (fastTimer)
|
|
55
|
-
return;
|
|
56
|
-
if (slowTimer)
|
|
57
|
-
clearInterval(slowTimer);
|
|
58
|
-
slowTimer = undefined;
|
|
59
|
-
fastTimer = setInterval(() => {
|
|
60
|
-
void probe(ctx);
|
|
61
|
-
}, 2000);
|
|
62
|
-
};
|
|
63
|
-
const scheduleSlow = (ctx) => {
|
|
64
|
-
if (slowTimer)
|
|
65
|
-
return;
|
|
66
|
-
if (fastTimer)
|
|
67
|
-
clearInterval(fastTimer);
|
|
68
|
-
fastTimer = undefined;
|
|
69
|
-
slowTimer = setInterval(() => {
|
|
70
|
-
void probe(ctx);
|
|
71
|
-
}, 10000);
|
|
72
|
-
};
|
|
73
|
-
const probe = async (ctx) => {
|
|
74
|
-
if (process.env.HERDR_ENV !== "1")
|
|
75
|
-
return;
|
|
76
|
-
if (inFlight)
|
|
77
|
-
return;
|
|
78
|
-
const ac = new AbortController();
|
|
79
|
-
const gen = generation;
|
|
80
|
-
inFlight = ac;
|
|
81
|
-
try {
|
|
82
|
-
const agentRun = await pi.exec("herdr", ["agent", "list"], {
|
|
83
|
-
timeout: 3000,
|
|
84
|
-
signal: ac.signal,
|
|
85
|
-
});
|
|
86
|
-
if (generation !== gen)
|
|
87
|
-
return;
|
|
88
|
-
const tabRun = await pi.exec("herdr", ["tab", "list"], {
|
|
89
|
-
timeout: 3000,
|
|
90
|
-
signal: ac.signal,
|
|
91
|
-
});
|
|
92
|
-
if (generation !== gen)
|
|
93
|
-
return;
|
|
94
|
-
if (agentRun.code !== 0 || tabRun.code !== 0 || agentRun.killed || tabRun.killed) {
|
|
95
|
-
siblings = undefined;
|
|
96
|
-
scheduleSlow(ctx);
|
|
97
|
-
return;
|
|
98
|
-
}
|
|
99
|
-
siblings = listSiblings(parseAgentList(agentRun.stdout), parseTabList(tabRun.stdout), process.env.HERDR_PANE_ID, process.env.HERDR_TAB_ID);
|
|
100
|
-
if (siblings)
|
|
101
|
-
scheduleFast(ctx);
|
|
102
|
-
else
|
|
103
|
-
scheduleSlow(ctx);
|
|
104
|
-
}
|
|
105
|
-
catch {
|
|
106
|
-
if (generation !== gen)
|
|
107
|
-
return;
|
|
108
|
-
siblings = undefined;
|
|
109
|
-
scheduleSlow(ctx);
|
|
110
|
-
}
|
|
111
|
-
finally {
|
|
112
|
-
if (inFlight === ac)
|
|
113
|
-
inFlight = undefined;
|
|
114
|
-
}
|
|
115
|
-
};
|
|
116
|
-
const hideForeignChrome = (ctx, reason) => {
|
|
117
|
-
if (ctx.mode !== "tui")
|
|
118
|
-
return;
|
|
119
|
-
applyReclaim(reason, ctx.ui, {
|
|
120
|
-
widgets: () => {
|
|
121
|
-
if (hideWidgets)
|
|
122
|
-
hideGauntletWidgets(ctx);
|
|
123
|
-
},
|
|
124
|
-
chrome: () => {
|
|
125
|
-
installHeader(ctx);
|
|
126
|
-
installChromeFooter(ctx);
|
|
127
|
-
},
|
|
128
|
-
});
|
|
129
|
-
};
|
|
130
|
-
const contextPct = (ctx) => {
|
|
131
|
-
const usage = ctx.getContextUsage?.();
|
|
132
|
-
const window = usage?.contextWindow || ctx.model?.contextWindow;
|
|
133
|
-
if (typeof usage?.tokens !== "number" || !window)
|
|
134
|
-
return undefined;
|
|
135
|
-
return Math.max(0, Math.min(100, Math.round((usage.tokens / window) * 100)));
|
|
136
|
-
};
|
|
137
|
-
const installChromeFooter = (ctx) => {
|
|
138
|
-
stopFooter();
|
|
139
|
-
stopFooter = installFooter(ctx, {
|
|
140
|
-
busy: () => busy,
|
|
141
|
-
editorText: () => (typeof ctx.ui.getEditorText === "function" ? ctx.ui.getEditorText() : ""),
|
|
142
|
-
contextPct: () => contextPct(ctx),
|
|
143
|
-
}, contributions);
|
|
144
|
-
};
|
|
145
|
-
const installStatusLine = (ctx) => {
|
|
146
|
-
installCwd(ctx, {
|
|
147
|
-
gitState: gitState.get,
|
|
148
|
-
siblings: () => siblings,
|
|
149
|
-
onGitChange: gitState.onChange,
|
|
150
|
-
});
|
|
151
|
-
};
|
|
152
|
-
const pinChrome = (ctx, reason) => {
|
|
153
|
-
hideForeignChrome(ctx, reason);
|
|
154
|
-
if (ctx.mode !== "tui" || !reclaimPolicy(reason).reinstallChrome)
|
|
155
|
-
return;
|
|
156
|
-
ctx.ui.setWidget("tw-cwd", undefined);
|
|
157
|
-
installStatusLine(ctx);
|
|
158
|
-
};
|
|
159
|
-
pi.on("session_start", async (_event, ctx) => {
|
|
160
|
-
stopFooter();
|
|
161
|
-
stopContributionEvents();
|
|
162
|
-
sessionActive = true;
|
|
163
|
-
generation += 1;
|
|
164
|
-
stopContributionEvents = bindFooterContributionEvents(pi.events, contributions, ctx.sessionManager.getSessionId(), ctx.mode);
|
|
165
|
-
if (ctx.mode !== "tui")
|
|
166
|
-
return;
|
|
167
|
-
const config = loadPiMinimalConfig({
|
|
168
|
-
agentDir: getAgentDir(),
|
|
169
|
-
cwd: ctx.cwd,
|
|
170
|
-
projectTrusted: ctx.isProjectTrusted(),
|
|
171
|
-
});
|
|
172
|
-
hideWidgets = config.hideGauntletWidgets;
|
|
173
|
-
setEditDiffMode(config.editDiff);
|
|
174
|
-
currentCwd = ctx.cwd;
|
|
175
|
-
setSessionCwd(ctx.cwd);
|
|
176
|
-
try {
|
|
177
|
-
const settings = SettingsManager.create(ctx.cwd, undefined, { projectTrusted: ctx.isProjectTrusted() });
|
|
178
|
-
setChromeMargin(settings.getOutputPad());
|
|
179
|
-
}
|
|
180
|
-
catch {
|
|
181
|
-
// Keep the default margin when settings are unavailable.
|
|
182
|
-
}
|
|
183
|
-
installHeader(ctx);
|
|
184
|
-
installChromeFooter(ctx);
|
|
185
|
-
installStatusLine(ctx);
|
|
186
|
-
void gitState.refresh(true);
|
|
187
|
-
pinChrome(ctx, "session_start");
|
|
188
|
-
ctx.ui.setHiddenThinkingLabel("◆ Thought");
|
|
189
|
-
ctx.ui.setWorkingIndicator();
|
|
190
|
-
const sessionGeneration = generation;
|
|
191
|
-
const settle = () => {
|
|
192
|
-
if (sessionActive && generation === sessionGeneration)
|
|
193
|
-
pinChrome(ctx, "session_settle");
|
|
194
|
-
};
|
|
195
|
-
setTimeout(settle, 0);
|
|
196
|
-
setTimeout(settle, 50);
|
|
197
|
-
if (!stealTimer) {
|
|
198
|
-
stealTimer = setInterval(() => hideForeignChrome(ctx, "interval"), 200);
|
|
199
|
-
}
|
|
200
|
-
if (process.env.HERDR_ENV === "1") {
|
|
201
|
-
await probe(ctx);
|
|
202
|
-
}
|
|
20
|
+
pi.on("session_start", (_event, ctx) => {
|
|
21
|
+
active?.dispose();
|
|
22
|
+
active = createSession(pi, ctx, { busy: () => busy });
|
|
203
23
|
});
|
|
204
24
|
pi.on("agent_start", () => {
|
|
205
25
|
busy = true;
|
|
206
26
|
});
|
|
207
27
|
pi.on("agent_end", () => {
|
|
208
28
|
busy = false;
|
|
209
|
-
|
|
29
|
+
active?.refreshGit();
|
|
210
30
|
});
|
|
211
|
-
pi.on("turn_end", (
|
|
212
|
-
|
|
213
|
-
|
|
31
|
+
pi.on("turn_end", () => {
|
|
32
|
+
active?.pin("turn_end");
|
|
33
|
+
active?.refreshGit();
|
|
214
34
|
});
|
|
215
|
-
pi.on("tool_execution_end", (
|
|
216
|
-
|
|
217
|
-
|
|
35
|
+
pi.on("tool_execution_end", () => {
|
|
36
|
+
active?.pin("tool_execution_end");
|
|
37
|
+
active?.refreshGit();
|
|
218
38
|
});
|
|
219
|
-
pi.on("session_shutdown",
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
stopContributionEvents();
|
|
39
|
+
pi.on("session_shutdown", () => {
|
|
40
|
+
active?.dispose();
|
|
41
|
+
active = undefined;
|
|
223
42
|
busy = false;
|
|
224
|
-
stopTimers();
|
|
225
43
|
stopWorkingStatus();
|
|
226
44
|
stopTurnRule();
|
|
227
45
|
stopLiveWatch();
|
|
228
|
-
generation += 1;
|
|
229
|
-
siblings = undefined;
|
|
230
46
|
});
|
|
231
47
|
}
|
package/dist/reclaim.js
CHANGED
|
@@ -2,9 +2,6 @@ export function reclaimPolicy(reason) {
|
|
|
2
2
|
if (reason === "session_start") {
|
|
3
3
|
return { resetEditor: true, reinstallChrome: true };
|
|
4
4
|
}
|
|
5
|
-
if (reason === "interval") {
|
|
6
|
-
return { resetEditor: false, reinstallChrome: false };
|
|
7
|
-
}
|
|
8
5
|
// session_settle / turn_end / tool_execution_end: restore chrome, keep editor
|
|
9
6
|
return { resetEditor: false, reinstallChrome: true };
|
|
10
7
|
}
|
package/dist/session.js
ADDED
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import { getAgentDir, SettingsManager } from "@earendil-works/pi-coding-agent";
|
|
2
|
+
import { setChromeMargin } from "./chrome.js";
|
|
3
|
+
import { loadPiMinimalConfig } from "./config.js";
|
|
4
|
+
import { installCwd } from "./cwd.js";
|
|
5
|
+
import { installFooter } from "./footer.js";
|
|
6
|
+
import { bindFooterContributionEvents } from "./footer-contribution-events.js";
|
|
7
|
+
import { createFooterContributions } from "./footer-contributions.js";
|
|
8
|
+
import { createGitState } from "./git-state.js";
|
|
9
|
+
import { installHeader } from "./header.js";
|
|
10
|
+
import { listSiblings, parseAgentList, parseTabList } from "./herdr.js";
|
|
11
|
+
import { applyReclaim, reclaimPolicy } from "./reclaim.js";
|
|
12
|
+
import { setSessionCwd } from "./tool-rows.js";
|
|
13
|
+
import { setEditDiffMode } from "./tools.js";
|
|
14
|
+
import { hideGauntletWidgets } from "./tracker.js";
|
|
15
|
+
const HERDR_FAST_MS = 2000;
|
|
16
|
+
const HERDR_SLOW_MS = 10000;
|
|
17
|
+
const HERDR_EXEC_TIMEOUT_MS = 3000;
|
|
18
|
+
/**
|
|
19
|
+
* Everything pi-minimal owns for one session: config, cwd, the contribution registry, the git and
|
|
20
|
+
* Herdr pollers, and the header/footer/status-line chrome. Disposal stops every timer and makes
|
|
21
|
+
* late async results inert, so two sessions in one process never share or overwrite each other's
|
|
22
|
+
* state. Non-TUI sessions get a session too, but it only binds the contribution protocol (which
|
|
23
|
+
* replies `not-tui`) and installs no chrome.
|
|
24
|
+
*/
|
|
25
|
+
export function createSession(pi, ctx, deps) {
|
|
26
|
+
const id = ctx.sessionManager.getSessionId();
|
|
27
|
+
let alive = true;
|
|
28
|
+
const contributions = createFooterContributions();
|
|
29
|
+
const stopContributionEvents = bindFooterContributionEvents(pi.events, contributions, id, ctx.mode);
|
|
30
|
+
if (ctx.mode !== "tui") {
|
|
31
|
+
return { id, pin() { }, refreshGit() { }, dispose() { if (!alive)
|
|
32
|
+
return; alive = false; stopContributionEvents(); } };
|
|
33
|
+
}
|
|
34
|
+
const config = loadPiMinimalConfig({ agentDir: getAgentDir(), cwd: ctx.cwd, projectTrusted: ctx.isProjectTrusted() });
|
|
35
|
+
setSessionCwd(ctx.cwd);
|
|
36
|
+
setEditDiffMode(config.editDiff);
|
|
37
|
+
try {
|
|
38
|
+
const settings = SettingsManager.create(ctx.cwd, undefined, { projectTrusted: ctx.isProjectTrusted() });
|
|
39
|
+
setChromeMargin(settings.getOutputPad());
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
// Keep the current margin when settings are unavailable.
|
|
43
|
+
}
|
|
44
|
+
const gitState = createGitState(pi, () => ctx.cwd);
|
|
45
|
+
let stopFooter = () => { };
|
|
46
|
+
let siblings;
|
|
47
|
+
let herdrTimer;
|
|
48
|
+
let herdrPeriod = 0;
|
|
49
|
+
let herdrInFlight;
|
|
50
|
+
const settleTimers = [];
|
|
51
|
+
const contextPct = () => {
|
|
52
|
+
const usage = ctx.getContextUsage?.();
|
|
53
|
+
const window = usage?.contextWindow || ctx.model?.contextWindow;
|
|
54
|
+
if (typeof usage?.tokens !== "number" || !window)
|
|
55
|
+
return undefined;
|
|
56
|
+
return Math.max(0, Math.min(100, Math.round((usage.tokens / window) * 100)));
|
|
57
|
+
};
|
|
58
|
+
const installChromeFooter = () => {
|
|
59
|
+
stopFooter();
|
|
60
|
+
stopFooter = installFooter(ctx, {
|
|
61
|
+
busy: deps.busy,
|
|
62
|
+
editorText: () => (typeof ctx.ui.getEditorText === "function" ? ctx.ui.getEditorText() : ""),
|
|
63
|
+
contextPct,
|
|
64
|
+
}, contributions);
|
|
65
|
+
};
|
|
66
|
+
const installStatusLine = () => {
|
|
67
|
+
installCwd(ctx, { gitState: gitState.get, siblings: () => siblings, onGitChange: gitState.onChange });
|
|
68
|
+
};
|
|
69
|
+
const pin = (reason) => {
|
|
70
|
+
if (!alive)
|
|
71
|
+
return;
|
|
72
|
+
applyReclaim(reason, ctx.ui, {
|
|
73
|
+
widgets: () => { if (config.hideGauntletWidgets)
|
|
74
|
+
hideGauntletWidgets(ctx); },
|
|
75
|
+
chrome: () => { installHeader(ctx); installChromeFooter(); },
|
|
76
|
+
});
|
|
77
|
+
if (!reclaimPolicy(reason).reinstallChrome)
|
|
78
|
+
return;
|
|
79
|
+
ctx.ui.setWidget("tw-cwd", undefined);
|
|
80
|
+
installStatusLine();
|
|
81
|
+
};
|
|
82
|
+
const scheduleHerdr = (periodMs) => {
|
|
83
|
+
if (!alive || herdrPeriod === periodMs)
|
|
84
|
+
return;
|
|
85
|
+
if (herdrTimer)
|
|
86
|
+
clearInterval(herdrTimer);
|
|
87
|
+
herdrPeriod = periodMs;
|
|
88
|
+
herdrTimer = setInterval(() => { void probeHerdr(); }, periodMs);
|
|
89
|
+
};
|
|
90
|
+
const probeHerdr = async () => {
|
|
91
|
+
if (!alive || herdrInFlight)
|
|
92
|
+
return;
|
|
93
|
+
const ac = new AbortController();
|
|
94
|
+
herdrInFlight = ac;
|
|
95
|
+
try {
|
|
96
|
+
const agentRun = await pi.exec("herdr", ["agent", "list"], { timeout: HERDR_EXEC_TIMEOUT_MS, signal: ac.signal });
|
|
97
|
+
if (!alive)
|
|
98
|
+
return;
|
|
99
|
+
const tabRun = await pi.exec("herdr", ["tab", "list"], { timeout: HERDR_EXEC_TIMEOUT_MS, signal: ac.signal });
|
|
100
|
+
if (!alive)
|
|
101
|
+
return;
|
|
102
|
+
if (agentRun.code !== 0 || tabRun.code !== 0 || agentRun.killed || tabRun.killed) {
|
|
103
|
+
siblings = undefined;
|
|
104
|
+
scheduleHerdr(HERDR_SLOW_MS);
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
siblings = listSiblings(parseAgentList(agentRun.stdout), parseTabList(tabRun.stdout), process.env.HERDR_PANE_ID, process.env.HERDR_TAB_ID);
|
|
108
|
+
scheduleHerdr(siblings ? HERDR_FAST_MS : HERDR_SLOW_MS);
|
|
109
|
+
}
|
|
110
|
+
catch {
|
|
111
|
+
if (!alive)
|
|
112
|
+
return;
|
|
113
|
+
siblings = undefined;
|
|
114
|
+
scheduleHerdr(HERDR_SLOW_MS);
|
|
115
|
+
}
|
|
116
|
+
finally {
|
|
117
|
+
if (herdrInFlight === ac)
|
|
118
|
+
herdrInFlight = undefined;
|
|
119
|
+
}
|
|
120
|
+
};
|
|
121
|
+
// Install once, then re-assert shortly after: other extensions' session_start handlers may draw after ours.
|
|
122
|
+
installHeader(ctx);
|
|
123
|
+
installChromeFooter();
|
|
124
|
+
installStatusLine();
|
|
125
|
+
void gitState.refresh(true);
|
|
126
|
+
pin("session_start");
|
|
127
|
+
ctx.ui.setHiddenThinkingLabel("◆ Thought");
|
|
128
|
+
ctx.ui.setWorkingIndicator();
|
|
129
|
+
for (const delay of [0, 50])
|
|
130
|
+
settleTimers.push(setTimeout(() => pin("session_settle"), delay));
|
|
131
|
+
if (process.env.HERDR_ENV === "1")
|
|
132
|
+
void probeHerdr();
|
|
133
|
+
return {
|
|
134
|
+
id,
|
|
135
|
+
pin,
|
|
136
|
+
refreshGit(force) { if (alive)
|
|
137
|
+
void gitState.refresh(force); },
|
|
138
|
+
dispose() {
|
|
139
|
+
if (!alive)
|
|
140
|
+
return;
|
|
141
|
+
alive = false;
|
|
142
|
+
for (const timer of settleTimers.splice(0))
|
|
143
|
+
clearTimeout(timer);
|
|
144
|
+
if (herdrTimer)
|
|
145
|
+
clearInterval(herdrTimer);
|
|
146
|
+
herdrTimer = undefined;
|
|
147
|
+
herdrInFlight?.abort();
|
|
148
|
+
herdrInFlight = undefined;
|
|
149
|
+
siblings = undefined;
|
|
150
|
+
gitState.dispose();
|
|
151
|
+
stopFooter();
|
|
152
|
+
stopContributionEvents();
|
|
153
|
+
},
|
|
154
|
+
};
|
|
155
|
+
}
|