@nelsonlongxiang/dsh-open-a2a-net 0.6.41 → 0.6.43

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.
Files changed (72) hide show
  1. package/README.md +2 -1
  2. package/README_zh.md +2 -1
  3. package/assets/nexusDist/assets/index-CaA76j0F.js +9 -0
  4. package/assets/nexusDist/index.html +1 -1
  5. package/assets/stageDist/assets/index-Bj7S2pA1.css +1 -1
  6. package/assets/stageDist/assets/index-C-28k_o5.js +974 -974
  7. package/assets/stageDist/index.html +12 -12
  8. package/cli/a2a.mjs +24 -4
  9. package/lib/canvas-store.js +249 -17
  10. package/lib/client.js +62 -72
  11. package/lib/client.js.map +1 -1
  12. package/lib/config.js +1 -0
  13. package/lib/faces/admin.js +103 -63
  14. package/lib/faces/wire.js +3 -1
  15. package/lib/index.js +116 -22
  16. package/lib/origin-claim.js +4 -0
  17. package/lib/skill/SKILL.md +117 -117
  18. package/lib/skill/references/collaboration.md +428 -428
  19. package/lib/skill/references/discovery.md +78 -78
  20. package/lib/skill/references/intake.md +107 -107
  21. package/lib/skill/references/membership.md +73 -73
  22. package/lib/skill/references/pitfalls.md +51 -51
  23. package/lib/skill/references/router.md +96 -96
  24. package/lib/skill/references/routing.md +65 -65
  25. package/lib/types/canvas-store.d.ts +48 -1
  26. package/lib/types/config.d.ts +2 -0
  27. package/lib/types/faces/admin.d.ts +2 -0
  28. package/lib/types/origin-claim.d.ts +2 -0
  29. package/nexus-stage/package.json +21 -21
  30. package/nexus-stage/scripts/mockhost.py +261 -261
  31. package/nexus-stage/src/canvas-ops.ts +191 -191
  32. package/nexus-stage/src/canvas-wire.ts +164 -164
  33. package/nexus-stage/src/cli-home-picker.ts +42 -42
  34. package/nexus-stage/src/fault.ts +56 -56
  35. package/nexus-stage/src/federation-overlay.ts +103 -103
  36. package/nexus-stage/src/federation.ts +241 -241
  37. package/nexus-stage/src/layout-doc.ts +145 -145
  38. package/nexus-stage/src/main.ts +520 -513
  39. package/nexus-stage/src/planning-card-text.ts +73 -73
  40. package/nexus-stage/src/planning-card.ts +63 -63
  41. package/nexus-stage/src/planning-edges.ts +26 -26
  42. package/nexus-stage/src/planning-fit.ts +45 -45
  43. package/nexus-stage/src/planning-frame-hue.ts +13 -13
  44. package/nexus-stage/src/planning-legend.ts +39 -39
  45. package/nexus-stage/src/planning-member-handles.ts +61 -61
  46. package/nexus-stage/src/planning-menus.ts +422 -422
  47. package/nexus-stage/src/planning-mirror.ts +75 -75
  48. package/nexus-stage/src/planning-nodelist.ts +294 -294
  49. package/nexus-stage/src/planning-overlap.ts +159 -159
  50. package/nexus-stage/src/planning-reachability.ts +28 -28
  51. package/nexus-stage/src/planning-relayout.ts +121 -121
  52. package/nexus-stage/src/planning-roster.ts +15 -15
  53. package/nexus-stage/src/planning-search.ts +168 -168
  54. package/nexus-stage/src/planning-types.ts +115 -115
  55. package/nexus-stage/src/planning-undo.ts +68 -68
  56. package/nexus-stage/src/planning-view.ts +1499 -1499
  57. package/nexus-stage/src/planning.css +340 -340
  58. package/nexus-stage/src/seat-name-editor.ts +31 -31
  59. package/nexus-stage/src/session-drag.ts +64 -64
  60. package/nexus-stage/src/viewport.ts +106 -106
  61. package/nexus-stage/src/wb-chat.ts +684 -684
  62. package/nexus-stage/src/wb-directory.ts +237 -237
  63. package/nexus-stage/src/wb-ledger.ts +279 -279
  64. package/nexus-stage/src/wb-names.ts +43 -43
  65. package/nexus-stage/src/wb-rail.ts +147 -147
  66. package/nexus-stage/src/workbench.css +388 -388
  67. package/nexus-stage/src/workbench.ts +1294 -1272
  68. package/nexus-stage/src/world.ts +509 -509
  69. package/nexus-stage/tsconfig.json +24 -24
  70. package/nexus-stage/vite.config.ts +15 -15
  71. package/package.json +1 -1
  72. package/assets/nexusDist/assets/index-NkNSeIx6.js +0 -9
