@agentdeck/shared 1.0.20 → 1.0.22

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 (78) hide show
  1. package/dist/adapter.d.ts +1 -1
  2. package/dist/adapter.d.ts.map +1 -1
  3. package/dist/adapter.js.map +1 -1
  4. package/dist/creature-layout.d.ts +10 -0
  5. package/dist/creature-layout.d.ts.map +1 -1
  6. package/dist/creature-layout.js +22 -0
  7. package/dist/creature-layout.js.map +1 -1
  8. package/dist/d200h-layout.js +28 -5
  9. package/dist/d200h-layout.js.map +1 -1
  10. package/dist/design-tokens.d.ts +4 -0
  11. package/dist/design-tokens.d.ts.map +1 -1
  12. package/dist/design-tokens.js +2 -0
  13. package/dist/design-tokens.js.map +1 -1
  14. package/dist/eval-schema.d.ts +81 -0
  15. package/dist/eval-schema.d.ts.map +1 -1
  16. package/dist/eval-schema.js +15 -0
  17. package/dist/eval-schema.js.map +1 -1
  18. package/dist/format-utils.d.ts +123 -8
  19. package/dist/format-utils.d.ts.map +1 -1
  20. package/dist/format-utils.js +147 -15
  21. package/dist/format-utils.js.map +1 -1
  22. package/dist/gateway-protocol.d.ts +17 -22
  23. package/dist/gateway-protocol.d.ts.map +1 -1
  24. package/dist/gateway-protocol.js.map +1 -1
  25. package/dist/index.d.ts +3 -0
  26. package/dist/index.d.ts.map +1 -1
  27. package/dist/index.js +3 -0
  28. package/dist/index.js.map +1 -1
  29. package/dist/mdns-identity.d.ts +68 -0
  30. package/dist/mdns-identity.d.ts.map +1 -0
  31. package/dist/mdns-identity.js +83 -0
  32. package/dist/mdns-identity.js.map +1 -0
  33. package/dist/model-provider.d.ts +67 -0
  34. package/dist/model-provider.d.ts.map +1 -0
  35. package/dist/model-provider.js +143 -0
  36. package/dist/model-provider.js.map +1 -0
  37. package/dist/openclaw-approval.d.ts +128 -0
  38. package/dist/openclaw-approval.d.ts.map +1 -0
  39. package/dist/openclaw-approval.js +177 -0
  40. package/dist/openclaw-approval.js.map +1 -0
  41. package/dist/protocol.d.ts +38 -0
  42. package/dist/protocol.d.ts.map +1 -1
  43. package/dist/protocol.js.map +1 -1
  44. package/dist/session-utils.d.ts +14 -1
  45. package/dist/session-utils.d.ts.map +1 -1
  46. package/dist/session-utils.js +22 -3
  47. package/dist/session-utils.js.map +1 -1
  48. package/dist/state-colors.d.ts.map +1 -1
  49. package/dist/state-colors.js +2 -0
  50. package/dist/state-colors.js.map +1 -1
  51. package/dist/states.d.ts +8 -0
  52. package/dist/states.d.ts.map +1 -1
  53. package/dist/states.js +31 -23
  54. package/dist/states.js.map +1 -1
  55. package/dist/subagent-activity.d.ts +10 -4
  56. package/dist/subagent-activity.d.ts.map +1 -1
  57. package/dist/subagent-activity.js +36 -19
  58. package/dist/subagent-activity.js.map +1 -1
  59. package/dist/svg-renderers/agent-logos.d.ts +2 -0
  60. package/dist/svg-renderers/agent-logos.d.ts.map +1 -1
  61. package/dist/svg-renderers/agent-logos.js +13 -0
  62. package/dist/svg-renderers/agent-logos.js.map +1 -1
  63. package/dist/svg-renderers/session-slot-renderer.d.ts +15 -0
  64. package/dist/svg-renderers/session-slot-renderer.d.ts.map +1 -1
  65. package/dist/svg-renderers/session-slot-renderer.js +28 -1
  66. package/dist/svg-renderers/session-slot-renderer.js.map +1 -1
  67. package/dist/telemetry-envelope.d.ts +13 -0
  68. package/dist/telemetry-envelope.d.ts.map +1 -1
  69. package/dist/telemetry-envelope.js +1 -0
  70. package/dist/telemetry-envelope.js.map +1 -1
  71. package/dist/timeline-label.d.ts.map +1 -1
  72. package/dist/timeline-label.js +4 -0
  73. package/dist/timeline-label.js.map +1 -1
  74. package/dist/timeline.d.ts +29 -0
  75. package/dist/timeline.d.ts.map +1 -1
  76. package/dist/timeline.js +38 -7
  77. package/dist/timeline.js.map +1 -1
  78. package/package.json +1 -1
