@stateforge-labs/herdr-sdk 0.0.0-stage → 0.3.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.
Files changed (171) hide show
  1. package/LICENSE +18 -0
  2. package/NOTICE.md +51 -0
  3. package/README.md +211 -2
  4. package/bin/herdr-drift.js +14 -0
  5. package/bin/herdr-skill.js +38 -0
  6. package/dist/admin.d.ts +2 -0
  7. package/dist/admin.js +3 -0
  8. package/dist/constants.d.ts +236 -0
  9. package/dist/constants.js +294 -0
  10. package/dist/core/backoff.d.ts +20 -0
  11. package/dist/core/backoff.js +53 -0
  12. package/dist/core/constants.d.ts +143 -0
  13. package/dist/core/constants.js +98 -0
  14. package/dist/core/errors.d.ts +35 -0
  15. package/dist/core/errors.js +16 -0
  16. package/dist/core/events.d.ts +42 -0
  17. package/dist/core/events.js +128 -0
  18. package/dist/core/kernel.d.ts +65 -0
  19. package/dist/core/kernel.js +138 -0
  20. package/dist/core/link.d.ts +47 -0
  21. package/dist/core/link.js +187 -0
  22. package/dist/core/test-kit/constants.d.ts +51 -0
  23. package/dist/core/test-kit/constants.js +43 -0
  24. package/dist/core/test-kit/fake-core.d.ts +61 -0
  25. package/dist/core/test-kit/fake-core.js +228 -0
  26. package/dist/core/test-kit/frames.d.ts +1 -0
  27. package/dist/core/test-kit/frames.js +480 -0
  28. package/dist/core/test-kit/setup-test.d.ts +18 -0
  29. package/dist/core/test-kit/setup-test.js +35 -0
  30. package/dist/core/wire.d.ts +85 -0
  31. package/dist/core/wire.js +199 -0
  32. package/dist/core-test-kit.d.ts +5 -0
  33. package/dist/core-test-kit.js +5 -0
  34. package/dist/core.d.ts +15 -0
  35. package/dist/core.js +12 -0
  36. package/dist/drift/cli.d.ts +22 -0
  37. package/dist/drift/cli.js +146 -0
  38. package/dist/drift/constants.d.ts +83 -0
  39. package/dist/drift/constants.js +73 -0
  40. package/dist/drift/diff.d.ts +7 -0
  41. package/dist/drift/diff.js +91 -0
  42. package/dist/drift/schema.d.ts +19 -0
  43. package/dist/drift/schema.js +190 -0
  44. package/dist/drift/types.d.ts +76 -0
  45. package/dist/drift/types.js +1 -0
  46. package/dist/drift.d.ts +5 -0
  47. package/dist/drift.js +6 -0
  48. package/dist/effect.d.ts +3 -0
  49. package/dist/effect.js +4 -0
  50. package/dist/herdr/client/connect.d.ts +5 -0
  51. package/dist/herdr/client/connect.js +81 -0
  52. package/dist/herdr/client/held.d.ts +54 -0
  53. package/dist/herdr/client/held.js +100 -0
  54. package/dist/herdr/client/long-poll.d.ts +33 -0
  55. package/dist/herdr/client/long-poll.js +66 -0
  56. package/dist/herdr/client/scoped.d.ts +45 -0
  57. package/dist/herdr/client/scoped.js +241 -0
  58. package/dist/herdr/client/streams.d.ts +9 -0
  59. package/dist/herdr/client/streams.js +40 -0
  60. package/dist/herdr/client/subscribe.d.ts +75 -0
  61. package/dist/herdr/client/subscribe.js +208 -0
  62. package/dist/herdr/client/types.d.ts +150 -0
  63. package/dist/herdr/client/types.js +1 -0
  64. package/dist/herdr/client/watch-pane-set.d.ts +34 -0
  65. package/dist/herdr/client/watch-pane-set.js +271 -0
  66. package/dist/herdr/client/watch.d.ts +117 -0
  67. package/dist/herdr/client/watch.js +138 -0
  68. package/dist/herdr/effect/to-tagged-error.d.ts +2 -0
  69. package/dist/herdr/effect/to-tagged-error.js +54 -0
  70. package/dist/herdr/effect/types.d.ts +51 -0
  71. package/dist/herdr/effect/types.js +26 -0
  72. package/dist/herdr/errors.d.ts +53 -0
  73. package/dist/herdr/errors.js +87 -0
  74. package/dist/herdr/generated/entries/admin.d.ts +2 -0
  75. package/dist/herdr/generated/entries/admin.js +5 -0
  76. package/dist/herdr/generated/entries/client.d.ts +2 -0
  77. package/dist/herdr/generated/entries/client.js +5 -0
  78. package/dist/herdr/generated/entries/held.d.ts +2 -0
  79. package/dist/herdr/generated/entries/held.js +5 -0
  80. package/dist/herdr/generated/entries/prompt.d.ts +2 -0
  81. package/dist/herdr/generated/entries/prompt.js +5 -0
  82. package/dist/herdr/generated/entries/read-only-content.d.ts +2 -0
  83. package/dist/herdr/generated/entries/read-only-content.js +5 -0
  84. package/dist/herdr/generated/entries/read-only.d.ts +2 -0
  85. package/dist/herdr/generated/entries/read-only.js +5 -0
  86. package/dist/herdr/generated/entry-methods.d.ts +9 -0
  87. package/dist/herdr/generated/entry-methods.js +17 -0
  88. package/dist/herdr/generated/errors.d.ts +4 -0
  89. package/dist/herdr/generated/errors.js +3 -0
  90. package/dist/herdr/generated/events.d.ts +274 -0
  91. package/dist/herdr/generated/events.js +3 -0
  92. package/dist/herdr/generated/index.d.ts +20 -0
  93. package/dist/herdr/generated/index.js +19 -0
  94. package/dist/herdr/generated/method-table.d.ts +615 -0
  95. package/dist/herdr/generated/method-table.js +106 -0
  96. package/dist/herdr/generated/names/agent-status.d.ts +10 -0
  97. package/dist/herdr/generated/names/agent-status.js +10 -0
  98. package/dist/herdr/generated/names/capability-class.d.ts +14 -0
  99. package/dist/herdr/generated/names/capability-class.js +15 -0
  100. package/dist/herdr/generated/names/event-kind.d.ts +31 -0
  101. package/dist/herdr/generated/names/event-kind.js +31 -0
  102. package/dist/herdr/generated/names/event-match-kind.d.ts +23 -0
  103. package/dist/herdr/generated/names/event-match-kind.js +24 -0
  104. package/dist/herdr/generated/names/index.d.ts +10 -0
  105. package/dist/herdr/generated/names/index.js +12 -0
  106. package/dist/herdr/generated/names/method.d.ts +209 -0
  107. package/dist/herdr/generated/names/method.js +209 -0
  108. package/dist/herdr/generated/names/result-tag.d.ts +68 -0
  109. package/dist/herdr/generated/names/result-tag.js +68 -0
  110. package/dist/herdr/generated/names/server-capability.d.ts +10 -0
  111. package/dist/herdr/generated/names/server-capability.js +11 -0
  112. package/dist/herdr/generated/names/subscription-event-kind.d.ts +8 -0
  113. package/dist/herdr/generated/names/subscription-event-kind.js +8 -0
  114. package/dist/herdr/generated/names/subscription-type.d.ts +31 -0
  115. package/dist/herdr/generated/names/subscription-type.js +32 -0
  116. package/dist/herdr/generated/names/token-name-pattern.d.ts +2 -0
  117. package/dist/herdr/generated/names/token-name-pattern.js +4 -0
  118. package/dist/herdr/generated/namespaces.d.ts +785 -0
  119. package/dist/herdr/generated/namespaces.js +3 -0
  120. package/dist/herdr/generated/overrides.d.ts +33 -0
  121. package/dist/herdr/generated/overrides.js +20 -0
  122. package/dist/herdr/generated/params.d.ts +799 -0
  123. package/dist/herdr/generated/params.js +3 -0
  124. package/dist/herdr/generated/preset-methods.d.ts +4 -0
  125. package/dist/herdr/generated/preset-methods.js +7 -0
  126. package/dist/herdr/generated/presets/sessions-reader.d.ts +2 -0
  127. package/dist/herdr/generated/presets/sessions-reader.js +5 -0
  128. package/dist/herdr/generated/results.d.ts +978 -0
  129. package/dist/herdr/generated/results.js +52 -0
  130. package/dist/herdr/generated/test-data/defaults.d.ts +739 -0
  131. package/dist/herdr/generated/test-data/defaults.js +741 -0
  132. package/dist/herdr/generated/test-data/shapes.d.ts +1325 -0
  133. package/dist/herdr/generated/test-data/shapes.js +2245 -0
  134. package/dist/herdr/test-kit/fake-herdr.d.ts +13 -0
  135. package/dist/herdr/test-kit/fake-herdr.js +216 -0
  136. package/dist/herdr/test-kit/fake-protocol.d.ts +107 -0
  137. package/dist/herdr/test-kit/fake-protocol.js +436 -0
  138. package/dist/herdr/test-kit/types.d.ts +88 -0
  139. package/dist/herdr/test-kit/types.js +1 -0
  140. package/dist/herdr/wire/codec.d.ts +36 -0
  141. package/dist/herdr/wire/codec.js +62 -0
  142. package/dist/herdr/wire/connection.d.ts +13 -0
  143. package/dist/herdr/wire/connection.js +65 -0
  144. package/dist/herdr/wire/dedicated.d.ts +2 -0
  145. package/dist/herdr/wire/dedicated.js +238 -0
  146. package/dist/herdr/wire/push-decoder.d.ts +2 -0
  147. package/dist/herdr/wire/push-decoder.js +40 -0
  148. package/dist/herdr/wire/rpc.d.ts +3 -0
  149. package/dist/herdr/wire/rpc.js +141 -0
  150. package/dist/herdr/wire/socket-path.d.ts +8 -0
  151. package/dist/herdr/wire/socket-path.js +23 -0
  152. package/dist/herdr/wire/types.d.ts +78 -0
  153. package/dist/herdr/wire/types.js +1 -0
  154. package/dist/index.d.ts +11 -0
  155. package/dist/index.js +7 -0
  156. package/dist/read-only.d.ts +5 -0
  157. package/dist/read-only.js +6 -0
  158. package/dist/schema.d.ts +5 -0
  159. package/dist/schema.js +6 -0
  160. package/dist/test-kit.d.ts +2 -0
  161. package/dist/test-kit.js +3 -0
  162. package/docs/api/events.md +43 -0
  163. package/docs/api/methods.md +232 -0
  164. package/package.json +112 -4
  165. package/schema/herdr-api.schema.json +10759 -0
  166. package/schema/herdr-version.json +5 -0
  167. package/skills/herdr-sdk/SKILL.md +75 -0
  168. package/skills/herdr-sdk/references/api-map.md +28 -0
  169. package/skills/herdr-sdk/references/errors.md +19 -0
  170. package/skills/herdr-sdk/references/recipes.md +171 -0
  171. package/skills/herdr-sdk/references/versions.md +7 -0
