@adhdev/mesh-shared 1.0.48 → 1.0.49-rc.10
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/dist/daemon-normalize.d.ts +50 -0
- package/dist/index.js +19 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +17 -1
- package/dist/index.mjs.map +1 -1
- package/dist/mesh-tool-names.d.ts +2 -2
- package/package.json +1 -1
- package/src/daemon-normalize.ts +67 -0
- package/src/mesh-tool-names.ts +2 -0
package/src/daemon-normalize.ts
CHANGED
|
@@ -33,6 +33,73 @@ import { readString } from './json'
|
|
|
33
33
|
|
|
34
34
|
const DAEMON_ID_PREFIXES = ['daemon_', 'standalone_'] as const
|
|
35
35
|
|
|
36
|
+
/**
|
|
37
|
+
* A daemon DO addressed by a raw 64-hex DO id (`idFromString`) rather than by a
|
|
38
|
+
* canonical name (`idFromName("daemon_mach_<hex>")`). Decide by FORMAT, not by
|
|
39
|
+
* length — the canonical name is 43+ chars, so a `length > 32` heuristic would
|
|
40
|
+
* misclassify it. Mirrors the server's session-routing `isRawDoId`.
|
|
41
|
+
*/
|
|
42
|
+
export function isRawDaemonDoId(id: string | null | undefined): boolean {
|
|
43
|
+
const trimmed = readString(id)
|
|
44
|
+
return !!trimmed && /^[0-9a-f]{64}$/i.test(trimmed)
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/** The machine-evidence fields a real daemon reports about its hardware. */
|
|
48
|
+
export interface DaemonMachineEvidence {
|
|
49
|
+
machineNickname?: string | null
|
|
50
|
+
nickname?: string | null
|
|
51
|
+
hostname?: string | null
|
|
52
|
+
platform?: string | null
|
|
53
|
+
machineId?: string | null
|
|
54
|
+
machine?: { hostname?: string | null; platform?: string | null } | null
|
|
55
|
+
sessions?: unknown[] | null
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* A phantom daemon entry — a UI surface must not offer it as a real machine.
|
|
60
|
+
*
|
|
61
|
+
* Symptom block for the raw-DO-id ghost (GHOST-MACHINE-REGISTRATIONS). When the
|
|
62
|
+
* `X-ADHDEV-Daemon` instanceId header is missing or unparseable, the /ws handler
|
|
63
|
+
* falls back to a random DO name, so every reconnect mints a FRESH raw 64-hex DO
|
|
64
|
+
* id. Those keys accumulate as hardware-less entries that render as a bare hash
|
|
65
|
+
* where a machine name belongs.
|
|
66
|
+
*
|
|
67
|
+
* BOTH conditions are required, and the second is what keeps this safe:
|
|
68
|
+
* 1. the id is a raw DO id — no `daemon_`/`standalone_` canonical prefix.
|
|
69
|
+
* 2. no machine evidence at all — no nickname, hostname, platform, registered
|
|
70
|
+
* machineId, and no sessions.
|
|
71
|
+
*
|
|
72
|
+
* A legacy / not-yet-reauthed daemon that ACTUALLY reports itself fails (2) and
|
|
73
|
+
* therefore still renders, still attaches, and still routes — dropping on (1)
|
|
74
|
+
* alone would make real daemons disappear from the picker. This is strictly a
|
|
75
|
+
* PRESENTATION filter: routing tables (server `lastStatuses`, P2P relay) keep
|
|
76
|
+
* the entry, because the raw key still resolves via `idFromString`.
|
|
77
|
+
*
|
|
78
|
+
* The server applies the same rule to its dashboard payloads via
|
|
79
|
+
* `_unresolvedIdentity` (UserSession.isPhantomMachineEntry). That marker is
|
|
80
|
+
* server-internal and never reaches the browser, and the client daemon store
|
|
81
|
+
* never evicts an entry once injected — so a client surface reading the merged
|
|
82
|
+
* P2P/WS store must re-derive the verdict from the entry SHAPE. This function is
|
|
83
|
+
* that shared rule.
|
|
84
|
+
*/
|
|
85
|
+
export function isPhantomDaemonEntry(
|
|
86
|
+
entry: (DaemonMachineEvidence & { id?: string | null }) | null | undefined,
|
|
87
|
+
): boolean {
|
|
88
|
+
if (!entry) return false
|
|
89
|
+
if (!isRawDaemonDoId(entry.id)) return false
|
|
90
|
+
const hasMachineEvidence = Boolean(
|
|
91
|
+
readString(entry.machineNickname)
|
|
92
|
+
|| readString(entry.nickname)
|
|
93
|
+
|| readString(entry.hostname)
|
|
94
|
+
|| readString(entry.platform)
|
|
95
|
+
|| readString(entry.machine?.hostname)
|
|
96
|
+
|| readString(entry.machine?.platform)
|
|
97
|
+
|| readString(entry.machineId)
|
|
98
|
+
|| (Array.isArray(entry.sessions) && entry.sessions.length > 0),
|
|
99
|
+
)
|
|
100
|
+
return !hasMachineEvidence
|
|
101
|
+
}
|
|
102
|
+
|
|
36
103
|
/**
|
|
37
104
|
* Reduce any daemon-id form to its machine core: strips a leading `daemon_` /
|
|
38
105
|
* `standalone_` prefix, leaving the bare `mach_<hex>` (or returning a non-prefixed
|
package/src/mesh-tool-names.ts
CHANGED
|
@@ -71,6 +71,8 @@ export const CANONICAL_MESH_TOOL_NAMES = [
|
|
|
71
71
|
'mesh_node_slots_set',
|
|
72
72
|
'mesh_node_slots_list',
|
|
73
73
|
'mesh_node_slots_propose',
|
|
74
|
+
'mesh_coordinator_prompt_append_get',
|
|
75
|
+
'mesh_coordinator_prompt_append_set',
|
|
74
76
|
] as const;
|
|
75
77
|
|
|
76
78
|
export type CanonicalMeshToolName = typeof CANONICAL_MESH_TOOL_NAMES[number];
|