pi-daddy 0.27.4 → 0.28.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.
Files changed (43) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/PRODUCT-GUIDE.md +22 -3
  3. package/README.md +9 -9
  4. package/REQUIREMENTS.md +1 -1
  5. package/dist/activity-timeline.d.ts +109 -0
  6. package/dist/activity-timeline.d.ts.map +1 -0
  7. package/dist/activity-timeline.js +208 -0
  8. package/dist/activity-timeline.js.map +1 -0
  9. package/dist/dashboard-cli.d.ts +6 -0
  10. package/dist/dashboard-cli.d.ts.map +1 -1
  11. package/dist/dashboard-cli.js +41 -5
  12. package/dist/dashboard-cli.js.map +1 -1
  13. package/dist/dashboard-display-controls.d.ts +5 -0
  14. package/dist/dashboard-display-controls.d.ts.map +1 -1
  15. package/dist/dashboard-display-controls.js +12 -3
  16. package/dist/dashboard-display-controls.js.map +1 -1
  17. package/dist/dashboard-handshake.d.ts +6 -1
  18. package/dist/dashboard-handshake.d.ts.map +1 -1
  19. package/dist/dashboard-handshake.js +21 -10
  20. package/dist/dashboard-handshake.js.map +1 -1
  21. package/dist/delegate-types.d.ts +8 -0
  22. package/dist/delegate-types.d.ts.map +1 -1
  23. package/dist/delegate-types.js.map +1 -1
  24. package/dist/delegate.d.ts.map +1 -1
  25. package/dist/delegate.js +14 -6
  26. package/dist/delegate.js.map +1 -1
  27. package/dist/measured-session.d.ts +1 -1
  28. package/extensions/activity-timeline.ts +90 -0
  29. package/extensions/execute-child.ts +6 -6
  30. package/extensions/grants-command.ts +1 -1
  31. package/extensions/grants-connected-command.ts +2 -2
  32. package/extensions/grants.ts +7 -6
  33. package/extensions/reload-environment.ts +1 -1
  34. package/extensions/session-environment.ts +6 -3
  35. package/extensions/session-report.ts +1 -0
  36. package/extensions/session.ts +21 -35
  37. package/package.json +2 -2
  38. package/src/activity-timeline.ts +133 -0
  39. package/src/dashboard-cli.ts +29 -4
  40. package/src/dashboard-display-controls.ts +6 -3
  41. package/src/dashboard-handshake.ts +18 -13
  42. package/src/delegate-types.ts +4 -0
  43. package/src/delegate.ts +13 -6
package/CHANGELOG.md CHANGED
@@ -12,6 +12,15 @@ the record of how the package got here and are worth keeping; they are not worth
12
12
  > the record of how the package arrived at what it does, and because the reasoning behind each one is
13
13
  > usually the clearest statement of why the current behaviour is what it is.
14
14
 
15
+ ## 0.28.0 — unified activity timeline and default-on operation
16
+
17
+ - Combine root turns, delegated agents and observed/declared skill activity in one filtered timeline with history.
18
+ - Load exact submitted prompts and final responses on demand from bounded private local content references.
19
+ - Track leaf children through a no-tool observer without expanding grants or tool allowlists.
20
+ - Enable root governance and local observation by default, with explicit opt-outs and compatible Herdr auto-presentation/Pi fallback.
21
+ - Available, read and declared-active skills remain distinct; shell-only reads and unavailable editor provenance are not invented.
22
+ - Upgrade behavior: local prompt/final retention is now default-on. Use the documented metadata-only or observation-off option when desired. This does not enable uploads, model learning calls or automatic policy adoption.
23
+
15
24
  ## 0.27.4 — independent Herdr delegation names (2026-09-17)
16
25
 
17
26
  - Generate a fresh execution suffix instead of a process-local counter, preventing parallel Pi parents
package/PRODUCT-GUIDE.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Work and learning in Pi
2
2
 
3
- This guide targets **pi-daddy 0.27.3** with **skill-harness 0.17.0**. Completed ledger history now has
3
+ This guide targets **pi-daddy 0.28.0** with **skill-harness 0.17.0**. Completed ledger history now has
4
4
  visible hidden counts and an h + Enter toggle. Existing installed-skill discovery remains unchanged.
5
5
  Release qualification and publication are recorded in the release PR; version metadata alone is not proof.
6
6
  The [current requirement register](./REQUIREMENTS.md) separates implementation from release evidence.
@@ -9,10 +9,10 @@ From an installed shell command, `pi-daddy guide` prints this guide; `pi-daddy c
9
9
  ## Start once
10
10
 
11
11
  After the patch is published, install it with Pi's normal package manager:
12
- `pi install npm:pi-daddy@0.27.3` and `pi install npm:skill-harness@0.17.0`.
12
+ `pi install npm:pi-daddy@0.28.0` and `pi install npm:skill-harness@0.17.0`.
13
13
  Do not treat these planned version commands as evidence the packages are already available.
14
14
  Start a **fresh Pi session** after upgrading the harness: its existing immutable bridge survives `/reload`.
15
- In the project, run `/grants init`, review capability consent, then `/grants` to see usable definitions.
15
+ The extension starts with local governance, observation and the timeline on; `/grants init` remains an optional way to save an explicit project ceiling, not a bootstrap requirement. Run `/grants` to see the root's observed tool ceiling and usable definitions.
16
16
  Enabled installed runtime skills are used in place, using Pi's package filters and config directory.
17
17
  No `.pi/skills/` copies are created for them. Existing local overrides and `.pi/grants.env` are preserved;
18
18
  review old copies before removing one to follow installed package updates. Unregistered npm packages retain
@@ -40,6 +40,25 @@ The run is finite, with no automatic retry or restart recovery. Esc requests can
40
40
  original children to settle. Ordinary model work has **no universal dollar/token cap**; provider usage is
41
41
  not invented from output size. Effort is an observed/requested launch setting, not measured internal thought.
42
42
 
43
+ ## Activity timeline
44
+
45
+ When the extension runs, pi-daddy records a local activity timeline by default at
46
+ `.pi/pi-daddy/activity.jsonl`. It shows separate parent turns, governed child lifecycles, observed
47
+ skill-file availability/reads, and declared runtime-skill lifecycle. A compatible Herdr plugin opens one
48
+ right-side panel per parent tab without taking focus; `/grants dashboard` remains the visible Pi fallback
49
+ when Herdr/panel setup is unavailable. `PI_DADDY_GOVERNANCE=off` is the visible governance opt-out;
50
+ `PI_DADDY_ACTIVITY_TIMELINE=off` stops observation; and
51
+ `PI_DADDY_ACTIVITY_CONTENT=metadata-only` stores only digest/size metadata for new prompts/final answers.
52
+ Those choices do not silently add grants, tools or child authority.
53
+
54
+ The dashboard's Everything / Agents / Skills / Needs-you filters and `h` history toggle are keyboard
55
+ controls. Press `d`, then use `p <root-id:task-id>` or `f <root-id:task-id>` exactly as shown on the row
56
+ to load the exact local finalized user message or final response after path, size and digest checks. A bare
57
+ task id is refused so simultaneous roots cannot select each other's private content. Pi exposes the finalized user message, not a separate
58
+ pre-transform editor buffer, so entered-text provenance is explicitly unavailable rather than guessed. A skill being available, read, or declaring itself active
59
+ are distinct facts; none proves compliance. Runtime skills can honestly report declared state with
60
+ a generic `activity_lifecycle` call; it adds no authority.
61
+
43
62
  ## Inspect the read-only execution ledger
44
63
 
45
64
  The ledger dashboard (`pi-daddy-dashboard --ledger <path>`, without a connected host or daily inputs)
package/README.md CHANGED
@@ -21,9 +21,9 @@ for this project. See *What this governs, and what it does not*.
21
21
  > **Known gaps are stated rather than implied** — see *Status* at the end of this file. The largest is
22
22
  > deliberate: a child granted `bash` escapes governance entirely, by decision.
23
23
 
24
- ## Everyday work and learning — 0.27.0 release candidate
24
+ ## Everyday work and learning — 0.28.0 release candidate
25
25
 
26
- Paired with planned **skill-harness 0.16.0**. Producer runtime is Sol-approved; feature PR #52 merged
26
+ Paired with planned **skill-harness 0.17.0**. Producer runtime is Sol-approved; feature PR #52 merged
27
27
  with green CI at `b974963a7d0ba5a74fdafe331356c348a1fba565`. Release PR CI/merge, installed qualification
28
28
  and publication remain pending. Release preparation changes metadata and test synchronization only,
29
29
  not runtime or dependencies.
@@ -606,20 +606,19 @@ so refusing is cheap and silence is not.
606
606
  `manager.spawn()` over the event bus and never produces a `tool_call` at all (ADR-0013 Finding 6), so a
607
607
  tool-name check cannot see it. It catches the ordinary case loudly. It is not containment.
608
608
 
609
- **Governance is opt-in.** With `PI_GRANTS_GRANT` unset, the session holds the wildcard and nothing is
610
- blocked — this extension must never silently tighten a normal workflow. Since 0.5.0 that holds for
611
- **descendants** too: an ungoverned session publishes no governance variables at all. It previously
612
- exported its own observed tool surface as its children's grant, so "inactive" governance quietly governed
613
- everything below it.
609
+ **Governance defaults on.** With `PI_GRANTS_GRANT` unset, a root starts with the wildcard only as an
610
+ upper bound and is tightened to Pi's observed tool surface before it can delegate. Descendants still receive
611
+ only their parent-computed narrowing grant. Set `PI_DADDY_GOVERNANCE=off` for the visible local opt-out;
612
+ observation and the activity timeline remain independent.
614
613
 
615
614
  ### Configuration, and how it fails
616
615
 
617
616
  | Variable | Default | Notes |
618
617
  | :--- | :--- | :--- |
619
- | `PI_GRANTS_GRANT` | unset → use this directory's stored init choice, or ungoverned when none exists | Presence switches governance on and bypasses the whole cwd store; this is how children and CI stay environment-only. |
618
+ | `PI_GRANTS_GRANT` | unset → observed-root ceiling, or this directory's stored init choice | Presence supplies an explicit ceiling and bypasses the whole cwd store; children receive their parent-computed value. |
620
619
  | `PI_GRANTS_MAX_DEPTH` | `2` | Child-depth bound. `0` disables spawning. |
621
620
  | `PI_GRANTS_DEPTH` | `0` | This session's own depth; set by the parent, not by hand. |
622
- | `PI_GRANTS_GATED` | **`tool:bash`** in a governed session | Capabilities needing human approval. Set to `""` to gate nothing. Gating is closed under subsumption, so this also covers `write`/`edit`/`read`/`grep`/`find`/`ls` (ADR-0012). |
621
+ | `PI_GRANTS_GATED` | **`tool:bash`** when governance is on | Capabilities needing human approval. Set to `""` to gate nothing. Gating is closed under subsumption, so this also covers `write`/`edit`/`read`/`grep`/`find`/`ls` (ADR-0012). |
623
622
  | `PI_GRANTS_APPROVED` | unset | Inherited `capability@subject#sha256` entries; set by the parent, clamped to the child's own grant, and honoured only against the definition body the child itself loaded (ADR-0022). |
