juno-code 1.0.36 → 1.0.38

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.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 installed = await ScriptInstaller2.autoInstallMissing(process.cwd(), true);
24348
- if (installed && (process.argv.includes("--verbose") || process.argv.includes("-v") || process.env.JUNO_CODE_DEBUG === "1")) {
24349
- console.error("[DEBUG] Project scripts auto-installed to .juno_task/scripts/");
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-install failed:", error instanceof Error ? error.message : String(error));
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");