@narumitw/pi-analytics 0.49.6 → 0.49.7
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/README.md +9 -0
- package/dist/index.ts +1811 -0
- package/dist/index.ts.map +7 -0
- package/package.json +12 -8
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/analytics.ts", "../src/collector.ts", "../src/errors.ts", "../src/menu.ts", "../src/storage/queries.ts", "../src/skills.ts", "../src/storage/files.ts", "../src/storage/format.ts", "../src/storage/store.ts"],
|
|
4
|
+
"sourcesContent": ["import { randomUUID } from \"node:crypto\";\nimport path from \"node:path\";\nimport {\n\ttype ExtensionAPI,\n\ttype ExtensionContext,\n\tgetAgentDir,\n} from \"@earendil-works/pi-coding-agent\";\nimport { ResponseCollector } from \"./collector.js\";\nimport { type AnalyticsMenuDataSource, showAnalyticsMenu } from \"./menu.js\";\nimport { SkillTracker } from \"./skills.js\";\nimport type { ClearAnalyticsResult } from \"./storage/files.js\";\nimport type { AnalyticsSnapshot, TimeRange } from \"./storage/queries.js\";\nimport { AnalyticsStore } from \"./storage/store.js\";\nimport type { ModelIdentity, SettledRun, TriggerSource } from \"./types.js\";\n\nconst EXPERIMENTAL_WARNING = \"pi-analytics is experimental; its metrics and dashboard may change.\";\nconst STORAGE_DIRECTORY = \"pi-analytics\";\n\nexport interface AnalyticsStorePort {\n\treadonly path: string;\n\trecordRun(run: SettledRun, signal?: AbortSignal): Promise<void>;\n\tgetSnapshot(range: TimeRange, signal?: AbortSignal): Promise<AnalyticsSnapshot>;\n\tclearAll(signal?: AbortSignal): Promise<ClearAnalyticsResult>;\n\tclose(): Promise<void>;\n}\n\ninterface AnalyticsDependencies {\n\tcreateStore(path: string): AnalyticsStorePort;\n\tcreateSkillTracker(cwd: string): SkillTracker;\n\tgetAgentDir(): string;\n\tnow(): number;\n\tcreateId(): string;\n}\n\nexport function createAnalyticsExtension(\n\tdependencies: Partial<AnalyticsDependencies> = {},\n): (pi: ExtensionAPI) => void {\n\tconst deps: AnalyticsDependencies = {\n\t\tcreateStore: dependencies.createStore ?? ((rootPath) => new AnalyticsStore(rootPath)),\n\t\tcreateSkillTracker: dependencies.createSkillTracker ?? ((cwd) => new SkillTracker(cwd)),\n\t\tgetAgentDir: dependencies.getAgentDir ?? getAgentDir,\n\t\tnow: dependencies.now ?? Date.now,\n\t\tcreateId: dependencies.createId ?? randomUUID,\n\t};\n\n\treturn function analyticsExtension(pi: ExtensionAPI): void {\n\t\tlet sessionGeneration = 0;\n\t\tlet sessionController = new AbortController();\n\t\tlet collector = new ResponseCollector();\n\t\tlet skillTracker: SkillTracker | undefined;\n\t\tlet store: AnalyticsStorePort | undefined;\n\t\tlet storageFailure: string | undefined;\n\t\tconst retiredCloseTasks = new Set<Promise<boolean>>();\n\t\tlet writeFailureActive = false;\n\t\tlet pendingTriggerSource: TriggerSource = \"unknown\";\n\t\tlet pendingAttemptWithoutRun = false;\n\n\t\tpi.registerCommand(\"analytics\", {\n\t\t\tdescription: \"Open local Pi usage analytics\",\n\t\t\thandler: async (args, ctx) => {\n\t\t\t\tif (args.trim()) {\n\t\t\t\t\tif (!ctx.hasUI || (ctx.mode !== \"tui\" && ctx.mode !== \"rpc\")) {\n\t\t\t\t\t\tthrow new Error(\"/analytics does not accept arguments.\");\n\t\t\t\t\t}\n\t\t\t\t\tctx.ui.notify(\"/analytics does not accept arguments.\", \"warning\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (!ctx.hasUI || (ctx.mode !== \"tui\" && ctx.mode !== \"rpc\")) {\n\t\t\t\t\tthrow new Error(\"/analytics requires Pi TUI or RPC mode.\");\n\t\t\t\t}\n\t\t\t\tconst generation = sessionGeneration;\n\t\t\t\tconst owner = sessionController;\n\t\t\t\tconst source = menuSource(generation, owner.signal);\n\t\t\t\tawait showAnalyticsMenu(ctx, source, {\n\t\t\t\t\tsignal: owner.signal,\n\t\t\t\t\tisCurrent: () => generation === sessionGeneration && !owner.signal.aborted,\n\t\t\t\t});\n\t\t\t},\n\t\t});\n\n\t\tpi.on(\"session_start\", (_event, ctx) => {\n\t\t\t++sessionGeneration;\n\t\t\tif (ctx.hasUI) ctx.ui.notify(EXPERIMENTAL_WARNING, \"warning\");\n\t\t\tconst previousStore = store;\n\t\t\tsessionController.abort(new DOMException(\"Analytics session replaced\", \"AbortError\"));\n\t\t\tif (previousStore) retire(previousStore);\n\t\t\tsessionController = new AbortController();\n\t\t\tcollector = new ResponseCollector();\n\t\t\tskillTracker = deps.createSkillTracker(ctx.cwd);\n\t\t\tstore = undefined;\n\t\t\tstorageFailure = undefined;\n\t\t\twriteFailureActive = false;\n\t\t\tpendingTriggerSource = \"unknown\";\n\t\t\tpendingAttemptWithoutRun = false;\n\t\t\tconst storageRoot = path.join(deps.getAgentDir(), STORAGE_DIRECTORY);\n\t\t\ttry {\n\t\t\t\tstore = deps.createStore(storageRoot);\n\t\t\t} catch {\n\t\t\t\tstorageFailure = unavailableMessage();\n\t\t\t\tsafeNotify(ctx, storageFailure, \"warning\");\n\t\t\t}\n\t\t});\n\n\t\tpi.on(\"input\", (event, ctx) => {\n\t\t\tconst now = deps.now();\n\t\t\tconst tracker = skillTracker;\n\t\t\ttracker?.observeInput(event.text, event.source, now);\n\t\t\tif (event.source !== \"extension\") pendingTriggerSource = event.source;\n\t\t\tif (!tracker || !collector.hasActiveRun()) return;\n\t\t\tconst explicit = tracker.consumeExplicitSkill();\n\t\t\tif (!explicit || !tracker.hasAvailableSkill(explicit.name)) return;\n\t\t\tcollector.activateSkill({\n\t\t\t\tname: explicit.name,\n\t\t\t\tinitiatedBy: \"user\",\n\t\t\t\tnow: explicit.observedAtMs,\n\t\t\t\tmodel: modelIdentity(ctx, pi),\n\t\t\t});\n\t\t});\n\n\t\tpi.on(\"before_agent_start\", async (event, ctx) => {\n\t\t\tconst generation = sessionGeneration;\n\t\t\tconst tracker = skillTracker;\n\t\t\tconst activeCollector = collector;\n\t\t\tif (!tracker) return;\n\t\t\tconst skills = availableSkills(pi, event.systemPromptOptions.skills ?? []);\n\t\t\tawait tracker.setAvailableSkills(skills);\n\t\t\tif (\n\t\t\t\tgeneration !== sessionGeneration ||\n\t\t\t\ttracker !== skillTracker ||\n\t\t\t\tactiveCollector !== collector\n\t\t\t) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst explicit = tracker.consumeExplicitSkill();\n\t\t\tconst interrupted = activeCollector.begin({\n\t\t\t\tid: deps.createId(),\n\t\t\t\tnow: deps.now(),\n\t\t\t\ttriggerSource: explicit?.source ?? pendingTriggerSource,\n\t\t\t\tmodel: modelIdentity(ctx, pi),\n\t\t\t});\n\t\t\tpendingTriggerSource = \"unknown\";\n\t\t\tif (interrupted) {\n\t\t\t\tawait persistRun(interrupted, ctx, generation, sessionController.signal);\n\t\t\t\tif (\n\t\t\t\t\tgeneration !== sessionGeneration ||\n\t\t\t\t\ttracker !== skillTracker ||\n\t\t\t\t\tactiveCollector !== collector\n\t\t\t\t) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (explicit && skills.some(({ name }) => name === explicit.name)) {\n\t\t\t\tactiveCollector.activateSkill({\n\t\t\t\t\tname: explicit.name,\n\t\t\t\t\tinitiatedBy: \"user\",\n\t\t\t\t\tnow: explicit.observedAtMs,\n\t\t\t\t\tmodel: modelIdentity(ctx, pi),\n\t\t\t\t});\n\t\t\t}\n\t\t});\n\n\t\tpi.on(\"agent_start\", () => {\n\t\t\tif (collector.hasActiveRun()) collector.beginAttempt();\n\t\t\telse pendingAttemptWithoutRun = true;\n\t\t});\n\n\t\tpi.on(\"turn_start\", (_event, ctx) => ensureRun(ctx, \"extension\"));\n\n\t\tpi.on(\"before_provider_request\", (_event, ctx) => {\n\t\t\tensureRun(ctx, \"extension\");\n\t\t\tcollector.beginGeneration({\n\t\t\t\tid: deps.createId(),\n\t\t\t\tnow: deps.now(),\n\t\t\t\tmodel: modelIdentity(ctx, pi),\n\t\t\t});\n\t\t});\n\n\t\tpi.on(\"after_provider_response\", (event) => {\n\t\t\tcollector.recordProviderResponse({ status: event.status, now: deps.now() });\n\t\t});\n\n\t\tpi.on(\"message_end\", (event) => {\n\t\t\tif (event.message.role !== \"assistant\") return;\n\t\t\tcollector.finishGeneration({\n\t\t\t\tnow: deps.now(),\n\t\t\t\tstopReason: event.message.stopReason,\n\t\t\t\terrorMessage: event.message.errorMessage,\n\t\t\t});\n\t\t});\n\n\t\tpi.on(\"tool_execution_start\", (event, ctx) => {\n\t\t\tensureRun(ctx, \"extension\");\n\t\t\tcollector.beginTool({\n\t\t\t\tid: event.toolCallId,\n\t\t\t\tname: event.toolName,\n\t\t\t\tnow: deps.now(),\n\t\t\t\tmodel: modelIdentity(ctx, pi),\n\t\t\t});\n\t\t});\n\n\t\tpi.on(\"tool_result\", async (event, ctx) => {\n\t\t\tif (event.toolName === \"read\" && !isBuiltinReadTool(pi)) return;\n\t\t\tconst generation = sessionGeneration;\n\t\t\tconst tracker = skillTracker;\n\t\t\tconst activeCollector = collector;\n\t\t\tconst runId = activeCollector.getActiveRunId();\n\t\t\tif (!tracker || !runId) return;\n\t\t\tconst name = await tracker.matchSuccessfulRead({\n\t\t\t\ttoolName: event.toolName,\n\t\t\t\tinput: event.input,\n\t\t\t\tisError: event.isError,\n\t\t\t});\n\t\t\tif (\n\t\t\t\t!name ||\n\t\t\t\tgeneration !== sessionGeneration ||\n\t\t\t\ttracker !== skillTracker ||\n\t\t\t\tactiveCollector !== collector ||\n\t\t\t\tactiveCollector.getActiveRunId() !== runId\n\t\t\t) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tactiveCollector.activateSkill({\n\t\t\t\tname,\n\t\t\t\tinitiatedBy: \"model\",\n\t\t\t\tnow: deps.now(),\n\t\t\t\tmodel: modelIdentity(ctx, pi),\n\t\t\t});\n\t\t});\n\n\t\tpi.on(\"tool_execution_end\", (event) => {\n\t\t\tcollector.finishTool({ id: event.toolCallId, now: deps.now(), isError: event.isError });\n\t\t});\n\n\t\tpi.on(\"agent_settled\", async (_event, ctx) => {\n\t\t\tconst generation = sessionGeneration;\n\t\t\tconst owner = sessionController;\n\t\t\tconst run = collector.settle(deps.now());\n\t\t\tpendingAttemptWithoutRun = false;\n\t\t\tpendingTriggerSource = \"unknown\";\n\t\t\tskillTracker?.clearPending();\n\t\t\tif (run) await persistRun(run, ctx, generation, owner.signal);\n\t\t});\n\n\t\tpi.on(\"session_shutdown\", async (_event, ctx) => {\n\t\t\tconst activeStore = store;\n\t\t\t++sessionGeneration;\n\t\t\tsessionController.abort(new DOMException(\"Analytics session shut down\", \"AbortError\"));\n\t\t\tskillTracker?.clearPending();\n\t\t\tskillTracker = undefined;\n\t\t\tstore = undefined;\n\t\t\tcollector.interrupt(deps.now());\n\t\t\tconst closing = activeStore\n\t\t\t\t? [closeResult(activeStore), ...retiredCloseTasks]\n\t\t\t\t: [...retiredCloseTasks];\n\t\t\tconst results = await Promise.all(closing);\n\t\t\tif (results.some((closed) => !closed)) {\n\t\t\t\tsafeNotify(ctx, \"Analytics storage shutdown was incomplete.\", \"warning\");\n\t\t\t}\n\t\t});\n\n\t\tfunction retire(retiredStore: AnalyticsStorePort): void {\n\t\t\tconst task = closeResult(retiredStore).finally(() => retiredCloseTasks.delete(task));\n\t\t\tretiredCloseTasks.add(task);\n\t\t}\n\n\t\tasync function closeResult(activeStore: AnalyticsStorePort): Promise<boolean> {\n\t\t\ttry {\n\t\t\t\tawait activeStore.close();\n\t\t\t\treturn true;\n\t\t\t} catch {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\tfunction ensureRun(ctx: ExtensionContext, triggerSource: TriggerSource): void {\n\t\t\tif (collector.hasActiveRun()) return;\n\t\t\tcollector.begin({\n\t\t\t\tid: deps.createId(),\n\t\t\t\tnow: deps.now(),\n\t\t\t\ttriggerSource,\n\t\t\t\tmodel: modelIdentity(ctx, pi),\n\t\t\t});\n\t\t\tif (pendingAttemptWithoutRun) {\n\t\t\t\tpendingAttemptWithoutRun = false;\n\t\t\t\tcollector.beginAttempt();\n\t\t\t}\n\t\t}\n\n\t\tasync function persistRun(\n\t\t\trun: SettledRun,\n\t\t\tctx: ExtensionContext,\n\t\t\tgeneration: number,\n\t\t\tsignal: AbortSignal,\n\t\t): Promise<void> {\n\t\t\tconst activeStore = store;\n\t\t\tif (!activeStore || signal.aborted) return;\n\t\t\ttry {\n\t\t\t\tawait activeStore.recordRun(run, signal);\n\t\t\t\tif (generation !== sessionGeneration || activeStore !== store || signal.aborted) return;\n\t\t\t\tif (writeFailureActive) {\n\t\t\t\t\twriteFailureActive = false;\n\t\t\t\t\tsafeNotify(ctx, \"Local analytics storage recovered.\", \"info\");\n\t\t\t\t}\n\t\t\t} catch {\n\t\t\t\tif (\n\t\t\t\t\tgeneration !== sessionGeneration ||\n\t\t\t\t\tactiveStore !== store ||\n\t\t\t\t\tsignal.aborted ||\n\t\t\t\t\twriteFailureActive\n\t\t\t\t) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\twriteFailureActive = true;\n\t\t\t\tsafeNotify(\n\t\t\t\t\tctx,\n\t\t\t\t\t\"Analytics could not save this response cycle; its metrics were dropped.\",\n\t\t\t\t\t\"warning\",\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\tfunction menuSource(generation: number, signal: AbortSignal): AnalyticsMenuDataSource {\n\t\t\treturn {\n\t\t\t\tpath: store?.path ?? path.join(deps.getAgentDir(), STORAGE_DIRECTORY),\n\t\t\t\tasync load(range, actionSignal) {\n\t\t\t\t\tassertCurrent(generation, signal);\n\t\t\t\t\tconst activeStore = store;\n\t\t\t\t\tif (!activeStore) {\n\t\t\t\t\t\treturn { kind: \"unavailable\", message: storageFailure ?? unavailableMessage() };\n\t\t\t\t\t}\n\t\t\t\t\tconst snapshot = await activeStore.getSnapshot(range, actionSignal);\n\t\t\t\t\tassertCurrent(generation, signal);\n\t\t\t\t\treturn { kind: \"ready\", snapshot };\n\t\t\t\t},\n\t\t\t\tasync clearAll(actionSignal) {\n\t\t\t\t\tassertCurrent(generation, signal);\n\t\t\t\t\tconst activeStore = store;\n\t\t\t\t\tif (!activeStore) return { cleanupIncomplete: false };\n\t\t\t\t\treturn activeStore.clearAll(actionSignal);\n\t\t\t\t},\n\t\t\t};\n\t\t}\n\n\t\tfunction assertCurrent(generation: number, signal: AbortSignal): void {\n\t\t\tif (generation !== sessionGeneration || signal.aborted) {\n\t\t\t\tthrow new DOMException(\"Analytics interaction replaced\", \"AbortError\");\n\t\t\t}\n\t\t}\n\t};\n}\n\nfunction modelIdentity(ctx: ExtensionContext, pi: ExtensionAPI): ModelIdentity | undefined {\n\tif (!ctx.model) return undefined;\n\treturn {\n\t\tprovider: ctx.model.provider,\n\t\tmodel: ctx.model.id,\n\t\tthinkingLevel: pi.getThinkingLevel(),\n\t};\n}\n\nexport function isBuiltinReadTool(pi: ExtensionAPI): boolean {\n\tconst read = pi.getAllTools().find(({ name }) => name === \"read\");\n\treturn read?.sourceInfo.source === \"builtin\";\n}\n\nfunction availableSkills(\n\tpi: ExtensionAPI,\n\tsystemSkills: ReadonlyArray<{ name: string; filePath: string }>,\n): Array<{ name: string; filePath: string }> {\n\tconst result = [...systemSkills];\n\tconst seen = new Set(result.map(({ name }) => name));\n\tconst getCommands = (pi as ExtensionAPI & { getCommands?: ExtensionAPI[\"getCommands\"] })\n\t\t.getCommands;\n\tfor (const command of typeof getCommands === \"function\" ? getCommands.call(pi) : []) {\n\t\tif (command.source !== \"skill\" || seen.has(command.name.replace(/^skill:/u, \"\"))) continue;\n\t\tconst name = command.name.replace(/^skill:/u, \"\");\n\t\tseen.add(name);\n\t\tresult.push({ name, filePath: command.sourceInfo.path });\n\t}\n\treturn result;\n}\n\nfunction unavailableMessage(): string {\n\treturn [\n\t\t\"Local analytics storage could not be initialized safely.\",\n\t\t\"Existing files were not replaced.\",\n\t\t\"No analytics are being collected.\",\n\t].join(\"\\n\");\n}\n\nfunction safeNotify(ctx: ExtensionContext, message: string, level: \"info\" | \"warning\"): void {\n\ttry {\n\t\tctx.ui.notify(message, level);\n\t} catch {\n\t\t// A replaced Pi context cannot receive lifecycle feedback.\n\t}\n}\n\nexport default createAnalyticsExtension();\n", "import { randomUUID } from \"node:crypto\";\nimport { classifyProviderError } from \"./errors.js\";\nimport type {\n\tGenerationOutcome,\n\tGenerationRecord,\n\tModelIdentity,\n\tProviderErrorRecord,\n\tRunOutcome,\n\tSettledRun,\n\tSkillActivationRecord,\n\tToolCallRecord,\n\tTriggerSource,\n} from \"./types.js\";\n\ninterface ActiveRun {\n\tid: string;\n\tstartedAtMs: number;\n\ttriggerSource: TriggerSource;\n\tinitialModel?: ModelIdentity;\n\tattemptCount: number;\n\tgenerations: GenerationRecord[];\n\tgenerationIds: Set<string>;\n\ttools: ToolCallRecord[];\n\ttoolIds: Set<string>;\n\tskills: SkillActivationRecord[];\n\tskillIndexes: Map<string, number>;\n\tproviderErrors: ProviderErrorRecord[];\n}\n\nexport class ResponseCollector {\n\tprivate active: ActiveRun | undefined;\n\n\thasActiveRun(): boolean {\n\t\treturn this.active !== undefined;\n\t}\n\n\tgetActiveRunId(): string | undefined {\n\t\treturn this.active?.id;\n\t}\n\n\tbegin(input: {\n\t\tid: string;\n\t\tnow: number;\n\t\ttriggerSource: TriggerSource;\n\t\tmodel?: ModelIdentity;\n\t}): SettledRun | undefined {\n\t\tconst interrupted = this.active ? this.finalize(input.now, \"interrupted\") : undefined;\n\t\tthis.active = {\n\t\t\tid: input.id,\n\t\t\tstartedAtMs: input.now,\n\t\t\ttriggerSource: input.triggerSource,\n\t\t\tinitialModel: input.model,\n\t\t\tattemptCount: 0,\n\t\t\tgenerations: [],\n\t\t\tgenerationIds: new Set(),\n\t\t\ttools: [],\n\t\t\ttoolIds: new Set(),\n\t\t\tskills: [],\n\t\t\tskillIndexes: new Map(),\n\t\t\tproviderErrors: [],\n\t\t};\n\t\treturn interrupted;\n\t}\n\n\tbeginAttempt(): void {\n\t\tif (this.active) this.active.attemptCount += 1;\n\t}\n\n\tbeginGeneration(input: { id: string; now: number; model?: ModelIdentity }): void {\n\t\tconst active = this.active;\n\t\tif (!active || active.generationIds.has(input.id)) return;\n\t\tactive.generationIds.add(input.id);\n\t\tactive.generations.push({\n\t\t\tid: input.id,\n\t\t\tordinal: active.generations.length,\n\t\t\tprovider: input.model?.provider,\n\t\t\tmodel: input.model?.model,\n\t\t\tthinkingLevel: input.model?.thinkingLevel,\n\t\t\tstartedAtMs: input.now,\n\t\t\toutcome: \"pending\",\n\t\t\tresponses: [],\n\t\t});\n\t}\n\n\trecordProviderResponse(input: { status: number; now: number }): void {\n\t\tconst generation = this.latestGeneration();\n\t\tif (generation?.outcome !== \"pending\") return;\n\t\tgeneration.responses.push({\n\t\t\tordinal: generation.responses.length,\n\t\t\toccurredAtMs: input.now,\n\t\t\tstatus: input.status,\n\t\t});\n\t}\n\n\tfinishGeneration(input: { now: number; stopReason: string; errorMessage?: string }): void {\n\t\tconst active = this.active;\n\t\tconst generation = this.latestGeneration();\n\t\tif (!active || !generation || generation.outcome !== \"pending\") return;\n\t\tgeneration.finishedAtMs = input.now;\n\t\tgeneration.durationMs = elapsed(generation.startedAtMs, input.now);\n\t\tgeneration.stopReason = input.stopReason;\n\t\tgeneration.outcome = generationOutcome(input.stopReason);\n\t\tif (generation.outcome === \"error\") {\n\t\t\tactive.providerErrors.push({\n\t\t\t\tid: randomUUID(),\n\t\t\t\tgenerationId: generation.id,\n\t\t\t\toccurredAtMs: input.now,\n\t\t\t\tprovider: generation.provider,\n\t\t\t\tmodel: generation.model,\n\t\t\t\tcategory: classifyProviderError(input.errorMessage),\n\t\t\t\trecovered: false,\n\t\t\t\tterminal: true,\n\t\t\t});\n\t\t}\n\t}\n\n\tbeginTool(input: { id: string; name: string; now: number; model?: ModelIdentity }): void {\n\t\tconst active = this.active;\n\t\tif (!active || active.toolIds.has(input.id)) return;\n\t\tactive.toolIds.add(input.id);\n\t\tactive.tools.push({\n\t\t\tid: input.id,\n\t\t\tordinal: active.tools.length,\n\t\t\tname: input.name,\n\t\t\tprovider: input.model?.provider,\n\t\t\tmodel: input.model?.model,\n\t\t\tstartedAtMs: input.now,\n\t\t\tisError: false,\n\t\t\tcompletionState: \"running\",\n\t\t});\n\t}\n\n\tfinishTool(input: { id: string; now: number; isError: boolean }): void {\n\t\tconst tool = this.active?.tools.find(({ id }) => id === input.id);\n\t\tif (tool?.completionState !== \"running\") return;\n\t\ttool.finishedAtMs = input.now;\n\t\ttool.durationMs = elapsed(tool.startedAtMs, input.now);\n\t\ttool.isError = input.isError;\n\t\ttool.completionState = \"finished\";\n\t}\n\n\tactivateSkill(input: {\n\t\tname: string;\n\t\tinitiatedBy: \"user\" | \"model\";\n\t\tnow: number;\n\t\tmodel?: ModelIdentity;\n\t}): void {\n\t\tconst active = this.active;\n\t\tif (!active) return;\n\t\tconst existingIndex = active.skillIndexes.get(input.name);\n\t\tif (existingIndex !== undefined) {\n\t\t\tconst existing = active.skills[existingIndex];\n\t\t\tif (existing && existing.initiatedBy === \"model\" && input.initiatedBy === \"user\") {\n\t\t\t\texisting.initiatedBy = \"user\";\n\t\t\t\texisting.occurredAtMs = input.now;\n\t\t\t\texisting.provider = input.model?.provider;\n\t\t\t\texisting.model = input.model?.model;\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\tactive.skillIndexes.set(input.name, active.skills.length);\n\t\tactive.skills.push({\n\t\t\tid: randomUUID(),\n\t\t\tname: input.name,\n\t\t\tinitiatedBy: input.initiatedBy,\n\t\t\toccurredAtMs: input.now,\n\t\t\tprovider: input.model?.provider,\n\t\t\tmodel: input.model?.model,\n\t\t});\n\t}\n\n\tsettle(now: number): SettledRun | undefined {\n\t\treturn this.finalize(now);\n\t}\n\n\tinterrupt(now: number): SettledRun | undefined {\n\t\treturn this.finalize(now, \"interrupted\");\n\t}\n\n\tprivate latestGeneration(): GenerationRecord | undefined {\n\t\treturn this.active?.generations.at(-1);\n\t}\n\n\tprivate finalize(now: number, forcedOutcome?: RunOutcome): SettledRun | undefined {\n\t\tconst active = this.active;\n\t\tif (!active) return undefined;\n\t\tthis.active = undefined;\n\n\t\tfor (const generation of active.generations) {\n\t\t\tif (generation.outcome !== \"pending\") continue;\n\t\t\tgeneration.outcome = \"interrupted\";\n\t\t\tgeneration.finishedAtMs = now;\n\t\t\tgeneration.durationMs = elapsed(generation.startedAtMs, now);\n\t\t}\n\t\tfor (const tool of active.tools) {\n\t\t\tif (tool.completionState !== \"running\") continue;\n\t\t\ttool.completionState = \"interrupted\";\n\t\t\ttool.finishedAtMs = now;\n\t\t\ttool.durationMs = elapsed(tool.startedAtMs, now);\n\t\t}\n\n\t\tconst successfulGenerationIndexes = new Set(\n\t\t\tactive.generations\n\t\t\t\t.map((generation, index) => ({ generation, index }))\n\t\t\t\t.filter(({ generation }) => isSuccessfulGeneration(generation))\n\t\t\t\t.map(({ index }) => index),\n\t\t);\n\t\tlet recoveredHttpErrors = 0;\n\t\tlet httpErrors = 0;\n\t\tfor (const [generationIndex, generation] of active.generations.entries()) {\n\t\t\tconst hasLaterSuccess = [...successfulGenerationIndexes].some(\n\t\t\t\t(index) => index > generationIndex,\n\t\t\t);\n\t\t\tfor (const [responseIndex, response] of generation.responses.entries()) {\n\t\t\t\tif (response.status < 400) continue;\n\t\t\t\thttpErrors += 1;\n\t\t\t\tconst laterSuccessInGeneration = generation.responses\n\t\t\t\t\t.slice(responseIndex + 1)\n\t\t\t\t\t.some(({ status }) => status >= 200 && status < 400);\n\t\t\t\tif (laterSuccessInGeneration || hasLaterSuccess) recoveredHttpErrors += 1;\n\t\t\t}\n\t\t}\n\t\tfor (const error of active.providerErrors) {\n\t\t\tconst generationIndex = active.generations.findIndex(({ id }) => id === error.generationId);\n\t\t\terror.recovered = [...successfulGenerationIndexes].some((index) => index > generationIndex);\n\t\t\terror.terminal = !error.recovered;\n\t\t}\n\n\t\tconst recoveredGenerationErrors = active.providerErrors.filter(\n\t\t\t({ recovered }) => recovered,\n\t\t).length;\n\t\tconst providerErrorCount = httpErrors + active.providerErrors.length;\n\t\tconst recoveredErrorCount = recoveredHttpErrors + recoveredGenerationErrors;\n\t\tconst outcome = forcedOutcome ?? deriveOutcome(active.generations, providerErrorCount);\n\n\t\treturn {\n\t\t\tid: active.id,\n\t\t\tstartedAtMs: active.startedAtMs,\n\t\t\tfinishedAtMs: now,\n\t\t\tdurationMs: elapsed(active.startedAtMs, now),\n\t\t\ttriggerSource: active.triggerSource,\n\t\t\tinitialProvider: active.initialModel?.provider,\n\t\t\tinitialModel: active.initialModel?.model,\n\t\t\toutcome,\n\t\t\tattemptCount: active.attemptCount,\n\t\t\tgenerations: active.generations,\n\t\t\ttools: active.tools,\n\t\t\tskills: active.skills,\n\t\t\tproviderErrors: active.providerErrors,\n\t\t\ttoolErrorCount: active.tools.filter(({ isError }) => isError).length,\n\t\t\tproviderErrorCount,\n\t\t\trecoveredErrorCount,\n\t\t};\n\t}\n}\n\nfunction elapsed(start: number, end: number): number {\n\treturn Math.max(0, end - start);\n}\n\nfunction generationOutcome(stopReason: string): GenerationOutcome {\n\tswitch (stopReason) {\n\t\tcase \"stop\":\n\t\t\treturn \"stop\";\n\t\tcase \"toolUse\":\n\t\t\treturn \"tool_use\";\n\t\tcase \"error\":\n\t\t\treturn \"error\";\n\t\tcase \"aborted\":\n\t\t\treturn \"aborted\";\n\t\tcase \"length\":\n\t\t\treturn \"length\";\n\t\tdefault:\n\t\t\treturn \"interrupted\";\n\t}\n}\n\nfunction isSuccessfulGeneration(generation: GenerationRecord): boolean {\n\treturn generation.outcome === \"stop\" || generation.outcome === \"tool_use\";\n}\n\nfunction deriveOutcome(\n\tgenerations: readonly GenerationRecord[],\n\tproviderErrors: number,\n): RunOutcome {\n\tconst last = generations.at(-1);\n\tif (!last) return providerErrors > 0 ? \"error\" : \"success\";\n\tswitch (last.outcome) {\n\t\tcase \"stop\":\n\t\tcase \"tool_use\":\n\t\t\treturn providerErrors > 0 ? \"recovered_success\" : \"success\";\n\t\tcase \"error\":\n\t\t\treturn \"error\";\n\t\tcase \"aborted\":\n\t\t\treturn \"aborted\";\n\t\tcase \"length\":\n\t\t\treturn \"length\";\n\t\tdefault:\n\t\t\treturn \"interrupted\";\n\t}\n}\n", "import type { ProviderErrorCategory } from \"./types.js\";\n\nexport function classifyProviderError(message: string | undefined): ProviderErrorCategory {\n\tconst value = message?.toLowerCase() ?? \"\";\n\tif (/\\b(enotfound|eai_again|dns|getaddrinfo)\\b/u.test(value)) return \"dns\";\n\tif (/\\b(etimedout|timeout|timed out)\\b/u.test(value)) return \"timeout\";\n\tif (/\\b(econnrefused|connection refused)\\b/u.test(value)) return \"connection_refused\";\n\tif (/\\b(econnreset|connection reset|socket hang up)\\b/u.test(value)) {\n\t\treturn \"connection_reset\";\n\t}\n\tif (/\\b(tls|ssl|certificate|cert_|handshake)\\b/u.test(value)) return \"tls\";\n\tif (/\\b(fetch failed|network|socket|connection|transport)\\b/u.test(value)) {\n\t\treturn \"network_other\";\n\t}\n\treturn \"provider_other\";\n}\n", "import { stripVTControlCharacters } from \"node:util\";\nimport type { ExtensionCommandContext } from \"@earendil-works/pi-coding-agent\";\nimport type { MenuDefinition } from \"@narumitw/pi-tui-kit\";\nimport type { ClearAnalyticsResult } from \"./storage/files.js\";\nimport type {\n\tAnalyticsSnapshot,\n\tSkillStats,\n\tTimeRange,\n\tTimeRangeId,\n\tToolStats,\n} from \"./storage/queries.js\";\nimport { resolveTimeRange } from \"./storage/queries.js\";\n\nexport type AnalyticsLoadResult =\n\t| { kind: \"ready\"; snapshot: AnalyticsSnapshot }\n\t| { kind: \"unavailable\"; message: string };\n\nexport interface AnalyticsMenuDataSource {\n\tpath: string;\n\tload(range: TimeRange, signal: AbortSignal): Promise<AnalyticsLoadResult>;\n\tclearAll(signal: AbortSignal): Promise<ClearAnalyticsResult>;\n}\n\nexport interface AnalyticsMenuState {\n\trangeId: TimeRangeId;\n\trange: TimeRange;\n\tpath: string;\n\tresult: AnalyticsLoadResult;\n}\n\nexport interface AnalyticsMenuOptions {\n\trunConfirmation: typeof import(\"@narumitw/pi-tui-kit\")[\"runConfirmation\"];\n\tisCurrent(): boolean;\n}\n\ntype Screen = \"main\" | \"range\" | \"skills\" | \"tools\" | \"reliability\" | \"responses\" | \"privacy\";\ntype Action = \"setRange\" | \"clearData\";\n\nconst RANGE_LABELS: Record<TimeRangeId, string> = {\n\ttoday: \"Today\",\n\t\"7d\": \"Last 7 days\",\n\t\"30d\": \"Last 30 days\",\n\tall: \"All time\",\n};\n\nexport function createAnalyticsMenu(\n\tsource: AnalyticsMenuDataSource,\n\tnow: () => number = Date.now,\n\toptions?: AnalyticsMenuOptions,\n) {\n\tlet rangeId: TimeRangeId = \"7d\";\n\tlet cachedState: AnalyticsMenuState | undefined;\n\tconst loadState = async (signal: AbortSignal): Promise<AnalyticsMenuState> => {\n\t\tif (cachedState?.rangeId === rangeId) return cachedState;\n\t\tconst range = resolveTimeRange(rangeId, now());\n\t\tconst loaded = { rangeId, range, path: source.path, result: await source.load(range, signal) };\n\t\tif (!signal.aborted && rangeId === loaded.rangeId) cachedState = loaded;\n\t\treturn loaded;\n\t};\n\tconst getState = ({ signal }: { signal: AbortSignal }): Promise<AnalyticsMenuState> =>\n\t\tloadState(signal);\n\tconst menu: MenuDefinition<AnalyticsMenuState, Screen, Action> = {\n\t\tstart: \"main\",\n\t\tscreens: {\n\t\t\tmain: ({ state }) => ({\n\t\t\t\tkind: \"actions\",\n\t\t\t\ttitle: `Analytics \u00B7 ${RANGE_LABELS[state.rangeId]}`,\n\t\t\t\tlines: overviewLines(state.result),\n\t\t\t\titems: [\n\t\t\t\t\t{ id: \"range\", label: \"Change time range\", to: \"range\" },\n\t\t\t\t\t{ id: \"skills\", label: \"Skills\", to: \"skills\" },\n\t\t\t\t\t{ id: \"tools\", label: \"Tools\", to: \"tools\" },\n\t\t\t\t\t{ id: \"reliability\", label: \"Provider reliability\", to: \"reliability\" },\n\t\t\t\t\t{ id: \"responses\", label: \"Response cycles\", to: \"responses\" },\n\t\t\t\t\t{ id: \"privacy\", label: \"Data & privacy\", to: \"privacy\" },\n\t\t\t\t\t{ id: \"close\", label: \"Close\", close: true },\n\t\t\t\t],\n\t\t\t\thint: \"close\",\n\t\t\t}),\n\t\t\trange: ({ state }) => ({\n\t\t\t\tkind: \"choice\",\n\t\t\t\ttitle: \"Analytics time range\",\n\t\t\t\titems: (Object.keys(RANGE_LABELS) as TimeRangeId[]).map((id) => ({\n\t\t\t\t\tid,\n\t\t\t\t\tlabel: RANGE_LABELS[id],\n\t\t\t\t})),\n\t\t\t\taction: \"setRange\",\n\t\t\t\tcurrentItemId: state.rangeId,\n\t\t\t\tinitialItemId: state.rangeId,\n\t\t\t\thint: \"back\",\n\t\t\t}),\n\t\t\tskills: ({ state }) => skillsScreen(state.result),\n\t\t\ttools: ({ state }) => toolsScreen(state.result),\n\t\t\treliability: ({ state }) => ({\n\t\t\t\tkind: \"detail\",\n\t\t\t\ttitle: `Provider reliability \u00B7 ${RANGE_LABELS[state.rangeId]}`,\n\t\t\t\tlines: reliabilityLines(state.result),\n\t\t\t\thint: \"back\",\n\t\t\t}),\n\t\t\tresponses: ({ state }) => ({\n\t\t\t\tkind: \"detail\",\n\t\t\t\ttitle: `Response cycles \u00B7 ${RANGE_LABELS[state.rangeId]}`,\n\t\t\t\tlines: responseLines(state.result),\n\t\t\t\thint: \"back\",\n\t\t\t}),\n\t\t\tprivacy: ({ state }) => ({\n\t\t\t\tkind: \"actions\",\n\t\t\t\ttitle: \"Analytics data & privacy\",\n\t\t\t\tlines: privacyLines(state),\n\t\t\t\titems: [\n\t\t\t\t\t{\n\t\t\t\t\t\tid: \"clear\",\n\t\t\t\t\t\tlabel: \"Clear analytics data\u2026\",\n\t\t\t\t\t\taction: \"clearData\",\n\t\t\t\t\t\tdisabled: state.result.kind !== \"ready\",\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t\thint: \"back\",\n\t\t\t}),\n\t\t},\n\t\tactions: {\n\t\t\tsetRange: async ({ itemId, signal }) => {\n\t\t\t\tif (!isRangeId(itemId)) return { kind: \"rejected\", error: new Error(\"Unknown range\") };\n\t\t\t\trangeId = itemId;\n\t\t\t\tcachedState = undefined;\n\t\t\t\tawait loadState(signal);\n\t\t\t\treturn signal.aborted ? { kind: \"close\" } : { kind: \"to\", screen: \"main\" };\n\t\t\t},\n\t\t\tclearData: async ({ ctx, state, signal }) => {\n\t\t\t\tif (state.result.kind !== \"ready\") return { kind: \"stay\" };\n\t\t\t\tif (!options) throw new Error(\"Analytics confirmation is unavailable\");\n\t\t\t\tconst count = state.result.snapshot.overview.responseCycles;\n\t\t\t\tconst confirmation = await options.runConfirmation(ctx, {\n\t\t\t\t\ttitle: \"Delete analytics data?\",\n\t\t\t\t\tmessage: `This will clear all local analytics history from:\\n\\n${safeDisplayText(state.path)}\\n\\nThe selected range currently shows ${count} response cycles. Other running Pi processes may add new records afterward.`,\n\t\t\t\t\tconfirmLabel: \"Delete data\",\n\t\t\t\t\tcancelLabel: \"Keep data\",\n\t\t\t\t\tsignal,\n\t\t\t\t\tisCurrent: options.isCurrent,\n\t\t\t\t\t// Keep the dashboard's existing domain-level error route as the only notifier.\n\t\t\t\t\tonError: () => undefined,\n\t\t\t\t});\n\t\t\t\tif (signal.aborted || !options.isCurrent()) return { kind: \"close\" };\n\t\t\t\tif (confirmation.kind === \"closed\") {\n\t\t\t\t\treturn confirmation.reason === \"close\" ? { kind: \"close\" } : { kind: \"stay\" };\n\t\t\t\t}\n\t\t\t\tif (confirmation.kind === \"stale\") return { kind: \"close\" };\n\t\t\t\tif (confirmation.kind === \"unsupported\") {\n\t\t\t\t\tthrow new Error(`Analytics confirmation is unavailable in ${confirmation.mode} mode`);\n\t\t\t\t}\n\t\t\t\tif (confirmation.kind === \"error\") throw confirmation.error;\n\n\t\t\t\tconst result = await source.clearAll(signal);\n\t\t\t\tcachedState = undefined;\n\t\t\t\tconst isCurrent = options.isCurrent();\n\t\t\t\tif (isCurrent) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tctx.ui.notify(\"Cleared local analytics data.\", \"info\");\n\t\t\t\t\t\tif (result.cleanupIncomplete) {\n\t\t\t\t\t\t\tctx.ui.notify(\n\t\t\t\t\t\t\t\t\"Some obsolete analytics files are still in use. Stop other Pi processes and clear again to remove them.\",\n\t\t\t\t\t\t\t\t\"warning\",\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t} catch {\n\t\t\t\t\t\t// The host can dispose the current UI after the ownership check.\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn signal.aborted || !isCurrent ? { kind: \"close\" } : { kind: \"to\", screen: \"main\" };\n\t\t\t},\n\t\t},\n\t};\n\treturn {\n\t\tmenu,\n\t\tgetState,\n\t\tpreload: (signal: AbortSignal) => loadState(signal),\n\t\tget rangeId() {\n\t\t\treturn rangeId;\n\t\t},\n\t};\n}\n\nexport async function showAnalyticsMenu(\n\tctx: ExtensionCommandContext,\n\tsource: AnalyticsMenuDataSource,\n\toptions: { signal: AbortSignal; isCurrent: () => boolean },\n): Promise<void> {\n\tconst { runConfirmation, runMenu, runTask } = await import(\"@narumitw/pi-tui-kit\");\n\tif (options.signal.aborted || !options.isCurrent()) return;\n\tconst controller = createAnalyticsMenu(source, Date.now, {\n\t\trunConfirmation,\n\t\tisCurrent: options.isCurrent,\n\t});\n\tconst loading = await runTask(ctx, {\n\t\tlabel: \"Loading local analytics\u2026\",\n\t\tsignal: options.signal,\n\t\tisCurrent: options.isCurrent,\n\t\ttask: ({ signal }) => controller.preload(signal),\n\t\tonError: () => undefined,\n\t});\n\tif (loading.kind !== \"completed\") {\n\t\tif (loading.kind === \"error\") {\n\t\t\tctx.ui.notify(\n\t\t\t\t\"Analytics failed: The local analytics query could not be completed. Existing data was not changed.\",\n\t\t\t\t\"error\",\n\t\t\t);\n\t\t}\n\t\treturn;\n\t}\n\tawait runMenu(ctx, controller.menu, {\n\t\tgetState: controller.getState,\n\t\tsignal: options.signal,\n\t\tisCurrent: options.isCurrent,\n\t\tonError: (_ctx, error) => {\n\t\t\tctx.ui.notify(`Analytics failed: ${safeErrorMessage(error)}`, \"error\");\n\t\t},\n\t});\n}\n\nfunction overviewLines(result: AnalyticsLoadResult): string[] {\n\tif (result.kind === \"unavailable\") {\n\t\treturn [result.message, \"\", \"No analytics are being collected.\"];\n\t}\n\tconst stats = result.snapshot.overview;\n\tif (stats.responseCycles === 0) {\n\t\treturn [\n\t\t\t\"No analytics yet.\",\n\t\t\t\"Collection is active. Complete one Pi response cycle, then open /analytics again.\",\n\t\t\t\"\",\n\t\t\t\"Includes settled response cycles only.\",\n\t\t];\n\t}\n\treturn [\n\t\tmetric(\"Response cycles\", stats.responseCycles),\n\t\tmetric(\"LLM calls\", stats.llmCalls),\n\t\tmetric(\n\t\t\t\"Calls per response\",\n\t\t\t`${formatDecimal(stats.callsPerResponse)} \u00B7 P95 ${stats.p95CallsPerResponse}`,\n\t\t),\n\t\tmetric(\"Tool calls\", stats.toolCalls),\n\t\tmetric(\"Tool errors\", stats.toolErrors),\n\t\tmetric(\"Skill activations\", stats.skillActivations),\n\t\tmetric(\"Provider errors\", stats.providerErrors),\n\t\tmetric(\"Recovered errors\", stats.recoveredErrors),\n\t\t\"\",\n\t\t\"Includes settled response cycles only.\",\n\t];\n}\n\nfunction skillsScreen(result: AnalyticsLoadResult) {\n\tif (result.kind === \"unavailable\") {\n\t\treturn {\n\t\t\tkind: \"browse\" as const,\n\t\t\ttitle: \"Skills\",\n\t\t\tlines: [result.message],\n\t\t\titems: [],\n\t\t\thint: \"back\" as const,\n\t\t};\n\t}\n\treturn {\n\t\tkind: \"browse\" as const,\n\t\ttitle: \"Skills\",\n\t\tlines:\n\t\t\tresult.snapshot.skills.length === 0\n\t\t\t\t? [\"No skill activations detected in this time range.\"]\n\t\t\t\t: undefined,\n\t\titems: result.snapshot.skills.map(skillItem),\n\t\tviewportSize: \"adaptive\" as const,\n\t\thint: \"back\" as const,\n\t};\n}\n\nfunction skillItem(skill: SkillStats) {\n\treturn {\n\t\tid: skill.name,\n\t\tlabel: safeDisplayText(skill.name),\n\t\tstatusText: `${skill.count} \u00B7 ${skill.modelInitiated} model / ${skill.userInitiated} user`,\n\t\tsearchText: skill.models.map(modelLabel).join(\" \"),\n\t\tdetails: [\n\t\t\tmetric(\"Activations\", skill.count),\n\t\t\tmetric(\"Model initiated\", skill.modelInitiated),\n\t\t\tmetric(\"User initiated\", skill.userInitiated),\n\t\t\t\"\",\n\t\t\t\"By model\",\n\t\t\t...skill.models.map((model) => `${modelLabel(model)}: ${model.count}`),\n\t\t\t\"\",\n\t\t\t`Last detected: ${formatTimestamp(skill.lastOccurredAtMs)}`,\n\t\t],\n\t};\n}\n\nfunction toolsScreen(result: AnalyticsLoadResult) {\n\tif (result.kind === \"unavailable\") {\n\t\treturn {\n\t\t\tkind: \"browse\" as const,\n\t\t\ttitle: \"Tools\",\n\t\t\tlines: [result.message],\n\t\t\titems: [],\n\t\t\thint: \"back\" as const,\n\t\t};\n\t}\n\treturn {\n\t\tkind: \"browse\" as const,\n\t\ttitle: \"Tools\",\n\t\tlines:\n\t\t\tresult.snapshot.tools.length === 0\n\t\t\t\t? [\"No tool calls detected in this time range.\"]\n\t\t\t\t: undefined,\n\t\titems: result.snapshot.tools.map(toolItem),\n\t\tviewportSize: \"adaptive\" as const,\n\t\thint: \"back\" as const,\n\t};\n}\n\nfunction toolItem(tool: ToolStats) {\n\treturn {\n\t\tid: tool.name,\n\t\tlabel: safeDisplayText(tool.name),\n\t\tstatusText: `${tool.count} \u00B7 ${tool.errors} errors`,\n\t\tsearchText: tool.models.map(modelLabel).join(\" \"),\n\t\tdetails: [\n\t\t\tmetric(\"Calls\", tool.count),\n\t\t\tmetric(\"Errors\", tool.errors),\n\t\t\t`Average duration: ${formatDecimal(tool.averageDurationMs)} ms`,\n\t\t\t\"\",\n\t\t\t\"By model\",\n\t\t\t...tool.models.map((model) => `${modelLabel(model)}: ${model.count}`),\n\t\t\t\"\",\n\t\t\t`Last detected: ${formatTimestamp(tool.lastOccurredAtMs)}`,\n\t\t],\n\t};\n}\n\nfunction reliabilityLines(result: AnalyticsLoadResult): string[] {\n\tif (result.kind === \"unavailable\") return [result.message];\n\tconst value = result.snapshot.reliability;\n\treturn [\n\t\t\"Observed provider errors only; provider-internal failures may be invisible.\",\n\t\t\"\",\n\t\tmetric(\"HTTP 429\", value.http429),\n\t\tmetric(\"HTTP 5xx\", value.http5xx),\n\t\tmetric(\"DNS\", value.categories.dns),\n\t\tmetric(\"Connection timeout\", value.categories.timeout),\n\t\tmetric(\"Connection refused\", value.categories.connection_refused),\n\t\tmetric(\"Connection reset\", value.categories.connection_reset),\n\t\tmetric(\"TLS\", value.categories.tls),\n\t\tmetric(\"Other network\", value.categories.network_other),\n\t\tmetric(\"Other provider\", value.categories.provider_other),\n\t\t\"\",\n\t\tmetric(\"Recovered\", value.recovered),\n\t\tmetric(\"Terminal failures\", value.terminal),\n\t];\n}\n\nfunction responseLines(result: AnalyticsLoadResult): string[] {\n\tif (result.kind === \"unavailable\") return [result.message];\n\tconst value = result.snapshot.responses;\n\treturn [\n\t\tmetric(\"Cycles\", value.count),\n\t\tmetric(\"LLM calls\", value.llmCalls),\n\t\tmetric(\"Average\", formatDecimal(value.average)),\n\t\tmetric(\"Median\", formatDecimal(value.median)),\n\t\tmetric(\"P95\", value.p95),\n\t\tmetric(\"Maximum\", value.maximum),\n\t\t\"\",\n\t\t\"Calls per response\",\n\t\tmetric(\"1 call\", value.distribution.one),\n\t\tmetric(\"2\u20133 calls\", value.distribution.twoToThree),\n\t\tmetric(\"4\u20136 calls\", value.distribution.fourToSix),\n\t\tmetric(\"7+ calls\", value.distribution.sevenPlus),\n\t];\n}\n\nfunction privacyLines(state: AnalyticsMenuState): string[] {\n\treturn [\n\t\t\"Local analytics files:\",\n\t\tsafeDisplayText(state.path),\n\t\t\"\",\n\t\t\"Stored: timestamps, extension-generated record IDs, model/provider IDs, thinking level, tool and skill names, durations, counts, HTTP statuses, and classified errors.\",\n\t\t\"Not stored: prompts, responses, thinking, tool arguments/results, raw errors, headers, cwd/file paths, session identity, or credentials.\",\n\t\t\"\",\n\t\t\"No database server, cloud connection, or other remote telemetry is used.\",\n\t\t\"Analytics are non-critical derived metadata; a failed local write may be dropped.\",\n\t];\n}\n\nfunction metric(label: string, value: string | number): string {\n\treturn `${label.padEnd(24)} ${value}`;\n}\n\nfunction formatDecimal(value: number): string {\n\treturn Number.isInteger(value)\n\t\t? String(value)\n\t\t: value.toFixed(2).replace(/0+$/u, \"\").replace(/\\.$/u, \"\");\n}\n\nfunction formatTimestamp(value: number): string {\n\treturn new Date(value).toLocaleString();\n}\n\nfunction modelLabel(model: { provider?: string; model?: string }): string {\n\tif (!model.provider && !model.model) return \"unknown\";\n\treturn safeDisplayText(`${model.provider ?? \"unknown\"}/${model.model ?? \"unknown\"}`);\n}\n\nfunction safeDisplayText(value: unknown): string {\n\treturn Array.from(stripVTControlCharacters(String(value)), (character) => {\n\t\tconst codePoint = character.codePointAt(0) ?? 0;\n\t\treturn codePoint <= 0x1f || (codePoint >= 0x7f && codePoint <= 0x9f) ? \" \" : character;\n\t}).join(\"\");\n}\n\nfunction isRangeId(value: string): value is TimeRangeId {\n\treturn value === \"today\" || value === \"7d\" || value === \"30d\" || value === \"all\";\n}\n\nfunction safeErrorMessage(_error: unknown): string {\n\treturn \"The local analytics query could not be completed. Try again; existing data was not changed.\";\n}\n", "import type { ProviderErrorCategory, SettledRun } from \"../types.js\";\n\nexport type TimeRangeId = \"today\" | \"7d\" | \"30d\" | \"all\";\nexport interface TimeRange {\n\tid?: TimeRangeId;\n\tfromMs: number;\n\ttoMs: number;\n}\n\nexport interface OverviewStats {\n\tresponseCycles: number;\n\tllmCalls: number;\n\tcallsPerResponse: number;\n\tp95CallsPerResponse: number;\n\ttoolCalls: number;\n\ttoolErrors: number;\n\tskillActivations: number;\n\tproviderErrors: number;\n\trecoveredErrors: number;\n}\n\nexport interface ModelCount {\n\tprovider?: string;\n\tmodel?: string;\n\tcount: number;\n}\n\nexport interface SkillStats {\n\tname: string;\n\tcount: number;\n\tmodelInitiated: number;\n\tuserInitiated: number;\n\tlastOccurredAtMs: number;\n\tmodels: ModelCount[];\n}\n\nexport interface ToolStats {\n\tname: string;\n\tcount: number;\n\terrors: number;\n\taverageDurationMs: number;\n\tlastOccurredAtMs: number;\n\tmodels: ModelCount[];\n}\n\nexport interface ReliabilityStats {\n\thttp429: number;\n\thttp5xx: number;\n\trecovered: number;\n\tterminal: number;\n\tcategories: Record<ProviderErrorCategory, number>;\n}\n\nexport interface ResponseStats {\n\tcount: number;\n\tllmCalls: number;\n\taverage: number;\n\tmedian: number;\n\tp95: number;\n\tmaximum: number;\n\tdistribution: { one: number; twoToThree: number; fourToSix: number; sevenPlus: number };\n}\n\nexport interface AnalyticsSnapshot {\n\toverview: OverviewStats;\n\tskills: SkillStats[];\n\ttools: ToolStats[];\n\treliability: ReliabilityStats;\n\tresponses: ResponseStats;\n}\n\nconst DAY_MS = 24 * 60 * 60 * 1_000;\nconst ERROR_CATEGORIES: readonly ProviderErrorCategory[] = [\n\t\"dns\",\n\t\"timeout\",\n\t\"connection_refused\",\n\t\"connection_reset\",\n\t\"tls\",\n\t\"network_other\",\n\t\"provider_other\",\n];\n\nexport function resolveTimeRange(id: TimeRangeId, now = Date.now()): TimeRange {\n\tlet fromMs = 0;\n\tif (id === \"today\") {\n\t\tconst date = new Date(now);\n\t\tfromMs = new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime();\n\t} else if (id === \"7d\") fromMs = now - 7 * DAY_MS;\n\telse if (id === \"30d\") fromMs = now - 30 * DAY_MS;\n\treturn { id, fromMs, toMs: now + 1 };\n}\n\nexport async function querySnapshot(\n\truns: AsyncIterable<SettledRun> | Iterable<SettledRun>,\n\trange: TimeRange,\n\tsignal?: AbortSignal,\n): Promise<AnalyticsSnapshot> {\n\tconst generationCounts: number[] = [];\n\tconst seenRunIds = new Set<string>();\n\tconst skills = new Map<string, SkillStats>();\n\tconst tools = new Map<string, ToolStats & { totalDurationMs: number }>();\n\tconst categories = Object.fromEntries(\n\t\tERROR_CATEGORIES.map((category) => [category, 0]),\n\t) as Record<ProviderErrorCategory, number>;\n\tlet toolErrors = 0;\n\tlet providerErrors = 0;\n\tlet recoveredErrors = 0;\n\tlet http429 = 0;\n\tlet http5xx = 0;\n\tlet terminal = 0;\n\n\tfor await (const run of runs) {\n\t\tthrowIfAborted(signal);\n\t\tif (seenRunIds.has(run.id)) continue;\n\t\tseenRunIds.add(run.id);\n\t\tif (run.startedAtMs < range.fromMs || run.startedAtMs >= range.toMs) continue;\n\t\tgenerationCounts.push(run.generations.length);\n\t\ttoolErrors += run.toolErrorCount;\n\t\tproviderErrors += run.providerErrorCount;\n\t\trecoveredErrors += run.recoveredErrorCount;\n\n\t\tfor (const skill of run.skills) {\n\t\t\tconst item = skills.get(skill.name) ?? {\n\t\t\t\tname: skill.name,\n\t\t\t\tcount: 0,\n\t\t\t\tmodelInitiated: 0,\n\t\t\t\tuserInitiated: 0,\n\t\t\t\tlastOccurredAtMs: 0,\n\t\t\t\tmodels: [],\n\t\t\t};\n\t\t\titem.count += 1;\n\t\t\tif (skill.initiatedBy === \"user\") item.userInitiated += 1;\n\t\t\telse item.modelInitiated += 1;\n\t\t\titem.lastOccurredAtMs = Math.max(item.lastOccurredAtMs, skill.occurredAtMs);\n\t\t\tmergeModelCount(item.models, {\n\t\t\t\tprovider: skill.provider,\n\t\t\t\tmodel: skill.model,\n\t\t\t\tcount: 1,\n\t\t\t});\n\t\t\tskills.set(skill.name, item);\n\t\t}\n\n\t\tfor (const tool of run.tools) {\n\t\t\tconst item = tools.get(tool.name) ?? {\n\t\t\t\tname: tool.name,\n\t\t\t\tcount: 0,\n\t\t\t\terrors: 0,\n\t\t\t\taverageDurationMs: 0,\n\t\t\t\ttotalDurationMs: 0,\n\t\t\t\tlastOccurredAtMs: 0,\n\t\t\t\tmodels: [],\n\t\t\t};\n\t\t\titem.count += 1;\n\t\t\titem.errors += tool.isError ? 1 : 0;\n\t\t\titem.totalDurationMs += tool.durationMs ?? 0;\n\t\t\titem.averageDurationMs = item.totalDurationMs / item.count;\n\t\t\titem.lastOccurredAtMs = Math.max(item.lastOccurredAtMs, tool.startedAtMs);\n\t\t\tmergeModelCount(item.models, {\n\t\t\t\tprovider: tool.provider,\n\t\t\t\tmodel: tool.model,\n\t\t\t\tcount: 1,\n\t\t\t});\n\t\t\ttools.set(tool.name, item);\n\t\t}\n\n\t\tfor (const error of run.providerErrors) {\n\t\t\tcategories[error.category] += 1;\n\t\t\tterminal += error.terminal ? 1 : 0;\n\t\t}\n\t\tfor (const generation of run.generations) {\n\t\t\tfor (const response of generation.responses) {\n\t\t\t\tif (response.status === 429) http429 += 1;\n\t\t\t\tif (response.status >= 500 && response.status < 600) http5xx += 1;\n\t\t\t}\n\t\t}\n\t}\n\n\tconst responses = responseStatistics(generationCounts);\n\treturn {\n\t\toverview: {\n\t\t\tresponseCycles: responses.count,\n\t\t\tllmCalls: responses.llmCalls,\n\t\t\tcallsPerResponse: responses.average,\n\t\t\tp95CallsPerResponse: responses.p95,\n\t\t\ttoolCalls: sum([...tools.values()].map(({ count }) => count)),\n\t\t\ttoolErrors,\n\t\t\tskillActivations: sum([...skills.values()].map(({ count }) => count)),\n\t\t\tproviderErrors,\n\t\t\trecoveredErrors,\n\t\t},\n\t\tskills: [...skills.values()]\n\t\t\t.map((item) => ({ ...item, models: sortModels(item.models) }))\n\t\t\t.sort((left, right) => right.count - left.count || left.name.localeCompare(right.name)),\n\t\ttools: [...tools.values()]\n\t\t\t.map(({ totalDurationMs: _, ...item }) => ({ ...item, models: sortModels(item.models) }))\n\t\t\t.sort((left, right) => right.count - left.count || left.name.localeCompare(right.name)),\n\t\treliability: {\n\t\t\thttp429,\n\t\t\thttp5xx,\n\t\t\trecovered: recoveredErrors,\n\t\t\tterminal,\n\t\t\tcategories,\n\t\t},\n\t\tresponses,\n\t};\n}\n\nfunction responseStatistics(generationCounts: number[]): ResponseStats {\n\tconst sorted = [...generationCounts].sort((left, right) => left - right);\n\tconst count = sorted.length;\n\tconst llmCalls = sum(sorted);\n\tconst nearestRank = (percentile: number) =>\n\t\tcount === 0 ? 0 : (sorted[Math.max(0, Math.ceil(percentile * count) - 1)] ?? 0);\n\tconst median =\n\t\tcount === 0\n\t\t\t? 0\n\t\t\t: count % 2 === 1\n\t\t\t\t? (sorted[Math.floor(count / 2)] ?? 0)\n\t\t\t\t: ((sorted[count / 2 - 1] ?? 0) + (sorted[count / 2] ?? 0)) / 2;\n\treturn {\n\t\tcount,\n\t\tllmCalls,\n\t\taverage: count > 0 ? llmCalls / count : 0,\n\t\tmedian,\n\t\tp95: nearestRank(0.95),\n\t\tmaximum: sorted.at(-1) ?? 0,\n\t\tdistribution: {\n\t\t\tone: sorted.filter((value) => value === 1).length,\n\t\t\ttwoToThree: sorted.filter((value) => value >= 2 && value <= 3).length,\n\t\t\tfourToSix: sorted.filter((value) => value >= 4 && value <= 6).length,\n\t\t\tsevenPlus: sorted.filter((value) => value >= 7).length,\n\t\t},\n\t};\n}\n\nfunction mergeModelCount(models: ModelCount[], next: ModelCount): void {\n\tconst existing = models.find(\n\t\t({ provider, model }) => provider === next.provider && model === next.model,\n\t);\n\tif (existing) existing.count += next.count;\n\telse models.push(next);\n}\n\nfunction sortModels(models: ModelCount[]): ModelCount[] {\n\treturn models.sort(\n\t\t(left, right) =>\n\t\t\tright.count - left.count ||\n\t\t\t`${left.provider ?? \"\"}/${left.model ?? \"\"}`.localeCompare(\n\t\t\t\t`${right.provider ?? \"\"}/${right.model ?? \"\"}`,\n\t\t\t),\n\t);\n}\n\nfunction throwIfAborted(signal?: AbortSignal): void {\n\tif (signal?.aborted)\n\t\tthrow signal.reason ?? new DOMException(\"Analytics query aborted\", \"AbortError\");\n}\n\nfunction sum(values: readonly number[]): number {\n\treturn values.reduce((total, value) => total + value, 0);\n}\n", "import { realpath } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport type { InputSource } from \"@earendil-works/pi-coding-agent\";\n\nexport interface AvailableSkill {\n\tname: string;\n\tfilePath: string;\n}\n\nexport interface PendingExplicitSkill {\n\tname: string;\n\tobservedAtMs: number;\n\tsource: \"interactive\" | \"rpc\";\n}\n\nexport function explicitSkillName(text: string): string | undefined {\n\treturn text.match(/^\\/skill:([a-z0-9](?:[a-z0-9-]{0,62}[a-z0-9])?)(?:\\s|$)/u)?.[1];\n}\n\nexport class SkillTracker {\n\tprivate pending: PendingExplicitSkill | undefined;\n\tprivate readonly skillByPath = new Map<string, string>();\n\tprivate readonly availableNames = new Set<string>();\n\n\tconstructor(\n\t\tprivate readonly cwd: string,\n\t\tprivate readonly canonicalize: (filePath: string) => Promise<string> = realpath,\n\t) {}\n\n\tobserveInput(text: string, source: InputSource, now: number): void {\n\t\tif (source === \"extension\") return;\n\t\tconst name = explicitSkillName(text);\n\t\tthis.pending = name ? { name, observedAtMs: now, source } : undefined;\n\t}\n\n\tconsumeExplicitSkill(): PendingExplicitSkill | undefined {\n\t\tconst pending = this.pending;\n\t\tthis.pending = undefined;\n\t\treturn pending;\n\t}\n\n\tclearPending(): void {\n\t\tthis.pending = undefined;\n\t}\n\n\thasAvailableSkill(name: string): boolean {\n\t\treturn this.availableNames.has(name);\n\t}\n\n\tasync setAvailableSkills(skills: readonly AvailableSkill[]): Promise<void> {\n\t\tthis.skillByPath.clear();\n\t\tthis.availableNames.clear();\n\t\tconst seenNames = new Set<string>();\n\t\tfor (const skill of skills) {\n\t\t\tif (seenNames.has(skill.name)) continue;\n\t\t\tseenNames.add(skill.name);\n\t\t\tthis.availableNames.add(skill.name);\n\t\t\tconst canonical = await this.canonicalize(skill.filePath).catch(() =>\n\t\t\t\tpath.resolve(this.cwd, skill.filePath),\n\t\t\t);\n\t\t\tthis.skillByPath.set(canonical, skill.name);\n\t\t}\n\t}\n\n\tasync matchSuccessfulRead(input: {\n\t\ttoolName: string;\n\t\tinput: unknown;\n\t\tisError: boolean;\n\t}): Promise<string | undefined> {\n\t\tif (input.toolName !== \"read\" || input.isError || !isRecord(input.input)) return undefined;\n\t\tconst rawPath = input.input.path;\n\t\tif (typeof rawPath !== \"string\" || rawPath.length === 0) return undefined;\n\t\tconst normalized = rawPath.startsWith(\"@\") ? rawPath.slice(1) : rawPath;\n\t\tconst absolute = path.resolve(this.cwd, normalized);\n\t\tconst canonical = await this.canonicalize(absolute).catch(() => absolute);\n\t\treturn this.skillByPath.get(canonical);\n\t}\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n", "import { randomUUID } from \"node:crypto\";\nimport { createReadStream, type Dirent } from \"node:fs\";\nimport {\n\tchmod,\n\tlstat,\n\tmkdir,\n\topen,\n\treaddir,\n\treadFile,\n\trename,\n\trm,\n\trmdir,\n\tunlink,\n\twriteFile,\n} from \"node:fs/promises\";\nimport path from \"node:path\";\nimport type { SettledRun } from \"../types.js\";\nimport {\n\tAnalyticsStorageFormatError,\n\tdecodeStoredRun,\n\tencodeStoredRun,\n\tMAX_STORED_RUN_BYTES,\n} from \"./format.js\";\n\nconst GENERATION_PATTERN =\n\t/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/u;\nconst DEFAULT_WRITE_TIMEOUT_MS = 5_000;\nconst YIELD_EVERY_RECORDS = 100;\n\nexport interface ClearAnalyticsResult {\n\tcleanupIncomplete: boolean;\n}\n\nexport class AnalyticsGenerationChangedError extends Error {\n\tconstructor() {\n\t\tsuper(\"The active analytics generation changed during the read.\");\n\t\tthis.name = \"AnalyticsGenerationChangedError\";\n\t}\n}\n\nexport class AnalyticsRunFiles {\n\tprivate readonly createId: () => string;\n\tprivate readonly writeTimeoutMs: number;\n\tprivate readonly beforeAppend?: (generation: string, signal: AbortSignal) => Promise<void>;\n\tprivate readonly beforeCleanupEntry?: (signal?: AbortSignal) => Promise<void>;\n\tprivate readonly beforeReadFile?: (signal?: AbortSignal) => Promise<void>;\n\tprivate writerId: string;\n\tprivate mutationTail: Promise<void> = Promise.resolve();\n\tprivate readonly lifecycle = new AbortController();\n\tprivate closed = false;\n\n\tconstructor(\n\t\treadonly path: string,\n\t\toptions: {\n\t\t\tcreateId?: () => string;\n\t\t\twriteTimeoutMs?: number;\n\t\t\tbeforeAppend?: (generation: string, signal: AbortSignal) => Promise<void>;\n\t\t\tbeforeCleanupEntry?: (signal?: AbortSignal) => Promise<void>;\n\t\t\tbeforeReadFile?: (signal?: AbortSignal) => Promise<void>;\n\t\t} = {},\n\t) {\n\t\tthis.createId = options.createId ?? randomUUID;\n\t\tthis.writeTimeoutMs = options.writeTimeoutMs ?? DEFAULT_WRITE_TIMEOUT_MS;\n\t\tthis.beforeAppend = options.beforeAppend;\n\t\tthis.beforeCleanupEntry = options.beforeCleanupEntry;\n\t\tthis.beforeReadFile = options.beforeReadFile;\n\t\tthis.writerId = validCreatedId(this.createId());\n\t}\n\n\tappend(run: SettledRun, signal?: AbortSignal): Promise<void> {\n\t\tif (this.closed) return Promise.reject(new Error(\"Analytics storage is closed.\"));\n\t\tconst frame = encodeStoredRun(run);\n\t\treturn this.enqueueMutation(() =>\n\t\t\twithDeadline(signal, this.lifecycle.signal, this.writeTimeoutMs, (operationSignal) =>\n\t\t\t\tthis.appendFrame(frame, operationSignal),\n\t\t\t),\n\t\t);\n\t}\n\n\tasync *read(signal?: AbortSignal): AsyncIterable<SettledRun> {\n\t\tthrowIfAborted(signal);\n\t\tconst generation = await this.readOrCreateGeneration(signal);\n\t\tconst directory = this.generationPath(generation);\n\t\tlet entries: Dirent[];\n\t\ttry {\n\t\t\tentries = await readdir(directory, { withFileTypes: true });\n\t\t} catch (error) {\n\t\t\tif (isNodeError(error) && error.code === \"ENOENT\") {\n\t\t\t\tawait this.assertGenerationUnchanged(generation, signal);\n\t\t\t\tthrow new AnalyticsGenerationChangedError();\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\t\tlet count = 0;\n\t\tfor (const entry of entries.sort((left, right) => left.name.localeCompare(right.name))) {\n\t\t\tthrowIfAborted(signal);\n\t\t\tif (!entry.name.endsWith(\".jsonl\")) continue;\n\t\t\tconst filePath = path.join(directory, entry.name);\n\t\t\ttry {\n\t\t\t\tawait this.beforeReadFile?.(signal);\n\t\t\t\tthrowIfAborted(signal);\n\t\t\t\tawait assertPrivateRegularFile(filePath);\n\t\t\t\tfor await (const run of readFrames(filePath, signal)) {\n\t\t\t\t\tyield run;\n\t\t\t\t\tcount += 1;\n\t\t\t\t\tif (count % YIELD_EVERY_RECORDS === 0) await yieldToEventLoop(signal);\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\tif (isNodeError(error) && error.code === \"ENOENT\") {\n\t\t\t\t\tawait this.assertGenerationUnchanged(generation, signal);\n\t\t\t\t\tthrow new AnalyticsGenerationChangedError();\n\t\t\t\t}\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t}\n\t\tawait this.assertGenerationUnchanged(generation, signal);\n\t}\n\n\tclear(signal?: AbortSignal): Promise<ClearAnalyticsResult> {\n\t\tif (this.closed) return Promise.reject(new Error(\"Analytics storage is closed.\"));\n\t\tlet result: ClearAnalyticsResult = { cleanupIncomplete: false };\n\t\treturn this.enqueueMutation(() =>\n\t\t\twithLinkedSignals(signal, this.lifecycle.signal, async (operationSignal) => {\n\t\t\t\tthrowIfAborted(operationSignal);\n\t\t\t\tawait this.readOrCreateGeneration(operationSignal);\n\t\t\t\tconst next = validCreatedId(this.createId());\n\t\t\t\tawait this.publishGeneration(next);\n\t\t\t\tthis.writerId = validCreatedId(this.createId());\n\t\t\t\tconst current = await readGenerationMarker(path.join(this.path, \"current\"));\n\t\t\t\tawait ensurePrivateDirectory(this.generationPath(current));\n\t\t\t\tif (!(await this.cleanupObsoleteGenerations(operationSignal))) {\n\t\t\t\t\tresult = { cleanupIncomplete: true };\n\t\t\t\t}\n\t\t\t}),\n\t\t).then(() => result);\n\t}\n\n\tasync close(): Promise<void> {\n\t\tif (this.closed) return;\n\t\tthis.closed = true;\n\t\tthis.lifecycle.abort(new DOMException(\"Analytics storage closed\", \"AbortError\"));\n\t\tawait this.mutationTail.catch(() => undefined);\n\t}\n\n\tprivate enqueueMutation(operation: () => Promise<void>): Promise<void> {\n\t\tconst result = this.mutationTail.then(operation);\n\t\tthis.mutationTail = result.catch(() => undefined);\n\t\treturn result;\n\t}\n\n\tprivate async appendFrame(frame: string, signal: AbortSignal): Promise<void> {\n\t\tthrowIfAborted(signal);\n\t\tlet obsoleteDirectory: string | undefined;\n\t\tfor (let attempt = 0; attempt < 3; attempt += 1) {\n\t\t\tconst generation = await this.readOrCreateGeneration(signal);\n\t\t\tconst directory = this.generationPath(generation);\n\t\t\tawait ensurePrivateDirectory(directory);\n\t\t\tconst filePath = path.join(directory, `${this.writerId}.jsonl`);\n\t\t\tawait assertOptionalPrivateRegularFile(filePath);\n\t\t\tthrowIfAborted(signal);\n\t\t\tawait this.beforeAppend?.(generation, signal);\n\t\t\tthrowIfAborted(signal);\n\t\t\ttry {\n\t\t\t\tawait writeFile(filePath, frame, {\n\t\t\t\t\tencoding: \"utf8\",\n\t\t\t\t\tflag: \"a\",\n\t\t\t\t\tmode: 0o600,\n\t\t\t\t\tsignal,\n\t\t\t\t});\n\t\t\t\tif (process.platform !== \"win32\") await chmod(filePath, 0o600);\n\t\t\t\tconst current = await readGenerationMarker(path.join(this.path, \"current\"), signal);\n\t\t\t\tif (current === generation) {\n\t\t\t\t\tif (obsoleteDirectory) {\n\t\t\t\t\t\tawait cleanupGeneration(obsoleteDirectory, signal).catch(() => undefined);\n\t\t\t\t\t}\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tobsoleteDirectory = directory;\n\t\t\t} catch (error) {\n\t\t\t\tthis.writerId = validCreatedId(this.createId());\n\t\t\t\tthrowIfAborted(signal);\n\t\t\t\tif (!isNodeError(error) || error.code !== \"ENOENT\") throw error;\n\t\t\t}\n\t\t}\n\t\tthrow new AnalyticsGenerationChangedError();\n\t}\n\n\tprivate async readOrCreateGeneration(signal?: AbortSignal): Promise<string> {\n\t\tthrowIfAborted(signal);\n\t\tawait ensurePrivateDirectory(this.path);\n\t\tawait ensurePrivateDirectory(path.join(this.path, \"generations\"));\n\t\tconst markerPath = path.join(this.path, \"current\");\n\t\tfor (let attempt = 0; attempt < 3; attempt += 1) {\n\t\t\tlet generation: string;\n\t\t\ttry {\n\t\t\t\tgeneration = await readGenerationMarker(markerPath, signal);\n\t\t\t} catch (error) {\n\t\t\t\tif (!isNodeError(error) || error.code !== \"ENOENT\") throw error;\n\t\t\t\tgeneration = validCreatedId(this.createId());\n\t\t\t\tthrowIfAborted(signal);\n\t\t\t\ttry {\n\t\t\t\t\tawait createPrivateFile(markerPath, `${generation}\\n`);\n\t\t\t\t} catch (createError) {\n\t\t\t\t\tif (!isNodeError(createError) || createError.code !== \"EEXIST\") throw createError;\n\t\t\t\t\tgeneration = await readGenerationMarker(markerPath, signal);\n\t\t\t\t}\n\t\t\t}\n\t\t\tawait ensurePrivateDirectory(this.generationPath(generation));\n\t\t\tconst current = await readGenerationMarker(markerPath, signal);\n\t\t\tif (current === generation) return generation;\n\t\t}\n\t\tthrow new AnalyticsGenerationChangedError();\n\t}\n\n\tprivate async publishGeneration(generation: string): Promise<void> {\n\t\tconst markerPath = path.join(this.path, \"current\");\n\t\tconst temporaryPath = path.join(this.path, `.current.${validCreatedId(this.createId())}.tmp`);\n\t\tawait createPrivateFile(temporaryPath, `${generation}\\n`);\n\t\ttry {\n\t\t\tawait rename(temporaryPath, markerPath);\n\t\t\tif (process.platform !== \"win32\") await chmod(markerPath, 0o600);\n\t\t} catch (error) {\n\t\t\tawait rm(temporaryPath, { force: true }).catch(() => undefined);\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tprivate async cleanupObsoleteGenerations(signal?: AbortSignal): Promise<boolean> {\n\t\tlet complete = true;\n\t\tconst root = path.join(this.path, \"generations\");\n\t\tfor (const entry of await readdir(root, { withFileTypes: true })) {\n\t\t\tconst active = await readGenerationMarker(path.join(this.path, \"current\"));\n\t\t\tif (entry.name === active) continue;\n\t\t\tif (!entry.isDirectory() || !GENERATION_PATTERN.test(entry.name)) {\n\t\t\t\tcomplete = false;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tawait cleanupGeneration(path.join(root, entry.name), signal, this.beforeCleanupEntry);\n\t\t\t} catch {\n\t\t\t\tcomplete = false;\n\t\t\t\tif (signal?.aborted) break;\n\t\t\t}\n\t\t}\n\t\tconst active = await readGenerationMarker(path.join(this.path, \"current\"));\n\t\tconst remaining = await readdir(root, { withFileTypes: true });\n\t\treturn complete && remaining.every((entry) => entry.isDirectory() && entry.name === active);\n\t}\n\n\tprivate async assertGenerationUnchanged(generation: string, signal?: AbortSignal): Promise<void> {\n\t\tconst current = await readGenerationMarker(path.join(this.path, \"current\"), signal);\n\t\tif (current !== generation) throw new AnalyticsGenerationChangedError();\n\t}\n\n\tprivate generationPath(generation: string): string {\n\t\treturn path.join(this.path, \"generations\", generation);\n\t}\n}\n\nasync function* readFrames(filePath: string, signal?: AbortSignal): AsyncIterable<SettledRun> {\n\tlet pending = \"\";\n\tconst stream = createReadStream(filePath, { encoding: \"utf8\", signal });\n\tfor await (const chunk of stream) {\n\t\tthrowIfAborted(signal);\n\t\tpending += String(chunk);\n\t\twhile (true) {\n\t\t\tconst newline = pending.indexOf(\"\\n\");\n\t\t\tif (newline < 0) break;\n\t\t\tconst line = pending.slice(0, newline);\n\t\t\tpending = pending.slice(newline + 1);\n\t\t\tif (!line) continue;\n\t\t\tyield decodeStoredRun(line);\n\t\t}\n\t\tif (Buffer.byteLength(pending) > MAX_STORED_RUN_BYTES) {\n\t\t\tthrow new AnalyticsStorageFormatError(\"Analytics record is too large to read safely.\");\n\t\t}\n\t}\n\t// A writer always terminates complete frames with a newline. An unterminated tail is a\n\t// crash residue and is ignored; this writer file will not be reused after its process exits.\n}\n\nasync function readGenerationMarker(markerPath: string, signal?: AbortSignal): Promise<string> {\n\tawait assertPrivateRegularFile(markerPath);\n\tthrowIfAborted(signal);\n\tconst value = (await readFile(markerPath, { encoding: \"utf8\", signal })).trim();\n\tif (!GENERATION_PATTERN.test(value)) {\n\t\tthrow new AnalyticsStorageFormatError(\"Analytics generation marker is invalid.\");\n\t}\n\treturn value;\n}\n\nasync function ensurePrivateDirectory(directoryPath: string): Promise<void> {\n\ttry {\n\t\tconst metadata = await lstat(directoryPath);\n\t\tif (!metadata.isDirectory() || metadata.isSymbolicLink()) {\n\t\t\tthrow new Error(\"Analytics storage paths must be regular directories, not links.\");\n\t\t}\n\t} catch (error) {\n\t\tif (!isNodeError(error) || error.code !== \"ENOENT\") throw error;\n\t\tawait mkdir(directoryPath, { recursive: true, mode: 0o700 });\n\t\tconst metadata = await lstat(directoryPath);\n\t\tif (!metadata.isDirectory() || metadata.isSymbolicLink()) {\n\t\t\tthrow new Error(\"Analytics storage paths must be regular directories, not links.\");\n\t\t}\n\t}\n\tif (process.platform !== \"win32\") await chmod(directoryPath, 0o700);\n}\n\nasync function assertOptionalPrivateRegularFile(filePath: string): Promise<void> {\n\ttry {\n\t\tawait assertPrivateRegularFile(filePath);\n\t} catch (error) {\n\t\tif (isNodeError(error) && error.code === \"ENOENT\") return;\n\t\tthrow error;\n\t}\n}\n\nasync function assertPrivateRegularFile(filePath: string): Promise<void> {\n\tconst metadata = await lstat(filePath);\n\tif (!metadata.isFile() || metadata.isSymbolicLink()) {\n\t\tthrow new Error(\"Analytics storage files must be regular files, not links.\");\n\t}\n\tif (process.platform !== \"win32\") await chmod(filePath, 0o600);\n}\n\nasync function createPrivateFile(filePath: string, content: string): Promise<void> {\n\tconst handle = await open(filePath, \"wx\", 0o600);\n\ttry {\n\t\tawait handle.writeFile(content, \"utf8\");\n\t\tawait handle.sync();\n\t} finally {\n\t\tawait handle.close();\n\t}\n}\n\nasync function cleanupGeneration(\n\tdirectoryPath: string,\n\tsignal?: AbortSignal,\n\tbeforeEntry?: (signal?: AbortSignal) => Promise<void>,\n): Promise<void> {\n\tthrowIfAborted(signal);\n\tlet entries: Dirent[];\n\ttry {\n\t\tentries = await readdir(directoryPath, { withFileTypes: true });\n\t} catch (error) {\n\t\tif (isNodeError(error) && error.code === \"ENOENT\") return;\n\t\tthrow error;\n\t}\n\tfor (const entry of entries) {\n\t\tthrowIfAborted(signal);\n\t\tawait beforeEntry?.(signal);\n\t\tthrowIfAborted(signal);\n\t\tif (!entry.isFile() || !entry.name.endsWith(\".jsonl\")) {\n\t\t\tthrow new Error(\"Analytics generation contains an unexpected storage entry.\");\n\t\t}\n\t\tawait unlink(path.join(directoryPath, entry.name));\n\t}\n\tthrowIfAborted(signal);\n\tawait rmdir(directoryPath);\n}\n\nasync function withLinkedSignals<T>(\n\tcallerSignal: AbortSignal | undefined,\n\tlifecycleSignal: AbortSignal,\n\toperation: (signal: AbortSignal) => Promise<T>,\n): Promise<T> {\n\tthrowIfAborted(callerSignal);\n\tthrowIfAborted(lifecycleSignal);\n\tconst controller = new AbortController();\n\tconst abort = (signal: AbortSignal) =>\n\t\tcontroller.abort(\n\t\t\tsignal.reason ?? new DOMException(\"Analytics operation aborted\", \"AbortError\"),\n\t\t);\n\tconst callerAbort = () => callerSignal && abort(callerSignal);\n\tconst lifecycleAbort = () => abort(lifecycleSignal);\n\tcallerSignal?.addEventListener(\"abort\", callerAbort, { once: true });\n\tlifecycleSignal.addEventListener(\"abort\", lifecycleAbort, { once: true });\n\ttry {\n\t\treturn await operation(controller.signal);\n\t} finally {\n\t\tcallerSignal?.removeEventListener(\"abort\", callerAbort);\n\t\tlifecycleSignal.removeEventListener(\"abort\", lifecycleAbort);\n\t}\n}\n\nasync function withDeadline<T>(\n\tcallerSignal: AbortSignal | undefined,\n\tlifecycleSignal: AbortSignal,\n\ttimeoutMs: number,\n\toperation: (signal: AbortSignal) => Promise<T>,\n): Promise<T> {\n\tthrowIfAborted(callerSignal);\n\tthrowIfAborted(lifecycleSignal);\n\tconst controller = new AbortController();\n\tconst abort = (signal: AbortSignal) =>\n\t\tcontroller.abort(\n\t\t\tsignal.reason ?? new DOMException(\"Analytics operation aborted\", \"AbortError\"),\n\t\t);\n\tconst callerAbort = () => callerSignal && abort(callerSignal);\n\tconst lifecycleAbort = () => abort(lifecycleSignal);\n\tcallerSignal?.addEventListener(\"abort\", callerAbort, { once: true });\n\tlifecycleSignal.addEventListener(\"abort\", lifecycleAbort, { once: true });\n\tconst timer = setTimeout(\n\t\t() => controller.abort(new DOMException(\"Analytics write timed out\", \"TimeoutError\")),\n\t\tMath.max(1, timeoutMs),\n\t);\n\ttry {\n\t\treturn await operation(controller.signal);\n\t} catch (error) {\n\t\tif (\n\t\t\tcontroller.signal.aborted &&\n\t\t\terror instanceof Error &&\n\t\t\terror.name === \"AbortError\" &&\n\t\t\terror.cause === controller.signal.reason\n\t\t) {\n\t\t\tthrow controller.signal.reason;\n\t\t}\n\t\tthrow error;\n\t} finally {\n\t\tclearTimeout(timer);\n\t\tcallerSignal?.removeEventListener(\"abort\", callerAbort);\n\t\tlifecycleSignal.removeEventListener(\"abort\", lifecycleAbort);\n\t}\n}\n\nasync function yieldToEventLoop(signal?: AbortSignal): Promise<void> {\n\tawait new Promise<void>((resolve) => setImmediate(resolve));\n\tthrowIfAborted(signal);\n}\n\nfunction validCreatedId(value: string): string {\n\tif (!GENERATION_PATTERN.test(value)) throw new Error(\"Analytics storage received an invalid ID.\");\n\treturn value;\n}\n\nfunction throwIfAborted(signal?: AbortSignal): void {\n\tif (signal?.aborted) {\n\t\tthrow signal.reason ?? new DOMException(\"Analytics operation aborted\", \"AbortError\");\n\t}\n}\n\nfunction isNodeError(error: unknown): error is NodeJS.ErrnoException {\n\treturn error instanceof Error && \"code\" in error;\n}\n", "import type {\n\tGenerationOutcome,\n\tGenerationRecord,\n\tProviderErrorCategory,\n\tProviderErrorRecord,\n\tProviderResponseRecord,\n\tRunOutcome,\n\tSettledRun,\n\tSkillActivationRecord,\n\tToolCallRecord,\n} from \"../types.js\";\n\nexport const MAX_STORED_RUN_BYTES = 1024 * 1024;\nconst MAX_STRING_LENGTH = 4096;\nconst MAX_NESTED_RECORDS = 20_000;\nconst TRIGGER_SOURCES = [\"interactive\", \"rpc\", \"extension\", \"unknown\"] as const;\nconst RUN_OUTCOMES = [\n\t\"success\",\n\t\"recovered_success\",\n\t\"error\",\n\t\"aborted\",\n\t\"length\",\n\t\"interrupted\",\n] as const;\nconst GENERATION_OUTCOMES = [\n\t\"pending\",\n\t\"stop\",\n\t\"tool_use\",\n\t\"error\",\n\t\"aborted\",\n\t\"length\",\n\t\"interrupted\",\n] as const;\nconst ERROR_CATEGORIES = [\n\t\"dns\",\n\t\"timeout\",\n\t\"connection_refused\",\n\t\"connection_reset\",\n\t\"tls\",\n\t\"network_other\",\n\t\"provider_other\",\n] as const;\n\nexport class AnalyticsStorageFormatError extends Error {\n\tconstructor(message: string, options: { cause?: unknown } = {}) {\n\t\tsuper(message, options);\n\t\tthis.name = \"AnalyticsStorageFormatError\";\n\t}\n}\n\nexport function encodeStoredRun(run: SettledRun): string {\n\tconst encoded = `${JSON.stringify({\n\t\tformatVersion: 1,\n\t\trun: parseRun(run, { remaining: MAX_NESTED_RECORDS }),\n\t})}\\n`;\n\tif (Buffer.byteLength(encoded) > MAX_STORED_RUN_BYTES) {\n\t\tthrow new AnalyticsStorageFormatError(\"Analytics record is too large to store safely.\");\n\t}\n\treturn encoded;\n}\n\nexport function decodeStoredRun(line: string): SettledRun {\n\tif (Buffer.byteLength(line) > MAX_STORED_RUN_BYTES) {\n\t\tthrow new AnalyticsStorageFormatError(\"Analytics record is too large to read safely.\");\n\t}\n\tlet value: unknown;\n\ttry {\n\t\tvalue = JSON.parse(line);\n\t} catch (error) {\n\t\tthrow new AnalyticsStorageFormatError(\"Analytics record contains invalid JSON.\", {\n\t\t\tcause: error,\n\t\t});\n\t}\n\tconst envelope = asRecord(value, \"analytics record\");\n\tif (envelope.formatVersion !== 1) {\n\t\tthrow new AnalyticsStorageFormatError(\"Analytics record uses an unsupported format version.\");\n\t}\n\treturn parseRun(envelope.run, { remaining: MAX_NESTED_RECORDS });\n}\n\ninterface ParseBudget {\n\tremaining: number;\n}\n\nfunction parseRun(value: unknown, budget: ParseBudget): SettledRun {\n\tconst run = asRecord(value, \"run\");\n\treturn {\n\t\tid: requiredString(run.id, \"run.id\"),\n\t\tstartedAtMs: timestampValue(run.startedAtMs, \"run.startedAtMs\"),\n\t\tfinishedAtMs: timestampValue(run.finishedAtMs, \"run.finishedAtMs\"),\n\t\tdurationMs: durationValue(run.durationMs, \"run.durationMs\"),\n\t\ttriggerSource: enumValue(run.triggerSource, TRIGGER_SOURCES, \"run.triggerSource\"),\n\t\t...optionalProperty(\n\t\t\t\"initialProvider\",\n\t\t\toptionalString(run.initialProvider, \"run.initialProvider\"),\n\t\t),\n\t\t...optionalProperty(\"initialModel\", optionalString(run.initialModel, \"run.initialModel\")),\n\t\toutcome: enumValue(run.outcome, RUN_OUTCOMES, \"run.outcome\") as RunOutcome,\n\t\tattemptCount: boundedCount(run.attemptCount, \"run.attemptCount\"),\n\t\tgenerations: boundedArray(run.generations, \"run.generations\", budget).map((item, index) =>\n\t\t\tparseGeneration(item, index, budget),\n\t\t),\n\t\ttools: boundedArray(run.tools, \"run.tools\", budget).map(parseTool),\n\t\tskills: boundedArray(run.skills, \"run.skills\", budget).map(parseSkill),\n\t\tproviderErrors: boundedArray(run.providerErrors, \"run.providerErrors\", budget).map(\n\t\t\tparseProviderError,\n\t\t),\n\t\ttoolErrorCount: boundedCount(run.toolErrorCount, \"run.toolErrorCount\"),\n\t\tproviderErrorCount: boundedCount(run.providerErrorCount, \"run.providerErrorCount\"),\n\t\trecoveredErrorCount: boundedCount(run.recoveredErrorCount, \"run.recoveredErrorCount\"),\n\t};\n}\n\nfunction parseGeneration(value: unknown, index: number, budget: ParseBudget): GenerationRecord {\n\tconst item = asRecord(value, `run.generations[${index}]`);\n\tconst prefix = `run.generations[${index}]`;\n\treturn {\n\t\tid: requiredString(item.id, `${prefix}.id`),\n\t\tordinal: boundedCount(item.ordinal, `${prefix}.ordinal`),\n\t\t...optionalProperty(\"provider\", optionalString(item.provider, `${prefix}.provider`)),\n\t\t...optionalProperty(\"model\", optionalString(item.model, `${prefix}.model`)),\n\t\t...optionalProperty(\n\t\t\t\"thinkingLevel\",\n\t\t\toptionalString(item.thinkingLevel, `${prefix}.thinkingLevel`),\n\t\t),\n\t\tstartedAtMs: timestampValue(item.startedAtMs, `${prefix}.startedAtMs`),\n\t\t...optionalProperty(\n\t\t\t\"finishedAtMs\",\n\t\t\toptionalTimestamp(item.finishedAtMs, `${prefix}.finishedAtMs`),\n\t\t),\n\t\t...optionalProperty(\"durationMs\", optionalDuration(item.durationMs, `${prefix}.durationMs`)),\n\t\t...optionalProperty(\"stopReason\", optionalString(item.stopReason, `${prefix}.stopReason`)),\n\t\toutcome: enumValue(item.outcome, GENERATION_OUTCOMES, `${prefix}.outcome`) as GenerationOutcome,\n\t\tresponses: boundedArray(item.responses, `${prefix}.responses`, budget).map(\n\t\t\tparseProviderResponse,\n\t\t),\n\t};\n}\n\nfunction parseProviderResponse(value: unknown, index: number): ProviderResponseRecord {\n\tconst item = asRecord(value, `provider response ${index}`);\n\treturn {\n\t\tordinal: boundedCount(item.ordinal, \"providerResponse.ordinal\"),\n\t\toccurredAtMs: timestampValue(item.occurredAtMs, \"providerResponse.occurredAtMs\"),\n\t\tstatus: boundedInteger(item.status, \"providerResponse.status\", 999),\n\t};\n}\n\nfunction parseTool(value: unknown, index: number): ToolCallRecord {\n\tconst item = asRecord(value, `run.tools[${index}]`);\n\tconst prefix = `run.tools[${index}]`;\n\tconst ordinal = boundedCount(item.ordinal, `${prefix}.ordinal`);\n\treturn {\n\t\tid: `tool-${ordinal}`,\n\t\tordinal,\n\t\tname: requiredString(item.name, `${prefix}.name`),\n\t\t...optionalProperty(\"provider\", optionalString(item.provider, `${prefix}.provider`)),\n\t\t...optionalProperty(\"model\", optionalString(item.model, `${prefix}.model`)),\n\t\tstartedAtMs: timestampValue(item.startedAtMs, `${prefix}.startedAtMs`),\n\t\t...optionalProperty(\n\t\t\t\"finishedAtMs\",\n\t\t\toptionalTimestamp(item.finishedAtMs, `${prefix}.finishedAtMs`),\n\t\t),\n\t\t...optionalProperty(\"durationMs\", optionalDuration(item.durationMs, `${prefix}.durationMs`)),\n\t\tisError: booleanValue(item.isError, `${prefix}.isError`),\n\t\tcompletionState: enumValue(\n\t\t\titem.completionState,\n\t\t\t[\"running\", \"finished\", \"interrupted\"] as const,\n\t\t\t`${prefix}.completionState`,\n\t\t),\n\t};\n}\n\nfunction parseSkill(value: unknown, index: number): SkillActivationRecord {\n\tconst item = asRecord(value, `run.skills[${index}]`);\n\tconst prefix = `run.skills[${index}]`;\n\treturn {\n\t\tid: requiredString(item.id, `${prefix}.id`),\n\t\tname: requiredString(item.name, `${prefix}.name`),\n\t\tinitiatedBy: enumValue(item.initiatedBy, [\"user\", \"model\"] as const, `${prefix}.initiatedBy`),\n\t\toccurredAtMs: timestampValue(item.occurredAtMs, `${prefix}.occurredAtMs`),\n\t\t...optionalProperty(\"provider\", optionalString(item.provider, `${prefix}.provider`)),\n\t\t...optionalProperty(\"model\", optionalString(item.model, `${prefix}.model`)),\n\t};\n}\n\nfunction parseProviderError(value: unknown, index: number): ProviderErrorRecord {\n\tconst item = asRecord(value, `run.providerErrors[${index}]`);\n\tconst prefix = `run.providerErrors[${index}]`;\n\treturn {\n\t\tid: requiredString(item.id, `${prefix}.id`),\n\t\t...optionalProperty(\n\t\t\t\"generationId\",\n\t\t\toptionalString(item.generationId, `${prefix}.generationId`),\n\t\t),\n\t\toccurredAtMs: timestampValue(item.occurredAtMs, `${prefix}.occurredAtMs`),\n\t\t...optionalProperty(\"provider\", optionalString(item.provider, `${prefix}.provider`)),\n\t\t...optionalProperty(\"model\", optionalString(item.model, `${prefix}.model`)),\n\t\tcategory: enumValue(\n\t\t\titem.category,\n\t\t\tERROR_CATEGORIES,\n\t\t\t`${prefix}.category`,\n\t\t) as ProviderErrorCategory,\n\t\trecovered: booleanValue(item.recovered, `${prefix}.recovered`),\n\t\tterminal: booleanValue(item.terminal, `${prefix}.terminal`),\n\t};\n}\n\nfunction asRecord(value: unknown, name: string): Record<string, unknown> {\n\tif (typeof value !== \"object\" || value === null || Array.isArray(value)) invalid(name);\n\treturn value as Record<string, unknown>;\n}\n\nfunction boundedArray(value: unknown, name: string, budget: ParseBudget): unknown[] {\n\tif (!Array.isArray(value)) invalid(name);\n\tbudget.remaining -= value.length;\n\tif (budget.remaining < 0) {\n\t\tthrow new AnalyticsStorageFormatError(\"Analytics record is too large to process safely.\");\n\t}\n\treturn value;\n}\n\nfunction requiredString(value: unknown, name: string): string {\n\tif (typeof value !== \"string\" || value.length === 0 || value.length > MAX_STRING_LENGTH) {\n\t\tinvalid(name);\n\t}\n\treturn value;\n}\n\nfunction optionalString(value: unknown, name: string): string | undefined {\n\treturn value === undefined ? undefined : requiredString(value, name);\n}\n\nfunction boundedInteger(value: unknown, name: string, maximum: number): number {\n\tif (typeof value !== \"number\" || !Number.isSafeInteger(value) || value < 0 || value > maximum) {\n\t\tinvalid(name);\n\t}\n\treturn value;\n}\n\nfunction timestampValue(value: unknown, name: string): number {\n\treturn boundedInteger(value, name, Number.MAX_SAFE_INTEGER);\n}\n\nfunction optionalTimestamp(value: unknown, name: string): number | undefined {\n\treturn value === undefined ? undefined : timestampValue(value, name);\n}\n\nfunction durationValue(value: unknown, name: string): number {\n\treturn boundedInteger(value, name, Math.floor(Number.MAX_SAFE_INTEGER / MAX_NESTED_RECORDS));\n}\n\nfunction optionalDuration(value: unknown, name: string): number | undefined {\n\treturn value === undefined ? undefined : durationValue(value, name);\n}\n\nfunction boundedCount(value: unknown, name: string): number {\n\treturn boundedInteger(value, name, MAX_NESTED_RECORDS);\n}\n\nfunction booleanValue(value: unknown, name: string): boolean {\n\tif (typeof value !== \"boolean\") invalid(name);\n\treturn value;\n}\n\nfunction enumValue<const T extends readonly string[]>(\n\tvalue: unknown,\n\tvalues: T,\n\tname: string,\n): T[number] {\n\tif (typeof value !== \"string\" || !values.includes(value)) invalid(name);\n\treturn value as T[number];\n}\n\nfunction optionalProperty<K extends string, T>(key: K, value: T | undefined): { [P in K]?: T } {\n\treturn value === undefined ? {} : ({ [key]: value } as { [P in K]?: T });\n}\n\nfunction invalid(name: string): never {\n\tthrow new AnalyticsStorageFormatError(`Analytics record has an invalid ${name}.`);\n}\n", "import type { SettledRun } from \"../types.js\";\nimport {\n\tAnalyticsGenerationChangedError,\n\tAnalyticsRunFiles,\n\ttype ClearAnalyticsResult,\n} from \"./files.js\";\nimport { type AnalyticsSnapshot, querySnapshot, type TimeRange } from \"./queries.js\";\n\nexport class AnalyticsStore {\n\tprivate readonly files: AnalyticsRunFiles;\n\n\tconstructor(\n\t\trootPath: string,\n\t\tdependencies: {\n\t\t\tfiles?: AnalyticsRunFiles;\n\t\t\tcreateId?: () => string;\n\t\t\twriteTimeoutMs?: number;\n\t\t} = {},\n\t) {\n\t\tthis.files =\n\t\t\tdependencies.files ??\n\t\t\tnew AnalyticsRunFiles(rootPath, {\n\t\t\t\tcreateId: dependencies.createId,\n\t\t\t\twriteTimeoutMs: dependencies.writeTimeoutMs,\n\t\t\t});\n\t}\n\n\tget path(): string {\n\t\treturn this.files.path;\n\t}\n\n\trecordRun(run: SettledRun, signal?: AbortSignal): Promise<void> {\n\t\treturn this.files.append(run, signal);\n\t}\n\n\tasync getSnapshot(range: TimeRange, signal?: AbortSignal): Promise<AnalyticsSnapshot> {\n\t\tfor (let attempt = 0; attempt < 2; attempt += 1) {\n\t\t\ttry {\n\t\t\t\treturn await querySnapshot(this.files.read(signal), range, signal);\n\t\t\t} catch (error) {\n\t\t\t\tif (!(error instanceof AnalyticsGenerationChangedError) || attempt > 0) throw error;\n\t\t\t}\n\t\t}\n\t\tthrow new AnalyticsGenerationChangedError();\n\t}\n\n\tclearAll(signal?: AbortSignal): Promise<ClearAnalyticsResult> {\n\t\treturn this.files.clear(signal);\n\t}\n\n\tclose(): Promise<void> {\n\t\treturn this.files.close();\n\t}\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["randomUUID", "path", "randomUUID", "path", "ERROR_CATEGORIES", "path", "randomUUID", "throwIfAborted", "active", "randomUUID", "path"]
|
|
7
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@narumitw/pi-analytics",
|
|
3
|
-
"version": "0.49.
|
|
3
|
+
"version": "0.49.7",
|
|
4
4
|
"description": "Local-first usage analytics for Pi models, skills, tools, and reliability.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -15,21 +15,24 @@
|
|
|
15
15
|
],
|
|
16
16
|
"files": [
|
|
17
17
|
"src",
|
|
18
|
+
"dist",
|
|
18
19
|
"README.md",
|
|
19
20
|
"LICENSE"
|
|
20
21
|
],
|
|
21
22
|
"pi": {
|
|
22
23
|
"extensions": [
|
|
23
|
-
"./
|
|
24
|
+
"./dist/index.ts"
|
|
24
25
|
]
|
|
25
26
|
},
|
|
26
27
|
"piExtension": {
|
|
27
28
|
"lifecycle": "experimental"
|
|
28
29
|
},
|
|
29
30
|
"scripts": {
|
|
30
|
-
"
|
|
31
|
-
"
|
|
32
|
-
"
|
|
31
|
+
"build": "node scripts/build-runtime.mjs",
|
|
32
|
+
"check": "npm run build && biome check --vcs-use-ignore-file=false src test scripts package.json tsconfig.json README.md && npm run typecheck",
|
|
33
|
+
"format": "biome check --write --vcs-use-ignore-file=false src test scripts package.json tsconfig.json README.md",
|
|
34
|
+
"typecheck": "tsc --noEmit",
|
|
35
|
+
"prepack": "npm run build"
|
|
33
36
|
},
|
|
34
37
|
"dependencies": {
|
|
35
38
|
"@narumitw/pi-tui-kit": "^0.51.0"
|
|
@@ -38,9 +41,10 @@
|
|
|
38
41
|
"@earendil-works/pi-coding-agent": "*"
|
|
39
42
|
},
|
|
40
43
|
"devDependencies": {
|
|
41
|
-
"@biomejs/biome": "2.5.
|
|
42
|
-
"@earendil-works/pi-coding-agent": "0.84.
|
|
43
|
-
"@types/node": "26.
|
|
44
|
+
"@biomejs/biome": "2.5.8",
|
|
45
|
+
"@earendil-works/pi-coding-agent": "0.84.2",
|
|
46
|
+
"@types/node": "26.2.0",
|
|
47
|
+
"esbuild": "0.28.1",
|
|
44
48
|
"typescript": "7.0.2"
|
|
45
49
|
},
|
|
46
50
|
"repository": {
|