624
623
  | `PI_GRANTS_APPROVAL_TIMEOUT` | `120` (seconds) | How long a dialog waits. `0` or an unreadable value means **no timeout**: waiting forever denies nothing, so it is the safe reading of a value we do not understand. |
625
624
  | `PI_GRANTS_LEDGER` | unset → a v2 `/grants init` choice uses `<cwd>/.pi/grants.jsonl`; otherwise not recording | Presence overrides the project default; `""` disables it for one run. Any effective path is load-bearing. |
@@ -633,6 +632,7 @@ everything below it.
633
632
  | `PI_GRANTS_HERDR` | unset ⇒ **probe** | Three-state. Unset probes for a reachable herdr and uses panes if one answers; `1` demands panes and refuses every delegation if herdr is unreachable; `0` demands captured subprocesses. Never detected from `herdr` merely being on `PATH`. |
634
633
  | `PI_GRANTS_HERDR_WORKSPACE` | the parent's `HERDR_WORKSPACE_ID` | herdr workspace for spawned panes. Defaults to the workspace this session is in, so a child is a tab away rather than a workspace away. |
635
634
  | `PI_GRANTS_HERDR_KEEP_PANE` | unset | `1` keeps each child's pane for inspection, and no sweep closes it. Off by default: a fan-out would flood the workspace. |
635
+ | `PI_DADDY_GOVERNANCE` | on | `off` or `0` explicitly opts this local session out of governance. |
636
636
  | `PI_CODING_AGENT_DIR` | `~/.pi/agent` | pi's own variable, not ours — but it decides where stored project grants/ledger consent and persisted approvals live. |
637
637
 
638
638
  **A malformed value disables spawning; it never falls back to a default.** Stored grants are likewise
package/REQUIREMENTS.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Current producer requirement register
2
2
 
3
- **Release candidate:** pi-daddy **0.27.0**, paired with planned skill-harness **0.16.0**, implementing the
3
+ **Release candidate:** pi-daddy **0.28.0**, paired with planned skill-harness **0.17.0**, implementing the
4
4
  2026-09-14 proposal. This is current product scope, not an npm/release receipt or a replacement for dated
5
5
  evidence. Read [PRODUCT-GUIDE.md](./PRODUCT-GUIDE.md).
6
6
 