@@ -1,145 +1,145 @@
1
- /**
2
- * Client-side mirror of the host layout contract (src/layout-store.ts).
3
- * The host module imports node:fs, so the stage cannot share its types -
4
- * this file redeclares the v1 document shape and reimplements the exact
5
- * clamp discipline. Parity is not optional: the save loop adopts the
6
- * host's normalized response, and a mirror that clamped differently from
7
- * the host would make every save look like an external edit and keep the
8
- * save lamp pending forever. The clamp vectors in tests/planning-world.spec.ts
9
- * pin both sides to the same answers.
10
- *
11
- * Zero dependencies, no DOM - unit-testable straight from the root suite.
12
- * @module nexus-stage/layout-doc
13
- */
14
-
15
- /** One draggable point in world space. */
16
- export interface LayoutPoint { readonly x: number; readonly y: number }
17
-
18
- /** One team-frame rectangle in world space. */
19
- export interface LayoutRect extends LayoutPoint { readonly w: number; readonly h: number }
20
-
21
- /** The viewport transform (world point at the top-left corner, plus zoom). */
22
- export interface LayoutViewport extends LayoutPoint { readonly scale: number }
23
-
24
- /** The whole persisted document (v1). */
25
- export interface LayoutDoc {
26
- readonly version: 1
27
- readonly viewport: LayoutViewport
28
- readonly nodes: Readonly<Record<string, LayoutPoint>>
29
- readonly frames: Readonly<Record<string, LayoutRect>>
30
- }
31
-
32
- /** World-coordinate magnitude bound: values beyond are clamped, never trusted. */
33
- export const COORD_LIMIT = 1_000_000
34
- /** Zoom bounds, matching the page's wheel clamps. */
35
- export const SCALE_MIN = 0.25
36
- export const SCALE_MAX = 3
37
- /** Document shape caps: a layout taxonomy, not a database. */
38
- export const LAYOUT_NODE_CAP = 256
39
- export const LAYOUT_FRAME_CAP = 96
40
-
41
- function clampCoord(v: unknown): number | undefined {
42
- const n = typeof v === 'number' ? v : Number.NaN
43
- if (!Number.isFinite(n)) return undefined
44
- return Math.max(-COORD_LIMIT, Math.min(COORD_LIMIT, Math.round(n)))
45
- }
46
-
47
- function clampPoint(raw: unknown): LayoutPoint | undefined {
48
- if (raw === null || typeof raw !== 'object') return undefined
49
- const rec = raw as Record<string, unknown>
50
- const x = clampCoord(rec.x)
51
- const y = clampCoord(rec.y)
52
- return x === undefined || y === undefined ? undefined : { x, y }
53
- }
54
-
55
- function clampRect(raw: unknown): LayoutRect | undefined {
56
- const point = clampPoint(raw)
57
- if (point === undefined) return undefined
58
- const rec = raw as Record<string, unknown>
59
- const w = clampCoord(rec.w)
60
- const h = clampCoord(rec.h)
61
- if (w === undefined || h === undefined || w <= 0 || h <= 0) return undefined
62
- return { ...point, w: Math.min(w, COORD_LIMIT), h: Math.min(h, COORD_LIMIT) }
63
- }
64
-
65
- /**
66
- * Normalize an untrusted layout document exactly as the host does:
67
- * version!==1 rejects the whole doc; non-finite coordinates drop the
68
- * point; coordinates round and clamp to ±COORD_LIMIT; scale clamps to
69
- * [SCALE_MIN, SCALE_MAX]; node keys cap at 128 chars; canvas frame names cap at 40,
70
- * roster:<name> reserves seven extra characters; rects need w>0 and h>0; caps are
71
- * first-wins in insertion order - entries beyond are silently dropped,
72
- * never refused (an overflow renders, it just does not persist).
73
- */
74
- const validFrame = (name: string): boolean => name !== '' && !name.includes('/') && (name.startsWith('roster:') ? name.length > 7 && name.length <= 47 : name.length <= 40)
75
-
76
- export function clampDoc(raw: unknown): LayoutDoc | undefined {
77
- if (raw === null || typeof raw !== 'object') return undefined
78
- const rec = raw as Record<string, unknown>
79
- if (rec.version !== 1) return undefined
80
- const vpRaw = rec.viewport
81
- if (vpRaw === null || typeof vpRaw !== 'object') return undefined
82
- const vp = vpRaw as Record<string, unknown>
83
- const vx = clampCoord(vp.x)
84
- const vy = clampCoord(vp.y)
85
- const vsRaw = vp.scale
86
- const vsNum = typeof vsRaw === 'number' ? vsRaw : Number.NaN
87
- if (vx === undefined || vy === undefined || !Number.isFinite(vsNum)) return undefined
88
- const scale = Math.max(SCALE_MIN, Math.min(SCALE_MAX, vsNum))
89
- const nodes: Record<string, LayoutPoint> = {}
90
- if (rec.nodes !== null && typeof rec.nodes === 'object') {
91
- for (const [id, point] of Object.entries(rec.nodes as Record<string, unknown>)) {
92
- if (typeof id !== 'string' || id === '' || id.length > 128) continue
93
- const p = clampPoint(point)
94
- if (p !== undefined) nodes[id] = p
95
- if (Object.keys(nodes).length >= LAYOUT_NODE_CAP) break
96
- }
97
- }
98
- const frames: Record<string, LayoutRect> = {}
99
- if (rec.frames !== null && typeof rec.frames === 'object') {
100
- for (const [name, rect] of Object.entries(rec.frames as Record<string, unknown>)) {
101
- if (!validFrame(name)) continue
102
- const r = clampRect(rect)
103
- if (r !== undefined) frames[name] = r
104
- if (Object.keys(frames).length >= LAYOUT_FRAME_CAP) break
105
- }
106
- }
107
- return { version: 1, viewport: { x: vx, y: vy, scale }, nodes, frames }
108
- }
109
-
110
- /**
111
- * Build a save payload from trusted in-memory state. Pre-clamps with the
112
- * same mirror discipline and truncates in roster insertion order, so the
113
- * document we send is already the document the host will normalize to -
114
- * the save response is then a fixpoint of our payload, which the save
115
- * loop relies on to tell "our own save echoed back" from "someone else
116
- * edited while the request was in flight".
117
- */
118
- export function buildLayoutDoc(
119
- viewport: LayoutViewport,
120
- nodes: ReadonlyMap<string, LayoutPoint>,
121
- frames: ReadonlyMap<string, LayoutRect>,
122
- ): LayoutDoc {
123
- const clamp = (n: number): number => Math.max(-COORD_LIMIT, Math.min(COORD_LIMIT, Math.round(n)))
124
- const docNodes: Record<string, LayoutPoint> = {}
125
- for (const [id, p] of nodes) {
126
- if (typeof id !== 'string' || id === '' || id.length > 128) continue
127
- docNodes[id] = { x: clamp(p.x), y: clamp(p.y) }
128
- if (Object.keys(docNodes).length >= LAYOUT_NODE_CAP) break
129
- }
130
- const docFrames: Record<string, LayoutRect> = {}
131
- for (const [name, r] of frames) {
132
- if (!validFrame(name)) continue
133
- const w = clamp(r.w)
134
- const h = clamp(r.h)
135
- if (w <= 0 || h <= 0) continue
136
- docFrames[name] = { x: clamp(r.x), y: clamp(r.y), w: Math.min(w, COORD_LIMIT), h: Math.min(h, COORD_LIMIT) }
137
- if (Object.keys(docFrames).length >= LAYOUT_FRAME_CAP) break
138
- }
139
- return {
140
- version: 1,
141
- viewport: { x: clamp(viewport.x), y: clamp(viewport.y), scale: Math.max(SCALE_MIN, Math.min(SCALE_MAX, viewport.scale)) },
142
- nodes: docNodes,
143
- frames: docFrames,
144
- }
145
- }
1
+ /**
2
+ * Client-side mirror of the host layout contract (src/layout-store.ts).
3
+ * The host module imports node:fs, so the stage cannot share its types -
4
+ * this file redeclares the v1 document shape and reimplements the exact
5
+ * clamp discipline. Parity is not optional: the save loop adopts the
6
+ * host's normalized response, and a mirror that clamped differently from
7
+ * the host would make every save look like an external edit and keep the
8
+ * save lamp pending forever. The clamp vectors in tests/planning-world.spec.ts
9
+ * pin both sides to the same answers.
10
+ *
11
+ * Zero dependencies, no DOM - unit-testable straight from the root suite.
12
+ * @module nexus-stage/layout-doc
13
+ */
14
+
15
+ /** One draggable point in world space. */
16
+ export interface LayoutPoint { readonly x: number; readonly y: number }
17
+
18
+ /** One team-frame rectangle in world space. */
19
+ export interface LayoutRect extends LayoutPoint { readonly w: number; readonly h: number }
20
+
21
+ /** The viewport transform (world point at the top-left corner, plus zoom). */
22
+ export interface LayoutViewport extends LayoutPoint { readonly scale: number }
23
+
24
+ /** The whole persisted document (v1). */
25
+ export interface LayoutDoc {
26
+ readonly version: 1
27
+ readonly viewport: LayoutViewport
28
+ readonly nodes: Readonly<Record<string, LayoutPoint>>
29
+ readonly frames: Readonly<Record<string, LayoutRect>>
30
+ }
31
+
32
+ /** World-coordinate magnitude bound: values beyond are clamped, never trusted. */
33
+ export const COORD_LIMIT = 1_000_000
34
+ /** Zoom bounds, matching the page's wheel clamps. */
35
+ export const SCALE_MIN = 0.25
36
+ export const SCALE_MAX = 3
37
+ /** Document shape caps: a layout taxonomy, not a database. */
38
+ export const LAYOUT_NODE_CAP = 256
39
+ export const LAYOUT_FRAME_CAP = 96
40
+
41
+ function clampCoord(v: unknown): number | undefined {
42
+ const n = typeof v === 'number' ? v : Number.NaN
43
+ if (!Number.isFinite(n)) return undefined
44
+ return Math.max(-COORD_LIMIT, Math.min(COORD_LIMIT, Math.round(n)))
45
+ }
46
+
47
+ function clampPoint(raw: unknown): LayoutPoint | undefined {
48
+ if (raw === null || typeof raw !== 'object') return undefined
49
+ const rec = raw as Record<string, unknown>
50
+ const x = clampCoord(rec.x)
51
+ const y = clampCoord(rec.y)
52
+ return x === undefined || y === undefined ? undefined : { x, y }
53
+ }
54
+
55
+ function clampRect(raw: unknown): LayoutRect | undefined {
56
+ const point = clampPoint(raw)
57
+ if (point === undefined) return undefined
58
+ const rec = raw as Record<string, unknown>
59
+ const w = clampCoord(rec.w)
60
+ const h = clampCoord(rec.h)
61
+ if (w === undefined || h === undefined || w <= 0 || h <= 0) return undefined
62
+ return { ...point, w: Math.min(w, COORD_LIMIT), h: Math.min(h, COORD_LIMIT) }
63
+ }
64
+
65
+ /**
66
+ * Normalize an untrusted layout document exactly as the host does:
67
+ * version!==1 rejects the whole doc; non-finite coordinates drop the
68
+ * point; coordinates round and clamp to ±COORD_LIMIT; scale clamps to
69
+ * [SCALE_MIN, SCALE_MAX]; node keys cap at 128 chars; canvas frame names cap at 40,
70
+ * roster:<name> reserves seven extra characters; rects need w>0 and h>0; caps are
71
+ * first-wins in insertion order - entries beyond are silently dropped,
72
+ * never refused (an overflow renders, it just does not persist).
73
+ */
74
+ const validFrame = (name: string): boolean => name !== '' && !name.includes('/') && (name.startsWith('roster:') ? name.length > 7 && name.length <= 47 : name.length <= 40)
75
+
76
+ export function clampDoc(raw: unknown): LayoutDoc | undefined {
77
+ if (raw === null || typeof raw !== 'object') return undefined
78
+ const rec = raw as Record<string, unknown>
79
+ if (rec.version !== 1) return undefined
80
+ const vpRaw = rec.viewport
81
+ if (vpRaw === null || typeof vpRaw !== 'object') return undefined
82
+ const vp = vpRaw as Record<string, unknown>
83
+ const vx = clampCoord(vp.x)
84
+ const vy = clampCoord(vp.y)
85
+ const vsRaw = vp.scale
86
+ const vsNum = typeof vsRaw === 'number' ? vsRaw : Number.NaN
87
+ if (vx === undefined || vy === undefined || !Number.isFinite(vsNum)) return undefined
88
+ const scale = Math.max(SCALE_MIN, Math.min(SCALE_MAX, vsNum))
89
+ const nodes: Record<string, LayoutPoint> = {}
90
+ if (rec.nodes !== null && typeof rec.nodes === 'object') {
91
+ for (const [id, point] of Object.entries(rec.nodes as Record<string, unknown>)) {
92
+ if (typeof id !== 'string' || id === '' || id.length > 128) continue
93
+ const p = clampPoint(point)
94
+ if (p !== undefined) nodes[id] = p
95
+ if (Object.keys(nodes).length >= LAYOUT_NODE_CAP) break
96
+ }
97
+ }
98
+ const frames: Record<string, LayoutRect> = {}
99
+ if (rec.frames !== null && typeof rec.frames === 'object') {
100
+ for (const [name, rect] of Object.entries(rec.frames as Record<string, unknown>)) {
101
+ if (!validFrame(name)) continue
102
+ const r = clampRect(rect)
103
+ if (r !== undefined) frames[name] = r
104
+ if (Object.keys(frames).length >= LAYOUT_FRAME_CAP) break
105
+ }
106
+ }
107
+ return { version: 1, viewport: { x: vx, y: vy, scale }, nodes, frames }
108
+ }
109
+
110
+ /**
111
+ * Build a save payload from trusted in-memory state. Pre-clamps with the
112
+ * same mirror discipline and truncates in roster insertion order, so the
113
+ * document we send is already the document the host will normalize to -
114
+ * the save response is then a fixpoint of our payload, which the save
115
+ * loop relies on to tell "our own save echoed back" from "someone else
116
+ * edited while the request was in flight".
117
+ */
118
+ export function buildLayoutDoc(
119
+ viewport: LayoutViewport,
120
+ nodes: ReadonlyMap<string, LayoutPoint>,
121
+ frames: ReadonlyMap<string, LayoutRect>,
122
+ ): LayoutDoc {
123
+ const clamp = (n: number): number => Math.max(-COORD_LIMIT, Math.min(COORD_LIMIT, Math.round(n)))
124
+ const docNodes: Record<string, LayoutPoint> = {}
125
+ for (const [id, p] of nodes) {
126
+ if (typeof id !== 'string' || id === '' || id.length > 128) continue
127
+ docNodes[id] = { x: clamp(p.x), y: clamp(p.y) }
128
+ if (Object.keys(docNodes).length >= LAYOUT_NODE_CAP) break
129
+ }
130
+ const docFrames: Record<string, LayoutRect> = {}
131
+ for (const [name, r] of frames) {
132
+ if (!validFrame(name)) continue
133
+ const w = clamp(r.w)
134
+ const h = clamp(r.h)
135
+ if (w <= 0 || h <= 0) continue
136
+ docFrames[name] = { x: clamp(r.x), y: clamp(r.y), w: Math.min(w, COORD_LIMIT), h: Math.min(h, COORD_LIMIT) }
137
+ if (Object.keys(docFrames).length >= LAYOUT_FRAME_CAP) break
138
+ }
139
+ return {
140
+ version: 1,
141
+ viewport: { x: clamp(viewport.x), y: clamp(viewport.y), scale: Math.max(SCALE_MIN, Math.min(SCALE_MAX, viewport.scale)) },
142
+ nodes: docNodes,
143
+ frames: docFrames,
144
+ }
145
+ }