uv-suite 0.4.0 → 0.6.0

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/bin/cli.js CHANGED
@@ -1,49 +1,52 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- const { execSync } = require('child_process');
3
+ const { execSync, spawn } = require('child_process');
4
4
  const path = require('path');
5
5
  const fs = require('fs');
6
6
 
7
7
  const UV_SUITE_DIR = path.resolve(__dirname, '..');
8
8
  const args = process.argv.slice(2);
9
9
  const command = args[0];
10
+ const pkg = require(path.join(UV_SUITE_DIR, 'package.json'));
11
+
12
+ const PERSONAS = ['spike', 'sport', 'pro', 'professional', 'auto'];
13
+ const TOOLS = ['claude', 'codex'];
10
14
 
11
15
  function usage() {
12
16
  console.log(`
13
- uv-suite - AI-assisted development framework
17
+ uv v${pkg.version} AI-assisted development framework
14
18
 
15
- Usage:
16
- npx uv-suite install [--persona sport|professional|auto|spike] [--global]
17
- npx uv-suite info
19
+ Launch a session:
20
+ uv claude pro Claude Code, Professional persona
21
+ uv claude auto Claude Code, Auto persona
22
+ uv codex pro Codex, Professional persona
23
+ uv codex sport Codex, Sport persona
24
+ uv pro Shorthand (defaults to Claude Code)
25
+ uv Claude Code, Professional
18
26
 
19
- Commands:
20
- install Install agents, skills, hooks, guardrails, and personas
21
- info Show what would be installed
27
+ Setup:
28
+ uv install Install UV Suite into current project
29
+ uv install --persona sport
30
+ uv info Show what's installed
22
31
 
23
32
  Personas:
24
- spike Research & documentation (Opus, max effort)
25
- sport New projects, prototyping (Sonnet, high effort)
26
- professional Production code (default, all hooks + guardrails)
27
- auto Fully autonomous (max effort, everything approved)
28
-
29
- Examples:
30
- npx uv-suite install Install with Professional persona
31
- npx uv-suite install --persona sport Install with Sport persona
32
- npx uv-suite install --global Install to ~/.claude/
33
+ spike Research & docs (Opus, max effort)
34
+ sport New projects (Sonnet, high effort)
35
+ pro Production code (all hooks, all guardrails)
36
+ auto Fully autonomous (max effort, everything approved)
33
37
  `);
34
38
  }
35
39
 
