Monday — workspaces, sharing and the internals (part 2)
Part 2 of the Monday page, kept for history: workspaces, accounts, board sharing and invites, the local data mirror, board templates and the automation engine — the parts carried over unchanged into what is now called Mission Control.
What it is
This is part 2 of the Monday page — a historical name for the board app now called Mission Control. Everything here was carried over unchanged in the rename.
Where to find it
Under the current name: see mission-control.md, where this material now lives.
How it behaves
Workspaces functionality (post-Phase-4 fast-follow)
A pixel-near rebuild of monday's Workspaces across three surfaces. (1) Left-nav header — the plain <select> became a monday workspace block: a colored icon tile (initial + home glyph; tint from a new workspaces.color or a deterministic id-hash fallback), a name + switcher popover, and a ⋯ actions menu (WorkspaceMenu) — Manage workspace, Edit workspace (icon-color + name + description modal), Sort workspace (a per-workspace localStorage display order), Add new workspace, Browse all workspaces, View archive/trash, and a confirm-gated Delete (disabled for the Main/last workspace). (2) Manage-workspace page (/workspace/:id, rebuilt WorkspacePage) — a banner (large icon, name, inline-editable description, Feedback (inert) / Members → /users / ⋯) over Recents · Content · Permissions tabs: Content is a boards+dashboards asset table (creator avatar, creation date, Last modified, folder, search, selection-delete, a real Cleanup mode that flags assets unmodified 30+ days; the AI-summary column is intentionally dropped); Recents reuses the Home recent-visit locators + favorite stars; Permissions sets the workspace access level (Open/Closed via workspaces.kind), manages workspace owners (people only — add/remove, last owner is guarded), and — for a closed workspace — the specific members & teams with access (an open workspace just reads "everyone in your account"), all via a searchable PrincipalPicker over the account directory + teams. (3) User-management page (/users, UserManagementPage) — the account directory as a full table with an editable role dropdown (PATCH /members/:id), a Products multi-select (real, seeded with work_management), status, Teams chips, joined/invited dates, an Invite dialog (reuses the member invite), and a Manage teams modal over a real Teams subsystem.
Backend (monday-back): migration 0012 adds workspaces.color + description (flow through /nav/tree); 0013 adds boards.updatedAt + dashboards.updatedAt ("Last modified" — auto-bumped via Drizzle $onUpdateFn on row edits and via touchBoard() at the publish() realtime chokepoint on content edits); 0014 adds the teams + team_members tables + a teamsRoutes module (account-scoped CRUD + membership); 0015 adds users.products (jsonb) + extends PATCH /members/:id (role/products) and the member payload (products, joinedAt, invitedAt). PATCH /workspaces/:id gained color/description/kind. Migration 0016 adds the workspace_principals table (polymorphic user|team rows, owner|member role) backing the Permissions tab — seeded so every workspace keeps a real owner (the creator on POST /workspaces + register; the account's earliest user in the migration backfill) — with GET/POST/DELETE /workspaces/:id/principals (owners-are-users, never-zero-owners 409, and account-isolation guards). Boards gained GET /boards/archived + /boards/trash listings and a POST /boards/:id/restore (clears archived + soft-delete; ownership via the board→workspace→account join). Pure Content-tab + Permissions helpers (asset shaping + staleness; owner-removal + picker-candidate filtering) are unit-tested (tests/unit/plugins/mission-control/manage-workspace.test.ts, workspace-permissions.test.ts); every route has bun coverage (the backend package’s workspace-permissions bun test, not tracked in this repo). Design specs docs/superpowers/specs/2026-06-08-monday-workspaces-design.md, docs/superpowers/specs/mission-control-workspace-permissions-design.md.
Kanban card actions + "⋯" menu (post-Phase-4 fast-follow)
Hovering a Kanban card reveals monday's two actions in the top-right: a pencil (opens the item card) and a ⋯ overflow menu (features/board/KanbanCardMenu.tsx, on the shared Popover). The menu mirrors monday's real order: Open task · Move to ▸ · Duplicate ▸ · Copy name · Copy task link · Add subitem · Customize cards ▸ · Archive · Delete (Delete confirms first). "Move to" and "Duplicate" open right-side flyout submenus (features/board/CardMenuFlyout.tsx — SubmenuRow/FlyoutItem, portaled out of the menu so they aren't clipped, flipping left near the screen edge): Move to → Move to group (lists the board's other groups → patchItem({groupId})) or Move to board (lists other boards from /nav/tree → a new POST /items/:id/move-to-board, which reassigns the board + a target group and drops the board-scoped column values); Duplicate → without / with updates (the existing POST /items/:id/duplicate, with ?includeUpdates=true also cloning the conversation thread). Copy name / Copy task link write to the clipboard (the link is #/board/<id>?item=<id>; BoardView opens an item from a ?item= param on load).
Subitems are real item rows tagged with parent_item_id (no migration — the column already existed). GET /boards/:id/full now returns top-level rows in items and child rows separately in subitems, so every other view is unchanged; the Kanban card renders its subitems as nested name-only mini-cards with a footer count badge and an inline "+ Add sub-task" composer (POST /items/:id/subitems), which the menu's Add subitem row opens and focuses. Backend behavior is covered by monday-back's item-card-actions bun test (a package not tracked in this repo); the subitem grouping helper is unit-tested (groupSubitemsByParent in tests/unit/plugins/mission-control/kanban-data.test.ts).
Account & passwords (parity fast-follow)
The login screen gained a "Forgot password?" link: enter your email and you get a neutral confirmation ("if that email exists, we've sent a reset link") that never reveals whether the address is registered. Because the plugin runs on an in-memory router — email links can't deep-link into it, the same constraint that puts the invitation-accept pages on the backend — the reset itself happens on a backend-served HTML page the emailed link points to. The reset token is single-use, expires in one hour, and a fresh request supersedes any earlier link; completing a reset signs out all existing sessions.
Signed in, the top-right account menu (the avatar) adds "Change password" — a modal that requires your current password and a new one of at least 8 characters. Changing it signs out all your OTHER devices while the current one stays signed in.
Logout is now server-side — signing out revokes the session on the backend too (not just a local token wipe), so it takes effect even after a long idle. (There is still no email verification on signup — accounts are usable immediately.)
Board sharing & private-board enforcement (parity fast-follow)
The board header gained a Share button → a modal with a copyable join link and the board's member list. The join link points at a backend-served join page (same pattern as reset/invite — the in-memory router can't be deep-linked); another user on the same account signs in there and is added to the board as an editor. Private boards are now enforced end-to-end: only a board's members — owner / editor / viewer principals, held directly or via a team — can see a board in listings or open it. Only the board owner can mint, rotate, or revoke the share link or add/remove members.
Workspace invite link (parity fast-follow)
The workspace ⋯ menu gained "Copy invite link." It reuses the workspace's existing invite link and only mints a new one when none exists yet, so the link stays stable across copies. Only workspace owners can manage the link.
Local SQLite mirror (Phase 5A)
Phase 5A adds a local SQLite mirror of Monday board data for offline access and as the foundation for automation (Phase 5B), CLI (5C), inbox (5D), and UI (5F). Five tables — pm_boards, pm_items, pm_columns, pm_column_values, pm_sync_state — cache the data returned by GET /boards/:id/full. These tables are a read cache, not the authority; the Monday backend (Postgres) remains the source of truth.
A background sync service (pm-sync-service) runs on a 5-minute heartbeat, re-fetching any board whose last_sync_at is older than 5 minutes. Each sync writes all tables in a single SQLite transaction (no partial state) and soft-deletes items no longer present in the response. A WebSocket connection to the Monday backend's /realtime endpoint listens for board-changed events and triggers an immediate re-sync of the affected board, so changes made in the Monday UI appear locally within seconds.
The sync service is gated on mondayEnabled + mondayRefreshToken — if Monday is disabled or the user hasn't logged in, the service does nothing. Auth is handled by a main-process token manager (pm-auth) that reads the encrypted refresh token from settings, deduplicates concurrent refresh calls, and retries on 401.
Board automation engine (Phase 5C)
Phase 5C adds an event-driven automation engine that fires action chains when board data changes. The sync service snapshots board state before each sync, diffs after, and emits typed BoardEvent objects (7 event types: item_created, item_archived, item_status_changed, item_assigned, item_due_date_passed, item_moved_to_group, item_column_changed). The automation engine matches events against user-defined rules in pm_board_automations and dispatches action chains through the existing Omniscio automation dispatcher.
Safety controls: master toggle (pmAutomationsEnabled, default off), event dedup (SQLite pm_automation_processed_events with 7-day retention), 5-second per-rule cooldown, stop-on-match, and always-persist run records (even on failure).
A due-date checker (pm-due-date-checker) runs every 15 minutes, scans date columns for overdue items, and feeds item_due_date_passed events into the engine. Two v2 actions — pm.move-item and pm.set-column-value — call the Monday backend REST API via pmAuthedFetch.
CLI routes: GET/POST/PATCH/DELETE /pm/automations — all auth-gated, rate-limited, Zod-validated. IPC: 6 channels for CRUD + presets + run history, all Zod-validated with push on mutation. Five preset templates (status-done-notify, new-item-assign, due-date-overdue-move, assigned-to-me-inbox, blocked-create-session).
Per-rule approval: rules created via CLI default to approval_status = 'pending_approval' and are excluded from listActiveBoardAutomations() until approved. A pm-automation-approval inbox source surfaces pending rules in the unified inbox (gated on mondayEnabled + pmAutomationsEnabled). IPC channels: pm:board-automation:pending-list (cross-board pending query) and pm:board-automation:set-approval (approve/reject).
Feature gating: registered as 'pm-automations' in UNRELEASED_FEATURES with status 'in-development'. No renderer UI yet (that is Phase 5F).
- Contract:
pm-automation-contract.md - Key files:
src/main/services/pm/automation/pm-automation-service.ts(engine),src/main/services/pm/pm-board-diff.ts(diff),src/main/services/pm/date-scanning/pm-due-date-checker.ts(cron),src/main/services/pm/automation/pm-automation-queries.ts(CRUD),src/main/services/pm/automation/pm-automation-presets.ts(presets),src/main/ipc/pm-automation-handlers.ts(IPC),src/main/services/cli/cli-server-pm-automation-routes.ts(CLI)
PM event channel bridge
Bridges PM board events into the channel automation engine (automations table), adding a fourth trigger type on_pm_event alongside on_message, manual, and on_session_state. This lets users create channel automations like "when a task goes overdue, nudge me in inbox" using the same rules UI as any other automation.
How it works: the PM sync service calls bridgePmEventsToChannelAutomations(events) fire-and-forget after each sync. The bridge checks both automationsEnabled and pmAutomationsEnabled, queries listEnabledPmEventAutomations() (channel automations with triggerType: 'on_pm_event'), matches events against each rule's PmEventConfig (event type + board scope + optional board/column filter), enforces a 5-second per-rule cooldown, deduplicates within a batch using bridge:-prefixed keys, and dispatches through dispatchActionChain() passing the BoardEvent as v2 trigger data so actions can read itemId/boardId from ctx.trigger. Errors are caught per-automation and never propagate to the sync pipeline.
Three v2 actions for PM-triggered automations:
pm.update-linked-status— updates a column value on the triggering item (readsitemIdfromctx.trigger; skips gracefully if no trigger context)pm.add-comment— adds a comment/update to the triggering item (same trigger skip behavior)pm.create-item— creates a new item on a specified board (does NOT require trigger context)
Four preset templates in the channel automation presets: Overdue Task Nudge (pm-overdue-nudge), Status Change Update (pm-status-changed-update), Comment on New Items (pm-new-item-comment, v2), Assignment Notification (pm-assignment-alert).
Architecture notes: the bridge is SEPARATE from the board automation engine (Phase 5C) — board automations use pm_board_automations table, channel bridge uses the automations table with pm_event_config column. The dispatchActionChain function accepts an optional v2TriggerData parameter that populates trigger on the v2 action context.
- Contract:
pm-automation-contract.md(§ PM event channel bridge) - Key files:
src/main/services/pm/pm-event-channel-bridge.ts(bridge),src/main/services/automation/v2/dispatcher.ts(v2TriggerData),src/main/services/automation/v2/actions/pm-update-linked-status.ts,pm-add-comment.ts,pm-create-item.ts(actions),src/main/services/automation/legacy/automation-presets.ts(presets),src/main/db/migrations/20260720203018-add-pm-event-config-to-automations.ts(migration)
Workflow Engine Nodes (Phase 5H)
Phase 5H integrates PM boards into the Workflow Engine with a poll-based trigger and five action nodes. The trigger watcher polls all synced boards every 60 seconds, computing deltas to fire workflows. The actions proxy writes through to the Monday backend via pmAuthedFetch.
Trigger node (trigger.pm_item): configurable event filter (item_status_changed, item_assigned, item_created, item_overdue), optional boardId/columnId scoping. First tick establishes a baseline (no false-fires on start). Dedup by pm-trigger:boardId:itemId:event:value. Kill switch: AMC_DISABLE_PM_WORKFLOW_TRIGGER.
Action nodes:
action.pm_create_item— create an item on a board (title, group, column values via JSON)action.pm_transition— set a column value (status transition)action.pm_comment— add an update/comment to an itemaction.pm_assign— assign a person to an item (personsAndTeams column)action.pm_search— search items by name/text (reads from local SQLite mirror)
Architecture: nodes are auto-registered via Vite's import.meta.glob('./nodes/*-node.ts'). Side effects route through WorkflowEnginePorts (never raw DB/fetch from a node). 'pm' is added to WORKFLOW_TRIGGER_SOURCES and renders as "PM Board" in the run-history viewer.
- Contract:
pm-workflow-nodes-contract.md - Key files:
src/main/services/workflow-engine/pm-item-trigger.ts(watcher),src/main/services/workflow-engine/nodes/pm-*-node.ts(6 node files),src/main/services/workflow-engine/ports.ts(port implementations),src/main/services/workflow-engine/types.ts(port interface)
Inbox source (Phase 5D)
Phase 5D adds a "board" inbox source that surfaces Monday board events as unified inbox rows. Six event types create rows: assigned to you, mentioned in an update, status changed on your item, due date approaching (1 day), due date passed, and automation fired. Events are detected locally from the Phase 5A SQLite mirror tables on each sync -- no Monday API polling beyond what the sync service already does.
How to use it: enable Settings → Features -> "Monday board events
in inbox" (on by default when Monday is enabled). Events appear as inbox rows
with a status-coloured dot routed through the status-* tokens (so custom themes
recolour it): the needs-you attention colour for most events, and the
error colour for overdue items. Click a row to see the item
name, board name, and a "Go to Board" button that opens the Monday panel.
Dismiss like any inbox item (far-future snooze with undo).
How it works (internals): the main-process pm-inbox-event-detector
subscribes to the pm:sync-updated push. On each sync it queries the pm_*
mirror tables, resolves the current user (cached from GET /auth/me), detects
which events are active, upserts them into pm_inbox_events (dedup on
event_type + item_id), soft-deletes cleared events, and emits
inbox-pm/updated if changed. The renderer's pm-inbox-store
(createDerivedInboxStore) listens for the push and projects events as
integration: 'board' items in the unified inbox. Dismiss uses the universal
far-future snooze pattern (kind 'board'). The detail pane routes through
InboxSummaryRedirectPane.
Data import/export (Phase 5G)
Two CLI routes let agent sessions move data between files and Monday boards:
- Export (
GET /pm/data/export/:boardId?format=csv|xlsx|json|txt) — fetches the board from the Monday backend, transforms to the requested format, writes a temp file, returns the path. Includes CSV formula injection defense. - Import (
POST /pm/data/import { filePath, newBoardName?, boardId?, format? }) — reads a local file (CSV/XLSX/JSON/TXT), auto-detects format from extension, infers column types (14 types: status, priority, date, numbers, email, phone, link, checkbox, dropdown, rating, long-text, text, plus header-name heuristics), detects groups from a "Group"/"Section" column, and creates boards/groups/columns/items on the Monday backend. Caps: 5000 rows, 50MB file size, 20K chars per cell.
Works independently of the Phase 5A local mirror — calls the Monday backend REST API directly via pm-auth.
- Contract:
pm-data-transfer-contract.md - Key files:
src/main/services/pm/data-transfer/(export, import, column inference, xlsx bridge, types),src/main/services/cli/cli-server-pm-data-transfer-routes.ts
Data Import (Phase 5F)
A one-time Python tool (monday-exports/import.py) that reads Monday.com xlsx board exports and imports them into the Monday clone backend via REST API. Two-pass workflow:
- Discover mode (
python import.py --discover): reads xlsx files frommonday-exports/boards/, infers column types from cell values, writescolumn-map.json. - Import mode (
python import.py --import --email X --password Y): readscolumn-map.json, creates boards/groups/columns/items/values on the backend via REST.
Successfully imported 29 boards with ~1,900 items. The tool handles all 18 column types (status, date, timeline, people, numbers, dropdown, files, rating, text, long-text, checkbox, link, email, phone, country, world-clock, week, priority). Design spec: docs/superpowers/specs/mission-control-data-import-design.md.
Board Templates (Phase 5C)
Save a board's full structure as a reusable template and deploy it into new boards. Right-click a board in the left nav → "Save as template" opens a dialog (name, description, shared/private visibility, include-items toggle). Templates are stored on the backend and browsable in a Template Gallery (opened from a "T" button in the left nav header) with three sections: built-in, team (shared), and private.
Deploy preview shows the template's groups, columns, views, and
automations. Each automation has a toggle and a cost badge ($) on
actions that invoke AI or spawn sessions (detected by isCostBearingAction
scanning the action chain for ai_classify, ai_generate, spawn_session).
Users can disable cost-bearing automations before deployment.
Template editor lets owners update name, description, icon, visibility, and the template's structure (rename/remove groups, columns, views, automations). Changes autosave with an 800ms debounce.
Portability: column and group references inside automations are replaced
with stable templateKeys (col_1, grp_1) on save and remapped back to
real IDs on deploy (matching by title, falling back to position).
- Contract:
pm-board-templates-contract.md - Key files:
src/main/services/pm/templates/pm-template-portability.ts(portability engine),src/main/services/cli/cli-server-pm-template-routes.ts(7 CLI routes),src/plugins/mission-control/web/features/templates/(gallery, deploy preview, save dialog, editor)
Calendar Overlay (Phase 5G)
PM due dates and sprint timelines appear as a visual overlay on the Calendar
alongside Google Calendar events. Items with date or timeline column
values render as CalendarEvents, color-coded by board with overdue items
highlighted in status-error red.
How to use it: enable Settings -> Monday -> "PM due dates in Calendar" (on by default when Monday is enabled). Due dates appear as single-day or timed events; sprint timelines appear as spanning bars across the calendar. Click any PM event to see the board name, date info, overdue warning, and an "Open in PM" button that navigates to the Monday panel.
How it works (internals): the CALENDAR_LIST_PM_EVENTS IPC handler queries
the pm_* SQLite mirror tables (joining pm_column_values with pm_items,
pm_columns, pm_boards, pm_groups), filters for date and timeline column
types, then transforms matching rows into CalendarEvent objects with PM
metadata fields (source: 'pm', pmBoardId, pmBoardColor, pmOverdue,
pmType). The calendar store fetches PM events in parallel with Google Calendar
via Promise.all and listens to pm:sync-updated for live updates. The
resolveEventColor() dispatcher routes PM events to getPmEventColor (board
color or overdue red) while Google events use the existing cascade.
- Contract:
pm-calendar-overlay-contract.md - Key files:
src/main/services/pm/calendar/pm-calendar-queries.ts(SQLite query),src/main/services/pm/calendar/pm-calendar-service.ts(transform),src/main/ipc/calendar-handlers.ts(handler),src/renderer/src/features/calendar/calendar-colors.ts(resolveEventColor)
Session Linking
Sessions can be linked to PM items bidirectionally. A linked session shows a PM item chip in the session header (accent-colored, displays the item name). Clicking the chip navigates to the Monday board; right-clicking unlinks.
Linking paths:
- At session creation: pass
pmItemIdtocreateSessionWithPrompt(thesessions.pm_item_idFK is set in the INSERT) - After creation: the
PM_SESSION_SET_LINKIPC channel sets or clears the link - From a PM item:
POST /pm/items/:id/start-sessionCLI route spawns a new session pre-linked to the item, with PM context injected viapmSessionContextProvider
Status sync: registerPmAgentLink() listens to sessionEvents.on('statusChanged').
When a linked session changes status, it maps to a closed vocabulary
(idle / running / needs_you / finished / error) and emits a
PM_SESSION_LINK_CHANGED push event. The chip subscribes via usePushListener
(300ms debounce) for live updates.
Data model: the FK is sessions.pm_item_id (nullable). A companion
pm_item_links row (entity_type = 'session') keeps the link browsable from
the item side. Both are written atomically in a SQLite transaction.
- Contract:
pm-session-link-contract.md - Key files:
src/main/services/pm/pm-agent-link.ts(core service),src/main/ipc/pm-session-link-handlers.ts(IPC),src/renderer/src/features/sessions/PmItemChip.tsx(UI chip),src/main/services/cli/cli-server-pm-routes.ts(CLI route)
For agents
CLI surface (Phase 5B)
Phase 5B adds 10 CLI routes under /pm/ on the control server (127.0.0.1:19519) so any agent session can read and write board data programmatically. Read endpoints serve from the local SQLite mirror tables; write endpoints proxy through to the Monday backend REST API via pm-auth.
Read routes (bearer + read-budgeted 60/min): GET /pm/boards (list), GET /pm/boards/:id (detail with groups + columns), GET /pm/boards/:id/items (items with enriched column values and filters for status/assignee/overdue/group/archived/limit), GET /pm/search?q= (cross-board item search by name or column text).
Write routes (bearer + mutation-limited 10/min, apply-immediately): POST /pm/boards/:id/items (create item), PATCH /pm/items/:id (update name/group), PUT /pm/items/:id/columns/:colId (set cell value), DELETE /pm/items/:id, POST /pm/boards/:id/columns (add column). All writes are proxied to the Monday backend and require a valid Monday session.
Workspace sync route (bearer + mutation-limited): POST /pm/workspaces/:id/sync fetches all boards in a workspace from the Monday backend and syncs each one into the local mirror. Continues past individual board failures and returns { synced, failed, total }. This is the entry point for initial workspace-level sync — callers no longer need to know individual board IDs.
All routes are feature-gated on the board app's feature flag (404 when off — the key is missionControlEnabled today; mondayEnabled survives only in the rename migration). The original single-file router has since been split: cli-server-pm-routes.ts is the registrar, and the per-family handlers live under src/main/services/cli/pm/. The spoke doc for agents is .claude/skills/omniscio-control/pm.md.
How it works
Auth is unified with Omniscio's Global Auth (Firebase) — users sign in once via Omniscio and get access to all boards; there is no separate Monday login. The plugin sends Firebase ID tokens (obtained from the main process via IPC) as Bearer auth to a separately-hosted backend (amc-back/, a Bun + Elysia + Postgres + Drizzle service; Omniscio does not bundle it). The backend URL is hardcoded in the plugin (web/lib/runtime-config.ts) — a fixed deploy target, not a user setting. The backend verifies tokens via admin.auth().verifyIdToken() (dual-auth: also accepts legacy JWT during migration). Firebase tokens auto-refresh (1hr expiry, handled by the main process).
Code references
- Isolated app:
src/plugins/mission-control/web/—amc/AmcMissionControlApp.tsx(composition root),lib/api.ts(authedFetch),lib/runtime-config.ts,lib/session-bridge.ts(Firebase auth bridge). Isolated from Omniscio tooling — owntsconfig.json(npm run typecheck:mission-control), scoped Tailwind (tailwind.mission-control.config.js→npm run build:mission-control-css), excluded from Omniscio's tsconfig/eslint/prettier. - Omniscio glue (normal tooling scope):
src/renderer/src/features/mission-control/—MissionControlPanel.tsx(panel host) +vendored-mission-control.d.ts(typecheck boundary). Vite aliases@mission-control/webinelectron.vite.renderer-shared.ts(that one alias is the whole bridge — there is no@mission-control/sharedalias). - Sentinel + registry:
MISSION_CONTROL_PROJECT_ID = '__mission_control__'insrc/shared/virtual-project-ids.ts; theid: 'mission-control'entry insrc/renderer/src/integrations/ui-registry.ts(panelOwnsLayout: true, lazyMissionControlPanel) and the manifest atsrc/shared/integrations/mission-control.ts(there is no longer an entry insrc/shared/integration-registry.ts). - Settings:
missionControlEnabledinsrc/shared/types/settings/mission-control-settings.ts(+ the Zod slice). Auth is via Omniscio's global Firebase auth — no Monday-specific credential. - IPC:
mission-control:get-firebase-tokenchannel (src/main/ipc/mission-control-auth-handlers.ts) provides Firebase ID tokens to the plugin. - Backend: the
amc-back/folder in this repo (moved in 2026-09-27). Deployed to Cloud Run atamcback.jls.dev/monday(serviceamc-backend, GCP projectamc-499110) withbash amc-back/deploy.sh.
Related
- Monday — part 1, and the note explaining the rename.
- mission-control.md — the same feature under its current name.
Last verified 2026-10-06