@senad-d/observme 0.1.5 → 0.1.6
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 +4 -4
- package/docs/compatibility-matrix.md +9 -7
- package/docs/review-validation.md +10 -0
- package/package.json +6 -6
- package/src/extension.ts +2 -2
- package/src/pi/compatibility.ts +9 -100
- package/src/pi/handler-runtime.ts +4 -4
package/CHANGELOG.md
CHANGED
|
@@ -21,8 +21,9 @@
|
|
|
21
21
|
|
|
22
22
|
### Changed
|
|
23
23
|
|
|
24
|
+
- Raised the release-tested Pi and exact compatibility CI target to 0.81.1 while retaining 0.80.5 as the earliest validated target.
|
|
24
25
|
- Made the 0.1.5 hardening patch self-contained with explicit review units, all imported production modules included, and unrelated specification history preserved.
|
|
25
|
-
- Established a typed Pi event registration contract, removed non-event legacy registrations, pinned the release-
|
|
26
|
+
- Established a typed Pi event registration contract, removed non-event legacy registrations, pinned the release-tested Pi API for validation, and added capability-based pre-registration diagnostics.
|
|
26
27
|
- Centralized embedded-credential Grafana URL diagnostics so configuration validation, readiness checks, URL construction, and transports share one safe failure class and operator guidance.
|
|
27
28
|
- Documented credential-free Grafana base URLs and the fail-closed canonical project-file boundary across configuration, security, query, and troubleshooting guidance.
|
|
28
29
|
- Completed production active-agent lease documentation, raw-query migration guidance, GitHub Actions/self-hosted clock and cleanup runbooks, missing/expired-lease troubleshooting, Collector restart semantics, and sanitized release-validation evidence.
|
|
@@ -42,9 +43,8 @@
|
|
|
42
43
|
|
|
43
44
|
### Fixed
|
|
44
45
|
|
|
45
|
-
-
|
|
46
|
-
-
|
|
47
|
-
- Rejected prerelease Pi builds excluded by the declared stable compatibility range before extension registration.
|
|
46
|
+
- Removed Pi version gating from extension startup entirely; tested versions are evidence only, essential ExtensionAPI capabilities are checked before registration, and optional APIs remain feature-detected.
|
|
47
|
+
- Made missing project-path component reversal explicit.
|
|
48
48
|
- Applied one control-safe 64-row/8,192-character policy to every `/obs` notification and capped query result counts at configuration and runtime boundaries.
|
|
49
49
|
- Coupled canonical project config, `.env`, and starter-config I/O to identity-verified file handles so concurrent symlink and ancestor swaps fail closed without exposing external paths.
|
|
50
50
|
- Rejected credentials embedded in Grafana base URLs during config validation, query readiness, and transport preflight without exposing their values.
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
# ObservMe Compatibility Matrix
|
|
2
2
|
|
|
3
|
-
Last updated: 2026-07-
|
|
3
|
+
Last updated: 2026-07-22
|
|
4
4
|
|
|
5
5
|
This matrix records the ObservMe runtime and observability-stack versions exercised or pinned for the current release line. A component is marked **validated** only when the named command actually exercised it; configured CI targets remain distinct from completed local or workflow evidence.
|
|
6
6
|
|
|
7
7
|
## Pi version policy
|
|
8
8
|
|
|
9
|
-
ObservMe
|
|
9
|
+
ObservMe never uses Pi's reported version as a startup gate. The Pi-mandated core package peers remain in `peerDependencies` with `"*"`, while exact 0.80.5 and 0.81.1 targets record compatibility evidence in CI. Before registering anything, startup checks only the essential `ExtensionAPI` capabilities `on` and `registerCommand`. When those methods exist, ObservMe starts regardless of whether Pi's version is older, newer, prerelease, malformed, or unavailable. Optional APIs are feature-detected by the handlers that use them.
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
Pi 0.80.5 is the earliest tested version, not a runtime minimum: its exported extension contract includes `session_info_changed`, which ObservMe uses for live rename metadata. Pi's current extension overloads do not include `bashExecution`, `model_change`, or `thinking_level_change`. `bashExecution` is an `AgentMessage` role observed through `message_end`, while model and thinking changes are session entry types represented at runtime by `model_select` and `thinking_level_select`; ObservMe no longer registers those three non-event names. Tested versions provide release evidence only and never define an accepted or rejected runtime range.
|
|
12
12
|
|
|
13
13
|
## Validation record
|
|
14
14
|
|
|
@@ -18,9 +18,11 @@ The 0.80.5 minimum is evidence-based: its exported extension contract includes `
|
|
|
18
18
|
| 2026-07-07 | Local Docker 29.5.2 with Collector Contrib 0.104.0 | `npm run test:integration:collector` | Starts a local debug-exporter Collector container, exports representative ObservMe traces/metrics/logs, and asserts default-disabled content capture is absent. |
|
|
19
19
|
| 2026-07-07 | Local Docker 29.5.2 with the pinned Grafana stack | `npm run test:integration:grafana-stack` | Starts `observability-stack/` services, exports representative ObservMe telemetry, queries Tempo by trace ID and lineage attributes, queries Loki by session ID, queries Prometheus token totals, and validates Grafana dashboard provisioning imports. |
|
|
20
20
|
| Continuous integration target | GitHub Actions `ubuntu-latest`, Node.js 22.19.0 | `npm ci --ignore-scripts` then `npm run validate` | CI target from `.github/workflows/ci.yml`; record the workflow run URL here after each release validation. |
|
|
21
|
-
| Pi compatibility CI matrix (
|
|
22
|
-
| 2026-07-14 | Local Node.js v26.0.0, npm 11.12.1; exact `@earendil-works/pi-coding-agent` and `@earendil-works/pi-ai` 0.80.5 | Exact version assertion then `npm run validate:pi-compatibility` | Passed typecheck, typed event contracts,
|
|
23
|
-
| 2026-07-14 | Local Node.js v26.0.0, npm 11.12.1; exact `@earendil-works/pi-coding-agent` and `@earendil-works/pi-ai` 0.80.6 | Exact version assertion then `npm run validate:pi-compatibility` | Passed the same compatibility suite at the release-
|
|
21
|
+
| Pi compatibility CI matrix (updated 2026-07-22) | GitHub Actions `ubuntu-latest`, Node.js 22.19.0; exact Pi 0.80.5 and 0.81.1 matrix targets | Exact Pi install, version assertion, then `npm run validate:pi-compatibility` | Compile-time event fixtures, capability diagnostics, package install, handler/lifecycle smoke, and a real Pi RPC runtime are exercised separately at the earliest-tested and release-tested versions. |
|
|
22
|
+
| 2026-07-14 | Local Node.js v26.0.0, npm 11.12.1; exact `@earendil-works/pi-coding-agent` and `@earendil-works/pi-ai` 0.80.5 | Exact version assertion then `npm run validate:pi-compatibility` | Passed typecheck, typed event contracts, capability diagnostics, packaged install, handler/lifecycle smoke, and real Pi RPC runtime at the earliest-tested version. |
|
|
23
|
+
| 2026-07-14 | Local Node.js v26.0.0, npm 11.12.1; exact `@earendil-works/pi-coding-agent` and `@earendil-works/pi-ai` 0.80.6 | Exact version assertion then `npm run validate:pi-compatibility` | Passed the same compatibility suite at the former release-tested version. |
|
|
24
|
+
| 2026-07-22 | Local Node.js v26.0.0, npm 11.12.1; exact `@earendil-works/pi-coding-agent` and `@earendil-works/pi-ai` 0.81.1 | Exact version assertion, typechecks, compatibility tests, packaged install, handler/lifecycle smoke, and real Pi RPC runtime | Passed the complete `npm run validate:pi-compatibility` suite at the current release-tested version. |
|
|
25
|
+
| 2026-07-22 | Local Node.js v26.0.0, npm 11.12.1; exact Pi 0.81.1 development dependencies | `npm run validate` | Passed source/test typechecks, ESLint, formatting, 618 unit/contract tests, package-content checks, packaged-install smoke, handler smoke, Pi lifecycle smoke, and real Pi runtime smoke. |
|
|
24
26
|
| Lease cancellation CI profile (configured 2026-07-14) | GitHub-hosted Linux `ubuntu-latest` (exact `ImageOS`/`ImageVersion` recorded in the Actions runner log); Node.js 22.19.0; Collector Contrib 0.104.0; Prometheus 2.53.1; Grafana 11.1.0 | `npm run test:active-agent-lease:contracts` then `npm run test:integration:active-agent-lease` | The bounded `lease-cancellation` job validates clean shutdown, `SIGTERM`, and cancellation-oriented `SIGKILL` convergence against the pinned Collector and Prometheus without secrets or a Grafana dependency. Grafana 11.1.0 is the recorded dashboard compatibility baseline validated separately by `npm run test:integration:grafana-stack`. `if: always()` cleanup is best effort; lease expiry is the asserted correctness mechanism. |
|
|
25
27
|
| 2026-07-14 | Local Node.js v26.0.0, npm 11.12.1 | `npm run validate` | Passed 493 unit/contract tests plus typecheck, ESLint, formatting, script, package-content, packaged-install, handler, Pi lifecycle, and Pi runtime checks for the lease release candidate. |
|
|
26
28
|
| 2026-07-14 | Local Docker 29.5.2, Compose 5.1.4, Collector Contrib 0.104.0 | `npm run test:integration:collector`; Compose config; pinned Collector `validate` | Passed representative OTLP export, Compose interpolation, and the shipped Collector config validation. |
|
|
@@ -34,7 +36,7 @@ Active-agent lease interpretation additionally requires producer and Prometheus
|
|
|
34
36
|
|
|
35
37
|
| Component | Version tested or pinned | Source of truth | Status | Evidence and notes |
|
|
36
38
|
| --- | --- | --- | --- | --- |
|
|
37
|
-
| Pi package API |
|
|
39
|
+
| Pi package API | Runtime policy: required API capabilities only; version never gates startup. Earliest tested Pi: 0.80.5; release-tested `@earendil-works/pi-coding-agent` and `@earendil-works/pi-ai`: 0.81.1 | `package.json` `observmeCompatibility`, exact dev dependencies, `package-lock.json`, `.github/workflows/ci.yml` | Validated locally at earliest-tested 0.80.5 and release-tested 0.81.1; exact CI matrix configured | `npm run validate:pi-compatibility` typechecks exported event contracts, tests pre-registration capability diagnostics, installs the package, runs handler/lifecycle smoke, and launches the real Pi RPC runtime. Pi version values do not participate in startup acceptance. |
|
|
38
40
|
| Node.js | Local: 26.0.0; CI target/minimum: 22.19.0 | `node --version`, `package.json` `engines.node`, `.github/workflows/ci.yml` | Validated locally for 26.0.0; CI target pinned at 22.19.0 | Local validation ran on 26.0.0. CI is configured to validate on 22.19.0, which is also the minimum supported Node.js version. |
|
|
39
41
|
| OpenTelemetry JS package set | `@opentelemetry/api` 1.9.1; `@opentelemetry/api-logs` 0.220.0; OTLP proto exporters 0.220.0; `@opentelemetry/resources` 2.9.0; `@opentelemetry/sdk-logs` 0.220.0; `@opentelemetry/sdk-metrics` 2.9.0; `@opentelemetry/sdk-trace-base` 2.9.0; `@opentelemetry/sdk-trace-node` 2.9.0 | `package.json`, `package-lock.json` | Validated locally | `npm run validate` includes the OTEL lifecycle/exporter unit tests under `test/otel-*.test.mjs`. |
|
|
40
42
|
|
|
@@ -93,6 +93,16 @@ This sanitized record covers the production active-agent lease release candidate
|
|
|
93
93
|
|
|
94
94
|
Post-run cleanup check found no containers or networks labeled for the active-agent lease integration and no `observme-grafana-it-*` containers or networks. Release remains blocked on the unrelated broad Grafana-stack validation unless the release owner accepts the explicitly allowed pre-existing blocker; all lease-specific release criteria passed.
|
|
95
95
|
|
|
96
|
+
## Pi 0.81.1 compatibility validation — 2026-07-22
|
|
97
|
+
|
|
98
|
+
This sanitized record covers the compatibility-policy correction against exact `@earendil-works/pi-coding-agent` and `@earendil-works/pi-ai` 0.81.1 development dependencies on local Node.js v26.0.0 and npm 11.12.1. No project, model, Grafana, or registry credentials were required or printed.
|
|
99
|
+
|
|
100
|
+
| Command | Result | Evidence and notes |
|
|
101
|
+
| --- | --- | --- |
|
|
102
|
+
| `npm run validate:pi-compatibility` | Pass | Source/test typechecks, compatibility and event-mapping tests, packaged-install smoke, handler and lifecycle smoke, and the real Pi RPC runtime passed against Pi 0.81.1. |
|
|
103
|
+
| `npm run validate` | Pass | ESLint, formatting, script checks, 618 unit/contract tests, package-content validation, packaged-install smoke, handler smoke, Pi lifecycle smoke, and real Pi runtime smoke passed. |
|
|
104
|
+
| `npm audit --omit=dev` | Pass | The production dependency tree reported no vulnerabilities. |
|
|
105
|
+
|
|
96
106
|
## Review-closure evidence categories
|
|
97
107
|
|
|
98
108
|
- **Read-only/check-only** — commands that inspect, type-check, lint, audit, run tests, dry-run packaging, or smoke local deterministic fixtures without publishing or writing tracked files.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@senad-d/observme",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.6",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "ObservMe: a Pi extension that instruments Pi agent sessions and exports OpenTelemetry traces, metrics, and logs to an external observability stack (OTel Collector, Grafana Tempo/Loki/Prometheus).",
|
|
6
6
|
"license": "MIT",
|
|
@@ -76,9 +76,9 @@
|
|
|
76
76
|
},
|
|
77
77
|
"observmeCompatibility": {
|
|
78
78
|
"pi": {
|
|
79
|
-
"
|
|
80
|
-
"releaseTestedVersion": "0.
|
|
81
|
-
"
|
|
79
|
+
"earliestTestedVersion": "0.80.5",
|
|
80
|
+
"releaseTestedVersion": "0.81.1",
|
|
81
|
+
"runtimePolicy": "required-api-capabilities"
|
|
82
82
|
}
|
|
83
83
|
},
|
|
84
84
|
"pi": {
|
|
@@ -96,8 +96,8 @@
|
|
|
96
96
|
"typebox": "*"
|
|
97
97
|
},
|
|
98
98
|
"devDependencies": {
|
|
99
|
-
"@earendil-works/pi-ai": "0.
|
|
100
|
-
"@earendil-works/pi-coding-agent": "0.
|
|
99
|
+
"@earendil-works/pi-ai": "0.81.1",
|
|
100
|
+
"@earendil-works/pi-coding-agent": "0.81.1",
|
|
101
101
|
"@eslint/js": "^10.0.1",
|
|
102
102
|
"@types/node": "^26.1.1",
|
|
103
103
|
"c8": "^11.0.0",
|
package/src/extension.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
2
2
|
import { registerObsCommand } from "./commands/obs.ts";
|
|
3
|
-
import {
|
|
3
|
+
import { assertObservMePiCapabilities } from "./pi/compatibility.ts";
|
|
4
4
|
import { registerHandlers } from "./pi/handlers.ts";
|
|
5
5
|
const partialInitializationErrorMessage =
|
|
6
6
|
"ObservMe extension initialization failed while registering /obs after Pi event handlers were already registered. Pi ExtensionAPI does not expose unregister hooks for event handlers or slash commands, so ObservMe cannot roll back partial registration; restart Pi after fixing command registration.";
|
|
7
7
|
|
|
8
8
|
export default function observme(pi: ExtensionAPI): void {
|
|
9
|
-
|
|
9
|
+
assertObservMePiCapabilities(pi);
|
|
10
10
|
// Only the Pi process environment is eligible for launcher-provided lineage.
|
|
11
11
|
// Session config loading keeps trusted project .env values out of this boundary.
|
|
12
12
|
registerHandlers(pi, { trustedParentContext: true });
|
package/src/pi/compatibility.ts
CHANGED
|
@@ -1,34 +1,17 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
export const EARLIEST_TESTED_PI_VERSION = "0.80.5";
|
|
2
|
+
export const RELEASE_TESTED_PI_VERSION = "0.81.1";
|
|
3
|
+
export const PI_RUNTIME_COMPATIBILITY_POLICY = "required-api-capabilities" as const;
|
|
3
4
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
const FIRST_UNSUPPORTED_PI_VERSION = "0.81.0";
|
|
7
|
-
export const SUPPORTED_PI_VERSION_RANGE =
|
|
8
|
-
`>=${MINIMUM_SUPPORTED_PI_VERSION} <${FIRST_UNSUPPORTED_PI_VERSION}`;
|
|
5
|
+
const capabilityErrorPrefix = "ObservMe/Pi API capability error";
|
|
6
|
+
const requiredPiMethods = ["on", "registerCommand"] as const;
|
|
9
7
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
const piVersionCorePattern = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)$/u;
|
|
13
|
-
const semanticVersionIdentifierPattern = /^[0-9A-Za-z-]+$/u;
|
|
14
|
-
const numericIdentifierPattern = /^\d+$/u;
|
|
15
|
-
const requiredPiMethods = ["on", "registerCommand", "appendEntry", "getThinkingLevel"] as const;
|
|
16
|
-
|
|
17
|
-
export function assertObservMePiCompatibility(
|
|
18
|
-
pi: unknown,
|
|
19
|
-
piVersion = PI_VERSION,
|
|
20
|
-
): asserts pi is ExtensionAPI {
|
|
8
|
+
/** Pi's reported version is intentionally not part of this startup decision. */
|
|
9
|
+
export function assertObservMePiCapabilities(pi: unknown): void {
|
|
21
10
|
const missingMethods = findMissingPiMethods(pi);
|
|
22
|
-
|
|
23
|
-
const versionSupported = isSupportedPiVersion(detectedVersion);
|
|
24
|
-
if (versionSupported && missingMethods.length === 0) return;
|
|
25
|
-
|
|
26
|
-
const reasons: string[] = [];
|
|
27
|
-
if (!versionSupported) reasons.push(`detected Pi ${detectedVersion}`);
|
|
28
|
-
if (missingMethods.length > 0) reasons.push(`missing required API method(s): ${missingMethods.join(", ")}`);
|
|
11
|
+
if (missingMethods.length === 0) return;
|
|
29
12
|
|
|
30
13
|
throw new TypeError(
|
|
31
|
-
`${
|
|
14
|
+
`${capabilityErrorPrefix}: ObservMe requires ExtensionAPI method(s): ${missingMethods.join(", ")}. Pi version is not used as a startup gate. No ObservMe event handlers or commands were registered.`,
|
|
32
15
|
);
|
|
33
16
|
}
|
|
34
17
|
|
|
@@ -45,77 +28,3 @@ function findMissingPiMethods(pi: unknown): string[] {
|
|
|
45
28
|
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
46
29
|
return typeof value === "object" && value !== null;
|
|
47
30
|
}
|
|
48
|
-
|
|
49
|
-
function normalizeDetectedVersion(value: unknown): string {
|
|
50
|
-
if (typeof value !== "string") return "unknown";
|
|
51
|
-
const trimmed = value.trim();
|
|
52
|
-
if (trimmed.length === 0 || trimmed.length > MAX_DETECTED_PI_VERSION_LENGTH) return "unknown";
|
|
53
|
-
return parsePiVersion(trimmed) ? trimmed : "unknown";
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
function isSupportedPiVersion(version: string): boolean {
|
|
57
|
-
const detected = parsePiVersion(version);
|
|
58
|
-
const minimum = parsePiVersion(MINIMUM_SUPPORTED_PI_VERSION);
|
|
59
|
-
const maximum = parsePiVersion(FIRST_UNSUPPORTED_PI_VERSION);
|
|
60
|
-
if (!detected || detected.prerelease || !minimum || !maximum) return false;
|
|
61
|
-
|
|
62
|
-
return comparePiVersions(detected, minimum) >= 0 && comparePiVersions(detected, maximum) < 0;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
interface PiVersion {
|
|
66
|
-
major: number;
|
|
67
|
-
minor: number;
|
|
68
|
-
patch: number;
|
|
69
|
-
prerelease?: string;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
function parsePiVersion(version: string): PiVersion | undefined {
|
|
73
|
-
const buildSeparatorIndex = version.indexOf("+");
|
|
74
|
-
const versionAndPrerelease = buildSeparatorIndex === -1 ? version : version.slice(0, buildSeparatorIndex);
|
|
75
|
-
const build = buildSeparatorIndex === -1 ? undefined : version.slice(buildSeparatorIndex + 1);
|
|
76
|
-
if (build !== undefined && !hasValidSemanticVersionIdentifiers(build, true)) return undefined;
|
|
77
|
-
|
|
78
|
-
const prereleaseSeparatorIndex = versionAndPrerelease.indexOf("-");
|
|
79
|
-
const coreVersion = prereleaseSeparatorIndex === -1
|
|
80
|
-
? versionAndPrerelease
|
|
81
|
-
: versionAndPrerelease.slice(0, prereleaseSeparatorIndex);
|
|
82
|
-
const prerelease = prereleaseSeparatorIndex === -1
|
|
83
|
-
? undefined
|
|
84
|
-
: versionAndPrerelease.slice(prereleaseSeparatorIndex + 1);
|
|
85
|
-
if (prerelease !== undefined && !hasValidSemanticVersionIdentifiers(prerelease, false)) return undefined;
|
|
86
|
-
|
|
87
|
-
const match = piVersionCorePattern.exec(coreVersion);
|
|
88
|
-
if (!match) return undefined;
|
|
89
|
-
|
|
90
|
-
const major = Number(match[1]);
|
|
91
|
-
const minor = Number(match[2]);
|
|
92
|
-
const patch = Number(match[3]);
|
|
93
|
-
if (!Number.isSafeInteger(major) || !Number.isSafeInteger(minor) || !Number.isSafeInteger(patch)) {
|
|
94
|
-
return undefined;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
return {
|
|
98
|
-
major,
|
|
99
|
-
minor,
|
|
100
|
-
patch,
|
|
101
|
-
...(prerelease === undefined ? {} : { prerelease }),
|
|
102
|
-
};
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
function hasValidSemanticVersionIdentifiers(value: string, allowLeadingZeros: boolean): boolean {
|
|
106
|
-
for (const identifier of value.split(".")) {
|
|
107
|
-
if (!semanticVersionIdentifierPattern.test(identifier)) return false;
|
|
108
|
-
if (!allowLeadingZeros && hasInvalidNumericIdentifier(identifier)) return false;
|
|
109
|
-
}
|
|
110
|
-
return true;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
function hasInvalidNumericIdentifier(identifier: string): boolean {
|
|
114
|
-
return identifier.length > 1 && identifier.startsWith("0") && numericIdentifierPattern.test(identifier);
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
function comparePiVersions(left: PiVersion, right: PiVersion): number {
|
|
118
|
-
if (left.major !== right.major) return left.major - right.major;
|
|
119
|
-
if (left.minor !== right.minor) return left.minor - right.minor;
|
|
120
|
-
return left.patch - right.patch;
|
|
121
|
-
}
|
|
@@ -65,8 +65,8 @@ import type { AgentWaitJoinState, SubagentSpawnState } from "./subagent-types.ts
|
|
|
65
65
|
|
|
66
66
|
export const OBSERVME_SEMCONV_VERSION = "0.1.0";
|
|
67
67
|
|
|
68
|
-
const
|
|
69
|
-
"ObservMe/Pi API
|
|
68
|
+
const piApiCapabilityErrorMessage =
|
|
69
|
+
"ObservMe/Pi API capability error: expected Pi ExtensionAPI with on(eventName, handler) before registering ObservMe handlers.";
|
|
70
70
|
const eventRegistrationOrder = [
|
|
71
71
|
"session_start",
|
|
72
72
|
"session_info_changed",
|
|
@@ -143,10 +143,10 @@ export class SerializedLifecycleQueue {
|
|
|
143
143
|
}
|
|
144
144
|
|
|
145
145
|
export function resolveObservMePiApi(pi: unknown): ObservMePiApi {
|
|
146
|
-
if (!isRecord(pi)) throw new TypeError(
|
|
146
|
+
if (!isRecord(pi)) throw new TypeError(piApiCapabilityErrorMessage);
|
|
147
147
|
|
|
148
148
|
const on = pi.on;
|
|
149
|
-
if (typeof on !== "function") throw new TypeError(
|
|
149
|
+
if (typeof on !== "function") throw new TypeError(piApiCapabilityErrorMessage);
|
|
150
150
|
|
|
151
151
|
const appendEntry = typeof pi.appendEntry === "function"
|
|
152
152
|
? (pi.appendEntry.bind(pi) as NonNullable<ObservMePiApi["appendEntry"]>)
|