@stan-chen/simple-cli 0.2.5 → 0.2.6

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.
@@ -1,4 +1,5 @@
1
1
  import { z } from 'zod';
2
+ export declare const cleanupProcesses: () => void;
2
3
  export declare const readFiles: {
3
4
  name: string;
4
5
  description: string;
@@ -255,21 +256,37 @@ export declare const runCommand: {
255
256
  inputSchema: z.ZodObject<{
256
257
  command: z.ZodString;
257
258
  timeout: z.ZodOptional<z.ZodNumber>;
259
+ background: z.ZodDefault<z.ZodBoolean>;
258
260
  }, "strip", z.ZodTypeAny, {
259
261
  command: string;
262
+ background: boolean;
260
263
  timeout?: number | undefined;
261
264
  }, {
262
265
  command: string;
263
266
  timeout?: number | undefined;
267
+ background?: boolean | undefined;
264
268
  }>;
265
- execute: ({ command, timeout }: {
269
+ execute: ({ command, timeout, background }: {
266
270
  command: string;
267
271
  timeout?: number;
272
+ background: boolean;
268
273
  }) => Promise<{
274
+ message: string;
275
+ pid: number | undefined;
276
+ success: boolean;
277
+ stdout?: undefined;
278
+ stderr?: undefined;
279
+ exitCode?: undefined;
280
+ timedOut?: undefined;
281
+ error?: undefined;
282
+ } | {
269
283
  stdout: string;
270
284
  stderr: string;
271
285
  exitCode: number;
272
286
  timedOut: boolean;
287
+ message?: undefined;
288
+ pid?: undefined;
289
+ success?: undefined;
273
290
  error?: undefined;
274
291
  } | {
275
292
  error: any;
@@ -277,7 +294,24 @@ export declare const runCommand: {
277
294
  stderr: any;
278
295
  exitCode: any;
279
296
  timedOut: any;
297
+ message?: undefined;
298
+ pid?: undefined;
299
+ success?: undefined;
300
+ }>;
301
+ };
302
+ export declare const stopCommand: {
303
+ name: string;
304
+ description: string;
305
+ inputSchema: z.ZodObject<{
306
+ pid: z.ZodNumber;
307
+ }, "strip", z.ZodTypeAny, {
308
+ pid: number;
309
+ }, {
310
+ pid: number;
280
311
  }>;
312
+ execute: ({ pid }: {
313
+ pid: number;
314
+ }) => Promise<string>;
281
315
  };
282
316
  export declare const deleteFile: {
283
317
  name: string;
@@ -617,21 +651,37 @@ export declare const allBuiltins: ({
617
651
  inputSchema: z.ZodObject<{
618
652
  command: z.ZodString;
619
653
  timeout: z.ZodOptional<z.ZodNumber>;
654
+ background: z.ZodDefault<z.ZodBoolean>;
620
655
  }, "strip", z.ZodTypeAny, {
621
656
  command: string;
657
+ background: boolean;
622
658
  timeout?: number | undefined;
623
659
  }, {
624
660
  command: string;
625
661
  timeout?: number | undefined;
662
+ background?: boolean | undefined;
626
663
  }>;
627
- execute: ({ command, timeout }: {
664
+ execute: ({ command, timeout, background }: {
628
665
  command: string;
629
666
  timeout?: number;
667
+ background: boolean;
630
668
  }) => Promise<{
669
+ message: string;
670
+ pid: number | undefined;
671
+ success: boolean;
672
+ stdout?: undefined;
673
+ stderr?: undefined;
674
+ exitCode?: undefined;
675
+ timedOut?: undefined;
676
+ error?: undefined;
677
+ } | {
631
678
  stdout: string;
632
679
  stderr: string;
633
680
  exitCode: number;
634
681
  timedOut: boolean;
682
+ message?: undefined;
683
+ pid?: undefined;
684
+ success?: undefined;
635
685
  error?: undefined;
636
686
  } | {
637
687
  error: any;
@@ -639,7 +689,23 @@ export declare const allBuiltins: ({
639
689
  stderr: any;
640
690
  exitCode: any;
641
691
  timedOut: any;
692
+ message?: undefined;
693
+ pid?: undefined;
694
+ success?: undefined;
695
+ }>;
696
+ } | {
697
+ name: string;
698
+ description: string;
699
+ inputSchema: z.ZodObject<{
700
+ pid: z.ZodNumber;
701
+ }, "strip", z.ZodTypeAny, {
702
+ pid: number;
703
+ }, {
704
+ pid: number;
642
705
  }>;
706
+ execute: ({ pid }: {
707
+ pid: number;
708
+ }) => Promise<string>;
643
709
  } | {
644
710
  name: string;
645
711
  description: string;
package/dist/builtins.js CHANGED
@@ -1,11 +1,39 @@
1
1
  import { readFile, writeFile, readdir, unlink, mkdir, stat } from 'fs/promises';
2
2
  import { existsSync } from 'fs';
3
3
  import { join, resolve, relative, extname } from 'path';
4
- import { exec } from 'child_process';
4
+ import { exec, spawn, execSync } from 'child_process';
5
5
  import { promisify } from 'util';
6
6
  import { z } from 'zod';
7
7
  import glob from 'fast-glob';
8
8
  const execAsync = promisify(exec);
9
+ const activeProcesses = [];
10
+ export const cleanupProcesses = () => {
11
+ for (const proc of activeProcesses) {
12
+ if (!proc.killed && proc.pid) {
13
+ if (process.platform === 'win32') {
14
+ try {
15
+ execSync(`taskkill /F /T /PID ${proc.pid}`);
16
+ }
17
+ catch {
18
+ proc.kill('SIGTERM');
19
+ }
20
+ }
21
+ else {
22
+ proc.kill('SIGTERM');
23
+ }
24
+ }
25
+ }
26
+ };
27
+ // Handle cleanup on exit
28
+ process.on('exit', cleanupProcesses);
29
+ process.on('SIGINT', () => {
30
+ cleanupProcesses();
31
+ process.exit();
32
+ });
33
+ process.on('SIGTERM', () => {
34
+ cleanupProcesses();
35
+ process.exit();
36
+ });
9
37
  export const readFiles = {
10
38
  name: 'read_files',
11
39
  description: 'Read contents of one or more files',
@@ -331,9 +359,27 @@ export const listDir = {
331
359
  };
332
360
  export const runCommand = {
333
361
  name: 'run_command',
334
- description: 'Run a shell command',
335
- inputSchema: z.object({ command: z.string(), timeout: z.number().optional() }),
336
- execute: async ({ command, timeout }) => {
362
+ description: 'Run a shell command. Use background: true for servers or long-running tasks.',
363
+ inputSchema: z.object({
364
+ command: z.string(),
365
+ timeout: z.number().optional(),
366
+ background: z.boolean().default(false).describe('Run command in background and return immediately')
367
+ }),
368
+ execute: async ({ command, timeout, background }) => {
369
+ if (background) {
370
+ const child = spawn(command, {
371
+ shell: true,
372
+ detached: true,
373
+ stdio: 'ignore'
374
+ });
375
+ child.unref();
376
+ activeProcesses.push(child);
377
+ return {
378
+ message: `Started background process: ${command}`,
379
+ pid: child.pid,
380
+ success: true
381
+ };
382
+ }
337
383
  try {
338
384
  const { stdout, stderr } = await execAsync(command, { timeout });
339
385
  return { stdout, stderr, exitCode: 0, timedOut: false };
@@ -350,6 +396,31 @@ export const runCommand = {
350
396
  }
351
397
  }
352
398
  };
399
+ export const stopCommand = {
400
+ name: 'stop_command',
401
+ description: 'Stop a background process by its PID',
402
+ inputSchema: z.object({ pid: z.number() }),
403
+ execute: async ({ pid }) => {
404
+ if (process.platform === 'win32') {
405
+ try {
406
+ await execAsync(`taskkill /F /T /PID ${pid}`);
407
+ return `Successfully stopped process ${pid}`;
408
+ }
409
+ catch (e) {
410
+ return `Error stopping process ${pid}: ${e.message}`;
411
+ }
412
+ }
413
+ else {
414
+ try {
415
+ process.kill(pid, 'SIGTERM');
416
+ return `Sent SIGTERM to process ${pid}`;
417
+ }
418
+ catch (e) {
419
+ return `Error stopping process ${pid}: ${e.message}`;
420
+ }
421
+ }
422
+ }
423
+ };
353
424
  export const deleteFile = {
354
425
  name: 'delete_file',
355
426
  description: 'Delete a file',
@@ -478,4 +549,4 @@ export const getTrackedFiles = async (cwd) => {
478
549
  return [];
479
550
  }
480
551
  };
481
- export const allBuiltins = [readFiles, writeFiles, createTool, scrapeUrl, listFiles, searchFiles, listDir, runCommand, deleteFile, gitTool, linter];
552
+ export const allBuiltins = [readFiles, writeFiles, createTool, scrapeUrl, listFiles, searchFiles, listDir, runCommand, stopCommand, deleteFile, gitTool, linter];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stan-chen/simple-cli",
3
- "version": "0.2.5",
3
+ "version": "0.2.6",
4
4
  "description": "A lean, lightweight coding agent. Packs a punch with token efficiency.",
5
5
  "type": "module",
6
6
  "main": "dist/cli.js",