@inneranimalmedia/agentsam-sdk 2.6.7 → 2.6.8
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/README.md +37 -0
- package/docs/REPO_FILE_MAP.txt +132 -0
- package/migrations/d1/0018_goap_control_plane_remaster.sql +40 -0
- package/migrations/d1/0019_agentsam_agent_run_plan_todo.sql +14 -0
- package/migrations/d1/README_PORTABLE_CONTROL_PLANE.md +20 -9
- package/migrations/runtime/0002_goap_blackboard_v1.sql +15 -0
- package/migrations/runtime/0004_agent_run_plan_linkage.sql +8 -0
- package/native/agentsam-machine/cli/Cargo.toml +8 -1
- package/native/agentsam-machine/cli/README.md +21 -0
- package/native/agentsam-machine/core/Cargo.toml +7 -0
- package/native/agentsam-machine/core/README.md +14 -0
- package/native/agentsam-machine/core/build.rs +33 -0
- package/native/agentsam-machine/core/contracts/source-types.v1.json +353 -0
- package/native/agentsam-machine/core/src/lib.rs +6 -0
- package/native/agentsam-machine/core/src/source_types.rs +2 -2
- package/package.json +16 -6
- package/packages/agentsam-errors/package.json +1 -1
- package/packages/agentsam-errors/src/index.js +1 -0
- package/packages/agentsam-errors/src/tool.js +56 -0
- package/packages/agentsam-errors/test/tool.test.mjs +58 -0
- package/packages/agentsam-goap/README.md +52 -0
- package/packages/agentsam-goap/package.json +37 -0
- package/packages/agentsam-goap/src/adapters/d1-sqlite.js +570 -0
- package/packages/agentsam-goap/src/adapters/memory.js +199 -0
- package/packages/agentsam-goap/src/contracts.js +226 -0
- package/packages/agentsam-goap/src/control-plane.js +112 -0
- package/packages/agentsam-goap/src/errors.js +157 -0
- package/packages/agentsam-goap/src/index.js +5 -0
- package/packages/agentsam-goap/src/world.js +202 -0
- package/packages/agentsam-goap/test/goap-control-plane.test.mjs +245 -0
- package/packages/agentsam-goap/test/world.test.mjs +79 -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 +135 -0
- package/packages/agentsam-nav/dist/browser.js +7290 -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 +7291 -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-repository/src/goap.js +13 -14
- package/packages/agentsam-repository/src/goap.js.bak-20260922011251 +670 -0
- package/packages/agentsam-repository/src/tickets.js +15 -22
- package/packages/agentsam-repository/test/goap-tickets-workspace-state.test.mjs +19 -8
- package/packages/connectors/cloudflare/package.json +3 -1
- package/packages/identity/tests/lane1-packed-consumer.test.mjs +1 -1
- package/python/agentsam_sdk/repository/intelligence/discovery.py +27 -2
- package/python/agentsam_sdk/repository/intelligence/git.py +4 -0
- package/python/tests/test_repository_intelligence.py +30 -0
- package/src/cli/command-catalog.js +2 -1
- package/src/cli.js +10 -1
- package/src/commands/goap-world.js +134 -0
- package/src/commands/goap.js +11 -4
- package/src/commands/machine-binary.js +33 -27
- package/src/commands/machine-runtime.js +266 -0
- package/src/commands/machine.js +122 -51
- package/src/commands/package.js +530 -0
- package/src/commands/plan-ledger.js +370 -0
- package/src/commands/plan.js +183 -0
- package/src/commands/skill.js +78 -17
- package/src/knowledge/source.js +1 -1
- package/src/lib/slash-commands.js +1 -1
- package/src/local/runtime-store.js +24 -2
- package/src/local/sqlite.js +17 -0
- package/src/sam/operations/package-audit.js +41 -0
- package/src/sam/seed.js +2 -0
- package/skills/grok-auth/SKILL.md +0 -110
- package/skills/grok-auth/agentsam.skill.json +0 -25
- package/skills/grok-auth/references/grok-identity.md +0 -64
- package/skills/grok-auth/references/per-user-data.md +0 -49
- package/skills/grok-auth/references/prewired-and-env.md +0 -54
- package/skills/grok-auth/references/session-ui.md +0 -133
- package/skills/grok-auth/references/sign-in-methods.md +0 -55
- package/skills/grok-auth/references/wiring.md +0 -71
- package/skills/grok-building-games/SKILL.md +0 -213
- package/skills/grok-building-games/agentsam.skill.json +0 -25
- package/skills/grok-building-games/references/3d-libs.md +0 -64
- package/skills/grok-building-games/references/ai-pathfinding.md +0 -122
- package/skills/grok-building-games/references/audio.md +0 -129
- package/skills/grok-building-games/references/babylon.md +0 -202
- package/skills/grok-building-games/references/collision-physics.md +0 -122
- package/skills/grok-building-games/references/ecs-architecture.md +0 -111
- package/skills/grok-building-games/references/game-feel-juice.md +0 -110
- package/skills/grok-building-games/references/genres/board-card-chess.md +0 -89
- package/skills/grok-building-games/references/genres/endless-runner.md +0 -83
- package/skills/grok-building-games/references/genres/fps.md +0 -105
- package/skills/grok-building-games/references/genres/platformer-2d.md +0 -97
- package/skills/grok-building-games/references/genres/puzzle-match3-tetris.md +0 -131
- package/skills/grok-building-games/references/genres/racing-kart.md +0 -106
- package/skills/grok-building-games/references/genres/topdown-twin-stick.md +0 -97
- package/skills/grok-building-games/references/genres/tower-defense.md +0 -84
- package/skills/grok-building-games/references/genres/voxel-minecraft.md +0 -89
- package/skills/grok-building-games/references/input.md +0 -139
- package/skills/grok-building-games/references/phaser.md +0 -277
- package/skills/grok-building-games/references/procedural-generation.md +0 -141
- package/skills/grok-building-games/references/save-persistence.md +0 -108
- package/skills/grok-building-games/references/threejs-foundational.md +0 -148
- package/skills/grok-controls/SKILL.md +0 -274
- package/skills/grok-controls/agentsam.skill.json +0 -25
- package/skills/grok-design-ui/SKILL.md +0 -122
- package/skills/grok-design-ui/agentsam.skill.json +0 -25
- package/skills/grok-design-ui/references/animations.md +0 -379
- package/skills/grok-design-ui/references/performance.md +0 -88
- package/skills/grok-design-ui/references/refined-ui.md +0 -384
- package/skills/grok-design-ui/references/surfaces.md +0 -247
- package/skills/grok-design-ui/references/typography.md +0 -123
- package/skills/grok-game-animation-frames/SKILL.md +0 -84
- package/skills/grok-game-animation-frames/agentsam.skill.json +0 -25
- package/skills/grok-game-asset-core/SKILL.md +0 -69
- package/skills/grok-game-asset-core/agentsam.skill.json +0 -25
- package/skills/grok-game-character-consistency/SKILL.md +0 -69
- package/skills/grok-game-character-consistency/agentsam.skill.json +0 -25
- package/skills/grok-game-tilesets/SKILL.md +0 -65
- package/skills/grok-game-tilesets/agentsam.skill.json +0 -25
- package/skills/grok-game-ui-icons/SKILL.md +0 -56
- package/skills/grok-game-ui-icons/agentsam.skill.json +0 -25
- package/skills/grok-generate2dmap/LICENSE +0 -21
- package/skills/grok-generate2dmap/SKILL.md +0 -120
- package/skills/grok-generate2dmap/SOURCE.md +0 -6
- package/skills/grok-generate2dmap/agentsam.skill.json +0 -25
- package/skills/grok-generate2dmap/references/deliverables.md +0 -101
- package/skills/grok-generate2dmap/references/layered-map-contract.md +0 -209
- package/skills/grok-generate2dmap/references/map-strategies.md +0 -341
- package/skills/grok-generate2dmap/references/object-production-gate.md +0 -24
- package/skills/grok-generate2dmap/references/pipeline.md +0 -149
- package/skills/grok-generate2dmap/references/prop-pack-contract.md +0 -174
- package/skills/grok-generate2dmap/references/side-scroll-stages.md +0 -29
- package/skills/grok-generate2dmap/scripts/compose_layered_preview.py +0 -157
- package/skills/grok-generate2dmap/scripts/extract_prop_pack.py +0 -369
- package/skills/grok-generate2dsprite/LICENSE +0 -21
- package/skills/grok-generate2dsprite/SKILL.md +0 -313
- package/skills/grok-generate2dsprite/SOURCE.md +0 -6
- package/skills/grok-generate2dsprite/agentsam.skill.json +0 -25
- package/skills/grok-generate2dsprite/references/modes.md +0 -124
- package/skills/grok-generate2dsprite/references/prompt-rules.md +0 -315
- package/skills/grok-generate2dsprite/scripts/generate2dsprite.py +0 -1031
- package/skills/grok-generate2dsprite/scripts/make_layout_guide.py +0 -109
- package/skills/grok-imagine/SKILL.md +0 -201
- package/skills/grok-imagine/agentsam.skill.json +0 -25
- package/skills/grok-multiplayer-p2p/SKILL.md +0 -111
- package/skills/grok-multiplayer-p2p/agentsam.skill.json +0 -25
- package/skills/grok-multiplayer-p2p/references/react-binding.md +0 -144
- package/skills/grok-multiplayer-p2p/references/signaling-relay.md +0 -269
- package/skills/grok-neon/SKILL.md +0 -157
- package/skills/grok-neon/agentsam.skill.json +0 -25
- package/skills/grok-og/SKILL.md +0 -102
- package/skills/grok-og/agentsam.skill.json +0 -25
- package/skills/grok-og/references/brand-pass.md +0 -53
- package/skills/grok-og/references/custom-card.md +0 -107
- package/skills/grok-og/references/favicon-and-icons.md +0 -48
- package/skills/grok-og/references/og-type-contract.md +0 -18
- package/skills/grok-og/references/placeholder-card.md +0 -21
- package/skills/grok-og/references/x-banner.md +0 -41
- package/skills/grok-threejs/SKILL.md +0 -67
- package/skills/grok-threejs/agentsam.skill.json +0 -25
- package/skills/grok-threejs/references/llms-full.txt +0 -2780
- package/skills/grok-video2dsprite/LICENSE +0 -21
- package/skills/grok-video2dsprite/SKILL.md +0 -236
- package/skills/grok-video2dsprite/SOURCE.md +0 -6
- package/skills/grok-video2dsprite/agentsam.skill.json +0 -25
- package/skills/grok-video2dsprite/references/pipeline.md +0 -90
- package/skills/grok-video2dsprite/references/prompt-rules.md +0 -63
- package/skills/grok-video2dsprite/scripts/video2dsprite.py +0 -490
- package/skills/grok-xai-api/SKILL.md +0 -152
- package/skills/grok-xai-api/agentsam.skill.json +0 -25
- package/test/account-session.test.mjs +0 -101
- package/test/agent-capabilities.test.mjs +0 -67
- package/test/app-authority-context.test.mjs +0 -32
- package/test/app-building-skills.test.mjs +0 -61
- package/test/apps-scaffold-contract.test.mjs +0 -115
- package/test/blender-cad.test.mjs +0 -146
- package/test/cad-docker.test.mjs +0 -96
- package/test/capabilities.test.mjs +0 -133
- package/test/cli/api-key-env-whoami.test.mjs +0 -129
- package/test/cli/catalog-authority.test.mjs +0 -64
- package/test/cli/codebaseindex-plan-ux.test.mjs +0 -37
- package/test/cli/eval-live.test.mjs +0 -219
- package/test/cli/go.test.mjs +0 -128
- package/test/cli/local-vault-and-provider-setup.test.mjs +0 -268
- package/test/cli/machine-command.test.mjs +0 -34
- package/test/cli/mcp-client.test.mjs +0 -256
- package/test/cli/preferences-runtime.test.mjs +0 -11
- package/test/cli/runtime-persist.test.mjs +0 -56
- package/test/cli/runtime-ui.test.mjs +0 -141
- package/test/cli/rust-command.test.mjs +0 -21
- package/test/cli/skill-npm-and-env.test.mjs +0 -52
- package/test/cli/status-actions.test.mjs +0 -88
- package/test/cli/wireframes-go-registry.test.mjs +0 -139
- package/test/cli-preferences.test.mjs +0 -46
- package/test/cloudflare-connector.test.mjs +0 -93
- package/test/cloudflare-runtime.test.mjs +0 -82
- package/test/context.test.mjs +0 -159
- package/test/credentials-audit.test.mjs +0 -113
- package/test/deploy-health-scan.test.mjs +0 -95
- package/test/deploy-receipt.test.mjs +0 -91
- package/test/dockerize.test.mjs +0 -93
- package/test/error-diagnostics.test.mjs +0 -124
- package/test/eval-context.test.mjs +0 -37
- package/test/execution-approvals.test.mjs +0 -27
- package/test/fixtures/cad/courtyard-house.json +0 -208
- package/test/fixtures/knowledge-rpc-worker.mjs +0 -16
- package/test/fixtures/project-authority/customer-app/.agentsam/app.json +0 -5
- package/test/fixtures/project-authority/customer-app/apps/my-product/index.ts +0 -1
- package/test/fixtures/project-authority/customer-app/wrangler.toml +0 -17
- package/test/gcloud-auth.test.mjs +0 -111
- package/test/go/build-source-identity.test.mjs +0 -31
- package/test/go/cloudflare-probe.test.mjs +0 -317
- package/test/go/distribution.test.mjs +0 -28
- package/test/google-cloud-connection.test.mjs +0 -83
- package/test/google-cloud-inventory.test.mjs +0 -64
- package/test/indexing-provider.test.mjs +0 -29
- package/test/init-options.test.mjs +0 -35
- package/test/integration/ai-access-onboarding.test.mjs +0 -47
- package/test/integration/app-command.test.mjs +0 -85
- package/test/integration/autorag-project-authority.integration.test.mjs +0 -51
- package/test/integration/autorag-runtime-discovery.test.mjs +0 -107
- package/test/integration/cad-discovery.test.mjs +0 -158
- package/test/integration/cad-docker-executor.test.mjs +0 -249
- package/test/integration/cad-execution.test.mjs +0 -184
- package/test/integration/cad-project-app.test.mjs +0 -31
- package/test/integration/cad-project-d1.test.mjs +0 -25
- package/test/integration/cad-project-native.test.mjs +0 -24
- package/test/integration/cad-project-workflow.test.mjs +0 -9
- package/test/integration/cad-project.test.mjs +0 -85
- package/test/integration/cli-help.test.mjs +0 -41
- package/test/integration/cms-app-scaffold.test.mjs +0 -77
- package/test/integration/cms-site-tenancy-contract.test.mjs +0 -268
- package/test/integration/codebaseindex-ingest.test.mjs +0 -255
- package/test/integration/core-client.integration.test.mjs +0 -55
- package/test/integration/database-hosted-honesty.test.mjs +0 -49
- package/test/integration/desktop-keychain-boundary.test.mjs +0 -45
- package/test/integration/error-runtime-rpc.test.mjs +0 -71
- package/test/integration/features-resolve.test.mjs +0 -147
- package/test/integration/hosted-work-host-authority.test.mjs +0 -47
- package/test/integration/icon-registry.test.mjs +0 -67
- package/test/integration/ingest-discover-models.test.mjs +0 -30
- package/test/integration/inspect-path-cli.test.mjs +0 -46
- package/test/integration/install-script.test.mjs +0 -110
- package/test/integration/inventory-core.test.mjs +0 -53
- package/test/integration/inventory-eligibility.test.mjs +0 -59
- package/test/integration/inventory-evidence.test.mjs +0 -125
- package/test/integration/knowledge-rpc.test.mjs +0 -112
- package/test/integration/local-fs.test.mjs +0 -113
- package/test/integration/local-provider-bridge.test.mjs +0 -65
- package/test/integration/local-studio-settings-production.test.mjs +0 -40
- package/test/integration/lockfile-sync.test.mjs +0 -26
- package/test/integration/merkle-cli.test.mjs +0 -61
- package/test/integration/merkle-persistence-identity.test.mjs +0 -48
- package/test/integration/plugins-cloudflare.integration.test.mjs +0 -28
- package/test/integration/provider-env-cli.test.mjs +0 -60
- package/test/integration/provider-factory.test.mjs +0 -197
- package/test/integration/repository-company-graph.test.mjs +0 -90
- package/test/integration/runtime-migrations.test.mjs +0 -87
- package/test/integration/runtime-status.integration.test.mjs +0 -227
- package/test/integration/sam-activity-recovery.test.mjs +0 -147
- package/test/integration/sam-decision.test.mjs +0 -584
- package/test/integration/sam-kernel.test.mjs +0 -99
- package/test/integration/sam-planning-astar.test.mjs +0 -279
- package/test/integration/scaffold-cloudflare.test.mjs +0 -46
- package/test/integration/skill-runtime.test.mjs +0 -240
- package/test/integration/storage-architecture.test.mjs +0 -154
- package/test/integration/store-discovery.test.mjs +0 -44
- package/test/integration/studio-fs-pty-e2e.test.mjs +0 -294
- package/test/integration/terminal-exec.integration.test.mjs +0 -86
- package/test/integration/theme-package-registry.test.mjs +0 -31
- package/test/integration/tool-runtime.test.mjs +0 -124
- package/test/integration/tool-schema.test.mjs +0 -59
- package/test/jr-dev-skill.test.mjs +0 -26
- package/test/knowledge-context-pack.test.mjs +0 -19
- package/test/knowledge-postgres.test.mjs +0 -40
- package/test/knowledge-service.test.mjs +0 -110
- package/test/knowledge.test.mjs +0 -206
- package/test/live/terminal-transport.live.test.mjs +0 -24
- package/test/local-sessions.test.mjs +0 -57
- package/test/local-studio-deploy.test.mjs +0 -83
- package/test/loopback-oauth.test.mjs +0 -53
- package/test/merkle-render.test.mjs +0 -31
- package/test/mini.test.mjs +0 -140
- package/test/model-catalog.test.mjs +0 -70
- package/test/models.test.mjs +0 -309
- package/test/npm10-lock.test.mjs +0 -29
- package/test/ollama.test.mjs +0 -137
- package/test/open-url.test.mjs +0 -64
- package/test/openai-responses.test.mjs +0 -155
- package/test/portable-context.test.mjs +0 -94
- package/test/project-config.test.mjs +0 -81
- package/test/project-rules.test.mjs +0 -44
- package/test/provider-credentials.test.mjs +0 -106
- package/test/rehydrate.test.mjs +0 -25
- package/test/release-hygiene.test.mjs +0 -42
- package/test/repository-snapshot-view.test.mjs +0 -112
- package/test/responses-runner.test.mjs +0 -465
- package/test/runtime-activity.test.mjs +0 -98
- package/test/sdk-worker-contract.test.mjs +0 -72
- package/test/security.test.mjs +0 -266
- package/test/setup-planner.test.mjs +0 -74
- package/test/setup-runtime.test.mjs +0 -51
- package/test/shell.test.mjs +0 -281
- package/test/skills.test.mjs +0 -22
- package/test/smoke.mjs +0 -122
- package/test/telemetry.test.mjs +0 -79
- package/test/terminal/local-pty.mock.test.mjs +0 -153
- package/test/terminal-machine-identity.test.mjs +0 -88
- package/test/theme-portability.test.mjs +0 -14
- package/test/tools-search.test.mjs +0 -73
- package/test/unit/website-assets-bindings.test.mjs +0 -60
- package/test/whoami-resume.test.mjs +0 -157
|
@@ -1,133 +0,0 @@
|
|
|
1
|
-
import test from 'node:test';
|
|
2
|
-
import assert from 'node:assert/strict';
|
|
3
|
-
import fs from 'node:fs';
|
|
4
|
-
import os from 'node:os';
|
|
5
|
-
import path from 'node:path';
|
|
6
|
-
import { execFileSync } from 'node:child_process';
|
|
7
|
-
import { getCapability, getCapabilityManifest, repositorySnapshot } from '../src/capabilities/index.js';
|
|
8
|
-
import { getPreset, resolvePreset } from '../src/presets/index.js';
|
|
9
|
-
import { scanTrustBoundary } from '../src/security/trust-boundary.js';
|
|
10
|
-
|
|
11
|
-
const CLI = path.resolve('src/cli.js');
|
|
12
|
-
|
|
13
|
-
function git(cwd, args) { return execFileSync('git', args, { cwd, encoding: 'utf8', stdio: ['ignore', 'pipe', 'pipe'] }).trim(); }
|
|
14
|
-
|
|
15
|
-
function fixture() {
|
|
16
|
-
const root = fs.mkdtempSync(path.join(os.tmpdir(), 'agentsam-capability-'));
|
|
17
|
-
fs.writeFileSync(path.join(root, 'package.json'), JSON.stringify({ name: 'snapshot-fixture', version: '1.0.0', type: 'module' }, null, 2));
|
|
18
|
-
fs.mkdirSync(path.join(root, 'src'));
|
|
19
|
-
fs.writeFileSync(path.join(root, 'src', 'index.js'), 'export const value = 1;\n');
|
|
20
|
-
git(root, ['init', '-q']);
|
|
21
|
-
git(root, ['config', 'user.email', 'test@example.com']);
|
|
22
|
-
git(root, ['config', 'user.name', 'AgentSam Test']);
|
|
23
|
-
git(root, ['add', '.']);
|
|
24
|
-
git(root, ['commit', '-qm', 'fixture']);
|
|
25
|
-
return root;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
test('capability manifest exposes deterministic primitives without requiring a model', () => {
|
|
29
|
-
const manifest = getCapabilityManifest();
|
|
30
|
-
assert.equal(manifest.schema_version, 1);
|
|
31
|
-
assert.equal(getCapability('repository.snapshot').model_required, false);
|
|
32
|
-
assert.equal(getCapability('repository.snapshot').side_effects, 'none');
|
|
33
|
-
assert.equal(getCapability('knowledge.index').deterministic, true);
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
test('presets resolve to explicit feature/capability selections', () => {
|
|
37
|
-
assert.equal(getPreset('cms').lane, 'cms');
|
|
38
|
-
const preset = resolvePreset('prototype');
|
|
39
|
-
assert.deepEqual(preset.features, ['agent']);
|
|
40
|
-
assert.throws(() => resolvePreset('nope'), /unknown_preset/);
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
test('repository.snapshot composes deterministic evidence and content addressing', async t => {
|
|
44
|
-
const root = fixture();
|
|
45
|
-
t.after(() => fs.rmSync(root, { recursive: true, force: true }));
|
|
46
|
-
const one = await repositorySnapshot({ cwd: root, churnDays: 30 });
|
|
47
|
-
const two = await repositorySnapshot({ cwd: root, churnDays: 30 });
|
|
48
|
-
assert.equal(one.capability, 'repository.snapshot');
|
|
49
|
-
assert.match(one.snapshot_id, /^rsnap_[a-f0-9]{24}$/);
|
|
50
|
-
assert.match(one.content_hash, /^sha256:[a-f0-9]{64}$/);
|
|
51
|
-
assert.equal(one.content_hash, two.content_hash);
|
|
52
|
-
assert.equal(one.snapshot_id, two.snapshot_id);
|
|
53
|
-
assert.equal(one.repository.revision_sha, git(root, ['rev-parse', 'HEAD']));
|
|
54
|
-
assert.ok(one.tree.merkle_root);
|
|
55
|
-
assert.match(one.tree.metadata_root, /^sha256:[a-f0-9]{64}$/);
|
|
56
|
-
assert.equal(one.tree.manifest.format, 'agentsam-merkle');
|
|
57
|
-
assert.equal(one.tree.manifest.version, 1);
|
|
58
|
-
assert.equal(one.tree.manifest.hash_algorithm, 'sha256');
|
|
59
|
-
assert.match(one.tree.manifest.policy_hash, /^sha256:[a-f0-9]{64}$/);
|
|
60
|
-
assert.equal(one.tree.classifier.format, 'agentsam-filemeta');
|
|
61
|
-
assert.equal(one.tree.classifier.version, 1);
|
|
62
|
-
const source = one.tree.files.find((entry) => entry.path === 'src/index.js');
|
|
63
|
-
assert.equal(source.mode, 420);
|
|
64
|
-
assert.equal(source.system, 'snapshot-fixture');
|
|
65
|
-
assert.equal(source.language, 'javascript');
|
|
66
|
-
assert.deepEqual(source.symbols, ['value']);
|
|
67
|
-
assert.equal(one.analysis.trust_boundary.analyzer, 'agentsam-execution-boundary');
|
|
68
|
-
assert.equal(one.analysis.trust_boundary.metadata_root, one.tree.metadata_root);
|
|
69
|
-
assert.equal(one.analysis.trust_boundary.complete, true);
|
|
70
|
-
assert.equal(one.analysis.trust_boundary.status, 'clean');
|
|
71
|
-
assert.ok(one.intelligence.summary.file_count >= 2);
|
|
72
|
-
assert.equal(one.packages[0].name, 'snapshot-fixture');
|
|
73
|
-
assert.equal(one.knowledge.configured, false);
|
|
74
|
-
});
|
|
75
|
-
|
|
76
|
-
test('repository inspection and security scan share one Git-ignore/Merkle trust authority', async t => {
|
|
77
|
-
const root = fixture();
|
|
78
|
-
t.after(() => fs.rmSync(root, { recursive: true, force: true }));
|
|
79
|
-
fs.mkdirSync(path.join(root, 'frontend'));
|
|
80
|
-
fs.mkdirSync(path.join(root, 'backend'));
|
|
81
|
-
fs.mkdirSync(path.join(root, 'ignored'));
|
|
82
|
-
fs.writeFileSync(path.join(root, 'frontend', 'client.ts'), "import { secretValue } from '../backend/secrets.ts';\nexport const value = secretValue;\n");
|
|
83
|
-
fs.writeFileSync(path.join(root, 'backend', 'secrets.ts'), "export const secretValue = process.env.API_KEY;\n");
|
|
84
|
-
fs.writeFileSync(path.join(root, 'ignored', 'noise.ts'), "import fs from 'node:fs'; export const x = process.env.PRIVATE_TOKEN + String(fs);\n");
|
|
85
|
-
fs.writeFileSync(path.join(root, '.gitignore'), 'ignored/\n');
|
|
86
|
-
|
|
87
|
-
const snapshot = await repositorySnapshot({ cwd: root, churnDays: 30 });
|
|
88
|
-
const boundary = await scanTrustBoundary(root);
|
|
89
|
-
assert.equal(snapshot.tree.metadata_root, boundary.metadata_root);
|
|
90
|
-
assert.equal(snapshot.tree.merkle_root, boundary.merkle_root);
|
|
91
|
-
assert.equal(snapshot.analysis.trust_boundary.status, 'action-required');
|
|
92
|
-
assert.deepEqual(
|
|
93
|
-
snapshot.analysis.trust_boundary.findings.map((item) => [item.kind, item.source, item.target]),
|
|
94
|
-
boundary.findings.map((item) => [item.kind, item.source, item.target]),
|
|
95
|
-
);
|
|
96
|
-
assert.equal(snapshot.tree.paths.some((value) => value.startsWith('ignored/')), false);
|
|
97
|
-
assert.equal(boundary.findings.some((item) => item.source.startsWith('ignored/')), false);
|
|
98
|
-
});
|
|
99
|
-
|
|
100
|
-
test('product UX creates a preset project, adds a feature, and inspects before first commit', t => {
|
|
101
|
-
const parent = fs.mkdtempSync(path.join(os.tmpdir(), 'agentsam-product-'));
|
|
102
|
-
t.after(() => fs.rmSync(parent, { recursive: true, force: true }));
|
|
103
|
-
execFileSync(process.execPath, [CLI, 'create', 'demo', '--preset', 'cms', '--target', 'local'], {
|
|
104
|
-
cwd: parent,
|
|
105
|
-
stdio: 'pipe',
|
|
106
|
-
});
|
|
107
|
-
const project = path.join(parent, 'demo');
|
|
108
|
-
const config = JSON.parse(fs.readFileSync(path.join(project, '.agentsam', 'config.json'), 'utf8'));
|
|
109
|
-
assert.equal(config.schema_version, 2);
|
|
110
|
-
assert.equal(config.project.name, 'demo');
|
|
111
|
-
assert.equal(config.product.preset, 'cms');
|
|
112
|
-
assert.deepEqual(config.product.features, ['cms', 'knowledge', 'brand', 'theme']);
|
|
113
|
-
assert.ok(config.product.capabilities.includes('repository.snapshot'));
|
|
114
|
-
assert.match(config.repository.id, /^local:[0-9a-f-]{36}$/);
|
|
115
|
-
assert.equal(config.defaults.runtime, 'local');
|
|
116
|
-
assert.equal(config.defaults.model, 'auto');
|
|
117
|
-
assert.equal(fs.existsSync(path.join(project, 'agentsam.config.js')), false);
|
|
118
|
-
|
|
119
|
-
execFileSync(process.execPath, [CLI, 'add', 'knowledge', '--cwd', project, '--json'], { stdio: 'pipe' });
|
|
120
|
-
const features = JSON.parse(fs.readFileSync(path.join(project, '.agentsam', 'features.json'), 'utf8'));
|
|
121
|
-
assert.equal(features.features.knowledge.selected, true);
|
|
122
|
-
|
|
123
|
-
const snapshot = JSON.parse(execFileSync(process.execPath, [CLI, 'inspect', '--cwd', project, '--json'], {
|
|
124
|
-
encoding: 'utf8',
|
|
125
|
-
stdio: ['ignore', 'pipe', 'pipe'],
|
|
126
|
-
}));
|
|
127
|
-
assert.equal(snapshot.capability, 'repository.snapshot');
|
|
128
|
-
assert.equal(snapshot.repository.repository_id, config.repository.id);
|
|
129
|
-
assert.equal(snapshot.repository.identity_source, 'project-config');
|
|
130
|
-
assert.equal(snapshot.repository.revision_sha, null);
|
|
131
|
-
assert.ok(snapshot.tree.stats.files > 0);
|
|
132
|
-
assert.ok(snapshot.analysis?.trust_boundary);
|
|
133
|
-
});
|
|
@@ -1,129 +0,0 @@
|
|
|
1
|
-
import assert from 'node:assert/strict';
|
|
2
|
-
import fs from 'node:fs';
|
|
3
|
-
import os from 'node:os';
|
|
4
|
-
import path from 'node:path';
|
|
5
|
-
import test from 'node:test';
|
|
6
|
-
import { runEnv } from '../../src/commands/env.js';
|
|
7
|
-
import { ensureAgentEnvLoader, renderEnvShellExports, setProviderCredential } from '../../src/lib/provider-credentials.js';
|
|
8
|
-
import { runApiKey } from '../../src/commands/api-key.js';
|
|
9
|
-
import { collectWhoami } from '../../src/commands/whoami.js';
|
|
10
|
-
|
|
11
|
-
function tmpHome() {
|
|
12
|
-
return fs.mkdtempSync(path.join(os.tmpdir(), 'agentsam-env-api-'));
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
test('load-agent-env.sh delegates to agentsam env shell (no plaintext secrets)', () => {
|
|
16
|
-
const home = tmpHome();
|
|
17
|
-
const loader = ensureAgentEnvLoader({ home });
|
|
18
|
-
const source = fs.readFileSync(loader, 'utf8');
|
|
19
|
-
assert.match(source, /agentsam env shell --profile default/);
|
|
20
|
-
assert.doesNotMatch(source, /export AGENTSAM_API_KEY=/);
|
|
21
|
-
assert.doesNotMatch(source, /env\.d\//);
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
test('env boot-line prints source load-agent-env without provider args', async () => {
|
|
25
|
-
const home = tmpHome();
|
|
26
|
-
const result = await runEnv(['boot-line'], { home, write: () => {} });
|
|
27
|
-
assert.equal(result.command, 'source ~/.agentsam/load-agent-env.sh');
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
test('env shell emits exports from vault without requiring ambient AGENTSAM_API_KEY', async () => {
|
|
31
|
-
const home = tmpHome();
|
|
32
|
-
setProviderCredential('inneranimalmedia', 'aak_testsecretvalue1234567890abcdef', {
|
|
33
|
-
home,
|
|
34
|
-
disableOsStore: true,
|
|
35
|
-
});
|
|
36
|
-
const result = await runEnv(['shell', '--profile', 'default'], {
|
|
37
|
-
home,
|
|
38
|
-
env: {},
|
|
39
|
-
write: () => {},
|
|
40
|
-
});
|
|
41
|
-
assert.match(result.script, /export AGENTSAM_API_KEY=/);
|
|
42
|
-
assert.ok(result.providers.includes('inneranimalmedia'));
|
|
43
|
-
});
|
|
44
|
-
|
|
45
|
-
test('renderEnvShellExports prefers vault over empty ambient env', () => {
|
|
46
|
-
const home = tmpHome();
|
|
47
|
-
setProviderCredential('cursor', 'cursor_test_key_value_xxxxxxxx', {
|
|
48
|
-
home,
|
|
49
|
-
disableOsStore: true,
|
|
50
|
-
});
|
|
51
|
-
const result = renderEnvShellExports({ home, env: {}, profile: 'default' });
|
|
52
|
-
assert.ok(result.providers.includes('cursor'));
|
|
53
|
-
assert.match(result.script, /export CURSOR_API_KEY=/);
|
|
54
|
-
});
|
|
55
|
-
|
|
56
|
-
test('api-key create stores secret via host mint response', async () => {
|
|
57
|
-
const home = tmpHome();
|
|
58
|
-
const result = await runApiKey(['create', '--name', 'Test Mac', '--store', 'vault', '--activate'], {
|
|
59
|
-
home,
|
|
60
|
-
env: {},
|
|
61
|
-
disableOsStore: true,
|
|
62
|
-
authorityLoader: async () => ({ value: 'oauth_session_token', kind: 'browser_oauth', source: 'test' }),
|
|
63
|
-
postJsonImpl: async () => ({
|
|
64
|
-
ok: true,
|
|
65
|
-
credential: { id: 'aakcred_1', name: 'Test Mac', prefix: 'aak_abc…', scopes: ['account:read'] },
|
|
66
|
-
secret_once: 'aak_mintedsecretvalue1234567890abcd',
|
|
67
|
-
}),
|
|
68
|
-
write: () => {},
|
|
69
|
-
});
|
|
70
|
-
assert.equal(result.ok, true);
|
|
71
|
-
assert.equal(result.activated, true);
|
|
72
|
-
assert.equal(result.credential.prefix, 'aak_abc…');
|
|
73
|
-
});
|
|
74
|
-
|
|
75
|
-
test('whoami surfaces tokenPermissions and authType from context', async () => {
|
|
76
|
-
const home = tmpHome();
|
|
77
|
-
const status = await collectWhoami({
|
|
78
|
-
home,
|
|
79
|
-
env: {},
|
|
80
|
-
authorityLoader: async () => ({ value: 'aak_presented', kind: 'api_key', source: 'environment' }),
|
|
81
|
-
contextLoader: async () => ({
|
|
82
|
-
user_id: 'au_1',
|
|
83
|
-
account_id: 'acct_1',
|
|
84
|
-
email: 'dev@example.test',
|
|
85
|
-
auth_type: 'api_key',
|
|
86
|
-
tokenPermissions: ['account:read', 'repository:read', 'models:invoke'],
|
|
87
|
-
credential: {
|
|
88
|
-
id: 'aakcred_1',
|
|
89
|
-
name: 'dev-machine',
|
|
90
|
-
prefix: 'aak_7fm…',
|
|
91
|
-
environment: 'development',
|
|
92
|
-
status: 'active',
|
|
93
|
-
},
|
|
94
|
-
cloudflare: { ok: true },
|
|
95
|
-
byok: {},
|
|
96
|
-
terminal: { available: false, instances: [], connections: [] },
|
|
97
|
-
}),
|
|
98
|
-
});
|
|
99
|
-
assert.equal(status.loggedIn, true);
|
|
100
|
-
assert.equal(status.authType, 'api_key');
|
|
101
|
-
assert.deepEqual(status.tokenPermissions, ['account:read', 'repository:read', 'models:invoke']);
|
|
102
|
-
assert.equal(status.credential.name, 'dev-machine');
|
|
103
|
-
assert.doesNotMatch(JSON.stringify(status), /aak_presented/);
|
|
104
|
-
});
|
|
105
|
-
|
|
106
|
-
test('repository does not normalize AGENTSAM_DEFAULT_APP', () => {
|
|
107
|
-
const root = path.resolve(path.dirname(new URL(import.meta.url).pathname), '../..');
|
|
108
|
-
const hits = [];
|
|
109
|
-
function walk(dir) {
|
|
110
|
-
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
|
|
111
|
-
if (entry.name === 'node_modules' || entry.name === '.git' || entry.name === 'dist') continue;
|
|
112
|
-
const full = path.join(dir, entry.name);
|
|
113
|
-
if (entry.isDirectory()) walk(full);
|
|
114
|
-
else if (/\.(js|mjs|ts|tsx|sh|json|md)$/.test(entry.name)) {
|
|
115
|
-
const text = fs.readFileSync(full, 'utf8');
|
|
116
|
-
// Allow docs that explicitly forbid the variable.
|
|
117
|
-
if (/AGENTSAM_DEFAULT_APP/.test(text) && !/no AGENTSAM_DEFAULT_APP|not normalize AGENTSAM_DEFAULT_APP|Remove.*AGENTSAM_DEFAULT_APP|doesNotMatch.*AGENTSAM_DEFAULT_APP|APP_SELECTOR=/.test(text)) {
|
|
118
|
-
if (/process\.env\.AGENTSAM_DEFAULT_APP|AGENTSAM_DEFAULT_APP\s*\|\||\$\{AGENTSAM_DEFAULT_APP/.test(text)) {
|
|
119
|
-
hits.push(full);
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
walk(path.join(root, 'src'));
|
|
126
|
-
walk(path.join(root, 'scripts'));
|
|
127
|
-
walk(path.join(root, 'apps/local-studio/backend'));
|
|
128
|
-
assert.deepEqual(hits, []);
|
|
129
|
-
});
|
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
import test from 'node:test';
|
|
2
|
-
import assert from 'node:assert/strict';
|
|
3
|
-
|
|
4
|
-
import { getCliCommand } from '../../src/cli/command-catalog.js';
|
|
5
|
-
import { runStatus } from '../../src/commands/status.js';
|
|
6
|
-
import { setupNextCommands } from '../../src/commands/setup.js';
|
|
7
|
-
import { renderRepositoryObservation } from '../../src/commands/knowledge.js';
|
|
8
|
-
|
|
9
|
-
test('status --help is catalog-backed and does not collect runtime state', async () => {
|
|
10
|
-
let output = '';
|
|
11
|
-
let collected = false;
|
|
12
|
-
const result = await runStatus(['--help'], {
|
|
13
|
-
write(value) { output += value; },
|
|
14
|
-
async collectRuntime() {
|
|
15
|
-
collected = true;
|
|
16
|
-
throw new Error('status help must not collect runtime');
|
|
17
|
-
},
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
assert.equal(result, null);
|
|
21
|
-
assert.equal(collected, false);
|
|
22
|
-
assert.match(output, /Agent Sam.*status/);
|
|
23
|
-
assert.match(output, /--offline/);
|
|
24
|
-
assert.match(output, /--json/);
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
test('setup next-actions only reference catalogued top-level commands', () => {
|
|
28
|
-
const commands = setupNextCommands(['google.cloud', 'image.vectorize']);
|
|
29
|
-
assert.ok(commands.includes('agentsam status'));
|
|
30
|
-
assert.ok(commands.includes('agentsam capabilities'));
|
|
31
|
-
assert.ok(commands.includes('agentsam google-cloud doctor'));
|
|
32
|
-
assert.ok(!commands.some((command) => command === 'agentsam doctor'));
|
|
33
|
-
assert.ok(!commands.some((command) => command.startsWith('agentsam image ')));
|
|
34
|
-
|
|
35
|
-
for (const command of commands) {
|
|
36
|
-
const [, id] = command.split(/\s+/);
|
|
37
|
-
assert.ok(getCliCommand(id), `next action must be catalogued: ${command}`);
|
|
38
|
-
}
|
|
39
|
-
});
|
|
40
|
-
|
|
41
|
-
test('repository summary is human-sized while preserving important machine evidence', () => {
|
|
42
|
-
const output = renderRepositoryObservation({
|
|
43
|
-
data: {
|
|
44
|
-
repo_root: '/tmp/example',
|
|
45
|
-
repo_name: 'example',
|
|
46
|
-
git: { branch: 'main', head_sha: 'abcdef1234567890', dirty: true, changed_paths: 2 },
|
|
47
|
-
summary: { file_count: 2995, source_file_count: 2840, total_lines: 491023 },
|
|
48
|
-
top_level: [
|
|
49
|
-
{ path: 'apps', files: 1351, lines: 289444 },
|
|
50
|
-
{ path: 'packages', files: 757, lines: 77579 },
|
|
51
|
-
],
|
|
52
|
-
pressure_points: [
|
|
53
|
-
{ path: 'apps/local-studio', pressure_score: 89.5, stability_score: 10.2 },
|
|
54
|
-
],
|
|
55
|
-
},
|
|
56
|
-
});
|
|
57
|
-
|
|
58
|
-
assert.match(output, /Agent Sam · repository/);
|
|
59
|
-
assert.match(output, /example/);
|
|
60
|
-
assert.match(output, /apps\/local-studio/);
|
|
61
|
-
assert.match(output, /not quality grades/);
|
|
62
|
-
assert.match(output, /agentsam repo --json/);
|
|
63
|
-
assert.doesNotMatch(output, /"pressure_points"/);
|
|
64
|
-
});
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
import assert from 'node:assert/strict';
|
|
2
|
-
import { describe, it } from 'node:test';
|
|
3
|
-
import {
|
|
4
|
-
createCodebaseindexJobGraph,
|
|
5
|
-
advanceJobGraph,
|
|
6
|
-
freezePlanJobGraph,
|
|
7
|
-
formatJobGraphHuman,
|
|
8
|
-
} from '../../src/indexing/ingest/job-graph.js';
|
|
9
|
-
import { classifyTopLevel } from '../../src/indexing/ingest/inventory.js';
|
|
10
|
-
|
|
11
|
-
describe('codebaseindex job graph plan freeze', () => {
|
|
12
|
-
it('does not leave → run pointer after plan.dry_run', () => {
|
|
13
|
-
let g = createCodebaseindexJobGraph();
|
|
14
|
-
g = advanceJobGraph(g, 'plan.dry_run');
|
|
15
|
-
assert.equal(g.nodes.find((n) => n.status === 'run')?.id, 'ast.parse');
|
|
16
|
-
g = freezePlanJobGraph(g, { skipEmbedding: true });
|
|
17
|
-
assert.equal(g.status, 'planned');
|
|
18
|
-
assert.equal(g.nodes.filter((n) => n.status === 'run').length, 0);
|
|
19
|
-
assert.equal(g.nodes.find((n) => n.id === 'embedding.generate')?.status, 'skipped');
|
|
20
|
-
const text = formatJobGraphHuman(g, { planOnly: true });
|
|
21
|
-
assert.match(text, /PLANNED FOR RUN/);
|
|
22
|
-
assert.match(text, /○ ast\.parse/);
|
|
23
|
-
assert.doesNotMatch(text, /→/);
|
|
24
|
-
});
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
describe('inventory path categories', () => {
|
|
28
|
-
it('classifies source vs dependencies vs generated', () => {
|
|
29
|
-
assert.equal(classifyTopLevel('src'), 'source');
|
|
30
|
-
assert.equal(classifyTopLevel('apps'), 'source');
|
|
31
|
-
assert.equal(classifyTopLevel('docs'), 'docs');
|
|
32
|
-
assert.equal(classifyTopLevel('node_modules'), 'dependencies');
|
|
33
|
-
assert.equal(classifyTopLevel('dist'), 'dependencies');
|
|
34
|
-
assert.equal(classifyTopLevel('generated'), 'generated');
|
|
35
|
-
assert.equal(classifyTopLevel('.agentsam'), 'operational');
|
|
36
|
-
});
|
|
37
|
-
});
|
|
@@ -1,219 +0,0 @@
|
|
|
1
|
-
import assert from 'node:assert/strict';
|
|
2
|
-
import fs from 'node:fs';
|
|
3
|
-
import os from 'node:os';
|
|
4
|
-
import path from 'node:path';
|
|
5
|
-
import test from 'node:test';
|
|
6
|
-
|
|
7
|
-
import {
|
|
8
|
-
finishLiveEvalRun,
|
|
9
|
-
getLiveEvalStatus,
|
|
10
|
-
startLiveEvalRun,
|
|
11
|
-
} from '../../src/eval/index.js';
|
|
12
|
-
import { recordToolReceipt } from '../../src/mcp/index.js';
|
|
13
|
-
import { runEval } from '../../src/commands/eval.js';
|
|
14
|
-
|
|
15
|
-
function tempHome() {
|
|
16
|
-
return fs.mkdtempSync(path.join(os.tmpdir(), 'agentsam-live-eval-test-'));
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
test('live eval lifecycle: start, track receipts, get status, finish', async () => {
|
|
20
|
-
const home = tempHome();
|
|
21
|
-
|
|
22
|
-
// Initially inactive
|
|
23
|
-
const initialStatus = getLiveEvalStatus({ home });
|
|
24
|
-
assert.equal(initialStatus.active, false);
|
|
25
|
-
|
|
26
|
-
// Start live eval run
|
|
27
|
-
const run = startLiveEvalRun(
|
|
28
|
-
{
|
|
29
|
-
suite: 'sdk-real-work-20260919',
|
|
30
|
-
case: 'cad-shell-unification',
|
|
31
|
-
model: 'Muse Spark 1.3',
|
|
32
|
-
provider: 'cursor',
|
|
33
|
-
client: 'cursor',
|
|
34
|
-
reasoning: 'high',
|
|
35
|
-
},
|
|
36
|
-
{ home }
|
|
37
|
-
);
|
|
38
|
-
|
|
39
|
-
assert.ok(run.run_id.startsWith('evr_'));
|
|
40
|
-
assert.equal(run.suite_id, 'sdk-real-work-20260919');
|
|
41
|
-
assert.equal(run.case_id, 'cad-shell-unification');
|
|
42
|
-
assert.equal(run.model, 'Muse Spark 1.3');
|
|
43
|
-
|
|
44
|
-
// Verify starting again fails
|
|
45
|
-
assert.throws(() => startLiveEvalRun({}, { home }), /live_eval_run_already_active/);
|
|
46
|
-
|
|
47
|
-
// Record tool calls into the live session
|
|
48
|
-
recordToolReceipt({ tool_key: 'github_read', source_client: 'cursor', duration_ms: 50 }, { home });
|
|
49
|
-
recordToolReceipt({ tool_key: 'mcp:d1_query', source_client: 'cursor_mcp', duration_ms: 12 }, { home });
|
|
50
|
-
recordToolReceipt({ tool_key: 'terminal_exec', source_client: 'agentsam', duration_ms: 300 }, { home });
|
|
51
|
-
|
|
52
|
-
// Status check reflects active state and tool receipts
|
|
53
|
-
const activeStatus = getLiveEvalStatus({ home });
|
|
54
|
-
assert.equal(activeStatus.active, true);
|
|
55
|
-
assert.equal(activeStatus.receipts_summary.tool_call_count, 3);
|
|
56
|
-
assert.equal(activeStatus.receipts_summary.mcp_call_count, 1);
|
|
57
|
-
|
|
58
|
-
// Finish run
|
|
59
|
-
const result = await finishLiveEvalRun({ home, gate: 'PASS' });
|
|
60
|
-
assert.equal(result.evalRunRow.id, run.run_id);
|
|
61
|
-
assert.equal(result.evalRunRow.passed, 1);
|
|
62
|
-
assert.equal(result.evalRunRow.tool_calls_attempted, 3);
|
|
63
|
-
assert.equal(result.evalRunRow.tool_calls_succeeded, 3);
|
|
64
|
-
assert.equal(result.modelObservationRow.id, `obs_${run.run_id}`);
|
|
65
|
-
assert.equal(result.modelObservationRow.passed, 1);
|
|
66
|
-
|
|
67
|
-
// After finish, status is inactive again
|
|
68
|
-
const postStatus = getLiveEvalStatus({ home });
|
|
69
|
-
assert.equal(postStatus.active, false);
|
|
70
|
-
});
|
|
71
|
-
|
|
72
|
-
test('agentsam eval live CLI commands work end-to-end', async () => {
|
|
73
|
-
const home = tempHome();
|
|
74
|
-
const logs = [];
|
|
75
|
-
const write = (str) => logs.push(str);
|
|
76
|
-
|
|
77
|
-
// CLI start
|
|
78
|
-
const startResult = await runEval(
|
|
79
|
-
['live', 'start', '--case', 'errors-v1-reconciliation', '--model', 'Muse Spark 1.3', '--json'],
|
|
80
|
-
{ home, write }
|
|
81
|
-
);
|
|
82
|
-
assert.ok(startResult.run_id.startsWith('evr_'));
|
|
83
|
-
|
|
84
|
-
// Record receipt
|
|
85
|
-
recordToolReceipt({ tool_key: 'mcp:eval_query', source_client: 'cursor_mcp', duration_ms: 40 }, { home });
|
|
86
|
-
|
|
87
|
-
// CLI status
|
|
88
|
-
const statusResult = await runEval(['live', 'status', '--json'], { home, write });
|
|
89
|
-
assert.equal(statusResult.active, true);
|
|
90
|
-
assert.equal(statusResult.receipts_summary.tool_call_count, 1);
|
|
91
|
-
|
|
92
|
-
// CLI finish
|
|
93
|
-
const finishResult = await runEval(['live', 'finish', '--gate', 'PASS', '--json'], { home, write });
|
|
94
|
-
assert.equal(finishResult.evalRunRow.passed, 1);
|
|
95
|
-
assert.equal(finishResult.summary.gate_status, 'PASS');
|
|
96
|
-
|
|
97
|
-
// Verify non-JSON output formats cleanly
|
|
98
|
-
const emptyStatus = await runEval(['live', 'status'], { home, write });
|
|
99
|
-
assert.equal(emptyStatus.active, false);
|
|
100
|
-
});
|
|
101
|
-
|
|
102
|
-
test('finishLiveEvalRun archives run locally, generates SQL for both tables, and respects configurable tenant/database', async () => {
|
|
103
|
-
const home = tempHome();
|
|
104
|
-
const run = startLiveEvalRun(
|
|
105
|
-
{
|
|
106
|
-
case: 'cad-render-eval',
|
|
107
|
-
model: 'Muse Spark 1.3',
|
|
108
|
-
tenant: 'test-tenant',
|
|
109
|
-
workspace: 'cad-workspace',
|
|
110
|
-
user: 'test-user',
|
|
111
|
-
database: 'test-database',
|
|
112
|
-
},
|
|
113
|
-
{ home }
|
|
114
|
-
);
|
|
115
|
-
|
|
116
|
-
assert.equal(run.tenant_id, 'test-tenant');
|
|
117
|
-
assert.equal(run.workspace_id, 'cad-workspace');
|
|
118
|
-
assert.equal(run.user_id, 'test-user');
|
|
119
|
-
assert.equal(run.database, 'test-database');
|
|
120
|
-
|
|
121
|
-
const result = await finishLiveEvalRun({ home, gate: 'PASS' });
|
|
122
|
-
|
|
123
|
-
// 1. Dual record construction
|
|
124
|
-
assert.equal(result.evalRunRow.tenant_id, 'test-tenant');
|
|
125
|
-
assert.equal(result.modelObservationRow.tenant_id, 'test-tenant');
|
|
126
|
-
assert.equal(result.modelObservationRow.workspace_id, 'cad-workspace');
|
|
127
|
-
assert.equal(result.modelObservationRow.user_id, 'test-user');
|
|
128
|
-
assert.equal(result.modelObservationRow.status, 'completed');
|
|
129
|
-
assert.equal(result.modelObservationRow.passed, 1);
|
|
130
|
-
assert.equal(result.modelObservationRow.expected_markers_total, 1);
|
|
131
|
-
assert.equal(typeof result.modelObservationRow.output_chars, 'number');
|
|
132
|
-
|
|
133
|
-
// 2. Both tables present in generated D1 SQL
|
|
134
|
-
assert.ok(result.summary.d1_sql.includes('INSERT OR REPLACE INTO agentsam_eval_runs'));
|
|
135
|
-
assert.ok(result.summary.d1_sql.includes('INSERT OR REPLACE INTO agentsam_model_eval_observations'));
|
|
136
|
-
|
|
137
|
-
// 3. Local archive created
|
|
138
|
-
const archivedRunPath = path.join(home, '.agentsam', 'eval', 'runs', `${run.run_id}.json`);
|
|
139
|
-
assert.ok(fs.existsSync(archivedRunPath), 'Archived run file must exist locally');
|
|
140
|
-
const archived = JSON.parse(fs.readFileSync(archivedRunPath, 'utf8'));
|
|
141
|
-
assert.equal(archived.evalRunRow.id, run.run_id);
|
|
142
|
-
assert.equal(archived.modelObservationRow.id, `obs_${run.run_id}`);
|
|
143
|
-
});
|
|
144
|
-
|
|
145
|
-
test('finishLiveEvalRun preserves active run state and receipts if remote persistence fails without --force', async () => {
|
|
146
|
-
const home = tempHome();
|
|
147
|
-
const run = startLiveEvalRun({ case: 'resilience-test' }, { home });
|
|
148
|
-
|
|
149
|
-
recordToolReceipt({ tool_key: 'git_status', duration_ms: 20 }, { home });
|
|
150
|
-
|
|
151
|
-
// Call finish with remote=true pointing to an unreachable endpoint and wrangler fallback disabled
|
|
152
|
-
const result = await finishLiveEvalRun({
|
|
153
|
-
home,
|
|
154
|
-
remote: true,
|
|
155
|
-
evalEndpoint: 'http://127.0.0.1:1/nonexistent',
|
|
156
|
-
wranglerFallback: false,
|
|
157
|
-
timeoutMs: 100,
|
|
158
|
-
});
|
|
159
|
-
|
|
160
|
-
// Verification: remote failure noted, evidence preserved, active run kept intact
|
|
161
|
-
assert.equal(result.summary.d1_executed, false);
|
|
162
|
-
assert.equal(result.summary.state_preserved, true);
|
|
163
|
-
assert.ok(result.summary.d1_error);
|
|
164
|
-
|
|
165
|
-
const activeStatus = getLiveEvalStatus({ home });
|
|
166
|
-
assert.equal(activeStatus.active, true, 'Active run state must be retained when remote persistence fails');
|
|
167
|
-
assert.equal(activeStatus.receipts_summary.tool_call_count, 1, 'Tool receipts must be preserved when remote persistence fails');
|
|
168
|
-
|
|
169
|
-
// Finish with force: true to finalize and clear active run
|
|
170
|
-
const forcedResult = await finishLiveEvalRun({
|
|
171
|
-
home,
|
|
172
|
-
remote: true,
|
|
173
|
-
evalEndpoint: 'http://127.0.0.1:1/nonexistent',
|
|
174
|
-
wranglerFallback: false,
|
|
175
|
-
timeoutMs: 100,
|
|
176
|
-
force: true,
|
|
177
|
-
});
|
|
178
|
-
|
|
179
|
-
assert.equal(forcedResult.summary.d1_executed, false);
|
|
180
|
-
const clearedStatus = getLiveEvalStatus({ home });
|
|
181
|
-
assert.equal(clearedStatus.active, false, 'Forced finish clears active run');
|
|
182
|
-
});
|
|
183
|
-
|
|
184
|
-
test('finishLiveEvalRun reuses the configured inneranimalmedia MCP bearer for remote persistence', { concurrency: false }, async () => {
|
|
185
|
-
const home = tempHome();
|
|
186
|
-
const mcpDir = path.join(home, '.agentsam', 'mcp');
|
|
187
|
-
fs.mkdirSync(mcpDir, { recursive: true });
|
|
188
|
-
fs.writeFileSync(
|
|
189
|
-
path.join(mcpDir, 'inneranimalmedia.json'),
|
|
190
|
-
JSON.stringify({ auth: { type: 'bearer', token: 'fixture-eval-token' } }),
|
|
191
|
-
);
|
|
192
|
-
|
|
193
|
-
startLiveEvalRun({ case: 'authenticated-remote-eval' }, { home });
|
|
194
|
-
|
|
195
|
-
const originalFetch = globalThis.fetch;
|
|
196
|
-
let authorization = null;
|
|
197
|
-
try {
|
|
198
|
-
globalThis.fetch = async (_url, init = {}) => {
|
|
199
|
-
authorization = new Headers(init.headers).get('Authorization');
|
|
200
|
-
return new Response(JSON.stringify({ ok: true }), {
|
|
201
|
-
status: 200,
|
|
202
|
-
headers: { 'Content-Type': 'application/json' },
|
|
203
|
-
});
|
|
204
|
-
};
|
|
205
|
-
|
|
206
|
-
const result = await finishLiveEvalRun({
|
|
207
|
-
home,
|
|
208
|
-
remote: true,
|
|
209
|
-
evalEndpoint: 'https://example.test/api/eval/record',
|
|
210
|
-
wranglerFallback: false,
|
|
211
|
-
});
|
|
212
|
-
|
|
213
|
-
assert.equal(authorization, 'Bearer fixture-eval-token');
|
|
214
|
-
assert.equal(result.summary.d1_executed, true);
|
|
215
|
-
assert.equal(result.summary.persistence_method, 'http_endpoint');
|
|
216
|
-
} finally {
|
|
217
|
-
globalThis.fetch = originalFetch;
|
|
218
|
-
}
|
|
219
|
-
});
|