juno-code 1.0.26 → 1.0.27

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
@@ -75,7 +75,7 @@ var __export = (target, all) => {
75
75
  exports.version = void 0;
76
76
  var init_version = __esm({
77
77
  "src/version.ts"() {
78
- exports.version = "1.0.26";
78
+ exports.version = "1.0.27";
79
79
  }
80
80
  });
81
81
  function isHeadlessEnvironment() {
package/dist/index.mjs CHANGED
@@ -44,7 +44,7 @@ var __export = (target, all) => {
44
44
  var version;
45
45
  var init_version = __esm({
46
46
  "src/version.ts"() {
47
- version = "1.0.26";
47
+ version = "1.0.27";
48
48
  }
49
49
  });
50
50
  function isHeadlessEnvironment() {
@@ -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(
@@ -316,9 +344,29 @@ Environment Variables:
316
344
 
317
345
  # Add either content or tool_use data
318
346
  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)
347
+ # Check if prompt field in tool_use.input has multi-line content
348
+ tool_input = tool_use_data.get("input", {})
349
+ prompt_field = tool_input.get("prompt", "")
350
+
351
+ if isinstance(prompt_field, str) and '\n' in prompt_field:
352
+ # Multi-line prompt: extract it and render separately
353
+ # Create a copy of tool_use_data with prompt removed
354
+ tool_use_copy = {
355
+ "name": tool_use_data.get("name", ""),
356
+ "input": {k: v for k, v in tool_input.items() if k != "prompt"}
357
+ }
358
+
359
+ simplified["tool_use"] = tool_use_copy
360
+
361
+ # Print metadata as compact JSON on first line
362
+ output = json.dumps(simplified, ensure_ascii=False)
363
+ # Then print prompt label and raw multi-line text
364
+ output += "\nprompt:\n" + prompt_field
365
+ return output
366
+ else:
367
+ # No multi-line prompt: normal JSON output for tool_use
368
+ simplified["tool_use"] = tool_use_data
369
+ return json.dumps(simplified, ensure_ascii=False)
322
370
  else:
323
371
  # For content, check if it has newlines
324
372
  if '\n' in text_content:
@@ -501,7 +549,8 @@ Environment Variables:
501
549
 
502
550
  # Set configuration from arguments
503
551
  self.project_path = os.path.abspath(args.cd)
504
- self.model_name = args.model
552
+ # Expand model shorthand (e.g., :haiku -> claude-haiku-4-5-20251001)
553
+ self.model_name = self.expand_model_shorthand(args.model)
505
554
  self.auto_instruction = args.auto_instruction
506
555
 
507
556
  # 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.27",
4
4
  "description": "TypeScript CLI tool for AI subagent orchestration with code automation",
5
5
  "keywords": [
6
6
  "ai",