pmx-canvas 0.4.8 → 0.5.0
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/extension.mjs +154 -5
- package/.github/extensions/pmx-canvas/steering-delivery.mjs +79 -0
- package/CHANGELOG.md +139 -0
- package/Readme.md +72 -23
- package/dist/canvas/global.css +3069 -796
- package/dist/canvas/index.js +104 -104
- package/dist/json-render/index.css +1 -1
- package/dist/types/cli/agent.d.ts +1 -0
- package/dist/types/cli/commands/pump.d.ts +9 -0
- package/dist/types/client/App.d.ts +1 -1
- package/dist/types/client/canvas/AgentPresenceLayer.d.ts +11 -0
- package/dist/types/client/canvas/BarHint.d.ts +22 -0
- package/dist/types/client/canvas/CanvasNode.d.ts +5 -0
- package/dist/types/client/canvas/CanvasViewport.d.ts +4 -4
- package/dist/types/client/canvas/CommandBar.d.ts +10 -0
- package/dist/types/client/canvas/ConnectionBanner.d.ts +13 -0
- package/dist/types/client/canvas/ContextMenu.d.ts +6 -0
- package/dist/types/client/canvas/EdgeLayer.d.ts +2 -1
- package/dist/types/client/canvas/EmptyState.d.ts +11 -0
- package/dist/types/client/canvas/ExternalWriters.d.ts +5 -0
- package/dist/types/client/canvas/HumanPresenceLayer.d.ts +8 -0
- package/dist/types/client/canvas/Minimap.d.ts +12 -1
- package/dist/types/client/canvas/ScopeFenceLayer.d.ts +8 -0
- package/dist/types/client/canvas/SelectionBar.d.ts +6 -0
- package/dist/types/client/canvas/SessionPanel.d.ts +1 -0
- package/dist/types/client/canvas/SessionReceipt.d.ts +17 -0
- package/dist/types/client/canvas/TextPrompt.d.ts +25 -0
- package/dist/types/client/canvas/ToolRail.d.ts +21 -0
- package/dist/types/client/canvas/TopBar.d.ts +7 -0
- package/dist/types/client/canvas/canvas-area.d.ts +25 -0
- package/dist/types/client/canvas/create-in-view.d.ts +18 -0
- package/dist/types/client/canvas/import-files.d.ts +8 -0
- package/dist/types/client/canvas/kind-colors.d.ts +3 -0
- package/dist/types/client/canvas/use-focus-trap.d.ts +14 -0
- package/dist/types/client/canvas/use-now.d.ts +6 -0
- package/dist/types/client/icons.d.ts +11 -4
- package/dist/types/client/nodes/GroupNode.d.ts +6 -1
- package/dist/types/client/nodes/MarkdownNode.d.ts +2 -0
- package/dist/types/client/nodes/inline-editor-commands.d.ts +3 -4
- package/dist/types/client/state/canvas-store.d.ts +49 -5
- package/dist/types/client/state/human-store.d.ts +26 -0
- package/dist/types/client/state/iframe-mode.d.ts +1 -0
- package/dist/types/client/state/intent-bridge.d.ts +37 -5
- package/dist/types/client/state/node-factory.d.ts +0 -1
- package/dist/types/client/state/presence-store.d.ts +78 -0
- package/dist/types/client/state/session-store.d.ts +176 -0
- package/dist/types/client/types.d.ts +2 -1
- package/dist/types/client/utils/platform.d.ts +2 -0
- package/dist/types/server/agent-presence.d.ts +192 -0
- package/dist/types/server/ax-gate-ttl.d.ts +6 -0
- package/dist/types/server/ax-interaction.d.ts +4 -10
- package/dist/types/server/ax-state-manager.d.ts +21 -2
- package/dist/types/server/ax-state.d.ts +49 -3
- package/dist/types/server/ax-wait.d.ts +13 -0
- package/dist/types/server/canvas-db.d.ts +9 -1
- package/dist/types/server/canvas-operations.d.ts +1 -0
- package/dist/types/server/canvas-state.d.ts +27 -13
- package/dist/types/server/canvas-validation.d.ts +0 -14
- package/dist/types/server/html-surface.d.ts +1 -1
- package/dist/types/server/human-presence.d.ts +40 -0
- package/dist/types/server/index.d.ts +29 -3
- package/dist/types/server/intent-registry.d.ts +7 -0
- package/dist/types/server/mutation-history.d.ts +15 -2
- package/dist/types/server/operations/invoker.d.ts +13 -2
- package/dist/types/server/operations/ops/ax-presence.d.ts +2 -0
- package/dist/types/server/operations/ops/human-presence.d.ts +3 -0
- package/dist/types/server/operations/registry.d.ts +11 -0
- package/dist/types/server/operations/types.d.ts +1 -1
- package/dist/types/server/scope-fence.d.ts +62 -0
- package/dist/types/server/server.d.ts +0 -12
- package/dist/types/shared/agent-presence.d.ts +130 -0
- package/dist/types/shared/approval-gates.d.ts +19 -0
- package/dist/types/shared/auto-arrange.d.ts +0 -1
- package/dist/types/shared/ax-kinds.d.ts +11 -0
- package/dist/types/shared/human-presence.d.ts +31 -0
- package/dist/types/shared/iframe-probe.d.ts +8 -0
- package/dist/types/shared/scope-fence.d.ts +21 -0
- package/docs/RELEASE.md +6 -0
- package/docs/ax-host-adapter-contract.md +30 -14
- package/docs/cli.md +37 -1
- package/docs/environment.md +3 -0
- package/docs/http-api.md +222 -5
- package/docs/mcp.md +6 -5
- package/docs/node-types.md +3 -1
- package/docs/plans/plan-009-tech-debt-backlog.md +13 -0
- package/docs/screenshot.png +0 -0
- package/docs/screenshots/multi-agent-live.png +0 -0
- package/docs/screenshots/workbench-live-dark.png +0 -0
- package/docs/screenshots/workbench-live-light.png +0 -0
- package/docs/sdk.md +1 -1
- package/package.json +1 -1
- package/skills/pmx-canvas/SKILL.md +103 -16
- package/skills/pmx-canvas/references/codex-app-adapter.md +28 -0
- package/skills/pmx-canvas/references/full-reference.md +55 -16
- package/skills/pmx-canvas/references/github-copilot-app-adapter.md +41 -24
- package/skills/pmx-canvas-orchestration/SKILL.md +56 -2
- package/skills/pmx-canvas-testing/SKILL.md +17 -0
- package/src/cli/agent.ts +1 -0
- package/src/cli/commands/copilot.ts +15 -8
- package/src/cli/commands/nodes.ts +1 -19
- package/src/cli/commands/pump.ts +252 -0
- package/src/cli/index.ts +1 -5
- package/src/cli/shared.ts +1 -1
- package/src/client/App.tsx +209 -585
- package/src/client/canvas/AgentPresenceLayer.tsx +74 -0
- package/src/client/canvas/AttentionHistory.tsx +0 -10
- package/src/client/canvas/BarHint.tsx +49 -0
- package/src/client/canvas/CanvasNode.tsx +488 -136
- package/src/client/canvas/CanvasViewport.tsx +190 -94
- package/src/client/canvas/CommandBar.tsx +140 -0
- package/src/client/canvas/CommandPalette.tsx +133 -58
- package/src/client/canvas/ConnectionBanner.tsx +65 -0
- package/src/client/canvas/ContextMenu.tsx +88 -27
- package/src/client/canvas/ContextPinBar.tsx +2 -2
- package/src/client/canvas/EdgeLayer.tsx +121 -38
- package/src/client/canvas/EmptyState.tsx +93 -0
- package/src/client/canvas/ExpandedNodeOverlay.tsx +64 -118
- package/src/client/canvas/ExternalWriters.tsx +308 -0
- package/src/client/canvas/FocusFieldLayer.tsx +12 -1
- package/src/client/canvas/HumanPresenceLayer.tsx +45 -0
- package/src/client/canvas/IntentLayer.tsx +1 -1
- package/src/client/canvas/Minimap.tsx +117 -190
- package/src/client/canvas/ScopeFenceLayer.tsx +38 -0
- package/src/client/canvas/SelectionBar.tsx +175 -23
- package/src/client/canvas/SessionPanel.tsx +481 -0
- package/src/client/canvas/SessionReceipt.tsx +141 -0
- package/src/client/canvas/ShortcutOverlay.tsx +21 -6
- package/src/client/canvas/SnapshotPanel.tsx +166 -80
- package/src/client/canvas/TextPrompt.tsx +128 -0
- package/src/client/canvas/ToolRail.tsx +447 -0
- package/src/client/canvas/TopBar.tsx +308 -0
- package/src/client/canvas/auto-fit.ts +1 -5
- package/src/client/canvas/canvas-area.ts +41 -0
- package/src/client/canvas/create-in-view.ts +48 -0
- package/src/client/canvas/import-files.ts +64 -0
- package/src/client/canvas/kind-colors.ts +22 -0
- package/src/client/canvas/snap-guides.ts +1 -1
- package/src/client/canvas/use-focus-trap.ts +54 -0
- package/src/client/canvas/use-now.ts +17 -0
- package/src/client/canvas/use-pan-zoom.ts +13 -2
- package/src/client/icons.tsx +57 -18
- package/src/client/nodes/GroupNode.tsx +9 -28
- package/src/client/nodes/InlineFormatBar.tsx +4 -3
- package/src/client/nodes/InlineMarkdownEditor.tsx +27 -0
- package/src/client/nodes/MarkdownNode.tsx +59 -24
- package/src/client/nodes/MdFormatBar.tsx +2 -4
- package/src/client/nodes/inline-editor-commands.ts +17 -6
- package/src/client/nodes/use-surface-frame.ts +3 -1
- package/src/client/state/attention-bridge.ts +3 -0
- package/src/client/state/canvas-store.ts +273 -84
- package/src/client/state/human-store.ts +175 -0
- package/src/client/state/iframe-mode.ts +33 -9
- package/src/client/state/intent-bridge.ts +75 -13
- package/src/client/state/node-factory.ts +2 -8
- package/src/client/state/presence-store.ts +168 -0
- package/src/client/state/session-store.ts +419 -0
- package/src/client/state/sse-bridge.ts +93 -30
- package/src/client/theme/global.css +3069 -796
- package/src/client/types.ts +3 -1
- package/src/client/utils/platform.ts +6 -1
- package/src/mcp/canvas-access.ts +2 -2
- package/src/server/agent-presence.ts +755 -0
- package/src/server/ax-context.ts +45 -0
- package/src/server/ax-gate-ttl.ts +61 -0
- package/src/server/ax-interaction.ts +29 -1
- package/src/server/ax-state-manager.ts +78 -6
- package/src/server/ax-state.ts +82 -15
- package/src/server/ax-wait.ts +33 -0
- package/src/server/canvas-db.ts +103 -33
- package/src/server/canvas-operations.ts +17 -8
- package/src/server/canvas-state.ts +131 -58
- package/src/server/canvas-validation.ts +3 -53
- package/src/server/demo-state.json +2 -70
- package/src/server/html-surface.ts +11 -2
- package/src/server/human-presence.ts +160 -0
- package/src/server/index.ts +107 -4
- package/src/server/intent-registry.ts +13 -0
- package/src/server/mutation-history.ts +47 -2
- package/src/server/operations/composites.ts +6 -3
- package/src/server/operations/http.ts +10 -1
- package/src/server/operations/index.ts +4 -0
- package/src/server/operations/invoker.ts +33 -6
- package/src/server/operations/ops/ax-presence.ts +62 -0
- package/src/server/operations/ops/ax-read.ts +8 -0
- package/src/server/operations/ops/ax-state.ts +106 -1
- package/src/server/operations/ops/ax-timeline.ts +54 -5
- package/src/server/operations/ops/ax-work.ts +46 -0
- package/src/server/operations/ops/batch.ts +3 -1
- package/src/server/operations/ops/edges.ts +88 -2
- package/src/server/operations/ops/groups.ts +4 -3
- package/src/server/operations/ops/human-presence.ts +35 -0
- package/src/server/operations/ops/json-render.ts +11 -1
- package/src/server/operations/ops/nodes.ts +65 -16
- package/src/server/operations/ops/query.ts +1 -0
- package/src/server/operations/ops/snapshots.ts +16 -0
- package/src/server/operations/registry.ts +196 -1
- package/src/server/operations/types.ts +1 -1
- package/src/server/scope-fence.ts +207 -0
- package/src/server/server.ts +177 -79
- package/src/server/trace-manager.ts +0 -2
- package/src/server/web-artifacts.ts +0 -1
- package/src/shared/agent-presence.ts +162 -0
- package/src/shared/approval-gates.ts +35 -0
- package/src/shared/auto-arrange.ts +121 -13
- package/src/shared/ax-kinds.ts +23 -0
- package/src/shared/human-presence.ts +30 -0
- package/src/shared/iframe-probe.ts +8 -0
- package/src/shared/scope-fence.ts +31 -0
- package/dist/types/client/canvas/DockedNode.d.ts +0 -4
- package/src/client/canvas/DockedNode.tsx +0 -165
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { useRef } from 'preact/hooks';
|
|
2
|
+
import { agentIdentityHue, agentPhaseLabel, type AgentPresence } from '../../shared/agent-presence.js';
|
|
3
|
+
import { nodes, viewport } from '../state/canvas-store';
|
|
4
|
+
import { agentPresences, presenceWorldPosition } from '../state/presence-store';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Agent presence layer (rail-chrome-v2 phase 3): one cursor + phase chip per
|
|
8
|
+
* live writer — attached sessions and external (unattached) writers alike. Lives inside the
|
|
9
|
+
* world layer (like IntentLayer) so it pans and zooms with the board; the
|
|
10
|
+
* glyph itself is counter-scaled so it stays a constant screen size. Moves
|
|
11
|
+
* glide (220ms) — pans and zooms do not, because those move the world layer.
|
|
12
|
+
*
|
|
13
|
+
* Sibling of IntentLayer by design: ghosts show WHAT is about to change and
|
|
14
|
+
* carry the veto; this layer shows WHERE the agent is and WHAT PHASE it is in.
|
|
15
|
+
*/
|
|
16
|
+
export function AgentPresenceLayer() {
|
|
17
|
+
// Remember the last resolved position per writer so a cursor parked on a
|
|
18
|
+
// node that was just removed stays where it was instead of vanishing.
|
|
19
|
+
const lastPositions = useRef(new Map<string, { x: number; y: number }>());
|
|
20
|
+
|
|
21
|
+
const scale = viewport.value.scale;
|
|
22
|
+
const nodeMap = nodes.value;
|
|
23
|
+
const counterScale = 1 / Math.max(0.05, scale);
|
|
24
|
+
|
|
25
|
+
// Every live writer paints a cursor, attached session or not — an external
|
|
26
|
+
// writer editing a quiet board is exactly when the human needs to see WHERE
|
|
27
|
+
// it is working (user call, 2026-08-24). Unattached writers get the
|
|
28
|
+
// `is-external` style; a board with no writers renders nothing. Attached
|
|
29
|
+
// twins never double-paint (twin-merge folds an agent's channels into one
|
|
30
|
+
// session), and an external writer's channels appear exactly as the
|
|
31
|
+
// External-activity panel counts them.
|
|
32
|
+
const cursors = agentPresences.value
|
|
33
|
+
.map((presence) => {
|
|
34
|
+
const resolved = presenceWorldPosition(presence, (id) => nodeMap.get(id));
|
|
35
|
+
if (resolved) lastPositions.current.set(presence.sessionId, resolved);
|
|
36
|
+
const position = resolved ?? lastPositions.current.get(presence.sessionId) ?? null;
|
|
37
|
+
return position ? { presence, position } : null;
|
|
38
|
+
})
|
|
39
|
+
.filter((entry): entry is { presence: AgentPresence; position: { x: number; y: number } } => entry !== null);
|
|
40
|
+
|
|
41
|
+
if (cursors.length === 0) return null;
|
|
42
|
+
|
|
43
|
+
return (
|
|
44
|
+
<div class="agent-presence-layer" aria-hidden="true">
|
|
45
|
+
{cursors.map(({ presence, position }) => (
|
|
46
|
+
<div
|
|
47
|
+
key={presence.sessionId}
|
|
48
|
+
class={`agent-cursor phase-${presence.phase}${presence.attached ? '' : ' is-external'}${presence.parentAgentId ? ' is-worker' : ''}`}
|
|
49
|
+
data-session-id={presence.sessionId}
|
|
50
|
+
style={{
|
|
51
|
+
transform: `translate(${position.x}px, ${position.y}px)`,
|
|
52
|
+
'--identity-color': `hsl(${agentIdentityHue(presence.sessionId)} 65% 62%)`,
|
|
53
|
+
}}
|
|
54
|
+
>
|
|
55
|
+
<div class="agent-cursor-inner" style={{ transform: `scale(${counterScale})` }}>
|
|
56
|
+
<svg class="agent-cursor-glyph" width="16" height="18" viewBox="0 0 16 18" aria-hidden="true">
|
|
57
|
+
<path
|
|
58
|
+
d="M1.5 1.5L14.5 9.2 8.3 10.6 5.2 16.5z"
|
|
59
|
+
fill="currentColor"
|
|
60
|
+
stroke="var(--c-bg)"
|
|
61
|
+
stroke-width="1.2"
|
|
62
|
+
/>
|
|
63
|
+
</svg>
|
|
64
|
+
<span class="agent-cursor-chip">
|
|
65
|
+
<span class="agent-cursor-dot" />
|
|
66
|
+
<span class="agent-cursor-label">{agentPhaseLabel(presence)}</span>
|
|
67
|
+
<span class="agent-cursor-who">{presence.label}</span>
|
|
68
|
+
</span>
|
|
69
|
+
</div>
|
|
70
|
+
</div>
|
|
71
|
+
))}
|
|
72
|
+
</div>
|
|
73
|
+
);
|
|
74
|
+
}
|
|
@@ -5,7 +5,6 @@ import {
|
|
|
5
5
|
closeAttentionHistory,
|
|
6
6
|
openAttentionHistory,
|
|
7
7
|
} from '../state/attention-store';
|
|
8
|
-
import { collapseDockedContextNodes, hasOpenDockedContextPanel } from '../state/canvas-store';
|
|
9
8
|
|
|
10
9
|
function formatTimestamp(timestamp: number): string {
|
|
11
10
|
return new Date(timestamp).toLocaleTimeString([], {
|
|
@@ -15,9 +14,6 @@ function formatTimestamp(timestamp: number): string {
|
|
|
15
14
|
}
|
|
16
15
|
|
|
17
16
|
function handleOpenUpdates(): void {
|
|
18
|
-
// Mutual exclusion with the Context panel — only one side panel open at a
|
|
19
|
-
// time (they share the same right-edge anchor).
|
|
20
|
-
collapseDockedContextNodes();
|
|
21
17
|
openAttentionHistory();
|
|
22
18
|
}
|
|
23
19
|
|
|
@@ -27,12 +23,6 @@ export function AttentionHistory() {
|
|
|
27
23
|
|
|
28
24
|
const isOpen = attentionHistoryOpen.value;
|
|
29
25
|
const unread = attentionHistoryUnread.value;
|
|
30
|
-
// Hide the collapsed Updates pill while the Context side panel is open —
|
|
31
|
-
// the panel sits at the same right-edge and would visually cover the pill.
|
|
32
|
-
// Mutual exclusion guarantees both can't be expanded simultaneously, so the
|
|
33
|
-
// pill only needs to hide while context is expanded.
|
|
34
|
-
if (!isOpen && hasOpenDockedContextPanel.value) return null;
|
|
35
|
-
|
|
36
26
|
if (!isOpen) {
|
|
37
27
|
return (
|
|
38
28
|
<button
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { ComponentChildren } from 'preact';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Styled hover/focus tooltip for bar controls — the replacement for native
|
|
5
|
+
* `title` hints, which are delay-gated and never render in embedded panes.
|
|
6
|
+
*/
|
|
7
|
+
export function BarHint({
|
|
8
|
+
label,
|
|
9
|
+
shortcut,
|
|
10
|
+
body,
|
|
11
|
+
align = 'center',
|
|
12
|
+
side = 'down',
|
|
13
|
+
tapToOpen = false,
|
|
14
|
+
children,
|
|
15
|
+
}: {
|
|
16
|
+
label: string;
|
|
17
|
+
shortcut?: string;
|
|
18
|
+
/** One or two plain sentences under the label — the explanation a native `title` used to hide. */
|
|
19
|
+
body?: string;
|
|
20
|
+
align?: 'start' | 'center' | 'end';
|
|
21
|
+
/** Which way the tooltip opens. Bars at the bottom of the region open 'up'. */
|
|
22
|
+
side?: 'down' | 'up';
|
|
23
|
+
/**
|
|
24
|
+
* Informational (non-button) content: a click/focus opens the tooltip, so
|
|
25
|
+
* surfaces that do not forward hover (embedded panes, touch) still reach
|
|
26
|
+
* the explanation. Never for action buttons — their tooltips must dismiss
|
|
27
|
+
* after the click, not linger on focus.
|
|
28
|
+
*/
|
|
29
|
+
tapToOpen?: boolean;
|
|
30
|
+
children: ComponentChildren;
|
|
31
|
+
}) {
|
|
32
|
+
return (
|
|
33
|
+
<span
|
|
34
|
+
class={`toolbar-tooltip-anchor toolbar-tooltip-anchor-${align}${side === 'up' ? ' toolbar-tooltip-anchor-up' : ''}${tapToOpen ? ' toolbar-tooltip-anchor-tap' : ''}`}
|
|
35
|
+
tabIndex={tapToOpen ? -1 : undefined}
|
|
36
|
+
>
|
|
37
|
+
{children}
|
|
38
|
+
<span class="toolbar-tooltip" role="tooltip">
|
|
39
|
+
<span class="toolbar-tooltip-label">{label}</span>
|
|
40
|
+
{body && <span class="toolbar-tooltip-body">{body}</span>}
|
|
41
|
+
{shortcut && (
|
|
42
|
+
<span class="toolbar-tooltip-meta">
|
|
43
|
+
<kbd class="toolbar-tooltip-shortcut">{shortcut}</kbd>
|
|
44
|
+
</span>
|
|
45
|
+
)}
|
|
46
|
+
</span>
|
|
47
|
+
</span>
|
|
48
|
+
);
|
|
49
|
+
}
|