toolroll 0.9.46 → 0.9.47

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 CHANGED
@@ -1,5 +1,20 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.9.47 — 2026-10-07
4
+
5
+ - **Live tasks.** Task pages update live and show who else is viewing.
6
+ - **Last activity.** Running tasks say what the agent did last and when
7
+ ("Ran the tests · 40 s ago"). After 5 minutes of silence they turn amber,
8
+ and they say "Worker offline" when it is.
9
+ - **Flow cards** show their task's state: "Building · step 3 of 6",
10
+ "Stuck: …", "Waiting on you".
11
+ - **Teammates.** People limited to some projects now get live flows and
12
+ presence.
13
+ - **Refresh.** The task list, task pages and home refresh on their own,
14
+ with or without the chat open.
15
+ - **One badge.** The Needs-you count is the same everywhere, and says which
16
+ projects it covers.
17
+
3
18
  ## 0.9.46 — 2026-10-07
4
19
 
5
20
  - **Tokens from the terminal.** `toolroll tokens create|list|revoke|rotate`.
@@ -0,0 +1,26 @@
1
+ /**
2
+ * What a running agent did last, in one line (live tasks): "Ran a command ·
3
+ * 40 s ago". Pure and shared: the server sends the facts, and each page words
4
+ * them against its own clock, so the age keeps counting between reads.
5
+ *
6
+ * After five minutes with no word the line turns amber and says so; a worker
7
+ * whose heartbeat stopped says that instead, because a quiet agent and a
8
+ * machine that went away need different help.
9
+ */
10
+ /** The facts behind the line: our own words for the last thing done (never a tool's arguments), when, and whether
11
+ * the worker running it still answers. */
12
+ export type RunActivity = {
13
+ what: string;
14
+ at: string;
15
+ worker: "online" | "offline";
16
+ };
17
+ export declare const QUIET_AFTER_MS: number;
18
+ /** The words for each fixed activity kind (live.ts's vocabulary) and for a progress checkpoint. */
19
+ export declare const ACTIVITY_WORDS: Readonly<Record<string, string>>;
20
+ /** "just now", "40 s ago", "3 min ago", "2 h ago". */
21
+ export declare function agoWords(ms: number): string;
22
+ /** The line itself, and whether it is quiet (amber): silent five minutes or more, or the worker is offline. */
23
+ export declare function activityLine(activity: RunActivity, now: number): {
24
+ text: string;
25
+ quiet: boolean;
26
+ };
@@ -0,0 +1,47 @@
1
+ /**
2
+ * What a running agent did last, in one line (live tasks): "Ran a command ·
3
+ * 40 s ago". Pure and shared: the server sends the facts, and each page words
4
+ * them against its own clock, so the age keeps counting between reads.
5
+ *
6
+ * After five minutes with no word the line turns amber and says so; a worker
7
+ * whose heartbeat stopped says that instead, because a quiet agent and a
8
+ * machine that went away need different help.
9
+ */
10
+ export const QUIET_AFTER_MS = 5 * 60_000;
11
+ /** The words for each fixed activity kind (live.ts's vocabulary) and for a progress checkpoint. */
12
+ export const ACTIVITY_WORDS = {
13
+ session: "Started work",
14
+ message: "Wrote an update",
15
+ edit: "Edited files",
16
+ command: "Ran a command",
17
+ read: "Read the code",
18
+ search: "Searched the code",
19
+ lookup: "Looked something up",
20
+ plan: "Updated its plan",
21
+ delegate: "Handed a step to a helper",
22
+ tool: "Used a tool",
23
+ progress: "Reported progress",
24
+ started: "Started",
25
+ };
26
+ /** "just now", "40 s ago", "3 min ago", "2 h ago". */
27
+ export function agoWords(ms) {
28
+ const seconds = Math.max(0, Math.floor(ms / 1000));
29
+ if (seconds < 10)
30
+ return "just now";
31
+ if (seconds < 60)
32
+ return `${seconds} s ago`;
33
+ const minutes = Math.floor(seconds / 60);
34
+ if (minutes < 60)
35
+ return `${minutes} min ago`;
36
+ return `${Math.floor(minutes / 60)} h ago`;
37
+ }
38
+ /** The line itself, and whether it is quiet (amber): silent five minutes or more, or the worker is offline. */
39
+ export function activityLine(activity, now) {
40
+ const at = Date.parse(activity.at);
41
+ const since = Number.isNaN(at) ? 0 : Math.max(0, now - at);
42
+ if (activity.worker === "offline")
43
+ return { text: `Worker offline · last word ${agoWords(since)}`, quiet: true };
44
+ if (since >= QUIET_AFTER_MS)
45
+ return { text: `No word for ${Math.floor(since / 60_000)} min`, quiet: true };
46
+ return { text: `${activity.what} · ${agoWords(since)}`, quiet: false };
47
+ }