@unicity-astrid/sdk 0.1.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 (124) hide show
  1. package/README.md +120 -0
  2. package/dist/approval.d.ts +23 -0
  3. package/dist/approval.d.ts.map +1 -0
  4. package/dist/approval.js +29 -0
  5. package/dist/approval.js.map +1 -0
  6. package/dist/capabilities.d.ts +14 -0
  7. package/dist/capabilities.d.ts.map +1 -0
  8. package/dist/capabilities.js +19 -0
  9. package/dist/capabilities.js.map +1 -0
  10. package/dist/capsule.d.ts +39 -0
  11. package/dist/capsule.d.ts.map +1 -0
  12. package/dist/capsule.js +67 -0
  13. package/dist/capsule.js.map +1 -0
  14. package/dist/contracts.d.ts +1104 -0
  15. package/dist/contracts.d.ts.map +1 -0
  16. package/dist/contracts.js +4 -0
  17. package/dist/contracts.js.map +1 -0
  18. package/dist/elicit.d.ts +30 -0
  19. package/dist/elicit.d.ts.map +1 -0
  20. package/dist/elicit.js +103 -0
  21. package/dist/elicit.js.map +1 -0
  22. package/dist/env.d.ts +19 -0
  23. package/dist/env.d.ts.map +1 -0
  24. package/dist/env.js +27 -0
  25. package/dist/env.js.map +1 -0
  26. package/dist/errors.d.ts +46 -0
  27. package/dist/errors.d.ts.map +1 -0
  28. package/dist/errors.js +108 -0
  29. package/dist/errors.js.map +1 -0
  30. package/dist/fs.d.ts +135 -0
  31. package/dist/fs.d.ts.map +1 -0
  32. package/dist/fs.js +257 -0
  33. package/dist/fs.js.map +1 -0
  34. package/dist/http.d.ts +90 -0
  35. package/dist/http.d.ts.map +1 -0
  36. package/dist/http.js +276 -0
  37. package/dist/http.js.map +1 -0
  38. package/dist/identity.d.ts +46 -0
  39. package/dist/identity.d.ts.map +1 -0
  40. package/dist/identity.js +69 -0
  41. package/dist/identity.js.map +1 -0
  42. package/dist/index.d.ts +30 -0
  43. package/dist/index.d.ts.map +1 -0
  44. package/dist/index.js +27 -0
  45. package/dist/index.js.map +1 -0
  46. package/dist/interceptors.d.ts +21 -0
  47. package/dist/interceptors.d.ts.map +1 -0
  48. package/dist/interceptors.js +22 -0
  49. package/dist/interceptors.js.map +1 -0
  50. package/dist/ipc.d.ts +143 -0
  51. package/dist/ipc.d.ts.map +1 -0
  52. package/dist/ipc.js +261 -0
  53. package/dist/ipc.js.map +1 -0
  54. package/dist/kv.d.ts +45 -0
  55. package/dist/kv.d.ts.map +1 -0
  56. package/dist/kv.js +91 -0
  57. package/dist/kv.js.map +1 -0
  58. package/dist/log.d.ts +17 -0
  59. package/dist/log.d.ts.map +1 -0
  60. package/dist/log.js +40 -0
  61. package/dist/log.js.map +1 -0
  62. package/dist/net.d.ts +154 -0
  63. package/dist/net.d.ts.map +1 -0
  64. package/dist/net.js +421 -0
  65. package/dist/net.js.map +1 -0
  66. package/dist/process.d.ts +77 -0
  67. package/dist/process.d.ts.map +1 -0
  68. package/dist/process.js +128 -0
  69. package/dist/process.js.map +1 -0
  70. package/dist/runtime/bridge.d.ts +34 -0
  71. package/dist/runtime/bridge.d.ts.map +1 -0
  72. package/dist/runtime/bridge.js +326 -0
  73. package/dist/runtime/bridge.js.map +1 -0
  74. package/dist/runtime/index.d.ts +3 -0
  75. package/dist/runtime/index.d.ts.map +1 -0
  76. package/dist/runtime/index.js +3 -0
  77. package/dist/runtime/index.js.map +1 -0
  78. package/dist/runtime/registry.d.ts +58 -0
  79. package/dist/runtime/registry.d.ts.map +1 -0
  80. package/dist/runtime/registry.js +129 -0
  81. package/dist/runtime/registry.js.map +1 -0
  82. package/dist/runtime.d.ts +36 -0
  83. package/dist/runtime.d.ts.map +1 -0
  84. package/dist/runtime.js +50 -0
  85. package/dist/runtime.js.map +1 -0
  86. package/dist/time.d.ts +29 -0
  87. package/dist/time.d.ts.map +1 -0
  88. package/dist/time.js +43 -0
  89. package/dist/time.js.map +1 -0
  90. package/dist/tool.d.ts +48 -0
  91. package/dist/tool.d.ts.map +1 -0
  92. package/dist/tool.js +86 -0
  93. package/dist/tool.js.map +1 -0
  94. package/dist/uplink.d.ts +27 -0
  95. package/dist/uplink.d.ts.map +1 -0
  96. package/dist/uplink.js +36 -0
  97. package/dist/uplink.js.map +1 -0
  98. package/package.json +38 -0
  99. package/src/approval.ts +38 -0
  100. package/src/capabilities.ts +22 -0
  101. package/src/capsule.ts +90 -0
  102. package/src/contracts.ts +1189 -0
  103. package/src/elicit.ts +136 -0
  104. package/src/env.ts +31 -0
  105. package/src/errors.ts +122 -0
  106. package/src/fs.ts +357 -0
  107. package/src/http.ts +345 -0
  108. package/src/identity.ts +101 -0
  109. package/src/index.ts +83 -0
  110. package/src/interceptors.ts +25 -0
  111. package/src/ipc.ts +354 -0
  112. package/src/kv.ts +123 -0
  113. package/src/log.ts +43 -0
  114. package/src/net.ts +545 -0
  115. package/src/process.ts +205 -0
  116. package/src/runtime/bridge.ts +374 -0
  117. package/src/runtime/index.ts +11 -0
  118. package/src/runtime/registry.ts +178 -0
  119. package/src/runtime.ts +70 -0
  120. package/src/time.ts +48 -0
  121. package/src/tool.ts +125 -0
  122. package/src/uplink.ts +49 -0
  123. package/src/wit-imports.d.ts +689 -0
  124. package/wit-contracts/astrid-contracts.wit +1266 -0
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Multi-platform identity resolution and linking. Mirrors `astrid_sdk::identity`.
3
+ *
4
+ * Required capability in `Capsule.toml`:
5
+ * `["resolve"]` — resolve platform users
6
+ * `["link"]` — resolve, link, unlink, list-links
7
+ * `["admin"]` — all of the above + create new users
8
+ *
9
+ * Post per-domain WIT split, the host returns typed records directly (no
10
+ * `linksJson` blob, no `ok` flags). Errors surface as `SysError` with
11
+ * `code` set to the WIT variant (`link-not-found`, `already-linked`, etc.).
12
+ *
13
+ * The {@link resolve} helper preserves the pre-migration "absent → undefined"
14
+ * shape by catching `link-not-found` and returning `undefined`. Other errors
15
+ * propagate.
16
+ */
17
+ export interface ResolvedUser {
18
+ userId: string;
19
+ displayName: string | undefined;
20
+ }
21
+ export interface Link {
22
+ platform: string;
23
+ platformUserId: string;
24
+ /** ISO 8601 timestamp the link was created. */
25
+ linkedAt: string;
26
+ /** Auth method used at link time (e.g. "passkey", "token"). */
27
+ method: string;
28
+ }
29
+ /**
30
+ * Resolve a platform identity to an Astrid user, or `undefined` if no link
31
+ * exists. Other identity errors (capability-denied, store-unavailable, etc.)
32
+ * propagate as `SysError`.
33
+ */
34
+ export declare function resolve(platform: string, platformUserId: string): ResolvedUser | undefined;
35
+ /** Link a platform identity to an Astrid user. */
36
+ export declare function link(platform: string, platformUserId: string, astridUserId: string, method: string): void;
37
+ /**
38
+ * Unlink a platform identity. Returns `true` if a link was removed,
39
+ * `false` if there was nothing to remove.
40
+ */
41
+ export declare function unlink(platform: string, platformUserId: string): boolean;
42
+ /** Create a new Astrid user. Returns the new user UUID. */
43
+ export declare function createUser(displayName?: string): string;
44
+ /** List all platform links for an Astrid user. */
45
+ export declare function listLinks(astridUserId: string): Link[];
46
+ //# sourceMappingURL=identity.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"identity.d.ts","sourceRoot":"","sources":["../src/identity.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAWH,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,GAAG,SAAS,CAAC;CACjC;AAED,MAAM,WAAW,IAAI;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,MAAM,CAAC;IACvB,+CAA+C;IAC/C,QAAQ,EAAE,MAAM,CAAC;IACjB,+DAA+D;IAC/D,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;;GAIG;AACH,wBAAgB,OAAO,CAAC,QAAQ,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS,CAU1F;AAED,kDAAkD;AAClD,wBAAgB,IAAI,CAClB,QAAQ,EAAE,MAAM,EAChB,cAAc,EAAE,MAAM,EACtB,YAAY,EAAE,MAAM,EACpB,MAAM,EAAE,MAAM,GACb,IAAI,CAIN;AAED;;;GAGG;AACH,wBAAgB,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAG,OAAO,CAQxE;AAED,2DAA2D;AAC3D,wBAAgB,UAAU,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,CAKvD;AAED,kDAAkD;AAClD,wBAAgB,SAAS,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,EAAE,CAQtD"}
@@ -0,0 +1,69 @@
1
+ /**
2
+ * Multi-platform identity resolution and linking. Mirrors `astrid_sdk::identity`.
3
+ *
4
+ * Required capability in `Capsule.toml`:
5
+ * `["resolve"]` — resolve platform users
6
+ * `["link"]` — resolve, link, unlink, list-links
7
+ * `["admin"]` — all of the above + create new users
8
+ *
9
+ * Post per-domain WIT split, the host returns typed records directly (no
10
+ * `linksJson` blob, no `ok` flags). Errors surface as `SysError` with
11
+ * `code` set to the WIT variant (`link-not-found`, `already-linked`, etc.).
12
+ *
13
+ * The {@link resolve} helper preserves the pre-migration "absent → undefined"
14
+ * shape by catching `link-not-found` and returning `undefined`. Other errors
15
+ * propagate.
16
+ */
17
+ import { identityResolve as hostResolve, identityLink as hostLink, identityUnlink as hostUnlink, identityCreateUser as hostCreateUser, identityListLinks as hostListLinks, } from "astrid:identity/host@1.0.0";
18
+ import { SysError, callHost } from "./errors.js";
19
+ /**
20
+ * Resolve a platform identity to an Astrid user, or `undefined` if no link
21
+ * exists. Other identity errors (capability-denied, store-unavailable, etc.)
22
+ * propagate as `SysError`.
23
+ */
24
+ export function resolve(platform, platformUserId) {
25
+ try {
26
+ const resp = callHost(`identity.resolve(${JSON.stringify(platform)})`, () => hostResolve({ platform, platformUserId }));
27
+ return { userId: resp.userId, displayName: resp.displayName };
28
+ }
29
+ catch (err) {
30
+ if (err instanceof SysError && err.code === "link-not-found")
31
+ return undefined;
32
+ throw err;
33
+ }
34
+ }
35
+ /** Link a platform identity to an Astrid user. */
36
+ export function link(platform, platformUserId, astridUserId, method) {
37
+ callHost("identity.link", () => hostLink({ platform, platformUserId, astridUserId, method }));
38
+ }
39
+ /**
40
+ * Unlink a platform identity. Returns `true` if a link was removed,
41
+ * `false` if there was nothing to remove.
42
+ */
43
+ export function unlink(platform, platformUserId) {
44
+ try {
45
+ callHost("identity.unlink", () => hostUnlink({ platform, platformUserId }));
46
+ return true;
47
+ }
48
+ catch (err) {
49
+ if (err instanceof SysError && err.code === "link-not-found")
50
+ return false;
51
+ throw err;
52
+ }
53
+ }
54
+ /** Create a new Astrid user. Returns the new user UUID. */
55
+ export function createUser(displayName) {
56
+ const resp = callHost("identity.createUser", () => hostCreateUser({ displayName }));
57
+ return resp.userId;
58
+ }
59
+ /** List all platform links for an Astrid user. */
60
+ export function listLinks(astridUserId) {
61
+ const links = callHost("identity.listLinks", () => hostListLinks(astridUserId));
62
+ return links.map((l) => ({
63
+ platform: l.platform,
64
+ platformUserId: l.platformUserId,
65
+ linkedAt: l.linkedAt,
66
+ method: l.method,
67
+ }));
68
+ }
69
+ //# sourceMappingURL=identity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"identity.js","sourceRoot":"","sources":["../src/identity.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EACL,eAAe,IAAI,WAAW,EAC9B,YAAY,IAAI,QAAQ,EACxB,cAAc,IAAI,UAAU,EAC5B,kBAAkB,IAAI,cAAc,EACpC,iBAAiB,IAAI,aAAa,GACnC,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAgBjD;;;;GAIG;AACH,MAAM,UAAU,OAAO,CAAC,QAAgB,EAAE,cAAsB;IAC9D,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,QAAQ,CAAC,oBAAoB,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE,CAC1E,WAAW,CAAC,EAAE,QAAQ,EAAE,cAAc,EAAE,CAAC,CAC1C,CAAC;QACF,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,WAAW,EAAE,IAAI,CAAC,WAAW,EAAE,CAAC;IAChE,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,GAAG,YAAY,QAAQ,IAAI,GAAG,CAAC,IAAI,KAAK,gBAAgB;YAAE,OAAO,SAAS,CAAC;QAC/E,MAAM,GAAG,CAAC;IACZ,CAAC;AACH,CAAC;AAED,kDAAkD;AAClD,MAAM,UAAU,IAAI,CAClB,QAAgB,EAChB,cAAsB,EACtB,YAAoB,EACpB,MAAc;IAEd,QAAQ,CAAC,eAAe,EAAE,GAAG,EAAE,CAC7B,QAAQ,CAAC,EAAE,QAAQ,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,EAAE,CAAC,CAC7D,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,MAAM,CAAC,QAAgB,EAAE,cAAsB;IAC7D,IAAI,CAAC;QACH,QAAQ,CAAC,iBAAiB,EAAE,GAAG,EAAE,CAAC,UAAU,CAAC,EAAE,QAAQ,EAAE,cAAc,EAAE,CAAC,CAAC,CAAC;QAC5E,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,GAAG,YAAY,QAAQ,IAAI,GAAG,CAAC,IAAI,KAAK,gBAAgB;YAAE,OAAO,KAAK,CAAC;QAC3E,MAAM,GAAG,CAAC;IACZ,CAAC;AACH,CAAC;AAED,2DAA2D;AAC3D,MAAM,UAAU,UAAU,CAAC,WAAoB;IAC7C,MAAM,IAAI,GAAG,QAAQ,CAAC,qBAAqB,EAAE,GAAG,EAAE,CAChD,cAAc,CAAC,EAAE,WAAW,EAAE,CAAC,CAChC,CAAC;IACF,OAAO,IAAI,CAAC,MAAM,CAAC;AACrB,CAAC;AAED,kDAAkD;AAClD,MAAM,UAAU,SAAS,CAAC,YAAoB;IAC5C,MAAM,KAAK,GAAG,QAAQ,CAAC,oBAAoB,EAAE,GAAG,EAAE,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC,CAAC;IAChF,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACvB,QAAQ,EAAE,CAAC,CAAC,QAAQ;QACpB,cAAc,EAAE,CAAC,CAAC,cAAc;QAChC,QAAQ,EAAE,CAAC,CAAC,QAAQ;QACpB,MAAM,EAAE,CAAC,CAAC,MAAM;KACjB,CAAC,CAAC,CAAC;AACN,CAAC"}
@@ -0,0 +1,30 @@
1
+ export { SysError, type SysErrorKind } from "./errors.js";
2
+ export { capsule, install, upgrade, run } from "./capsule.js";
3
+ export { tool, interceptor, command, type ToolOptions, type InterceptorOptions, type CommandOptions, } from "./tool.js";
4
+ export * as log from "./log.js";
5
+ export * as kv from "./kv.js";
6
+ export * as ipc from "./ipc.js";
7
+ export * as fs from "./fs.js";
8
+ export * as http from "./http.js";
9
+ export * as net from "./net.js";
10
+ export * as process from "./process.js";
11
+ export * as env from "./env.js";
12
+ export * as time from "./time.js";
13
+ export * as runtime from "./runtime.js";
14
+ export * as capabilities from "./capabilities.js";
15
+ export * as elicit from "./elicit.js";
16
+ export * as identity from "./identity.js";
17
+ export * as approval from "./approval.js";
18
+ export * as uplink from "./uplink.js";
19
+ export * as interceptors from "./interceptors.js";
20
+ export type { IpcMessage, PollResult, Subscription, InterceptorBinding, PrincipalAttribution, } from "./ipc.js";
21
+ export type { Stats, Dirent, FileHandle, OpenMode, FileType } from "./fs.js";
22
+ export type { Request as HttpRequest, Response as HttpResponse, HttpMethod, HttpStreamHandle, StreamStart, FetchInit, FetchResponse, } from "./http.js";
23
+ export type { UnixListener, TcpListener, TcpStream, UdpSocket, ListenerHandle, StreamHandle, RecvError, SendError, TryRecvError, ShutdownHow, NetReadStatus, UdpDatagram, } from "./net.js";
24
+ export type { ProcessResult, ProcessLogs, KillResult, BackgroundProcessHandle, SpawnOptions, ProcessSignal, EnvVar, } from "./process.js";
25
+ export type { CallerContext } from "./runtime.js";
26
+ export type { ResolvedUser, Link } from "./identity.js";
27
+ export type { UplinkId, UplinkProfile } from "./uplink.js";
28
+ export type { ApprovalDecision } from "./approval.js";
29
+ export type { KeyPage } from "./kv.js";
30
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,QAAQ,EAAE,KAAK,YAAY,EAAE,MAAM,aAAa,CAAC;AAE1D,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AAC9D,OAAO,EACL,IAAI,EACJ,WAAW,EACX,OAAO,EACP,KAAK,WAAW,EAChB,KAAK,kBAAkB,EACvB,KAAK,cAAc,GACpB,MAAM,WAAW,CAAC;AAKnB,OAAO,KAAK,GAAG,MAAM,UAAU,CAAC;AAChC,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,GAAG,MAAM,UAAU,CAAC;AAChC,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,KAAK,GAAG,MAAM,UAAU,CAAC;AAChC,OAAO,KAAK,OAAO,MAAM,cAAc,CAAC;AACxC,OAAO,KAAK,GAAG,MAAM,UAAU,CAAC;AAChC,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,KAAK,OAAO,MAAM,cAAc,CAAC;AACxC,OAAO,KAAK,YAAY,MAAM,mBAAmB,CAAC;AAClD,OAAO,KAAK,MAAM,MAAM,aAAa,CAAC;AACtC,OAAO,KAAK,QAAQ,MAAM,eAAe,CAAC;AAC1C,OAAO,KAAK,QAAQ,MAAM,eAAe,CAAC;AAC1C,OAAO,KAAK,MAAM,MAAM,aAAa,CAAC;AACtC,OAAO,KAAK,YAAY,MAAM,mBAAmB,CAAC;AAGlD,YAAY,EACV,UAAU,EACV,UAAU,EACV,YAAY,EACZ,kBAAkB,EAClB,oBAAoB,GACrB,MAAM,UAAU,CAAC;AAClB,YAAY,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC7E,YAAY,EACV,OAAO,IAAI,WAAW,EACtB,QAAQ,IAAI,YAAY,EACxB,UAAU,EACV,gBAAgB,EAChB,WAAW,EACX,SAAS,EACT,aAAa,GACd,MAAM,WAAW,CAAC;AACnB,YAAY,EACV,YAAY,EACZ,WAAW,EACX,SAAS,EACT,SAAS,EACT,cAAc,EACd,YAAY,EACZ,SAAS,EACT,SAAS,EACT,YAAY,EACZ,WAAW,EACX,aAAa,EACb,WAAW,GACZ,MAAM,UAAU,CAAC;AAClB,YAAY,EACV,aAAa,EACb,WAAW,EACX,UAAU,EACV,uBAAuB,EACvB,YAAY,EACZ,aAAa,EACb,MAAM,GACP,MAAM,cAAc,CAAC;AACtB,YAAY,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAClD,YAAY,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AACxD,YAAY,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC3D,YAAY,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACtD,YAAY,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,27 @@
1
+ // Public API of @unicity-astrid/sdk.
2
+ //
3
+ // Module-by-module mirror of `astrid_sdk::prelude`, with idiom translated
4
+ // from Rust-std to Node/WHATWG conventions where appropriate.
5
+ export { SysError } from "./errors.js";
6
+ export { capsule, install, upgrade, run } from "./capsule.js";
7
+ export { tool, interceptor, command, } from "./tool.js";
8
+ // Namespaced submodules. Authors import as
9
+ // `import { fs, http, ipc, ... } from "@unicity-astrid/sdk"` and call
10
+ // `await fs.readFile(...)`, `ipc.publish(...)`, etc.
11
+ export * as log from "./log.js";
12
+ export * as kv from "./kv.js";
13
+ export * as ipc from "./ipc.js";
14
+ export * as fs from "./fs.js";
15
+ export * as http from "./http.js";
16
+ export * as net from "./net.js";
17
+ export * as process from "./process.js";
18
+ export * as env from "./env.js";
19
+ export * as time from "./time.js";
20
+ export * as runtime from "./runtime.js";
21
+ export * as capabilities from "./capabilities.js";
22
+ export * as elicit from "./elicit.js";
23
+ export * as identity from "./identity.js";
24
+ export * as approval from "./approval.js";
25
+ export * as uplink from "./uplink.js";
26
+ export * as interceptors from "./interceptors.js";
27
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,qCAAqC;AACrC,EAAE;AACF,0EAA0E;AAC1E,8DAA8D;AAE9D,OAAO,EAAE,QAAQ,EAAqB,MAAM,aAAa,CAAC;AAE1D,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AAC9D,OAAO,EACL,IAAI,EACJ,WAAW,EACX,OAAO,GAIR,MAAM,WAAW,CAAC;AAEnB,2CAA2C;AAC3C,sEAAsE;AACtE,qDAAqD;AACrD,OAAO,KAAK,GAAG,MAAM,UAAU,CAAC;AAChC,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,GAAG,MAAM,UAAU,CAAC;AAChC,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,KAAK,GAAG,MAAM,UAAU,CAAC;AAChC,OAAO,KAAK,OAAO,MAAM,cAAc,CAAC;AACxC,OAAO,KAAK,GAAG,MAAM,UAAU,CAAC;AAChC,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,KAAK,OAAO,MAAM,cAAc,CAAC;AACxC,OAAO,KAAK,YAAY,MAAM,mBAAmB,CAAC;AAClD,OAAO,KAAK,MAAM,MAAM,aAAa,CAAC;AACtC,OAAO,KAAK,QAAQ,MAAM,eAAe,CAAC;AAC1C,OAAO,KAAK,QAAQ,MAAM,eAAe,CAAC;AAC1C,OAAO,KAAK,MAAM,MAAM,aAAa,CAAC;AACtC,OAAO,KAAK,YAAY,MAAM,mBAAmB,CAAC"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Interceptor binding registry — metadata for the kernel-managed
3
+ * interceptor subscriptions a capsule declared in `Capsule.toml`.
4
+ *
5
+ * Mirrors `astrid_sdk::interceptors`. Under the per-domain ABI, interceptor
6
+ * events are delivered to the capsule via `astrid-hook-trigger` rather than
7
+ * a run-loop IPC subscription. The host fn `get-interceptor-bindings` returns
8
+ * metadata-only — capsules use it to enumerate the `(action, topic)` pairs
9
+ * they're subscribed to for debugging, introspection, and tooling. `handle`
10
+ * is the kernel-side registry handle (for log correlation only); it is NOT
11
+ * convertible into an `ipc.Subscription`.
12
+ */
13
+ import { type InterceptorBinding } from "./ipc.js";
14
+ export type { InterceptorBinding } from "./ipc.js";
15
+ /**
16
+ * Query the runtime for auto-subscribed interceptor handles. Returns an
17
+ * empty array if this capsule has no auto-subscribed interceptors (i.e. it
18
+ * does not have both `@run` and `[[interceptor]]`).
19
+ */
20
+ export declare function bindings(): InterceptorBinding[];
21
+ //# sourceMappingURL=interceptors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interceptors.d.ts","sourceRoot":"","sources":["../src/interceptors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAuB,KAAK,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAExE,YAAY,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAEnD;;;;GAIG;AACH,wBAAgB,QAAQ,IAAI,kBAAkB,EAAE,CAE/C"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Interceptor binding registry — metadata for the kernel-managed
3
+ * interceptor subscriptions a capsule declared in `Capsule.toml`.
4
+ *
5
+ * Mirrors `astrid_sdk::interceptors`. Under the per-domain ABI, interceptor
6
+ * events are delivered to the capsule via `astrid-hook-trigger` rather than
7
+ * a run-loop IPC subscription. The host fn `get-interceptor-bindings` returns
8
+ * metadata-only — capsules use it to enumerate the `(action, topic)` pairs
9
+ * they're subscribed to for debugging, introspection, and tooling. `handle`
10
+ * is the kernel-side registry handle (for log correlation only); it is NOT
11
+ * convertible into an `ipc.Subscription`.
12
+ */
13
+ import { runtimeInterceptors } from "./ipc.js";
14
+ /**
15
+ * Query the runtime for auto-subscribed interceptor handles. Returns an
16
+ * empty array if this capsule has no auto-subscribed interceptors (i.e. it
17
+ * does not have both `@run` and `[[interceptor]]`).
18
+ */
19
+ export function bindings() {
20
+ return runtimeInterceptors();
21
+ }
22
+ //# sourceMappingURL=interceptors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interceptors.js","sourceRoot":"","sources":["../src/interceptors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,mBAAmB,EAA2B,MAAM,UAAU,CAAC;AAIxE;;;;GAIG;AACH,MAAM,UAAU,QAAQ;IACtB,OAAO,mBAAmB,EAAE,CAAC;AAC/B,CAAC"}
package/dist/ipc.d.ts ADDED
@@ -0,0 +1,143 @@
1
+ /**
2
+ * IPC event bus. Mirrors `astrid_sdk::ipc`.
3
+ *
4
+ * Publish: {@link publish} / {@link publishJson} for the calling capsule's
5
+ * own principal, {@link publishAs} / {@link publishJsonAs} for uplinks
6
+ * asserting an end-user principal (requires `uplink = true` capability —
7
+ * subscribers see the principal as `claimed`, not `verified`).
8
+ *
9
+ * Subscribe: {@link subscribe} returns a {@link Subscription} resource handle.
10
+ * Resources are Component Model objects with a drop step; we surface
11
+ * `Symbol.dispose` so `using sub = ipc.subscribe(...)` cleans up automatically
12
+ * on scope exit, and an explicit `.close()` for codebases that haven't moved
13
+ * to the explicit-resource-management proposal. AsyncIterable convenience
14
+ * preserved from the pre-migration API.
15
+ *
16
+ * Request/response: {@link requestResponse} mirrors `astrid_sdk::ipc::request_response`.
17
+ * Validates the request payload, pre-subscribes to the reply topic, publishes
18
+ * with an auto-injected `correlation_id`, blocks up to `timeoutMs` for the
19
+ * single reply, always tears down the subscription.
20
+ */
21
+ import { type PrincipalAttribution, type Subscription as WitSubscription } from "astrid:ipc/host@1.0.0";
22
+ /** A single IPC message dispatched to a subscriber. */
23
+ export interface IpcMessage {
24
+ topic: string;
25
+ payload: string;
26
+ /** UUID of the capsule that published this message. */
27
+ sourceId: string;
28
+ /**
29
+ * Principal attributed to the publisher. `verified(...)` for kernel-attributed
30
+ * principals, `claimed(...)` for uplink-asserted principals (NOT kernel-
31
+ * verified), `system` for kernel-originated events.
32
+ *
33
+ * Subscribers MUST check this variant on sensitive actions. Multi-message
34
+ * batches MUST be read per-message rather than relying on `runtime.caller()`
35
+ * (which only reflects the first message's publisher).
36
+ */
37
+ principal: PrincipalAttribution;
38
+ /** Convenience: parse `payload` as JSON. Throws SysError.json on failure. */
39
+ json<T = unknown>(): T;
40
+ }
41
+ export type { PrincipalAttribution } from "astrid:ipc/host@1.0.0";
42
+ export interface PollResult {
43
+ messages: IpcMessage[];
44
+ /** Messages dropped due to buffer overflow since the previous poll. */
45
+ dropped: bigint;
46
+ /** Cumulative lag — total messages missed since subscription opened. */
47
+ lagged: bigint;
48
+ }
49
+ export interface InterceptorBinding {
50
+ /** Subscription handle ID. */
51
+ handle: bigint;
52
+ /** Hook action name the kernel dispatches when a message matches. */
53
+ action: string;
54
+ /** Topic pattern this subscription was registered for. */
55
+ topic: string;
56
+ }
57
+ export declare function publish(topic: string, payload: string): void;
58
+ export declare function publishJson<T>(topic: string, payload: T): void;
59
+ /**
60
+ * Publish on behalf of a specific principal. Requires `uplink = true` in
61
+ * `Capsule.toml [capabilities]`; non-uplinks see `capability-denied`.
62
+ * Subscribers see the principal as `claimed(...)`, NOT `verified(...)` —
63
+ * downstream consumers MUST treat the principal as caller-input, not
64
+ * authenticated context.
65
+ */
66
+ export declare function publishAs(topic: string, payload: string, principal: string): void;
67
+ export declare function publishJsonAs<T>(topic: string, payload: T, principal: string): void;
68
+ /**
69
+ * Subscribe to an IPC topic pattern. Supports exact matches and trailing-suffix
70
+ * wildcards (`foo.bar.*`). Mid-segment wildcards are rejected by the host.
71
+ *
72
+ * The returned {@link Subscription} is a Resource handle. Use `using` for
73
+ * scope-bound cleanup, or call `.close()` explicitly:
74
+ *
75
+ * ```ts
76
+ * using sub = ipc.subscribe("foo.bar"); // disposed at scope exit
77
+ * for await (const msg of sub) { ... }
78
+ *
79
+ * const sub = ipc.subscribe("foo.bar"); // explicit close
80
+ * try { ... } finally { sub.close(); }
81
+ * ```
82
+ *
83
+ * Per-capsule cap: 128 subscriptions.
84
+ */
85
+ export declare function subscribe(topicPattern: string): Subscription;
86
+ /**
87
+ * Pre-registered interceptor handles for run-loop capsules. Returns ONLY the
88
+ * calling capsule's own interceptors. Most authors don't call this — the
89
+ * `@interceptor` decorator + bridge handle dispatch.
90
+ */
91
+ export declare function runtimeInterceptors(): InterceptorBinding[];
92
+ export declare class Subscription {
93
+ #private;
94
+ readonly topic: string;
95
+ constructor(inner: WitSubscription, topic: string);
96
+ /** Non-blocking poll. Returns whatever's already queued. */
97
+ poll(): PollResult;
98
+ /** Blocking receive (timeout capped at 60s by the host). */
99
+ recv(timeoutMs?: bigint): PollResult;
100
+ /**
101
+ * Idempotent — closing an already-closed subscription is a no-op.
102
+ * Equivalent to the resource Drop. Prefer `using` when the surrounding
103
+ * code can adopt explicit resource management.
104
+ */
105
+ close(): void;
106
+ [Symbol.dispose](): void;
107
+ /**
108
+ * AsyncIterable convenience. Loops calling `.recv()` and yielding each
109
+ * message. Stops when the subscription is closed. Drops `lagged`/`dropped`
110
+ * info — use `.poll()`/`.recv()` explicitly if you need to react to lag.
111
+ */
112
+ [Symbol.asyncIterator](): AsyncIterableIterator<IpcMessage>;
113
+ }
114
+ /**
115
+ * Send a request on `requestTopic` and await a single response on a scoped
116
+ * reply topic. Mirrors `astrid_sdk::ipc::request_response` exactly.
117
+ *
118
+ * The helper:
119
+ * 1. Generates a v4 correlation ID.
120
+ * 2. Subscribes to `{responseNamespace}.{correlationId}` *before* publishing
121
+ * (so the response can never be missed in the race).
122
+ * 3. Injects the correlation ID into the request payload as a top-level
123
+ * `correlation_id` field.
124
+ * 4. Publishes the request.
125
+ * 5. Blocks up to `timeoutMs` for the response.
126
+ * 6. Unsubscribes (always, even on error).
127
+ * 7. Returns the parsed response payload as `Resp`.
128
+ *
129
+ * `request` must serialize to a JSON object. Primitives, arrays, strings,
130
+ * etc. are rejected synchronously with `SysError.api` because there is
131
+ * nowhere to put the correlation ID.
132
+ *
133
+ * `responseNamespace` should be the dotted topic prefix the responder
134
+ * publishes to, *without* the trailing correlation id segment. For example,
135
+ * if the responder publishes to
136
+ * `registry.v1.response.set_active_model.<corr_id>`, pass
137
+ * `"registry.v1.response.set_active_model"`.
138
+ *
139
+ * `timeoutMs` is capped at 60,000 ms by the host. A timeout throws
140
+ * `SysError.api` with `request_response: no reply within …`.
141
+ */
142
+ export declare function requestResponse<Req, Resp = unknown>(requestTopic: string, responseNamespace: string, request: Req, timeoutMs: number | bigint): Resp;
143
+ //# sourceMappingURL=ipc.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ipc.d.ts","sourceRoot":"","sources":["../src/ipc.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAQL,KAAK,oBAAoB,EACzB,KAAK,YAAY,IAAI,eAAe,EACrC,MAAM,uBAAuB,CAAC;AAI/B,uDAAuD;AACvD,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,uDAAuD;IACvD,QAAQ,EAAE,MAAM,CAAC;IACjB;;;;;;;;OAQG;IACH,SAAS,EAAE,oBAAoB,CAAC;IAChC,6EAA6E;IAC7E,IAAI,CAAC,CAAC,GAAG,OAAO,KAAK,CAAC,CAAC;CACxB;AAED,YAAY,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAElE,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,UAAU,EAAE,CAAC;IACvB,uEAAuE;IACvE,OAAO,EAAE,MAAM,CAAC;IAChB,wEAAwE;IACxE,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,kBAAkB;IACjC,8BAA8B;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,qEAAqE;IACrE,MAAM,EAAE,MAAM,CAAC;IACf,0DAA0D;IAC1D,KAAK,EAAE,MAAM,CAAC;CACf;AAID,wBAAgB,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAE5D;AAED,wBAAgB,WAAW,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,GAAG,IAAI,CAE9D;AAED;;;;;;GAMG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,CAIjF;AAED,wBAAgB,aAAa,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,CAEnF;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,SAAS,CAAC,YAAY,EAAE,MAAM,GAAG,YAAY,CAK5D;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,IAAI,kBAAkB,EAAE,CAK1D;AAED,qBAAa,YAAY;;IACvB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;gBAGX,KAAK,EAAE,eAAe,EAAE,KAAK,EAAE,MAAM;IAKjD,4DAA4D;IAC5D,IAAI,IAAI,UAAU;IAKlB,4DAA4D;IAC5D,IAAI,CAAC,SAAS,GAAE,MAAgC,GAAG,UAAU;IAO7D;;;;OAIG;IACH,KAAK,IAAI,IAAI;IAYb,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,IAAI;IAIxB;;;;OAIG;IACI,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,qBAAqB,CAAC,UAAU,CAAC;CAenE;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,IAAI,GAAG,OAAO,EACjD,YAAY,EAAE,MAAM,EACpB,iBAAiB,EAAE,MAAM,EACzB,OAAO,EAAE,GAAG,EACZ,SAAS,EAAE,MAAM,GAAG,MAAM,GACzB,IAAI,CA0CN"}
package/dist/ipc.js ADDED
@@ -0,0 +1,261 @@
1
+ /**
2
+ * IPC event bus. Mirrors `astrid_sdk::ipc`.
3
+ *
4
+ * Publish: {@link publish} / {@link publishJson} for the calling capsule's
5
+ * own principal, {@link publishAs} / {@link publishJsonAs} for uplinks
6
+ * asserting an end-user principal (requires `uplink = true` capability —
7
+ * subscribers see the principal as `claimed`, not `verified`).
8
+ *
9
+ * Subscribe: {@link subscribe} returns a {@link Subscription} resource handle.
10
+ * Resources are Component Model objects with a drop step; we surface
11
+ * `Symbol.dispose` so `using sub = ipc.subscribe(...)` cleans up automatically
12
+ * on scope exit, and an explicit `.close()` for codebases that haven't moved
13
+ * to the explicit-resource-management proposal. AsyncIterable convenience
14
+ * preserved from the pre-migration API.
15
+ *
16
+ * Request/response: {@link requestResponse} mirrors `astrid_sdk::ipc::request_response`.
17
+ * Validates the request payload, pre-subscribes to the reply topic, publishes
18
+ * with an auto-injected `correlation_id`, blocks up to `timeoutMs` for the
19
+ * single reply, always tears down the subscription.
20
+ */
21
+ import { publish as hostPublish, publishAs as hostPublishAs, subscribe as hostSubscribe, getInterceptorBindings as hostGetInterceptorBindings, } from "astrid:ipc/host@1.0.0";
22
+ import { randomBytes as hostRandomBytes } from "astrid:sys/host@1.0.0";
23
+ import { SysError, callHost } from "./errors.js";
24
+ const DEFAULT_RECV_TIMEOUT_MS = 5000n;
25
+ export function publish(topic, payload) {
26
+ callHost(`ipc.publish(${quote(topic)})`, () => hostPublish(topic, payload));
27
+ }
28
+ export function publishJson(topic, payload) {
29
+ publish(topic, jsonify(`ipc.publishJson(${quote(topic)})`, payload));
30
+ }
31
+ /**
32
+ * Publish on behalf of a specific principal. Requires `uplink = true` in
33
+ * `Capsule.toml [capabilities]`; non-uplinks see `capability-denied`.
34
+ * Subscribers see the principal as `claimed(...)`, NOT `verified(...)` —
35
+ * downstream consumers MUST treat the principal as caller-input, not
36
+ * authenticated context.
37
+ */
38
+ export function publishAs(topic, payload, principal) {
39
+ callHost(`ipc.publishAs(${quote(topic)})`, () => hostPublishAs(topic, payload, principal));
40
+ }
41
+ export function publishJsonAs(topic, payload, principal) {
42
+ publishAs(topic, jsonify(`ipc.publishJsonAs(${quote(topic)})`, payload), principal);
43
+ }
44
+ /**
45
+ * Subscribe to an IPC topic pattern. Supports exact matches and trailing-suffix
46
+ * wildcards (`foo.bar.*`). Mid-segment wildcards are rejected by the host.
47
+ *
48
+ * The returned {@link Subscription} is a Resource handle. Use `using` for
49
+ * scope-bound cleanup, or call `.close()` explicitly:
50
+ *
51
+ * ```ts
52
+ * using sub = ipc.subscribe("foo.bar"); // disposed at scope exit
53
+ * for await (const msg of sub) { ... }
54
+ *
55
+ * const sub = ipc.subscribe("foo.bar"); // explicit close
56
+ * try { ... } finally { sub.close(); }
57
+ * ```
58
+ *
59
+ * Per-capsule cap: 128 subscriptions.
60
+ */
61
+ export function subscribe(topicPattern) {
62
+ const inner = callHost(`ipc.subscribe(${quote(topicPattern)})`, () => hostSubscribe(topicPattern));
63
+ return new Subscription(inner, topicPattern);
64
+ }
65
+ /**
66
+ * Pre-registered interceptor handles for run-loop capsules. Returns ONLY the
67
+ * calling capsule's own interceptors. Most authors don't call this — the
68
+ * `@interceptor` decorator + bridge handle dispatch.
69
+ */
70
+ export function runtimeInterceptors() {
71
+ const handles = callHost("ipc.runtimeInterceptors", () => hostGetInterceptorBindings());
72
+ return handles.map((h) => ({ handle: h.handleId, action: h.action, topic: h.topic }));
73
+ }
74
+ export class Subscription {
75
+ topic;
76
+ #inner;
77
+ constructor(inner, topic) {
78
+ this.#inner = inner;
79
+ this.topic = topic;
80
+ }
81
+ /** Non-blocking poll. Returns whatever's already queued. */
82
+ poll() {
83
+ const env = callHost(`ipc.poll(${quote(this.topic)})`, () => this.#requireInner().poll());
84
+ return envelopeToPollResult(env);
85
+ }
86
+ /** Blocking receive (timeout capped at 60s by the host). */
87
+ recv(timeoutMs = DEFAULT_RECV_TIMEOUT_MS) {
88
+ const env = callHost(`ipc.recv(${quote(this.topic)})`, () => this.#requireInner().recv(timeoutMs));
89
+ return envelopeToPollResult(env);
90
+ }
91
+ /**
92
+ * Idempotent — closing an already-closed subscription is a no-op.
93
+ * Equivalent to the resource Drop. Prefer `using` when the surrounding
94
+ * code can adopt explicit resource management.
95
+ */
96
+ close() {
97
+ if (this.#inner === undefined)
98
+ return;
99
+ const inner = this.#inner;
100
+ this.#inner = undefined;
101
+ try {
102
+ inner[Symbol.dispose]();
103
+ }
104
+ catch {
105
+ // Resource may already be released (interceptor-owned handles, etc.).
106
+ // close() is meant to be safe to call from any cleanup path.
107
+ }
108
+ }
109
+ [Symbol.dispose]() {
110
+ this.close();
111
+ }
112
+ /**
113
+ * AsyncIterable convenience. Loops calling `.recv()` and yielding each
114
+ * message. Stops when the subscription is closed. Drops `lagged`/`dropped`
115
+ * info — use `.poll()`/`.recv()` explicitly if you need to react to lag.
116
+ */
117
+ async *[Symbol.asyncIterator]() {
118
+ while (this.#inner !== undefined) {
119
+ const batch = this.recv();
120
+ for (const msg of batch.messages) {
121
+ yield msg;
122
+ }
123
+ }
124
+ }
125
+ #requireInner() {
126
+ if (this.#inner === undefined) {
127
+ throw SysError.api(`subscription on ${quote(this.topic)} is closed`);
128
+ }
129
+ return this.#inner;
130
+ }
131
+ }
132
+ /**
133
+ * Send a request on `requestTopic` and await a single response on a scoped
134
+ * reply topic. Mirrors `astrid_sdk::ipc::request_response` exactly.
135
+ *
136
+ * The helper:
137
+ * 1. Generates a v4 correlation ID.
138
+ * 2. Subscribes to `{responseNamespace}.{correlationId}` *before* publishing
139
+ * (so the response can never be missed in the race).
140
+ * 3. Injects the correlation ID into the request payload as a top-level
141
+ * `correlation_id` field.
142
+ * 4. Publishes the request.
143
+ * 5. Blocks up to `timeoutMs` for the response.
144
+ * 6. Unsubscribes (always, even on error).
145
+ * 7. Returns the parsed response payload as `Resp`.
146
+ *
147
+ * `request` must serialize to a JSON object. Primitives, arrays, strings,
148
+ * etc. are rejected synchronously with `SysError.api` because there is
149
+ * nowhere to put the correlation ID.
150
+ *
151
+ * `responseNamespace` should be the dotted topic prefix the responder
152
+ * publishes to, *without* the trailing correlation id segment. For example,
153
+ * if the responder publishes to
154
+ * `registry.v1.response.set_active_model.<corr_id>`, pass
155
+ * `"registry.v1.response.set_active_model"`.
156
+ *
157
+ * `timeoutMs` is capped at 60,000 ms by the host. A timeout throws
158
+ * `SysError.api` with `request_response: no reply within …`.
159
+ */
160
+ export function requestResponse(requestTopic, responseNamespace, request, timeoutMs) {
161
+ // Validate input before touching the host so bad calls never allocate a
162
+ // subscription handle.
163
+ if (typeof request !== "object" || request === null || Array.isArray(request)) {
164
+ throw SysError.api("request_response: request payload must serialize to a JSON object so the " +
165
+ "correlation_id can be injected");
166
+ }
167
+ const correlationId = randomUuidV4();
168
+ // Defensive copy + injection. Don't mutate the caller's object.
169
+ const augmented = {
170
+ ...request,
171
+ correlation_id: correlationId,
172
+ };
173
+ const payload = jsonify("requestResponse", augmented);
174
+ const replyTopic = `${responseNamespace}.${correlationId}`;
175
+ const sub = subscribe(replyTopic);
176
+ try {
177
+ publish(requestTopic, payload);
178
+ const timeoutBig = typeof timeoutMs === "bigint" ? timeoutMs : BigInt(Math.max(0, Math.floor(timeoutMs)));
179
+ const poll = sub.recv(timeoutBig);
180
+ const msg = poll.messages[0];
181
+ if (msg === undefined) {
182
+ throw SysError.api(`request_response: no reply on '${replyTopic}' within ${String(timeoutMs)}ms`);
183
+ }
184
+ try {
185
+ return JSON.parse(msg.payload);
186
+ }
187
+ catch (err) {
188
+ throw SysError.json(`request_response: failed to parse reply on '${replyTopic}': ${err.message}`, err);
189
+ }
190
+ }
191
+ finally {
192
+ sub.close();
193
+ }
194
+ }
195
+ function envelopeToPollResult(env) {
196
+ return {
197
+ messages: env.messages.map(makeIpcMessage),
198
+ dropped: env.dropped,
199
+ lagged: env.lagged,
200
+ };
201
+ }
202
+ function makeIpcMessage(m) {
203
+ return {
204
+ topic: m.topic,
205
+ payload: m.payload,
206
+ sourceId: m.sourceId,
207
+ principal: m.principal,
208
+ json() {
209
+ try {
210
+ return JSON.parse(m.payload);
211
+ }
212
+ catch (err) {
213
+ throw SysError.json(`IpcMessage.json() on topic ${quote(m.topic)}: ${err.message}`, err);
214
+ }
215
+ },
216
+ };
217
+ }
218
+ function jsonify(label, value) {
219
+ try {
220
+ return JSON.stringify(value);
221
+ }
222
+ catch (err) {
223
+ throw SysError.json(`${label}: ${err.message}`, err);
224
+ }
225
+ }
226
+ function quote(s) {
227
+ return `"${s.replace(/"/g, '\\"')}"`;
228
+ }
229
+ /**
230
+ * UUIDv4 generator. The Astrid host exposes `randomBytes`; pulling from
231
+ * `globalThis.crypto` would work too (StarlingMonkey exposes `crypto`), but
232
+ * routing through `sys::randomBytes` keeps the audit trail on the host side.
233
+ *
234
+ * Lazy-loaded to avoid a load-order cycle between ipc.ts and sys.ts.
235
+ */
236
+ function randomUuidV4() {
237
+ // 16 random bytes → format as 8-4-4-4-12 hex with version (0x40) and
238
+ // variant (0x80) bits set. RFC 4122 §4.4.
239
+ const bytes = getRandomBytes();
240
+ bytes[6] = ((bytes[6] ?? 0) & 0x0f) | 0x40;
241
+ bytes[8] = ((bytes[8] ?? 0) & 0x3f) | 0x80;
242
+ const hex = [];
243
+ for (let i = 0; i < 16; i++) {
244
+ hex.push((bytes[i] ?? 0).toString(16).padStart(2, "0"));
245
+ }
246
+ return (hex.slice(0, 4).join("") +
247
+ "-" +
248
+ hex.slice(4, 6).join("") +
249
+ "-" +
250
+ hex.slice(6, 8).join("") +
251
+ "-" +
252
+ hex.slice(8, 10).join("") +
253
+ "-" +
254
+ hex.slice(10, 16).join(""));
255
+ }
256
+ function getRandomBytes() {
257
+ // Audit-traced via sys::random-bytes rather than reaching for globalThis.crypto
258
+ // so every UUID generation flows through the kernel's principal-scoped audit.
259
+ return hostRandomBytes(16n);
260
+ }
261
+ //# sourceMappingURL=ipc.js.map