--- install scripts ---
### prepublishOnly
bun run clean && bun run build
--- package/src/agent-detection.ts (excerpt) ---
import { dlopen, FFIType, ptr } from 'bun:ffi';
import { readFileSync } from 'node:fs';
/**
* Map of process names to internal agent short names.
* The key is the process name (or substring) that appears in the parent process path or command line.
* The value is the internal short name used to identify the agent.
*
* Process names verified via `agentuity cloud sandbox run --runtime <agent>:latest`:
* - opencode: binary 'opencode' (from bun install -g opencode-ai)
* - codex: binary 'codex' (from npm install -g @openai/codex)
* - cursor: binary 'cursor-agent' (from curl installer)
* - claude-code: binary 'claude', shows as 'node /usr/local/bin/claude'
* - copilot: binary 'copilot', shows as 'node /usr/local/bin/copilot' and spawns native binary
* - gemini: binary 'gemini', shows as 'node /usr/local/bin/gemini'
* - amp: binary 'amp', shows as 'node --no-warnings /usr/local/bin/amp'
*
* IMPORTANT: Order matters! More specific patterns should come before less specific ones.
* For example, 'opencode' must be checked before 'code' to avoid false matches.
*/
export const KNOWN_AGENTS: [string, string][] = [
// Verified via cloud sandbox runtime - most specific patterns first
['opencode', 'opencode'],
['codex', 'codex'],
['cursor-agent', 'cursor'],
['claude', 'claude-code'],
['copilot', 'copilot'],
['gemini', 'gemini'],
['cline', 'cline'],
['roo-code', 'roo'],
['windsurf', 'windsurf'],
['zed', 'zed'],
['amp', 'amp'],
['warp', 'warp'],
['pi', 'pi'],
['co
--- package/src/api.ts (excerpt) ---
/**
* CLI-specific API client wrapper
*
* Re-exports from @agentuity/server with CLI-specific configuration
*/
import type { Config, Logger } from './types';
import { getVersion, getRevision } from './version';
import {
APIClient as BaseAPIClient,
getAPIBaseURL as baseGetAPIBaseURL,
getAppBaseURL as baseGetAppBaseURL,
type APIClientConfig,
} from '@agentuity/server';
export function getUserAgent(config?: Config | null): string {
// If we're skipping version check, send "dev" to signal the server to skip too
let version = getVersion();
if (shouldSkipVersionCheck(config)) {
version = 'dev';
}
const revision = getRevision();
return `Agentuity CLI/${version} (${revision})`;
}
function shouldSkipVersionCheck(config?: Config | null): boolean {
// Priority order:
// 1. CLI flag (set via env var in cli.ts)
// 2. Environment variable
// 3. Config override
// 4. Auto-detection (dev/0.0.x versions)
// Skip if environment variable is set (includes CLI flag)
if (
process.env.AGENTUITY_SKIP_VERSION_CHECK === '1' ||
process.env.AGENTUITY_SKIP_VERSION_CHECK === 'true'
) {
return true;
}
// Check config overrides
const overrides = config?.overrides as { skip_version_check?: boolean } | undefined;
if (overrides?.skip_version_check === true) {
return true;
}
// Skip if version is 'dev' or starts with '0.0.' (pre-release/local development)
const version = getVersion();
if (version === 'dev' || version.startsWith('0.0.')) {
return true;
}
return
--- package/src/auth.ts (excerpt) ---
import enquirer from 'enquirer';
import { getDefaultConfigPath, getAuth, saveConfig, loadConfig, saveOrgId } from './config';
import { getResourceInfo, type ResourceType } from './cache';
import { getCommand } from './command-prefix';
import type { CommandContext, AuthData, Config } from './types';
import * as tui from './tui';
import { defaultProfileName } from './config';
import { listOrganizations } from '@agentuity/server';
import { APIClient, getAPIBaseURL, getAppBaseURL, type APIClient as APIClientType } from './api';
export function isTTY(): boolean {
return process.stdin.isTTY === true && process.stdout.isTTY === true;
}
const ORG_ID_ENV_VAR = 'AGENTUITY_CLOUD_ORG_ID';
const NON_INTERACTIVE_ORG_ERROR =
'Cannot select organization in non-interactive mode. ' +
`Use --org-id, set ${ORG_ID_ENV_VAR}, or run interactively.`;
const RESOURCE_PREFIXES: Array<{ prefix: string; type: ResourceType }> = [
{ prefix: 'sbx_', type: 'sandbox' },
{ prefix: 'proj_', type: 'project' },
{ prefix: 'db_', type: 'db' },
{ prefix: 'deploy_', type: 'deployment' },
{ prefix: 'machine_', type: 'machine' },
{ prefix: 'que_', type: 'queue' },
{ prefix: 'vec_', type: 'vector' },
{ prefix: 'kv_', type: 'kv' },
{ prefix: 'stream_', type: 'stream' },
{ prefix: 'eaddr_', type: 'email' },
{ prefix: 'edest_', type: 'email' },
{ prefix: 'ein_', type: 'email' },
{ prefix: 'eout_', type: 'email' },
{ prefix: 'edlv_', type: 'email' },
{ prefix: 'wh_', type: 'webhook' },
{ prefix: 'task_import { dlopen, FFIType, ptr } from 'bun:ffi';
import { readFileSync } from 'node:fs';
/**
* Map of process names to internal agent short names.
* The key is the process name (or substring) that appears in the parent process path or command line.
* The value is the internal short name used to identify the agent.
*
* Process names verified via `agentuity cloud sandbox run --runtime <agent>:latest`:
* - opencode: binary 'opencode' (from bun install -g opencode-ai)
* - codex: binary 'codex' (from npm install -g @openai/codex)
* - cursor: binary 'cursor-agent' (from curl installer)
* - claude-code: binary 'claude', shows as 'node /usr/local/bin/claude'
* - copilot: binary 'copilot', shows as 'node /usr/local/bin/copilot' and spawns native binary
* - gemini: binary 'gemini', shows as 'node /usr/local/bin/gemini'
* - amp: binary 'amp', shows as 'node --no-warnings /usr/local/bin/amp'
*
* IMPORTANT: Order matters! More specific patterns should come before less specific ones.
* For example, 'opencode' must be checked before 'code' to avoid false matches.
*/
export const KNOWN_AGENTS: [string, string][] = [
// Verified via cloud sandbox runtime - most specific patterns first
['opencode', 'opencode'],
['codex', 'codex'],
['cursor-agent', 'cursor'],
['claude', 'claude-code'],
['copilot', 'copilot'],
['gemini', 'gemini'],
['cline', 'cline'],
['roo-code', 'roo'],
['windsurf', 'windsurf'],
['zed', 'zed'],
['amp', 'amp'],
['warp', 'warp'],
['pi', 'pi'],
['co
import enquirer from 'enquirer';
import { getDefaultConfigPath, getAuth, saveConfig, loadConfig, saveOrgId } from './config';
import { getResourceInfo, type ResourceType } from './cache';
import { getCommand } from './command-prefix';
import type { CommandContext, AuthData, Config } from './types';
import * as tui from './tui';
import { defaultProfileName } from './config';
import { listOrganizations } from '@agentuity/server';
import { APIClient, getAPIBaseURL, getAppBaseURL, type APIClient as APIClientType } from './api';
export function isTTY(): boolean {
return process.stdin.isTTY === true && process.stdout.isTTY === true;
}
const ORG_ID_ENV_VAR = 'AGENTUITY_CLOUD_ORG_ID';
const NON_INTERACTIVE_ORG_ERROR =
'Cannot select organization in non-interactive mode. ' +
`Use --org-id, set ${ORG_ID_ENV_VAR}, or run interactively.`;
const RESOURCE_PREFIXES: Array<{ prefix: string; type: ResourceType }> = [
{ prefix: 'sbx_', type: 'sandbox' },
{ prefix: 'proj_', type: 'project' },
{ prefix: 'db_', type: 'db' },
{ prefix: 'deploy_', type: 'deployment' },
{ prefix: 'machine_', type: 'machine' },
{ prefix: 'que_', type: 'queue' },
{ prefix: 'vec_', type: 'vector' },
{ prefix: 'kv_', type: 'kv' },
{ prefix: 'stream_', type: 'stream' },
{ prefix: 'eaddr_', type: 'email' },
{ prefix: 'edest_', type: 'email' },
{ prefix: 'ein_', type: 'email' },
{ prefix: 'eout_', type: 'email' },
{ prefix: 'edlv_', type: 'email' },
{ prefix: 'wh_', type: 'webhook' },
{ prefix: 'task_