@huynle/hub 0.7.4 → 0.8.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/CHANGELOG.md +430 -1
- package/Dockerfile +7 -2
- package/README.md +230 -32
- package/package.json +5 -3
- package/packages/claude-code/package.json +1 -1
- package/packages/claude-code/src/daemon.ts +8 -1
- package/packages/claude-code/src/launcher.ts +29 -9
- package/packages/claude-code/src/paths.ts +3 -3
- package/packages/claude-code/src/profile.ts +173 -0
- package/packages/claude-code/src/sessions.ts +22 -4
- package/packages/cli/dist/hub-cli.js +6871 -3460
- package/packages/cli/package.json +1 -1
- package/packages/cli/src/artifact-jobs-mcp.ts +226 -0
- package/packages/cli/src/artifacts-mcp.ts +160 -0
- package/packages/cli/src/bootstrap/adapters/node-services/render.ts +2 -2
- package/packages/cli/src/bootstrap/discovery/host.ts +15 -1
- package/packages/cli/src/bootstrap/discovery/probe.ts +1 -1
- package/packages/cli/src/bootstrap/enrollment/enroll.ts +21 -9
- package/packages/cli/src/bootstrap/enrollment/policy.ts +138 -12
- package/packages/cli/src/bootstrap/enrollment/status.ts +3 -2
- package/packages/cli/src/cli.ts +96 -14
- package/packages/cli/src/format.ts +48 -10
- package/packages/cli/src/http.ts +2 -0
- package/packages/cli/src/intents.ts +23 -0
- package/packages/cli/src/launches.ts +9 -3
- package/packages/cli/src/login.ts +20 -6
- package/packages/cli/src/mcp.ts +385 -10
- package/packages/cli/src/messaging.ts +7 -3
- package/packages/cli/src/profiles-mcp.ts +301 -0
- package/packages/cli/src/setup/commands.ts +23 -4
- package/packages/cli/src/setup/runtime.ts +3 -2
- package/packages/cli/src/spoke-services.ts +1 -1
- package/packages/cli/src/team-intake-mcp.ts +158 -0
- package/packages/cli/src/teams-mcp.ts +460 -0
- package/packages/cli/src/watchlist.ts +135 -0
- package/packages/codex/package.json +1 -1
- package/packages/codex/src/paths.ts +3 -3
- package/packages/codex/src/profile.ts +163 -0
- package/packages/codex/src/sessions.ts +12 -0
- package/packages/codex/src/spoke.ts +19 -1
- package/packages/node/package.json +1 -1
- package/packages/node/src/config.ts +104 -2
- package/packages/node/src/opencode-warm.ts +344 -0
- package/packages/node/src/run.ts +28 -1
- package/packages/preset/package.json +1 -1
- package/packages/preset/src/profile.ts +34 -0
- package/packages/preset/src/spoke.ts +4 -0
- package/packages/protocol/package.json +1 -1
- package/packages/protocol/src/artifacts.ts +142 -0
- package/packages/protocol/src/concierge.ts +366 -0
- package/packages/protocol/src/contracts.ts +104 -0
- package/packages/protocol/src/graph.ts +70 -0
- package/packages/protocol/src/hub-workspace.ts +201 -0
- package/packages/protocol/src/index.ts +175 -6
- package/packages/protocol/src/launch.ts +36 -0
- package/packages/protocol/src/profiles.ts +301 -0
- package/packages/protocol/src/teams.ts +204 -0
- package/packages/runtime-openshell/package.json +1 -1
- package/packages/runtime-sdk/package.json +1 -1
- package/packages/sdk/package.json +1 -1
- package/packages/sdk/src/address.ts +50 -2
- package/packages/sdk/src/artifact-jobs.ts +194 -0
- package/packages/sdk/src/artifacts.ts +187 -0
- package/packages/sdk/src/client.ts +226 -5
- package/packages/sdk/src/concierge.ts +88 -0
- package/packages/sdk/src/errors.ts +4 -1
- package/packages/sdk/src/index.ts +6 -0
- package/packages/sdk/src/team-intake.ts +122 -0
- package/packages/sdk/src/teams.ts +346 -0
- package/packages/sdk/src/types.ts +568 -1
- package/packages/sdk/src/wake.ts +20 -0
- package/packages/spoke-sdk/package.json +1 -1
- package/packages/spoke-sdk/src/index.ts +1 -0
- package/packages/spoke-sdk/src/profile-apply.ts +245 -0
- package/src/central/actions.ts +7 -0
- package/src/central/agent/acting-routes.ts +2 -1
- package/src/central/agent/acting-switch.ts +2 -1
- package/src/central/agent/acting.ts +218 -10
- package/src/central/agent/app-tokens.ts +3 -2
- package/src/central/agent/audit.ts +18 -1
- package/src/central/agent/body.ts +163 -0
- package/src/central/agent/decisions.ts +125 -2
- package/src/central/agent/delivery.ts +194 -40
- package/src/central/agent/directory-routes.ts +37 -7
- package/src/central/agent/directory.ts +70 -14
- package/src/central/agent/errors.ts +7 -0
- package/src/central/agent/escalation.ts +10 -2
- package/src/central/agent/events-routes.ts +21 -4
- package/src/central/agent/events.ts +18 -4
- package/src/central/agent/form-check.ts +85 -0
- package/src/central/agent/grant-requests.ts +2 -1
- package/src/central/agent/grant-routes.ts +4 -3
- package/src/central/agent/grants.ts +29 -2
- package/src/central/agent/idempotency.ts +133 -0
- package/src/central/agent/intent-routes.ts +116 -0
- package/src/central/agent/intents.ts +505 -0
- package/src/central/agent/interaction-graph-routes.ts +212 -0
- package/src/central/agent/interaction-graph.ts +865 -0
- package/src/central/agent/launch-engine.ts +189 -32
- package/src/central/agent/launch-routes.ts +26 -10
- package/src/central/agent/launch-spec.ts +40 -3
- package/src/central/agent/launch-store.ts +55 -2
- package/src/central/agent/message-limits.ts +89 -11
- package/src/central/agent/message-routes.ts +10 -4
- package/src/central/agent/messages.ts +28 -2
- package/src/central/agent/names.ts +12 -2
- package/src/central/agent/placement.ts +93 -18
- package/src/central/agent/read-routes.ts +89 -19
- package/src/central/agent/routes.ts +178 -5
- package/src/central/agent/webhook-routes.ts +2 -1
- package/src/central/agent/webhooks.ts +17 -2
- package/src/central/agent-data.ts +4 -0
- package/src/central/artifacts/access.ts +44 -0
- package/src/central/artifacts/blob-store.ts +113 -0
- package/src/central/artifacts/blob-support.ts +98 -0
- package/src/central/artifacts/events.ts +27 -0
- package/src/central/artifacts/host-caps.ts +162 -0
- package/src/central/artifacts/host.ts +315 -0
- package/src/central/artifacts/idempotency.ts +109 -0
- package/src/central/artifacts/jobs-routes.ts +776 -0
- package/src/central/artifacts/jobs.ts +344 -0
- package/src/central/artifacts/maintenance.ts +103 -0
- package/src/central/artifacts/routes.ts +360 -0
- package/src/central/artifacts/store.ts +776 -0
- package/src/central/artifacts/workspaces.ts +31 -0
- package/src/central/backend/file-blobs.ts +377 -0
- package/src/central/backend/index.ts +12 -3
- package/src/central/backend/memory-blobs.ts +116 -0
- package/src/central/backend/postgres-blobs.ts +513 -0
- package/src/central/backend/postgres-migrate.ts +33 -0
- package/src/central/backend/postgres-state.ts +19 -0
- package/src/central/backend/types.ts +8 -0
- package/src/central/concierge/activity.ts +142 -0
- package/src/central/concierge/arm.ts +63 -0
- package/src/central/concierge/board-render.ts +190 -0
- package/src/central/concierge/board-results.ts +169 -0
- package/src/central/concierge/board-routes.ts +350 -0
- package/src/central/concierge/board.ts +249 -0
- package/src/central/concierge/context.ts +221 -0
- package/src/central/concierge/entitlements.ts +13 -0
- package/src/central/concierge/guard.ts +120 -0
- package/src/central/concierge/inbound.ts +86 -0
- package/src/central/concierge/index.ts +84 -0
- package/src/central/concierge/notes.ts +41 -0
- package/src/central/concierge/notifier.ts +986 -0
- package/src/central/concierge/prompt.ts +131 -0
- package/src/central/concierge/proposals.ts +268 -0
- package/src/central/concierge/push-remap.ts +49 -0
- package/src/central/concierge/routes.ts +122 -0
- package/src/central/concierge/schedule.ts +113 -0
- package/src/central/concierge/service.ts +243 -0
- package/src/central/concierge/session-routes.ts +125 -0
- package/src/central/concierge/settings.ts +217 -0
- package/src/central/concierge/supervisor.ts +767 -0
- package/src/central/concierge/tiers.ts +260 -0
- package/src/central/concierge/watchlist-routes.ts +279 -0
- package/src/central/concierge/watchlist.ts +273 -0
- package/src/central/config.ts +28 -6
- package/src/central/http.ts +660 -54
- package/src/central/main.ts +1 -1
- package/src/central/mcp-http.ts +10 -21
- package/src/central/profiles/apply.ts +333 -0
- package/src/central/profiles/content.ts +174 -0
- package/src/central/profiles/events.ts +40 -0
- package/src/central/profiles/idempotency.ts +14 -0
- package/src/central/profiles/import.ts +139 -0
- package/src/central/profiles/routes.ts +356 -0
- package/src/central/profiles/store.ts +597 -0
- package/src/central/profiles/usage-ports.ts +120 -0
- package/src/central/profiles/usage.ts +364 -0
- package/src/central/push.ts +7 -0
- package/src/central/registry.ts +69 -7
- package/src/central/store.ts +4 -0
- package/src/central/teams/collections.ts +34 -0
- package/src/central/teams/discovery.ts +346 -0
- package/src/central/teams/draft-edits.ts +46 -0
- package/src/central/teams/events.ts +46 -0
- package/src/central/teams/intake-routes.ts +100 -0
- package/src/central/teams/intake.ts +786 -0
- package/src/central/teams/policy.ts +231 -0
- package/src/central/teams/routes.ts +516 -0
- package/src/central/teams/seats.ts +272 -0
- package/src/central/teams/staffing.ts +910 -0
- package/src/central/teams/store.ts +667 -0
- package/src/central/teams/validation.ts +256 -0
- package/src/central/workspaces/board.ts +408 -0
- package/src/central/workspaces/checkpoints.ts +316 -0
- package/src/central/workspaces/coordinator.ts +841 -0
- package/src/central/workspaces/events.ts +85 -0
- package/src/central/workspaces/lifecycle.ts +93 -0
- package/src/central/workspaces/master.ts +490 -0
- package/src/central/workspaces/members.ts +632 -0
- package/src/central/workspaces/routes.ts +354 -0
- package/src/central/workspaces/sidechats-routes.ts +410 -0
- package/src/central/workspaces/sidechats.ts +482 -0
- package/src/central/workspaces/store.ts +571 -0
- package/src/central/workspaces/supervision.ts +355 -0
- package/src/index.ts +126 -23
- package/src/migrate.ts +109 -3
- package/src/spoke/concierge-agent.ts +33 -0
- package/src/spoke/deliver.ts +22 -4
- package/src/spoke/env-inject.ts +8 -1
- package/src/spoke/fork-revert.ts +142 -0
- package/src/spoke/hub-rpc.ts +41 -5
- package/src/spoke/hub-tool.ts +404 -25
- package/src/spoke/launchers.ts +6 -4
- package/src/spoke/listing.ts +65 -10
- package/src/spoke/localhub.ts +14 -4
- package/src/spoke/locations.ts +40 -0
- package/src/spoke/profile-apply.ts +298 -0
- package/src/spoke/session-context.ts +256 -0
- package/src/spoke/spoke.ts +330 -23
- package/src/spoke/timeline.ts +6 -1
- package/src/spoke/tracker.ts +23 -1
- package/src/spoke/who-teams.ts +81 -0
- package/src/tui-messaging.ts +32 -18
- package/web/dist/assets/ArtifactPage-mNzjlP_U.js +1 -0
- package/web/dist/assets/ArtifactPane-CPQcuX7c.js +1 -0
- package/web/dist/assets/ArtifactWorkbench-9eTj1CeW.css +1 -0
- package/web/dist/assets/ArtifactWorkbench-NoFC5Sb2.js +6 -0
- package/web/dist/assets/Library-DYsFj_5c.css +1 -0
- package/web/dist/assets/Library-LXHsP5Fw.js +2 -0
- package/web/dist/assets/ProfilesDestination-DhVVcAep.js +1 -0
- package/web/dist/assets/TeamsPage-DBrO5hoL.js +1 -0
- package/web/dist/assets/Watchtower-CTgqHk5g.css +1 -0
- package/web/dist/assets/Watchtower-DxaJYQp_.js +2 -0
- package/web/dist/assets/index-BabrNDB3.css +1 -0
- package/web/dist/assets/index-lIOfSYck.js +34 -0
- package/web/dist/assets/live-BDq0AABg.js +5 -0
- package/web/dist/assets/live-BUofsQpz.css +1 -0
- package/web/dist/assets/pane-layout-DWXfDU-1.js +1 -0
- package/web/dist/assets/plural-Bspvoqfq.js +1 -0
- package/web/dist/assets/renderer2d-DAr4IHM8.js +1 -0
- package/web/dist/assets/renderer3d-DWZj595u.js +5393 -0
- package/web/dist/assets/safe-area-JUb6OeI3.js +1 -0
- package/web/dist/assets/source-CDU04kYw.js +1 -0
- package/web/dist/assets/ui-Dh1-78Cl.js +3 -0
- package/web/dist/index.html +5 -2
- package/web/dist/sw.js +22 -2
- package/web/dist/assets/index-Dm8OmkaO.css +0 -1
- package/web/dist/assets/index-FUJbj_Du.js +0 -20
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
// Compact journal events of workspaces (HWA-06; contract: WORKSPACE_EVENT_TYPES, family `manage`). Allowlisted
|
|
2
|
+
// payloads only: IDs, enums (state, role, status, reason, change), revisions and counts. Never titles,
|
|
3
|
+
// descriptions, tags, metadata, labels, repository paths, assignment titles/criteria/refs or any other free text.
|
|
4
|
+
// A reader that missed events (journal reset) re-reads the `workspaces` snapshot (RESET_REFRESH).
|
|
5
|
+
import type { HostRepoBinding, HubWorkspace, SupervisionLink, WorkspaceAssignment, WorkspaceMember } from "../../protocol"
|
|
6
|
+
import type { EventInput } from "../agent/events"
|
|
7
|
+
import type { DepartureResult, SupervisionResult } from "./supervision"
|
|
8
|
+
|
|
9
|
+
export const workspaceCreatedEvent = (workspace: HubWorkspace): EventInput => ({
|
|
10
|
+
type: "workspace.created",
|
|
11
|
+
family: "manage",
|
|
12
|
+
subject: { workspaceID: workspace.id },
|
|
13
|
+
data: { revision: workspace.revision, state: workspace.state },
|
|
14
|
+
})
|
|
15
|
+
|
|
16
|
+
/** Title, description, tags or metadata changed. */
|
|
17
|
+
export const workspacePatchedEvent = (workspace: HubWorkspace): EventInput => ({
|
|
18
|
+
type: "workspace.updated",
|
|
19
|
+
family: "manage",
|
|
20
|
+
subject: { workspaceID: workspace.id },
|
|
21
|
+
data: { change: "patched", revision: workspace.revision },
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
/** A host repo binding was added or removed (the binding aggregate, not the workspace record, changed). */
|
|
25
|
+
export const bindingEvent = (workspaceID: string, binding: HostRepoBinding, change: "bound" | "unbound"): EventInput => ({
|
|
26
|
+
type: "workspace.updated",
|
|
27
|
+
family: "manage",
|
|
28
|
+
subject: { workspaceID, bindingID: binding.id, machineID: binding.machineID },
|
|
29
|
+
data: { change, bindingRevision: binding.revision },
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
/** Archived (`state: archived`, with how many members departed) or restored (`state: active`). */
|
|
33
|
+
export const workspaceArchivedEvent = (workspace: HubWorkspace, departed: number): EventInput => ({
|
|
34
|
+
type: "workspace.archived",
|
|
35
|
+
family: "manage",
|
|
36
|
+
subject: { workspaceID: workspace.id },
|
|
37
|
+
data: { state: workspace.state, revision: workspace.revision, departed },
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
export const memberJoinedEvent = (member: WorkspaceMember): EventInput => ({
|
|
41
|
+
type: "workspace.member.joined",
|
|
42
|
+
family: "manage",
|
|
43
|
+
subject: { workspaceID: member.workspaceID, memberID: member.id, sessionID: member.sessionID },
|
|
44
|
+
data: { role: member.role, generation: member.generation, revision: member.revision },
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
/** A current member changed role (a workspace update; joined/left stay for membership itself). */
|
|
48
|
+
export const memberRoleEvent = (member: WorkspaceMember): EventInput => ({
|
|
49
|
+
type: "workspace.updated",
|
|
50
|
+
family: "manage",
|
|
51
|
+
subject: { workspaceID: member.workspaceID, memberID: member.id, sessionID: member.sessionID },
|
|
52
|
+
data: { change: "member_role", role: member.role, memberRevision: member.revision },
|
|
53
|
+
})
|
|
54
|
+
|
|
55
|
+
export const memberLeftEvent = (member: WorkspaceMember): EventInput => ({
|
|
56
|
+
type: "workspace.member.left",
|
|
57
|
+
family: "manage",
|
|
58
|
+
subject: { workspaceID: member.workspaceID, memberID: member.id, sessionID: member.sessionID },
|
|
59
|
+
data: { role: member.role, reason: member.leftReason ?? "removed", revision: member.revision },
|
|
60
|
+
})
|
|
61
|
+
|
|
62
|
+
/** A PUT /supervision change (attached, moved, reordered, detached) or stale links pruned by it. */
|
|
63
|
+
export function supervisionSetEvent(memberID: string, result: SupervisionResult, link?: SupervisionLink): EventInput {
|
|
64
|
+
return {
|
|
65
|
+
type: "workspace.supervision.changed",
|
|
66
|
+
family: "manage",
|
|
67
|
+
subject: { workspaceID: result.workspaceID, memberID, ...(link ? { supervisorMemberID: link.supervisorMemberID } : {}) },
|
|
68
|
+
data: { change: result.change, revision: result.revision, pruned: result.pruned, ...(link ? { order: link.order, linkRevision: link.revision } : {}) },
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/** A departure detached or transferred a member's links. */
|
|
73
|
+
export const supervisionDepartedEvent = (memberID: string, result: DepartureResult): EventInput => ({
|
|
74
|
+
type: "workspace.supervision.changed",
|
|
75
|
+
family: "manage",
|
|
76
|
+
subject: { workspaceID: result.workspaceID, memberID },
|
|
77
|
+
data: { change: "departed", revision: result.revision, detached: result.detached, transferred: result.transferred, pruned: result.pruned },
|
|
78
|
+
})
|
|
79
|
+
|
|
80
|
+
export const assignmentChangedEvent = (assignment: WorkspaceAssignment, change: "created" | "status" | "reassigned"): EventInput => ({
|
|
81
|
+
type: "workspace.assignment.changed",
|
|
82
|
+
family: "manage",
|
|
83
|
+
subject: { workspaceID: assignment.workspaceID, assignmentID: assignment.id, memberID: assignment.memberID },
|
|
84
|
+
data: { change, status: assignment.status, revision: assignment.revision },
|
|
85
|
+
})
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
// Departures across the workspace stores (HWA-06; contract clarifications from HWA-04 and HWA-05): whenever a
|
|
2
|
+
// member departs, its supervision links follow, and the journal gets compact events.
|
|
3
|
+
//
|
|
4
|
+
// - leave (DELETE /workspaces/:id/members/:memberID): MembershipStore.leave (`removed`), then
|
|
5
|
+
// SupervisionStore.memberDeparted.
|
|
6
|
+
// - archive (POST /workspaces/:id/archive): MembershipStore.archiveWorkspace (members depart as `archived`), then
|
|
7
|
+
// memberDeparted for each member that was current before.
|
|
8
|
+
// - sessionEnded (the hub's session-deleted path): MembershipStore.sessionEnded (`ended`) in every workspace of
|
|
9
|
+
// the user, then memberDeparted for each.
|
|
10
|
+
//
|
|
11
|
+
// memberDeparted is called even when the membership step was a no-op, so repeating a call finishes a sweep a crash
|
|
12
|
+
// interrupted (the supervision step is idempotent). Events are appended after the writes; an event failure is
|
|
13
|
+
// reported, never thrown (the change already happened). Nothing here grants authority or touches native
|
|
14
|
+
// parentID/rootID.
|
|
15
|
+
import type { HubWorkspace, WorkspaceMember } from "../../protocol"
|
|
16
|
+
import type { AgentEvents, EventInput } from "../agent/events"
|
|
17
|
+
import { memberLeftEvent, supervisionDepartedEvent, workspaceArchivedEvent } from "./events"
|
|
18
|
+
import type { MembershipStore } from "./members"
|
|
19
|
+
import type { WorkspaceStore } from "./store"
|
|
20
|
+
import type { DepartureResult, SupervisionStore } from "./supervision"
|
|
21
|
+
|
|
22
|
+
export interface WorkspaceLifecycleDeps {
|
|
23
|
+
readonly workspaces: WorkspaceStore
|
|
24
|
+
readonly members: MembershipStore
|
|
25
|
+
readonly supervision: SupervisionStore
|
|
26
|
+
readonly events?: Pick<AgentEvents, "append">
|
|
27
|
+
readonly report?: (cause: unknown) => void
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export interface Departure {
|
|
31
|
+
readonly member: WorkspaceMember
|
|
32
|
+
readonly supervision: DepartureResult
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const touched = (r: DepartureResult) => r.detached + r.transferred + r.pruned > 0
|
|
36
|
+
|
|
37
|
+
export class WorkspaceLifecycle {
|
|
38
|
+
private readonly report: (cause: unknown) => void
|
|
39
|
+
|
|
40
|
+
constructor(private readonly deps: WorkspaceLifecycleDeps) {
|
|
41
|
+
this.report = deps.report ?? ((cause) => console.error(`[hub] workspace event failed: ${cause instanceof Error ? cause.message : String(cause)}`))
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/** Appends compact events in order; failures are reported. */
|
|
45
|
+
async emit(userID: string, ...events: EventInput[]): Promise<void> {
|
|
46
|
+
if (!this.deps.events) return
|
|
47
|
+
for (const event of events) await this.deps.events.append(userID, event).catch(this.report)
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/** Removes a member under its expected revision and detaches its supervision. */
|
|
51
|
+
async leave(userID: string, workspaceID: string, memberID: string, expectedRevision: number): Promise<Departure> {
|
|
52
|
+
const member = await this.deps.members.leave(userID, workspaceID, memberID, { expectedRevision, reason: "removed" })
|
|
53
|
+
const changed = member.revision !== expectedRevision
|
|
54
|
+
const result = await this.deps.supervision.memberDeparted(userID, workspaceID, memberID)
|
|
55
|
+
await this.emit(userID, ...(changed ? [memberLeftEvent(member)] : []), ...(touched(result) ? [supervisionDepartedEvent(memberID, result)] : []))
|
|
56
|
+
return { member, supervision: result }
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/** Archives the workspace under its expected revision; every current member departs and loses its links. */
|
|
60
|
+
async archive(userID: string, workspaceID: string, expectedRevision: number): Promise<{ workspace: HubWorkspace; departed: number; supervision: { detached: number } }> {
|
|
61
|
+
const before = await this.deps.members.members(userID, workspaceID)
|
|
62
|
+
const { workspace, departed } = await this.deps.members.archiveWorkspace(userID, workspaceID, expectedRevision)
|
|
63
|
+
const out: EventInput[] = []
|
|
64
|
+
if (workspace.revision !== expectedRevision || departed > 0) out.push(workspaceArchivedEvent(workspace, departed))
|
|
65
|
+
let detached = 0
|
|
66
|
+
for (const { member } of before) {
|
|
67
|
+
const result = await this.deps.supervision.memberDeparted(userID, workspaceID, member.id)
|
|
68
|
+
detached += result.detached + result.transferred
|
|
69
|
+
if (touched(result)) out.push(supervisionDepartedEvent(member.id, result))
|
|
70
|
+
}
|
|
71
|
+
await this.emit(userID, ...out)
|
|
72
|
+
return { workspace, departed, supervision: { detached } }
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* The session was deleted: it departs every workspace of the user as `ended` and its links are detached.
|
|
77
|
+
* Returns the memberships it ended. Per-workspace supervision failures are reported, not thrown.
|
|
78
|
+
*/
|
|
79
|
+
async sessionEnded(userID: string, sessionID: string): Promise<WorkspaceMember[]> {
|
|
80
|
+
const ended = await this.deps.members.sessionEnded(userID, sessionID)
|
|
81
|
+
for (const member of ended) {
|
|
82
|
+
const out: EventInput[] = [memberLeftEvent(member)]
|
|
83
|
+
try {
|
|
84
|
+
const result = await this.deps.supervision.memberDeparted(userID, member.workspaceID, member.id)
|
|
85
|
+
if (touched(result)) out.push(supervisionDepartedEvent(member.id, result))
|
|
86
|
+
} catch (cause) {
|
|
87
|
+
this.report(cause)
|
|
88
|
+
}
|
|
89
|
+
await this.emit(userID, ...out)
|
|
90
|
+
}
|
|
91
|
+
return ended
|
|
92
|
+
}
|
|
93
|
+
}
|