@pouchy_ai/companion-sdk 0.37.1 → 0.38.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 +15 -2
- package/README.md +11 -2
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/scopes.d.ts +11 -1
- package/dist/scopes.d.ts.map +1 -1
- package/dist/scopes.js +24 -1
- package/dist/scopes.js.map +1 -1
- package/package.json +1 -1
- package/src/index.ts +2 -1
- package/src/scopes.ts +25 -1
package/CHANGELOG.md
CHANGED
|
@@ -12,6 +12,17 @@ a protocol bump is always called out explicitly here.
|
|
|
12
12
|
|
|
13
13
|
## [Unreleased]
|
|
14
14
|
|
|
15
|
+
## [0.38.0] - 2026-07-19
|
|
16
|
+
|
|
17
|
+
Additive: new `grantsScope(granted, required)` helper. Like `hasScope`, but it
|
|
18
|
+
honours the server's scope subsumption — a key granted only `wallet.spend` now
|
|
19
|
+
`grantsScope(g, 'wallet.read')`, because the wallet API (`GET
|
|
20
|
+
/api/companion/wallet`, `getWallet()`) serves the balance to a spender. Gate a
|
|
21
|
+
read-only affordance on `grantsScope`, not `hasScope`, or the UI hides a feature
|
|
22
|
+
the server would allow. `hasScope` is unchanged (exact-match), for
|
|
23
|
+
"was-this-scope-explicitly-granted" checks. No wire/protocol change
|
|
24
|
+
(`PROTOCOL_VERSION` stays `1`); no scope vocabulary change.
|
|
25
|
+
|
|
15
26
|
## [0.37.1] - 2026-07-18
|
|
16
27
|
|
|
17
28
|
Documentation-only patch — no code, no surface, no protocol change
|
|
@@ -213,7 +224,7 @@ Backwards-compatible fixes to the adapter view controller (`createCompanionView`
|
|
|
213
224
|
now removes the dead card from `pendingConfirms` (other rejections keep the
|
|
214
225
|
card for retry). The error still propagates.
|
|
215
226
|
|
|
216
|
-
|
|
227
|
+
## [0.32.0] - 2026-07-14
|
|
217
228
|
|
|
218
229
|
No breaking changes — additive surface + docs infrastructure. No protocol
|
|
219
230
|
change (`PROTOCOL_VERSION` stays `1`).
|
|
@@ -961,7 +972,9 @@ self-hosted/CDN build; this entry captures the surface that ships publicly.
|
|
|
961
972
|
- **Versioned wire protocol.** `PROTOCOL_VERSION = 1`, kept in lockstep with the
|
|
962
973
|
server by `protocol.drift.test.ts` (fails CI on divergence).
|
|
963
974
|
|
|
964
|
-
[Unreleased]: https://github.com/oviswang/Pouchy/compare/companion-sdk-v0.
|
|
975
|
+
[Unreleased]: https://github.com/oviswang/Pouchy/compare/companion-sdk-v0.37.1...HEAD
|
|
976
|
+
[0.37.1]: https://github.com/oviswang/Pouchy/compare/companion-sdk-v0.37.0...companion-sdk-v0.37.1
|
|
977
|
+
[0.37.0]: https://github.com/oviswang/Pouchy/compare/companion-sdk-v0.36.0...companion-sdk-v0.37.0
|
|
965
978
|
[0.36.0]: https://github.com/oviswang/Pouchy/compare/companion-sdk-v0.35.0...companion-sdk-v0.36.0
|
|
966
979
|
[0.35.0]: https://github.com/oviswang/Pouchy/compare/companion-sdk-v0.34.0...companion-sdk-v0.35.0
|
|
967
980
|
[0.34.0]: https://github.com/oviswang/Pouchy/compare/companion-sdk-v0.33.0...companion-sdk-v0.34.0
|
package/README.md
CHANGED
|
@@ -264,18 +264,27 @@ copying scope strings from prose:
|
|
|
264
264
|
```ts
|
|
265
265
|
import {
|
|
266
266
|
COMPANION_SCOPES, SENSITIVE_SCOPES, DEFAULT_SCOPES,
|
|
267
|
-
hasScope, isSensitiveScope, type CompanionScope
|
|
267
|
+
hasScope, grantsScope, isSensitiveScope, type CompanionScope
|
|
268
268
|
} from '@pouchy_ai/companion-sdk';
|
|
269
269
|
|
|
270
270
|
const ack = await c.connect();
|
|
271
271
|
if (!hasScope(ack.grantedScopes, 'skills.execute')) {
|
|
272
272
|
// hide the "run a skill" affordance instead of eating a 403
|
|
273
273
|
}
|
|
274
|
+
// Gate a READ-ONLY affordance with grantsScope, not hasScope: a key granted
|
|
275
|
+
// only `wallet.spend` can still read the balance, so hasScope(g,'wallet.read')
|
|
276
|
+
// would wrongly hide it. grantsScope honours that subsumption.
|
|
277
|
+
if (grantsScope(ack.grantedScopes, 'wallet.read')) {
|
|
278
|
+
// safe to show the wallet balance (getWallet() will succeed)
|
|
279
|
+
}
|
|
274
280
|
```
|
|
275
281
|
|
|
276
282
|
`COMPANION_SCOPES` lists every scope a key can carry; `SENSITIVE_SCOPES` are
|
|
277
283
|
the ones that are never on by default (money / skills / social / core memory /
|
|
278
|
-
the representative plane); `DEFAULT_SCOPES` is what a fresh key gets.
|
|
284
|
+
the representative plane); `DEFAULT_SCOPES` is what a fresh key gets.
|
|
285
|
+
`hasScope(granted, required)` is an exact-grant check; **`grantsScope(granted,
|
|
286
|
+
required)`** additionally honours scope subsumption (`wallet.spend` ⊇
|
|
287
|
+
`wallet.read`) — use it to gate whether an API call will succeed. Also
|
|
279
288
|
exported: `COMPANION_MODALITIES`, `REPRESENT_SCOPES`, `DEFAULT_MODALITIES`,
|
|
280
289
|
`isRepresentScope()`. The list mirrors the server vocabulary and is guarded by
|
|
281
290
|
the SDK's drift test.
|
package/dist/index.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ export type { CompanionErrorCodeValue, ControlErrorCodeValue } from './errors.js
|
|
|
5
5
|
export type { CompanionClientOptions, CompanionStreamState, HelloAck, RecalledMemory, CompanionTurn, CallCredentials, CompanionToolDecl, ToolCallEvent, WorldStateInput, CompanionAvatar, CompanionWallet, WalletBalance, BrandIconSize, EndSessionResult, SendTextReply, QueuedSend, OutboxStore } from './client.js';
|
|
6
6
|
export { openCompanionCall, HOST_CONTROL_TOOLS, HOST_CONTROL_TOOL_NAMES, AVATAR_VISUAL_TOOLS, AVATAR_VISUAL_TOOL_NAMES } from './call.js';
|
|
7
7
|
export type { CompanionCall, CompanionCallOptions, VoiceToolBridge } from './call.js';
|
|
8
|
-
export { COMPANION_SCOPES, COMPANION_MODALITIES, SENSITIVE_SCOPES, REPRESENT_SCOPES, DEFAULT_SCOPES, DEFAULT_MODALITIES, isSensitiveScope, isRepresentScope, hasScope } from './scopes.js';
|
|
8
|
+
export { COMPANION_SCOPES, COMPANION_MODALITIES, SENSITIVE_SCOPES, REPRESENT_SCOPES, DEFAULT_SCOPES, DEFAULT_MODALITIES, isSensitiveScope, isRepresentScope, hasScope, grantsScope } from './scopes.js';
|
|
9
9
|
export type { CompanionScope, CompanionModality } from './scopes.js';
|
|
10
10
|
export type { CompanionEnvelope, OutboundType, InboundType, WorldStateEvent, RenderInterfacePayload, InterfaceUpdatePayload, SocialMessagePayload, ConfirmRequestPayload, PendingConfirm, PendingToolCall, ToolCallPayload, AudioClipPayload, ExpressionPayload, TypingPayload, VoiceInjectPayload, UsagePayload, MessagePayload, ControlErrorPayload, HelloAckPayload, CallReadyPayload, OutboundPayloadMap } from './protocol.js';
|
|
11
11
|
export { PROTOCOL_VERSION, INBOUND_TYPES, OUTBOUND_TYPES, COMPANION_ERROR_CODES, CONTROL_ERROR_CODES } from './protocol.js';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAYA,OAAO,EAAE,eAAe,EAAE,KAAK,sBAAsB,EAAE,MAAM,UAAU,CAAC;AAExE,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAC/E,YAAY,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AACpD,YAAY,EAAE,uBAAuB,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAC;AAC/E,YAAY,EACX,sBAAsB,EACtB,oBAAoB,EACpB,QAAQ,EACR,cAAc,EACd,aAAa,EACb,eAAe,EACf,iBAAiB,EACjB,aAAa,EACb,eAAe,EACf,eAAe,EACf,eAAe,EACf,aAAa,EACb,aAAa,EACb,gBAAgB,EAChB,aAAa,EACb,UAAU,EACV,WAAW,EACX,MAAM,UAAU,CAAC;AAClB,OAAO,EACN,iBAAiB,EACjB,kBAAkB,EAClB,uBAAuB,EACvB,mBAAmB,EACnB,wBAAwB,EACxB,MAAM,QAAQ,CAAC;AAChB,YAAY,EAAE,aAAa,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,QAAQ,CAAC;AACnF,OAAO,EACN,gBAAgB,EAChB,oBAAoB,EACpB,gBAAgB,EAChB,gBAAgB,EAChB,cAAc,EACd,kBAAkB,EAClB,gBAAgB,EAChB,gBAAgB,EAChB,QAAQ,EACR,MAAM,UAAU,CAAC;AAClB,YAAY,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAClE,YAAY,EACX,iBAAiB,EACjB,YAAY,EACZ,WAAW,EACX,eAAe,EACf,sBAAsB,EACtB,sBAAsB,EACtB,oBAAoB,EACpB,qBAAqB,EACrB,cAAc,EACd,eAAe,EACf,eAAe,EACf,gBAAgB,EAChB,iBAAiB,EACjB,aAAa,EACb,kBAAkB,EAClB,YAAY,EACZ,cAAc,EACd,mBAAmB,EACnB,eAAe,EACf,gBAAgB,EAChB,kBAAkB,EAClB,MAAM,YAAY,CAAC;AAKpB,OAAO,EACN,gBAAgB,EAChB,aAAa,EACb,cAAc,EACd,qBAAqB,EACrB,mBAAmB,EACnB,MAAM,YAAY,CAAC;AACpB,YAAY,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAMvE,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AACrD,YAAY,EACX,aAAa,EACb,oBAAoB,EACpB,qBAAqB,EACrB,wBAAwB,EACxB,MAAM,gBAAgB,CAAC;AAExB,iCAAiC;AACjC,wBAAgB,eAAe,CAAC,IAAI,EAAE,sBAAsB,GAAG,eAAe,CAE7E"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAYA,OAAO,EAAE,eAAe,EAAE,KAAK,sBAAsB,EAAE,MAAM,UAAU,CAAC;AAExE,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAC/E,YAAY,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AACpD,YAAY,EAAE,uBAAuB,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAC;AAC/E,YAAY,EACX,sBAAsB,EACtB,oBAAoB,EACpB,QAAQ,EACR,cAAc,EACd,aAAa,EACb,eAAe,EACf,iBAAiB,EACjB,aAAa,EACb,eAAe,EACf,eAAe,EACf,eAAe,EACf,aAAa,EACb,aAAa,EACb,gBAAgB,EAChB,aAAa,EACb,UAAU,EACV,WAAW,EACX,MAAM,UAAU,CAAC;AAClB,OAAO,EACN,iBAAiB,EACjB,kBAAkB,EAClB,uBAAuB,EACvB,mBAAmB,EACnB,wBAAwB,EACxB,MAAM,QAAQ,CAAC;AAChB,YAAY,EAAE,aAAa,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,QAAQ,CAAC;AACnF,OAAO,EACN,gBAAgB,EAChB,oBAAoB,EACpB,gBAAgB,EAChB,gBAAgB,EAChB,cAAc,EACd,kBAAkB,EAClB,gBAAgB,EAChB,gBAAgB,EAChB,QAAQ,EACR,WAAW,EACX,MAAM,UAAU,CAAC;AAClB,YAAY,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAClE,YAAY,EACX,iBAAiB,EACjB,YAAY,EACZ,WAAW,EACX,eAAe,EACf,sBAAsB,EACtB,sBAAsB,EACtB,oBAAoB,EACpB,qBAAqB,EACrB,cAAc,EACd,eAAe,EACf,eAAe,EACf,gBAAgB,EAChB,iBAAiB,EACjB,aAAa,EACb,kBAAkB,EAClB,YAAY,EACZ,cAAc,EACd,mBAAmB,EACnB,eAAe,EACf,gBAAgB,EAChB,kBAAkB,EAClB,MAAM,YAAY,CAAC;AAKpB,OAAO,EACN,gBAAgB,EAChB,aAAa,EACb,cAAc,EACd,qBAAqB,EACrB,mBAAmB,EACnB,MAAM,YAAY,CAAC;AACpB,YAAY,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAMvE,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AACrD,YAAY,EACX,aAAa,EACb,oBAAoB,EACpB,qBAAqB,EACrB,wBAAwB,EACxB,MAAM,gBAAgB,CAAC;AAExB,iCAAiC;AACjC,wBAAgB,eAAe,CAAC,IAAI,EAAE,sBAAsB,GAAG,eAAe,CAE7E"}
|
package/dist/index.js
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
import { CompanionClient } from './client.js';
|
|
13
13
|
export { CompanionClient, CompanionError, pouchyBrandIconUrl } from './client.js';
|
|
14
14
|
export { openCompanionCall, HOST_CONTROL_TOOLS, HOST_CONTROL_TOOL_NAMES, AVATAR_VISUAL_TOOLS, AVATAR_VISUAL_TOOL_NAMES } from './call.js';
|
|
15
|
-
export { COMPANION_SCOPES, COMPANION_MODALITIES, SENSITIVE_SCOPES, REPRESENT_SCOPES, DEFAULT_SCOPES, DEFAULT_MODALITIES, isSensitiveScope, isRepresentScope, hasScope } from './scopes.js';
|
|
15
|
+
export { COMPANION_SCOPES, COMPANION_MODALITIES, SENSITIVE_SCOPES, REPRESENT_SCOPES, DEFAULT_SCOPES, DEFAULT_MODALITIES, isSensitiveScope, isRepresentScope, hasScope, grantsScope } from './scopes.js';
|
|
16
16
|
// Runtime protocol constants — so a host can assert PROTOCOL_VERSION or
|
|
17
17
|
// enumerate/validate the event vocabulary without hard-coding the strings.
|
|
18
18
|
// CONTROL_ERROR_CODES (0.30.0) is the stream-plane control.error vocabulary —
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,yEAAyE;AACzE,sDAAsD;AACtD,EAAE;AACF,0DAA0D;AAC1D,6EAA6E;AAC7E,uBAAuB;AACvB,8CAA8C;AAC9C,eAAe;AACf,8EAA8E;AAC9E,2CAA2C;AAE3C,OAAO,EAAE,eAAe,EAA+B,MAAM,UAAU,CAAC;AAExE,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAsB/E,OAAO,EACN,iBAAiB,EACjB,kBAAkB,EAClB,uBAAuB,EACvB,mBAAmB,EACnB,wBAAwB,EACxB,MAAM,QAAQ,CAAC;AAEhB,OAAO,EACN,gBAAgB,EAChB,oBAAoB,EACpB,gBAAgB,EAChB,gBAAgB,EAChB,cAAc,EACd,kBAAkB,EAClB,gBAAgB,EAChB,gBAAgB,EAChB,QAAQ,EACR,MAAM,UAAU,CAAC;AAyBlB,wEAAwE;AACxE,2EAA2E;AAC3E,8EAA8E;AAC9E,gEAAgE;AAChE,OAAO,EACN,gBAAgB,EAChB,aAAa,EACb,cAAc,EACd,qBAAqB,EACrB,mBAAmB,EACnB,MAAM,YAAY,CAAC;AAGpB,6EAA6E;AAC7E,6EAA6E;AAC7E,0EAA0E;AAC1E,+BAA+B;AAC/B,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAQrD,iCAAiC;AACjC,MAAM,UAAU,eAAe,CAAC,IAA4B;IAC3D,OAAO,IAAI,eAAe,CAAC,IAAI,CAAC,CAAC;AAClC,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,yEAAyE;AACzE,sDAAsD;AACtD,EAAE;AACF,0DAA0D;AAC1D,6EAA6E;AAC7E,uBAAuB;AACvB,8CAA8C;AAC9C,eAAe;AACf,8EAA8E;AAC9E,2CAA2C;AAE3C,OAAO,EAAE,eAAe,EAA+B,MAAM,UAAU,CAAC;AAExE,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAsB/E,OAAO,EACN,iBAAiB,EACjB,kBAAkB,EAClB,uBAAuB,EACvB,mBAAmB,EACnB,wBAAwB,EACxB,MAAM,QAAQ,CAAC;AAEhB,OAAO,EACN,gBAAgB,EAChB,oBAAoB,EACpB,gBAAgB,EAChB,gBAAgB,EAChB,cAAc,EACd,kBAAkB,EAClB,gBAAgB,EAChB,gBAAgB,EAChB,QAAQ,EACR,WAAW,EACX,MAAM,UAAU,CAAC;AAyBlB,wEAAwE;AACxE,2EAA2E;AAC3E,8EAA8E;AAC9E,gEAAgE;AAChE,OAAO,EACN,gBAAgB,EAChB,aAAa,EACb,cAAc,EACd,qBAAqB,EACrB,mBAAmB,EACnB,MAAM,YAAY,CAAC;AAGpB,6EAA6E;AAC7E,6EAA6E;AAC7E,0EAA0E;AAC1E,+BAA+B;AAC/B,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAQrD,iCAAiC;AACjC,MAAM,UAAU,eAAe,CAAC,IAA4B;IAC3D,OAAO,IAAI,eAAe,CAAC,IAAI,CAAC,CAAC;AAClC,CAAC"}
|
package/dist/scopes.d.ts
CHANGED
|
@@ -20,6 +20,16 @@ export declare const DEFAULT_MODALITIES: readonly CompanionModality[];
|
|
|
20
20
|
export declare function isSensitiveScope(s: CompanionScope): boolean;
|
|
21
21
|
export declare function isRepresentScope(s: CompanionScope): boolean;
|
|
22
22
|
/** Does a granted scope set (e.g. `hello.ack.grantedScopes`) satisfy a
|
|
23
|
-
* required scope? Exact-match for v1 (no hierarchical wildcards).
|
|
23
|
+
* required scope? Exact-match for v1 (no hierarchical wildcards). Use this for
|
|
24
|
+
* an EXACT-grant check ("was this scope explicitly granted?"). To gate a
|
|
25
|
+
* feature on whether an API CALL will succeed, prefer `grantsScope`, which
|
|
26
|
+
* also honours scope subsumption. */
|
|
24
27
|
export declare function hasScope(granted: readonly string[], required: CompanionScope): boolean;
|
|
28
|
+
/** Like {@link hasScope}, but honours the server's scope subsumptions — so a key
|
|
29
|
+
* granted only `wallet.spend` still `grantsScope(g, 'wallet.read')` (the API
|
|
30
|
+
* would serve the balance). Gate a read-only affordance (e.g. showing the
|
|
31
|
+
* wallet balance via `getWallet()`) on THIS, not `hasScope`, or the UI hides a
|
|
32
|
+
* feature the server would allow. For non-subsumed scopes it is identical to
|
|
33
|
+
* `hasScope`. */
|
|
34
|
+
export declare function grantsScope(granted: readonly string[], required: CompanionScope): boolean;
|
|
25
35
|
//# sourceMappingURL=scopes.d.ts.map
|
package/dist/scopes.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scopes.d.ts","sourceRoot":"","sources":["../src/scopes.ts"],"names":[],"mappings":"AAUA,8EAA8E;AAC9E,eAAO,MAAM,gBAAgB,8UAsBnB,CAAC;AACX,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,gBAAgB,CAAC,CAAC,MAAM,CAAC,CAAC;AAE/D,2DAA2D;AAC3D,eAAO,MAAM,oBAAoB,6CAA8C,CAAC;AAChF,MAAM,MAAM,iBAAiB,GAAG,CAAC,OAAO,oBAAoB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEtE;;iDAEiD;AACjD,eAAO,MAAM,gBAAgB,EAAE,WAAW,CAAC,cAAc,CAWvD,CAAC;AAEH;;;6EAG6E;AAC7E,eAAO,MAAM,gBAAgB,EAAE,WAAW,CAAC,cAAc,CAMvD,CAAC;AAEH;oEACoE;AACpE,eAAO,MAAM,cAAc,EAAE,SAAS,cAAc,EASnD,CAAC;AACF,eAAO,MAAM,kBAAkB,EAAE,SAAS,iBAAiB,EAAsB,CAAC;AAElF,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,cAAc,GAAG,OAAO,CAE3D;AACD,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,cAAc,GAAG,OAAO,CAE3D;AAED;
|
|
1
|
+
{"version":3,"file":"scopes.d.ts","sourceRoot":"","sources":["../src/scopes.ts"],"names":[],"mappings":"AAUA,8EAA8E;AAC9E,eAAO,MAAM,gBAAgB,8UAsBnB,CAAC;AACX,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,gBAAgB,CAAC,CAAC,MAAM,CAAC,CAAC;AAE/D,2DAA2D;AAC3D,eAAO,MAAM,oBAAoB,6CAA8C,CAAC;AAChF,MAAM,MAAM,iBAAiB,GAAG,CAAC,OAAO,oBAAoB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEtE;;iDAEiD;AACjD,eAAO,MAAM,gBAAgB,EAAE,WAAW,CAAC,cAAc,CAWvD,CAAC;AAEH;;;6EAG6E;AAC7E,eAAO,MAAM,gBAAgB,EAAE,WAAW,CAAC,cAAc,CAMvD,CAAC;AAEH;oEACoE;AACpE,eAAO,MAAM,cAAc,EAAE,SAAS,cAAc,EASnD,CAAC;AACF,eAAO,MAAM,kBAAkB,EAAE,SAAS,iBAAiB,EAAsB,CAAC;AAElF,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,cAAc,GAAG,OAAO,CAE3D;AACD,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,cAAc,GAAG,OAAO,CAE3D;AAED;;;;sCAIsC;AACtC,wBAAgB,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,EAAE,QAAQ,EAAE,cAAc,GAAG,OAAO,CAEtF;AAWD;;;;;kBAKkB;AAClB,wBAAgB,WAAW,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,EAAE,QAAQ,EAAE,cAAc,GAAG,OAAO,CAIzF"}
|
package/dist/scopes.js
CHANGED
|
@@ -79,8 +79,31 @@ export function isRepresentScope(s) {
|
|
|
79
79
|
return REPRESENT_SCOPES.has(s);
|
|
80
80
|
}
|
|
81
81
|
/** Does a granted scope set (e.g. `hello.ack.grantedScopes`) satisfy a
|
|
82
|
-
* required scope? Exact-match for v1 (no hierarchical wildcards).
|
|
82
|
+
* required scope? Exact-match for v1 (no hierarchical wildcards). Use this for
|
|
83
|
+
* an EXACT-grant check ("was this scope explicitly granted?"). To gate a
|
|
84
|
+
* feature on whether an API CALL will succeed, prefer `grantsScope`, which
|
|
85
|
+
* also honours scope subsumption. */
|
|
83
86
|
export function hasScope(granted, required) {
|
|
84
87
|
return granted.includes(required);
|
|
85
88
|
}
|
|
89
|
+
/** Scope subsumption: for a required scope, the OTHER granted scopes that also
|
|
90
|
+
* satisfy it on the server. v1 has exactly one — `wallet.spend` can already see
|
|
91
|
+
* the balance, so it also satisfies a `wallet.read` (mirrors the server gate at
|
|
92
|
+
* `GET /api/companion/wallet`). Keep in lockstep with the server if more are
|
|
93
|
+
* added. */
|
|
94
|
+
const SCOPE_SUBSUMED_BY = {
|
|
95
|
+
'wallet.read': ['wallet.spend']
|
|
96
|
+
};
|
|
97
|
+
/** Like {@link hasScope}, but honours the server's scope subsumptions — so a key
|
|
98
|
+
* granted only `wallet.spend` still `grantsScope(g, 'wallet.read')` (the API
|
|
99
|
+
* would serve the balance). Gate a read-only affordance (e.g. showing the
|
|
100
|
+
* wallet balance via `getWallet()`) on THIS, not `hasScope`, or the UI hides a
|
|
101
|
+
* feature the server would allow. For non-subsumed scopes it is identical to
|
|
102
|
+
* `hasScope`. */
|
|
103
|
+
export function grantsScope(granted, required) {
|
|
104
|
+
if (granted.includes(required))
|
|
105
|
+
return true;
|
|
106
|
+
const implied = SCOPE_SUBSUMED_BY[required];
|
|
107
|
+
return implied ? implied.some((s) => granted.includes(s)) : false;
|
|
108
|
+
}
|
|
86
109
|
//# sourceMappingURL=scopes.js.map
|
package/dist/scopes.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scopes.js","sourceRoot":"","sources":["../src/scopes.ts"],"names":[],"mappings":"AAAA,uEAAuE;AACvE,0EAA0E;AAC1E,6EAA6E;AAC7E,kCAAkC;AAClC,EAAE;AACF,4EAA4E;AAC5E,8EAA8E;AAC9E,8EAA8E;AAC9E,0CAA0C;AAE1C,8EAA8E;AAC9E,MAAM,CAAC,MAAM,gBAAgB,GAAG;IAC/B,MAAM,EAAE,aAAa;IACrB,OAAO,EAAE,YAAY;IACrB,MAAM,EAAE,gCAAgC;IACxC,OAAO,EAAE,0CAA0C;IACnD,kBAAkB,EAAE,8CAA8C;IAClE,kBAAkB,EAAE,iDAAiD;IACrE,WAAW,EAAE,4FAA4F;IACzG,iBAAiB,EAAE,uCAAuC;IAC1D,kBAAkB,EAAE,6CAA6C;IACjE,kBAAkB,EAAE,2CAA2C;IAC/D,mBAAmB,EAAE,iDAAiD;IACtE,gBAAgB,EAAE,8CAA8C;IAChE,aAAa,EAAE,4KAA4K;IAC3L,cAAc,EAAE,yCAAyC;IACzD,gBAAgB,EAAE,sCAAsC;IACxD,yEAAyE;IACzE,WAAW,EAAE,0DAA0D;IACvE,kBAAkB,EAAE,wEAAwE;IAC5F,cAAc,EAAE,qEAAqE;IACrF,gBAAgB,EAAE,mFAAmF;IACrG,oBAAoB,CAAC,gFAAgF;CAC5F,CAAC;AAGX,2DAA2D;AAC3D,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAU,CAAC;AAGhF;;iDAEiD;AACjD,MAAM,CAAC,MAAM,gBAAgB,GAAgC,IAAI,GAAG,CAAiB;IACpF,kBAAkB;IAClB,mBAAmB;IACnB,gBAAgB;IAChB,cAAc;IACd,gBAAgB;IAChB,WAAW;IACX,kBAAkB;IAClB,cAAc;IACd,gBAAgB;IAChB,oBAAoB;CACpB,CAAC,CAAC;AAEH;;;6EAG6E;AAC7E,MAAM,CAAC,MAAM,gBAAgB,GAAgC,IAAI,GAAG,CAAiB;IACpF,WAAW;IACX,kBAAkB;IAClB,cAAc;IACd,gBAAgB;IAChB,oBAAoB;CACpB,CAAC,CAAC;AAEH;oEACoE;AACpE,MAAM,CAAC,MAAM,cAAc,GAA8B;IACxD,MAAM;IACN,OAAO;IACP,MAAM;IACN,OAAO;IACP,kBAAkB;IAClB,kBAAkB;IAClB,iBAAiB;IACjB,kBAAkB;CAClB,CAAC;AACF,MAAM,CAAC,MAAM,kBAAkB,GAAiC,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAElF,MAAM,UAAU,gBAAgB,CAAC,CAAiB;IACjD,OAAO,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;AAChC,CAAC;AACD,MAAM,UAAU,gBAAgB,CAAC,CAAiB;IACjD,OAAO,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;AAChC,CAAC;AAED;
|
|
1
|
+
{"version":3,"file":"scopes.js","sourceRoot":"","sources":["../src/scopes.ts"],"names":[],"mappings":"AAAA,uEAAuE;AACvE,0EAA0E;AAC1E,6EAA6E;AAC7E,kCAAkC;AAClC,EAAE;AACF,4EAA4E;AAC5E,8EAA8E;AAC9E,8EAA8E;AAC9E,0CAA0C;AAE1C,8EAA8E;AAC9E,MAAM,CAAC,MAAM,gBAAgB,GAAG;IAC/B,MAAM,EAAE,aAAa;IACrB,OAAO,EAAE,YAAY;IACrB,MAAM,EAAE,gCAAgC;IACxC,OAAO,EAAE,0CAA0C;IACnD,kBAAkB,EAAE,8CAA8C;IAClE,kBAAkB,EAAE,iDAAiD;IACrE,WAAW,EAAE,4FAA4F;IACzG,iBAAiB,EAAE,uCAAuC;IAC1D,kBAAkB,EAAE,6CAA6C;IACjE,kBAAkB,EAAE,2CAA2C;IAC/D,mBAAmB,EAAE,iDAAiD;IACtE,gBAAgB,EAAE,8CAA8C;IAChE,aAAa,EAAE,4KAA4K;IAC3L,cAAc,EAAE,yCAAyC;IACzD,gBAAgB,EAAE,sCAAsC;IACxD,yEAAyE;IACzE,WAAW,EAAE,0DAA0D;IACvE,kBAAkB,EAAE,wEAAwE;IAC5F,cAAc,EAAE,qEAAqE;IACrF,gBAAgB,EAAE,mFAAmF;IACrG,oBAAoB,CAAC,gFAAgF;CAC5F,CAAC;AAGX,2DAA2D;AAC3D,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAU,CAAC;AAGhF;;iDAEiD;AACjD,MAAM,CAAC,MAAM,gBAAgB,GAAgC,IAAI,GAAG,CAAiB;IACpF,kBAAkB;IAClB,mBAAmB;IACnB,gBAAgB;IAChB,cAAc;IACd,gBAAgB;IAChB,WAAW;IACX,kBAAkB;IAClB,cAAc;IACd,gBAAgB;IAChB,oBAAoB;CACpB,CAAC,CAAC;AAEH;;;6EAG6E;AAC7E,MAAM,CAAC,MAAM,gBAAgB,GAAgC,IAAI,GAAG,CAAiB;IACpF,WAAW;IACX,kBAAkB;IAClB,cAAc;IACd,gBAAgB;IAChB,oBAAoB;CACpB,CAAC,CAAC;AAEH;oEACoE;AACpE,MAAM,CAAC,MAAM,cAAc,GAA8B;IACxD,MAAM;IACN,OAAO;IACP,MAAM;IACN,OAAO;IACP,kBAAkB;IAClB,kBAAkB;IAClB,iBAAiB;IACjB,kBAAkB;CAClB,CAAC;AACF,MAAM,CAAC,MAAM,kBAAkB,GAAiC,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAElF,MAAM,UAAU,gBAAgB,CAAC,CAAiB;IACjD,OAAO,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;AAChC,CAAC;AACD,MAAM,UAAU,gBAAgB,CAAC,CAAiB;IACjD,OAAO,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;AAChC,CAAC;AAED;;;;sCAIsC;AACtC,MAAM,UAAU,QAAQ,CAAC,OAA0B,EAAE,QAAwB;IAC5E,OAAO,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;AACnC,CAAC;AAED;;;;aAIa;AACb,MAAM,iBAAiB,GAA+D;IACrF,aAAa,EAAE,CAAC,cAAc,CAAC;CAC/B,CAAC;AAEF;;;;;kBAKkB;AAClB,MAAM,UAAU,WAAW,CAAC,OAA0B,EAAE,QAAwB;IAC/E,IAAI,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC;QAAE,OAAO,IAAI,CAAC;IAC5C,MAAM,OAAO,GAAG,iBAAiB,CAAC,QAAQ,CAAC,CAAC;IAC5C,OAAO,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;AACnE,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pouchy_ai/companion-sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.38.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",
|
package/src/index.ts
CHANGED
package/src/scopes.ts
CHANGED
|
@@ -88,7 +88,31 @@ export function isRepresentScope(s: CompanionScope): boolean {
|
|
|
88
88
|
}
|
|
89
89
|
|
|
90
90
|
/** Does a granted scope set (e.g. `hello.ack.grantedScopes`) satisfy a
|
|
91
|
-
* required scope? Exact-match for v1 (no hierarchical wildcards).
|
|
91
|
+
* required scope? Exact-match for v1 (no hierarchical wildcards). Use this for
|
|
92
|
+
* an EXACT-grant check ("was this scope explicitly granted?"). To gate a
|
|
93
|
+
* feature on whether an API CALL will succeed, prefer `grantsScope`, which
|
|
94
|
+
* also honours scope subsumption. */
|
|
92
95
|
export function hasScope(granted: readonly string[], required: CompanionScope): boolean {
|
|
93
96
|
return granted.includes(required);
|
|
94
97
|
}
|
|
98
|
+
|
|
99
|
+
/** Scope subsumption: for a required scope, the OTHER granted scopes that also
|
|
100
|
+
* satisfy it on the server. v1 has exactly one — `wallet.spend` can already see
|
|
101
|
+
* the balance, so it also satisfies a `wallet.read` (mirrors the server gate at
|
|
102
|
+
* `GET /api/companion/wallet`). Keep in lockstep with the server if more are
|
|
103
|
+
* added. */
|
|
104
|
+
const SCOPE_SUBSUMED_BY: Partial<Record<CompanionScope, readonly CompanionScope[]>> = {
|
|
105
|
+
'wallet.read': ['wallet.spend']
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
/** Like {@link hasScope}, but honours the server's scope subsumptions — so a key
|
|
109
|
+
* granted only `wallet.spend` still `grantsScope(g, 'wallet.read')` (the API
|
|
110
|
+
* would serve the balance). Gate a read-only affordance (e.g. showing the
|
|
111
|
+
* wallet balance via `getWallet()`) on THIS, not `hasScope`, or the UI hides a
|
|
112
|
+
* feature the server would allow. For non-subsumed scopes it is identical to
|
|
113
|
+
* `hasScope`. */
|
|
114
|
+
export function grantsScope(granted: readonly string[], required: CompanionScope): boolean {
|
|
115
|
+
if (granted.includes(required)) return true;
|
|
116
|
+
const implied = SCOPE_SUBSUMED_BY[required];
|
|
117
|
+
return implied ? implied.some((s) => granted.includes(s)) : false;
|
|
118
|
+
}
|