@pouchy_ai/companion-sdk 0.18.1 → 0.19.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/CHANGELOG.md +14 -0
- package/README.md +24 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1 -0
- package/dist/scopes.d.ts +24 -0
- package/dist/scopes.js +85 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -12,6 +12,20 @@ a protocol bump is always called out explicitly here.
|
|
|
12
12
|
|
|
13
13
|
## [Unreleased]
|
|
14
14
|
|
|
15
|
+
## [0.19.0] - 2026-07-10
|
|
16
|
+
|
|
17
|
+
### Added
|
|
18
|
+
|
|
19
|
+
- **Typed scope vocabulary exported from the package.** `COMPANION_SCOPES` /
|
|
20
|
+
`CompanionScope`, `COMPANION_MODALITIES` / `CompanionModality`,
|
|
21
|
+
`SENSITIVE_SCOPES`, `REPRESENT_SCOPES`, `DEFAULT_SCOPES`,
|
|
22
|
+
`DEFAULT_MODALITIES`, and the helpers `isSensitiveScope()`,
|
|
23
|
+
`isRepresentScope()`, `hasScope(granted, required)`. Configure keys, gate
|
|
24
|
+
features on `hello.ack.grantedScopes`, and explain 403s with compile-checked
|
|
25
|
+
scope strings instead of prose-copied literals. Mirrors the server vocabulary
|
|
26
|
+
and is guarded by the same drift test as the wire protocol. Additive — no
|
|
27
|
+
wire-protocol change.
|
|
28
|
+
|
|
15
29
|
## [0.18.1] - 2026-07-08
|
|
16
30
|
|
|
17
31
|
### Changed
|
package/README.md
CHANGED
|
@@ -92,6 +92,30 @@ Reference renderers ship in [`examples/`](../../examples): `web-instant-ui` (van
|
|
|
92
92
|
`native-instant-ui` (SwiftUI + Jetpack Compose), and `cli-skills` (terminal +
|
|
93
93
|
local/device skills).
|
|
94
94
|
|
|
95
|
+
## Scopes (typed)
|
|
96
|
+
|
|
97
|
+
The full capability-scope vocabulary ships as typed constants — no more
|
|
98
|
+
copying scope strings from prose:
|
|
99
|
+
|
|
100
|
+
```ts
|
|
101
|
+
import {
|
|
102
|
+
COMPANION_SCOPES, SENSITIVE_SCOPES, DEFAULT_SCOPES,
|
|
103
|
+
hasScope, isSensitiveScope, type CompanionScope
|
|
104
|
+
} from '@pouchy_ai/companion-sdk';
|
|
105
|
+
|
|
106
|
+
const ack = await c.connect();
|
|
107
|
+
if (!hasScope(ack.grantedScopes, 'skills.execute')) {
|
|
108
|
+
// hide the "run a skill" affordance instead of eating a 403
|
|
109
|
+
}
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
`COMPANION_SCOPES` lists every scope a key can carry; `SENSITIVE_SCOPES` are
|
|
113
|
+
the ones that are never on by default (money / skills / social / core memory /
|
|
114
|
+
the representative plane); `DEFAULT_SCOPES` is what a fresh key gets. Also
|
|
115
|
+
exported: `COMPANION_MODALITIES`, `REPRESENT_SCOPES`, `DEFAULT_MODALITIES`,
|
|
116
|
+
`isRepresentScope()`. The list mirrors the server vocabulary and is guarded by
|
|
117
|
+
the SDK's drift test.
|
|
118
|
+
|
|
95
119
|
## Representative mode (代聊)
|
|
96
120
|
|
|
97
121
|
Pass a `visitor` and the session flips from **owner-facing** to **representative**:
|
package/dist/index.d.ts
CHANGED
|
@@ -3,6 +3,8 @@ export { CompanionClient, CompanionError, pouchyBrandIconUrl } from './client.js
|
|
|
3
3
|
export type { CompanionClientOptions, HelloAck, RecalledMemory, CompanionTurn, CallCredentials, CompanionToolDecl, WorldStateInput, CompanionAvatar, BrandIconSize, EndSessionResult } from './client.js';
|
|
4
4
|
export { openCompanionCall, HOST_CONTROL_TOOLS, HOST_CONTROL_TOOL_NAMES, AVATAR_VISUAL_TOOLS, AVATAR_VISUAL_TOOL_NAMES } from './call.js';
|
|
5
5
|
export type { CompanionCall, CompanionCallOptions, VoiceToolBridge } from './call.js';
|
|
6
|
+
export { COMPANION_SCOPES, COMPANION_MODALITIES, SENSITIVE_SCOPES, REPRESENT_SCOPES, DEFAULT_SCOPES, DEFAULT_MODALITIES, isSensitiveScope, isRepresentScope, hasScope } from './scopes.js';
|
|
7
|
+
export type { CompanionScope, CompanionModality } from './scopes.js';
|
|
6
8
|
export type { CompanionEnvelope, OutboundType, InboundType, WorldStateEvent, RenderInterfacePayload, InterfaceUpdatePayload, SocialMessagePayload, ConfirmRequestPayload, PendingConfirm, AudioClipPayload, ExpressionPayload, TypingPayload, VoiceInjectPayload, UsagePayload } from './protocol.js';
|
|
7
9
|
/** Create a companion client. */
|
|
8
10
|
export declare function createCompanion(opts: CompanionClientOptions): CompanionClient;
|
package/dist/index.js
CHANGED
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
import { CompanionClient } from './client.js';
|
|
12
12
|
export { CompanionClient, CompanionError, pouchyBrandIconUrl } from './client.js';
|
|
13
13
|
export { openCompanionCall, HOST_CONTROL_TOOLS, HOST_CONTROL_TOOL_NAMES, AVATAR_VISUAL_TOOLS, AVATAR_VISUAL_TOOL_NAMES } from './call.js';
|
|
14
|
+
export { COMPANION_SCOPES, COMPANION_MODALITIES, SENSITIVE_SCOPES, REPRESENT_SCOPES, DEFAULT_SCOPES, DEFAULT_MODALITIES, isSensitiveScope, isRepresentScope, hasScope } from './scopes.js';
|
|
14
15
|
/** Create a companion client. */
|
|
15
16
|
export function createCompanion(opts) {
|
|
16
17
|
return new CompanionClient(opts);
|
package/dist/scopes.d.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/** Every capability scope a Personal Access Token / OAuth grant can carry. */
|
|
2
|
+
export declare const COMPANION_SCOPES: readonly ["chat", "voice", "call", "files", "events.subscribe", "worldstate.write", "ui.render", "memory.read:app", "memory.write:app", "memory.read:core", "memory.write:core", "skills.execute", "wallet.read", "wallet.spend", "social.message", "represent", "expose:knowledge", "expose:facts", "represent:pair", "represent:remember"];
|
|
3
|
+
export type CompanionScope = (typeof COMPANION_SCOPES)[number];
|
|
4
|
+
/** I/O modalities a key can carry alongside its scopes. */
|
|
5
|
+
export declare const COMPANION_MODALITIES: readonly ["text", "voice", "call", "files"];
|
|
6
|
+
export type CompanionModality = (typeof COMPANION_MODALITIES)[number];
|
|
7
|
+
/** Sensitive scopes — never granted by default; the user opts in at key
|
|
8
|
+
* creation, and execution still passes a confirm on a Pouchy-controlled
|
|
9
|
+
* surface (see `companion.confirm_request`). */
|
|
10
|
+
export declare const SENSITIVE_SCOPES: ReadonlySet<CompanionScope>;
|
|
11
|
+
/** The representative ("on-behalf-of") plane — a distinct axis from the
|
|
12
|
+
* execution scopes: one lets the companion ACT for the owner, the other lets
|
|
13
|
+
* it REPRESENT the owner to an outside visitor. `represent` is the umbrella;
|
|
14
|
+
* the `expose:*` / `represent:*` scopes only mean anything alongside it. */
|
|
15
|
+
export declare const REPRESENT_SCOPES: ReadonlySet<CompanionScope>;
|
|
16
|
+
/** What a freshly-generated key carries unless the user opts into more: a
|
|
17
|
+
* chat/play companion confined to its own app memory namespace. */
|
|
18
|
+
export declare const DEFAULT_SCOPES: readonly CompanionScope[];
|
|
19
|
+
export declare const DEFAULT_MODALITIES: readonly CompanionModality[];
|
|
20
|
+
export declare function isSensitiveScope(s: CompanionScope): boolean;
|
|
21
|
+
export declare function isRepresentScope(s: CompanionScope): boolean;
|
|
22
|
+
/** Does a granted scope set (e.g. `hello.ack.grantedScopes`) satisfy a
|
|
23
|
+
* required scope? Exact-match for v1 (no hierarchical wildcards). */
|
|
24
|
+
export declare function hasScope(granted: readonly string[], required: CompanionScope): boolean;
|
package/dist/scopes.js
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
// Companion capability scopes — the SDK's self-contained copy (no $lib
|
|
2
|
+
// imports; same doctrine as protocol.ts). The server's source of truth is
|
|
3
|
+
// src/lib/types/companion-scopes.ts; protocol.drift.test.ts fails if the two
|
|
4
|
+
// diverge — extend both together.
|
|
5
|
+
//
|
|
6
|
+
// Why the SDK exports these: a host app configuring a key, gating a feature
|
|
7
|
+
// on `hello.ack.grantedScopes`, or explaining a `403 missing scope` needs the
|
|
8
|
+
// vocabulary as types and constants, not prose. Typos in scope strings become
|
|
9
|
+
// compile errors instead of runtime 403s.
|
|
10
|
+
/** Every capability scope a Personal Access Token / OAuth grant can carry. */
|
|
11
|
+
export const COMPANION_SCOPES = [
|
|
12
|
+
'chat', // text turns
|
|
13
|
+
'voice', // TTS / STT
|
|
14
|
+
'call', // realtime WebRTC voice session
|
|
15
|
+
'files', // multimodal file in/out (vision / image)
|
|
16
|
+
'events.subscribe', // receive the outbound companion event stream
|
|
17
|
+
'worldstate.write', // push inbound live world-state / context events
|
|
18
|
+
'ui.render', // let the companion render Instant UI surfaces on the host (display + forms; not sensitive)
|
|
19
|
+
'memory.read:app', // read this app's own memory namespace
|
|
20
|
+
'memory.write:app', // write into this app's own memory namespace
|
|
21
|
+
'memory.read:core', // read the shared global brain (SENSITIVE)
|
|
22
|
+
'memory.write:core', // write into the shared global brain (SENSITIVE)
|
|
23
|
+
'skills.execute', // run the user's installed skills (SENSITIVE)
|
|
24
|
+
'wallet.read', // READ-ONLY wallet: balance + own deposit address (receive-only; not sensitive)
|
|
25
|
+
'wallet.spend', // spend from the Care Wallet (SENSITIVE)
|
|
26
|
+
'social.message', // message friends via A2A (SENSITIVE)
|
|
27
|
+
// ── Representative ("on-behalf-of") plane ─────────────────────────────
|
|
28
|
+
'represent', // open visitor-facing representative sessions (SENSITIVE)
|
|
29
|
+
'expose:knowledge', // let the representative draw on the owner's knowledge base (SENSITIVE)
|
|
30
|
+
'expose:facts', // widen exposed facts past the identity/preference floor (SENSITIVE)
|
|
31
|
+
'represent:pair', // let a representative pair a visitor (also a Pouchy user) as a friend (SENSITIVE)
|
|
32
|
+
'represent:remember' // let a representative keep durable per-visitor notes across visits (SENSITIVE)
|
|
33
|
+
];
|
|
34
|
+
/** I/O modalities a key can carry alongside its scopes. */
|
|
35
|
+
export const COMPANION_MODALITIES = ['text', 'voice', 'call', 'files'];
|
|
36
|
+
/** Sensitive scopes — never granted by default; the user opts in at key
|
|
37
|
+
* creation, and execution still passes a confirm on a Pouchy-controlled
|
|
38
|
+
* surface (see `companion.confirm_request`). */
|
|
39
|
+
export const SENSITIVE_SCOPES = new Set([
|
|
40
|
+
'memory.read:core',
|
|
41
|
+
'memory.write:core',
|
|
42
|
+
'skills.execute',
|
|
43
|
+
'wallet.spend',
|
|
44
|
+
'social.message',
|
|
45
|
+
'represent',
|
|
46
|
+
'expose:knowledge',
|
|
47
|
+
'expose:facts',
|
|
48
|
+
'represent:pair',
|
|
49
|
+
'represent:remember'
|
|
50
|
+
]);
|
|
51
|
+
/** The representative ("on-behalf-of") plane — a distinct axis from the
|
|
52
|
+
* execution scopes: one lets the companion ACT for the owner, the other lets
|
|
53
|
+
* it REPRESENT the owner to an outside visitor. `represent` is the umbrella;
|
|
54
|
+
* the `expose:*` / `represent:*` scopes only mean anything alongside it. */
|
|
55
|
+
export const REPRESENT_SCOPES = new Set([
|
|
56
|
+
'represent',
|
|
57
|
+
'expose:knowledge',
|
|
58
|
+
'expose:facts',
|
|
59
|
+
'represent:pair',
|
|
60
|
+
'represent:remember'
|
|
61
|
+
]);
|
|
62
|
+
/** What a freshly-generated key carries unless the user opts into more: a
|
|
63
|
+
* chat/play companion confined to its own app memory namespace. */
|
|
64
|
+
export const DEFAULT_SCOPES = [
|
|
65
|
+
'chat',
|
|
66
|
+
'voice',
|
|
67
|
+
'call',
|
|
68
|
+
'files',
|
|
69
|
+
'events.subscribe',
|
|
70
|
+
'worldstate.write',
|
|
71
|
+
'memory.read:app',
|
|
72
|
+
'memory.write:app'
|
|
73
|
+
];
|
|
74
|
+
export const DEFAULT_MODALITIES = ['text', 'voice'];
|
|
75
|
+
export function isSensitiveScope(s) {
|
|
76
|
+
return SENSITIVE_SCOPES.has(s);
|
|
77
|
+
}
|
|
78
|
+
export function isRepresentScope(s) {
|
|
79
|
+
return REPRESENT_SCOPES.has(s);
|
|
80
|
+
}
|
|
81
|
+
/** Does a granted scope set (e.g. `hello.ack.grantedScopes`) satisfy a
|
|
82
|
+
* required scope? Exact-match for v1 (no hierarchical wildcards). */
|
|
83
|
+
export function hasScope(granted, required) {
|
|
84
|
+
return granted.includes(required);
|
|
85
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pouchy_ai/companion-sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.19.0",
|
|
4
4
|
"description": "Embed the Pouchy companion — chat, voice, tools, memory, live world-state, instant UI, and agent-to-agent messaging — in any app, game, or site.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "SEE LICENSE IN LICENSE",
|