@byokit/ui 0.0.0-stage → 0.7.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.
@@ -0,0 +1,62 @@
1
+ import { type Approval, type ApprovalsSource, type FollowOptions } from './approvals.ts';
2
+ import { type HerdrSource } from './herdr.ts';
3
+ import { type RunSource, type RunWordsOptions } from './run.ts';
4
+ /** One run at a time: `send(message)` streams the reply in; `words` says how a failed run ended. */
5
+ export declare function useRun(source: RunSource, o: RunWordsOptions): {
6
+ send: (message: string, o?: {
7
+ sessionKey?: string;
8
+ }) => void;
9
+ stop: () => void;
10
+ phase: import("./run.ts").RunPhase;
11
+ text: string;
12
+ tools: {
13
+ name: string;
14
+ done: boolean;
15
+ }[];
16
+ tool: string | undefined;
17
+ words: string;
18
+ };
19
+ /** The approvals waiting for a yes, live; `decide` answers one (it leaves the list when the computer says so). */
20
+ export declare function useApprovals(source: ApprovalsSource & {
21
+ decide(id: string, d: {
22
+ allow: boolean;
23
+ reason?: string;
24
+ answer?: unknown;
25
+ }): Promise<void>;
26
+ }, o?: FollowOptions): {
27
+ approvals: Approval[];
28
+ decide: (id: string, d: {
29
+ allow: boolean;
30
+ reason?: string;
31
+ answer?: unknown;
32
+ }) => Promise<void>;
33
+ };
34
+ /** Herdr's agents grouped by where they run, live; `agent(paneId)` finds one. `ready` once the computer has said. */
35
+ export declare function useHerdrTree(source: HerdrSource): {
36
+ ready: boolean;
37
+ tree: import("./herdr.ts").HerdrTree | null;
38
+ groups: {
39
+ workspaceId: string;
40
+ tabId: string;
41
+ project: string;
42
+ where: string;
43
+ agents: import("./herdr.ts").AgentRow[];
44
+ }[];
45
+ agent: (paneId: string) => import("./herdr.ts").AgentRow | undefined;
46
+ };
47
+ /** The agents waiting for an answer, live; `answer` sends keys to one, with the revision it was asked at. */
48
+ export declare function useBlocked(source: HerdrSource & {
49
+ answer(paneId: string, keys: string[], revision: number): Promise<void>;
50
+ }): {
51
+ blocked: {
52
+ name: string;
53
+ paneId: string;
54
+ workspaceId: string;
55
+ tabId: string;
56
+ kind?: string;
57
+ revision: number;
58
+ prompt: string;
59
+ since: number;
60
+ }[];
61
+ answer: (paneId: string, keys: string[], revision: number) => Promise<void>;
62
+ };
@@ -0,0 +1,30 @@
1
+ // The runtime kits' view state as React hooks (React and React Native alike). Each hook reads one of the
2
+ // framework-free stores from `@byokit/ui/kits`; pass the same device client each render (e.g. from useMemo),
3
+ // since a new one starts following afresh.
4
+ import { useEffect, useMemo, useSyncExternalStore } from 'react';
5
+ import { approvalsStore } from "./approvals.js";
6
+ import { agentIn, blockedView, herdrStore, herdrTreeView } from "./herdr.js";
7
+ import { runStore, runView } from "./run.js";
8
+ const useStore = (s) => useSyncExternalStore(s.subscribe, s.get, s.get);
9
+ /** One run at a time: `send(message)` streams the reply in; `words` says how a failed run ended. */
10
+ export function useRun(source, o) {
11
+ const run = useMemo(() => runStore(source), [source]);
12
+ useEffect(() => run.stop, [run]); // leaving the screen stops listening
13
+ const state = useStore(run);
14
+ return { ...runView(state, o), send: run.send, stop: run.stop };
15
+ }
16
+ /** The approvals waiting for a yes, live; `decide` answers one (it leaves the list when the computer says so). */
17
+ export function useApprovals(source, o) {
18
+ const approvals = useStore(useMemo(() => approvalsStore(source, o), [source]));
19
+ return { approvals, decide: (id, d) => source.decide(id, d) };
20
+ }
21
+ /** Herdr's agents grouped by where they run, live; `agent(paneId)` finds one. `ready` once the computer has said. */
22
+ export function useHerdrTree(source) {
23
+ const { tree } = useStore(herdrStore(source));
24
+ return { ready: tree !== null, tree, groups: useMemo(() => herdrTreeView(tree), [tree]), agent: (paneId) => agentIn(tree, paneId) };
25
+ }
26
+ /** The agents waiting for an answer, live; `answer` sends keys to one, with the revision it was asked at. */
27
+ export function useBlocked(source) {
28
+ const state = useStore(herdrStore(source));
29
+ return { blocked: useMemo(() => blockedView(state), [state]), answer: (paneId, keys, revision) => source.answer(paneId, keys, revision) };
30
+ }
@@ -0,0 +1,32 @@
1
+ import { type AccountView, type Phase } from './phase.ts';
2
+ export type UseSignIn = {
3
+ /** This account, fresh from the back end. A rejection counts as the home computer being out of reach unless `offline` says otherwise. */
4
+ read: () => Promise<AccountView | null>;
5
+ /** Begin the sign-in on the back end. Absent when something else starts it (a CLI in a Herdr tab): the sheet
6
+ * then only watches, and nothing begins as it opens. */
7
+ start?: (body?: {
8
+ via?: 'code';
9
+ fresh?: boolean;
10
+ }) => Promise<unknown>;
11
+ cancel: () => Promise<unknown>;
12
+ offline?: (e: unknown) => boolean;
13
+ ms?: number;
14
+ /** Draw one phase regardless (design review, screenshots): nothing starts and nothing polls. */
15
+ pinned?: Phase | null;
16
+ };
17
+ export declare function useSignIn({ read, start, cancel, offline: isOffline, ms, pinned }: UseSignIn): {
18
+ phase: Phase;
19
+ account: AccountView | null;
20
+ code: string | undefined;
21
+ url: string | undefined;
22
+ /** Start again: `{ via: 'code' }` for "Having trouble?", `{ fresh: true }` to pick the account again. */
23
+ start: (body?: {
24
+ via?: "code";
25
+ fresh?: boolean;
26
+ }) => void;
27
+ cancel: () => void;
28
+ /** "Keep this one": a work plan the person chose to use anyway. */
29
+ keepWork: () => void;
30
+ /** Closing the sheet mid-way cancels the sign-in too. */
31
+ close: () => void;
32
+ };
@@ -0,0 +1,38 @@
1
+ // "Sign in with …" as a headless React hook: starts the sign-in as the sheet opens, polls the app's back end, and
2
+ // reports the phase to draw. The app keeps its own look (and its own tab for the provider's page); this is the
3
+ // behaviour every sign-in sheet shares.
4
+ import { useEffect, useState } from 'react';
5
+ import { phaseOf } from "./phase.js";
6
+ export function useSignIn({ read, start, cancel, offline: isOffline = () => true, ms = 1500, pinned }) {
7
+ const [value, setValue] = useState(null);
8
+ const [offline, setOffline] = useState(false);
9
+ const [cancelled, setCancelled] = useState(false);
10
+ const [keepWork, setKeepWork] = useState(false);
11
+ useEffect(() => {
12
+ if (pinned)
13
+ return;
14
+ let alive = true;
15
+ const pull = () => read().then((v) => { if (alive) {
16
+ setValue(v);
17
+ setOffline(false);
18
+ } }, (e) => alive && isOffline(e) && setOffline(true));
19
+ pull();
20
+ const t = setInterval(pull, ms);
21
+ return () => { alive = false; clearInterval(t); };
22
+ }, [ms, pinned]);
23
+ const begin = (body = {}) => { setCancelled(false); start?.(body).catch(() => { }); };
24
+ useEffect(() => { if (!pinned && start)
25
+ begin(); }, []);
26
+ const phase = pinned ?? phaseOf(value, { offline, cancelled, keepWork });
27
+ return {
28
+ phase, account: value, code: value?.signIn?.code, url: value?.signIn?.url,
29
+ /** Start again: `{ via: 'code' }` for "Having trouble?", `{ fresh: true }` to pick the account again. */
30
+ start: begin,
31
+ cancel: () => { setCancelled(true); cancel().catch(() => { }); },
32
+ /** "Keep this one": a work plan the person chose to use anyway. */
33
+ keepWork: () => setKeepWork(true),
34
+ /** Closing the sheet mid-way cancels the sign-in too. */
35
+ close: () => { if (phase === 'waiting' || phase === 'opening' || phase === 'code')
36
+ cancel().catch(() => { }); },
37
+ };
38
+ }
@@ -0,0 +1,66 @@
1
+ {
2
+ "connect.plans": "Plans",
3
+ "connect.plans.note": "Uses a plan you already pay for.",
4
+ "connect.perUse": "Pay per use",
5
+ "connect.perUse.note": "Charged each time you use it. Used only when you pick it.",
6
+ "connect.local": "On this computer",
7
+ "connect.local.note": "Runs on this computer. Used only when you pick it.",
8
+ "connect.server": "Your own server",
9
+ "connect.server.note": "A server you run. You say how it is paid for. Used only when you pick it.",
10
+ "connect.cloud": "Cloud account",
11
+ "connect.cloud.note": "Charged to your cloud account. Used only when you pick it.",
12
+ "connect.other": "Other ways to connect",
13
+ "connect.other.note": "How these are paid for is set by each company. Used only when you pick one.",
14
+ "connect.services": "Speech, search and media",
15
+ "connect.services.note": "Services other than chat. Used only when you pick one.",
16
+ "billing.subscription": "Uses your {name} plan",
17
+ "billing.api": "Charged per use to your {company} account",
18
+ "billing.local": "Runs on this computer",
19
+ "billing.server": "Your own server",
20
+ "billing.free": "Free tier from {company}",
21
+ "billing.unknown": "Billing set by {company}",
22
+ "via.browser": "Sign in on their page",
23
+ "via.code": "Sign in with a code",
24
+ "via.paste": "Sign in, then paste the code back",
25
+ "via.session": "Sign in",
26
+ "via.setup_token": "Paste a setup code from your plan",
27
+ "via.cli": "Sign in inside its own app",
28
+ "via.key": "Paste a key",
29
+ "via.plan_key": "Paste the key from your plan",
30
+ "via.cloud": "Use your cloud account",
31
+ "via.local": "Use a model on this computer",
32
+ "via.endpoint": "Use your own server's address",
33
+ "ready.ready": "Ready",
34
+ "ready.needs_binary": "Install its app on this computer first.",
35
+ "ready.needs_plugin": "Add its add-on first.",
36
+ "ready.needs_host": "Needs the app on your computer.",
37
+ "ready.needs_client": "Not set up for this app yet.",
38
+ "ready.unsupported_platform": "Not available on this device.",
39
+ "ready.no_upstream_flow": "This way to sign in is not available yet.",
40
+ "key.label.plan": "Key from your plan",
41
+ "key.label.perUse": "Key (charged per use)",
42
+ "key.label.other": "Key",
43
+ "key.entry": "Paste your key. It stays on this device.",
44
+ "key.checking": "Checking your key…",
45
+ "key.ok": "Your key is ready. It is used only when you choose this option.",
46
+ "key.invalid": "This key could not be saved. Check it and try again.",
47
+ "key.notIncluded": "This option is not available here.",
48
+ "account.signing": "Checking…",
49
+ "account.resting": "Cooling down",
50
+ "account.signed_out": "Not signed in",
51
+ "account.needs_again": "Sign in again",
52
+ "account.not_included": "Not in your plan",
53
+ "account.room.unknown": "Room left unknown",
54
+ "account.room.session": "{left} left this session",
55
+ "account.room.week": "{left} left this week",
56
+ "account.room.month": "{left} left this month",
57
+ "account.room.tightest": "{left} left for now",
58
+ "picker.auto": "Auto — most room left",
59
+ "picker.out.state": "Sign in first",
60
+ "picker.out.resting": "Taking a break",
61
+ "picker.out.billing": "Pay per use, so picked only when you choose it",
62
+ "picker.out.model": "Doesn't include this run's model",
63
+ "picker.out.provider": "A different service",
64
+ "move.to": "Move to {name}",
65
+ "move.failed": "Couldn't move to {name}"
66
+ }
package/package.json CHANGED
@@ -1,6 +1,77 @@
1
1
  {
2
2
  "name": "@byokit/ui",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "0.7.0",
4
+ "description": "Headless sign-in, pairing and runtime-kit view state for any UI, plus plain-words copy.",
5
+ "license": "Apache-2.0",
6
+ "type": "module",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git+https://github.com/umeranjum17/byokit.git",
10
+ "directory": "packages/ui"
11
+ },
12
+ "engines": {
13
+ "node": ">=22.18"
14
+ },
15
+ "exports": {
16
+ ".": {
17
+ "types": "./dist/index.d.ts",
18
+ "default": "./dist/index.js"
19
+ },
20
+ "./phase": {
21
+ "types": "./dist/phase.d.ts",
22
+ "default": "./dist/phase.js"
23
+ },
24
+ "./route": {
25
+ "types": "./dist/route.d.ts",
26
+ "default": "./dist/route.js"
27
+ },
28
+ "./link": {
29
+ "types": "./dist/link.d.ts",
30
+ "default": "./dist/link.js"
31
+ },
32
+ "./kits": {
33
+ "types": "./dist/kits.d.ts",
34
+ "default": "./dist/kits.js"
35
+ },
36
+ "./steps": {
37
+ "types": "./dist/steps.d.ts",
38
+ "default": "./dist/steps.js"
39
+ },
40
+ "./connect": {
41
+ "types": "./dist/connect.d.ts",
42
+ "default": "./dist/connect.js"
43
+ },
44
+ "./accounts": {
45
+ "types": "./dist/accounts.d.ts",
46
+ "default": "./dist/accounts.js"
47
+ }
48
+ },
49
+ "files": [
50
+ "dist",
51
+ "CHANGELOG.md"
52
+ ],
53
+ "scripts": {
54
+ "prepack": "tsc -b"
55
+ },
56
+ "peerDependencies": {
57
+ "react": ">=18"
58
+ },
59
+ "peerDependenciesMeta": {
60
+ "react": {
61
+ "optional": true
62
+ }
63
+ },
64
+ "devDependencies": {
65
+ "@byokit/accounts": "0.22.0",
66
+ "@types/react": "^19.3.0",
67
+ "@types/react-test-renderer": "^19.3.0",
68
+ "react": "^19.3.0",
69
+ "react-test-renderer": "^19.3.0"
70
+ },
71
+ "publishConfig": {
72
+ "access": "public"
73
+ },
74
+ "dependencies": {
75
+ "uqr": "0.1.3"
76
+ }
77
+ }