@inneranimalmedia/agentsam-sdk 2.6.4 → 2.6.5
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/AGENTSAM.md +11 -0
- package/README.md +15 -9
- package/apps/client-cms-editor/AGENTS.md +12 -0
- package/apps/client-cms-editor/IMPORT_PROVENANCE.json +8 -0
- package/apps/client-cms-editor/README.md +72 -0
- package/apps/client-cms-editor/agentsam.app.json +57 -0
- package/apps/client-cms-editor/backend/README.md +5 -0
- package/apps/client-cms-editor/backend/package.json +22 -0
- package/apps/client-cms-editor/backend/src/api/client.ts +200 -0
- package/apps/client-cms-editor/backend/src/demo-bootstrap.ts +145 -0
- package/apps/client-cms-editor/backend/src/index.ts +6 -0
- package/apps/client-cms-editor/backend/src/model.ts +115 -0
- package/apps/client-cms-editor/backend/src/preview/bridge.ts +79 -0
- package/apps/client-cms-editor/backend/src/preview/urls.ts +55 -0
- package/apps/client-cms-editor/backend/src/routing/cms-route.js +293 -0
- package/apps/client-cms-editor/backend/src/routing/index.js +10 -0
- package/apps/client-cms-editor/backend/src/storefront.ts +52 -0
- package/apps/client-cms-editor/backend/tsconfig.json +15 -0
- package/apps/client-cms-editor/backend/worker/index.js +34 -0
- package/apps/client-cms-editor/backend/wrangler.jsonc +11 -0
- package/apps/client-cms-editor/bin/agentsam-cms.mjs +229 -0
- package/apps/client-cms-editor/frontend/index.html +12 -0
- package/apps/client-cms-editor/frontend/package.json +33 -0
- package/apps/client-cms-editor/frontend/src/AgentSamDrawer.tsx +188 -0
- package/apps/client-cms-editor/frontend/src/CmsAgentSurface.tsx +191 -0
- package/apps/client-cms-editor/frontend/src/CmsEditor.tsx +1345 -0
- package/apps/client-cms-editor/frontend/src/env.d.ts +14 -0
- package/apps/client-cms-editor/frontend/src/index.ts +8 -0
- package/apps/client-cms-editor/frontend/src/lib/content-safety.ts +63 -0
- package/apps/client-cms-editor/frontend/src/main.tsx +17 -0
- package/apps/client-cms-editor/frontend/src/mount.tsx +51 -0
- package/apps/client-cms-editor/frontend/src/styles/agentsam-drawer.css +214 -0
- package/apps/client-cms-editor/frontend/src/styles/cmsShell.css +1739 -0
- package/apps/client-cms-editor/frontend/src/styles/studio.css +106 -0
- package/apps/client-cms-editor/frontend/src/surfaces/CmsDashboard.tsx +313 -0
- package/apps/client-cms-editor/frontend/src/surfaces/CmsGuidedChatHero.tsx +121 -0
- package/apps/client-cms-editor/frontend/src/surfaces/CmsHubPage.tsx +132 -0
- package/apps/client-cms-editor/frontend/src/surfaces/CmsSiteSwitcher.tsx +176 -0
- package/apps/client-cms-editor/frontend/src/surfaces/index.ts +5 -0
- package/apps/client-cms-editor/frontend/src/surfaces/types.ts +48 -0
- package/apps/client-cms-editor/frontend/tsconfig.json +25 -0
- package/apps/client-cms-editor/frontend/vite.config.ts +13 -0
- package/apps/client-cms-editor/package-lock.json +3832 -0
- package/apps/client-cms-editor/package.json +23 -0
- package/apps/client-cms-editor/reference/DONOR_README.md +52 -0
- package/apps/client-cms-editor/reference/DONOR_package-lock.json +1253 -0
- package/apps/client-cms-editor/reference/DONOR_tsconfig.json +15 -0
- package/apps/client-cms-editor/shared/cms/package.json +21 -0
- package/apps/client-cms-editor/shared/cms/src/agent-context.ts +35 -0
- package/apps/client-cms-editor/shared/cms/src/cloudflare-bindings.ts +51 -0
- package/apps/client-cms-editor/shared/cms/src/editor-types.ts +58 -0
- package/apps/client-cms-editor/shared/cms/src/index.ts +5 -0
- package/apps/client-cms-editor/shared/cms/src/publication.ts +24 -0
- package/apps/client-cms-editor/shared/cms/src/routes.ts +11 -0
- package/apps/client-cms-editor/shared/cms/tsconfig.json +12 -0
- package/bin/agentsam-rapid-rust +36 -0
- package/docs/AUTH_IDENTITY_CONTRACT.md +2 -0
- package/docs/MACHINE_INTELLIGENCE.md +120 -0
- package/docs/WINDOWS_RUNTIME_INSTALL.md +30 -0
- package/docs/architecture/AGENTSAM_APPLICATION_CONTRACT.md +188 -0
- package/docs/architecture/AGENTSAM_RUNTIME_PROTOCOL.md +151 -0
- package/docs/architecture/LOCAL_STUDIO_CLOUDFLARE_OAUTH.md +12 -4
- package/docs/architecture/R2_SLUG_NAMESPACE.md +20 -0
- package/docs/architecture/WORK_PRODUCT_EXTRACTION.md +97 -0
- package/docs/brand/AGENT_SAM_ICON_GRAMMAR.md +70 -0
- package/docs/content-studio/HOST_MOUNT_CHECKLIST.md +71 -0
- package/docs/content-studio/REVISION_GATE_2026-09-27.md +501 -0
- package/docs/contracts/capability-install-planner.md +67 -0
- package/docs/contracts/environment-vocabulary.md +195 -0
- package/docs/contracts/google-cloud-oauth-setup.md +199 -0
- package/docs/local-studio/WORKMODE_DONOR_NOTES.md +1 -1
- package/docs/plans/LOCAL-STUDIO-GRADUATION-2026-09-26.md +290 -0
- package/docs/plans/LOCAL-STUDIO-REAL-APP-CONTRACT-ADDENDUM-2026-09-27.md +394 -0
- package/docs/plans/MACHINE-FIRST-APPS-TUI-2026-09-24.md +227 -0
- package/docs/plans/TOMORROW-EXTENSIVE-TODO-2026-09-26.md +221 -0
- package/docs/plans/TOMORROW-MACHINE-FIRST-BRIEFING.md +145 -0
- package/docs/plans/UNIVERSAL-INGEST-MACHINE-FIRST-2026-09-24.md +215 -0
- package/docs/plugins.md +2 -2
- package/docs/product/AGENTSAM_PRODUCT_EXPERIENCE_STANDARD.md +280 -0
- package/docs/product/LOCAL_STUDIO_DESKTOP_EXPERIENCE.md +139 -0
- package/docs/product/README.md +8 -0
- package/docs/rapid-rust-wasm.md +35 -0
- package/migrations/d1/0016_cloudflare_oauth_user_oauth_tokens_ssot.sql +14 -0
- package/package.json +73 -14
- package/packages/agentsam-brand/README.md +106 -11
- package/packages/agentsam-brand/bin/agentsam-brand.mjs +9 -0
- package/packages/agentsam-brand/package.json +39 -7
- package/packages/agentsam-brand/src/adapters/cloudflare-images.js +453 -0
- package/packages/agentsam-brand/src/adapters/cloudflare-r2.js +74 -0
- package/packages/agentsam-brand/src/adapters/d1-registry.js +26 -0
- package/packages/agentsam-brand/src/adapters/filesystem.js +59 -0
- package/packages/agentsam-brand/src/adapters/memory.js +31 -0
- package/packages/agentsam-brand/src/cli/controller.js +503 -0
- package/packages/agentsam-brand/src/cli/wizard.js +526 -0
- package/packages/agentsam-brand/src/core/capabilities.js +201 -0
- package/packages/agentsam-brand/src/core/derivatives.js +211 -0
- package/packages/agentsam-brand/src/core/errors.js +12 -0
- package/packages/agentsam-brand/src/core/ingest.js +195 -0
- package/packages/agentsam-brand/src/core/inspect.js +109 -0
- package/packages/agentsam-brand/src/core/keys.js +83 -0
- package/packages/agentsam-brand/src/core/naming.js +142 -0
- package/packages/agentsam-brand/src/core/optimize.js +316 -0
- package/packages/agentsam-brand/src/core/pack.js +305 -0
- package/packages/agentsam-brand/src/core/plan.js +276 -0
- package/packages/agentsam-brand/src/core/preview.js +159 -0
- package/packages/agentsam-brand/src/core/processors/cloudflare.js +68 -0
- package/packages/agentsam-brand/src/core/processors/contract.js +203 -0
- package/packages/agentsam-brand/src/core/processors/index.js +148 -0
- package/packages/agentsam-brand/src/core/processors/native.js +82 -0
- package/packages/agentsam-brand/src/core/processors/sharp.js +113 -0
- package/packages/agentsam-brand/src/core/processors/squoosh-binary.js +195 -0
- package/packages/agentsam-brand/src/core/promote.js +288 -0
- package/packages/agentsam-brand/src/core/receipts.js +155 -0
- package/packages/agentsam-brand/src/core/v2/compile.js +280 -0
- package/packages/agentsam-brand/src/core/v2/derivatives-semantic.js +207 -0
- package/packages/agentsam-brand/src/core/v2/ingest-graph.js +387 -0
- package/packages/agentsam-brand/src/core/v2/roles.js +180 -0
- package/packages/agentsam-brand/src/core/v2/schema.js +209 -0
- package/packages/agentsam-brand/src/core/v2/templates.js +114 -0
- package/packages/agentsam-brand/src/index.js +193 -36
- package/packages/agentsam-brand/src/presets/app-icon.json +16 -0
- package/packages/agentsam-brand/src/presets/favicon.json +17 -0
- package/packages/agentsam-brand/src/presets/hero.json +12 -0
- package/packages/agentsam-brand/src/presets/index.js +40 -0
- package/packages/agentsam-brand/src/presets/logo.json +12 -0
- package/packages/agentsam-brand/src/presets/model.json +8 -0
- package/packages/agentsam-brand/src/presets/og-image.json +10 -0
- package/packages/agentsam-brand/src/presets/product-shot.json +11 -0
- package/packages/agentsam-brand/src/presets/social-image.json +10 -0
- package/packages/agentsam-brand/src/presets/web-image.json +10 -0
- package/packages/agentsam-contracts/src/artifacts.ts +41 -0
- package/packages/agentsam-knowledge/src/autorag/index.js +1 -1
- package/packages/agentsam-knowledge/src/providers/index.js +6 -4
- package/packages/agentsam-knowledge/src/providers/ollama-endpoint.js +31 -0
- package/packages/agentsam-knowledge/test/autorag.test.mjs +22 -1
- package/packages/agentsam-nav/package.json +2 -2
- package/packages/agentsam-rapid-rust/Cargo.lock +344 -0
- package/packages/agentsam-rapid-rust/Cargo.toml +18 -0
- package/packages/agentsam-rapid-rust/README.md +5 -0
- package/packages/agentsam-rapid-rust/src/main.rs +718 -0
- package/packages/agentsam-rapid-rust/templates/api/Cargo.toml.tmpl +18 -0
- package/packages/agentsam-rapid-rust/templates/api/src/lib.rs.tmpl +17 -0
- package/packages/agentsam-rapid-rust/templates/common/README.md.tmpl +22 -0
- package/packages/agentsam-rapid-rust/templates/common/package.json.tmpl +12 -0
- package/packages/agentsam-rapid-rust/templates/common/wrangler.toml.tmpl +6 -0
- package/packages/agentsam-rapid-rust/templates/crypto-auth/Cargo.toml.tmpl +21 -0
- package/packages/agentsam-rapid-rust/templates/crypto-auth/src/lib.rs.tmpl +32 -0
- package/packages/agentsam-rapid-rust/templates/data-processor/Cargo.toml.tmpl +18 -0
- package/packages/agentsam-rapid-rust/templates/data-processor/src/lib.rs.tmpl +41 -0
- package/packages/agentsam-rapid-rust/templates/shared-core/Cargo.toml.tmpl +9 -0
- package/packages/agentsam-rapid-rust/templates/shared-core/core/Cargo.toml.tmpl +7 -0
- package/packages/agentsam-rapid-rust/templates/shared-core/core/src/lib.rs.tmpl +23 -0
- package/packages/agentsam-rapid-rust/templates/shared-core/worker/Cargo.toml.tmpl +12 -0
- package/packages/agentsam-rapid-rust/templates/shared-core/worker/src/lib.rs.tmpl +16 -0
- package/packages/agentsam-rapid-rust/templates/shared-core/wrangler.toml.tmpl +6 -0
- package/packages/agentsam-repository/src/index.js +1 -0
- package/packages/agentsam-repository/src/merkle/semantic.js +3 -10
- package/packages/agentsam-repository/src/source-types.js +85 -0
- package/packages/agentsam-vault/README.md +96 -0
- package/packages/agentsam-vault/package.json +32 -0
- package/packages/agentsam-vault/src/contracts/credential.d.ts +78 -0
- package/packages/agentsam-vault/src/contracts/credential.js +132 -0
- package/packages/agentsam-vault/src/crypto/aes-gcm.d.ts +30 -0
- package/packages/agentsam-vault/src/crypto/aes-gcm.js +107 -0
- package/packages/agentsam-vault/src/crypto/oauth-envelope.js +150 -0
- package/packages/agentsam-vault/src/index.d.ts +9 -0
- package/packages/agentsam-vault/src/index.js +27 -0
- package/packages/agentsam-vault/src/providers/registry.js +90 -0
- package/packages/agentsam-vault/src/runtime/resolver.js +77 -0
- package/packages/agentsam-workbench/README.md +24 -0
- package/packages/agentsam-workbench/package.json +38 -0
- package/packages/agentsam-workbench/src/agent/AgentPanel.tsx +41 -0
- package/packages/agentsam-workbench/src/agent/ArtifactCard.tsx +9 -0
- package/packages/agentsam-workbench/src/agent/Composer.tsx +102 -0
- package/packages/agentsam-workbench/src/agent/ConnectedAgentPanel.tsx +194 -0
- package/packages/agentsam-workbench/src/agent/ContextualComposer.tsx +788 -0
- package/packages/agentsam-workbench/src/agent/GoalStatusStrip.tsx +38 -0
- package/packages/agentsam-workbench/src/agent/MiniAgentSam.tsx +86 -0
- package/packages/agentsam-workbench/src/agent/ModelSelect.tsx +19 -0
- package/packages/agentsam-workbench/src/agent/Thread.tsx +56 -0
- package/packages/agentsam-workbench/src/agent/ToolReceipt.tsx +11 -0
- package/packages/agentsam-workbench/src/agent/contextual-composer.css +611 -0
- package/packages/agentsam-workbench/src/agent/index.ts +10 -0
- package/packages/agentsam-workbench/src/agent/mini-agentsam.css +12 -0
- package/packages/agentsam-workbench/src/browser/BrowserFrame.tsx +37 -0
- package/packages/agentsam-workbench/src/browser/index.ts +1 -0
- package/packages/agentsam-workbench/src/index.ts +6 -0
- package/packages/agentsam-workbench/src/project-control.css +160 -0
- package/packages/agentsam-workbench/src/projects/ProjectsSurface.tsx +131 -0
- package/packages/agentsam-workbench/src/projects/index.ts +1 -0
- package/packages/agentsam-workbench/src/shell/Breadcrumb.tsx +35 -0
- package/packages/agentsam-workbench/src/shell/ResizableStage.tsx +99 -0
- package/packages/agentsam-workbench/src/shell/SidePanel.tsx +5 -0
- package/packages/agentsam-workbench/src/shell/index.ts +4 -0
- package/packages/agentsam-workbench/src/shell/surfaceRegistry.ts +29 -0
- package/packages/agentsam-workbench/src/terminal/TerminalSurface.tsx +5 -0
- package/packages/agentsam-workbench/src/terminal/index.ts +1 -0
- package/packages/agentsam-workbench/src/timeline/GanttBoard.tsx +258 -0
- package/packages/agentsam-workbench/src/timeline/index.ts +1 -0
- package/packages/agentsam-workbench/tsconfig.json +13 -0
- package/packages/connectors/cloudflare/OAUTH_STORAGE_AUDIT.md +53 -0
- package/packages/connectors/cloudflare/package.json +3 -1
- package/packages/connectors/cloudflare/src/api-client.js +279 -0
- package/packages/connectors/cloudflare/src/capabilities.js +585 -0
- package/packages/connectors/cloudflare/src/credential.js +318 -0
- package/packages/connectors/cloudflare/src/families/brand-protection.js +123 -0
- package/packages/connectors/cloudflare/src/families/keyless.js +114 -0
- package/packages/connectors/cloudflare/src/families/pages.js +151 -0
- package/packages/connectors/cloudflare/src/families/scanner.js +123 -0
- package/packages/connectors/cloudflare/src/families/snippets.js +207 -0
- package/packages/connectors/cloudflare/src/families/tag-gateway.js +46 -0
- package/packages/connectors/cloudflare/src/families/tags.js +124 -0
- package/packages/connectors/cloudflare/src/families/token-validation.js +95 -0
- package/packages/connectors/cloudflare/src/families/workflows.js +156 -0
- package/packages/connectors/cloudflare/src/index.js +102 -265
- package/packages/connectors/cloudflare/src/oauth-persist.js +336 -0
- package/packages/connectors/cloudflare/src/owner.js +42 -12
- package/packages/connectors/cloudflare/src/permission-options.js +1064 -0
- package/packages/connectors/cloudflare/src/routes.js +309 -144
- package/packages/connectors/cloudflare/src/scope-catalog.js +345 -0
- package/packages/connectors/cloudflare/src/vault.js +2 -2
- package/packages/connectors/cloudflare/tests/capabilities.test.mjs +276 -0
- package/packages/connectors/cloudflare/tests/connector.test.mjs +26 -30
- package/packages/connectors/cloudflare/tests/oauth-persist.test.mjs +125 -0
- package/packages/identity/.agentsam/features/oauth-login-portal/providers.json +22 -2
- package/packages/identity/.agentsam/features/oauth-login-portal/resources.json +10 -4
- package/packages/identity/.agentsam/features/oauth-login-portal/routes.json +20 -0
- package/packages/identity/README.md +1 -1
- package/packages/identity/backend/README.md +1 -1
- package/packages/identity/migrations/D1_SCHEMA_MAPPING.md +3 -2
- package/packages/identity/migrations/sqlite/004_identity_oauth_consent_catalog.sql +48 -0
- package/packages/identity/package.json +4 -3
- package/packages/identity/scripts/local-identity-bridge.mjs +184 -0
- package/packages/identity/scripts/preview-auth-portal.mjs +7 -7
- package/packages/identity/src/adapters/cloudflare-d1/index.js +31 -2
- package/packages/identity/src/adapters/sqlite/index.js +4 -1
- package/packages/identity/src/contracts/auth-config.js +28 -8
- package/packages/identity/src/contracts/external-identity.js +1 -1
- package/packages/identity/src/contracts/provider.js +1 -0
- package/packages/identity/src/frontend/auth-portal/README.md +2 -1
- package/packages/identity/src/frontend/auth-portal/pages/login.html +6 -5
- package/packages/identity/src/frontend/auth-portal/pages/reset.html +6 -5
- package/packages/identity/src/frontend/auth-portal/pages/signup.html +6 -5
- package/packages/identity/src/frontend/auth-portal/shared/company-branding.js +1 -1
- package/packages/identity/src/frontend/auth-portal/shared/desktop-identity-bridge.js +207 -0
- package/packages/identity/src/index.js +16 -0
- package/packages/identity/src/migrations/0001_identity_core.sql +19 -2
- package/packages/identity/src/migrations/0003_accounts_ssot.sql +20 -0
- package/packages/identity/src/migrations/README.md +5 -2
- package/packages/identity/src/oauth/README.md +10 -5
- package/packages/identity/src/oauth/consent-view.js +388 -0
- package/packages/identity/src/oauth/credentials.js +31 -11
- package/packages/identity/src/oauth/google-desktop-exchange.js +173 -0
- package/packages/identity/src/providers/cloudflare/oauth.js +3 -4
- package/packages/identity/src/providers/cloudflare/profile.js +49 -14
- package/packages/identity/src/providers/iam/index.js +27 -5
- package/packages/identity/src/server/identity-service.js +31 -2
- package/packages/identity/src/server/worker-router.js +111 -81
- package/packages/identity/tests/auth-config.test.mjs +3 -2
- package/packages/identity/tests/identity-init-scaffold.test.mjs +3 -0
- package/packages/identity/tests/identity-service.test.mjs +16 -0
- package/packages/identity/tests/native-session-worker.test.mjs +64 -0
- package/packages/identity/tests/oauth-consent-view.test.mjs +106 -0
- package/packages/identity/tests/oauth-credentials.test.mjs +17 -4
- package/packages/identity/tests/oauth-presets-accounts-ssot.test.mjs +58 -0
- package/packages/identity/tests/preview-auth-portal.test.mjs +3 -3
- package/packages/runtime-protocol/src/index.js +154 -0
- package/packages/theme-scenes/README.md +164 -0
- package/packages/theme-scenes/package.json +53 -0
- package/packages/theme-scenes/src/blocks/index.js +30 -0
- package/packages/theme-scenes/src/contracts/index.js +286 -0
- package/packages/theme-scenes/src/demos/index.js +65 -0
- package/packages/theme-scenes/src/index.js +75 -0
- package/packages/theme-scenes/src/presets/index.js +263 -0
- package/packages/theme-scenes/src/runtime/compile.js +119 -0
- package/packages/theme-scenes/src/scenes/index.js +146 -0
- package/packages/theme-scenes/src/shell/index.js +47 -0
- package/packages/theme-scenes/src/themes/index.js +129 -0
- package/packages/theme-scenes/src/visuals/index.js +41 -0
- package/packages/theme-scenes/test/theme-scenes.test.mjs +179 -0
- package/packages/work-graph/src/index.js +34 -1
- package/packages/work-graph/src/renderers/gantt-model.js +24 -0
- package/packages/work-graph/test/work-graph.test.mjs +27 -7
- package/protocol/README.md +15 -7
- package/protocol/apps/agentsam.app.v1.schema.json +89 -7
- package/protocol/apps/agentsam.host-install.v1.schema.json +36 -0
- package/protocol/assets/README.md +9 -0
- package/protocol/assets/asset-record.v1.schema.json +64 -0
- package/protocol/runtime/agentsam.runtime.v1.schema.json +75 -0
- package/protocol/scoring/README.md +10 -0
- package/protocol/scoring/scorecard.v1.schema.json +65 -0
- package/protocol/ui/icon-registry.mjs +1 -0
- package/registry/cms-rust-machine-20260928/installable-products.json +31 -0
- package/registry/cms-rust-machine-20260928/manifest.json +22 -0
- package/registry/cms-rust-machine-20260928/migration.sql +237 -0
- package/registry/cms-rust-machine-20260928/receipt.json +21 -0
- package/registry/cms-rust-machine-20260928/receipt.sql +27 -0
- package/scripts/build_rapid_rust_cli.py +83 -0
- package/src/attachments/index.js +6 -0
- package/src/attachments/intake.js +235 -0
- package/src/capabilities/repository-snapshot.js +19 -2
- package/src/cli/command-catalog.js +8 -0
- package/src/cli.js +182 -26
- package/src/commands/account-auth.js +94 -8
- package/src/commands/app.js +307 -3
- package/src/commands/billing.js +127 -0
- package/src/commands/brand.js +74 -60
- package/src/commands/cheat-sheet.js +154 -0
- package/src/commands/cloudflare-login.js +222 -0
- package/src/commands/cloudflare.js +453 -23
- package/src/commands/codebaseindex.js +6 -1
- package/src/commands/compute.js +4 -0
- package/src/commands/connections.js +11 -5
- package/src/commands/credentials.js +116 -0
- package/src/commands/gcloud-auth.js +427 -0
- package/src/commands/google-cloud.js +375 -0
- package/src/commands/identity-init.js +2 -2
- package/src/commands/mcp.js +226 -33
- package/src/commands/ollama.js +3 -2
- package/src/commands/plugins.js +7 -2
- package/src/commands/product.js +36 -0
- package/src/commands/runtime-status.js +28 -9
- package/src/commands/runtime.js +313 -0
- package/src/commands/rust.js +24 -0
- package/src/commands/setup.js +279 -0
- package/src/commands/shell.js +16 -3
- package/src/commands/start-local.js +2 -2
- package/src/commands/terminal.js +171 -0
- package/src/commands/update.js +140 -0
- package/src/commands/whoami.js +329 -65
- package/src/features/resolve.js +1 -0
- package/src/index.js +4 -0
- package/src/indexing/ingest/inventory.js +254 -19
- package/src/indexing/ingest/materials.js +3 -9
- package/src/indexing/ingest/style-evidence.js +181 -0
- package/src/knowledge/source.js +3 -3
- package/src/lib/account-session.js +11 -4
- package/src/lib/app-authority.js +172 -0
- package/src/lib/auth.js +94 -21
- package/src/lib/core-client.js +5 -6
- package/src/lib/credentials-audit.js +451 -0
- package/src/lib/deploy/health.js +24 -6
- package/src/lib/detect-context.js +7 -1
- package/src/lib/google-cloud-connection.js +270 -0
- package/src/lib/google-cloud-inventory.js +385 -0
- package/src/lib/google-desktop-oauth.js +372 -0
- package/src/lib/google-studio-brokered-oauth.js +158 -0
- package/src/lib/identity-scaffold.js +24 -6
- package/src/lib/init-options.js +192 -0
- package/src/lib/local-scaffold.js +48 -16
- package/src/lib/provider-command-remediation.js +308 -0
- package/src/lib/provider-credentials.js +8 -0
- package/src/lib/scaffold/index.js +8 -2
- package/src/lib/scaffold/mcp-server.js +43 -0
- package/src/lib/scaffold/templates/mcp-server/index.js +397 -0
- package/src/lib/scaffold/templates/mcp-server/presets.js +39 -0
- package/src/lib/scaffold/wizards/cms.js +93 -0
- package/src/lib/scaffold/wizards/mcp-server.js +61 -0
- package/src/lib/setup/contract.js +26 -0
- package/src/lib/setup/discover.js +116 -0
- package/src/lib/setup/execute.js +205 -0
- package/src/lib/setup/planner.js +134 -0
- package/src/lib/setup/recipes.js +235 -0
- package/src/lib/setup/runtime-persist.js +197 -0
- package/src/lib/setup/runtime.js +394 -0
- package/src/lib/slash-commands.js +2 -0
- package/src/lib/terminal/machine-identity.js +95 -0
- package/src/lib/terminal-local.js +164 -0
- package/src/lib/terminal-scopes.js +52 -0
- package/src/lib/whoami-capabilities.js +184 -0
- package/src/local-pty/server.js +34 -5
- package/src/mcp/authority.js +58 -108
- package/src/mcp/client-adapters.js +68 -144
- package/src/mcp/client.js +142 -122
- package/src/mcp/cloudflare-bundles.js +225 -0
- package/src/mcp/index.js +12 -0
- package/src/plugins/cloudflare.js +1 -1
- package/src/providers/ollama-chat.js +2 -1
- package/src/sam/types.js +27 -2
- package/src/security/inventory.js +12 -2
- package/src/security/local-vault.js +2 -0
- package/src/security/scan.js +1 -1
- package/test/account-session.test.mjs +3 -3
- package/test/app-authority-context.test.mjs +32 -0
- package/test/cli/codebaseindex-plan-ux.test.mjs +1 -1
- package/test/cli/mcp-client.test.mjs +21 -10
- package/test/cli/runtime-persist.test.mjs +56 -0
- package/test/cli/rust-command.test.mjs +21 -0
- package/test/credentials-audit.test.mjs +113 -0
- package/test/deploy-health-scan.test.mjs +29 -1
- package/test/gcloud-auth.test.mjs +111 -0
- package/test/google-cloud-connection.test.mjs +83 -0
- package/test/google-cloud-inventory.test.mjs +64 -0
- package/test/init-options.test.mjs +35 -0
- package/test/integration/app-command.test.mjs +30 -0
- package/test/integration/cad-project.test.mjs +4 -1
- package/test/integration/cms-app-scaffold.test.mjs +71 -0
- package/test/integration/cms-site-tenancy-contract.test.mjs +3 -2
- package/test/integration/codebaseindex-ingest.test.mjs +48 -0
- package/test/integration/features-resolve.test.mjs +30 -11
- package/test/integration/inspect-path-cli.test.mjs +46 -0
- package/test/integration/inventory-evidence.test.mjs +125 -0
- package/test/integration/runtime-status.integration.test.mjs +2 -1
- package/test/knowledge.test.mjs +35 -1
- package/test/loopback-oauth.test.mjs +53 -0
- package/test/ollama.test.mjs +22 -0
- package/test/security.test.mjs +23 -0
- package/test/setup-planner.test.mjs +74 -0
- package/test/setup-runtime.test.mjs +51 -0
- package/test/terminal/local-pty.mock.test.mjs +3 -1
- package/test/terminal-machine-identity.test.mjs +88 -0
- package/test/whoami-resume.test.mjs +27 -6
- package/packages/agentsam-brand/test/brand-scan.test.mjs +0 -106
- package/packages/work-graph/prototype/README.md +0 -32
- package/packages/work-graph/prototype/data/demo-workgraph.js +0 -47
- package/packages/work-graph/prototype/renderers/timeline-model.js +0 -21
- package/packages/work-graph/prototype/renderers/workgraph-runtime.js +0 -38
- package/packages/work-graph/prototype-gnantt.html +0 -655
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* APP / HOST / PLATFORM authority resolution.
|
|
3
|
+
*
|
|
4
|
+
* One canonical identifier per namespace — no alias env vars.
|
|
5
|
+
* APP.id → agentsam.app.json
|
|
6
|
+
* HOST → agentsam.app.json hosts[] (host_id + origin)
|
|
7
|
+
* PLATFORM → IAM_OAUTH_ISSUER (account API / OAuth issuer)
|
|
8
|
+
*
|
|
9
|
+
* Relationships are explicit pointers, never collapsed aliases like
|
|
10
|
+
* AGENTSAM_STUDIO_ORIGIN ≈ AGENTSAM_LOCAL_STUDIO_ORIGIN ≈ IAM_OAUTH_ISSUER.
|
|
11
|
+
*/
|
|
12
|
+
import fs from 'node:fs';
|
|
13
|
+
import path from 'node:path';
|
|
14
|
+
import { fileURLToPath } from 'node:url';
|
|
15
|
+
import {
|
|
16
|
+
PLATFORM_ACCOUNT_ISSUER,
|
|
17
|
+
resolveIamIssuer,
|
|
18
|
+
} from '../../packages/identity/src/contracts/auth-config.js';
|
|
19
|
+
|
|
20
|
+
const HERE = path.dirname(fileURLToPath(import.meta.url));
|
|
21
|
+
const REPO_ROOT = path.resolve(HERE, '../..');
|
|
22
|
+
|
|
23
|
+
/** PLATFORM account-authority issuer — re-export from identity contract. */
|
|
24
|
+
export { PLATFORM_ACCOUNT_ISSUER };
|
|
25
|
+
|
|
26
|
+
/** APP.id for the Local Studio host product. */
|
|
27
|
+
export const LOCAL_STUDIO_APP_ID = 'local-studio';
|
|
28
|
+
|
|
29
|
+
function clean(value) {
|
|
30
|
+
return value == null ? '' : String(value).trim();
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function normalizeOrigin(value) {
|
|
34
|
+
return clean(value).replace(/\/+$/, '');
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function readManifestFile(manifestPath) {
|
|
38
|
+
if (!fs.existsSync(manifestPath)) return null;
|
|
39
|
+
try {
|
|
40
|
+
return JSON.parse(fs.readFileSync(manifestPath, 'utf8'));
|
|
41
|
+
} catch {
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export function readAppManifest(appId, root = REPO_ROOT) {
|
|
47
|
+
const id = clean(appId);
|
|
48
|
+
if (!id) return null;
|
|
49
|
+
for (const parent of ['apps', 'packages']) {
|
|
50
|
+
const manifestPath = path.join(root, parent, id, 'agentsam.app.json');
|
|
51
|
+
const manifest = readManifestFile(manifestPath);
|
|
52
|
+
if (manifest) return manifest;
|
|
53
|
+
}
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* HOST namespace entries declared on an APP manifest.
|
|
59
|
+
* @returns {Array<{ host_id: string, origin: string, role?: string }>}
|
|
60
|
+
*/
|
|
61
|
+
export function listAppHosts(appId, options = {}) {
|
|
62
|
+
const manifest = readAppManifest(appId, options.root || REPO_ROOT);
|
|
63
|
+
const hosts = manifest?.hosts;
|
|
64
|
+
if (!Array.isArray(hosts)) return [];
|
|
65
|
+
return hosts
|
|
66
|
+
.map((row) => ({
|
|
67
|
+
host_id: clean(row?.host_id || row?.id),
|
|
68
|
+
origin: normalizeOrigin(row?.origin),
|
|
69
|
+
role: clean(row?.role) || null,
|
|
70
|
+
}))
|
|
71
|
+
.filter((row) => row.host_id && row.origin);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Resolve one HOST origin for an APP.
|
|
76
|
+
* Prefers role=production, then first declared host.
|
|
77
|
+
*/
|
|
78
|
+
export function resolveAppHostOrigin(appId, options = {}) {
|
|
79
|
+
const hosts = listAppHosts(appId, options);
|
|
80
|
+
if (!hosts.length) return '';
|
|
81
|
+
if (options.hostId) {
|
|
82
|
+
const hit = hosts.find((h) => h.host_id === options.hostId);
|
|
83
|
+
return hit?.origin || '';
|
|
84
|
+
}
|
|
85
|
+
const role = clean(options.role) || 'production';
|
|
86
|
+
const byRole = hosts.find((h) => h.role === role);
|
|
87
|
+
return (byRole || hosts[0]).origin;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Resolve APP/HOST context from the actual execution directory.
|
|
93
|
+
* Generic repo-root commands intentionally return null APP/HOST values.
|
|
94
|
+
* The nearest agentsam.app.json is authoritative when inside an app/package.
|
|
95
|
+
*/
|
|
96
|
+
export function resolveCurrentAppContext(options = {}) {
|
|
97
|
+
const root = path.resolve(options.root || REPO_ROOT);
|
|
98
|
+
const explicitAppId = clean(options.appId);
|
|
99
|
+
if (explicitAppId) {
|
|
100
|
+
const manifest = readAppManifest(explicitAppId, root);
|
|
101
|
+
if (!manifest) {
|
|
102
|
+
return { app_id: null, host_origin: null, source: null };
|
|
103
|
+
}
|
|
104
|
+
const appId = clean(manifest.id) || explicitAppId;
|
|
105
|
+
return {
|
|
106
|
+
app_id: appId,
|
|
107
|
+
host_origin: resolveAppHostOrigin(explicitAppId, {
|
|
108
|
+
root,
|
|
109
|
+
role: options.role || 'production',
|
|
110
|
+
hostId: options.hostId,
|
|
111
|
+
}) || null,
|
|
112
|
+
source: 'explicit-app-id',
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
let current = path.resolve(options.cwd || process.cwd());
|
|
117
|
+
const relative = path.relative(root, current);
|
|
118
|
+
if (relative.startsWith('..') || path.isAbsolute(relative)) {
|
|
119
|
+
return { app_id: null, host_origin: null, source: null };
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
while (current === root || current.startsWith(root + path.sep)) {
|
|
123
|
+
const manifestPath = path.join(current, 'agentsam.app.json');
|
|
124
|
+
const manifest = readManifestFile(manifestPath);
|
|
125
|
+
if (manifest) {
|
|
126
|
+
const appId = clean(manifest.id);
|
|
127
|
+
const hosts = Array.isArray(manifest.hosts) ? manifest.hosts : [];
|
|
128
|
+
const hostRows = hosts
|
|
129
|
+
.map((row) => ({
|
|
130
|
+
host_id: clean(row?.host_id || row?.id),
|
|
131
|
+
origin: normalizeOrigin(row?.origin),
|
|
132
|
+
role: clean(row?.role) || null,
|
|
133
|
+
}))
|
|
134
|
+
.filter((row) => row.host_id && row.origin);
|
|
135
|
+
const role = clean(options.role) || 'production';
|
|
136
|
+
const host = options.hostId
|
|
137
|
+
? hostRows.find((row) => row.host_id === options.hostId)
|
|
138
|
+
: (hostRows.find((row) => row.role === role) || hostRows[0]);
|
|
139
|
+
return {
|
|
140
|
+
app_id: appId || null,
|
|
141
|
+
host_origin: host?.origin || null,
|
|
142
|
+
source: manifestPath,
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
if (current === root) break;
|
|
146
|
+
current = path.dirname(current);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
return { app_id: null, host_origin: null, source: null };
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* PLATFORM issuer for account API / whoami / aak_* calls.
|
|
154
|
+
* Delegates to identity resolveIamIssuer (never APP host).
|
|
155
|
+
*/
|
|
156
|
+
export function resolvePlatformAccountIssuer(env = process.env, explicit = '') {
|
|
157
|
+
return resolveIamIssuer(env, explicit);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Origin for Google / Cloudflare identity + CF connection OAuth owned by local-studio.
|
|
162
|
+
* HOST namespace from APP.hosts — never aliased to IAM_OAUTH_ISSUER.
|
|
163
|
+
*/
|
|
164
|
+
export function resolveLocalStudioHostOrigin(options = {}) {
|
|
165
|
+
const fromManifest = resolveAppHostOrigin(LOCAL_STUDIO_APP_ID, {
|
|
166
|
+
root: options.root,
|
|
167
|
+
role: options.role || 'production',
|
|
168
|
+
hostId: options.hostId,
|
|
169
|
+
});
|
|
170
|
+
if (fromManifest) return fromManifest;
|
|
171
|
+
return 'https://agentsam.inneranimalmedia.com';
|
|
172
|
+
}
|
package/src/lib/auth.js
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* RFC 8252 native-app OAuth for AgentSam CLI.
|
|
3
3
|
*
|
|
4
|
-
* The CLI is a public client
|
|
5
|
-
*
|
|
6
|
-
* reusable AGENTSAM_API_KEY (aak_*) credentials.
|
|
4
|
+
* The CLI is a public PKCE client of canonical IAM. It does not reuse the
|
|
5
|
+
* confidential hosted-web client or ship an IAM client secret.
|
|
7
6
|
*/
|
|
8
7
|
import http from 'node:http';
|
|
9
8
|
import { createHash, randomBytes } from 'node:crypto';
|
|
@@ -16,9 +15,10 @@ import {
|
|
|
16
15
|
saveAccountSession,
|
|
17
16
|
} from './account-session.js';
|
|
18
17
|
|
|
19
|
-
export const
|
|
20
|
-
export const AGENTSAM_NATIVE_OAUTH_SCOPE = 'openid profile email offline_access';
|
|
18
|
+
export const AGENTSAM_OAUTH_SCOPE = 'openid profile email offline_access';
|
|
21
19
|
export const AGENTSAM_OAUTH_CALLBACK_PATH = '/callback';
|
|
20
|
+
/** First-party public OAuth client used by the AgentSam CLI. */
|
|
21
|
+
export const DEFAULT_AGENTSAM_IAM_CLIENT_ID = 'iam_cli_agentsam';
|
|
22
22
|
|
|
23
23
|
function clean(value) { return value == null ? '' : String(value).trim(); }
|
|
24
24
|
function base64url(value) {
|
|
@@ -37,6 +37,22 @@ function oauthErrorMessage(body, status) {
|
|
|
37
37
|
return code || description || `OAuth token HTTP ${status}`;
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
+
/**
|
|
41
|
+
* Resolve the public native IAM OAuth client for the CLI.
|
|
42
|
+
* IAM_CLIENT_ID belongs to hosted/confidential app surfaces and is intentionally ignored.
|
|
43
|
+
* @returns {{ clientId: string, error: null } | { clientId: string, error: string }}
|
|
44
|
+
*/
|
|
45
|
+
export function resolveIamClientId(options = {}) {
|
|
46
|
+
const env = options.env || process.env;
|
|
47
|
+
const clientId = clean(options.clientId)
|
|
48
|
+
|| clean(env.AGENTSAM_NATIVE_OAUTH_CLIENT_ID)
|
|
49
|
+
|| DEFAULT_AGENTSAM_IAM_CLIENT_ID;
|
|
50
|
+
if (!clientId) {
|
|
51
|
+
return { error: 'iam_oauth_not_configured', clientId: '' };
|
|
52
|
+
}
|
|
53
|
+
return { clientId, error: null };
|
|
54
|
+
}
|
|
55
|
+
|
|
40
56
|
export function createPkcePair(options = {}) {
|
|
41
57
|
const verifier = randomUrlSafe(32, options.randomBytesImpl || randomBytes);
|
|
42
58
|
const challenge = base64url(createHash('sha256').update(verifier, 'ascii').digest());
|
|
@@ -46,11 +62,17 @@ export function createPkcePair(options = {}) {
|
|
|
46
62
|
export function buildNativeAuthorizationUrl(options = {}) {
|
|
47
63
|
const env = options.env || process.env;
|
|
48
64
|
const issuer = resolveIamIssuer(env, options.issuer || '');
|
|
49
|
-
const
|
|
65
|
+
const resolved = resolveIamClientId(options);
|
|
66
|
+
if (resolved.error) {
|
|
67
|
+
const err = new Error(resolved.error);
|
|
68
|
+
err.code = resolved.error;
|
|
69
|
+
throw err;
|
|
70
|
+
}
|
|
71
|
+
const clientId = resolved.clientId;
|
|
50
72
|
const redirectUri = clean(options.redirectUri);
|
|
51
73
|
const state = clean(options.state);
|
|
52
74
|
const codeChallenge = clean(options.codeChallenge);
|
|
53
|
-
const scope = clean(options.scope ??
|
|
75
|
+
const scope = clean(options.scope ?? AGENTSAM_OAUTH_SCOPE);
|
|
54
76
|
if (!redirectUri || !state || !codeChallenge) throw new Error('oauth_authorization_parameters_required');
|
|
55
77
|
|
|
56
78
|
const url = new URL('/api/oauth/authorize', `${issuer}/`);
|
|
@@ -73,7 +95,6 @@ async function oauthTokenRequest(params, options = {}) {
|
|
|
73
95
|
const normalized = clean(value);
|
|
74
96
|
if (normalized) body.set(key, normalized);
|
|
75
97
|
}
|
|
76
|
-
|
|
77
98
|
const response = await fetchImpl(new URL('/api/oauth/token', `${issuer}/`).toString(), {
|
|
78
99
|
method: 'POST',
|
|
79
100
|
headers: {
|
|
@@ -99,9 +120,15 @@ export async function exchangeAuthorizationCode(options = {}) {
|
|
|
99
120
|
const codeVerifier = clean(options.codeVerifier);
|
|
100
121
|
const redirectUri = clean(options.redirectUri);
|
|
101
122
|
if (!code || !codeVerifier || !redirectUri) throw new Error('oauth_authorization_code_exchange_parameters_required');
|
|
123
|
+
const resolved = resolveIamClientId(options);
|
|
124
|
+
if (resolved.error) {
|
|
125
|
+
const err = new Error(resolved.error);
|
|
126
|
+
err.code = resolved.error;
|
|
127
|
+
throw err;
|
|
128
|
+
}
|
|
102
129
|
return oauthTokenRequest({
|
|
103
130
|
grant_type: 'authorization_code',
|
|
104
|
-
client_id:
|
|
131
|
+
client_id: resolved.clientId,
|
|
105
132
|
redirect_uri: redirectUri,
|
|
106
133
|
code,
|
|
107
134
|
code_verifier: codeVerifier,
|
|
@@ -111,17 +138,25 @@ export async function exchangeAuthorizationCode(options = {}) {
|
|
|
111
138
|
export async function refreshAccountSession(options = {}) {
|
|
112
139
|
const session = options.session || readAccountSession(options);
|
|
113
140
|
if (!session?.refresh_token) throw new Error('browser_oauth_refresh_unavailable');
|
|
114
|
-
const
|
|
141
|
+
const resolved = resolveIamClientId({
|
|
142
|
+
...options,
|
|
143
|
+
clientId: clean(session.client_id) || clean(options.clientId),
|
|
144
|
+
});
|
|
145
|
+
if (resolved.error) {
|
|
146
|
+
const err = new Error(resolved.error);
|
|
147
|
+
err.code = resolved.error;
|
|
148
|
+
throw err;
|
|
149
|
+
}
|
|
115
150
|
const refreshed = await oauthTokenRequest({
|
|
116
151
|
grant_type: 'refresh_token',
|
|
117
|
-
client_id: clientId,
|
|
152
|
+
client_id: resolved.clientId,
|
|
118
153
|
refresh_token: session.refresh_token,
|
|
119
154
|
}, options);
|
|
120
155
|
|
|
121
156
|
return saveAccountSession({
|
|
122
157
|
...refreshed,
|
|
123
158
|
refresh_token: clean(refreshed.refresh_token) || session.refresh_token,
|
|
124
|
-
client_id: clientId,
|
|
159
|
+
client_id: resolved.clientId,
|
|
125
160
|
user_id: session.user_id,
|
|
126
161
|
account_id: session.account_id,
|
|
127
162
|
email: session.email,
|
|
@@ -150,7 +185,7 @@ export async function resolveAccountAuthority(options = {}) {
|
|
|
150
185
|
return {
|
|
151
186
|
value: '',
|
|
152
187
|
source: 'agentsam_browser_oauth',
|
|
153
|
-
kind: '
|
|
188
|
+
kind: 'agentsam_browser_oauth',
|
|
154
189
|
session,
|
|
155
190
|
error: 'browser_oauth_session_expired',
|
|
156
191
|
};
|
|
@@ -162,7 +197,7 @@ export async function resolveAccountAuthority(options = {}) {
|
|
|
162
197
|
return {
|
|
163
198
|
value: '',
|
|
164
199
|
source: 'agentsam_browser_oauth',
|
|
165
|
-
kind: '
|
|
200
|
+
kind: 'agentsam_browser_oauth',
|
|
166
201
|
session,
|
|
167
202
|
error: `browser_oauth_refresh_failed: ${error?.message || String(error)}`,
|
|
168
203
|
};
|
|
@@ -172,7 +207,7 @@ export async function resolveAccountAuthority(options = {}) {
|
|
|
172
207
|
return {
|
|
173
208
|
value: session.access_token,
|
|
174
209
|
source: 'agentsam_browser_oauth',
|
|
175
|
-
kind: '
|
|
210
|
+
kind: 'agentsam_browser_oauth',
|
|
176
211
|
session,
|
|
177
212
|
fallback_error: apiKey.error || null,
|
|
178
213
|
};
|
|
@@ -201,6 +236,13 @@ export async function createLoopbackCallbackListener(options = {}) {
|
|
|
201
236
|
|
|
202
237
|
const server = createServerImpl((req, res) => {
|
|
203
238
|
try {
|
|
239
|
+
const method = String(req.method || 'GET').toUpperCase();
|
|
240
|
+
if (method !== 'GET' && method !== 'HEAD') {
|
|
241
|
+
res.writeHead(405, { 'Content-Type': 'text/plain; charset=utf-8', Allow: 'GET' });
|
|
242
|
+
res.end('Method not allowed');
|
|
243
|
+
return;
|
|
244
|
+
}
|
|
245
|
+
|
|
204
246
|
const requestUrl = new URL(req.url || '/', `http://${host}`);
|
|
205
247
|
if (requestUrl.pathname !== callbackPath) {
|
|
206
248
|
res.writeHead(404, { 'Content-Type': 'text/plain; charset=utf-8' });
|
|
@@ -212,6 +254,7 @@ export async function createLoopbackCallbackListener(options = {}) {
|
|
|
212
254
|
const oauthError = clean(requestUrl.searchParams.get('error'));
|
|
213
255
|
const oauthDescription = clean(requestUrl.searchParams.get('error_description'));
|
|
214
256
|
const code = clean(requestUrl.searchParams.get('code'));
|
|
257
|
+
const pickup = clean(requestUrl.searchParams.get('pickup'));
|
|
215
258
|
|
|
216
259
|
if (!returnedState || returnedState !== expectedState) {
|
|
217
260
|
res.writeHead(400, { 'Content-Type': 'text/plain; charset=utf-8' });
|
|
@@ -225,16 +268,25 @@ export async function createLoopbackCallbackListener(options = {}) {
|
|
|
225
268
|
settle(new Error(oauthDescription ? `${oauthError}: ${oauthDescription}` : oauthError));
|
|
226
269
|
return;
|
|
227
270
|
}
|
|
271
|
+
// Studio Web-brokered CLI cloud login returns pickup= instead of Google code=.
|
|
272
|
+
if (pickup) {
|
|
273
|
+
settle(null, { pickup, state: returnedState, mode: 'studio_pickup' });
|
|
274
|
+
res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
|
|
275
|
+
res.end('<!doctype html><html><body style="font-family:system-ui"><h1>Agent Sam</h1><p>Authentication complete. You can close this tab and return to your terminal.</p></body></html>');
|
|
276
|
+
return;
|
|
277
|
+
}
|
|
228
278
|
if (!code) {
|
|
279
|
+
// Ignore probe/prefetch hits with no code so a later real redirect can settle.
|
|
229
280
|
res.writeHead(400, { 'Content-Type': 'text/plain; charset=utf-8' });
|
|
230
281
|
res.end('Authorization code missing. Return to the terminal and retry.');
|
|
231
|
-
settle(new Error('oauth_authorization_code_missing'));
|
|
232
282
|
return;
|
|
233
283
|
}
|
|
234
284
|
|
|
285
|
+
// Settle before writing the body so the CLI continues even if the client
|
|
286
|
+
// disconnects mid-response (common with some browsers closing the tab).
|
|
287
|
+
settle(null, { code, state: returnedState, mode: 'google_code' });
|
|
235
288
|
res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
|
|
236
289
|
res.end('<!doctype html><html><body style="font-family:system-ui"><h1>Agent Sam</h1><p>Authentication complete. You can close this tab and return to your terminal.</p></body></html>');
|
|
237
|
-
settle(null, { code, state: returnedState });
|
|
238
290
|
} catch (error) {
|
|
239
291
|
try {
|
|
240
292
|
res.writeHead(500, { 'Content-Type': 'text/plain; charset=utf-8' });
|
|
@@ -279,7 +331,21 @@ export async function createLoopbackCallbackListener(options = {}) {
|
|
|
279
331
|
|
|
280
332
|
export async function authenticateViaBrowser(options = {}) {
|
|
281
333
|
const env = options.env || process.env;
|
|
282
|
-
const
|
|
334
|
+
const resolved = resolveIamClientId(options);
|
|
335
|
+
if (resolved.error) {
|
|
336
|
+
const err = new Error(
|
|
337
|
+
'IAM OAuth is not configured. AgentSam CLI uses the public PKCE client '
|
|
338
|
+
+ `${DEFAULT_AGENTSAM_IAM_CLIENT_ID}. Set AGENTSAM_NATIVE_OAUTH_CLIENT_ID only to override that registered native client. `
|
|
339
|
+
+ 'Do not use IAM_CLIENT_ID/IAM_CLIENT_SECRET for CLI authentication.',
|
|
340
|
+
);
|
|
341
|
+
err.code = 'iam_oauth_not_configured';
|
|
342
|
+
throw err;
|
|
343
|
+
}
|
|
344
|
+
const clientId = resolved.clientId;
|
|
345
|
+
// Native login always enters through the canonical IAM portal. Google or other
|
|
346
|
+
// login methods may be offered by IAM itself; provider grants are not CLI sessions.
|
|
347
|
+
const issuer = resolveIamIssuer(env, options.issuer || '');
|
|
348
|
+
|
|
283
349
|
const state = randomUrlSafe(24, options.randomBytesImpl || randomBytes);
|
|
284
350
|
const pkce = createPkcePair({ randomBytesImpl: options.randomBytesImpl });
|
|
285
351
|
const listener = await createLoopbackCallbackListener({
|
|
@@ -302,10 +368,17 @@ export async function authenticateViaBrowser(options = {}) {
|
|
|
302
368
|
scope: options.scope,
|
|
303
369
|
});
|
|
304
370
|
|
|
371
|
+
// Gate through IAM /auth/login; authorize URL preserved in `next`.
|
|
372
|
+
const authorizePath = authorizationUrl.startsWith(issuer)
|
|
373
|
+
? authorizationUrl.slice(issuer.length)
|
|
374
|
+
: authorizationUrl.replace(/^https?:\/\/[^/]+/, '');
|
|
375
|
+
const loginGateUrl = new URL('/auth/login', `${issuer}/`);
|
|
376
|
+
loginGateUrl.searchParams.set('next', authorizePath.startsWith('/') ? authorizePath : `/${authorizePath}`);
|
|
377
|
+
|
|
305
378
|
const promptImpl = options.promptToOpenUrlImpl || promptToOpenUrl;
|
|
306
|
-
await promptImpl(
|
|
307
|
-
heading: 'Authenticate your
|
|
308
|
-
prompt: 'Press ENTER to open
|
|
379
|
+
await promptImpl(loginGateUrl.toString(), {
|
|
380
|
+
heading: 'Authenticate your Inner Animal Media account at:',
|
|
381
|
+
prompt: 'Press ENTER to open Inner Animal Media sign-in in your browser.',
|
|
309
382
|
input: options.input,
|
|
310
383
|
output: options.output,
|
|
311
384
|
openImpl: options.openImpl,
|
package/src/lib/core-client.js
CHANGED
|
@@ -1,15 +1,14 @@
|
|
|
1
|
-
import { resolveIamOrigin } from '../../packages/identity/src/contracts/auth-config.js';
|
|
2
1
|
import { resolveAccountAuthority } from './auth.js';
|
|
2
|
+
import { resolvePlatformAccountIssuer } from './app-authority.js';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* IAM CORE client — SDK is a delivery mechanism; intelligence lives server-side.
|
|
6
6
|
*
|
|
7
|
-
* IAM_OAUTH_ISSUER
|
|
8
|
-
*
|
|
7
|
+
* PLATFORM namespace: IAM_OAUTH_ISSUER (account API). Falls back to platform default
|
|
8
|
+
* via resolvePlatformAccountIssuer — never aliases Local Studio APP HOST.
|
|
9
9
|
*/
|
|
10
10
|
export function coreBaseUrl(env = process.env) {
|
|
11
|
-
|
|
12
|
-
return resolveIamOrigin(env, explicit);
|
|
11
|
+
return resolvePlatformAccountIssuer(env);
|
|
13
12
|
}
|
|
14
13
|
|
|
15
14
|
function authOptions(options) {
|
|
@@ -49,7 +48,7 @@ async function authorizedFetch(url, init, options = {}) {
|
|
|
49
48
|
const baseHeaders = init.headers || {};
|
|
50
49
|
let resolved = await authorizedHeaders(baseHeaders, options);
|
|
51
50
|
let response = await (options.fetchImpl || fetch)(url, { ...init, headers: resolved.headers });
|
|
52
|
-
if (response.status === 401 && resolved.authority?.kind
|
|
51
|
+
if (response.status === 401 && ['browser_oauth', 'agentsam_browser_oauth'].includes(resolved.authority?.kind) && options.forceRefresh !== true) {
|
|
53
52
|
resolved = await authorizedHeaders(baseHeaders, { ...options, forceRefresh: true });
|
|
54
53
|
response = await (options.fetchImpl || fetch)(url, { ...init, headers: resolved.headers });
|
|
55
54
|
}
|