@uxnan/shared 0.0.15-alpha.20260813 → 0.0.17-alpha.20260926
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.
- package/README.md +6 -3
- package/agent-locations.json +82 -0
- package/dist/src/agents/agent-adapter.d.ts +14 -0
- package/dist/src/agents/agent-capabilities.d.ts +17 -3
- package/dist/src/agents/agent-locations.d.ts +61 -0
- package/dist/src/agents/agent-locations.js +124 -0
- package/dist/src/agents/agent-locations.js.map +1 -0
- package/dist/src/index.d.ts +4 -0
- package/dist/src/index.js +5 -0
- package/dist/src/index.js.map +1 -1
- package/dist/src/jsonrpc/method-registry.d.ts +1 -1
- package/dist/src/jsonrpc/method-registry.js +13 -0
- package/dist/src/jsonrpc/method-registry.js.map +1 -1
- package/dist/src/jsonrpc/methods.d.ts +81 -12
- package/dist/src/jsonrpc/notifications.d.ts +136 -14
- package/dist/src/jsonrpc/notifications.js +30 -2
- package/dist/src/jsonrpc/notifications.js.map +1 -1
- package/dist/src/local-control/local-control.d.ts +137 -0
- package/dist/src/local-control/local-control.js +68 -0
- package/dist/src/local-control/local-control.js.map +1 -0
- package/dist/src/models/project.d.ts +40 -1
- package/dist/src/models/project.js +5 -0
- package/dist/src/models/project.js.map +1 -1
- package/dist/src/models/session.d.ts +86 -0
- package/dist/src/models/session.js +0 -5
- package/dist/src/models/session.js.map +1 -1
- package/dist/src/models/sync.d.ts +88 -0
- package/dist/src/models/sync.js +2 -0
- package/dist/src/models/sync.js.map +1 -0
- package/dist/src/models/thread.d.ts +25 -0
- package/dist/src/models/tool.d.ts +68 -0
- package/dist/src/models/tool.js +11 -0
- package/dist/src/models/tool.js.map +1 -0
- package/dist/src/models/usage.d.ts +12 -3
- package/dist/src/models/usage.js +5 -2
- package/dist/src/models/usage.js.map +1 -1
- package/package.json +3 -2
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Replica sync: how a client converges on the bridge's shared state without
|
|
3
|
+
* trusting that it saw every notification (architecture/02a §5.8.17).
|
|
4
|
+
*
|
|
5
|
+
* The bridge numbers every change to shared state — a thread, a project, the
|
|
6
|
+
* shared settings — with one global, persisted, strictly increasing **revision**
|
|
7
|
+
* (`rev`), and keeps a bounded list of deletions. A client remembers the last
|
|
8
|
+
* `rev` it applied and asks `sync/changes { since }`:
|
|
9
|
+
*
|
|
10
|
+
* - on every (re)connect and app resume;
|
|
11
|
+
* - whenever a notification carries a `rev` that is not `last + 1` (it missed
|
|
12
|
+
* something in between).
|
|
13
|
+
*
|
|
14
|
+
* The answer is either the changes after `since` or, when the client cannot be
|
|
15
|
+
* served incrementally (`storeId` differs — a new state directory — or `since`
|
|
16
|
+
* predates the deletions the bridge still remembers), a full snapshot with
|
|
17
|
+
* `reset: true` that the client applies by replacing its replica.
|
|
18
|
+
*/
|
|
19
|
+
import type { Project } from './project.js';
|
|
20
|
+
import type { Thread } from './thread.js';
|
|
21
|
+
import type { TrustedDevice } from './session.js';
|
|
22
|
+
/**
|
|
23
|
+
* Settings the bridge shares with every client, editable from any of them
|
|
24
|
+
* (`settings/set`) and from its own CLI (`uxnan-bridge config set`).
|
|
25
|
+
*/
|
|
26
|
+
export interface BridgeSettings {
|
|
27
|
+
/**
|
|
28
|
+
* The folder the bridge starts from, whatever directory `start` ran in: where
|
|
29
|
+
* exploring for a new project begins, and the boundary a phone may register
|
|
30
|
+
* projects under. Defaults to the user's home directory.
|
|
31
|
+
*/
|
|
32
|
+
home: string;
|
|
33
|
+
/**
|
|
34
|
+
* What every client calls this PC. Defaults to the machine's own name; any
|
|
35
|
+
* client, or `uxnan-bridge config set name`, can change it.
|
|
36
|
+
*/
|
|
37
|
+
name: string;
|
|
38
|
+
}
|
|
39
|
+
export interface SettingsSetParams {
|
|
40
|
+
/** New start folder: an absolute path to an existing directory. */
|
|
41
|
+
home?: string;
|
|
42
|
+
/** New name for this PC; empty goes back to the machine's own name. */
|
|
43
|
+
name?: string;
|
|
44
|
+
/**
|
|
45
|
+
* See `ActionAgeMs`: a change made offline and sent now, applied to each
|
|
46
|
+
* setting only if nobody changed that setting later.
|
|
47
|
+
*/
|
|
48
|
+
ageMs?: number;
|
|
49
|
+
}
|
|
50
|
+
export interface SyncChangesParams {
|
|
51
|
+
/** The last revision this client applied; absent on a first sync. */
|
|
52
|
+
since?: number;
|
|
53
|
+
/** The `storeId` that revision belongs to; a different one forces a reset. */
|
|
54
|
+
storeId?: string;
|
|
55
|
+
}
|
|
56
|
+
/** What kind of client is connected. */
|
|
57
|
+
export type ClientKind = 'phone' | 'desktop';
|
|
58
|
+
/** One client connected to the bridge right now. */
|
|
59
|
+
export interface ClientPresence {
|
|
60
|
+
/** Stable id: the phone's device id, or `local:<client>` for the desktop. */
|
|
61
|
+
id: string;
|
|
62
|
+
kind: ClientKind;
|
|
63
|
+
/** Human name (the phone's device name, the desktop's machine name). */
|
|
64
|
+
name: string;
|
|
65
|
+
/** When this connection opened (epoch ms). */
|
|
66
|
+
since: number;
|
|
67
|
+
}
|
|
68
|
+
export interface SyncChanges {
|
|
69
|
+
/** Identity of the bridge's state directory; changes only if it is recreated. */
|
|
70
|
+
storeId: string;
|
|
71
|
+
/** The revision this answer brings the client up to. */
|
|
72
|
+
rev: number;
|
|
73
|
+
/** True → a full snapshot: replace the replica instead of merging. */
|
|
74
|
+
reset: boolean;
|
|
75
|
+
settings: BridgeSettings;
|
|
76
|
+
/** Projects changed after `since` (all of them on a reset). */
|
|
77
|
+
projects: Project[];
|
|
78
|
+
/** Projects removed after `since` (empty on a reset). */
|
|
79
|
+
removedProjectIds: string[];
|
|
80
|
+
/** Threads changed after `since` (all of them on a reset). */
|
|
81
|
+
threads: Thread[];
|
|
82
|
+
/** Threads deleted after `since` (empty on a reset). */
|
|
83
|
+
removedThreadIds: string[];
|
|
84
|
+
/** Who is connected right now (live, not revisioned). */
|
|
85
|
+
clients: ClientPresence[];
|
|
86
|
+
/** Every paired phone, as it stands (small; always whole). */
|
|
87
|
+
devices: TrustedDevice[];
|
|
88
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sync.js","sourceRoot":"","sources":["../../../src/models/sync.ts"],"names":[],"mappings":""}
|
|
@@ -70,6 +70,13 @@ export interface Message {
|
|
|
70
70
|
export interface Turn {
|
|
71
71
|
id: string;
|
|
72
72
|
threadId: string;
|
|
73
|
+
/**
|
|
74
|
+
* The turn's position in its thread (1-based, assigned by the bridge when the
|
|
75
|
+
* turn is stored, never reused). Clients order a conversation by it — never by
|
|
76
|
+
* the order notifications happened to arrive — so a turn a client missed and
|
|
77
|
+
* fetched later still lands in its place. Absent on an older bridge.
|
|
78
|
+
*/
|
|
79
|
+
seq?: number;
|
|
73
80
|
status: TurnStatus;
|
|
74
81
|
messages: Message[];
|
|
75
82
|
createdAt: number;
|
|
@@ -112,6 +119,14 @@ export interface Thread {
|
|
|
112
119
|
agentSessionId?: string;
|
|
113
120
|
/** Per-thread access (approval) mode; see {@link AccessMode}. */
|
|
114
121
|
accessMode?: AccessMode;
|
|
122
|
+
/**
|
|
123
|
+
* Live, never persisted: the turn running on this thread right now, set by
|
|
124
|
+
* the bridge on `thread/list` and `thread/read` responses (the same value as
|
|
125
|
+
* `TurnList.activeTurnId`). Lets a client that just connected show which
|
|
126
|
+
* conversations are working without reading each one's turns. Absent when
|
|
127
|
+
* nothing runs.
|
|
128
|
+
*/
|
|
129
|
+
activeTurnId?: string;
|
|
115
130
|
/**
|
|
116
131
|
* Where {@link title} came from, so a better title can replace a weaker one
|
|
117
132
|
* without ever overwriting a name the **user** chose.
|
|
@@ -126,6 +141,16 @@ export interface Thread {
|
|
|
126
141
|
* is what they are.
|
|
127
142
|
*/
|
|
128
143
|
titleSource?: ThreadTitleSource;
|
|
144
|
+
/** Which client started the conversation, when known. */
|
|
145
|
+
origin?: ThreadOrigin;
|
|
146
|
+
/** Sync revision of the thread's last change (see `SyncChanges`). */
|
|
147
|
+
rev?: number;
|
|
148
|
+
}
|
|
149
|
+
/** Where a conversation was started. */
|
|
150
|
+
export interface ThreadOrigin {
|
|
151
|
+
kind: 'phone' | 'desktop';
|
|
152
|
+
/** The device's or machine's name. */
|
|
153
|
+
name: string;
|
|
129
154
|
}
|
|
130
155
|
/** Where a thread's title came from. See {@link Thread.titleSource}. */
|
|
131
156
|
export type ThreadTitleSource = 'prompt' | 'agent' | 'user';
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What a tool call did, in one vocabulary shared by every agent. Each agent
|
|
3
|
+
* names its tools its own way (`Read`, `read_file`, `view_file`, an ACP
|
|
4
|
+
* `kind`, a Codex item type…); the bridge classifies them once, so a client
|
|
5
|
+
* says "Read notes.txt" for all of them instead of learning every CLI.
|
|
6
|
+
*
|
|
7
|
+
* - `read`: read a file or an image
|
|
8
|
+
* - `search`: search file contents or names (grep, glob, find)
|
|
9
|
+
* - `list`: list a folder
|
|
10
|
+
* - `fetch`: fetch a URL
|
|
11
|
+
* - `web_search`: search the web
|
|
12
|
+
* - `mcp`: a tool of an MCP server
|
|
13
|
+
* - `other`: anything else — clients show the tool's name
|
|
14
|
+
*/
|
|
15
|
+
export type ToolKind = 'read' | 'search' | 'list' | 'fetch' | 'web_search' | 'mcp' | 'other';
|
|
16
|
+
/** Every {@link ToolKind}, for validators and exhaustive checks. */
|
|
17
|
+
export declare const TOOL_KINDS: readonly ToolKind[];
|
|
18
|
+
/**
|
|
19
|
+
* A step shown while it runs. Any structured block may carry a `blockId`, the
|
|
20
|
+
* id of the step it stands for: a later block of the **same turn** with the
|
|
21
|
+
* same `blockId` replaces it in place — in the bridge's store and in every
|
|
22
|
+
* client's live view — so a step appears as it starts (`status: 'running'`,
|
|
23
|
+
* or `state.status: 'running'` for a subagent) and settles into its result
|
|
24
|
+
* where it stood. Once the turn ends a step is never running: the bridge
|
|
25
|
+
* settles any the agent left open, and a client treats a running step of a
|
|
26
|
+
* turn that is no longer live as settled.
|
|
27
|
+
*/
|
|
28
|
+
export interface LiveBlock {
|
|
29
|
+
blockId?: string;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* A tool call that is not a shell command, an edit, a plan or a subagent,
|
|
33
|
+
* as a `stream/content/block` (persisted with the assistant message).
|
|
34
|
+
*/
|
|
35
|
+
export interface ToolContentBlock extends LiveBlock {
|
|
36
|
+
type: 'tool';
|
|
37
|
+
/** The agent's own name for the tool (`Read`, `grep`, `server/tool`…). */
|
|
38
|
+
toolName: string;
|
|
39
|
+
toolId: string;
|
|
40
|
+
input: Record<string, unknown>;
|
|
41
|
+
output?: string;
|
|
42
|
+
isError: boolean;
|
|
43
|
+
/** `running` while the call is in flight (see {@link LiveBlock}); absent once it finished. */
|
|
44
|
+
status?: 'running';
|
|
45
|
+
/** What the call did, classified by the bridge. */
|
|
46
|
+
kind: ToolKind;
|
|
47
|
+
/**
|
|
48
|
+
* What it acted on, ready to show: a path (relative to the project when it
|
|
49
|
+
* is inside it), a search pattern, a URL, a query. Absent when there is none.
|
|
50
|
+
*/
|
|
51
|
+
target?: string;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* A subagent the agent delegated to (Claude's `Agent`, OpenCode's `task`,
|
|
55
|
+
* Codex's collaboration tools, Antigravity's subagents): running, then
|
|
56
|
+
* finished with its report.
|
|
57
|
+
*/
|
|
58
|
+
export interface SubagentContentBlock extends LiveBlock {
|
|
59
|
+
type: 'subagent';
|
|
60
|
+
state: {
|
|
61
|
+
id: string;
|
|
62
|
+
/** What the subagent was asked to do, in a few words. */
|
|
63
|
+
name: string;
|
|
64
|
+
status: 'running' | 'completed' | 'error';
|
|
65
|
+
/** Its final report, truncated for the wire. */
|
|
66
|
+
output?: string;
|
|
67
|
+
};
|
|
68
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool.js","sourceRoot":"","sources":["../../../src/models/tool.ts"],"names":[],"mappings":"AAgBA,oEAAoE;AACpE,MAAM,CAAC,MAAM,UAAU,GAAwB;IAC7C,MAAM;IACN,QAAQ;IACR,MAAM;IACN,OAAO;IACP,YAAY;IACZ,KAAK;IACL,OAAO;CACR,CAAC"}
|
|
@@ -11,8 +11,11 @@
|
|
|
11
11
|
* over `agent/usageStats`. The Dart equivalents live in uxnanmobile and are kept
|
|
12
12
|
* in sync manually (see 02e-bridge-integration.md §4.2).
|
|
13
13
|
*
|
|
14
|
-
* Posture: only the CLI
|
|
15
|
-
*
|
|
14
|
+
* Posture: only the token the CLI itself stored is read — from its file, or
|
|
15
|
+
* from the OS credential store where that is where the CLI keeps it (Claude
|
|
16
|
+
* Code on macOS), and then only after the user has granted the OS-level
|
|
17
|
+
* permission once (see `accessRequired`). Never browser cookies, never
|
|
18
|
+
* user-pasted API keys, never a refresh token.
|
|
16
19
|
*/
|
|
17
20
|
/** A coding CLI whose usage we read from its own stored token. */
|
|
18
21
|
export type UsageProvider = 'codex' | 'claude' | 'copilot' | 'grok';
|
|
@@ -22,6 +25,11 @@ export type UsageStatus =
|
|
|
22
25
|
'ok'
|
|
23
26
|
/** CLI is present but not signed in (no usable token). */
|
|
24
27
|
| 'authRequired'
|
|
28
|
+
/** The CLI's token exists in the OS credential store, but the OS has not yet
|
|
29
|
+
* authorized the reader to open it. The user grants that once from the
|
|
30
|
+
* desktop's Providers panel (the OS shows its own dialog); the reader never
|
|
31
|
+
* prompts on its own. A phone shows "grant access on the PC". */
|
|
32
|
+
| 'accessRequired'
|
|
25
33
|
/** CLI / its config directory is not present on this machine. */
|
|
26
34
|
| 'notInstalled'
|
|
27
35
|
/** Read/network/parse failure — see {@link ProviderUsage.message}. */
|
|
@@ -121,7 +129,8 @@ export interface ProviderUsage {
|
|
|
121
129
|
resetCredits?: ResetCredits;
|
|
122
130
|
/** When this snapshot was produced (epoch ms). */
|
|
123
131
|
updatedAt: number;
|
|
124
|
-
/** Error/hint message for `error` / `authRequired` / `
|
|
132
|
+
/** Error/hint message for `error` / `authRequired` / `accessRequired` /
|
|
133
|
+
* `notInstalled` states. */
|
|
125
134
|
message?: string;
|
|
126
135
|
}
|
|
127
136
|
/**
|
package/dist/src/models/usage.js
CHANGED
|
@@ -11,8 +11,11 @@
|
|
|
11
11
|
* over `agent/usageStats`. The Dart equivalents live in uxnanmobile and are kept
|
|
12
12
|
* in sync manually (see 02e-bridge-integration.md §4.2).
|
|
13
13
|
*
|
|
14
|
-
* Posture: only the CLI
|
|
15
|
-
*
|
|
14
|
+
* Posture: only the token the CLI itself stored is read — from its file, or
|
|
15
|
+
* from the OS credential store where that is where the CLI keeps it (Claude
|
|
16
|
+
* Code on macOS), and then only after the user has granted the OS-level
|
|
17
|
+
* permission once (see `accessRequired`). Never browser cookies, never
|
|
18
|
+
* user-pasted API keys, never a refresh token.
|
|
16
19
|
*/
|
|
17
20
|
export {};
|
|
18
21
|
//# sourceMappingURL=usage.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"usage.js","sourceRoot":"","sources":["../../../src/models/usage.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"usage.js","sourceRoot":"","sources":["../../../src/models/usage.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@uxnan/shared",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.17-alpha.20260926",
|
|
4
4
|
"description": "Shared JSON-RPC and E2EE contracts for the Uxnan ecosystem (bridge, relay, mobile).",
|
|
5
5
|
"license": "MPL-2.0",
|
|
6
6
|
"author": "Luis Donaldo Gamas Vazquez",
|
|
@@ -14,7 +14,8 @@
|
|
|
14
14
|
}
|
|
15
15
|
},
|
|
16
16
|
"files": [
|
|
17
|
-
"dist/src"
|
|
17
|
+
"dist/src",
|
|
18
|
+
"agent-locations.json"
|
|
18
19
|
],
|
|
19
20
|
"engines": {
|
|
20
21
|
"node": ">=18"
|