@parlor/client 0.0.0-stage → 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 (143) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +20 -2
  3. package/dist/action-client.d.ts +40 -0
  4. package/dist/action-client.d.ts.map +1 -0
  5. package/dist/action-client.js +83 -0
  6. package/dist/action-client.js.map +1 -0
  7. package/dist/index.d.ts +8 -0
  8. package/dist/index.d.ts.map +1 -0
  9. package/dist/index.js +6 -0
  10. package/dist/index.js.map +1 -0
  11. package/dist/plugin-client.d.ts +11 -0
  12. package/dist/plugin-client.d.ts.map +1 -0
  13. package/dist/plugin-client.js +14 -0
  14. package/dist/plugin-client.js.map +1 -0
  15. package/dist/query-keys.d.ts +3 -0
  16. package/dist/query-keys.d.ts.map +1 -0
  17. package/dist/query-keys.js +5 -0
  18. package/dist/query-keys.js.map +1 -0
  19. package/dist/react/agent-ui/activity-state.d.ts +20 -0
  20. package/dist/react/agent-ui/activity-state.d.ts.map +1 -0
  21. package/dist/react/agent-ui/activity-state.js +14 -0
  22. package/dist/react/agent-ui/activity-state.js.map +1 -0
  23. package/dist/react/agent-ui/chat-activity.d.ts +13 -0
  24. package/dist/react/agent-ui/chat-activity.d.ts.map +1 -0
  25. package/dist/react/agent-ui/chat-activity.js +26 -0
  26. package/dist/react/agent-ui/chat-activity.js.map +1 -0
  27. package/dist/react/agent-ui/chat-confirm.d.ts +28 -0
  28. package/dist/react/agent-ui/chat-confirm.d.ts.map +1 -0
  29. package/dist/react/agent-ui/chat-confirm.js +140 -0
  30. package/dist/react/agent-ui/chat-confirm.js.map +1 -0
  31. package/dist/react/agent-ui/chat.d.ts +7 -0
  32. package/dist/react/agent-ui/chat.d.ts.map +1 -0
  33. package/dist/react/agent-ui/chat.js +7 -0
  34. package/dist/react/agent-ui/chat.js.map +1 -0
  35. package/dist/react/agent-ui/dev.d.ts +12 -0
  36. package/dist/react/agent-ui/dev.d.ts.map +1 -0
  37. package/dist/react/agent-ui/dev.js +80 -0
  38. package/dist/react/agent-ui/dev.js.map +1 -0
  39. package/dist/react/agent-ui/runtime.d.ts +12 -0
  40. package/dist/react/agent-ui/runtime.d.ts.map +1 -0
  41. package/dist/react/agent-ui/runtime.js +50 -0
  42. package/dist/react/agent-ui/runtime.js.map +1 -0
  43. package/dist/react/agent-ui/use-agent-activity.d.ts +3 -0
  44. package/dist/react/agent-ui/use-agent-activity.d.ts.map +1 -0
  45. package/dist/react/agent-ui/use-agent-activity.js +7 -0
  46. package/dist/react/agent-ui/use-agent-activity.js.map +1 -0
  47. package/dist/react/agent-ui/use-agent-confirmations.d.ts +8 -0
  48. package/dist/react/agent-ui/use-agent-confirmations.d.ts.map +1 -0
  49. package/dist/react/agent-ui/use-agent-confirmations.js +12 -0
  50. package/dist/react/agent-ui/use-agent-confirmations.js.map +1 -0
  51. package/dist/react/agent-ui/use-agent-view.d.ts +11 -0
  52. package/dist/react/agent-ui/use-agent-view.d.ts.map +1 -0
  53. package/dist/react/agent-ui/use-agent-view.js +25 -0
  54. package/dist/react/agent-ui/use-agent-view.js.map +1 -0
  55. package/dist/react/chat/ask-fields.d.ts +13 -0
  56. package/dist/react/chat/ask-fields.d.ts.map +1 -0
  57. package/dist/react/chat/ask-fields.js +46 -0
  58. package/dist/react/chat/ask-fields.js.map +1 -0
  59. package/dist/react/chat/chat-ask.d.ts +32 -0
  60. package/dist/react/chat/chat-ask.d.ts.map +1 -0
  61. package/dist/react/chat/chat-ask.js +69 -0
  62. package/dist/react/chat/chat-ask.js.map +1 -0
  63. package/dist/react/chat/chat-composer.d.ts +18 -0
  64. package/dist/react/chat/chat-composer.d.ts.map +1 -0
  65. package/dist/react/chat/chat-composer.js +81 -0
  66. package/dist/react/chat/chat-composer.js.map +1 -0
  67. package/dist/react/chat/chat-root.d.ts +14 -0
  68. package/dist/react/chat/chat-root.d.ts.map +1 -0
  69. package/dist/react/chat/chat-root.js +21 -0
  70. package/dist/react/chat/chat-root.js.map +1 -0
  71. package/dist/react/chat/chat-thread.d.ts +18 -0
  72. package/dist/react/chat/chat-thread.d.ts.map +1 -0
  73. package/dist/react/chat/chat-thread.js +69 -0
  74. package/dist/react/chat/chat-thread.js.map +1 -0
  75. package/dist/react/chat/context.d.ts +6 -0
  76. package/dist/react/chat/context.d.ts.map +1 -0
  77. package/dist/react/chat/context.js +24 -0
  78. package/dist/react/chat/context.js.map +1 -0
  79. package/dist/react/chat/create.d.ts +15 -0
  80. package/dist/react/chat/create.d.ts.map +1 -0
  81. package/dist/react/chat/create.js +23 -0
  82. package/dist/react/chat/create.js.map +1 -0
  83. package/dist/react/chat/open-turns.d.ts +10 -0
  84. package/dist/react/chat/open-turns.d.ts.map +1 -0
  85. package/dist/react/chat/open-turns.js +60 -0
  86. package/dist/react/chat/open-turns.js.map +1 -0
  87. package/dist/react/chat/runtime.d.ts +156 -0
  88. package/dist/react/chat/runtime.d.ts.map +1 -0
  89. package/dist/react/chat/runtime.js +928 -0
  90. package/dist/react/chat/runtime.js.map +1 -0
  91. package/dist/react/chat/use-chat.d.ts +4 -0
  92. package/dist/react/chat/use-chat.d.ts.map +1 -0
  93. package/dist/react/chat/use-chat.js +22 -0
  94. package/dist/react/chat/use-chat.js.map +1 -0
  95. package/dist/react/chat/use-device-setup.d.ts +9 -0
  96. package/dist/react/chat/use-device-setup.d.ts.map +1 -0
  97. package/dist/react/chat/use-device-setup.js +17 -0
  98. package/dist/react/chat/use-device-setup.js.map +1 -0
  99. package/dist/react/hooks.d.ts +11 -0
  100. package/dist/react/hooks.d.ts.map +1 -0
  101. package/dist/react/hooks.js +32 -0
  102. package/dist/react/hooks.js.map +1 -0
  103. package/dist/react/index.d.ts +20 -0
  104. package/dist/react/index.d.ts.map +1 -0
  105. package/dist/react/index.js +13 -0
  106. package/dist/react/index.js.map +1 -0
  107. package/dist/react/provider.d.ts +38 -0
  108. package/dist/react/provider.d.ts.map +1 -0
  109. package/dist/react/provider.js +126 -0
  110. package/dist/react/provider.js.map +1 -0
  111. package/dist/react/retry.d.ts +5 -0
  112. package/dist/react/retry.d.ts.map +1 -0
  113. package/dist/react/retry.js +22 -0
  114. package/dist/react/retry.js.map +1 -0
  115. package/dist/react/sync-bridge.d.ts +25 -0
  116. package/dist/react/sync-bridge.d.ts.map +1 -0
  117. package/dist/react/sync-bridge.js +65 -0
  118. package/dist/react/sync-bridge.js.map +1 -0
  119. package/dist/react/sync.d.ts +12 -0
  120. package/dist/react/sync.d.ts.map +1 -0
  121. package/dist/react/sync.js +36 -0
  122. package/dist/react/sync.js.map +1 -0
  123. package/dist/react/use-capability.d.ts +6 -0
  124. package/dist/react/use-capability.d.ts.map +1 -0
  125. package/dist/react/use-capability.js +21 -0
  126. package/dist/react/use-capability.js.map +1 -0
  127. package/dist/react/use-devices.d.ts +34 -0
  128. package/dist/react/use-devices.d.ts.map +1 -0
  129. package/dist/react/use-devices.js +93 -0
  130. package/dist/react/use-devices.js.map +1 -0
  131. package/dist/react/use-link-device.d.ts +42 -0
  132. package/dist/react/use-link-device.d.ts.map +1 -0
  133. package/dist/react/use-link-device.js +58 -0
  134. package/dist/react/use-link-device.js.map +1 -0
  135. package/dist/register.d.ts +7 -0
  136. package/dist/register.d.ts.map +1 -0
  137. package/dist/register.js +2 -0
  138. package/dist/register.js.map +1 -0
  139. package/dist/session.d.ts +121 -0
  140. package/dist/session.d.ts.map +1 -0
  141. package/dist/session.js +5 -0
  142. package/dist/session.js.map +1 -0
  143. package/package.json +62 -3
