@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
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import os from 'node:os';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import { spawnSync } from 'node:child_process';
|
|
5
|
+
|
|
6
|
+
export const MACHINE_RUNTIME_SCHEMA = 'agentsam.machine.runtime.v1';
|
|
7
|
+
export const MACHINE_PACKAGE = 'agentsam-machine-cli';
|
|
8
|
+
|
|
9
|
+
function expandHome(value, home) {
|
|
10
|
+
if (!value) return value;
|
|
11
|
+
if (value === '~') return home;
|
|
12
|
+
if (value.startsWith('~/')) return path.join(home, value.slice(2));
|
|
13
|
+
return value;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function agentsamHome(env = process.env) {
|
|
17
|
+
const home = os.homedir();
|
|
18
|
+
const configured = String(env.AGENTSAM_HOME || '').trim();
|
|
19
|
+
return configured ? path.resolve(expandHome(configured, home)) : path.join(home, '.agentsam');
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export function machineRuntimeRoot(env = process.env) {
|
|
23
|
+
return path.join(agentsamHome(env), 'runtimes', 'machine');
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export function machineRuntimeStatePath(env = process.env) {
|
|
27
|
+
return path.join(machineRuntimeRoot(env), 'current.json');
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export function machineBinaryName() {
|
|
31
|
+
return process.platform === 'win32' ? 'agentsam-machine.exe' : 'agentsam-machine';
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export function machineManagedAliasPath(env = process.env) {
|
|
35
|
+
return path.join(agentsamHome(env), 'bin', machineBinaryName());
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export function readMachineRuntimeState(env = process.env) {
|
|
39
|
+
const file = machineRuntimeStatePath(env);
|
|
40
|
+
if (!fs.existsSync(file)) return null;
|
|
41
|
+
try {
|
|
42
|
+
const parsed = JSON.parse(fs.readFileSync(file, 'utf8'));
|
|
43
|
+
if (parsed?.schema !== MACHINE_RUNTIME_SCHEMA) return null;
|
|
44
|
+
if (typeof parsed?.current_version !== 'string' || !parsed.current_version.trim()) return null;
|
|
45
|
+
return parsed;
|
|
46
|
+
} catch {
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export function managedMachineResolution(env = process.env) {
|
|
52
|
+
const statePath = machineRuntimeStatePath(env);
|
|
53
|
+
const state = readMachineRuntimeState(env);
|
|
54
|
+
const tried = [statePath];
|
|
55
|
+
if (!state) return { available: false, state: null, path: null, tried };
|
|
56
|
+
|
|
57
|
+
const binary = path.join(
|
|
58
|
+
machineRuntimeRoot(env),
|
|
59
|
+
'versions',
|
|
60
|
+
state.current_version,
|
|
61
|
+
'bin',
|
|
62
|
+
machineBinaryName(),
|
|
63
|
+
);
|
|
64
|
+
tried.push(binary);
|
|
65
|
+
|
|
66
|
+
if (!fs.existsSync(binary) || !fs.statSync(binary).isFile()) {
|
|
67
|
+
return { available: false, state, path: binary, tried };
|
|
68
|
+
}
|
|
69
|
+
return { available: true, state, path: binary, tried };
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export function findExecutable(command, env = process.env) {
|
|
73
|
+
const probe = process.platform === 'win32' ? ['where', [command]] : ['which', [command]];
|
|
74
|
+
const result = spawnSync(probe[0], probe[1], {
|
|
75
|
+
encoding: 'utf8',
|
|
76
|
+
stdio: ['ignore', 'pipe', 'ignore'],
|
|
77
|
+
env,
|
|
78
|
+
});
|
|
79
|
+
if (result.status !== 0) return null;
|
|
80
|
+
return String(result.stdout || '')
|
|
81
|
+
.split(/\r?\n/)
|
|
82
|
+
.map((line) => line.trim())
|
|
83
|
+
.find(Boolean) || null;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export function machineBinaryVersion(binary, env = process.env) {
|
|
87
|
+
const result = spawnSync(binary, ['--version'], {
|
|
88
|
+
encoding: 'utf8',
|
|
89
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
90
|
+
env,
|
|
91
|
+
});
|
|
92
|
+
if (result.status !== 0) return null;
|
|
93
|
+
const output = String(result.stdout || result.stderr || '').trim();
|
|
94
|
+
const match = output.match(/(?:^|\s)(\d+\.\d+\.\d+(?:[-+][0-9A-Za-z.-]+)?)(?:\s|$)/);
|
|
95
|
+
return match?.[1] || null;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
export function machineRuntimeStatus(env = process.env) {
|
|
99
|
+
const managed = managedMachineResolution(env);
|
|
100
|
+
const cargo = findExecutable('cargo', env);
|
|
101
|
+
return {
|
|
102
|
+
schema: MACHINE_RUNTIME_SCHEMA,
|
|
103
|
+
manager: 'agentsam',
|
|
104
|
+
runtime_root: machineRuntimeRoot(env),
|
|
105
|
+
state_path: machineRuntimeStatePath(env),
|
|
106
|
+
installed: managed.available,
|
|
107
|
+
current_version: managed.state?.current_version || null,
|
|
108
|
+
binary: managed.path,
|
|
109
|
+
source: managed.state?.source || null,
|
|
110
|
+
installed_at_iso: managed.state?.installed_at_iso || null,
|
|
111
|
+
stable_alias: machineManagedAliasPath(env),
|
|
112
|
+
cargo: { available: Boolean(cargo), path: cargo },
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
export function discoverLatestMachineVersion(env = process.env) {
|
|
117
|
+
const cargo = findExecutable('cargo', env);
|
|
118
|
+
if (!cargo) {
|
|
119
|
+
const error = new Error('Cargo is required to install the current agentsam-machine crates.io distribution.');
|
|
120
|
+
error.code = 'AGENTSAM_MACHINE_CARGO_MISSING';
|
|
121
|
+
throw error;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
const result = spawnSync(cargo, ['search', MACHINE_PACKAGE, '--limit', '1'], {
|
|
125
|
+
encoding: 'utf8',
|
|
126
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
127
|
+
env,
|
|
128
|
+
});
|
|
129
|
+
if (result.status !== 0) {
|
|
130
|
+
const error = new Error(
|
|
131
|
+
String(result.stderr || '').trim() ||
|
|
132
|
+
'Unable to resolve latest ' + MACHINE_PACKAGE + ' version from crates.io.',
|
|
133
|
+
);
|
|
134
|
+
error.code = 'AGENTSAM_MACHINE_REGISTRY_LOOKUP_FAILED';
|
|
135
|
+
throw error;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
const match = String(result.stdout || '').match(/^agentsam-machine-cli\s*=\s*"([^"]+)"/m);
|
|
139
|
+
if (!match) {
|
|
140
|
+
const error = new Error('Unable to parse crates.io version for ' + MACHINE_PACKAGE + '.');
|
|
141
|
+
error.code = 'AGENTSAM_MACHINE_REGISTRY_PARSE_FAILED';
|
|
142
|
+
throw error;
|
|
143
|
+
}
|
|
144
|
+
return match[1];
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
function writeCurrentState(version, env = process.env) {
|
|
148
|
+
const root = machineRuntimeRoot(env);
|
|
149
|
+
fs.mkdirSync(root, { recursive: true });
|
|
150
|
+
const state = {
|
|
151
|
+
schema: MACHINE_RUNTIME_SCHEMA,
|
|
152
|
+
manager: 'agentsam',
|
|
153
|
+
package: MACHINE_PACKAGE,
|
|
154
|
+
current_version: version,
|
|
155
|
+
source: 'crates.io',
|
|
156
|
+
installed_at_iso: new Date().toISOString(),
|
|
157
|
+
};
|
|
158
|
+
const target = machineRuntimeStatePath(env);
|
|
159
|
+
const temp = target + '.tmp-' + process.pid;
|
|
160
|
+
fs.writeFileSync(temp, JSON.stringify(state, null, 2) + '\n', { mode: 0o600 });
|
|
161
|
+
fs.renameSync(temp, target);
|
|
162
|
+
return state;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
function syncManagedAlias(binary, env = process.env) {
|
|
166
|
+
const alias = machineManagedAliasPath(env);
|
|
167
|
+
fs.mkdirSync(path.dirname(alias), { recursive: true });
|
|
168
|
+
try { fs.rmSync(alias, { force: true }); } catch {}
|
|
169
|
+
if (process.platform === 'win32') fs.copyFileSync(binary, alias);
|
|
170
|
+
else fs.symlinkSync(binary, alias);
|
|
171
|
+
return alias;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
export function installManagedMachine({
|
|
175
|
+
env = process.env,
|
|
176
|
+
version = null,
|
|
177
|
+
force = false,
|
|
178
|
+
write = () => {},
|
|
179
|
+
} = {}) {
|
|
180
|
+
const cargo = findExecutable('cargo', env);
|
|
181
|
+
if (!cargo) {
|
|
182
|
+
const error = new Error(
|
|
183
|
+
'Cargo is required by the current Machine distribution. Install Rust/Cargo, then rerun agentsam machine install.',
|
|
184
|
+
);
|
|
185
|
+
error.code = 'AGENTSAM_MACHINE_CARGO_MISSING';
|
|
186
|
+
throw error;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
const desired = version || discoverLatestMachineVersion(env);
|
|
190
|
+
const root = machineRuntimeRoot(env);
|
|
191
|
+
const versionsRoot = path.join(root, 'versions');
|
|
192
|
+
const finalRoot = path.join(versionsRoot, desired);
|
|
193
|
+
const finalBinary = path.join(finalRoot, 'bin', machineBinaryName());
|
|
194
|
+
fs.mkdirSync(versionsRoot, { recursive: true });
|
|
195
|
+
|
|
196
|
+
if (!force && fs.existsSync(finalBinary)) {
|
|
197
|
+
const actual = machineBinaryVersion(finalBinary, env);
|
|
198
|
+
if (actual === desired) {
|
|
199
|
+
const state = writeCurrentState(desired, env);
|
|
200
|
+
const alias = syncManagedAlias(finalBinary, env);
|
|
201
|
+
return { changed: false, version: desired, binary: finalBinary, alias, state, source: 'managed-cache' };
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
const stage = fs.mkdtempSync(path.join(root, '.install-'));
|
|
206
|
+
write('Installing ' + MACHINE_PACKAGE + '@' + desired + ' from crates.io…\n');
|
|
207
|
+
|
|
208
|
+
const result = spawnSync(
|
|
209
|
+
cargo,
|
|
210
|
+
['install', MACHINE_PACKAGE, '--root', stage, '--version', desired, '--locked', '--force'],
|
|
211
|
+
{ encoding: 'utf8', stdio: ['ignore', 'pipe', 'pipe'], env },
|
|
212
|
+
);
|
|
213
|
+
if (result.status !== 0) {
|
|
214
|
+
fs.rmSync(stage, { recursive: true, force: true });
|
|
215
|
+
const error = new Error(
|
|
216
|
+
String(result.stderr || result.stdout || '').trim() ||
|
|
217
|
+
'cargo install failed for ' + MACHINE_PACKAGE + '@' + desired,
|
|
218
|
+
);
|
|
219
|
+
error.code = 'AGENTSAM_MACHINE_INSTALL_FAILED';
|
|
220
|
+
throw error;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
const stagedBinary = path.join(stage, 'bin', machineBinaryName());
|
|
224
|
+
if (!fs.existsSync(stagedBinary)) {
|
|
225
|
+
fs.rmSync(stage, { recursive: true, force: true });
|
|
226
|
+
const error = new Error('cargo install completed without ' + machineBinaryName());
|
|
227
|
+
error.code = 'AGENTSAM_MACHINE_INSTALL_BINARY_MISSING';
|
|
228
|
+
throw error;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
const actual = machineBinaryVersion(stagedBinary, env);
|
|
232
|
+
if (actual !== desired) {
|
|
233
|
+
fs.rmSync(stage, { recursive: true, force: true });
|
|
234
|
+
const error = new Error(
|
|
235
|
+
'installed Machine version mismatch: expected ' + desired + ', received ' + (actual || 'unknown'),
|
|
236
|
+
);
|
|
237
|
+
error.code = 'AGENTSAM_MACHINE_INSTALL_VERSION_MISMATCH';
|
|
238
|
+
throw error;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
if (fs.existsSync(finalRoot)) fs.rmSync(finalRoot, { recursive: true, force: true });
|
|
242
|
+
fs.renameSync(stage, finalRoot);
|
|
243
|
+
const state = writeCurrentState(desired, env);
|
|
244
|
+
const alias = syncManagedAlias(finalBinary, env);
|
|
245
|
+
return { changed: true, version: desired, binary: finalBinary, alias, state, source: 'crates.io' };
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
export function updateManagedMachine({
|
|
249
|
+
env = process.env,
|
|
250
|
+
force = false,
|
|
251
|
+
write = () => {},
|
|
252
|
+
} = {}) {
|
|
253
|
+
const latest = discoverLatestMachineVersion(env);
|
|
254
|
+
const status = machineRuntimeStatus(env);
|
|
255
|
+
if (!force && status.installed && status.current_version === latest) {
|
|
256
|
+
return {
|
|
257
|
+
changed: false,
|
|
258
|
+
version: latest,
|
|
259
|
+
binary: status.binary,
|
|
260
|
+
alias: machineManagedAliasPath(env),
|
|
261
|
+
state: readMachineRuntimeState(env),
|
|
262
|
+
source: 'already-current',
|
|
263
|
+
};
|
|
264
|
+
}
|
|
265
|
+
return installManagedMachine({ env, version: latest, force, write });
|
|
266
|
+
}
|
package/src/commands/machine.js
CHANGED
|
@@ -1,81 +1,131 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* agentsam machine —
|
|
3
|
-
*
|
|
4
|
-
* Graduation rule: capability is complete when reachable through
|
|
5
|
-
* `agentsam machine …`, emits bounded deterministic receipts, and preserves evidence.
|
|
6
|
-
*
|
|
7
|
-
* Asset perception rule: discovery is read-only and network-free by default.
|
|
2
|
+
* agentsam machine — deterministic native Machine lifecycle + perception.
|
|
8
3
|
*/
|
|
9
4
|
|
|
10
5
|
import path from 'node:path';
|
|
11
6
|
import { resolveMachineBinary, spawnMachine } from './machine-binary.js';
|
|
7
|
+
import {
|
|
8
|
+
installManagedMachine,
|
|
9
|
+
machineBinaryVersion,
|
|
10
|
+
machineRuntimeStatus,
|
|
11
|
+
updateManagedMachine,
|
|
12
|
+
} from './machine-runtime.js';
|
|
12
13
|
|
|
13
14
|
function usage() {
|
|
14
|
-
return
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
agentsam machine
|
|
18
|
-
agentsam machine
|
|
19
|
-
agentsam machine --
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
15
|
+
return 'agentsam machine — deterministic local perception (native engine)\n\n' +
|
|
16
|
+
'Usage:\n' +
|
|
17
|
+
' agentsam machine status [--json]\n' +
|
|
18
|
+
' agentsam machine doctor [--json]\n' +
|
|
19
|
+
' agentsam machine install [--version <semver>] [--force] [--json]\n' +
|
|
20
|
+
' agentsam machine update [--force] [--json]\n' +
|
|
21
|
+
' agentsam machine inspect <path> [--json] [--run-id <id>] [--include-generated]\n' +
|
|
22
|
+
' agentsam machine --help\n\n' +
|
|
23
|
+
'Runtime authority:\n' +
|
|
24
|
+
' AgentSam manages one user-level Machine runtime under ~/.agentsam/runtimes/machine/.\n' +
|
|
25
|
+
' Every repository uses that managed runtime first; PATH and SDK source are fallbacks only.\n' +
|
|
26
|
+
' Install/update are explicit and never run merely because you entered a repository.\n\n' +
|
|
27
|
+
'Notes:\n' +
|
|
28
|
+
' Default inspect is read-only and network-free.\n' +
|
|
29
|
+
' Large detail is externalized under <target>/.agentsam/machine/runs/<run_id>/.\n' +
|
|
30
|
+
' Generated/cache trees are summarized unless --include-generated is set.\n' +
|
|
31
|
+
' Current registry distribution uses crates.io and therefore requires Cargo for install/update.\n';
|
|
27
32
|
}
|
|
28
33
|
|
|
29
34
|
function parseArgs(argv = []) {
|
|
30
35
|
const out = {
|
|
31
36
|
help: false,
|
|
32
37
|
json: false,
|
|
38
|
+
force: false,
|
|
33
39
|
includeGenerated: false,
|
|
34
40
|
runId: null,
|
|
41
|
+
version: null,
|
|
35
42
|
subcommand: null,
|
|
36
43
|
target: null,
|
|
37
44
|
positionals: [],
|
|
38
45
|
};
|
|
46
|
+
|
|
39
47
|
for (let i = 0; i < argv.length; i += 1) {
|
|
40
48
|
const arg = argv[i];
|
|
41
49
|
if (arg === '--help' || arg === '-h') out.help = true;
|
|
42
50
|
else if (arg === '--json') out.json = true;
|
|
51
|
+
else if (arg === '--force') out.force = true;
|
|
43
52
|
else if (arg === '--include-generated') out.includeGenerated = true;
|
|
44
53
|
else if (arg === '--run-id') {
|
|
45
54
|
const value = argv[++i];
|
|
46
|
-
if (value == null || value.startsWith('--'))
|
|
47
|
-
throw new Error('--run-id requires a value');
|
|
48
|
-
}
|
|
55
|
+
if (value == null || value.startsWith('--')) throw new Error('--run-id requires a value');
|
|
49
56
|
out.runId = value;
|
|
57
|
+
} else if (arg === '--version') {
|
|
58
|
+
const value = argv[++i];
|
|
59
|
+
if (value == null || value.startsWith('--')) throw new Error('--version requires a value');
|
|
60
|
+
out.version = value;
|
|
50
61
|
} else if (arg.startsWith('-')) {
|
|
51
|
-
throw new Error(
|
|
62
|
+
throw new Error('unknown machine option: ' + arg);
|
|
52
63
|
} else {
|
|
53
64
|
out.positionals.push(arg);
|
|
54
65
|
}
|
|
55
66
|
}
|
|
67
|
+
|
|
56
68
|
out.subcommand = out.positionals[0] || null;
|
|
57
69
|
out.target = out.positionals[1] || null;
|
|
58
70
|
return out;
|
|
59
71
|
}
|
|
60
72
|
|
|
61
|
-
function
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
73
|
+
function statusPayload() {
|
|
74
|
+
const managed = machineRuntimeStatus();
|
|
75
|
+
const resolution = resolveMachineBinary();
|
|
76
|
+
let effectiveVersion = null;
|
|
77
|
+
if (resolution.kind === 'binary') effectiveVersion = machineBinaryVersion(resolution.path);
|
|
78
|
+
|
|
79
|
+
return {
|
|
80
|
+
capability: 'machine.status',
|
|
81
|
+
managed,
|
|
82
|
+
effective: {
|
|
83
|
+
...resolution,
|
|
84
|
+
version: resolution.version || effectiveVersion,
|
|
85
|
+
},
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function printTextStatus(payload) {
|
|
90
|
+
console.log('AgentSam Machine');
|
|
91
|
+
console.log('');
|
|
92
|
+
console.log(' managed ' + (payload.managed.installed ? 'installed' : 'not installed'));
|
|
93
|
+
console.log(' version ' + (payload.managed.current_version || '—'));
|
|
94
|
+
console.log(' binary ' + (payload.managed.binary || '—'));
|
|
95
|
+
console.log(' runtime ' + payload.managed.runtime_root);
|
|
96
|
+
console.log(' effective ' + payload.effective.source);
|
|
97
|
+
console.log(' effective v ' + (payload.effective.version || 'unknown'));
|
|
98
|
+
console.log(' cargo ' + (payload.managed.cargo.available ? payload.managed.cargo.path : 'not found'));
|
|
99
|
+
if (!payload.managed.installed) {
|
|
100
|
+
console.log('');
|
|
101
|
+
console.log(' Run agentsam machine install to adopt the user-managed runtime.');
|
|
66
102
|
}
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
function printTextDoctor(payload) {
|
|
106
|
+
printTextStatus(payload);
|
|
107
|
+
console.log('');
|
|
108
|
+
if (payload.effective.kind === 'missing') {
|
|
109
|
+
console.log(' ✕ Machine unavailable');
|
|
110
|
+
console.log(' tried ' + (payload.effective.tried || []).join(', '));
|
|
111
|
+
} else if (payload.managed.installed) {
|
|
112
|
+
console.log(' ✓ managed Machine runtime is available');
|
|
113
|
+
} else {
|
|
114
|
+
console.log(' ○ Machine works through fallback source: ' + payload.effective.source);
|
|
115
|
+
console.log(' ○ install the managed runtime to make resolution consistent across repositories');
|
|
71
116
|
}
|
|
72
|
-
console.log('agentsam-machine unavailable');
|
|
73
|
-
console.log(`tried: ${(resolution.tried || []).join(', ')}`);
|
|
74
117
|
}
|
|
75
118
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
119
|
+
function printInstallResult(action, result) {
|
|
120
|
+
console.log('AgentSam Machine ' + action);
|
|
121
|
+
console.log('');
|
|
122
|
+
console.log(' version ' + result.version);
|
|
123
|
+
console.log(' binary ' + result.binary);
|
|
124
|
+
console.log(' alias ' + result.alias);
|
|
125
|
+
console.log(' source ' + result.source);
|
|
126
|
+
console.log(' changed ' + (result.changed ? 'yes' : 'no'));
|
|
127
|
+
}
|
|
128
|
+
|
|
79
129
|
export async function runMachine(argv = []) {
|
|
80
130
|
const args = parseArgs(argv);
|
|
81
131
|
if (args.help || !args.subcommand) {
|
|
@@ -83,20 +133,43 @@ export async function runMachine(argv = []) {
|
|
|
83
133
|
return 0;
|
|
84
134
|
}
|
|
85
135
|
|
|
86
|
-
|
|
136
|
+
if (args.subcommand === 'status') {
|
|
137
|
+
const payload = statusPayload();
|
|
138
|
+
if (args.json) console.log(JSON.stringify(payload));
|
|
139
|
+
else printTextStatus(payload);
|
|
140
|
+
return 0;
|
|
141
|
+
}
|
|
87
142
|
|
|
88
143
|
if (args.subcommand === 'doctor') {
|
|
89
|
-
const payload =
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
144
|
+
const payload = statusPayload();
|
|
145
|
+
if (args.json) console.log(JSON.stringify({ ...payload, capability: 'machine.doctor' }));
|
|
146
|
+
else printTextDoctor(payload);
|
|
147
|
+
return payload.effective.kind === 'missing' ? 1 : 0;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
if (args.subcommand === 'install') {
|
|
151
|
+
const result = installManagedMachine({
|
|
152
|
+
version: args.version,
|
|
153
|
+
force: args.force,
|
|
154
|
+
write: args.json ? () => {} : (value) => process.stdout.write(value),
|
|
155
|
+
});
|
|
156
|
+
if (args.json) console.log(JSON.stringify({ capability: 'machine.install', ...result }));
|
|
157
|
+
else printInstallResult('install', result);
|
|
158
|
+
return 0;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
if (args.subcommand === 'update') {
|
|
162
|
+
const result = updateManagedMachine({
|
|
163
|
+
force: args.force,
|
|
164
|
+
write: args.json ? () => {} : (value) => process.stdout.write(value),
|
|
165
|
+
});
|
|
166
|
+
if (args.json) console.log(JSON.stringify({ capability: 'machine.update', ...result }));
|
|
167
|
+
else printInstallResult('update', result);
|
|
168
|
+
return 0;
|
|
97
169
|
}
|
|
98
170
|
|
|
99
171
|
if (args.subcommand === 'inspect') {
|
|
172
|
+
const resolution = resolveMachineBinary();
|
|
100
173
|
const target = args.target || process.cwd();
|
|
101
174
|
const abs = path.resolve(target);
|
|
102
175
|
const machineArgv = ['inspect', abs];
|
|
@@ -106,7 +179,6 @@ export async function runMachine(argv = []) {
|
|
|
106
179
|
|
|
107
180
|
const result = spawnMachine(resolution, machineArgv, {
|
|
108
181
|
stdio: args.json ? ['ignore', 'pipe', 'pipe'] : 'inherit',
|
|
109
|
-
// Large donors still emit bounded compact JSON; raise buffer for safety.
|
|
110
182
|
maxBuffer: 32 * 1024 * 1024,
|
|
111
183
|
});
|
|
112
184
|
|
|
@@ -115,13 +187,12 @@ export async function runMachine(argv = []) {
|
|
|
115
187
|
const stdout = String(result.stdout || '');
|
|
116
188
|
const stderr = String(result.stderr || '');
|
|
117
189
|
if (result.status && result.status !== 0) {
|
|
118
|
-
const err = new Error(stderr.trim() ||
|
|
190
|
+
const err = new Error(stderr.trim() || 'agentsam-machine exited with code ' + result.status);
|
|
119
191
|
err.exitCode = result.status;
|
|
120
192
|
throw err;
|
|
121
193
|
}
|
|
122
194
|
try {
|
|
123
|
-
|
|
124
|
-
console.log(JSON.stringify(parsed));
|
|
195
|
+
console.log(JSON.stringify(JSON.parse(stdout)));
|
|
125
196
|
} catch {
|
|
126
197
|
process.stdout.write(stdout);
|
|
127
198
|
}
|
|
@@ -131,7 +202,7 @@ export async function runMachine(argv = []) {
|
|
|
131
202
|
}
|
|
132
203
|
|
|
133
204
|
console.log(usage());
|
|
134
|
-
const err = new Error(
|
|
205
|
+
const err = new Error('Unknown machine subcommand: ' + args.subcommand);
|
|
135
206
|
err.exitCode = 1;
|
|
136
207
|
throw err;
|
|
137
208
|
}
|