| 文件 | 最后提交记录 | 最后更新时间 |
|---|---|---|
fix: correct github org links in issue templates (#562) | 1 个月前 | |
feat(mastra): add @corsair-dev/mastra ToolProvider for Mastra (#1491) * feat(mastra): add @corsair-dev/mastra ToolProvider for Mastra * feat(mastra): move to adapters/ and address review - move packages/mastra -> adapters/mastra; wire adapters/* into the workspace, publish-changed, deploy/pr-checks, and turbo filters - resolveTenant: a decodable connectionId is authoritative over the tenant function (authorize and resolve can't diverge) - add getToolSchema for the editor tool-detail view - add revokeConnection + supportsRevoke (via corsair manage.disconnect) - peer @mastra/core >=1.64.0; form-field docstrings; README tool recipes - demo/mastra: minimal Mastra playground app * fix(mastra): harden tenant isolation and close review gaps - resolveTenant: the configured tenant is authoritative. A pinned string is never overridden by a connectionId, and when the caller is known a connectionId naming a different tenant is rejected (no cross-tenant access). A fresh connection under a function resolver throws instead of silently opening OAuth under a fallback tenant (Mastra passes no context to authorize). - Document connectionId as an unsigned, server-minted handle. - Require zod ^4.4.0 so z.unknown() rejects omitted required fields. - CI: build/test the full lane over adapters/* too, not just packages/*. - demo: pin the LLM gateway host; ignore SQLite sidecar files. * fix(mastra): optional @mastra/core peer, run checks in CI, document fresh-auth limit * docs(mastra): document ToolAction<any> constraint from @mastra/core base class * chore: regenerate lockfile to resolve missing ts-jest entry * fix(mastra): narrow corsair config field and invokeOperation types * fix(corsair): make AnyCorsairInstance accept real createCorsair() results AnyCorsairInstance instantiated the client generics with a fake shallow plugin shape, expanding the per-plugin mapped types to a structure no real instance matches — so every createCorsair() result was rejected (TS2322) and callers had to cast. Parameterize with an empty plugin set instead: that is the shape common to all instances, so any concrete client is a structural superset and assigns. Drops the widening casts the mastra checks needed. * fix(corsair): accept multi-tenant wrapper in AnyCorsairInstance The empty-plugin-set fix covered single-tenant and tenant-scoped clients but rejected the multi-tenant wrapper: the wrapper is matched by its plugin-tuple argument, and an empty tuple is not assignable from a real one. Give the wrapper member the open plugin array; the two structurally-matched clients keep the empty set. Verified all three instance shapes assign with no cast. * fix(mastra): require a root instance in config; drop narrating comments Narrow the provider config from AnyCorsairInstance to the manage-bearing root instances (single-tenant client or multi-tenant wrapper) via Extract, so a withTenant() scope — which has no manage — is a compile error, not a runtime throw. Drops the now-unneeded manage cast. Also strip narrating comments flagged in review across the adapter, core type, and demo. * build(mastra): keep check files out of the published dts The declaration build shipped stray *.check.d.ts.map into dist; scope it to src minus *.check.ts so the package publishes only its real modules. | 29 天前 | |
feat(cloud): language client wrappers, useCorsair, cloud-proxy, and cloud CLI (#1741) * feat(clients): Swift Corsair Cloud client wrapper Thin URLSession client mirroring createCorsairCloud: dynamic tool calls (tenant(t).call(plugin, op, args)) + management (connectionStatus, connect link, disconnect, tenants). Zero deps; JSONValue for dynamic in/out. Swift Testing covers URL/bearer/body/data, connection-status, and the error envelope. WRAPPER-SPEC.md pins the canonical shape every language wrapper follows. * docs(cloud): add Corsair Cloud overview page Explains the hosted runtime, the key+URL, the server (createCorsairCloud) and client (CorsairProvider) surfaces, the connect flow, multi-tenancy, and the pull-generated types. Wired into Get Started. * feat(client): add useCorsair() react hook for tool calls Adds client.call(plugin, op, tenantId, args) to the vanilla management client, posting to /:tenant/:plugin/call/:op, and a public useCorsair() hook returning { api, db } built on the existing useAsync state machine. db is a reserved placeholder — no /db route exists yet. Renames the internal context accessor useCorsair -> useCorsairContext to free the name for the new public hook. * feat(clients): Python Corsair Cloud client wrapper Thin stdlib (urllib) client mirroring the Swift/TS shape: with_tenant(t).call( plugin, op, args) -> data, plus manage (connection_status, connect link, disconnect, tenants). CorsairError from the runtime envelope. pytest, no network. * feat(clients): Go Corsair Cloud client wrapper Thin net/http client mirroring the Swift/Python/TS shape: Tenant(id).Call(ctx, plugin, op, args) -> json.RawMessage, plus ConnectionStatus/CreateConnectLink/ Disconnect/Tenants/CreateTenant. *CorsairError from the runtime envelope. httptest-backed tests, stdlib only. * feat(cloud): add corsair/cloud-proxy backend helper createCloudProxy({ apiKey, url }) is a framework-agnostic (Request)=>Response that forwards a same-origin /api/corsair route to the runtime and injects the ck_cloud_ bearer server-side. Drops the caller's Authorization/cookies. Pairs with CorsairProvider so the key never reaches the browser. Docs snippet + wiring. * ci: add clients CI, docs pages, and PyPI publish for cloud wrappers Swift/Python/Go each run their own job on clients/** PRs. Docs get a Client libraries nav group. Python pyproject is publish-ready and gated behind a corsair-cloud-py-v* tag + PYPI_TOKEN secret. Go/Swift READMEs note their monorepo distribution constraints (subdir tags, SPM root). * feat(cli): add corsair cloud list/pull for Corsair Cloud discovery corsair cloud list prints a hosted project's op tree (GET /call, bearer project key). corsair cloud pull writes corsair-env.d.ts, merging the ops into CorsairCloudRegistry so createCorsairCloud() is typed without a plugin list. Nested under `cloud` since top-level `list` is already the local-instance operation lister. * docs(cloud): correct CLI command to 'corsair cloud pull/list' * chore(clients): stop tracking Swift .build output * fix(cli): preserve terminal+nested ops and quote generated d.ts keys insertOp overwrote a terminal op's true with an object when a longer op shared its prefix (users vs users.list), dropping the leaf. Track call state separately from children, and quote every generated key so plugin/op names with punctuation don't break corsair-env.d.ts. * fix(cli): require https for the cloud url, fix env-var test cleanup The cloud key goes out as a bearer token, so an --url pointing at plain http would leak it. Reject non-https unless the host is loopback, matching the reference client's rule. Also stop restoring 'undefined' as a string into process.env in afterEach — delete when the original value was actually unset. * fix(corsair): gate cloud proxy behind https and an authorize hook createCloudProxy forwarded any caller-chosen tenant/plugin/op with the project bearer attached, so once mounted, an unauthenticated caller could reach any op the project key is allowed to invoke. Add an optional authorize hook that runs before forwarding and rejects with 401 when it returns false, document it as required in the Next.js snippet, and reject non-https upstream urls the same way the reference client does. * fix(client): rename useCorsair's api to useApi — it calls hooks internally api() called useAsync (useReducer/useEffect/useRef) but wasn't named like a hook, so nothing stopped a caller from invoking it conditionally, in a loop, or from an event handler and breaking hook order at runtime. Rename to useApi so it reads — and lints — as the hook it already was. * fix(go-client): require https, escape path segments, add redirectUri send() joined path segments raw, so a tenant/plugin/op containing '/' changed the route instead of addressing it — escape each segment with url.PathEscape. Reject non-https base URLs (loopback excepted, so the existing httptest.NewServer-based tests keep working) since the API key rides as a bearer token. Give the default client a finite timeout instead of http.DefaultClient's none. Add the redirectUri param to CreateConnectLink so it matches the Python and Swift wrappers. * fix(python-client): require https, escape path segments, add timeout _request joined tenant/plugin/op into the path unescaped, so a value containing '/' changed the route instead of addressing it — quote each dynamic segment. Reject non-https urls (loopback excepted) since the API key rides as a bearer token, and pass a finite timeout to urlopen so a stalled server can't hang the caller forever. Also bump the setuptools floor to 77, the minimum that understands the Apache-2.0 license-expression syntax already in pyproject.toml. * fix(swift-client): require https, escape path segments; fix docs install send() built the URL path by joining segments raw through URLComponents.path, so a tenant/plugin/op containing '/' changed the route instead of addressing it — percent-encode each segment into percentEncodedPath instead. Reject non-https base URLs (loopback excepted) at call time. Also fix the docs/README install snippet: SPM can't resolve .package(url:) against a monorepo subdirectory, so show a local path dependency instead of a command that can't actually resolve. * ci(clients): pin Xcode 16 for swift test, restrict checkout token macos-14's default Xcode (15.4) has no Testing module, so 'import Testing' failed to compile — pin DEVELOPER_DIR to the Xcode 16.2 image already on the runner. Also set workflow permissions to contents:read and persist-credentials:false on every checkout so same-repo PR test code can't exfiltrate a writable token. * chore: bump corsair 0.1.137 + @corsair-dev/cli 0.1.24 (cloud wrappers + CLI) * docs(cloud): rewrite client docs and fix swift/go client bugs - Rewrite cloud/overview + python/go/swift client docs and READMEs as step-by-step first-time walkthroughs; drop AI-tell phrasing - Move client libraries under Frameworks > Clients in the nav - Swift: strip trailing slash on base URL (was producing //path) - Go: coerce nil args to {} so body is {"args":{}}, not {"args":null} - Add Go + Swift regression tests * fix(cloud): warn when cloud proxy has no authorize gate * docs(cloud): add client icons and swift mirror publish workflow * feat(cloud): resolve createCorsairCloud URL from the key createCorsairCloud({ apiKey }) now derives its base URL from the key slug (ck_cloud_<slug>_<secret> -> https://api.corsair.cloud/<slug>/api/corsair), so the developer passes only the key. `url` stays as an internal dev/test override. * feat(cloud): resolve the URL from the key across all clients Mirror the TS createCorsairCloud change in every client so the developer passes only the API key: Python/Go/Swift clients, cloud-proxy, and the cloud CLI now derive https://api.corsair.cloud/<slug>/api/corsair from a ck_cloud_<slug>_<secret> key; url stays as an optional dev/testing override. Tests: Go 6/6, Swift 8/8, Python + cloud-proxy + CLI green. * docs(cloud): key-only Corsair Cloud docs across the client surface Rewrite the cloud + per-client docs to the one-key contract: the overview, each language guide (Python/Go/Swift), the client READMEs, the cloud-proxy snippet, the WRAPPER-SPEC (source of truth), and the OpenAPI servers block no longer tell developers to copy a URL — the client derives it from the key. Also documents mapping tenants (manage.tenants.list) and marks raw-DB access as coming with BYO DB. * docs(cloud): give the curl example a URL source (derive from key slug) * fix(cloud): parse ck_cloud key slug on '.' delimiter The Hub now mints cloud keys as ck_cloud_<slug>.<secret>. Switch all client URL resolvers (TS core, cloud-proxy, CLI, Python, Go, Swift) to split the slug on the first '.' instead of '_'. The base64url secret can't contain '.', so an older slug-less key resolves to null rather than a wrong URL — locked by a legacy-underscore-key test in each suite. * fix(cloud): harden clients against review findings - cli op-tree: null-prototype maps so op names like toString/constructor key real nodes instead of inherited Object.prototype members - cloud-proxy: a thrown authorize() returns 401, not an escaping 500 - swift: percent-encode literal % in path segments (a%2Fb no longer decodes to a/b server-side), matching Go/Python - go: WithHTTPClient(nil) keeps the default; typed-nil args marshal to {} - reject a query/fragment in cloud URLs across core/proxy/cli (path segments are appended, so it would misroute) - docs: python client is 3.10+ (matches pyproject) - ci: publish-python guards tag==version; publish-swift tags then pushes branch+tag atomically * fix(cloud): ship py.typed marker for the Python client The Typing :: Typed classifier promises inline types; without the marker + package-data, type checkers ignore them for consumers. * fix(cloud): reject an empty tenant id in the language clients TS withTenant rejects an empty tenant; Go/Python/Swift silently built a path with a missing segment (…//plugin/call/op) that misroutes. Guard it: Python raises in with_tenant, Go returns an error from Call, Swift throws EmptyTenantIdError. Tests added for Go and Python. * refactor(cloud): rename to corsairCloud + corsairConnect Per the agreed surface naming: createCorsairCloud -> corsairCloud (the hosted client), createCloudProxy -> corsairConnect (the same-origin route handler), and the subpath corsair/cloud-proxy -> corsair/connect (file cloud-proxy.ts -> connect.ts). CorsairProvider keeps its name. Config type CreateCorsairCloudConfig -> CorsairCloudConfig, CloudProxyOptions -> CorsairConnectOptions. No behavior change. * docs(cloud): fix stale slug delimiter + unslop the cloud docs Overview curl example now derives the slug on the first '.' (not the old last '_'); renamed the stale CloudProxyNext import alias to ConnectExample; tightened the tenants/connection-status note to state exactly what the manage surface returns (redacted) vs what BYO-DB adds later; removed em-dashes across overview, the three client guides, and the connect snippet. * feat(cloud): expose manage.permissions.get on the cloud clients The runtime already serves GET /permissions/:id (admin, same gate as /tenants which the client uses) and POST /permissions/lookup-by-token (public approval-page lookup). Wire both through the TS manage namespace (by id or by token) and add a by-id read to the Python/Go/Swift clients. Lets a project read a tenant's permission grants — scopes and approval status — without touching credentials. * ci: publish corsair-cloud via PyPI trusted publishing (OIDC) Drop the stored PYPI_TOKEN in favor of OIDC: id-token: write + a pypi environment + pypa/gh-action-pypi-publish. Keeps the tag==pyproject version guard. * refactor(cloud): share the key-URL contract + warn on open proxy in prod - Extract cloudUrlFromKey + the https/query-fragment assertion + loopback set into core/cloud/url.ts, consumed by both the cloud client and the connect route handler, so the ck_cloud key format can't drift between them. - corsairConnect now warns about a missing authorize in every environment, production included — suppressing the signal in prod was backwards for a route that forwards any op with the project key. * docs(cloud): handle err in the Go connect/status examples so they compile * feat(cloud): corsairConnect fails closed without authorize An open proxy by omission forwards any tenant/plugin/op with the project key. Require authorize (or an explicit allowUnauthenticated: true opt-in), throwing at construction otherwise. Addresses the proxy-authorization review finding. * chore(cloud): drop internal WRAPPER-SPEC scaffolding doc It was the design spec that guided the client shape — not user-facing (the docs are docs/clients/*.mdx + per-client READMEs) and unreferenced. Doesn't belong in the shipped clients/ dir. | 19 天前 | |
ci: skip plugin gate for plugin-docs.yaml PRs (#1248) | 1 个月前 | |
feat(ci): automated plugin PR review loop (#403) | 2 个月前 | |
ci: add PR checks workflow, CI/CD automation, and code quality tooling (#259) (#268) | 3 个月前 | |
ci: add PR checks workflow, CI/CD automation, and code quality tooling (#259) (#268) | 3 个月前 |
| 文件 | 最后提交记录 | 最后更新时间 |
|---|---|---|
| 1 个月前 | ||
| 29 天前 | ||
| 19 天前 | ||
| 1 个月前 | ||
| 2 个月前 | ||
| 3 个月前 | ||
| 3 个月前 |