arsenal-agent 0.1.2 → 0.1.4

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/dist/index.js CHANGED
@@ -1,61 +1,29 @@
1
1
  #!/usr/bin/env node
2
2
  import { spawn } from "node:child_process";
3
- import { createInterface } from "node:readline";
4
3
  import { Command } from "commander";
5
4
  import chalk from "chalk";
6
- import { classifyTask } from "./router.js";
7
5
  import { loadProfile, applyProfile, addProfile, listProfiles, useProfile } from "./profiles.js";
8
6
  const program = new Command();
9
7
  program
10
8
  .name("arsenal-agent")
11
- .description("Router: classifica a task e lança claude ou opencode automaticamente")
12
- .version("0.1.2")
9
+ .description("Launcher do Claude Code com perfil de conta configurado")
10
+ .version("0.1.3")
13
11
  .option("-p, --profile <name>", "perfil a usar")
14
- .argument("[task...]", "task a executar diretamente");
12
+ .argument("[args...]", "argumentos passados direto ao claude")
13
+ .allowUnknownOption(true)
14
+ .passThroughOptions(true);
15
15
  const profileCmd = program.command("profile").description("gerenciar perfis");
16
16
  profileCmd.command("add [name]").description("adicionar perfil").action(async (name) => { await addProfile(name); process.exit(0); });
17
17
  profileCmd.command("list").alias("ls").description("listar perfis").action(() => { listProfiles(); process.exit(0); });
18
18
  profileCmd.command("use <name>").description("definir perfil ativo").action((name) => { useProfile(name); process.exit(0); });
19
- program.action(async (taskArgs, opts) => {
20
- // Aplica perfil
19
+ program.action((claudeArgs, opts) => {
21
20
  const profile = loadProfile(opts.profile);
22
21
  if (profile) {
23
22
  applyProfile(profile);
24
23
  process.stderr.write(chalk.dim(`[${profile.label ?? profile.name}]\n`));
25
24
  }
26
- else if (!process.env.ANTHROPIC_API_KEY) {
27
- console.error(chalk.red("Nenhuma conta configurada. Rode: aa profile add"));
28
- process.exit(1);
29
- }
30
- // Task via argumento ou prompt interativo
31
- const task = taskArgs.length > 0
32
- ? taskArgs.join(" ")
33
- : await askTask();
34
- if (!task.trim())
35
- process.exit(0);
36
- // Classifica e lança
37
- const { model, reason } = classifyTask(task);
38
- const isFree = model !== "sonnet";
39
- console.log(chalk.dim("→ ") +
40
- (isFree ? chalk.yellow("Nemotron 120B") : chalk.cyan("Claude Sonnet")) +
41
- chalk.dim(` (${reason})`) +
42
- (isFree ? chalk.green(" free") : ""));
43
- console.log();
44
- if (model === "sonnet") {
45
- launch("claude", [task]);
46
- }
47
- else {
48
- launch("opencode", ["run", task, "--model", "openrouter/nvidia/nemotron-3-super-120b-a12b:free"]);
49
- }
50
- });
51
- function askTask() {
52
- return new Promise((resolve) => {
53
- const rl = createInterface({ input: process.stdin, output: process.stdout });
54
- rl.question(chalk.white("> "), (answer) => { rl.close(); resolve(answer.trim()); });
55
- });
56
- }
57
- function launch(cmd, args) {
58
- const child = spawn(cmd, args, { stdio: "inherit", env: process.env });
25
+ // Passa tudo direto pro claude — argumentos, flags, o que for
26
+ const child = spawn("claude", claudeArgs, { stdio: "inherit", env: process.env });
59
27
  child.on("exit", (code) => process.exit(code ?? 0));
60
- }
28
+ });
61
29
  program.parse();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "arsenal-agent",
3
- "version": "0.1.2",
3
+ "version": "0.1.4",
4
4
  "description": "Task router: classifies and launches claude or opencode automatically",
5
5
  "license": "MIT",
6
6
  "author": "DBC Tech",
@@ -26,7 +26,14 @@
26
26
  "engines": {
27
27
  "node": ">=20"
28
28
  },
