@tangle-network/agent-runtime 0.82.0 → 0.83.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.
Files changed (88) hide show
  1. package/README.md +4 -0
  2. package/dist/agent.d.ts +5 -3
  3. package/dist/agent.js +7 -7
  4. package/dist/agent.js.map +1 -1
  5. package/dist/analyst-loop.d.ts +3 -2
  6. package/dist/analyst-loop.js +2 -2
  7. package/dist/{chunk-A7LZR5DT.js → chunk-4WXGK6GV.js} +2 -2
  8. package/dist/chunk-4WXGK6GV.js.map +1 -0
  9. package/dist/{chunk-UZ5SODU7.js → chunk-5IBQAPVB.js} +1 -1
  10. package/dist/chunk-5IBQAPVB.js.map +1 -0
  11. package/dist/{chunk-5JAUQZQA.js → chunk-7LO5GMAO.js} +1 -1
  12. package/dist/chunk-7LO5GMAO.js.map +1 -0
  13. package/dist/{chunk-H7IBHAFT.js → chunk-BZF3KQ6G.js} +1 -1
  14. package/dist/chunk-BZF3KQ6G.js.map +1 -0
  15. package/dist/{chunk-WIR4HOOJ.js → chunk-DPEUKJRO.js} +1 -1
  16. package/dist/chunk-DPEUKJRO.js.map +1 -0
  17. package/dist/{chunk-DJQFJEOD.js → chunk-J3N6GODQ.js} +2 -2
  18. package/dist/chunk-J3N6GODQ.js.map +1 -0
  19. package/dist/{chunk-GRAGM4MC.js → chunk-NURIQBJQ.js} +1 -1
  20. package/dist/chunk-NURIQBJQ.js.map +1 -0
  21. package/dist/{chunk-JYURIKPF.js → chunk-QDVLTRCP.js} +4 -4
  22. package/dist/chunk-QDVLTRCP.js.map +1 -0
  23. package/dist/{chunk-FNMGYYSS.js → chunk-SGKPNBXE.js} +1 -1
  24. package/dist/chunk-SGKPNBXE.js.map +1 -0
  25. package/dist/{chunk-CO2KBPRE.js → chunk-SSA6OERV.js} +6 -6
  26. package/dist/chunk-SSA6OERV.js.map +1 -0
  27. package/dist/{chunk-SRGV56W4.js → chunk-UD4BHQMI.js} +2 -2
  28. package/dist/{chunk-SRGV56W4.js.map → chunk-UD4BHQMI.js.map} +1 -1
  29. package/dist/{chunk-KSGHI53L.js → chunk-UJ3ONGHR.js} +6 -6
  30. package/dist/chunk-UJ3ONGHR.js.map +1 -0
  31. package/dist/{chunk-LWGVVP2C.js → chunk-VNOOH22O.js} +2 -2
  32. package/dist/chunk-VNOOH22O.js.map +1 -0
  33. package/dist/{chunk-NBV35BR6.js → chunk-YEJR7IXO.js} +1 -1
  34. package/dist/chunk-YEJR7IXO.js.map +1 -0
  35. package/dist/{chunk-C2FZ6GR6.js → chunk-YPA5MLVE.js} +2 -2
  36. package/dist/chunk-YPA5MLVE.js.map +1 -0
  37. package/dist/{coordination-BI9tpcmF.d.ts → coordination-CuDLO8wj.d.ts} +53 -32
  38. package/dist/environment-provider.d.ts +2 -2
  39. package/dist/environment-provider.js +1 -1
  40. package/dist/{improvement-adapter-CioiEE2z.d.ts → improvement-adapter-CDR8QNVM.d.ts} +3 -0
  41. package/dist/index.d.ts +163 -49
  42. package/dist/index.js +43 -13
  43. package/dist/index.js.map +1 -1
  44. package/dist/intelligence.d.ts +14 -8
  45. package/dist/intelligence.js +1 -1
  46. package/dist/intelligence.js.map +1 -1
  47. package/dist/{kb-gate-CuzMYGYM.d.ts → kb-gate-CwHO0vz6.d.ts} +4 -2
  48. package/dist/lifecycle.d.ts +2 -2
  49. package/dist/lifecycle.js +3 -3
  50. package/dist/{local-harness-DU7yV6mG.d.ts → local-harness-sI0S_XNA.d.ts} +2 -1
  51. package/dist/{loop-runner-bin-CBkLsyFg.d.ts → loop-runner-bin-hQDUL8Ld.d.ts} +28 -13
  52. package/dist/loop-runner-bin.d.ts +7 -7
  53. package/dist/loop-runner-bin.js +10 -10
  54. package/dist/loops.d.ts +102 -45
  55. package/dist/loops.js +7 -7
  56. package/dist/mcp/bin.js +8 -8
  57. package/dist/mcp/bin.js.map +1 -1
  58. package/dist/mcp/index.d.ts +44 -38
  59. package/dist/mcp/index.js +11 -11
  60. package/dist/mcp/index.js.map +1 -1
  61. package/dist/{mcp-serve-verifier-BvMAV_8U.d.ts → mcp-serve-verifier-FL7-ZEb_.d.ts} +8 -3
  62. package/dist/{openai-tools-B-3v06BE.d.ts → openai-tools-BnrOmGjN.d.ts} +7 -4
  63. package/dist/platform.d.ts +4 -0
  64. package/dist/platform.js.map +1 -1
  65. package/dist/profiles.d.ts +36 -23
  66. package/dist/profiles.js +2 -2
  67. package/dist/profiles.js.map +1 -1
  68. package/dist/{router-client-D6Ocf4jG.d.ts → router-client-r8y_VFVM.d.ts} +1 -0
  69. package/dist/{substrate-rNj6TDc3.d.ts → substrate-DO2GHNg2.d.ts} +5 -3
  70. package/dist/{types-By9LXllv.d.ts → types-Driepl87.d.ts} +3 -2
  71. package/dist/{types-BF-MEsQB.d.ts → types-ESeMOj94.d.ts} +26 -11
  72. package/dist/{worktree-fanout-D9Z2dMS9.d.ts → worktree-fanout-D6xR2CIA.d.ts} +16 -10
  73. package/dist/{worktree-harness-Dx8XULW3.d.ts → worktree-harness-CX_McRLp.d.ts} +11 -8
  74. package/package.json +1 -1
  75. package/dist/chunk-5JAUQZQA.js.map +0 -1
  76. package/dist/chunk-A7LZR5DT.js.map +0 -1
  77. package/dist/chunk-C2FZ6GR6.js.map +0 -1
  78. package/dist/chunk-CO2KBPRE.js.map +0 -1
  79. package/dist/chunk-DJQFJEOD.js.map +0 -1
  80. package/dist/chunk-FNMGYYSS.js.map +0 -1
  81. package/dist/chunk-GRAGM4MC.js.map +0 -1
  82. package/dist/chunk-H7IBHAFT.js.map +0 -1
  83. package/dist/chunk-JYURIKPF.js.map +0 -1
  84. package/dist/chunk-KSGHI53L.js.map +0 -1
  85. package/dist/chunk-LWGVVP2C.js.map +0 -1
  86. package/dist/chunk-NBV35BR6.js.map +0 -1
  87. package/dist/chunk-UZ5SODU7.js.map +0 -1
  88. package/dist/chunk-WIR4HOOJ.js.map +0 -1
@@ -1,9 +1,8 @@
1
1
  import { AnalystFinding } from '@tangle-network/agent-eval';
2
- import { L as LocalHarness, r as runLocalHarness } from './local-harness-DU7yV6mG.js';
2
+ import { L as LocalHarness, r as runLocalHarness } from './local-harness-sI0S_XNA.js';
3
3
  import { LabeledScenarioStore, WorktreeAdapter, SurfaceProposer } from '@tangle-network/agent-eval/campaign';
4
4
 
5
5
  /**
6
- * @experimental
7
6
  *
8
7
  * `improvementDriver` — the ONE reflective/agentic improvement proposer for
9
8
  * agent-eval's improvement loop. It implements `SurfaceProposer` and owns
@@ -21,6 +20,8 @@ import { LabeledScenarioStore, WorktreeAdapter, SurfaceProposer } from '@tangle-
21
20
  * Both emit changes into a worktree the driver finalizes into a
22
21
  * `CodeSurface{ worktreeRef }` the loop measures on the holdout. See
23
22
  * agent-eval's `docs/design/self-improvement-engine.md`.
23
+ *
24
+ * @experimental
24
25
  */
