@mastra/factory 0.0.0 → 0.1.0-alpha.2
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 +10 -0
- package/LICENSE.md +30 -0
- package/dist/auth.d.ts +181 -0
- package/dist/auth.d.ts.map +1 -0
- package/dist/auth.js +370 -0
- package/dist/auth.js.map +1 -0
- package/dist/capabilities/connection.d.ts +9 -0
- package/dist/capabilities/connection.d.ts.map +1 -0
- package/dist/capabilities/connection.js +1 -0
- package/dist/capabilities/connection.js.map +1 -0
- package/dist/capabilities/intake.d.ts +93 -0
- package/dist/capabilities/intake.d.ts.map +1 -0
- package/dist/capabilities/intake.js +1 -0
- package/dist/capabilities/intake.js.map +1 -0
- package/dist/capabilities/version-control.d.ts +239 -0
- package/dist/capabilities/version-control.d.ts.map +1 -0
- package/dist/capabilities/version-control.js +1 -0
- package/dist/capabilities/version-control.js.map +1 -0
- package/dist/factory.d.ts +145 -0
- package/dist/factory.d.ts.map +1 -0
- package/dist/factory.js +38208 -0
- package/dist/factory.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +38208 -0
- package/dist/index.js.map +1 -0
- package/dist/integrations/base.d.ts +197 -0
- package/dist/integrations/base.d.ts.map +1 -0
- package/dist/integrations/base.js +1 -0
- package/dist/integrations/base.js.map +1 -0
- package/dist/integrations/github/config.d.ts +60 -0
- package/dist/integrations/github/config.d.ts.map +1 -0
- package/dist/integrations/github/config.js +28 -0
- package/dist/integrations/github/config.js.map +1 -0
- package/dist/integrations/github/factory-session.d.ts +12 -0
- package/dist/integrations/github/factory-session.d.ts.map +1 -0
- package/dist/integrations/github/factory-session.js +41 -0
- package/dist/integrations/github/factory-session.js.map +1 -0
- package/dist/integrations/github/integration.d.ts +191 -0
- package/dist/integrations/github/integration.d.ts.map +1 -0
- package/dist/integrations/github/integration.js +2999 -0
- package/dist/integrations/github/integration.js.map +1 -0
- package/dist/integrations/github/issue-triage.d.ts +27 -0
- package/dist/integrations/github/issue-triage.d.ts.map +1 -0
- package/dist/integrations/github/issue-triage.js +82 -0
- package/dist/integrations/github/issue-triage.js.map +1 -0
- package/dist/integrations/github/project-lock.d.ts +78 -0
- package/dist/integrations/github/project-lock.d.ts.map +1 -0
- package/dist/integrations/github/project-lock.js +70 -0
- package/dist/integrations/github/project-lock.js.map +1 -0
- package/dist/integrations/github/provenance.d.ts +27 -0
- package/dist/integrations/github/provenance.d.ts.map +1 -0
- package/dist/integrations/github/provenance.js +104 -0
- package/dist/integrations/github/provenance.js.map +1 -0
- package/dist/integrations/github/routes.d.ts +72 -0
- package/dist/integrations/github/routes.d.ts.map +1 -0
- package/dist/integrations/github/routes.js +1832 -0
- package/dist/integrations/github/routes.js.map +1 -0
- package/dist/integrations/github/sandbox.d.ts +268 -0
- package/dist/integrations/github/sandbox.d.ts.map +1 -0
- package/dist/integrations/github/sandbox.js +381 -0
- package/dist/integrations/github/sandbox.js.map +1 -0
- package/dist/integrations/github/session-subscriptions.d.ts +23 -0
- package/dist/integrations/github/session-subscriptions.d.ts.map +1 -0
- package/dist/integrations/github/session-subscriptions.js +190 -0
- package/dist/integrations/github/session-subscriptions.js.map +1 -0
- package/dist/integrations/github/subscriptions.d.ts +54 -0
- package/dist/integrations/github/subscriptions.d.ts.map +1 -0
- package/dist/integrations/github/subscriptions.js +70 -0
- package/dist/integrations/github/subscriptions.js.map +1 -0
- package/dist/integrations/github/webhook.d.ts +87 -0
- package/dist/integrations/github/webhook.d.ts.map +1 -0
- package/dist/integrations/github/webhook.js +381 -0
- package/dist/integrations/github/webhook.js.map +1 -0
- package/dist/integrations/linear/agent-tools.d.ts +34 -0
- package/dist/integrations/linear/agent-tools.d.ts.map +1 -0
- package/dist/integrations/linear/agent-tools.js +108 -0
- package/dist/integrations/linear/agent-tools.js.map +1 -0
- package/dist/integrations/linear/integration.d.ts +233 -0
- package/dist/integrations/linear/integration.d.ts.map +1 -0
- package/dist/integrations/linear/integration.js +962 -0
- package/dist/integrations/linear/integration.js.map +1 -0
- package/dist/integrations/linear/routes.d.ts +61 -0
- package/dist/integrations/linear/routes.d.ts.map +1 -0
- package/dist/integrations/linear/routes.js +242 -0
- package/dist/integrations/linear/routes.js.map +1 -0
- package/dist/integrations/linear/storage.d.ts +65 -0
- package/dist/integrations/linear/storage.d.ts.map +1 -0
- package/dist/integrations/linear/storage.js +1 -0
- package/dist/integrations/linear/storage.js.map +1 -0
- package/dist/integrations/platform/api-client.d.ts +24 -0
- package/dist/integrations/platform/api-client.d.ts.map +1 -0
- package/dist/integrations/platform/api-client.js +153 -0
- package/dist/integrations/platform/api-client.js.map +1 -0
- package/dist/integrations/platform/github/event-worker.d.ts +42 -0
- package/dist/integrations/platform/github/event-worker.d.ts.map +1 -0
- package/dist/integrations/platform/github/event-worker.js +577 -0
- package/dist/integrations/platform/github/event-worker.js.map +1 -0
- package/dist/integrations/platform/github/integration.d.ts +36 -0
- package/dist/integrations/platform/github/integration.d.ts.map +1 -0
- package/dist/integrations/platform/github/integration.js +3242 -0
- package/dist/integrations/platform/github/integration.js.map +1 -0
- package/dist/integrations/platform/linear/integration.d.ts +46 -0
- package/dist/integrations/platform/linear/integration.d.ts.map +1 -0
- package/dist/integrations/platform/linear/integration.js +891 -0
- package/dist/integrations/platform/linear/integration.js.map +1 -0
- package/dist/integrations/workos/integration.d.ts +39 -0
- package/dist/integrations/workos/integration.d.ts.map +1 -0
- package/dist/integrations/workos/integration.js +96 -0
- package/dist/integrations/workos/integration.js.map +1 -0
- package/dist/routes/config.d.ts +220 -0
- package/dist/routes/config.d.ts.map +1 -0
- package/dist/routes/config.js +770 -0
- package/dist/routes/config.js.map +1 -0
- package/dist/routes/fs.d.ts +105 -0
- package/dist/routes/fs.d.ts.map +1 -0
- package/dist/routes/fs.js +294 -0
- package/dist/routes/fs.js.map +1 -0
- package/dist/routes/intake.d.ts +23 -0
- package/dist/routes/intake.d.ts.map +1 -0
- package/dist/routes/intake.js +179 -0
- package/dist/routes/intake.js.map +1 -0
- package/dist/routes/oauth.d.ts +43 -0
- package/dist/routes/oauth.d.ts.map +1 -0
- package/dist/routes/oauth.js +25058 -0
- package/dist/routes/oauth.js.map +1 -0
- package/dist/routes/projects.d.ts +19 -0
- package/dist/routes/projects.d.ts.map +1 -0
- package/dist/routes/projects.js +395 -0
- package/dist/routes/projects.js.map +1 -0
- package/dist/routes/provider-credentials.d.ts +81 -0
- package/dist/routes/provider-credentials.d.ts.map +1 -0
- package/dist/routes/provider-credentials.js +68 -0
- package/dist/routes/provider-credentials.js.map +1 -0
- package/dist/routes/route.d.ts +48 -0
- package/dist/routes/route.d.ts.map +1 -0
- package/dist/routes/route.js +11 -0
- package/dist/routes/route.js.map +1 -0
- package/dist/routes/skills.d.ts +30 -0
- package/dist/routes/skills.d.ts.map +1 -0
- package/dist/routes/skills.js +181 -0
- package/dist/routes/skills.js.map +1 -0
- package/dist/routes/surface.d.ts +83 -0
- package/dist/routes/surface.d.ts.map +1 -0
- package/dist/routes/surface.js +28504 -0
- package/dist/routes/surface.js.map +1 -0
- package/dist/routes/tenant-credentials.d.ts +74 -0
- package/dist/routes/tenant-credentials.d.ts.map +1 -0
- package/dist/routes/tenant-credentials.js +181 -0
- package/dist/routes/tenant-credentials.js.map +1 -0
- package/dist/routes/work-items.d.ts +40 -0
- package/dist/routes/work-items.d.ts.map +1 -0
- package/dist/routes/work-items.js +902 -0
- package/dist/routes/work-items.js.map +1 -0
- package/dist/rules/binding-context.d.ts +5 -0
- package/dist/rules/binding-context.d.ts.map +1 -0
- package/dist/rules/binding-context.js +40 -0
- package/dist/rules/binding-context.js.map +1 -0
- package/dist/rules/defaults.d.ts +9 -0
- package/dist/rules/defaults.d.ts.map +1 -0
- package/dist/rules/defaults.js +328 -0
- package/dist/rules/defaults.js.map +1 -0
- package/dist/rules/dispatcher.d.ts +40 -0
- package/dist/rules/dispatcher.d.ts.map +1 -0
- package/dist/rules/dispatcher.js +695 -0
- package/dist/rules/dispatcher.js.map +1 -0
- package/dist/rules/github-service.d.ts +27 -0
- package/dist/rules/github-service.d.ts.map +1 -0
- package/dist/rules/github-service.js +460 -0
- package/dist/rules/github-service.js.map +1 -0
- package/dist/rules/index.d.ts +7 -0
- package/dist/rules/index.d.ts.map +1 -0
- package/dist/rules/index.js +577 -0
- package/dist/rules/index.js.map +1 -0
- package/dist/rules/linear-service.d.ts +27 -0
- package/dist/rules/linear-service.d.ts.map +1 -0
- package/dist/rules/linear-service.js +343 -0
- package/dist/rules/linear-service.js.map +1 -0
- package/dist/rules/processor.d.ts +54 -0
- package/dist/rules/processor.d.ts.map +1 -0
- package/dist/rules/processor.js +629 -0
- package/dist/rules/processor.js.map +1 -0
- package/dist/rules/resolve.d.ts +17 -0
- package/dist/rules/resolve.d.ts.map +1 -0
- package/dist/rules/resolve.js +27 -0
- package/dist/rules/resolve.js.map +1 -0
- package/dist/rules/start-coordinator.d.ts +58 -0
- package/dist/rules/start-coordinator.d.ts.map +1 -0
- package/dist/rules/start-coordinator.js +136 -0
- package/dist/rules/start-coordinator.js.map +1 -0
- package/dist/rules/tools.d.ts +10 -0
- package/dist/rules/tools.d.ts.map +1 -0
- package/dist/rules/tools.js +93 -0
- package/dist/rules/tools.js.map +1 -0
- package/dist/rules/transition-service.d.ts +32 -0
- package/dist/rules/transition-service.d.ts.map +1 -0
- package/dist/rules/transition-service.js +474 -0
- package/dist/rules/transition-service.js.map +1 -0
- package/dist/rules/types.d.ts +220 -0
- package/dist/rules/types.d.ts.map +1 -0
- package/dist/rules/types.js +33 -0
- package/dist/rules/types.js.map +1 -0
- package/dist/rules/validation.d.ts +11 -0
- package/dist/rules/validation.d.ts.map +1 -0
- package/dist/rules/validation.js +310 -0
- package/dist/rules/validation.js.map +1 -0
- package/dist/sandbox/fleet.d.ts +208 -0
- package/dist/sandbox/fleet.d.ts.map +1 -0
- package/dist/sandbox/fleet.js +259 -0
- package/dist/sandbox/fleet.js.map +1 -0
- package/dist/sandbox/reattach.d.ts +3 -0
- package/dist/sandbox/reattach.d.ts.map +1 -0
- package/dist/sandbox/reattach.js +9 -0
- package/dist/sandbox/reattach.js.map +1 -0
- package/dist/server-error.d.ts +12 -0
- package/dist/server-error.d.ts.map +1 -0
- package/dist/server-error.js +20 -0
- package/dist/server-error.js.map +1 -0
- package/dist/skills/service.d.ts +48 -0
- package/dist/skills/service.d.ts.map +1 -0
- package/dist/skills/service.js +45 -0
- package/dist/skills/service.js.map +1 -0
- package/dist/spa-static.d.ts +34 -0
- package/dist/spa-static.d.ts.map +1 -0
- package/dist/spa-static.js +73 -0
- package/dist/spa-static.js.map +1 -0
- package/dist/state-signing.d.ts +48 -0
- package/dist/state-signing.d.ts.map +1 -0
- package/dist/state-signing.js +48 -0
- package/dist/state-signing.js.map +1 -0
- package/dist/storage/domains/audit/agent-audit.d.ts +27 -0
- package/dist/storage/domains/audit/agent-audit.d.ts.map +1 -0
- package/dist/storage/domains/audit/agent-audit.js +65 -0
- package/dist/storage/domains/audit/agent-audit.js.map +1 -0
- package/dist/storage/domains/audit/base.d.ts +140 -0
- package/dist/storage/domains/audit/base.d.ts.map +1 -0
- package/dist/storage/domains/audit/base.js +127 -0
- package/dist/storage/domains/audit/base.js.map +1 -0
- package/dist/storage/domains/audit/domain.d.ts +69 -0
- package/dist/storage/domains/audit/domain.d.ts.map +1 -0
- package/dist/storage/domains/audit/domain.js +165 -0
- package/dist/storage/domains/audit/domain.js.map +1 -0
- package/dist/storage/domains/credentials/base.d.ts +134 -0
- package/dist/storage/domains/credentials/base.d.ts.map +1 -0
- package/dist/storage/domains/credentials/base.js +257 -0
- package/dist/storage/domains/credentials/base.js.map +1 -0
- package/dist/storage/domains/intake/base.d.ts +38 -0
- package/dist/storage/domains/intake/base.d.ts.map +1 -0
- package/dist/storage/domains/intake/base.js +62 -0
- package/dist/storage/domains/intake/base.js.map +1 -0
- package/dist/storage/domains/integrations/base.d.ts +126 -0
- package/dist/storage/domains/integrations/base.d.ts.map +1 -0
- package/dist/storage/domains/integrations/base.js +252 -0
- package/dist/storage/domains/integrations/base.js.map +1 -0
- package/dist/storage/domains/model-packs/base.d.ts +49 -0
- package/dist/storage/domains/model-packs/base.d.ts.map +1 -0
- package/dist/storage/domains/model-packs/base.js +95 -0
- package/dist/storage/domains/model-packs/base.js.map +1 -0
- package/dist/storage/domains/projects/base.d.ts +55 -0
- package/dist/storage/domains/projects/base.d.ts.map +1 -0
- package/dist/storage/domains/projects/base.js +99 -0
- package/dist/storage/domains/projects/base.js.map +1 -0
- package/dist/storage/domains/queue-health/base.d.ts +52 -0
- package/dist/storage/domains/queue-health/base.d.ts.map +1 -0
- package/dist/storage/domains/queue-health/base.js +87 -0
- package/dist/storage/domains/queue-health/base.js.map +1 -0
- package/dist/storage/domains/source-control/base.d.ts +288 -0
- package/dist/storage/domains/source-control/base.d.ts.map +1 -0
- package/dist/storage/domains/source-control/base.js +722 -0
- package/dist/storage/domains/source-control/base.js.map +1 -0
- package/dist/storage/domains/source-control/inmemory.d.ts +158 -0
- package/dist/storage/domains/source-control/inmemory.d.ts.map +1 -0
- package/dist/storage/domains/source-control/inmemory.js +348 -0
- package/dist/storage/domains/source-control/inmemory.js.map +1 -0
- package/dist/storage/domains/work-items/base.d.ts +412 -0
- package/dist/storage/domains/work-items/base.d.ts.map +1 -0
- package/dist/storage/domains/work-items/base.js +1174 -0
- package/dist/storage/domains/work-items/base.js.map +1 -0
- package/dist/storage/domains/work-items/metrics.d.ts +101 -0
- package/dist/storage/domains/work-items/metrics.d.ts.map +1 -0
- package/dist/storage/domains/work-items/metrics.js +203 -0
- package/dist/storage/domains/work-items/metrics.js.map +1 -0
- package/dist/workspace.d.ts +20 -0
- package/dist/workspace.d.ts.map +1 -0
- package/dist/workspace.js +364 -0
- package/dist/workspace.js.map +1 -0
- package/package.json +19 -19
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/routes/provider-credentials.ts"],"sourcesContent":["/**\n * Per-request model-provider credential context.\n *\n * The provider config/OAuth routes serve two deployment shapes:\n *\n * - **Local** (no web auth adapter): credentials live in the server-global\n * file-backed `AuthStorage` (`auth.json`) — unchanged TUI behavior.\n * - **Tenant** (auth adapter active): credentials live in the\n * `model-credentials` factory storage domain, scoped per `(orgId, userId)`\n * with optional org-wide rows (`userId` absent).\n *\n * `resolveCredentialContext` decides which shape a request is in: an\n * authenticated user always gets the tenant path; an unauthenticated request\n * is rejected when auth is enabled and falls back to local otherwise.\n */\n\nimport type { Context } from 'hono';\n\nimport type {\n CredentialRecord,\n LoginSessionKind,\n ModelCredentialsStorage,\n} from '../storage/domains/credentials/base.js';\nimport type { RouteAuth } from './route.js';\n\n/**\n * OAuth credentials are stored under the auth provider id, which differs from\n * the catalog provider id for OpenAI (stored as `openai-codex`). Tenant rows\n * use the same keying so one lookup serves both OAuth tokens and API keys.\n */\nexport function getAuthProviderId(provider: string): string {\n return provider === 'openai' ? 'openai-codex' : provider;\n}\n\n/**\n * Providers that support a browser-driven OAuth sign-in flow, keyed by\n * *catalog* provider id (what the routes and settings UI use). All flows need\n * no inbound connection to the server: Anthropic uses paste-code PKCE, the\n * rest use RFC 8628-style device codes.\n */\nexport const WEB_OAUTH_FLOW_KINDS: Readonly<Record<string, LoginSessionKind>> = {\n anthropic: 'paste-code',\n openai: 'device-code',\n 'github-copilot': 'device-code',\n xai: 'device-code',\n};\n\nexport type CredentialContext =\n { mode: 'local' } | { mode: 'tenant'; storage: ModelCredentialsStorage; orgId: string; userId: string };\n\n/**\n * The tenant credentials domain, when registered and ready. `undefined` means\n * the factory never ran (no handle threaded in) or the domain's init failed\n * (fail-soft — callers report the feature unavailable instead of crashing).\n */\nexport async function getTenantCredentialsStorage(\n credentials: ModelCredentialsStorage | undefined,\n): Promise<ModelCredentialsStorage | undefined> {\n if (!credentials) return undefined;\n try {\n await credentials.ensureReady();\n } catch {\n return undefined;\n }\n return credentials;\n}\n\n/**\n * Org key for tenant rows. Personal accounts get an org bootstrapped by the\n * auth adapter (`ensureOrg`); if one still isn't present, scope rows under a\n * per-user synthetic org so credentials never become server-global.\n */\nexport function tenantOrgId(tenant: { orgId?: string; userId: string }): string {\n return tenant.orgId ?? `user:${tenant.userId}`;\n}\n\n/**\n * Resolve the credential context for a request, or a ready-to-return error\n * response. Mutating credential routes call this and hard-fail (401/503)\n * when the tenant path is required but unavailable.\n */\nexport async function resolveCredentialContext({\n c,\n auth,\n credentials,\n}: {\n c: Context;\n auth: RouteAuth;\n /** Tenant credential domain handle; absent in local (no-DB) mode. */\n credentials?: ModelCredentialsStorage;\n}): Promise<CredentialContext | { response: Response }> {\n await auth.ensureUser(c);\n const tenant = auth.tenant(c);\n if (!tenant) {\n // When an auth provider is active, credential operations always require a\n // signed-in caller — otherwise one anonymous request could write keys for\n // everyone. Without a provider this is a single-user local server.\n if (auth.enabled()) return { response: c.json({ error: 'unauthorized' }, 401) };\n return { mode: 'local' };\n }\n const storage = await getTenantCredentialsStorage(credentials);\n if (!storage) {\n return {\n response: c.json(\n {\n error: 'credentials_unavailable',\n message: 'Tenant credential storage is unavailable — the app database is not configured or failed to start.',\n },\n 503,\n ),\n };\n }\n return { mode: 'tenant', storage, orgId: tenantOrgId(tenant), userId: tenant.userId };\n}\n\n/**\n * List the caller's tenant credential records for provider listing, or\n * `undefined` in local mode (caller should fall back to `AuthStorage`).\n * Read-only and degradation-friendly: an authenticated caller with the domain\n * unavailable gets an empty list (sources show `env`/`none`) instead of a 503\n * so the settings page still renders.\n */\nexport async function listTenantCredentialsForRequest({\n c,\n auth,\n credentials,\n}: {\n c: Context;\n auth: RouteAuth;\n /** Tenant credential domain handle; absent in local (no-DB) mode. */\n credentials?: ModelCredentialsStorage;\n}): Promise<CredentialRecord[] | undefined> {\n await auth.ensureUser(c);\n const tenant = auth.tenant(c);\n if (!tenant) return auth.enabled() ? [] : undefined;\n const storage = await getTenantCredentialsStorage(credentials);\n if (!storage) return [];\n return storage.listCredentials(tenantOrgId(tenant), tenant.userId);\n}\n"],"mappings":";AA8BO,SAAS,kBAAkB,UAA0B;AAC1D,SAAO,aAAa,WAAW,iBAAiB;AAClD;AAQO,IAAM,uBAAmE;AAAA,EAC9E,WAAW;AAAA,EACX,QAAQ;AAAA,EACR,kBAAkB;AAAA,EAClB,KAAK;AACP;AAUA,eAAsB,4BACpB,aAC8C;AAC9C,MAAI,CAAC,YAAa,QAAO;AACzB,MAAI;AACF,UAAM,YAAY,YAAY;AAAA,EAChC,QAAQ;AACN,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAOO,SAAS,YAAY,QAAoD;AAC9E,SAAO,OAAO,SAAS,QAAQ,OAAO,MAAM;AAC9C;AAOA,eAAsB,yBAAyB;AAAA,EAC7C;AAAA,EACA;AAAA,EACA;AACF,GAKwD;AACtD,QAAM,KAAK,WAAW,CAAC;AACvB,QAAM,SAAS,KAAK,OAAO,CAAC;AAC5B,MAAI,CAAC,QAAQ;AAIX,QAAI,KAAK,QAAQ,EAAG,QAAO,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,eAAe,GAAG,GAAG,EAAE;AAC9E,WAAO,EAAE,MAAM,QAAQ;AAAA,EACzB;AACA,QAAM,UAAU,MAAM,4BAA4B,WAAW;AAC7D,MAAI,CAAC,SAAS;AACZ,WAAO;AAAA,MACL,UAAU,EAAE;AAAA,QACV;AAAA,UACE,OAAO;AAAA,UACP,SAAS;AAAA,QACX;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACA,SAAO,EAAE,MAAM,UAAU,SAAS,OAAO,YAAY,MAAM,GAAG,QAAQ,OAAO,OAAO;AACtF;AASA,eAAsB,gCAAgC;AAAA,EACpD;AAAA,EACA;AAAA,EACA;AACF,GAK4C;AAC1C,QAAM,KAAK,WAAW,CAAC;AACvB,QAAM,SAAS,KAAK,OAAO,CAAC;AAC5B,MAAI,CAAC,OAAQ,QAAO,KAAK,QAAQ,IAAI,CAAC,IAAI;AAC1C,QAAM,UAAU,MAAM,4BAA4B,WAAW;AAC7D,MAAI,CAAC,QAAS,QAAO,CAAC;AACtB,SAAO,QAAQ,gBAAgB,YAAY,MAAM,GAAG,OAAO,MAAM;AACnE;","names":[]}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Base class for factory route modules.
|
|
3
|
+
*
|
|
4
|
+
* Route modules build Mastra `apiRoutes` from injected dependencies instead of
|
|
5
|
+
* reaching into host globals. The host server (e.g. `mastracode/web`) supplies
|
|
6
|
+
* the auth seam and storage domain handles at construction time, so the routes
|
|
7
|
+
* stay portable and testable with fakes.
|
|
8
|
+
*/
|
|
9
|
+
import type { ApiRoute } from '@mastra/core/server';
|
|
10
|
+
import type { Context } from 'hono';
|
|
11
|
+
/**
|
|
12
|
+
* The auth surface factory routes need, implemented by the host server.
|
|
13
|
+
*
|
|
14
|
+
* Local (no-auth) deployments implement this with a stub where `enabled()`
|
|
15
|
+
* returns `false` and `tenant()` returns `undefined` — routes then take their
|
|
16
|
+
* single-user local paths.
|
|
17
|
+
*/
|
|
18
|
+
export interface RouteAuth {
|
|
19
|
+
/** Whether an auth provider is active (tenant mode). */
|
|
20
|
+
enabled(): boolean;
|
|
21
|
+
/**
|
|
22
|
+
* Resolve (and cache) the signed-in user for the request, if any. Must be
|
|
23
|
+
* called before `tenant()` so the request context is populated.
|
|
24
|
+
*/
|
|
25
|
+
ensureUser(c: Context): Promise<unknown>;
|
|
26
|
+
/** Tenant identity for the request, when signed in. */
|
|
27
|
+
tenant(c: Context): {
|
|
28
|
+
orgId?: string;
|
|
29
|
+
userId: string;
|
|
30
|
+
} | undefined;
|
|
31
|
+
/** Fail-closed check that the caller administers the given organization. */
|
|
32
|
+
isOrganizationAdmin(c: Context, organizationId: string): Promise<boolean>;
|
|
33
|
+
}
|
|
34
|
+
/** Dependencies shared by every factory route module. */
|
|
35
|
+
export interface RouteDependencies {
|
|
36
|
+
auth: RouteAuth;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* A route module: constructed once at boot with its dependencies, then asked
|
|
40
|
+
* for the `ApiRoute[]` it serves.
|
|
41
|
+
*/
|
|
42
|
+
export declare abstract class Route<TDeps extends RouteDependencies = RouteDependencies> {
|
|
43
|
+
protected readonly deps: TDeps;
|
|
44
|
+
constructor(deps: TDeps);
|
|
45
|
+
/** Build the Mastra `apiRoutes` served by this module. */
|
|
46
|
+
abstract routes(): ApiRoute[];
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=route.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../src/routes/route.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAEpC;;;;;;GAMG;AACH,MAAM,WAAW,SAAS;IACxB,wDAAwD;IACxD,OAAO,IAAI,OAAO,CAAC;IACnB;;;OAGG;IACH,UAAU,CAAC,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACzC,uDAAuD;IACvD,MAAM,CAAC,CAAC,EAAE,OAAO,GAAG;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,GAAG,SAAS,CAAC;IACnE,4EAA4E;IAC5E,mBAAmB,CAAC,CAAC,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CAC3E;AAED,yDAAyD;AACzD,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,SAAS,CAAC;CACjB;AAED;;;GAGG;AACH,8BAAsB,KAAK,CAAC,KAAK,SAAS,iBAAiB,GAAG,iBAAiB;IAC7E,SAAS,CAAC,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC;gBAEnB,IAAI,EAAE,KAAK;IAIvB,0DAA0D;IAC1D,QAAQ,CAAC,MAAM,IAAI,QAAQ,EAAE;CAC9B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/routes/route.ts"],"sourcesContent":["/**\n * Base class for factory route modules.\n *\n * Route modules build Mastra `apiRoutes` from injected dependencies instead of\n * reaching into host globals. The host server (e.g. `mastracode/web`) supplies\n * the auth seam and storage domain handles at construction time, so the routes\n * stay portable and testable with fakes.\n */\n\nimport type { ApiRoute } from '@mastra/core/server';\nimport type { Context } from 'hono';\n\n/**\n * The auth surface factory routes need, implemented by the host server.\n *\n * Local (no-auth) deployments implement this with a stub where `enabled()`\n * returns `false` and `tenant()` returns `undefined` — routes then take their\n * single-user local paths.\n */\nexport interface RouteAuth {\n /** Whether an auth provider is active (tenant mode). */\n enabled(): boolean;\n /**\n * Resolve (and cache) the signed-in user for the request, if any. Must be\n * called before `tenant()` so the request context is populated.\n */\n ensureUser(c: Context): Promise<unknown>;\n /** Tenant identity for the request, when signed in. */\n tenant(c: Context): { orgId?: string; userId: string } | undefined;\n /** Fail-closed check that the caller administers the given organization. */\n isOrganizationAdmin(c: Context, organizationId: string): Promise<boolean>;\n}\n\n/** Dependencies shared by every factory route module. */\nexport interface RouteDependencies {\n auth: RouteAuth;\n}\n\n/**\n * A route module: constructed once at boot with its dependencies, then asked\n * for the `ApiRoute[]` it serves.\n */\nexport abstract class Route<TDeps extends RouteDependencies = RouteDependencies> {\n protected readonly deps: TDeps;\n\n constructor(deps: TDeps) {\n this.deps = deps;\n }\n\n /** Build the Mastra `apiRoutes` served by this module. */\n abstract routes(): ApiRoute[];\n}\n"],"mappings":";AA0CO,IAAe,QAAf,MAA0E;AAAA,EAC5D;AAAA,EAEnB,YAAY,MAAa;AACvB,SAAK,OAAO;AAAA,EACd;AAIF;","names":[]}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { MastraCodeState } from '@mastra/code-sdk/schema';
|
|
2
|
+
import type { AgentController } from '@mastra/core/agent-controller';
|
|
3
|
+
import type { ApiRoute } from '@mastra/core/server';
|
|
4
|
+
import type { Context } from 'hono';
|
|
5
|
+
import type { SourceControlStorageHandle } from '../storage/domains/source-control/base.js';
|
|
6
|
+
import type { RouteDependencies } from './route.js';
|
|
7
|
+
import { Route } from './route.js';
|
|
8
|
+
interface SessionAuthorizationResult {
|
|
9
|
+
allowed: boolean;
|
|
10
|
+
status?: 400 | 401 | 403;
|
|
11
|
+
code?: 'invalid_request' | 'unauthorized' | 'session_forbidden';
|
|
12
|
+
message?: string;
|
|
13
|
+
}
|
|
14
|
+
export interface SkillRoutesDeps extends RouteDependencies {
|
|
15
|
+
controllerId: string;
|
|
16
|
+
controller: Pick<AgentController<MastraCodeState>, 'getSessionByResource'>;
|
|
17
|
+
sourceControlStorage?: SourceControlStorageHandle;
|
|
18
|
+
ensureSourceControlReady?: () => Promise<void>;
|
|
19
|
+
authorizeSessionAddress?: (context: Context, address: {
|
|
20
|
+
resourceId: string;
|
|
21
|
+
projectRepositoryId?: string;
|
|
22
|
+
scope?: string;
|
|
23
|
+
}) => Promise<SessionAuthorizationResult>;
|
|
24
|
+
}
|
|
25
|
+
export declare class SkillRoutes extends Route<SkillRoutesDeps> {
|
|
26
|
+
#private;
|
|
27
|
+
routes(): ApiRoute[];
|
|
28
|
+
}
|
|
29
|
+
export {};
|
|
30
|
+
//# sourceMappingURL=skills.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skills.d.ts","sourceRoot":"","sources":["../../src/routes/skills.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC/D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AACrE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAEpD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAGpC,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,2CAA2C,CAAC;AAC5F,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AACpD,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAgBnC,UAAU,0BAA0B;IAClC,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;IACzB,IAAI,CAAC,EAAE,iBAAiB,GAAG,cAAc,GAAG,mBAAmB,CAAC;IAChE,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,eAAgB,SAAQ,iBAAiB;IACxD,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,IAAI,CAAC,eAAe,CAAC,eAAe,CAAC,EAAE,sBAAsB,CAAC,CAAC;IAC3E,oBAAoB,CAAC,EAAE,0BAA0B,CAAC;IAClD,wBAAwB,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/C,uBAAuB,CAAC,EAAE,CACxB,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,mBAAmB,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,KAC1E,OAAO,CAAC,0BAA0B,CAAC,CAAC;CAC1C;AAiCD,qBAAa,WAAY,SAAQ,KAAK,CAAC,eAAe,CAAC;;IA6DrD,MAAM,IAAI,QAAQ,EAAE;CA6DrB"}
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
// src/routes/skills.ts
|
|
2
|
+
import { registerApiRoute } from "@mastra/core/server";
|
|
3
|
+
|
|
4
|
+
// src/skills/service.ts
|
|
5
|
+
import { formatSkillActivation } from "@mastra/core/workspace";
|
|
6
|
+
var SkillInvocationError = class extends Error {
|
|
7
|
+
code;
|
|
8
|
+
constructor(code, message) {
|
|
9
|
+
super(message);
|
|
10
|
+
this.name = "SkillInvocationError";
|
|
11
|
+
this.code = code;
|
|
12
|
+
}
|
|
13
|
+
};
|
|
14
|
+
function escapeSkillBoundary(value) {
|
|
15
|
+
return value.replaceAll("</skill>", "</skill>");
|
|
16
|
+
}
|
|
17
|
+
async function resolveSkillInvocation(controller, input) {
|
|
18
|
+
const session = await controller.getSessionByResource(input.resourceId, input.scope);
|
|
19
|
+
if (!session) throw new SkillInvocationError("session_not_found", "Agent controller session not found.");
|
|
20
|
+
const skills = session.getWorkspace().skills;
|
|
21
|
+
await skills?.maybeRefresh();
|
|
22
|
+
const skill = await skills?.get(input.name);
|
|
23
|
+
if (!skill || skill["user-invocable"] === false) {
|
|
24
|
+
throw new SkillInvocationError("skill_not_found", `Skill not found: ${input.name}.`);
|
|
25
|
+
}
|
|
26
|
+
const args = input.arguments?.trim();
|
|
27
|
+
const content = `${formatSkillActivation(skill)}${args ? `
|
|
28
|
+
|
|
29
|
+
ARGUMENTS: ${args}` : ""}`.trim();
|
|
30
|
+
return {
|
|
31
|
+
session,
|
|
32
|
+
skillName: skill.name,
|
|
33
|
+
message: `<skill name="${skill.name}">
|
|
34
|
+
${escapeSkillBoundary(content)}
|
|
35
|
+
</skill>`
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// src/routes/route.ts
|
|
40
|
+
var Route = class {
|
|
41
|
+
deps;
|
|
42
|
+
constructor(deps) {
|
|
43
|
+
this.deps = deps;
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
// src/routes/skills.ts
|
|
48
|
+
var MAX_RESOURCE_ID_LENGTH = 512;
|
|
49
|
+
var MAX_SCOPE_LENGTH = 2048;
|
|
50
|
+
var MAX_ARGUMENTS_LENGTH = 16384;
|
|
51
|
+
var SKILL_NAME_RE = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
|
|
52
|
+
var UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
|
|
53
|
+
function loose(context) {
|
|
54
|
+
return context;
|
|
55
|
+
}
|
|
56
|
+
function parseBody(value) {
|
|
57
|
+
if (!value || typeof value !== "object") return void 0;
|
|
58
|
+
const input = value;
|
|
59
|
+
if (typeof input.resourceId !== "string" || input.resourceId.length === 0) return void 0;
|
|
60
|
+
if (input.resourceId.length > MAX_RESOURCE_ID_LENGTH) return void 0;
|
|
61
|
+
if (input.projectRepositoryId !== void 0 && (typeof input.projectRepositoryId !== "string" || !UUID_RE.test(input.projectRepositoryId))) {
|
|
62
|
+
return void 0;
|
|
63
|
+
}
|
|
64
|
+
if (input.scope !== void 0 && (typeof input.scope !== "string" || input.scope.length > MAX_SCOPE_LENGTH)) {
|
|
65
|
+
return void 0;
|
|
66
|
+
}
|
|
67
|
+
if (typeof input.name !== "string" || input.name.length > 64 || !SKILL_NAME_RE.test(input.name)) return void 0;
|
|
68
|
+
if (input.arguments !== void 0) {
|
|
69
|
+
if (typeof input.arguments !== "string" || input.arguments.length > MAX_ARGUMENTS_LENGTH) return void 0;
|
|
70
|
+
}
|
|
71
|
+
return {
|
|
72
|
+
resourceId: input.resourceId,
|
|
73
|
+
...input.projectRepositoryId ? { projectRepositoryId: input.projectRepositoryId } : {},
|
|
74
|
+
...input.scope ? { scope: input.scope } : {},
|
|
75
|
+
name: input.name,
|
|
76
|
+
...input.arguments !== void 0 ? { arguments: input.arguments } : {}
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
var SkillRoutes = class extends Route {
|
|
80
|
+
async #authorizeSessionAddress(context, address) {
|
|
81
|
+
const { auth, sourceControlStorage: storage, ensureSourceControlReady } = this.deps;
|
|
82
|
+
if (!auth.enabled()) return { allowed: true };
|
|
83
|
+
await auth.ensureUser(context);
|
|
84
|
+
const tenant = auth.tenant(context);
|
|
85
|
+
if (!tenant) {
|
|
86
|
+
return { allowed: false, status: 401, code: "unauthorized", message: "Authentication required." };
|
|
87
|
+
}
|
|
88
|
+
if (address.resourceId === tenant.userId) return { allowed: true };
|
|
89
|
+
if (!UUID_RE.test(address.resourceId) || !address.projectRepositoryId || !UUID_RE.test(address.projectRepositoryId)) {
|
|
90
|
+
return { allowed: false, status: 400, code: "invalid_request", message: "Invalid skill invocation request." };
|
|
91
|
+
}
|
|
92
|
+
if (!tenant.orgId || !address.scope) {
|
|
93
|
+
return { allowed: false, status: 403, code: "session_forbidden", message: "Session access denied." };
|
|
94
|
+
}
|
|
95
|
+
if (!storage) {
|
|
96
|
+
return { allowed: false, status: 403, code: "session_forbidden", message: "Session access denied." };
|
|
97
|
+
}
|
|
98
|
+
if (ensureSourceControlReady) {
|
|
99
|
+
try {
|
|
100
|
+
await ensureSourceControlReady();
|
|
101
|
+
} catch {
|
|
102
|
+
return { allowed: false, status: 403, code: "session_forbidden", message: "Session access denied." };
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
const projectRepository = await storage.projectRepositories.get({
|
|
106
|
+
orgId: tenant.orgId,
|
|
107
|
+
id: address.projectRepositoryId
|
|
108
|
+
});
|
|
109
|
+
if (!projectRepository) {
|
|
110
|
+
return { allowed: false, status: 403, code: "session_forbidden", message: "Session access denied." };
|
|
111
|
+
}
|
|
112
|
+
const connection = await storage.connections.get({ orgId: tenant.orgId, id: projectRepository.connectionId });
|
|
113
|
+
if (!connection || connection.factoryProjectId !== address.resourceId) {
|
|
114
|
+
return { allowed: false, status: 403, code: "session_forbidden", message: "Session access denied." };
|
|
115
|
+
}
|
|
116
|
+
const worktree = await storage.worktrees.findByPath({
|
|
117
|
+
projectRepositoryId: address.projectRepositoryId,
|
|
118
|
+
userId: tenant.userId,
|
|
119
|
+
worktreePath: address.scope
|
|
120
|
+
});
|
|
121
|
+
return worktree ? { allowed: true } : { allowed: false, status: 403, code: "session_forbidden", message: "Session access denied." };
|
|
122
|
+
}
|
|
123
|
+
routes() {
|
|
124
|
+
const { controllerId, controller, authorizeSessionAddress: customAuthorize } = this.deps;
|
|
125
|
+
const authorize = customAuthorize ?? ((context, address) => this.#authorizeSessionAddress(context, address));
|
|
126
|
+
const handleSkillRequest = async (context, dispatch) => {
|
|
127
|
+
const c = loose(context);
|
|
128
|
+
if (c.req.param("controllerId") !== controllerId) {
|
|
129
|
+
return c.json({ error: "controller_not_found", message: "Agent controller not found." }, 404);
|
|
130
|
+
}
|
|
131
|
+
let rawBody;
|
|
132
|
+
try {
|
|
133
|
+
rawBody = await c.req.json();
|
|
134
|
+
} catch {
|
|
135
|
+
return c.json({ error: "invalid_request", message: "Invalid JSON body." }, 400);
|
|
136
|
+
}
|
|
137
|
+
const body = parseBody(rawBody);
|
|
138
|
+
if (!body) {
|
|
139
|
+
return c.json({ error: "invalid_request", message: "Invalid skill invocation request." }, 400);
|
|
140
|
+
}
|
|
141
|
+
const authorization = await authorize(c, {
|
|
142
|
+
resourceId: body.resourceId,
|
|
143
|
+
projectRepositoryId: body.projectRepositoryId,
|
|
144
|
+
scope: body.scope
|
|
145
|
+
});
|
|
146
|
+
if (!authorization.allowed) {
|
|
147
|
+
return c.json({ error: authorization.code, message: authorization.message }, authorization.status ?? 403);
|
|
148
|
+
}
|
|
149
|
+
try {
|
|
150
|
+
const resolved = await resolveSkillInvocation(controller, body);
|
|
151
|
+
if (dispatch) {
|
|
152
|
+
void resolved.session.sendMessage({ content: resolved.message }).catch((error) => {
|
|
153
|
+
console.error("Workspace skill dispatch failed after acceptance", error);
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
return c.json({ ok: true, skill: resolved.skillName, message: resolved.message });
|
|
157
|
+
} catch (error) {
|
|
158
|
+
if (error instanceof SkillInvocationError) {
|
|
159
|
+
return c.json({ error: error.code, message: error.message }, 404);
|
|
160
|
+
}
|
|
161
|
+
throw error;
|
|
162
|
+
}
|
|
163
|
+
};
|
|
164
|
+
return [
|
|
165
|
+
registerApiRoute("/web/agent-controller/:controllerId/skills/prepare", {
|
|
166
|
+
method: "POST",
|
|
167
|
+
requiresAuth: false,
|
|
168
|
+
handler: (context) => handleSkillRequest(context, false)
|
|
169
|
+
}),
|
|
170
|
+
registerApiRoute("/web/agent-controller/:controllerId/skills/invoke", {
|
|
171
|
+
method: "POST",
|
|
172
|
+
requiresAuth: false,
|
|
173
|
+
handler: (context) => handleSkillRequest(context, true)
|
|
174
|
+
})
|
|
175
|
+
];
|
|
176
|
+
}
|
|
177
|
+
};
|
|
178
|
+
export {
|
|
179
|
+
SkillRoutes
|
|
180
|
+
};
|
|
181
|
+
//# sourceMappingURL=skills.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/routes/skills.ts","../../src/skills/service.ts","../../src/routes/route.ts"],"sourcesContent":["import type { MastraCodeState } from '@mastra/code-sdk/schema';\nimport type { AgentController } from '@mastra/core/agent-controller';\nimport type { ApiRoute } from '@mastra/core/server';\nimport { registerApiRoute } from '@mastra/core/server';\nimport type { Context } from 'hono';\n\nimport { resolveSkillInvocation, SkillInvocationError } from '../skills/service.js';\nimport type { SourceControlStorageHandle } from '../storage/domains/source-control/base.js';\nimport type { RouteDependencies } from './route.js';\nimport { Route } from './route.js';\n\nconst MAX_RESOURCE_ID_LENGTH = 512;\nconst MAX_SCOPE_LENGTH = 2048;\nconst MAX_ARGUMENTS_LENGTH = 16_384;\nconst SKILL_NAME_RE = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;\nconst UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;\n\ninterface SkillInvocationBody {\n resourceId: string;\n projectRepositoryId?: string;\n scope?: string;\n name: string;\n arguments?: string;\n}\n\ninterface SessionAuthorizationResult {\n allowed: boolean;\n status?: 400 | 401 | 403;\n code?: 'invalid_request' | 'unauthorized' | 'session_forbidden';\n message?: string;\n}\n\nexport interface SkillRoutesDeps extends RouteDependencies {\n controllerId: string;\n controller: Pick<AgentController<MastraCodeState>, 'getSessionByResource'>;\n sourceControlStorage?: SourceControlStorageHandle;\n ensureSourceControlReady?: () => Promise<void>;\n authorizeSessionAddress?: (\n context: Context,\n address: { resourceId: string; projectRepositoryId?: string; scope?: string },\n ) => Promise<SessionAuthorizationResult>;\n}\n\nfunction loose(context: unknown): Context {\n return context as Context;\n}\n\nfunction parseBody(value: unknown): SkillInvocationBody | undefined {\n if (!value || typeof value !== 'object') return undefined;\n const input = value as Record<string, unknown>;\n if (typeof input.resourceId !== 'string' || input.resourceId.length === 0) return undefined;\n if (input.resourceId.length > MAX_RESOURCE_ID_LENGTH) return undefined;\n if (\n input.projectRepositoryId !== undefined &&\n (typeof input.projectRepositoryId !== 'string' || !UUID_RE.test(input.projectRepositoryId))\n ) {\n return undefined;\n }\n if (input.scope !== undefined && (typeof input.scope !== 'string' || input.scope.length > MAX_SCOPE_LENGTH)) {\n return undefined;\n }\n if (typeof input.name !== 'string' || input.name.length > 64 || !SKILL_NAME_RE.test(input.name)) return undefined;\n if (input.arguments !== undefined) {\n if (typeof input.arguments !== 'string' || input.arguments.length > MAX_ARGUMENTS_LENGTH) return undefined;\n }\n return {\n resourceId: input.resourceId,\n ...(input.projectRepositoryId ? { projectRepositoryId: input.projectRepositoryId } : {}),\n ...(input.scope ? { scope: input.scope } : {}),\n name: input.name,\n ...(input.arguments !== undefined ? { arguments: input.arguments } : {}),\n };\n}\n\nexport class SkillRoutes extends Route<SkillRoutesDeps> {\n async #authorizeSessionAddress(\n context: Context,\n address: { resourceId: string; projectRepositoryId?: string; scope?: string },\n ): Promise<SessionAuthorizationResult> {\n const { auth, sourceControlStorage: storage, ensureSourceControlReady } = this.deps;\n if (!auth.enabled()) return { allowed: true };\n\n await auth.ensureUser(context);\n const tenant = auth.tenant(context);\n if (!tenant) {\n return { allowed: false, status: 401, code: 'unauthorized', message: 'Authentication required.' };\n }\n\n // Personal sessions are keyed by the authenticated WorkOS user id. Their\n // scope is a client-managed local/user-session worktree and needs no app DB.\n if (address.resourceId === tenant.userId) return { allowed: true };\n\n // Factory sessions are keyed by factoryProjectId and explicitly identify the\n // linked repository whose user-owned worktree supplies the session scope.\n if (\n !UUID_RE.test(address.resourceId) ||\n !address.projectRepositoryId ||\n !UUID_RE.test(address.projectRepositoryId)\n ) {\n return { allowed: false, status: 400, code: 'invalid_request', message: 'Invalid skill invocation request.' };\n }\n if (!tenant.orgId || !address.scope) {\n return { allowed: false, status: 403, code: 'session_forbidden', message: 'Session access denied.' };\n }\n if (!storage) {\n return { allowed: false, status: 403, code: 'session_forbidden', message: 'Session access denied.' };\n }\n if (ensureSourceControlReady) {\n try {\n await ensureSourceControlReady();\n } catch {\n return { allowed: false, status: 403, code: 'session_forbidden', message: 'Session access denied.' };\n }\n }\n const projectRepository = await storage.projectRepositories.get({\n orgId: tenant.orgId,\n id: address.projectRepositoryId,\n });\n if (!projectRepository) {\n return { allowed: false, status: 403, code: 'session_forbidden', message: 'Session access denied.' };\n }\n const connection = await storage.connections.get({ orgId: tenant.orgId, id: projectRepository.connectionId });\n if (!connection || connection.factoryProjectId !== address.resourceId) {\n return { allowed: false, status: 403, code: 'session_forbidden', message: 'Session access denied.' };\n }\n const worktree = await storage.worktrees.findByPath({\n projectRepositoryId: address.projectRepositoryId,\n userId: tenant.userId,\n worktreePath: address.scope,\n });\n return worktree\n ? { allowed: true }\n : { allowed: false, status: 403, code: 'session_forbidden', message: 'Session access denied.' };\n }\n\n routes(): ApiRoute[] {\n const { controllerId, controller, authorizeSessionAddress: customAuthorize } = this.deps;\n const authorize =\n customAuthorize ??\n ((context: Context, address: { resourceId: string; projectRepositoryId?: string; scope?: string }) =>\n this.#authorizeSessionAddress(context, address));\n const handleSkillRequest = async (context: unknown, dispatch: boolean) => {\n const c = loose(context);\n if (c.req.param('controllerId') !== controllerId) {\n return c.json({ error: 'controller_not_found', message: 'Agent controller not found.' }, 404);\n }\n\n let rawBody: unknown;\n try {\n rawBody = await c.req.json();\n } catch {\n return c.json({ error: 'invalid_request', message: 'Invalid JSON body.' }, 400);\n }\n const body = parseBody(rawBody);\n if (!body) {\n return c.json({ error: 'invalid_request', message: 'Invalid skill invocation request.' }, 400);\n }\n\n const authorization = await authorize(c, {\n resourceId: body.resourceId,\n projectRepositoryId: body.projectRepositoryId,\n scope: body.scope,\n });\n if (!authorization.allowed) {\n return c.json({ error: authorization.code, message: authorization.message }, authorization.status ?? 403);\n }\n\n try {\n const resolved = await resolveSkillInvocation(controller, body);\n if (dispatch) {\n void resolved.session.sendMessage({ content: resolved.message }).catch((error: unknown) => {\n console.error('Workspace skill dispatch failed after acceptance', error);\n });\n }\n return c.json({ ok: true, skill: resolved.skillName, message: resolved.message });\n } catch (error) {\n if (error instanceof SkillInvocationError) {\n return c.json({ error: error.code, message: error.message }, 404);\n }\n throw error;\n }\n };\n\n return [\n registerApiRoute('/web/agent-controller/:controllerId/skills/prepare', {\n method: 'POST',\n requiresAuth: false,\n handler: context => handleSkillRequest(context, false),\n }),\n registerApiRoute('/web/agent-controller/:controllerId/skills/invoke', {\n method: 'POST',\n requiresAuth: false,\n handler: context => handleSkillRequest(context, true),\n }),\n ];\n }\n}\n","import type { MastraCodeState } from '@mastra/code-sdk/schema';\nimport type { SendAgentSignalResult } from '@mastra/core/agent';\nimport type { AgentController } from '@mastra/core/agent-controller';\nimport type { RequestContext } from '@mastra/core/request-context';\nimport { formatSkillActivation } from '@mastra/core/workspace';\nimport type { Workspace } from '@mastra/core/workspace';\n\nexport interface SkillInvocationInput {\n resourceId: string;\n scope?: string;\n name: string;\n arguments?: string;\n}\n\nexport interface SkillSession {\n getWorkspace(): Workspace;\n sendMessage(input: { content: string }): Promise<unknown>;\n sendNotificationSignal(\n input: {\n source: string;\n kind: string;\n summary: string;\n priority?: 'low' | 'medium' | 'high' | 'urgent';\n payload?: unknown;\n dedupeKey?: string;\n sourceId?: string;\n },\n options?: {\n ifActive?: { behavior?: 'deliver' | 'persist' };\n ifIdle?: { behavior?: 'persist' | 'wake' };\n requestContext?: RequestContext;\n },\n ): Promise<Pick<SendAgentSignalResult, 'persisted' | 'accepted'>>;\n}\n\nexport class SkillInvocationError extends Error {\n readonly code: 'session_not_found' | 'skill_not_found';\n\n constructor(code: SkillInvocationError['code'], message: string) {\n super(message);\n this.name = 'SkillInvocationError';\n this.code = code;\n }\n}\n\nfunction escapeSkillBoundary(value: string): string {\n return value.replaceAll('</skill>', '</skill>');\n}\n\nexport async function resolveSkillInvocation(\n controller: Pick<AgentController<MastraCodeState>, 'getSessionByResource'>,\n input: SkillInvocationInput,\n): Promise<{ session: SkillSession; skillName: string; message: string }> {\n const session = (await controller.getSessionByResource(input.resourceId, input.scope)) as SkillSession | undefined;\n if (!session) throw new SkillInvocationError('session_not_found', 'Agent controller session not found.');\n\n const skills = session.getWorkspace().skills;\n await skills?.maybeRefresh();\n const skill = await skills?.get(input.name);\n if (!skill || skill['user-invocable'] === false) {\n throw new SkillInvocationError('skill_not_found', `Skill not found: ${input.name}.`);\n }\n\n const args = input.arguments?.trim();\n const content = `${formatSkillActivation(skill)}${args ? `\\n\\nARGUMENTS: ${args}` : ''}`.trim();\n return {\n session,\n skillName: skill.name,\n message: `<skill name=\"${skill.name}\">\\n${escapeSkillBoundary(content)}\\n</skill>`,\n };\n}\n\nexport async function dispatchSkillInvocation(\n controller: Pick<AgentController<MastraCodeState>, 'getSessionByResource'>,\n input: SkillInvocationInput,\n): Promise<{ skillName: string; message: string }> {\n const resolved = await resolveSkillInvocation(controller, input);\n await resolved.session.sendMessage({ content: resolved.message });\n return { skillName: resolved.skillName, message: resolved.message };\n}\n","/**\n * Base class for factory route modules.\n *\n * Route modules build Mastra `apiRoutes` from injected dependencies instead of\n * reaching into host globals. The host server (e.g. `mastracode/web`) supplies\n * the auth seam and storage domain handles at construction time, so the routes\n * stay portable and testable with fakes.\n */\n\nimport type { ApiRoute } from '@mastra/core/server';\nimport type { Context } from 'hono';\n\n/**\n * The auth surface factory routes need, implemented by the host server.\n *\n * Local (no-auth) deployments implement this with a stub where `enabled()`\n * returns `false` and `tenant()` returns `undefined` — routes then take their\n * single-user local paths.\n */\nexport interface RouteAuth {\n /** Whether an auth provider is active (tenant mode). */\n enabled(): boolean;\n /**\n * Resolve (and cache) the signed-in user for the request, if any. Must be\n * called before `tenant()` so the request context is populated.\n */\n ensureUser(c: Context): Promise<unknown>;\n /** Tenant identity for the request, when signed in. */\n tenant(c: Context): { orgId?: string; userId: string } | undefined;\n /** Fail-closed check that the caller administers the given organization. */\n isOrganizationAdmin(c: Context, organizationId: string): Promise<boolean>;\n}\n\n/** Dependencies shared by every factory route module. */\nexport interface RouteDependencies {\n auth: RouteAuth;\n}\n\n/**\n * A route module: constructed once at boot with its dependencies, then asked\n * for the `ApiRoute[]` it serves.\n */\nexport abstract class Route<TDeps extends RouteDependencies = RouteDependencies> {\n protected readonly deps: TDeps;\n\n constructor(deps: TDeps) {\n this.deps = deps;\n }\n\n /** Build the Mastra `apiRoutes` served by this module. */\n abstract routes(): ApiRoute[];\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import type { AuthStorage } from '@mastra/code-sdk/auth/storage';
|
|
2
|
+
import type { MastraCodeState } from '@mastra/code-sdk/schema';
|
|
3
|
+
import type { AgentController } from '@mastra/core/agent-controller';
|
|
4
|
+
import type { ApiRoute } from '@mastra/core/server';
|
|
5
|
+
import type { FactoryStorage } from '@mastra/core/storage';
|
|
6
|
+
import type { FactoryIntegration, IntegrationContext } from '../integrations/base.js';
|
|
7
|
+
import type { FactoryBindingPreparationInput } from '../rules/dispatcher.js';
|
|
8
|
+
import { FactoryTransitionService } from '../rules/transition-service.js';
|
|
9
|
+
import type { FactoryRules } from '../rules/types.js';
|
|
10
|
+
import type { SandboxFleet } from '../sandbox/fleet.js';
|
|
11
|
+
import type { StateSigner } from '../state-signing.js';
|
|
12
|
+
import type { AuditEmitter } from '../storage/domains/audit/domain.js';
|
|
13
|
+
import type { ModelCredentialsStorage } from '../storage/domains/credentials/base.js';
|
|
14
|
+
import type { IntakeStorage } from '../storage/domains/intake/base.js';
|
|
15
|
+
import type { IntegrationStorage } from '../storage/domains/integrations/base.js';
|
|
16
|
+
import type { ModelPacksStorage } from '../storage/domains/model-packs/base.js';
|
|
17
|
+
import type { FactoryProjectsStorage } from '../storage/domains/projects/base.js';
|
|
18
|
+
import type { QueueHealthStorage } from '../storage/domains/queue-health/base.js';
|
|
19
|
+
import type { SourceControlStorage } from '../storage/domains/source-control/base.js';
|
|
20
|
+
import type { WorkItemsStorage } from '../storage/domains/work-items/base.js';
|
|
21
|
+
import type { RouteAuth } from './route.js';
|
|
22
|
+
export interface IntegrationRegistration {
|
|
23
|
+
integration: FactoryIntegration;
|
|
24
|
+
ready: boolean;
|
|
25
|
+
ensureReady: () => Promise<void>;
|
|
26
|
+
}
|
|
27
|
+
export interface FactoryApiRoutesDeps {
|
|
28
|
+
controllerId: string;
|
|
29
|
+
controller: AgentController<MastraCodeState>;
|
|
30
|
+
/** Request-auth seam threaded from the host (no service locator). */
|
|
31
|
+
auth: RouteAuth;
|
|
32
|
+
authStorage: AuthStorage;
|
|
33
|
+
audit: AuditEmitter;
|
|
34
|
+
fsRoot?: string;
|
|
35
|
+
publicOrigin: string;
|
|
36
|
+
stateSigner?: StateSigner;
|
|
37
|
+
/** Sandbox fleet constructed by the factory (disabled when no machine). */
|
|
38
|
+
fleet: SandboxFleet;
|
|
39
|
+
/** Root factory storage backend (distributed locks, app-db diagnostics). */
|
|
40
|
+
factoryStorage?: FactoryStorage;
|
|
41
|
+
integrationStorage: IntegrationStorage;
|
|
42
|
+
sourceControlStorage: SourceControlStorage;
|
|
43
|
+
/** App-table domain handles, registered and owned by `MastraFactory.prepare()`. */
|
|
44
|
+
domains: {
|
|
45
|
+
intake: IntakeStorage;
|
|
46
|
+
modelCredentials: ModelCredentialsStorage;
|
|
47
|
+
modelPacks: ModelPacksStorage;
|
|
48
|
+
projects: FactoryProjectsStorage;
|
|
49
|
+
queueHealth: QueueHealthStorage;
|
|
50
|
+
workItems: WorkItemsStorage;
|
|
51
|
+
};
|
|
52
|
+
integrations?: IntegrationRegistration[];
|
|
53
|
+
intakeReady: boolean;
|
|
54
|
+
factoryReady: boolean;
|
|
55
|
+
/** Resolved Factory rule set, threaded from the host (no service locator). */
|
|
56
|
+
rules: FactoryRules;
|
|
57
|
+
factoryTransitionService?: FactoryTransitionService;
|
|
58
|
+
onFactoryRuntime?: (runtime: {
|
|
59
|
+
transitionService: FactoryTransitionService;
|
|
60
|
+
prepareBinding?: (input: FactoryBindingPreparationInput) => Promise<void>;
|
|
61
|
+
}) => void;
|
|
62
|
+
}
|
|
63
|
+
export declare function factoryRuleBranch(item: FactoryBindingPreparationInput['item']): string;
|
|
64
|
+
/**
|
|
65
|
+
* Build the {@link IntegrationContext} handed to an integration when the
|
|
66
|
+
* factory collects its capabilities (routes, workers). One shape everywhere:
|
|
67
|
+
* `assembleFactoryApiRoutes` uses it per registration, and `MastraFactory` uses it
|
|
68
|
+
* when collecting integration workers at finalize.
|
|
69
|
+
*/
|
|
70
|
+
export declare function buildIntegrationContext(deps: Pick<FactoryApiRoutesDeps, 'controller' | 'publicOrigin' | 'auth' | 'fleet' | 'factoryStorage' | 'integrationStorage' | 'sourceControlStorage'> & {
|
|
71
|
+
stateSigner: StateSigner;
|
|
72
|
+
emitAudit?: AuditEmitter['emit'];
|
|
73
|
+
domains: Pick<FactoryApiRoutesDeps['domains'], 'projects' | 'intake'>;
|
|
74
|
+
}, integrationId: string): IntegrationContext;
|
|
75
|
+
/**
|
|
76
|
+
* Assemble the custom `/web/*` API routes as Mastra `server.apiRoutes`:
|
|
77
|
+
* - fs browser routes (project picker), confined to `fsRoot`
|
|
78
|
+
* - config routes (provider/API-key/model-pack/OM management)
|
|
79
|
+
* - every registered integration's `routes()` surface (full set when ready,
|
|
80
|
+
* disabled-status stub otherwise), plus stubs for absent known ids
|
|
81
|
+
*/
|
|
82
|
+
export declare function assembleFactoryApiRoutes(deps: FactoryApiRoutesDeps): ApiRoute[];
|
|
83
|
+
//# sourceMappingURL=surface.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"surface.d.ts","sourceRoot":"","sources":["../../src/routes/surface.ts"],"names":[],"mappings":"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"}
|