@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
|
@@ -1,21 +1,116 @@
|
|
|
1
1
|
# @inneranimalmedia/agentsam-sdk-brand
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
**Brand compiler** — not just an image optimizer CLI.
|
|
4
4
|
|
|
5
5
|
```text
|
|
6
|
-
|
|
6
|
+
drop anything → ingest/classify → brand.pack.json (source of truth)
|
|
7
|
+
│
|
|
8
|
+
┌─────────────────┼─────────────────┐
|
|
9
|
+
▼ ▼ ▼
|
|
10
|
+
localhost studio ZIP export production publish
|
|
7
11
|
```
|
|
8
12
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
+
## BrandPack v2
|
|
14
|
+
|
|
15
|
+
`brand.pack.json` owns:
|
|
16
|
+
|
|
17
|
+
| Graph node | Purpose |
|
|
18
|
+
|---|---|
|
|
19
|
+
| `assets[]` | Role-tagged masters + semantic derivatives |
|
|
20
|
+
| `tokens` | color / type / space / radius / motion |
|
|
21
|
+
| `rules` | logo clearspace, forbidden ops, template requirements |
|
|
22
|
+
| `provenance` | source → transforms → sha256 |
|
|
23
|
+
| `delivery` | Images / Stream / R2 policy (`role_canonical`) |
|
|
24
|
+
|
|
25
|
+
ZIP, `studio.html`, CSS tokens, icons, and CF uploads are **compiled representations**.
|
|
26
|
+
|
|
27
|
+
### CLI
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
# Ingest folder, previous build zip/tar/gz, or HTML/CSS for token extraction
|
|
31
|
+
agentsam brand ingest ./exports --brand acme --template product-saas
|
|
32
|
+
|
|
33
|
+
# Compile dist + studio + zip export
|
|
34
|
+
agentsam brand build --from .agentsam/brand/packs/acme
|
|
35
|
+
|
|
36
|
+
# Preview studio (prefers studio.html)
|
|
37
|
+
agentsam brand preview --from .agentsam/brand/dist/acme
|
|
38
|
+
|
|
39
|
+
agentsam brand templates
|
|
40
|
+
agentsam brand roles
|
|
41
|
+
agentsam brand presets
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### Asset roles (examples)
|
|
45
|
+
|
|
46
|
+
`logo.primary` · `favicon` · `icon.app` · `hero.landscape` · `social.og` · `product.raw` · `motion.hero` · `model.product` · `type.body` · `token.color`
|
|
47
|
+
|
|
48
|
+
A 512px logo and a 512px app icon are **different assets**.
|
|
49
|
+
|
|
50
|
+
### Semantic derivatives
|
|
51
|
+
|
|
52
|
+
- **DERIVABLE** — system knows how to make it (often on-demand via Cloudflare Images)
|
|
53
|
+
- **MATERIALIZED** — file included in this pack export
|
|
54
|
+
|
|
55
|
+
Shared responsive ladder: `320…2560` — roles pick a subset. Logos get raster fallbacks (256/512/1024), not a giant ladder.
|
|
56
|
+
|
|
57
|
+
### Format families
|
|
58
|
+
|
|
59
|
+
Logo/vector, raster, photography, favicon, app-icon, social, video, motion-graphics, 3D, fonts (licensing gate), tokens, theme, docs, archives (zip/tar/gz containers).
|
|
60
|
+
|
|
61
|
+
Fonts default to `licensing.redistributable: false` — never dumped into client ZIPs until confirmed.
|
|
62
|
+
|
|
63
|
+
### Templates
|
|
64
|
+
|
|
65
|
+
`web-app` · `mobile-app` · `marketing-site` · `product-saas` · `spatial-3d`
|
|
66
|
+
|
|
67
|
+
### V1 still works
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
agentsam brand pack --brand acme --asset app-icon --source ./master.png --preset app-icon --out ./acme.zip
|
|
71
|
+
agentsam brand promote --brand acme --asset logo --source - --preset logo
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Delivery policy id: **`canonical_png`** / per-role **`role_canonical`**. Prefer high-quality masters; let Cloudflare Images negotiate AVIF/WebP.
|
|
75
|
+
|
|
76
|
+
No product brand defaults (`agentsam` as brand id is rejected in the wizard).
|
|
77
|
+
|
|
78
|
+
## Image / media processors (pluggable)
|
|
79
|
+
|
|
80
|
+
**Do not** depend on abandoned `@squoosh/cli` (npm 0.7.3 — Node 12–16 only; crashes on Node 22+).
|
|
81
|
+
|
|
82
|
+
Public UX:
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
agentsam brand optimize ./hero.png --role hero.landscape --target web
|
|
86
|
+
agentsam brand optimize ./logo.png --role logo.primary --processor sharp
|
|
87
|
+
agentsam brand processors # sharp | squoosh (binary) | native | cloudflare
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
Internally:
|
|
91
|
+
|
|
92
|
+
```text
|
|
93
|
+
Asset Pipeline
|
|
94
|
+
├── sharp ← dependable Node path
|
|
95
|
+
├── squoosh ← maintained Homebrew/Scoop binary (optional)
|
|
96
|
+
├── native ← ImageMagick
|
|
97
|
+
├── cloudflare ← edge DERIVABLE (retain master)
|
|
98
|
+
├── wasm / go ← Studio preview / heavy queued jobs (scheduler hooks)
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Role-aware policies choose formats (logo → lossless/SVG path; hero → AVIF+WebP; screenshots → sharper WebP). Semantic delivery names (`acme-showroom-hero-1280.avif`) are aliases — `asset.id` stays the machine identity. Cloudflare custom metadata / R2 `customMetadata` / BrandPack own SEO+provenance — not EXIF alone.
|
|
102
|
+
|
|
103
|
+
## Website composition (sibling package)
|
|
104
|
+
|
|
105
|
+
BrandPack owns **what the brand is**. Page experiences live in **`@inneranimalmedia/theme-scenes`**:
|
|
106
|
+
|
|
107
|
+
- `SECTION_CONTENT` → scene kinds (hero, bridge, product.demo, gallery, …)
|
|
108
|
+
- Route refs + asset roles (no hardcoded CDN / nav URLs in scenes)
|
|
109
|
+
- Demo adapters (`agentsam-mini-composer`, `database-editor`) — real product surfaces, not fake Meaux cards
|
|
110
|
+
- Themes: `foundation` → `inneranimal` → `agentsam` / `autodidact`
|
|
13
111
|
|
|
14
112
|
```bash
|
|
15
|
-
|
|
16
|
-
agentsam brand resolve
|
|
17
|
-
agentsam plan brand --goap
|
|
18
|
-
agentsam brand --write # writes .agentsam/brand/{evidence,resolved,contract}.json
|
|
113
|
+
npm --prefix packages/theme-scenes test
|
|
19
114
|
```
|
|
20
115
|
|
|
21
|
-
|
|
116
|
+
See `packages/theme-scenes/README.md`. Studio shell (Moon Glass → Brand Studio) sits above both packages in a later tranche.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { runBrandAssetCommand, runBrandPromoteWizard } from '../src/index.js';
|
|
3
|
+
import { cancel, confirm, intro, isCancel, note, outro, select, text } from '@clack/prompts';
|
|
4
|
+
|
|
5
|
+
const code = await runBrandAssetCommand(process.argv.slice(2), {
|
|
6
|
+
runWizard: runBrandPromoteWizard,
|
|
7
|
+
prompts: { intro, outro, cancel, isCancel, select, text, confirm, note },
|
|
8
|
+
});
|
|
9
|
+
process.exitCode = typeof code === 'number' ? code : 0;
|
|
@@ -1,22 +1,54 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@inneranimalmedia/agentsam-sdk-brand",
|
|
3
3
|
"version": "0.1.0",
|
|
4
|
-
"
|
|
4
|
+
"description": "Deterministic Brand Intelligence + portable brand-asset promotion SDK for AgentSam (inspect, derive, plan, promote, publish, verify).",
|
|
5
5
|
"type": "module",
|
|
6
|
-
"
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"engines": {
|
|
8
|
+
"node": ">=22 <25"
|
|
9
|
+
},
|
|
10
|
+
"dependencies": {
|
|
11
|
+
"sharp": "^0.34.5"
|
|
12
|
+
},
|
|
7
13
|
"main": "./src/index.js",
|
|
14
|
+
"bin": {
|
|
15
|
+
"agentsam-brand": "./bin/agentsam-brand.mjs"
|
|
16
|
+
},
|
|
8
17
|
"exports": {
|
|
9
18
|
".": "./src/index.js",
|
|
10
19
|
"./scan": "./src/scan.js",
|
|
11
20
|
"./resolve": "./src/resolve.js",
|
|
12
21
|
"./contract": "./src/contract.js",
|
|
13
22
|
"./plan": "./src/plan.js",
|
|
14
|
-
"./goap-actions": "./src/goap-actions.js"
|
|
23
|
+
"./goap-actions": "./src/goap-actions.js",
|
|
24
|
+
"./assets": "./src/index.js",
|
|
25
|
+
"./presets": "./src/presets/index.js",
|
|
26
|
+
"./cli": "./src/cli/controller.js",
|
|
27
|
+
"./package.json": "./package.json"
|
|
15
28
|
},
|
|
29
|
+
"files": [
|
|
30
|
+
"bin",
|
|
31
|
+
"src",
|
|
32
|
+
"README.md"
|
|
33
|
+
],
|
|
16
34
|
"scripts": {
|
|
17
|
-
"test": "node --test test/*.test.mjs"
|
|
35
|
+
"test": "node --test test/*.test.mjs",
|
|
36
|
+
"pack:dry": "npm pack --dry-run"
|
|
18
37
|
},
|
|
19
|
-
"
|
|
20
|
-
"
|
|
21
|
-
|
|
38
|
+
"repository": {
|
|
39
|
+
"type": "git",
|
|
40
|
+
"url": "git+https://github.com/SamPrimeaux/agentsam-sdk.git",
|
|
41
|
+
"directory": "packages/agentsam-brand"
|
|
42
|
+
},
|
|
43
|
+
"publishConfig": {
|
|
44
|
+
"access": "restricted"
|
|
45
|
+
},
|
|
46
|
+
"keywords": [
|
|
47
|
+
"agentsam",
|
|
48
|
+
"brand",
|
|
49
|
+
"assets",
|
|
50
|
+
"promotion",
|
|
51
|
+
"r2",
|
|
52
|
+
"images"
|
|
53
|
+
]
|
|
22
54
|
}
|
|
@@ -0,0 +1,453 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cloudflare Images delivery adapter.
|
|
3
|
+
*
|
|
4
|
+
* Prefer shared transport `@inneranimalmedia/agentsam-cloudflare-images` for
|
|
5
|
+
* credentials, delivery URLs, and HTTP. This Brand adapter retains BrandPack
|
|
6
|
+
* publish policy (canonical PNG) and will thin-wrap the shared package next.
|
|
7
|
+
*
|
|
8
|
+
* HARD RULE: An asset is "on Cloudflare Images" ONLY when POST
|
|
9
|
+
* /accounts/{account_id}/images/v1 returns success + non-empty result.id.
|
|
10
|
+
*
|
|
11
|
+
* Account-level identity (never infer from R2):
|
|
12
|
+
* CLOUDFLARE_ACCOUNT_ID — management/API identity (non-secret)
|
|
13
|
+
* CLOUDFLARE_IMAGES_ACCOUNT_HASH — delivery namespace (non-secret)
|
|
14
|
+
* CLOUDFLARE_IMAGES_API_TOKEN — secret Bearer credential (canonical)
|
|
15
|
+
* CLOUDFLARE_API_TOKEN — broader compatibility fallback
|
|
16
|
+
*
|
|
17
|
+
* R2 keys, WEBSITE_ASSETS bindings, and D1 rows are never evidence of Images.
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
/** Cloudflare-hosted Images accepts these inputs (plan-dependent for some). */
|
|
21
|
+
export const CLOUDFLARE_IMAGES_PLATFORM_INPUT_TYPES = Object.freeze([
|
|
22
|
+
'image/png',
|
|
23
|
+
'image/jpeg',
|
|
24
|
+
'image/gif',
|
|
25
|
+
'image/webp',
|
|
26
|
+
'image/svg+xml',
|
|
27
|
+
'image/heic',
|
|
28
|
+
'image/avif',
|
|
29
|
+
]);
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Canonical PNG publishing policy (not a Cloudflare limitation):
|
|
33
|
+
* prefer a canonical PNG as the Images delivery source so CF can negotiate
|
|
34
|
+
* WebP/AVIF output. Explicit WebP/AVIF/SVG archives stay in storage (R2).
|
|
35
|
+
*/
|
|
36
|
+
export const CANONICAL_PNG_DELIVERY_POLICY_TYPES = Object.freeze(['image/png']);
|
|
37
|
+
|
|
38
|
+
/** @deprecated Use CANONICAL_PNG_DELIVERY_POLICY_TYPES */
|
|
39
|
+
export const AGENTSAM_IMAGES_DELIVERY_POLICY_TYPES = CANONICAL_PNG_DELIVERY_POLICY_TYPES;
|
|
40
|
+
|
|
41
|
+
export function resolveCloudflareImagesCredentials(env = process.env) {
|
|
42
|
+
const accountId = String(env.CLOUDFLARE_ACCOUNT_ID || '').trim();
|
|
43
|
+
const accountHash = String(env.CLOUDFLARE_IMAGES_ACCOUNT_HASH || '').trim();
|
|
44
|
+
// Canonical least-privilege token first; broader session token as fallback.
|
|
45
|
+
// CLOUDFLARE_IMAGES_TOKEN retained as deprecated alias only.
|
|
46
|
+
const tokenSource = env.CLOUDFLARE_IMAGES_API_TOKEN
|
|
47
|
+
? 'CLOUDFLARE_IMAGES_API_TOKEN'
|
|
48
|
+
: env.CLOUDFLARE_API_TOKEN
|
|
49
|
+
? 'CLOUDFLARE_API_TOKEN'
|
|
50
|
+
: env.CLOUDFLARE_IMAGES_TOKEN
|
|
51
|
+
? 'CLOUDFLARE_IMAGES_TOKEN'
|
|
52
|
+
: null;
|
|
53
|
+
const apiToken = tokenSource ? String(env[tokenSource] || '').trim() : '';
|
|
54
|
+
return {
|
|
55
|
+
accountId,
|
|
56
|
+
accountHash,
|
|
57
|
+
apiToken,
|
|
58
|
+
tokenEnv: tokenSource,
|
|
59
|
+
// Opaque credential — never validate by shape/prefix (cfat_ or otherwise)
|
|
60
|
+
tokenConfigured: Boolean(apiToken),
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/** Public delivery base — derived from account hash, not independently configured. */
|
|
65
|
+
export function cloudflareImagesDeliveryBase(accountHash) {
|
|
66
|
+
const hash = String(accountHash || '').trim();
|
|
67
|
+
if (!hash) return null;
|
|
68
|
+
return `https://imagedelivery.net/${hash}`;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Construct a delivery URL only from verified Images identity.
|
|
73
|
+
* Prefer Cloudflare-returned variants[] over reconstruction when available.
|
|
74
|
+
*/
|
|
75
|
+
export function cloudflareImageUrl({ accountHash, imageId, variant = 'public' } = {}) {
|
|
76
|
+
const hash = String(accountHash || '').trim();
|
|
77
|
+
const id = String(imageId || '').trim();
|
|
78
|
+
const v = String(variant || 'public').trim() || 'public';
|
|
79
|
+
if (!hash || !id) return null;
|
|
80
|
+
return `https://imagedelivery.net/${hash}/${id}/${v}`;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export function resolveCloudflareImagesConfig(env = process.env) {
|
|
84
|
+
const creds = resolveCloudflareImagesCredentials(env);
|
|
85
|
+
const deliveryBase = cloudflareImagesDeliveryBase(creds.accountHash);
|
|
86
|
+
return {
|
|
87
|
+
provider: 'cloudflare-images',
|
|
88
|
+
accountId: creds.accountId || null,
|
|
89
|
+
accountHash: creds.accountHash || null,
|
|
90
|
+
deliveryBase,
|
|
91
|
+
apiTokenConfigured: creds.tokenConfigured,
|
|
92
|
+
tokenEnv: creds.tokenEnv,
|
|
93
|
+
authMode: 'bearer_api_token',
|
|
94
|
+
requiredPermission: 'Account → Images → Write',
|
|
95
|
+
apiUploadPath: '/accounts/{account_id}/images/v1',
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export class CloudflareImagesDeliveryAdapter {
|
|
100
|
+
constructor({
|
|
101
|
+
accountId,
|
|
102
|
+
accountHash,
|
|
103
|
+
apiToken,
|
|
104
|
+
env = process.env,
|
|
105
|
+
/**
|
|
106
|
+
* Default: canonical PNG-only delivery source.
|
|
107
|
+
* Pass CLOUDFLARE_IMAGES_PLATFORM_INPUT_TYPES to allow full CF input set.
|
|
108
|
+
*/
|
|
109
|
+
acceptedContentTypes = [...CANONICAL_PNG_DELIVERY_POLICY_TYPES],
|
|
110
|
+
fetchImpl = globalThis.fetch,
|
|
111
|
+
} = {}) {
|
|
112
|
+
const resolved = resolveCloudflareImagesCredentials(env);
|
|
113
|
+
this.provider = 'cloudflare-images';
|
|
114
|
+
this.accountId = String(accountId ?? resolved.accountId ?? '').trim();
|
|
115
|
+
this.accountHash = String(accountHash ?? resolved.accountHash ?? '').trim();
|
|
116
|
+
this.apiToken = String(apiToken ?? resolved.apiToken ?? '').trim();
|
|
117
|
+
this.tokenEnv = apiToken
|
|
118
|
+
? 'constructor'
|
|
119
|
+
: resolved.tokenEnv;
|
|
120
|
+
this.acceptedContentTypes = new Set(acceptedContentTypes);
|
|
121
|
+
this.policy = 'canonical_png';
|
|
122
|
+
this.fetchImpl = fetchImpl;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
get deliveryBase() {
|
|
126
|
+
return cloudflareImagesDeliveryBase(this.accountHash);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
authHeaders() {
|
|
130
|
+
return { Authorization: `Bearer ${this.apiToken}` };
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Capability snapshot. `authorized` stays false until verifyConnection() succeeds.
|
|
135
|
+
*/
|
|
136
|
+
async capabilities() {
|
|
137
|
+
const configured = Boolean(this.accountId && this.apiToken);
|
|
138
|
+
return {
|
|
139
|
+
provider: this.provider,
|
|
140
|
+
available: true,
|
|
141
|
+
configured,
|
|
142
|
+
authorized: false,
|
|
143
|
+
account_resolved: Boolean(this.accountId),
|
|
144
|
+
account_hash_resolved: Boolean(this.accountHash),
|
|
145
|
+
delivery_base: this.deliveryBase,
|
|
146
|
+
token_env: this.tokenEnv,
|
|
147
|
+
auth_mode: 'bearer_api_token',
|
|
148
|
+
required_permission: 'Account → Images → Write',
|
|
149
|
+
api_path: '/accounts/{account_id}/images/v1',
|
|
150
|
+
// Policy vs platform — do not conflate
|
|
151
|
+
delivery_policy_types: [...CANONICAL_PNG_DELIVERY_POLICY_TYPES],
|
|
152
|
+
/** @deprecated alias */
|
|
153
|
+
agentsam_delivery_policy_types: [...CANONICAL_PNG_DELIVERY_POLICY_TYPES],
|
|
154
|
+
cloudflare_platform_input_types: [...CLOUDFLARE_IMAGES_PLATFORM_INPUT_TYPES],
|
|
155
|
+
accepted_content_types: [...this.acceptedContentTypes],
|
|
156
|
+
policy: this.policy,
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Live verify against Cloudflare Images API (stats).
|
|
162
|
+
* Env presence alone is never proof of authorization.
|
|
163
|
+
*/
|
|
164
|
+
async verifyConnection() {
|
|
165
|
+
const config = {
|
|
166
|
+
account_id: this.accountId || null,
|
|
167
|
+
account_hash: this.accountHash || null,
|
|
168
|
+
delivery_base: this.deliveryBase,
|
|
169
|
+
token_env: this.tokenEnv,
|
|
170
|
+
auth_mode: 'bearer_api_token',
|
|
171
|
+
required_permission: 'Account → Images → Write',
|
|
172
|
+
};
|
|
173
|
+
|
|
174
|
+
if (!this.accountId || !this.apiToken) {
|
|
175
|
+
return {
|
|
176
|
+
ok: false,
|
|
177
|
+
provider: this.provider,
|
|
178
|
+
configured: false,
|
|
179
|
+
authorized: false,
|
|
180
|
+
reason: 'not_configured',
|
|
181
|
+
error: 'cloudflare_images_credentials_required',
|
|
182
|
+
hint: 'Set CLOUDFLARE_ACCOUNT_ID + CLOUDFLARE_IMAGES_API_TOKEN (Images Write)',
|
|
183
|
+
config,
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
const url = `https://api.cloudflare.com/client/v4/accounts/${this.accountId}/images/v1/stats`;
|
|
188
|
+
let res;
|
|
189
|
+
let body;
|
|
190
|
+
try {
|
|
191
|
+
res = await this.fetchImpl(url, {
|
|
192
|
+
method: 'GET',
|
|
193
|
+
headers: this.authHeaders(),
|
|
194
|
+
});
|
|
195
|
+
body = await res.json().catch(() => ({}));
|
|
196
|
+
} catch (err) {
|
|
197
|
+
return {
|
|
198
|
+
ok: false,
|
|
199
|
+
provider: this.provider,
|
|
200
|
+
configured: true,
|
|
201
|
+
authorized: false,
|
|
202
|
+
reason: 'network_error',
|
|
203
|
+
error: String(err?.message || err),
|
|
204
|
+
config,
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
const authorized = Boolean(res.ok && body?.success !== false);
|
|
209
|
+
return {
|
|
210
|
+
ok: authorized,
|
|
211
|
+
provider: this.provider,
|
|
212
|
+
configured: true,
|
|
213
|
+
authorized,
|
|
214
|
+
reason: authorized ? 'verified' : 'api_unauthorized',
|
|
215
|
+
error: authorized
|
|
216
|
+
? null
|
|
217
|
+
: (body?.errors?.[0]?.message || `cf_images_verify_failed:${res.status}`),
|
|
218
|
+
http_status: res.status,
|
|
219
|
+
stats: authorized ? (body?.result || null) : null,
|
|
220
|
+
config: {
|
|
221
|
+
...config,
|
|
222
|
+
// Mirror Local Studio / dashboard vocabulary
|
|
223
|
+
authentication: 'API token',
|
|
224
|
+
permission: authorized ? 'Images Write ✓' : 'Images Write unverified',
|
|
225
|
+
},
|
|
226
|
+
};
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
async supports({ contentType } = {}) {
|
|
230
|
+
const mime = String(contentType || '').toLowerCase();
|
|
231
|
+
return this.acceptedContentTypes.has(mime);
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* @returns {Promise<{
|
|
236
|
+
* ok: boolean,
|
|
237
|
+
* provider: 'cloudflare-images',
|
|
238
|
+
* status: 'planned'|'published'|'failed'|'skipped',
|
|
239
|
+
* provider_receipt?: object,
|
|
240
|
+
* error?: string,
|
|
241
|
+
* }>}
|
|
242
|
+
*/
|
|
243
|
+
async upload({
|
|
244
|
+
filePath,
|
|
245
|
+
fileName,
|
|
246
|
+
contentType = 'image/png',
|
|
247
|
+
metadata = {},
|
|
248
|
+
dryRun = false,
|
|
249
|
+
sourceSha256 = null,
|
|
250
|
+
sourceStorage = null,
|
|
251
|
+
} = {}) {
|
|
252
|
+
const mime = String(contentType || metadata.contentType || 'image/png').toLowerCase();
|
|
253
|
+
if (!(await this.supports({ contentType: mime }))) {
|
|
254
|
+
return {
|
|
255
|
+
ok: true,
|
|
256
|
+
provider: this.provider,
|
|
257
|
+
status: 'skipped',
|
|
258
|
+
reason: 'canonical_png_delivery_policy',
|
|
259
|
+
content_type: mime,
|
|
260
|
+
note: 'Canonical PNG policy: prefer PNG as Images delivery source; other formats remain storage-only. Cloudflare itself accepts broader inputs.',
|
|
261
|
+
};
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
if (dryRun) {
|
|
265
|
+
return {
|
|
266
|
+
ok: true,
|
|
267
|
+
provider: this.provider,
|
|
268
|
+
status: 'planned',
|
|
269
|
+
dry_run: true,
|
|
270
|
+
provider_receipt: null,
|
|
271
|
+
account_id: this.accountId || null,
|
|
272
|
+
account_hash: this.accountHash || null,
|
|
273
|
+
source: sourceStorage || null,
|
|
274
|
+
};
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
if (!this.accountId || !this.apiToken) {
|
|
278
|
+
return {
|
|
279
|
+
ok: false,
|
|
280
|
+
provider: this.provider,
|
|
281
|
+
status: 'failed',
|
|
282
|
+
error: 'cloudflare_images_credentials_required',
|
|
283
|
+
reason: 'not_configured',
|
|
284
|
+
};
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
const fs = await import('node:fs');
|
|
288
|
+
const form = new FormData();
|
|
289
|
+
const buf = fs.readFileSync(filePath);
|
|
290
|
+
form.append('file', new Blob([buf], { type: mime }), fileName || 'image.png');
|
|
291
|
+
const metaPayload = {
|
|
292
|
+
...metadata,
|
|
293
|
+
...(sourceSha256 ? { source_sha256: String(sourceSha256).replace(/^sha256:/, '') } : {}),
|
|
294
|
+
};
|
|
295
|
+
if (Object.keys(metaPayload).length) {
|
|
296
|
+
form.append('metadata', JSON.stringify(metaPayload));
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
const url = `https://api.cloudflare.com/client/v4/accounts/${this.accountId}/images/v1`;
|
|
300
|
+
let res;
|
|
301
|
+
let body;
|
|
302
|
+
try {
|
|
303
|
+
res = await this.fetchImpl(url, {
|
|
304
|
+
method: 'POST',
|
|
305
|
+
headers: this.authHeaders(),
|
|
306
|
+
body: form,
|
|
307
|
+
});
|
|
308
|
+
body = await res.json().catch(() => ({}));
|
|
309
|
+
} catch (err) {
|
|
310
|
+
return {
|
|
311
|
+
ok: false,
|
|
312
|
+
provider: this.provider,
|
|
313
|
+
status: 'failed',
|
|
314
|
+
error: String(err?.message || err),
|
|
315
|
+
reason: 'network_error',
|
|
316
|
+
};
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
const imageId = body?.result?.id ? String(body.result.id).trim() : '';
|
|
320
|
+
const errCode = body?.errors?.[0]?.code;
|
|
321
|
+
const errMsg = body?.errors?.[0]?.message || '';
|
|
322
|
+
// Idempotent: CF Images 5409 Resource already exists — treat as skip, not fatal
|
|
323
|
+
if (errCode === 5409 || /already exists/i.test(errMsg)) {
|
|
324
|
+
const existingId = String(metadata?.id || metadata?.image_id || fileName || '').trim();
|
|
325
|
+
return {
|
|
326
|
+
ok: true,
|
|
327
|
+
provider: this.provider,
|
|
328
|
+
status: 'exists',
|
|
329
|
+
reason: 'resource_already_exists',
|
|
330
|
+
http_status: res.status,
|
|
331
|
+
error_code: 5409,
|
|
332
|
+
provider_receipt: existingId
|
|
333
|
+
? {
|
|
334
|
+
account_id: this.accountId,
|
|
335
|
+
account_hash: this.accountHash || null,
|
|
336
|
+
delivery_base: this.deliveryBase,
|
|
337
|
+
image_id: existingId,
|
|
338
|
+
provider_asset_id: existingId,
|
|
339
|
+
variants: [],
|
|
340
|
+
note: 'Image id already present in Cloudflare Images; upload skipped',
|
|
341
|
+
}
|
|
342
|
+
: null,
|
|
343
|
+
note: 'Cloudflare Images id already exists (5409). Pass --force with a new --version or delete the remote id.',
|
|
344
|
+
};
|
|
345
|
+
}
|
|
346
|
+
if (!res.ok || body?.success === false || !imageId) {
|
|
347
|
+
return {
|
|
348
|
+
ok: false,
|
|
349
|
+
provider: this.provider,
|
|
350
|
+
status: 'failed',
|
|
351
|
+
error:
|
|
352
|
+
errMsg
|
|
353
|
+
|| (!imageId && res.ok ? 'cloudflare_images_missing_result_id' : `cf_images_upload_failed:${res.status}`),
|
|
354
|
+
reason: !imageId && res.ok ? 'missing_result_id' : 'api_error',
|
|
355
|
+
http_status: res.status,
|
|
356
|
+
error_code: errCode ?? null,
|
|
357
|
+
};
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
const variants = Array.isArray(body.result?.variants) ? body.result.variants : [];
|
|
361
|
+
return {
|
|
362
|
+
ok: true,
|
|
363
|
+
provider: this.provider,
|
|
364
|
+
status: 'published',
|
|
365
|
+
provider_receipt: {
|
|
366
|
+
// Account-level + image-level identity — never from R2
|
|
367
|
+
account_id: this.accountId,
|
|
368
|
+
account_hash: this.accountHash || null,
|
|
369
|
+
delivery_base: this.deliveryBase,
|
|
370
|
+
image_id: imageId,
|
|
371
|
+
provider_asset_id: imageId,
|
|
372
|
+
filename: body.result?.filename || fileName || null,
|
|
373
|
+
// Receipt truth from Cloudflare — prefer over reconstructed URLs
|
|
374
|
+
variants,
|
|
375
|
+
uploaded_at: body.result?.uploaded || null,
|
|
376
|
+
requireSignedURLs: body.result?.requireSignedURLs ?? null,
|
|
377
|
+
source_sha256: sourceSha256 || null,
|
|
378
|
+
// Provenance only — NEVER evidence that Images ≡ R2
|
|
379
|
+
source: sourceStorage
|
|
380
|
+
? {
|
|
381
|
+
storage_provider: sourceStorage.provider || null,
|
|
382
|
+
bucket: sourceStorage.bucket || null,
|
|
383
|
+
key: sourceStorage.key || null,
|
|
384
|
+
}
|
|
385
|
+
: null,
|
|
386
|
+
},
|
|
387
|
+
};
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
/** Fetch one image by id — used by integration verify. */
|
|
391
|
+
async get(imageId) {
|
|
392
|
+
if (!this.accountId || !this.apiToken || !imageId) {
|
|
393
|
+
return { ok: false, error: 'not_configured_or_missing_id' };
|
|
394
|
+
}
|
|
395
|
+
const url = `https://api.cloudflare.com/client/v4/accounts/${this.accountId}/images/v1/${encodeURIComponent(imageId)}`;
|
|
396
|
+
const res = await this.fetchImpl(url, {
|
|
397
|
+
headers: this.authHeaders(),
|
|
398
|
+
});
|
|
399
|
+
const body = await res.json().catch(() => ({}));
|
|
400
|
+
const id = body?.result?.id ? String(body.result.id) : '';
|
|
401
|
+
return {
|
|
402
|
+
ok: Boolean(res.ok && body?.success && id),
|
|
403
|
+
provider: this.provider,
|
|
404
|
+
provider_receipt: id
|
|
405
|
+
? {
|
|
406
|
+
account_id: this.accountId,
|
|
407
|
+
account_hash: this.accountHash || null,
|
|
408
|
+
delivery_base: this.deliveryBase,
|
|
409
|
+
image_id: id,
|
|
410
|
+
provider_asset_id: id,
|
|
411
|
+
variants: body.result?.variants || [],
|
|
412
|
+
filename: body.result?.filename || null,
|
|
413
|
+
uploaded_at: body.result?.uploaded || null,
|
|
414
|
+
}
|
|
415
|
+
: null,
|
|
416
|
+
http_status: res.status,
|
|
417
|
+
};
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
async delete(imageId) {
|
|
421
|
+
if (!this.accountId || !this.apiToken || !imageId) {
|
|
422
|
+
return { ok: false, error: 'not_configured_or_missing_id' };
|
|
423
|
+
}
|
|
424
|
+
const url = `https://api.cloudflare.com/client/v4/accounts/${this.accountId}/images/v1/${encodeURIComponent(imageId)}`;
|
|
425
|
+
const res = await this.fetchImpl(url, {
|
|
426
|
+
method: 'DELETE',
|
|
427
|
+
headers: this.authHeaders(),
|
|
428
|
+
});
|
|
429
|
+
const body = await res.json().catch(() => ({}));
|
|
430
|
+
return { ok: Boolean(res.ok && body?.success !== false), http_status: res.status };
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
/** True only when a real Images publish receipt exists. */
|
|
435
|
+
export function isCloudflareImagesPublished(delivery) {
|
|
436
|
+
if (!delivery || delivery.provider !== 'cloudflare-images') return false;
|
|
437
|
+
if (delivery.status !== 'published') return false;
|
|
438
|
+
const id = delivery.provider_receipt?.provider_asset_id
|
|
439
|
+
|| delivery.provider_receipt?.image_id
|
|
440
|
+
|| delivery.provider_asset_id;
|
|
441
|
+
return Boolean(id && String(id).trim());
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
/**
|
|
445
|
+
* Canonical PNG delivery-source policy.
|
|
446
|
+
* Not a Cloudflare API limitation — CF accepts broader inputs.
|
|
447
|
+
* policy: 'canonical_png' | 'agentsam' (alias) | 'platform'
|
|
448
|
+
*/
|
|
449
|
+
export function mayUploadToCloudflareImages(contentType, { policy = 'canonical_png' } = {}) {
|
|
450
|
+
const mime = String(contentType || '').toLowerCase();
|
|
451
|
+
if (policy === 'platform') return CLOUDFLARE_IMAGES_PLATFORM_INPUT_TYPES.includes(mime);
|
|
452
|
+
return CANONICAL_PNG_DELIVERY_POLICY_TYPES.includes(mime);
|
|
453
|
+
}
|