@sapiom/harness 0.1.5 → 0.1.6
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 +61 -0
- package/dist/cli/bin.js +24 -7
- package/dist/cli/bin.js.map +1 -1
- package/dist/cli/consent.js +1 -1
- package/dist/core/adapters/adapter.d.ts +2 -2
- package/dist/core/api-key-provider.d.ts +79 -0
- package/dist/core/api-key-provider.d.ts.map +1 -0
- package/dist/core/api-key-provider.js +91 -0
- package/dist/core/api-key-provider.js.map +1 -0
- package/dist/core/canvas-run-state.d.ts +9 -5
- package/dist/core/canvas-run-state.d.ts.map +1 -1
- package/dist/core/canvas-run-state.js +42 -13
- package/dist/core/canvas-run-state.js.map +1 -1
- package/dist/core/definition-slug-resolver.d.ts +13 -0
- package/dist/core/definition-slug-resolver.d.ts.map +1 -1
- package/dist/core/definition-slug-resolver.js +29 -0
- package/dist/core/definition-slug-resolver.js.map +1 -1
- package/dist/core/render-local-run.d.ts +82 -0
- package/dist/core/render-local-run.d.ts.map +1 -0
- package/dist/core/render-local-run.js +105 -0
- package/dist/core/render-local-run.js.map +1 -0
- package/dist/core/render-log-slice.d.ts +30 -0
- package/dist/core/render-log-slice.d.ts.map +1 -0
- package/dist/core/render-log-slice.js +49 -0
- package/dist/core/render-log-slice.js.map +1 -0
- package/dist/core/render-run-state.d.ts.map +1 -1
- package/dist/core/render-run-state.js +30 -49
- package/dist/core/render-run-state.js.map +1 -1
- package/dist/core/run-local-bootstrap.d.ts +93 -0
- package/dist/core/run-local-bootstrap.d.ts.map +1 -0
- package/dist/core/run-local-bootstrap.js +155 -0
- package/dist/core/run-local-bootstrap.js.map +1 -0
- package/dist/core/run-state.d.ts +16 -1
- package/dist/core/run-state.d.ts.map +1 -1
- package/dist/core/run-state.js +75 -25
- package/dist/core/run-state.js.map +1 -1
- package/dist/core/stub-feedback.d.ts +52 -0
- package/dist/core/stub-feedback.d.ts.map +1 -0
- package/dist/core/stub-feedback.js +33 -0
- package/dist/core/stub-feedback.js.map +1 -0
- package/dist/server/actions.d.ts +139 -0
- package/dist/server/actions.d.ts.map +1 -0
- package/dist/server/actions.js +430 -0
- package/dist/server/actions.js.map +1 -0
- package/dist/server/auth-routes.d.ts +92 -0
- package/dist/server/auth-routes.d.ts.map +1 -0
- package/dist/server/auth-routes.js +151 -0
- package/dist/server/auth-routes.js.map +1 -0
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +0 -0
- package/dist/server/index.js.map +1 -1
- package/dist/server/rest.d.ts.map +1 -1
- package/dist/server/rest.js +0 -2
- package/dist/server/rest.js.map +1 -1
- package/dist/server/runs.d.ts +16 -15
- package/dist/server/runs.d.ts.map +1 -1
- package/dist/server/runs.js +15 -80
- package/dist/server/runs.js.map +1 -1
- package/dist/server/static.d.ts +15 -1
- package/dist/server/static.d.ts.map +1 -1
- package/dist/server/static.js +54 -4
- package/dist/server/static.js.map +1 -1
- package/dist/shared/types.d.ts +79 -35
- package/dist/shared/types.d.ts.map +1 -1
- package/dist/shared/types.js.map +1 -1
- package/dist/web/assets/index-DCtyI4VW.css +32 -0
- package/dist/web/assets/index-WSw5RvYR.js +445 -0
- package/dist/web/canvas/sess-boot/index.html +305 -0
- package/dist/web/index.html +4 -9
- package/dist/web/welcome-hero-dark.png +0 -0
- package/dist/web/welcome-hero-light.png +0 -0
- package/package.json +6 -3
- package/dist/core/run-spend.d.ts +0 -55
- package/dist/core/run-spend.d.ts.map +0 -1
- package/dist/core/run-spend.js +0 -109
- package/dist/core/run-spend.js.map +0 -1
- package/dist/core/run-transactions.d.ts +0 -60
- package/dist/core/run-transactions.d.ts.map +0 -1
- package/dist/core/run-transactions.js +0 -129
- package/dist/core/run-transactions.js.map +0 -1
- package/dist/server/skills.d.ts +0 -51
- package/dist/server/skills.d.ts.map +0 -1
- package/dist/server/skills.js +0 -312
- package/dist/server/skills.js.map +0 -1
- package/dist/web/assets/index-DM84J83Y.js +0 -234
- package/dist/web/assets/index-DemtWW4L.css +0 -32
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,66 @@
|
|
|
1
1
|
# @sapiom/harness
|
|
2
2
|
|
|
3
|
+
## 0.1.6
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- b6b9d16: Add a server-side actions router with direct Deploy and Prod-run routes:
|
|
8
|
+
|
|
9
|
+
- `POST /api/workflows/:id/deploy` deploys a linked agent and streams build status as NDJSON (a `building` line up front, then a terminal `ready`/`error` line).
|
|
10
|
+
- `POST /api/runs` `{ definitionId, input }` starts an execution and returns `{ executionId }`.
|
|
11
|
+
|
|
12
|
+
Both run entirely server-side with the held API key (never exposed to the browser) and require no coding-agent session, so an action consumes no LLM credits.
|
|
13
|
+
|
|
14
|
+
- b6b9d16: Enrich the step debug/explain context with the run's real per-step evidence. When you ask the agent to debug or explain a step from the run inspector, the injected context now folds in the step's actual input and output, the capabilities it called (with a marker for any served by a stub), and — for offline runs — supplied stubs that matched nothing or carried the wrong shape, on top of the step's status, latency, error, and logs. Every section is emitted only when the trace carries it (no fabricated placeholders), and the context names capabilities, never a model, so "why did this step do X" carries the real evidence instead of just the step name.
|
|
15
|
+
- b6b9d16: Extend the expired/rotated API key recovery to the Deploy and Prod-run actions. When one of these actions is rejected as unauthorized, the Studio now re-reads your cached credentials and retries once — so signing in again (in the CLI or elsewhere) unblocks Deploy/Prod-run in place, matching the live-run status path, instead of every action staying stuck on the stale key until a restart.
|
|
16
|
+
- b6b9d16: The Harness Studio presents your coding agent in a terminal view.
|
|
17
|
+
- b6b9d16: Studio run and step-inspection hardening:
|
|
18
|
+
|
|
19
|
+
- Auto-bind a session to the workflow in its folder the moment the session starts, not only when a file later changes — so the canvas and Run actions light up immediately for an existing workflow.
|
|
20
|
+
- Animate the canvas board (per-step running / passed / failed status) during both local and production runs.
|
|
21
|
+
- Never let a direct action (Local Run / Prod Run / Deploy) fail silently: surface the reason on a blocked click, clear the in-flight indicator when the action settles, and distinguish "deploy failed — retry" from "not deployed yet".
|
|
22
|
+
- Enrich the step inspector: per-step input/output and logs, the capability calls a step made (with the served stub values on offline runs), and clickable preview / download / research links found in a step's output — all shown when you click into a step.
|
|
23
|
+
|
|
24
|
+
- b6b9d16: Degrade gracefully when the Studio is offline or the session drops. Losing your network connection no longer blanks the Studio: a boot failure now shows an honest, recoverable state (offline / session needs a refresh / server unreachable) with a Retry that reconnects in place, and a non-blocking banner appears if the connection drops mid-session so the app stays usable against its last-known state. A rejected credential surfaces as a recoverable "reconnect" state rather than a hard lockout. These states are wired to real signals (the browser's connectivity and the kind of the failed request).
|
|
25
|
+
- b6b9d16: Recover from an expired or rotated API key instead of getting stuck. When a live-run status request is rejected as unauthorized, the Studio now re-reads your cached credentials and retries once, so signing in again (in the CLI or elsewhere) unblocks the app in place rather than requiring a restart. Studio actions always authenticate with your held API key.
|
|
26
|
+
- b6b9d16: Remove the Studio's cost and pricing surfaces. The wallet card, the per-workflow price note, and per-step cost figures are gone; the run inspector now shows logs, latency, and pass/fail only. `StepView` no longer carries a `costUsd` field.
|
|
27
|
+
- b6b9d16: Remove the run spend and transactions endpoints (`GET /api/runs/:executionId/spend` and `/transactions`) and their supporting fetchers. The runs router now serves only run state (`GET /api/runs/:executionId/state`).
|
|
28
|
+
- b6b9d16: Restore the bundled demo canvas document (`web/public/canvas/sess-boot/`) the
|
|
29
|
+
Studio's mock/demo mode renders on first paint. The web app already references
|
|
30
|
+
it (the demo session opens on its seeded board), but the file was missing, so
|
|
31
|
+
the canvas pane stayed empty in demo mode. This is demo/mock-only content; real
|
|
32
|
+
local mode still renders the server-generated canvas.
|
|
33
|
+
- b6b9d16: Show real per-step input and output in the run inspector's "Last run" section. When a step's run recorded the value it ran on and the value it produced, each is rendered as a collapsible, inspectable payload; a step that carried no input/output shows no block at all (never a fabricated placeholder). Objects are pretty-printed, plain strings shown as-is, and a real `null`/`false`/`0` is displayed faithfully.
|
|
34
|
+
- b6b9d16: Add `POST /api/runs/local`: run an agent entirely offline against stub capabilities and stream the result back as NDJSON — one per-step trace line, then a terminal summary carrying the run outcome plus which supplied stub keys went unused or had the wrong shape. It runs in a child process, needs no sign-in, and makes no network call, so a local run works signed-out and at zero cost.
|
|
35
|
+
- b6b9d16: Serve the harness web UI from the package build and harden the design-system seam:
|
|
36
|
+
|
|
37
|
+
- `pnpm build` emits the web app to `dist/web` and the harness server serves it as the SPA (index.html, hashed assets, and client-side deep-route fallback), so `start` and `npx @sapiom/harness` launch the full UI against the real server. Adds a regression test pinning the build → serve path.
|
|
38
|
+
- The design system resolves to the real package when it's installed and falls back to a committed neutral, unbranded token set otherwise — so a public build renders legibly out of the box, with no theme source required. The stylesheet only bridges variable names onto tokens; it never redefines a token.
|
|
39
|
+
|
|
40
|
+
No behavioral or API changes to the harness server.
|
|
41
|
+
|
|
42
|
+
- b6b9d16: Surface how an offline run's stubs behaved in the run inspector. A step that ran in an offline (stub) run now shows a read-only "stubbed" chip on its row and in its detail, so it is clear its capability calls were served by stubs rather than real calls. The inspector also shows, when present, a read-only notice for supplied stubs that matched no capability call (a no-op mock — usually a typo or the wrong path) and for stubs whose value had the wrong shape — so a stub that silently did nothing is visible instead of a mystery. Nothing is shown when a run has no such issues, and the affordance names capabilities, never a model. Real (non-offline) runs are unaffected.
|
|
43
|
+
- b6b9d16: Refresh the harness web UI with a rebuilt workspace: a three-zone layout (an on-disk explorer of your agents, a per-agent workbench with a session tab strip, and session-keyed projections — Canvas / Steps / Code / Skills), a command palette, a chat/terminal view toggle, and a click-into-step run inspector. The bundle ships with a neutral, unbranded default theme so a public build renders legibly out of the box; light and dark are both supported. No behavioral or API changes to the harness server.
|
|
44
|
+
- b6b9d16: Point the harness web UI's `@shared/types` alias at the package's own shared contract instead of a vendored copy, so the web and server always build against a single source of truth. The snippet panel now reads the real deployed-agent slug and executions base URL when the server provides them, falling back cleanly when it does not. No behavioral or API changes to the harness server.
|
|
45
|
+
- b6b9d16: Wire prod and offline run logs into the Studio's click-into-step run inspector.
|
|
46
|
+
|
|
47
|
+
- **Prod runs** light up per-step in the inspector as they progress — status, latency, pass/fail, and (when the run carries them) the step's real input and output. The inspector polls the run's state after it starts and stops quietly once the run finishes or can't be found, so a click into any step shows what it actually did.
|
|
48
|
+
- **Offline stub runs** render in the SAME inspector: their streamed per-step trace is mapped into the identical step view (logs, pass/fail, and the input/output each step ran on), so an offline run reads exactly like a real one — just free and untimed, since a stub run records no cost or duration.
|
|
49
|
+
|
|
50
|
+
Both paths share one step-render shape, so the inspector can never disagree with itself about how a run looks. The inspector names the capability a step called, never a model.
|
|
51
|
+
|
|
52
|
+
- b6b9d16: Restore the `resolveCoreBaseUrl` helper that the actions router relies on to derive the core API base URL. It is now co-located with `resolveAgentsBaseUrl` (its only dependency) instead of living in a since-removed module, so the harness server builds and the actions router self-defaults its base URL again.
|
|
53
|
+
- b6b9d16: Wire the Studio's Deploy, Prod-run, and Run-local buttons to their direct routes instead of typing a command into the coding agent:
|
|
54
|
+
|
|
55
|
+
- **Deploy** streams build status and refreshes the workflow once it publishes, flipping the Draft/Deployed state.
|
|
56
|
+
- **Prod-run** starts a real execution and hands the new execution off to the run inspector, so it shows up in the Steps view.
|
|
57
|
+
- **Run-local** runs the workflow offline with capabilities stubbed and reports the outcome — no network, no spend.
|
|
58
|
+
|
|
59
|
+
These three actions now run without a coding-agent session, so they consume no LLM credits. Debug, Explain, and free-form prompts still go through the coding agent, and Visualize is unchanged.
|
|
60
|
+
|
|
61
|
+
- Updated dependencies [b6b9d16]
|
|
62
|
+
- @sapiom/agent-core@0.9.9
|
|
63
|
+
|
|
3
64
|
## 0.1.5
|
|
4
65
|
|
|
5
66
|
### Patch Changes
|
package/dist/cli/bin.js
CHANGED
|
@@ -2,11 +2,16 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* sapiom-harness CLI entry (workstream W4).
|
|
4
4
|
*
|
|
5
|
-
* Flow: doctor → auth (reuse
|
|
6
|
-
*
|
|
5
|
+
* Flow: doctor → auth (non-blocking: reuse cached credential if present, skip
|
|
6
|
+
* browser OAuth at boot) → consent (first run) → generate boot token →
|
|
7
|
+
* startServer → open browser → print a startup banner.
|
|
7
8
|
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
9
|
+
* The Studio launches unauthenticated when no cached credential exists; the
|
|
10
|
+
* web app drives sign-in (D4/D5). Use --login to trigger an interactive
|
|
11
|
+
* browser OAuth before the server starts.
|
|
12
|
+
*
|
|
13
|
+
* Flags: [dir] (default cwd), --port, --login, --no-auth, --no-telemetry,
|
|
14
|
+
* --no-open, --no-session, --dev.
|
|
10
15
|
*/
|
|
11
16
|
import * as path from "node:path";
|
|
12
17
|
import * as crypto from "node:crypto";
|
|
@@ -21,6 +26,7 @@ import { startServer } from "../server/index.js";
|
|
|
21
26
|
function parseArgs(argv) {
|
|
22
27
|
let dir;
|
|
23
28
|
let port = DEFAULT_PORT;
|
|
29
|
+
let login = false;
|
|
24
30
|
let noAuth = false;
|
|
25
31
|
let noTelemetry = false;
|
|
26
32
|
let noOpen = false;
|
|
@@ -37,6 +43,9 @@ function parseArgs(argv) {
|
|
|
37
43
|
port = Number(value);
|
|
38
44
|
break;
|
|
39
45
|
}
|
|
46
|
+
case "--login":
|
|
47
|
+
login = true;
|
|
48
|
+
break;
|
|
40
49
|
case "--no-auth":
|
|
41
50
|
noAuth = true;
|
|
42
51
|
break;
|
|
@@ -65,6 +74,7 @@ function parseArgs(argv) {
|
|
|
65
74
|
return {
|
|
66
75
|
dir: path.resolve(dir ?? process.cwd()),
|
|
67
76
|
port,
|
|
77
|
+
login,
|
|
68
78
|
noAuth,
|
|
69
79
|
noTelemetry,
|
|
70
80
|
noOpen,
|
|
@@ -77,8 +87,8 @@ function printBanner(opts) {
|
|
|
77
87
|
? `${opts.identity.organizationName} (${opts.identity.userId})${opts.identity.source === "cached" ? " — cached" : ""}`
|
|
78
88
|
: "not authenticated";
|
|
79
89
|
console.log("");
|
|
80
|
-
console.log(" Sapiom
|
|
81
|
-
console.log("
|
|
90
|
+
console.log(" Sapiom Studio");
|
|
91
|
+
console.log(" -------------");
|
|
82
92
|
console.log(` directory ${opts.dir}`);
|
|
83
93
|
console.log(` auth ${authLine}`);
|
|
84
94
|
console.log(` telemetry ${opts.telemetryOptIn ? "on" : "off"}`);
|
|
@@ -105,7 +115,14 @@ const main = async () => {
|
|
|
105
115
|
" Continuing with the Codex harness.");
|
|
106
116
|
}
|
|
107
117
|
const machineId = await getOrCreateMachineId();
|
|
108
|
-
|
|
118
|
+
// Auth is non-blocking at boot: use a cached credential if one exists, but
|
|
119
|
+
// never open a browser at startup. The Studio launches unauthenticated and
|
|
120
|
+
// the web app drives sign-in (D4/D5). Pass --login to run an interactive
|
|
121
|
+
// browser OAuth before the server starts.
|
|
122
|
+
const identity = await ensureAuthenticated({
|
|
123
|
+
interactive: options.login,
|
|
124
|
+
noAuth: options.noAuth,
|
|
125
|
+
});
|
|
109
126
|
// A cached credential signs you in with no visible prompt at all — call it
|
|
110
127
|
// out explicitly so "auth silently worked" doesn't read as "nothing
|
|
111
128
|
// happened" (a fresh login is its own visible browser flow already).
|
package/dist/cli/bin.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bin.js","sourceRoot":"","sources":["../../src/cli/bin.ts"],"names":[],"mappings":";AACA
|
|
1
|
+
{"version":3,"file":"bin.js","sourceRoot":"","sources":["../../src/cli/bin.ts"],"names":[],"mappings":"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"}
|
package/dist/cli/consent.js
CHANGED
|
@@ -13,7 +13,7 @@ import { hasStoredSettings, loadSettings, saveSettings } from "./settings.js";
|
|
|
13
13
|
// which surfaces this path to interactive users who did get the default.
|
|
14
14
|
const DEFAULT_TELEMETRY_OPT_IN = true;
|
|
15
15
|
const CONSENT_COPY = `
|
|
16
|
-
Sapiom
|
|
16
|
+
Sapiom Studio collects usage analytics locally and, with telemetry on,
|
|
17
17
|
sends them to Sapiom to improve the product:
|
|
18
18
|
- the prompts you send and the tool calls your agent makes
|
|
19
19
|
- session start/stop lifecycle events
|
|
@@ -30,8 +30,8 @@ export interface HarnessAdapterBase {
|
|
|
30
30
|
/**
|
|
31
31
|
* Per-agent prompt text guiding the user through installing and
|
|
32
32
|
* configuring the Sapiom MCP server (`@sapiom/mcp`) for this harness.
|
|
33
|
-
*
|
|
34
|
-
*
|
|
33
|
+
* Rendered in the Install MCP modal. Returns the text string directly —
|
|
34
|
+
* callers may render it as preformatted text.
|
|
35
35
|
*/
|
|
36
36
|
installMcpPrompt(): string;
|
|
37
37
|
/**
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* api-key-provider — the single source of truth for the Sapiom API key that
|
|
3
|
+
* Studio actions authenticate with server-side.
|
|
4
|
+
*
|
|
5
|
+
* WHY this exists: the key is resolved ONCE at CLI boot (from the cached
|
|
6
|
+
* credential or a fresh browser login) and then handed to the server as a plain
|
|
7
|
+
* string. Two problems fell out of that snapshot:
|
|
8
|
+
*
|
|
9
|
+
* 1. It never refreshes. If the key is rotated/revoked — or the user runs the
|
|
10
|
+
* shared login again in another process, rewriting the credential store —
|
|
11
|
+
* the running Studio server keeps sending the stale key and every upstream
|
|
12
|
+
* call 401s until the whole server is restarted. There was no re-auth path.
|
|
13
|
+
* 2. It conflated two different secrets. The per-boot *boot token*
|
|
14
|
+
* (`X-Harness-Token`) only gates the LOCAL `/api` surface; the *API key*
|
|
15
|
+
* (`sk_…`) is what authenticates upstream Sapiom calls. Studio actions must
|
|
16
|
+
* authenticate with the held API key, never the boot token.
|
|
17
|
+
*
|
|
18
|
+
* This provider holds the current key behind a getter (so consumers read the
|
|
19
|
+
* live value, not a boot-time copy) and can `refresh()` it by re-reading the
|
|
20
|
+
* shared credential store the CLI/MCP login writes to
|
|
21
|
+
* (`~/.sapiom/credentials.json`, via `@sapiom/mcp/auth`). A 401 from an
|
|
22
|
+
* upstream call can therefore recover in place — refresh, then retry — instead
|
|
23
|
+
* of locking the Studio.
|
|
24
|
+
*
|
|
25
|
+
* NOT in scope (deliberately, per the ticket): triggering an interactive
|
|
26
|
+
* browser re-login from the server, or a broader session-auth redesign. Refresh
|
|
27
|
+
* here is a silent re-read of already-cached credentials; if the store has no
|
|
28
|
+
* newer key, the call surfaces the auth error honestly.
|
|
29
|
+
*/
|
|
30
|
+
/**
|
|
31
|
+
* Reads the currently-held API key and can refresh it from the shared
|
|
32
|
+
* credential store. Consumers should call {@link getKey} per request (never
|
|
33
|
+
* cache the returned string across requests) and {@link refresh} exactly once
|
|
34
|
+
* when an upstream call returns 401/403, retrying only if refresh yields a
|
|
35
|
+
* different, non-null key.
|
|
36
|
+
*/
|
|
37
|
+
export interface ApiKeyProvider {
|
|
38
|
+
/** The current API key, or null when the harness is not signed in. */
|
|
39
|
+
getKey(): string | null;
|
|
40
|
+
/**
|
|
41
|
+
* Re-read the shared credential store and adopt any newer key found there.
|
|
42
|
+
* Returns the (possibly updated) current key, or null if none is available.
|
|
43
|
+
* Never throws — a read failure leaves the current key untouched and is
|
|
44
|
+
* reported by returning the existing value.
|
|
45
|
+
*/
|
|
46
|
+
refresh(): Promise<string | null>;
|
|
47
|
+
/**
|
|
48
|
+
* Unconditionally zero the in-memory key (sets it to null). Called on
|
|
49
|
+
* disconnect so that {@link getKey} returns null immediately — distinct from
|
|
50
|
+
* {@link refresh}, whose `if (latest)` guard deliberately preserves the
|
|
51
|
+
* cached key when the credential store has nothing to offer.
|
|
52
|
+
*/
|
|
53
|
+
clear(): void;
|
|
54
|
+
}
|
|
55
|
+
/** Overridable reads for the credential store — a test seam. Defaults hit the
|
|
56
|
+
* real `@sapiom/mcp/auth` store the CLI login writes to. */
|
|
57
|
+
export interface ApiKeyProviderDeps {
|
|
58
|
+
/** Resolve the active environment name (governs which cached entry to read). */
|
|
59
|
+
resolveEnvironmentName?: () => Promise<string>;
|
|
60
|
+
/** Read the cached API key for a given environment, or null if absent. */
|
|
61
|
+
readApiKeyForEnv?: (envName: string) => Promise<string | null>;
|
|
62
|
+
/** Overrides SAPIOM_ENVIRONMENT for environment resolution. */
|
|
63
|
+
environment?: string;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Build an {@link ApiKeyProvider} seeded with the boot-time key. `refresh()`
|
|
67
|
+
* re-reads the shared credential store for the active environment and adopts a
|
|
68
|
+
* newer key when one is present — the reconciliation point between the key the
|
|
69
|
+
* CLI captured at boot and any key rotated/re-logged-in afterward.
|
|
70
|
+
*/
|
|
71
|
+
export declare function createApiKeyProvider(initialKey: string | null, deps?: ApiKeyProviderDeps): ApiKeyProvider;
|
|
72
|
+
/**
|
|
73
|
+
* Adapt a plain `string | null` API key into an {@link ApiKeyProvider} whose
|
|
74
|
+
* `refresh()` is a no-op and `clear()` is a no-op. Lets call sites that only
|
|
75
|
+
* ever have a static key (tests, callers with no credential store) share the
|
|
76
|
+
* one provider-shaped contract without special-casing.
|
|
77
|
+
*/
|
|
78
|
+
export declare function staticApiKeyProvider(key: string | null): ApiKeyProvider;
|
|
79
|
+
//# sourceMappingURL=api-key-provider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api-key-provider.d.ts","sourceRoot":"","sources":["../../src/core/api-key-provider.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAIH;;;;;;GAMG;AACH,MAAM,WAAW,cAAc;IAC7B,sEAAsE;IACtE,MAAM,IAAI,MAAM,GAAG,IAAI,CAAC;IACxB;;;;;OAKG;IACH,OAAO,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAClC;;;;;OAKG;IACH,KAAK,IAAI,IAAI,CAAC;CACf;AAED;6DAC6D;AAC7D,MAAM,WAAW,kBAAkB;IACjC,gFAAgF;IAChF,sBAAsB,CAAC,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;IAC/C,0EAA0E;IAC1E,gBAAgB,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAC/D,+DAA+D;IAC/D,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAkBD;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAClC,UAAU,EAAE,MAAM,GAAG,IAAI,EACzB,IAAI,GAAE,kBAAuB,GAC5B,cAAc,CA8BhB;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,cAAc,CAQvE"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* api-key-provider — the single source of truth for the Sapiom API key that
|
|
3
|
+
* Studio actions authenticate with server-side.
|
|
4
|
+
*
|
|
5
|
+
* WHY this exists: the key is resolved ONCE at CLI boot (from the cached
|
|
6
|
+
* credential or a fresh browser login) and then handed to the server as a plain
|
|
7
|
+
* string. Two problems fell out of that snapshot:
|
|
8
|
+
*
|
|
9
|
+
* 1. It never refreshes. If the key is rotated/revoked — or the user runs the
|
|
10
|
+
* shared login again in another process, rewriting the credential store —
|
|
11
|
+
* the running Studio server keeps sending the stale key and every upstream
|
|
12
|
+
* call 401s until the whole server is restarted. There was no re-auth path.
|
|
13
|
+
* 2. It conflated two different secrets. The per-boot *boot token*
|
|
14
|
+
* (`X-Harness-Token`) only gates the LOCAL `/api` surface; the *API key*
|
|
15
|
+
* (`sk_…`) is what authenticates upstream Sapiom calls. Studio actions must
|
|
16
|
+
* authenticate with the held API key, never the boot token.
|
|
17
|
+
*
|
|
18
|
+
* This provider holds the current key behind a getter (so consumers read the
|
|
19
|
+
* live value, not a boot-time copy) and can `refresh()` it by re-reading the
|
|
20
|
+
* shared credential store the CLI/MCP login writes to
|
|
21
|
+
* (`~/.sapiom/credentials.json`, via `@sapiom/mcp/auth`). A 401 from an
|
|
22
|
+
* upstream call can therefore recover in place — refresh, then retry — instead
|
|
23
|
+
* of locking the Studio.
|
|
24
|
+
*
|
|
25
|
+
* NOT in scope (deliberately, per the ticket): triggering an interactive
|
|
26
|
+
* browser re-login from the server, or a broader session-auth redesign. Refresh
|
|
27
|
+
* here is a silent re-read of already-cached credentials; if the store has no
|
|
28
|
+
* newer key, the call surfaces the auth error honestly.
|
|
29
|
+
*/
|
|
30
|
+
import { readCredentials, resolveEnvironment } from "@sapiom/mcp/auth";
|
|
31
|
+
async function defaultResolveEnvironmentName(environment) {
|
|
32
|
+
const env = await resolveEnvironment(environment ?? process.env.SAPIOM_ENVIRONMENT);
|
|
33
|
+
return env.name;
|
|
34
|
+
}
|
|
35
|
+
async function defaultReadApiKeyForEnv(envName) {
|
|
36
|
+
const entry = await readCredentials(envName);
|
|
37
|
+
return entry?.apiKey ?? null;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Build an {@link ApiKeyProvider} seeded with the boot-time key. `refresh()`
|
|
41
|
+
* re-reads the shared credential store for the active environment and adopts a
|
|
42
|
+
* newer key when one is present — the reconciliation point between the key the
|
|
43
|
+
* CLI captured at boot and any key rotated/re-logged-in afterward.
|
|
44
|
+
*/
|
|
45
|
+
export function createApiKeyProvider(initialKey, deps = {}) {
|
|
46
|
+
let current = initialKey;
|
|
47
|
+
const resolveEnvName = deps.resolveEnvironmentName ??
|
|
48
|
+
(() => defaultResolveEnvironmentName(deps.environment));
|
|
49
|
+
const readApiKey = deps.readApiKeyForEnv ?? defaultReadApiKeyForEnv;
|
|
50
|
+
return {
|
|
51
|
+
getKey() {
|
|
52
|
+
return current;
|
|
53
|
+
},
|
|
54
|
+
async refresh() {
|
|
55
|
+
try {
|
|
56
|
+
const envName = await resolveEnvName();
|
|
57
|
+
const latest = await readApiKey(envName);
|
|
58
|
+
// Only adopt a real, non-empty key. A missing/emptied credential must
|
|
59
|
+
// not clobber a key that's simply been rotated out from under us but is
|
|
60
|
+
// still the best value we have to report an honest auth error with.
|
|
61
|
+
if (latest)
|
|
62
|
+
current = latest;
|
|
63
|
+
}
|
|
64
|
+
catch {
|
|
65
|
+
// Store unreadable (HOME missing, malformed file, …) — keep the current
|
|
66
|
+
// key. The caller's retry will simply hit the same auth error, which is
|
|
67
|
+
// the correct, honest outcome.
|
|
68
|
+
}
|
|
69
|
+
return current;
|
|
70
|
+
},
|
|
71
|
+
clear() {
|
|
72
|
+
current = null;
|
|
73
|
+
},
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Adapt a plain `string | null` API key into an {@link ApiKeyProvider} whose
|
|
78
|
+
* `refresh()` is a no-op and `clear()` is a no-op. Lets call sites that only
|
|
79
|
+
* ever have a static key (tests, callers with no credential store) share the
|
|
80
|
+
* one provider-shaped contract without special-casing.
|
|
81
|
+
*/
|
|
82
|
+
export function staticApiKeyProvider(key) {
|
|
83
|
+
return {
|
|
84
|
+
getKey: () => key,
|
|
85
|
+
refresh: () => Promise.resolve(key),
|
|
86
|
+
clear: () => {
|
|
87
|
+
/* static key — clear is a no-op */
|
|
88
|
+
},
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=api-key-provider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api-key-provider.js","sourceRoot":"","sources":["../../src/core/api-key-provider.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAuCvE,KAAK,UAAU,6BAA6B,CAC1C,WAAoB;IAEpB,MAAM,GAAG,GAAG,MAAM,kBAAkB,CAClC,WAAW,IAAI,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAC9C,CAAC;IACF,OAAO,GAAG,CAAC,IAAI,CAAC;AAClB,CAAC;AAED,KAAK,UAAU,uBAAuB,CACpC,OAAe;IAEf,MAAM,KAAK,GAAG,MAAM,eAAe,CAAC,OAAO,CAAC,CAAC;IAC7C,OAAO,KAAK,EAAE,MAAM,IAAI,IAAI,CAAC;AAC/B,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,oBAAoB,CAClC,UAAyB,EACzB,OAA2B,EAAE;IAE7B,IAAI,OAAO,GAAG,UAAU,CAAC;IACzB,MAAM,cAAc,GAClB,IAAI,CAAC,sBAAsB;QAC3B,CAAC,GAAG,EAAE,CAAC,6BAA6B,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC;IAC1D,MAAM,UAAU,GAAG,IAAI,CAAC,gBAAgB,IAAI,uBAAuB,CAAC;IAEpE,OAAO;QACL,MAAM;YACJ,OAAO,OAAO,CAAC;QACjB,CAAC;QACD,KAAK,CAAC,OAAO;YACX,IAAI,CAAC;gBACH,MAAM,OAAO,GAAG,MAAM,cAAc,EAAE,CAAC;gBACvC,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,OAAO,CAAC,CAAC;gBACzC,sEAAsE;gBACtE,wEAAwE;gBACxE,oEAAoE;gBACpE,IAAI,MAAM;oBAAE,OAAO,GAAG,MAAM,CAAC;YAC/B,CAAC;YAAC,MAAM,CAAC;gBACP,wEAAwE;gBACxE,wEAAwE;gBACxE,+BAA+B;YACjC,CAAC;YACD,OAAO,OAAO,CAAC;QACjB,CAAC;QACD,KAAK;YACH,OAAO,GAAG,IAAI,CAAC;QACjB,CAAC;KACF,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,oBAAoB,CAAC,GAAkB;IACrD,OAAO;QACL,MAAM,EAAE,GAAG,EAAE,CAAC,GAAG;QACjB,OAAO,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC;QACnC,KAAK,EAAE,GAAG,EAAE;YACV,mCAAmC;QACrC,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -79,11 +79,15 @@ export declare function bootCanvasRunState(): void;
|
|
|
79
79
|
/**
|
|
80
80
|
* Wires the reverse click channel: iframe → parent.
|
|
81
81
|
*
|
|
82
|
-
* Adds
|
|
83
|
-
*
|
|
84
|
-
*
|
|
85
|
-
*
|
|
86
|
-
*
|
|
82
|
+
* Adds a delegated `click` listener on `document` AND a `message` listener for
|
|
83
|
+
* the harness gesture layer's `sapiom-canvas:pick` / `sapiom-canvas:hover`.
|
|
84
|
+
* The gesture layer overlays the iframe (for pan / zoom) and swallows raw
|
|
85
|
+
* clicks, so the direct listener alone never fires in the harness; the layer
|
|
86
|
+
* instead forwards the click/hover point, which we hit-test with
|
|
87
|
+
* `elementFromPoint`. Either path resolves the `.canvas-node[data-step-name]`
|
|
88
|
+
* under the point and posts `{ type: "sapiom:node-click", stepName }` to the
|
|
89
|
+
* parent (hover answers `{ type: "sapiom-canvas:hit", id }` for the cursor).
|
|
90
|
+
* The parent maps the step name to the current RunView to open the inspector.
|
|
87
91
|
*
|
|
88
92
|
* Uses a delegated listener (one listener on document) rather than per-node
|
|
89
93
|
* listeners so it works even when the SVG is replaced (e.g. after a
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"canvas-run-state.d.ts","sourceRoot":"","sources":["../../src/core/canvas-run-state.ts"],"names":[],"mappings":"AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAEH,MAAM,MAAM,aAAa,GAAG,SAAS,GAAG,SAAS,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAExE;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAKxD;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,qBAAqB,CACnC,GAAG,EAAE,QAAQ,EACb,GAAG,EAAE;IACH,KAAK,EAAE,KAAK,CAAC;QACX,IAAI,EAAE,MAAM,CAAC;QACb,EAAE,CAAC,EAAE,MAAM,CAAC;QACZ,MAAM,EAAE,MAAM,CAAC;QACf,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB,CAAC,CAAC;IACH,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB,GACA,IAAI,CA+CN;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,kBAAkB,IAAI,IAAI,CAMzC;AAED
|
|
1
|
+
{"version":3,"file":"canvas-run-state.d.ts","sourceRoot":"","sources":["../../src/core/canvas-run-state.ts"],"names":[],"mappings":"AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAEH,MAAM,MAAM,aAAa,GAAG,SAAS,GAAG,SAAS,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAExE;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAKxD;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,qBAAqB,CACnC,GAAG,EAAE,QAAQ,EACb,GAAG,EAAE;IACH,KAAK,EAAE,KAAK,CAAC;QACX,IAAI,EAAE,MAAM,CAAC;QACb,EAAE,CAAC,EAAE,MAAM,CAAC;QACZ,MAAM,EAAE,MAAM,CAAC;QACf,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB,CAAC,CAAC;IACH,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB,GACA,IAAI,CA+CN;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,kBAAkB,IAAI,IAAI,CAMzC;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,oBAAoB,IAAI,IAAI,CAqC3C"}
|
|
@@ -134,11 +134,15 @@ export function bootCanvasRunState() {
|
|
|
134
134
|
/**
|
|
135
135
|
* Wires the reverse click channel: iframe → parent.
|
|
136
136
|
*
|
|
137
|
-
* Adds
|
|
138
|
-
*
|
|
139
|
-
*
|
|
140
|
-
*
|
|
141
|
-
*
|
|
137
|
+
* Adds a delegated `click` listener on `document` AND a `message` listener for
|
|
138
|
+
* the harness gesture layer's `sapiom-canvas:pick` / `sapiom-canvas:hover`.
|
|
139
|
+
* The gesture layer overlays the iframe (for pan / zoom) and swallows raw
|
|
140
|
+
* clicks, so the direct listener alone never fires in the harness; the layer
|
|
141
|
+
* instead forwards the click/hover point, which we hit-test with
|
|
142
|
+
* `elementFromPoint`. Either path resolves the `.canvas-node[data-step-name]`
|
|
143
|
+
* under the point and posts `{ type: "sapiom:node-click", stepName }` to the
|
|
144
|
+
* parent (hover answers `{ type: "sapiom-canvas:hit", id }` for the cursor).
|
|
145
|
+
* The parent maps the step name to the current RunView to open the inspector.
|
|
142
146
|
*
|
|
143
147
|
* Uses a delegated listener (one listener on document) rather than per-node
|
|
144
148
|
* listeners so it works even when the SVG is replaced (e.g. after a
|
|
@@ -147,16 +151,41 @@ export function bootCanvasRunState() {
|
|
|
147
151
|
* Stringified into the iframe template by `canvas-template.ts`.
|
|
148
152
|
*/
|
|
149
153
|
export function bootCanvasNodeClicks() {
|
|
154
|
+
// Resolve the step name of the `.canvas-node[data-step-name]` at or above an
|
|
155
|
+
// element (null when the point/target is not on a node).
|
|
156
|
+
function stepNameAt(target) {
|
|
157
|
+
const node = target && target.closest ? target.closest(".canvas-node[data-step-name]") : null;
|
|
158
|
+
return node ? node.getAttribute("data-step-name") : null;
|
|
159
|
+
}
|
|
160
|
+
function emitNodeClick(target) {
|
|
161
|
+
const stepName = stepNameAt(target);
|
|
162
|
+
if (stepName) {
|
|
163
|
+
window.parent.postMessage({ type: "sapiom:node-click", stepName: stepName }, "*");
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
// Direct clicks on the board — the path when nothing overlays the iframe.
|
|
150
167
|
document.addEventListener("click", function (e) {
|
|
151
|
-
if (
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
168
|
+
if (e && e.target)
|
|
169
|
+
emitNodeClick(/** @type {Element} */ e.target);
|
|
170
|
+
});
|
|
171
|
+
// The harness renders a gesture layer OVER this iframe (for pan / zoom), so
|
|
172
|
+
// raw clicks never reach this document. That layer forwards a click as
|
|
173
|
+
// `{ type: "sapiom-canvas:pick", x, y }` and hovers as
|
|
174
|
+
// `{ type: "sapiom-canvas:hover", x, y }` in this frame's coordinate space —
|
|
175
|
+
// the iframe never transforms, so a frame-local point IS a viewport point.
|
|
176
|
+
// Hit-test with elementFromPoint so a node still selects on click, and answer
|
|
177
|
+
// hovers with `{ type: "sapiom-canvas:hit", id }` so the layer shows a
|
|
178
|
+
// pointer cursor over nodes (and keeps a node's selection on click).
|
|
179
|
+
window.addEventListener("message", function (e) {
|
|
180
|
+
const d = e && e.data;
|
|
181
|
+
if (!d)
|
|
158
182
|
return;
|
|
159
|
-
|
|
183
|
+
if (d.type === "sapiom-canvas:pick") {
|
|
184
|
+
emitNodeClick(document.elementFromPoint(d.x, d.y));
|
|
185
|
+
}
|
|
186
|
+
else if (d.type === "sapiom-canvas:hover") {
|
|
187
|
+
window.parent.postMessage({ type: "sapiom-canvas:hit", id: stepNameAt(document.elementFromPoint(d.x, d.y)) }, "*");
|
|
188
|
+
}
|
|
160
189
|
});
|
|
161
190
|
}
|
|
162
191
|
//# sourceMappingURL=canvas-run-state.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"canvas-run-state.js","sourceRoot":"","sources":["../../src/core/canvas-run-state.ts"],"names":[],"mappings":"AAAA,2BAA2B;AAC3B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAIH;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAAC,MAAc;IAC9C,IAAI,MAAM,KAAK,SAAS;QAAE,OAAO,YAAY,CAAC;IAC9C,IAAI,MAAM,KAAK,QAAQ;QAAE,OAAO,WAAW,CAAC;IAC5C,IAAI,MAAM,KAAK,QAAQ;QAAE,OAAO,WAAW,CAAC;IAC5C,OAAO,YAAY,CAAC;AACtB,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,qBAAqB,CACnC,GAAa,EACb,GASC;IAED,MAAM,YAAY,GAAG,CAAC,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,YAAY,CAAC,CAAC;IAE5E,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAC1C,MAAM,IAAI,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAC1B,sEAAsE;QACtE,wEAAwE;QACxE,uEAAuE;QACvE,IAAI,IAAI,GAAG,IAAI,CAAC;QAChB,IAAI,CAAC;YACH,IAAI;gBACF,GAAG,CAAC,aAAa,CAAC,mBAAmB,GAAG,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;oBACzD,CAAC,IAAI,CAAC,EAAE;wBACN,CAAC,CAAC,GAAG,CAAC,aAAa,CAAC,iBAAiB,GAAG,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC;wBACvD,CAAC,CAAC,IAAI,CAAC,CAAC;QACd,CAAC;QAAC,MAAM,CAAC;YACP,IAAI,GAAG,IAAI,CAAC;QACd,CAAC;QACD,IAAI,CAAC,IAAI;YAAE,SAAS;QACpB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,YAAY,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YAC7C,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC;QACzC,CAAC;QACD,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,iBAAiB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;QACnD,IAAI,IAAI,CAAC,SAAS,IAAI,IAAI,EAAE,CAAC;YAC3B,IAAI,CAAC,YAAY,CAAC,cAAc,EAAE,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC;QAC5D,CAAC;IACH,CAAC;IAED,MAAM,QAAQ,GAAG,GAAG,CAAC,aAAa,CAAC,mBAAmB,CAAC,CAAC;IACxD,IAAI,CAAC,QAAQ;QAAE,OAAO;IACtB,MAAM,KAAK,GAAG,QAAQ,CAAC,aAAa,CAAC,eAAe,CAAC,CAAC;IACtD,IAAI,CAAC,KAAK;QAAE,OAAO;IAEnB,IAAI,GAAG,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;QAC7B,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,iBAAiB,CAAC,EAAE,CAAC;YAC3C,KAAK,CAAC,YAAY,CAAC,iBAAiB,EAAE,KAAK,CAAC,WAAW,IAAI,EAAE,CAAC,CAAC;QACjE,CAAC;QACD,KAAK,CAAC,WAAW,GAAG,GAAG,CAAC,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC;QACnE,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC;IAC9C,CAAC;SAAM,CAAC;QACN,MAAM,SAAS,GAAG,KAAK,CAAC,YAAY,CAAC,iBAAiB,CAAC,CAAC;QACxD,IAAI,SAAS,IAAI,IAAI,EAAE,CAAC;YACtB,KAAK,CAAC,WAAW,GAAG,SAAS,CAAC;YAC9B,KAAK,CAAC,eAAe,CAAC,iBAAiB,CAAC,CAAC;QAC3C,CAAC;QACD,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,sBAAsB,CAAC,CAAC;IACjD,CAAC;AACH,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,kBAAkB;IAChC,MAAM,CAAC,gBAAgB,CAAC,SAAS,EAAE,UAAU,CAAC;QAC5C,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC;QACtB,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,KAAK,kBAAkB;YAAE,OAAO;QAChD,qBAAqB,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC;IACrC,CAAC,CAAC,CAAC;AACL,CAAC;AAED
|
|
1
|
+
{"version":3,"file":"canvas-run-state.js","sourceRoot":"","sources":["../../src/core/canvas-run-state.ts"],"names":[],"mappings":"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"}
|
|
@@ -14,6 +14,19 @@
|
|
|
14
14
|
/** Returns the agents API base URL, honouring the same env-var precedence as
|
|
15
15
|
* @sapiom/tools's DEFAULT_BASE_URL. */
|
|
16
16
|
export declare function resolveAgentsBaseUrl(): string;
|
|
17
|
+
/**
|
|
18
|
+
* Resolve the CORE surface base URL (`api.<env>`), distinct from the agents
|
|
19
|
+
* host (`tools.<env>`) resolved above. A run lives in the agents env, and any
|
|
20
|
+
* core-surface call for that run must target the MATCHING core env — otherwise
|
|
21
|
+
* a prod run queried against dev 401s. So we DERIVE the core host from the
|
|
22
|
+
* agents host (`tools.<env>` → `api.<env>`) rather than reading
|
|
23
|
+
* `SAPIOM_API_URL`, which in some setups points at a different env than the
|
|
24
|
+
* agents surface. An explicit `SAPIOM_CORE_URL` still wins for full control.
|
|
25
|
+
*
|
|
26
|
+
* Co-located with {@link resolveAgentsBaseUrl} (its sole dependency) so the two
|
|
27
|
+
* env-precedence helpers live together.
|
|
28
|
+
*/
|
|
29
|
+
export declare function resolveCoreBaseUrl(): string;
|
|
17
30
|
export interface DefinitionSlugResolver {
|
|
18
31
|
resolve(definitionId: string): Promise<string | null>;
|
|
19
32
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"definition-slug-resolver.d.ts","sourceRoot":"","sources":["../../src/core/definition-slug-resolver.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH;wCACwC;AACxC,wBAAgB,oBAAoB,IAAI,MAAM,CAM7C;AAED,MAAM,WAAW,sBAAsB;IACrC,OAAO,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;CACvD;AAED;;;;;;GAMG;AACH,wBAAgB,4BAA4B,CAAC,IAAI,EAAE;IACjD,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,iEAAiE;IACjE,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;CAC1B,GAAG,sBAAsB,CAyDzB"}
|
|
1
|
+
{"version":3,"file":"definition-slug-resolver.d.ts","sourceRoot":"","sources":["../../src/core/definition-slug-resolver.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH;wCACwC;AACxC,wBAAgB,oBAAoB,IAAI,MAAM,CAM7C;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,CAc3C;AAED,MAAM,WAAW,sBAAsB;IACrC,OAAO,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;CACvD;AAED;;;;;;GAMG;AACH,wBAAgB,4BAA4B,CAAC,IAAI,EAAE;IACjD,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,iEAAiE;IACjE,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;CAC1B,GAAG,sBAAsB,CAyDzB"}
|
|
@@ -18,6 +18,35 @@ export function resolveAgentsBaseUrl() {
|
|
|
18
18
|
process.env.SAPIOM_TOOLS_BASE ??
|
|
19
19
|
"https://tools.sapiom.ai");
|
|
20
20
|
}
|
|
21
|
+
/**
|
|
22
|
+
* Resolve the CORE surface base URL (`api.<env>`), distinct from the agents
|
|
23
|
+
* host (`tools.<env>`) resolved above. A run lives in the agents env, and any
|
|
24
|
+
* core-surface call for that run must target the MATCHING core env — otherwise
|
|
25
|
+
* a prod run queried against dev 401s. So we DERIVE the core host from the
|
|
26
|
+
* agents host (`tools.<env>` → `api.<env>`) rather than reading
|
|
27
|
+
* `SAPIOM_API_URL`, which in some setups points at a different env than the
|
|
28
|
+
* agents surface. An explicit `SAPIOM_CORE_URL` still wins for full control.
|
|
29
|
+
*
|
|
30
|
+
* Co-located with {@link resolveAgentsBaseUrl} (its sole dependency) so the two
|
|
31
|
+
* env-precedence helpers live together.
|
|
32
|
+
*/
|
|
33
|
+
export function resolveCoreBaseUrl() {
|
|
34
|
+
const override = process.env.SAPIOM_CORE_URL;
|
|
35
|
+
if (override)
|
|
36
|
+
return override;
|
|
37
|
+
const agents = resolveAgentsBaseUrl();
|
|
38
|
+
try {
|
|
39
|
+
const url = new URL(agents);
|
|
40
|
+
if (url.hostname.startsWith("tools.")) {
|
|
41
|
+
url.hostname = `api.${url.hostname.slice("tools.".length)}`;
|
|
42
|
+
return url.origin;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
catch {
|
|
46
|
+
// Unparseable agents URL — fall through to the prod default.
|
|
47
|
+
}
|
|
48
|
+
return "https://api.sapiom.ai";
|
|
49
|
+
}
|
|
21
50
|
/**
|
|
22
51
|
* Creates a resolver that fetches `GET /agents/v1/definitions/<id>` with the
|
|
23
52
|
* caller's API key and returns the `slug` field from the response.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"definition-slug-resolver.js","sourceRoot":"","sources":["../../src/core/definition-slug-resolver.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH;wCACwC;AACxC,MAAM,UAAU,oBAAoB;IAClC,OAAO,CACL,OAAO,CAAC,GAAG,CAAC,iBAAiB;QAC7B,OAAO,CAAC,GAAG,CAAC,iBAAiB;QAC7B,yBAAyB,CAC1B,CAAC;AACJ,CAAC;AAMD;;;;;;GAMG;AACH,MAAM,UAAU,4BAA4B,CAAC,IAK5C;IACC,MAAM,EAAE,MAAM,EAAE,OAAO,GAAG,oBAAoB,EAAE,EAAE,SAAS,GAAG,KAAK,EAAE,GAAG,IAAI,CAAC;IAC7E,MAAM,KAAK,GAAG,IAAI,GAAG,EAAkB,CAAC;IACxC,yEAAyE;IACzE,6EAA6E;IAC7E,yEAAyE;IACzE,0EAA0E;IAC1E,6EAA6E;IAC7E,gEAAgE;IAChE,MAAM,cAAc,GAAG,IAAI,GAAG,EAAU,CAAC;IACzC,MAAM,QAAQ,GAAG,CAAC,YAAoB,EAAE,MAAc,EAAQ,EAAE;QAC9D,IAAI,cAAc,CAAC,GAAG,CAAC,YAAY,CAAC;YAAE,OAAO;QAC7C,cAAc,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;QACjC,OAAO,CAAC,KAAK,CACX,oEAAoE,YAAY,GAAG;YACjF,MAAM,OAAO,KAAK,MAAM,4DAA4D;YACpF,mEAAmE,CACtE,CAAC;IACJ,CAAC,CAAC;IAEF,OAAO;QACL,KAAK,CAAC,OAAO,CAAC,YAAoB;YAChC,mEAAmE;YACnE,uEAAuE;YACvE,IAAI,CAAC,MAAM;gBAAE,OAAO,IAAI,CAAC;YAEzB,MAAM,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;YACvC,IAAI,MAAM,KAAK,SAAS;gBAAE,OAAO,MAAM,CAAC;YAExC,IAAI,CAAC;gBACH,MAAM,GAAG,GAAG,GAAG,OAAO,0BAA0B,kBAAkB,CAAC,YAAY,CAAC,EAAE,CAAC;gBACnF,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC,GAAG,EAAE;oBACpC,OAAO,EAAE,EAAE,kBAAkB,EAAE,MAAM,EAAE;iBACxC,CAAC,CAAC;gBAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;oBACjB,QAAQ,CAAC,YAAY,EAAE,QAAQ,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;oBAClD,OAAO,IAAI,CAAC;gBACd,CAAC;gBAED,MAAM,IAAI,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAA4B,CAAC;gBAChE,MAAM,IAAI,GAAG,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;gBAC9D,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;oBAClB,KAAK,CAAC,GAAG,CAAC,YAAY,EAAE,IAAI,CAAC,CAAC;gBAChC,CAAC;qBAAM,CAAC;oBACN,QAAQ,CAAC,YAAY,EAAE,qCAAqC,CAAC,CAAC;gBAChE,CAAC;gBACD,OAAO,IAAI,CAAC;YACd,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,QAAQ,CACN,YAAY,EACZ,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CACjD,CAAC;gBACF,OAAO,IAAI,CAAC;YACd,CAAC;QACH,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
1
|
+
{"version":3,"file":"definition-slug-resolver.js","sourceRoot":"","sources":["../../src/core/definition-slug-resolver.ts"],"names":[],"mappings":"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"}
|