@@ -0,0 +1,109 @@
1
+ export declare const ACTIVITY_TIMELINE_VERSION: 1;
2
+ export declare const ENV_ACTIVITY_TIMELINE = "PI_DADDY_ACTIVITY_TIMELINE";
3
+ export declare const ENV_ACTIVITY_CONTENT = "PI_DADDY_ACTIVITY_CONTENT";
4
+ /** Per-child transport; these are observation identities, not capability authority. */
5
+ export declare const ENV_ACTIVITY_PATH = "PI_DADDY_ACTIVITY_PATH";
6
+ export declare const ENV_ACTIVITY_ROOT = "PI_DADDY_ACTIVITY_ROOT";
7
+ export declare const ENV_ACTIVITY_TASK = "PI_DADDY_ACTIVITY_TASK";
8
+ export declare const ENV_ACTIVITY_PARENT_TASK = "PI_DADDY_ACTIVITY_PARENT_TASK";
9
+ export type TimelineFilter = "everything" | "agents" | "skills" | "needs-you";
10
+ export interface ContentReference {
11
+ digest: string;
12
+ bytes: number;
13
+ ref?: string;
14
+ }
15
+ export interface ActivitySkill {
16
+ name: string;
17
+ source: string;
18
+ digest: string;
19
+ }
20
+ export interface ActivityEvent {
21
+ version: 1;
22
+ id: string;
23
+ kind: string;
24
+ at: string;
25
+ rootId: string;
26
+ taskId: string;
27
+ parentTaskId?: string;
28
+ agentId?: string;
29
+ agent?: string;
30
+ outcome?: string;
31
+ model?: string;
32
+ thinking?: string;
33
+ prompt?: ContentReference;
34
+ final?: ContentReference;
35
+ skill?: ActivitySkill;
36
+ }
37
+ export interface TimelineSkill extends ActivitySkill {
38
+ available: boolean;
39
+ read: boolean;
40
+ active: boolean;
41
+ superseded: boolean;
42
+ }
43
+ export interface TimelineTask {
44
+ id: string;
45
+ rootId: string;
46
+ parentTaskId?: string;
47
+ startedAt: string;
48
+ endedAt?: string;
49
+ status: "active" | "finished" | "failed" | "cancelled" | "needs-you";
50
+ model?: string;
51
+ thinking?: string;
52
+ prompt?: ContentReference;
53
+ final?: ContentReference;
54
+ skills: TimelineSkill[];
55
+ agents: Array<{
56
+ id: string;
57
+ parentTaskId?: string;
58
+ agent: string;
59
+ state: string;
60
+ }>;
61
+ }
62
+ export interface ActivityTimeline {
63
+ tasks: TimelineTask[];
64
+ refusals: string[];
65
+ }
66
+ export interface ActivityIdentity {
67
+ rootId: string;
68
+ path: string;
69
+ taskId?: string;
70
+ parentTaskId?: string;
71
+ }
72
+ /** Stable, unambiguous local selector: encoded root identity and task id, separated once by `:`. */
73
+ export declare const activityTaskKey: (rootId: string, taskId: string) => string;
74
+ export declare function parseActivityTimeline(text: string): ActivityTimeline;
75
+ export declare function renderActivityTimeline(timeline: ActivityTimeline, options?: {
76
+ filter?: TimelineFilter;
77
+ details?: boolean;
78
+ content?: {
79
+ taskKey: string;
80
+ field: "prompt" | "final";
81
+ text: string;
82
+ };
83
+ }): string;
84
+ export declare const defaultActivityTimelinePath: (cwd: string) => string;
85
+ export declare function activityIdentity(cwd: string, env?: NodeJS.ProcessEnv): ActivityIdentity;
86
+ export declare class ActivityTimelineRecorder {
87
+ readonly enabled: boolean;
88
+ readonly contentEnabled: boolean;
89
+ readonly path: string;
90
+ readonly rootId: string;
91
+ private taskId?;
92
+ constructor(cwd: string, env?: NodeJS.ProcessEnv);
93
+ get task(): string | undefined;
94
+ attach(taskId: string): void;
95
+ start(prompt: string, model?: string, thinking?: string, parentTaskId?: string): Promise<string | undefined>;
96
+ childStarted(taskId: string, parentTaskId: string | undefined, agent: string, prompt: string, model?: string, thinking?: string): Promise<void>;
97
+ childFinished(taskId: string, parentTaskId: string | undefined, agent: string, final: string, outcome: "completed" | "failed" | "cancelled"): Promise<void>;
98
+ finish(final: string | undefined, outcome?: "completed" | "failed" | "cancelled"): Promise<void>;
99
+ skill(kind: "skill_available" | "skill_read" | "skill_active" | "skill_finished" | "skill_superseded", skill: ActivitySkill): Promise<void>;
100
+ append(kind: string, fields: Omit<Partial<ActivityEvent>, "version" | "id" | "kind" | "at" | "rootId" | "taskId">): Promise<void>;
101
+ private content;
102
+ }
103
+ export declare function readActivityContent(timelinePath: string, reference: ContentReference): Promise<string>;
104
+ export declare function detailForTimeline(timelinePath: string, taskKey: string, field: "prompt" | "final"): Promise<{
105
+ taskKey: string;
106
+ field: "prompt" | "final";
107
+ text: string;
108
+ }>;
109
+ //# sourceMappingURL=activity-timeline.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"activity-timeline.d.ts","sourceRoot":"","sources":["../src/activity-timeline.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,208 @@
1
+ /** Durable, local-only activity facts. Timeline events never infer skill compliance or provider reasoning. */
2
+ import { createHash, randomUUID } from "node:crypto";
3
+ import { constants } from "node:fs";
4
+ import { appendFile, mkdir, open, readFile, realpath, rename, writeFile } from "node:fs/promises";
5
+ import { dirname, join, resolve, sep } from "node:path";
6
+ export const ACTIVITY_TIMELINE_VERSION = 1;
7
+ export const ENV_ACTIVITY_TIMELINE = "PI_DADDY_ACTIVITY_TIMELINE";
8
+ export const ENV_ACTIVITY_CONTENT = "PI_DADDY_ACTIVITY_CONTENT";
9
+ /** Per-child transport; these are observation identities, not capability authority. */
10
+ export const ENV_ACTIVITY_PATH = "PI_DADDY_ACTIVITY_PATH";
11
+ export const ENV_ACTIVITY_ROOT = "PI_DADDY_ACTIVITY_ROOT";
12
+ export const ENV_ACTIVITY_TASK = "PI_DADDY_ACTIVITY_TASK";
13
+ export const ENV_ACTIVITY_PARENT_TASK = "PI_DADDY_ACTIVITY_PARENT_TASK";
14
+ const MAX_EVENT_BYTES = 16 * 1024, MAX_CONTENT_BYTES = 256 * 1024;
15
+ const DIGEST = /^[a-f0-9]{64}$/, REF = /^content\/[a-f0-9]{64}$/;
16
+ const sha = (value) => createHash("sha256").update(value).digest("hex");
17
+ const validId = (value) => typeof value === "string" && value.length > 0 && value.length <= 200;
18
+ /** Stable, unambiguous local selector: encoded root identity and task id, separated once by `:`. */
19
+ export const activityTaskKey = (rootId, taskId) => `${encodeURIComponent(rootId)}:${encodeURIComponent(taskId)}`;
20
+ function taskFromKey(value) {
21
+ const parts = value.split(":");
22
+ if (parts.length !== 2 || value.length > 1400)
23
+ return null;
24
+ try {
25
+ const [rootId, taskId] = parts.map(decodeURIComponent);
26
+ return validId(rootId) && validId(taskId) && value === activityTaskKey(rootId, taskId) ? { rootId, taskId } : null;
27
+ }
28
+ catch {
29
+ return null;
30
+ }
31
+ }
32
+ function validRef(value) {
33
+ const ref = value;
34
+ return !!ref && typeof ref === "object" && DIGEST.test(String(ref.digest)) && Number.isSafeInteger(ref.bytes) && ref.bytes >= 0 &&
35
+ (ref.ref === undefined || (ref.bytes <= MAX_CONTENT_BYTES && REF.test(ref.ref)));
36
+ }
37
+ function eventOf(value) {
38
+ if (!value || typeof value !== "object" || Array.isArray(value))
39
+ return null;
40
+ const event = value;
41
+ if (event.version !== 1 || !validId(event.id) || !validId(event.kind) || !validId(event.rootId) || !validId(event.taskId) ||
42
+ typeof event.at !== "string" || !Number.isFinite(Date.parse(event.at)))
43
+ return null;
44
+ if ((event.parentTaskId && !validId(event.parentTaskId)) || (event.agentId && !validId(event.agentId)) ||
45
+ (event.agent && !validId(event.agent)) || (event.prompt && !validRef(event.prompt)) || (event.final && !validRef(event.final)))
46
+ return null;
47
+ if (event.skill && (!validId(event.skill.name) || typeof event.skill.source !== "string" || event.skill.source.length > 2048 || !DIGEST.test(event.skill.digest)))
48
+ return null;
49
+ return event;
50
+ }
51
+ export function parseActivityTimeline(text) {
52
+ const tasks = new Map(), refusals = [];
53
+ for (const [index, raw] of text.split("\n").entries()) {
54
+ if (!raw.trim())
55
+ continue;
56
+ let event = null;
57
+ try {
58
+ event = eventOf(JSON.parse(raw));
59
+ }
60
+ catch { /* reported below */ }
61
+ if (!event) {
62
+ refusals.push(`line ${index + 1}: invalid or unsafe timeline event`);
63
+ continue;
64
+ }
65
+ const key = `${event.rootId}\0${event.taskId}`;
66
+ let task = tasks.get(key);
67
+ if (!task) {
68
+ task = { id: event.taskId, rootId: event.rootId, parentTaskId: event.parentTaskId, startedAt: event.at, status: "active", skills: [], agents: [] };
69
+ tasks.set(key, task);
70
+ }
71
+ if (event.kind === "task_started") {
72
+ task.model = event.model;
73
+ task.thinking = event.thinking;
74
+ task.prompt = event.prompt;
75
+ task.parentTaskId = event.parentTaskId ?? task.parentTaskId;
76
+ }
77
+ if (event.kind === "task_finished") {
78
+ task.endedAt = event.at;
79
+ task.final = event.final;
80
+ task.status = event.outcome === "cancelled" ? "cancelled" : ["failed", "error"].includes(event.outcome ?? "") ? "failed" : "finished";
81
+ }
82
+ if (event.kind === "needs_you")
83
+ task.status = "needs-you";
84
+ if (event.skill) {
85
+ let skill = task.skills.find(value => value.name === event.skill.name && value.digest === event.skill.digest && value.source === event.skill.source);
86
+ if (!skill) {
87
+ skill = { ...event.skill, available: false, read: false, active: false, superseded: false };
88
+ task.skills.push(skill);
89
+ }
90
+ if (event.kind === "skill_available")
91
+ skill.available = true;
92
+ if (event.kind === "skill_read")
93
+ skill.read = true;
94
+ if (event.kind === "skill_active")
95
+ skill.active = true;
96
+ if (event.kind === "skill_finished")
97
+ skill.active = false;
98
+ if (event.kind === "skill_superseded") {
99
+ skill.superseded = true;
100
+ skill.active = false;
101
+ }
102
+ }
103
+ if (event.kind === "agent_started" && event.agentId)
104
+ task.agents.push({ id: event.agentId, parentTaskId: event.parentTaskId, agent: event.agent ?? "unknown", state: "active" });
105
+ if (event.kind === "agent_finished" && event.agentId) {
106
+ const agent = task.agents.find(value => value.id === event.agentId);
107
+ if (agent)
108
+ agent.state = event.outcome ?? "finished";
109
+ }
110
+ }
111
+ return { tasks: [...tasks.values()].sort((a, b) => a.startedAt.localeCompare(b.startedAt)), refusals };
112
+ }
113
+ function mark(status) { return status === "active" ? "●" : status === "needs-you" ? "!" : status === "failed" || status === "cancelled" ? "×" : "✓"; }
114
+ export function renderActivityTimeline(timeline, options = {}) {
115
+ const filter = options.filter ?? "everything", lines = ["PI-DADDY ACTIVITY", ""];
116
+ const tasks = timeline.tasks.filter(task => filter === "everything" || filter === "needs-you" && task.status === "needs-you" || filter === "agents" && task.agents.length > 0 || filter === "skills" && task.skills.length > 0);
117
+ for (const task of tasks) {
118
+ lines.push(`${task.parentTaskId ? " └─ " : ""}${mark(task.status)} ${task.id} ${task.status}${task.model ? ` · ${task.model}` : ""}${task.thinking ? ` · requested thinking ${task.thinking}` : ""}`);
119
+ if (filter !== "agents")
120
+ for (const skill of task.skills)
121
+ lines.push(` skill ${skill.name} · ${skill.available ? "available" : "availability unknown"}; ${skill.read ? "read" : "not observed read"}; ${skill.active ? "declared active" : "not declared active"}${skill.superseded ? "; superseded" : ""}`);
122
+ if (filter !== "skills")
123
+ for (const agent of task.agents)
124
+ lines.push(` agent ${agent.agent} · ${agent.state}${agent.parentTaskId ? ` · parent ${agent.parentTaskId}` : ""}`);
125
+ if (options.details && (task.prompt || task.final)) {
126
+ const key = activityTaskKey(task.rootId, task.id);
127
+ lines.push(` private details: p ${key} (submitted prompt) · f ${key} (final response)`);
128
+ }
129
+ }
130
+ if (options.content)
131
+ lines.push("", `PRIVATE ${options.content.field.toUpperCase()} · ${options.content.taskKey}`, options.content.text);
132
+ if (!tasks.length)
133
+ lines.push("No activity recorded yet.");
134
+ if (timeline.refusals.length)
135
+ lines.push(...timeline.refusals.map(refusal => `timeline refusal: ${refusal}`));
136
+ lines.push("", "Filters: Everything · Agents · Skills · Needs-you. Type p <root-id:task-id> or f <root-id:task-id> after d Details; shorthand task ids are refused. Read is observation; active is a declaration; neither proves compliance.");
137
+ return lines.join("\n");
138
+ }
139
+ export const defaultActivityTimelinePath = (cwd) => join(cwd, ".pi", "pi-daddy", "activity.jsonl");
140
+ export function activityIdentity(cwd, env = process.env) {
141
+ const configured = env[ENV_ACTIVITY_TIMELINE]?.trim(), transported = env[ENV_ACTIVITY_PATH]?.trim();
142
+ const path = transported ? resolve(transported) : configured && configured !== "1" && configured !== "off" && configured !== "0" ? resolve(cwd, configured) : defaultActivityTimelinePath(cwd);
143
+ return { rootId: env[ENV_ACTIVITY_ROOT]?.trim() || randomUUID(), path, ...(env[ENV_ACTIVITY_TASK]?.trim() ? { taskId: env[ENV_ACTIVITY_TASK].trim() } : {}), ...(env[ENV_ACTIVITY_PARENT_TASK]?.trim() ? { parentTaskId: env[ENV_ACTIVITY_PARENT_TASK].trim() } : {}) };
144
+ }
145
+ export class ActivityTimelineRecorder {
146
+ enabled;
147
+ contentEnabled;
148
+ path;
149
+ rootId;
150
+ taskId;
151
+ constructor(cwd, env = process.env) { const configured = env[ENV_ACTIVITY_TIMELINE]?.trim(); this.enabled = configured !== "off" && configured !== "0"; this.contentEnabled = env[ENV_ACTIVITY_CONTENT]?.trim() !== "metadata-only" && env[ENV_ACTIVITY_CONTENT]?.trim() !== "off"; const identity = activityIdentity(cwd, env); this.path = identity.path; this.rootId = identity.rootId; this.taskId = identity.taskId; }
152
+ get task() { return this.taskId; }
153
+ attach(taskId) { this.taskId = taskId; }
154
+ async start(prompt, model, thinking, parentTaskId) { if (!this.enabled)
155
+ return undefined; this.taskId = randomUUID(); await this.append("task_started", { parentTaskId, model, thinking, prompt: await this.content(prompt) }); return this.taskId; }
156
+ async childStarted(taskId, parentTaskId, agent, prompt, model, thinking) { if (!this.enabled)
157
+ return; this.taskId = taskId; await this.append("task_started", { parentTaskId, agentId: taskId, agent, model, thinking, prompt: await this.content(prompt) }); await this.append("agent_started", { parentTaskId, agentId: taskId, agent }); }
158
+ async childFinished(taskId, parentTaskId, agent, final, outcome) { if (!this.enabled)
159
+ return; this.taskId = taskId; await this.append("agent_finished", { parentTaskId, agentId: taskId, agent, outcome }); await this.finish(final, outcome); }
160
+ async finish(final, outcome = "completed") { if (this.enabled && this.taskId)
161
+ await this.append("task_finished", { outcome, ...(final === undefined ? {} : { final: await this.content(final) }) }); }
162
+ async skill(kind, skill) { if (this.taskId)
163
+ await this.append(kind, { skill }); }
164
+ async append(kind, fields) { if (!this.enabled || !this.taskId)
165
+ return; const event = { version: 1, id: randomUUID(), kind, at: new Date().toISOString(), rootId: this.rootId, taskId: this.taskId, ...fields }; const text = JSON.stringify(event); if (Buffer.byteLength(text) > MAX_EVENT_BYTES)
166
+ throw Error("activity timeline event exceeds bound"); await mkdir(dirname(this.path), { recursive: true, mode: 0o700 }); await appendFile(this.path, `${text}\n`, { mode: 0o600 }); }
167
+ async content(value) { const digest = sha(value), bytes = Buffer.byteLength(value); if (!this.contentEnabled || bytes > MAX_CONTENT_BYTES)
168
+ return { digest, bytes }; const root = join(dirname(this.path), "content"), target = join(root, digest); await mkdir(root, { recursive: true, mode: 0o700 }); try {
169
+ await readFile(target, "utf8");
170
+ }
171
+ catch {
172
+ const temporary = `${target}.${process.pid}.${randomUUID()}.tmp`;
173
+ await writeFile(temporary, value, { encoding: "utf8", mode: 0o600 });
174
+ await rename(temporary, target);
175
+ } return { digest, bytes, ref: `content/${digest}` }; }
176
+ }
177
+ export async function readActivityContent(timelinePath, reference) {
178
+ if (!validRef(reference) || !reference.ref)
179
+ throw Error("TIMELINE_REFERENCE_INVALID");
180
+ const root = resolve(dirname(timelinePath), "content"), target = resolve(dirname(timelinePath), reference.ref);
181
+ if (!target.startsWith(`${root}${sep}`) || await realpath(root) !== root)
182
+ throw Error("TIMELINE_REFERENCE_INVALID");
183
+ const handle = await open(target, constants.O_RDONLY | constants.O_NOFOLLOW | constants.O_NONBLOCK);
184
+ try {
185
+ const before = await handle.stat();
186
+ if (!before.isFile() || before.nlink !== 1 || before.size > MAX_CONTENT_BYTES)
187
+ throw Error("TIMELINE_REFERENCE_INVALID");
188
+ const value = await handle.readFile("utf8"), after = await handle.stat();
189
+ if (after.size !== before.size || Buffer.byteLength(value) !== reference.bytes || sha(value) !== reference.digest)
190
+ throw Error("TIMELINE_REFERENCE_TAMPERED");
191
+ return value;
192
+ }
193
+ finally {
194
+ await handle.close();
195
+ }
196
+ }
197
+ export async function detailForTimeline(timelinePath, taskKey, field) {
198
+ const identity = taskFromKey(taskKey);
199
+ if (!identity)
200
+ throw Error("TIMELINE_DETAIL_INVALID");
201
+ const timeline = parseActivityTimeline(await readFile(timelinePath, "utf8"));
202
+ const task = timeline.tasks.find(value => value.rootId === identity.rootId && value.id === identity.taskId);
203
+ const reference = task?.[field];
204
+ if (!reference)
205
+ throw Error("TIMELINE_DETAIL_UNAVAILABLE");
206
+ return { taskKey, field, text: await readActivityContent(timelinePath, reference) };
207
+ }
208
+ //# sourceMappingURL=activity-timeline.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"activity-timeline.js","sourceRoot":"","sources":["../src/activity-timeline.ts"],"names":[],"mappings":"AAAA,8GAA8G;AAC9G,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACrD,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACpC,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAClG,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,WAAW,CAAC;AAExD,MAAM,CAAC,MAAM,yBAAyB,GAAG,CAAU,CAAC;AACpD,MAAM,CAAC,MAAM,qBAAqB,GAAG,4BAA4B,CAAC;AAClE,MAAM,CAAC,MAAM,oBAAoB,GAAG,2BAA2B,CAAC;AAChE,uFAAuF;AACvF,MAAM,CAAC,MAAM,iBAAiB,GAAG,wBAAwB,CAAC;AAC1D,MAAM,CAAC,MAAM,iBAAiB,GAAG,wBAAwB,CAAC;AAC1D,MAAM,CAAC,MAAM,iBAAiB,GAAG,wBAAwB,CAAC;AAC1D,MAAM,CAAC,MAAM,wBAAwB,GAAG,+BAA+B,CAAC;AACxE,MAAM,eAAe,GAAG,EAAE,GAAG,IAAI,EAAE,iBAAiB,GAAG,GAAG,GAAG,IAAI,CAAC;AAClE,MAAM,MAAM,GAAG,gBAAgB,EAAE,GAAG,GAAG,yBAAyB,CAAC;AAmBjE,MAAM,GAAG,GAAG,CAAC,KAAa,EAAE,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAChF,MAAM,OAAO,GAAG,CAAC,KAAc,EAAE,EAAE,CAAC,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,KAAK,CAAC,MAAM,IAAI,GAAG,CAAC;AACzG,oGAAoG;AACpG,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,MAAc,EAAE,MAAc,EAAE,EAAE,CAAC,GAAG,kBAAkB,CAAC,MAAM,CAAC,IAAI,kBAAkB,CAAC,MAAM,CAAC,EAAE,CAAC;AACjI,SAAS,WAAW,CAAC,KAAa;IAChC,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAAC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,KAAK,CAAC,MAAM,GAAG,IAAI;QAAE,OAAO,IAAI,CAAC;IAC3F,IAAI,CAAC;QAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;QAAC,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,KAAK,eAAe,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC;QAAC,OAAO,IAAI,CAAC;IAAC,CAAC;AAC5M,CAAC;AACD,SAAS,QAAQ,CAAC,KAAc;IAC9B,MAAM,GAAG,GAAG,KAAgC,CAAC;IAC7C,OAAO,CAAC,CAAC,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,MAAM,CAAC,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,GAAG,CAAC,KAAK,IAAI,CAAC;QAC7H,CAAC,GAAG,CAAC,GAAG,KAAK,SAAS,IAAI,CAAC,GAAG,CAAC,KAAK,IAAI,iBAAiB,IAAI,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;AACrF,CAAC;AACD,SAAS,OAAO,CAAC,KAAc;IAC7B,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAC7E,MAAM,KAAK,GAAG,KAA+B,CAAC;IAC9C,IAAI,KAAK,CAAC,OAAO,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC;QACrH,OAAO,KAAK,CAAC,EAAE,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IACxF,IAAI,CAAC,KAAK,CAAC,YAAY,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAClG,CAAC,KAAK,CAAC,KAAK,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IAChJ,IAAI,KAAK,CAAC,KAAK,IAAI,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,OAAO,KAAK,CAAC,KAAK,CAAC,MAAM,KAAK,QAAQ,IAAI,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,GAAG,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IAC/K,OAAO,KAAsB,CAAC;AAChC,CAAC;AACD,MAAM,UAAU,qBAAqB,CAAC,IAAY;IAChD,MAAM,KAAK,GAAG,IAAI,GAAG,EAAwB,EAAE,QAAQ,GAAa,EAAE,CAAC;IACvE,KAAK,MAAM,CAAC,KAAK,EAAE,GAAG,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC;QACtD,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE;YAAE,SAAS;QAC1B,IAAI,KAAK,GAAyB,IAAI,CAAC;QACvC,IAAI,CAAC;YAAC,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;QAAC,CAAC;QAAC,MAAM,CAAC,CAAC,oBAAoB,CAAC,CAAC;QACxE,IAAI,CAAC,KAAK,EAAE,CAAC;YAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,KAAK,GAAG,CAAC,oCAAoC,CAAC,CAAC;YAAC,SAAS;QAAC,CAAC;QAC/F,MAAM,GAAG,GAAG,GAAG,KAAK,CAAC,MAAM,KAAK,KAAK,CAAC,MAAM,EAAE,CAAC;QAC/C,IAAI,IAAI,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAC1B,IAAI,CAAC,IAAI,EAAE,CAAC;YAAC,IAAI,GAAG,EAAE,EAAE,EAAE,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,YAAY,EAAE,KAAK,CAAC,YAAY,EAAE,SAAS,EAAE,KAAK,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;YAAC,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QAAC,CAAC;QACxL,IAAI,KAAK,CAAC,IAAI,KAAK,cAAc,EAAE,CAAC;YAAC,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC;YAAC,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC;YAAC,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC;YAAC,IAAI,CAAC,YAAY,GAAG,KAAK,CAAC,YAAY,IAAI,IAAI,CAAC,YAAY,CAAC;QAAC,CAAC;QACzL,IAAI,KAAK,CAAC,IAAI,KAAK,eAAe,EAAE,CAAC;YAAC,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC,EAAE,CAAC;YAAC,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC;YAAC,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC,OAAO,KAAK,WAAW,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC;QAAC,CAAC;QACjO,IAAI,KAAK,CAAC,IAAI,KAAK,WAAW;YAAE,IAAI,CAAC,MAAM,GAAG,WAAW,CAAC;QAC1D,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;YAChB,IAAI,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,KAAM,CAAC,KAAM,CAAC,IAAI,IAAI,KAAK,CAAC,MAAM,KAAK,KAAM,CAAC,KAAM,CAAC,MAAM,IAAI,KAAK,CAAC,MAAM,KAAK,KAAM,CAAC,KAAM,CAAC,MAAM,CAAC,CAAC;YAC3J,IAAI,CAAC,KAAK,EAAE,CAAC;gBAAC,KAAK,GAAG,EAAE,GAAG,KAAK,CAAC,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC;gBAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAAC,CAAC;YACrI,IAAI,KAAK,CAAC,IAAI,KAAK,iBAAiB;gBAAE,KAAK,CAAC,SAAS,GAAG,IAAI,CAAC;YAC7D,IAAI,KAAK,CAAC,IAAI,KAAK,YAAY;gBAAE,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC;YACnD,IAAI,KAAK,CAAC,IAAI,KAAK,cAAc;gBAAE,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC;YACvD,IAAI,KAAK,CAAC,IAAI,KAAK,gBAAgB;gBAAE,KAAK,CAAC,MAAM,GAAG,KAAK,CAAC;YAC1D,IAAI,KAAK,CAAC,IAAI,KAAK,kBAAkB,EAAE,CAAC;gBAAC,KAAK,CAAC,UAAU,GAAG,IAAI,CAAC;gBAAC,KAAK,CAAC,MAAM,GAAG,KAAK,CAAC;YAAC,CAAC;QAC3F,CAAC;QACD,IAAI,KAAK,CAAC,IAAI,KAAK,eAAe,IAAI,KAAK,CAAC,OAAO;YAAE,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,KAAK,CAAC,OAAO,EAAE,YAAY,EAAE,KAAK,CAAC,YAAY,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,IAAI,SAAS,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;QACjL,IAAI,KAAK,CAAC,IAAI,KAAK,gBAAgB,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;YAAC,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,KAAK,KAAM,CAAC,OAAO,CAAC,CAAC;YAAC,IAAI,KAAK;gBAAE,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,OAAO,IAAI,UAAU,CAAC;QAAC,CAAC;IACvL,CAAC;IACD,OAAO,EAAE,KAAK,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC;AACzG,CAAC;AACD,SAAS,IAAI,CAAC,MAA8B,IAAY,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,KAAK,WAAW,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,WAAW,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;AACtL,MAAM,UAAU,sBAAsB,CAAC,QAA0B,EAAE,UAAkI,EAAE;IACrM,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,YAAY,EAAE,KAAK,GAAG,CAAC,mBAAmB,EAAE,EAAE,CAAC,CAAC;IACjF,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,KAAK,YAAY,IAAI,MAAM,KAAK,WAAW,IAAI,IAAI,CAAC,MAAM,KAAK,WAAW,IAAI,MAAM,KAAK,QAAQ,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,IAAI,MAAM,KAAK,QAAQ,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAChO,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,KAAK,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC,EAAE,KAAK,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,yBAAyB,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACxM,IAAI,MAAM,KAAK,QAAQ;YAAE,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,MAAM;gBAAE,KAAK,CAAC,IAAI,CAAC,WAAW,KAAK,CAAC,IAAI,MAAM,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,sBAAsB,KAAK,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,mBAAmB,KAAK,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,qBAAqB,GAAG,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QAC9S,IAAI,MAAM,KAAK,QAAQ;YAAE,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,MAAM;gBAAE,KAAK,CAAC,IAAI,CAAC,WAAW,KAAK,CAAC,KAAK,MAAM,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC,aAAa,KAAK,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QAC9K,IAAI,OAAO,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;YAAC,MAAM,GAAG,GAAG,eAAe,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;YAAC,KAAK,CAAC,IAAI,CAAC,wBAAwB,GAAG,2BAA2B,GAAG,mBAAmB,CAAC,CAAC;QAAC,CAAC;IACtM,CAAC;IACD,IAAI,OAAO,CAAC,OAAO;QAAE,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,WAAW,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,WAAW,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IACzI,IAAI,CAAC,KAAK,CAAC,MAAM;QAAE,KAAK,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC;IAC3D,IAAI,QAAQ,CAAC,QAAQ,CAAC,MAAM;QAAE,KAAK,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,qBAAqB,OAAO,EAAE,CAAC,CAAC,CAAC;IAC9G,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,8NAA8N,CAAC,CAAC;IAC/O,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AACD,MAAM,CAAC,MAAM,2BAA2B,GAAG,CAAC,GAAW,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,EAAE,UAAU,EAAE,gBAAgB,CAAC,CAAC;AAC3G,MAAM,UAAU,gBAAgB,CAAC,GAAW,EAAE,MAAyB,OAAO,CAAC,GAAG;IAChF,MAAM,UAAU,GAAG,GAAG,CAAC,qBAAqB,CAAC,EAAE,IAAI,EAAE,EAAE,WAAW,GAAG,GAAG,CAAC,iBAAiB,CAAC,EAAE,IAAI,EAAE,CAAC;IACpG,MAAM,IAAI,GAAG,WAAW,CAAC,CAAC,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,UAAU,IAAI,UAAU,KAAK,GAAG,IAAI,UAAU,KAAK,KAAK,IAAI,UAAU,KAAK,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,2BAA2B,CAAC,GAAG,CAAC,CAAC;IAC/L,OAAO,EAAE,MAAM,EAAE,GAAG,CAAC,iBAAiB,CAAC,EAAE,IAAI,EAAE,IAAI,UAAU,EAAE,EAAE,IAAI,EAAE,GAAG,CAAC,GAAG,CAAC,iBAAiB,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,GAAG,CAAC,iBAAiB,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC,wBAAwB,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,GAAG,CAAC,wBAAwB,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;AAC1Q,CAAC;AACD,MAAM,OAAO,wBAAwB;IAC1B,OAAO,CAAU;IAAU,cAAc,CAAU;IAAU,IAAI,CAAS;IAAU,MAAM,CAAS;IAAS,MAAM,CAAU;IACrI,YAAY,GAAW,EAAE,MAAyB,OAAO,CAAC,GAAG,IAAI,MAAM,UAAU,GAAG,GAAG,CAAC,qBAAqB,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,OAAO,GAAG,UAAU,KAAK,KAAK,IAAI,UAAU,KAAK,GAAG,CAAC,CAAC,IAAI,CAAC,cAAc,GAAG,GAAG,CAAC,oBAAoB,CAAC,EAAE,IAAI,EAAE,KAAK,eAAe,IAAI,GAAG,CAAC,oBAAoB,CAAC,EAAE,IAAI,EAAE,KAAK,KAAK,CAAC,CAAC,MAAM,QAAQ,GAAG,gBAAgB,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;IACtb,IAAI,IAAI,KAAyB,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;IACtD,MAAM,CAAC,MAAc,IAAU,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC;IACtD,KAAK,CAAC,KAAK,CAAC,MAAc,EAAE,KAAc,EAAE,QAAiB,EAAE,YAAqB,IAAiC,IAAI,CAAC,IAAI,CAAC,OAAO;QAAE,OAAO,SAAS,CAAC,CAAC,IAAI,CAAC,MAAM,GAAG,UAAU,EAAE,CAAC,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,cAAc,EAAE,EAAE,YAAY,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;IACrT,KAAK,CAAC,YAAY,CAAC,MAAc,EAAE,YAAgC,EAAE,KAAa,EAAE,MAAc,EAAE,KAAc,EAAE,QAAiB,IAAmB,IAAI,CAAC,IAAI,CAAC,OAAO;QAAE,OAAO,CAAC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,cAAc,EAAE,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,eAAe,EAAE,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC;IAC1Z,KAAK,CAAC,aAAa,CAAC,MAAc,EAAE,YAAgC,EAAE,KAAa,EAAE,KAAa,EAAE,OAA6C,IAAmB,IAAI,CAAC,IAAI,CAAC,OAAO;QAAE,OAAO,CAAC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,gBAAgB,EAAE,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;IACjV,KAAK,CAAC,MAAM,CAAC,KAAyB,EAAE,UAAgD,WAAW,IAAmB,IAAI,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,MAAM;QAAE,MAAM,IAAI,CAAC,MAAM,CAAC,eAAe,EAAE,EAAE,OAAO,EAAE,GAAG,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAC/Q,KAAK,CAAC,KAAK,CAAC,IAA+F,EAAE,KAAoB,IAAmB,IAAI,IAAI,CAAC,MAAM;QAAE,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC;IAC1M,KAAK,CAAC,MAAM,CAAC,IAAY,EAAE,MAA4F,IAAmB,IAAI,CAAC,IAAI,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM;QAAE,OAAO,CAAC,MAAM,KAAK,GAAkB,EAAE,OAAO,EAAE,CAAC,EAAE,EAAE,EAAE,UAAU,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC,CAAC,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,eAAe;QAAE,MAAM,KAAK,CAAC,uCAAuC,CAAC,CAAC,CAAC,MAAM,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,MAAM,UAAU,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,IAAI,IAAI,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC;IAC7kB,KAAK,CAAC,OAAO,CAAC,KAAa,IAA+B,MAAM,MAAM,GAAG,GAAG,CAAC,KAAK,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,cAAc,IAAI,KAAK,GAAG,iBAAiB;QAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,MAAM,KAAK,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;QAAC,MAAM,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC;QAAC,MAAM,SAAS,GAAG,GAAG,MAAM,IAAI,OAAO,CAAC,GAAG,IAAI,UAAU,EAAE,MAAM,CAAC;QAAC,MAAM,SAAS,CAAC,SAAS,EAAE,KAAK,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QAAC,MAAM,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;IAAC,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,WAAW,MAAM,EAAE,EAAE,CAAC,CAAC,CAAC;CACrmB;AACD,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,YAAoB,EAAE,SAA2B;IACzF,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG;QAAE,MAAM,KAAK,CAAC,4BAA4B,CAAC,CAAC;IACtF,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,SAAS,CAAC,GAAG,CAAC,CAAC;IAC/G,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,GAAG,IAAI,GAAG,GAAG,EAAE,CAAC,IAAI,MAAM,QAAQ,CAAC,IAAI,CAAC,KAAK,IAAI;QAAE,MAAM,KAAK,CAAC,4BAA4B,CAAC,CAAC;IACpH,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,MAAM,EAAE,SAAS,CAAC,QAAQ,GAAG,SAAS,CAAC,UAAU,GAAG,SAAS,CAAC,UAAU,CAAC,CAAC;IACpG,IAAI,CAAC;QAAC,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC;QAAC,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,MAAM,CAAC,KAAK,KAAK,CAAC,IAAI,MAAM,CAAC,IAAI,GAAG,iBAAiB;YAAE,MAAM,KAAK,CAAC,4BAA4B,CAAC,CAAC;QAAC,MAAM,KAAK,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,KAAK,GAAG,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC;QAAC,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,KAAK,SAAS,CAAC,KAAK,IAAI,GAAG,CAAC,KAAK,CAAC,KAAK,SAAS,CAAC,MAAM;YAAE,MAAM,KAAK,CAAC,6BAA6B,CAAC,CAAC;QAAC,OAAO,KAAK,CAAC;IAAC,CAAC;YAAS,CAAC;QAAC,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;IAAC,CAAC;AAChc,CAAC;AACD,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,YAAoB,EAAE,OAAe,EAAE,KAAyB;IACtG,MAAM,QAAQ,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC;IAAC,IAAI,CAAC,QAAQ;QAAE,MAAM,KAAK,CAAC,yBAAyB,CAAC,CAAC;IAC7F,MAAM,QAAQ,GAAG,qBAAqB,CAAC,MAAM,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC,CAAC;IAC7E,MAAM,IAAI,GAAG,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,MAAM,KAAK,QAAQ,CAAC,MAAM,IAAI,KAAK,CAAC,EAAE,KAAK,QAAQ,CAAC,MAAM,CAAC,CAAC;IAC5G,MAAM,SAAS,GAAG,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC;IAAC,IAAI,CAAC,SAAS;QAAE,MAAM,KAAK,CAAC,6BAA6B,CAAC,CAAC;IAC5F,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC,YAAY,EAAE,SAAS,CAAC,EAAE,CAAC;AACtF,CAAC"}
@@ -1,6 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import { type DashboardConnection } from "./dashboard-host-transport.ts";
3
3
  export { ENV_DASHBOARD_HOST_SOCKET } from "./dashboard-host-transport.ts";
