juno-code 1.0.28 → 1.0.30
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/bin/cli.js +89 -17
- package/dist/bin/cli.js.map +1 -1
- package/dist/bin/cli.mjs +89 -17
- package/dist/bin/cli.mjs.map +1 -1
- package/dist/index.js +24 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +24 -1
- package/dist/index.mjs.map +1 -1
- package/dist/templates/services/claude.py +17 -4
- package/package.json +6 -6
package/dist/bin/cli.js
CHANGED
|
@@ -1140,8 +1140,23 @@ async function ensureHooksConfig(baseDir) {
|
|
|
1140
1140
|
await fs3__default.default.writeJson(configPath, defaultConfig, { spaces: 2 });
|
|
1141
1141
|
} else {
|
|
1142
1142
|
const existingConfig = await fs3__default.default.readJson(configPath);
|
|
1143
|
+
let needsUpdate = false;
|
|
1143
1144
|
if (!existingConfig.hooks) {
|
|
1144
1145
|
existingConfig.hooks = allHookTypes;
|
|
1146
|
+
needsUpdate = true;
|
|
1147
|
+
}
|
|
1148
|
+
if (!existingConfig.defaultModel) {
|
|
1149
|
+
const subagent = existingConfig.defaultSubagent || "claude";
|
|
1150
|
+
const modelDefaults = {
|
|
1151
|
+
claude: ":sonnet",
|
|
1152
|
+
codex: "gpt-5",
|
|
1153
|
+
gemini: "gemini-2.5-pro",
|
|
1154
|
+
cursor: "auto"
|
|
1155
|
+
};
|
|
1156
|
+
existingConfig.defaultModel = modelDefaults[subagent] || ":sonnet";
|
|
1157
|
+
needsUpdate = true;
|
|
1158
|
+
}
|
|
1159
|
+
if (needsUpdate) {
|
|
1145
1160
|
await fs3__default.default.writeJson(configPath, existingConfig, { spaces: 2 });
|
|
1146
1161
|
}
|
|
1147
1162
|
}
|
|
@@ -3565,6 +3580,12 @@ function createExecutionRequest(options) {
|
|
|
3565
3580
|
if (options.agents !== void 0) {
|
|
3566
3581
|
result.agents = options.agents;
|
|
3567
3582
|
}
|
|
3583
|
+
if (options.tools !== void 0) {
|
|
3584
|
+
result.tools = options.tools;
|
|
3585
|
+
}
|
|
3586
|
+
if (options.disallowedTools !== void 0) {
|
|
3587
|
+
result.disallowedTools = options.disallowedTools;
|
|
3588
|
+
}
|
|
3568
3589
|
if (options.mcpServerName !== void 0) {
|
|
3569
3590
|
result.mcpServerName = options.mcpServerName;
|
|
3570
3591
|
}
|
|
@@ -4014,6 +4035,8 @@ var init_engine = __esm({
|
|
|
4014
4035
|
project_path: context.request.workingDirectory,
|
|
4015
4036
|
...context.request.model !== void 0 && { model: context.request.model },
|
|
4016
4037
|
...context.request.agents !== void 0 && { agents: context.request.agents },
|
|
4038
|
+
...context.request.tools !== void 0 && { tools: context.request.tools },
|
|
4039
|
+
...context.request.disallowedTools !== void 0 && { disallowedTools: context.request.disallowedTools },
|
|
4017
4040
|
iteration: iterationNumber
|
|
4018
4041
|
},
|
|
4019
4042
|
timeout: context.request.timeoutMs || this.engineConfig.config.mcpTimeout,
|
|
@@ -7179,6 +7202,16 @@ var init_shell_backend = __esm({
|
|
|
7179
7202
|
if (isPython && request.arguments?.agents) {
|
|
7180
7203
|
args.push("--agents", request.arguments.agents);
|
|
7181
7204
|
}
|
|
7205
|
+
if (isPython && request.arguments?.tools && Array.isArray(request.arguments.tools)) {
|
|
7206
|
+
for (const tool of request.arguments.tools) {
|
|
7207
|
+
args.push("--tool", tool);
|
|
7208
|
+
}
|
|
7209
|
+
}
|
|
7210
|
+
if (isPython && request.arguments?.disallowedTools && Array.isArray(request.arguments.disallowedTools)) {
|
|
7211
|
+
for (const tool of request.arguments.disallowedTools) {
|
|
7212
|
+
args.push("--disallowed-tool", tool);
|
|
7213
|
+
}
|
|
7214
|
+
}
|
|
7182
7215
|
if (this.config.debug) {
|
|
7183
7216
|
engineLogger.debug(`Executing script: ${command} ${args.join(" ")}`);
|
|
7184
7217
|
engineLogger.debug(`Working directory: ${this.config.workingDirectory}`);
|
|
@@ -12584,6 +12617,9 @@ async function mainCommandHandler(args, options, command) {
|
|
|
12584
12617
|
if (options.agents && selectedBackend !== "shell") {
|
|
12585
12618
|
console.error(chalk15__default.default.yellow("\n\u26A0\uFE0F Note: --agents flag is only supported with shell backend and will be ignored"));
|
|
12586
12619
|
}
|
|
12620
|
+
if ((options.tools || options.disallowedTools) && selectedBackend !== "shell") {
|
|
12621
|
+
console.error(chalk15__default.default.yellow("\n\u26A0\uFE0F Note: --tools and --disallowed-tools flags are only supported with shell backend and will be ignored"));
|
|
12622
|
+
}
|
|
12587
12623
|
const executionRequest = createExecutionRequest({
|
|
12588
12624
|
instruction,
|
|
12589
12625
|
subagent: options.subagent,
|
|
@@ -12591,7 +12627,9 @@ async function mainCommandHandler(args, options, command) {
|
|
|
12591
12627
|
workingDirectory: config.workingDirectory,
|
|
12592
12628
|
maxIterations: options.maxIterations || config.defaultMaxIterations,
|
|
12593
12629
|
model: options.model || config.defaultModel,
|
|
12594
|
-
agents: options.agents
|
|
12630
|
+
agents: options.agents,
|
|
12631
|
+
tools: options.tools,
|
|
12632
|
+
disallowedTools: options.disallowedTools
|
|
12595
12633
|
});
|
|
12596
12634
|
const coordinator = new MainExecutionCoordinator(config, options.verbose, options.enableFeedback || false);
|
|
12597
12635
|
const result = await coordinator.execute(executionRequest);
|
|
@@ -12684,6 +12722,11 @@ function createMainCommand() {
|
|
|
12684
12722
|
description: "Model to use (optional, subagent-specific)",
|
|
12685
12723
|
env: "JUNO_CODE_MODEL"
|
|
12686
12724
|
}),
|
|
12725
|
+
createOption({
|
|
12726
|
+
flags: "--agents <config>",
|
|
12727
|
+
description: "Agents configuration (forwarded to shell backend, ignored for MCP)",
|
|
12728
|
+
env: "JUNO_CODE_AGENTS"
|
|
12729
|
+
}),
|
|
12687
12730
|
createOption({
|
|
12688
12731
|
flags: "-I, --interactive",
|
|
12689
12732
|
description: "Interactive mode for typing/pasting prompts",
|
|
@@ -15969,7 +16012,7 @@ ${variables.EDITOR ? `using ${variables.EDITOR} as primary AI subagent` : ""}
|
|
|
15969
16012
|
}
|
|
15970
16013
|
getDefaultModelForSubagent(subagent) {
|
|
15971
16014
|
const modelDefaults = {
|
|
15972
|
-
claude: "sonnet
|
|
16015
|
+
claude: ":sonnet",
|
|
15973
16016
|
codex: "gpt-5",
|
|
15974
16017
|
gemini: "gemini-2.5-pro",
|
|
15975
16018
|
cursor: "auto"
|
|
@@ -16262,12 +16305,13 @@ async function initCommandHandler(args, options, command) {
|
|
|
16262
16305
|
}
|
|
16263
16306
|
}
|
|
16264
16307
|
function configureInitCommand(program) {
|
|
16265
|
-
program.command("init").description("Initialize new juno-code project
|
|
16308
|
+
program.command("init").description("Initialize new juno-code project - supports both interactive and inline modes").argument("[description]", "Task description for inline mode (optional - triggers inline mode if provided)").option("-s, --subagent <name>", "AI subagent to use (claude, codex, gemini, cursor)").option("-g, --git-repo <url>", "Git repository URL").option("-d, --directory <path>", "Target directory (default: current directory)").option("-f, --force", "Force overwrite existing files").option("-i, --interactive", "Force interactive mode (even if description is provided)").option("--git-url <url>", "Git repository URL (alias for --git-repo)").option("-t, --task <description>", "Task description (alias for positional description)").action(async (description, options, command) => {
|
|
16309
|
+
const taskDescription = description || options.task;
|
|
16266
16310
|
const initOptions = {
|
|
16267
|
-
directory,
|
|
16311
|
+
directory: options.directory,
|
|
16268
16312
|
force: options.force,
|
|
16269
|
-
task:
|
|
16270
|
-
gitUrl: options.gitUrl,
|
|
16313
|
+
task: taskDescription,
|
|
16314
|
+
gitUrl: options.gitRepo || options.gitUrl,
|
|
16271
16315
|
subagent: options.subagent,
|
|
16272
16316
|
interactive: options.interactive,
|
|
16273
16317
|
// Global options
|
|
@@ -16279,12 +16323,35 @@ function configureInitCommand(program) {
|
|
|
16279
16323
|
};
|
|
16280
16324
|
await initCommandHandler([], initOptions, command);
|
|
16281
16325
|
}).addHelpText("after", `
|
|
16282
|
-
|
|
16283
|
-
|
|
16284
|
-
|
|
16285
|
-
|
|
16326
|
+
Modes:
|
|
16327
|
+
Interactive Mode (default):
|
|
16328
|
+
$ juno-code init # Opens interactive TUI
|
|
16329
|
+
$ juno-code init --interactive # Force interactive mode
|
|
16330
|
+
|
|
16331
|
+
Inline Mode (for automation):
|
|
16332
|
+
$ juno-code init "Build a REST API" # Minimal inline mode
|
|
16333
|
+
$ juno-code init "Build a REST API" --subagent claude --git-repo https://github.com/owner/repo
|
|
16334
|
+
$ juno-code init "Build a REST API" --subagent codex --directory ./my-project
|
|
16286
16335
|
|
|
16287
|
-
|
|
16336
|
+
Examples:
|
|
16337
|
+
# Interactive mode (default)
|
|
16338
|
+
$ juno-code init # Initialize in current directory with TUI
|
|
16339
|
+
$ juno-code init --directory my-project # Initialize in ./my-project with TUI
|
|
16340
|
+
|
|
16341
|
+
# Inline mode (automation-friendly)
|
|
16342
|
+
$ juno-code init "Create a TypeScript library" # Quick init with inline description
|
|
16343
|
+
$ juno-code init "Build web app" --subagent claude # Specify AI subagent
|
|
16344
|
+
$ juno-code init "API server" --git-repo https://github.com/me/repo
|
|
16345
|
+
|
|
16346
|
+
Arguments & Options:
|
|
16347
|
+
[description] Task description (optional - triggers inline mode)
|
|
16348
|
+
-s, --subagent <name> AI subagent: claude, codex, gemini, cursor (default: claude)
|
|
16349
|
+
-g, --git-repo <url> Git repository URL
|
|
16350
|
+
-d, --directory <path> Target directory (default: current directory)
|
|
16351
|
+
-f, --force Force overwrite existing files
|
|
16352
|
+
-i, --interactive Force interactive mode
|
|
16353
|
+
|
|
16354
|
+
Interactive Flow:
|
|
16288
16355
|
1. Project Root \u2192 Specify target directory
|
|
16289
16356
|
2. Main Task \u2192 Multi-line description (no character limits)
|
|
16290
16357
|
3. Subagent Selection \u2192 Choose from Claude, Codex, Gemini, Cursor
|
|
@@ -16292,10 +16359,10 @@ Simplified Interactive Flow:
|
|
|
16292
16359
|
5. Save \u2192 Handle existing files with override/cancel options
|
|
16293
16360
|
|
|
16294
16361
|
Notes:
|
|
16362
|
+
- All inline mode arguments are optional
|
|
16363
|
+
- Defaults: directory=cwd, subagent=claude, no git repo
|
|
16295
16364
|
- No prompt cost calculation or token counting
|
|
16296
16365
|
- No character limits on task descriptions
|
|
16297
|
-
- Simple file structure with basic templates
|
|
16298
|
-
- Focus on quick project setup without complexity
|
|
16299
16366
|
`);
|
|
16300
16367
|
}
|
|
16301
16368
|
|
|
@@ -16361,6 +16428,9 @@ async function startCommandHandler(args, options, command) {
|
|
|
16361
16428
|
backend: options.backend,
|
|
16362
16429
|
maxIterations: options.maxIterations,
|
|
16363
16430
|
model: options.model,
|
|
16431
|
+
agents: options.agents,
|
|
16432
|
+
tools: options.tools,
|
|
16433
|
+
disallowedTools: options.disallowedTools,
|
|
16364
16434
|
directory: options.directory,
|
|
16365
16435
|
verbose: options.verbose,
|
|
16366
16436
|
quiet: options.quiet,
|
|
@@ -16395,7 +16465,7 @@ async function startCommandHandler(args, options, command) {
|
|
|
16395
16465
|
}
|
|
16396
16466
|
}
|
|
16397
16467
|
function configureStartCommand(program) {
|
|
16398
|
-
program.command("start").description("Start execution using .juno_task/init.md as prompt").option("-s, --subagent <name>", "Subagent to use (claude, cursor, codex, gemini)").option("-b, --backend <type>", "Backend to use (mcp, shell)").option("-i, --max-iterations <number>", "Maximum number of iterations", parseInt).option("-m, --model <name>", "Model to use for execution").option("-d, --directory <path>", "Project directory (default: current)").option("--enable-feedback", "Enable concurrent feedback collection during execution").option("--show-metrics", "Display performance metrics summary after execution").option("--show-dashboard", "Show interactive performance dashboard after execution").option("--show-trends", "Display performance trends from historical data").option("--save-metrics [file]", "Save performance metrics to file (default: .juno_task/metrics.json)").option("--metrics-file <path>", "Specify custom path for metrics file").option("--dry-run", "Validate configuration and exit without executing").action(async (options, command) => {
|
|
16468
|
+
program.command("start").description("Start execution using .juno_task/init.md as prompt").option("-s, --subagent <name>", "Subagent to use (claude, cursor, codex, gemini)").option("-b, --backend <type>", "Backend to use (mcp, shell)").option("-i, --max-iterations <number>", "Maximum number of iterations", parseInt).option("-m, --model <name>", "Model to use for execution").option("--agents <config>", "Agents configuration (forwarded to shell backend, ignored for MCP)").option("-d, --directory <path>", "Project directory (default: current)").option("--enable-feedback", "Enable concurrent feedback collection during execution").option("--show-metrics", "Display performance metrics summary after execution").option("--show-dashboard", "Show interactive performance dashboard after execution").option("--show-trends", "Display performance trends from historical data").option("--save-metrics [file]", "Save performance metrics to file (default: .juno_task/metrics.json)").option("--metrics-file <path>", "Specify custom path for metrics file").option("--dry-run", "Validate configuration and exit without executing").action(async (options, command) => {
|
|
16399
16469
|
const allOptions2 = command.optsWithGlobals ? command.optsWithGlobals() : { ...command.opts(), ...options };
|
|
16400
16470
|
if (allOptions2.saveMetrics === true) {
|
|
16401
16471
|
allOptions2.saveMetrics = true;
|
|
@@ -23638,7 +23708,7 @@ function handleCLIError(error, verbose = false) {
|
|
|
23638
23708
|
process.exit(EXIT_CODES.UNEXPECTED_ERROR);
|
|
23639
23709
|
}
|
|
23640
23710
|
function setupGlobalOptions(program) {
|
|
23641
|
-
program.option("-v, --verbose", "Enable verbose output with detailed progress").option("-q, --quiet", "Disable rich formatting, use plain text").option("-c, --config <path>", "Configuration file path (.json, .toml, pyproject.toml)").option("-l, --log-file <path>", "Log file path (auto-generated if not specified)").option("--no-color", "Disable colored output").option("--log-level <level>", "Log level for output (error, warn, info, debug, trace)", "info").option("-s, --subagent <name>", "Subagent to use (claude, cursor, codex, gemini)").option("--mcp-timeout <number>", "MCP server timeout in milliseconds", parseInt).option("--enable-feedback", "Enable interactive feedback mode (F+Enter to enter, Q+Enter to submit)");
|
|
23711
|
+
program.option("-v, --verbose", "Enable verbose output with detailed progress").option("-q, --quiet", "Disable rich formatting, use plain text").option("-c, --config <path>", "Configuration file path (.json, .toml, pyproject.toml)").option("-l, --log-file <path>", "Log file path (auto-generated if not specified)").option("--no-color", "Disable colored output").option("--log-level <level>", "Log level for output (error, warn, info, debug, trace)", "info").option("-s, --subagent <name>", "Subagent to use (claude, cursor, codex, gemini)").option("-b, --backend <type>", "Backend to use (mcp, shell)").option("-m, --model <name>", "Model to use (subagent-specific)").option("--agents <config>", "Agents configuration (forwarded to shell backend, ignored for MCP)").option("--tools <tools...>", "Allowed tools for Claude (passed to shell backend, ignored for MCP)").option("--disallowed-tools <tools...>", "Disallowed tools for Claude (passed to shell backend, ignored for MCP)").option("--mcp-timeout <number>", "MCP server timeout in milliseconds", parseInt).option("--enable-feedback", "Enable interactive feedback mode (F+Enter to enter, Q+Enter to submit)");
|
|
23642
23712
|
program.exitOverride((err) => {
|
|
23643
23713
|
if (err.code === "commander.helpDisplayed") {
|
|
23644
23714
|
process.exit(0);
|
|
@@ -23656,7 +23726,7 @@ function setupGlobalOptions(program) {
|
|
|
23656
23726
|
});
|
|
23657
23727
|
}
|
|
23658
23728
|
function setupMainCommand(program) {
|
|
23659
|
-
program.option("-p, --prompt <text>", "Prompt input (file path or inline text)").option("-w, --cwd <path>", "Working directory").option("-i, --max-iterations <number>", "Maximum iterations (-1 for unlimited)", parseInt).option("-
|
|
23729
|
+
program.option("-p, --prompt <text>", "Prompt input (file path or inline text)").option("-w, --cwd <path>", "Working directory").option("-i, --max-iterations <number>", "Maximum iterations (-1 for unlimited)", parseInt).option("-I, --interactive", "Interactive mode for typing prompts").option("-ip, --interactive-prompt", "Launch TUI prompt editor").action(async (options, command) => {
|
|
23660
23730
|
try {
|
|
23661
23731
|
const globalOptions = program.opts();
|
|
23662
23732
|
const definedGlobalOptions = Object.fromEntries(
|
|
@@ -23739,11 +23809,13 @@ function setupCompletion(program) {
|
|
|
23739
23809
|
function setupAliases(program) {
|
|
23740
23810
|
const subagents = ["claude", "cursor", "codex", "gemini"];
|
|
23741
23811
|
for (const subagent of subagents) {
|
|
23742
|
-
program.command(subagent, { hidden: true }).description(`Execute with ${subagent} subagent`).argument("[prompt...]", "Prompt text or file path").option("-i, --max-iterations <number>", "Maximum iterations", parseInt).option("-
|
|
23812
|
+
program.command(subagent, { hidden: true }).description(`Execute with ${subagent} subagent`).argument("[prompt...]", "Prompt text or file path").option("-i, --max-iterations <number>", "Maximum iterations", parseInt).option("-w, --cwd <path>", "Working directory").action(async (prompt, options, command) => {
|
|
23743
23813
|
try {
|
|
23744
23814
|
const { mainCommandHandler: mainCommandHandler2 } = await Promise.resolve().then(() => (init_main(), main_exports));
|
|
23745
23815
|
const promptText = Array.isArray(prompt) ? prompt.join(" ") : prompt;
|
|
23816
|
+
const globalOptions = program.opts();
|
|
23746
23817
|
await mainCommandHandler2([], {
|
|
23818
|
+
...globalOptions,
|
|
23747
23819
|
...options,
|
|
23748
23820
|
subagent,
|
|
23749
23821
|
prompt: promptText
|