@henryqw/pi-footer 4.1.0 → 4.1.1
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/extensions/footer.ts +5 -22
- package/extensions/open.ts +12 -8
- package/package.json +1 -1
package/extensions/footer.ts
CHANGED
|
@@ -28,15 +28,10 @@ function isNonNegativeNumber(value: unknown): value is number {
|
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
function subagentBackgroundUsage(details: unknown): CountedUsage | undefined {
|
|
31
|
-
|
|
32
|
-
const
|
|
33
|
-
if (!usage ||
|
|
34
|
-
|
|
35
|
-
const cost = record.cost;
|
|
36
|
-
if (!cost || typeof cost !== "object" || Array.isArray(cost)) return;
|
|
37
|
-
const total = (cost as Record<string, unknown>).total;
|
|
38
|
-
if (!isNonNegativeNumber(record.input) || !isNonNegativeNumber(record.output) || !isNonNegativeNumber(total)) return;
|
|
39
|
-
return { input: record.input, output: record.output, cost: { total } };
|
|
31
|
+
const usage = (details as { usage?: { input?: unknown; output?: unknown; cost?: { total?: unknown } } } | undefined)?.usage;
|
|
32
|
+
const total = usage?.cost?.total;
|
|
33
|
+
if (!isNonNegativeNumber(usage?.input) || !isNonNegativeNumber(usage.output) || !isNonNegativeNumber(total)) return;
|
|
34
|
+
return { input: usage.input, output: usage.output, cost: { total } };
|
|
40
35
|
}
|
|
41
36
|
|
|
42
37
|
function formatTokens(count: number): string {
|
|
@@ -239,21 +234,9 @@ export default function footerExtension(pi: ExtensionAPI): void {
|
|
|
239
234
|
if (finalizeActive()) pi.appendEntry(AGENT_TIME_ENTRY, activeMilliseconds);
|
|
240
235
|
await refreshGitStatus?.();
|
|
241
236
|
});
|
|
242
|
-
pi.on("session_shutdown",
|
|
243
|
-
stopRuntimeTimer();
|
|
244
|
-
activeStartedAt = undefined;
|
|
245
|
-
promptPaused = false;
|
|
246
|
-
refreshGitStatus = undefined;
|
|
247
|
-
activeCodegraphCalls.clear();
|
|
248
|
-
});
|
|
237
|
+
pi.on("session_shutdown", stopRuntimeTimer);
|
|
249
238
|
|
|
250
239
|
pi.on("session_start", async (_event, ctx) => {
|
|
251
|
-
stopRuntimeTimer();
|
|
252
|
-
activeStartedAt = undefined;
|
|
253
|
-
promptPaused = false;
|
|
254
|
-
requestRuntimeRender = undefined;
|
|
255
|
-
refreshGitStatus = undefined;
|
|
256
|
-
activeCodegraphCalls.clear();
|
|
257
240
|
// Latest valid entry wins; stored data is untrusted.
|
|
258
241
|
activeMilliseconds = 0;
|
|
259
242
|
for (const entry of ctx.sessionManager.getEntries()) {
|
package/extensions/open.ts
CHANGED
|
@@ -7,11 +7,15 @@ const DEFAULT_COMMAND = "code";
|
|
|
7
7
|
export type OpenInConfig = { command: string };
|
|
8
8
|
|
|
9
9
|
function parseOpenInConfig(value: unknown): OpenInConfig {
|
|
10
|
-
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
11
|
-
throw new Error('Invalid open-in config: expected exactly one non-empty string "command" property');
|
|
12
|
-
}
|
|
13
10
|
const config = value as Record<string, unknown>;
|
|
14
|
-
if (
|
|
11
|
+
if (
|
|
12
|
+
!config ||
|
|
13
|
+
typeof config !== "object" ||
|
|
14
|
+
Array.isArray(config) ||
|
|
15
|
+
Object.keys(config).length !== 1 ||
|
|
16
|
+
typeof config.command !== "string" ||
|
|
17
|
+
!config.command.trim()
|
|
18
|
+
) {
|
|
15
19
|
throw new Error('Invalid open-in config: expected exactly one non-empty string "command" property');
|
|
16
20
|
}
|
|
17
21
|
return { command: config.command.trim() };
|
|
@@ -31,15 +35,15 @@ export function loadOpenInConfig(agentDir?: string): { source: "file" | "missing
|
|
|
31
35
|
}
|
|
32
36
|
|
|
33
37
|
export function configuredOpenUri(path: string): string | undefined {
|
|
34
|
-
let
|
|
38
|
+
let command: string;
|
|
35
39
|
try {
|
|
36
|
-
|
|
37
|
-
if (executable !== "code") return undefined;
|
|
38
|
-
args = commandArgs;
|
|
40
|
+
command = loadOpenInConfig().value.command;
|
|
39
41
|
} catch {
|
|
40
42
|
// Invalid config must not break footer render; just omit the URI.
|
|
41
43
|
return undefined;
|
|
42
44
|
}
|
|
45
|
+
const [executable, ...args] = command.split(/\s+/);
|
|
46
|
+
if (executable !== "code") return undefined;
|
|
43
47
|
const query = args.includes("-n") || args.includes("--new-window") ? "?windowId=_blank" : "";
|
|
44
48
|
if (path.startsWith("\\\\")) {
|
|
45
49
|
const [host, ...parts] = path.slice(2).split("\\");
|