@stigmer/sdk 3.1.7 → 3.1.9
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/__tests__/errors.test.js +42 -0
- package/__tests__/errors.test.js.map +1 -1
- package/__tests__/guest-auth.test.d.ts +2 -0
- package/__tests__/guest-auth.test.d.ts.map +1 -0
- package/__tests__/guest-auth.test.js +223 -0
- package/__tests__/guest-auth.test.js.map +1 -0
- package/__tests__/sharing.test.d.ts +2 -0
- package/__tests__/sharing.test.d.ts.map +1 -0
- package/__tests__/sharing.test.js +106 -0
- package/__tests__/sharing.test.js.map +1 -0
- package/gen/agentshare.d.ts +45 -0
- package/gen/agentshare.d.ts.map +1 -0
- package/gen/agentshare.js +142 -0
- package/gen/agentshare.js.map +1 -0
- package/gen/authorization-config.d.ts.map +1 -1
- package/gen/authorization-config.js +1 -0
- package/gen/authorization-config.js.map +1 -1
- package/gen/client.d.ts +4 -0
- package/gen/client.d.ts.map +1 -1
- package/gen/client.js +4 -0
- package/gen/client.js.map +1 -1
- package/gen/environment.d.ts +2 -0
- package/gen/environment.d.ts.map +1 -1
- package/gen/environment.js +8 -0
- package/gen/environment.js.map +1 -1
- package/gen/platformclient.d.ts +2 -1
- package/gen/platformclient.d.ts.map +1 -1
- package/gen/platformclient.js +8 -0
- package/gen/platformclient.js.map +1 -1
- package/gen/session.d.ts +2 -2
- package/gen/session.d.ts.map +1 -1
- package/gen/session.js +2 -2
- package/gen/session.js.map +1 -1
- package/guest-auth.d.ts +175 -0
- package/guest-auth.d.ts.map +1 -0
- package/guest-auth.js +227 -0
- package/guest-auth.js.map +1 -0
- package/index.d.ts +3 -0
- package/index.d.ts.map +1 -1
- package/index.js +5 -0
- package/index.js.map +1 -1
- package/package.json +2 -2
- package/sharing.d.ts +76 -0
- package/sharing.d.ts.map +1 -0
- package/sharing.js +117 -0
- package/sharing.js.map +1 -0
- package/src/__tests__/errors.test.ts +56 -0
- package/src/__tests__/guest-auth.test.ts +287 -0
- package/src/__tests__/sharing.test.ts +159 -0
- package/src/gen/agentshare.ts +148 -0
- package/src/gen/authorization-config.ts +1 -0
- package/src/gen/client.ts +5 -0
- package/src/gen/environment.ts +7 -1
- package/src/gen/platformclient.ts +7 -1
- package/src/gen/session.ts +3 -3
- package/src/guest-auth.ts +334 -0
- package/src/index.ts +25 -0
- package/src/sharing.ts +135 -0
package/src/sharing.ts
ADDED
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent-sharing helpers — the single source of truth for the hosted chat
|
|
3
|
+
* URL shape, the embed snippet, and client-side `allowed_origins`
|
|
4
|
+
* validation. Framework-free by design: consumed by the web console and
|
|
5
|
+
* desktop app (via `@stigmer/react`), the `stigmer` CLI, and any platform
|
|
6
|
+
* builder that wants to construct share links or embed snippets itself.
|
|
7
|
+
*
|
|
8
|
+
* The canonical URL shape is `<app-origin>/chat/<org>/<slug>` (a T01
|
|
9
|
+
* design decision), and `embed.js` is served from the root of that same
|
|
10
|
+
* app origin (T04). Callers supply the origin — resolving it is a host
|
|
11
|
+
* concern (the console knows its `appUrl`, the CLI resolves it from the
|
|
12
|
+
* backend type) — while the path and snippet shapes live here so every
|
|
13
|
+
* surface emits byte-identical output.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
/** Maximum number of allowed origins (proto: `repeated.max_items = 32`). */
|
|
17
|
+
export const MAX_ALLOWED_ORIGINS = 32;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Exact web origin: scheme://host[:port] — no path, query, fragment, or
|
|
21
|
+
* trailing slash. Mirrors the CEL expression `allowed_origins.format` on
|
|
22
|
+
* `AgentShareSpec` (`apis/ai/stigmer/agentic/agentshare/v1/spec.proto`).
|
|
23
|
+
*
|
|
24
|
+
* The proto is the source of truth — if the CEL expression changes, this
|
|
25
|
+
* pattern must change with it. Mirroring it client-side gives immediate
|
|
26
|
+
* feedback instead of a round-trip rejection.
|
|
27
|
+
*/
|
|
28
|
+
const ORIGIN_PATTERN =
|
|
29
|
+
/^https?:\/\/[A-Za-z0-9]([A-Za-z0-9-]*[A-Za-z0-9])?(\.[A-Za-z0-9]([A-Za-z0-9-]*[A-Za-z0-9])?)*(:[0-9]{1,5})?$/;
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Validate a single `allowed_origins` entry.
|
|
33
|
+
*
|
|
34
|
+
* Returns `null` when valid, or a user-facing message explaining what
|
|
35
|
+
* to fix (DD-006: errors state what happened and what to do).
|
|
36
|
+
*/
|
|
37
|
+
export function validateOrigin(value: string): string | null {
|
|
38
|
+
const trimmed = value.trim();
|
|
39
|
+
if (!trimmed) return "Enter an origin, like https://example.com";
|
|
40
|
+
if (!ORIGIN_PATTERN.test(trimmed)) {
|
|
41
|
+
return "Must be an exact web origin like https://example.com — no path, query, or trailing slash";
|
|
42
|
+
}
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Query parameter carrying the share-link token on a locked link:
|
|
48
|
+
* `/chat/<org>/<slug>?k=<token>`. Short by design — the token rides every
|
|
49
|
+
* copied link, and `k` (for "key") is the platform's one-character
|
|
50
|
+
* convention, mirrored by the hosted page and the embed widget.
|
|
51
|
+
*/
|
|
52
|
+
export const LINK_TOKEN_PARAM = "k";
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* The hosted chat page path for a shared agent: `/chat/<org>/<slug>`
|
|
56
|
+
* (the AgentShare's org and slug — the slug defaults to the agent's),
|
|
57
|
+
* plus `?k=<token>` when the share link is locked with a rotatable
|
|
58
|
+
* token (`AgentShareStatus.share_link_token`).
|
|
59
|
+
*
|
|
60
|
+
* Useful on its own when the caller renders relative to the current
|
|
61
|
+
* origin (e.g. a host that never configured an absolute app URL).
|
|
62
|
+
*/
|
|
63
|
+
export function chatPath(org: string, slug: string, linkToken?: string): string {
|
|
64
|
+
const path = `/chat/${org}/${slug}`;
|
|
65
|
+
return linkToken
|
|
66
|
+
? `${path}?${LINK_TOKEN_PARAM}=${encodeURIComponent(linkToken)}`
|
|
67
|
+
: path;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* The absolute hosted chat URL for a shared agent:
|
|
72
|
+
* `<appOrigin>/chat/<org>/<slug>[?k=<token>]`.
|
|
73
|
+
*
|
|
74
|
+
* A trailing slash on `appOrigin` is tolerated so callers can pass
|
|
75
|
+
* user-configured values verbatim. An empty `appOrigin` degrades to the
|
|
76
|
+
* relative {@link chatPath} — the same graceful fallback a host without a
|
|
77
|
+
* configured public origin gets in the share dialog.
|
|
78
|
+
*/
|
|
79
|
+
export function buildChatUrl(
|
|
80
|
+
appOrigin: string,
|
|
81
|
+
org: string,
|
|
82
|
+
slug: string,
|
|
83
|
+
linkToken?: string,
|
|
84
|
+
): string {
|
|
85
|
+
return stripTrailingSlash(appOrigin) + chatPath(org, slug, linkToken);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Append the share-link token to an already-built chat URL.
|
|
90
|
+
*
|
|
91
|
+
* For hosts that construct the base URL through their own callback (the
|
|
92
|
+
* share dialog's `buildShareUrl` prop) rather than {@link buildChatUrl}.
|
|
93
|
+
* A `null`/empty token returns the URL unchanged, so callers can pass
|
|
94
|
+
* `share.status?.shareLinkToken` straight through. Emits the identical
|
|
95
|
+
* `?k=` shape as {@link chatPath} — one URL grammar across every surface.
|
|
96
|
+
*/
|
|
97
|
+
export function appendLinkToken(url: string, linkToken: string | null | undefined): string {
|
|
98
|
+
if (!linkToken) return url;
|
|
99
|
+
const separator = url.includes("?") ? "&" : "?";
|
|
100
|
+
return `${url}${separator}${LINK_TOKEN_PARAM}=${encodeURIComponent(linkToken)}`;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* The embed loader URL: `embed.js` lives at the root of the app origin
|
|
105
|
+
* (the loader derives the chat-page origin from its own script URL, so
|
|
106
|
+
* the two must share an origin). An empty `appOrigin` degrades to the
|
|
107
|
+
* relative `/embed.js`.
|
|
108
|
+
*/
|
|
109
|
+
export function buildEmbedLoaderUrl(appOrigin: string): string {
|
|
110
|
+
return `${stripTrailingSlash(appOrigin)}/embed.js`;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* The two-line embed snippet an owner pastes into any website: the
|
|
115
|
+
* loader script plus the `<stigmer-agent>` element where the widget
|
|
116
|
+
* renders. A locked share link adds the `token` attribute, which the
|
|
117
|
+
* widget forwards as `?k=` on its iframe URL. Every surface (share
|
|
118
|
+
* dialog, CLI, docs) emits exactly this.
|
|
119
|
+
*/
|
|
120
|
+
export function buildEmbedSnippet(
|
|
121
|
+
appOrigin: string,
|
|
122
|
+
org: string,
|
|
123
|
+
slug: string,
|
|
124
|
+
linkToken?: string,
|
|
125
|
+
): string {
|
|
126
|
+
const tokenAttribute = linkToken ? ` token="${linkToken}"` : "";
|
|
127
|
+
return [
|
|
128
|
+
`<script src="${buildEmbedLoaderUrl(appOrigin)}" async></script>`,
|
|
129
|
+
`<stigmer-agent org="${org}" agent="${slug}"${tokenAttribute}></stigmer-agent>`,
|
|
130
|
+
].join("\n");
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
function stripTrailingSlash(origin: string): string {
|
|
134
|
+
return origin.endsWith("/") ? origin.slice(0, -1) : origin;
|
|
135
|
+
}
|