@songsid/agend 2.3.1 → 2.3.2-beta.10
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/THIRD_PARTY_NOTICES.md +40 -0
- package/dist/agent-cli.js +21 -2
- package/dist/agent-cli.js.map +1 -1
- package/dist/agent-endpoint.js +5 -0
- package/dist/agent-endpoint.js.map +1 -1
- package/dist/antigravity-usage-scan.d.ts +58 -0
- package/dist/antigravity-usage-scan.js +257 -0
- package/dist/antigravity-usage-scan.js.map +1 -0
- package/dist/antigravity-usage-worker.d.ts +1 -0
- package/dist/antigravity-usage-worker.js +10 -0
- package/dist/antigravity-usage-worker.js.map +1 -0
- package/dist/auth-api.js +4 -0
- package/dist/auth-api.js.map +1 -1
- package/dist/authority/authority-state.d.ts +4 -0
- package/dist/authority/authority-state.js +16 -10
- package/dist/authority/authority-state.js.map +1 -1
- package/dist/authority/session-authorizations.d.ts +7 -1
- package/dist/authority/session-authorizations.js +6 -4
- package/dist/authority/session-authorizations.js.map +1 -1
- package/dist/authority/web-authority.d.ts +19 -6
- package/dist/authority/web-authority.js +22 -8
- package/dist/authority/web-authority.js.map +1 -1
- package/dist/backend/kiro-identity.d.ts +64 -0
- package/dist/backend/kiro-identity.js +101 -0
- package/dist/backend/kiro-identity.js.map +1 -1
- package/dist/backend/kiro-retired-model.d.ts +62 -0
- package/dist/backend/kiro-retired-model.js +160 -0
- package/dist/backend/kiro-retired-model.js.map +1 -0
- package/dist/backend/kiro.d.ts +71 -2
- package/dist/backend/kiro.js +352 -11
- package/dist/backend/kiro.js.map +1 -1
- package/dist/backend/types.d.ts +59 -0
- package/dist/backend/types.js.map +1 -1
- package/dist/backend-signin-guide.d.ts +1 -0
- package/dist/backend-signin-guide.js +9 -0
- package/dist/backend-signin-guide.js.map +1 -0
- package/dist/backend-signin-pending.d.ts +10 -0
- package/dist/backend-signin-pending.js +44 -0
- package/dist/backend-signin-pending.js.map +1 -0
- package/dist/browser-backend-signins.d.ts +56 -0
- package/dist/browser-backend-signins.js +189 -0
- package/dist/browser-backend-signins.js.map +1 -0
- package/dist/cache-ledger.d.ts +38 -2
- package/dist/cache-ledger.js +133 -8
- package/dist/cache-ledger.js.map +1 -1
- package/dist/cache-prices.d.ts +2 -1
- package/dist/cache-prices.js +5 -2
- package/dist/cache-prices.js.map +1 -1
- package/dist/cache-service.d.ts +68 -0
- package/dist/cache-service.js +355 -13
- package/dist/cache-service.js.map +1 -1
- package/dist/channel/adapters/discord.d.ts +13 -0
- package/dist/channel/adapters/discord.js +103 -16
- package/dist/channel/adapters/discord.js.map +1 -1
- package/dist/channel/mcp-tools.js +34 -7
- 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/channel/types.d.ts +11 -0
- package/dist/classic-channel-manager.d.ts +11 -0
- package/dist/classic-channel-manager.js +39 -1
- package/dist/classic-channel-manager.js.map +1 -1
- package/dist/cli.js +21 -2
- package/dist/cli.js.map +1 -1
- package/dist/config-validator.d.ts +7 -1
- package/dist/config-validator.js +92 -12
- package/dist/config-validator.js.map +1 -1
- package/dist/config.d.ts +19 -0
- package/dist/config.js +31 -1
- package/dist/config.js.map +1 -1
- package/dist/cpu-quota.d.ts +23 -0
- package/dist/cpu-quota.js +86 -0
- package/dist/cpu-quota.js.map +1 -0
- package/dist/daemon.d.ts +57 -3
- package/dist/daemon.js +330 -50
- package/dist/daemon.js.map +1 -1
- package/dist/dashboard-permissions.d.ts +20 -6
- package/dist/dashboard-permissions.js +58 -9
- package/dist/dashboard-permissions.js.map +1 -1
- package/dist/delivery-outbox.d.ts +12 -1
- package/dist/delivery-outbox.js +67 -15
- package/dist/delivery-outbox.js.map +1 -1
- package/dist/doctor.d.ts +3 -0
- package/dist/doctor.js +11 -1
- package/dist/doctor.js.map +1 -1
- package/dist/event-log.d.ts +5 -0
- package/dist/event-log.js +13 -0
- package/dist/event-log.js.map +1 -1
- package/dist/fleet-manager.d.ts +212 -0
- package/dist/fleet-manager.js +914 -111
- package/dist/fleet-manager.js.map +1 -1
- package/dist/fleet-process-handlers.d.ts +1 -0
- package/dist/fleet-process-handlers.js +9 -1
- package/dist/fleet-process-handlers.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-knowledge/skills/credential-profiles/SKILL.md +5 -2
- package/dist/general-knowledge/skills/kiro-engine-migration/SKILL.md +14 -1
- package/dist/general-knowledge/skills/web-appearance/SKILL.canvas-worker-off.md +28 -5
- package/dist/general-knowledge/skills/web-appearance/SKILL.md +31 -8
- package/dist/general-knowledge/skills/web-dashboard/SKILL.canvas-worker-off.md +138 -59
- package/dist/general-knowledge/skills/web-dashboard/SKILL.md +145 -61
- package/dist/guest-seen-people.d.ts +38 -0
- package/dist/guest-seen-people.js +78 -0
- package/dist/guest-seen-people.js.map +1 -0
- package/dist/instance-config-impact.js +14 -6
- package/dist/instance-config-impact.js.map +1 -1
- package/dist/instance-lifecycle.d.ts +20 -0
- package/dist/instance-lifecycle.js +71 -13
- package/dist/instance-lifecycle.js.map +1 -1
- package/dist/kiro-db-reader.d.ts +5 -0
- package/dist/kiro-db-reader.js +18 -0
- package/dist/kiro-db-reader.js.map +1 -1
- package/dist/kiro-engine-status.d.ts +2 -0
- package/dist/kiro-engine-status.js +9 -0
- package/dist/kiro-engine-status.js.map +1 -1
- package/dist/kiro-migrate.d.ts +49 -0
- package/dist/kiro-migrate.js +105 -0
- package/dist/kiro-migrate.js.map +1 -0
- package/dist/kiro-transcript-lane.d.ts +2 -0
- package/dist/kiro-transcript-lane.js.map +1 -1
- package/dist/kiro-transcript-worker.js +1 -0
- package/dist/kiro-transcript-worker.js.map +1 -1
- package/dist/kiro-tui-forensic.d.ts +7 -0
- package/dist/kiro-tui-forensic.js +110 -0
- package/dist/kiro-tui-forensic.js.map +1 -0
- package/dist/kiro-usage-run.d.ts +7 -0
- package/dist/kiro-usage-run.js +39 -0
- package/dist/kiro-usage-run.js.map +1 -0
- package/dist/kiro-usage-scan.d.ts +49 -0
- package/dist/kiro-usage-scan.js +223 -0
- package/dist/kiro-usage-scan.js.map +1 -0
- package/dist/kiro-usage-worker.d.ts +1 -0
- package/dist/kiro-usage-worker.js +10 -0
- package/dist/kiro-usage-worker.js.map +1 -0
- package/dist/kiro-usage.d.ts +58 -0
- package/dist/kiro-usage.js +310 -0
- package/dist/kiro-usage.js.map +1 -0
- package/dist/locale.js +120 -12
- package/dist/locale.js.map +1 -1
- package/dist/log-service.js +1 -1
- package/dist/log-service.js.map +1 -1
- package/dist/login-url.d.ts +4 -0
- package/dist/login-url.js +22 -0
- package/dist/login-url.js.map +1 -0
- package/dist/mac-auto-restore.d.ts +117 -0
- package/dist/mac-auto-restore.js +294 -0
- package/dist/mac-auto-restore.js.map +1 -0
- package/dist/needs-you-hub.d.ts +2 -1
- package/dist/needs-you-hub.js +1 -1
- package/dist/needs-you-hub.js.map +1 -1
- package/dist/needs-you.d.ts +8 -2
- package/dist/needs-you.js +6 -0
- package/dist/needs-you.js.map +1 -1
- package/dist/notice-delivery.d.ts +16 -0
- package/dist/notice-delivery.js +35 -0
- package/dist/notice-delivery.js.map +1 -0
- package/dist/office-share-page.d.ts +16 -0
- package/dist/office-share-page.js +85 -0
- package/dist/office-share-page.js.map +1 -0
- package/dist/office-share-service.d.ts +91 -0
- package/dist/office-share-service.js +176 -0
- package/dist/office-share-service.js.map +1 -0
- package/dist/office-share.d.ts +258 -0
- package/dist/office-share.js +549 -0
- package/dist/office-share.js.map +1 -0
- package/dist/opencode-usage-scan.d.ts +28 -0
- package/dist/opencode-usage-scan.js +92 -0
- package/dist/opencode-usage-scan.js.map +1 -0
- package/dist/opencode-usage-worker.d.ts +1 -0
- package/dist/opencode-usage-worker.js +10 -0
- package/dist/opencode-usage-worker.js.map +1 -0
- package/dist/outbound-handlers.js +22 -2
- package/dist/outbound-handlers.js.map +1 -1
- package/dist/outbound-schemas.d.ts +28 -2
- package/dist/outbound-schemas.js +29 -2
- package/dist/outbound-schemas.js.map +1 -1
- package/dist/public-web-gateway.js +16 -2
- package/dist/public-web-gateway.js.map +1 -1
- package/dist/quickstart-api.js +13 -2
- package/dist/quickstart-api.js.map +1 -1
- package/dist/quickstart.js +2 -1
- package/dist/quickstart.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/reply-triggers.d.ts +2 -0
- package/dist/reply-triggers.js +3 -0
- package/dist/reply-triggers.js.map +1 -0
- package/dist/settings-api.d.ts +28 -0
- package/dist/settings-api.js +148 -17
- package/dist/settings-api.js.map +1 -1
- package/dist/settings-change.js +54 -17
- package/dist/settings-change.js.map +1 -1
- package/dist/settings-effect.js +12 -3
- package/dist/settings-effect.js.map +1 -1
- package/dist/settings-instance-patch.js +4 -1
- package/dist/settings-instance-patch.js.map +1 -1
- package/dist/setup-form.d.ts +1 -1
- package/dist/setup-form.js +55 -6
- package/dist/setup-form.js.map +1 -1
- package/dist/setup-host.d.ts +9 -0
- package/dist/setup-host.js +127 -6
- package/dist/setup-host.js.map +1 -1
- package/dist/setup-signin-assets.d.ts +2 -0
- package/dist/setup-signin-assets.js +6 -0
- package/dist/setup-signin-assets.js.map +1 -0
- package/dist/setup-wizard.js +2 -0
- package/dist/setup-wizard.js.map +1 -1
- package/dist/start-attempt.d.ts +9 -5
- package/dist/start-attempt.js +27 -8
- package/dist/start-attempt.js.map +1 -1
- package/dist/start-failure-chat.d.ts +4 -0
- package/dist/start-failure-chat.js +23 -6
- package/dist/start-failure-chat.js.map +1 -1
- package/dist/start-failure-notice.d.ts +4 -0
- package/dist/start-failure-notice.js +8 -0
- package/dist/start-failure-notice.js.map +1 -1
- package/dist/start-failure.d.ts +25 -0
- package/dist/start-failure.js +75 -2
- package/dist/start-failure.js.map +1 -1
- package/dist/structured-signin-transport.d.ts +8 -0
- package/dist/structured-signin-transport.js +79 -0
- package/dist/structured-signin-transport.js.map +1 -0
- package/dist/structured-signin.d.ts +131 -0
- package/dist/structured-signin.js +388 -0
- package/dist/structured-signin.js.map +1 -0
- package/dist/tool-permissions.js +12 -0
- package/dist/tool-permissions.js.map +1 -1
- package/dist/topic-commands.js +6 -2
- package/dist/topic-commands.js.map +1 -1
- package/dist/transcript-sources.d.ts +26 -2
- package/dist/transcript-sources.js +103 -40
- package/dist/transcript-sources.js.map +1 -1
- package/dist/turn-reply-guard.d.ts +25 -0
- package/dist/turn-reply-guard.js +111 -12
- package/dist/turn-reply-guard.js.map +1 -1
- package/dist/types.d.ts +46 -9
- package/dist/ui/backend-signin.js +68 -12
- package/dist/ui/chat-ambient.js +1 -1
- package/dist/ui/chat-effects.js +4 -4
- package/dist/ui/chat-render.js +5 -2
- package/dist/ui/chat-strings.js +4 -4
- package/dist/ui/chat-thread.js +2 -2
- package/dist/ui/first-run.js +2 -2
- package/dist/ui/fleet-canvas-view.js +114 -0
- package/dist/ui/fleet-canvas.js +15 -77
- package/dist/ui/fleet-office-editor.js +94 -14
- package/dist/ui/fleet-office-layout.js +235 -0
- package/dist/ui/fleet-office-model.js +12 -6
- package/dist/ui/fleet-office-overview.js +167 -0
- package/dist/ui/fleet-office-pack.d.ts +44 -0
- package/dist/ui/fleet-office-pack.js +352 -37
- package/dist/ui/fleet-office-skin.js +220 -36
- package/dist/ui/fleet-office-store.js +112 -7
- package/dist/ui/fleet-office-view.js +155 -0
- package/dist/ui/fleet-office-zones.js +264 -42
- package/dist/ui/fleet-office.js +957 -160
- package/dist/ui/fleet-usage.js +26 -21
- package/dist/ui/office-share-dialog.js +145 -0
- package/dist/ui/office-share-page.js +164 -0
- package/dist/ui/panel-chat.js +9 -2
- package/dist/ui/panel-details.js +2 -2
- package/dist/ui/panel-fleet.js +11 -77
- package/dist/ui/panel-log.js +4 -4
- package/dist/ui/panel-needs.js +4 -4
- package/dist/ui/panel-settings.js +608 -167
- package/dist/ui/search-dialog.js +26 -7
- package/dist/ui/settings-appearance.js +82 -29
- package/dist/ui/settings-apply.js +42 -7
- package/dist/ui/settings-dialogs.js +76 -23
- package/dist/ui/settings-draft.js +51 -0
- package/dist/ui/settings-guests.js +255 -79
- package/dist/ui/settings-learn.js +2 -2
- package/dist/ui/settings-model.js +16 -6
- package/dist/ui/settings-registry.js +146 -0
- package/dist/ui/settings-strings.js +116 -44
- package/dist/ui/settings-web-authority.js +34 -23
- package/dist/ui/shared/app-i18n.js +18 -2
- package/dist/ui/shared/app-nav.js +10 -5
- package/dist/ui/shared/app-prefs.js +80 -2
- package/dist/ui/shared/app-route.js +39 -5
- package/dist/ui/shared/app-shell.js +73 -10
- package/dist/ui/shared/app-stream.js +3 -1
- package/dist/ui/shared/app.css +307 -17
- package/dist/ui/shared/app.js +3 -0
- package/dist/ui/shared/effect-stock-trust.js +1 -1
- package/dist/ui/shared/identity-color.js +4 -4
- package/dist/ui/shared/office/cozy.png +0 -0
- package/dist/ui/shared/side-panel.js +95 -0
- package/dist/ui/shared/signin.js +2 -2
- package/dist/ui/shared/ui-dialog.js +6 -1
- package/dist/ui/shared/ui-icons.js +2 -0
- package/dist/ui/shared/web-authorize.js +13 -12
- package/dist/ui/structured-signin.js +115 -0
- package/dist/usage-report.d.ts +20 -0
- package/dist/usage-report.js +54 -17
- package/dist/usage-report.js.map +1 -1
- package/dist/usage-rollup.d.ts +9 -1
- package/dist/usage-rollup.js +20 -4
- package/dist/usage-rollup.js.map +1 -1
- package/dist/web-api.d.ts +26 -2
- package/dist/web-api.js +361 -5
- package/dist/web-api.js.map +1 -1
- package/dist/web-auth.js +8 -2
- package/dist/web-auth.js.map +1 -1
- package/dist/web-backend-login.d.ts +1 -7
- package/dist/web-backend-login.js +2 -24
- package/dist/web-backend-login.js.map +1 -1
- package/dist/web-experimental.d.ts +1 -1
- package/dist/web-experimental.js +1 -1
- package/dist/web-experimental.js.map +1 -1
- package/dist/web-mod-agent.js +2 -2
- package/dist/web-mod-agent.js.map +1 -1
- package/dist/web-office-acts.d.ts +173 -0
- package/dist/web-office-acts.js +285 -0
- package/dist/web-office-acts.js.map +1 -0
- package/dist/web-office-skins.d.ts +109 -0
- package/dist/web-office-skins.js +299 -0
- package/dist/web-office-skins.js.map +1 -0
- package/dist/web-office-store.d.ts +8 -2
- package/dist/web-office-store.js +77 -14
- package/dist/web-office-store.js.map +1 -1
- package/dist/web-settings-patch.d.ts +8 -1
- package/dist/web-settings-patch.js +65 -5
- package/dist/web-settings-patch.js.map +1 -1
- package/dist/web-shell-routes.d.ts +4 -2
- package/dist/web-shell-routes.js +17 -7
- package/dist/web-shell-routes.js.map +1 -1
- package/dist/working-recovery.d.ts +104 -0
- package/dist/working-recovery.js +298 -0
- package/dist/working-recovery.js.map +1 -0
- package/dist/working-state-journal.d.ts +5 -1
- package/dist/working-state-journal.js +31 -3
- package/dist/working-state-journal.js.map +1 -1
- package/package.json +3 -2
- package/templates/windows-shortcuts.ps1 +155 -140
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* #2578: an agent sees and directs its own character in Fleet → Org chart → Office — office_view (the stored offices
|
|
3
|
+
* it is in: who is there, in what state, and the spots it may walk to) and office_set (walk to a seat, a waypoint or a
|
|
4
|
+
* person; say a line; hold a pose; for a few seconds). Its own only: the caller is the instance its IPC connection or
|
|
5
|
+
* agent token belongs to, never anything the call says. The `office` dashboard feature (dashboard-permissions.ts) is
|
|
6
|
+
* off until a person switches it on; the fleet's sinks refuse both tools before they reach here.
|
|
7
|
+
*
|
|
8
|
+
* An act is kept in memory, one per instance (a new office_set replaces it; `clear` ends it; a fleet restart forgets
|
|
9
|
+
* them all), and is live while `until` is ahead (wall clock, the page's): every change — set, clear, expiry — goes to
|
|
10
|
+
* every page as the `office_acts` SSE event, and GET /ui/office-acts reads the same list. The page draws it until new
|
|
11
|
+
* work begins (fleet-office.js actLive: the turn it was set in, and idle after it, keep it; working again after that, or
|
|
12
|
+
* after acting while idle, ends it), its instance is called or asleep, or bedtime puts it to bed: an act never hides real
|
|
13
|
+
* work.
|
|
14
|
+
*
|
|
15
|
+
* Spots come from the office's skin: a pack the host keeps (web-office-skins.ts), with the office's layout overrides on
|
|
16
|
+
* it (applyOverrides — the page's own rule); a built-in style (pixel, studio) or a pack without stateZones draws desks,
|
|
17
|
+
* with none: there the line and the pose show, and `go` is refused (nobody walks; review). A seat is "area:index", its
|
|
18
|
+
* index in the area's seat list from 0, as office_view lists it.
|
|
19
|
+
*
|
|
20
|
+
* office_set is limited per instance (OfficeActLimiter: 6 a minute, 60 an hour, monotonic, memory only), like the
|
|
21
|
+
* appearance limiter: checked before anything is validated, counted only once the act is in place; a refusal says when
|
|
22
|
+
* the next call may come (cooldown_ms). office_view is not limited.
|
|
23
|
+
*/
|
|
24
|
+
import { applyOverrides, fitNight } from "./ui/fleet-office-pack.js";
|
|
25
|
+
import { OfficeSetArgs, OfficeViewArgs, validateArgs } from "./outbound-schemas.js";
|
|
26
|
+
export const OFFICE_ACT_LIMITS = { perMinute: 6, perHour: 60, say: 40, minSeconds: 5, maxSeconds: 120, defaultSeconds: 30 };
|
|
27
|
+
export const OFFICE_POSES = ["idle", "working", "needs", "paused"];
|
|
28
|
+
const MINUTE_MS = 60_000, HOUR_MS = 60 * MINUTE_MS;
|
|
29
|
+
// Control characters, line breaks, and the invisible and direction-changing ones (zero-width, bidi embeddings/isolates).
|
|
30
|
+
const CONTROL = /[\u0000-\u001f\u007f-\u009f\u200b-\u200f\u2028-\u202e\u2060-\u2069\ufeff]/;
|
|
31
|
+
/**
|
|
32
|
+
* A stored office's members, as the page reads them (fleet-office-model.js membersOf): instance names, or `team:<name>`
|
|
33
|
+
* for a team's members; none means everyone the dashboard lists. A name the chart does not have is left out.
|
|
34
|
+
*/
|
|
35
|
+
export function officeMembers(office, chart) {
|
|
36
|
+
const listed = new Set([...chart.names, ...chart.teams.flatMap(t => t.members)]);
|
|
37
|
+
if (!office.members.length)
|
|
38
|
+
return [...listed];
|
|
39
|
+
const out = [];
|
|
40
|
+
for (const m of office.members) {
|
|
41
|
+
const team = m.startsWith("team:") ? chart.teams.find(t => t.name === m.slice(5)) : undefined;
|
|
42
|
+
for (const n of team ? team.members : listed.has(m) ? [m] : [])
|
|
43
|
+
if (!out.includes(n))
|
|
44
|
+
out.push(n);
|
|
45
|
+
}
|
|
46
|
+
return out;
|
|
47
|
+
}
|
|
48
|
+
/** Whether an office's style walks its people (a pack with stateZones, as the page's `zones`); else it draws desks. */
|
|
49
|
+
export const officeWalks = (pack) => !!pack?.stateZones;
|
|
50
|
+
/** The spots of an office's skin: a kept zones pack's, with the office's overrides on it; a desks style's are none. */
|
|
51
|
+
export function officeSpots(office, pack) {
|
|
52
|
+
if (!pack || !officeWalks(pack))
|
|
53
|
+
return { seats: [], waypoints: [], npcs: [], door: null };
|
|
54
|
+
const applied = applyOverrides(pack, fitNight(pack, office.overrides ?? null)); // #2665: a night place the pack lost: left out
|
|
55
|
+
const p = applied.ok ? applied.pack : pack;
|
|
56
|
+
return {
|
|
57
|
+
seats: Object.values(p.areas).flatMap(a => a.seats.map((s, index) => ({ area: a.name, index, x: s.x, y: s.y }))),
|
|
58
|
+
waypoints: p.waypoints.map(w => ({ id: w.id, x: w.x, y: w.y })),
|
|
59
|
+
npcs: p.furniture.map(f => ({ id: f.id, label: f.label ?? null, x: f.x, y: f.y })),
|
|
60
|
+
door: { x: p.door.x, y: p.door.y },
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
/** How often one instance may call office_set: 6 a minute and 60 an hour, accepted calls only (monotonic clock). */
|
|
64
|
+
export class OfficeActLimiter {
|
|
65
|
+
now;
|
|
66
|
+
limits;
|
|
67
|
+
calls = new Map();
|
|
68
|
+
constructor(now = () => performance.now(), limits = OFFICE_ACT_LIMITS) {
|
|
69
|
+
this.now = now;
|
|
70
|
+
this.limits = limits;
|
|
71
|
+
}
|
|
72
|
+
recent(instance, now) {
|
|
73
|
+
const kept = (this.calls.get(instance) ?? []).filter(t => now - t < HOUR_MS);
|
|
74
|
+
if (kept.length)
|
|
75
|
+
this.calls.set(instance, kept);
|
|
76
|
+
else
|
|
77
|
+
this.calls.delete(instance);
|
|
78
|
+
return kept;
|
|
79
|
+
}
|
|
80
|
+
/** Ms until `instance` may call again (0: now). Changes nothing. */
|
|
81
|
+
waitMs(instance) {
|
|
82
|
+
const now = this.now(), kept = this.recent(instance, now), waits = [0];
|
|
83
|
+
const minute = kept.filter(t => now - t < MINUTE_MS);
|
|
84
|
+
if (minute.length >= this.limits.perMinute)
|
|
85
|
+
waits.push(MINUTE_MS - (now - minute[minute.length - this.limits.perMinute]));
|
|
86
|
+
if (kept.length >= this.limits.perHour)
|
|
87
|
+
waits.push(HOUR_MS - (now - kept[kept.length - this.limits.perHour]));
|
|
88
|
+
return Math.max(0, Math.ceil(Math.max(...waits)));
|
|
89
|
+
}
|
|
90
|
+
/** Count an accepted call. */
|
|
91
|
+
record(instance) { const now = this.now(); this.calls.set(instance, [...this.recent(instance, now), now]); }
|
|
92
|
+
forget(instance) { this.calls.delete(instance); }
|
|
93
|
+
}
|
|
94
|
+
const refuse = (error, message, extra = {}) => ({ error, message, ...extra });
|
|
95
|
+
export class OfficeActs {
|
|
96
|
+
deps;
|
|
97
|
+
limiter;
|
|
98
|
+
acts = new Map();
|
|
99
|
+
timer = null;
|
|
100
|
+
/** The wall clock an act's since / until are on (the page's). */
|
|
101
|
+
now;
|
|
102
|
+
constructor(deps, opts = {}) {
|
|
103
|
+
this.deps = deps;
|
|
104
|
+
this.limiter = opts.limiter ?? new OfficeActLimiter();
|
|
105
|
+
this.now = opts.now ?? (() => Date.now());
|
|
106
|
+
}
|
|
107
|
+
/** Drop the acts that ended; true when one did. */
|
|
108
|
+
prune() {
|
|
109
|
+
const now = this.now();
|
|
110
|
+
let dropped = false;
|
|
111
|
+
for (const [name, act] of this.acts)
|
|
112
|
+
if (act.until <= now) {
|
|
113
|
+
this.acts.delete(name);
|
|
114
|
+
dropped = true;
|
|
115
|
+
}
|
|
116
|
+
return dropped;
|
|
117
|
+
}
|
|
118
|
+
/** One timer, for the next act to end: it is dropped then and every page hears it. */
|
|
119
|
+
schedule() {
|
|
120
|
+
if (this.timer) {
|
|
121
|
+
clearTimeout(this.timer);
|
|
122
|
+
this.timer = null;
|
|
123
|
+
}
|
|
124
|
+
if (!this.acts.size)
|
|
125
|
+
return;
|
|
126
|
+
const next = Math.min(...[...this.acts.values()].map(a => a.until));
|
|
127
|
+
this.timer = setTimeout(() => { this.timer = null; if (this.prune())
|
|
128
|
+
this.announce();
|
|
129
|
+
else
|
|
130
|
+
this.schedule(); }, Math.max(0, next - this.now()) + 5);
|
|
131
|
+
this.timer.unref?.();
|
|
132
|
+
}
|
|
133
|
+
announce() {
|
|
134
|
+
this.schedule();
|
|
135
|
+
try {
|
|
136
|
+
this.deps.changed(this.live());
|
|
137
|
+
}
|
|
138
|
+
catch { /* a page reads GET /ui/office-acts on opening */ }
|
|
139
|
+
}
|
|
140
|
+
/** The live acts (until ahead), the most recently set last: GET /ui/office-acts and the `office_acts` event. */
|
|
141
|
+
live() {
|
|
142
|
+
if (this.prune())
|
|
143
|
+
queueMicrotask(() => this.announce());
|
|
144
|
+
return [...this.acts.values()].map(a => ({ ...a }));
|
|
145
|
+
}
|
|
146
|
+
/** This instance's live act, or null. */
|
|
147
|
+
actOf(instance) {
|
|
148
|
+
const a = this.acts.get(instance);
|
|
149
|
+
return a && a.until > this.now() ? { ...a } : null;
|
|
150
|
+
}
|
|
151
|
+
/** The stored offices `instance` is a member of, in their stored order. */
|
|
152
|
+
officesOf(instance) {
|
|
153
|
+
const chart = this.deps.chart();
|
|
154
|
+
return this.deps.offices().filter(o => officeMembers(o, chart).includes(instance));
|
|
155
|
+
}
|
|
156
|
+
seen(o, people) {
|
|
157
|
+
const members = officeMembers(o, this.deps.chart()).map(name => {
|
|
158
|
+
const display = people.displayName(name);
|
|
159
|
+
return { name, ...(display ? { display_name: display } : {}), state: people.stateOf(name) };
|
|
160
|
+
});
|
|
161
|
+
const pack = this.deps.pack(o.skin);
|
|
162
|
+
return { id: o.id, name: o.name, skin: o.skin, walks: officeWalks(pack), members, spots: officeSpots(o, pack) };
|
|
163
|
+
}
|
|
164
|
+
/** The office a call names, or the only one it is in; else a refusal naming them. */
|
|
165
|
+
pick(wanted, mine) {
|
|
166
|
+
if (!mine.length)
|
|
167
|
+
return { refused: refuse("no_office", "You are in no stored office (Fleet → Org chart → Office): a person adds you to one first.") };
|
|
168
|
+
const ids = mine.map(o => `${o.id} (${o.name})`).join(", ");
|
|
169
|
+
if (wanted !== undefined) {
|
|
170
|
+
const o = mine.find(m => m.id === wanted);
|
|
171
|
+
return o ? { office: o } : { refused: refuse("office", `You are not in an office "${wanted}". Yours: ${ids}.`) };
|
|
172
|
+
}
|
|
173
|
+
if (mine.length > 1)
|
|
174
|
+
return { refused: refuse("office_required", `You are in ${mine.length} offices; name one with office: ${ids}.`) };
|
|
175
|
+
return { office: mine[0] };
|
|
176
|
+
}
|
|
177
|
+
/** office_view { office? }: the offices it is in, its act and when office_set may be called again. */
|
|
178
|
+
view(instance, raw) {
|
|
179
|
+
const v = validateArgs(OfficeViewArgs, raw ?? {}, "office_view");
|
|
180
|
+
if (!v.ok)
|
|
181
|
+
return refuse("invalid", v.error);
|
|
182
|
+
let shown = this.officesOf(instance);
|
|
183
|
+
if (v.data.office !== undefined) {
|
|
184
|
+
const one = this.pick(v.data.office, shown);
|
|
185
|
+
if ("refused" in one)
|
|
186
|
+
return one.refused;
|
|
187
|
+
shown = [one.office];
|
|
188
|
+
}
|
|
189
|
+
const people = this.deps.people();
|
|
190
|
+
return { offices: shown.map(o => this.seen(o, people)), act: this.actOf(instance), cooldown_ms: this.limiter.waitMs(instance) };
|
|
191
|
+
}
|
|
192
|
+
/** office_set { office?, go?, say?, pose?, seconds?, clear? }: its own act, placed (replacing one), or cleared. */
|
|
193
|
+
set(instance, raw) {
|
|
194
|
+
const wait = this.limiter.waitMs(instance);
|
|
195
|
+
if (wait > 0)
|
|
196
|
+
return refuse("rate_limited", `Too many office_set calls (at most ${OFFICE_ACT_LIMITS.perMinute} a minute, ${OFFICE_ACT_LIMITS.perHour} an hour); try again in ${Math.ceil(wait / 1000)} s.`, { cooldown_ms: wait });
|
|
197
|
+
const v = validateArgs(OfficeSetArgs, raw ?? {}, "office_set");
|
|
198
|
+
if (!v.ok)
|
|
199
|
+
return refuse("invalid", v.error);
|
|
200
|
+
const a = v.data;
|
|
201
|
+
const targets = a.go ? ["seat", "waypoint", "person"].filter(k => a.go[k] !== undefined) : [];
|
|
202
|
+
if (a.go && targets.length !== 1)
|
|
203
|
+
return refuse("go", "go: exactly one of seat, waypoint or person.");
|
|
204
|
+
if (a.clear !== undefined && a.clear !== true)
|
|
205
|
+
return refuse("clear", "clear: true, or leave it out.");
|
|
206
|
+
if (a.clear && (a.go || a.say !== undefined || a.pose || a.seconds !== undefined))
|
|
207
|
+
return refuse("clear", "clear: true goes alone.");
|
|
208
|
+
if (!a.clear && !a.go && a.say === undefined && !a.pose)
|
|
209
|
+
return refuse("nothing", "Nothing to do: give go, say or pose (or clear: true).");
|
|
210
|
+
let say;
|
|
211
|
+
if (a.say !== undefined) {
|
|
212
|
+
say = a.say.trim();
|
|
213
|
+
if (!say || [...say].length > OFFICE_ACT_LIMITS.say || CONTROL.test(say))
|
|
214
|
+
return refuse("say", `say: 1–${OFFICE_ACT_LIMITS.say} characters on one line, no control characters.`);
|
|
215
|
+
}
|
|
216
|
+
if (a.seconds !== undefined && (!Number.isFinite(a.seconds) || a.seconds < OFFICE_ACT_LIMITS.minSeconds || a.seconds > OFFICE_ACT_LIMITS.maxSeconds)) {
|
|
217
|
+
return refuse("seconds", `seconds: ${OFFICE_ACT_LIMITS.minSeconds} to ${OFFICE_ACT_LIMITS.maxSeconds}.`);
|
|
218
|
+
}
|
|
219
|
+
const mine = this.officesOf(instance);
|
|
220
|
+
if (a.clear) {
|
|
221
|
+
// Ending its own act needs nothing else: not an office named, not even being in one still (it may have been taken
|
|
222
|
+
// out of every office since it acted).
|
|
223
|
+
const had = this.acts.delete(instance);
|
|
224
|
+
this.limiter.record(instance);
|
|
225
|
+
if (had)
|
|
226
|
+
this.announce();
|
|
227
|
+
return { cleared: had, act: null, cooldown_ms: this.limiter.waitMs(instance) };
|
|
228
|
+
}
|
|
229
|
+
const picked = this.pick(a.office, mine);
|
|
230
|
+
if ("refused" in picked)
|
|
231
|
+
return picked.refused;
|
|
232
|
+
const o = picked.office;
|
|
233
|
+
let point, person;
|
|
234
|
+
if (a.go) {
|
|
235
|
+
const pack = this.deps.pack(o.skin);
|
|
236
|
+
// A desks style (a built-in one, or a pack without stateZones) walks nobody: refused, not accepted to do nothing (review).
|
|
237
|
+
if (!officeWalks(pack))
|
|
238
|
+
return refuse("go", `go: ${o.id} is drawn as desks (its style "${o.skin}"): nobody walks there. say and pose still show.`);
|
|
239
|
+
const spots = officeSpots(o, pack);
|
|
240
|
+
if (a.go.seat !== undefined) {
|
|
241
|
+
const m = /^([A-Za-z0-9_-]{1,40}):(\d{1,3})$/.exec(a.go.seat), seat = m ? spots.seats.find(s => s.area === m[1] && s.index === Number(m[2])) : undefined;
|
|
242
|
+
if (!seat)
|
|
243
|
+
return refuse("seat", spots.seats.length ? `go.seat: "${a.go.seat}" is not a seat of ${o.id}; office_view lists them as "area:index".` : `go.seat: ${o.id} has no seats to walk to (its style "${o.skin}" has none).`);
|
|
244
|
+
point = { x: seat.x, y: seat.y };
|
|
245
|
+
}
|
|
246
|
+
else if (a.go.waypoint !== undefined) {
|
|
247
|
+
const w = spots.waypoints.find(p => p.id === a.go.waypoint);
|
|
248
|
+
if (!w)
|
|
249
|
+
return refuse("waypoint", spots.waypoints.length ? `go.waypoint: "${a.go.waypoint}" is not a waypoint of ${o.id}; office_view lists them.` : `go.waypoint: ${o.id} has no waypoints.`);
|
|
250
|
+
point = { x: w.x, y: w.y };
|
|
251
|
+
}
|
|
252
|
+
else {
|
|
253
|
+
const who = a.go.person;
|
|
254
|
+
if (who === instance)
|
|
255
|
+
return refuse("person", "go.person: someone other than you.");
|
|
256
|
+
if (!officeMembers(o, this.deps.chart()).includes(who))
|
|
257
|
+
return refuse("person", `go.person: "${who}" is not in ${o.id}; office_view lists its members.`);
|
|
258
|
+
person = who;
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
const since = this.now(), seconds = a.seconds ?? OFFICE_ACT_LIMITS.defaultSeconds;
|
|
262
|
+
const act = { instance, office: o.id, ...(point ?? {}), ...(person ? { person } : {}), ...(say ? { say } : {}), ...(a.pose ? { pose: a.pose } : {}),
|
|
263
|
+
since, until: since + Math.round(seconds * 1000), state: this.deps.people().stateOf(instance) };
|
|
264
|
+
this.acts.delete(instance); // the newest last
|
|
265
|
+
this.acts.set(instance, act);
|
|
266
|
+
this.limiter.record(instance);
|
|
267
|
+
this.announce();
|
|
268
|
+
return { act: { ...act }, cooldown_ms: this.limiter.waitMs(instance) };
|
|
269
|
+
}
|
|
270
|
+
/** An instance was removed: its act and its counters go. */
|
|
271
|
+
forget(instance) { this.limiter.forget(instance); if (this.acts.delete(instance))
|
|
272
|
+
this.announce(); }
|
|
273
|
+
/** Stop the expiry timer (the fleet stopping; a test). */
|
|
274
|
+
close() { if (this.timer)
|
|
275
|
+
clearTimeout(this.timer); this.timer = null; }
|
|
276
|
+
/** The dispatcher both doors share (typed IPC from the daemon, the agent endpoint for agend-agent). */
|
|
277
|
+
handle(instance, tool, args) {
|
|
278
|
+
if (tool === "office_view")
|
|
279
|
+
return this.view(instance, args);
|
|
280
|
+
if (tool === "office_set")
|
|
281
|
+
return this.set(instance, args);
|
|
282
|
+
return { error: "unknown_tool" };
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
//# sourceMappingURL=web-office-acts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"web-office-acts.js","sourceRoot":"","sources":["../src/web-office-acts.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { type CheckedPack } from "./ui/fleet-office-pack.js";
|
|
2
|
+
/** #2632: 160 files and 20 MiB a pack (was 64, 6 MiB) — room for a whole fleet's character sets. */
|
|
3
|
+
export declare const SKIN_LIMITS: {
|
|
4
|
+
readonly packs: 16;
|
|
5
|
+
readonly files: 160;
|
|
6
|
+
readonly fileBytes: number;
|
|
7
|
+
readonly packBytes: number;
|
|
8
|
+
readonly manifestBytes: number;
|
|
9
|
+
readonly side: 4096;
|
|
10
|
+
readonly pixels: number;
|
|
11
|
+
readonly name: 60;
|
|
12
|
+
readonly src: 200;
|
|
13
|
+
};
|
|
14
|
+
/** The most an upload's body may be: every picture's base64 (4/3) plus the manifest and the envelope. */
|
|
15
|
+
export declare const SKIN_WIRE_BYTES: number;
|
|
16
|
+
export interface SkinFile {
|
|
17
|
+
id: string;
|
|
18
|
+
bytes: number;
|
|
19
|
+
width: number;
|
|
20
|
+
height: number;
|
|
21
|
+
}
|
|
22
|
+
export interface SkinRecord {
|
|
23
|
+
version: 1;
|
|
24
|
+
id: string;
|
|
25
|
+
name: string;
|
|
26
|
+
sha: string;
|
|
27
|
+
bytes: number;
|
|
28
|
+
uploaded_at: number;
|
|
29
|
+
by: string;
|
|
30
|
+
manifest: Record<string, unknown>;
|
|
31
|
+
files: Record<string, SkinFile>;
|
|
32
|
+
}
|
|
33
|
+
export interface SkinSummary {
|
|
34
|
+
id: string;
|
|
35
|
+
name: string;
|
|
36
|
+
sha: string;
|
|
37
|
+
bytes: number;
|
|
38
|
+
files: number;
|
|
39
|
+
uploaded_at: number;
|
|
40
|
+
}
|
|
41
|
+
export type SkinRefusal = {
|
|
42
|
+
ok: false;
|
|
43
|
+
status: 400 | 404 | 409 | 413 | 503;
|
|
44
|
+
error: string;
|
|
45
|
+
detail?: string;
|
|
46
|
+
};
|
|
47
|
+
export type SkinChecked = {
|
|
48
|
+
ok: true;
|
|
49
|
+
record: SkinRecord;
|
|
50
|
+
pack: CheckedPack;
|
|
51
|
+
pictures: Map<string, Buffer>;
|
|
52
|
+
} | SkinRefusal;
|
|
53
|
+
/** Whether `src` is a file name a pack may use (fleet-office-pack.js's rule, and no hidden or empty segment). */
|
|
54
|
+
export declare function skinFileNameOk(src: string): boolean;
|
|
55
|
+
/**
|
|
56
|
+
* One picture: a PNG, walked to its end, its metadata stripped, within the caps. { kept, width, height } or a refusal
|
|
57
|
+
* naming the file.
|
|
58
|
+
*/
|
|
59
|
+
export declare function checkSkinPicture(name: string, bytes: Uint8Array): {
|
|
60
|
+
ok: true;
|
|
61
|
+
kept: Buffer;
|
|
62
|
+
width: number;
|
|
63
|
+
height: number;
|
|
64
|
+
} | SkinRefusal;
|
|
65
|
+
/**
|
|
66
|
+
* An upload, as the page sends it: { manifest, files: { <src>: <base64> }, name? }. Every rule, or a refusal naming
|
|
67
|
+
* where it broke. Pure (no I/O); `by` and `now` are kept in the record.
|
|
68
|
+
*/
|
|
69
|
+
export declare function checkSkinUpload(body: unknown, by: string, now: number): SkinChecked;
|
|
70
|
+
export declare class OfficeSkinStore {
|
|
71
|
+
private readonly now;
|
|
72
|
+
private state;
|
|
73
|
+
readonly dir: string;
|
|
74
|
+
constructor(dataDir: string, now?: () => number);
|
|
75
|
+
private load;
|
|
76
|
+
readable(): boolean;
|
|
77
|
+
/** A rev that moves with any change (the packs' ids and shas), the same after a restart. */
|
|
78
|
+
rev(): string;
|
|
79
|
+
/** GET /ui/office-skins: what every viewer's style picker lists. */
|
|
80
|
+
list(): {
|
|
81
|
+
rev: string;
|
|
82
|
+
packs: SkinSummary[];
|
|
83
|
+
readable: boolean;
|
|
84
|
+
limits: typeof SKIN_LIMITS;
|
|
85
|
+
};
|
|
86
|
+
/** GET /ui/office-skins/<id>: the manifest as uploaded and each file's picture id; null when there is no such pack. */
|
|
87
|
+
get(id: string): {
|
|
88
|
+
id: string;
|
|
89
|
+
name: string;
|
|
90
|
+
sha: string;
|
|
91
|
+
manifest: Record<string, unknown>;
|
|
92
|
+
files: Record<string, string>;
|
|
93
|
+
} | null;
|
|
94
|
+
/** The checked pack (an office's overrides are checked against it), or null. */
|
|
95
|
+
pack(id: string): CheckedPack | null;
|
|
96
|
+
/** One picture of a pack, by its id (the sha of its bytes); null when the pack does not have it. */
|
|
97
|
+
picture(id: string, file: string): Buffer | null;
|
|
98
|
+
/** Keep an upload (POST /ui/office-skins). A pack is immutable: its id taken is a 409 (delete it first). */
|
|
99
|
+
add(body: unknown, by: string): {
|
|
100
|
+
ok: true;
|
|
101
|
+
rev: string;
|
|
102
|
+
pack: SkinSummary;
|
|
103
|
+
} | SkinRefusal;
|
|
104
|
+
/** Remove a pack (DELETE /ui/office-skins/<id>). Offices naming it are drawn in a built-in style until it is back. */
|
|
105
|
+
remove(id: string): {
|
|
106
|
+
ok: true;
|
|
107
|
+
rev: string;
|
|
108
|
+
} | SkinRefusal;
|
|
109
|
+
}
|