25
26
 
26
27
  /** The byte-producing seam — the ONE thing that differs between the cheap
@@ -53,10 +54,10 @@ interface ImprovementDriverOptions {
53
54
  /** Base ref candidate worktrees fork from. Default `main`. */
54
55
  baseRef?: string;
55
56
  }
57
+ /** The one reflective/agentic improvement proposer (`SurfaceProposer`): owns the candidate worktree lifecycle and delegates HOW a change is produced to a pluggable `CandidateGenerator`. */
56
58
  declare function improvementDriver(opts: ImprovementDriverOptions): SurfaceProposer<AnalystFinding>;
57
59
 
58
60
  /**
59
- * @experimental
60
61
  *
61
62
  * `agenticGenerator` — the full-agentic `CandidateGenerator`: the
62
63
  * `shots=N, sandbox=on` setting of the one `improvementDriver`. It runs a real
@@ -86,6 +87,8 @@ declare function improvementDriver(opts: ImprovementDriverOptions): SurfacePropo
86
87
  * false`), never shipped — if you configured a verifier, a non-passing tree is
87
88
  * not a candidate. With no verifier the legacy behavior holds: first dirty shot
88
89
  * is the candidate.
90
+ *
91
+ * @experimental
89
92
  */
90
93
 
91
94
  /** Outcome of verifying a candidate worktree. `feedback` (compiler errors,
@@ -120,6 +123,7 @@ interface AgenticGeneratorOptions {
120
123
  /** Test seam — inject the worktree-dirty check (defaults to `git status`). */
121
124
  isDirty?: (worktreePath: string) => boolean;
122
125
  }
126
+ /** Full-agentic `CandidateGenerator` (the `shots=N, sandbox=on` setting): run a real coding harness inside the candidate worktree so the agent makes the change in place. */
123
127
  declare function agenticGenerator(opts?: AgenticGeneratorOptions): CandidateGenerator;
124
128
  /** A `Verifier` that runs a command in the worktree: exit 0 ⇒ ok, any other
125
129
  * exit ⇒ failed with stdout+stderr as feedback. The common case — verify by
@@ -157,6 +161,7 @@ interface McpServeSpec {
157
161
  /** Minimum tools the server must expose to pass. Default 1. */
158
162
  minTools?: number;
159
163
  }
164
+ /** Build a `Verifier` that boots a generated MCP server over stdio and checks it exposes tools. */
160
165
  declare function mcpServeVerifier(spec: McpServeSpec): Verifier;
161
166
 
162
167
  export { type AgenticGeneratorOptions as A, type CandidateGenerator as C, type ImprovementDriverOptions as I, type McpServeSpec as M, type Verifier as V, type VerifyResult as a, agenticGenerator as b, commandVerifier as c, improvementDriver as i, mcpServeVerifier as m };
@@ -1,7 +1,6 @@
1
- import { O as OpenAIChatTool } from './types-BF-MEsQB.js';
1
+ import { O as OpenAIChatTool } from './types-ESeMOj94.js';
2
2
 
3
3
  /**
4
- * @experimental
5
4
  *
6
5
  * OpenAI Chat Completions `tools[]` projection of the queue-bound agent-runtime
7
6
  * MCP delegation tools.
@@ -20,23 +19,27 @@ import { O as OpenAIChatTool } from './types-BF-MEsQB.js';
20
19
  * Tool name + description + JSON-schema are pulled from the canonical
21
20
  * `DELEGATE_*` constants exported by `./tools/*` so the projection cannot
22
21
  * drift from the server's own validators.
22
+ *
23
+ * @experimental
23
24
  */
24
25
 
25
26
  /**
26
- * @experimental
27
27
  *
28
28
  * Returns the queue-bound delegation tools projected into OpenAI Chat
29
29
  * Completions `tools[]` shape. The order is stable: `delegate_feedback`,
30
30
  * `delegation_status`, `delegation_history`.
31
+ *
32
+ * @experimental
31
33
  */
32
34
  declare function mcpToolsForRuntimeMcp(): OpenAIChatTool[];
33
35
  /**
34
- * @experimental
35
36
  *
36
37
  * Subset filter — return only the projected tools whose `function.name`
37
38
  * appears in `names`. Useful for curated mounts (e.g. only the queue-bound
38
39
  * delegation tools, omitting `delegate_feedback`). Unknown names are
39
40
  * silently ignored; pass an empty array to get an empty result.
41
+ *
42
+ * @experimental
40
43
  */
41
44
  declare function mcpToolsForRuntimeMcpSubset(names: ReadonlyArray<string>): OpenAIChatTool[];
42
45
 
@@ -43,11 +43,13 @@ interface ExchangeCodeResult {
43
43
  tier: string;
44
44
  };
45
45
  }
46
+ /** Thrown when a `PlatformAuthClient` request returns a non-success status. */
46
47
  declare class PlatformAuthError extends Error {
47
48
  readonly status: number;
48
49
  readonly body: unknown;
49
50
  constructor(message: string, status: number, body: unknown);
50
51
  }
52
+ /** HTTP client for the Tangle Platform SSO: builds authorize URLs and exchanges auth codes for API keys. */
51
53
  declare class PlatformAuthClient {
52
54
  private readonly baseUrl;
53
55
  private readonly appId;
@@ -194,12 +196,14 @@ interface PlatformHubStatus {
194
196
  unhealthyProviderCount: number;
195
197
  };
196
198
  }
199
+ /** Thrown when a `PlatformHubClient` request returns a non-success status. */
197
200
  declare class PlatformHubError extends Error {
198
201
  readonly status: number;
199
202
  readonly code: string | undefined;
200
203
  readonly body: unknown;
201
204
  constructor(message: string, status: number, code: string | undefined, body: unknown);
202
205
  }
