@inneranimalmedia/agentsam-sdk 2.6.5 → 2.6.7
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 +29 -0
- package/apps/README.md +5 -0
- package/apps/cad-creator/README.md +4 -4
- package/apps/cad-creator/shared/cad/package.json +1 -1
- package/apps/client-cms-editor/AGENTS.md +12 -7
- package/apps/client-cms-editor/README.md +76 -48
- package/apps/client-cms-editor/agentsam.app.json +26 -9
- package/apps/client-cms-editor/backend/package.json +20 -3
- package/apps/client-cms-editor/backend/src/api/client.ts +134 -101
- package/apps/client-cms-editor/backend/src/index.ts +1 -1
- package/apps/client-cms-editor/backend/src/model.ts +11 -115
- package/apps/client-cms-editor/backend/src/preview/bridge.ts +1 -1
- package/apps/client-cms-editor/backend/tsconfig.json +6 -1
- package/apps/client-cms-editor/bin/agentsam-cms.js +262 -0
- package/apps/client-cms-editor/bin/agentsam-cms.mjs +2 -228
- package/apps/client-cms-editor/frontend/package.json +16 -7
- package/apps/client-cms-editor/frontend/src/AgentSamDrawer.tsx +9 -41
- package/apps/client-cms-editor/frontend/src/CmsAgentSurface.tsx +19 -174
- package/apps/client-cms-editor/frontend/src/adapters/heuristic.ts +29 -0
- package/apps/client-cms-editor/frontend/src/adapters/http.ts +628 -0
- package/apps/client-cms-editor/frontend/src/adapters/memory.ts +510 -0
- package/apps/client-cms-editor/frontend/src/editor/CmsEditor.tsx +213 -0
- package/apps/client-cms-editor/frontend/src/editor/CmsEditorProvider.tsx +20 -0
- package/apps/client-cms-editor/frontend/src/editor/canvas/PreviewCanvas.tsx +53 -0
- package/apps/client-cms-editor/frontend/src/{CmsEditor.tsx → editor/legacy/CmsEditorPrototype.tsx} +52 -23
- package/apps/client-cms-editor/frontend/src/editor/useCmsEditorController.ts +218 -0
- package/apps/client-cms-editor/frontend/src/index.ts +19 -5
- package/apps/client-cms-editor/frontend/src/lib/agent-host.ts +24 -0
- package/apps/client-cms-editor/frontend/src/main.tsx +82 -8
- package/apps/client-cms-editor/frontend/src/mount.tsx +92 -30
- package/apps/client-cms-editor/frontend/src/styles/agentsam-drawer.css +1 -1
- package/apps/client-cms-editor/frontend/src/styles/cmsShell.css +8 -8
- package/apps/client-cms-editor/frontend/src/styles/studio.css +55 -3
- package/apps/client-cms-editor/frontend/tsconfig.json +12 -1
- package/apps/client-cms-editor/frontend/vite.config.ts +12 -0
- package/apps/client-cms-editor/package-lock.json +973 -134
- package/apps/client-cms-editor/package.json +118 -6
- package/apps/client-cms-editor/reference/harvest/HARVEST_RECEIPT.json +201 -0
- package/apps/client-cms-editor/reference/harvest/PROVENANCE_HISTORY.txt +10 -0
- package/apps/client-cms-editor/reference/harvest/README.md +8 -0
- package/apps/client-cms-editor/reference/harvest/plans/ARCHIVE-INTAKE.md +135 -0
- package/apps/client-cms-editor/reference/harvest/plans/CHATGPT-IDENTITY-HARVEST.md +83 -0
- package/apps/client-cms-editor/reference/harvest/plans/CMS-EDITOR-HARVEST.md +166 -0
- package/apps/client-cms-editor/reference/harvest/plans/HARVEST-INDEX.md +196 -0
- package/apps/client-cms-editor/reference/harvest/plans/INNERANIMALS-CONTENT-001.md +137 -0
- package/apps/client-cms-editor/reference/harvest/plans/NO-IMPLICIT-SIDE-EFFECTS.md +87 -0
- package/apps/client-cms-editor/reference/harvest/plans/STOREFRONT-SURFACE-MAP.md +140 -0
- package/apps/client-cms-editor/reference/harvest/plans/THEME-INNERANIMALS-HARVEST.md +137 -0
- package/apps/client-cms-editor/reference/harvest/plans/TOOLING-LAB.md +63 -0
- package/apps/client-cms-editor/reference/harvest/plans/harvest-manifest.json +97 -0
- package/apps/client-cms-editor/reference/harvest/plans/local-cms-harvest-schema.sql +328 -0
- package/apps/client-cms-editor/shared/cms/package.json +17 -7
- package/apps/client-cms-editor/shared/cms/src/adapter.ts +204 -0
- package/apps/client-cms-editor/shared/cms/src/agent-context.ts +7 -5
- package/apps/client-cms-editor/shared/cms/src/editor-types.ts +32 -0
- package/apps/client-cms-editor/shared/cms/src/host.ts +82 -0
- package/apps/client-cms-editor/shared/cms/src/index.ts +4 -0
- package/apps/client-cms-editor/shared/cms/src/map.ts +115 -0
- package/apps/client-cms-editor/shared/cms/src/starter-pack.ts +158 -0
- package/contracts/source-types.v1.json +353 -0
- package/docs/CMS_CONTEXTUAL_COMPOSER.md +1 -1
- package/docs/PRODUCT_LIFECYCLE.md +566 -0
- package/docs/THEME_REFINERY.md +2 -2
- package/docs/architecture/AGENTSAM_RUNTIME_PROTOCOL.md +40 -20
- package/docs/content-studio/REVISION_GATE_2026-09-27.md +1 -1
- package/docs/plans/LOCAL_STUDIO_DESKTOP_RELEASE_2026-09-29.md +150 -0
- package/migrations/d1/0017_identity_native_oauth.sql +21 -0
- package/native/agentsam-machine/Cargo.lock +426 -0
- package/native/agentsam-machine/Cargo.toml +9 -0
- package/native/agentsam-machine/cli/Cargo.toml +14 -0
- package/native/agentsam-machine/cli/src/main.rs +77 -0
- package/native/agentsam-machine/core/Cargo.toml +15 -0
- package/native/agentsam-machine/core/src/assets.rs +790 -0
- package/native/agentsam-machine/core/src/bound.rs +298 -0
- package/native/agentsam-machine/core/src/enrich.rs +706 -0
- package/native/agentsam-machine/core/src/frontend.rs +442 -0
- package/native/agentsam-machine/core/src/lib.rs +1086 -0
- package/native/agentsam-machine/core/src/liquid.rs +528 -0
- package/native/agentsam-machine/core/src/source_types.rs +78 -0
- package/package.json +51 -21
- package/packages/agentsam-brand/README.md +1 -1
- package/packages/agentsam-brand/package.json +4 -4
- package/packages/agentsam-brand/src/index.js +1 -1
- package/packages/agentsam-contracts/package.json +13 -3
- package/packages/agentsam-contracts/src/tools.ts +22 -0
- package/packages/agentsam-errors/package.json +13 -3
- package/packages/agentsam-knowledge/package.json +18 -4
- package/packages/agentsam-knowledge/src/autorag/index.js +10 -3
- package/packages/agentsam-knowledge/src/backends/index.js +33 -1
- package/packages/agentsam-knowledge/test/autorag.test.mjs +60 -1
- package/packages/agentsam-nav/package.json +24 -6
- package/packages/agentsam-queue-control/README.md +1 -1
- package/packages/agentsam-queue-control/package.json +7 -2
- package/packages/agentsam-rapid-rust/src/main.rs +1 -1
- package/packages/agentsam-repository/package.json +13 -3
- package/packages/agentsam-repository/src/source-types.js +8 -0
- package/packages/agentsam-vault/package.json +14 -4
- package/packages/agentsam-workbench/package.json +15 -4
- package/packages/agentsam-workbench/src/agent/ToolPermissionRequest.tsx +94 -0
- package/packages/agentsam-workbench/src/agent/index.ts +2 -0
- package/packages/agentsam-workbench/src/agent/tool-permission.css +134 -0
- package/packages/connectors/cloudflare/package.json +13 -3
- package/packages/connectors/cloudflare/src/api-client.js +3 -2
- package/packages/connectors/cloudflare/src/families/vectorize.js +127 -0
- package/packages/connectors/cloudflare/src/index.js +1 -0
- package/packages/heuristic-theme/README.md +2 -2
- package/packages/heuristic-theme/package.json +8 -3
- package/packages/heuristic-theme/src/registry.js +2 -2
- package/packages/heuristic-theme/src/theme.js +1 -1
- package/packages/heuristic-theme/test/theme.test.mjs +1 -1
- package/packages/identity/.agentsam/features/oauth-login-portal/agentsam.feature.json +1 -1
- package/packages/identity/.agentsam/features/oauth-login-portal/providers.json +27 -7
- package/packages/identity/README.md +2 -2
- package/packages/identity/migrations/D1_SCHEMA_MAPPING.md +18 -15
- package/packages/identity/migrations/apply-portable.js +109 -0
- package/packages/identity/migrations/sqlite/004_identity_oauth_consent_catalog.sql +1 -1
- package/packages/identity/migrations/sqlite/005_identity_company_native.sql +52 -0
- package/packages/identity/package.json +27 -6
- package/packages/identity/schema/agentsam.identity/manifest.json +101 -0
- package/packages/identity/scripts/local-identity-bridge.mjs +13 -7
- package/packages/identity/scripts/preview-auth-portal.mjs +6 -6
- package/packages/identity/src/adapters/cloudflare-d1/index.js +8 -401
- package/packages/identity/src/adapters/iam-compat/index.js +540 -0
- package/packages/identity/src/adapters/portable-d1/index.js +18 -0
- package/packages/identity/src/adapters/portable-store.js +479 -0
- package/packages/identity/src/adapters/sqlite/index.js +13 -312
- package/packages/identity/src/contracts/auth-config.js +0 -1
- package/packages/identity/src/contracts/identity-store.js +56 -5
- package/packages/identity/src/contracts/provider.js +1 -0
- package/packages/identity/src/contracts/sign-in-options.js +104 -0
- package/packages/identity/src/core/constants.js +1 -1
- package/packages/identity/src/core/session-policy.js +31 -0
- package/packages/identity/src/frontend/auth-portal/pages/login.html +6 -6
- package/packages/identity/src/frontend/auth-portal/pages/reset.html +5 -5
- package/packages/identity/src/frontend/auth-portal/pages/signup.html +5 -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 +6 -37
- package/packages/identity/src/index.js +28 -1
- package/packages/identity/src/migrations/README.md +23 -23
- package/packages/identity/src/oauth/README.md +1 -1
- package/packages/identity/src/oauth/credentials.js +10 -11
- package/packages/identity/src/oauth/google-desktop-exchange.js +195 -27
- package/packages/identity/src/oauth/iam-platform.js +21 -9
- package/packages/identity/src/oauth/native-handoff.js +136 -0
- package/packages/identity/src/providers/chatgpt/headers.js +65 -0
- package/packages/identity/src/providers/chatgpt/index.js +86 -0
- package/packages/identity/src/providers/chatgpt/mapper.js +43 -0
- package/packages/identity/src/providers/chatgpt/paths.js +45 -0
- package/packages/identity/src/providers/github/oauth.js +1 -2
- package/packages/identity/src/providers/github/profile.js +16 -2
- package/packages/identity/src/providers/index.js +11 -3
- package/packages/identity/src/server/identity-service.js +2 -1
- package/packages/identity/src/server/worker-router.js +71 -18
- package/packages/identity/tests/chatgpt-provider.test.mjs +75 -0
- package/packages/identity/tests/google-desktop-identity-login.test.mjs +210 -0
- package/packages/identity/tests/identity-init-scaffold.test.mjs +15 -4
- package/packages/identity/tests/lane1-identity-store-parity.test.mjs +527 -0
- package/packages/identity/tests/lane1-packed-consumer.test.mjs +175 -0
- package/packages/identity/tests/native-oauth-handoff.test.mjs +292 -0
- package/packages/identity/tests/oauth-credentials.test.mjs +4 -4
- package/packages/identity/tests/preview-auth-portal.test.mjs +4 -2
- package/packages/identity/tests/session-routes-policy.test.mjs +13 -1
- package/packages/identity/tests/worker-runtime-boundary.test.mjs +11 -0
- package/packages/providers/completeful/package.json +7 -2
- package/packages/theme-church-site/package.json +17 -6
- package/packages/theme-church-site/src/harvest.json +4 -2
- package/packages/theme-church-site/src/index.js +7 -3
- package/packages/theme-church-site/test/theme.test.mjs +4 -2
- package/packages/theme-companions-site/package.json +17 -6
- package/packages/theme-companions-site/src/harvest.json +4 -2
- package/packages/theme-companions-site/src/index.js +7 -3
- package/packages/theme-companions-site/test/theme.test.mjs +4 -2
- package/packages/theme-floors-site/package.json +17 -6
- package/packages/theme-floors-site/src/harvest.json +4 -2
- package/packages/theme-floors-site/src/index.js +7 -3
- package/packages/theme-floors-site/test/theme.test.mjs +4 -2
- package/packages/theme-fuelnfree-site/package.json +17 -6
- package/packages/theme-fuelnfree-site/src/harvest.json +4 -2
- package/packages/theme-fuelnfree-site/src/index.js +7 -3
- package/packages/theme-fuelnfree-site/test/theme.test.mjs +4 -2
- package/packages/theme-handyman-site/package.json +17 -6
- package/packages/theme-handyman-site/src/harvest.json +4 -2
- package/packages/theme-handyman-site/src/index.js +7 -3
- package/packages/theme-handyman-site/test/theme.test.mjs +4 -2
- package/packages/theme-insurance-site/package.json +17 -6
- package/packages/theme-insurance-site/src/harvest.json +4 -2
- package/packages/theme-insurance-site/src/index.js +7 -3
- package/packages/theme-insurance-site/test/theme.test.mjs +4 -2
- package/packages/theme-scenes/README.md +1 -1
- package/packages/theme-scenes/package.json +4 -3
- package/packages/theme-scenes/src/registry.js +187 -0
- package/packages/theme-shinshu-site/package.json +17 -6
- package/packages/theme-shinshu-site/src/harvest.json +4 -2
- package/packages/theme-shinshu-site/src/index.js +7 -3
- package/packages/theme-shinshu-site/test/theme.test.mjs +4 -2
- package/packages/work-graph/package.json +14 -4
- package/protocol/FILEMETA_V1.md +2 -2
- package/protocol/capabilities/manifest.json +1 -1
- package/protocol/database/agentsam.schema-pack.v1.schema.json +72 -0
- package/protocol/presets/catalog.json +2 -2
- package/protocol/theme-refinery/lineage-registry.json +105 -0
- package/protocol/theme-refinery/product-metadata.schema.json +21 -1
- package/skills/grok-auth/SKILL.md +110 -0
- package/skills/grok-auth/agentsam.skill.json +25 -0
- package/skills/grok-auth/references/grok-identity.md +64 -0
- package/skills/grok-auth/references/per-user-data.md +49 -0
- package/skills/grok-auth/references/prewired-and-env.md +54 -0
- package/skills/grok-auth/references/session-ui.md +133 -0
- package/skills/grok-auth/references/sign-in-methods.md +55 -0
- package/skills/grok-auth/references/wiring.md +71 -0
- package/skills/grok-building-games/SKILL.md +213 -0
- package/skills/grok-building-games/agentsam.skill.json +25 -0
- package/skills/grok-building-games/references/3d-libs.md +64 -0
- package/skills/grok-building-games/references/ai-pathfinding.md +122 -0
- package/skills/grok-building-games/references/audio.md +129 -0
- package/skills/grok-building-games/references/babylon.md +202 -0
- package/skills/grok-building-games/references/collision-physics.md +122 -0
- package/skills/grok-building-games/references/ecs-architecture.md +111 -0
- package/skills/grok-building-games/references/game-feel-juice.md +110 -0
- package/skills/grok-building-games/references/genres/board-card-chess.md +89 -0
- package/skills/grok-building-games/references/genres/endless-runner.md +83 -0
- package/skills/grok-building-games/references/genres/fps.md +105 -0
- package/skills/grok-building-games/references/genres/platformer-2d.md +97 -0
- package/skills/grok-building-games/references/genres/puzzle-match3-tetris.md +131 -0
- package/skills/grok-building-games/references/genres/racing-kart.md +106 -0
- package/skills/grok-building-games/references/genres/topdown-twin-stick.md +97 -0
- package/skills/grok-building-games/references/genres/tower-defense.md +84 -0
- package/skills/grok-building-games/references/genres/voxel-minecraft.md +89 -0
- package/skills/grok-building-games/references/input.md +139 -0
- package/skills/grok-building-games/references/phaser.md +277 -0
- package/skills/grok-building-games/references/procedural-generation.md +141 -0
- package/skills/grok-building-games/references/save-persistence.md +108 -0
- package/skills/grok-building-games/references/threejs-foundational.md +148 -0
- package/skills/grok-controls/SKILL.md +274 -0
- package/skills/grok-controls/agentsam.skill.json +25 -0
- package/skills/grok-design-ui/SKILL.md +122 -0
- package/skills/grok-design-ui/agentsam.skill.json +25 -0
- package/skills/grok-design-ui/references/animations.md +379 -0
- package/skills/grok-design-ui/references/performance.md +88 -0
- package/skills/grok-design-ui/references/refined-ui.md +384 -0
- package/skills/grok-design-ui/references/surfaces.md +247 -0
- package/skills/grok-design-ui/references/typography.md +123 -0
- package/skills/grok-game-animation-frames/SKILL.md +84 -0
- package/skills/grok-game-animation-frames/agentsam.skill.json +25 -0
- package/skills/grok-game-asset-core/SKILL.md +69 -0
- package/skills/grok-game-asset-core/agentsam.skill.json +25 -0
- package/skills/grok-game-character-consistency/SKILL.md +69 -0
- package/skills/grok-game-character-consistency/agentsam.skill.json +25 -0
- package/skills/grok-game-tilesets/SKILL.md +65 -0
- package/skills/grok-game-tilesets/agentsam.skill.json +25 -0
- package/skills/grok-game-ui-icons/SKILL.md +56 -0
- package/skills/grok-game-ui-icons/agentsam.skill.json +25 -0
- package/skills/grok-generate2dmap/LICENSE +21 -0
- package/skills/grok-generate2dmap/SKILL.md +120 -0
- package/skills/grok-generate2dmap/SOURCE.md +6 -0
- package/skills/grok-generate2dmap/agentsam.skill.json +25 -0
- package/skills/grok-generate2dmap/references/deliverables.md +101 -0
- package/skills/grok-generate2dmap/references/layered-map-contract.md +209 -0
- package/skills/grok-generate2dmap/references/map-strategies.md +341 -0
- package/skills/grok-generate2dmap/references/object-production-gate.md +24 -0
- package/skills/grok-generate2dmap/references/pipeline.md +149 -0
- package/skills/grok-generate2dmap/references/prop-pack-contract.md +174 -0
- package/skills/grok-generate2dmap/references/side-scroll-stages.md +29 -0
- package/skills/grok-generate2dmap/scripts/compose_layered_preview.py +157 -0
- package/skills/grok-generate2dmap/scripts/extract_prop_pack.py +369 -0
- package/skills/grok-generate2dsprite/LICENSE +21 -0
- package/skills/grok-generate2dsprite/SKILL.md +313 -0
- package/skills/grok-generate2dsprite/SOURCE.md +6 -0
- package/skills/grok-generate2dsprite/agentsam.skill.json +25 -0
- package/skills/grok-generate2dsprite/references/modes.md +124 -0
- package/skills/grok-generate2dsprite/references/prompt-rules.md +315 -0
- package/skills/grok-generate2dsprite/scripts/generate2dsprite.py +1031 -0
- package/skills/grok-generate2dsprite/scripts/make_layout_guide.py +109 -0
- package/skills/grok-imagine/SKILL.md +201 -0
- package/skills/grok-imagine/agentsam.skill.json +25 -0
- package/skills/grok-multiplayer-p2p/SKILL.md +111 -0
- package/skills/grok-multiplayer-p2p/agentsam.skill.json +25 -0
- package/skills/grok-multiplayer-p2p/references/react-binding.md +144 -0
- package/skills/grok-multiplayer-p2p/references/signaling-relay.md +269 -0
- package/skills/grok-neon/SKILL.md +157 -0
- package/skills/grok-neon/agentsam.skill.json +25 -0
- package/skills/grok-og/SKILL.md +102 -0
- package/skills/grok-og/agentsam.skill.json +25 -0
- package/skills/grok-og/references/brand-pass.md +53 -0
- package/skills/grok-og/references/custom-card.md +107 -0
- package/skills/grok-og/references/favicon-and-icons.md +48 -0
- package/skills/grok-og/references/og-type-contract.md +18 -0
- package/skills/grok-og/references/placeholder-card.md +21 -0
- package/skills/grok-og/references/x-banner.md +41 -0
- package/skills/grok-threejs/SKILL.md +67 -0
- package/skills/grok-threejs/agentsam.skill.json +25 -0
- package/skills/grok-threejs/references/llms-full.txt +2780 -0
- package/skills/grok-video2dsprite/LICENSE +21 -0
- package/skills/grok-video2dsprite/SKILL.md +236 -0
- package/skills/grok-video2dsprite/SOURCE.md +6 -0
- package/skills/grok-video2dsprite/agentsam.skill.json +25 -0
- package/skills/grok-video2dsprite/references/pipeline.md +90 -0
- package/skills/grok-video2dsprite/references/prompt-rules.md +63 -0
- package/skills/grok-video2dsprite/scripts/video2dsprite.py +490 -0
- package/skills/grok-xai-api/SKILL.md +152 -0
- package/skills/grok-xai-api/agentsam.skill.json +25 -0
- package/src/cli/command-catalog.js +46 -4
- package/src/cli/dispatch.js +1 -0
- package/src/cli.js +10 -0
- package/src/cloudflare/runtime-status.js +2 -1
- package/src/commands/autorag.js +67 -13
- package/src/commands/cheat-sheet.js +29 -4
- package/src/commands/codebaseindex.js +45 -2
- package/src/commands/knowledge.js +59 -2
- package/src/commands/machine-binary.js +103 -0
- package/src/commands/machine.js +137 -0
- package/src/commands/security.js +67 -4
- package/src/commands/setup.js +33 -16
- package/src/commands/status.js +8 -1
- package/src/features/resolve.js +1 -0
- package/src/knowledge/engine.js +21 -2
- package/src/knowledge/runtime-discovery.js +127 -0
- package/src/lib/identity-scaffold.js +53 -13
- package/src/lib/setup/recipes.js +1 -1
- package/src/models/discovery.js +40 -22
- package/src/models/inventory-core.d.ts +105 -0
- package/src/models/inventory-core.js +54 -6
- package/src/security/logs.js +3 -0
- package/src/ui/cli/help.js +41 -0
- package/test/apps-scaffold-contract.test.mjs +3 -2
- package/test/cli/api-key-env-whoami.test.mjs +2 -2
- package/test/cli/catalog-authority.test.mjs +64 -0
- package/test/cli/machine-command.test.mjs +34 -0
- package/test/fixtures/project-authority/customer-app/.agentsam/app.json +5 -0
- package/test/fixtures/project-authority/customer-app/apps/my-product/index.ts +1 -0
- package/test/fixtures/project-authority/customer-app/wrangler.toml +17 -0
- package/test/integration/autorag-project-authority.integration.test.mjs +51 -0
- package/test/integration/autorag-runtime-discovery.test.mjs +107 -0
- package/test/integration/cms-app-scaffold.test.mjs +37 -31
- package/test/integration/cms-site-tenancy-contract.test.mjs +28 -17
- package/test/integration/codebaseindex-ingest.test.mjs +41 -0
- package/test/integration/database-hosted-honesty.test.mjs +49 -0
- package/test/integration/desktop-keychain-boundary.test.mjs +45 -0
- package/test/integration/hosted-work-host-authority.test.mjs +47 -0
- package/test/integration/inventory-eligibility.test.mjs +59 -0
- package/test/integration/local-provider-bridge.test.mjs +65 -0
- package/test/integration/local-studio-settings-production.test.mjs +40 -0
- package/test/integration/lockfile-sync.test.mjs +26 -0
- package/test/integration/provider-env-cli.test.mjs +13 -3
- package/test/integration/runtime-status.integration.test.mjs +16 -1
- package/test/integration/theme-package-registry.test.mjs +31 -0
- package/test/repository-snapshot-view.test.mjs +2 -2
- package/test/security.test.mjs +14 -0
- package/test/terminal-machine-identity.test.mjs +2 -2
- package/apps/client-cms-editor/backend/src/demo-bootstrap.ts +0 -145
- package/packages/agentsam-nav/dist/Nav.d.ts +0 -43
- package/packages/agentsam-nav/dist/NavCollapsible.d.ts +0 -10
- package/packages/agentsam-nav/dist/NavContent.d.ts +0 -2
- package/packages/agentsam-nav/dist/NavFooter.d.ts +0 -2
- package/packages/agentsam-nav/dist/NavGroup.d.ts +0 -3
- package/packages/agentsam-nav/dist/NavHeader.d.ts +0 -2
- package/packages/agentsam-nav/dist/NavMenu.d.ts +0 -22
- package/packages/agentsam-nav/dist/NavProvider.d.ts +0 -35
- package/packages/agentsam-nav/dist/NavTrigger.d.ts +0 -2
- package/packages/agentsam-nav/dist/Surfaces.d.ts +0 -41
- package/packages/agentsam-nav/dist/browser.d.ts +0 -11
- package/packages/agentsam-nav/dist/browser.global.js +0 -132
- package/packages/agentsam-nav/dist/browser.js +0 -613
- package/packages/agentsam-nav/dist/contracts.d.ts +0 -76
- package/packages/agentsam-nav/dist/index.d.ts +0 -11
- package/packages/agentsam-nav/dist/index.js +0 -614
- package/packages/agentsam-nav/dist/legacy.css +0 -83
- package/packages/agentsam-nav/dist/shell.css +0 -113
- package/packages/agentsam-nav/dist/theme.css +0 -113
- package/packages/agentsam-nav/dist/utils.d.ts +0 -1
- package/packages/agentsam-repository/src/goap.js.bak-20260922011251 +0 -670
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* Alias ≠ authority: skill tips and SAM operation ids live here so help is not a prose-only dump.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
/** @typedef {{ id: string, aliases?: string[], summary: string, topic: string, skill?: string, operation?: string, common?: boolean }} CliCommandEntry */
|
|
6
|
+
/** @typedef {{ id: string, aliases?: string[], summary: string, topic: string, skill?: string, operation?: string, common?: boolean, usage?: string[], options?: Array<{ flag: string, description: string }> }} CliCommandEntry */
|
|
7
7
|
|
|
8
8
|
/** @type {CliCommandEntry[]} */
|
|
9
9
|
export const CLI_COMMAND_CATALOG = Object.freeze([
|
|
@@ -13,11 +13,36 @@ export const CLI_COMMAND_CATALOG = Object.freeze([
|
|
|
13
13
|
{ id: 'plugins', summary: 'Install and manage AgentSam plugins', topic: 'create', skill: 'agentsam-app-fundamentals' },
|
|
14
14
|
{ id: 'dev', summary: 'Run this project’s npm dev script', topic: 'work', skill: 'agentsam-app-fundamentals' },
|
|
15
15
|
{ id: 'inspect', summary: 'Bounded repository inspect / authority view', topic: 'work', skill: 'agentsam-app-fundamentals', operation: 'repository.inspect', common: true },
|
|
16
|
+
{ id: 'machine', summary: 'Deterministic local machine perception (inspect / asset discovery)', topic: 'work', skill: 'agentsam-app-fundamentals', operation: 'machine.inspect', common: true },
|
|
16
17
|
{ id: 'capabilities', summary: 'Inspect capability contracts', topic: 'create', skill: 'agentsam-app-fundamentals' },
|
|
17
|
-
{
|
|
18
|
+
{
|
|
19
|
+
id: 'setup',
|
|
20
|
+
summary: 'Discover → plan → approve → install capabilities (Homebrew-style)',
|
|
21
|
+
topic: 'start',
|
|
22
|
+
skill: 'agentsam-app-fundamentals',
|
|
23
|
+
common: true,
|
|
24
|
+
usage: [
|
|
25
|
+
'agentsam setup [capability-id] [--dry-run|--yes]',
|
|
26
|
+
'agentsam setup runtime [--profile <id>] [--dry-run|--yes]',
|
|
27
|
+
'agentsam setup --list',
|
|
28
|
+
],
|
|
29
|
+
},
|
|
18
30
|
{ id: 'skills', aliases: ['skill'], summary: 'List or load portable skill instructions', topic: 'create', skill: 'agentsam-app-fundamentals', common: true },
|
|
19
31
|
{ id: 'context', summary: 'Git + bridge context from any repo', topic: 'work', skill: 'agentsam-app-fundamentals' },
|
|
20
|
-
{
|
|
32
|
+
{
|
|
33
|
+
id: 'status',
|
|
34
|
+
summary: 'Account, models, terminal, and live deploy awareness',
|
|
35
|
+
topic: 'runtime',
|
|
36
|
+
skill: 'agentsam-progression-guard',
|
|
37
|
+
common: true,
|
|
38
|
+
usage: ['agentsam status [--offline] [--no-discover] [--json] [-i|--interactive]'],
|
|
39
|
+
options: [
|
|
40
|
+
{ flag: '--offline', description: 'Skip network-dependent status probes.' },
|
|
41
|
+
{ flag: '--no-discover', description: 'Skip provider model discovery.' },
|
|
42
|
+
{ flag: '--json', description: 'Emit the machine-readable status + next-action plan.' },
|
|
43
|
+
{ flag: '-i, --interactive', description: 'Open the interactive next-action menu.' },
|
|
44
|
+
],
|
|
45
|
+
},
|
|
21
46
|
{ id: 'db', summary: 'Project-local SQLite status/init', topic: 'runtime', skill: 'agentsam-app-fundamentals' },
|
|
22
47
|
{ id: 'models', summary: 'Probe hosted/local model availability', topic: 'start', skill: 'agentsam-app-fundamentals', common: true },
|
|
23
48
|
{ id: 'providers', summary: 'Configure machine provider credentials', topic: 'start', skill: 'agentsam-app-fundamentals' },
|
|
@@ -47,7 +72,24 @@ export const CLI_COMMAND_CATALOG = Object.freeze([
|
|
|
47
72
|
{ id: 'eval', summary: 'Context fixtures and live eval telemetry', topic: 'runtime', skill: 'agentsam-app-fundamentals' },
|
|
48
73
|
{ id: 'index', summary: 'Plan/run incremental AST (+ optional embeddings)', topic: 'work', skill: 'agentsam-codebaseindex', operation: 'codebaseindex.ingest' },
|
|
49
74
|
{ id: 'search', summary: 'Retrieve indexed code/text', topic: 'work', skill: 'agentsam-codebaseindex' },
|
|
50
|
-
{
|
|
75
|
+
{
|
|
76
|
+
id: 'repo',
|
|
77
|
+
summary: 'Repository snapshot / observations',
|
|
78
|
+
topic: 'work',
|
|
79
|
+
skill: 'agentsam-app-fundamentals',
|
|
80
|
+
operation: 'repository.inspect',
|
|
81
|
+
usage: [
|
|
82
|
+
'agentsam repo [snapshot] [--cwd <path>] [--churn-days <days>] [--save] [--json]',
|
|
83
|
+
'agentsam repo history [--cwd <path>]',
|
|
84
|
+
'agentsam repo compare [--cwd <path>]',
|
|
85
|
+
],
|
|
86
|
+
options: [
|
|
87
|
+
{ flag: '--json', description: 'Emit the full deterministic repository-intelligence receipt.' },
|
|
88
|
+
{ flag: '--save', description: 'Persist the observation for history/compare.' },
|
|
89
|
+
{ flag: '--churn-days <days>', description: 'Set the Git churn window (1..3650).' },
|
|
90
|
+
{ flag: '--cwd <path>', description: 'Inspect another repository root.' },
|
|
91
|
+
],
|
|
92
|
+
},
|
|
51
93
|
{ id: 'init', summary: 'Knowledge setup or local scaffold', topic: 'create', skill: 'agentsam-app-fundamentals' },
|
|
52
94
|
{ id: 'codebaseindex', aliases: ['ingest', 'codebase-index'], summary: 'Guided codebase ingest: materials, allowlist, embeddings, storage', topic: 'work', skill: 'agentsam-codebaseindex', operation: 'codebaseindex.ingest', common: true },
|
|
53
95
|
{ id: 'brand', summary: 'Deterministic brand intelligence', topic: 'work', skill: 'agentsam-app-fundamentals', operation: 'brand.scan' },
|
package/src/cli/dispatch.js
CHANGED
|
@@ -10,6 +10,7 @@ const HANDLERS = {
|
|
|
10
10
|
codebaseindex: async () => (await import('../commands/codebaseindex.js')).runCodebaseindex,
|
|
11
11
|
ingest: async () => (await import('../commands/codebaseindex.js')).runCodebaseindex,
|
|
12
12
|
'codebase-index': async () => (await import('../commands/codebaseindex.js')).runCodebaseindex,
|
|
13
|
+
machine: async () => (await import('../commands/machine.js')).runMachine,
|
|
13
14
|
skill: async () => (await import('../commands/skill.js')).runSkill,
|
|
14
15
|
skills: async () => (await import('../commands/skills.js')).runSkills,
|
|
15
16
|
};
|
package/src/cli.js
CHANGED
|
@@ -33,6 +33,7 @@ import { runDeployReceipt } from './commands/deploy-receipt.js';
|
|
|
33
33
|
import { runSecurity } from './commands/security.js';
|
|
34
34
|
import { runRecon } from './commands/recon.js';
|
|
35
35
|
import { runCad } from './commands/cad.js';
|
|
36
|
+
import { runMachine } from './commands/machine.js';
|
|
36
37
|
import { runSkills } from './commands/skills.js';
|
|
37
38
|
import { runSkill } from './commands/skill.js';
|
|
38
39
|
import { runEval } from './commands/eval.js';
|
|
@@ -95,6 +96,7 @@ function printLegacyHelp() {
|
|
|
95
96
|
agentsam plugins list|install|connect|status|remove [@agentsam-mcp]
|
|
96
97
|
agentsam dev Run this project's existing npm dev script
|
|
97
98
|
agentsam inspect [--json] Bounded repository index by default; use --view full for authority envelope
|
|
99
|
+
agentsam machine inspect Native deterministic perception + asset discovery (--json)
|
|
98
100
|
agentsam brand [scan|…] Deterministic brand intelligence on repository.snapshot authority
|
|
99
101
|
agentsam plan brand Composable brand normalization plan (--goap optional)
|
|
100
102
|
agentsam deploy Graduate an AgentSam project intentionally
|
|
@@ -450,6 +452,14 @@ if (command === '--version' || command === '-v') {
|
|
|
450
452
|
} else if (command === 'inspect') {
|
|
451
453
|
try { await runInspect(rest); }
|
|
452
454
|
catch (e) { reportCliError(e); process.exitCode = 1; }
|
|
455
|
+
} else if (command === 'machine') {
|
|
456
|
+
try {
|
|
457
|
+
const code = await runMachine(rest);
|
|
458
|
+
if (typeof code === 'number' && code !== 0) process.exitCode = code;
|
|
459
|
+
} catch (e) {
|
|
460
|
+
reportCliError(e);
|
|
461
|
+
process.exitCode = e?.exitCode || 1;
|
|
462
|
+
}
|
|
453
463
|
} else if (command === 'capabilities') {
|
|
454
464
|
try { await runCapabilities(rest); }
|
|
455
465
|
catch (e) { reportCliError(e); process.exitCode = 1; }
|
|
@@ -37,7 +37,7 @@ function parseJsonc(source) {
|
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
export function parseWranglerToml(source = '') {
|
|
40
|
-
const result = { vars: {}, d1_databases: [], r2_buckets: [], hyperdrive: [], kv_namespaces: [], services: [] };
|
|
40
|
+
const result = { vars: {}, d1_databases: [], r2_buckets: [], hyperdrive: [], kv_namespaces: [], services: [], vectorize: [] };
|
|
41
41
|
const lines = source.split(/\r?\n/);
|
|
42
42
|
let currentSection = '';
|
|
43
43
|
let currentBlock = null;
|
|
@@ -55,6 +55,7 @@ export function parseWranglerToml(source = '') {
|
|
|
55
55
|
else if (currentSection === 'hyperdrive') result.hyperdrive.push(currentBlock);
|
|
56
56
|
else if (currentSection === 'kv_namespaces') result.kv_namespaces.push(currentBlock);
|
|
57
57
|
else if (currentSection === 'services') result.services.push(currentBlock);
|
|
58
|
+
else if (currentSection === 'vectorize') result.vectorize.push(currentBlock);
|
|
58
59
|
continue;
|
|
59
60
|
}
|
|
60
61
|
|
package/src/commands/autorag.js
CHANGED
|
@@ -2,10 +2,12 @@ import fs from 'node:fs';
|
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
import { parseArgs } from 'node:util';
|
|
4
4
|
import { createInterface } from 'node:readline/promises';
|
|
5
|
-
import { repositoryRoot, readConfig, validateConfig, CONFIG_PATH } from '../knowledge/config.js';
|
|
5
|
+
import { repositoryRoot, readConfig, validateConfig, defaultConfig, scopeKey, CONFIG_PATH } from '../knowledge/config.js';
|
|
6
6
|
import { openSqliteStore } from '../knowledge/stores/sqlite.js';
|
|
7
7
|
import { openPostgresStore } from '../knowledge/stores/postgres.js';
|
|
8
8
|
import { planIndex, runIndex, retrieve } from '../knowledge/engine.js';
|
|
9
|
+
import { discoverKnowledgeRuntime } from '../knowledge/runtime-discovery.js';
|
|
10
|
+
import { getRepositoryId, portableRepositoryIdFromGit, tryReadProjectConfig } from '../lib/project-config.js';
|
|
9
11
|
import { discoverAutoRag, recommendAutoRag, safeAutoRagConfig, runAutoRagProbe, createProviderRegistry, createBackendRegistry } from '../../packages/agentsam-knowledge/src/index.js';
|
|
10
12
|
|
|
11
13
|
const show = value => console.log(JSON.stringify(value, null, 2));
|
|
@@ -16,6 +18,12 @@ const parse = argv => parseArgs({ args: argv, allowPositionals: true, options: {
|
|
|
16
18
|
kind: { type: 'string' }, scope: { type: 'string' }, provider: { type: 'string' }, backend: { type: 'string' }, model: { type: 'string' }, dimensions: { type: 'string' }, semantic: { type: 'boolean' }, 'allow-paid': { type: 'boolean' }, query: { type: 'string' },
|
|
17
19
|
} });
|
|
18
20
|
function readExisting(root) { try { return readConfig(root); } catch (error) { if (error.code === 'ENOENT') return null; throw error; } }
|
|
21
|
+
function generationConfig(root, existing) {
|
|
22
|
+
if (existing) return existing;
|
|
23
|
+
const project = tryReadProjectConfig(root);
|
|
24
|
+
const repositoryId = getRepositoryId(project) || portableRepositoryIdFromGit(root);
|
|
25
|
+
return repositoryId ? defaultConfig({ repositoryId }) : null;
|
|
26
|
+
}
|
|
19
27
|
function writeConfig(root, config) {
|
|
20
28
|
const filename = path.join(root, CONFIG_PATH); fs.mkdirSync(path.dirname(filename), { recursive: true, mode: 0o700 });
|
|
21
29
|
const safe = JSON.stringify(validateConfig(config), null, 2) + '\n';
|
|
@@ -28,10 +36,20 @@ function adapterFor(config) {
|
|
|
28
36
|
return { validate: profile => adapter.validate(profile), async embed(text, profile, context) { return context?.kind === 'query' ? adapter.embedQuery(text, profile, context) : (await adapter.embedDocuments([text], profile, context))[0]; } };
|
|
29
37
|
}
|
|
30
38
|
async function storeFor(root, config, readOnly = false) { return config.storage.driver === 'sqlite' ? openSqliteStore(localPath(root), { readOnly }) : openPostgresStore(process.env[config.storage.connection_env]); }
|
|
31
|
-
function defaults(discovery, opts, existing) {
|
|
39
|
+
function defaults(discovery, opts, existing, runtime) {
|
|
32
40
|
const purpose = opts.kind || existing?.scope?.name || 'code';
|
|
33
|
-
const
|
|
41
|
+
const declaredVectorize = (runtime?.cloudflare?.vectorize || []).filter(row => row.binding && row.index);
|
|
42
|
+
const adoptVectorize = !opts.backend && !existing?.lane?.backend && declaredVectorize.length === 1;
|
|
43
|
+
const backend = opts.backend || existing?.lane?.backend || (adoptVectorize ? 'cloudflare_vectorize' : 'local_exact');
|
|
44
|
+
const recommendation = recommendAutoRag({ discovery, purpose, include: opts.scope ? split(opts.scope) : existing?.scope?.include, provider: opts.provider || 'none', backend, semantic: Boolean(opts.semantic) });
|
|
34
45
|
const config = safeAutoRagConfig({ existing: existing || {}, recommendation, repositoryId: existing?.repository_id || discovery.repository.identity, projectKey: existing?.project_key || discovery.repository.identity });
|
|
46
|
+
if (adoptVectorize) {
|
|
47
|
+
const resource = declaredVectorize[0];
|
|
48
|
+
config.lane.id = `${purpose}-cloudflare-vectorize`;
|
|
49
|
+
config.lane.backend = 'cloudflare_vectorize';
|
|
50
|
+
config.lane.binding = resource.binding;
|
|
51
|
+
config.lane.index = resource.index;
|
|
52
|
+
}
|
|
35
53
|
if (opts.provider) {
|
|
36
54
|
const models = { fixture: 'deterministic', gemini: 'gemini-embedding-2', openai: 'text-embedding-3-small', 'workers-ai': '@cf/baai/bge-base-en-v1.5', ollama: 'nomic-embed-text' };
|
|
37
55
|
config.embedding = opts.provider === 'none' ? { provider: 'none', model: 'none', revision: '1', dimensions: 0, parameters: {} } : { provider: opts.provider, model: opts.model || models[opts.provider] || '', revision: '1', dimensions: Number(opts.dimensions || (opts.provider === 'fixture' ? 3 : 768)), parameters: { task: 'code retrieval' } };
|
|
@@ -43,7 +61,7 @@ async function interactiveOptions(discovery, opts) {
|
|
|
43
61
|
const prompt = createInterface({ input: process.stdin, output: process.stdout });
|
|
44
62
|
try {
|
|
45
63
|
const kind = opts.kind || await prompt.question('What kind of knowledge? code, documents, schema, media, memory, mixed [code]: ') || 'code';
|
|
46
|
-
const suggested =
|
|
64
|
+
const suggested = recommendAutoRag({ discovery, purpose: kind }).scope.join(',');
|
|
47
65
|
const scope = opts.scope || await prompt.question(`Sources (literal paths, comma separated) [${suggested || '.'}]: `) || suggested || '.';
|
|
48
66
|
const semantic = opts.semantic || (await prompt.question('Enable semantic embeddings for this setup? [no]: ')).toLowerCase() === 'yes';
|
|
49
67
|
const provider = opts.provider || (semantic ? await prompt.question('Provider: fixture, gemini, openai, workers-ai, ollama [fixture]: ') || 'fixture' : 'none');
|
|
@@ -55,18 +73,54 @@ export async function runAutoRag(argv) {
|
|
|
55
73
|
if (opts.help || !['setup', 'status', 'doctor', 'lanes', 'configure', 'probe', 'providers', 'backends', 'scope'].includes(command)) {
|
|
56
74
|
console.log('agentsam autorag setup|status|doctor|lanes|configure|probe|providers|backends|scope [--cwd PATH] [--yes] [--kind code|documents|schema|media|memory|mixed] [--scope a,b] [--provider none|fixture|gemini|openai|workers-ai|ollama] [--backend local_exact|postgres_pgvector|supabase_pgvector|cloudflare_vectorize] [--semantic]'); return;
|
|
57
75
|
}
|
|
58
|
-
const root = repositoryRoot(opts.cwd); const discovery = await discoverAutoRag({ root }); const existing = readExisting(root);
|
|
59
|
-
if (command === 'providers')
|
|
60
|
-
|
|
61
|
-
|
|
76
|
+
const root = repositoryRoot(opts.cwd); const discovery = await discoverAutoRag({ root }); const existing = readExisting(root); const runtime = discoverKnowledgeRuntime(root, { knowledgeConfig: existing });
|
|
77
|
+
if (command === 'providers') {
|
|
78
|
+
const providers = await createProviderRegistry().capabilities();
|
|
79
|
+
const workersAi = runtime.resources.workers_ai;
|
|
80
|
+
return show(providers.map(item => item.id === 'workers-ai'
|
|
81
|
+
? { ...item, runtime_configured: workersAi.configured, runtime_binding: workersAi.binding, locally_executable: workersAi.locally_executable, remotely_executable: workersAi.remotely_executable, credential_state: workersAi.credential_state }
|
|
82
|
+
: item));
|
|
83
|
+
}
|
|
84
|
+
if (command === 'backends') {
|
|
85
|
+
const backends = createBackendRegistry().capabilities();
|
|
86
|
+
const vectorize = runtime.resources.vectorize;
|
|
87
|
+
return show(backends.map(item => item.id === 'cloudflare_vectorize'
|
|
88
|
+
? { ...item, declared_resources: vectorize, locally_executable: vectorize.some(row => row.locally_executable), remotely_executable: vectorize.some(row => row.remotely_executable), conflicts: runtime.conflicts }
|
|
89
|
+
: item));
|
|
90
|
+
}
|
|
91
|
+
if (command === 'status') {
|
|
92
|
+
const generationProfile = runtime.local_index.exists ? generationConfig(root, existing) : null;
|
|
93
|
+
const generation = generationProfile ? await (async () => {
|
|
94
|
+
const store = await storeFor(root, generationProfile, true);
|
|
95
|
+
try { return await store?.active(scopeKey(generationProfile)); }
|
|
96
|
+
finally { await store?.close(); }
|
|
97
|
+
})() : null;
|
|
98
|
+
return show({ discovery, config: existing || null, project_context: runtime, runtime, generation });
|
|
99
|
+
}
|
|
62
100
|
if (command === 'doctor') {
|
|
63
|
-
const
|
|
64
|
-
|
|
65
|
-
|
|
101
|
+
const hasRuntimeLane = runtime.lanes.some(lane => lane.configured);
|
|
102
|
+
const checks = [
|
|
103
|
+
{ check: 'knowledge_authority', ok: Boolean(existing) || hasRuntimeLane, detail: existing ? CONFIG_PATH : hasRuntimeLane ? 'Detected repository knowledge runtime.' : 'No local config or declared runtime lane found.' },
|
|
104
|
+
{ check: 'local_sqlite', ok: runtime.local_index.exists, blocking: false, detail: runtime.local_index.exists ? runtime.local_index.path : 'Not indexed yet; run agentsam index run or agentsam autorag probe.' },
|
|
105
|
+
{ check: 'git_merkle', ok: discovery.repository.merkle, blocking: false, detail: discovery.repository.merkle ? '.agentsam/merkle.json' : 'No Merkle snapshot yet; run agentsam merkle root . --json when snapshot evidence is needed.' },
|
|
106
|
+
];
|
|
107
|
+
if (existing?.embedding && existing.embedding.provider !== 'none') {
|
|
108
|
+
try { adapterFor(existing).validate(existing.embedding); checks.push({ check: 'provider:' + existing.embedding.provider, ok: true }); }
|
|
109
|
+
catch (error) { checks.push({ check: 'provider:' + existing.embedding.provider, ok: false, detail: error.message }); }
|
|
110
|
+
}
|
|
111
|
+
if (runtime.resources.vectorize.length) checks.push({ check: 'cloudflare_vectorize', ok: runtime.conflicts.length === 0 && runtime.resources.vectorize.every(row => row.configured && (row.locally_executable || row.remotely_executable)), detail: runtime.resources.vectorize });
|
|
112
|
+
if (runtime.resources.workers_ai.observed) checks.push({ check: 'workers_ai_runtime', ok: runtime.resources.workers_ai.remotely_executable || runtime.resources.workers_ai.locally_executable, detail: runtime.resources.workers_ai });
|
|
113
|
+
if (runtime.conflicts.length) checks.push({ check: 'project_context_conflicts', ok: false, detail: runtime.conflicts });
|
|
114
|
+
return show({ ok: checks.filter(check => check.blocking !== false).every(check => check.ok), checks, project_context: runtime, runtime });
|
|
115
|
+
}
|
|
116
|
+
if (command === 'lanes') {
|
|
117
|
+
const configured = existing ? [existing.lane || { id: 'legacy-local', backend: existing.storage.driver === 'sqlite' ? 'local_exact' : 'postgres_pgvector', source: CONFIG_PATH }] : [];
|
|
118
|
+
const laneKey = lane => [lane.backend, lane.binding || '', lane.index || ''].join(':');
|
|
119
|
+
const seen = new Set(configured.map(laneKey));
|
|
120
|
+
return show([...configured, ...runtime.lanes.filter(lane => !seen.has(laneKey(lane)))]);
|
|
66
121
|
}
|
|
67
|
-
if (command === 'lanes') return show(existing ? [existing.lane || { id: 'legacy-local', backend: existing.storage.driver === 'sqlite' ? 'local_exact' : 'postgres_pgvector' }] : []);
|
|
68
122
|
if (command === 'setup' || command === 'configure' || command === 'scope') {
|
|
69
|
-
const selected = opts.yes ? opts : await interactiveOptions(discovery, opts); const { recommendation, config } = defaults(discovery, selected, existing);
|
|
123
|
+
const selected = opts.yes ? opts : await interactiveOptions(discovery, opts); const { recommendation, config } = defaults(discovery, selected, existing, runtime);
|
|
70
124
|
writeConfig(root, config); return show({ action: command, config: CONFIG_PATH, recommendation, config, next: ['agentsam autorag probe', 'agentsam index plan', 'agentsam index run', 'agentsam search "symbol or phrase"'] });
|
|
71
125
|
}
|
|
72
126
|
if (!existing) throw new Error('AutoRAG is not configured. Run agentsam autorag setup first.');
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Canonical Agent Sam cheat-sheet — gcloud-like command groups.
|
|
3
3
|
* Old top-level commands remain as compatibility aliases.
|
|
4
|
+
* Every row shows a copy-pasteable `agentsam …` invocation.
|
|
4
5
|
*/
|
|
5
6
|
|
|
6
7
|
const GROUPS = Object.freeze([
|
|
@@ -19,8 +20,13 @@ const GROUPS = Object.freeze([
|
|
|
19
20
|
label: 'Repository',
|
|
20
21
|
commands: [
|
|
21
22
|
['inspect', 'Bounded repository authority view'],
|
|
23
|
+
['machine', 'Deterministic local perception + asset discovery'],
|
|
24
|
+
['machine inspect', 'Inspect a path (file or directory)'],
|
|
22
25
|
['recon', 'Bounded-worker finding packets'],
|
|
23
26
|
['codebaseindex', 'AST ingest + optional embeddings'],
|
|
27
|
+
['index', 'Project inventory + knowledge index commands'],
|
|
28
|
+
['index status', 'Show knowledge index freshness'],
|
|
29
|
+
['search', 'Retrieve from the local knowledge index'],
|
|
24
30
|
['merkle', 'Integrity snapshots'],
|
|
25
31
|
['security', 'Dependency + trust-boundary scan'],
|
|
26
32
|
],
|
|
@@ -103,16 +109,30 @@ const GROUPS = Object.freeze([
|
|
|
103
109
|
['update', 'Component update preview (gcloud-like)'],
|
|
104
110
|
['billing', 'Billing account relationships (not --billing-project)'],
|
|
105
111
|
['cheat-sheet', 'This page'],
|
|
106
|
-
['version', '
|
|
112
|
+
['version', 'Print CLI version'],
|
|
107
113
|
],
|
|
108
114
|
},
|
|
109
115
|
]);
|
|
110
116
|
|
|
117
|
+
/** Expand "a / b" rows into copy-pasteable `agentsam …` invocations. */
|
|
118
|
+
export function agentsamInvocations(cmd) {
|
|
119
|
+
const raw = String(cmd || '').trim();
|
|
120
|
+
if (!raw) return [];
|
|
121
|
+
if (raw.includes(' / ')) {
|
|
122
|
+
return raw.split(' / ').map((part) => `agentsam ${part.trim()}`);
|
|
123
|
+
}
|
|
124
|
+
return [`agentsam ${raw}`];
|
|
125
|
+
}
|
|
126
|
+
|
|
111
127
|
export function listCheatSheetGroups() {
|
|
112
128
|
return GROUPS.map((group) => ({
|
|
113
129
|
id: group.id,
|
|
114
130
|
label: group.label,
|
|
115
|
-
commands: group.commands.map(([cmd, summary]) => ({
|
|
131
|
+
commands: group.commands.map(([cmd, summary]) => ({
|
|
132
|
+
cmd,
|
|
133
|
+
summary,
|
|
134
|
+
invocations: agentsamInvocations(cmd),
|
|
135
|
+
})),
|
|
116
136
|
}));
|
|
117
137
|
}
|
|
118
138
|
|
|
@@ -120,13 +140,18 @@ export function renderCheatSheet(version) {
|
|
|
120
140
|
const lines = [
|
|
121
141
|
'',
|
|
122
142
|
` Agent Sam cheat-sheet${version ? ` · v${version}` : ''}`,
|
|
123
|
-
' Organized hierarchy ·
|
|
143
|
+
' Organized hierarchy · each row shows a runnable `agentsam …` command.',
|
|
124
144
|
'',
|
|
125
145
|
];
|
|
126
146
|
for (const group of GROUPS) {
|
|
127
147
|
lines.push(` ${group.label}`);
|
|
128
148
|
for (const [cmd, summary] of group.commands) {
|
|
129
|
-
|
|
149
|
+
const invocations = agentsamInvocations(cmd);
|
|
150
|
+
const primary = invocations[0] || `agentsam ${cmd}`;
|
|
151
|
+
lines.push(` ${primary.padEnd(52)} ${summary}`);
|
|
152
|
+
for (const extra of invocations.slice(1)) {
|
|
153
|
+
lines.push(` ${extra.padEnd(52)} (same group)`);
|
|
154
|
+
}
|
|
130
155
|
}
|
|
131
156
|
lines.push('');
|
|
132
157
|
}
|
|
@@ -16,6 +16,8 @@ import { openSqliteStore } from '../knowledge/stores/sqlite.js';
|
|
|
16
16
|
import { openPostgresStore } from '../knowledge/stores/postgres.js';
|
|
17
17
|
import { planIndex, retrieve, runIndex } from '../knowledge/engine.js';
|
|
18
18
|
import { createProviderRegistry } from '../../packages/agentsam-knowledge/src/providers/index.js';
|
|
19
|
+
import { createBackendRegistry } from '../../packages/agentsam-knowledge/src/backends/index.js';
|
|
20
|
+
import { discoverProjectContext } from '../knowledge/runtime-discovery.js';
|
|
19
21
|
import { ensureProjectManifest, getRepositoryId, portableRepositoryIdFromGit, tryReadProjectConfig } from '../lib/project-config.js';
|
|
20
22
|
import { parsePastedPaths, stageMaterials } from '../indexing/ingest/materials.js';
|
|
21
23
|
import {
|
|
@@ -74,6 +76,21 @@ function writeKnowledgeConfig(root, config) {
|
|
|
74
76
|
return validated;
|
|
75
77
|
}
|
|
76
78
|
|
|
79
|
+
function resolveVectorLane(root, vectors, input = {}) {
|
|
80
|
+
if (vectors !== 'vectorize') return null;
|
|
81
|
+
const explicitBinding = String(input.vectorBinding || input.binding || '').trim();
|
|
82
|
+
const explicitIndex = String(input.vectorIndex || input.index || '').trim();
|
|
83
|
+
if (explicitBinding || explicitIndex) {
|
|
84
|
+
if (!explicitBinding || !explicitIndex) throw new Error('Vectorize requires both vectorBinding and vectorIndex when either is supplied.');
|
|
85
|
+
return { backend: 'cloudflare_vectorize', binding: explicitBinding, index: explicitIndex };
|
|
86
|
+
}
|
|
87
|
+
const context = discoverProjectContext(root);
|
|
88
|
+
const resources = context.resources.vectorize.filter(row => row.configured);
|
|
89
|
+
if (resources.length === 1) return { backend: 'cloudflare_vectorize', binding: resources[0].binding, index: resources[0].index };
|
|
90
|
+
if (!resources.length) throw new Error('No Cloudflare Vectorize binding is declared by this project. Configure Wrangler or pass vectorBinding/vectorIndex explicitly.');
|
|
91
|
+
throw new Error('Multiple Cloudflare Vectorize bindings are declared. Select vectorBinding/vectorIndex explicitly.');
|
|
92
|
+
}
|
|
93
|
+
|
|
77
94
|
function loadOrBuildConfig(root, preferences) {
|
|
78
95
|
const project = tryReadProjectConfig(root) || ensureProjectManifest(root, {});
|
|
79
96
|
const repositoryId = getRepositoryId(project) || portableRepositoryIdFromGit(root) || preferences.repositoryId;
|
|
@@ -103,7 +120,14 @@ function loadOrBuildConfig(root, preferences) {
|
|
|
103
120
|
storage: preferences.storage === 'postgres'
|
|
104
121
|
? { driver: 'postgres', connection_env: preferences.connectionEnv || 'AGENTSAM_DATABASE_URL' }
|
|
105
122
|
: { driver: 'sqlite' },
|
|
106
|
-
lane: {
|
|
123
|
+
lane: preferences.vectorLane ? {
|
|
124
|
+
id: `${preferences.scopeName || 'default'}-cloudflare-vectorize`,
|
|
125
|
+
backend: 'cloudflare_vectorize',
|
|
126
|
+
resource: null,
|
|
127
|
+
binding: preferences.vectorLane.binding,
|
|
128
|
+
index: preferences.vectorLane.index,
|
|
129
|
+
metric: 'cosine',
|
|
130
|
+
} : {
|
|
107
131
|
id: `${preferences.scopeName || 'default'}-ingest`,
|
|
108
132
|
backend: preferences.storage === 'postgres' ? 'postgres_pgvector' : 'local_exact',
|
|
109
133
|
resource: null,
|
|
@@ -172,11 +196,13 @@ export async function runCodebaseindexIngest(input = {}, ctx = {}) {
|
|
|
172
196
|
const vectors = input.vectors || (embedding.provider === 'none' ? 'none'
|
|
173
197
|
: storage === 'postgres' ? 'pgvector' : 'sqlite_exact');
|
|
174
198
|
|
|
199
|
+
const vectorLane = resolveVectorLane(root, vectors, input);
|
|
175
200
|
const config = loadOrBuildConfig(root, {
|
|
176
201
|
include,
|
|
177
202
|
exclude,
|
|
178
203
|
embedding,
|
|
179
204
|
storage,
|
|
205
|
+
vectorLane,
|
|
180
206
|
scopeName: input.scope || 'ingest',
|
|
181
207
|
connectionEnv: input.connectionEnv,
|
|
182
208
|
});
|
|
@@ -185,6 +211,9 @@ export async function runCodebaseindexIngest(input = {}, ctx = {}) {
|
|
|
185
211
|
jobGraph = advanceJobGraph(jobGraph, 'lane.resolve');
|
|
186
212
|
|
|
187
213
|
const embed = Boolean(input.embed) && embedding.provider !== 'none';
|
|
214
|
+
if (vectors === 'vectorize' && !embed && !input.planOnly) {
|
|
215
|
+
throw new Error('Cloudflare Vectorize execution requires an embedding provider and embed=true. Use planOnly to inspect the lane without writing vectors.');
|
|
216
|
+
}
|
|
188
217
|
const store = await openStore(root, config, false);
|
|
189
218
|
try {
|
|
190
219
|
if (input.planOnly) {
|
|
@@ -214,12 +243,26 @@ export async function runCodebaseindexIngest(input = {}, ctx = {}) {
|
|
|
214
243
|
validate: (...args) => (adapter ??= providerAdapter(config.embedding)).validate(...args),
|
|
215
244
|
embed: (...args) => (adapter ??= providerAdapter(config.embedding)).embed(...args),
|
|
216
245
|
};
|
|
246
|
+
const vectorBackend = config.lane?.backend === 'cloudflare_vectorize'
|
|
247
|
+
? createBackendRegistry().get('cloudflare_vectorize')
|
|
248
|
+
: null;
|
|
249
|
+
const vectorContext = {
|
|
250
|
+
...(ctx.cloudflare || {}),
|
|
251
|
+
...(input.vectorContext || {}),
|
|
252
|
+
env: input.env || ctx.env || process.env,
|
|
253
|
+
ownerId: input.ownerId || ctx.ownerId || ctx.owner_id || '',
|
|
254
|
+
accountId: input.accountId || ctx.accountId || '',
|
|
255
|
+
workerBinding: input.workerBinding || ctx.workerBinding,
|
|
256
|
+
apiClient: input.apiClient || ctx.apiClient,
|
|
257
|
+
};
|
|
217
258
|
const result = await runIndex({
|
|
218
259
|
root,
|
|
219
260
|
config,
|
|
220
261
|
store,
|
|
221
262
|
embed,
|
|
222
263
|
embedder,
|
|
264
|
+
vectorBackend,
|
|
265
|
+
vectorContext,
|
|
223
266
|
maxInputs: Number(input.maxInputs ?? 200),
|
|
224
267
|
maxCharacters: Number(input.maxCharacters ?? 400000),
|
|
225
268
|
});
|
|
@@ -568,7 +611,7 @@ async function runWizard(root, opts) {
|
|
|
568
611
|
}));
|
|
569
612
|
const storage = lane === 'supabase' ? 'postgres' : 'sqlite';
|
|
570
613
|
if (lane === 'vectorize') {
|
|
571
|
-
note('Vectorize
|
|
614
|
+
note('Uses this project’s declared Vectorize binding via Worker runtime or the current user’s authorized Cloudflare API transport.', 'Lane note');
|
|
572
615
|
}
|
|
573
616
|
if (lane === 'supabase') {
|
|
574
617
|
note('Uses AGENTSAM_DATABASE_URL / Hyperdrive-style postgres. Owner IAM already has node-api.', 'Lane note');
|
|
@@ -169,10 +169,66 @@ export async function runSearch(argv) {
|
|
|
169
169
|
finally { await store?.close(); }
|
|
170
170
|
}
|
|
171
171
|
|
|
172
|
+
function compactNumber(value) {
|
|
173
|
+
const n = Number(value || 0);
|
|
174
|
+
if (!Number.isFinite(n)) return '0';
|
|
175
|
+
if (Math.abs(n) >= 1_000_000) return `${(n / 1_000_000).toFixed(n >= 10_000_000 ? 1 : 2).replace(/\.0+$/, '')}m`;
|
|
176
|
+
if (Math.abs(n) >= 1_000) return `${(n / 1_000).toFixed(n >= 100_000 ? 0 : 1).replace(/\.0$/, '')}k`;
|
|
177
|
+
return String(n);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
export function renderRepositoryObservation(observation) {
|
|
181
|
+
const data = observation?.data || {};
|
|
182
|
+
const git = data.git || {};
|
|
183
|
+
const summary = data.summary || {};
|
|
184
|
+
const top = Array.isArray(data.top_level) ? data.top_level.slice(0, 5) : [];
|
|
185
|
+
const pressure = Array.isArray(data.pressure_points) ? data.pressure_points.slice(0, 6) : [];
|
|
186
|
+
const dirty = git.dirty ? `dirty · ${git.changed_paths || 0} changed` : 'clean';
|
|
187
|
+
const head = git.head_sha ? String(git.head_sha).slice(0, 10) : 'unknown';
|
|
188
|
+
|
|
189
|
+
const lines = [
|
|
190
|
+
'',
|
|
191
|
+
' Agent Sam · repository',
|
|
192
|
+
'',
|
|
193
|
+
` repo ${data.repo_name || path.basename(data.repo_root || '') || 'unknown'}`,
|
|
194
|
+
` root ${data.repo_root || 'unknown'}`,
|
|
195
|
+
` git ${git.branch || 'unknown'} @ ${head} · ${dirty}`,
|
|
196
|
+
` scale ${compactNumber(summary.file_count)} files · ${compactNumber(summary.source_file_count)} source · ${compactNumber(summary.total_lines)} lines`,
|
|
197
|
+
];
|
|
198
|
+
|
|
199
|
+
if (top.length) {
|
|
200
|
+
lines.push('', ' Primary areas');
|
|
201
|
+
for (const row of top) {
|
|
202
|
+
lines.push(` ${String(row.path || '.').padEnd(28)} ${compactNumber(row.files)} files · ${compactNumber(row.lines)} lines`);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
if (pressure.length) {
|
|
207
|
+
lines.push('', ' Change pressure');
|
|
208
|
+
for (const row of pressure) {
|
|
209
|
+
lines.push(` ${String(row.path || '.').padEnd(28)} pressure ${Number(row.pressure_score || 0).toFixed(1)} · stability ${Number(row.stability_score || 0).toFixed(1)}`);
|
|
210
|
+
}
|
|
211
|
+
lines.push(' relative activity heuristics — not quality grades');
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
lines.push(
|
|
215
|
+
'',
|
|
216
|
+
' More',
|
|
217
|
+
' agentsam repo --json full deterministic receipt',
|
|
218
|
+
' agentsam repo history saved observations',
|
|
219
|
+
' agentsam repo compare compare latest saved observations',
|
|
220
|
+
' agentsam inspect bounded architecture / authority view',
|
|
221
|
+
' agentsam machine inspect native deterministic perception',
|
|
222
|
+
'',
|
|
223
|
+
);
|
|
224
|
+
return lines.join('\n');
|
|
225
|
+
}
|
|
226
|
+
|
|
172
227
|
export async function runRepository(argv) {
|
|
173
228
|
const { values: opts, positionals } = flags(argv, { save: { type: 'boolean' }, 'churn-days': { type: 'string' } });
|
|
174
229
|
const command = positionals[0] || 'snapshot';
|
|
175
|
-
if (opts.help) { console.log('agentsam repo snapshot [--cwd PATH] [--churn-days 30] [--save] [--json]\nagentsam repo history|compare [--cwd PATH]\
|
|
230
|
+
if (opts.help) { console.log('agentsam repo [snapshot] [--cwd PATH] [--churn-days 30] [--save] [--json]\nagentsam repo history|compare [--cwd PATH]\nDefault output is a human summary; --json emits the full deterministic receipt.'); return; }
|
|
231
|
+
if (command === 'context') throw new Error('Repository context is `agentsam context`. Use `agentsam repo snapshot|history|compare` for repository intelligence.');
|
|
176
232
|
if (positionals.length > 1 || !['snapshot', 'history', 'compare'].includes(command)) throw new Error('Use agentsam repo snapshot|history|compare.');
|
|
177
233
|
const root = repositoryRoot(opts.cwd);
|
|
178
234
|
let store;
|
|
@@ -190,6 +246,7 @@ export async function runRepository(argv) {
|
|
|
190
246
|
});
|
|
191
247
|
const observation = { id: randomUUID(), created_at: new Date().toISOString(), kind: 'repository-intelligence', data: JSON.parse(result.stdout) };
|
|
192
248
|
if (store) await store.observe(cacheNamespace(readConfig(root)), observation);
|
|
193
|
-
show(observation);
|
|
249
|
+
if (opts.json) show(observation);
|
|
250
|
+
else console.log(renderRepositoryObservation(observation));
|
|
194
251
|
} finally { await store?.close(); }
|
|
195
252
|
}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resolve the agentsam-machine native binary.
|
|
3
|
+
* Preference order:
|
|
4
|
+
* 1. AGENTSAM_MACHINE_BIN
|
|
5
|
+
* 2. agentsam-machine on PATH
|
|
6
|
+
* 3. Built binary under native/agentsam-machine/target/{release,debug}
|
|
7
|
+
* 4. cargo run --manifest-path … (dev fallback inside the SDK repo)
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import fs from 'node:fs';
|
|
11
|
+
import path from 'node:path';
|
|
12
|
+
import { fileURLToPath } from 'node:url';
|
|
13
|
+
import { spawnSync } from 'node:child_process';
|
|
14
|
+
|
|
15
|
+
const here = path.dirname(fileURLToPath(import.meta.url));
|
|
16
|
+
const sdkRoot = path.resolve(here, '../..');
|
|
17
|
+
const machineCrate = path.join(sdkRoot, 'native/agentsam-machine');
|
|
18
|
+
const machineManifest = path.join(machineCrate, 'Cargo.toml');
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* @typedef {{ kind: 'binary', path: string, source: string } | { kind: 'cargo', manifest: string, source: string } | { kind: 'missing', tried: string[] }} MachineBinaryResolution
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* @returns {MachineBinaryResolution}
|
|
26
|
+
*/
|
|
27
|
+
export function resolveMachineBinary(env = process.env) {
|
|
28
|
+
const tried = [];
|
|
29
|
+
|
|
30
|
+
const explicit = String(env.AGENTSAM_MACHINE_BIN || '').trim();
|
|
31
|
+
if (explicit) {
|
|
32
|
+
tried.push(explicit);
|
|
33
|
+
if (fs.existsSync(explicit) && fs.statSync(explicit).isFile()) {
|
|
34
|
+
return { kind: 'binary', path: explicit, source: 'AGENTSAM_MACHINE_BIN' };
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const pathHit = which('agentsam-machine');
|
|
39
|
+
if (pathHit) {
|
|
40
|
+
return { kind: 'binary', path: pathHit, source: 'PATH' };
|
|
41
|
+
}
|
|
42
|
+
tried.push('PATH:agentsam-machine');
|
|
43
|
+
|
|
44
|
+
for (const rel of ['target/release/agentsam-machine', 'target/debug/agentsam-machine']) {
|
|
45
|
+
const candidate = path.join(machineCrate, rel);
|
|
46
|
+
tried.push(candidate);
|
|
47
|
+
if (fs.existsSync(candidate) && fs.statSync(candidate).isFile()) {
|
|
48
|
+
return { kind: 'binary', path: candidate, source: rel.includes('release') ? 'crate-release' : 'crate-debug' };
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
if (fs.existsSync(machineManifest)) {
|
|
53
|
+
const cargo = which('cargo');
|
|
54
|
+
if (cargo) {
|
|
55
|
+
return { kind: 'cargo', manifest: machineManifest, source: 'cargo-run' };
|
|
56
|
+
}
|
|
57
|
+
tried.push('cargo');
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return { kind: 'missing', tried };
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* @param {MachineBinaryResolution} resolution
|
|
65
|
+
* @param {string[]} machineArgv args after `agentsam machine` (e.g. ['inspect', './site', '--json'])
|
|
66
|
+
* @param {{ stdio?: import('node:child_process').StdioOptions, env?: NodeJS.ProcessEnv }} [options]
|
|
67
|
+
*/
|
|
68
|
+
export function spawnMachine(resolution, machineArgv, options = {}) {
|
|
69
|
+
const env = options.env || process.env;
|
|
70
|
+
const stdio = options.stdio || 'inherit';
|
|
71
|
+
const maxBuffer = options.maxBuffer || 32 * 1024 * 1024;
|
|
72
|
+
|
|
73
|
+
if (resolution.kind === 'binary') {
|
|
74
|
+
return spawnSync(resolution.path, machineArgv, { stdio, env, encoding: 'utf8', maxBuffer });
|
|
75
|
+
}
|
|
76
|
+
if (resolution.kind === 'cargo') {
|
|
77
|
+
return spawnSync(
|
|
78
|
+
'cargo',
|
|
79
|
+
['run', '--quiet', '--manifest-path', resolution.manifest, '--bin', 'agentsam-machine', '--', ...machineArgv],
|
|
80
|
+
{ stdio, env, encoding: 'utf8', maxBuffer },
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
const err = new Error(
|
|
84
|
+
`agentsam-machine binary not found. Tried: ${(resolution.tried || []).join(', ') || '(none)'}. Build with: cargo build --manifest-path native/agentsam-machine/Cargo.toml --release`,
|
|
85
|
+
);
|
|
86
|
+
err.code = 'AGENTSAM_MACHINE_BINARY_MISSING';
|
|
87
|
+
throw err;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function which(cmd) {
|
|
91
|
+
const probe = process.platform === 'win32' ? ['where', [cmd]] : ['which', [cmd]];
|
|
92
|
+
const result = spawnSync(probe[0], probe[1], { encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'] });
|
|
93
|
+
if (result.status !== 0) return null;
|
|
94
|
+
const line = String(result.stdout || '')
|
|
95
|
+
.split(/\r?\n/)
|
|
96
|
+
.map((s) => s.trim())
|
|
97
|
+
.find(Boolean);
|
|
98
|
+
return line || null;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
export function machineSdkRoot() {
|
|
102
|
+
return sdkRoot;
|
|
103
|
+
}
|