Big News: Socket raises $60M Series C at a $1B valuation to secure software supply chains for AI-driven development.Announcement
Sign In

@agentuity/cli

Package Overview
Dependencies
Maintainers
2
Versions
251
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@agentuity/cli - npm Package Compare versions

Comparing version
0.0.11
to
0.0.12
+43
-2
bin/cli.ts

@@ -11,4 +11,24 @@ #!/usr/bin/env bun

import { checkLegacyCLI } from '../src/legacy-check';
import type { LogLevel } from '../src/types';
import type { CommandContext, LogLevel } from '../src/types';
// Cleanup TTY state before exit
function cleanupAndExit() {
if (process.stdin.isTTY) {
process.stdin.setRawMode(false);
process.stdout.write('\x1B[?25h'); // Restore cursor
}
process.exitCode = 0;
process.exit(0);
}
// Handle Ctrl+C gracefully
process.once('SIGINT', () => {
console.log('\n');
cleanupAndExit();
});
process.once('SIGTERM', () => {
cleanupAndExit();
});
validateRuntime();

@@ -65,3 +85,3 @@

const commands = await discoverCommands();
await registerCommands(program, commands, ctx);
await registerCommands(program, commands, ctx as unknown as CommandContext);

@@ -71,4 +91,25 @@ try {

} catch (error) {
// Don't log error if it's from Ctrl+C, user cancellation, or signal termination
if (error instanceof Error) {
const msg = error.message.toLowerCase();
if (
msg.includes('sigint') ||
msg.includes('sigterm') ||
msg.includes('user force closed') ||
msg.includes('cancelled') || // UK
msg.includes('canceled') || // US
msg === ''
) {
process.exit(0);
}
if ('name' in error && error.name === 'AbortError') {
process.exit(0);
}
}
// Also exit cleanly if error is empty/undefined (user cancellation)
if (!error) {
process.exit(0);
}
logger.error('CLI error:', error);
process.exit(1);
}
+1
-1

@@ -1,1 +0,1 @@