206
+ /** HTTP client for the Tangle Platform Hub API: provider catalog, connection flow, and status. */
203
207
  declare class PlatformHubClient {
204
208
  private readonly baseUrl;
205
209
  private readonly bearer;
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/platform/auth.ts","../src/platform/integrations.ts"],"sourcesContent":["/**\n * Server-side client for the Tangle platform's cross-site SSO bridge.\n *\n * Consumer apps (gtm-agent, tax-agent, legal-agent, creative-agent, …)\n * use this to:\n * 1. Build an /authorize URL that lands the user on id.tangle.tools\n * and brings them back with a single-use code.\n * 2. Exchange that code for an API key + the user's identity.\n *\n * The platform endpoint contract is documented in\n * `products/platform/api/src/routes/cross-site.ts`. This client only\n * speaks HTTP — no SDK weight, no transitive deps.\n */\n\nexport interface PlatformAuthClientOptions {\n /** Platform base URL, e.g. `https://id.tangle.tools`. */\n baseUrl: string\n /** App id as registered in the platform's TRUSTED_APPS registry. */\n appId: string\n /** Override the global fetch (useful for tests + edge runtimes). */\n fetchImpl?: typeof fetch\n}\n\nexport interface AuthorizeUrlOptions {\n /** Required CSRF token; the consumer verifies it on the callback. */\n state: string\n /**\n * Final redirect URI. Must be one of the URIs registered for `appId`\n * on the platform. Omit to use the first registered URI.\n */\n redirectUri?: string\n /** Force the login screen even if a session is already active. */\n prompt?: 'login'\n /** Pre-fill the email field on the login screen. */\n email?: string\n}\n\nexport interface ExchangeCodeResult {\n apiKey: string\n user: {\n id: string\n email: string\n name?: string\n }\n plan: {\n tier: string\n }\n}\n\nexport class PlatformAuthError extends Error {\n constructor(\n message: string,\n public readonly status: number,\n public readonly body: unknown,\n ) {\n super(message)\n this.name = 'PlatformAuthError'\n }\n}\n\nexport class PlatformAuthClient {\n private readonly baseUrl: string\n private readonly appId: string\n private readonly fetchImpl: typeof fetch\n\n constructor(options: PlatformAuthClientOptions) {\n if (!options.baseUrl) throw new Error('PlatformAuthClient: baseUrl is required')\n if (!options.appId) throw new Error('PlatformAuthClient: appId is required')\n this.baseUrl = options.baseUrl.replace(/\\/+$/, '')\n this.appId = options.appId\n this.fetchImpl =\n options.fetchImpl ??\n ((url: Parameters<typeof fetch>[0], init?: Parameters<typeof fetch>[1]) => fetch(url, init))\n }\n\n /**\n * Build the URL the user is redirected to in order to start SSO.\n * The platform redirects back to one of `appId`'s registered\n * `redirectUris` with `?code=...&app=...&state=...`.\n */\n authorizeUrl(options: AuthorizeUrlOptions): string {\n if (!options.state) {\n throw new Error('PlatformAuthClient.authorizeUrl: state is required for CSRF')\n }\n const url = new URL('/cross-site/authorize', this.baseUrl)\n url.searchParams.set('app', this.appId)\n url.searchParams.set('state', options.state)\n if (options.redirectUri) url.searchParams.set('redirect', options.redirectUri)\n if (options.prompt) url.searchParams.set('prompt', options.prompt)\n if (options.email) url.searchParams.set('email', options.email)\n return url.toString()\n }\n\n /**\n * Exchange a single-use auth code (delivered to the consumer's\n * callback by the platform) for an API key + the user's identity.\n * Codes are single-use and expire ~5 minutes after issue.\n */\n async exchange(code: string): Promise<ExchangeCodeResult> {\n if (!code) throw new Error('PlatformAuthClient.exchange: code is required')\n const res = await this.fetchImpl(`${this.baseUrl}/cross-site/exchange`, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ code, app: this.appId }),\n })\n const body = await res.json().catch(() => null)\n if (!res.ok) {\n const message =\n body && typeof body === 'object' && 'error' in body && typeof body.error === 'string'\n ? body.error\n : `Platform exchange failed (${res.status})`\n throw new PlatformAuthError(message, res.status, body)\n }\n const result = body as Partial<ExchangeCodeResult>\n if (!result.apiKey || !result.user?.id) {\n throw new PlatformAuthError(\n 'Platform exchange response is missing apiKey or user',\n res.status,\n body,\n )\n }\n return result as ExchangeCodeResult\n }\n}\n","/**\n * Server-side client for the Tangle platform's integration hub\n * (`/v1/hub/*`). Consumer apps use this instead of rolling their own\n * OAuth + connection tables.\n *\n * Auth: the caller supplies a bearer (either the user's API key from\n * cross-site exchange, or a platform service token) on construction.\n *\n * Endpoint contract (authoritative): the platform's `src/lib/hub-contract.ts`\n * + `src/routes/hub.ts`. The platform wraps every response in\n * `{ success, data }`; non-2xx or `success:false` surfaces as `PlatformHubError`\n * carrying the real upstream status.\n */\n\nexport interface PlatformHubClientOptions {\n /** Platform base URL, e.g. `https://id.tangle.tools`. */\n baseUrl: string\n /** Bearer credential — user API key or service token. */\n bearer: string\n /** Override fetch (tests + edge runtimes). */\n fetchImpl?: typeof fetch\n}\n\n/** A live integration connection, as returned by `/v1/hub/connections`. */\nexport interface PlatformConnection {\n id: string\n providerId: string\n displayName: string\n accountDisplay: string | null\n scopes: string[]\n status: 'active' | 'revoked' | 'unhealthy' | 'reconnect_required' | (string & {})\n health: 'unknown' | 'healthy' | 'unhealthy' | 'rate_limited' | (string & {})\n createdAt: string\n updatedAt: string\n lastUsedAt: string | null\n}\n\n/** A connectable provider in the catalog (`/v1/hub/providers`). */\nexport interface PlatformCatalogProvider {\n providerId: string\n title?: string\n authKind?: string\n category?: string\n scopes?: string[]\n capabilityCount?: number\n native?: boolean\n /** Whether the OAuth app's credentials are wired — the UI offers Connect\n * only when true. */\n configured?: boolean\n [k: string]: unknown\n}\n\nexport interface CatalogResult {\n providers: PlatformCatalogProvider[]\n /** Count of substrate-bundled connectors behind the catalog. */\n substrateBundled?: number\n [k: string]: unknown\n}\n\nexport interface StartAuthInput {\n /** The provider to connect (goes in the URL path). */\n providerId: string\n /** Accepted for interface compatibility; the platform's start endpoint is\n * provider-level and does not consume a connector id. */\n connectorId?: string\n /** Where the platform redirects the user back to after OAuth. */\n returnUrl: string\n /** Accepted for interface compatibility; not consumed by the start endpoint. */\n requestedScopes?: string[]\n /** CLI flow flag — affects the platform's post-auth redirect handling. */\n cli?: boolean\n}\n\nexport interface StartAuthResult {\n /** The URL to send the user to. Normalized across the platform's two start\n * branches: github returns `authorizationUrl`, substrate returns\n * `redirectUrl`. */\n authorizationUrl: string\n state: string\n expiresAt?: string\n scopes?: string[]\n}\n\nexport interface ConnectionHealth {\n status: 'unknown' | 'healthy' | 'unhealthy' | 'rate_limited' | (string & {})\n checkedAt: string\n error?: { code: string; message: string }\n}\n\nexport interface ConnectionHealthResult {\n connection: PlatformConnection\n health: ConnectionHealth\n}\n\n/** Last-known health for a connection, derived from the connection row. */\nexport interface HealthCheck {\n connectionId: string\n providerId: string\n /** Mirrors `PlatformConnection.health`. */\n status: ConnectionHealth['status']\n checkedAt?: string\n}\n\nexport interface MintTokenInput {\n /** The hub action the token authorizes (e.g. `slack.chat.postMessage`). */\n actionPath: string\n /** Bind to a specific connection, or … */\n connectionId?: string\n /** … resolve the connection by provider for the calling user. */\n provider?: string\n}\n\nexport interface MintTokenResult {\n tokenId: string\n token: string\n expiresAt: string\n}\n\nexport interface ExecInput {\n /** The hub action path to execute. */\n path: string\n input?: unknown\n connectionId?: string\n}\n\nexport interface PlatformHubStatus {\n contract?: unknown\n principal: { kind: string; userId: string; [k: string]: unknown }\n connections: { connectedProviderCount: number; unhealthyProviderCount: number }\n}\n\nexport class PlatformHubError extends Error {\n constructor(\n message: string,\n public readonly status: number,\n public readonly code: string | undefined,\n public readonly body: unknown,\n ) {\n super(message)\n this.name = 'PlatformHubError'\n }\n}\n\ninterface PlatformEnvelope<T> {\n success: boolean\n data?: T\n error?: { code?: string; message?: string } | string\n}\n\nexport class PlatformHubClient {\n private readonly baseUrl: string\n private readonly bearer: string\n private readonly fetchImpl: typeof fetch\n\n constructor(options: PlatformHubClientOptions) {\n if (!options.baseUrl) throw new Error('PlatformHubClient: baseUrl is required')\n if (!options.bearer) throw new Error('PlatformHubClient: bearer is required')\n this.baseUrl = options.baseUrl.replace(/\\/+$/, '')\n this.bearer = options.bearer\n this.fetchImpl =\n options.fetchImpl ??\n ((url: Parameters<typeof fetch>[0], init?: Parameters<typeof fetch>[1]) => fetch(url, init))\n }\n\n /** GET /v1/hub/providers — the connectable provider catalog. */\n catalog(): Promise<CatalogResult> {\n return this.request('GET', '/v1/hub/providers')\n }\n\n /** GET /v1/hub/connections — the calling user's live connections. */\n async listConnections(): Promise<PlatformConnection[]> {\n const data = await this.request<{ connections: PlatformConnection[] }>(\n 'GET',\n '/v1/hub/connections',\n )\n return data.connections\n }\n\n /** DELETE /v1/hub/connections/:connectionId — revoke + disable a connection. */\n revokeConnection(connectionId: string): Promise<{ connection: PlatformConnection }> {\n return this.request('DELETE', `/v1/hub/connections/${encodeURIComponent(connectionId)}`)\n }\n\n /**\n * POST /v1/hub/connections/:provider/start — begin OAuth/grant. The provider\n * is taken from the URL; the body carries `returnUrl` (+ `cli`). The platform's\n * two start branches name the URL field differently (github → `authorizationUrl`,\n * substrate → `redirectUrl`); this normalizes to `authorizationUrl`.\n */\n async startAuth(input: StartAuthInput): Promise<StartAuthResult> {\n const body: { returnUrl: string; cli?: boolean } = { returnUrl: input.returnUrl }\n if (input.cli !== undefined) body.cli = input.cli\n const data = await this.request<{\n authorizationUrl?: string\n redirectUrl?: string\n state: string\n expiresAt?: string\n scopes?: string[]\n }>('POST', `/v1/hub/connections/${encodeURIComponent(input.providerId)}/start`, body)\n const authorizationUrl = data.authorizationUrl ?? data.redirectUrl\n if (!authorizationUrl) {\n throw new PlatformHubError(\n 'Platform hub start response missing an authorization URL',\n 502,\n 'HUB_INVALID_START_RESPONSE',\n data,\n )\n }\n return { authorizationUrl, state: data.state, expiresAt: data.expiresAt, scopes: data.scopes }\n }\n\n /**\n * Last-known health for every connection. The platform has no global\n * healthcheck listing — health rides on each connection row — so this derives\n * the list from `listConnections()` (one request, no extra round-trips).\n */\n async listHealthchecks(): Promise<HealthCheck[]> {\n const connections = await this.listConnections()\n return connections.map((c) => ({\n connectionId: c.id,\n providerId: c.providerId,\n status: c.health,\n checkedAt: c.updatedAt,\n }))\n }\n\n /**\n * POST /v1/hub/connections/:connectionId/health — trigger a fresh health\n * probe for one connection and return its updated state.\n */\n checkConnectionHealth(connectionId: string): Promise<ConnectionHealthResult> {\n return this.request('POST', `/v1/hub/connections/${encodeURIComponent(connectionId)}/health`)\n }\n\n /**\n * Trigger a fresh health probe across all of the user's connections. The\n * platform exposes health per-connection only, so this fans out over\n * `listConnections()`. `scheduled` is the number of probes dispatched.\n */\n async runHealthchecks(): Promise<{ scheduled: number }> {\n const connections = await this.listConnections()\n await Promise.allSettled(connections.map((c) => this.checkConnectionHealth(c.id)))\n return { scheduled: connections.length }\n }\n\n /** GET /v1/hub/status — principal + aggregate connection counts. */\n status(): Promise<PlatformHubStatus> {\n return this.request('GET', '/v1/hub/status')\n }\n\n /**\n * POST /v1/hub/tokens — mint a short-lived, action-scoped capability token a\n * sandbox can use to invoke one hub action on the user's behalf without\n * seeing the underlying provider credential.\n */\n mintToken(input: MintTokenInput): Promise<MintTokenResult> {\n return this.request('POST', '/v1/hub/tokens', input)\n }\n\n /** POST /v1/hub/exec — execute a hub action and return its result. */\n async exec(input: ExecInput): Promise<unknown> {\n const data = await this.request<{ result: unknown }>('POST', '/v1/hub/exec', input)\n return data.result\n }\n\n private async request<T>(\n method: 'GET' | 'POST' | 'DELETE' | 'PUT',\n path: string,\n body?: unknown,\n ): Promise<T> {\n const headers: Record<string, string> = {\n authorization: `Bearer ${this.bearer}`,\n accept: 'application/json',\n }\n if (body !== undefined) headers['content-type'] = 'application/json'\n\n const res = await this.fetchImpl(`${this.baseUrl}${path}`, {\n method,\n headers,\n body: body !== undefined ? JSON.stringify(body) : undefined,\n })\n const text = await res.text()\n let parsed: PlatformEnvelope<T> | null = null\n if (text) {\n try {\n parsed = JSON.parse(text)\n } catch {\n // fall through to error handling below\n }\n }\n if (!res.ok || (parsed && parsed.success === false)) {\n const code = parsed?.error && typeof parsed.error === 'object' ? parsed.error.code : undefined\n const message =\n (parsed?.error && typeof parsed.error === 'object' && parsed.error.message) ||\n (typeof parsed?.error === 'string' ? parsed.error : `Platform hub error (${res.status})`)\n throw new PlatformHubError(message, res.status, code, parsed ?? text)\n }\n if (!parsed) {\n throw new PlatformHubError(\n `Platform hub returned non-JSON success (${res.status})`,\n res.status,\n undefined,\n text,\n )\n }\n if (parsed.data === undefined) {\n throw new PlatformHubError(\n 'Platform hub envelope missing `data`',\n res.status,\n undefined,\n parsed,\n )\n }\n return parsed.data\n }\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/platform/auth.ts","../src/platform/integrations.ts"],"sourcesContent":["/**\n * Server-side client for the Tangle platform's cross-site SSO bridge.\n *\n * Consumer apps (gtm-agent, tax-agent, legal-agent, creative-agent, …)\n * use this to:\n * 1. Build an /authorize URL that lands the user on id.tangle.tools\n * and brings them back with a single-use code.\n * 2. Exchange that code for an API key + the user's identity.\n *\n * The platform endpoint contract is documented in\n * `products/platform/api/src/routes/cross-site.ts`. This client only\n * speaks HTTP — no SDK weight, no transitive deps.\n */\n\nexport interface PlatformAuthClientOptions {\n /** Platform base URL, e.g. `https://id.tangle.tools`. */\n baseUrl: string\n /** App id as registered in the platform's TRUSTED_APPS registry. */\n appId: string\n /** Override the global fetch (useful for tests + edge runtimes). */\n fetchImpl?: typeof fetch\n}\n\nexport interface AuthorizeUrlOptions {\n /** Required CSRF token; the consumer verifies it on the callback. */\n state: string\n /**\n * Final redirect URI. Must be one of the URIs registered for `appId`\n * on the platform. Omit to use the first registered URI.\n */\n redirectUri?: string\n /** Force the login screen even if a session is already active. */\n prompt?: 'login'\n /** Pre-fill the email field on the login screen. */\n email?: string\n}\n\nexport interface ExchangeCodeResult {\n apiKey: string\n user: {\n id: string\n email: string\n name?: string\n }\n plan: {\n tier: string\n }\n}\n\n/** Thrown when a `PlatformAuthClient` request returns a non-success status. */\nexport class PlatformAuthError extends Error {\n constructor(\n message: string,\n public readonly status: number,\n public readonly body: unknown,\n ) {\n super(message)\n this.name = 'PlatformAuthError'\n }\n}\n\n/** HTTP client for the Tangle Platform SSO: builds authorize URLs and exchanges auth codes for API keys. */\nexport class PlatformAuthClient {\n private readonly baseUrl: string\n private readonly appId: string\n private readonly fetchImpl: typeof fetch\n\n constructor(options: PlatformAuthClientOptions) {\n if (!options.baseUrl) throw new Error('PlatformAuthClient: baseUrl is required')\n if (!options.appId) throw new Error('PlatformAuthClient: appId is required')\n this.baseUrl = options.baseUrl.replace(/\\/+$/, '')\n this.appId = options.appId\n this.fetchImpl =\n options.fetchImpl ??\n ((url: Parameters<typeof fetch>[0], init?: Parameters<typeof fetch>[1]) => fetch(url, init))\n }\n\n /**\n * Build the URL the user is redirected to in order to start SSO.\n * The platform redirects back to one of `appId`'s registered\n * `redirectUris` with `?code=...&app=...&state=...`.\n */\n authorizeUrl(options: AuthorizeUrlOptions): string {\n if (!options.state) {\n throw new Error('PlatformAuthClient.authorizeUrl: state is required for CSRF')\n }\n const url = new URL('/cross-site/authorize', this.baseUrl)\n url.searchParams.set('app', this.appId)\n url.searchParams.set('state', options.state)\n if (options.redirectUri) url.searchParams.set('redirect', options.redirectUri)\n if (options.prompt) url.searchParams.set('prompt', options.prompt)\n if (options.email) url.searchParams.set('email', options.email)\n return url.toString()\n }\n\n /**\n * Exchange a single-use auth code (delivered to the consumer's\n * callback by the platform) for an API key + the user's identity.\n * Codes are single-use and expire ~5 minutes after issue.\n */\n async exchange(code: string): Promise<ExchangeCodeResult> {\n if (!code) throw new Error('PlatformAuthClient.exchange: code is required')\n const res = await this.fetchImpl(`${this.baseUrl}/cross-site/exchange`, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ code, app: this.appId }),\n })\n const body = await res.json().catch(() => null)\n if (!res.ok) {\n const message =\n body && typeof body === 'object' && 'error' in body && typeof body.error === 'string'\n ? body.error\n : `Platform exchange failed (${res.status})`\n throw new PlatformAuthError(message, res.status, body)\n }\n const result = body as Partial<ExchangeCodeResult>\n if (!result.apiKey || !result.user?.id) {\n throw new PlatformAuthError(\n 'Platform exchange response is missing apiKey or user',\n res.status,\n body,\n )\n }\n return result as ExchangeCodeResult\n }\n}\n","/**\n * Server-side client for the Tangle platform's integration hub\n * (`/v1/hub/*`). Consumer apps use this instead of rolling their own\n * OAuth + connection tables.\n *\n * Auth: the caller supplies a bearer (either the user's API key from\n * cross-site exchange, or a platform service token) on construction.\n *\n * Endpoint contract (authoritative): the platform's `src/lib/hub-contract.ts`\n * + `src/routes/hub.ts`. The platform wraps every response in\n * `{ success, data }`; non-2xx or `success:false` surfaces as `PlatformHubError`\n * carrying the real upstream status.\n */\n\nexport interface PlatformHubClientOptions {\n /** Platform base URL, e.g. `https://id.tangle.tools`. */\n baseUrl: string\n /** Bearer credential — user API key or service token. */\n bearer: string\n /** Override fetch (tests + edge runtimes). */\n fetchImpl?: typeof fetch\n}\n\n/** A live integration connection, as returned by `/v1/hub/connections`. */\nexport interface PlatformConnection {\n id: string\n providerId: string\n displayName: string\n accountDisplay: string | null\n scopes: string[]\n status: 'active' | 'revoked' | 'unhealthy' | 'reconnect_required' | (string & {})\n health: 'unknown' | 'healthy' | 'unhealthy' | 'rate_limited' | (string & {})\n createdAt: string\n updatedAt: string\n lastUsedAt: string | null\n}\n\n/** A connectable provider in the catalog (`/v1/hub/providers`). */\nexport interface PlatformCatalogProvider {\n providerId: string\n title?: string\n authKind?: string\n category?: string\n scopes?: string[]\n capabilityCount?: number\n native?: boolean\n /** Whether the OAuth app's credentials are wired — the UI offers Connect\n * only when true. */\n configured?: boolean\n [k: string]: unknown\n}\n\nexport interface CatalogResult {\n providers: PlatformCatalogProvider[]\n /** Count of substrate-bundled connectors behind the catalog. */\n substrateBundled?: number\n [k: string]: unknown\n}\n\nexport interface StartAuthInput {\n /** The provider to connect (goes in the URL path). */\n providerId: string\n /** Accepted for interface compatibility; the platform's start endpoint is\n * provider-level and does not consume a connector id. */\n connectorId?: string\n /** Where the platform redirects the user back to after OAuth. */\n returnUrl: string\n /** Accepted for interface compatibility; not consumed by the start endpoint. */\n requestedScopes?: string[]\n /** CLI flow flag — affects the platform's post-auth redirect handling. */\n cli?: boolean\n}\n\nexport interface StartAuthResult {\n /** The URL to send the user to. Normalized across the platform's two start\n * branches: github returns `authorizationUrl`, substrate returns\n * `redirectUrl`. */\n authorizationUrl: string\n state: string\n expiresAt?: string\n scopes?: string[]\n}\n\nexport interface ConnectionHealth {\n status: 'unknown' | 'healthy' | 'unhealthy' | 'rate_limited' | (string & {})\n checkedAt: string\n error?: { code: string; message: string }\n}\n\nexport interface ConnectionHealthResult {\n connection: PlatformConnection\n health: ConnectionHealth\n}\n\n/** Last-known health for a connection, derived from the connection row. */\nexport interface HealthCheck {\n connectionId: string\n providerId: string\n /** Mirrors `PlatformConnection.health`. */\n status: ConnectionHealth['status']\n checkedAt?: string\n}\n\nexport interface MintTokenInput {\n /** The hub action the token authorizes (e.g. `slack.chat.postMessage`). */\n actionPath: string\n /** Bind to a specific connection, or … */\n connectionId?: string\n /** … resolve the connection by provider for the calling user. */\n provider?: string\n}\n\nexport interface MintTokenResult {\n tokenId: string\n token: string\n expiresAt: string\n}\n\nexport interface ExecInput {\n /** The hub action path to execute. */\n path: string\n input?: unknown\n connectionId?: string\n}\n\nexport interface PlatformHubStatus {\n contract?: unknown\n principal: { kind: string; userId: string; [k: string]: unknown }\n connections: { connectedProviderCount: number; unhealthyProviderCount: number }\n}\n\n/** Thrown when a `PlatformHubClient` request returns a non-success status. */\nexport class PlatformHubError extends Error {\n constructor(\n message: string,\n public readonly status: number,\n public readonly code: string | undefined,\n public readonly body: unknown,\n ) {\n super(message)\n this.name = 'PlatformHubError'\n }\n}\n\ninterface PlatformEnvelope<T> {\n success: boolean\n data?: T\n error?: { code?: string; message?: string } | string\n}\n\n/** HTTP client for the Tangle Platform Hub API: provider catalog, connection flow, and status. */\nexport class PlatformHubClient {\n private readonly baseUrl: string\n private readonly bearer: string\n private readonly fetchImpl: typeof fetch\n\n constructor(options: PlatformHubClientOptions) {\n if (!options.baseUrl) throw new Error('PlatformHubClient: baseUrl is required')\n if (!options.bearer) throw new Error('PlatformHubClient: bearer is required')\n this.baseUrl = options.baseUrl.replace(/\\/+$/, '')\n this.bearer = options.bearer\n this.fetchImpl =\n options.fetchImpl ??\n ((url: Parameters<typeof fetch>[0], init?: Parameters<typeof fetch>[1]) => fetch(url, init))\n }\n\n /** GET /v1/hub/providers — the connectable provider catalog. */\n catalog(): Promise<CatalogResult> {\n return this.request('GET', '/v1/hub/providers')\n }\n\n /** GET /v1/hub/connections — the calling user's live connections. */\n async listConnections(): Promise<PlatformConnection[]> {\n const data = await this.request<{ connections: PlatformConnection[] }>(\n 'GET',\n '/v1/hub/connections',\n )\n return data.connections\n }\n\n /** DELETE /v1/hub/connections/:connectionId — revoke + disable a connection. */\n revokeConnection(connectionId: string): Promise<{ connection: PlatformConnection }> {\n return this.request('DELETE', `/v1/hub/connections/${encodeURIComponent(connectionId)}`)\n }\n\n /**\n * POST /v1/hub/connections/:provider/start — begin OAuth/grant. The provider\n * is taken from the URL; the body carries `returnUrl` (+ `cli`). The platform's\n * two start branches name the URL field differently (github → `authorizationUrl`,\n * substrate → `redirectUrl`); this normalizes to `authorizationUrl`.\n */\n async startAuth(input: StartAuthInput): Promise<StartAuthResult> {\n const body: { returnUrl: string; cli?: boolean } = { returnUrl: input.returnUrl }\n if (input.cli !== undefined) body.cli = input.cli\n const data = await this.request<{\n authorizationUrl?: string\n redirectUrl?: string\n state: string\n expiresAt?: string\n scopes?: string[]\n }>('POST', `/v1/hub/connections/${encodeURIComponent(input.providerId)}/start`, body)\n const authorizationUrl = data.authorizationUrl ?? data.redirectUrl\n if (!authorizationUrl) {\n throw new PlatformHubError(\n 'Platform hub start response missing an authorization URL',\n 502,\n 'HUB_INVALID_START_RESPONSE',\n data,\n )\n }\n return { authorizationUrl, state: data.state, expiresAt: data.expiresAt, scopes: data.scopes }\n }\n\n /**\n * Last-known health for every connection. The platform has no global\n * healthcheck listing — health rides on each connection row — so this derives\n * the list from `listConnections()` (one request, no extra round-trips).\n */\n async listHealthchecks(): Promise<HealthCheck[]> {\n const connections = await this.listConnections()\n return connections.map((c) => ({\n connectionId: c.id,\n providerId: c.providerId,\n status: c.health,\n checkedAt: c.updatedAt,\n }))\n }\n\n /**\n * POST /v1/hub/connections/:connectionId/health — trigger a fresh health\n * probe for one connection and return its updated state.\n */\n checkConnectionHealth(connectionId: string): Promise<ConnectionHealthResult> {\n return this.request('POST', `/v1/hub/connections/${encodeURIComponent(connectionId)}/health`)\n }\n\n /**\n * Trigger a fresh health probe across all of the user's connections. The\n * platform exposes health per-connection only, so this fans out over\n * `listConnections()`. `scheduled` is the number of probes dispatched.\n */\n async runHealthchecks(): Promise<{ scheduled: number }> {\n const connections = await this.listConnections()\n await Promise.allSettled(connections.map((c) => this.checkConnectionHealth(c.id)))\n return { scheduled: connections.length }\n }\n\n /** GET /v1/hub/status — principal + aggregate connection counts. */\n status(): Promise<PlatformHubStatus> {\n return this.request('GET', '/v1/hub/status')\n }\n\n /**\n * POST /v1/hub/tokens — mint a short-lived, action-scoped capability token a\n * sandbox can use to invoke one hub action on the user's behalf without\n * seeing the underlying provider credential.\n */\n mintToken(input: MintTokenInput): Promise<MintTokenResult> {\n return this.request('POST', '/v1/hub/tokens', input)\n }\n\n /** POST /v1/hub/exec — execute a hub action and return its result. */\n async exec(input: ExecInput): Promise<unknown> {\n const data = await this.request<{ result: unknown }>('POST', '/v1/hub/exec', input)\n return data.result\n }\n\n private async request<T>(\n method: 'GET' | 'POST' | 'DELETE' | 'PUT',\n path: string,\n body?: unknown,\n ): Promise<T> {\n const headers: Record<string, string> = {\n authorization: `Bearer ${this.bearer}`,\n accept: 'application/json',\n }\n if (body !== undefined) headers['content-type'] = 'application/json'\n\n const res = await this.fetchImpl(`${this.baseUrl}${path}`, {\n method,\n headers,\n body: body !== undefined ? JSON.stringify(body) : undefined,\n })\n const text = await res.text()\n let parsed: PlatformEnvelope<T> | null = null\n if (text) {\n try {\n parsed = JSON.parse(text)\n } catch {\n // fall through to error handling below\n }\n }\n if (!res.ok || (parsed && parsed.success === false)) {\n const code = parsed?.error && typeof parsed.error === 'object' ? parsed.error.code : undefined\n const message =\n (parsed?.error && typeof parsed.error === 'object' && parsed.error.message) ||\n (typeof parsed?.error === 'string' ? parsed.error : `Platform hub error (${res.status})`)\n throw new PlatformHubError(message, res.status, code, parsed ?? text)\n }\n if (!parsed) {\n throw new PlatformHubError(\n `Platform hub returned non-JSON success (${res.status})`,\n res.status,\n undefined,\n text,\n )\n }\n if (parsed.data === undefined) {\n throw new PlatformHubError(\n 'Platform hub envelope missing `data`',\n res.status,\n undefined,\n parsed,\n )\n }\n return parsed.data\n }\n}\n"],"mappings":";;;AAkDO,IAAM,oBAAN,cAAgC,MAAM;AAAA,EAC3C,YACE,SACgB,QACA,MAChB;AACA,UAAM,OAAO;AAHG;AACA;AAGhB,SAAK,OAAO;AAAA,EACd;AAAA,EALkB;AAAA,EACA;AAKpB;AAGO,IAAM,qBAAN,MAAyB;AAAA,EACb;AAAA,EACA;AAAA,EACA;AAAA,EAEjB,YAAY,SAAoC;AAC9C,QAAI,CAAC,QAAQ,QAAS,OAAM,IAAI,MAAM,yCAAyC;AAC/E,QAAI,CAAC,QAAQ,MAAO,OAAM,IAAI,MAAM,uCAAuC;AAC3E,SAAK,UAAU,QAAQ,QAAQ,QAAQ,QAAQ,EAAE;AACjD,SAAK,QAAQ,QAAQ;AACrB,SAAK,YACH,QAAQ,cACP,CAAC,KAAkC,SAAuC,MAAM,KAAK,IAAI;AAAA,EAC9F;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,aAAa,SAAsC;AACjD,QAAI,CAAC,QAAQ,OAAO;AAClB,YAAM,IAAI,MAAM,6DAA6D;AAAA,IAC/E;AACA,UAAM,MAAM,IAAI,IAAI,yBAAyB,KAAK,OAAO;AACzD,QAAI,aAAa,IAAI,OAAO,KAAK,KAAK;AACtC,QAAI,aAAa,IAAI,SAAS,QAAQ,KAAK;AAC3C,QAAI,QAAQ,YAAa,KAAI,aAAa,IAAI,YAAY,QAAQ,WAAW;AAC7E,QAAI,QAAQ,OAAQ,KAAI,aAAa,IAAI,UAAU,QAAQ,MAAM;AACjE,QAAI,QAAQ,MAAO,KAAI,aAAa,IAAI,SAAS,QAAQ,KAAK;AAC9D,WAAO,IAAI,SAAS;AAAA,EACtB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,SAAS,MAA2C;AACxD,QAAI,CAAC,KAAM,OAAM,IAAI,MAAM,+CAA+C;AAC1E,UAAM,MAAM,MAAM,KAAK,UAAU,GAAG,KAAK,OAAO,wBAAwB;AAAA,MACtE,QAAQ;AAAA,MACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,MAC9C,MAAM,KAAK,UAAU,EAAE,MAAM,KAAK,KAAK,MAAM,CAAC;AAAA,IAChD,CAAC;AACD,UAAM,OAAO,MAAM,IAAI,KAAK,EAAE,MAAM,MAAM,IAAI;AAC9C,QAAI,CAAC,IAAI,IAAI;AACX,YAAM,UACJ,QAAQ,OAAO,SAAS,YAAY,WAAW,QAAQ,OAAO,KAAK,UAAU,WACzE,KAAK,QACL,6BAA6B,IAAI,MAAM;AAC7C,YAAM,IAAI,kBAAkB,SAAS,IAAI,QAAQ,IAAI;AAAA,IACvD;AACA,UAAM,SAAS;AACf,QAAI,CAAC,OAAO,UAAU,CAAC,OAAO,MAAM,IAAI;AACtC,YAAM,IAAI;AAAA,QACR;AAAA,QACA,IAAI;AAAA,QACJ;AAAA,MACF;AAAA,IACF;AACA,WAAO;AAAA,EACT;AACF;;;ACOO,IAAM,mBAAN,cAA+B,MAAM;AAAA,EAC1C,YACE,SACgB,QACA,MACA,MAChB;AACA,UAAM,OAAO;AAJG;AACA;AACA;AAGhB,SAAK,OAAO;AAAA,EACd;AAAA,EANkB;AAAA,EACA;AAAA,EACA;AAKpB;AASO,IAAM,oBAAN,MAAwB;AAAA,EACZ;AAAA,EACA;AAAA,EACA;AAAA,EAEjB,YAAY,SAAmC;AAC7C,QAAI,CAAC,QAAQ,QAAS,OAAM,IAAI,MAAM,wCAAwC;AAC9E,QAAI,CAAC,QAAQ,OAAQ,OAAM,IAAI,MAAM,uCAAuC;AAC5E,SAAK,UAAU,QAAQ,QAAQ,QAAQ,QAAQ,EAAE;AACjD,SAAK,SAAS,QAAQ;AACtB,SAAK,YACH,QAAQ,cACP,CAAC,KAAkC,SAAuC,MAAM,KAAK,IAAI;AAAA,EAC9F;AAAA;AAAA,EAGA,UAAkC;AAChC,WAAO,KAAK,QAAQ,OAAO,mBAAmB;AAAA,EAChD;AAAA;AAAA,EAGA,MAAM,kBAAiD;AACrD,UAAM,OAAO,MAAM,KAAK;AAAA,MACtB;AAAA,MACA;AAAA,IACF;AACA,WAAO,KAAK;AAAA,EACd;AAAA;AAAA,EAGA,iBAAiB,cAAmE;AAClF,WAAO,KAAK,QAAQ,UAAU,uBAAuB,mBAAmB,YAAY,CAAC,EAAE;AAAA,EACzF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,UAAU,OAAiD;AAC/D,UAAM,OAA6C,EAAE,WAAW,MAAM,UAAU;AAChF,QAAI,MAAM,QAAQ,OAAW,MAAK,MAAM,MAAM;AAC9C,UAAM,OAAO,MAAM,KAAK,QAMrB,QAAQ,uBAAuB,mBAAmB,MAAM,UAAU,CAAC,UAAU,IAAI;AACpF,UAAM,mBAAmB,KAAK,oBAAoB,KAAK;AACvD,QAAI,CAAC,kBAAkB;AACrB,YAAM,IAAI;AAAA,QACR;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AACA,WAAO,EAAE,kBAAkB,OAAO,KAAK,OAAO,WAAW,KAAK,WAAW,QAAQ,KAAK,OAAO;AAAA,EAC/F;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,mBAA2C;AAC/C,UAAM,cAAc,MAAM,KAAK,gBAAgB;AAC/C,WAAO,YAAY,IAAI,CAAC,OAAO;AAAA,MAC7B,cAAc,EAAE;AAAA,MAChB,YAAY,EAAE;AAAA,MACd,QAAQ,EAAE;AAAA,MACV,WAAW,EAAE;AAAA,IACf,EAAE;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,sBAAsB,cAAuD;AAC3E,WAAO,KAAK,QAAQ,QAAQ,uBAAuB,mBAAmB,YAAY,CAAC,SAAS;AAAA,EAC9F;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,kBAAkD;AACtD,UAAM,cAAc,MAAM,KAAK,gBAAgB;AAC/C,UAAM,QAAQ,WAAW,YAAY,IAAI,CAAC,MAAM,KAAK,sBAAsB,EAAE,EAAE,CAAC,CAAC;AACjF,WAAO,EAAE,WAAW,YAAY,OAAO;AAAA,EACzC;AAAA;AAAA,EAGA,SAAqC;AACnC,WAAO,KAAK,QAAQ,OAAO,gBAAgB;AAAA,EAC7C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,UAAU,OAAiD;AACzD,WAAO,KAAK,QAAQ,QAAQ,kBAAkB,KAAK;AAAA,EACrD;AAAA;AAAA,EAGA,MAAM,KAAK,OAAoC;AAC7C,UAAM,OAAO,MAAM,KAAK,QAA6B,QAAQ,gBAAgB,KAAK;AAClF,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,MAAc,QACZ,QACA,MACA,MACY;AACZ,UAAM,UAAkC;AAAA,MACtC,eAAe,UAAU,KAAK,MAAM;AAAA,MACpC,QAAQ;AAAA,IACV;AACA,QAAI,SAAS,OAAW,SAAQ,cAAc,IAAI;AAElD,UAAM,MAAM,MAAM,KAAK,UAAU,GAAG,KAAK,OAAO,GAAG,IAAI,IAAI;AAAA,MACzD;AAAA,MACA;AAAA,MACA,MAAM,SAAS,SAAY,KAAK,UAAU,IAAI,IAAI;AAAA,IACpD,CAAC;AACD,UAAM,OAAO,MAAM,IAAI,KAAK;AAC5B,QAAI,SAAqC;AACzC,QAAI,MAAM;AACR,UAAI;AACF,iBAAS,KAAK,MAAM,IAAI;AAAA,MAC1B,QAAQ;AAAA,MAER;AAAA,IACF;AACA,QAAI,CAAC,IAAI,MAAO,UAAU,OAAO,YAAY,OAAQ;AACnD,YAAM,OAAO,QAAQ,SAAS,OAAO,OAAO,UAAU,WAAW,OAAO,MAAM,OAAO;AACrF,YAAM,UACH,QAAQ,SAAS,OAAO,OAAO,UAAU,YAAY,OAAO,MAAM,YAClE,OAAO,QAAQ,UAAU,WAAW,OAAO,QAAQ,uBAAuB,IAAI,MAAM;AACvF,YAAM,IAAI,iBAAiB,SAAS,IAAI,QAAQ,MAAM,UAAU,IAAI;AAAA,IACtE;AACA,QAAI,CAAC,QAAQ;AACX,YAAM,IAAI;AAAA,QACR,2CAA2C,IAAI,MAAM;AAAA,QACrD,IAAI;AAAA,QACJ;AAAA,QACA;AAAA,MACF;AAAA,IACF;AACA,QAAI,OAAO,SAAS,QAAW;AAC7B,YAAM,IAAI;AAAA,QACR;AAAA,QACA,IAAI;AAAA,QACJ;AAAA,QACA;AAAA,MACF;AAAA,IACF;AACA,WAAO,OAAO;AAAA,EAChB;AACF;","names":[]}
@@ -1,12 +1,11 @@
1
- import { a as UiFinding, U as UiLens } from './substrate-rNj6TDc3.js';
2
- export { C as CoderTask, b as UI_FINDING_SEVERITIES, c as UI_LENSES, d as UiFindingScreenshot, e as UiFindingSeverity, f as coderTaskToPrompt } from './substrate-rNj6TDc3.js';
3
- import { S as SandboxClient, b as OutputAdapter, V as Validator, A as AgentRunSpec } from './types-BF-MEsQB.js';
1
+ import { a as UiFinding, U as UiLens } from './substrate-DO2GHNg2.js';
2
+ export { C as CoderTask, b as UI_FINDING_SEVERITIES, c as UI_LENSES, d as UiFindingScreenshot, e as UiFindingSeverity, f as coderTaskToPrompt } from './substrate-DO2GHNg2.js';
3
+ import { S as SandboxClient, b as OutputAdapter, V as Validator, A as AgentRunSpec } from './types-ESeMOj94.js';
4
4
  import { SandboxEvent } from '@tangle-network/sandbox';
5
5
  import { AgentProfile } from '@tangle-network/agent-interface';
6
6
  import '@tangle-network/agent-eval';
7
7
 
8
8
  /**
9
- * @experimental
10
9
  *
11
10
  * UI-audit issue writer — pure I/O. Takes a workspace dir + `UiFinding[]`
12
11
  * and emits:
@@ -21,6 +20,8 @@ import '@tangle-network/agent-eval';
21
20
  * The writer is deterministic, idempotent for `appendFindings()`, and
22
21
  * never invokes an LLM. It assigns the next monotonic id to a finding the
23
22
  * caller did not pre-id.
23
+ *
24
+ * @experimental
24
25
  */
25
26
 
26
27
  /** @experimental */
@@ -41,9 +42,9 @@ interface AuditRegistryCapture {
41
42
  elementSelector?: string;
42
43
  capturedAt: string;
43
44
  }
44
- /** @experimental */
45
+ /** Create the `issues/`, `screenshots/`, and `registry.json` scaffold in a new audit workspace. @experimental */
45
46
  declare function initAuditWorkspace(workspaceDir: string): Promise<void>;
46
- /** @experimental */
47
+ /** Read and validate the `registry.json` from an audit workspace. @experimental */
47
48
  declare function readAuditRegistry(workspaceDir: string): Promise<AuditRegistry>;
48
49
  /** @experimental */
49
50
  interface AppendFindingsResult {
@@ -86,7 +87,7 @@ interface AuditIndex {
86
87
  byLens: Partial<Record<UiLens, number>>;
87
88
  byRoute: Record<string, number>;
88
89
  }
89
- /** @experimental */
90
+ /** Compute finding counts by severity, lens, and route from an `AuditRegistry`. @experimental */
90
91
  declare function summarizeRegistry(reg: AuditRegistry): AuditIndex;
91
92
  /**
92
93
  * Regenerate `<workspace>/index.md` from registry.json.
@@ -96,7 +97,6 @@ declare function summarizeRegistry(reg: AuditRegistry): AuditIndex;
96
97
  declare function writeAuditIndex(workspaceDir: string): Promise<string>;
97
98
 
98
99
  /**
99
- * @experimental
100
100
  *
101
101
  * UI auditor task + output shapes — what one iteration of the audit loop
102
102
  * does and what it returns.
@@ -105,6 +105,8 @@ declare function writeAuditIndex(workspaceDir: string): Promise<string>;
105
105
  * decides which iterations to plan (lens-cycling, route-cycling,
106
106
  * refine-on-low-yield, etc.); the iteration itself captures screenshots
107
107
  * and asks a vision judge to identify findings under that lens.
108
+ *
109
+ * @experimental
108
110
  */
109
111
 
110
112
  /** @experimental */
@@ -190,7 +192,6 @@ interface UiAuditOutput {
190
192
  }
191
193
 
192
194
  /**
193
- * @experimental
194
195
  *
195
196
  * UI judge seam — consumer-supplied vision LLM hook the in-process
196
197
  * auditor client invokes to identify findings from captured screenshots.
@@ -212,6 +213,8 @@ interface UiAuditOutput {
212
213
  * - Treat any exception thrown by the judge as the iteration's failure —
213
214
  * do not swallow LLM errors. Per agent-runtime's fail-loud doctrine,
214
215
  * surfacing the error to the kernel beats producing a silent zero.
216
+ *
217
+ * @experimental
215
218
  */
216
219
 
217
220
  /** @experimental */
@@ -246,7 +249,6 @@ interface UiJudgeOutput {
246
249
  type UiJudge = (input: UiJudgeInput) => Promise<UiJudgeOutput>;
247
250
 
248
251
  /**
249
- * @experimental
250
252
  *
251
253
  * `createInProcessUiAuditClient` — a `SandboxClient` that drives a
252
254
  * Playwright browser in-process and delegates finding identification to a
@@ -268,6 +270,8 @@ type UiJudge = (input: UiJudgeInput) => Promise<UiJudgeOutput>;
268
270
  * Concurrency: each iteration's prompt carries a self-describing task
269
271
  * envelope (see `prompt.ts`), so concurrent fanout iterations do not race
270
272
  * over per-client side state.
273
+ *
274
+ * @experimental
271
275
  */
272
276
 
273
277
  /** @experimental */
@@ -337,7 +341,7 @@ interface PageHandle {
337
341
  };
338
342
  };
339
343
  }
340
- /** @experimental */
344
+ /** Create a `SandboxClient` that drives a local Playwright browser for in-process UI audits. @experimental */
341
345
  declare function createInProcessUiAuditClient(options: InProcessUiAuditClientOptions): SandboxClient & {
342
346
  /**
343
347
  * Close the underlying browser. Idempotent.
@@ -355,7 +359,6 @@ declare function createInProcessUiAuditClient(options: InProcessUiAuditClientOpt
355
359
  };
356
360
 
357
361
  /**
358
- * @experimental
359
362
  *
360
363
  * Per-lens guidance the auditor inlines into its system prompt for an
361
364
  * iteration. Each entry is a self-contained brief — the same content the
@@ -365,11 +368,13 @@ declare function createInProcessUiAuditClient(options: InProcessUiAuditClientOpt
365
368
  * Briefs are deliberately concrete: they enumerate the SIGNALS to look for
366
369
  * and the cross-lens distinctions to respect, so the judge files fewer
367
370
  * pile-on findings under generic labels.
371
+ *
372
+ * @experimental
368
373
  */
369
374
 
370
- /** @experimental */
375
+ /** Cross-lens rules injected into every UI audit iteration: finding quality standards and scope limits. @experimental */
371
376
  declare const SHARED_AUDITOR_RULES: string;
372
- /** @experimental */
377
+ /** Per-lens auditor briefs: concrete signals to look for and cross-lens distinctions to respect. @experimental */
373
378
  declare const LENS_BRIEFS: Record<UiLens, string>;
374
379
  /**
375
380
  * Build a system prompt for a single auditor iteration.
@@ -379,7 +384,6 @@ declare const LENS_BRIEFS: Record<UiLens, string>;
379
384
  declare function buildAuditorSystemPrompt(lens: UiLens): string;
380
385
 
381
386
  /**
382
- * @experimental
383
387
  *
384
388
  * Sandbox-event stream → UiAuditOutput decoder. The custom auditor
385
389
  * `SandboxClient` emits events of the form:
@@ -392,13 +396,14 @@ declare function buildAuditorSystemPrompt(lens: UiLens): string;
392
396
  *
393
397
  * Other event types are tolerated and ignored. The adapter is pure: it
394
398
  * folds an already-collected event array into a UiAuditOutput.
399
+ *
400
+ * @experimental
395
401
  */
396
402
 
397
- /** @experimental */
403
+ /** Parse raw `SandboxEvent` emissions from an audit iteration into structured `UiAuditOutput`. @experimental */
398
404
  declare function parseAuditorEvents(events: SandboxEvent[]): UiAuditOutput;
399
405
 
400
406
  /**
401
- * @experimental
402
407
  *
403
408
  * `uiAuditorProfile` — preset for vision-driven UI audit iterations.
404
409
  *
@@ -407,6 +412,8 @@ declare function parseAuditorEvents(events: SandboxEvent[]): UiAuditOutput;
407
412
  * vision-capable judge driving a browser. The loop kernel still iterates
408
413
  * `client.create() → box.streamPrompt() → box.delete()`; the client/box pair are provided by
409
414
  * `createInProcessUiAuditClient` (in `./in-process-client.ts`) or a consumer-supplied `SandboxClient`.
415
+ *
416
+ * @experimental
410
417
  */
411
418
 
412
419
  /** @experimental */
@@ -427,7 +434,11 @@ interface UiAuditorProfileOptions {
427
434
  */
428
435
  task?: UiAuditTask;
429
436
  }
430
- /** @experimental */
437
+ /**
438
+ * Preset `runLoop` bundle for vision-driven UI audits: returns the `AgentRunSpec`, output adapter, validator, and prompt formatter the loop kernel needs.
439
+ *
440
+ * @experimental
441
+ */
431
442
  declare function uiAuditorProfile(options?: UiAuditorProfileOptions): {
432
443
  profile: AgentProfile;
433
444
  taskToPrompt: (task: UiAuditTask) => string;
@@ -437,7 +448,6 @@ declare function uiAuditorProfile(options?: UiAuditorProfileOptions): {
437
448
  };
438
449
 
439
450
  /**
440
- * @experimental
441
451
  *
442
452
  * Prompt formatter for the auditor profile. `formatAuditorPrompt` produces
443
453
  * the user message handed to the iteration — describes the captures to be
@@ -452,9 +462,11 @@ declare function uiAuditorProfile(options?: UiAuditorProfileOptions): {
452
462
  *
453
463
  * The formatter is pure and deterministic — re-run on the same task
454
464
  * produces the same prompt. Tests and trace replays rely on this.
465
+ *
466
+ * @experimental
455
467
  */
456
468
 
457
- /** @experimental */
469
+ /** Wrap a `UiAuditTask` in a machine-readable envelope so iterations are self-describing. @experimental */
458
470
  declare function encodeAuditTaskEnvelope(task: UiAuditTask): string;
459
471
  /**
460
472
  * Parse a task envelope back out of a prompt string. Returns undefined if
@@ -464,11 +476,10 @@ declare function encodeAuditTaskEnvelope(task: UiAuditTask): string;
464
476
  * @experimental
465
477
  */
466
478
  declare function decodeAuditTaskEnvelope(prompt: string): UiAuditTask | undefined;
467
- /** @experimental */
479
+ /** Produce the user message for one audit iteration: lens, captures to take, and the task envelope. @experimental */
468
480
  declare function formatAuditorPrompt(task: UiAuditTask): string;
469
481
 
470
482
  /**
471
- * @experimental
472
483
  *
473
484
  * Auditor validator — scores a single iteration's findings for actionability
474
485
  * and gates the iteration result. The kernel uses `valid` + `score` for
@@ -493,9 +504,11 @@ declare function formatAuditorPrompt(task: UiAuditTask): string;
493
504
  * An iteration with zero findings scores 0.5 by convention — neither a
494
505
  * confident pass nor a hard failure (the judge might just have nothing to
495
506
  * say on this lens). The driver decides what to do with it.
507
+ *
508
+ * @experimental
496
509
  */
497
510
 
498
- /** @experimental */
511
+ /** Build a `Validator` that rejects off-lens findings and findings missing screenshot evidence. @experimental */
499
512
  declare function createUiAuditorValidator(task: UiAuditTask): Validator<UiAuditOutput>;
500
513
 
501
514
  export { type AppendFindingsResult, type AuditIndex, type AuditRegistry, type AuditRegistryCapture, type BrowserContextHandle, type BrowserHandle, type InProcessUiAuditClientOptions, LENS_BRIEFS, type PageHandle, type RegisterCapturesOptions, SHARED_AUDITOR_RULES, type UiAuditCapture, type UiAuditCaptureRequest, type UiAuditOutput, type UiAuditTask, type UiAuditViewport, type UiAuditorProfileOptions, UiFinding, type UiJudge, type UiJudgeInput, type UiJudgeOutput, type UiJudgeTokenUsage, UiLens, appendFindings, buildAuditorSystemPrompt, createInProcessUiAuditClient, createUiAuditorValidator, decodeAuditTaskEnvelope, encodeAuditTaskEnvelope, formatAuditorPrompt, initAuditWorkspace, parseAuditorEvents, readAuditRegistry, registerCaptures, summarizeRegistry, uiAuditorProfile, writeAuditIndex };
package/dist/profiles.js CHANGED
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  coderTaskToPrompt
3
- } from "./chunk-UZ5SODU7.js";
3
+ } from "./chunk-5IBQAPVB.js";
4
4
  import {
5
5
  UI_FINDING_SEVERITIES,
6
6
  UI_LENSES
7
- } from "./chunk-WIR4HOOJ.js";
7
+ } from "./chunk-DPEUKJRO.js";
8
8
  import "./chunk-DGUM43GV.js";
9
9
 
10
10
  // src/audit/issue-writer.ts