@danypops/pi-papyrus 0.46.6 → 0.48.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -12,7 +12,7 @@ The `papyrus_*` tools are the low-level graph-store API:
12
12
 
13
13
  Agent-facing domain tools own lifecycle invariants and sit above this store API. `notes`, `docs`, `rules`, `playbooks`, `tasks`, and `discuss` are all projected from Papyrus's own Vehicle as one real tool per operation (`notes_capture`, `rules_create`, `playbooks_invoke`, `tasks_complete`, `discuss_open`, and so on) -- no `action` dispatch, each with its own schema. `discuss_open`/`discuss_reply` additionally accept `live: true` for a synchronous human round-trip, via vehicle-client-pi's `interactiveFollowUps` hook rather than a bespoke tool:
14
14
 
15
- - **tasks** (`tasks_create`, `tasks_update`, `tasks_list`, `tasks_show`, `tasks_plan`, `tasks_graph`, `tasks_focus`, `tasks_pause`, `tasks_unpause`, `tasks_clear_focus`, `tasks_start`, `tasks_submit`, `tasks_complete`, `tasks_reject`, `tasks_retry`, `tasks_cancel`, `tasks_cancel_subtree`, `tasks_run_gates`, `tasks_set_checklist`, `tasks_set_gates`, `tasks_depend`, `tasks_undepend`, `tasks_contain`, `tasks_uncontain`, `tasks_claim`, `tasks_heartbeat_lease`, `tasks_release_lease`, `tasks_lease`, `tasks_context`, `tasks_event_feed`, `tasks_scope`, `tasks_set_scope`, `tasks_assign_project`, `tasks_active`, `tasks_focused`, `tasks_history`) — manages the singleton active focus, evidence-bearing checklists, hierarchy/dependencies, lifecycle transitions, non-blocking gates, and review completion that focuses one deterministic ready successor without claiming effort. `project_root` is required wherever a plain `tasks` call would otherwise need one (list/graph/plan/active/focused/scope/context/create) -- there is no ambient Pi cwd server-side. `tasks_focus`/`tasks_pause`/`tasks_unpause`/`tasks_clear_focus` still authorize their write via this session's own cached secret, and still broadcast `papyrus.task-focus.v1` on Pi's own event bus for a sibling extension to observe, exactly as before
15
+ - **tasks** (`tasks_create`, `tasks_update`, `tasks_list`, `tasks_show`, `tasks_plan`, `tasks_graph`, `tasks_focus`, `tasks_pause`, `tasks_unpause`, `tasks_clear_focus`, `tasks_start`, `tasks_submit`, `tasks_complete`, `tasks_reject`, `tasks_retry`, `tasks_cancel`, `tasks_cancel_subtree`, `tasks_run_gates`, `tasks_set_checklist`, `tasks_set_gates`, `tasks_depend`, `tasks_undepend`, `tasks_contain`, `tasks_uncontain`, `tasks_claim`, `tasks_heartbeat_lease`, `tasks_release_lease`, `tasks_lease`, `tasks_context`, `tasks_event_feed`, `tasks_projects`, `tasks_resolve_project`, `tasks_register_project`, `tasks_scope`, `tasks_set_scope`, `tasks_assign_project`, `tasks_active`, `tasks_focused`, `tasks_history`) — manages the singleton active focus, evidence-bearing checklists, hierarchy/dependencies, lifecycle transitions, non-blocking gates, and review completion that focuses one deterministic ready successor without claiming effort. `project_root` is required wherever a plain `tasks` call would otherwise need one (list/graph/plan/active/focused/scope/context/create) -- there is no ambient Pi cwd server-side. Resolve human scope names through `tasks_resolve_project`, then pass its canonical root. `tasks_create` supports a seven-day caller/project-scoped `idempotency_key` for exact-payload retries. `tasks_focus`/`tasks_pause`/`tasks_unpause`/`tasks_clear_focus` still authorize their write via this session's own cached secret, and still broadcast `papyrus.task-focus.v1` on Pi's own event bus for a sibling extension to observe, exactly as before
16
16
  - **notes** (`notes_capture`, `notes_list`, `notes_show`, `notes_consume`, `notes_promote`, `notes_archive`) — capture/list/show deferred human intent, mark it consumed, promote it to an existing Task/Doc/Rule/Playbook, or archive it with an explicit disposition