@@ -0,0 +1,68 @@
1
+ /**
2
+ * How a daemon names itself on `_agentdeck._tcp`, and how a client tells one
3
+ * daemon's advertisement from another's.
4
+ *
5
+ * A DNS-SD instance name must be unique **per network segment**, not per host.
6
+ * Both daemons published `${project}-${port}` — literally `AgentDeck-9120` on
7
+ * every machine — so on an office subnet fifty daemons fought over one name.
8
+ * The Node side does not rename on conflict: it treats "already in use on the
9
+ * network" as non-fatal, destroys the responder, and the 5-second recovery
10
+ * timer republishes it, forever. The result is a permanent republish storm and
11
+ * no daemon that stays reliably resolvable (docs/ENTERPRISE-ROADMAP.md §2.1).
12
+ *
13
+ * There is prior art for how badly naming goes wrong here: issue #67, where the
14
+ * responder's HOSTNAME claim renamed users' Macs. `MDNS_SERVICE_HOST` was made
15
+ * process-unique for exactly that reason; the instance name never got the same
16
+ * treatment.
17
+ *
18
+ * The name identifies host, user and port, because those are the three ways two
19
+ * daemons on one segment can legitimately differ. The user is a short hash, not
20
+ * an account name — the segment does not need to learn who is logged in where,
21
+ * and multicast is readable by everyone on it.
22
+ *
23
+ * This is the SSOT for both daemons; the Swift mirror is generated
24
+ * (`pnpm generate-mdns-identity`, drift-gated in
25
+ * `shared/src/__tests__/mdns-identity.test.ts`).
26
+ */
27
+ /** TXT schema version, in lockstep between the Node and Swift daemons.
28
+ * Unchanged by the host/user keys below: no reader validates the key SET (the
29
+ * ESP32 walks the record looking for `agent` and `project`), so additive keys
30
+ * are readable by every existing client, and bumping would be a compatibility
31
+ * event with no compatibility problem to solve. */
32
+ export declare const MDNS_TXT_SCHEMA_VERSION = "3";
33
+ /** Longest host label kept in the instance name. DNS-SD allows 63 bytes for
34
+ * the whole instance name, and it also has to hold the project, the user tag
35
+ * and the port. */
36
+ export declare const MDNS_HOST_LABEL_MAX = 20;
37
+ /**
38
+ * Reduce a string to characters that are safe and readable in a DNS-SD
39
+ * instance label. The spec permits far more than this — the point is not
40
+ * escaping rules but that the name stays greppable in `dns-sd -B` output and
41
+ * cannot collide by way of some client's normalization.
42
+ */
43
+ export declare function sanitizeMdnsLabel(raw: string, maxLength?: number): string;
44
+ /**
45
+ * Short, stable, non-reversible tag for the OS user a daemon runs as.
46
+ *
47
+ * FNV-1a rather than a crypto hash so the Swift mirror is a dozen lines with no
48
+ * framework import, and because this is a disambiguator, not a secret: it only
49
+ * has to distinguish the handful of accounts on one machine, and it must never
50
+ * be the account name itself, which multicast would then publish to the whole
51
+ * segment.
52
+ */
53
+ export declare function mdnsUserTag(uid: number, username?: string): string;
54
+ /**
55
+ * The instance name a daemon publishes.
56
+ *
57
+ * Every component is optional-safe: an empty hostname or user tag collapses to
58
+ * the old `${project}-${port}` shape rather than producing `AgentDeck--9120`,
59
+ * so a platform that cannot answer one of the questions degrades to today's
60
+ * behaviour instead of a malformed name.
61
+ */
62
+ export declare function buildMdnsInstanceName(opts: {
63
+ project: string;
64
+ hostname?: string;
65
+ userTag?: string;
66
+ port: number;
67
+ }): string;
68
+ //# sourceMappingURL=mdns-identity.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mdns-identity.d.ts","sourceRoot":"","sources":["../src/mdns-identity.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH;;;;oDAIoD;AACpD,eAAO,MAAM,uBAAuB,MAAM,CAAC;AAE3C;;oBAEoB;AACpB,eAAO,MAAM,mBAAmB,KAAK,CAAC;AAEtC;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,SAAsB,GAAG,MAAM,CAOtF;AAED;;;;;;;;GAQG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,SAAK,GAAG,MAAM,CAS9D;AAED;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE;IAC1C,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;CACd,GAAG,MAAM,CAIT"}
@@ -0,0 +1,83 @@
1
+ /**
2
+ * How a daemon names itself on `_agentdeck._tcp`, and how a client tells one
3
+ * daemon's advertisement from another's.
4
+ *
5
+ * A DNS-SD instance name must be unique **per network segment**, not per host.
6
+ * Both daemons published `${project}-${port}` — literally `AgentDeck-9120` on
7
+ * every machine — so on an office subnet fifty daemons fought over one name.
8
+ * The Node side does not rename on conflict: it treats "already in use on the
9
+ * network" as non-fatal, destroys the responder, and the 5-second recovery
10
+ * timer republishes it, forever. The result is a permanent republish storm and
11
+ * no daemon that stays reliably resolvable (docs/ENTERPRISE-ROADMAP.md §2.1).
12
+ *
13
+ * There is prior art for how badly naming goes wrong here: issue #67, where the
14
+ * responder's HOSTNAME claim renamed users' Macs. `MDNS_SERVICE_HOST` was made
15
+ * process-unique for exactly that reason; the instance name never got the same
16
+ * treatment.
17
+ *
18
+ * The name identifies host, user and port, because those are the three ways two
19
+ * daemons on one segment can legitimately differ. The user is a short hash, not
20
+ * an account name — the segment does not need to learn who is logged in where,
21
+ * and multicast is readable by everyone on it.
22
+ *
23
+ * This is the SSOT for both daemons; the Swift mirror is generated
24
+ * (`pnpm generate-mdns-identity`, drift-gated in
25
+ * `shared/src/__tests__/mdns-identity.test.ts`).
26
+ */
27
+ /** TXT schema version, in lockstep between the Node and Swift daemons.
28
+ * Unchanged by the host/user keys below: no reader validates the key SET (the
29
+ * ESP32 walks the record looking for `agent` and `project`), so additive keys
30
+ * are readable by every existing client, and bumping would be a compatibility
31
+ * event with no compatibility problem to solve. */
32
+ export const MDNS_TXT_SCHEMA_VERSION = '3';
33
+ /** Longest host label kept in the instance name. DNS-SD allows 63 bytes for
34
+ * the whole instance name, and it also has to hold the project, the user tag
35
+ * and the port. */
36
+ export const MDNS_HOST_LABEL_MAX = 20;
37
+ /**
38
+ * Reduce a string to characters that are safe and readable in a DNS-SD
39
+ * instance label. The spec permits far more than this — the point is not
40
+ * escaping rules but that the name stays greppable in `dns-sd -B` output and
41
+ * cannot collide by way of some client's normalization.
42
+ */
43
+ export function sanitizeMdnsLabel(raw, maxLength = MDNS_HOST_LABEL_MAX) {
44
+ const cleaned = (raw || '')
45
+ .split('.')[0] // `mac.local` / FQDN → the short name
46
+ .replace(/[^A-Za-z0-9-]+/g, '-') // spaces, apostrophes ("Sam's MacBook")
47
+ .replace(/-+/g, '-')
48
+ .replace(/^-|-$/g, '');
49
+ return cleaned.slice(0, maxLength);
50
+ }
51
+ /**
52
+ * Short, stable, non-reversible tag for the OS user a daemon runs as.
53
+ *
54
+ * FNV-1a rather than a crypto hash so the Swift mirror is a dozen lines with no
55
+ * framework import, and because this is a disambiguator, not a secret: it only
56
+ * has to distinguish the handful of accounts on one machine, and it must never
57
+ * be the account name itself, which multicast would then publish to the whole
58
+ * segment.
59
+ */
60
+ export function mdnsUserTag(uid, username = '') {
61
+ let hash = 0x811c9dc5;
62
+ const input = `${uid}:${username}`;
63
+ for (let i = 0; i < input.length; i++) {
64
+ hash ^= input.charCodeAt(i) & 0xff;
65
+ // FNV prime 16777619, kept in 32-bit range via Math.imul.
66
+ hash = Math.imul(hash, 0x01000193) >>> 0;
67
+ }
68
+ return hash.toString(16).padStart(8, '0').slice(0, 4);
69
+ }
70
+ /**
71
+ * The instance name a daemon publishes.
72
+ *
73
+ * Every component is optional-safe: an empty hostname or user tag collapses to
74
+ * the old `${project}-${port}` shape rather than producing `AgentDeck--9120`,
75
+ * so a platform that cannot answer one of the questions degrades to today's
76
+ * behaviour instead of a malformed name.
77
+ */
78
+ export function buildMdnsInstanceName(opts) {
79
+ const host = sanitizeMdnsLabel(opts.hostname ?? '');
80
+ const user = sanitizeMdnsLabel(opts.userTag ?? '', 8);
81
+ return [opts.project, host, user, String(opts.port)].filter(Boolean).join('-');
82
+ }
83
+ //# sourceMappingURL=mdns-identity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mdns-identity.js","sourceRoot":"","sources":["../src/mdns-identity.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH;;;;oDAIoD;AACpD,MAAM,CAAC,MAAM,uBAAuB,GAAG,GAAG,CAAC;AAE3C;;oBAEoB;AACpB,MAAM,CAAC,MAAM,mBAAmB,GAAG,EAAE,CAAC;AAEtC;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAAC,GAAW,EAAE,SAAS,GAAG,mBAAmB;IAC5E,MAAM,OAAO,GAAG,CAAC,GAAG,IAAI,EAAE,CAAC;SACxB,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAoB,sCAAsC;SACvE,OAAO,CAAC,iBAAiB,EAAE,GAAG,CAAC,CAAE,wCAAwC;SACzE,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC;SACnB,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;IACzB,OAAO,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC;AACrC,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,WAAW,CAAC,GAAW,EAAE,QAAQ,GAAG,EAAE;IACpD,IAAI,IAAI,GAAG,UAAU,CAAC;IACtB,MAAM,KAAK,GAAG,GAAG,GAAG,IAAI,QAAQ,EAAE,CAAC;IACnC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,IAAI,IAAI,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;QACnC,0DAA0D;QAC1D,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,UAAU,CAAC,KAAK,CAAC,CAAC;IAC3C,CAAC;IACD,OAAO,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AACxD,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,qBAAqB,CAAC,IAKrC;IACC,MAAM,IAAI,GAAG,iBAAiB,CAAC,IAAI,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC;IACpD,MAAM,IAAI,GAAG,iBAAiB,CAAC,IAAI,CAAC,OAAO,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC;IACtD,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACjF,CAAC"}
@@ -0,0 +1,67 @@
1
+ /**
2
+ * Which company's endpoint is this model actually answering from — the third
3
+ * identity axis, next to the harness (`agentType`) and the model (`modelName`).
4
+ *
5
+ * Three axes, not two, because they vary independently:
6
+ *
7
+ * - **harness** — which CLI/app is driving (Claude Code, Codex, OpenCode …).
8
+ * It decides the hook set, the transcript format, the steering path and the
9
+ * creature. `agentType` carries it.
10
+ * - **model** — which weights answered. `modelName` carries it.
11
+ * - **provider** — whose endpoint served those weights. Nothing carried it.
12
+ *
13
+ * A `claude-glm` session is Claude Code (same binary, same hooks, same
14
+ * transcript) pointed at z.ai by `ANTHROPIC_BASE_URL`. Minting a `claude-glm`
15
+ * *agentType* for it would be wrong twice over: it conflates the harness with
16
+ * the endpoint, and — because every surface's agent handling is an allow-list —
17
+ * a value no client predates renders as nothing at all. The model field already
18
+ * says `glm-5.3`. What was missing is the one-bit fact a reader actually wants:
19
+ * *this Claude is not talking to Anthropic*.
20
+ *
21
+ * Polarity, per the unknown-agent rule: every mapping here is an ALLOW-list.
22
+ * An unrecognized model returns `'unknown'`, which means "no information" and
23
+ * renders as nothing — never as some other company's name. A deny-list would
24
+ * dress every model released after this file as whatever the fallback bucket
25
+ * happened to be.
26
+ */
27
+ /** Companies whose endpoints AgentDeck can name. `'unknown'` is the honest
28
+ * answer for anything else and must render as no badge, never as a guess. */
29
+ export type ModelProvider = 'anthropic' | 'openai' | 'google' | 'zai' | 'moonshot' | 'deepseek' | 'alibaba' | 'xai' | 'mistral' | 'meta' | 'unknown';
30
+ /** Display names. Kept beside the ids so a surface never spells one itself. */
31
+ export declare const MODEL_PROVIDER_LABELS: Readonly<Record<ModelProvider, string>>;
32
+ /** Substrings that identify a provider from a model id, most specific first.
33
+ * Order matters only where one family's name contains another's. */
34
+ export declare const MODEL_MARKERS: ReadonlyArray<readonly [ModelProvider, readonly string[]]>;
35
+ /** Vendor prefixes as they appear in `provider/model` ids (`zai/glm-5.2`). */
36
+ export declare const VENDOR_PREFIXES: Readonly<Record<string, ModelProvider>>;
37
+ /**
38
+ * Name the provider behind a model id, or `'unknown'` when nothing matches.
39
+ *
40
+ * Accepts every id shape the wire actually carries: bare (`glm-5.3`), vendored
41
+ * (`zai/glm-5.2`), and display-formatted (`GLM-5.2 (1M)`, `gpt-5.6-sol high`).
42
+ */
43
+ export declare function modelProvider(modelName?: string | null): ModelProvider;
44
+ /**
45
+ * The provider each harness talks to when nobody has redirected it.
46
+ *
47
+ * Allow-list, and deliberately short: `openclaw`, `opencode`, `antigravity` and
48
+ * `kiro` are multi-provider by design, so they HAVE no native provider and are
49
+ * absent here — which is what stops them from wearing a permanent "off-harness"
50
+ * badge for doing exactly what they are for.
51
+ */
52
+ export declare const HARNESS_NATIVE_PROVIDERS: Readonly<Record<string, ModelProvider>>;
53
+ /** The provider a harness talks to unredirected, or `'unknown'`. */
54
+ export declare function harnessNativeProvider(agentType?: string | null): ModelProvider;
55
+ /**
56
+ * The provider to badge on a session row, or `null` for "say nothing".
57
+ *
58
+ * Non-null only when BOTH sides are known and they disagree — i.e. a harness
59
+ * with a native provider is demonstrably answering from somewhere else. Two
60
+ * unknowns must never combine into a claim: absence of evidence is not evidence
61
+ * of redirection, and a badge on every unrecognized model would be noise on
62
+ * exactly the rows we know least about.
63
+ */
64
+ export declare function offHarnessProvider(agentType?: string | null, modelName?: string | null): ModelProvider | null;
65
+ /** Badge text for a session row — `''` when there is nothing to say. */
66
+ export declare function offHarnessProviderLabel(agentType?: string | null, modelName?: string | null): string;
67
+ //# sourceMappingURL=model-provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model-provider.d.ts","sourceRoot":"","sources":["../src/model-provider.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH;8EAC8E;AAC9E,MAAM,MAAM,aAAa,GACrB,WAAW,GACX,QAAQ,GACR,QAAQ,GACR,KAAK,GACL,UAAU,GACV,UAAU,GACV,SAAS,GACT,KAAK,GACL,SAAS,GACT,MAAM,GACN,SAAS,CAAC;AAEd,+EAA+E;AAC/E,eAAO,MAAM,qBAAqB,EAAE,QAAQ,CAAC,MAAM,CAAC,aAAa,EAAE,MAAM,CAAC,CAYzE,CAAC;AAEF;qEACqE;AACrE,eAAO,MAAM,aAAa,EAAE,aAAa,CAAC,SAAS,CAAC,aAAa,EAAE,SAAS,MAAM,EAAE,CAAC,CAapF,CAAC;AAEF,8EAA8E;AAC9E,eAAO,MAAM,eAAe,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAgBnE,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,aAAa,CAkBtE;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,wBAAwB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAM5E,CAAC;AAEF,oEAAoE;AACpE,wBAAgB,qBAAqB,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,aAAa,CAE9E;AAED;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAChC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,EACzB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,GACxB,aAAa,GAAG,IAAI,CAMtB;AAED,wEAAwE;AACxE,wBAAgB,uBAAuB,CACrC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,EACzB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,GACxB,MAAM,CAGR"}
@@ -0,0 +1,143 @@
1
+ /**
2
+ * Which company's endpoint is this model actually answering from — the third
3
+ * identity axis, next to the harness (`agentType`) and the model (`modelName`).
4
+ *
5
+ * Three axes, not two, because they vary independently:
6
+ *
7
+ * - **harness** — which CLI/app is driving (Claude Code, Codex, OpenCode …).
8
+ * It decides the hook set, the transcript format, the steering path and the
9
+ * creature. `agentType` carries it.
10
+ * - **model** — which weights answered. `modelName` carries it.
11
+ * - **provider** — whose endpoint served those weights. Nothing carried it.
12
+ *
13
+ * A `claude-glm` session is Claude Code (same binary, same hooks, same
14
+ * transcript) pointed at z.ai by `ANTHROPIC_BASE_URL`. Minting a `claude-glm`
15
+ * *agentType* for it would be wrong twice over: it conflates the harness with
16
+ * the endpoint, and — because every surface's agent handling is an allow-list —
17
+ * a value no client predates renders as nothing at all. The model field already
18
+ * says `glm-5.3`. What was missing is the one-bit fact a reader actually wants:
19
+ * *this Claude is not talking to Anthropic*.
20
+ *
21
+ * Polarity, per the unknown-agent rule: every mapping here is an ALLOW-list.
22
+ * An unrecognized model returns `'unknown'`, which means "no information" and
23
+ * renders as nothing — never as some other company's name. A deny-list would
24
+ * dress every model released after this file as whatever the fallback bucket
25
+ * happened to be.
26
+ */
27
+ /** Display names. Kept beside the ids so a surface never spells one itself. */
28
+ export const MODEL_PROVIDER_LABELS = {
29
+ anthropic: 'Anthropic',
30
+ openai: 'OpenAI',
31
+ google: 'Google',
32
+ zai: 'z.ai',
33
+ moonshot: 'Moonshot',
34
+ deepseek: 'DeepSeek',
35
+ alibaba: 'Qwen',
36
+ xai: 'xAI',
37
+ mistral: 'Mistral',
38
+ meta: 'Meta',
39
+ unknown: '',
40
+ };
41
+ /** Substrings that identify a provider from a model id, most specific first.
42
+ * Order matters only where one family's name contains another's. */
43
+ export const MODEL_MARKERS = [
44
+ ['anthropic', ['claude', 'opus', 'sonnet', 'haiku', 'fable']],
45
+ // `codex-mini` is an OpenAI model id; the Codex *harness* is matched
46
+ // separately by `harnessNativeProvider`.
47
+ ['openai', ['gpt-', 'gpt.', 'o1-', 'o3-', 'o4-', 'codex-', 'davinci', 'chatgpt']],
48
+ ['google', ['gemini', 'gemma', 'palm-']],
49
+ ['zai', ['glm', 'z-ai', 'zai']],
50
+ ['moonshot', ['kimi', 'moonshot']],
51
+ ['deepseek', ['deepseek']],
52
+ ['alibaba', ['qwen', 'qwq']],
53
+ ['xai', ['grok']],
54
+ ['mistral', ['mistral', 'magistral', 'devstral', 'codestral', 'mixtral']],
55
+ ['meta', ['llama']],
56
+ ];
57
+ /** Vendor prefixes as they appear in `provider/model` ids (`zai/glm-5.2`). */
58
+ export const VENDOR_PREFIXES = {
59
+ anthropic: 'anthropic',
60
+ openai: 'openai',
61
+ google: 'google',
62
+ 'google-vertex': 'google',
63
+ zai: 'zai',
64
+ 'z-ai': 'zai',
65
+ zhipu: 'zai',
66
+ moonshot: 'moonshot',
67
+ moonshotai: 'moonshot',
68
+ deepseek: 'deepseek',
69
+ alibaba: 'alibaba',
70
+ qwen: 'alibaba',
71
+ xai: 'xai',
72
+ mistral: 'mistral',
73
+ meta: 'meta',
74
+ };
75
+ /**
76
+ * Name the provider behind a model id, or `'unknown'` when nothing matches.
77
+ *
78
+ * Accepts every id shape the wire actually carries: bare (`glm-5.3`), vendored
79
+ * (`zai/glm-5.2`), and display-formatted (`GLM-5.2 (1M)`, `gpt-5.6-sol high`).
80
+ */
81
+ export function modelProvider(modelName) {
82
+ const raw = (modelName ?? '').trim().toLowerCase();
83
+ if (!raw)
84
+ return 'unknown';
85
+ // `vendor/model` — the vendor half is authoritative when we recognize it.
86
+ const slash = raw.indexOf('/');
87
+ if (slash > 0) {
88
+ const vendor = VENDOR_PREFIXES[raw.slice(0, slash)];
89
+ if (vendor)
90
+ return vendor;
91
+ }
92
+ const id = slash > 0 ? raw.slice(slash + 1) : raw;
93
+ for (const [provider, markers] of MODEL_MARKERS) {
94
+ for (const marker of markers) {
95
+ if (id.includes(marker))
96
+ return provider;
97
+ }
98
+ }
99
+ return 'unknown';
100
+ }
101
+ /**
102
+ * The provider each harness talks to when nobody has redirected it.
103
+ *
104
+ * Allow-list, and deliberately short: `openclaw`, `opencode`, `antigravity` and
105
+ * `kiro` are multi-provider by design, so they HAVE no native provider and are
106
+ * absent here — which is what stops them from wearing a permanent "off-harness"
107
+ * badge for doing exactly what they are for.
108
+ */
109
+ export const HARNESS_NATIVE_PROVIDERS = {
110
+ claude: 'anthropic',
111
+ 'claude-code': 'anthropic',
112
+ codex: 'openai',
113
+ 'codex-cli': 'openai',
114
+ 'codex-app': 'openai',
115
+ };
116
+ /** The provider a harness talks to unredirected, or `'unknown'`. */
117
+ export function harnessNativeProvider(agentType) {
118
+ return HARNESS_NATIVE_PROVIDERS[(agentType ?? '').trim().toLowerCase()] ?? 'unknown';
119
+ }
120
+ /**
121
+ * The provider to badge on a session row, or `null` for "say nothing".
122
+ *
123
+ * Non-null only when BOTH sides are known and they disagree — i.e. a harness
124
+ * with a native provider is demonstrably answering from somewhere else. Two
125
+ * unknowns must never combine into a claim: absence of evidence is not evidence
126
+ * of redirection, and a badge on every unrecognized model would be noise on
127
+ * exactly the rows we know least about.
128
+ */
129
+ export function offHarnessProvider(agentType, modelName) {
130
+ const native = harnessNativeProvider(agentType);
131
+ if (native === 'unknown')
132
+ return null;
133
+ const actual = modelProvider(modelName);
134
+ if (actual === 'unknown' || actual === native)
135
+ return null;
136
+ return actual;
137
+ }
138
+ /** Badge text for a session row — `''` when there is nothing to say. */
139
+ export function offHarnessProviderLabel(agentType, modelName) {
140
+ const provider = offHarnessProvider(agentType, modelName);
141
+ return provider ? MODEL_PROVIDER_LABELS[provider] : '';
142
+ }
143
+ //# sourceMappingURL=model-provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model-provider.js","sourceRoot":"","sources":["../src/model-provider.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,128 @@
1
+ /**
2
+ * openclaw-approval.ts — SSOT for OpenClaw exec-approval prompts.
3
+ *
4
+ * WHY THIS FILE EXISTS. The approval surface was originally typed from an
5
+ * assumption rather than from OpenClaw's own SDK, and every part of that guess
6
+ * was wrong in a way that failed silently:
7
+ *
8
+ * - The `exec.approval.requested` event was read as a FLAT payload
9
+ * (`payload.command` / `payload.ask`). The Gateway actually nests the whole
10
+ * thing under `request` (`buildRequestedApprovalEvent` →
11
+ * `{ id, request, createdAtMs, expiresAtMs }`), so every field read as
12
+ * `undefined` and the prompt collapsed to the literal fallback string
13
+ * "Approve tool execution?" — the user could see that something wanted
14
+ * approval but never WHAT.
15
+ * - `ask` is the approval POLICY ("on-miss" / "always"), not a question. It
16
+ * was being rendered as if it were the human-readable ask.
17
+ * - The decision vocabulary was typed as `'allow' | 'deny'`. The Gateway
18
+ * accepts only `'allow-once' | 'allow-always' | 'deny'` (its
19
+ * `isApprovalDecision`), and validates the decision BEFORE it looks the
20
+ * approval id up — so every "allow" AgentDeck ever sent came back
21
+ * INVALID_REQUEST and the approval stayed pending. The wrong vocabulary was
22
+ * baked into the shared TypeScript type, so the compiler actively enforced
23
+ * the unusable value.
24
+ *
25
+ * The lesson that keeps this file honest: the requested format lives in THEIR
26
+ * SDK. Everything below is derived from the OpenClaw gateway bundle
27
+ * (`approval-shared`, `exec-approval`, `exec-approvals`), not from inference.
28
+ *
29
+ * Parsing is pure and lives here so the Node adapter, the Swift daemon mirror,
30
+ * and the tests all agree on one normalization.
31
+ */
32
+ /**
33
+ * The decisions the Gateway will accept for an exec approval.
34
+ * Mirror of OpenClaw's `isApprovalDecision` / `DEFAULT_EXEC_APPROVAL_DECISIONS`.
35
+ * `'allow'` is NOT a member — sending it is rejected as an invalid decision.
36
+ */
37
+ export type ExecApprovalDecision = 'allow-once' | 'allow-always' | 'deny';
38
+ /** Full decision set, in the order the Gateway lists them. */
39
+ export declare const EXEC_APPROVAL_DECISIONS: readonly ExecApprovalDecision[];
40
+ export declare function isExecApprovalDecision(value: unknown): value is ExecApprovalDecision;
41
+ /** `true` for the decisions that let the command run. */
42
+ export declare function execApprovalAllows(decision: string | null | undefined): boolean;
43
+ export declare function execApprovalDecisionLabel(decision: ExecApprovalDecision): string;
44
+ /** The `request` body OpenClaw nests inside the requested event. */
45
+ export interface ExecApprovalRequestBody {
46
+ /** Sanitized command display text — the thing the user is approving. */
47
+ command?: string;
48
+ /** Non-node hosts send a preview instead of the full command. */
49
+ commandPreview?: string;
50
+ commandArgv?: string[];
51
+ cwd?: string | null;
52
+ host?: string | null;
53
+ /** Approval POLICY ("on-miss" | "always" | …), never a question. */
54
+ ask?: string | null;
55
+ security?: string | null;
56
+ /** Human-readable risk note, when the Gateway produced one. */
57
+ warningText?: string | null;
58
+ /** Gateway-side static analysis summary of the command. */
59
+ commandAnalysis?: string | null;
60
+ /** Decisions this specific request permits (policy may drop allow-always). */
61
+ allowedDecisions?: string[];
62
+ unavailableDecisions?: string[];
63
+ agentId?: string | null;
64
+ sessionKey?: string | null;
65
+ resolvedPath?: string | null;
66
+ }
67
+ /**
68
+ * `exec.approval.requested` payload. The nested `request` is the real shape;
69
+ * the flat fields are tolerated so a future/legacy Gateway that inlines them
70
+ * still parses instead of silently producing an empty prompt.
71
+ */
72
+ export interface ExecApprovalRequestedPayload extends Partial<ExecApprovalRequestBody> {
73
+ id: string;
74
+ request?: ExecApprovalRequestBody;
75
+ createdAtMs?: number;
76
+ expiresAtMs?: number;
77
+ }
78
+ /** `exec.approval.resolved` payload (`buildResolvedEvent` in exec-approval). */
79
+ export interface ExecApprovalResolvedPayload {
80
+ id: string;
81
+ decision: ExecApprovalDecision | string;
82
+ resolvedBy?: string | null;
83
+ ts?: number;
84
+ request?: ExecApprovalRequestBody;
85
+ }
86
+ /** One renderable choice on a deck surface. */
87
+ export interface ExecApprovalOption {
88
+ index: number;
89
+ label: string;
90
+ shortcut: string;
91
+ decision: ExecApprovalDecision;
92
+ }
93
+ /**
94
+ * Normalized prompt — what every surface renders and what an answer maps back
95
+ * through. Deliberately carries the decision on each option so an index press
96
+ * can never be re-derived (and mis-derived) at the answer site.
97
+ */
98
+ export interface OpenClawApprovalPrompt {
99
+ id: string;
100
+ /** Headline: the command itself, so the user knows what they are approving. */
101
+ question: string;
102
+ /** Supporting lines (cwd, warning, analysis) for surfaces with room. */
103
+ detail?: string;
104
+ /** Raw command text, unprefixed — for the timeline row. */
105
+ command: string;
106
+ cwd?: string;
107
+ options: ExecApprovalOption[];
108
+ /** Wall-clock expiry, when the Gateway set one. */
109
+ expiresAtMs?: number;
110
+ requestedAtMs: number;
111
+ sessionKey?: string;
112
+ }
113
+ /**
114
+ * Normalize a raw `exec.approval.requested` payload. Returns `null` only when
115
+ * the payload carries no usable id — a request with no command text still
116
+ * produces a prompt (labeled as unknown) so the user keeps the ability to deny.
117
+ */
118
+ export declare function parseExecApprovalRequest(payload: ExecApprovalRequestedPayload | Record<string, unknown> | null | undefined, nowMs: number): OpenClawApprovalPrompt | null;
119
+ /** Map a `select_option` index onto the decision that option represents. */
120
+ export declare function decisionForOptionIndex(prompt: OpenClawApprovalPrompt, index: number): ExecApprovalDecision | null;
121
+ /**
122
+ * Map a `respond` value onto a decision. Accepts the option shortcut, the
123
+ * decision name itself, and the y/n/a spellings a hardware key or the wake-word
124
+ * assistant sends. Anything unrecognized returns `null` — an ambiguous press
125
+ * must never be guessed into an approval.
126
+ */
127
+ export declare function decisionForRespondValue(prompt: OpenClawApprovalPrompt, value: string): ExecApprovalDecision | null;
128
+ //# sourceMappingURL=openclaw-approval.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openclaw-approval.d.ts","sourceRoot":"","sources":["../src/openclaw-approval.ts"],"names":[],"mappings":"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"}