instar 0.12.15 → 0.12.17

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.
Files changed (47) hide show
  1. package/dist/commands/server.d.ts.map +1 -1
  2. package/dist/commands/server.js +209 -3
  3. package/dist/commands/server.js.map +1 -1
  4. package/dist/core/AdaptiveTrust.d.ts +8 -0
  5. package/dist/core/AdaptiveTrust.d.ts.map +1 -1
  6. package/dist/core/AdaptiveTrust.js +21 -2
  7. package/dist/core/AdaptiveTrust.js.map +1 -1
  8. package/dist/core/AutoDispatcher.d.ts +9 -0
  9. package/dist/core/AutoDispatcher.d.ts.map +1 -1
  10. package/dist/core/AutoDispatcher.js +38 -0
  11. package/dist/core/AutoDispatcher.js.map +1 -1
  12. package/dist/core/AutonomySkill.d.ts +98 -0
  13. package/dist/core/AutonomySkill.d.ts.map +1 -0
  14. package/dist/core/AutonomySkill.js +497 -0
  15. package/dist/core/AutonomySkill.js.map +1 -0
  16. package/dist/core/DispatchScopeEnforcer.d.ts +57 -0
  17. package/dist/core/DispatchScopeEnforcer.d.ts.map +1 -0
  18. package/dist/core/DispatchScopeEnforcer.js +173 -0
  19. package/dist/core/DispatchScopeEnforcer.js.map +1 -0
  20. package/dist/core/EvolutionManager.d.ts +36 -0
  21. package/dist/core/EvolutionManager.d.ts.map +1 -1
  22. package/dist/core/EvolutionManager.js +67 -0
  23. package/dist/core/EvolutionManager.js.map +1 -1
  24. package/dist/core/MigrationProvenance.d.ts +62 -0
  25. package/dist/core/MigrationProvenance.d.ts.map +1 -0
  26. package/dist/core/MigrationProvenance.js +183 -0
  27. package/dist/core/MigrationProvenance.js.map +1 -0
  28. package/dist/core/TrustRecovery.d.ts +109 -0
  29. package/dist/core/TrustRecovery.d.ts.map +1 -0
  30. package/dist/core/TrustRecovery.js +190 -0
  31. package/dist/core/TrustRecovery.js.map +1 -0
  32. package/dist/index.d.ts +12 -1
  33. package/dist/index.d.ts.map +1 -1
  34. package/dist/index.js +6 -0
  35. package/dist/index.js.map +1 -1
  36. package/dist/server/AgentServer.d.ts +1 -0
  37. package/dist/server/AgentServer.d.ts.map +1 -1
  38. package/dist/server/AgentServer.js +1 -0
  39. package/dist/server/AgentServer.js.map +1 -1
  40. package/dist/server/routes.d.ts +2 -0
  41. package/dist/server/routes.d.ts.map +1 -1
  42. package/dist/server/routes.js +112 -1
  43. package/dist/server/routes.js.map +1 -1
  44. package/package.json +1 -1
  45. package/src/data/builtin-manifest.json +48 -48
  46. package/upgrades/0.12.16.md +33 -0
  47. package/upgrades/0.12.17.md +38 -0
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/commands/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAsFH,UAAU,YAAY;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;2DACuD;IACvD,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAmyBD,wBAAsB,WAAW,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAymDtE;AAED,wBAAsB,UAAU,CAAC,OAAO,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAsDzE"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/commands/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AA6OH,UAAU,YAAY;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;2DACuD;IACvD,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAy0BD,wBAAsB,WAAW,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CA6pDtE;AAED,wBAAsB,UAAU,CAAC,OAAO,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAsDzE"}
@@ -57,6 +57,9 @@ import { MessageSentinel } from '../core/MessageSentinel.js';
57
57
  import { AdaptiveTrust } from '../core/AdaptiveTrust.js';
58
58
  import { AutonomyProfileManager } from '../core/AutonomyProfileManager.js';
59
59
  import { TrustElevationTracker } from '../core/TrustElevationTracker.js';
60
+ import { AutonomousEvolution } from '../core/AutonomousEvolution.js';
61
+ import { DispatchScopeEnforcer } from '../core/DispatchScopeEnforcer.js';
62
+ import { TrustRecovery } from '../core/TrustRecovery.js';
60
63
  import { DegradationReporter } from '../monitoring/DegradationReporter.js';