package/LICENSE ADDED
@@ -0,0 +1,18 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 the @stateforge-labs/herdr-sdk authors (including its intermediate port) and brooswit (jsHerdrSDK)
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software
6
+ and associated documentation files (the "Software"), to deal in the Software without
7
+ restriction, including without limitation the rights to use, copy, modify, merge, publish,
8
+ distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
9
+ Software is furnished to do so, subject to the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be included in all copies or
12
+ substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
15
+ BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
16
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
17
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
package/NOTICE.md ADDED
@@ -0,0 +1,51 @@
1
+ # Provenance of `tools/gen/`, `src/herdr/generated/` and the schema
2
+
3
+ `@stateforge-labs/herdr-sdk` is built on a **port of a third party's generator**, not on our own original work.
4
+ The chain below is complete from the upstream project to this package. Licence text: [LICENSE](LICENSE).
5
+
6
+ | | |
7
+ | --- | --- |
8
+ | Upstream | `https://github.com/brooswit-factory/jsHerdrSDK`, commit `e34fd3f2cf32722ed570d1c232c35bdd83eef312` (2026-08-26), paths `scripts/gen/` and `src/` |
9
+ | Published as | `@brooswit/herdr-sdk` 0.1.3 on npm. **Not depended on** by this package |
10
+ | Licence | MIT, declared in the upstream `package.json`. The upstream repository has no LICENSE file |
11
+ | Author | brooswit `<brooswit@gmail.com>` |
12
+
13
+ ## 1. Intermediate port
14
+
15
+ A private port by the same authors as this package, commit `097adfd662c4818a351c714e4863c1d606726822`.
16
+ Its changes to upstream, as stated in its own `NOTICE.md`:
17
+
18
+ 1. `Bun.file(path).text()` replaced by `readFileSync(path, 'utf8')`.
19
+ 2. `.js` import specifiers replaced by `.ts`.
20
+ 3. `JSONSchema` is a real recursive interface instead of `Record<string, any>`.
21
+ 4. The regular-expression `typeName` scan is a character scan.
22
+
23
+ ## 2. Owner's repairs carried into this package
24
+
25
+ From the NOTICE of an earlier private copy of the client. These landed in the runtime client:
26
+
27
+ 1. `Connection.destroy()` (hard teardown beside `close()`).
28
+ 2. `rpc` takes `signal`, destroys the connection on every settle, and rejects a non-object reply.
29
+
30
+ ## 3. Changes in this package
31
+
32
+ | File | Change |
33
+ | --- | --- |
34
+ | `tools/gen/schema.ts` | Path parameter: `loadSchema(path)` (the port read a fixed `SCHEMA_PATH`); `GEN_PATHS` replaces the port's `ROOT`, `SCHEMA_PATH` and `OUT_DIR`, and points the output at `src/generated/`. `#gen/*` alias dropped. `constOf` checks its value through an `isString` type guard (TypeScript 7 narrows `typeof` only against a literal, so the P0 form failed `bun run typecheck`). Names (`JS_TYPE`, `SCHEMA_KEY`, `SCHEMA_NAMESPACE`) are `as const` objects. `JSONSchema` gains `default`, `format`, `pattern` and `propertyNames`, for the doc comments. `requestNamespace()` added. The generated header ends "Do not edit." (ASCII full stop, no em dash). |
35
+ | `tools/gen/json-type.ts` | New file, no counterpart in the intermediate port. Holds `JSON_TYPE` and `FORMAT` as `as const` objects and `kindsOf()`, which the port kept inline in `ts-type.ts` and compared against string literals. |
36
+ | `tools/gen/doc-comment.ts` | New file, no counterpart in the intermediate port. Builds one-line JSDoc from `description`, `default` (`@default`), `propertyNames.pattern` (`keys match`) and `format: uint64`, which the port did not emit. Also fixes the port's unescaped `*/` in `emitDefs`: `*/` becomes `* /` and line breaks fold to spaces, for every doc, not only field docs. |
37
+ | `tools/gen/ts-type.ts` | Imports use `./` with `.ts` (`#gen/*` alias dropped). Literal comparisons (`kind === 'string'` and the like) replaced by a `switch` on `JSON_TYPE`; output spellings and separators are named constants. `kindsOf` moved to `json-type.ts`. Field and `$defs` docs go through `schemaDoc()`. The map test for `additionalProperties` is `isSchemaMap` (object, not null). |
38
+ | `tools/gen/merge-defs.ts` | New file, no counterpart in the intermediate port. Replaces the port's hard-coded `SHARED` set in `emit-events.ts` (`AgentStatus`, `PaneScrollInfo`). `mergeDefinitions()` emits a `$def` that several bundles repeat once when the definitions are structurally equal after `$ref` normalisation and key sorting, and throws on a conflict. |
39
+ | `tools/gen/emit-params.ts` | `METHODS` and `Method` moved out to `emit-method-table.ts`; imports `Method` from `./methods.ts`. Adds `MethodParamsCheck`, which fails to compile when a method has no params entry. Bundle and key names from `SCHEMA_NAMESPACE` and `SCHEMA_KEY`, not literals. |
40
+ | `tools/gen/emit-results.ts` | Names (`success_response`, `ResponseResult`, the `Result_` prefix, the `type` key) come from constants. `METHOD_RESULT` is built from the seed by `methodResultTags()` (method to tag only) and checked with `satisfies Partial<Record<Method, ResultTag>>`, where the port imported the record. Imports `Method` from `./methods.ts`. |
41
+ | `tools/gen/emit-errors.ts` | Bundle name from `SCHEMA_NAMESPACE.errorResponse` (the port used the literal `'error_response'`). Otherwise as the port. |
42
+ | `tools/gen/emit-events.ts` | `SHARED` set removed; `mergeDefinitions()` over the `event` and `subscription_event` bundles replaces it, emitting all definitions in one block (the port emitted two blocks with section comments). Bundle names from `SCHEMA_NAMESPACE`. |
43
+ | `tools/gen/emit-index.ts` | New file, no counterpart in the intermediate port. Holds the `index.ts` text that the port's `gen/index.ts` inlined. Re-exports `METHODS` and `Method` from `./methods.ts` rather than `./params.ts`. |
44
+ | `tools/gen/emit-method-table.ts` | New file, no counterpart in the intermediate port. Emits `METHODS` as `{ name, ns }` rows (namespace path split from the dotted name; duplicate names refused) and `Method` derived from it. The class and result columns arrive in phases 1b and 3. |
45
+ | `tools/gen/method-result-map.ts` | The 25 the port rows are the seed as `METHOD_RESULT_SEED`; each row carries a `source` (`RESULT_SOURCE`, all `seed` today). `methodResultTags()` projects them to method to tag. The 25 mappings are unchanged. |
46
+ | `tools/gen/index.ts` | Writes its modules into `src/herdr/generated/` (nested `names/`, `entries/`, `presets/`, `test-data/` since the 2026-11-02 build split), keyed by `renderOutputs()`. The port wrote five into `generated/`, with the index text inline. Bodies come from `renderOutputs()`; `runGenerator({ schemaPath, outDir })` takes paths; the CLI runs under `import.meta.main`. |
47
+ | `package.json` | First version; `herdr` block (protocol 22, schemaVersion 1, testedWith 0.9.5); scripts `capture`, `test:gen`, `check:pins`, `typecheck`; dev pins `@types/node` 22.20.5 and `typescript` 7.0.2 (exact, released at least 14 days before adoption, see HERDR-ADR-0015). |
48
+ | `tsconfig.json` | New. Strict set from the port, `nodenext`, `erasableSyntaxOnly`; includes `gen`, `scripts`, `src`; `test/` excluded until `@types/bun` is adopted. |
49
+ | `tools/scripts/check-pins.ts` | New. Pin gate (exact version, released at least 14 days ago, via `npm view <pkg> time`). |
50
+ | `tools/scripts/capture-schema.ts` | New. Captures `herdr api schema --json` and `herdr --version` into `schema/`. |
51
+ | `LICENSE`, `NOTICE.md`, `.gitignore` | New. MIT licence, this provenance, ignores `node_modules/` and `dist/`. |
package/README.md CHANGED
@@ -1,3 +1,212 @@
1
- # Temporary Holding Version
1
+ # @stateforge-labs/herdr-sdk
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ A typed client for the whole [herdr](https://herdr.dev) socket API (protocol 22, herdr 0.9.5: 102 methods, 26 event kinds, 27 subscription types), for Bun and Node.
4
+
5
+ > **Version 0.3.0.** ESM only, Node 22.18+ and Bun. The Promise API, the herdr-core client (`/core`, `/core/test-kit`), the three capability-scoped clients, the fake herdr (`/test-kit`), the schema and drift tools, the tagged errors of `/effect` and the agent skill, all tested against the fake herdr. Every snippet marked "runs" is executed in CI.
6
+
7
+ ## Entry points
8
+
9
+ | Import | What | Runtime deps |
10
+ |---|---|---|
11
+ | `@stateforge-labs/herdr-sdk` | `connect()`: reads, writes, input, hooks, long-poll, `hold()`; errors; generated types and constants | none |
12
+ | `@stateforge-labs/herdr-sdk/read-only` | `connectReadOnly()`: structure reads only; terminal content on opt-in | none |
13
+ | `@stateforge-labs/herdr-sdk/admin` | `connectAdmin()`: adds destructive, server-control and spawn/execute methods | none |
14
+ | `@stateforge-labs/herdr-sdk/effect` | `toTaggedError`, `EffectErrorTag` and the tagged error types, for mapping the Promise errors into an Effect program | none |
15
+ | `@stateforge-labs/herdr-sdk/test-kit` | `createFakeHerdr()` (tests only) | none |
16
+ | `@stateforge-labs/herdr-sdk/schema` | method table and parameter shapes of the generated API (what a generator, such as an MCP server, builds its tools from) | none |
17
+ | `@stateforge-labs/herdr-sdk/core` | `CoreLink`, `CoreEvents`, the wire parsers and the socket path rule: a client of the herdr-core (`hc`) socket, standalone from the protocol-22 client | none |
18
+ | `@stateforge-labs/herdr-sdk/core/test-kit` | `FakeHcCore`, `setupTest(t)`, `openWorld()` (tests only) | none |
19
+ | `@stateforge-labs/herdr-sdk/drift` | `driftBetween`, `inventoryOf`, `exitCodeFor`: the library behind `herdr-drift`, for your own tooling | none |
20
+ | `herdr-drift` (bin) | compare the committed schema with the installed herdr | none |
21
+ | `herdr-skill` (bin) | print or install the agent skill that ships in `skills/herdr-sdk` | none |
22
+
23
+ Wire types are `export type` only. Raw strings are accepted by the types, but these docs always use the generated constants (`Method`, `EventKind`, `SubscriptionType`, `AgentStatus`, `WatchKind`).
24
+
25
+ ## Install
26
+
27
+ ```sh
28
+ npm install @stateforge-labs/herdr-sdk
29
+ # or
30
+ bun add @stateforge-labs/herdr-sdk
31
+ ```
32
+
33
+ Versions published from GitHub Actions with npm trusted publishing carry a provenance attestation
34
+ (`npm audit signatures` checks it); 0.3.0 was published by hand and has none. The release tag equals the `package.json` version.
35
+
36
+ ## Footprint
37
+
38
+ The package ships compiled ESM in `dist/` with declarations (no bundle). A bundler or Node loads only the modules a call reaches: `connect()` does not load the streams until `events.subscribe`, `watch()` or `hold()` is first used.
39
+
40
+ Measured on 2026-11-02, minified (`bun run check:size`, which builds `dist/` and fails on a budget or a leak):
41
+
42
+ | What a consumer imports | Bytes |
43
+ |---|---|
44
+ | `@stateforge-labs/herdr-sdk` (every method, `connect()`) | 26,887 |
45
+ | `@stateforge-labs/herdr-sdk/read-only` | 18,691 |
46
+ | `@stateforge-labs/herdr-sdk/admin` | 15,561 |
47
+ | a read-only script that narrows to one method | 17,513 |
48
+ | the streams chunk (`events.subscribe`, `watch`, `hold`), loaded on first use | 7,672 |
49
+
50
+ The declarations use `AbortSignal` and `AsyncDisposable`. Consumers need `@types/node` 22 or later, or a `lib` that has them (`es2023`, `esnext.disposable`, and `DOM` or `@types/node`). `/test-kit` declarations also import `node:net`.
51
+
52
+ ## 1. A small script (Promise API)
53
+
54
+ ```ts
55
+ import { connect, HerdrError } from "@stateforge-labs/herdr-sdk"
56
+
57
+ const herdr = await connect() // finds the socket (HERDR_SOCKET, else ~/.config/herdr/herdr.sock), pings, checks protocol 22
58
+
59
+ const { agents } = await herdr.agent.list({})
60
+ for (const agent of agents) console.log(agent.name, agent.agent_status)
61
+
62
+ try {
63
+ await herdr.agent.prompt({ target: "reviewer", text: "run the tests" })
64
+ } catch (error) {
65
+ if (error instanceof HerdrError) console.error(error.code, error.message)
66
+ else throw error
67
+ }
68
+
69
+ herdr.close()
70
+ ```
71
+
72
+ Methods are nested by their dotted name: `herdr.pane.list({})`, `herdr.agent.view.set({...})`. `connect()` has no destructive or server-control methods (`*.close`, `server.stop`, `plugin.link`...); those need `connectAdmin()` from `@stateforge-labs/herdr-sdk/admin`.
73
+
74
+ A protocol mismatch fails fast; a method the server does not support fails before sending:
75
+
76
+ ```ts
77
+ import { connect, ProtocolMismatchError } from "@stateforge-labs/herdr-sdk"
78
+
79
+ try {
80
+ await connect()
81
+ } catch (error) {
82
+ if (error instanceof ProtocolMismatchError) console.error(`herdr speaks ${error.actual}, this library ${error.expected}`)
83
+ }
84
+ ```
85
+
86
+ ## 2. Subscriptions, long-poll and held connections
87
+
88
+ ```ts
89
+ import { connect, SubscriptionType, EventKind, AgentStatus, WatchKind } from "@stateforge-labs/herdr-sdk"
90
+
91
+ const herdr = await connect({ onCall: ({ method, durationMs, outcome }) => metrics.record(method, durationMs, outcome) })
92
+
93
+ const subscription = await herdr.events.subscribe([
94
+ { type: SubscriptionType.PaneCreated },
95
+ { type: SubscriptionType.PaneClosed },
96
+ { type: SubscriptionType.PaneAgentStatusChanged, pane_id: "p_1" },
97
+ ])
98
+ for await (const frame of subscription) {
99
+ if (frame.event === EventKind.PaneClosed) break
100
+ }
101
+ subscription.close()
102
+
103
+ // Long-poll: the timeout is required (herdr would wait forever).
104
+ const done = await herdr.agent.wait({ target: "reviewer", until: [AgentStatus.Done], timeout_ms: 60_000 })
105
+
106
+ // watch: subscribe, snapshot, replay frames that arrived meanwhile, resubscribe with backoff (1 s doubling to 30 s).
107
+ for await (const change of herdr.watch({ snapshot: () => herdr.session.snapshot({}) })) {
108
+ if (change.kind === WatchKind.Live) render(change.snapshot)
109
+ else apply(change.frame)
110
+ }
111
+
112
+ // Connection-bound methods run on a held connection; closing it ends the title, lease or registration.
113
+ await using held = await herdr.hold()
114
+ await held.client.window_title.set({ title: "review" })
115
+ ```
116
+
117
+ A timeout is not proof that a prompt was not delivered: never resend blindly.
118
+
119
+ ## 3. Read-only and prompt-only clients
120
+
121
+ ```ts
122
+ import { connectReadOnly, Presets } from "@stateforge-labs/herdr-sdk/read-only"
123
+
124
+ const herdr = await connectReadOnly({ preset: Presets.SessionsReader }) // session.snapshot, agent.list, agent.get, pane.get, pane.list
125
+ const snapshot = await herdr.session.snapshot({})
126
+ // @ts-expect-error a read-only client has no write methods and no generic call()
127
+ await herdr.agent.prompt({ target: "x", text: "y" })
128
+ ```
129
+
130
+ Without options it allows structure reads and long-poll; terminal content (`pane.read`, `agent.read`) needs `{ content: true }`. `{ methods: [Method.AgentList, ...] }` narrows at runtime. `connectPrompt()` adds exactly `agent.prompt`.
131
+
132
+ ## 4. Effect: tagged errors
133
+
134
+ `toTaggedError(error)` turns an error thrown by the Promise API into a plain object with an Effect-style `_tag`, so an Effect
135
+ program can fail with it (`Effect.tryPromise({ try, catch: toTaggedError })`). The package does not depend on `effect`.
136
+
137
+ | Promise error | Effect `_tag` | Fields |
138
+ |---|---|---|
139
+ | `HerdrError` | `HerdrRefused` | `method`, `code`, `message` |
140
+ | `HerdrTransportError`, `SubscriptionEnded` | `HerdrUnavailable` | `cause`, `isTimeout` |
141
+ | `ProtocolMismatchError` | `ProtocolMismatch` | `expected`, `actual` |
142
+ | `UnsupportedByServerError` | `HerdrUnsupported` | `method`, `capability` |
143
+
144
+ Every tagged error also has `message` (the Promise error's message).
145
+
146
+ ## 5. Tests (no live herdr) — runs
147
+
148
+ ```ts
149
+ import { test, expect } from "bun:test"
150
+ import { connect, Method, ResultTag } from "@stateforge-labs/herdr-sdk"
151
+ import { createFakeHerdr } from "@stateforge-labs/herdr-sdk/test-kit"
152
+
153
+ test("lists agents", async () => {
154
+ const fake = await createFakeHerdr()
155
+ fake.reply(Method.AgentList, { type: ResultTag.AgentList, agents: [] })
156
+ const herdr = await connect({ socketPath: fake.path })
157
+
158
+ await herdr.agent.list({})
159
+
160
+ expect(fake.receivedMethods()).toEqual([Method.Ping, Method.AgentList])
161
+ herdr.close()
162
+ await fake.stop()
163
+ })
164
+ ```
165
+
166
+ The fake runs on `node:net`, answers `ping` and every method you script with `reply`, answers an unscripted method with an `unknown_method` error envelope, and supports `fail`, `silent`, `replySequence`, `push(frame)`, `closeSubscribers()`, `subscriberCount()`, `connectionCount()` and `capabilities`. No test talks to a real herdr.
167
+
168
+ ## Drift
169
+
170
+ `herdr-drift` ships as a bin. Refreshing the schema and regenerating the client happen in a clone of the repository:
171
+
172
+ ```sh
173
+ bun run capture # herdr api schema --json > schema/herdr-api.schema.json
174
+ bun run gen # regenerate src/herdr/generated and docs/api
175
+ herdr-drift # exit 0 clean, 1 drift, 2 usage, 3 herdr not found
176
+ ```
177
+
178
+ ## For coding agents (the skill)
179
+
180
+ The package ships an Agent Skill, `skills/herdr-sdk/` ([HERDR-ADR-0018](https://github.com/stateforge-labs/herdr-sdk/blob/main/docs/decisions/HERDR-ADR-0018-the-skill-ships-in-the-package.md)): which entry point to pick, recipes, errors, version facts. Its code blocks are type-checked and run against the fake in the repository's `test/skill/`.
181
+
182
+ ```sh
183
+ herdr-skill install # copies it to .claude/skills/herdr-sdk (or: herdr-skill install ~/.claude/skills)
184
+ herdr-skill print # prints SKILL.md, for agents that take a prompt rather than a folder
185
+ ```
186
+
187
+ Claude Code does not look inside `node_modules`, so `install` copies the skill to a skills directory. For other agents, add this to the project's `AGENTS.md`:
188
+
189
+ > Code that uses `@stateforge-labs/herdr-sdk`: read `node_modules/@stateforge-labs/herdr-sdk/skills/herdr-sdk/SKILL.md` first.
190
+
191
+ ## Using it from your own domain
192
+
193
+ The library conforms to herdr's wire vocabulary. Keep your own domain language behind your own port, and let one adapter file import `@stateforge-labs/herdr-sdk`. `tools/scripts/check-layers.ts` enforces the library's own layers; the one-adapter rule for consumers is a convention. Snapshot before you subscribe, because a subscription delivers changes, not the present. `watch()` does this for you (see the [decision records](https://github.com/stateforge-labs/herdr-sdk/tree/main/docs/decisions)).
194
+
195
+ ## Repository layout
196
+
197
+ This section describes the [GitHub repository](https://github.com/stateforge-labs/herdr-sdk); the npm package ships only `dist/`, the bins, the skill, the schema and the API docs.
198
+
199
+ One folder per product ([HERDR-ADR-0021](https://github.com/stateforge-labs/herdr-sdk/blob/main/docs/decisions/HERDR-ADR-0021-one-folder-per-product.md)); the entry files at the top of `src/` are the published subpaths.
200
+
201
+ | Folder | What it is |
202
+ | --- | --- |
203
+ | `src/herdr/` | The herdr server client (protocol 22): `errors.ts` (every error it throws), `wire/`, `client/` (one module per feature: `connect`, `scoped`, `subscribe`, `watch`, `watch-pane-set`, `held`, `long-poll`, and `streams`, loaded on first use), `generated/` (output of `tools/gen/`), `effect/`, `test-kit/` |
204
+ | `src/core/` | The herdr-core client (`./core`): `errors.ts` (every failure it returns), `kernel.ts` (its value types), `wire`, `link`, `events`, `backoff`, `constants`; its fake core in `test-kit/` (`./core/test-kit`) |
205
+ | `src/drift/` | The schema-drift tool behind `herdr-drift`: `schema`, `diff`, `cli`, `constants`, `types` |
206
+ | `test/` | Mirrors `src/` (`test/herdr/`, `test/core/`, `test/drift/`), plus `test/tools/`, `integration/` and `types/` |
207
+ | `tools/` | Build time only, never published: `gen/` (the generator), `scripts/` (gates, capture, build helpers), `rules/` (the layer rule) |
208
+ | `bin/`, `skills/`, `schema/`, `docs/` | The bins, the agent skill, the captured schema, the docs and decisions |
209
+
210
+ ## Licence
211
+
212
+ MIT. Derived from [brooswit-factory/jsHerdrSDK](https://github.com/brooswit-factory/jsHerdrSDK) (e34fd3f) through an intermediate private port (097adfd); see `NOTICE.md`.
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env node
2
+ // Role: the herdr-drift bin (package bin, plain JS so Node runs it from node_modules): the process I/O of the drift CLI. It runs the herdr CLI and sets the exit code; the logic is dist/drift/cli.js.
3
+ // Informs HERDR-ADR-0009 (exit codes 0/1/2/3), HERDR-ADR-0008 (the herdr CLI runs here only, never the socket) and HERDR-ADR-0012 (the package runs compiled JavaScript, not .ts).
4
+ import { execFileSync } from 'node:child_process';
5
+ import { HerdrCall } from '../dist/drift/constants.js';
6
+ import { runDriftCli } from '../dist/drift/cli.js';
7
+
8
+ const spawnHerdr = (binary) => (args) => execFileSync(binary, [...args], {
9
+ encoding: 'utf8',
10
+ timeout: HerdrCall.TimeoutMs,
11
+ stdio: ['ignore', 'pipe', 'pipe'],
12
+ });
13
+
14
+ process.exitCode = await runDriftCli(process.argv.slice(2), spawnHerdr);
@@ -0,0 +1,38 @@
1
+ #!/usr/bin/env node
2
+ // Role: the herdr-skill bin: prints or installs the agent skill that ships in this package (skills/herdr-sdk), so an agent can load it without knowing where node_modules is.
3
+ // Informs HERDR-ADR-0018 (the skill ships in the package; Claude Code does not discover node_modules, so `install` copies it into a skills directory) and the hc `--skill` convention.
4
+ import { cpSync, existsSync, readFileSync } from 'node:fs';
5
+ import { dirname, join, resolve } from 'node:path';
6
+ import { fileURLToPath } from 'node:url';
7
+
8
+ const SKILL_NAME = 'herdr-sdk';
9
+ const SKILL_DIR = join(dirname(fileURLToPath(import.meta.url)), '..', 'skills', SKILL_NAME);
10
+ const DEFAULT_TARGET = join('.claude', 'skills');
11
+ const USAGE = `usage: herdr-skill <command>
12
+ print print SKILL.md to stdout
13
+ path print the directory of the skill inside this package
14
+ install [skills-dir] copy the skill to <skills-dir>/${SKILL_NAME} (default ${DEFAULT_TARGET}); an existing copy is replaced
15
+ exit: 0 ok, 2 usage`;
16
+
17
+ function run(args) {
18
+ const [command, target] = args;
19
+ if (command === 'print') {
20
+ process.stdout.write(readFileSync(join(SKILL_DIR, 'SKILL.md'), 'utf8'));
21
+ return 0;
22
+ }
23
+ if (command === 'path') {
24
+ console.log(SKILL_DIR);
25
+ return 0;
26
+ }
27
+ if (command === 'install') {
28
+ const destination = resolve(target ?? DEFAULT_TARGET, SKILL_NAME);
29
+ const replaced = existsSync(destination);
30
+ cpSync(SKILL_DIR, destination, { recursive: true, force: true });
31
+ console.log(`${replaced ? 'replaced' : 'installed'} ${destination}`);
32
+ return 0;
33
+ }
34
+ console.error(USAGE);
35
+ return 2;
36
+ }
37
+
38
+ process.exitCode = run(process.argv.slice(2));
@@ -0,0 +1,2 @@
1
+ export { connectAdmin } from './herdr/client/scoped.js';
2
+ export type { AdminClient } from './herdr/client/types.js';
package/dist/admin.js ADDED
@@ -0,0 +1,3 @@
1
+ // Role: the /admin entry: connectAdmin() with destructive, server-control and spawn/execute methods.
2
+ // Informs HERDR-ADR-0003, HERDR-ADR-0005 and HERDR-ADR-0017; edited only by the integration step.
3
+ export { connectAdmin } from './herdr/client/scoped.js';
@@ -0,0 +1,236 @@
1
+ import { SubscriptionType } from './herdr/generated/index.js';
2
+ import type { ServerCapabilities } from './herdr/generated/results.js';
3
+ export { TOKEN_NAME_PATTERN } from './herdr/generated/names/token-name-pattern.js';
4
+ export declare const HerdrEnv: {
5
+ readonly Socket: 'HERDR_SOCKET';
6
+ readonly Home: 'HOME';
7
+ readonly Live: 'HERDR_LIVE';
8
+ };
9
+ export declare const SocketPathPart: {
10
+ readonly ConfigDir: '.config';
11
+ readonly HerdrDir: 'herdr';
12
+ readonly SocketFile: 'herdr.sock';
13
+ };
14
+ export declare const Timeout: {
15
+ readonly DefaultMs: 10000;
16
+ readonly LongPollMarginMs: 5000;
17
+ };
18
+ export declare const Backoff: {
19
+ readonly InitialMs: 1000;
20
+ readonly MaxMs: 30000;
21
+ readonly Factor: 2;
22
+ readonly StableResetMs: 60000;
23
+ };
24
+ export declare const ProtocolPolicy: {
25
+ readonly Exact: 'exact';
26
+ readonly Minimum: 'minimum';
27
+ };
28
+ export type ProtocolPolicy = (typeof ProtocolPolicy)[keyof typeof ProtocolPolicy];
29
+ export declare const Overflow: {
30
+ readonly DropOldest: 'drop-oldest';
31
+ readonly Fail: 'fail';
32
+ };
33
+ export type Overflow = (typeof Overflow)[keyof typeof Overflow];
34
+ export declare const WatchKind: {
35
+ readonly Live: 'live';
36
+ readonly Frame: 'frame';
37
+ };
38
+ export type WatchKind = (typeof WatchKind)[keyof typeof WatchKind];
39
+ export declare const Presets: {
40
+ readonly SessionsReader: 'SessionsReader';
41
+ };
42
+ export type Preset = (typeof Presets)[keyof typeof Presets];
43
+ export declare const SUBSCRIBE_ID_PREFIX = "sub";
44
+ export declare const ErrorText: {
45
+ readonly NoAck: (ms: number) => string;
46
+ readonly Unavailable: (method: string, what: string) => string;
47
+ readonly NoResponse: (method: string, ms: number) => string;
48
+ readonly Aborted: (method: string) => string;
49
+ readonly Unparseable: (method: string) => string;
50
+ readonly ClosedBeforeResponse: (method: string) => string;
51
+ readonly ClientClosed: (method: string) => string;
52
+ readonly SocketError: (method: string) => string;
53
+ readonly CannotConnect: (path: string) => string;
54
+ readonly NoSocket: (path: string) => string;
55
+ readonly ProtocolMismatch: (expected: number, actual: number) => string;
56
+ readonly Unsupported: (method: string, capability: string) => string;
57
+ readonly Refused: (method: string, message: string, code: string) => string;
58
+ readonly SubscriptionEnded: (method: string) => string;
59
+ readonly NotImplemented: (what: string, lane: string) => string;
60
+ readonly NotAllowed: (method: string) => string;
61
+ };
62
+ export declare const ErrorName: {
63
+ readonly Herdr: 'HerdrError';
64
+ readonly Transport: 'HerdrTransportError';
65
+ readonly ProtocolMismatch: 'ProtocolMismatchError';
66
+ readonly UnsupportedByServer: 'UnsupportedByServerError';
67
+ readonly SubscriptionEnded: 'SubscriptionEnded';
68
+ readonly NotImplemented: 'NotImplementedError';
69
+ readonly MalformedSchema: 'MalformedSchemaError';
70
+ readonly UnsupportedWatch: 'UnsupportedWatchError';
71
+ };
72
+ export declare const WireField: {
73
+ readonly Id: 'id';
74
+ readonly Method: 'method';
75
+ readonly Params: 'params';
76
+ readonly Result: 'result';
77
+ readonly Error: 'error';
78
+ readonly Code: 'code';
79
+ readonly Message: 'message';
80
+ readonly Type: 'type';
81
+ readonly Protocol: 'protocol';
82
+ readonly Version: 'version';
83
+ readonly Capabilities: 'capabilities';
84
+ readonly Event: 'event';
85
+ };
86
+ export declare const REQUEST_ID_PREFIX = "sdk";
87
+ export declare const EMPTY_REPLY_ID = "";
88
+ export declare const LINE_SEPARATOR = "\n";
89
+ export declare const TEXT_ENCODING: 'utf8';
90
+ export declare const CallOutcome: {
91
+ readonly Answered: 'answered';
92
+ readonly Refused: 'refused';
93
+ readonly Transport: 'transport';
94
+ };
95
+ export type CallOutcome = (typeof CallOutcome)[keyof typeof CallOutcome];
96
+ export declare const TypeofTag: {
97
+ readonly Object: 'object';
98
+ readonly String: 'string';
99
+ };
100
+ export declare const Fake: {
101
+ readonly DirPrefix: 'herdr-fake-';
102
+ readonly SocketFile: 'herdr.sock';
103
+ readonly Version: '0.9.5-fake';
104
+ readonly UnknownMethodCode: 'unknown_method';
105
+ readonly InvalidRequestCode: 'invalid_request';
106
+ readonly SplitAckDelayMs: 5;
107
+ };
108
+ export declare const FakeText: {
109
+ readonly UnknownMethod: (method: string) => string;
110
+ readonly InvalidRequest: 'unparseable request';
111
+ };
112
+ export declare const DEFAULT_CAPABILITIES: ServerCapabilities;
113
+ export declare const AnswerKind: {
114
+ readonly Silent: 'silent';
115
+ readonly Raw: 'raw';
116
+ readonly Envelope: 'envelope';
117
+ };
118
+ export type AnswerKind = (typeof AnswerKind)[keyof typeof AnswerKind];
119
+ export declare const ServedState: {
120
+ readonly Fresh: 'fresh';
121
+ readonly Answered: 'answered';
122
+ readonly Subscriber: 'subscriber';
123
+ readonly Held: 'held';
124
+ };
125
+ export type ServedState = (typeof ServedState)[keyof typeof ServedState];
126
+ export declare const UNKNOWN_EVENT: '@stateforge-labs/herdr-sdk:unknown-event';
127
+ export declare const PaneSetKind: {
128
+ readonly Added: 'added';
129
+ readonly Removed: 'removed';
130
+ readonly Frame: 'frame';
131
+ };
132
+ export type PaneSetKind = (typeof PaneSetKind)[keyof typeof PaneSetKind];
133
+ export declare const PER_PANE_SUBSCRIPTION_TYPES: readonly ["pane.output_matched", "pane.agent_status_changed", "pane.scroll_changed"];
134
+ export declare const GLOBAL_SUBSCRIPTION_TYPES: readonly SubscriptionType[];
135
+ export declare const DriftExitCode: {
136
+ readonly Clean: 0;
137
+ readonly Drift: 1;
138
+ readonly Usage: 2;
139
+ readonly NotCovered: 3;
140
+ };
141
+ export type DriftExitCode = (typeof DriftExitCode)[keyof typeof DriftExitCode];
142
+ export declare const SchemaReadKind: {
143
+ readonly Found: 'found';
144
+ readonly NotFound: 'not-found';
145
+ readonly Unreadable: 'unreadable';
146
+ };
147
+ export type SchemaReadKind = (typeof SchemaReadKind)[keyof typeof SchemaReadKind];
148
+ export declare const DriftOutcomeKind: {
149
+ readonly Usage: 'usage';
150
+ readonly NotCovered: 'not-covered';
151
+ readonly Report: 'report';
152
+ };
153
+ export type DriftOutcomeKind = (typeof DriftOutcomeKind)[keyof typeof DriftOutcomeKind];
154
+ export declare const EffectErrorTag: {
155
+ readonly Refused: 'HerdrRefused';
156
+ readonly Unavailable: 'HerdrUnavailable';
157
+ readonly ProtocolMismatch: 'ProtocolMismatch';
158
+ readonly Unsupported: 'HerdrUnsupported';
159
+ };
160
+ export type EffectErrorTag = (typeof EffectErrorTag)[keyof typeof EffectErrorTag];
161
+ export declare const WireFact: {
162
+ readonly W1CloseAfterResponse: 'W1';
163
+ readonly W2AckThenStream: 'W2';
164
+ readonly W3EmptyIdOnUnparseable: 'W3';
165
+ readonly W4SchemaOverSocketIsEmpty: 'W4';
166
+ readonly W5NoHistoryReplay: 'W5';
167
+ readonly W6PerPaneNeedsPaneId: 'W6';
168
+ };
169
+ export type WireFact = (typeof WireFact)[keyof typeof WireFact];
170
+ export declare const Lane: {
171
+ readonly P2a: 'P2a';
172
+ readonly P2b: 'P2b';
173
+ readonly P3: 'P3';
174
+ readonly P4a: 'P4a';
175
+ readonly P4b: 'P4b';
176
+ readonly P5a: 'P5a';
177
+ readonly P5c: 'P5c';
178
+ readonly P6a: 'P6a';
179
+ };
180
+ export type Lane = (typeof Lane)[keyof typeof Lane];
181
+ export declare const EntryKey: {
182
+ readonly client: 'client';
183
+ readonly admin: 'admin';
184
+ readonly prompt: 'prompt';
185
+ readonly readOnly: 'readOnly';
186
+ readonly readOnlyContent: 'readOnlyContent';
187
+ readonly held: 'held';
188
+ };
189
+ export type EntryKey = (typeof EntryKey)[keyof typeof EntryKey];
190
+ export declare const METHOD_SEPARATOR = ".";
191
+ export declare const TreeKey: {
192
+ readonly Events: 'events';
193
+ readonly Subscribe: 'subscribe';
194
+ };
195
+ export declare const TypeofKind: {
196
+ readonly Function: 'function';
197
+ readonly Object: 'object';
198
+ };
199
+ export declare const WatchText: {
200
+ readonly ReplayOverflow: (max: number) => string;
201
+ readonly OutputMatchUnsupported: 'watchPaneSet does not subscribe to pane.output_matched: its match and source are not options yet (HERDR-ADR-0016 open issue 8)';
202
+ };
203
+ export declare const HeldText: {
204
+ readonly Ended: (method: string) => string;
205
+ };
206
+ export declare const PANE_LIFECYCLE_SUBSCRIPTION_TYPES: readonly ["pane.created", "pane.closed"];
207
+ export declare const FakeErrorCode: {
208
+ readonly InvalidParams: 'invalid_params';
209
+ };
210
+ export declare const FakeCheckText: {
211
+ readonly NotAnObject: (method: string) => string;
212
+ readonly MissingField: (method: string, field: string) => string;
213
+ readonly WrongKind: (method: string, field: string) => string;
214
+ readonly NotInEnum: (method: string, field: string) => string;
215
+ readonly KeyNotAllowed: (method: string, field: string) => string;
216
+ readonly NeedsPaneId: (type: string) => string;
217
+ };
218
+ export declare const TypeofValue: {
219
+ readonly Number: 'number';
220
+ readonly Boolean: 'boolean';
221
+ };
222
+ export declare const EMPTY_SCHEMA_RESULT: Readonly<Record<string, never>>;
223
+ export declare const SpecField: {
224
+ readonly Subscriptions: 'subscriptions';
225
+ readonly PaneId: 'pane_id';
226
+ };
227
+ export declare const FakeMethod: {
228
+ readonly ApiSchema: 'api.schema';
229
+ };
230
+ export declare const NameSeparator: {
231
+ readonly Event: '_';
232
+ readonly Subscription: '.';
233
+ };
234
+ export declare const EffectFallbackMessage: {
235
+ readonly UnknownError: 'unknown herdr error';
236
+ };