juno-code 1.0.26 → 1.0.28

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.
@@ -22,6 +22,16 @@ class ClaudeService:
22
22
  DEFAULT_PERMISSION_MODE = "default"
23
23
  DEFAULT_AUTO_INSTRUCTION = """You are Claude Code, an AI coding assistant. Follow the instructions provided and generate high-quality code."""
24
24
 
25
+ # Model shorthand mappings (colon-prefixed names expand to full model IDs)
26
+ MODEL_SHORTHANDS = {
27
+ ":claude-haiku-4-5": "claude-haiku-4-5-20251001",
28
+ ":claude-sonnet-4-5": "claude-sonnet-4-5-20250929",
29
+ ":claude-opus-4": "claude-opus-4-20250514",
30
+ ":haiku": "claude-haiku-4-5-20251001",
31
+ ":sonnet": "claude-sonnet-4-5-20250929",
32
+ ":opus": "claude-opus-4-20250514",
33
+ }
34
+
25
35
  def __init__(self):
26
36
  self.model_name = self.DEFAULT_MODEL
27
37
  self.permission_mode = self.DEFAULT_PERMISSION_MODE
@@ -34,6 +44,22 @@ class ClaudeService:
34
44
  # User message truncation: -1 = no truncation, N = truncate to N lines
35
45
  self.user_message_truncate = int(os.environ.get("CLAUDE_USER_MESSAGE_PRETTY_TRUNCATE", "4"))
36
46
 
47
+ def expand_model_shorthand(self, model: str) -> str:
48
+ """
49
+ Expand model shorthand names to full model IDs.
50
+
51
+ If the model starts with ':', look it up in MODEL_SHORTHANDS.
52
+ Otherwise, return the model name as-is.
53
+
54
+ Examples:
55
+ :claude-haiku-4-5 -> claude-haiku-4-5-20251001
56
+ :haiku -> claude-haiku-4-5-20251001
57
+ claude-sonnet-4-5-20250929 -> claude-sonnet-4-5-20250929 (unchanged)
58
+ """
59
+ if model.startswith(':'):
60
+ return self.MODEL_SHORTHANDS.get(model, model)
61
+ return model
62
+
37
63
  def check_claude_installed(self) -> bool:
38
64
  """Check if claude CLI is installed and available"""
39
65
  try:
@@ -56,7 +82,9 @@ class ClaudeService:
56
82
  Examples:
57
83
  %(prog)s -p "Write a hello world function"
58
84
  %(prog)s -pp prompt.txt --cd /path/to/project
59
- %(prog)s -p "Add tests" -m claude-opus-4-20250514 --tool "Bash Edit"
85
+ %(prog)s -p "Add tests" -m :opus --tool "Bash Edit"
86
+ %(prog)s -p "Quick task" -m :haiku
87
+ %(prog)s -p "Complex task" -m claude-opus-4-20250514
60
88
 
61
89
  Environment Variables:
62
90
  CLAUDE_PROJECT_PATH Project path (default: current directory)
@@ -93,7 +121,7 @@ Environment Variables:
93
121
  "-m", "--model",
94
122
  type=str,
95
123
  default=os.environ.get("CLAUDE_MODEL", self.DEFAULT_MODEL),
96
- help=f"Model name (e.g. 'sonnet', 'opus', or full name). Default: {self.DEFAULT_MODEL} (env: CLAUDE_MODEL)"
124
+ help=f"Model name. Supports shorthand (e.g., ':haiku', ':sonnet', ':opus', ':claude-haiku-4-5') or full model ID (e.g., 'claude-haiku-4-5-20251001'). Default: {self.DEFAULT_MODEL} (env: CLAUDE_MODEL)"
97
125
  )
98
126
 
99
127
  parser.add_argument(
@@ -147,6 +175,12 @@ Environment Variables:
147
175
  help="Continue the most recent conversation"
148
176
  )
149
177
 
178
+ parser.add_argument(
179
+ "--agents",
180
+ type=str,
181
+ help="Agents configuration (forwarded to Claude CLI --agents flag)"
182
+ )
183
+
150
184
  parser.add_argument(
151
185
  "--additional-args",
152
186
  type=str,
@@ -201,6 +235,10 @@ Environment Variables:
201
235
  if args.continue_conversation:
202
236
  cmd.append("--continue")
203
237
 
238
+ # Add agents configuration if specified
239
+ if args.agents:
240
+ cmd.extend(["--agents", args.agents])
241
+
204
242
  # Add output format if JSON requested
205
243
  # Note: stream-json requires --verbose when using --print mode
206
244
  if args.json:
@@ -316,9 +354,29 @@ Environment Variables:
316
354
 
317
355
  # Add either content or tool_use data
318
356
  if tool_use_data:
319
- simplified["tool_use"] = tool_use_data
320
- # Normal JSON output for tool_use
321
- return json.dumps(simplified, ensure_ascii=False)
357
+ # Check if prompt field in tool_use.input has multi-line content
358
+ tool_input = tool_use_data.get("input", {})
359
+ prompt_field = tool_input.get("prompt", "")
360
+
361
+ if isinstance(prompt_field, str) and '\n' in prompt_field:
362
+ # Multi-line prompt: extract it and render separately
363
+ # Create a copy of tool_use_data with prompt removed
364
+ tool_use_copy = {
365
+ "name": tool_use_data.get("name", ""),
366
+ "input": {k: v for k, v in tool_input.items() if k != "prompt"}
367
+ }
368
+
369
+ simplified["tool_use"] = tool_use_copy
370
+
371
+ # Print metadata as compact JSON on first line
372
+ output = json.dumps(simplified, ensure_ascii=False)
373
+ # Then print prompt label and raw multi-line text
374
+ output += "\nprompt:\n" + prompt_field
375
+ return output
376
+ else:
377
+ # No multi-line prompt: normal JSON output for tool_use
378
+ simplified["tool_use"] = tool_use_data
379
+ return json.dumps(simplified, ensure_ascii=False)
322
380
  else:
323
381
  # For content, check if it has newlines
324
382
  if '\n' in text_content:
@@ -501,7 +559,8 @@ Environment Variables:
501
559
 
502
560
  # Set configuration from arguments
503
561
  self.project_path = os.path.abspath(args.cd)
504
- self.model_name = args.model
562
+ # Expand model shorthand (e.g., :haiku -> claude-haiku-4-5-20251001)
563
+ self.model_name = self.expand_model_shorthand(args.model)
505
564
  self.auto_instruction = args.auto_instruction
506
565
 
507
566
  # Get prompt from file or argument
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "juno-code",
3
- "version": "1.0.26",
3
+ "version": "1.0.28",
4
4
  "description": "TypeScript CLI tool for AI subagent orchestration with code automation",
5
5
  "keywords": [
6
6
  "ai",