4
+ import { type TimelineFilter } from "./activity-timeline.ts";
4
5
  import { createDailyViewReader, type DailyViewOptions } from "./daily-view.ts";
5
6
  import { createDashboardMenu } from "./dashboard-menu.ts";
6
7
  import { type DebriefPresenter } from "./debrief.ts";
@@ -22,6 +23,11 @@ export interface DashboardFrameOptions {
22
23
  width?: number;
23
24
  details?: boolean;
24
25
  history?: boolean;
26
+ filter?: TimelineFilter;
27
+ activityDetail?: {
28
+ taskKey: string;
29
+ field: "prompt" | "final";
30
+ };
25
31
  now?: Date;
26
32
  dailyView?: DailyViewOptions;
27
33
  dailyReader?: ReturnType<typeof createDailyViewReader>;
@@ -1 +1 @@
1
- {"version":3,"file":"dashboard-cli.d.ts","sourceRoot":"","sources":["../src/dashboard-cli.ts"],"names":[],"mappings":";AACA,OAAO,EAA0E,KAAK,mBAAmB,EAAE,MAAM,+BAA+B,CAAC;AAEjJ,OAAO,EAAE,yBAAyB,EAAE,MAAM,+BAA+B,CAAC;AAQ1E,OAAO,EAAE,qBAAqB,EAAoC,KAAK,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAGjH,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAI1D,OAAO,EAAsB,KAAK,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAGzE,eAAO,MAAM,mBAAmB,6BAA6B,CAAC;AAC9D,OAAO,EAAE,aAAa,IAAI,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAE9E,eAAO,MAAM,iBAAiB,gCAAgC,CAAC;AAC/D,eAAO,MAAM,cAAc,yBAAyB,CAAC;AACrD,eAAO,MAAM,mBAAmB,2BAA2B,CAAC;AAQ5D,eAAO,MAAM,0BAA0B,EAAG,CAAU,CAAC;AACrD,eAAO,MAAM,oBAAoB,oBAAoB,CAAC;AACtD,eAAO,MAAM,sBAAsB,gCAAgC,CAAC;AACpE,eAAO,MAAM,iBAAiB,2BAA2B,CAAC;AAC1D,eAAO,MAAM,oBAAoB,MAAM,CAAC;AAExC,MAAM,WAAW,qBAAqB;IACpC,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,GAAG,CAAC,EAAE,IAAI,CAAC;IACX,SAAS,CAAC,EAAE,gBAAgB,CAAC;IAC7B,WAAW,CAAC,EAAE,UAAU,CAAC,OAAO,qBAAqB,CAAC,CAAC;IACvD,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,OAAO,CAAC,EAAE,gBAAgB,CAAC;IAC3B,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,SAAS,CAAC,EAAE,mBAAmB,CAAC;IAChC,UAAU,CAAC,EAAE,UAAU,CAAC,OAAO,mBAAmB,CAAC,CAAC;CACrD;AACD,wBAAsB,mBAAmB,CAAC,IAAI,EAAC,mBAAmB,EAAC,IAAI,EAAC,MAAM;;;;;;GAM7E;AAED,8GAA8G;AAC9G,wBAAgB,uBAAuB,CAAC,OAAO,EAAC,MAAM,EAAC,OAAO,EAAC,OAAO,GAAE,MAAM,CAW7E;AAiCD,wBAAsB,cAAc,CAAC,OAAO,EAAE,qBAAqB,GAAG,OAAO,CAAC,MAAM,CAAC,CAwDpF;AA2CD,wBAAsB,YAAY,CAAC,IAAI,WAAwB,EAAE,GAAG,GAAE,MAAM,CAAC,UAAwB,EAAE,IAAI,GAAE;IAAE,OAAO,CAAC,EAAE,gBAAgB,CAAC;IAAC,SAAS,CAAC,EAAC,mBAAmB,CAAA;CAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CA2F/L"}
1
+ {"version":3,"file":"dashboard-cli.d.ts","sourceRoot":"","sources":["../src/dashboard-cli.ts"],"names":[],"mappings":";AACA,OAAO,EAA0E,KAAK,mBAAmB,EAAE,MAAM,+BAA+B,CAAC;AAEjJ,OAAO,EAAE,yBAAyB,EAAE,MAAM,+BAA+B,CAAC;AAO1E,OAAO,EAAiG,KAAK,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAE5J,OAAO,EAAE,qBAAqB,EAAoC,KAAK,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAGjH,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAI1D,OAAO,EAAsB,KAAK,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAGzE,eAAO,MAAM,mBAAmB,6BAA6B,CAAC;AAC9D,OAAO,EAAE,aAAa,IAAI,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAE9E,eAAO,MAAM,iBAAiB,gCAAgC,CAAC;AAC/D,eAAO,MAAM,cAAc,yBAAyB,CAAC;AACrD,eAAO,MAAM,mBAAmB,2BAA2B,CAAC;AAQ5D,eAAO,MAAM,0BAA0B,EAAG,CAAU,CAAC;AACrD,eAAO,MAAM,oBAAoB,oBAAoB,CAAC;AACtD,eAAO,MAAM,sBAAsB,gCAAgC,CAAC;AACpE,eAAO,MAAM,iBAAiB,2BAA2B,CAAC;AAC1D,eAAO,MAAM,oBAAoB,MAAM,CAAC;AAExC,MAAM,WAAW,qBAAqB;IACpC,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,cAAc,CAAC;IACxB,cAAc,CAAC,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,QAAQ,GAAG,OAAO,CAAA;KAAE,CAAC;IAChE,GAAG,CAAC,EAAE,IAAI,CAAC;IACX,SAAS,CAAC,EAAE,gBAAgB,CAAC;IAC7B,WAAW,CAAC,EAAE,UAAU,CAAC,OAAO,qBAAqB,CAAC,CAAC;IACvD,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,OAAO,CAAC,EAAE,gBAAgB,CAAC;IAC3B,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,SAAS,CAAC,EAAE,mBAAmB,CAAC;IAChC,UAAU,CAAC,EAAE,UAAU,CAAC,OAAO,mBAAmB,CAAC,CAAC;CACrD;AACD,wBAAsB,mBAAmB,CAAC,IAAI,EAAC,mBAAmB,EAAC,IAAI,EAAC,MAAM;;;;;;GAM7E;AAED,8GAA8G;AAC9G,wBAAgB,uBAAuB,CAAC,OAAO,EAAC,MAAM,EAAC,OAAO,EAAC,OAAO,GAAE,MAAM,CAW7E;AAiCD,wBAAsB,cAAc,CAAC,OAAO,EAAE,qBAAqB,GAAG,OAAO,CAAC,MAAM,CAAC,CA8EpF;AA2CD,wBAAsB,YAAY,CAAC,IAAI,WAAwB,EAAE,GAAG,GAAE,MAAM,CAAC,UAAwB,EAAE,IAAI,GAAE;IAAE,OAAO,CAAC,EAAE,gBAAgB,CAAC;IAAC,SAAS,CAAC,EAAC,mBAAmB,CAAA;CAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CA2F/L"}
@@ -8,6 +8,7 @@ import { resolve } from "node:path";
8
8
  import { pathToFileURL } from "node:url";
9
9
  import { parseDashboardLedger } from "./dashboard-projection.js";
10
10
  import { renderDashboard } from "./dashboard-render.js";
11
+ import { defaultActivityTimelinePath, detailForTimeline, parseActivityTimeline, renderActivityTimeline } from "./activity-timeline.js";
11
12
  import { createDashboardDisplayControls } from "./dashboard-display-controls.js";
12
13
  import { createDailyViewReader, isDailyViewReader, readDailyView } from "./daily-view.js";
13
14
  import { renderDailyView } from "./daily-view-render.js";
@@ -133,9 +134,31 @@ export async function dashboardFrame(options) {
133
134
  return "PI-DADDY — DAILY VIEW UNAVAILABLE\nInvalid or unavailable read-only input. No previous acceptance or continuity was substituted.";
134
135
  }
135
136
  }
