@stelis/agent-q-core 0.0.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.
- package/README.md +144 -0
- package/dist/adapter-internal.d.ts +5 -0
- package/dist/adapter-internal.js +6 -0
- package/dist/adapter-internal.js.map +1 -0
- package/dist/config.d.ts +74 -0
- package/dist/config.js +489 -0
- package/dist/config.js.map +1 -0
- package/dist/core.d.ts +320 -0
- package/dist/core.js +840 -0
- package/dist/core.js.map +1 -0
- package/dist/device.d.ts +55 -0
- package/dist/device.js +23 -0
- package/dist/device.js.map +1 -0
- package/dist/errors.d.ts +6 -0
- package/dist/errors.js +20 -0
- package/dist/errors.js.map +1 -0
- package/dist/host-output-schema.d.ts +2437 -0
- package/dist/host-output-schema.js +655 -0
- package/dist/host-output-schema.js.map +1 -0
- package/dist/protocol-error.d.ts +4 -0
- package/dist/protocol-error.js +9 -0
- package/dist/protocol-error.js.map +1 -0
- package/dist/protocol-management-primitives.d.ts +27 -0
- package/dist/protocol-management-primitives.js +51 -0
- package/dist/protocol-management-primitives.js.map +1 -0
- package/dist/protocol-primitives.d.ts +53 -0
- package/dist/protocol-primitives.js +331 -0
- package/dist/protocol-primitives.js.map +1 -0
- package/dist/protocol.d.ts +207 -0
- package/dist/protocol.js +897 -0
- package/dist/protocol.js.map +1 -0
- package/dist/provider-protocol.d.ts +262 -0
- package/dist/provider-protocol.js +637 -0
- package/dist/provider-protocol.js.map +1 -0
- package/dist/public-error.d.ts +9 -0
- package/dist/public-error.js +79 -0
- package/dist/public-error.js.map +1 -0
- package/dist/safe-text.d.ts +31 -0
- package/dist/safe-text.js +143 -0
- package/dist/safe-text.js.map +1 -0
- package/dist/transport-invariants.d.ts +18 -0
- package/dist/transport-invariants.js +24 -0
- package/dist/transport-invariants.js.map +1 -0
- package/dist/usb.d.ts +76 -0
- package/dist/usb.js +454 -0
- package/dist/usb.js.map +1 -0
- package/package.json +58 -0
package/README.md
ADDED
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
# Agent-Q Core
|
|
2
|
+
|
|
3
|
+
`@stelis/agent-q-core` is the shared Agent-Q core package.
|
|
4
|
+
|
|
5
|
+
It provides transport, protocol builders and parsers, runtime session mirroring,
|
|
6
|
+
local device selection/config storage, public error mapping, and Firmware result
|
|
7
|
+
parsing. The `agent-q` local server, Sui provider, and Sui CLI signer use this
|
|
8
|
+
package instead of reimplementing the device/protocol boundary.
|
|
9
|
+
|
|
10
|
+
The core package is not a signing authority and is not a policy authority.
|
|
11
|
+
It does not store signing keys, does not make signing decisions, and does not
|
|
12
|
+
apply policy. Agent-Q Firmware owns keys, policy evaluation, sensitive approval,
|
|
13
|
+
and active policy commits.
|
|
14
|
+
|
|
15
|
+
## Quick Start
|
|
16
|
+
|
|
17
|
+
Use this package directly when a Node process needs to discover an Agent-Q
|
|
18
|
+
device, open a session, read accounts, and request signatures.
|
|
19
|
+
|
|
20
|
+
```ts
|
|
21
|
+
import { createDefaultAgentQDeviceClient } from "@stelis/agent-q-core/device";
|
|
22
|
+
|
|
23
|
+
const client = createDefaultAgentQDeviceClient();
|
|
24
|
+
|
|
25
|
+
await client.scanDevices();
|
|
26
|
+
await client.connectDevice({});
|
|
27
|
+
|
|
28
|
+
const accounts = await client.getAccounts({});
|
|
29
|
+
|
|
30
|
+
const result = await client.signTransaction({
|
|
31
|
+
chain: "sui",
|
|
32
|
+
method: "sign_transaction",
|
|
33
|
+
network: "testnet",
|
|
34
|
+
txBytes,
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
await client.disconnectDevice({});
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
The core request succeeds only when Firmware accepts the state, session,
|
|
41
|
+
route, parameters, policy or device-confirmation gate, and signing operation.
|
|
42
|
+
|
|
43
|
+
## Common Flow
|
|
44
|
+
|
|
45
|
+
```text
|
|
46
|
+
scanDevices
|
|
47
|
+
-> identifyDevices?
|
|
48
|
+
-> selectDevice?
|
|
49
|
+
-> connectDevice
|
|
50
|
+
-> getCapabilities
|
|
51
|
+
-> getAccounts
|
|
52
|
+
-> signTransaction or signPersonalMessage
|
|
53
|
+
-> disconnectDevice
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Use `getCapabilities` before signing. It reports the device's current signing
|
|
57
|
+
mode and supported signing methods for display and request selection. The
|
|
58
|
+
client cannot choose the device signing mode.
|
|
59
|
+
|
|
60
|
+
## Entrypoints
|
|
61
|
+
|
|
62
|
+
- `@stelis/agent-q-core` exposes the full `AgentQCore`,
|
|
63
|
+
`createDefaultAgentQCore`, and low-level transport classes used by the
|
|
64
|
+
`agent-q` local server.
|
|
65
|
+
- `@stelis/agent-q-core/device` exposes the limited
|
|
66
|
+
`createDefaultAgentQDeviceClient` facade for provider/app code that should not
|
|
67
|
+
see policy proposal or server management methods.
|
|
68
|
+
- `@stelis/agent-q-core/protocol` exposes the shared protocol builders,
|
|
69
|
+
parsers, constants, and response types.
|
|
70
|
+
- `@stelis/agent-q-core/provider-protocol` exposes the browser-safe provider
|
|
71
|
+
protocol projection used by official dapp-facing adapters. It includes
|
|
72
|
+
provider request builders, an exact provider request serializer, provider
|
|
73
|
+
response parsers, bounded response-line handling, USB identifiers, and fixed
|
|
74
|
+
internal deadline constants; it does not expose Admin, policy read/update,
|
|
75
|
+
approval-history, or full-protocol request serialization.
|
|
76
|
+
- `@stelis/agent-q-core/adapter-internal` exposes support APIs for official
|
|
77
|
+
Agent-Q adapters, including bounded output schemas, public error mapping, safe
|
|
78
|
+
text validation, and the local host device registry. It is not the
|
|
79
|
+
dapp-facing provider API.
|
|
80
|
+
|
|
81
|
+
## Boundaries
|
|
82
|
+
|
|
83
|
+
- A connection session opens a communication channel between the host process and
|
|
84
|
+
Firmware. It is not signing approval.
|
|
85
|
+
- Session ids are held in host process memory only and are not returned to callers.
|
|
86
|
+
- Labels and purpose names are local host process metadata. They are not Firmware
|
|
87
|
+
policy and are not authorization facts.
|
|
88
|
+
- Policy update proposals are available only through the full core. They are
|
|
89
|
+
not part of the limited device API facade.
|
|
90
|
+
This is API surface separation, not a security barrier against code that
|
|
91
|
+
deliberately imports the full core. Firmware remains responsible for
|
|
92
|
+
validating and approving sensitive writes.
|
|
93
|
+
- Current StackChan CoreS3 capabilities report Sui account identity and no
|
|
94
|
+
delegated signing methods in `chains[].methods`. Signing availability is
|
|
95
|
+
advertised through top-level `signing.authorization` and `signing.methods`,
|
|
96
|
+
and the device API facade exposes `signTransaction` and
|
|
97
|
+
`signPersonalMessage`. The core parser accepts Firmware-authored
|
|
98
|
+
`sign_result` values for transaction policy/user outcomes and user-mode
|
|
99
|
+
personal-message outcomes. It accepts `messageBytes` only for signed
|
|
100
|
+
personal-message results and rejects raw transaction bytes in results, decoded
|
|
101
|
+
internals, session ids, request ids, and secret-like fields.
|
|
102
|
+
- External inputs do not accept caller-controlled timing fields. The host process
|
|
103
|
+
uses fixed internal transport budgets. Firmware-owned device-local approval
|
|
104
|
+
windows remain 30 seconds; the host process waits with a non-configurable transport
|
|
105
|
+
margin so a valid terminal device result can still be received at the end of
|
|
106
|
+
that window.
|
|
107
|
+
- Shared signing calls classify bounded `(type, chain, method)` routes before
|
|
108
|
+
resolving state/session. Sui is currently the only executable chain.
|
|
109
|
+
Method-parameter validation remains after a runtime session exists. Common
|
|
110
|
+
Core validation owns transport bounds and canonical base64 syntax, not the
|
|
111
|
+
current Sui Firmware adapter's decoded-payload capacities.
|
|
112
|
+
|
|
113
|
+
## Development
|
|
114
|
+
|
|
115
|
+
From the repository root:
|
|
116
|
+
|
|
117
|
+
```sh
|
|
118
|
+
npm --workspace @stelis/agent-q-core run build
|
|
119
|
+
npm --workspace @stelis/agent-q-core test
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
Direct USB/Firmware hardware smoke tests live in this package and are opt-in.
|
|
123
|
+
They are skipped unless their `AGENTQ_HW_CLIENT_*` environment gates are set:
|
|
124
|
+
|
|
125
|
+
```sh
|
|
126
|
+
npm --workspace @stelis/agent-q-core run build
|
|
127
|
+
|
|
128
|
+
AGENTQ_HW_CLIENT_SIGN_TRANSACTION_USER=1 \
|
|
129
|
+
AGENTQ_HW_CLIENT_SIGN_TRANSACTION_USER_SCENARIO=positive \
|
|
130
|
+
AGENTQ_HW_CLIENT_SIGN_TRANSACTION_USER_TX_BYTES=<base64> \
|
|
131
|
+
node --test packages/core/test/hardware-sign-api-smoke.test.mjs
|
|
132
|
+
|
|
133
|
+
AGENTQ_HW_CLIENT_SIGN_TRANSACTION_POLICY=1 \
|
|
134
|
+
AGENTQ_HW_CLIENT_SIGN_TRANSACTION_POLICY_SCENARIO=rejected \
|
|
135
|
+
node --test packages/core/test/hardware-sign-api-smoke.test.mjs
|
|
136
|
+
|
|
137
|
+
AGENTQ_HW_CLIENT_POLICY_UPDATE=1 \
|
|
138
|
+
node --test packages/core/test/hardware-sign-api-smoke.test.mjs
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
Adapter packages keep their tests focused on adapter projection and public API
|
|
142
|
+
boundaries. Hardware smoke evidence must still record target hardware, commit,
|
|
143
|
+
build/flash command, manual steps, observed result, and unchecked paths before
|
|
144
|
+
implementation status is raised.
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { ConfigStore } from "./config.js";
|
|
2
|
+
export { AgentQError, toAgentQError } from "./errors.js";
|
|
3
|
+
export * from "./host-output-schema.js";
|
|
4
|
+
export { PUBLIC_ERROR_MESSAGES, normalizeErrorCode, toPublicError } from "./public-error.js";
|
|
5
|
+
export * from "./safe-text.js";
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { ConfigStore } from "./config.js";
|
|
2
|
+
export { AgentQError, toAgentQError } from "./errors.js";
|
|
3
|
+
export * from "./host-output-schema.js";
|
|
4
|
+
export { PUBLIC_ERROR_MESSAGES, normalizeErrorCode, toPublicError } from "./public-error.js";
|
|
5
|
+
export * from "./safe-text.js";
|
|
6
|
+
//# sourceMappingURL=adapter-internal.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter-internal.js","sourceRoot":"","sources":["../src/adapter-internal.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACzD,cAAc,yBAAyB,CAAC;AACxC,OAAO,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAC7F,cAAc,gBAAgB,CAAC"}
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { type DeviceStatusSnapshot } from "./protocol.js";
|
|
2
|
+
import { MAX_LABEL_LENGTH, PURPOSE_PATTERN, RESERVED_PURPOSES, isValidLabel, isValidPurpose } from "./safe-text.js";
|
|
3
|
+
export declare const CONFIG_SCHEMA_VERSION = 0;
|
|
4
|
+
export { MAX_LABEL_LENGTH, PURPOSE_PATTERN, RESERVED_PURPOSES, isValidLabel, isValidPurpose };
|
|
5
|
+
export interface DeviceRecord {
|
|
6
|
+
deviceId: string;
|
|
7
|
+
transport: "usb";
|
|
8
|
+
lastPortHint: string;
|
|
9
|
+
lastSeenAt: string;
|
|
10
|
+
label: string | null;
|
|
11
|
+
lastStatus: DeviceStatusSnapshot;
|
|
12
|
+
}
|
|
13
|
+
export interface AgentQConfig {
|
|
14
|
+
schemaVersion: typeof CONFIG_SCHEMA_VERSION;
|
|
15
|
+
activeDeviceId: string | null;
|
|
16
|
+
activeDeviceIdsByPurpose: Record<string, string>;
|
|
17
|
+
devices: DeviceRecord[];
|
|
18
|
+
}
|
|
19
|
+
export interface DeviceListing {
|
|
20
|
+
deviceId: string;
|
|
21
|
+
transport: "usb";
|
|
22
|
+
lastPortHint: string;
|
|
23
|
+
lastSeenAt: string;
|
|
24
|
+
label: string | null;
|
|
25
|
+
lastStatus: DeviceStatusSnapshot;
|
|
26
|
+
assignedPurposes: string[];
|
|
27
|
+
isDefaultActive: boolean;
|
|
28
|
+
}
|
|
29
|
+
export interface ConfigPathOptions {
|
|
30
|
+
env?: NodeJS.ProcessEnv;
|
|
31
|
+
homeDir?: string;
|
|
32
|
+
}
|
|
33
|
+
export interface RememberUsbStatusOptions {
|
|
34
|
+
observedAt?: Date;
|
|
35
|
+
setActive?: boolean;
|
|
36
|
+
}
|
|
37
|
+
export interface SetDeviceMetadataInput {
|
|
38
|
+
deviceId: string;
|
|
39
|
+
label?: string | null;
|
|
40
|
+
}
|
|
41
|
+
export interface ConfigValidationError {
|
|
42
|
+
code: string;
|
|
43
|
+
message: string;
|
|
44
|
+
}
|
|
45
|
+
export declare class ConfigError extends Error {
|
|
46
|
+
readonly code: string;
|
|
47
|
+
constructor(code: string, message: string);
|
|
48
|
+
}
|
|
49
|
+
export declare function defaultAgentQConfig(): AgentQConfig;
|
|
50
|
+
export declare function getConfigPath(options?: ConfigPathOptions): string;
|
|
51
|
+
export declare class ConfigStore {
|
|
52
|
+
readonly path: string;
|
|
53
|
+
constructor(path?: string);
|
|
54
|
+
private lastWarnedRaw;
|
|
55
|
+
load(): Promise<AgentQConfig>;
|
|
56
|
+
private writeConfig;
|
|
57
|
+
private maybeWarnNormalized;
|
|
58
|
+
listDevices(): Promise<DeviceListing[]>;
|
|
59
|
+
rememberUsbStatus(status: DeviceStatusSnapshot, portPath: string, options?: RememberUsbStatusOptions): Promise<AgentQConfig>;
|
|
60
|
+
setDeviceMetadata(input: SetDeviceMetadataInput): Promise<DeviceRecord>;
|
|
61
|
+
setActiveDevice(deviceId: string, purpose?: string): Promise<DeviceRecord>;
|
|
62
|
+
getActiveDevice(purpose?: string): Promise<DeviceRecord | undefined>;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Drop routing selections that point at devices not present in `devices`.
|
|
66
|
+
* Writes always validate references, so dangling entries only arise from a
|
|
67
|
+
* hand-edited config. Pruning keeps `list_devices` and purpose routing
|
|
68
|
+
* self-consistent instead of failing later with `device_not_found`.
|
|
69
|
+
*
|
|
70
|
+
* Stable exported shape. Internally this is the report-free view of the
|
|
71
|
+
* pipeline's reference-pruning stage ({@link pruneReferences}); load and write
|
|
72
|
+
* thread a NormalizationReport through that stage instead.
|
|
73
|
+
*/
|
|
74
|
+
export declare function normalizeReferences(config: AgentQConfig): AgentQConfig;
|