@a-t-h-i/bot-lobby 0.6.4 → 0.6.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.
Files changed (44) hide show
  1. package/README.md +150 -12
  2. package/package.json +12 -3
  3. package/prompts/backend.md +3 -1
  4. package/prompts/designer.md +24 -1
  5. package/prompts/global.md +18 -0
  6. package/prompts/master.md +122 -20
  7. package/prompts/quickfix.md +16 -3
  8. package/prompts/worker.md +7 -2
  9. package/src/agents/backend.ts +2 -2
  10. package/src/agents/designer.ts +2 -2
  11. package/src/ask/dialog.ts +11 -1
  12. package/src/classifier/triage.ts +24 -7
  13. package/src/index.ts +4 -1
  14. package/src/lobby/feed.ts +7 -2
  15. package/src/lobby/keys.ts +0 -1
  16. package/src/lobby/quickfix.ts +29 -3
  17. package/src/lobby/runtime.ts +29 -26
  18. package/src/lobby/tabs/home.ts +6 -42
  19. package/src/lobby/tabs/quickfix.ts +1 -1
  20. package/src/lobby/tabs/tasks.ts +3 -2
  21. package/src/lobby/view.ts +18 -23
  22. package/src/master/decisions.ts +10 -2
  23. package/src/pi/activity.ts +1 -33
  24. package/src/pi/commands.ts +22 -11
  25. package/src/pi/events.ts +3 -17
  26. package/src/pi/plan-checklist.ts +305 -0
  27. package/src/pi/route.ts +180 -0
  28. package/src/pi/run-summary.ts +12 -3
  29. package/src/pi/settings-ui.ts +2 -2
  30. package/src/pi/start-task.ts +51 -5
  31. package/src/pi/tools.ts +13 -7
  32. package/src/pi/ui.ts +18 -284
  33. package/src/roles/worker.ts +11 -3
  34. package/src/schemas/configuration.ts +19 -6
  35. package/src/schemas/task.ts +31 -0
  36. package/src/workflow/brief.ts +59 -0
  37. package/src/workflow/track.ts +436 -0
  38. package/src/workflow/workflow.ts +151 -10
  39. package/src/pi/expressions.ts +0 -169
  40. package/src/pi/kaomoji.ts +0 -227
  41. package/src/pi/mascot-art.ts +0 -359
  42. package/src/pi/zen-large.ts +0 -699
  43. package/src/pi/zen-metrics.ts +0 -130
  44. package/src/pi/zen.ts +0 -659