61
64
  import { LiveConfig } from '../config/LiveConfig.js';
62
65
  import { CoherenceMonitor } from '../monitoring/CoherenceMonitor.js';
@@ -81,6 +84,131 @@ import { createLifelineProbes } from '../monitoring/probes/LifelineProbe.js';
81
84
  import { toInjection } from '../types/pipeline.js';
82
85
  import { UserManager } from '../users/UserManager.js';
83
86
  import { formatUserContextForSession, hasUserContext } from '../users/UserContextBuilder.js';
87
+ /**
88
+ * Handle "fix X" and "clean X" commands from Agent Attention notifications.
89
+ * These are mechanical server-side operations — no Claude session needed.
90
+ * Returns true if the command was recognized and handled.
91
+ */
92
+ async function handleFixCommand(topicId, text, deps) {
93
+ const cmd = text.trim().toLowerCase();
94
+ // Only handle commands in the Agent Attention topic
95
+ const attentionTopicId = deps.state.get('agent-attention-topic');
96
+ if (!attentionTopicId || topicId !== attentionTopicId) {
97
+ return false;
98
+ }
99
+ const send = (msg) => deps.telegram.sendToTopic(topicId, msg);
100
+ if (cmd === 'fix auth') {
101
+ const existing = deps.liveConfig.get('authToken', '');
102
+ if (existing) {
103
+ await send('Your API already has an authentication token configured. No changes needed.');
104
+ return true;
105
+ }
106
+ // Generate a random token
107
+ const token = Array.from({ length: 32 }, () => 'abcdefghijklmnopqrstuvwxyz0123456789'.charAt(Math.floor(Math.random() * 36))).join('');
108
+ deps.liveConfig.set('authToken', token);
109
+ await send(`Done! Generated and saved a new API authentication token. Your API is now protected.\n\nToken: ${token.slice(0, 8)}... (stored in config)`);
110
+ return true;
111
+ }
112
+ if (cmd === 'fix dashboard') {
113
+ const existing = deps.liveConfig.get('dashboardPin', '');
114
+ if (existing) {
115
+ await send(`Your dashboard already has a PIN: ${existing}`);
116
+ return true;
117
+ }
118
+ const pin = String(Math.floor(100000 + Math.random() * 900000));
119
+ deps.liveConfig.set('dashboardPin', pin);
120
+ await send(`Done! Generated dashboard PIN: ${pin}`);
121
+ return true;
122
+ }
123
+ if (cmd === 'fix shadow') {
124
+ const localPkg = path.join(deps.config.projectDir, 'node_modules', 'instar');
125
+ if (!fs.existsSync(localPkg)) {
126
+ await send('No shadow installation found — your agent is using the global Instar installation correctly.');
127
+ return true;
128
+ }
129
+ try {
130
+ // Remove the shadow installation
131
+ const { spawnSync } = await import('node:child_process');
132
+ spawnSync('rm', ['-rf',
133
+ path.join(deps.config.projectDir, 'node_modules'),
134
+ path.join(deps.config.projectDir, 'package.json'),
135
+ path.join(deps.config.projectDir, 'package-lock.json'),
136
+ ], { timeout: 10000 });
137
+ await send('Done! Removed the local shadow installation. Your agent will now use the global Instar binary and receive auto-updates properly.');
138
+ }
139
+ catch (err) {
140
+ await send(`Failed to remove shadow installation: ${err instanceof Error ? err.message : String(err)}\n\nYou can fix this manually by deleting the node_modules folder in your project directory.`);
141
+ }
142
+ return true;
143
+ }
144
+ if (cmd === 'clean processes' || cmd === 'clean') {
145
+ if (!deps.orphanReaper) {
146
+ await send('The process monitor is still starting up. Try again in a minute.');
147
+ return true;
148
+ }
149
+ // Run a fresh scan first
150
+ await deps.orphanReaper.scan();
151
+ const result = deps.orphanReaper.killAllExternal();
152
+ if (result.killed === 0) {
153
+ await send('No external Claude processes found to clean up. Everything looks good.');
154
+ }
155
+ else {
156
+ await send(`Cleaned up ${result.killed} external Claude process${result.killed === 1 ? '' : 'es'}, freeing ~${result.freedMB}MB of memory.`);
157
+ }
158
+ return true;
159
+ }
160
+ if (cmd === 'restart') {
161
+ // Request a graceful server restart
162
+ const restartFile = path.join(deps.config.stateDir, 'restart-requested.json');
163
+ fs.writeFileSync(restartFile, JSON.stringify({
164
+ requestedAt: new Date().toISOString(),
165
+ reason: 'User requested restart via Agent Attention fix command',
166
+ requestedBy: 'fix-command',
167
+ }));
168
+ await send('Restart requested. Your agent will restart momentarily.');
169
+ return true;
170
+ }
171
+ if (cmd === 'restart sessions') {
172
+ const running = deps.sessionManager.listRunningSessions();
173
+ const stale = running.filter(s => !deps.sessionManager.isSessionAlive(s.tmuxSession));
174
+ if (stale.length === 0) {
175
+ await send(`All ${running.length} session${running.length === 1 ? ' is' : 's are'} running normally. No action needed.`);
176
+ }
177
+ else {
178
+ for (const s of stale) {
179
+ try {
180
+ deps.sessionManager.killSession(s.tmuxSession);
181
+ }
182
+ catch { /* best effort */ }
183
+ }
184
+ await send(`Found ${stale.length} stuck session${stale.length === 1 ? '' : 's'} and cleaned ${stale.length === 1 ? 'it' : 'them'} up. New sessions will start fresh when needed.`);
185
+ }
186
+ return true;
187
+ }
188
+ if (cmd === 'fix lifeline') {
189
+ // Lifeline is managed by the separate lifeline process, not the server.
190
+ // Best we can do is suggest the right command.
191
+ await send('The lifeline runs as a separate process. To restart it, use the Lifeline topic and send:\n/lifeline restart\n\nThis will reset the circuit breaker and restart your server.');
192
+ return true;
193
+ }
194
+ if (cmd === 'fix output') {
195
+ if (!deps.coherenceMonitor) {
196
+ await send('The coherence monitor is still starting up. Try again in a minute.');
197
+ return true;
198
+ }
199
+ const report = deps.coherenceMonitor.runCheck();
200
+ const outputCheck = report.checks.find(c => c.name === 'output-sanity');
201
+ if (!outputCheck || outputCheck.passed) {
202
+ await send('Output check passed — no bad patterns found in recent messages. The earlier issue may have resolved itself.');
203
+ }
204
+ else {
205
+ await send(`Output check still showing issues: ${outputCheck.message}\n\nThis usually means your agent is including internal URLs (like "localhost") in messages. Your agent should be using your public domain instead. The issue will be flagged to your agent in its next session.`);
206
+ }
207
+ return true;
208
+ }
209
+ // Not a recognized fix command
210
+ return false;
211
+ }
84
212
  /**
85
213
  * Check if autostart is installed for this project.
86
214
  * Extracted from the CLI `autostart status` handler for programmatic use.
@@ -115,6 +243,7 @@ function isAutostartInstalled(projectName) {
115
243
  // Set once the reaper is initialized in startServer().
116
244
  let _orphanReaper = null;
117
245
  let _memoryMonitor = null;
246
+ let _fixDeps = null;
118
247
  // Module-level reference for session resume mapping.
119
248
  // Set once in startServer() and used by spawnSessionForTopic/respawnSessionForTopic.
120
249
  let _topicResumeMap = null;
@@ -543,7 +672,7 @@ function messageToPipeline(msg, topicName) {
543
672
  timestamp: msg.receivedAt,
544
673
  };
545
674
  }
546
- function wireTelegramRouting(telegram, sessionManager, quotaTracker, topicMemory, userManager) {
675
+ function wireTelegramRouting(telegram, sessionManager, quotaTracker, topicMemory, userManager, fixCommandHandler) {
547
676
  telegram.onTopicMessage = (msg) => {
548
677
  const topicId = msg.metadata?.messageThreadId ?? null;
549
678
  if (!topicId)
@@ -578,6 +707,38 @@ function wireTelegramRouting(telegram, sessionManager, quotaTracker, topicMemory
578
707
  })();
579
708
  return;
580
709
  }
710
+ // ── Fix commands from notification messages ──────────────────────
711
+ // Handle "fix auth", "clean processes", "restart", etc. directly
712
+ // in the server process — no need to spawn a Claude session for these.
713
+ if (fixCommandHandler) {
714
+ const cmdText = text.trim().toLowerCase();
715
+ const isFixCommand = cmdText.startsWith('fix ') || cmdText.startsWith('clean ') ||
716
+ cmdText.startsWith('restart') || cmdText === 'fix' || cmdText === 'clean';
717
+ if (isFixCommand) {
718
+ (async () => {
719
+ try {
720
+ const handled = await fixCommandHandler(topicId, text);
721
+ if (!handled) {
722
+ // Not a recognized fix command — fall through to session routing
723
+ // Re-trigger the normal routing by calling the topic message handler again
724
+ // Actually, since we can't re-trigger, just send a help message
725
+ await telegram.sendToTopic(topicId, `I didn't recognize that command. Available fix commands:\n` +
726
+ `• "fix auth" — Generate an API security token\n` +
727
+ `• "fix lifeline" — Restart the crash-recovery system\n` +
728
+ `• "fix shadow" — Remove shadow installation\n` +
729
+ `• "clean processes" — Kill external Claude processes\n` +
730
+ `• "restart" — Restart the server\n` +
731
+ `• "restart sessions" — Restart stuck sessions`);
732
+ }
733
+ }
734
+ catch (err) {
735
+ console.error(`[telegram] Fix command error:`, err);
736
+ await telegram.sendToTopic(topicId, `Something went wrong while trying to fix that: ${err instanceof Error ? err.message : String(err)}`).catch(() => { });
737
+ }
738
+ })();
739
+ return;
740
+ }
741
+ }
581
742
  // ── Pipeline-typed routing ──────────────────────────────────────
582
743
  // Convert to PipelineMessage — types enforce that sender identity
583
744
  // and topic context are present at every stage downstream.
@@ -1222,8 +1383,17 @@ export async function startServer(options) {
1222
1383
  }
1223
1384
  // Initialize persistent UserManager for user identity resolution (Gap 8)
1224
1385
  const userManager = new UserManager(config.stateDir, config.users);
1386
+ // Fix command dependencies — populated later when subsystems initialize.
1387
+ // Uses a mutable ref so wireTelegramRouting can capture it in a closure now.
1388
+ _fixDeps = {
1389
+ state,
1390
+ liveConfig,
1391
+ sessionManager,
1392
+ telegram,
1393
+ config,
1394
+ };
1225
1395
  // Wire up topic → session routing and session management callbacks
1226
- wireTelegramRouting(telegram, sessionManager, quotaTracker, topicMemory, userManager);
1396
+ wireTelegramRouting(telegram, sessionManager, quotaTracker, topicMemory, userManager, (topicId, text) => handleFixCommand(topicId, text, _fixDeps));
1227
1397
  wireTelegramCallbacks(telegram, sessionManager, state, quotaTracker, accountSwitcher, config.sessions.claudePath, topicMemory);
1228
1398
  // Wire up unknown-user handling (Multi-User Setup Wizard Phase 4.5)
1229
1399
  telegram.onGetRegistrationPolicy = () => ({
@@ -1707,6 +1877,8 @@ export async function startServer(options) {
1707
1877
  });
1708
1878
  orphanReaper.start();
1709
1879
  _orphanReaper = orphanReaper;
1880
+ if (_fixDeps)
1881
+ _fixDeps.orphanReaper = orphanReaper;
1710
1882
  _memoryMonitor = memoryMonitor;
1711
1883
  console.log(pc.green(' Orphan process reaper enabled'));
1712
1884
  // Coherence Monitor — runtime self-awareness for homeostasis.
@@ -1726,6 +1898,8 @@ export async function startServer(options) {
1726
1898
  },
1727
1899
  });
1728
1900
  coherenceMonitor.start();
1901
+ if (_fixDeps)
1902
+ _fixDeps.coherenceMonitor = coherenceMonitor;
1729
1903
  console.log(pc.green(' Coherence monitor enabled'));
1730
1904
  // Commitment Tracker — durable promise enforcement for agent commitments.
1731
1905
  // When users ask agents to change settings/behavior, this ensures it sticks.
@@ -1881,6 +2055,38 @@ export async function startServer(options) {
1881
2055
  const trustElevationTracker = new TrustElevationTracker({
1882
2056
  stateDir: config.stateDir,
1883
2057
  });
2058
+ // Autonomous Evolution — auto-approval and auto-implementation of proposals
2059
+ const autonomousEvolution = new AutonomousEvolution({
2060
+ stateDir: config.stateDir,
2061
+ enabled: autonomyManager.getResolvedState().evolutionApprovalMode === 'autonomous',
2062
+ });
2063
+ // Dispatch Scope Enforcer — scope tiers for dispatch execution
2064
+ const dispatchScopeEnforcer = new DispatchScopeEnforcer();
2065
+ // Trust Recovery — recovery path after trust incidents
2066
+ const trustRecovery = extOpsEnabled ? new TrustRecovery({
2067
+ stateDir: config.stateDir,
2068
+ }) : undefined;
2069
+ // ── Adaptive Autonomy Wiring ──────────────────────────────────────
2070
+ // Wire the new modules together so they exchange events at runtime.
2071
+ // 1. AdaptiveTrust ↔ TrustRecovery
2072
+ // When trust drops (incident), record in TrustRecovery.
2073
+ // When operations succeed post-incident, increment recovery counter.
2074
+ if (adaptiveTrust && trustRecovery) {
2075
+ adaptiveTrust.setTrustRecovery(trustRecovery);
2076
+ }
2077
+ // 2. AutoDispatcher ↔ DispatchScopeEnforcer
2078
+ // Before executing a dispatch, check scope permissions against current autonomy profile.
2079
+ if (autoDispatcher) {
2080
+ autoDispatcher.setScopeEnforcer(dispatchScopeEnforcer, autonomyManager);
2081
+ }
2082
+ // 3. EvolutionManager ↔ TrustElevationTracker + AutonomousEvolution
2083
+ // Proposal decisions feed trust elevation tracking.
2084
+ // Autonomous mode uses AutonomousEvolution for auto-implementation.
2085
+ evolution.setAdaptiveAutonomyModules({
2086
+ trustElevationTracker,
2087
+ autonomousEvolution,
2088
+ autonomyManager,
2089
+ });
1884
2090
  // Wire sentinel into Telegram message flow — intercepts BEFORE session routing.
1885
2091
  // Must be wired AFTER sentinel is created but BEFORE server starts.
1886
2092
  if (sentinel && telegram) {
@@ -2103,7 +2309,7 @@ export async function startServer(options) {
2103
2309
  systemReviewer.start();
2104
2310
  console.log(pc.green(` System Reviewer: ${probes.length} probes registered`));
2105
2311
  }
2106
- const server = new AgentServer({ config, sessionManager, state, scheduler, telegram, relationships, feedback, feedbackAnomalyDetector, dispatches, updateChecker, autoUpdater, autoDispatcher, quotaTracker, quotaManager, publisher, viewer, tunnel, evolution, watchdog, topicMemory, triageNurse, projectMapper, coherenceGate, contextHierarchy, canonicalState, operationGate, sentinel, adaptiveTrust, memoryMonitor, orphanReaper, coherenceMonitor, commitmentTracker, semanticMemory, activitySentinel, messageRouter, summarySentinel, spawnManager, systemReviewer, capabilityMapper, topicResumeMap: _topicResumeMap ?? undefined, autonomyManager, trustElevationTracker, coordinator: coordinator.enabled ? coordinator : undefined, localSigningKeyPem });
2312
+ const server = new AgentServer({ config, sessionManager, state, scheduler, telegram, relationships, feedback, feedbackAnomalyDetector, dispatches, updateChecker, autoUpdater, autoDispatcher, quotaTracker, quotaManager, publisher, viewer, tunnel, evolution, watchdog, topicMemory, triageNurse, projectMapper, coherenceGate, contextHierarchy, canonicalState, operationGate, sentinel, adaptiveTrust, memoryMonitor, orphanReaper, coherenceMonitor, commitmentTracker, semanticMemory, activitySentinel, messageRouter, summarySentinel, spawnManager, systemReviewer, capabilityMapper, topicResumeMap: _topicResumeMap ?? undefined, autonomyManager, trustElevationTracker, autonomousEvolution, coordinator: coordinator.enabled ? coordinator : undefined, localSigningKeyPem });
2107
2313
  await server.start();
2108
2314
  // Connect DegradationReporter downstream systems now that everything is initialized.
2109
2315
  // Any degradation events queued during startup will drain to feedback + telegram.