@inneranimalmedia/agentsam-sdk 2.6.2 → 2.6.3
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 +45 -1
- package/README.md +80 -0
- package/apps/README.md +34 -0
- package/apps/cad-creator/README.md +728 -0
- package/apps/cad-creator/shared/cad/package.json +19 -0
- package/apps/cad-creator/shared/cad/src/domain/operations.ts +7 -0
- package/apps/cad-creator/shared/cad/src/domain/project-contract.d.ts +3 -0
- package/apps/cad-creator/shared/cad/src/domain/project-contract.js +75 -0
- package/apps/cad-creator/shared/cad/src/domain/project-tools.d.ts +1 -0
- package/apps/cad-creator/shared/cad/src/domain/project-tools.js +24 -0
- package/apps/cad-creator/shared/cad/src/domain/validation.ts +191 -0
- package/apps/cad-creator/shared/cad/src/index.ts +4 -0
- package/apps/cad-creator/shared/cad/src/robotics/types.ts +232 -0
- package/apps/cad-creator/shared/cad/src/types.ts +507 -0
- package/apps/cad-creator/shared/cad/tsconfig.json +14 -0
- package/docs/AUTORAG.md +58 -0
- package/docs/BRAND_INTELLIGENCE.md +30 -0
- package/docs/CLI_SHELL.md +4 -2
- package/docs/CMS_CONTEXTUAL_COMPOSER.md +38 -0
- package/docs/MERKLE.md +4 -0
- package/docs/PROJECT_CONFIG.md +3 -0
- package/docs/REPOSITORY_KNOWLEDGE.md +2 -0
- package/docs/THEME_REFINERY.md +120 -0
- package/docs/architecture/PROVIDER-TOOLS-AND-COMPACTION.md +60 -0
- package/docs/architecture/STORAGE.md +87 -0
- package/docs/cad-project-tools.md +69 -0
- package/docs/cms-scaffolding-pattern-reference.md +73 -0
- package/docs/plans/AGENTSAM-INTERACTIVE-UI-REQUIREMENTS-codex-tui-20260919.md +113 -0
- package/docs/plans/AGENTSAM-INTERACTIVE-UI-REQUIREMENTS.md +85 -0
- package/docs/plans/AGENTSAM-MCP-CLIENT-2026-09-19.md +181 -0
- package/docs/plans/ASBD-PORTABLE-WORKGRAPH-UI-DEFERRED.md +34 -0
- package/docs/plans/ASTRA-BRIEF-2026-09-18.md +258 -0
- package/docs/plans/MULTI-AGENT-SPRINTS-2026-09-19.md +373 -0
- package/docs/plans/NEXT-AGENT-HANDOFF.md +167 -0
- package/docs/plans/RECONCILIATION-2026-09-19.md +178 -0
- package/docs/plugins.md +43 -0
- package/docs/tools/README.md +57 -0
- package/docs/tools/agent-and-orchestration.md +49 -0
- package/docs/tools/browser-and-research.md +46 -0
- package/docs/tools/cloudflare-platform.md +32 -0
- package/docs/tools/cms.md +25 -0
- package/docs/tools/communications.md +41 -0
- package/docs/tools/database-and-storage.md +62 -0
- package/docs/tools/design-and-media.md +64 -0
- package/docs/tools/filesystem-and-code.md +55 -0
- package/docs/tools/github.md +56 -0
- package/docs/tools/integrations-and-misc.md +16 -0
- package/docs/tools/memory.md +21 -0
- package/docs/tools/terminal-and-execution.md +29 -0
- package/docs/tools/tickets-and-platform.md +30 -0
- package/migrations/d1/0001_agentsam_plugin_runtime.sql +177 -0
- package/migrations/d1/0002_agentsam_ticket_ownership.sql +8 -0
- package/migrations/d1/0002_dynamic_model_policies.sql +23 -0
- package/migrations/d1/0003_expand_tool_handler_families.sql +18 -0
- package/migrations/d1/0004_project_aware_retrieval_lanes.sql +24 -0
- package/migrations/d1/0005_portable_knowledge_identity.sql +104 -0
- package/migrations/d1/0006_repair_ops_trail_account_scope.sql +14 -0
- package/migrations/d1/0007_repair_ops_trail_agent_run_account.sql +13 -0
- package/migrations/d1/0008_backfill_knowledge_run_legacy_tenant.sql +14 -0
- package/migrations/d1/0009_normalize_cloudflare_plugin_installations.sql +137 -0
- package/migrations/runtime/0001_cli_runtime.sql +67 -0
- package/migrations/runtime/0002_project_sessions.sql +15 -0
- package/migrations/runtime/0003_provider_continuations.sql +8 -0
- package/package.json +92 -12
- package/packages/agentsam-brand/README.md +21 -0
- package/packages/agentsam-brand/package.json +22 -0
- package/packages/agentsam-brand/src/contract.js +59 -0
- package/packages/agentsam-brand/src/extract.js +126 -0
- package/packages/agentsam-brand/src/goap-actions.js +73 -0
- package/packages/agentsam-brand/src/index.js +48 -0
- package/packages/agentsam-brand/src/plan.js +115 -0
- package/packages/agentsam-brand/src/resolve.js +139 -0
- package/packages/agentsam-brand/src/scan.js +250 -0
- package/packages/agentsam-brand/test/brand-scan.test.mjs +106 -0
- package/packages/agentsam-contracts/README.md +23 -0
- package/packages/agentsam-contracts/package.json +32 -0
- package/packages/agentsam-contracts/src/adapter.ts +25 -0
- package/packages/agentsam-contracts/src/agent.ts +35 -0
- package/packages/agentsam-contracts/src/artifacts.ts +33 -0
- package/packages/agentsam-contracts/src/authority.ts +29 -0
- package/packages/agentsam-contracts/src/context.ts +16 -0
- package/packages/agentsam-contracts/src/errors.ts +46 -0
- package/packages/agentsam-contracts/src/events.ts +47 -0
- package/packages/agentsam-contracts/src/execution.ts +50 -0
- package/packages/agentsam-contracts/src/hooks.ts +40 -0
- package/packages/agentsam-contracts/src/identity.ts +16 -0
- package/packages/agentsam-contracts/src/index.ts +14 -0
- package/packages/agentsam-contracts/src/models.ts +9 -0
- package/packages/agentsam-contracts/src/providers.ts +33 -0
- package/packages/agentsam-contracts/src/repository.ts +64 -0
- package/packages/agentsam-contracts/src/tools.ts +98 -0
- package/packages/agentsam-contracts/test/contracts.test.mjs +16 -0
- package/packages/agentsam-contracts/test/errors-catalog.test.mjs +25 -0
- package/packages/agentsam-contracts/test/repository.test.mjs +18 -0
- package/packages/agentsam-contracts/tsconfig.json +12 -0
- package/packages/agentsam-errors/package.json +17 -0
- package/packages/agentsam-errors/src/adapters/anthropic.js +15 -0
- package/packages/agentsam-errors/src/adapters/cad.js +109 -0
- package/packages/agentsam-errors/src/adapters/cloudflare.js +21 -0
- package/packages/agentsam-errors/src/adapters/cursor.js +4 -0
- package/packages/agentsam-errors/src/adapters/device.js +38 -0
- package/packages/agentsam-errors/src/adapters/docker.js +28 -0
- package/packages/agentsam-errors/src/adapters/gcp.js +14 -0
- package/packages/agentsam-errors/src/adapters/github.js +22 -0
- package/packages/agentsam-errors/src/adapters/google.js +17 -0
- package/packages/agentsam-errors/src/adapters/index.js +55 -0
- package/packages/agentsam-errors/src/adapters/internal.js +40 -0
- package/packages/agentsam-errors/src/adapters/oauth.js +24 -0
- package/packages/agentsam-errors/src/adapters/openai.js +17 -0
- package/packages/agentsam-errors/src/adapters/process.js +35 -0
- package/packages/agentsam-errors/src/adapters/provider.js +114 -0
- package/packages/agentsam-errors/src/envelope.js +186 -0
- package/packages/agentsam-errors/src/error.js +24 -0
- package/packages/agentsam-errors/src/fingerprint.js +35 -0
- package/packages/agentsam-errors/src/index.js +10 -0
- package/packages/agentsam-errors/src/normalize.js +30 -0
- package/packages/agentsam-errors/src/redaction.js +52 -0
- package/packages/agentsam-errors/src/render.js +16 -0
- package/packages/agentsam-errors/src/retry.js +10 -0
- package/packages/agentsam-errors/src/transport.js +52 -0
- package/packages/agentsam-errors/src/vocabulary.js +320 -0
- package/packages/agentsam-errors/test/envelope.test.mjs +70 -0
- package/packages/agentsam-errors/test/providers.test.mjs +99 -0
- package/packages/agentsam-errors/test/redaction.test.mjs +21 -0
- package/packages/agentsam-errors/test/runtime-cad-device.test.mjs +76 -0
- package/packages/agentsam-errors/test/transport.test.mjs +46 -0
- package/packages/agentsam-knowledge/package.json +15 -0
- package/packages/agentsam-knowledge/src/autorag/index.js +64 -0
- package/packages/agentsam-knowledge/src/backends/index.js +26 -0
- package/packages/agentsam-knowledge/src/index.js +3 -0
- package/packages/agentsam-knowledge/src/providers/index.js +95 -0
- package/packages/agentsam-knowledge/test/autorag.test.mjs +42 -0
- package/packages/agentsam-nav/README.md +40 -0
- package/packages/agentsam-nav/dist/Nav.d.ts +43 -0
- package/packages/agentsam-nav/dist/NavCollapsible.d.ts +10 -0
- package/packages/agentsam-nav/dist/NavContent.d.ts +2 -0
- package/packages/agentsam-nav/dist/NavFooter.d.ts +2 -0
- package/packages/agentsam-nav/dist/NavGroup.d.ts +3 -0
- package/packages/agentsam-nav/dist/NavHeader.d.ts +2 -0
- package/packages/agentsam-nav/dist/NavMenu.d.ts +22 -0
- package/packages/agentsam-nav/dist/NavProvider.d.ts +35 -0
- package/packages/agentsam-nav/dist/NavTrigger.d.ts +2 -0
- package/packages/agentsam-nav/dist/Surfaces.d.ts +41 -0
- package/packages/agentsam-nav/dist/browser.d.ts +11 -0
- package/packages/agentsam-nav/dist/browser.global.js +132 -0
- package/packages/agentsam-nav/dist/browser.js +613 -0
- package/packages/agentsam-nav/dist/contracts.d.ts +76 -0
- package/packages/agentsam-nav/dist/index.d.ts +11 -0
- package/packages/agentsam-nav/dist/index.js +614 -0
- package/packages/agentsam-nav/dist/legacy.css +83 -0
- package/packages/agentsam-nav/dist/shell.css +113 -0
- package/packages/agentsam-nav/dist/theme.css +113 -0
- package/packages/agentsam-nav/dist/utils.d.ts +1 -0
- package/packages/agentsam-nav/package.json +43 -0
- package/packages/agentsam-queue-control/README.md +107 -0
- package/packages/agentsam-queue-control/package.json +31 -0
- package/packages/agentsam-queue-control/schemas/job-envelope.schema.json +56 -0
- package/packages/agentsam-queue-control/src/adapters/cloudflare.js +152 -0
- package/packages/agentsam-queue-control/src/adapters/memory.js +38 -0
- package/packages/agentsam-queue-control/src/contracts.js +130 -0
- package/packages/agentsam-queue-control/src/control-plane.js +141 -0
- package/packages/agentsam-queue-control/src/dispatch.js +43 -0
- package/packages/agentsam-queue-control/src/index.js +7 -0
- package/packages/agentsam-queue-control/src/policy.js +88 -0
- package/packages/agentsam-queue-control/src/topology.js +66 -0
- package/packages/agentsam-queue-control/test/queue-control.test.mjs +100 -0
- package/packages/agentsam-repository/src/goap.js +718 -0
- package/packages/agentsam-repository/src/goap.js.bak-20260922011251 +670 -0
- package/packages/agentsam-repository/src/index.js +5 -0
- package/packages/agentsam-repository/src/merkle/cloudflare-persistence.js +2 -2
- package/packages/agentsam-repository/src/tickets.js +184 -0
- package/packages/agentsam-repository/src/work-tracking.js +199 -0
- package/packages/agentsam-repository/src/workspace-state.js +176 -0
- package/packages/agentsam-repository/test/goap-tickets-workspace-state.test.mjs +152 -0
- package/packages/connectors/cloudflare/src/index.js +297 -15
- package/packages/connectors/cloudflare/src/owner.js +43 -40
- package/packages/connectors/cloudflare/src/routes.js +167 -26
- package/packages/connectors/cloudflare/tests/connector.test.mjs +112 -2
- package/packages/heuristic-theme/README.md +11 -0
- package/packages/heuristic-theme/package.json +25 -0
- package/packages/heuristic-theme/src/index.js +2 -0
- package/packages/heuristic-theme/src/registry.js +36 -0
- package/packages/heuristic-theme/src/theme.js +41 -0
- package/packages/heuristic-theme/test/theme.test.mjs +26 -0
- package/packages/identity/.agentsam/features/oauth-login-portal/agentsam.feature.json +64 -0
- package/packages/identity/.agentsam/features/oauth-login-portal/providers.json +96 -0
- package/packages/identity/.agentsam/features/oauth-login-portal/resources.json +47 -0
- package/packages/identity/.agentsam/features/oauth-login-portal/routes.json +74 -0
- package/packages/identity/.agentsam/features/oauth-login-portal/ui.json +35 -0
- package/packages/identity/package.json +3 -2
- package/packages/identity/src/adapters/cloudflare-d1/ids.js +4 -0
- package/packages/identity/src/adapters/cloudflare-d1/index.js +39 -1
- package/packages/identity/src/contracts/provider.js +3 -2
- package/packages/identity/src/frontend/auth-portal/pages/login.html +7 -0
- package/packages/identity/src/index.js +2 -0
- package/packages/identity/src/oauth/credentials.js +13 -0
- package/packages/identity/src/oauth/iam-platform.js +5 -5
- package/packages/identity/src/providers/cloudflare/index.js +19 -0
- package/packages/identity/src/providers/cloudflare/mapper.js +21 -0
- package/packages/identity/src/providers/cloudflare/oauth.js +48 -0
- package/packages/identity/src/providers/cloudflare/profile.js +28 -0
- package/packages/identity/src/providers/index.js +18 -2
- package/packages/identity/src/server/identity-service.js +13 -3
- package/packages/identity/src/server/worker-router.js +63 -8
- package/packages/identity/tests/identity-service.test.mjs +15 -0
- package/packages/providers/completeful/README.md +38 -0
- package/packages/providers/completeful/package.json +29 -0
- package/packages/providers/completeful/src/client.js +162 -0
- package/packages/providers/completeful/src/events.js +49 -0
- package/packages/providers/completeful/src/index.js +22 -0
- package/packages/providers/completeful/src/tools.js +579 -0
- package/packages/providers/completeful/src/webhooks.js +55 -0
- package/packages/providers/completeful/test/provider.test.mjs +196 -0
- package/packages/theme-church-site/README.md +10 -0
- package/packages/theme-church-site/package.json +30 -0
- package/packages/theme-church-site/src/harvest.json +14 -0
- package/packages/theme-church-site/src/index.js +84 -0
- package/packages/theme-church-site/test/theme.test.mjs +19 -0
- package/packages/theme-companions-site/README.md +10 -0
- package/packages/theme-companions-site/package.json +30 -0
- package/packages/theme-companions-site/src/harvest.json +12 -0
- package/packages/theme-companions-site/src/index.js +82 -0
- package/packages/theme-companions-site/test/theme.test.mjs +19 -0
- package/packages/theme-floors-site/README.md +10 -0
- package/packages/theme-floors-site/package.json +30 -0
- package/packages/theme-floors-site/src/harvest.json +14 -0
- package/packages/theme-floors-site/src/index.js +82 -0
- package/packages/theme-floors-site/test/theme.test.mjs +19 -0
- package/packages/theme-fuelnfree-site/README.md +10 -0
- package/packages/theme-fuelnfree-site/package.json +30 -0
- package/packages/theme-fuelnfree-site/src/harvest.json +13 -0
- package/packages/theme-fuelnfree-site/src/index.js +81 -0
- package/packages/theme-fuelnfree-site/test/theme.test.mjs +19 -0
- package/packages/theme-handyman-site/README.md +10 -0
- package/packages/theme-handyman-site/package.json +30 -0
- package/packages/theme-handyman-site/src/harvest.json +10 -0
- package/packages/theme-handyman-site/src/index.js +83 -0
- package/packages/theme-handyman-site/test/theme.test.mjs +19 -0
- package/packages/theme-insurance-site/README.md +10 -0
- package/packages/theme-insurance-site/package.json +30 -0
- package/packages/theme-insurance-site/src/harvest.json +10 -0
- package/packages/theme-insurance-site/src/index.js +83 -0
- package/packages/theme-insurance-site/test/theme.test.mjs +19 -0
- package/packages/theme-shinshu-site/README.md +10 -0
- package/packages/theme-shinshu-site/package.json +30 -0
- package/packages/theme-shinshu-site/src/harvest.json +12 -0
- package/packages/theme-shinshu-site/src/index.js +83 -0
- package/packages/theme-shinshu-site/test/theme.test.mjs +19 -0
- package/packages/work-graph/README.md +49 -0
- package/packages/work-graph/package.json +19 -0
- package/packages/work-graph/prototype/README.md +32 -0
- package/packages/work-graph/prototype/data/demo-workgraph.js +47 -0
- package/packages/work-graph/prototype/renderers/timeline-model.js +21 -0
- package/packages/work-graph/prototype/renderers/workgraph-runtime.js +38 -0
- package/packages/work-graph/prototype-gnantt.html +655 -0
- package/packages/work-graph/src/adapters/business/projects.js +23 -0
- package/packages/work-graph/src/adapters/engineering/git.js +22 -0
- package/packages/work-graph/src/adapters/engineering/mcp.js +22 -0
- package/packages/work-graph/src/index.js +76 -0
- package/packages/work-graph/src/renderers/gantt-model.js +11 -0
- package/packages/work-graph/src/renderers/timeline.js +16 -0
- package/packages/work-graph/test/work-graph.test.mjs +37 -0
- package/protocol/README.md +12 -0
- package/protocol/capabilities/cloudflare-cpu-audit-input.schema.json +30 -6
- package/protocol/capabilities/cloudflare-cpu-profile-input.schema.json +18 -4
- package/protocol/capabilities/cloudflare-wrangler-native-input.schema.json +59 -10
- package/protocol/capabilities/knowledge-search-input.schema.json +35 -0
- package/protocol/capabilities/manifest.json +163 -1
- package/protocol/capabilities/repository-audit-input.schema.json +39 -6
- package/protocol/capabilities/repository-snapshot-input.schema.json +15 -3
- package/protocol/capabilities/terminal-exec-input.schema.json +55 -0
- package/protocol/commerce/catalog.v1.json +50 -0
- package/protocol/errors/error-catalog.json +164 -0
- package/protocol/errors/error-envelope.schema.json +544 -0
- package/protocol/features/README.md +57 -0
- package/protocol/features/agentsam.feature.v1.schema.json +290 -0
- package/protocol/features/catalog.json +65 -0
- package/protocol/features/examples/provider-resend.feature.json +17 -0
- package/protocol/go/agentsam-go-runtime.v1.json +17 -0
- package/protocol/knowledge/LIFECYCLE.md +140 -0
- package/protocol/knowledge/README.md +4 -0
- package/protocol/presets/catalog.json +128 -19
- package/protocol/rpc/v1/errors.proto +24 -0
- package/protocol/theme-refinery/d1-reconciliation.md +48 -0
- package/protocol/theme-refinery/product-metadata.schema.json +27 -0
- package/protocol/theme-refinery/receipts/products-registry-batch-20260924.json +318 -0
- package/protocol/theme-refinery/receipts/theme-harvest-20260924.json +472 -0
- package/protocol/theme-refinery/reconciliation-receipt.schema.json +83 -0
- package/services/cad/server.py +249 -2
- package/src/agent/capability-adapter.js +15 -5
- package/src/agent/index.js +2 -1
- package/src/agent/model-turn.js +51 -0
- package/src/agent/responses-runner.js +304 -38
- package/src/capabilities/index.js +1 -0
- package/src/capabilities/terminal-exec.js +78 -0
- package/src/cli.js +117 -9
- package/src/cloudflare/index.js +6 -0
- package/src/cloudflare/runtime-status.js +393 -0
- package/src/cloudflare/wrangler.js +17 -1
- package/src/commands/app.js +106 -0
- package/src/commands/autorag.js +77 -0
- package/src/commands/brand.js +293 -0
- package/src/commands/cad.js +1 -0
- package/src/commands/connections.js +126 -29
- package/src/commands/context-economics.js +8 -0
- package/src/commands/db.js +7 -0
- package/src/commands/env.js +5 -4
- package/src/commands/eval.js +209 -14
- package/src/commands/go.js +365 -0
- package/src/commands/goap.js +176 -0
- package/src/commands/identity-init.js +27 -3
- package/src/commands/identity-protocol.js +195 -0
- package/src/commands/knowledge.js +64 -5
- package/src/commands/mcp.js +341 -0
- package/src/commands/merkle-persist.js +3 -1
- package/src/commands/merkle.js +18 -3
- package/src/commands/models.js +109 -23
- package/src/commands/plugins.js +175 -0
- package/src/commands/preferences.js +28 -8
- package/src/commands/product.js +53 -10
- package/src/commands/providers.js +118 -37
- package/src/commands/resume.js +9 -5
- package/src/commands/runtime-status.js +154 -0
- package/src/commands/shell.js +466 -55
- package/src/commands/status.js +82 -7
- package/src/commands/tunnel.js +228 -195
- package/src/commands/whoami.js +78 -6
- package/src/context/budget.js +6 -0
- package/src/context/index.js +2 -1
- package/src/context/project-card.js +75 -0
- package/src/errors/contract.js +34 -211
- package/src/errors/diagnostic.js +95 -51
- package/src/errors/index.js +6 -13
- package/src/eval/index.js +6 -0
- package/src/eval/live.js +439 -0
- package/src/features/resolve.js +242 -0
- package/src/go/build.js +108 -0
- package/src/go/cloudflare.js +207 -0
- package/src/go/contract.js +139 -0
- package/src/go/discover.js +96 -0
- package/src/go/index.js +13 -0
- package/src/go/receipts.js +77 -0
- package/src/go/registry.js +223 -0
- package/src/go/verify.js +31 -0
- package/src/index.js +100 -1
- package/src/knowledge/config.js +13 -5
- package/src/knowledge/engine.js +23 -8
- package/src/knowledge/index.js +1 -0
- package/src/knowledge/lane-registry.js +46 -0
- package/src/knowledge/providers/gemini.js +48 -8
- package/src/knowledge/service/client.js +13 -1
- package/src/knowledge/service/grpc-codec.js +156 -53
- package/src/knowledge/service/job-engine.js +133 -11
- package/src/knowledge/service/job-worker.js +34 -5
- package/src/knowledge/service/server.js +10 -1
- package/src/knowledge/store-discovery.js +77 -0
- package/src/lib/account-session.js +8 -2
- package/src/lib/agent-instructions.js +3 -0
- package/src/lib/auth.js +7 -3
- package/src/lib/cad/blender.js +42 -3
- package/src/lib/cad/d1-project-store.js +43 -0
- package/src/lib/cad/discovery.js +616 -0
- package/src/lib/cad/docker-executor.js +352 -0
- package/src/lib/cad/freecad.js +253 -0
- package/src/lib/cad/index.js +40 -0
- package/src/lib/cad/openscad.js +198 -0
- package/src/lib/cad/project-cli.d.ts +2 -0
- package/src/lib/cad/project-cli.js +21 -0
- package/src/lib/cad/project-contract.d.ts +3 -0
- package/src/lib/cad/project-contract.js +1 -0
- package/src/lib/cad/project-recipe.js +30 -0
- package/src/lib/cad/project-runtime.d.ts +2 -0
- package/src/lib/cad/project-runtime.js +53 -0
- package/src/lib/cad/project-store.js +25 -0
- package/src/lib/cad/project-workflows.js +31 -0
- package/src/lib/cad-docker.js +21 -2
- package/src/lib/cli-preferences.js +17 -2
- package/src/lib/core-client.js +37 -18
- package/src/lib/deploy/local-studio.js +6 -5
- package/src/lib/dockerize.js +3 -0
- package/src/lib/execution-approvals.js +1 -0
- package/src/lib/identity-scaffold.js +4 -1
- package/src/lib/knowledge-docker.js +9 -1
- package/src/lib/local-sessions.js +124 -34
- package/src/lib/local-status.js +35 -14
- package/src/lib/project-config.js +9 -0
- package/src/lib/provider-credentials.js +73 -11
- package/src/lib/scaffold/resolve-cloudflare-account.js +37 -0
- package/src/lib/scaffold/wizards/cms.js +2 -8
- package/src/lib/scaffold/wizards/worker-api.js +2 -8
- package/src/lib/slash-commands.js +9 -2
- package/src/local/migrations.js +109 -1
- package/src/local/runtime-store.js +31 -5
- package/src/local/sqlite.js +36 -1
- package/src/mcp/authority.js +348 -0
- package/src/mcp/client-adapters.js +431 -0
- package/src/mcp/client.js +172 -0
- package/src/mcp/index.js +47 -0
- package/src/mcp/telemetry.js +103 -0
- package/src/models/catalog.js +329 -51
- package/src/models/discovery.js +24 -4
- package/src/models/index.js +2 -0
- package/src/models/inventory-core.js +182 -0
- package/src/models/policy.js +20 -0
- package/src/plugins/cloudflare.js +103 -0
- package/src/plugins/completeful.js +69 -0
- package/src/plugins/contracts.js +86 -0
- package/src/plugins/index.js +11 -0
- package/src/plugins/registry.js +207 -0
- package/src/plugins/resource-scope.js +45 -0
- package/src/plugins/runtime.js +118 -0
- package/src/plugins/vectorize.js +31 -0
- package/src/progression/engine.js +171 -0
- package/src/progression/index.js +1 -0
- package/src/providers/cloudflare-chat.js +1 -1
- package/src/providers/gemini-generate-content.js +2 -1
- package/src/providers/openai-responses.js +45 -16
- package/src/providers/tool-schema.js +85 -0
- package/src/repository/index.js +29 -0
- package/src/rpc/generated/errors_pb.js +961 -1
- package/src/security/local-vault.js +415 -0
- package/src/security/process.js +20 -4
- package/src/status/actions.js +192 -0
- package/src/tools/hydrate.js +5 -1
- package/src/tools/index.js +7 -0
- package/src/tools/redact.js +64 -0
- package/src/tools/registry.js +83 -0
- package/src/tools/runtime.js +257 -0
- package/src/tools/search.js +21 -8
- package/src/ui/ansi.js +117 -3
- package/src/ui/cli/activity.js +76 -7
- package/src/ui/cli/footer.js +110 -9
- package/src/ui/cli/help.js +11 -4
- package/src/ui/wireframes.js +166 -0
- package/test/account-session.test.mjs +28 -0
- package/test/apps-scaffold-contract.test.mjs +16 -1
- package/test/capabilities.test.mjs +1 -1
- package/test/cli/eval-live.test.mjs +219 -0
- package/test/cli/go.test.mjs +71 -0
- package/test/cli/local-vault-and-provider-setup.test.mjs +268 -0
- package/test/cli/mcp-client.test.mjs +245 -0
- package/test/cli/runtime-ui.test.mjs +69 -2
- package/test/cli/status-actions.test.mjs +88 -0
- package/test/cli/wireframes-go-registry.test.mjs +54 -0
- package/test/cloudflare-connector.test.mjs +3 -6
- package/test/cloudflare-runtime.test.mjs +8 -1
- package/test/context.test.mjs +15 -0
- package/test/error-diagnostics.test.mjs +9 -0
- package/test/fixtures/cad/courtyard-house.json +208 -0
- package/test/go/cloudflare-probe.test.mjs +53 -0
- package/test/integration/app-command.test.mjs +55 -0
- package/test/integration/cad-discovery.test.mjs +158 -0
- package/test/integration/cad-docker-executor.test.mjs +249 -0
- package/test/integration/cad-execution.test.mjs +184 -0
- package/test/integration/cad-project-app.test.mjs +31 -0
- package/test/integration/cad-project-d1.test.mjs +25 -0
- package/test/integration/cad-project-native.test.mjs +24 -0
- package/test/integration/cad-project-workflow.test.mjs +9 -0
- package/test/integration/cad-project.test.mjs +82 -0
- package/test/integration/cli-help.test.mjs +4 -0
- package/test/integration/cms-site-tenancy-contract.test.mjs +256 -0
- package/test/integration/core-client.integration.test.mjs +55 -0
- package/test/integration/error-runtime-rpc.test.mjs +71 -0
- package/test/integration/features-resolve.test.mjs +128 -0
- package/test/integration/install-script.test.mjs +107 -0
- package/test/integration/inventory-core.test.mjs +53 -0
- package/test/integration/plugins-cloudflare.integration.test.mjs +28 -0
- package/test/integration/provider-env-cli.test.mjs +1 -1
- package/test/integration/runtime-migrations.test.mjs +6 -1
- package/test/integration/runtime-status.integration.test.mjs +211 -0
- package/test/integration/scaffold-cloudflare.test.mjs +46 -0
- package/test/integration/storage-architecture.test.mjs +154 -0
- package/test/integration/store-discovery.test.mjs +44 -0
- package/test/integration/terminal-exec.integration.test.mjs +86 -0
- package/test/integration/tool-runtime.test.mjs +124 -0
- package/test/integration/tool-schema.test.mjs +59 -0
- package/test/knowledge-service.test.mjs +4 -0
- package/test/local-sessions.test.mjs +11 -2
- package/test/local-studio-deploy.test.mjs +1 -1
- package/test/model-catalog.test.mjs +28 -1
- package/test/models.test.mjs +159 -5
- package/test/openai-responses.test.mjs +60 -0
- package/test/provider-credentials.test.mjs +15 -5
- package/test/responses-runner.test.mjs +321 -6
- package/test/shell.test.mjs +149 -4
- package/test/smoke.mjs +2 -2
- package/test/tools-search.test.mjs +33 -0
- package/test/unit/website-assets-bindings.test.mjs +60 -0
- package/test/whoami-resume.test.mjs +82 -3
- package/examples/gorilla-shell/README.md +0 -15
- package/src/lib/gorilla-template.js +0 -54
- package/templates/gorilla-shell/App.tsx +0 -639
- package/templates/gorilla-shell/README.md +0 -34
- package/templates/gorilla-shell/index.html +0 -15
- package/templates/gorilla-shell/main.jsx +0 -9
- package/templates/gorilla-shell/package.json +0 -19
- package/templates/gorilla-shell/vite.config.js +0 -21
|
@@ -7,6 +7,8 @@ import { getGoogleAuthUrl, exchangeGoogleCode } from '../providers/google/oauth.
|
|
|
7
7
|
import { fetchGoogleProfile } from '../providers/google/profile.js';
|
|
8
8
|
import { getGithubAuthUrl, exchangeGithubCode } from '../providers/github/oauth.js';
|
|
9
9
|
import { fetchGithubProfile } from '../providers/github/profile.js';
|
|
10
|
+
import { getCloudflareAuthUrl, exchangeCloudflareCode } from '../providers/cloudflare/oauth.js';
|
|
11
|
+
import { fetchCloudflareProfile } from '../providers/cloudflare/profile.js';
|
|
10
12
|
import { AUTH_LOGIN_PATH } from '../core/constants.js';
|
|
11
13
|
import { resolveOAuthCredentialLane } from '../oauth/credentials.js';
|
|
12
14
|
import { iamPlatformOAuthCallback, iamPlatformOAuthStart } from '../oauth/iam-platform.js';
|
|
@@ -89,8 +91,14 @@ export async function handleIdentityWorkerRequest(request, env, options = {}) {
|
|
|
89
91
|
password: body.password,
|
|
90
92
|
});
|
|
91
93
|
if (!result.ok) {
|
|
94
|
+
await adapter.logAuthEvent({
|
|
95
|
+
eventType: 'login', status: 'failed', provider: 'email', request,
|
|
96
|
+
});
|
|
92
97
|
return jsonResponse({ ok: false, error: result.error }, 401);
|
|
93
98
|
}
|
|
99
|
+
await adapter.logAuthEvent({
|
|
100
|
+
userId: result.user.id, eventType: 'login', status: 'ok', provider: 'email', request,
|
|
101
|
+
});
|
|
94
102
|
return identity.buildLoginSuccessResponse(request, result.sessionId, body.next);
|
|
95
103
|
}
|
|
96
104
|
|
|
@@ -108,7 +116,11 @@ export async function handleIdentityWorkerRequest(request, env, options = {}) {
|
|
|
108
116
|
}
|
|
109
117
|
|
|
110
118
|
if (path === '/api/auth/logout' && method === 'POST') {
|
|
119
|
+
const sessionCtx = await identity.sessionFromRequest(request).catch(() => null);
|
|
111
120
|
await identity.logout(request);
|
|
121
|
+
await adapter.logAuthEvent({
|
|
122
|
+
userId: sessionCtx?.user?.id, eventType: 'logout', status: 'ok', request,
|
|
123
|
+
});
|
|
112
124
|
return identity.buildLogoutResponse(request);
|
|
113
125
|
}
|
|
114
126
|
|
|
@@ -198,21 +210,26 @@ export async function handleIdentityWorkerRequest(request, env, options = {}) {
|
|
|
198
210
|
if (path === '/api/oauth/iam/start' && method === 'GET') {
|
|
199
211
|
const lane = resolveOAuthCredentialLane(env, 'iam');
|
|
200
212
|
if (!lane) return jsonResponse({ ok: false, error: 'iam_oauth_not_configured' }, 503);
|
|
201
|
-
return iamPlatformOAuthStart(request, env, adapter);
|
|
213
|
+
return iamPlatformOAuthStart(request, env, adapter, identity);
|
|
202
214
|
}
|
|
203
215
|
|
|
204
216
|
if (path === '/api/oauth/google/start' && method === 'GET') {
|
|
205
217
|
const lane = resolveOAuthCredentialLane(env, 'google');
|
|
206
218
|
if (!lane) return jsonResponse({ ok: false, error: 'google_oauth_not_configured' }, 503);
|
|
207
|
-
if (lane.lane === 'iam_platform') return iamPlatformOAuthStart(request, env, adapter);
|
|
219
|
+
if (lane.lane === 'iam_platform') return iamPlatformOAuthStart(request, env, adapter, identity);
|
|
208
220
|
return oauthStart(request, env, adapter, 'google', lane);
|
|
209
221
|
}
|
|
210
222
|
if (path === '/api/oauth/github/start' && method === 'GET') {
|
|
211
223
|
const lane = resolveOAuthCredentialLane(env, 'github');
|
|
212
224
|
if (!lane) return jsonResponse({ ok: false, error: 'github_oauth_not_configured' }, 503);
|
|
213
|
-
if (lane.lane === 'iam_platform') return iamPlatformOAuthStart(request, env, adapter);
|
|
225
|
+
if (lane.lane === 'iam_platform') return iamPlatformOAuthStart(request, env, adapter, identity);
|
|
214
226
|
return oauthStart(request, env, adapter, 'github', lane);
|
|
215
227
|
}
|
|
228
|
+
if (path === '/api/oauth/cloudflare/start' && method === 'GET') {
|
|
229
|
+
const lane = resolveOAuthCredentialLane(env, 'cloudflare');
|
|
230
|
+
if (!lane) return jsonResponse({ ok: false, error: 'cloudflare_oauth_not_configured' }, 503);
|
|
231
|
+
return oauthStart(request, env, adapter, 'cloudflare', lane);
|
|
232
|
+
}
|
|
216
233
|
|
|
217
234
|
if (path === '/api/oauth/google/callback' && method === 'GET') {
|
|
218
235
|
const lane = resolveOAuthCredentialLane(env, 'google');
|
|
@@ -234,6 +251,13 @@ export async function handleIdentityWorkerRequest(request, env, options = {}) {
|
|
|
234
251
|
}
|
|
235
252
|
return oauthCallback(request, env, identity, adapter, 'github', lane);
|
|
236
253
|
}
|
|
254
|
+
if (path === '/api/oauth/cloudflare/callback' && method === 'GET') {
|
|
255
|
+
const lane = resolveOAuthCredentialLane(env, 'cloudflare');
|
|
256
|
+
if (!lane) {
|
|
257
|
+
return Response.redirect(`${url.origin}${AUTH_LOGIN_PATH}?error=oauth_not_configured`, 302);
|
|
258
|
+
}
|
|
259
|
+
return oauthCallback(request, env, identity, adapter, 'cloudflare', lane);
|
|
260
|
+
}
|
|
237
261
|
|
|
238
262
|
// Auth HTML shells — use extensionless paths; assets serves foo.html at /foo.
|
|
239
263
|
const authPageMap = {
|
|
@@ -277,7 +301,9 @@ async function oauthStart(request, env, adapter, provider, creds) {
|
|
|
277
301
|
const state = randomOAuthState();
|
|
278
302
|
const codeVerifier = pkceVerifier();
|
|
279
303
|
const codeChallenge = await pkceChallenge(codeVerifier);
|
|
280
|
-
const redirectTo =
|
|
304
|
+
const redirectTo = identity.resolvePostLoginPath(
|
|
305
|
+
url.searchParams.get('next') || url.searchParams.get('return_to'),
|
|
306
|
+
);
|
|
281
307
|
await adapter.saveOAuthState({ state, provider, codeVerifier, redirectTo });
|
|
282
308
|
|
|
283
309
|
const redirectUri = `${url.origin}/api/oauth/${provider}/callback`;
|
|
@@ -289,6 +315,13 @@ async function oauthStart(request, env, adapter, provider, creds) {
|
|
|
289
315
|
state,
|
|
290
316
|
codeChallenge,
|
|
291
317
|
});
|
|
318
|
+
} else if (provider === 'cloudflare') {
|
|
319
|
+
authUrl = getCloudflareAuthUrl({
|
|
320
|
+
clientId: creds.clientId,
|
|
321
|
+
redirectUri,
|
|
322
|
+
state,
|
|
323
|
+
codeChallenge,
|
|
324
|
+
});
|
|
292
325
|
} else {
|
|
293
326
|
authUrl = getGithubAuthUrl({
|
|
294
327
|
clientId: creds.clientId,
|
|
@@ -306,10 +339,12 @@ async function oauthCallback(request, env, identity, adapter, provider, creds) {
|
|
|
306
339
|
const state = url.searchParams.get('state');
|
|
307
340
|
const err = url.searchParams.get('error');
|
|
308
341
|
if (err || !code || !state) {
|
|
342
|
+
await adapter.logAuthEvent({ eventType: 'login', status: 'failed', provider, request, metadata: { reason: 'oauth_failed' } });
|
|
309
343
|
return Response.redirect(`${url.origin}${AUTH_LOGIN_PATH}?error=oauth_failed`, 302);
|
|
310
344
|
}
|
|
311
345
|
const saved = await adapter.consumeOAuthState(state);
|
|
312
346
|
if (!saved || saved.provider !== provider) {
|
|
347
|
+
await adapter.logAuthEvent({ eventType: 'login', status: 'failed', provider, request, metadata: { reason: 'state_mismatch' } });
|
|
313
348
|
return Response.redirect(`${url.origin}${AUTH_LOGIN_PATH}?error=state_mismatch`, 302);
|
|
314
349
|
}
|
|
315
350
|
const redirectUri = `${url.origin}/api/oauth/${provider}/callback`;
|
|
@@ -327,6 +362,18 @@ async function oauthCallback(request, env, identity, adapter, provider, creds) {
|
|
|
327
362
|
return Response.redirect(`${url.origin}${AUTH_LOGIN_PATH}?error=token_exchange_failed`, 302);
|
|
328
363
|
}
|
|
329
364
|
profile = await fetchGoogleProfile(token.access_token);
|
|
365
|
+
} else if (provider === 'cloudflare') {
|
|
366
|
+
token = await exchangeCloudflareCode({
|
|
367
|
+
code,
|
|
368
|
+
codeVerifier: saved.code_verifier,
|
|
369
|
+
clientId: creds.clientId,
|
|
370
|
+
clientSecret: creds.clientSecret,
|
|
371
|
+
redirectUri,
|
|
372
|
+
});
|
|
373
|
+
if (!token?.access_token) {
|
|
374
|
+
return Response.redirect(`${url.origin}${AUTH_LOGIN_PATH}?error=token_exchange_failed`, 302);
|
|
375
|
+
}
|
|
376
|
+
profile = await fetchCloudflareProfile(token.access_token);
|
|
330
377
|
} else {
|
|
331
378
|
token = await exchangeGithubCode({
|
|
332
379
|
code,
|
|
@@ -344,9 +391,14 @@ async function oauthCallback(request, env, identity, adapter, provider, creds) {
|
|
|
344
391
|
return Response.redirect(`${url.origin}${AUTH_LOGIN_PATH}?error=userinfo_failed`, 302);
|
|
345
392
|
}
|
|
346
393
|
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
394
|
+
let normalized;
|
|
395
|
+
if (provider === 'google') {
|
|
396
|
+
normalized = { subject: profile.sub, email: profile.email, name: profile.name };
|
|
397
|
+
} else if (provider === 'cloudflare') {
|
|
398
|
+
normalized = { subject: String(profile.sub), email: profile.email, name: profile.name || profile.email };
|
|
399
|
+
} else {
|
|
400
|
+
normalized = { subject: String(profile.id), email: profile.email, name: profile.name || profile.login };
|
|
401
|
+
}
|
|
350
402
|
|
|
351
403
|
const result = await identity.provisionOAuthUser({
|
|
352
404
|
provider,
|
|
@@ -354,8 +406,11 @@ async function oauthCallback(request, env, identity, adapter, provider, creds) {
|
|
|
354
406
|
email: normalized.email,
|
|
355
407
|
displayName: normalized.name,
|
|
356
408
|
});
|
|
409
|
+
await adapter.logAuthEvent({
|
|
410
|
+
userId: result.authUserId, eventType: 'login', status: 'ok', provider, request,
|
|
411
|
+
});
|
|
357
412
|
|
|
358
|
-
const redirectTo = saved.redirect_to
|
|
413
|
+
const redirectTo = identity.resolvePostLoginPath(saved.redirect_to);
|
|
359
414
|
const res = identity.buildLoginSuccessResponse(request, result.sessionId, redirectTo);
|
|
360
415
|
const globeUrl = `${url.origin}${AUTH_LOGIN_PATH}?globe_exit=1&next=${encodeURIComponent(redirectTo)}`;
|
|
361
416
|
return new Response(null, {
|
|
@@ -66,6 +66,21 @@ function createMemoryAdapter() {
|
|
|
66
66
|
}
|
|
67
67
|
|
|
68
68
|
describe('identity service', () => {
|
|
69
|
+
it('owns its fallback and rejects external OAuth return targets', () => {
|
|
70
|
+
const identity = createIdentityService({
|
|
71
|
+
adapter: createMemoryAdapter(),
|
|
72
|
+
defaultRedirect: '/agentsam',
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
assert.equal(identity.resolvePostLoginPath('/projects?tab=recent'), '/projects?tab=recent');
|
|
76
|
+
assert.equal(identity.resolvePostLoginPath('https://attacker.example/'), '/agentsam');
|
|
77
|
+
assert.equal(identity.resolvePostLoginPath('//attacker.example/'), '/agentsam');
|
|
78
|
+
assert.equal(identity.resolvePostLoginPath(null), '/agentsam');
|
|
79
|
+
|
|
80
|
+
const neutral = createIdentityService({ adapter: createMemoryAdapter() });
|
|
81
|
+
assert.equal(neutral.resolvePostLoginPath(null), '/');
|
|
82
|
+
});
|
|
83
|
+
|
|
69
84
|
it('signup and login issue session', async () => {
|
|
70
85
|
const identity = createIdentityService({ adapter: createMemoryAdapter() });
|
|
71
86
|
const signup = await identity.signup({
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# @inneranimalmedia/agentsam-provider-completeful
|
|
2
|
+
|
|
3
|
+
Portable Completeful provider mechanics for AgentSam.
|
|
4
|
+
|
|
5
|
+
This package is deliberately **not** a Fuel & Free Time data layer. It owns provider HTTP behavior, provider tool definitions/execution, structured provider errors, webhook signature verification, and normalized Completeful event envelopes.
|
|
6
|
+
|
|
7
|
+
The host owns:
|
|
8
|
+
|
|
9
|
+
- resolving `completeful.api_key` to a real secret such as Fuel & Free Time's `CAPP_KEY`;
|
|
10
|
+
- account/shop configuration and authorization;
|
|
11
|
+
- D1/R2 catalog mirrors and curation;
|
|
12
|
+
- business workflows such as `fnf.order.sync`;
|
|
13
|
+
- mapping provider events like `completeful.order.created` into domain events such as `commerce.order.created`;
|
|
14
|
+
- execution receipts, queues, hook persistence, approvals and UI.
|
|
15
|
+
|
|
16
|
+
## First slice
|
|
17
|
+
|
|
18
|
+
The initial read-first tool surface is:
|
|
19
|
+
|
|
20
|
+
- `completeful.shop.list`
|
|
21
|
+
- `completeful.shop.get`
|
|
22
|
+
- `completeful.catalog.list`
|
|
23
|
+
- `completeful.catalog.get`
|
|
24
|
+
- `completeful.catalog.semantic`
|
|
25
|
+
- `completeful.order.get`
|
|
26
|
+
- `completeful.webhook.list`
|
|
27
|
+
|
|
28
|
+
The first mutation set is also present, with fail-closed live-write checks and explicit side-effect/idempotency metadata:
|
|
29
|
+
|
|
30
|
+
- `completeful.design.create`
|
|
31
|
+
- `completeful.product.create`
|
|
32
|
+
- `completeful.product.publish`
|
|
33
|
+
- `completeful.order.quote`
|
|
34
|
+
- `completeful.order.create`
|
|
35
|
+
- `completeful.order.cancel`
|
|
36
|
+
- `completeful.webhook.ensure`
|
|
37
|
+
|
|
38
|
+
Order reads/writes declare redacted receipt policy for address/email fields, and webhook tools declare/redact secret-bearing paths. The Completeful pinned OpenAPI contract remains under `apps/ecommerce-cms-agentsam/providers/completeful/reference/`.
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@inneranimalmedia/agentsam-provider-completeful",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"private": false,
|
|
5
|
+
"description": "Portable Completeful provider adapter and AgentSam tool definitions.",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"main": "./src/index.js",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": "./src/index.js",
|
|
10
|
+
"./client": "./src/client.js",
|
|
11
|
+
"./tools": "./src/tools.js",
|
|
12
|
+
"./webhooks": "./src/webhooks.js",
|
|
13
|
+
"./events": "./src/events.js"
|
|
14
|
+
},
|
|
15
|
+
"scripts": {
|
|
16
|
+
"test": "node --test test/*.test.mjs"
|
|
17
|
+
},
|
|
18
|
+
"files": [
|
|
19
|
+
"src",
|
|
20
|
+
"README.md"
|
|
21
|
+
],
|
|
22
|
+
"engines": {
|
|
23
|
+
"node": ">=22 <25"
|
|
24
|
+
},
|
|
25
|
+
"publishConfig": {
|
|
26
|
+
"access": "public"
|
|
27
|
+
},
|
|
28
|
+
"license": "MIT"
|
|
29
|
+
}
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
export const DEFAULT_COMPLETEFUL_API_ORIGIN = 'https://vxapi.completeful.com';
|
|
2
|
+
|
|
3
|
+
function trimSlashes(value) {
|
|
4
|
+
return String(value || '').replace(/\/+$/, '');
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export function completefulApiBase(apiUrl = DEFAULT_COMPLETEFUL_API_ORIGIN) {
|
|
8
|
+
const configured = trimSlashes(apiUrl || DEFAULT_COMPLETEFUL_API_ORIGIN);
|
|
9
|
+
return configured.endsWith('/v1') ? configured : `${configured}/v1`;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function completefulKeyMode(apiKey) {
|
|
13
|
+
const key = String(apiKey || '');
|
|
14
|
+
if (key.startsWith('capp_test_')) return 'test';
|
|
15
|
+
if (key.startsWith('capp_live_')) return 'live';
|
|
16
|
+
return key ? 'unknown' : 'missing';
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export class CompletefulApiError extends Error {
|
|
20
|
+
constructor(message, details = {}) {
|
|
21
|
+
super(message);
|
|
22
|
+
this.name = 'CompletefulApiError';
|
|
23
|
+
this.status = details.status || 502;
|
|
24
|
+
this.code = details.code || null;
|
|
25
|
+
this.requestId = details.requestId || null;
|
|
26
|
+
this.path = details.path || null;
|
|
27
|
+
this.remediation = details.remediation || null;
|
|
28
|
+
this.details = details.details || null;
|
|
29
|
+
this.providerBody = details.providerBody || null;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
toJSON() {
|
|
33
|
+
return {
|
|
34
|
+
error: this.message,
|
|
35
|
+
code: this.code,
|
|
36
|
+
request_id: this.requestId,
|
|
37
|
+
path: this.path,
|
|
38
|
+
remediation: this.remediation,
|
|
39
|
+
details: this.details,
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function buildUrl(base, path, query) {
|
|
45
|
+
const normalizedPath = String(path || '').startsWith('/') ? String(path) : `/${path}`;
|
|
46
|
+
const url = new URL(`${base}${normalizedPath}`);
|
|
47
|
+
if (query) {
|
|
48
|
+
for (const [key, value] of Object.entries(query)) {
|
|
49
|
+
if (value === undefined || value === null || value === '') continue;
|
|
50
|
+
url.searchParams.set(key, String(value));
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return url;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
async function parseProviderResponse(response) {
|
|
57
|
+
const text = await response.text();
|
|
58
|
+
if (!text) return null;
|
|
59
|
+
try {
|
|
60
|
+
return JSON.parse(text);
|
|
61
|
+
} catch {
|
|
62
|
+
return { raw: text.slice(0, 4000) };
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export function createCompletefulClient({
|
|
67
|
+
apiKey,
|
|
68
|
+
apiUrl = DEFAULT_COMPLETEFUL_API_ORIGIN,
|
|
69
|
+
allowLiveWrites = false,
|
|
70
|
+
fetchImpl = globalThis.fetch,
|
|
71
|
+
} = {}) {
|
|
72
|
+
if (typeof fetchImpl !== 'function') {
|
|
73
|
+
throw new TypeError('Completeful client requires a fetch implementation');
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const base = completefulApiBase(apiUrl);
|
|
77
|
+
const mode = completefulKeyMode(apiKey);
|
|
78
|
+
|
|
79
|
+
function assertConfigured() {
|
|
80
|
+
if (mode !== 'missing') return;
|
|
81
|
+
throw new CompletefulApiError('Completeful API key is missing', {
|
|
82
|
+
status: 503,
|
|
83
|
+
code: 'completeful_not_configured',
|
|
84
|
+
remediation: 'Resolve a Completeful API key through the host authority adapter.',
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function assertMutationAllowed() {
|
|
89
|
+
assertConfigured();
|
|
90
|
+
if (mode === 'test') return;
|
|
91
|
+
if (mode === 'live' && allowLiveWrites) return;
|
|
92
|
+
throw new CompletefulApiError('Completeful live writes are disabled', {
|
|
93
|
+
status: 409,
|
|
94
|
+
code: 'completeful_live_writes_disabled',
|
|
95
|
+
remediation: 'Use a capp_test_ key or explicitly enable live writes in the host configuration.',
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
async function request(method, path, { query = null, body = undefined, idempotencyKey = null, headers = null } = {}) {
|
|
100
|
+
assertConfigured();
|
|
101
|
+
|
|
102
|
+
const url = buildUrl(base, path, query);
|
|
103
|
+
const requestHeaders = new Headers(headers || {});
|
|
104
|
+
requestHeaders.set('Accept', 'application/json');
|
|
105
|
+
requestHeaders.set('Authorization', `Bearer ${apiKey}`);
|
|
106
|
+
|
|
107
|
+
let requestBody = body;
|
|
108
|
+
if (body !== undefined && body !== null && !(body instanceof FormData)) {
|
|
109
|
+
requestHeaders.set('Content-Type', 'application/json');
|
|
110
|
+
requestBody = typeof body === 'string' ? body : JSON.stringify(body);
|
|
111
|
+
}
|
|
112
|
+
if (idempotencyKey) requestHeaders.set('Idempotency-Key', idempotencyKey);
|
|
113
|
+
|
|
114
|
+
const response = await fetchImpl(url.toString(), {
|
|
115
|
+
method,
|
|
116
|
+
headers: requestHeaders,
|
|
117
|
+
body: requestBody,
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
const data = await parseProviderResponse(response);
|
|
121
|
+
const requestId =
|
|
122
|
+
response.headers.get('x-request-id') ||
|
|
123
|
+
response.headers.get('x-capp-request-id') ||
|
|
124
|
+
data?.request_id ||
|
|
125
|
+
null;
|
|
126
|
+
|
|
127
|
+
const meta = {
|
|
128
|
+
status: response.status,
|
|
129
|
+
request_id: requestId,
|
|
130
|
+
mode: response.headers.get('x-capp-mode') || null,
|
|
131
|
+
dry_run: response.headers.get('x-capp-dry-run') === 'true',
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
if (!response.ok) {
|
|
135
|
+
const provider = data && typeof data === 'object' ? data : {};
|
|
136
|
+
throw new CompletefulApiError(
|
|
137
|
+
provider.error || provider.message || `Completeful request failed (${response.status})`,
|
|
138
|
+
{
|
|
139
|
+
status: response.status,
|
|
140
|
+
code: provider.code || 'completeful_request_failed',
|
|
141
|
+
requestId,
|
|
142
|
+
path: provider.path || url.pathname,
|
|
143
|
+
remediation: provider.remediation || null,
|
|
144
|
+
details: provider.details || null,
|
|
145
|
+
providerBody: provider,
|
|
146
|
+
},
|
|
147
|
+
);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
return { data, meta };
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
return {
|
|
154
|
+
providerKey: 'completeful',
|
|
155
|
+
apiBase: base,
|
|
156
|
+
keyMode: mode,
|
|
157
|
+
allowLiveWrites: Boolean(allowLiveWrites),
|
|
158
|
+
request,
|
|
159
|
+
assertConfigured,
|
|
160
|
+
assertMutationAllowed,
|
|
161
|
+
};
|
|
162
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
function normalizeTopic(topic) {
|
|
2
|
+
return String(topic || 'unknown')
|
|
3
|
+
.trim()
|
|
4
|
+
.toLowerCase()
|
|
5
|
+
.replace(/[^a-z0-9]+/g, '.')
|
|
6
|
+
.replace(/^\.+|\.+$/g, '') || 'unknown';
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
function providerObjectId(event) {
|
|
10
|
+
const data = event?.data || {};
|
|
11
|
+
return data.order_id || data.product_id || data.shop_id || data.id || event?.resource_id || null;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function toUnixMilliseconds(value, fallback = Date.now()) {
|
|
15
|
+
if (value == null || value === '') return fallback;
|
|
16
|
+
if (Number.isFinite(Number(value))) {
|
|
17
|
+
const n = Number(value);
|
|
18
|
+
return n > 1e12 ? Math.floor(n) : Math.floor(n * 1000);
|
|
19
|
+
}
|
|
20
|
+
const parsed = Date.parse(String(value));
|
|
21
|
+
return Number.isFinite(parsed) ? parsed : fallback;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export function normalizeCompletefulEvent(event, context = {}) {
|
|
25
|
+
const topic = normalizeTopic(event?.type);
|
|
26
|
+
const id = String(event?.id || context.id || crypto.randomUUID());
|
|
27
|
+
const subject = providerObjectId(event);
|
|
28
|
+
return {
|
|
29
|
+
id,
|
|
30
|
+
eventKey: `completeful.${topic}`,
|
|
31
|
+
occurredAt: toUnixMilliseconds(event?.created ?? event?.created_at, context.occurredAt),
|
|
32
|
+
source: {
|
|
33
|
+
kind: 'webhook',
|
|
34
|
+
provider: 'completeful',
|
|
35
|
+
ref: context.webhookId || undefined,
|
|
36
|
+
metadata: {
|
|
37
|
+
provider_event_id: event?.id || null,
|
|
38
|
+
provider_webhook_id: context.providerWebhookId || null,
|
|
39
|
+
shop_id: context.shopId || event?.data?.shop_id || null,
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
payload: event,
|
|
43
|
+
accountId: context.accountId,
|
|
44
|
+
subject: subject ? String(subject) : undefined,
|
|
45
|
+
correlationId: context.correlationId,
|
|
46
|
+
causationId: context.causationId,
|
|
47
|
+
metadata: context.metadata,
|
|
48
|
+
};
|
|
49
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export {
|
|
2
|
+
DEFAULT_COMPLETEFUL_API_ORIGIN,
|
|
3
|
+
CompletefulApiError,
|
|
4
|
+
completefulApiBase,
|
|
5
|
+
completefulKeyMode,
|
|
6
|
+
createCompletefulClient,
|
|
7
|
+
} from './client.js';
|
|
8
|
+
|
|
9
|
+
export {
|
|
10
|
+
COMPLETEFUL_TOOL_DEFINITIONS,
|
|
11
|
+
getCompletefulToolDefinition,
|
|
12
|
+
executeCompletefulProviderTool,
|
|
13
|
+
createCompletefulProviderAdapter,
|
|
14
|
+
} from './tools.js';
|
|
15
|
+
|
|
16
|
+
export {
|
|
17
|
+
COMPLETEFUL_WEBHOOK_TOLERANCE_SECONDS,
|
|
18
|
+
computeCompletefulWebhookSignature,
|
|
19
|
+
verifyCompletefulWebhook,
|
|
20
|
+
} from './webhooks.js';
|
|
21
|
+
|
|
22
|
+
export { normalizeCompletefulEvent } from './events.js';
|