@@ -1,130 +0,0 @@
1
- /**
2
- * Derived zen-scene metrics: plan progress and per-slot status, live activity
3
- * word and per-agent elapsed.
4
- * Pure by construction: the only clock input is the `now` argument, and nothing
5
- * here reads the wall clock, a random source or the environment. Percentages
6
- * are plan-derived measurements.
7
- */
8
- import type { AgentRun } from "../schemas/findings.ts";
9
- import type { Task } from "../schemas/task.ts";
10
- import { SLOT_IDS, SLOT_LABELS, type SlotId, type SlotState } from "./mascot-art.ts";
11
- import { formatDuration, planChecklist } from "./zen.ts";
12
- import { QUIET_MS, quietFor, slotOf } from "./run-summary.ts";
13
- import type { Situation } from "./kaomoji.ts";
14
- import { formatMinutes } from "../state/budget.ts";
15
-
16
- /** A task's time budget as the scene shows it: work time spent of the whole. */
17
- export interface SceneTime {
18
- usedMs: number;
19
- totalMs: number;
20
- }
21
-
22
- export type { SlotId, SlotState };
23
-
24
- /** One agent column: its latest run's status, live activity word and elapsed label. */
25
- export interface SlotView {
26
- id: SlotId;
27
- label: string;
28
- status: SlotState;
29
- /** The run's one-word tool activity, when the backend reported one. */
30
- activity?: string;
31
- /** "—" without a run, live since `startedAt` while running, fixed once terminal. */
32
- elapsedLabel: string;
33
- /** Something about a working agent worth flagging in its status row. */
34
- flag?: SlotFlag;
35
- /** The run was asked to wrap up early. */
36
- wrappedUp?: boolean;
37
- /** A file was just handed to this agent by the file desk. */
38
- handover?: boolean;
39
- }
40
-
41
- /** Status-row flags for a working agent, in priority order: waiting on a file, gone quiet, retrying. */
42
- export type SlotFlag = { kind: "waiting" } | { kind: "quiet"; ms: number } | { kind: "retry" };
43
-
44
- function slotFlag(run: AgentRun | undefined, now: number): SlotFlag | undefined {
45
- if (!run || run.status !== "running") return undefined;
46
- if (run.waitingFor) return { kind: "waiting" };
47
- const quiet = quietFor(run, now);
48
- if (quiet >= QUIET_MS) return { kind: "quiet", ms: quiet };
49
- if (run.noteKind === "warning" && run.note && /retry/.test(run.note)) return { kind: "retry" };
50
- return undefined;
51
- }
52
-
53
- export interface SceneMetrics {
54
- done: number;
55
- total: number;
56
- elapsedLabel: string;
57
- slots: SlotView[];
58
- }
59
-
60
- /** Latest run state per slot: running -> working, success -> done, everything else -> failed. */
61
- export function runStatus(status: AgentRun["status"]): SlotState {
62
- if (status === "running") return "working";
63
- return status === "success" ? "done" : "failed";
64
- }
65
-
66
-
67
- function latestRunFor(runs: AgentRun[], id: SlotId): AgentRun | undefined {
68
- let latest: AgentRun | undefined;
69
- for (const run of runs) {
70
- if (slotOf(run) !== id) continue;
71
- if (!latest || Date.parse(run.startedAt) >= Date.parse(latest.startedAt)) latest = run;
72
- }
73
- return latest;
74
- }
75
-
76
- /** A run's duration label from the injected clock; a malformed timestamp reads "0s". */
77
- function runElapsedLabel(run: AgentRun | undefined, now: number): string {
78
- if (!run) return "—";
79
- const end = run.finishedAt ? Date.parse(run.finishedAt) : now;
80
- const elapsed = end - Date.parse(run.startedAt);
81
- // Under a time budget: minutes spent of the minutes given (`12/30m`).
82
- if (run.allotMs) return `${Math.max(0, Math.floor(elapsed / 60_000))}/${Math.round((run.allotMs + (run.extendedMs ?? 0)) / 60_000)}m`;
83
- return formatDuration(elapsed);
84
- }
85
-
86
- function slotView(id: SlotId, runs: AgentRun[], now: number): SlotView {
87
- const run = latestRunFor(runs, id);
88
- const status: SlotState = run ? runStatus(run.status) : "idle";
89
- const flag = slotFlag(run, now);
90
- return {
91
- id,
92
- label: SLOT_LABELS[id],
93
- status,
94
- activity: run?.activity,
95
- elapsedLabel: runElapsedLabel(run, now),
96
- ...(flag ? { flag } : {}),
97
- ...(run?.wrappedUp ? { wrappedUp: true } : {}),
98
- ...(run?.status === "running" && run.note?.startsWith("got ") ? { handover: true } : {}),
99
- };
100
- }
101
-
102
- export function sceneMetrics(task: Task, runs: AgentRun[], now: number, time?: SceneTime): SceneMetrics {
103
- const checklist = planChecklist(task.plan ?? "", runs);
104
- const total = checklist.length;
105
- const done = checklist.filter((step) => step.status === "done").length;
106
- const summary = { done, total };
107
- const created = Date.parse(task.createdAt);
108
- const elapsed = Number.isFinite(created) ? Math.max(0, now - created) : 0;
109
- return {
110
- ...summary,
111
- elapsedLabel: time ? `${formatMinutes(time.usedMs)} of ${formatMinutes(time.totalMs)}` : formatDuration(elapsed),
112
- slots: SLOT_IDS.map((id) => slotView(id, runs, now)),
113
- };
114
- }
115
-
116
- /** Each slot's situation for its face: status, activity and flags (see kaomoji.ts). */
117
- export function slotSituation(slot: SlotView): Situation {
118
- return {
119
- status: slot.status,
120
- ...(slot.activity ? { activity: slot.activity } : {}),
121
- ...(slot.flag ? { flag: slot.flag.kind } : {}),
122
- ...(slot.wrappedUp ? { wrappedUp: true } : {}),
123
- ...(slot.handover ? { handover: true } : {}),
124
- };
125
- }
126
-
127
- /** Per-slot situations straight from runs, for the widget's reaction triggers. */
128
- export function slotSituations(runs: AgentRun[], now: number): Record<SlotId, Situation> {
129
- return Object.fromEntries(SLOT_IDS.map((id) => [id, slotSituation(slotView(id, runs, now))])) as Record<SlotId, Situation>;
130
- }