17
17
  - **docs** (`docs_create`, `docs_list`, `docs_show`, `docs_activate`, `docs_archive`, `docs_reopen`, `docs_link`, `docs_assign_project`, `docs_update`) — activate/archive/reopen and document-safe graph links; Note mutations remain behind the Notes facade
18
18
  - **rules** (`rules_create`, `rules_list`, `rules_show`, `rules_preview`, `rules_enable`, `rules_disable`, `rules_gate`, `rules_assign_project`, `rules_update`) — enable/disable and attach governance gates to tasks
@@ -15,6 +15,7 @@ export interface StatusPresentation {
15
15
  }
16
16
 
17
17
  export const RULE_STATUS_PRESENTATION: Record<string, StatusPresentation> = {
18
+ draft: { label: "draft", glyph: "◌", color: "dim" },
18
19
  active: { label: "active", glyph: "●", color: "success" },
19
20
  deprecated: { label: "deprecated", glyph: "○", color: "muted" },
20
21
  };
@@ -23,7 +23,7 @@
23
23
  * had died.
24
24
  */
25
25
 
26
- import { createReconnectingVehicleClient } from "@danypops/vehicle-client/daemon-client";
26
+ import { createReconnectingVehicleClient, daemonInstanceIdentity } from "@danypops/vehicle-client/daemon-client";
27
27
  import { RemoteVehicleClient } from "@danypops/vehicle-client/http";
28
28
  import { type RegisteredPiVehicle, registerVehicleToolsWhenReady, type VehicleReadyEvent } from "@danypops/vehicle-client-pi";
29
29
  import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
@@ -105,11 +105,24 @@ function notifyReadyEvent(event: VehicleReadyEvent): void {
105
105
  */
106
106
  export function registerNotesVehicle(pi: ExtensionAPI): Promise<RegisteredPiVehicle | undefined> {
107
107
  recordRenderDiagnostic({ event: "register-notes-vehicle-called" });
108
- const client = createReconnectingVehicleClient(async () => {
108
+ function resolveTarget() {
109
109
  const resolved = currentVehicleClientTarget();
110
110
  if (!resolved) throw new Error("Papyrus daemon is not running");
111
- return new RemoteVehicleClient({ baseUrl: resolved.baseUrl, token: resolved.token });
112
- });
111
+ return resolved;
112
+ }
113
+ const client = createReconnectingVehicleClient(
114
+ async () => {
115
+ const resolved = resolveTarget();
116
+ return new RemoteVehicleClient({ baseUrl: resolved.baseUrl, token: resolved.token });
117
+ },
118
+ {
119
+ // The random loopback port is process-instance identity for Papyrus: it changes on
120
+ // every restart while the bearer token intentionally survives. Re-read it before
121
+ // every dispatch so a long-lived Pi session never sends one sacrificial call to a
122
+ // cached dead port just to discover what the handle file already says.
123
+ resolveIdentity: () => daemonInstanceIdentity(resolveTarget().baseUrl),
124
+ },
125
+ );
113
126
  return registerVehicleToolsWhenReady(pi, () => Promise.resolve(currentVehicleClientTarget() ? client : undefined), {
114
127
  log: (event) => {
115
128
  // Correlates against onInvoked's own timestamps below -- the /reload investigation's
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@danypops/pi-papyrus",
3
- "version": "0.46.6",
3
+ "version": "0.48.0",
4
4
  "description": "Pi host extension for Papyrus: native tools, TUI panels, and context injection over the daemon-backed graph store",
5
5
  "type": "module",
6
6
  "keywords": ["pi-package"],
@@ -18,9 +18,9 @@
18
18
  },
19
19
  "dependencies": {
20
20
  "@danypops/jittor": "^0.14.0",
21
- "@danypops/papyrus": "^0.45.2",
22
- "@danypops/vehicle-client": "^0.5.0",
23
- "@danypops/vehicle-client-pi": "^0.18.4",
21
+ "@danypops/papyrus": "^0.46.0",
22
+ "@danypops/vehicle-client": "^0.7.0",
23
+ "@danypops/vehicle-client-pi": "^0.19.0",
24
24
  "@danypops/vehicle-core": "^0.12.3",
25
25
  "@danypops/vehicle-server": "^0.18.1",
26
26
  "beautiful-mermaid": "1.1.3",