29
- "keywords": ["ai", "claude", "opencode", "nemotron", "cli", "router"],
29
+ "keywords": [
30
+ "ai",
31
+ "claude",
32
+ "opencode",
33
+ "nemotron",
34
+ "cli",
35
+ "router"
36
+ ],
30
37
  "repository": {
31
38
  "type": "git",
32
39
  "url": "git+https://github.com/dbezerra95/arsenal-cli.git"
package/src/index.tsx CHANGED
@@ -3,70 +3,35 @@ import { spawn } from "node:child_process"
3
3
  import { createInterface } from "node:readline"
4
4
  import { Command } from "commander"
5
5
  import chalk from "chalk"
6
- import { classifyTask } from "./router.js"
7
6
  import { loadProfile, applyProfile, addProfile, listProfiles, useProfile } from "./profiles.js"
8
7
 
9
8
  const program = new Command()
10
9
 
11
10
  program
12
11
  .name("arsenal-agent")
13
- .description("Router: classifica a task e lança claude ou opencode automaticamente")
14
- .version("0.1.2")
12
+ .description("Launcher do Claude Code com perfil de conta configurado")
13
+ .version("0.1.3")
15
14
  .option("-p, --profile <name>", "perfil a usar")
16
- .argument("[task...]", "task a executar diretamente")
15
+ .argument("[args...]", "argumentos passados direto ao claude")
16
+ .allowUnknownOption(true)
17
+ .passThroughOptions(true)
17
18
 
18
19
  const profileCmd = program.command("profile").description("gerenciar perfis")
19
20
  profileCmd.command("add [name]").description("adicionar perfil").action(async (name) => { await addProfile(name); process.exit(0) })
20
21
  profileCmd.command("list").alias("ls").description("listar perfis").action(() => { listProfiles(); process.exit(0) })
21
22
  profileCmd.command("use <name>").description("definir perfil ativo").action((name) => { useProfile(name); process.exit(0) })
22
23
 
23
- program.action(async (taskArgs: string[], opts: { profile?: string }) => {
24
- // Aplica perfil
24
+ program.action((claudeArgs: string[], opts: { profile?: string }) => {
25
25
  const profile = loadProfile(opts.profile)
26
+
26
27
  if (profile) {
27
28
  applyProfile(profile)
28
29
  process.stderr.write(chalk.dim(`[${profile.label ?? profile.name}]\n`))
29
- } else if (!process.env.ANTHROPIC_API_KEY) {
30
- console.error(chalk.red("Nenhuma conta configurada. Rode: aa profile add"))
31
- process.exit(1)
32
- }
33
-
34
- // Task via argumento ou prompt interativo
35
- const task = taskArgs.length > 0
36
- ? taskArgs.join(" ")
37
- : await askTask()
38
-
39
- if (!task.trim()) process.exit(0)
40
-
41
- // Classifica e lança
42
- const { model, reason } = classifyTask(task)
43
- const isFree = model !== "sonnet"
44
-
45
- console.log(
46
- chalk.dim("→ ") +
47
- (isFree ? chalk.yellow("Nemotron 120B") : chalk.cyan("Claude Sonnet")) +
48
- chalk.dim(` (${reason})`) +
49
- (isFree ? chalk.green(" free") : "")
50
- )
51
- console.log()
52
-
53
- if (model === "sonnet") {
54
- launch("claude", [task])
55
- } else {
56
- launch("opencode", ["run", task, "--model", "openrouter/nvidia/nemotron-3-super-120b-a12b:free"])
57
30
  }
58
- })
59
31
 
60
- function askTask(): Promise<string> {
61
- return new Promise((resolve) => {
62
- const rl = createInterface({ input: process.stdin, output: process.stdout })
63
- rl.question(chalk.white("> "), (answer) => { rl.close(); resolve(answer.trim()) })
64
- })
65
- }
66
-
67
- function launch(cmd: string, args: string[]): void {
68
- const child = spawn(cmd, args, { stdio: "inherit", env: process.env })
32
+ // Passa tudo direto pro claude — argumentos, flags, o que for
33
+ const child = spawn("claude", claudeArgs, { stdio: "inherit", env: process.env })
69
34
  child.on("exit", (code) => process.exit(code ?? 0))
70
- }
35
+ })
71
36
 
72
37
  program.parse()
package/src/router.ts DELETED
@@ -1,35 +0,0 @@
1
- export type ModelAlias = "nemotron-120b" | "nemotron-nano" | "sonnet"
2
-
3
- export interface RouterDecision {
4
- model: ModelAlias
5
- reason: string
6
- }
7
-
8
- const COMPLEX_PATTERNS = [
9
- /arquitetura|architecture/i,
10
- /seguran[cç]a|security|vulnerabilidade/i,
11
- /debug|investiga|diagnos/i,
12
- /refatora|refactor/i,
13
- /por que|why|como funciona|how does/i,
14
- /analisa|analyze|avalia/i,
15
- /projeta|design system/i,
16
- /pipeline|infraestrutura|infrastructure/i,
17
- /revis[aã]o|review/i,
18
- /estrat[eé]gia|strategy/i,
19
- /crie um sistema|cria um sistema|build a system/i,
20
- /explique a arquitetura/i,
21
- /implemente.*sistema|implement.*system/i,
22
- /agent[e]? mcp|mcp server/i,
23
- ]
24
-
25
- export function classifyTask(task: string): RouterDecision {
26
- for (const pattern of COMPLEX_PATTERNS) {
27
- if (pattern.test(task)) {
28
- return { model: "sonnet", reason: `match: ${pattern.source.split("|")[0]}` }
29
- }
30
- }
31
- if (task.length > 400) {
32
- return { model: "sonnet", reason: "prompt longo (>400 chars)" }
33
- }
34
- return { model: "nemotron-120b", reason: "task simples → free" }
35
- }