136
- if (!options.ledgerPath)
137
- return setupFrame(options.cwd);
138
- const ledgerPath = resolve(options.cwd, options.ledgerPath);
137
+ // Timeline is the default local activity surface. Retain the existing setup frame until a real
138
+ // extension-owned timeline exists, so opening a plugin before Pi has run remains explanatory.
139
+ const configuredPath = options.ledgerPath ?? defaultActivityTimelinePath(options.cwd);
140
+ if (!options.ledgerPath) {
141
+ try {
142
+ const activityPath = resolve(options.cwd, configuredPath);
143
+ const activity = await readFile(activityPath, "utf8");
144
+ const timeline = parseActivityTimeline(activity);
145
+ let content;
146
+ if (options.activityDetail)
147
+ try {
148
+ content = await detailForTimeline(activityPath, options.activityDetail.taskKey, options.activityDetail.field);
149
+ }
150
+ catch (error) {
151
+ return `PI-DADDY — ACTIVITY DETAIL UNAVAILABLE\n${error instanceof Error ? error.message : String(error)}`;
152
+ }
153
+ return renderActivityTimeline(timeline, { details: options.details, filter: options.filter, content });
154
+ }
155
+ catch (error) {
156
+ if (error.code === "ENOENT")
157
+ return setupFrame(options.cwd);
158
+ return "PI-DADDY — ACTIVITY UNAVAILABLE\nTimeline could not be read; no substitute view was shown.";
159
+ }
160
+ }
161
+ const ledgerPath = resolve(options.cwd, configuredPath);
139
162
  let text = "";