{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/cmd/dev/index.ts"],"names":[],"mappings":"AAOA,eAAO,MAAM,OAAO,qCA2ElB,CAAC"}
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/cmd/dev/index.ts"],"names":[],"mappings":"AAOA,eAAO,MAAM,OAAO,qCAyElB,CAAC"}

@@ -1,1 +0,1 @@

{"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../../src/cmd/project/create.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,uBAAuB,wCA8ClC,CAAC"}
{"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../../src/cmd/project/create.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,uBAAuB,wCA+ClC,CAAC"}

@@ -1,1 +0,1 @@

{"version":3,"file":"download.d.ts","sourceRoot":"","sources":["../../../src/cmd/project/download.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAGvC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAKhD,UAAU,eAAe;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,YAAY,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,UAAU,YAAY;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,OAAO,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;CACf;AAED,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CA6E9E;AAED,wBAAsB,YAAY,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CA8CvE"}
{"version":3,"file":"download.d.ts","sourceRoot":"","sources":["../../../src/cmd/project/download.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAGvC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAKhD,UAAU,eAAe;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,YAAY,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,UAAU,YAAY;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,OAAO,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;CACf;AAsBD,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAuD9E;AAED,wBAAsB,YAAY,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAgCvE"}
import type { Logger } from '@/logger';
interface CreateFlowOptions {
projectName?: string;
dir?: string;
template?: string;

@@ -5,0 +6,0 @@ templateDir?: string;

@@ -1,1 +0,1 @@

{"version":3,"file":"template-flow.d.ts","sourceRoot":"","sources":["../../../src/cmd/project/template-flow.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAKvC,UAAU,iBAAiB;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,SAAS,EAAE,OAAO,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,EAAE,OAAO,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;CACf;AAED,wBAAsB,aAAa,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CA+I7E"}
{"version":3,"file":"template-flow.d.ts","sourceRoot":"","sources":["../../../src/cmd/project/template-flow.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAMvC,UAAU,iBAAiB;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,SAAS,EAAE,OAAO,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,EAAE,OAAO,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;CACf;AAED,wBAAsB,aAAa,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CA0J7E"}

@@ -1,2 +0,2 @@

export declare function playSound(): Promise<void>;
export declare function playSound(): void;
//# sourceMappingURL=sound.d.ts.map

@@ -1,1 +0,1 @@

{"version":3,"file":"sound.d.ts","sourceRoot":"","sources":["../src/sound.ts"],"names":[],"mappings":"AAEA,wBAAsB,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC,CAsB/C"}
{"version":3,"file":"sound.d.ts","sourceRoot":"","sources":["../src/sound.ts"],"names":[],"mappings":"AAEA,wBAAgB,SAAS,IAAI,IAAI,CAoChC"}

@@ -20,3 +20,3 @@ /**

*/
export declare function warning(message: string): void;
export declare function warning(message: string, asError?: boolean): void;
/**

@@ -23,0 +23,0 @@ * Print an info message with a cyan info icon

@@ -1,1 +0,1 @@

{"version":3,"file":"tui.d.ts","sourceRoot":"","sources":["../src/tui.ts"],"names":[],"mappings":"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"}
{"version":3,"file":"tui.d.ts","sourceRoot":"","sources":["../src/tui.ts"],"names":[],"mappings":"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"}
{
"name": "@agentuity/cli",
"version": "0.0.11",
"version": "0.0.12",
"type": "module",

@@ -5,0 +5,0 @@ "main": "./src/index.ts",

@@ -38,5 +38,3 @@ import { createCommand } from '@/types';

tui.newline();
tui.info('Starting development server...');
tui.newline();

@@ -43,0 +41,0 @@ // Use shell to run in a process group for proper cleanup

@@ -9,7 +9,7 @@ import type { SubcommandDefinition } from '../../types';

async handler() {
handler() {
tui.info('Playing completion sound...');
await playSound();
playSound();
tui.success('Sound played!');
},
};

@@ -42,2 +42,3 @@ import { createSubcommand } from '@/types';

projectName: opts.name,
dir: opts.dir,
template: opts.template,

@@ -44,0 +45,0 @@ templateDir: opts.templateDir,

@@ -1,6 +0,7 @@

import { join } from 'node:path';
import { join, resolve } from 'node:path';
import { existsSync, mkdirSync, renameSync, readdirSync, cpSync, rmSync } from 'node:fs';
import { homedir } from 'node:os';
import { pipeline } from 'node:stream/promises';
import { createGunzip } from 'node:zlib';
import { extract } from 'tar-fs';
import { extract, type Headers } from 'tar-fs';
import type { Logger } from '@/logger';

@@ -30,2 +31,22 @@ import * as tui from '@/tui';

async function cleanup(sourceDir: string, dest: string) {
if (!existsSync(sourceDir)) {
throw new Error(`Template directory not found: ${sourceDir}`);
}
tui.spinner(`📦 Copying template from ${sourceDir}...`, async () => {
// Copy all files from source to dest
const files = readdirSync(sourceDir);
for (const file of files) {
cpSync(join(sourceDir, file), join(dest, file), { recursive: true });
}
// Rename gitignore -> .gitignore
const gi = join(dest, 'gitignore');
if (existsSync(gi)) {
renameSync(gi, join(dest, '.gitignore'));
}
});
}
export async function downloadTemplate(options: DownloadOptions): Promise<void> {

@@ -38,3 +59,2 @@ const { dest, template, templateDir, templateBranch } = options;

if (templateDir) {
const { resolve } = await import('node:path');
const sourceDir = resolve(join(templateDir, template.directory));

@@ -46,17 +66,3 @@

tui.info(`📦 Copying template from ${sourceDir}...`);
// Copy all files from source to dest
const files = readdirSync(sourceDir);
for (const file of files) {
cpSync(join(sourceDir, file), join(dest, file), { recursive: true });
}
// Rename gitignore -> .gitignore
const gi = join(dest, 'gitignore');
if (existsSync(gi)) {
renameSync(gi, join(dest, '.gitignore'));
}
return;
return cleanup(sourceDir, dest);
}

@@ -80,2 +86,3 @@

// Extract only the template directory from tarball
const prefix = `sdk-${branch}/${templatePath}/`;
await pipeline(

@@ -85,10 +92,6 @@ stream,

extract(tempDir, {
map: (header) => {
const prefix = `sdk-${branch}/${templatePath}/`;
if (header.name.startsWith(prefix)) {
header.name = header.name.substring(prefix.length);
return header;
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
return null as any;
filter: (name: string) => name.startsWith(prefix),
map: (header: Headers) => {
header.name = header.name.substring(prefix.length);
return header;
},

@@ -100,14 +103,10 @@ })

// Move files from temp to dest
const files = readdirSync(tempDir);
for (const file of files) {
cpSync(join(tempDir, file), join(dest, file), { recursive: true });
await cleanup(tempDir, dest);
// Extra safety: refuse to delete root or home directories
const home = homedir();
if (tempDir === '/' || tempDir === home) {
throw new Error(`Refusing to delete protected path: ${tempDir}`);
}
rmSync(tempDir, { recursive: true, force: true });
// Rename gitignore -> .gitignore
const gi = join(dest, 'gitignore');
if (existsSync(gi)) {
renameSync(gi, join(dest, '.gitignore'));
}
}

@@ -118,4 +117,2 @@

process.chdir(dest);
// Replace {{PROJECT_NAME}} in files

@@ -125,16 +122,2 @@ tui.info(`🔧 Setting up ${projectName}...`);

// Run setup.ts if it exists (legacy)
if (await Bun.file('./setup.ts').exists()) {
await tui.spinner({
message: 'Running setup script...',
callback: async () => {
const proc = Bun.spawn(['bun', './setup.ts'], { stdio: ['pipe', 'pipe', 'pipe'] });
const exitCode = await proc.exited;
if (exitCode !== 0) {
logger.error('Setup script failed');
}
},
});
}
// Install dependencies

@@ -144,2 +127,3 @@ if (!noInstall) {

command: 'bun install',
cwd: dest,
cmd: ['bun', 'install'],

@@ -157,2 +141,3 @@ clearOnSuccess: true,

command: 'bun run build',
cwd: dest,
cmd: ['bun', 'run', 'build'],

@@ -159,0 +144,0 @@ clearOnSuccess: true,

import { basename, resolve } from 'node:path';
import { existsSync, readdirSync, rmSync } from 'node:fs';
import { cwd } from 'node:process';
import { homedir } from 'node:os';
import enquirer from 'enquirer';
import type { Logger } from '@/logger';
import * as tui from '@/tui';
import { playSound } from '@/sound';
import { fetchTemplates, type TemplateInfo } from './templates';

@@ -11,2 +14,3 @@ import { downloadTemplate, setupProject } from './download';

projectName?: string;
dir?: string;
template?: string;

@@ -24,2 +28,3 @@ templateDir?: string;

projectName: initialProjectName,
dir: targetDir,
template: initialTemplate,

@@ -69,3 +74,9 @@ templateDir,

// Step 4: Determine destination directory
const dest = dirName === '.' ? process.cwd() : resolve(process.cwd(), dirName);
// Expand ~ to home directory
let expandedTargetDir = targetDir;
if (expandedTargetDir && expandedTargetDir.startsWith('~')) {
expandedTargetDir = expandedTargetDir.replace(/^~/, homedir());
}
const baseDir = expandedTargetDir ? resolve(expandedTargetDir) : process.cwd();
const dest = dirName === '.' ? baseDir : resolve(baseDir, dirName);
const destExists = existsSync(dest);

@@ -77,3 +88,3 @@ const destEmpty = destExists ? readdirSync(dest).length === 0 : true;

if (process.stdin.isTTY && !skipPrompts) {
tui.warning(`Directory ${dirName} already exists and is not empty.\n`);
tui.warning(`Directory ${dest} already exists and is not empty.`, true);
const response = await enquirer.prompt<{ overwrite: boolean }>({

@@ -91,7 +102,12 @@ type: 'confirm',

// Delete the existing directory
// Extra safety: refuse to delete root or home directories
const home = homedir();
if (dest === '/' || dest === home) {
logger.fatal(`Refusing to delete protected path: ${dest}`);
return;
}
rmSync(dest, { recursive: true, force: true });
tui.success(`Deleted ${dirName}\n`);
tui.success(`Deleted ${dest}\n`);
} else {
logger.fatal(`Directory ${dirName} already exists and is not empty.`);
logger.fatal(`Directory ${dest} already exists and is not empty.`, true);
}

@@ -102,5 +118,4 @@ }

if (!skipPrompts) {
const displayPath = dirName === '.' ? basename(dest) : dirName;
tui.info(`📁 Project: ${tui.bold(projectName)}`);
tui.info(`📂 Directory: ${tui.bold(displayPath)}\n`);
tui.info(`📂 Directory: ${tui.bold(dest)}\n`);
}

@@ -161,10 +176,10 @@

if (dirName !== '.') {
const dirDisplay = cwd() == targetDir ? basename(dirName) : dest;
tui.newline();
console.log(` 1. ${tui.bold(`cd ${dirName}`)}`);
console.log(` 1. ${tui.bold(`cd ${dirDisplay}`)}`);
console.log(` 2. ${tui.bold('bun run dev')}`);
} else {
console.log(` 1. ${tui.bold('bun run dev')}`);
console.log(` ${tui.bold('bun run dev')}`);
}
tui.newline();
console.log(`Your agents will be running at ${tui.link('http://localhost:3000')}`);
playSound();
}

@@ -171,0 +186,0 @@

@@ -1,2 +0,2 @@

import { Transform } from 'node:stream';
import { Transform, Readable } from 'node:stream';
import * as tui from './tui';

@@ -51,3 +51,3 @@

// Pipe the response through the progress tracker
const responseStream = response.body as unknown as NodeJS.ReadableStream;
const responseStream = Readable.fromWeb(response.body as unknown as ReadableStream);
responseStream.pipe(progressStream);

@@ -54,0 +54,0 @@

@@ -1,25 +0,39 @@

import { $ } from 'bun';
import { join } from 'node:path';
export async function playSound(): Promise<void> {
export function playSound(): void {
const platform = process.platform;
let result;
let command: string[];
switch (platform) {
case 'darwin':
result = await $`afplay /System/Library/Sounds/Glass.aiff`.quiet().nothrow();
case 'darwin': {
const items = [
'Blow.aiff',
'Bottle.aiff',
'Frog.aiff',
'Funk.aiff',
'Glass.aiff',
'Hero.aiff',
'Morse.aiff',
'Ping.aiff',
'Pop.aiff',
'Purr.aiff',
'Sosumi.aiff',
] as const;
const file = items[Math.floor(Math.random() * items.length)];
command = ['afplay', join('/System/Library/Sounds', file)];
break;
}
case 'linux':
result = await $`paplay /usr/share/sounds/freedesktop/stereo/complete.oga`
.quiet()
.nothrow();
command = ['paplay', '/usr/share/sounds/freedesktop/stereo/complete.oga'];
break;
case 'win32':
result = await $`rundll32 user32.dll,MessageBeep 0x00000040`.quiet().nothrow();
command = ['rundll32', 'user32.dll,MessageBeep', '0x00000040'];
break;
default:
return;
}
// Fallback to terminal bell if command failed or platform unsupported
if (!result || result.exitCode !== 0) {
process.stdout.write('\u0007');
}
Bun.spawn(command, {
stdio: ['ignore', 'ignore', 'ignore'],
}).unref();
}

@@ -88,4 +88,4 @@ /**

*/
export function warning(message: string): void {
const color = getColor('warning');
export function warning(message: string, asError = false): void {
const color = asError ? getColor('error') : getColor('warning');
const reset = COLORS.reset;

@@ -809,3 +809,5 @@ console.log(`${color}${ICONS.warning} ${message}${reset}`);

// Show compact success: ✓ command
process.stdout.write(`\r\x1b[K${green}${ICONS.success}${reset} ${cmdColor}${displayCmd}${reset}\n`);
process.stdout.write(
`\r\x1b[K${green}${ICONS.success}${reset} ${cmdColor}${displayCmd}${reset}\n`
);
} else {

@@ -812,0 +814,0 @@ // Determine how many lines to show in final output