juno-code 1.0.36 → 1.0.37
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/README.md +170 -0
- package/dist/bin/cli.js +143 -5
- package/dist/bin/cli.js.map +1 -1
- package/dist/bin/cli.mjs +143 -5
- package/dist/bin/cli.mjs.map +1 -1
- package/dist/index.js +18 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +18 -1
- package/dist/index.mjs.map +1 -1
- package/dist/templates/scripts/install_requirements.sh +3 -0
- package/dist/templates/scripts/run_until_completion.sh +227 -11
- package/dist/templates/scripts/slack_fetch.py +717 -0
- package/dist/templates/scripts/slack_fetch.sh +269 -0
- package/dist/templates/scripts/slack_respond.py +691 -0
- package/dist/templates/scripts/slack_respond.sh +263 -0
- package/dist/templates/scripts/slack_state.py +383 -0
- package/package.json +8 -2
package/dist/bin/cli.mjs
CHANGED
|
@@ -282,6 +282,13 @@ var init_default_hooks = __esm({
|
|
|
282
282
|
"src/templates/default-hooks.ts"() {
|
|
283
283
|
init_version();
|
|
284
284
|
DEFAULT_HOOKS = {
|
|
285
|
+
// Executes once at the beginning of a run (before all iterations)
|
|
286
|
+
// Use for: setup, environment checks, notifications, pre-run cleanup
|
|
287
|
+
START_RUN: {
|
|
288
|
+
commands: []
|
|
289
|
+
},
|
|
290
|
+
// Executes at the start of each iteration
|
|
291
|
+
// Use for: file monitoring, state checks, per-iteration setup
|
|
285
292
|
START_ITERATION: {
|
|
286
293
|
commands: [
|
|
287
294
|
// Monitor CLAUDE.md file size
|
|
@@ -290,6 +297,16 @@ var init_default_hooks = __esm({
|
|
|
290
297
|
'file="AGENTS.md"; lines=$(wc -l < "$file" 2>/dev/null || echo 0); chars=$(wc -m < "$file" 2>/dev/null || echo 0); if [ "$lines" -gt 450 ] || [ "$chars" -gt 60000 ]; then juno-kanban "[Critical] file $file is too large, keep it lean and useful for every run of the agent."; fi',
|
|
291
298
|
"./.juno_task/scripts/cleanup_feedback.sh"
|
|
292
299
|
]
|
|
300
|
+
},
|
|
301
|
+
// Executes at the end of each iteration
|
|
302
|
+
// Use for: validation, logging, per-iteration cleanup, progress tracking
|
|
303
|
+
END_ITERATION: {
|
|
304
|
+
commands: []
|
|
305
|
+
},
|
|
306
|
+
// Executes once at the end of a run (after all iterations complete)
|
|
307
|
+
// Use for: final cleanup, notifications, reports, post-run actions
|
|
308
|
+
END_RUN: {
|
|
309
|
+
commands: []
|
|
293
310
|
}
|
|
294
311
|
};
|
|
295
312
|
}
|
|
@@ -13357,12 +13374,24 @@ var init_script_installer = __esm({
|
|
|
13357
13374
|
/**
|
|
13358
13375
|
* Required scripts include both standalone scripts and their dependencies.
|
|
13359
13376
|
* kanban.sh depends on install_requirements.sh for Python venv setup.
|
|
13377
|
+
* Slack integration scripts allow fetching tasks from Slack and responding.
|
|
13360
13378
|
*/
|
|
13361
13379
|
static REQUIRED_SCRIPTS = [
|
|
13362
13380
|
"run_until_completion.sh",
|
|
13363
13381
|
"kanban.sh",
|
|
13364
|
-
"install_requirements.sh"
|
|
13382
|
+
"install_requirements.sh",
|
|
13365
13383
|
// Required by kanban.sh for Python venv creation
|
|
13384
|
+
// Slack integration scripts
|
|
13385
|
+
"slack_state.py",
|
|
13386
|
+
// State management for Slack integration
|
|
13387
|
+
"slack_fetch.py",
|
|
13388
|
+
// Core logic for fetching Slack messages
|
|
13389
|
+
"slack_fetch.sh",
|
|
13390
|
+
// Wrapper script for Slack fetch
|
|
13391
|
+
"slack_respond.py",
|
|
13392
|
+
// Core logic for sending responses to Slack
|
|
13393
|
+
"slack_respond.sh"
|
|
13394
|
+
// Wrapper script for Slack respond
|
|
13366
13395
|
];
|
|
13367
13396
|
/**
|
|
13368
13397
|
* Get the templates scripts directory from the package
|
|
@@ -13551,6 +13580,115 @@ var init_script_installer = __esm({
|
|
|
13551
13580
|
}
|
|
13552
13581
|
return results;
|
|
13553
13582
|
}
|
|
13583
|
+
/**
|
|
13584
|
+
* Get scripts that need updates based on content comparison
|
|
13585
|
+
* @param projectDir - The project root directory
|
|
13586
|
+
* @returns Array of script names that have different content from package version
|
|
13587
|
+
*/
|
|
13588
|
+
static async getOutdatedScripts(projectDir) {
|
|
13589
|
+
const outdated = [];
|
|
13590
|
+
const packageScriptsDir = this.getPackageScriptsDir();
|
|
13591
|
+
if (!packageScriptsDir) {
|
|
13592
|
+
return outdated;
|
|
13593
|
+
}
|
|
13594
|
+
for (const script of this.REQUIRED_SCRIPTS) {
|
|
13595
|
+
const sourcePath = path3.join(packageScriptsDir, script);
|
|
13596
|
+
const destPath = path3.join(projectDir, ".juno_task", "scripts", script);
|
|
13597
|
+
if (!await fs3.pathExists(sourcePath)) {
|
|
13598
|
+
continue;
|
|
13599
|
+
}
|
|
13600
|
+
if (!await fs3.pathExists(destPath)) {
|
|
13601
|
+
continue;
|
|
13602
|
+
}
|
|
13603
|
+
try {
|
|
13604
|
+
const [sourceContent, destContent] = await Promise.all([
|
|
13605
|
+
fs3.readFile(sourcePath, "utf-8"),
|
|
13606
|
+
fs3.readFile(destPath, "utf-8")
|
|
13607
|
+
]);
|
|
13608
|
+
if (sourceContent !== destContent) {
|
|
13609
|
+
outdated.push(script);
|
|
13610
|
+
}
|
|
13611
|
+
} catch {
|
|
13612
|
+
outdated.push(script);
|
|
13613
|
+
}
|
|
13614
|
+
}
|
|
13615
|
+
return outdated;
|
|
13616
|
+
}
|
|
13617
|
+
/**
|
|
13618
|
+
* Check if any scripts need installation or update
|
|
13619
|
+
* @param projectDir - The project root directory
|
|
13620
|
+
* @returns true if any scripts need to be installed or updated
|
|
13621
|
+
*/
|
|
13622
|
+
static async needsUpdate(projectDir) {
|
|
13623
|
+
try {
|
|
13624
|
+
const junoTaskDir = path3.join(projectDir, ".juno_task");
|
|
13625
|
+
if (!await fs3.pathExists(junoTaskDir)) {
|
|
13626
|
+
return false;
|
|
13627
|
+
}
|
|
13628
|
+
const missing = await this.getMissingScripts(projectDir);
|
|
13629
|
+
if (missing.length > 0) {
|
|
13630
|
+
return true;
|
|
13631
|
+
}
|
|
13632
|
+
const outdated = await this.getOutdatedScripts(projectDir);
|
|
13633
|
+
return outdated.length > 0;
|
|
13634
|
+
} catch {
|
|
13635
|
+
return false;
|
|
13636
|
+
}
|
|
13637
|
+
}
|
|
13638
|
+
/**
|
|
13639
|
+
* Automatically update scripts - installs missing AND updates outdated scripts
|
|
13640
|
+
* Similar to ServiceInstaller.autoUpdate(), this ensures project scripts
|
|
13641
|
+
* are always in sync with the package version.
|
|
13642
|
+
*
|
|
13643
|
+
* This should be called on every CLI run to ensure scripts are up-to-date.
|
|
13644
|
+
* @param projectDir - The project root directory
|
|
13645
|
+
* @param silent - If true, suppresses console output
|
|
13646
|
+
* @returns true if any scripts were installed or updated
|
|
13647
|
+
*/
|
|
13648
|
+
static async autoUpdate(projectDir, silent = true) {
|
|
13649
|
+
try {
|
|
13650
|
+
const debug = process.env.JUNO_CODE_DEBUG === "1";
|
|
13651
|
+
const junoTaskDir = path3.join(projectDir, ".juno_task");
|
|
13652
|
+
if (!await fs3.pathExists(junoTaskDir)) {
|
|
13653
|
+
return false;
|
|
13654
|
+
}
|
|
13655
|
+
const missing = await this.getMissingScripts(projectDir);
|
|
13656
|
+
const outdated = await this.getOutdatedScripts(projectDir);
|
|
13657
|
+
if (debug) {
|
|
13658
|
+
if (missing.length > 0) {
|
|
13659
|
+
console.error(`[DEBUG] ScriptInstaller: Missing scripts: ${missing.join(", ")}`);
|
|
13660
|
+
}
|
|
13661
|
+
if (outdated.length > 0) {
|
|
13662
|
+
console.error(`[DEBUG] ScriptInstaller: Outdated scripts: ${outdated.join(", ")}`);
|
|
13663
|
+
}
|
|
13664
|
+
}
|
|
13665
|
+
if (missing.length === 0 && outdated.length === 0) {
|
|
13666
|
+
return false;
|
|
13667
|
+
}
|
|
13668
|
+
const scriptsToUpdate = [.../* @__PURE__ */ new Set([...missing, ...outdated])];
|
|
13669
|
+
let updatedAny = false;
|
|
13670
|
+
for (const script of scriptsToUpdate) {
|
|
13671
|
+
const installed = await this.installScript(projectDir, script, silent);
|
|
13672
|
+
if (installed) {
|
|
13673
|
+
updatedAny = true;
|
|
13674
|
+
}
|
|
13675
|
+
}
|
|
13676
|
+
if (updatedAny) {
|
|
13677
|
+
if (debug) {
|
|
13678
|
+
console.error(`[DEBUG] ScriptInstaller: Updated ${scriptsToUpdate.length} script(s)`);
|
|
13679
|
+
}
|
|
13680
|
+
if (!silent) {
|
|
13681
|
+
console.log(`\u2713 Updated ${scriptsToUpdate.length} script(s) in .juno_task/scripts/`);
|
|
13682
|
+
}
|
|
13683
|
+
}
|
|
13684
|
+
return updatedAny;
|
|
13685
|
+
} catch (error) {
|
|
13686
|
+
if (process.env.JUNO_CODE_DEBUG === "1") {
|
|
13687
|
+
console.error("[DEBUG] ScriptInstaller: autoUpdate error:", error);
|
|
13688
|
+
}
|
|
13689
|
+
return false;
|
|
13690
|
+
}
|
|
13691
|
+
}
|
|
13554
13692
|
};
|
|
13555
13693
|
}
|
|
13556
13694
|
});
|
|
@@ -24344,13 +24482,13 @@ async function main() {
|
|
|
24344
24482
|
}
|
|
24345
24483
|
try {
|
|
24346
24484
|
const { ScriptInstaller: ScriptInstaller2 } = await Promise.resolve().then(() => (init_script_installer(), script_installer_exports));
|
|
24347
|
-
const
|
|
24348
|
-
if (
|
|
24349
|
-
console.error("[DEBUG] Project scripts auto-
|
|
24485
|
+
const updated = await ScriptInstaller2.autoUpdate(process.cwd(), true);
|
|
24486
|
+
if (updated && (process.argv.includes("--verbose") || process.argv.includes("-v") || process.env.JUNO_CODE_DEBUG === "1")) {
|
|
24487
|
+
console.error("[DEBUG] Project scripts auto-updated in .juno_task/scripts/");
|
|
24350
24488
|
}
|
|
24351
24489
|
} catch (error) {
|
|
24352
24490
|
if (process.env.JUNO_CODE_DEBUG === "1") {
|
|
24353
|
-
console.error("[DEBUG] Script auto-
|
|
24491
|
+
console.error("[DEBUG] Script auto-update failed:", error instanceof Error ? error.message : String(error));
|
|
24354
24492
|
}
|
|
24355
24493
|
}
|
|
24356
24494
|
program.name("juno-code").description("TypeScript implementation of juno-code CLI tool for AI subagent orchestration").version(VERSION, "-V, --version", "Display version information").helpOption("-h, --help", "Display help information");
|