instar 0.3.2 → 0.3.3

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.
@@ -39,9 +39,10 @@ interface InitOptions {
39
39
  */
40
40
  export declare function initProject(options: InitOptions): Promise<void>;
41
41
  /**
42
- * Refresh hooks and Claude settings for an existing installation.
43
- * Called after updates to ensure new hooks are installed.
44
- * Re-writes all hook files (idempotent) and merges new hooks into settings.
42
+ * Refresh hooks, Claude settings, and CLAUDE.md for an existing installation.
43
+ * Called after updates to ensure new hooks and documentation are installed.
44
+ * Re-writes all hook files (idempotent), merges new hooks into settings,
45
+ * and appends any missing sections to CLAUDE.md.
45
46
  */
46
47
  export declare function refreshHooksAndSettings(projectDir: string, stateDir: string): void;
47
48
  export {};
@@ -601,13 +601,97 @@ If everything looks healthy, exit silently. Only report issues.`,
601
601
  ];
602
602
  }
603
603
  /**
604
- * Refresh hooks and Claude settings for an existing installation.
605
- * Called after updates to ensure new hooks are installed.
606
- * Re-writes all hook files (idempotent) and merges new hooks into settings.
604
+ * Refresh hooks, Claude settings, and CLAUDE.md for an existing installation.
605
+ * Called after updates to ensure new hooks and documentation are installed.
606
+ * Re-writes all hook files (idempotent), merges new hooks into settings,
607
+ * and appends any missing sections to CLAUDE.md.
607
608
  */
608
609
  export function refreshHooksAndSettings(projectDir, stateDir) {
609
610
  installHooks(stateDir);
610
611
  installClaudeSettings(projectDir);
612
+ refreshClaudeMd(projectDir, stateDir);
613
+ refreshJobs(stateDir);
614
+ }
615
+ /**
616
+ * Merge new default jobs into existing jobs.json without overwriting user changes.
617
+ * Only adds jobs whose slugs don't already exist.
618
+ */
619
+ function refreshJobs(stateDir) {
620
+ const jobsPath = path.join(stateDir, 'jobs.json');
621
+ if (!fs.existsSync(jobsPath))
622
+ return;
623
+ let port = 4321;
624
+ try {
625
+ const config = JSON.parse(fs.readFileSync(path.join(stateDir, 'config.json'), 'utf-8'));
626
+ port = config.port || 4321;
627
+ }
628
+ catch { /* use default */ }
629
+ try {
630
+ const existingJobs = JSON.parse(fs.readFileSync(jobsPath, 'utf-8'));
631
+ const existingSlugs = new Set(existingJobs.map(j => j.slug));
632
+ const defaultJobs = getDefaultJobs(port);
633
+ let added = 0;
634
+ for (const job of defaultJobs) {
635
+ if (!existingSlugs.has(job.slug)) {
636
+ existingJobs.push(job);
637
+ added++;
638
+ }
639
+ }
640
+ if (added > 0) {
641
+ fs.writeFileSync(jobsPath, JSON.stringify(existingJobs, null, 2));
642
+ }
643
+ }
644
+ catch { /* don't break on errors */ }
645
+ }
646
+ /**
647
+ * Append missing sections to CLAUDE.md without overwriting user customizations.
648
+ * Reads config.json for port, checks for known section headers, appends if missing.
649
+ */
650
+ function refreshClaudeMd(projectDir, stateDir) {
651
+ const claudeMdPath = path.join(projectDir, 'CLAUDE.md');
652
+ if (!fs.existsSync(claudeMdPath))
653
+ return;
654
+ // Read port from config
655
+ let port = 4321;
656
+ try {
657
+ const config = JSON.parse(fs.readFileSync(path.join(stateDir, 'config.json'), 'utf-8'));
658
+ port = config.port || 4321;
659
+ }
660
+ catch { /* use default port */ }
661
+ const content = fs.readFileSync(claudeMdPath, 'utf-8');
662
+ const additions = [];
663
+ // Check for Self-Diagnosis section
664
+ if (!content.includes('Self-Diagnosis')) {
665
+ additions.push(`
666
+ ### Self-Diagnosis — Be Your Own QA
667
+
668
+ **This is critical.** You are running on infrastructure (instar) that is actively evolving. When something breaks, feels wrong, or could be better — **you are the first line of detection.** Do not silently absorb errors. Do not work around bugs without reporting them. Every issue you surface helps every agent on the platform.
669
+
670
+ **What to watch for:**
671
+ - Server errors: API calls to localhost:${port} failing, unexpected responses, timeouts
672
+ - Hook failures: hooks throwing errors, not firing when expected, blocking when they shouldn't
673
+ - Job issues: jobs not running on schedule, failing silently, taking too long
674
+ - Session problems: sessions not spawning, not being tracked, zombie sessions
675
+ - State corruption: JSON parse errors in .instar/state/ files, missing fields, stale data
676
+ - Config confusion: settings not being applied, defaults not making sense
677
+ - Missing capabilities: something you need to do but can't because instar doesn't support it
678
+ - Design flaws: patterns that feel wrong, workflows that are unnecessarily complex
679
+
680
+ **When you detect an issue, report it immediately:**
681
+ \`\`\`bash
682
+ curl -s -X POST http://localhost:${port}/feedback \\
683
+ -H 'Content-Type: application/json' \\
684
+ -d '{"type":"bug","title":"CONCISE_TITLE","description":"FULL_CONTEXT_WITH_ERROR_MESSAGES"}'
685
+ \`\`\`
686
+
687
+ Types: \`bug\`, \`feature\`, \`improvement\`, \`question\`
688
+
689
+ **Do not wait for the user to notice.** If a hook throws an error, report it. If a job fails, report it. If the server returns unexpected data, report it. You are not just using instar — you are part of its immune system.
690
+ `);
691
+ }
692
+ if (additions.length > 0) {
693
+ fs.appendFileSync(claudeMdPath, '\n' + additions.join('\n'));
694
+ }
611
695
  }
612
696
  function installHooks(stateDir) {
613
697
  const hooksDir = path.join(stateDir, 'hooks');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "instar",
3
- "version": "0.3.2",
3
+ "version": "0.3.3",
4
4
  "description": "Persistent autonomy infrastructure for AI agents",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",