@@ -0,0 +1,36 @@
1
+ import { tagsOverlap } from "@parlor/core";
2
+ import { ACTION_QUERY_PREFIX } from "../query-keys.js";
3
+ export class ReadTagRegistry {
4
+ #tags = new Map();
5
+ attach(queryClient) {
6
+ return queryClient.getQueryCache().subscribe((event) => {
7
+ if (event.type === "removed")
8
+ this.#tags.delete(event.query.queryHash);
9
+ });
10
+ }
11
+ record(queryHash, tags) {
12
+ this.#tags.set(queryHash, tags);
13
+ }
14
+ tagsFor(queryHash) {
15
+ return this.#tags.get(queryHash);
16
+ }
17
+ affected(events) {
18
+ const hashes = new Set();
19
+ for (const [hash, reads] of this.#tags) {
20
+ if (reads.some((read) => events.some((e) => e.tags.some((write) => tagsOverlap(read, write))))) {
21
+ hashes.add(hash);
22
+ }
23
+ }
24
+ return hashes;
25
+ }
26
+ }
27
+ export function invalidateForEvents(queryClient, registry, events) {
28
+ const hashes = registry.affected(events);
29
+ if (hashes.size === 0)
30
+ return Promise.resolve();
31
+ return queryClient.invalidateQueries({
32
+ queryKey: ACTION_QUERY_PREFIX,
33
+ predicate: (query) => hashes.has(query.queryHash),
34
+ });
35
+ }
36
+ //# sourceMappingURL=sync.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync.js","sourceRoot":"","sources":["../../src/react/sync.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAI3C,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAEvD,MAAM,OAAO,eAAe;IACjB,KAAK,GAAG,IAAI,GAAG,EAA0B,CAAC;IAEnD,MAAM,CAAC,WAAwB;QAC7B,OAAO,WAAW,CAAC,aAAa,EAAE,CAAC,SAAS,CAAC,CAAC,KAAK,EAAE,EAAE;YACrD,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS;gBAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;QACzE,CAAC,CAAC,CAAC;IACL,CAAC;IAED,MAAM,CAAC,SAAiB,EAAE,IAAoB;QAC5C,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;IAClC,CAAC;IAED,OAAO,CAAC,SAAiB;QACvB,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IACnC,CAAC;IAED,QAAQ,CAAC,MAA4B;QACnC,MAAM,MAAM,GAAG,IAAI,GAAG,EAAU,CAAC;QACjC,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YACvC,IACE,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAClB,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,WAAW,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,CACrE,EACD,CAAC;gBACD,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YACnB,CAAC;QACH,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;CACF;AAED,MAAM,UAAU,mBAAmB,CACjC,WAAwB,EACxB,QAAyB,EACzB,MAA4B;IAE5B,MAAM,MAAM,GAAG,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IACzC,IAAI,MAAM,CAAC,IAAI,KAAK,CAAC;QAAE,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;IAChD,OAAO,WAAW,CAAC,iBAAiB,CAAC;QACnC,QAAQ,EAAE,mBAAmB;QAC7B,SAAS,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC;KAClD,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,6 @@
1
+ import { type CapabilityDefinition, type CapabilityHandle } from "@parlor/capabilities";
2
+ export type CapabilityState<T> = CapabilityHandle<T> & {
3
+ readonly resolving?: boolean;
4
+ };
5
+ export declare function useCapability<T>(definition: CapabilityDefinition<T>): CapabilityState<T>;
6
+ //# sourceMappingURL=use-capability.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-capability.d.ts","sourceRoot":"","sources":["../../src/react/use-capability.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,oBAAoB,EACzB,KAAK,gBAAgB,EAEtB,MAAM,sBAAsB,CAAC;AAK9B,MAAM,MAAM,eAAe,CAAC,CAAC,IAAI,gBAAgB,CAAC,CAAC,CAAC,GAAG;IAAE,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC;AAExF,wBAAgB,aAAa,CAAC,CAAC,EAC7B,UAAU,EAAE,oBAAoB,CAAC,CAAC,CAAC,GAClC,eAAe,CAAC,CAAC,CAAC,CAepB"}
@@ -0,0 +1,21 @@
1
+ import { resolveCapability, } from "@parlor/capabilities";
2
+ import { useEffect, useState } from "react";
3
+ const RESOLVING = { available: false, reason: "resolving" };
4
+ export function useCapability(definition) {
5
+ const [state, setState] = useState({
6
+ ...RESOLVING,
7
+ resolving: true,
8
+ });
9
+ useEffect(() => {
10
+ let active = true;
11
+ void resolveCapability(definition).then((handle) => {
12
+ if (active)
13
+ setState(handle);
14
+ });
15
+ return () => {
16
+ active = false;
17
+ };
18
+ }, [definition]);
19
+ return state;
20
+ }
21
+ //# sourceMappingURL=use-capability.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-capability.js","sourceRoot":"","sources":["../../src/react/use-capability.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,iBAAiB,GAClB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAE5C,MAAM,SAAS,GAAG,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,EAAW,CAAC;AAIrE,MAAM,UAAU,aAAa,CAC3B,UAAmC;IAEnC,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAqB;QACrD,GAAG,SAAS;QACZ,SAAS,EAAE,IAAI;KAChB,CAAC,CAAC;IACH,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,MAAM,GAAG,IAAI,CAAC;QAClB,KAAK,iBAAiB,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE;YACjD,IAAI,MAAM;gBAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;QAC/B,CAAC,CAAC,CAAC;QACH,OAAO,GAAG,EAAE;YACV,MAAM,GAAG,KAAK,CAAC;QACjB,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC;IACjB,OAAO,KAAK,CAAC;AACf,CAAC"}
@@ -0,0 +1,34 @@
1
+ import type { AccountDevice } from "../session.js";
2
+ /** What removing a device is doing: confirming, or showing the command a device without Face ID or Touch ID needs. */
3
+ export type RemoveDeviceState = {
4
+ readonly step: "idle";
5
+ } | {
6
+ readonly step: "removing";
7
+ readonly id: string;
8
+ } | {
9
+ readonly step: "on-computer";
10
+ readonly id: string;
11
+ readonly command: string;
12
+ } | {
13
+ readonly step: "error";
14
+ readonly id: string;
15
+ readonly message: string;
16
+ };
17
+ /** Devices another device linked since `before` was read; this device's own links are not news here. */
18
+ export declare function newlyLinked(before: readonly AccountDevice[], after: readonly AccountDevice[]): AccountDevice[];
19
+ /**
20
+ * The account's devices, read again whenever one is added, linked or removed; the ones another
21
+ * device linked while this page was open, to tell the user; and removing one with Face ID or
22
+ * Touch ID.
23
+ */
24
+ export declare function useDevices(): {
25
+ readonly available: boolean;
26
+ readonly devices: readonly AccountDevice[] | undefined;
27
+ readonly linked: readonly AccountDevice[];
28
+ readonly removal: RemoveDeviceState;
29
+ /** Whether it was removed. */
30
+ remove(id: string): Promise<boolean>;
31
+ dismiss(id: string): void;
32
+ reset(): void;
33
+ };
34
+ //# sourceMappingURL=use-devices.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-devices.d.ts","sourceRoot":"","sources":["../../src/react/use-devices.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAKnD,sHAAsH;AACtH,MAAM,MAAM,iBAAiB,GACzB;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACzB;IAAE,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAAC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;CAAE,GAClD;IAAE,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;IAAC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAC/E;IAAE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAI9E,wGAAwG;AACxG,wBAAgB,WAAW,CACzB,MAAM,EAAE,SAAS,aAAa,EAAE,EAChC,KAAK,EAAE,SAAS,aAAa,EAAE,GAC9B,aAAa,EAAE,CAUjB;AAED;;;;GAIG;AACH,wBAAgB,UAAU,IAAI;IAC5B,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,OAAO,EAAE,SAAS,aAAa,EAAE,GAAG,SAAS,CAAC;IACvD,QAAQ,CAAC,MAAM,EAAE,SAAS,aAAa,EAAE,CAAC;IAC1C,QAAQ,CAAC,OAAO,EAAE,iBAAiB,CAAC;IACpC,8BAA8B;IAC9B,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACrC,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,KAAK,IAAI,IAAI,CAAC;CACf,CAuFA"}
@@ -0,0 +1,93 @@
1
+ import { tagsOverlap } from "@parlor/core";
2
+ import { useCallback, useEffect, useMemo, useRef, useState } from "react";
3
+ import { appOrigin } from "../action-client.js";
4
+ import { useFramework } from "./provider.js";
5
+ const DEVICES_TAG = "parlor_auth_devices";
6
+ const IDLE = { step: "idle" };
7
+ /** Devices another device linked since `before` was read; this device's own links are not news here. */
8
+ export function newlyLinked(before, after) {
9
+ const self = after.find((device) => device.current)?.id;
10
+ const was = new Map(before.map((device) => [device.id, device.vouched]));
11
+ return after.filter((device) => device.vouched &&
12
+ was.get(device.id) !== true &&
13
+ !device.current &&
14
+ device.linkedBy !== self);
15
+ }
16
+ /**
17
+ * The account's devices, read again whenever one is added, linked or removed; the ones another
18
+ * device linked while this page was open, to tell the user; and removing one with Face ID or
19
+ * Touch ID.
20
+ */
21
+ export function useDevices() {
22
+ const { auth, sync } = useFramework();
23
+ const [devices, setDevices] = useState(undefined);
24
+ const [linked, setLinked] = useState([]);
25
+ const [removal, setRemoval] = useState(IDLE);
26
+ const last = useRef(undefined);
27
+ const reload = useRef(async () => undefined);
28
+ const available = Boolean(auth?.listDevices && auth.removeDevice);
29
+ useEffect(() => {
30
+ if (!auth?.listDevices)
31
+ return;
32
+ let live = true;
33
+ const load = () => auth.listDevices().then((listed) => {
34
+ if (!live)
35
+ return;
36
+ const before = last.current;
37
+ last.current = listed;
38
+ setDevices(listed);
39
+ const fresh = before ? newlyLinked(before, listed) : [];
40
+ const present = new Set(listed.map((device) => device.id));
41
+ setLinked((shown) => [
42
+ ...shown.filter((device) => present.has(device.id)),
43
+ ...fresh.filter((device) => !shown.some((entry) => entry.id === device.id)),
44
+ ]);
45
+ }, () => undefined);
46
+ reload.current = load;
47
+ void load();
48
+ const off = sync.onEvents((events) => {
49
+ if (events.some((event) => event.tags.some((tag) => tagsOverlap(tag, [DEVICES_TAG])))) {
50
+ void load();
51
+ }
52
+ });
53
+ return () => {
54
+ live = false;
55
+ off();
56
+ };
57
+ }, [auth, sync]);
58
+ const remove = useCallback(async (id) => {
59
+ if (!auth?.removeDevice)
60
+ return false;
61
+ setRemoval({ step: "removing", id });
62
+ try {
63
+ await auth.removeDevice(id);
64
+ setRemoval(IDLE);
65
+ await reload.current();
66
+ return true;
67
+ }
68
+ catch (error) {
69
+ if (error instanceof Error && error.name === "LinkOnComputer") {
70
+ setRemoval({
71
+ step: "on-computer",
72
+ id,
73
+ command: `npx @parlor/agent-host devices ${appOrigin()} --remove ${id}`,
74
+ });
75
+ return false;
76
+ }
77
+ setRemoval({
78
+ step: "error",
79
+ id,
80
+ message: error instanceof Error && error.name === "NotAllowedError"
81
+ ? "Face ID or Touch ID was cancelled, so nothing was removed."
82
+ : error instanceof Error && error.message
83
+ ? error.message
84
+ : "That did not work. Try again.",
85
+ });
86
+ return false;
87
+ }
88
+ }, [auth]);
89
+ const reset = useCallback(() => setRemoval(IDLE), []);
90
+ const dismiss = useCallback((id) => setLinked((shown) => shown.filter((device) => device.id !== id)), []);
91
+ return useMemo(() => ({ available, devices, linked, removal, remove, dismiss, reset }), [available, devices, linked, removal, remove, dismiss, reset]);
92
+ }
93
+ //# sourceMappingURL=use-devices.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-devices.js","sourceRoot":"","sources":["../../src/react/use-devices.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Linking another device from this one: `check` the code it shows, `confirm` with Face ID or
3
+ * Touch ID. A device without a presence key gets the command that links from the computer.
4
+ */
5
+ export type LinkDeviceState = {
6
+ readonly step: "idle";
7
+ } | {
8
+ readonly step: "checking";
9
+ } | {
10
+ readonly step: "confirm";
11
+ readonly device: {
12
+ readonly name: string;
13
+ readonly platform: string;
14
+ };
15
+ } | {
16
+ readonly step: "linking";
17
+ } | {
18
+ readonly step: "linked";
19
+ readonly name: string;
20
+ } | {
21
+ readonly step: "on-computer";
22
+ readonly device: {
23
+ readonly name: string;
24
+ readonly platform: string;
25
+ };
26
+ readonly command: string;
27
+ } | {
28
+ readonly step: "error";
29
+ readonly message: string;
30
+ };
31
+ export declare function useLinkDevice(): {
32
+ readonly available: boolean;
33
+ readonly state: LinkDeviceState;
34
+ /** A typed code, or the device id and commitment a scanned QR carried. */
35
+ check(from: string | {
36
+ readonly deviceId: string;
37
+ readonly commitment: string;
38
+ }): Promise<void>;
39
+ confirm(): Promise<void>;
40
+ reset(): void;
41
+ };
42
+ //# sourceMappingURL=use-link-device.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-link-device.d.ts","sourceRoot":"","sources":["../../src/react/use-link-device.ts"],"names":[],"mappings":"AAMA;;;GAGG;AACH,MAAM,MAAM,eAAe,GACvB;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACzB;IAAE,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAA;CAAE,GAC7B;IACE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IACzB,QAAQ,CAAC,MAAM,EAAE;QAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;CACvE,GACD;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAA;CAAE,GAC5B;IAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAClD;IACE,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;IAC7B,QAAQ,CAAC,MAAM,EAAE;QAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;IACtE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B,GACD;IAAE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAazD,wBAAgB,aAAa,IAAI;IAC/B,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,KAAK,EAAE,eAAe,CAAC;IAChC,0EAA0E;IAC1E,KAAK,CACH,IAAI,EAAE,MAAM,GAAG;QAAE,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;KAAE,GACxE,OAAO,CAAC,IAAI,CAAC,CAAC;IACjB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACzB,KAAK,IAAI,IAAI,CAAC;CACf,CAoDA"}
@@ -0,0 +1,58 @@
1
+ import { useCallback, useMemo, useRef, useState } from "react";
2
+ import { appOrigin } from "../action-client.js";
3
+ import { useFramework } from "./provider.js";
4
+ const IDLE = { step: "idle" };
5
+ const messageOf = (error) => {
6
+ if (error instanceof Error && error.name === "NotAllowedError") {
7
+ return "Face ID or Touch ID was cancelled, so nothing was linked.";
8
+ }
9
+ return error instanceof Error && error.message
10
+ ? error.message
11
+ : "That did not work. Try again.";
12
+ };
13
+ export function useLinkDevice() {
14
+ const { auth } = useFramework();
15
+ const [state, setState] = useState(IDLE);
16
+ const pending = useRef(undefined);
17
+ const available = Boolean(auth?.resolveLink && auth.vouch && auth.canVouch);
18
+ const check = useCallback(async (from) => {
19
+ if (!auth?.resolveLink || !auth.canVouch)
20
+ return;
21
+ setState({ step: "checking" });
22
+ try {
23
+ const link = await auth.resolveLink(from);
24
+ pending.current = link;
25
+ const device = { name: link.name, platform: link.platform };
26
+ setState((await auth.canVouch())
27
+ ? { step: "confirm", device }
28
+ : {
29
+ step: "on-computer",
30
+ device,
31
+ command: `npx @parlor/agent-host link ${appOrigin()} ${link.code}`,
32
+ });
33
+ }
34
+ catch (error) {
35
+ setState({ step: "error", message: messageOf(error) });
36
+ }
37
+ }, [auth]);
38
+ const confirm = useCallback(async () => {
39
+ const link = pending.current;
40
+ if (!auth?.vouch || !link)
41
+ return;
42
+ setState({ step: "linking" });
43
+ try {
44
+ await auth.vouch(link);
45
+ pending.current = undefined;
46
+ setState({ step: "linked", name: link.name });
47
+ }
48
+ catch (error) {
49
+ setState({ step: "error", message: messageOf(error) });
50
+ }
51
+ }, [auth]);
52
+ const reset = useCallback(() => {
53
+ pending.current = undefined;
54
+ setState(IDLE);
55
+ }, []);
56
+ return useMemo(() => ({ available, state, check, confirm, reset }), [available, state, check, confirm, reset]);
57
+ }
58
+ //# sourceMappingURL=use-link-device.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-link-device.js","sourceRoot":"","sources":["../../src/react/use-link-device.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import type { ActionMap } from "@parlor/core";
2
+ export interface Register {
3
+ }
4
+ export type RegisteredActions = Register extends {
5
+ actions: infer A extends ActionMap;
6
+ } ? A : ActionMap;
7
+ //# sourceMappingURL=register.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"register.d.ts","sourceRoot":"","sources":["../src/register.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAE9C,MAAM,WAAW,QAAQ;CAAG;AAE5B,MAAM,MAAM,iBAAiB,GAAG,QAAQ,SAAS;IAAE,OAAO,EAAE,MAAM,CAAC,SAAS,SAAS,CAAA;CAAE,GACnF,CAAC,GACD,SAAS,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=register.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"register.js","sourceRoot":"","sources":["../src/register.ts"],"names":[],"mappings":""}
@@ -0,0 +1,121 @@
1
+ import type { HostPairing, PairingDevice } from "@parlor/capabilities";
2
+ import type { AnswerToSign, ItemSignature, PromptToSign } from "@parlor/chat";
3
+ import type { DeviceId } from "@parlor/core";
4
+ export interface SessionUser {
5
+ readonly id: string;
6
+ readonly name: string;
7
+ readonly email: string;
8
+ }
9
+ /** `anonymous`: the server signs nobody in, so everyone uses the app without an account. */
10
+ export type SessionSnapshot = {
11
+ readonly status: "loading";
12
+ } | {
13
+ readonly status: "anonymous";
14
+ } | {
15
+ readonly status: "signed-out";
16
+ } | {
17
+ readonly status: "signed-in";
18
+ readonly user: SessionUser;
19
+ };
20
+ /**
21
+ * Who is signed in on this device, as the app's auth client sees it. `current` returns the
22
+ * same object until the session changes.
23
+ */
24
+ export interface SessionSource {
25
+ current(): SessionSnapshot;
26
+ subscribe(listener: () => void): () => void;
27
+ }
28
+ /** This device's signing identity, as the chat needs it. */
29
+ export interface SessionDevice {
30
+ readonly id: DeviceId;
31
+ /** The public half of its keys, as the account registered them. */
32
+ readonly keys: PairingDevice;
33
+ /** With `presence`, the platform asks for Touch ID, Face ID or a passkey first. */
34
+ signPrompt(prompt: PromptToSign, options?: {
35
+ readonly presence?: boolean;
36
+ }): Promise<ItemSignature>;
37
+ /** With `presence`, the platform asks for Touch ID, Face ID or a passkey first. */
38
+ signAnswer(answer: AnswerToSign, options: {
39
+ readonly presence: boolean;
40
+ }): Promise<ItemSignature>;
41
+ }
42
+ export interface DeviceSource {
43
+ /**
44
+ * Enrolls this device with the account on first use; undefined where it cannot sign.
45
+ * `presence: false` enrolls it without a presence key. Rejects with the capability's
46
+ * `PresenceSetupCancelled` when the user dismisses the passkey prompt.
47
+ */
48
+ device(options?: {
49
+ readonly presence?: boolean;
50
+ }): Promise<SessionDevice | undefined>;
51
+ /** `needed` while the first `device()` would ask the user to create a passkey. */
52
+ deviceSetup?(): Promise<"needed" | "ready">;
53
+ }
54
+ export interface HostAuthorizer {
55
+ /** For pairing the host on this computer: a code for it, approved by this session. */
56
+ authorizeHost(pairing: HostPairing): Promise<string>;
57
+ }
58
+ /** A device waiting to be linked, its keys checked against the code it shows. */
59
+ export interface PendingLink {
60
+ readonly id: string;
61
+ readonly name: string;
62
+ readonly platform: string;
63
+ readonly commitment: string;
64
+ /** The short code the device shows, for `parlor-host link` on the computer. */
65
+ readonly code: string;
66
+ }
67
+ /** One of the account's devices, as the devices list shows it. */
68
+ export interface AccountDevice {
69
+ readonly id: string;
70
+ readonly name: string;
71
+ readonly platform: string;
72
+ /** This device. */
73
+ readonly current: boolean;
74
+ readonly createdAt: string;
75
+ readonly vouched: boolean;
76
+ readonly linking: boolean;
77
+ /** The device whose vouch linked it last. */
78
+ readonly linkedBy?: string | undefined;
79
+ }
80
+ /** Thrown by `vouch` on a device with no presence key: the computer itself links it then. */
81
+ export declare class LinkOnComputer extends Error {
82
+ readonly name = "LinkOnComputer";
83
+ }
84
+ /** Linking devices: a new one shows a code, a linked one checks it and vouches for it. */
85
+ export interface DeviceLinker {
86
+ /** Never prompts: a device not created yet reads as none. */
87
+ linkState(): Promise<{
88
+ readonly deviceId?: string | undefined;
89
+ readonly vouched: boolean;
90
+ /** It approved `connect` on the computer, so its first prompt links it. */
91
+ readonly pairing: boolean;
92
+ }>;
93
+ /** Enrolls this device, with Face ID or Touch ID unless `presence` is false, and shows its code. */
94
+ startLink(options?: {
95
+ readonly presence?: boolean;
96
+ }): Promise<{
97
+ readonly deviceId: string;
98
+ readonly code: string;
99
+ /** The whole hash the code is the start of; the QR carries it. */
100
+ readonly commitment: string;
101
+ readonly expiresAt: string;
102
+ }>;
103
+ /**
104
+ * The device showing `code`, or the one whose QR named its id and whole commitment; throws
105
+ * when the keys the app returns do not match.
106
+ */
107
+ resolveLink(from: string | {
108
+ readonly deviceId: string;
109
+ readonly commitment: string;
110
+ }): Promise<PendingLink>;
111
+ /** Vouches with this device's presence key; throws `LinkOnComputer` when it has none. */
112
+ vouch(link: PendingLink): Promise<void>;
113
+ /** Whether this device has a presence key to vouch with; never prompts. */
114
+ canVouch(): Promise<boolean>;
115
+ listDevices(): Promise<readonly AccountDevice[]>;
116
+ /** Removes a device, confirmed with Face ID or Touch ID; throws `LinkOnComputer` without them. */
117
+ removeDevice(id: string): Promise<void>;
118
+ }
119
+ /** What `FrameworkProvider` takes as `auth`; signing, host pairing and linking are optional. */
120
+ export type FrameworkAuth = SessionSource & Partial<DeviceSource & HostAuthorizer & DeviceLinker>;
121
+ //# sourceMappingURL=session.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /** Thrown by `vouch` on a device with no presence key: the computer itself links it then. */
2
+ export class LinkOnComputer extends Error {
3
+ name = "LinkOnComputer";
4
+ }
5
+ //# sourceMappingURL=session.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session.js","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":"AAmFA,6FAA6F;AAC7F,MAAM,OAAO,cAAe,SAAQ,KAAK;IACrB,IAAI,GAAG,gBAAgB,CAAC;CAC3C"}
package/package.json CHANGED
@@ -1,6 +1,65 @@
1
1
  {
2
2
  "name": "@parlor/client",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
3
+ "version": "0.1.0",
4
+ "homepage": "https://cychien.github.io/parlor",
5
+ "bugs": "https://github.com/cychien/parlor/issues",
6
+ "license": "MIT",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git+https://github.com/cychien/parlor.git",
10
+ "directory": "packages/client"
11
+ },
12
+ "files": [
13
+ "dist"
14
+ ],
15
+ "type": "module",
16
+ "sideEffects": false,
17
+ "exports": {
18
+ ".": {
19
+ "types": "./dist/index.d.ts",
20
+ "import": "./dist/index.js"
21
+ },
22
+ "./react": {
23
+ "types": "./dist/react/index.d.ts",
24
+ "import": "./dist/react/index.js"
25
+ }
26
+ },
27
+ "dependencies": {
28
+ "@parlor/chat": "0.1.0",
29
+ "@parlor/capabilities": "0.1.0",
30
+ "@parlor/agent-ui": "0.1.0",
31
+ "@parlor/core": "0.1.0",
32
+ "@parlor/sync": "0.1.0"
33
+ },
34
+ "devDependencies": {
35
+ "@tanstack/react-query": "^5.104.1",
36
+ "@tanstack/react-router": "^1.170.45",
37
+ "@testing-library/react": "^16.3.3",
38
+ "@types/node": "^24.14.0",
39
+ "@types/react": "^19.3.0",
40
+ "@types/react-dom": "^19.3.0",
41
+ "happy-dom": "^20.14.5",
42
+ "react": "^19.3.0",
43
+ "react-dom": "^19.3.0",
44
+ "typescript": "^7.0.2",
45
+ "vite": "^8.3.5",
46
+ "vitest": "^5.0.3",
47
+ "zod": "^4.6.5"
48
+ },
49
+ "peerDependencies": {
50
+ "@tanstack/react-query": ">=5",
51
+ "@tanstack/react-router": ">=1.170",
52
+ "react": ">=19",
53
+ "react-dom": ">=19"
54
+ },
55
+ "peerDependenciesMeta": {
56
+ "@tanstack/react-router": {
57
+ "optional": true
58
+ }
59
+ },
60
+ "scripts": {
61
+ "build": "tsc -p tsconfig.json",
62
+ "typecheck": "tsc -p tsconfig.json --noEmit",
63
+ "test": "vitest run"
64
+ }
6
65
  }