@songsid/agend 2.3.2-beta.9 → 2.3.3-beta.1
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 +6 -0
- package/README.zh-TW.md +6 -0
- package/dist/agent-cli-instructions.md +2 -2
- package/dist/agent-cli.js +48 -0
- package/dist/agent-cli.js.map +1 -1
- package/dist/agent-endpoint.js +6 -0
- package/dist/agent-endpoint.js.map +1 -1
- package/dist/agent-whats-new.d.ts +21 -0
- package/dist/agent-whats-new.js +53 -21
- package/dist/agent-whats-new.js.map +1 -1
- package/dist/auth-api.js +2 -0
- package/dist/auth-api.js.map +1 -1
- package/dist/backend/claude-code.d.ts +13 -1
- package/dist/backend/claude-code.js +43 -2
- package/dist/backend/claude-code.js.map +1 -1
- package/dist/backend/codex-session-lookup.d.ts +15 -0
- package/dist/backend/codex-session-lookup.js +58 -0
- package/dist/backend/codex-session-lookup.js.map +1 -1
- package/dist/backend/codex.js +15 -4
- package/dist/backend/codex.js.map +1 -1
- package/dist/backend/kiro-classic-archive.d.ts +57 -0
- package/dist/backend/kiro-classic-archive.js +622 -0
- package/dist/backend/kiro-classic-archive.js.map +1 -0
- package/dist/backend/kiro-classic-links.d.ts +24 -0
- package/dist/backend/kiro-classic-links.js +135 -0
- package/dist/backend/kiro-classic-links.js.map +1 -0
- package/dist/backend/kiro-identity.d.ts +100 -1
- package/dist/backend/kiro-identity.js +262 -31
- package/dist/backend/kiro-identity.js.map +1 -1
- package/dist/backend/kiro-migration-verify.d.ts +10 -0
- package/dist/backend/kiro-migration-verify.js +52 -0
- package/dist/backend/kiro-migration-verify.js.map +1 -0
- package/dist/backend/kiro-reconcile-store.d.ts +27 -0
- package/dist/backend/kiro-reconcile-store.js +351 -0
- package/dist/backend/kiro-reconcile-store.js.map +1 -0
- package/dist/backend/kiro-v2-store-worker.js +35 -1
- package/dist/backend/kiro-v2-store-worker.js.map +1 -1
- package/dist/backend/kiro-v2-store.d.ts +31 -1
- package/dist/backend/kiro-v2-store.js +22 -12
- package/dist/backend/kiro-v2-store.js.map +1 -1
- package/dist/backend/kiro.d.ts +124 -6
- package/dist/backend/kiro.js +553 -39
- package/dist/backend/kiro.js.map +1 -1
- package/dist/backend/types.d.ts +109 -4
- package/dist/backend/types.js +9 -0
- package/dist/backend/types.js.map +1 -1
- package/dist/cache-service.d.ts +13 -1
- package/dist/cache-service.js +45 -2
- package/dist/cache-service.js.map +1 -1
- package/dist/channel/ipc-timeouts.js +3 -0
- package/dist/channel/ipc-timeouts.js.map +1 -1
- package/dist/channel/mcp-tools.js +40 -5
- package/dist/channel/mcp-tools.js.map +1 -1
- package/dist/channel/tool-router.js +2 -1
- package/dist/channel/tool-router.js.map +1 -1
- package/dist/classic-channel-manager.d.ts +6 -0
- package/dist/classic-channel-manager.js +25 -0
- package/dist/classic-channel-manager.js.map +1 -1
- package/dist/cli.js +52 -6
- package/dist/cli.js.map +1 -1
- package/dist/config-validator.d.ts +7 -1
- package/dist/config-validator.js +20 -9
- package/dist/config-validator.js.map +1 -1
- package/dist/config.js +2 -0
- package/dist/config.js.map +1 -1
- package/dist/cross-instance-envelope.d.ts +10 -5
- package/dist/cross-instance-envelope.js +20 -17
- package/dist/cross-instance-envelope.js.map +1 -1
- package/dist/daemon.d.ts +125 -63
- package/dist/daemon.js +694 -330
- package/dist/daemon.js.map +1 -1
- package/dist/dashboard-permissions.d.ts +15 -4
- package/dist/dashboard-permissions.js +49 -23
- package/dist/dashboard-permissions.js.map +1 -1
- package/dist/delivery-outbox.d.ts +27 -22
- package/dist/delivery-outbox.js +109 -161
- package/dist/delivery-outbox.js.map +1 -1
- package/dist/delivery-outbox.test.js +10 -25
- package/dist/delivery-outbox.test.js.map +1 -1
- package/dist/doctor.js +2 -1
- package/dist/doctor.js.map +1 -1
- package/dist/fleet-control-audit.d.ts +1 -1
- package/dist/fleet-control-audit.js +3 -0
- package/dist/fleet-control-audit.js.map +1 -1
- package/dist/fleet-manager.d.ts +94 -15
- package/dist/fleet-manager.js +597 -133
- package/dist/fleet-manager.js.map +1 -1
- package/dist/forged-envelope-scan.d.ts +9 -0
- package/dist/forged-envelope-scan.js +30 -5
- package/dist/forged-envelope-scan.js.map +1 -1
- package/dist/general-instance.d.ts +24 -0
- package/dist/general-instance.js +53 -0
- package/dist/general-instance.js.map +1 -1
- package/dist/general-knowledge/skills/delegation-playbook/SKILL.md +1 -1
- package/dist/general-knowledge/skills/docker-install/SKILL.md +25 -0
- package/dist/general-knowledge/skills/fleet-config/SKILL.md +5 -3
- package/dist/general-knowledge/skills/fleet-restart/SKILL.md +1 -1
- package/dist/general-knowledge/skills/kiro-engine-migration/SKILL.md +34 -0
- package/dist/general-knowledge/skills/session-management/SKILL.md +2 -2
- package/dist/general-knowledge/skills/tui-effort/SKILL.md +1 -1
- package/dist/general-knowledge/skills/web-appearance/SKILL.canvas-worker-off.md +32 -0
- package/dist/general-knowledge/skills/web-appearance/SKILL.md +32 -0
- package/dist/general-knowledge/skills/web-dashboard/SKILL.canvas-worker-off.md +57 -17
- package/dist/general-knowledge/skills/web-dashboard/SKILL.md +57 -17
- package/dist/instance-config-impact.js +3 -2
- package/dist/instance-config-impact.js.map +1 -1
- package/dist/instance-lifecycle.d.ts +4 -0
- package/dist/instance-lifecycle.js +28 -5
- package/dist/instance-lifecycle.js.map +1 -1
- package/dist/instructions.js +6 -7
- package/dist/instructions.js.map +1 -1
- package/dist/kiro-migrate.d.ts +19 -2
- package/dist/kiro-migrate.js +133 -35
- package/dist/kiro-migrate.js.map +1 -1
- package/dist/kiro-reconcile.d.ts +21 -0
- package/dist/kiro-reconcile.js +88 -0
- package/dist/kiro-reconcile.js.map +1 -0
- package/dist/kiro-session-proof.d.ts +41 -0
- package/dist/kiro-session-proof.js +89 -0
- package/dist/kiro-session-proof.js.map +1 -0
- package/dist/kiro-tui-forensic.d.ts +19 -0
- package/dist/kiro-tui-forensic.js +124 -0
- package/dist/kiro-tui-forensic.js.map +1 -0
- package/dist/locale.js +202 -16
- package/dist/locale.js.map +1 -1
- package/dist/log-service.js +3 -3
- package/dist/log-service.js.map +1 -1
- package/dist/needs-you.d.ts +3 -1
- package/dist/needs-you.js +4 -2
- package/dist/needs-you.js.map +1 -1
- package/dist/office-levels.d.ts +64 -0
- package/dist/office-levels.js +66 -0
- package/dist/office-levels.js.map +1 -0
- package/dist/office-share-page.d.ts +3 -1
- package/dist/office-share-page.js +8 -3
- package/dist/office-share-page.js.map +1 -1
- package/dist/office-share-service.d.ts +6 -3
- package/dist/office-share-service.js +12 -8
- package/dist/office-share-service.js.map +1 -1
- package/dist/office-share.d.ts +45 -8
- package/dist/office-share.js +75 -15
- package/dist/office-share.js.map +1 -1
- package/dist/outbound-handlers.js +21 -2
- package/dist/outbound-handlers.js.map +1 -1
- package/dist/outbound-schemas.d.ts +47 -2
- package/dist/outbound-schemas.js +42 -3
- package/dist/outbound-schemas.js.map +1 -1
- package/dist/public-web-gateway.js +1 -1
- package/dist/public-web-gateway.js.map +1 -1
- package/dist/quickstart-api.d.ts +39 -1
- package/dist/quickstart-api.js +115 -17
- package/dist/quickstart-api.js.map +1 -1
- package/dist/remote-card-answer.d.ts +83 -0
- package/dist/remote-card-answer.js +208 -0
- package/dist/remote-card-answer.js.map +1 -0
- package/dist/remote-card-prompt.d.ts +38 -0
- package/dist/remote-card-prompt.js +86 -0
- package/dist/remote-card-prompt.js.map +1 -0
- package/dist/scheduler/task-board.d.ts +44 -17
- package/dist/scheduler/task-board.js +95 -36
- package/dist/scheduler/task-board.js.map +1 -1
- package/dist/sd-notify.d.ts +13 -14
- package/dist/sd-notify.js +62 -28
- package/dist/sd-notify.js.map +1 -1
- package/dist/service-installer.d.ts +13 -0
- package/dist/service-installer.js +15 -0
- package/dist/service-installer.js.map +1 -1
- package/dist/service-owner.d.ts +25 -0
- package/dist/service-owner.js +43 -2
- package/dist/service-owner.js.map +1 -1
- package/dist/settings-api.d.ts +2 -1
- package/dist/settings-api.js +19 -26
- package/dist/settings-api.js.map +1 -1
- package/dist/settings-change.js +10 -5
- package/dist/settings-change.js.map +1 -1
- package/dist/settings-effect.js +7 -6
- package/dist/settings-effect.js.map +1 -1
- package/dist/settings-instance-patch.js +1 -1
- package/dist/settings-instance-patch.js.map +1 -1
- package/dist/setup-form.d.ts +2 -2
- package/dist/setup-form.js +139 -93
- package/dist/setup-form.js.map +1 -1
- package/dist/setup-i18n.d.ts +25 -0
- package/dist/setup-i18n.js +226 -0
- package/dist/setup-i18n.js.map +1 -0
- package/dist/task-board-waker.d.ts +40 -1
- package/dist/task-board-waker.js +115 -9
- package/dist/task-board-waker.js.map +1 -1
- package/dist/tmux-control.d.ts +1 -1
- package/dist/tmux-control.js +3 -2
- package/dist/tmux-control.js.map +1 -1
- package/dist/tmux-manager.js +18 -16
- package/dist/tmux-manager.js.map +1 -1
- package/dist/tmux-read.d.ts +2 -0
- package/dist/tmux-read.js +7 -1
- package/dist/tmux-read.js.map +1 -1
- package/dist/tool-permissions.js +18 -0
- package/dist/tool-permissions.js.map +1 -1
- package/dist/topic-commands.d.ts +2 -0
- package/dist/topic-commands.js +2 -1
- package/dist/topic-commands.js.map +1 -1
- package/dist/transcript-sources.d.ts +1 -0
- package/dist/transcript-sources.js +20 -3
- package/dist/transcript-sources.js.map +1 -1
- package/dist/types.d.ts +11 -5
- package/dist/ui/backend-signin.js +4 -3
- package/dist/ui/chat-store.js +3 -2
- package/dist/ui/chat-strings.js +2 -2
- package/dist/ui/fleet-office-card.js +114 -0
- package/dist/ui/fleet-office-editor.js +81 -9
- package/dist/ui/fleet-office-layout.js +56 -11
- package/dist/ui/fleet-office-levels.js +105 -0
- package/dist/ui/fleet-office-model.js +9 -1
- package/dist/ui/fleet-office-pack.d.ts +15 -3
- package/dist/ui/fleet-office-pack.js +177 -23
- package/dist/ui/fleet-office-skin.js +39 -3
- package/dist/ui/fleet-office-store.js +74 -3
- package/dist/ui/fleet-office-view.js +8 -0
- package/dist/ui/fleet-office-zones.js +102 -19
- package/dist/ui/fleet-office.js +308 -44
- package/dist/ui/fleet-org.js +2 -0
- package/dist/ui/fleet-task-card.js +2 -2
- package/dist/ui/fleet-task-common.js +30 -7
- package/dist/ui/fleet-task-work.js +2 -2
- package/dist/ui/fleet-tasks.js +10 -11
- package/dist/ui/office-share-dialog.js +31 -7
- package/dist/ui/office-share-page.js +1 -0
- package/dist/ui/panel-chat.js +14 -2
- package/dist/ui/panel-log.js +6 -6
- package/dist/ui/panel-needs.js +1 -1
- package/dist/ui/panel-settings.js +16 -8
- package/dist/ui/settings-appearance.js +3 -35
- package/dist/ui/settings-discord.js +3 -2
- package/dist/ui/settings-guests.js +17 -7
- package/dist/ui/settings-model.js +17 -9
- package/dist/ui/settings-registry.js +1 -1
- package/dist/ui/settings-strings.js +18 -6
- package/dist/ui/settings-token.js +3 -2
- package/dist/ui/settings-wizard.js +25 -9
- package/dist/ui/shared/app-i18n.js +2 -2
- package/dist/ui/shared/app-stream.js +1 -1
- package/dist/ui/shared/app.css +70 -2
- package/dist/ui/shared/setup-host-text.js +107 -0
- package/dist/ui/structured-signin.js +89 -38
- package/dist/update-check.d.ts +13 -4
- package/dist/update-check.js +17 -4
- package/dist/update-check.js.map +1 -1
- package/dist/usage-rollup.d.ts +34 -3
- package/dist/usage-rollup.js +56 -3
- package/dist/usage-rollup.js.map +1 -1
- package/dist/web-api.d.ts +10 -1
- package/dist/web-api.js +207 -17
- package/dist/web-api.js.map +1 -1
- package/dist/web-auth.js +1 -1
- package/dist/web-auth.js.map +1 -1
- package/dist/web-experimental.d.ts +6 -2
- package/dist/web-experimental.js +8 -4
- package/dist/web-experimental.js.map +1 -1
- package/dist/web-office-acts.d.ts +5 -2
- package/dist/web-office-acts.js +9 -4
- package/dist/web-office-acts.js.map +1 -1
- package/dist/web-office-pack-read.d.ts +35 -0
- package/dist/web-office-pack-read.js +252 -0
- package/dist/web-office-pack-read.js.map +1 -0
- package/dist/web-office-pack-tools.d.ts +241 -0
- package/dist/web-office-pack-tools.js +785 -0
- package/dist/web-office-pack-tools.js.map +1 -0
- package/dist/web-office-skins.d.ts +68 -4
- package/dist/web-office-skins.js +324 -33
- package/dist/web-office-skins.js.map +1 -1
- package/dist/web-office-store.d.ts +47 -4
- package/dist/web-office-store.js +124 -23
- package/dist/web-office-store.js.map +1 -1
- package/dist/web-settings-patch.d.ts +3 -2
- package/dist/web-settings-patch.js +7 -5
- package/dist/web-settings-patch.js.map +1 -1
- package/dist/workflow-templates/default.md +3 -3
- package/dist/working-recovery.d.ts +0 -2
- package/dist/working-recovery.js +2 -23
- package/dist/working-recovery.js.map +1 -1
- package/package.json +2 -2
- package/templates/windows-shortcuts.ps1 +18 -17
- package/dist/upgrade-notices.d.ts +0 -17
- package/dist/upgrade-notices.js +0 -93
- package/dist/upgrade-notices.js.map +0 -1
|
@@ -42,33 +42,62 @@ export function overflowSpots(area, need = 0) {
|
|
|
42
42
|
* slot }). Someone still in the same area keeps their slot; the others take the first free seat, in the area's order,
|
|
43
43
|
* then an overflow spot (slot -1, -2, …). No two share one. Whoever finds neither is counted in `crowd` (area → n).
|
|
44
44
|
* Returns { seats: Map name → { area, slot, x, y }, crowd: Map }.
|
|
45
|
+
*
|
|
46
|
+
* #2691: a seat may be reserved (its `for`). Whoever it is for, wanting its area, takes a free seat reserved for them
|
|
47
|
+
* before anything else (the one they sat on last time, else their first in the area's order) — owners are seated
|
|
48
|
+
* before anyone keeps a slot, so a borrower on an owner's seat moves off when the owner comes. Everyone else keeps
|
|
49
|
+
* their slot or takes the first free seat not reserved for someone else: a plain one, else a reserved one that says
|
|
50
|
+
* `lend` (one no owner of it took). A reserved seat not lent, none of whose owners wants the area, is unavailable:
|
|
51
|
+
* the area's overflow spots and `over` count without it. Seats without `for` work as before.
|
|
45
52
|
*/
|
|
46
53
|
export function assignSeats(pack, wants, prev = new Map()) {
|
|
47
|
-
const seats = new Map(), crowd = new Map(), taken = new Map(), spill = new Map(), demand = new Map();
|
|
54
|
+
const seats = new Map(), crowd = new Map(), taken = new Map(), spill = new Map(), demand = new Map(), wanting = new Map();
|
|
48
55
|
const areaOf = (a) => own(pack.areas, a);
|
|
49
|
-
for (const w of wants)
|
|
56
|
+
for (const w of wants) {
|
|
57
|
+
demand.set(w.area, (demand.get(w.area) || 0) + 1);
|
|
58
|
+
if (!wanting.has(w.area)) wanting.set(w.area, new Set());
|
|
59
|
+
wanting.get(w.area).add(w.name);
|
|
60
|
+
}
|
|
61
|
+
const mine = (s, name) => !!s.for && s.for.includes(name);
|
|
62
|
+
const lent = (s) => !!s.for && s.lend === true;
|
|
63
|
+
// The seats someone wanting the area may end up on: plain, lent, or reserved for someone who wants it.
|
|
64
|
+
const usable = (area) => areaOf(area).seats.filter((s) => !s.for || s.lend === true || s.for.some((n) => wanting.get(area).has(n))).length;
|
|
50
65
|
const spotsOf = (area) => {
|
|
51
|
-
if (!spill.has(area)) spill.set(area, overflowSpots(areaOf(area), Math.max(0, (demand.get(area) || 0) -
|
|
66
|
+
if (!spill.has(area)) spill.set(area, overflowSpots(areaOf(area), Math.max(0, (demand.get(area) || 0) - usable(area))));
|
|
52
67
|
return spill.get(area);
|
|
53
68
|
};
|
|
54
69
|
const pos = (area, slot) => (slot >= 0 ? areaOf(area).seats[slot] : spotsOf(area)[-slot - 1]);
|
|
55
70
|
const usedIn = (area) => { if (!taken.has(area)) taken.set(area, new Set()); return taken.get(area); };
|
|
56
71
|
const give = (name, area, slot) => { const p = pos(area, slot); usedIn(area).add(slot); seats.set(name, { area, slot, x: p.x, y: p.y }); };
|
|
72
|
+
const free = (w) => !seats.has(w.name) && !!areaOf(w.area);
|
|
73
|
+
// Owners first: their own seat from last time, then their first free one.
|
|
74
|
+
for (const w of wants) {
|
|
75
|
+
const p = prev.get(w.name), s = p && p.area === w.area && p.slot >= 0 && areaOf(w.area) ? areaOf(w.area).seats[p.slot] : null;
|
|
76
|
+
if (s && mine(s, w.name) && !usedIn(w.area).has(p.slot)) give(w.name, w.area, p.slot);
|
|
77
|
+
}
|
|
78
|
+
for (const w of wants) {
|
|
79
|
+
if (!free(w)) continue;
|
|
80
|
+
const used = usedIn(w.area), slot = areaOf(w.area).seats.findIndex((s, i) => mine(s, w.name) && !used.has(i));
|
|
81
|
+
if (slot >= 0) give(w.name, w.area, slot);
|
|
82
|
+
}
|
|
57
83
|
for (const w of wants) {
|
|
58
84
|
const p = prev.get(w.name);
|
|
59
|
-
if (!p || p.area !== w.area || !
|
|
85
|
+
if (!free(w) || !p || p.area !== w.area || !pos(w.area, p.slot) || usedIn(w.area).has(p.slot)) continue;
|
|
86
|
+
const s = p.slot >= 0 ? areaOf(w.area).seats[p.slot] : null;
|
|
87
|
+
if (s && s.for && !lent(s)) continue; // reserved for someone else (theirs would be taken above)
|
|
60
88
|
give(w.name, w.area, p.slot);
|
|
61
89
|
}
|
|
62
90
|
for (const w of wants) {
|
|
63
|
-
if (
|
|
91
|
+
if (!free(w)) continue;
|
|
64
92
|
const used = usedIn(w.area), area = areaOf(w.area);
|
|
65
|
-
let slot = area.seats.findIndex((
|
|
93
|
+
let slot = area.seats.findIndex((s, i) => !s.for && !used.has(i));
|
|
94
|
+
if (slot < 0) slot = area.seats.findIndex((s, i) => lent(s) && !used.has(i));
|
|
66
95
|
if (slot < 0) { const j = spotsOf(w.area).findIndex((_, i) => !used.has(-i - 1)); slot = j < 0 ? null : -j - 1; }
|
|
67
96
|
if (slot === null) crowd.set(w.area, (crowd.get(w.area) || 0) + 1);
|
|
68
97
|
else give(w.name, w.area, slot);
|
|
69
98
|
}
|
|
70
|
-
// Over capacity: more people want the area than it has seats (their bubbles and tags are thinned, fleet-office.js).
|
|
71
|
-
const over = new Set([...demand].filter(([a, n]) => areaOf(a) && n >
|
|
99
|
+
// Over capacity: more people want the area than it has seats for them (their bubbles and tags are thinned, fleet-office.js).
|
|
100
|
+
const over = new Set([...demand].filter(([a, n]) => areaOf(a) && n > usable(a)).map(([a]) => a));
|
|
72
101
|
return { seats, crowd, over };
|
|
73
102
|
}
|
|
74
103
|
|
|
@@ -79,17 +108,39 @@ export function assignSeats(pack, wants, prev = new Map()) {
|
|
|
79
108
|
*/
|
|
80
109
|
export function zonesLayout(pack, nodes, prev = new Map(), { night = false } = {}) {
|
|
81
110
|
// At night (#2568) the idle go to bed: the area asleep people go to while it has a free seat; the rest doze where they are.
|
|
82
|
-
const bed = zoneOf(pack, "paused"),
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
111
|
+
const bed = zoneOf(pack, "paused"), bedSeats = own(pack.areas, bed)?.seats || [], sleepers = new Set(), inBed = new Set();
|
|
112
|
+
const wantsOf = (beds) => nodes.filter((n) => n.state !== "missing").map((n) => ({ name: n.name, area: beds.has(n.name) ? bed : zoneOf(pack, n.state) }));
|
|
113
|
+
let placed = assignSeats(pack, wantsOf(inBed), prev);
|
|
114
|
+
if (night) {
|
|
115
|
+
// #2691 review: who goes to bed is decided by the seat assignment itself (assignSeats' reservation rules), one
|
|
116
|
+
// sleeper at a time — whoever has a bed of their own there first, then the rest in the fleet's order. A sleeper
|
|
117
|
+
// goes to bed only if it gives them a bed (never an overflow spot) without taking one from anyone already in one
|
|
118
|
+
// (the awake first, then the sleepers admitted before), unless it is a bed reserved for them: an owner comes first,
|
|
119
|
+
// as by day. Everyone else dozes where they are.
|
|
120
|
+
const inABed = (r) => new Set([...r.seats].filter(([, s]) => s.area === bed && s.slot >= 0).map(([name]) => name));
|
|
121
|
+
const idle = nodes.filter((n) => n.state === "idle");
|
|
122
|
+
const hasBed = (n) => bedSeats.some((s) => s.for && s.for.includes(n.name));
|
|
123
|
+
for (const n of idle) sleepers.add(n.name);
|
|
124
|
+
for (const n of [...idle.filter(hasBed), ...idle.filter((n) => !hasBed(n))]) {
|
|
125
|
+
const trial = assignSeats(pack, wantsOf(new Set([...inBed, n.name])), prev), s = trial.seats.get(n.name);
|
|
126
|
+
if (!s || s.area !== bed || s.slot < 0) {
|
|
127
|
+
if (!hasBed(n)) break; // no bed free for anyone without one: none for the rest either
|
|
128
|
+
continue;
|
|
129
|
+
}
|
|
130
|
+
const before = inABed(placed), after = inABed(trial);
|
|
131
|
+
const theirs = !!bedSeats[s.slot].for && bedSeats[s.slot].for.includes(n.name);
|
|
132
|
+
if (!theirs && [...before].some((m) => !after.has(m))) continue;
|
|
133
|
+
inBed.add(n.name);
|
|
134
|
+
placed = trial;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
const { seats, crowd, over } = placed;
|
|
87
138
|
const desks = nodes.filter((n) => seats.has(n.name)).map((n) => {
|
|
88
139
|
const s = seats.get(n.name);
|
|
89
140
|
return { key: `zone/${n.name}`, node: n, x: s.x - 24, y: s.y - 52, w: 48, h: 66, seat: { x: s.x, y: s.y }, wp: null, area: s.area, slot: s.slot, night: sleepers.has(n.name) };
|
|
90
141
|
});
|
|
91
142
|
return { mode: "zones", rooms: [{ key: "\u0000zones", name: null, lobby: false, x: 0, y: 0, w: LOGICAL.w, h: LOGICAL.h, desks }], areas: pack.areas,
|
|
92
|
-
waypoints: pack.waypoints || [], edges: pack.edges || [], straight: pack.straight === true, door: pack.door, width: LOGICAL.w, height: LOGICAL.h, seats, crowd, over };
|
|
143
|
+
waypoints: pack.waypoints || [], edges: pack.edges || [], straight: pack.straight === true, door: pack.door, mailDrop: pack.mailDrop || null, width: LOGICAL.w, height: LOGICAL.h, seats, crowd, over };
|
|
93
144
|
}
|
|
94
145
|
|
|
95
146
|
// ── Walking ──
|
|
@@ -176,7 +227,9 @@ export function walkTargets(desks, graph, t, wander = true, furniture = [], nigh
|
|
|
176
227
|
*/
|
|
177
228
|
export const MAIL = { MAX_WAIT: 60000, GAP: 16, SEARCH: 320, ASLEEP: new Set(["paused", "stopped"]), MAX: 20 };
|
|
178
229
|
/**
|
|
179
|
-
* Where the `n`th waiting letter lands: `
|
|
230
|
+
* Where the `n`th waiting letter lands. #2736: the layout's `mailDrop` when it has one — the `n`th of the slots GAP
|
|
231
|
+
* apart rightwards from it that no seat is on (never beyond the room's right edge); fewer than that, today's rule. Otherwise `n`
|
|
232
|
+
* GAPs along from the waypoint nearest the room's middle — the nearest whose
|
|
180
233
|
* spot (offset included) no seat of the office is on, taken or free (someone may sit there any moment; #2561 likewise);
|
|
181
234
|
* with none, the nearest point round the middle (rings GAP·2 apart, inside the room) that no seat is on; with none of
|
|
182
235
|
* those either, null — the letter is not delivered here (never on a seat).
|
|
@@ -185,6 +238,12 @@ export function dropPoint(L, n = 0) {
|
|
|
185
238
|
const mid = { x: L.width / 2, y: L.height * 0.55 }, d = (p, q) => Math.hypot(p.x - q.x, p.y - q.y);
|
|
186
239
|
const seats = [...Object.values(L.areas || {}).flatMap((a) => a.seats || []), ...desksIn(L).map((q) => q.seat)];
|
|
187
240
|
const onSeat = (p) => seats.some((q) => d(p, q) < 4);
|
|
241
|
+
// #2751 review: the nth off-seat slot (slots GAP apart from the mailDrop), so two letters never share one.
|
|
242
|
+
const md = L.mailDrop;
|
|
243
|
+
if (md) for (let i = 0, free = 0; md.x + i * MAIL.GAP <= L.width; i++) {
|
|
244
|
+
const p = { x: Math.round(md.x + i * MAIL.GAP), y: Math.round(md.y) };
|
|
245
|
+
if (!onSeat(p) && free++ === n) return p;
|
|
246
|
+
}
|
|
188
247
|
const spots = (L.waypoints || []).map((w) => ({ x: Math.round(w.x + n * MAIL.GAP), y: Math.round(w.y), from: w }))
|
|
189
248
|
.filter((p) => !onSeat(p.from) && !onSeat(p)).sort((p, q) => d(p.from, mid) - d(q.from, mid));
|
|
190
249
|
if (spots.length) return { x: spots[0].x, y: spots[0].y };
|
|
@@ -386,14 +445,38 @@ export function linesFor(state, lang, pack, defaults) {
|
|
|
386
445
|
|
|
387
446
|
// ── Furniture ──
|
|
388
447
|
|
|
389
|
-
/**
|
|
390
|
-
|
|
448
|
+
/**
|
|
449
|
+
* The people an item with `activeFor` is active for now (#2570): those of them shown in an `activeWhen` state — with
|
|
450
|
+
* "activeOn": "seated" (#2698), only those `posture(name)` says are "seated" (at the seat zones gave them, not walking).
|
|
451
|
+
* `posture` null: no walkers, everyone at their seat.
|
|
452
|
+
*/
|
|
453
|
+
function activeForNow(f, byName, posture) {
|
|
454
|
+
const seated = (n) => f.activeOn !== "seated" || !posture || posture(n) === "seated";
|
|
455
|
+
return (f.activeFor || [...byName.keys()]).filter((n) => byName.has(n) && f.activeWhen.includes(byName.get(n)) && seated(n));
|
|
456
|
+
}
|
|
457
|
+
/**
|
|
458
|
+
* The furniture active now: an item whose `activeWhen` names a state someone shown is in. With activeFor (#2570),
|
|
459
|
+
* only those people's states count; with "activeOn": "seated" (#2698), only once one of them is seated (`posture`,
|
|
460
|
+
* name → "walking" | "seated" | "standing"; null: everyone seated) — it turns back as they walk off.
|
|
461
|
+
*/
|
|
462
|
+
export function activeFurniture(pack, states, byName = new Map(), posture = null) {
|
|
391
463
|
const on = new Set();
|
|
392
464
|
for (const f of (pack && pack.furniture) || []) {
|
|
393
465
|
if (!f.activeWhen) continue;
|
|
394
|
-
|
|
395
|
-
const hit = f.activeFor ? f.activeFor.some((n) => byName.has(n) && f.activeWhen.includes(byName.get(n))) : f.activeWhen.some((s) => states.has(s));
|
|
466
|
+
const hit = f.activeFor || f.activeOn === "seated" ? activeForNow(f, byName, posture).length > 0 : f.activeWhen.some((s) => states.has(s));
|
|
396
467
|
if (hit) on.add(f.id);
|
|
397
468
|
}
|
|
398
469
|
return on;
|
|
399
470
|
}
|
|
471
|
+
/**
|
|
472
|
+
* #2698: who is drawn on an item instead of themselves (name → the item's id): for each `active` item with "hides",
|
|
473
|
+
* the people it is active for (activeFor's order) who are not walking — someone walking is always drawn. One item each.
|
|
474
|
+
*/
|
|
475
|
+
export function hiddenBy(pack, active, byName = new Map(), posture = null) {
|
|
476
|
+
const out = new Map();
|
|
477
|
+
for (const f of (pack && pack.furniture) || []) {
|
|
478
|
+
if (!f.hides || !f.activeWhen || !active.has(f.id)) continue;
|
|
479
|
+
for (const n of activeForNow(f, byName, posture)) if (!out.has(n) && (!posture || posture(n) !== "walking")) out.set(n, f.id);
|
|
480
|
+
}
|
|
481
|
+
return out;
|
|
482
|
+
}
|