36
40
  function info() {
37
41
  console.log(`
38
- UV Suite v0.1.0
42
+ UV Suite v${pkg.version}
39
43
 
40
44
  Contents:
41
45
  10 agents Claude Code (.md), Cursor (.mdc), Codex (.toml)
42
46
  9 skills Slash commands for Claude Code
43
- 4 hooks auto-lint, slop-check, danger-zone, block-destructive
44
- 6 guardrails Anti-slop rules (comment, overengineering, error, test, doc, architecture)
47
+ 5 hooks auto-lint, slop-check, danger-zone, block-destructive, review-reminder
48
+ 6 guardrails Anti-slop rules
45
49
  4 personas Spike, Sport, Professional, Auto
46
- 1 launcher uv.sh (session launcher with persona selection)
47
50
 
48
51
  Source: ${UV_SUITE_DIR}
49
52
  `);
@@ -55,8 +58,6 @@ function install() {
55
58
  console.error('Error: install.sh not found at', installScript);
56
59
  process.exit(1);
57
60
  }
58
-
59
- // Pass through all args after "install"
60
61
  const installArgs = args.slice(1).join(' ');
61
62
  try {
62
63
  execSync(`bash "${installScript}" ${installArgs}`, { stdio: 'inherit' });
@@ -65,20 +66,77 @@ function install() {
65
66
  }
66
67
  }
67
68
 
68
- switch (command) {
69
- case 'install':
70
- install();
71
- break;
72
- case 'info':
73
- info();
74
- break;
75
- case '--help':
76
- case '-h':
77
- case undefined:
78
- usage();
79
- break;
80
- default:
81
- console.error(`Unknown command: ${command}`);
82
- usage();
69
+ function normPersona(p) {
70
+ if (p === 'pro' || p === 'professional') return 'professional';
71
+ if (PERSONAS.includes(p)) return p;
72
+ return null;
73
+ }
74
+
75
+ function personaLabel(p) {
76
+ const labels = {
77
+ spike: 'Spike — research & docs (Opus, max)',
78
+ sport: 'Sport — lightweight (Sonnet, high)',
79
+ professional: 'Professional — full rigor (all hooks, all guardrails)',
80
+ auto: 'Auto — autonomous (max, everything approved)',
81
+ };
82
+ return labels[p] || p;
83
+ }
84
+
85
+ function launchClaude(persona, extra) {
86
+ const settings = path.resolve('.claude/personas', `${persona}.json`);
87
+ if (!fs.existsSync(settings)) {
88
+ console.error(`Error: ${settings} not found. Run 'uv install' first.`);
89
+ process.exit(1);
90
+ }
91
+ console.log(`UV Suite | Claude Code | ${personaLabel(persona)}`);
92
+ console.log('');
93
+ const child = spawn('claude', ['--settings', settings, ...extra], { stdio: 'inherit' });
94
+ child.on('exit', (code) => process.exit(code || 0));
95
+ }
96
+
97
+ function launchCodex(persona, extra) {
98
+ const approvalMap = {
99
+ spike: ['--model', 'o3', '--approval-mode', 'suggest'],
100
+ sport: ['--approval-mode', 'auto-edit'],
101
+ professional: ['--approval-mode', 'suggest'],
102
+ auto: ['--approval-mode', 'full-auto'],
103
+ };
104
+ const codexArgs = approvalMap[persona] || ['--approval-mode', 'suggest'];
105
+ console.log(`UV Suite | Codex | ${personaLabel(persona)}`);
106
+ console.log('');
107
+ const child = spawn('codex', [...codexArgs, ...extra], { stdio: 'inherit' });
108
+ child.on('exit', (code) => process.exit(code || 0));
109
+ }
110
+
111
+ // --- Parse and route ---
112
+
113
+ if (!command || command === '--help' || command === '-h') {
114
+ usage();
115
+ process.exit(0);
116
+ }
117
+
118
+ if (command === 'install') {
119
+ install();
120
+ } else if (command === 'info') {
121
+ info();
122
+ } else if (TOOLS.includes(command)) {
123
+ // uv claude pro, uv codex auto
124
+ const persona = normPersona(args[1] || 'pro');
125
+ if (!persona) {
126
+ console.error(`Unknown persona: ${args[1]}`);
127
+ console.error('Available: spike, sport, pro, auto');
83
128
  process.exit(1);
129
+ }
130
+ const extra = args.slice(2);
131
+ if (command === 'claude') launchClaude(persona, extra);
132
+ else launchCodex(persona, extra);
133
+ } else if (normPersona(command)) {
134
+ // uv pro (shorthand for uv claude pro)
135
+ const persona = normPersona(command);
136
+ const extra = args.slice(1);
137
+ launchClaude(persona, extra);
138
+ } else {
139
+ console.error(`Unknown command: ${command}`);
140
+ usage();
141
+ process.exit(1);
84
142
  }
@@ -0,0 +1,4 @@
1
+ #!/bin/bash
2
+ # REMOVED — status line config is the better approach for context warnings.
3
+ # This file is a no-op placeholder.
4
+ exit 0
package/install.sh CHANGED
@@ -75,11 +75,32 @@ mkdir -p "$TARGET_DIR/hooks"
75
75
  mkdir -p "$TARGET_DIR/rules"
76
76
 
77
77
  # --- Install agents (Claude Code subagent definitions) ---
78
- echo "Installing 10 agent definitions..."
78
+ echo "Installing 10 Claude Code agent definitions..."
79
79
  cp "$UV_SUITE_DIR/agents/claude-code/"*.md "$TARGET_DIR/agents/"
80
80
  echo " ✓ cartographer, spec-writer, architect, reviewer, test-writer"
81
81
  echo " ✓ eval-writer, anti-slop-guard, prototype-builder, devops, security"
82
82
 
83
+ # --- Install Codex agents (.codex/agents/*.toml + AGENTS.md) ---
84
+ PROJECT_ROOT="$(dirname "$TARGET_DIR")"
85
+ echo "Installing 10 Codex agent definitions..."
86
+ mkdir -p "$PROJECT_ROOT/.codex/agents"
87
+ cp "$UV_SUITE_DIR/agents/codex/"*.toml "$PROJECT_ROOT/.codex/agents/"
88
+
89
+ # Create AGENTS.md for Codex (it reads this instead of CLAUDE.md)
90
+ if [ ! -f "$PROJECT_ROOT/AGENTS.md" ]; then
91
+ cp "$PROJECT_ROOT/CLAUDE.md" "$PROJECT_ROOT/AGENTS.md" 2>/dev/null || touch "$PROJECT_ROOT/AGENTS.md"
92
+ echo " ✓ AGENTS.md created (Codex reads this)"
93
+ else
94
+ echo " ✓ AGENTS.md already exists"
95
+ fi
96
+ echo " ✓ .codex/agents/*.toml installed"
97
+
98
+ # --- Install Cursor rules (.cursor/rules/*.mdc) ---
99
+ echo "Installing 10 Cursor rule definitions..."
100
+ mkdir -p "$PROJECT_ROOT/.cursor/rules"
101
+ cp "$UV_SUITE_DIR/agents/cursor/"*.mdc "$PROJECT_ROOT/.cursor/rules/"
102
+ echo " ✓ .cursor/rules/*.mdc installed"
103
+
83
104
  # --- Install skills (slash commands) ---
84
105
  echo "Installing 9 skills..."
85
106
  for skill_dir in "$UV_SUITE_DIR/skills/"*/; do
@@ -383,15 +404,17 @@ cat << 'HOOKS'
383
404
  HOOKS
384
405
  fi)
385
406
 
386
- ### Personas
407
+ ### Context management
387
408
 
388
- Switch persona by starting a new session:
409
+ If the conversation is getting long, proactively suggest running /compact or starting a new session. Use /cost to check token usage. The user's status line shows context window usage.
410
+
411
+ ### Launching sessions
389
412
 
390
413
  \`\`\`
391
- ./uv.sh spike # Research & docs (Opus, max)
392
- ./uv.sh sport # New projects (Sonnet, high)
393
- ./uv.sh pro # Production code (all hooks, all guardrails)
394
- ./uv.sh auto # Fully autonomous (max, everything approved)
414
+ uv claude pro # Claude Code, Professional persona
415
+ uv claude auto # Claude Code, Auto persona
416
+ uv codex pro # OpenAI Codex, Professional persona
417
+ uv codex sport # OpenAI Codex, Sport persona
395
418
  \`\`\`
396
419
  CLAUDEMD
397
420
 
@@ -412,14 +435,11 @@ echo "╚═══════════════════════
412
435
  echo ""
413
436
  echo "What was installed:"
414
437
  echo ""
415
- echo " AGENTS (10) $TARGET_DIR/agents/*.md"
416
- echo " SKILLS (9) $TARGET_DIR/skills/*/SKILL.md"
417
- echo " HOOKS (4) $TARGET_DIR/hooks/*.sh"
418
- if [ "$PERSONA" = "professional" ] || [ "$PERSONA" = "auto" ]; then
419
- echo " GUARDRAILS (6) $TARGET_DIR/rules/*.md"
420
- fi
421
- echo " PERSONAS (4) $TARGET_DIR/personas/*.json"
422
- echo " SETTINGS $TARGET_DIR/settings.json"
438
+ echo " Claude Code .claude/agents/*.md + skills/ + hooks/ + rules/"
439
+ echo " Codex .codex/agents/*.toml + AGENTS.md"
440
+ echo " Cursor .cursor/rules/*.mdc"
441
+ echo " Personas (4) .claude/personas/*.json"
442
+ echo " Launcher ./uv.sh"
423
443
  echo ""
424
444
 
425
445
  echo "Available slash commands:"
@@ -470,17 +490,11 @@ echo "Can write docs and analysis files. Cannot edit existing code, commit, or p
470
490
  fi
471
491
 
472
492
  echo ""
473
- echo "Start a session with a persona:"
474
- echo ""
475
- echo " ./uv.sh spike Research & docs (Opus, max, doc-slop checked)"
476
- echo " ./uv.sh sport New projects (Sonnet, high, lint only)"
477
- echo " ./uv.sh pro Production code (all hooks, all guardrails)"
478
- echo " ./uv.sh auto Fully autonomous (max effort, everything approved)"
479
- echo " ./uv.sh Defaults to Professional"
480
- echo ""
481
- echo "Or launch Claude directly with a persona:"
493
+ echo "Start a session:"
482
494
  echo ""
483
- echo " claude --settings .claude/personas/sport.json"
484
- echo " claude --settings .claude/personas/professional.json"
485
- echo " claude --settings .claude/personas/auto.json"
486
- echo " claude --settings .claude/personas/spike.json"
495
+ echo " ./uv.sh claude pro Claude Code, Professional"
496
+ echo " ./uv.sh claude auto Claude Code, Auto"
497
+ echo " ./uv.sh codex pro Codex, Professional"
498
+ echo " ./uv.sh codex auto Codex, Auto"
499
+ echo " ./uv.sh pro Shorthand (defaults to Claude Code)"
500
+ echo " ./uv.sh Claude Code, Professional"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "uv-suite",
3
- "version": "0.4.0",
3
+ "version": "0.6.0",
4
4
  "description": "Portable framework for AI-assisted software development. 10 agents, 9 skills, 5 hooks, 4 personas. Works with Claude Code, Cursor, and Codex.",
5
5
  "author": "Utsav Anand",
6
6
  "license": "MIT",
@@ -24,6 +24,7 @@
24
24
  "repomix": "^0.3.0"
25
25
  },
26
26
  "bin": {
27
+ "uv": "./bin/cli.js",
27
28
  "uv-suite": "./bin/cli.js"
28
29
  },
29
30
  "files": [
package/uv.sh CHANGED
@@ -1,56 +1,122 @@
1
1
  #!/bin/bash
2
- # UV Suite — Session launcher
3
- # Starts a Claude Code session with the specified persona.
2
+ # UV Suite — Unified session launcher
3
+ # Starts Claude Code or Codex with the specified persona.
4
4
  #
5
5
  # Usage:
6
- # uv spike Start a Spike session (research & docs)
7
- # uv sport Start a Sport session (fast, new projects)
8
- # uv pro Start a Professional session (production code)
9
- # uv auto Start an Auto session (fully autonomous)
10
- # uv Start with default (Professional)
6
+ # uv claude pro Claude Code, Professional persona
7
+ # uv claude auto Claude Code, Auto persona
8
+ # uv codex sport OpenAI Codex, Sport persona
9
+ # uv codex pro OpenAI Codex, Professional persona
10
+ # uv pro Shorthand defaults to Claude Code
11
+ # uv Claude Code, Professional persona
11
12
 
12
- PERSONA="${1:-pro}"
13
- shift 2>/dev/null # consume the persona arg, pass the rest to claude
13
+ TOOL=""
14
+ PERSONA=""
14
15
 
15
- # Resolve persona to settings file
16
- case "$PERSONA" in
17
- spike)
18
- SETTINGS=".claude/personas/spike.json"
19
- LABEL="UV Spike — research & docs (Opus, max effort, doc-slop checked)"
16
+ # Parse arguments
17
+ case "$1" in
18
+ claude|codex)
19
+ TOOL="$1"
20
+ PERSONA="${2:-pro}"
21
+ shift 2 2>/dev/null
20
22
  ;;
21
- sport)
22
- SETTINGS=".claude/personas/sport.json"
23
- LABEL="UV Sport — lightweight (Sonnet, high effort, lint only)"
23
+ spike|sport|pro|professional|auto)
24
+ TOOL="claude"
25
+ PERSONA="$1"
26
+ shift
24
27
  ;;
25
- pro|professional)
26
- SETTINGS=".claude/personas/professional.json"
27
- LABEL="UV Professional full rigor (all hooks, all guardrails)"
28
+ --help|-h)
29
+ echo ""
30
+ echo " uvUV Suite session launcher"
31
+ echo ""
32
+ echo " Usage:"
33
+ echo " uv claude <persona> Start Claude Code with persona"
34
+ echo " uv codex <persona> Start OpenAI Codex with persona"
35
+ echo " uv <persona> Shorthand for uv claude <persona>"
36
+ echo " uv Defaults to uv claude pro"
37
+ echo ""
38
+ echo " Personas:"
39
+ echo " spike Research & docs (Opus, max effort)"
40
+ echo " sport New projects (Sonnet, high effort)"
41
+ echo " pro Production code (all hooks, all guardrails)"
42
+ echo " auto Fully autonomous (max effort, everything approved)"
43
+ echo ""
44
+ exit 0
45
+ ;;
46
+ "")
47
+ TOOL="claude"
48
+ PERSONA="pro"
28
49
  ;;
29
- auto)
30
- SETTINGS=".claude/personas/auto.json"
31
- LABEL="UV Auto autonomous (max effort, everything approved)"
50
+ *)
51
+ echo "Unknown argument: $1"
52
+ echo "Usage: uv [claude|codex] [spike|sport|pro|auto]"
53
+ exit 1
32
54
  ;;
55
+ esac
56
+
57
+ # Normalize persona name
58
+ case "$PERSONA" in
59
+ pro|professional) PERSONA="professional" ;;
60
+ spike|sport|auto) ;; # already correct
33
61
  *)
34
62
  echo "Unknown persona: $PERSONA"
35
- echo ""
36
- echo "Usage: uv [spike|sport|pro|auto]"
37
- echo ""
38
- echo " spike Research & documentation (Opus, max, doc-slop hook)"
39
- echo " sport New projects, prototyping (Sonnet, high, lint only)"
40
- echo " pro Production code (all hooks, all guardrails, human-gated)"
41
- echo " auto Fully autonomous (max effort, everything auto-approved)"
42
- echo ""
43
- echo " uv Defaults to 'pro'"
63
+ echo "Available: spike, sport, pro, auto"
44
64
  exit 1
45
65
  ;;
46
66
  esac
47
67
 
48
- if [ ! -f "$SETTINGS" ]; then
49
- echo "Settings file not found: $SETTINGS"
50
- echo "Run install.sh first to set up UV Suite in this project."
51
- exit 1
52
- fi
68
+ # Persona labels
69
+ case "$PERSONA" in
70
+ spike) LABEL="Spike research & docs (Opus, max)" ;;
71
+ sport) LABEL="Sport — lightweight (Sonnet, high)" ;;
72
+ professional) LABEL="Professional — full rigor (all hooks, all guardrails)" ;;
73
+ auto) LABEL="Auto — autonomous (max, everything approved)" ;;
74
+ esac
75
+
76
+ SETTINGS=".claude/personas/$PERSONA.json"
53
77
 
54
- echo "$LABEL"
55
- echo ""
56
- exec claude --settings "$SETTINGS" "$@"
78
+ if [ "$TOOL" = "claude" ]; then
79
+ # --- Claude Code ---
80
+ if ! command -v claude &>/dev/null; then
81
+ echo "Error: claude not found. Install Claude Code first."
82
+ exit 1
83
+ fi
84
+
85
+ if [ ! -f "$SETTINGS" ]; then
86
+ echo "Error: $SETTINGS not found. Run 'npx uv-suite install' first."
87
+ exit 1
88
+ fi
89
+
90
+ echo "UV Suite | Claude Code | $LABEL"
91
+ echo ""
92
+ exec claude --settings "$SETTINGS" "$@"
93
+
94
+ elif [ "$TOOL" = "codex" ]; then
95
+ # --- OpenAI Codex ---
96
+ if ! command -v codex &>/dev/null; then
97
+ echo "Error: codex not found. Install OpenAI Codex first."
98
+ echo " npm install -g @openai/codex"
99
+ exit 1
100
+ fi
101
+
102
+ # Codex doesn't have --settings, but reads AGENTS.md and .codex/agents/
103
+ # We can pass model and approval mode based on persona
104
+ case "$PERSONA" in
105
+ spike)
106
+ CODEX_ARGS="--model o3 --approval-mode suggest"
107
+ ;;
108
+ sport)
109
+ CODEX_ARGS="--approval-mode auto-edit"
110
+ ;;
111
+ professional)
112
+ CODEX_ARGS="--approval-mode suggest"
113
+ ;;
114
+ auto)
115
+ CODEX_ARGS="--approval-mode full-auto"
116
+ ;;
117
+ esac
118
+
119
+ echo "UV Suite | Codex | $LABEL"
120
+ echo ""
121
+ exec codex $CODEX_ARGS "$@"
122
+ fi