140
163
  let waiting = false;
141
164
  try {
@@ -154,7 +177,20 @@ export async function dashboardFrame(options) {
154
177
  ].join("\n");
155
178
  }
156
179
  }
157
- const rendered = renderDashboard(parseDashboardLedger(text, { now: options.now }), {
180
+ let timeline;
181
+ if (text.trimStart().startsWith('{"version":1')) {
182
+ const activity = parseActivityTimeline(text);
183
+ let content;
184
+ if (options.activityDetail)
185
+ try {
186
+ content = await detailForTimeline(ledgerPath, options.activityDetail.taskKey, options.activityDetail.field);
187
+ }
188
+ catch (error) {
189
+ return `PI-DADDY — ACTIVITY DETAIL UNAVAILABLE\n${error instanceof Error ? error.message : String(error)}`;
190
+ }
191
+ timeline = renderActivityTimeline(activity, { details: options.details, filter: options.filter, content });
192
+ }
193
+ const rendered = timeline ?? renderDashboard(parseDashboardLedger(text, { now: options.now }), {
158
194
  color: options.color,
159
195
  width: options.width,
160
196
  details: options.details,
@@ -235,7 +271,7 @@ export async function runDashboard(argv = process.argv.slice(2), env = process.e
235
271
  }
236
272
  const dailyReader = createDailyViewReader();
237
273
  const actionMenu = createDashboardMenu();
238
- const display = createDashboardDisplayControls(cli.details, Boolean(ledgerPath && !connected && !debrief && !cli.debriefJson && !dailyView));
274
+ const display = createDashboardDisplayControls(cli.details, Boolean(!connected && !debrief && !cli.debriefJson && !dailyView));
239
275
  let previous = "";
240
276
  let feedback = "";
241
277
  let input = null;