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

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 (61) hide show
  1. package/README.md +1 -1
  2. package/README_zh.md +1 -1
  3. package/assets/stageDist/assets/index-Bj7S2pA1.css +1 -1
  4. package/assets/stageDist/assets/index-C-28k_o5.js +974 -974
  5. package/assets/stageDist/index.html +12 -12
  6. package/lib/client.js +64 -64
  7. package/lib/client.js.map +1 -1
  8. package/lib/index.js +57 -9
  9. package/lib/origin-claim.js +4 -0
  10. package/lib/skill/SKILL.md +117 -117
  11. package/lib/skill/references/collaboration.md +428 -428
  12. package/lib/skill/references/discovery.md +78 -78
  13. package/lib/skill/references/intake.md +107 -107
  14. package/lib/skill/references/membership.md +73 -73
  15. package/lib/skill/references/pitfalls.md +51 -51
  16. package/lib/skill/references/router.md +96 -96
  17. package/lib/skill/references/routing.md +65 -65
  18. package/lib/types/origin-claim.d.ts +2 -0
  19. package/nexus-stage/package.json +21 -21
  20. package/nexus-stage/scripts/mockhost.py +261 -261
  21. package/nexus-stage/src/canvas-ops.ts +191 -191
  22. package/nexus-stage/src/canvas-wire.ts +164 -164
  23. package/nexus-stage/src/cli-home-picker.ts +42 -42
  24. package/nexus-stage/src/fault.ts +56 -56
  25. package/nexus-stage/src/federation-overlay.ts +103 -103
  26. package/nexus-stage/src/federation.ts +241 -241
  27. package/nexus-stage/src/layout-doc.ts +145 -145
  28. package/nexus-stage/src/main.ts +513 -513
  29. package/nexus-stage/src/planning-card-text.ts +73 -73
  30. package/nexus-stage/src/planning-card.ts +63 -63
  31. package/nexus-stage/src/planning-edges.ts +26 -26
  32. package/nexus-stage/src/planning-fit.ts +45 -45
  33. package/nexus-stage/src/planning-frame-hue.ts +13 -13
  34. package/nexus-stage/src/planning-legend.ts +39 -39
  35. package/nexus-stage/src/planning-member-handles.ts +61 -61
  36. package/nexus-stage/src/planning-menus.ts +422 -422
  37. package/nexus-stage/src/planning-mirror.ts +75 -75
  38. package/nexus-stage/src/planning-nodelist.ts +294 -294
  39. package/nexus-stage/src/planning-overlap.ts +159 -159
  40. package/nexus-stage/src/planning-reachability.ts +28 -28
  41. package/nexus-stage/src/planning-relayout.ts +121 -121
  42. package/nexus-stage/src/planning-roster.ts +15 -15
  43. package/nexus-stage/src/planning-search.ts +168 -168
  44. package/nexus-stage/src/planning-types.ts +115 -115
  45. package/nexus-stage/src/planning-undo.ts +68 -68
  46. package/nexus-stage/src/planning-view.ts +1499 -1499
  47. package/nexus-stage/src/planning.css +340 -340
  48. package/nexus-stage/src/seat-name-editor.ts +31 -31
  49. package/nexus-stage/src/session-drag.ts +64 -64
  50. package/nexus-stage/src/viewport.ts +106 -106
  51. package/nexus-stage/src/wb-chat.ts +684 -684
  52. package/nexus-stage/src/wb-directory.ts +237 -237
  53. package/nexus-stage/src/wb-ledger.ts +279 -279
  54. package/nexus-stage/src/wb-names.ts +43 -43
  55. package/nexus-stage/src/wb-rail.ts +147 -147
  56. package/nexus-stage/src/workbench.css +388 -388
  57. package/nexus-stage/src/workbench.ts +1272 -1272
  58. package/nexus-stage/src/world.ts +509 -509
  59. package/nexus-stage/tsconfig.json +24 -24
  60. package/nexus-stage/vite.config.ts +15 -15
  61. package/package.json +1 -1
@@ -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
+ }