@staix/agent-hub 0.12.26 → 0.12.28
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 +13 -0
- package/README.md +3 -3
- package/docs/agent-notes/bus.md +1 -0
- package/docs/agent-notes/tests.md +1 -0
- package/docs/operations.md +119 -27
- package/docs/quickstart.md +1 -1
- package/docs/security.md +34 -6
- package/docs/specs/2026-09-19-agent-hub-design.md +111 -27
- package/docs/specs/2026-10-12-office-view-design.md +55 -11
- package/docs/verification/2026-10-15-0.12.27.md +31 -0
- package/docs/verification/assets/391-pet-window-spike.png +0 -0
- package/docs/verified.json +11 -11
- package/package.json +3 -1
- package/plugins/agent-hub/.claude-plugin/plugin.json +1 -1
- package/plugins/agent-hub/server.js +26 -5
- package/src/adapters/claude-channel.ts +26 -4
- package/src/adapters/pi.ts +12 -10
- package/src/cli/help.ts +2 -1
- package/src/cli/identity.ts +2 -0
- package/src/cli/main.ts +21 -6
- package/src/cli/pet-config.ts +1 -1
- package/src/cli/preview.ts +7 -1
- package/src/hub/bus.ts +9 -0
- package/src/hub/daemon.ts +30 -7
- package/src/hub/ui.ts +1 -3
- package/src/pet/config.ts +42 -5
- package/src/pet/window.html +114 -0
- package/src/pet/window.jxa.js +122 -0
- package/src/pet/window.ts +154 -0
- package/src/pi/session.ts +28 -0
- package/src/pi/tool-receipts.ts +1 -0
- package/src/ui/index.html +318 -129
- package/src/ui/office-model.ts +12 -12
package/src/ui/office-model.ts
CHANGED
|
@@ -81,7 +81,7 @@ export interface OfficeCard {
|
|
|
81
81
|
rework: boolean;
|
|
82
82
|
/** The task's check is running; the card stays at its owner's desk. */
|
|
83
83
|
checking: boolean;
|
|
84
|
-
/** Visible text: "#id
|
|
84
|
+
/** Visible text: "#id public title". */
|
|
85
85
|
label: string;
|
|
86
86
|
/** Accessible name: "#id class: public title (state)", plus waiting/rework/review marks. */
|
|
87
87
|
name: string;
|
|
@@ -182,8 +182,9 @@ export function officeModel(snapshot: OfficeSnapshotInput, previous: OfficeScene
|
|
|
182
182
|
const GLYPHS: Record<string, string> = { idle: "○", busy: "●", offline: "×", paused: "‖", waiting: "⚑", unknown: "?" };
|
|
183
183
|
const LABELS: Record<string, string> = { idle: "idle", busy: "busy", offline: "offline", paused: "paused", waiting: "waiting on approval" };
|
|
184
184
|
const DESK_CAP = 12, ROOM_CARDS = 8, DESK_CARDS = 3;
|
|
185
|
-
const DESK_W = 10, DESK_H =
|
|
186
|
-
const ROOM_W = 22, ROOM_H =
|
|
185
|
+
const DESK_W = 10, DESK_H = 20, DESK_DX = 12, DESK_DY = 22, DESK_COLS = 4, DESK_TOP = 3;
|
|
186
|
+
const ROOM_W = 22, ROOM_H = 29, ROOM_DX = 23, ROOM_DY = 30;
|
|
187
|
+
const ROOM_CARD_H = 7 / 3, ROOM_CARD_GAP = 0.5;
|
|
187
188
|
const ARC_MS = 10_000, LATCH_MS = 3_000, SETTLE_GAP_MS = 3_000, SETTLE_MAX_MOVES = 6, ARC_CAP = 12, ALERT_CAP = 12;
|
|
188
189
|
const text = (value: unknown) => typeof value === "string" ? value : "";
|
|
189
190
|
const num = (value: unknown) => typeof value === "number" && Number.isFinite(value) ? value : 0;
|
|
@@ -270,7 +271,7 @@ export function officeModel(snapshot: OfficeSnapshotInput, previous: OfficeScene
|
|
|
270
271
|
if (rework) name += ", rework";
|
|
271
272
|
if (checking) name += ", check running";
|
|
272
273
|
if (state === "in_review") name += `, ${owner || "unassigned"} reviewed by ${reviewer || "unassigned"}`;
|
|
273
|
-
return { id: task.id, taskClass, state, owner, reviewer, waiting, rework, checking, label: `#${task.id} ${
|
|
274
|
+
return { id: task.id, taskClass, state, owner, reviewer, waiting, rework, checking, label: `#${task.id} ${text(task.title)}`, name, x, y, w, h };
|
|
274
275
|
};
|
|
275
276
|
|
|
276
277
|
const desks: OfficeDesk[] = shownIds.map((id) => {
|
|
@@ -317,7 +318,7 @@ export function officeModel(snapshot: OfficeSnapshotInput, previous: OfficeScene
|
|
|
317
318
|
tray: { queued: num(peer.queued), important: num(peer.queuedImportant), heldBy: text(peer.heldBy), needsReview: num(peer.needsReview) },
|
|
318
319
|
mode: text(peer.permissionMode), bubble, breakNote, breakResetsAt,
|
|
319
320
|
finishing,
|
|
320
|
-
cards: shown.map((task, index) => card(task, x + 0.8, y +
|
|
321
|
+
cards: shown.map((task, index) => card(task, x + 0.8, y + 8.5 + index * 2.5, DESK_W - 1.6, 2)),
|
|
321
322
|
extraCards: work.length - shown.length,
|
|
322
323
|
};
|
|
323
324
|
});
|
|
@@ -325,18 +326,18 @@ export function officeModel(snapshot: OfficeSnapshotInput, previous: OfficeScene
|
|
|
325
326
|
const desksBottom = Math.max(0, ...desks.map(desk => desk.y + desk.h));
|
|
326
327
|
const roomsY = desksBottom ? desksBottom + 2 : 0;
|
|
327
328
|
const roomDefs = [
|
|
328
|
-
{ id: "todo", label: "To
|
|
329
|
+
{ id: "todo", label: "To do", filterState: "proposed", list: todo, count: counts.proposed + counts.waiting },
|
|
329
330
|
{ id: "work", label: "Work floor", filterState: "work", list: workUnplaced, count: counts.in_progress + counts.changes_requested },
|
|
330
331
|
{ id: "review", label: "Review", filterState: "in_review", list: review, count: counts.in_review },
|
|
331
|
-
{ id: "done", label: "Done
|
|
332
|
+
{ id: "done", label: "Done", filterState: "", list: [] as OfficeTaskInput[], count: counts.approved },
|
|
332
333
|
];
|
|
333
334
|
const rooms: OfficeRoom[] = roomDefs.map((def, index) => {
|
|
334
335
|
const x = (index % cols) * ROOM_DX;
|
|
335
336
|
const y = roomsY + Math.floor(index / cols) * ROOM_DY;
|
|
336
337
|
return {
|
|
337
338
|
id: def.id, label: def.label, filterState: def.filterState, count: def.count,
|
|
338
|
-
//
|
|
339
|
-
cards: def.list.slice(0, ROOM_CARDS).map((task, row) => card(task, x + 1
|
|
339
|
+
// One column at 12 px per unit: 28 px cards, 6 px gaps, eight cards at most.
|
|
340
|
+
cards: def.list.slice(0, ROOM_CARDS).map((task, row) => card(task, x + 1, y + 3.4 + row * (ROOM_CARD_H + ROOM_CARD_GAP), ROOM_W - 2, ROOM_CARD_H)),
|
|
340
341
|
overflow: Math.max(0, def.list.length - ROOM_CARDS),
|
|
341
342
|
x, y, w: ROOM_W, h: ROOM_H,
|
|
342
343
|
};
|
|
@@ -411,7 +412,6 @@ export function officeModel(snapshot: OfficeSnapshotInput, previous: OfficeScene
|
|
|
411
412
|
const settle = !previous ? true : moves === 0 ? previous.settle : now - previous.at > SETTLE_GAP_MS || moves > SETTLE_MAX_MOVES;
|
|
412
413
|
const at = !previous || moves > 0 ? now : previous.at;
|
|
413
414
|
|
|
414
|
-
const roomRows = Math.ceil(rooms.length / cols);
|
|
415
415
|
const desksWidth = Math.max(0, ...desks.map(desk => desk.x + desk.w));
|
|
416
416
|
// Phase 3 warning lines: validated down to the three kinds and their id lists; nothing else is copied.
|
|
417
417
|
const links: OfficeLink[] = [];
|
|
@@ -431,8 +431,8 @@ export function officeModel(snapshot: OfficeSnapshotInput, previous: OfficeScene
|
|
|
431
431
|
}
|
|
432
432
|
return {
|
|
433
433
|
cols,
|
|
434
|
-
width: Math.max(desksWidth,
|
|
435
|
-
height:
|
|
434
|
+
width: Math.max(desksWidth, ...rooms.map(room => room.x + room.w), 1),
|
|
435
|
+
height: Math.max(desksBottom, ...rooms.map(room => room.y + room.h), 1),
|
|
436
436
|
desks, extraPeers, rooms, counts, transitions, slots, placed,
|
|
437
437
|
links,
|
|
438
438
|
arcs: keptArcs, alerts: keptAlerts, latched, settle, at, eventTime, lastSeq,
|