pmx-canvas 0.8.2 → 0.9.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/.github/extensions/pmx-canvas/runtime.json +1 -1
- package/.github/extensions/pmx-canvas/tools.json +601 -22
- package/CHANGELOG.md +59 -0
- package/Readme.md +131 -532
- package/dist/canvas/global.css +2724 -476
- package/dist/canvas/index.js +168 -107
- package/dist/canvas/mcp-app.html +2899 -596
- package/dist/json-render/index.js +20 -20
- package/dist/types/client/canvas/BarHint.d.ts +12 -2
- package/dist/types/client/canvas/BoardLinkDialog.d.ts +3 -1
- package/dist/types/client/canvas/BoardPinButton.d.ts +10 -0
- package/dist/types/client/canvas/BoardSwitcher.d.ts +1 -1
- package/dist/types/client/canvas/CanvasViewport.d.ts +1 -1
- package/dist/types/client/canvas/CommandBar.d.ts +3 -4
- package/dist/types/client/canvas/ConnectionBanner.d.ts +2 -1
- package/dist/types/client/canvas/ContextChip.d.ts +3 -0
- package/dist/types/client/canvas/CrossBoardReferences.d.ts +5 -0
- package/dist/types/client/canvas/EdgeLayer.d.ts +14 -3
- package/dist/types/client/canvas/EmptyState.d.ts +4 -4
- package/dist/types/client/canvas/HomeGraphView.d.ts +2 -0
- package/dist/types/client/canvas/HomeMapView.d.ts +1 -0
- package/dist/types/client/canvas/HomeReviewView.d.ts +6 -0
- package/dist/types/client/canvas/HomeView.d.ts +9 -7
- package/dist/types/client/canvas/KnowledgeDialog.d.ts +4 -0
- package/dist/types/client/canvas/LifecycleChrome.d.ts +5 -0
- package/dist/types/client/canvas/LifecycleFields.d.ts +7 -0
- package/dist/types/client/canvas/LifecyclePanel.d.ts +1 -0
- package/dist/types/client/canvas/MemoryInspector.d.ts +7 -0
- package/dist/types/client/canvas/NearPinLayer.d.ts +14 -0
- package/dist/types/client/canvas/NodeContextMark.d.ts +40 -7
- package/dist/types/client/canvas/RelationPresetsDialog.d.ts +4 -0
- package/dist/types/client/canvas/RelationsPanel.d.ts +4 -0
- package/dist/types/client/canvas/SessionPanel.d.ts +2 -0
- package/dist/types/client/canvas/canvas-area.d.ts +1 -1
- package/dist/types/client/canvas/graph-geometry.d.ts +27 -0
- package/dist/types/client/canvas/graph-model.d.ts +37 -0
- package/dist/types/client/canvas/memory-layout.d.ts +23 -0
- package/dist/types/client/canvas/use-chrome-height.d.ts +2 -0
- package/dist/types/client/canvas/use-focus-trap.d.ts +1 -0
- package/dist/types/client/canvas/use-memory-graph.d.ts +8 -0
- package/dist/types/client/canvas/use-pan-zoom.d.ts +4 -1
- package/dist/types/client/icons.d.ts +0 -10
- package/dist/types/client/nodes/AxStepControls.d.ts +1 -1
- package/dist/types/client/nodes/InlineMarkdownEditor.d.ts +4 -4
- package/dist/types/client/nodes/MarkdownNode.d.ts +5 -1
- package/dist/types/client/nodes/McpAppNode.d.ts +4 -4
- package/dist/types/client/nodes/viewer-runtime-state.d.ts +1 -1
- package/dist/types/client/state/boards-store.d.ts +81 -9
- package/dist/types/client/state/canvas-store.d.ts +14 -1
- package/dist/types/client/state/context-chip-store.d.ts +22 -0
- package/dist/types/client/state/context-status-store.d.ts +35 -0
- package/dist/types/client/state/human-store.d.ts +2 -1
- package/dist/types/client/state/intent-bridge.d.ts +11 -8
- package/dist/types/client/state/knowledge-store.d.ts +22 -0
- package/dist/types/client/state/near-pin-store.d.ts +44 -1
- package/dist/types/client/state/presence-store.d.ts +4 -4
- package/dist/types/client/state/presentation.d.ts +28 -0
- package/dist/types/client/state/relation-store.d.ts +10 -0
- package/dist/types/client/state/session-store.d.ts +41 -2
- package/dist/types/client/state/workspace-settings.d.ts +7 -0
- package/dist/types/client/types.d.ts +13 -1
- package/dist/types/client/utils/keyboard.d.ts +2 -0
- package/dist/types/client/utils/time-ago.d.ts +4 -0
- package/dist/types/mcp/context-uri-template.d.ts +3 -1
- package/dist/types/server/agent-presence.d.ts +10 -3
- package/dist/types/server/ax-context.d.ts +1 -1
- package/dist/types/server/canvas-db.d.ts +30 -7
- package/dist/types/server/canvas-operations.d.ts +24 -2
- package/dist/types/server/canvas-provenance.d.ts +22 -2
- package/dist/types/server/canvas-serialization.d.ts +2 -0
- package/dist/types/server/canvas-state.d.ts +93 -15
- package/dist/types/server/canvas-validation.d.ts +1 -1
- package/dist/types/server/context-brief.d.ts +94 -6
- package/dist/types/server/context-reads.d.ts +33 -7
- package/dist/types/server/edit-summary.d.ts +20 -0
- package/dist/types/server/index.d.ts +71 -10
- package/dist/types/server/knowledge-lifecycle.d.ts +221 -0
- package/dist/types/server/lifecycle-status.d.ts +10 -0
- package/dist/types/server/memory-graph.d.ts +9 -0
- package/dist/types/server/mutation-history.d.ts +2 -0
- package/dist/types/server/operations/ops/ax-shared.d.ts +1 -1
- package/dist/types/server/operations/ops/boards.d.ts +2 -1
- package/dist/types/server/operations/ops/lifecycle.d.ts +2 -0
- package/dist/types/server/operations/ops/memory-graph.d.ts +2 -0
- package/dist/types/server/operations/ops/nodes.d.ts +5 -0
- package/dist/types/server/operations/ops/query.d.ts +23 -0
- package/dist/types/server/operations/registry.d.ts +1 -0
- package/dist/types/server/placement.d.ts +7 -0
- package/dist/types/server/scope-fence.d.ts +2 -1
- package/dist/types/server/spatial-analysis.d.ts +6 -3
- package/dist/types/server/tour-control.d.ts +32 -0
- package/dist/types/server/wiki-links.d.ts +14 -0
- package/dist/types/server/workbench-auth.d.ts +2 -0
- package/dist/types/shared/agent-context.d.ts +2 -0
- package/dist/types/shared/agent-presence.d.ts +15 -12
- package/dist/types/shared/auto-arrange.d.ts +1 -0
- package/dist/types/shared/boards.d.ts +4 -4
- package/dist/types/shared/knowledge-lifecycle.d.ts +41 -0
- package/dist/types/shared/knowledge-presets.d.ts +6 -0
- package/dist/types/shared/lifecycle-status.d.ts +24 -0
- package/dist/types/shared/memory-graph.d.ts +53 -0
- package/dist/types/shared/relations.d.ts +68 -0
- package/dist/types/shared/semantic-attention.d.ts +2 -0
- package/dist/types/shared/tour.d.ts +38 -0
- package/dist/types/shared/workspace-settings.d.ts +11 -0
- package/docs/RELEASE.md +21 -3
- package/docs/adr-001-bun-only-runtime.md +7 -1
- package/docs/adr-002-shared-product-separate-runtimes.md +93 -0
- package/docs/api-reference.md +109 -0
- package/docs/ax-host-adapter-contract.md +1 -1
- package/docs/ax-state-contract.md +5 -4
- package/docs/cli.md +153 -15
- package/docs/demos/pmx-canvas-demo.mp4 +0 -0
- package/docs/design/AgentContext.dc.html +3 -3
- package/docs/design/BoardPins.dc.html +37 -22
- package/docs/design/Categories.dc.html +208 -0
- package/docs/design/CategoryEditor.dc.html +33 -0
- package/docs/design/Chrome.dc.html +52 -9
- package/docs/design/ContextChip.dc.html +224 -0
- package/docs/design/ContextChip600.dc.html +136 -0
- package/docs/design/EmptyState.dc.html +45 -0
- package/docs/design/Flows.dc.html +23 -1
- package/docs/design/HeaderMarks.dc.html +183 -0
- package/docs/design/Home.dc.html +19 -1
- package/docs/design/HomeGraph.dc.html +86 -202
- package/docs/design/HomeMap.dc.html +23 -1
- package/docs/design/HomeTeam.dc.html +32 -14
- package/docs/design/Lifecycle.dc.html +22 -0
- package/docs/design/Lifecycle600.dc.html +18 -0
- package/docs/design/LifecycleVariants.dc.html +157 -0
- package/docs/design/LinkAuthorship.dc.html +139 -0
- package/docs/design/LinksChanged.dc.html +203 -0
- package/docs/design/LinksOptions.dc.html +137 -0
- package/docs/design/LinksOptions600.dc.html +134 -0
- package/docs/design/NearPin.dc.html +9 -10
- package/docs/design/Pane600.dc.html +4 -3
- package/docs/design/Relations.dc.html +3 -2
- package/docs/design/Restore.dc.html +152 -0
- package/docs/design/SeeChange.dc.html +267 -0
- package/docs/design/Uses.dc.html +12 -6
- package/docs/design/canvas.json +146 -19
- package/docs/design.md +449 -16
- package/docs/environment.md +0 -1
- package/docs/evals/curation-effect.md +128 -0
- package/docs/http-api.md +459 -37
- package/docs/mcp.md +146 -18
- package/docs/node-types.md +58 -3
- package/docs/plans/design-gaps-2026-10-08.md +53 -0
- package/docs/plans/plan-009-tech-debt-backlog.md +379 -0
- package/docs/plans/plan-016-context-made-visible-wave-1.md +150 -5
- package/docs/plans/plan-017-knowledge-categories-and-lifecycle.md +175 -0
- package/docs/plans/plan-018-connected-memory-wave-2.md +594 -0
- package/docs/plans/plan-019-post-0.9-roadmap.md +198 -0
- package/docs/product-context-vision-2026-09.md +17 -1
- package/docs/product-vision-2026-09.md +1082 -43
- package/docs/product-vision-review-2026-09.md +13 -1
- package/docs/screenshots/workbench-live-dark.png +0 -0
- package/docs/screenshots/workbench-live-light.png +0 -0
- package/docs/sdk.md +62 -2
- package/package.json +1 -1
- package/plugins/pmx-canvas/com.github.copilot/extensions/pmx-canvas/runtime.json +1 -1
- package/plugins/pmx-canvas/plugin.json +1 -1
- package/plugins/pmx-canvas/runtime.json +1 -1
- package/plugins/pmx-canvas/tools.json +601 -22
- package/skills/pmx-canvas/SKILL.md +216 -42
- package/skills/pmx-canvas/evals/evals.json +224 -0
- package/skills/pmx-canvas/references/full-reference.md +120 -21
- package/skills/pmx-canvas/references/github-copilot-app-adapter.md +2 -2
- package/skills/pmx-canvas/references/importing-context.md +132 -0
- package/skills/pmx-canvas/references/installing-pmx-canvas.md +6 -6
- package/skills/pmx-canvas/references/tours-and-recording.md +16 -1
- package/skills/pmx-canvas-testing/SKILL.md +20 -0
- package/src/cli/agent.ts +2 -0
- package/src/cli/commands/ax.ts +12 -0
- package/src/cli/commands/boards.ts +88 -11
- package/src/cli/commands/edges.ts +28 -0
- package/src/cli/commands/groups.ts +7 -0
- package/src/cli/commands/nodes.ts +1 -0
- package/src/cli/commands/query.ts +34 -2
- package/src/cli/commands/record.ts +199 -48
- package/src/cli/index.ts +6 -1
- package/src/client/App.tsx +177 -70
- package/src/client/canvas/AttentionHistory.tsx +0 -2
- package/src/client/canvas/BarHint.tsx +40 -2
- package/src/client/canvas/BoardCopyDialog.tsx +1 -1
- package/src/client/canvas/BoardFolderDialog.tsx +7 -7
- package/src/client/canvas/BoardLinkDialog.tsx +138 -33
- package/src/client/canvas/BoardPinButton.tsx +33 -0
- package/src/client/canvas/BoardSwitcher.tsx +26 -40
- package/src/client/canvas/CanvasNode.tsx +360 -237
- package/src/client/canvas/CanvasViewport.tsx +45 -7
- package/src/client/canvas/CommandBar.tsx +29 -23
- package/src/client/canvas/CommandPalette.tsx +5 -12
- package/src/client/canvas/ConnectionBanner.tsx +3 -3
- package/src/client/canvas/ContextChip.tsx +296 -0
- package/src/client/canvas/ContextMenu.tsx +63 -5
- package/src/client/canvas/CrossBoardReferences.tsx +60 -0
- package/src/client/canvas/EdgeLayer.tsx +339 -76
- package/src/client/canvas/EmptyState.tsx +33 -18
- package/src/client/canvas/ExpandedNodeOverlay.tsx +72 -40
- package/src/client/canvas/ExternalWriters.tsx +57 -42
- package/src/client/canvas/HomeGraphView.tsx +942 -0
- package/src/client/canvas/HomeMapView.tsx +641 -0
- package/src/client/canvas/HomeReviewView.tsx +167 -0
- package/src/client/canvas/HomeView.tsx +687 -160
- package/src/client/canvas/IntentLayer.tsx +19 -12
- package/src/client/canvas/KnowledgeDialog.tsx +488 -0
- package/src/client/canvas/LifecycleChrome.tsx +133 -0
- package/src/client/canvas/LifecycleFields.tsx +91 -0
- package/src/client/canvas/LifecyclePanel.tsx +543 -0
- package/src/client/canvas/MemoryInspector.tsx +104 -0
- package/src/client/canvas/Minimap.tsx +3 -3
- package/src/client/canvas/NearPinLayer.tsx +187 -0
- package/src/client/canvas/NodeContextMark.tsx +175 -97
- package/src/client/canvas/Presentation.tsx +23 -57
- package/src/client/canvas/RelationPresetsDialog.tsx +413 -0
- package/src/client/canvas/RelationsPanel.tsx +82 -0
- package/src/client/canvas/SelectionBar.tsx +3 -6
- package/src/client/canvas/SessionPanel.tsx +90 -50
- package/src/client/canvas/SessionReceipt.tsx +311 -39
- package/src/client/canvas/ShortcutOverlay.tsx +1 -1
- package/src/client/canvas/SnapshotPanel.tsx +27 -36
- package/src/client/canvas/ToolRail.tsx +367 -192
- package/src/client/canvas/TopBar.tsx +354 -124
- package/src/client/canvas/canvas-area.ts +10 -3
- package/src/client/canvas/graph-geometry.ts +195 -0
- package/src/client/canvas/graph-model.ts +254 -0
- package/src/client/canvas/memory-layout.ts +106 -0
- package/src/client/canvas/use-chrome-height.ts +20 -0
- package/src/client/canvas/use-focus-trap.ts +31 -5
- package/src/client/canvas/use-memory-graph.ts +58 -0
- package/src/client/canvas/use-node-drag.ts +2 -1
- package/src/client/canvas/use-pan-zoom.ts +64 -7
- package/src/client/icons.tsx +0 -63
- package/src/client/mcp-app/style.css +0 -6
- package/src/client/nodes/AxStepControls.tsx +74 -50
- package/src/client/nodes/BoardNode.tsx +5 -1
- package/src/client/nodes/ContextNode.tsx +18 -11
- package/src/client/nodes/ExtAppFrame.tsx +6 -3
- package/src/client/nodes/FileNode.tsx +46 -42
- package/src/client/nodes/HtmlNode.tsx +32 -0
- package/src/client/nodes/ImageNode.tsx +1 -1
- package/src/client/nodes/InlineFormatBar.tsx +6 -9
- package/src/client/nodes/InlineMarkdownEditor.tsx +56 -17
- package/src/client/nodes/MarkdownNode.tsx +377 -109
- package/src/client/nodes/McpAppNode.tsx +50 -20
- package/src/client/nodes/MdFormatBar.tsx +21 -18
- package/src/client/nodes/PromptNode.tsx +1 -1
- package/src/client/nodes/ResponseNode.tsx +1 -1
- package/src/client/nodes/viewer-runtime-state.ts +54 -22
- package/src/client/state/attention-bridge.ts +64 -15
- package/src/client/state/boards-store.ts +193 -39
- package/src/client/state/canvas-store.ts +99 -12
- package/src/client/state/context-chip-store.ts +70 -0
- package/src/client/state/context-status-store.ts +53 -0
- package/src/client/state/human-store.ts +13 -7
- package/src/client/state/intent-bridge.ts +51 -30
- package/src/client/state/knowledge-store.ts +43 -0
- package/src/client/state/near-pin-store.ts +115 -6
- package/src/client/state/presence-store.ts +7 -10
- package/src/client/state/presentation.ts +91 -0
- package/src/client/state/relation-store.ts +81 -0
- package/src/client/state/session-store.ts +144 -18
- package/src/client/state/sse-bridge.ts +235 -32
- package/src/client/state/workspace-settings.ts +11 -0
- package/src/client/theme/global.css +2724 -476
- package/src/client/types.ts +12 -0
- package/src/client/utils/keyboard.ts +10 -0
- package/src/client/utils/time-ago.ts +14 -0
- package/src/json-render/renderer/index.tsx +31 -0
- package/src/mcp/canvas-app.ts +12 -2
- package/src/mcp/context-uri-template.ts +7 -4
- package/src/mcp/server.ts +63 -41
- package/src/mcp/workbench-app.ts +39 -6
- package/src/server/agent-presence.ts +128 -28
- package/src/server/ax-context.ts +27 -13
- package/src/server/board-export.ts +12 -1
- package/src/server/canvas-db.ts +331 -42
- package/src/server/canvas-operations.ts +195 -83
- package/src/server/canvas-provenance.ts +53 -22
- package/src/server/canvas-serialization.ts +2 -0
- package/src/server/canvas-state.ts +950 -122
- package/src/server/canvas-validation.ts +9 -2
- package/src/server/context-brief.ts +345 -38
- package/src/server/context-reads.ts +178 -30
- package/src/server/demo-state.json +355 -24
- package/src/server/edit-summary.ts +74 -0
- package/src/server/html-surface.ts +8 -1
- package/src/server/index.ts +181 -11
- package/src/server/knowledge-lifecycle.ts +304 -0
- package/src/server/lifecycle-status.ts +232 -0
- package/src/server/memory-graph.ts +166 -0
- package/src/server/mutation-history.ts +18 -6
- package/src/server/operations/composites.ts +32 -11
- package/src/server/operations/http.ts +7 -2
- package/src/server/operations/index.ts +4 -0
- package/src/server/operations/mcp.ts +26 -1
- package/src/server/operations/ops/ax-presence.ts +1 -1
- package/src/server/operations/ops/ax-read.ts +57 -6
- package/src/server/operations/ops/ax-timeline.ts +28 -2
- package/src/server/operations/ops/backup.ts +5 -3
- package/src/server/operations/ops/batch.ts +35 -4
- package/src/server/operations/ops/boards.ts +188 -47
- package/src/server/operations/ops/canvas-wire.ts +31 -1
- package/src/server/operations/ops/edges.ts +36 -2
- package/src/server/operations/ops/groups.ts +6 -1
- package/src/server/operations/ops/lifecycle.ts +262 -0
- package/src/server/operations/ops/memory-graph.ts +45 -0
- package/src/server/operations/ops/nodes.ts +107 -24
- package/src/server/operations/ops/query.ts +281 -68
- package/src/server/operations/ops/snapshots.ts +73 -1
- package/src/server/operations/ops/validate.ts +5 -1
- package/src/server/operations/ops/viewport.ts +97 -3
- package/src/server/operations/registry.ts +74 -25
- package/src/server/placement.ts +29 -0
- package/src/server/scope-fence.ts +78 -6
- package/src/server/server.ts +115 -16
- package/src/server/spatial-analysis.ts +48 -23
- package/src/server/tour-control.ts +82 -0
- package/src/server/wiki-links.ts +137 -0
- package/src/server/workbench-auth.ts +11 -0
- package/src/shared/agent-context.ts +3 -0
- package/src/shared/agent-presence.ts +15 -15
- package/src/shared/auto-arrange.ts +2 -0
- package/src/shared/boards.ts +4 -4
- package/src/shared/knowledge-lifecycle.ts +22 -0
- package/src/shared/knowledge-presets.ts +80 -0
- package/src/shared/lifecycle-status.ts +26 -0
- package/src/shared/memory-graph.ts +74 -0
- package/src/shared/relations.ts +98 -0
- package/src/shared/semantic-attention.ts +15 -1
- package/src/shared/tour.ts +23 -5
- package/src/shared/workspace-settings.ts +13 -0
- package/dist/types/client/canvas/ContextPinBar.d.ts +0 -1
- package/dist/types/client/canvas/FocusFieldLayer.d.ts +0 -1
- package/dist/types/client/canvas/kind-colors.d.ts +0 -3
- package/dist/types/server/agent-context.d.ts +0 -22
- package/src/client/canvas/ContextPinBar.tsx +0 -25
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { HTML_SURFACE_PUSH_SOURCE } from '../../shared/ax-surface-protocol.js';
|
|
2
|
+
import { BarHint } from './BarHint';
|
|
2
3
|
import { useCallback, useEffect, useLayoutEffect, useRef, useState } from 'preact/hooks';
|
|
3
4
|
import { ContextNode } from '../nodes/ContextNode';
|
|
4
5
|
import { DiffNode } from '../nodes/DiffNode';
|
|
@@ -17,6 +18,10 @@ import { AxStepControls } from '../nodes/AxStepControls';
|
|
|
17
18
|
import { ResponseNode } from '../nodes/ResponseNode';
|
|
18
19
|
import { TraceNode } from '../nodes/TraceNode';
|
|
19
20
|
import { BoardNode } from '../nodes/BoardNode';
|
|
21
|
+
import { RelationsPanel } from './RelationsPanel';
|
|
22
|
+
import { CrossBoardReferences } from './CrossBoardReferences';
|
|
23
|
+
import { lifecycleTarget, openLifecycle } from '../state/knowledge-store';
|
|
24
|
+
import { knowledgeLifecycleEnabled } from '../state/workspace-settings';
|
|
20
25
|
import {
|
|
21
26
|
collapseExpandedNode,
|
|
22
27
|
contextPinnedNodeIds,
|
|
@@ -129,6 +134,7 @@ export function ExpandedNodeOverlay() {
|
|
|
129
134
|
const nodeId = expandedNodeId.value;
|
|
130
135
|
const node = nodeId ? nodes.value.get(nodeId) : undefined;
|
|
131
136
|
const [copied, setCopied] = useState(false);
|
|
137
|
+
const [relationsFor, setRelationsFor] = useState<string | null>(null);
|
|
132
138
|
const [presenting, setPresenting] = useState(false);
|
|
133
139
|
const [presentationExitToken, setPresentationExitToken] = useState('');
|
|
134
140
|
const presentationOverlayRef = useRef<HTMLDivElement>(null);
|
|
@@ -243,7 +249,17 @@ export function ExpandedNodeOverlay() {
|
|
|
243
249
|
() => (nodeId ? document.querySelector<HTMLElement>(`.canvas-node[data-node-id="${CSS.escape(nodeId)}"]`) : null),
|
|
244
250
|
[nodeId],
|
|
245
251
|
);
|
|
246
|
-
|
|
252
|
+
const reviewing = knowledgeLifecycleEnabled.value && lifecycleTarget.value?.nodeId === nodeId;
|
|
253
|
+
const suspendingFocusedReview =
|
|
254
|
+
!knowledgeLifecycleEnabled.value &&
|
|
255
|
+
lifecycleTarget.value?.nodeId === nodeId &&
|
|
256
|
+
!!document.activeElement?.closest('.lifecycle-dialog');
|
|
257
|
+
useFocusTrap(panelRef, node !== undefined && !reviewing, { restoreTo: restoreToNode });
|
|
258
|
+
useLayoutEffect(() => {
|
|
259
|
+
// Resuming the expanded card's trap must not steal the hidden review's return focus.
|
|
260
|
+
if (suspendingFocusedReview)
|
|
261
|
+
document.querySelector<HTMLElement>('button[aria-label="Settings"]')?.focus({ preventScroll: true });
|
|
262
|
+
}, [reviewing]);
|
|
247
263
|
|
|
248
264
|
if (!node) return null;
|
|
249
265
|
|
|
@@ -282,7 +298,7 @@ export function ExpandedNodeOverlay() {
|
|
|
282
298
|
ref={panelRef}
|
|
283
299
|
class={`expanded-overlay-panel${isCtxPinned ? ' is-pinned' : ''}`}
|
|
284
300
|
role="dialog"
|
|
285
|
-
aria-modal=
|
|
301
|
+
aria-modal={reviewing ? undefined : 'true'}
|
|
286
302
|
aria-label={title}
|
|
287
303
|
data-testid="expanded-node"
|
|
288
304
|
>
|
|
@@ -293,56 +309,73 @@ export function ExpandedNodeOverlay() {
|
|
|
293
309
|
</span>
|
|
294
310
|
<span class="expanded-title">{title}</span>
|
|
295
311
|
<span class="expanded-kind-pill">{TYPE_LABELS[node.type]}</span>
|
|
296
|
-
<
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
312
|
+
<BarHint label={isCtxPinned ? 'In agent context — click to unpin' : 'Pin as agent context'}>
|
|
313
|
+
<button
|
|
314
|
+
type="button"
|
|
315
|
+
class={`expanded-pin${isCtxPinned ? ' is-on' : ''}`}
|
|
316
|
+
onClick={handleToggleCtxPin}
|
|
317
|
+
aria-label={isCtxPinned ? 'In agent context — click to unpin' : 'Pin as agent context'}
|
|
318
|
+
aria-pressed={isCtxPinned}
|
|
319
|
+
>
|
|
320
|
+
✦
|
|
321
|
+
</button>
|
|
322
|
+
</BarHint>
|
|
305
323
|
<span class="expanded-spacer" />
|
|
306
324
|
<div class="expanded-actions">
|
|
307
|
-
{
|
|
308
|
-
<button type="button" class="expanded-action-btn" onClick={
|
|
309
|
-
|
|
325
|
+
{knowledgeLifecycleEnabled.value && (
|
|
326
|
+
<button type="button" class="expanded-action-btn" onClick={() => openLifecycle(node.id)}>
|
|
327
|
+
Review
|
|
310
328
|
</button>
|
|
311
329
|
)}
|
|
330
|
+
<button
|
|
331
|
+
type="button"
|
|
332
|
+
class="expanded-action-btn"
|
|
333
|
+
aria-pressed={relationsFor === nodeId}
|
|
334
|
+
onClick={() => setRelationsFor(relationsFor === nodeId ? null : nodeId)}
|
|
335
|
+
>
|
|
336
|
+
Relations
|
|
337
|
+
</button>
|
|
338
|
+
{hasText && (
|
|
339
|
+
<BarHint label="Copy content to clipboard">
|
|
340
|
+
<button type="button" class="expanded-action-btn" onClick={handleCopy}>
|
|
341
|
+
{copied ? 'Copied!' : 'Copy'}
|
|
342
|
+
</button>
|
|
343
|
+
</BarHint>
|
|
344
|
+
)}
|
|
312
345
|
{canOpenAsSite(node) && (
|
|
313
|
-
<
|
|
314
|
-
type="button"
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
>
|
|
319
|
-
Open in tab <IconExternalLink size={14} />
|
|
320
|
-
</button>
|
|
346
|
+
<BarHint label="Open as a full-page site in the system browser">
|
|
347
|
+
<button type="button" class="expanded-action-btn" onClick={() => void openNodeAsSite(node)}>
|
|
348
|
+
Open in tab <IconExternalLink size={14} />
|
|
349
|
+
</button>
|
|
350
|
+
</BarHint>
|
|
321
351
|
)}
|
|
322
352
|
{canPresent && (
|
|
323
|
-
<
|
|
324
|
-
type="button"
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
>
|
|
329
|
-
Present
|
|
330
|
-
</button>
|
|
353
|
+
<BarHint label="Present this HTML node fullscreen">
|
|
354
|
+
<button type="button" class="expanded-action-btn expanded-action-primary" onClick={handlePresent}>
|
|
355
|
+
Present
|
|
356
|
+
</button>
|
|
357
|
+
</BarHint>
|
|
331
358
|
)}
|
|
332
359
|
</div>
|
|
333
|
-
<
|
|
334
|
-
<
|
|
335
|
-
|
|
360
|
+
<BarHint label="Close" shortcut="Esc" align="end">
|
|
361
|
+
<button type="button" class="expanded-close" onClick={handleClose} aria-label="Close">
|
|
362
|
+
<IconClose />
|
|
363
|
+
</button>
|
|
364
|
+
</BarHint>
|
|
336
365
|
</div>
|
|
337
366
|
|
|
338
367
|
{/* Body: the surface at full size */}
|
|
339
|
-
<div class=
|
|
340
|
-
{isEmbeddedViewer ?
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
368
|
+
<div class="expanded-content-row">
|
|
369
|
+
<div class={`expanded-body${isEmbeddedViewer ? ' is-embedded' : ''}`}>
|
|
370
|
+
{isEmbeddedViewer ? (
|
|
371
|
+
<div style={{ flex: 1, minHeight: 0, display: 'flex' }}>{renderContent(node, true)}</div>
|
|
372
|
+
) : (
|
|
373
|
+
renderContent(node, true)
|
|
374
|
+
)}
|
|
375
|
+
</div>
|
|
376
|
+
{relationsFor === nodeId && <RelationsPanel key={nodeId} nodeId={node.id} />}
|
|
345
377
|
</div>
|
|
378
|
+
<CrossBoardReferences node={node} />
|
|
346
379
|
{/* AX step controls follow the node into focus mode. Without this,
|
|
347
380
|
expanding a materialized flow step showed only its text — the
|
|
348
381
|
Start/Done/Blocked and loop controls live in CanvasNode's body,
|
|
@@ -380,7 +413,6 @@ export function ExpandedNodeOverlay() {
|
|
|
380
413
|
type="button"
|
|
381
414
|
class="html-presentation-exit"
|
|
382
415
|
onClick={handleExitPresentation}
|
|
383
|
-
title="Exit presentation (Esc)"
|
|
384
416
|
aria-label="Exit presentation"
|
|
385
417
|
>
|
|
386
418
|
Exit presentation
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { useLayoutEffect, useRef } from 'preact/hooks';
|
|
2
|
+
import { BarHint } from './BarHint';
|
|
2
3
|
import { IconClose, IconExternalLink } from '../icons';
|
|
3
4
|
import type { AgentPresence } from '../../shared/agent-presence.js';
|
|
4
5
|
import { vetoGhostIntent } from '../state/intent-bridge';
|
|
@@ -10,11 +11,12 @@ import {
|
|
|
10
11
|
agentPresences,
|
|
11
12
|
externalWriterPresences,
|
|
12
13
|
relativeAge,
|
|
13
|
-
|
|
14
|
+
sessionChromeActive,
|
|
14
15
|
writerColor,
|
|
15
16
|
writerInitial,
|
|
16
17
|
writersSheetOpen,
|
|
17
18
|
} from '../state/presence-store';
|
|
19
|
+
import { agentSessionsEnabled } from '../state/workspace-settings';
|
|
18
20
|
import { scopeFence, pendingGates, startSession } from '../state/session-store';
|
|
19
21
|
import { sessionId } from '../state/canvas-store';
|
|
20
22
|
import { useFocusTrap } from './use-focus-trap';
|
|
@@ -46,32 +48,38 @@ function Avatar({ presence, size = 18 }: { presence: Pick<AgentPresence, 'sessio
|
|
|
46
48
|
/** Top-bar indicator: avatar cluster, "3 writers", op count, pulsing dot. */
|
|
47
49
|
export function ExternalWriterIndicator() {
|
|
48
50
|
const writers = externalWriterPresences.value;
|
|
49
|
-
if (
|
|
51
|
+
if (sessionChromeActive.value || writers.length === 0) return null;
|
|
50
52
|
const ops = writers.reduce((sum, writer) => sum + writer.opCount, 0);
|
|
51
53
|
const label = writers.length === 1 ? writers[0]!.label : `${writers.length} writers`;
|
|
52
54
|
const open = activityFeedOpen.value;
|
|
53
55
|
return (
|
|
54
|
-
<
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
aria-expanded={open}
|
|
59
|
-
title={`${writers.length} external writer${writers.length === 1 ? '' : 's'} on this board — click for activity`}
|
|
60
|
-
onClick={() => {
|
|
61
|
-
activityFeedOpen.value = !open;
|
|
62
|
-
}}
|
|
56
|
+
<BarHint
|
|
57
|
+
label={`${writers.length} external writer${writers.length === 1 ? '' : 's'} on this board`}
|
|
58
|
+
body="Click for their activity."
|
|
59
|
+
align="end"
|
|
63
60
|
>
|
|
64
|
-
<
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
61
|
+
<button
|
|
62
|
+
type="button"
|
|
63
|
+
class="external-indicator"
|
|
64
|
+
data-testid="external-indicator"
|
|
65
|
+
aria-label={`${label} external activity, ${ops} operation${ops === 1 ? '' : 's'}`}
|
|
66
|
+
aria-expanded={open}
|
|
67
|
+
onClick={() => {
|
|
68
|
+
activityFeedOpen.value = !open;
|
|
69
|
+
}}
|
|
70
|
+
>
|
|
71
|
+
<span class="external-indicator-avatars">
|
|
72
|
+
{writers.slice(0, 3).map((writer) => (
|
|
73
|
+
<Avatar key={writer.sessionId} presence={writer} />
|
|
74
|
+
))}
|
|
75
|
+
</span>
|
|
76
|
+
<span class="external-indicator-label">{label}</span>
|
|
77
|
+
<span class="external-indicator-ops hud-collapsible-text">
|
|
78
|
+
{ops} op{ops === 1 ? '' : 's'}
|
|
79
|
+
</span>
|
|
80
|
+
<span class="external-indicator-dot" aria-hidden="true" />
|
|
81
|
+
</button>
|
|
82
|
+
</BarHint>
|
|
75
83
|
);
|
|
76
84
|
}
|
|
77
85
|
|
|
@@ -100,17 +108,18 @@ export function ActivityFeed() {
|
|
|
100
108
|
const writers = externalWriterPresences.value;
|
|
101
109
|
const now = useNow(open ? 10_000 : 0);
|
|
102
110
|
// Esc closes the top-most surface: the sheet first, then the feed.
|
|
103
|
-
|
|
111
|
+
useLayoutEffect(() => {
|
|
104
112
|
if (!open) return;
|
|
105
113
|
const onKey = (e: KeyboardEvent) => {
|
|
106
|
-
if (e.key !== 'Escape') return;
|
|
114
|
+
if (e.key !== 'Escape' || e.defaultPrevented) return;
|
|
115
|
+
e.preventDefault();
|
|
107
116
|
if (writersSheetOpen.value) writersSheetOpen.value = false;
|
|
108
117
|
else activityFeedOpen.value = false;
|
|
109
118
|
};
|
|
110
119
|
window.addEventListener('keydown', onKey);
|
|
111
120
|
return () => window.removeEventListener('keydown', onKey);
|
|
112
121
|
}, [open]);
|
|
113
|
-
if (!open ||
|
|
122
|
+
if (!open || sessionChromeActive.value || writers.length === 0) return null;
|
|
114
123
|
|
|
115
124
|
const filter = activityFilter.value;
|
|
116
125
|
const proposals = pendingProposals().filter((intent) => !filter || (intent.source ?? '') === filter);
|
|
@@ -139,7 +148,7 @@ export function ActivityFeed() {
|
|
|
139
148
|
</div>
|
|
140
149
|
<div class="activity-feed-sub">
|
|
141
150
|
{writers.reduce((sum, writer) => sum + writer.opCount, 0)} writes · last{' '}
|
|
142
|
-
{relativeAge(latestWrite(writers), now)} ·
|
|
151
|
+
{relativeAge(latestWrite(writers), now)} · live writers
|
|
143
152
|
</div>
|
|
144
153
|
</div>
|
|
145
154
|
<button
|
|
@@ -219,16 +228,18 @@ export function ActivityFeed() {
|
|
|
219
228
|
>
|
|
220
229
|
Writers
|
|
221
230
|
</button>
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
231
|
+
{agentSessionsEnabled.value && (
|
|
232
|
+
<button
|
|
233
|
+
type="button"
|
|
234
|
+
class="activity-feed-link is-accent"
|
|
235
|
+
onClick={() => {
|
|
236
|
+
activityFeedOpen.value = false;
|
|
237
|
+
void startSession();
|
|
238
|
+
}}
|
|
239
|
+
>
|
|
240
|
+
Start session <IconExternalLink size={14} />
|
|
241
|
+
</button>
|
|
242
|
+
)}
|
|
232
243
|
</div>
|
|
233
244
|
</div>
|
|
234
245
|
);
|
|
@@ -248,8 +259,8 @@ export function WritersSheet() {
|
|
|
248
259
|
const sheetRef = useRef<HTMLDivElement>(null);
|
|
249
260
|
useFocusTrap(sheetRef, open);
|
|
250
261
|
if (!open) return null;
|
|
251
|
-
const sessions = agentPresences.value.filter((presence) => presence.attached);
|
|
252
|
-
const external =
|
|
262
|
+
const sessions = agentSessionsEnabled.value ? agentPresences.value.filter((presence) => presence.attached) : [];
|
|
263
|
+
const external = externalWriterPresences.value;
|
|
253
264
|
const close = () => {
|
|
254
265
|
writersSheetOpen.value = false;
|
|
255
266
|
};
|
|
@@ -272,8 +283,12 @@ export function WritersSheet() {
|
|
|
272
283
|
</button>
|
|
273
284
|
</div>
|
|
274
285
|
<div class="writers-body">
|
|
275
|
-
|
|
276
|
-
|
|
286
|
+
{agentSessionsEnabled.value && (
|
|
287
|
+
<>
|
|
288
|
+
<div class="writers-section">Agent sessions</div>
|
|
289
|
+
{sessions.length === 0 && <div class="writers-empty">None attached — start one from the top bar.</div>}
|
|
290
|
+
</>
|
|
291
|
+
)}
|
|
277
292
|
{sessions.map((presence) => (
|
|
278
293
|
<div key={presence.sessionId} class="writers-row">
|
|
279
294
|
<Avatar presence={presence} size={20} />
|
|
@@ -281,7 +296,7 @@ export function WritersSheet() {
|
|
|
281
296
|
<span class="writers-config">{sessionConfig()}</span>
|
|
282
297
|
</div>
|
|
283
298
|
))}
|
|
284
|
-
<div class="writers-section">External writers · MCP</div>
|
|
299
|
+
<div class="writers-section">{agentSessionsEnabled.value ? 'External writers · MCP' : 'Live writers'}</div>
|
|
285
300
|
{external.length === 0 && <div class="writers-empty">No external writers right now.</div>}
|
|
286
301
|
{external.map((presence) => (
|
|
287
302
|
<div key={presence.sessionId} class="writers-row">
|