Skip to content

Commit 12b17c9

Browse files
authored
Merge pull request #95 from dasomji/agent/fix-statusbar-open-count
Fix stale footer counts and npm package updates
2 parents 9798105 + b5b4d1b commit 12b17c9

44 files changed

Lines changed: 199 additions & 100 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ The product requirements document is in [`docs/prd/pi-postbox.md`](docs/prd/pi-p
88

99
## Current status
1010

11-
Issues #1-#11 provide the v1 implementation: runnable TypeScript workspace, `pi-postbox-server` CLI, Pi extension with `write_question`, WebSocket session registration, SSE browser state, SQLite persistence/history, structured Questions and options, semantic working/blocked/idle state, reconnect/idempotency/expiry, local terminal fallback commands, editable presentation metadata, and packaging/deployment docs plus a release smoke script. Version 0.2.3 adds validated npm Trusted Publishing from pushes to the main branch through GitHub Actions OIDC. Version 0.2.2 adds complete npm license and source metadata, fixes the published CLI bin path, and excludes test source from the package tarball. Version 0.2.1 bounds and paginates every model-facing bulk read, uses compact stateless cursors, hides inactive historical owners by default, trims repeated list fields, and preserves checkout development ports across restarts. Version 0.2.0 replaces the separate model-facing create/update tools with one explicit-action `write_question` surface and returns reusable current Question handles from creation. Version 0.1.9 requires a concise ambiguity for new Questions, simplifies parent and expiry inputs, renames option `meaning` to `impact`, removes top-level handoff context and per-option context, removes reconstructed Question Chat, and renders single/multi choice with accessible ballot controls. Version 0.1.8 exposed single-Question create/idempotent receipt disposition and safely required a full Pi restart when `/reload` retained an incompatible shared protocol dependency. Version 0.1.7 reduced model-facing tool schemas, strictly described exact-owner filters, and made recovery reads compact by default with an explicit full view while preserving strict server-side action validation and internal provenance/expiry compatibility.
11+
Issues #1-#11 provide the v1 implementation: runnable TypeScript workspace, `pi-postbox-server` CLI, Pi extension with `write_question`, WebSocket session registration, SSE browser state, SQLite persistence/history, structured Questions and options, semantic working/blocked/idle state, reconnect/idempotency/expiry, local terminal fallback commands, editable presentation metadata, and packaging/deployment docs plus a release smoke script. Version 0.2.5 keeps the footer and status surfaces from undercounting a locally tracked open Question when the durable owner snapshot is briefly stale, makes published package updates robust on npm 11, and prebuilds the shared protocol before clean-checkout test runs. Version 0.2.3 adds validated npm Trusted Publishing from pushes to the main branch through GitHub Actions OIDC. Version 0.2.2 adds complete npm license and source metadata, fixes the published CLI bin path, and excludes test source from the package tarball. Version 0.2.1 bounds and paginates every model-facing bulk read, uses compact stateless cursors, hides inactive historical owners by default, trims repeated list fields, and preserves checkout development ports across restarts. Version 0.2.0 replaces the separate model-facing create/update tools with one explicit-action `write_question` surface and returns reusable current Question handles from creation. Version 0.1.9 requires a concise ambiguity for new Questions, simplifies parent and expiry inputs, renames option `meaning` to `impact`, removes top-level handoff context and per-option context, removes reconstructed Question Chat, and renders single/multi choice with accessible ballot controls. Version 0.1.8 exposed single-Question create/idempotent receipt disposition and safely required a full Pi restart when `/reload` retained an incompatible shared protocol dependency. Version 0.1.7 reduced model-facing tool schemas, strictly described exact-owner filters, and made recovery reads compact by default with an explicit full view while preserving strict server-side action validation and internal provenance/expiry compatibility.
1212

1313
## Quick start from this checkout
1414

apps/web/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@pi-postbox/web",
3-
"version": "0.2.3",
3+
"version": "0.2.5",
44
"private": true,
55
"type": "module",
66
"scripts": {
@@ -10,7 +10,7 @@
1010
"typecheck": "svelte-check --tsconfig ./tsconfig.json"
1111
},
1212
"dependencies": {
13-
"@pi-postbox/protocol": "0.2.3",
13+
"@pi-postbox/protocol": "0.2.5",
1414
"marked": "^18.0.5"
1515
},
1616
"devDependencies": {

docs/protocol.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,6 @@ Package-local autostart is a client recovery behavior for `write_question` and t
279279
- Handle unknown fields gracefully.
280280
- Use `/healthz` to confirm service and protocol version before relying on newer fields.
281281
- Question Chat is exact-fork only. `forkKind` accepts only `"exact"`; context-only activation endpoints and relay commands are not part of the current protocol.
282-
- Package version 0.2.3 retains protocol compatibility version 0.1.8 and adds validated npm Trusted Publishing from pushes to the main branch through GitHub Actions OIDC. Package version 0.2.2 retained protocol compatibility version 0.1.8 and changed release packaging metadata only. Package version 0.2.1 introduced protocol compatibility version 0.1.8, adds server-enforced bulk-read limits and paged status/history/owner envelopes, emits compact stateless cursors, and omits inactive owners by default. Matching extension/server/protocol builds are required. Package version 0.2.0 used protocol 0.1.7, merged Question creation and updates into the model-facing `write_question` tool, and extended create receipts with current content/ownership revisions and lifecycle status. Package version 0.1.9 used protocol 0.1.6 and required ambiguity on new Questions, simplified model-facing parent/expiry fields, renamed legacy option `meaning` to `impact`, removed top-level handoff context and per-option context, removed reconstructed Question Chat, and used exact-fork Chat only. Package version 0.1.8 added single-Question receipt disposition and suppressed autostart when exact live-profile identity proved that `/reload` retained an incompatible protocol dependency; a full Pi restart was then required. Package version 0.1.7 added compact recovery views, explicit exact-owner schemas, and a compact model-facing update schema.
282+
- Package version 0.2.5 retains protocol compatibility version 0.1.8, prevents stale durable owner counts from hiding locally tracked open Questions in status surfaces, makes published package updates robust on npm 11, and prebuilds the shared protocol before clean-checkout test runs. Package version 0.2.3 retains protocol compatibility version 0.1.8 and adds validated npm Trusted Publishing from pushes to the main branch through GitHub Actions OIDC. Package version 0.2.2 retained protocol compatibility version 0.1.8 and changed release packaging metadata only. Package version 0.2.1 introduced protocol compatibility version 0.1.8, adds server-enforced bulk-read limits and paged status/history/owner envelopes, emits compact stateless cursors, and omits inactive owners by default. Matching extension/server/protocol builds are required. Package version 0.2.0 used protocol 0.1.7, merged Question creation and updates into the model-facing `write_question` tool, and extended create receipts with current content/ownership revisions and lifecycle status. Package version 0.1.9 used protocol 0.1.6 and required ambiguity on new Questions, simplified model-facing parent/expiry fields, renamed legacy option `meaning` to `impact`, removed top-level handoff context and per-option context, removed reconstructed Question Chat, and used exact-fork Chat only. Package version 0.1.8 added single-Question receipt disposition and suppressed autostart when exact live-profile identity proved that `/reload` retained an incompatible protocol dependency; a full Pi restart was then required. Package version 0.1.7 added compact recovery views, explicit exact-owner schemas, and a compact model-facing update schema.
283283
- V1 has no app-level authentication; restrict network reachability with Tailscale/lizardtail or an external auth proxy.
284284
- State-changing HTTP actions and extension WebSockets reject cross-origin browser requests unless the `Origin` host matches the Postbox service host. Node/Pi extension clients normally omit `Origin` and are accepted if they can reach the service.

package-lock.json

Lines changed: 9 additions & 25 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@wienerberliner/pi-postbox",
3-
"version": "0.2.3",
3+
"version": "0.2.5",
44
"description": "Pi Postbox extension and web service for remote human decision handoffs.",
55
"license": "MIT",
66
"type": "module",
@@ -20,6 +20,7 @@
2020
"build": "tsc -b && npm run build -w @pi-postbox/web && node scripts/copy-web-to-server.mjs && node scripts/prune-obsolete-build.mjs",
2121
"dev": "node scripts/dev.mjs",
2222
"typecheck": "tsc -b",
23+
"pretest": "npm run build -w @pi-postbox/protocol",
2324
"test": "vitest run",
2425
"test:notification-performance": "npm run build && node scripts/notification-open-performance.mjs",
2526
"smoke": "node scripts/smoke-postbox.mjs",
@@ -72,7 +73,6 @@
7273
"@fastify/compress": "9.1.0",
7374
"@fastify/static": "9.1.3",
7475
"@fastify/websocket": "^11.2.0",
75-
"@pi-postbox/protocol": "file:packages/protocol",
7676
"better-sqlite3": "^12.10.0",
7777
"fastify": "^5.2.1",
7878
"typebox": "^1.1.38",

packages/extension/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@pi-postbox/extension",
3-
"version": "0.2.3",
3+
"version": "0.2.5",
44
"description": "Pi extension that registers sessions with Pi Postbox and exposes write_question.",
55
"type": "module",
66
"main": "src/index.ts",
@@ -32,7 +32,7 @@
3232
},
3333
"dependencies": {
3434
"@earendil-works/pi-coding-agent": "0.80.10",
35-
"@pi-postbox/protocol": "0.2.3",
35+
"@pi-postbox/protocol": "0.2.5",
3636
"typebox": "^1.1.38",
3737
"ws": "^8.21.0"
3838
},

packages/extension/src/adapterContract.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type { OwnerIdentity } from "@pi-postbox/protocol";
1+
import type { OwnerIdentity } from "./protocol.js";
22

33
export type NativeHarnessIdentity =
44
| { harness: "pi"; sessionUuid: string }

packages/extension/src/client/PostboxClient.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import {
2020
type ServerProfileIdentity,
2121
type SessionRegisterPayload,
2222
type SessionShutdownReason
23-
} from "@pi-postbox/protocol";
23+
} from "../protocol.js";
2424
import type {
2525
QuestionChatEvent,
2626
QuestionChatAvailabilityError,
@@ -30,7 +30,7 @@ import type {
3030
QuestionChatSource,
3131
QuestionChatStopPayload,
3232
QuestionChatStopResponse
33-
} from "@pi-postbox/protocol";
33+
} from "../protocol.js";
3434
import {
3535
QuestionChatRuntimeError,
3636
type QuestionChatReconciliationDecision,
@@ -504,7 +504,10 @@ export class PostboxClient {
504504
const awaitingPersistence = [...this.pendingCreateReceipts.keys()]
505505
.filter((requestId) => this.pendingAsks.has(requestId))
506506
.length;
507-
openQuestionCount = Number(status.activeQuestionCount) + awaitingPersistence;
507+
openQuestionCount = Math.max(
508+
openQuestionCount,
509+
Number(status.activeQuestionCount) + awaitingPersistence
510+
);
508511
}
509512
} catch {
510513
// Pending client state remains a safe fallback while the durable status query is unavailable.

packages/extension/src/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import {
88
QUESTION_HISTORY_PAGE_MAX,
99
QUESTION_STATUS_PAGE_MAX,
1010
type SessionRegisterPayload
11-
} from "@pi-postbox/protocol";
11+
} from "./protocol.js";
1212
import { PostboxClient } from "./client/PostboxClient.js";
1313
import { registerPostboxFallbackCommands } from "./commands/localFallback.js";
1414
import { registerOpenPostboxCommand } from "./commands/openPostbox.js";
@@ -830,7 +830,7 @@ async function renderPostboxFooter(
830830
?? snapshot.connection.localUrl
831831
?? snapshot.connection.activeUrl
832832
?? fallbackUrl;
833-
openQuestionCount = snapshot.openQuestionCount;
833+
openQuestionCount = Math.max(openQuestionCount, snapshot.openQuestionCount);
834834
} catch {
835835
// The known target and pending asks still make a useful footer if diagnostics fail.
836836
}

packages/extension/src/lifecycle.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type { SemanticState } from "@pi-postbox/protocol";
1+
import type { SemanticState } from "./protocol.js";
22
import { emitHerdrBlocked } from "./herdrInterop.js";
33

44
export interface SemanticStateClient {

0 commit comments

Comments
 (0)