@iflow-mcp/jkheadley-instar 0.26.2
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/.claude/hooks/free-text-guard.sh +117 -0
- package/.claude/settings.json +201 -0
- package/.claude/skills/autonomous/hooks/autonomous-stop-hook.sh +234 -0
- package/.claude/skills/autonomous/hooks/hooks.json +15 -0
- package/.claude/skills/autonomous/scripts/setup-autonomous.sh +166 -0
- package/.claude/skills/autonomous/skill.md +254 -0
- package/.claude/skills/secret-setup/skill.md +210 -0
- package/.claude/skills/setup-wizard/skill.md +2132 -0
- package/LICENSE +21 -0
- package/README.md +214 -0
- package/dashboard/favicon.png +0 -0
- package/dashboard/index.html +5740 -0
- package/dashboard/logo.png +0 -0
- package/dist/cli.d.ts +21 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +1782 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/backup.d.ts +16 -0
- package/dist/commands/backup.d.ts.map +1 -0
- package/dist/commands/backup.js +84 -0
- package/dist/commands/backup.js.map +1 -0
- package/dist/commands/discovery.d.ts +158 -0
- package/dist/commands/discovery.d.ts.map +1 -0
- package/dist/commands/discovery.js +532 -0
- package/dist/commands/discovery.js.map +1 -0
- package/dist/commands/git.d.ts +25 -0
- package/dist/commands/git.d.ts.map +1 -0
- package/dist/commands/git.js +152 -0
- package/dist/commands/git.js.map +1 -0
- package/dist/commands/init.d.ts +52 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +4211 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/intent.d.ts +30 -0
- package/dist/commands/intent.d.ts.map +1 -0
- package/dist/commands/intent.js +349 -0
- package/dist/commands/intent.js.map +1 -0
- package/dist/commands/job.d.ts +42 -0
- package/dist/commands/job.d.ts.map +1 -0
- package/dist/commands/job.js +202 -0
- package/dist/commands/job.js.map +1 -0
- package/dist/commands/knowledge.d.ts +25 -0
- package/dist/commands/knowledge.d.ts.map +1 -0
- package/dist/commands/knowledge.js +127 -0
- package/dist/commands/knowledge.js.map +1 -0
- package/dist/commands/machine.d.ts +53 -0
- package/dist/commands/machine.d.ts.map +1 -0
- package/dist/commands/machine.js +680 -0
- package/dist/commands/machine.js.map +1 -0
- package/dist/commands/memory.d.ts +24 -0
- package/dist/commands/memory.d.ts.map +1 -0
- package/dist/commands/memory.js +163 -0
- package/dist/commands/memory.js.map +1 -0
- package/dist/commands/nuke.d.ts +22 -0
- package/dist/commands/nuke.d.ts.map +1 -0
- package/dist/commands/nuke.js +216 -0
- package/dist/commands/nuke.js.map +1 -0
- package/dist/commands/org.d.ts +16 -0
- package/dist/commands/org.d.ts.map +1 -0
- package/dist/commands/org.js +69 -0
- package/dist/commands/org.js.map +1 -0
- package/dist/commands/playbook.d.ts +91 -0
- package/dist/commands/playbook.d.ts.map +1 -0
- package/dist/commands/playbook.js +1016 -0
- package/dist/commands/playbook.js.map +1 -0
- package/dist/commands/reflect.d.ts +52 -0
- package/dist/commands/reflect.d.ts.map +1 -0
- package/dist/commands/reflect.js +316 -0
- package/dist/commands/reflect.js.map +1 -0
- package/dist/commands/relationship.d.ts +17 -0
- package/dist/commands/relationship.d.ts.map +1 -0
- package/dist/commands/relationship.js +156 -0
- package/dist/commands/relationship.js.map +1 -0
- package/dist/commands/relay.d.ts +26 -0
- package/dist/commands/relay.d.ts.map +1 -0
- package/dist/commands/relay.js +121 -0
- package/dist/commands/relay.js.map +1 -0
- package/dist/commands/review.d.ts +18 -0
- package/dist/commands/review.d.ts.map +1 -0
- package/dist/commands/review.js +193 -0
- package/dist/commands/review.js.map +1 -0
- package/dist/commands/semantic.d.ts +37 -0
- package/dist/commands/semantic.d.ts.map +1 -0
- package/dist/commands/semantic.js +198 -0
- package/dist/commands/semantic.js.map +1 -0
- package/dist/commands/server.d.ts +37 -0
- package/dist/commands/server.d.ts.map +1 -0
- package/dist/commands/server.js +4875 -0
- package/dist/commands/server.js.map +1 -0
- package/dist/commands/setup.d.ts +63 -0
- package/dist/commands/setup.d.ts.map +1 -0
- package/dist/commands/setup.js +1235 -0
- package/dist/commands/setup.js.map +1 -0
- package/dist/commands/slack-cli.d.ts +16 -0
- package/dist/commands/slack-cli.d.ts.map +1 -0
- package/dist/commands/slack-cli.js +259 -0
- package/dist/commands/slack-cli.js.map +1 -0
- package/dist/commands/status.d.ts +11 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +120 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/user.d.ts +17 -0
- package/dist/commands/user.d.ts.map +1 -0
- package/dist/commands/user.js +53 -0
- package/dist/commands/user.js.map +1 -0
- package/dist/commands/whatsapp.d.ts +31 -0
- package/dist/commands/whatsapp.d.ts.map +1 -0
- package/dist/commands/whatsapp.js +408 -0
- package/dist/commands/whatsapp.js.map +1 -0
- package/dist/config/ConfigDefaults.d.ts +40 -0
- package/dist/config/ConfigDefaults.d.ts.map +1 -0
- package/dist/config/ConfigDefaults.js +175 -0
- package/dist/config/ConfigDefaults.js.map +1 -0
- package/dist/config/LiveConfig.d.ts +97 -0
- package/dist/config/LiveConfig.d.ts.map +1 -0
- package/dist/config/LiveConfig.js +220 -0
- package/dist/config/LiveConfig.js.map +1 -0
- package/dist/core/AccessControl.d.ts +91 -0
- package/dist/core/AccessControl.d.ts.map +1 -0
- package/dist/core/AccessControl.js +184 -0
- package/dist/core/AccessControl.js.map +1 -0
- package/dist/core/AdaptationValidator.d.ts +44 -0
- package/dist/core/AdaptationValidator.d.ts.map +1 -0
- package/dist/core/AdaptationValidator.js +132 -0
- package/dist/core/AdaptationValidator.js.map +1 -0
- package/dist/core/AdaptiveTrust.d.ts +188 -0
- package/dist/core/AdaptiveTrust.d.ts.map +1 -0
- package/dist/core/AdaptiveTrust.js +354 -0
- package/dist/core/AdaptiveTrust.js.map +1 -0
- package/dist/core/AgentBus.d.ts +168 -0
- package/dist/core/AgentBus.d.ts.map +1 -0
- package/dist/core/AgentBus.js +369 -0
- package/dist/core/AgentBus.js.map +1 -0
- package/dist/core/AgentConnector.d.ts +76 -0
- package/dist/core/AgentConnector.d.ts.map +1 -0
- package/dist/core/AgentConnector.js +324 -0
- package/dist/core/AgentConnector.js.map +1 -0
- package/dist/core/AgentRegistry.d.ts +107 -0
- package/dist/core/AgentRegistry.d.ts.map +1 -0
- package/dist/core/AgentRegistry.js +569 -0
- package/dist/core/AgentRegistry.js.map +1 -0
- package/dist/core/AnthropicIntelligenceProvider.d.ts +24 -0
- package/dist/core/AnthropicIntelligenceProvider.d.ts.map +1 -0
- package/dist/core/AnthropicIntelligenceProvider.js +63 -0
- package/dist/core/AnthropicIntelligenceProvider.js.map +1 -0
- package/dist/core/AuditTrail.d.ts +207 -0
- package/dist/core/AuditTrail.d.ts.map +1 -0
- package/dist/core/AuditTrail.js +271 -0
- package/dist/core/AuditTrail.js.map +1 -0
- package/dist/core/AutoApprover.d.ts +63 -0
- package/dist/core/AutoApprover.d.ts.map +1 -0
- package/dist/core/AutoApprover.js +151 -0
- package/dist/core/AutoApprover.js.map +1 -0
- package/dist/core/AutoDispatcher.d.ts +170 -0
- package/dist/core/AutoDispatcher.d.ts.map +1 -0
- package/dist/core/AutoDispatcher.js +647 -0
- package/dist/core/AutoDispatcher.js.map +1 -0
- package/dist/core/AutoUpdater.d.ts +193 -0
- package/dist/core/AutoUpdater.d.ts.map +1 -0
- package/dist/core/AutoUpdater.js +648 -0
- package/dist/core/AutoUpdater.js.map +1 -0
- package/dist/core/AutonomousEvolution.d.ts +168 -0
- package/dist/core/AutonomousEvolution.d.ts.map +1 -0
- package/dist/core/AutonomousEvolution.js +384 -0
- package/dist/core/AutonomousEvolution.js.map +1 -0
- package/dist/core/AutonomyProfileManager.d.ts +108 -0
- package/dist/core/AutonomyProfileManager.d.ts.map +1 -0
- package/dist/core/AutonomyProfileManager.js +323 -0
- package/dist/core/AutonomyProfileManager.js.map +1 -0
- package/dist/core/AutonomySkill.d.ts +98 -0
- package/dist/core/AutonomySkill.d.ts.map +1 -0
- package/dist/core/AutonomySkill.js +497 -0
- package/dist/core/AutonomySkill.js.map +1 -0
- package/dist/core/BackupManager.d.ts +66 -0
- package/dist/core/BackupManager.d.ts.map +1 -0
- package/dist/core/BackupManager.js +266 -0
- package/dist/core/BackupManager.js.map +1 -0
- package/dist/core/BitwardenProvider.d.ts +85 -0
- package/dist/core/BitwardenProvider.d.ts.map +1 -0
- package/dist/core/BitwardenProvider.js +437 -0
- package/dist/core/BitwardenProvider.js.map +1 -0
- package/dist/core/BlockerLearningLoop.d.ts +99 -0
- package/dist/core/BlockerLearningLoop.d.ts.map +1 -0
- package/dist/core/BlockerLearningLoop.js +205 -0
- package/dist/core/BlockerLearningLoop.js.map +1 -0
- package/dist/core/BranchManager.d.ts +165 -0
- package/dist/core/BranchManager.d.ts.map +1 -0
- package/dist/core/BranchManager.js +413 -0
- package/dist/core/BranchManager.js.map +1 -0
- package/dist/core/CaffeinateManager.d.ts +50 -0
- package/dist/core/CaffeinateManager.d.ts.map +1 -0
- package/dist/core/CaffeinateManager.js +189 -0
- package/dist/core/CaffeinateManager.js.map +1 -0
- package/dist/core/CallbackRegistry.d.ts +67 -0
- package/dist/core/CallbackRegistry.d.ts.map +1 -0
- package/dist/core/CallbackRegistry.js +145 -0
- package/dist/core/CallbackRegistry.js.map +1 -0
- package/dist/core/CanonicalState.d.ts +132 -0
- package/dist/core/CanonicalState.d.ts.map +1 -0
- package/dist/core/CanonicalState.js +297 -0
- package/dist/core/CanonicalState.js.map +1 -0
- package/dist/core/CapabilityMapper.d.ts +192 -0
- package/dist/core/CapabilityMapper.d.ts.map +1 -0
- package/dist/core/CapabilityMapper.js +958 -0
- package/dist/core/CapabilityMapper.js.map +1 -0
- package/dist/core/CapabilityRegistryGenerator.d.ts +72 -0
- package/dist/core/CapabilityRegistryGenerator.d.ts.map +1 -0
- package/dist/core/CapabilityRegistryGenerator.js +310 -0
- package/dist/core/CapabilityRegistryGenerator.js.map +1 -0
- package/dist/core/ClaudeCliIntelligenceProvider.d.ts +21 -0
- package/dist/core/ClaudeCliIntelligenceProvider.d.ts.map +1 -0
- package/dist/core/ClaudeCliIntelligenceProvider.js +60 -0
- package/dist/core/ClaudeCliIntelligenceProvider.js.map +1 -0
- package/dist/core/CoherenceGate.d.ts +198 -0
- package/dist/core/CoherenceGate.d.ts.map +1 -0
- package/dist/core/CoherenceGate.js +986 -0
- package/dist/core/CoherenceGate.js.map +1 -0
- package/dist/core/CoherenceReviewer.d.ts +104 -0
- package/dist/core/CoherenceReviewer.d.ts.map +1 -0
- package/dist/core/CoherenceReviewer.js +185 -0
- package/dist/core/CoherenceReviewer.js.map +1 -0
- package/dist/core/Config.d.ts +32 -0
- package/dist/core/Config.d.ts.map +1 -0
- package/dist/core/Config.js +332 -0
- package/dist/core/Config.js.map +1 -0
- package/dist/core/ConflictNegotiator.d.ts +167 -0
- package/dist/core/ConflictNegotiator.d.ts.map +1 -0
- package/dist/core/ConflictNegotiator.js +280 -0
- package/dist/core/ConflictNegotiator.js.map +1 -0
- package/dist/core/ContextHierarchy.d.ts +102 -0
- package/dist/core/ContextHierarchy.d.ts.map +1 -0
- package/dist/core/ContextHierarchy.js +594 -0
- package/dist/core/ContextHierarchy.js.map +1 -0
- package/dist/core/ContextSnapshotBuilder.d.ts +80 -0
- package/dist/core/ContextSnapshotBuilder.d.ts.map +1 -0
- package/dist/core/ContextSnapshotBuilder.js +342 -0
- package/dist/core/ContextSnapshotBuilder.js.map +1 -0
- package/dist/core/ContextualEvaluator.d.ts +103 -0
- package/dist/core/ContextualEvaluator.d.ts.map +1 -0
- package/dist/core/ContextualEvaluator.js +389 -0
- package/dist/core/ContextualEvaluator.js.map +1 -0
- package/dist/core/ConvergenceChecker.d.ts +24 -0
- package/dist/core/ConvergenceChecker.d.ts.map +1 -0
- package/dist/core/ConvergenceChecker.js +113 -0
- package/dist/core/ConvergenceChecker.js.map +1 -0
- package/dist/core/CoordinationProtocol.d.ts +198 -0
- package/dist/core/CoordinationProtocol.d.ts.map +1 -0
- package/dist/core/CoordinationProtocol.js +363 -0
- package/dist/core/CoordinationProtocol.js.map +1 -0
- package/dist/core/CustomReviewerLoader.d.ts +45 -0
- package/dist/core/CustomReviewerLoader.d.ts.map +1 -0
- package/dist/core/CustomReviewerLoader.js +153 -0
- package/dist/core/CustomReviewerLoader.js.map +1 -0
- package/dist/core/DecisionJournal.d.ts +56 -0
- package/dist/core/DecisionJournal.d.ts.map +1 -0
- package/dist/core/DecisionJournal.js +132 -0
- package/dist/core/DecisionJournal.js.map +1 -0
- package/dist/core/DeferredDispatchTracker.d.ts +91 -0
- package/dist/core/DeferredDispatchTracker.d.ts.map +1 -0
- package/dist/core/DeferredDispatchTracker.js +213 -0
- package/dist/core/DeferredDispatchTracker.js.map +1 -0
- package/dist/core/DiscoveryEvaluator.d.ts +131 -0
- package/dist/core/DiscoveryEvaluator.d.ts.map +1 -0
- package/dist/core/DiscoveryEvaluator.js +377 -0
- package/dist/core/DiscoveryEvaluator.js.map +1 -0
- package/dist/core/DispatchDecisionJournal.d.ts +83 -0
- package/dist/core/DispatchDecisionJournal.d.ts.map +1 -0
- package/dist/core/DispatchDecisionJournal.js +181 -0
- package/dist/core/DispatchDecisionJournal.js.map +1 -0
- package/dist/core/DispatchExecutor.d.ts +127 -0
- package/dist/core/DispatchExecutor.d.ts.map +1 -0
- package/dist/core/DispatchExecutor.js +355 -0
- package/dist/core/DispatchExecutor.js.map +1 -0
- package/dist/core/DispatchManager.d.ts +200 -0
- package/dist/core/DispatchManager.d.ts.map +1 -0
- package/dist/core/DispatchManager.js +524 -0
- package/dist/core/DispatchManager.js.map +1 -0
- package/dist/core/DispatchScopeEnforcer.d.ts +57 -0
- package/dist/core/DispatchScopeEnforcer.d.ts.map +1 -0
- package/dist/core/DispatchScopeEnforcer.js +173 -0
- package/dist/core/DispatchScopeEnforcer.js.map +1 -0
- package/dist/core/DispatchVerifier.d.ts +76 -0
- package/dist/core/DispatchVerifier.d.ts.map +1 -0
- package/dist/core/DispatchVerifier.js +128 -0
- package/dist/core/DispatchVerifier.js.map +1 -0
- package/dist/core/EvolutionManager.d.ts +223 -0
- package/dist/core/EvolutionManager.d.ts.map +1 -0
- package/dist/core/EvolutionManager.js +630 -0
- package/dist/core/EvolutionManager.js.map +1 -0
- package/dist/core/ExecutionJournal.d.ts +101 -0
- package/dist/core/ExecutionJournal.d.ts.map +1 -0
- package/dist/core/ExecutionJournal.js +301 -0
- package/dist/core/ExecutionJournal.js.map +1 -0
- package/dist/core/ExternalOperationGate.d.ts +204 -0
- package/dist/core/ExternalOperationGate.d.ts.map +1 -0
- package/dist/core/ExternalOperationGate.js +413 -0
- package/dist/core/ExternalOperationGate.js.map +1 -0
- package/dist/core/FeatureDefinitions.d.ts +14 -0
- package/dist/core/FeatureDefinitions.d.ts.map +1 -0
- package/dist/core/FeatureDefinitions.js +374 -0
- package/dist/core/FeatureDefinitions.js.map +1 -0
- package/dist/core/FeatureRegistry.d.ts +337 -0
- package/dist/core/FeatureRegistry.d.ts.map +1 -0
- package/dist/core/FeatureRegistry.js +863 -0
- package/dist/core/FeatureRegistry.js.map +1 -0
- package/dist/core/FeedbackManager.d.ts +69 -0
- package/dist/core/FeedbackManager.d.ts.map +1 -0
- package/dist/core/FeedbackManager.js +284 -0
- package/dist/core/FeedbackManager.js.map +1 -0
- package/dist/core/FileClassifier.d.ts +74 -0
- package/dist/core/FileClassifier.d.ts.map +1 -0
- package/dist/core/FileClassifier.js +377 -0
- package/dist/core/FileClassifier.js.map +1 -0
- package/dist/core/ForegroundRestartWatcher.d.ts +55 -0
- package/dist/core/ForegroundRestartWatcher.d.ts.map +1 -0
- package/dist/core/ForegroundRestartWatcher.js +116 -0
- package/dist/core/ForegroundRestartWatcher.js.map +1 -0
- package/dist/core/GitStateManager.d.ts +78 -0
- package/dist/core/GitStateManager.d.ts.map +1 -0
- package/dist/core/GitStateManager.js +366 -0
- package/dist/core/GitStateManager.js.map +1 -0
- package/dist/core/GitSync.d.ts +199 -0
- package/dist/core/GitSync.d.ts.map +1 -0
- package/dist/core/GitSync.js +955 -0
- package/dist/core/GitSync.js.map +1 -0
- package/dist/core/GlobalInstallCleanup.d.ts +23 -0
- package/dist/core/GlobalInstallCleanup.d.ts.map +1 -0
- package/dist/core/GlobalInstallCleanup.js +130 -0
- package/dist/core/GlobalInstallCleanup.js.map +1 -0
- package/dist/core/GlobalSecretStore.d.ts +112 -0
- package/dist/core/GlobalSecretStore.d.ts.map +1 -0
- package/dist/core/GlobalSecretStore.js +396 -0
- package/dist/core/GlobalSecretStore.js.map +1 -0
- package/dist/core/HandoffManager.d.ts +163 -0
- package/dist/core/HandoffManager.d.ts.map +1 -0
- package/dist/core/HandoffManager.js +370 -0
- package/dist/core/HandoffManager.js.map +1 -0
- package/dist/core/HeartbeatManager.d.ts +120 -0
- package/dist/core/HeartbeatManager.d.ts.map +1 -0
- package/dist/core/HeartbeatManager.js +240 -0
- package/dist/core/HeartbeatManager.js.map +1 -0
- package/dist/core/InputGuard.d.ts +98 -0
- package/dist/core/InputGuard.d.ts.map +1 -0
- package/dist/core/InputGuard.js +316 -0
- package/dist/core/InputGuard.js.map +1 -0
- package/dist/core/IntentDriftDetector.d.ts +100 -0
- package/dist/core/IntentDriftDetector.d.ts.map +1 -0
- package/dist/core/IntentDriftDetector.js +325 -0
- package/dist/core/IntentDriftDetector.js.map +1 -0
- package/dist/core/JobReflector.d.ts +81 -0
- package/dist/core/JobReflector.d.ts.map +1 -0
- package/dist/core/JobReflector.js +244 -0
- package/dist/core/JobReflector.js.map +1 -0
- package/dist/core/LLMConflictResolver.d.ts +132 -0
- package/dist/core/LLMConflictResolver.d.ts.map +1 -0
- package/dist/core/LLMConflictResolver.js +372 -0
- package/dist/core/LLMConflictResolver.js.map +1 -0
- package/dist/core/LedgerAuth.d.ts +99 -0
- package/dist/core/LedgerAuth.d.ts.map +1 -0
- package/dist/core/LedgerAuth.js +215 -0
- package/dist/core/LedgerAuth.js.map +1 -0
- package/dist/core/MachineIdentity.d.ts +196 -0
- package/dist/core/MachineIdentity.d.ts.map +1 -0
- package/dist/core/MachineIdentity.js +476 -0
- package/dist/core/MachineIdentity.js.map +1 -0
- package/dist/core/MessageSentinel.d.ts +142 -0
- package/dist/core/MessageSentinel.d.ts.map +1 -0
- package/dist/core/MessageSentinel.js +426 -0
- package/dist/core/MessageSentinel.js.map +1 -0
- package/dist/core/MigrationProvenance.d.ts +62 -0
- package/dist/core/MigrationProvenance.d.ts.map +1 -0
- package/dist/core/MigrationProvenance.js +183 -0
- package/dist/core/MigrationProvenance.js.map +1 -0
- package/dist/core/MultiMachineCoordinator.d.ts +106 -0
- package/dist/core/MultiMachineCoordinator.d.ts.map +1 -0
- package/dist/core/MultiMachineCoordinator.js +311 -0
- package/dist/core/MultiMachineCoordinator.js.map +1 -0
- package/dist/core/NonceStore.d.ts +72 -0
- package/dist/core/NonceStore.d.ts.map +1 -0
- package/dist/core/NonceStore.js +163 -0
- package/dist/core/NonceStore.js.map +1 -0
- package/dist/core/OrgIntentManager.d.ts +58 -0
- package/dist/core/OrgIntentManager.d.ts.map +1 -0
- package/dist/core/OrgIntentManager.js +250 -0
- package/dist/core/OrgIntentManager.js.map +1 -0
- package/dist/core/OverlapGuard.d.ts +112 -0
- package/dist/core/OverlapGuard.d.ts.map +1 -0
- package/dist/core/OverlapGuard.js +241 -0
- package/dist/core/OverlapGuard.js.map +1 -0
- package/dist/core/PairingProtocol.d.ts +129 -0
- package/dist/core/PairingProtocol.d.ts.map +1 -0
- package/dist/core/PairingProtocol.js +265 -0
- package/dist/core/PairingProtocol.js.map +1 -0
- package/dist/core/PatternAnalyzer.d.ts +128 -0
- package/dist/core/PatternAnalyzer.d.ts.map +1 -0
- package/dist/core/PatternAnalyzer.js +388 -0
- package/dist/core/PatternAnalyzer.js.map +1 -0
- package/dist/core/PlatformActivityRegistry.d.ts +163 -0
- package/dist/core/PlatformActivityRegistry.d.ts.map +1 -0
- package/dist/core/PlatformActivityRegistry.js +307 -0
- package/dist/core/PlatformActivityRegistry.js.map +1 -0
- package/dist/core/PolicyEnforcementLayer.d.ts +63 -0
- package/dist/core/PolicyEnforcementLayer.d.ts.map +1 -0
- package/dist/core/PolicyEnforcementLayer.js +250 -0
- package/dist/core/PolicyEnforcementLayer.js.map +1 -0
- package/dist/core/PortRegistry.d.ts +9 -0
- package/dist/core/PortRegistry.d.ts.map +1 -0
- package/dist/core/PortRegistry.js +8 -0
- package/dist/core/PortRegistry.js.map +1 -0
- package/dist/core/PostUpdateMigrator.d.ts +170 -0
- package/dist/core/PostUpdateMigrator.d.ts.map +1 -0
- package/dist/core/PostUpdateMigrator.js +3674 -0
- package/dist/core/PostUpdateMigrator.js.map +1 -0
- package/dist/core/Prerequisites.d.ts +37 -0
- package/dist/core/Prerequisites.d.ts.map +1 -0
- package/dist/core/Prerequisites.js +272 -0
- package/dist/core/Prerequisites.js.map +1 -0
- package/dist/core/ProcessIntegrity.d.ts +90 -0
- package/dist/core/ProcessIntegrity.d.ts.map +1 -0
- package/dist/core/ProcessIntegrity.js +119 -0
- package/dist/core/ProcessIntegrity.js.map +1 -0
- package/dist/core/ProjectMapper.d.ts +97 -0
- package/dist/core/ProjectMapper.d.ts.map +1 -0
- package/dist/core/ProjectMapper.js +370 -0
- package/dist/core/ProjectMapper.js.map +1 -0
- package/dist/core/PromptGuard.d.ts +121 -0
- package/dist/core/PromptGuard.d.ts.map +1 -0
- package/dist/core/PromptGuard.js +259 -0
- package/dist/core/PromptGuard.js.map +1 -0
- package/dist/core/RecipientResolver.d.ts +54 -0
- package/dist/core/RecipientResolver.d.ts.map +1 -0
- package/dist/core/RecipientResolver.js +143 -0
- package/dist/core/RecipientResolver.js.map +1 -0
- package/dist/core/ReflectionConsolidator.d.ts +73 -0
- package/dist/core/ReflectionConsolidator.d.ts.map +1 -0
- package/dist/core/ReflectionConsolidator.js +202 -0
- package/dist/core/ReflectionConsolidator.js.map +1 -0
- package/dist/core/RelationshipManager.d.ts +146 -0
- package/dist/core/RelationshipManager.d.ts.map +1 -0
- package/dist/core/RelationshipManager.js +736 -0
- package/dist/core/RelationshipManager.js.map +1 -0
- package/dist/core/RelevanceFilter.d.ts +61 -0
- package/dist/core/RelevanceFilter.d.ts.map +1 -0
- package/dist/core/RelevanceFilter.js +160 -0
- package/dist/core/RelevanceFilter.js.map +1 -0
- package/dist/core/ResearchRateLimiter.d.ts +76 -0
- package/dist/core/ResearchRateLimiter.d.ts.map +1 -0
- package/dist/core/ResearchRateLimiter.js +168 -0
- package/dist/core/ResearchRateLimiter.js.map +1 -0
- package/dist/core/ResumeValidator.d.ts +58 -0
- package/dist/core/ResumeValidator.d.ts.map +1 -0
- package/dist/core/ResumeValidator.js +195 -0
- package/dist/core/ResumeValidator.js.map +1 -0
- package/dist/core/ScopeCoherenceTracker.d.ts +87 -0
- package/dist/core/ScopeCoherenceTracker.d.ts.map +1 -0
- package/dist/core/ScopeCoherenceTracker.js +226 -0
- package/dist/core/ScopeCoherenceTracker.js.map +1 -0
- package/dist/core/ScopeVerifier.d.ts +122 -0
- package/dist/core/ScopeVerifier.d.ts.map +1 -0
- package/dist/core/ScopeVerifier.js +350 -0
- package/dist/core/ScopeVerifier.js.map +1 -0
- package/dist/core/SecretManager.d.ts +120 -0
- package/dist/core/SecretManager.d.ts.map +1 -0
- package/dist/core/SecretManager.js +324 -0
- package/dist/core/SecretManager.js.map +1 -0
- package/dist/core/SecretMigrator.d.ts +39 -0
- package/dist/core/SecretMigrator.d.ts.map +1 -0
- package/dist/core/SecretMigrator.js +182 -0
- package/dist/core/SecretMigrator.js.map +1 -0
- package/dist/core/SecretRedactor.d.ts +121 -0
- package/dist/core/SecretRedactor.d.ts.map +1 -0
- package/dist/core/SecretRedactor.js +309 -0
- package/dist/core/SecretRedactor.js.map +1 -0
- package/dist/core/SecretStore.d.ts +104 -0
- package/dist/core/SecretStore.d.ts.map +1 -0
- package/dist/core/SecretStore.js +405 -0
- package/dist/core/SecretStore.js.map +1 -0
- package/dist/core/SecurityLog.d.ts +58 -0
- package/dist/core/SecurityLog.d.ts.map +1 -0
- package/dist/core/SecurityLog.js +123 -0
- package/dist/core/SecurityLog.js.map +1 -0
- package/dist/core/SendGateway.d.ts +77 -0
- package/dist/core/SendGateway.d.ts.map +1 -0
- package/dist/core/SendGateway.js +181 -0
- package/dist/core/SendGateway.js.map +1 -0
- package/dist/core/SessionManager.d.ts +304 -0
- package/dist/core/SessionManager.d.ts.map +1 -0
- package/dist/core/SessionManager.js +1402 -0
- package/dist/core/SessionManager.js.map +1 -0
- package/dist/core/SleepWakeDetector.d.ts +37 -0
- package/dist/core/SleepWakeDetector.d.ts.map +1 -0
- package/dist/core/SleepWakeDetector.js +59 -0
- package/dist/core/SleepWakeDetector.js.map +1 -0
- package/dist/core/SoulManager.d.ts +107 -0
- package/dist/core/SoulManager.d.ts.map +1 -0
- package/dist/core/SoulManager.js +574 -0
- package/dist/core/SoulManager.js.map +1 -0
- package/dist/core/StaleProcessGuard.d.ts +113 -0
- package/dist/core/StaleProcessGuard.d.ts.map +1 -0
- package/dist/core/StaleProcessGuard.js +134 -0
- package/dist/core/StaleProcessGuard.js.map +1 -0
- package/dist/core/StateManager.d.ts +56 -0
- package/dist/core/StateManager.d.ts.map +1 -0
- package/dist/core/StateManager.js +266 -0
- package/dist/core/StateManager.js.map +1 -0
- package/dist/core/StateWriteAuthority.d.ts +101 -0
- package/dist/core/StateWriteAuthority.d.ts.map +1 -0
- package/dist/core/StateWriteAuthority.js +169 -0
- package/dist/core/StateWriteAuthority.js.map +1 -0
- package/dist/core/SurfacingTemplates.d.ts +63 -0
- package/dist/core/SurfacingTemplates.d.ts.map +1 -0
- package/dist/core/SurfacingTemplates.js +138 -0
- package/dist/core/SurfacingTemplates.js.map +1 -0
- package/dist/core/SyncOrchestrator.d.ts +308 -0
- package/dist/core/SyncOrchestrator.d.ts.map +1 -0
- package/dist/core/SyncOrchestrator.js +925 -0
- package/dist/core/SyncOrchestrator.js.map +1 -0
- package/dist/core/TemporalCoherenceChecker.d.ts +140 -0
- package/dist/core/TemporalCoherenceChecker.d.ts.map +1 -0
- package/dist/core/TemporalCoherenceChecker.js +375 -0
- package/dist/core/TemporalCoherenceChecker.js.map +1 -0
- package/dist/core/TopicClassifier.d.ts +54 -0
- package/dist/core/TopicClassifier.d.ts.map +1 -0
- package/dist/core/TopicClassifier.js +144 -0
- package/dist/core/TopicClassifier.js.map +1 -0
- package/dist/core/TopicResumeMap.d.ts +76 -0
- package/dist/core/TopicResumeMap.d.ts.map +1 -0
- package/dist/core/TopicResumeMap.js +252 -0
- package/dist/core/TopicResumeMap.js.map +1 -0
- package/dist/core/TrustElevationTracker.d.ts +178 -0
- package/dist/core/TrustElevationTracker.d.ts.map +1 -0
- package/dist/core/TrustElevationTracker.js +343 -0
- package/dist/core/TrustElevationTracker.js.map +1 -0
- package/dist/core/TrustRecovery.d.ts +109 -0
- package/dist/core/TrustRecovery.d.ts.map +1 -0
- package/dist/core/TrustRecovery.js +190 -0
- package/dist/core/TrustRecovery.js.map +1 -0
- package/dist/core/UpdateChecker.d.ts +108 -0
- package/dist/core/UpdateChecker.d.ts.map +1 -0
- package/dist/core/UpdateChecker.js +593 -0
- package/dist/core/UpdateChecker.js.map +1 -0
- package/dist/core/UpdateGate.d.ts +102 -0
- package/dist/core/UpdateGate.d.ts.map +1 -0
- package/dist/core/UpdateGate.js +149 -0
- package/dist/core/UpdateGate.js.map +1 -0
- package/dist/core/UpgradeGuideProcessor.d.ts +105 -0
- package/dist/core/UpgradeGuideProcessor.d.ts.map +1 -0
- package/dist/core/UpgradeGuideProcessor.js +278 -0
- package/dist/core/UpgradeGuideProcessor.js.map +1 -0
- package/dist/core/UpgradeNotifyManager.d.ts +98 -0
- package/dist/core/UpgradeNotifyManager.d.ts.map +1 -0
- package/dist/core/UpgradeNotifyManager.js +205 -0
- package/dist/core/UpgradeNotifyManager.js.map +1 -0
- package/dist/core/WorkLedger.d.ts +144 -0
- package/dist/core/WorkLedger.d.ts.map +1 -0
- package/dist/core/WorkLedger.js +246 -0
- package/dist/core/WorkLedger.js.map +1 -0
- package/dist/core/models.d.ts +70 -0
- package/dist/core/models.d.ts.map +1 -0
- package/dist/core/models.js +110 -0
- package/dist/core/models.js.map +1 -0
- package/dist/core/reviewers/capability-accuracy.d.ts +13 -0
- package/dist/core/reviewers/capability-accuracy.d.ts.map +1 -0
- package/dist/core/reviewers/capability-accuracy.js +38 -0
- package/dist/core/reviewers/capability-accuracy.js.map +1 -0
- package/dist/core/reviewers/claim-provenance.d.ts +14 -0
- package/dist/core/reviewers/claim-provenance.d.ts.map +1 -0
- package/dist/core/reviewers/claim-provenance.js +50 -0
- package/dist/core/reviewers/claim-provenance.js.map +1 -0
- package/dist/core/reviewers/context-completeness.d.ts +13 -0
- package/dist/core/reviewers/context-completeness.d.ts.map +1 -0
- package/dist/core/reviewers/context-completeness.js +43 -0
- package/dist/core/reviewers/context-completeness.js.map +1 -0
- package/dist/core/reviewers/conversational-tone.d.ts +13 -0
- package/dist/core/reviewers/conversational-tone.d.ts.map +1 -0
- package/dist/core/reviewers/conversational-tone.js +55 -0
- package/dist/core/reviewers/conversational-tone.js.map +1 -0
- package/dist/core/reviewers/escalation-resolution.d.ts +56 -0
- package/dist/core/reviewers/escalation-resolution.d.ts.map +1 -0
- package/dist/core/reviewers/escalation-resolution.js +239 -0
- package/dist/core/reviewers/escalation-resolution.js.map +1 -0
- package/dist/core/reviewers/gate-reviewer.d.ts +26 -0
- package/dist/core/reviewers/gate-reviewer.d.ts.map +1 -0
- package/dist/core/reviewers/gate-reviewer.js +130 -0
- package/dist/core/reviewers/gate-reviewer.js.map +1 -0
- package/dist/core/reviewers/information-leakage.d.ts +21 -0
- package/dist/core/reviewers/information-leakage.d.ts.map +1 -0
- package/dist/core/reviewers/information-leakage.js +72 -0
- package/dist/core/reviewers/information-leakage.js.map +1 -0
- package/dist/core/reviewers/settling-detection.d.ts +13 -0
- package/dist/core/reviewers/settling-detection.d.ts.map +1 -0
- package/dist/core/reviewers/settling-detection.js +48 -0
- package/dist/core/reviewers/settling-detection.js.map +1 -0
- package/dist/core/reviewers/url-validity.d.ts +18 -0
- package/dist/core/reviewers/url-validity.d.ts.map +1 -0
- package/dist/core/reviewers/url-validity.js +60 -0
- package/dist/core/reviewers/url-validity.js.map +1 -0
- package/dist/core/reviewers/value-alignment.d.ts +14 -0
- package/dist/core/reviewers/value-alignment.d.ts.map +1 -0
- package/dist/core/reviewers/value-alignment.js +71 -0
- package/dist/core/reviewers/value-alignment.js.map +1 -0
- package/dist/core/types.d.ts +2159 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +20 -0
- package/dist/core/types.js.map +1 -0
- package/dist/data/http-hook-templates.d.ts +53 -0
- package/dist/data/http-hook-templates.d.ts.map +1 -0
- package/dist/data/http-hook-templates.js +64 -0
- package/dist/data/http-hook-templates.js.map +1 -0
- package/dist/index.d.ts +263 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +164 -0
- package/dist/index.js.map +1 -0
- package/dist/knowledge/CoverageAuditor.d.ts +58 -0
- package/dist/knowledge/CoverageAuditor.d.ts.map +1 -0
- package/dist/knowledge/CoverageAuditor.js +153 -0
- package/dist/knowledge/CoverageAuditor.js.map +1 -0
- package/dist/knowledge/IntegrityManager.d.ts +46 -0
- package/dist/knowledge/IntegrityManager.d.ts.map +1 -0
- package/dist/knowledge/IntegrityManager.js +101 -0
- package/dist/knowledge/IntegrityManager.js.map +1 -0
- package/dist/knowledge/KnowledgeManager.d.ts +85 -0
- package/dist/knowledge/KnowledgeManager.d.ts.map +1 -0
- package/dist/knowledge/KnowledgeManager.js +194 -0
- package/dist/knowledge/KnowledgeManager.js.map +1 -0
- package/dist/knowledge/ProbeRegistry.d.ts +54 -0
- package/dist/knowledge/ProbeRegistry.d.ts.map +1 -0
- package/dist/knowledge/ProbeRegistry.js +119 -0
- package/dist/knowledge/ProbeRegistry.js.map +1 -0
- package/dist/knowledge/SelfKnowledgeTree.d.ts +108 -0
- package/dist/knowledge/SelfKnowledgeTree.d.ts.map +1 -0
- package/dist/knowledge/SelfKnowledgeTree.js +560 -0
- package/dist/knowledge/SelfKnowledgeTree.js.map +1 -0
- package/dist/knowledge/TreeGenerator.d.ts +57 -0
- package/dist/knowledge/TreeGenerator.d.ts.map +1 -0
- package/dist/knowledge/TreeGenerator.js +527 -0
- package/dist/knowledge/TreeGenerator.js.map +1 -0
- package/dist/knowledge/TreeSynthesis.d.ts +24 -0
- package/dist/knowledge/TreeSynthesis.d.ts.map +1 -0
- package/dist/knowledge/TreeSynthesis.js +61 -0
- package/dist/knowledge/TreeSynthesis.js.map +1 -0
- package/dist/knowledge/TreeTraversal.d.ts +93 -0
- package/dist/knowledge/TreeTraversal.d.ts.map +1 -0
- package/dist/knowledge/TreeTraversal.js +359 -0
- package/dist/knowledge/TreeTraversal.js.map +1 -0
- package/dist/knowledge/TreeTriage.d.ts +80 -0
- package/dist/knowledge/TreeTriage.d.ts.map +1 -0
- package/dist/knowledge/TreeTriage.js +413 -0
- package/dist/knowledge/TreeTriage.js.map +1 -0
- package/dist/knowledge/types.d.ts +183 -0
- package/dist/knowledge/types.d.ts.map +1 -0
- package/dist/knowledge/types.js +28 -0
- package/dist/knowledge/types.js.map +1 -0
- package/dist/lifeline/MessageQueue.d.ts +42 -0
- package/dist/lifeline/MessageQueue.d.ts.map +1 -0
- package/dist/lifeline/MessageQueue.js +63 -0
- package/dist/lifeline/MessageQueue.js.map +1 -0
- package/dist/lifeline/ServerSupervisor.d.ts +203 -0
- package/dist/lifeline/ServerSupervisor.d.ts.map +1 -0
- package/dist/lifeline/ServerSupervisor.js +1103 -0
- package/dist/lifeline/ServerSupervisor.js.map +1 -0
- package/dist/lifeline/SlackLifeline.d.ts +43 -0
- package/dist/lifeline/SlackLifeline.d.ts.map +1 -0
- package/dist/lifeline/SlackLifeline.js +227 -0
- package/dist/lifeline/SlackLifeline.js.map +1 -0
- package/dist/lifeline/TelegramLifeline.d.ts +180 -0
- package/dist/lifeline/TelegramLifeline.d.ts.map +1 -0
- package/dist/lifeline/TelegramLifeline.js +1533 -0
- package/dist/lifeline/TelegramLifeline.js.map +1 -0
- package/dist/memory/ActivityPartitioner.d.ts +67 -0
- package/dist/memory/ActivityPartitioner.d.ts.map +1 -0
- package/dist/memory/ActivityPartitioner.js +193 -0
- package/dist/memory/ActivityPartitioner.js.map +1 -0
- package/dist/memory/Chunker.d.ts +39 -0
- package/dist/memory/Chunker.d.ts.map +1 -0
- package/dist/memory/Chunker.js +154 -0
- package/dist/memory/Chunker.js.map +1 -0
- package/dist/memory/EmbeddingProvider.d.ts +82 -0
- package/dist/memory/EmbeddingProvider.d.ts.map +1 -0
- package/dist/memory/EmbeddingProvider.js +168 -0
- package/dist/memory/EmbeddingProvider.js.map +1 -0
- package/dist/memory/EpisodicMemory.d.ts +141 -0
- package/dist/memory/EpisodicMemory.d.ts.map +1 -0
- package/dist/memory/EpisodicMemory.js +303 -0
- package/dist/memory/EpisodicMemory.js.map +1 -0
- package/dist/memory/MemoryExporter.d.ts +82 -0
- package/dist/memory/MemoryExporter.d.ts.map +1 -0
- package/dist/memory/MemoryExporter.js +233 -0
- package/dist/memory/MemoryExporter.js.map +1 -0
- package/dist/memory/MemoryIndex.d.ts +76 -0
- package/dist/memory/MemoryIndex.d.ts.map +1 -0
- package/dist/memory/MemoryIndex.js +413 -0
- package/dist/memory/MemoryIndex.js.map +1 -0
- package/dist/memory/MemoryMigrator.d.ts +103 -0
- package/dist/memory/MemoryMigrator.d.ts.map +1 -0
- package/dist/memory/MemoryMigrator.js +510 -0
- package/dist/memory/MemoryMigrator.js.map +1 -0
- package/dist/memory/SemanticMemory.d.ts +255 -0
- package/dist/memory/SemanticMemory.d.ts.map +1 -0
- package/dist/memory/SemanticMemory.js +1130 -0
- package/dist/memory/SemanticMemory.js.map +1 -0
- package/dist/memory/TopicMemory.d.ts +227 -0
- package/dist/memory/TopicMemory.d.ts.map +1 -0
- package/dist/memory/TopicMemory.js +731 -0
- package/dist/memory/TopicMemory.js.map +1 -0
- package/dist/memory/TopicSummarizer.d.ts +69 -0
- package/dist/memory/TopicSummarizer.d.ts.map +1 -0
- package/dist/memory/TopicSummarizer.js +163 -0
- package/dist/memory/TopicSummarizer.js.map +1 -0
- package/dist/memory/VectorSearch.d.ts +80 -0
- package/dist/memory/VectorSearch.d.ts.map +1 -0
- package/dist/memory/VectorSearch.js +148 -0
- package/dist/memory/VectorSearch.js.map +1 -0
- package/dist/memory/WorkingMemoryAssembler.d.ts +122 -0
- package/dist/memory/WorkingMemoryAssembler.d.ts.map +1 -0
- package/dist/memory/WorkingMemoryAssembler.js +406 -0
- package/dist/memory/WorkingMemoryAssembler.js.map +1 -0
- package/dist/messaging/AdapterRegistry.d.ts +27 -0
- package/dist/messaging/AdapterRegistry.d.ts.map +1 -0
- package/dist/messaging/AdapterRegistry.js +40 -0
- package/dist/messaging/AdapterRegistry.js.map +1 -0
- package/dist/messaging/AgentTokenManager.d.ts +86 -0
- package/dist/messaging/AgentTokenManager.d.ts.map +1 -0
- package/dist/messaging/AgentTokenManager.js +213 -0
- package/dist/messaging/AgentTokenManager.js.map +1 -0
- package/dist/messaging/DeliveryRetryManager.d.ts +47 -0
- package/dist/messaging/DeliveryRetryManager.d.ts.map +1 -0
- package/dist/messaging/DeliveryRetryManager.js +201 -0
- package/dist/messaging/DeliveryRetryManager.js.map +1 -0
- package/dist/messaging/DropPickup.d.ts +37 -0
- package/dist/messaging/DropPickup.d.ts.map +1 -0
- package/dist/messaging/DropPickup.js +120 -0
- package/dist/messaging/DropPickup.js.map +1 -0
- package/dist/messaging/GitSyncTransport.d.ts +120 -0
- package/dist/messaging/GitSyncTransport.d.ts.map +1 -0
- package/dist/messaging/GitSyncTransport.js +296 -0
- package/dist/messaging/GitSyncTransport.js.map +1 -0
- package/dist/messaging/MessageDelivery.d.ts +27 -0
- package/dist/messaging/MessageDelivery.d.ts.map +1 -0
- package/dist/messaging/MessageDelivery.js +90 -0
- package/dist/messaging/MessageDelivery.js.map +1 -0
- package/dist/messaging/MessageFormatter.d.ts +30 -0
- package/dist/messaging/MessageFormatter.d.ts.map +1 -0
- package/dist/messaging/MessageFormatter.js +97 -0
- package/dist/messaging/MessageFormatter.js.map +1 -0
- package/dist/messaging/MessageRouter.d.ts +157 -0
- package/dist/messaging/MessageRouter.d.ts.map +1 -0
- package/dist/messaging/MessageRouter.js +657 -0
- package/dist/messaging/MessageRouter.js.map +1 -0
- package/dist/messaging/MessageStore.d.ts +52 -0
- package/dist/messaging/MessageStore.d.ts.map +1 -0
- package/dist/messaging/MessageStore.js +363 -0
- package/dist/messaging/MessageStore.js.map +1 -0
- package/dist/messaging/NotificationBatcher.d.ts +95 -0
- package/dist/messaging/NotificationBatcher.d.ts.map +1 -0
- package/dist/messaging/NotificationBatcher.js +253 -0
- package/dist/messaging/NotificationBatcher.js.map +1 -0
- package/dist/messaging/SessionSummarySentinel.d.ts +104 -0
- package/dist/messaging/SessionSummarySentinel.d.ts.map +1 -0
- package/dist/messaging/SessionSummarySentinel.js +386 -0
- package/dist/messaging/SessionSummarySentinel.js.map +1 -0
- package/dist/messaging/SpawnRequestManager.d.ts +88 -0
- package/dist/messaging/SpawnRequestManager.d.ts.map +1 -0
- package/dist/messaging/SpawnRequestManager.js +159 -0
- package/dist/messaging/SpawnRequestManager.js.map +1 -0
- package/dist/messaging/TelegramAdapter.d.ts +636 -0
- package/dist/messaging/TelegramAdapter.d.ts.map +1 -0
- package/dist/messaging/TelegramAdapter.js +3434 -0
- package/dist/messaging/TelegramAdapter.js.map +1 -0
- package/dist/messaging/TopicContentValidator.d.ts +81 -0
- package/dist/messaging/TopicContentValidator.d.ts.map +1 -0
- package/dist/messaging/TopicContentValidator.js +113 -0
- package/dist/messaging/TopicContentValidator.js.map +1 -0
- package/dist/messaging/WhatsAppAdapter.d.ts +224 -0
- package/dist/messaging/WhatsAppAdapter.d.ts.map +1 -0
- package/dist/messaging/WhatsAppAdapter.js +736 -0
- package/dist/messaging/WhatsAppAdapter.js.map +1 -0
- package/dist/messaging/backends/BaileysBackend.d.ts +74 -0
- package/dist/messaging/backends/BaileysBackend.d.ts.map +1 -0
- package/dist/messaging/backends/BaileysBackend.js +481 -0
- package/dist/messaging/backends/BaileysBackend.js.map +1 -0
- package/dist/messaging/backends/BusinessApiBackend.d.ts +173 -0
- package/dist/messaging/backends/BusinessApiBackend.d.ts.map +1 -0
- package/dist/messaging/backends/BusinessApiBackend.js +269 -0
- package/dist/messaging/backends/BusinessApiBackend.js.map +1 -0
- package/dist/messaging/backends/WhatsAppWebhookRoutes.d.ts +26 -0
- package/dist/messaging/backends/WhatsAppWebhookRoutes.d.ts.map +1 -0
- package/dist/messaging/backends/WhatsAppWebhookRoutes.js +50 -0
- package/dist/messaging/backends/WhatsAppWebhookRoutes.js.map +1 -0
- package/dist/messaging/shared/AuthGate.d.ts +102 -0
- package/dist/messaging/shared/AuthGate.d.ts.map +1 -0
- package/dist/messaging/shared/AuthGate.js +159 -0
- package/dist/messaging/shared/AuthGate.js.map +1 -0
- package/dist/messaging/shared/CommandRouter.d.ts +84 -0
- package/dist/messaging/shared/CommandRouter.d.ts.map +1 -0
- package/dist/messaging/shared/CommandRouter.js +145 -0
- package/dist/messaging/shared/CommandRouter.js.map +1 -0
- package/dist/messaging/shared/CrossPlatformAlerts.d.ts +67 -0
- package/dist/messaging/shared/CrossPlatformAlerts.d.ts.map +1 -0
- package/dist/messaging/shared/CrossPlatformAlerts.js +134 -0
- package/dist/messaging/shared/CrossPlatformAlerts.js.map +1 -0
- package/dist/messaging/shared/EncryptedAuthStore.d.ts +51 -0
- package/dist/messaging/shared/EncryptedAuthStore.d.ts.map +1 -0
- package/dist/messaging/shared/EncryptedAuthStore.js +194 -0
- package/dist/messaging/shared/EncryptedAuthStore.js.map +1 -0
- package/dist/messaging/shared/FeatureFlags.d.ts +21 -0
- package/dist/messaging/shared/FeatureFlags.d.ts.map +1 -0
- package/dist/messaging/shared/FeatureFlags.js +21 -0
- package/dist/messaging/shared/FeatureFlags.js.map +1 -0
- package/dist/messaging/shared/MessageBridge.d.ts +70 -0
- package/dist/messaging/shared/MessageBridge.d.ts.map +1 -0
- package/dist/messaging/shared/MessageBridge.js +178 -0
- package/dist/messaging/shared/MessageBridge.js.map +1 -0
- package/dist/messaging/shared/MessageLogger.d.ts +94 -0
- package/dist/messaging/shared/MessageLogger.d.ts.map +1 -0
- package/dist/messaging/shared/MessageLogger.js +173 -0
- package/dist/messaging/shared/MessageLogger.js.map +1 -0
- package/dist/messaging/shared/MessagingEventBus.d.ts +149 -0
- package/dist/messaging/shared/MessagingEventBus.d.ts.map +1 -0
- package/dist/messaging/shared/MessagingEventBus.js +111 -0
- package/dist/messaging/shared/MessagingEventBus.js.map +1 -0
- package/dist/messaging/shared/PhoneUtils.d.ts +44 -0
- package/dist/messaging/shared/PhoneUtils.d.ts.map +1 -0
- package/dist/messaging/shared/PhoneUtils.js +110 -0
- package/dist/messaging/shared/PhoneUtils.js.map +1 -0
- package/dist/messaging/shared/PrivacyConsent.d.ts +61 -0
- package/dist/messaging/shared/PrivacyConsent.d.ts.map +1 -0
- package/dist/messaging/shared/PrivacyConsent.js +132 -0
- package/dist/messaging/shared/PrivacyConsent.js.map +1 -0
- package/dist/messaging/shared/SessionChannelRegistry.d.ts +48 -0
- package/dist/messaging/shared/SessionChannelRegistry.d.ts.map +1 -0
- package/dist/messaging/shared/SessionChannelRegistry.js +144 -0
- package/dist/messaging/shared/SessionChannelRegistry.js.map +1 -0
- package/dist/messaging/shared/SmartChunker.d.ts +16 -0
- package/dist/messaging/shared/SmartChunker.d.ts.map +1 -0
- package/dist/messaging/shared/SmartChunker.js +100 -0
- package/dist/messaging/shared/SmartChunker.js.map +1 -0
- package/dist/messaging/shared/StallDetector.d.ts +85 -0
- package/dist/messaging/shared/StallDetector.d.ts.map +1 -0
- package/dist/messaging/shared/StallDetector.js +225 -0
- package/dist/messaging/shared/StallDetector.js.map +1 -0
- package/dist/messaging/shared/index.d.ts +22 -0
- package/dist/messaging/shared/index.d.ts.map +1 -0
- package/dist/messaging/shared/index.js +13 -0
- package/dist/messaging/shared/index.js.map +1 -0
- package/dist/messaging/slack/ChannelManager.d.ts +36 -0
- package/dist/messaging/slack/ChannelManager.d.ts.map +1 -0
- package/dist/messaging/slack/ChannelManager.js +100 -0
- package/dist/messaging/slack/ChannelManager.js.map +1 -0
- package/dist/messaging/slack/FileHandler.d.ts +30 -0
- package/dist/messaging/slack/FileHandler.d.ts.map +1 -0
- package/dist/messaging/slack/FileHandler.js +87 -0
- package/dist/messaging/slack/FileHandler.js.map +1 -0
- package/dist/messaging/slack/RingBuffer.d.ts +22 -0
- package/dist/messaging/slack/RingBuffer.d.ts.map +1 -0
- package/dist/messaging/slack/RingBuffer.js +48 -0
- package/dist/messaging/slack/RingBuffer.js.map +1 -0
- package/dist/messaging/slack/SlackAdapter.d.ts +283 -0
- package/dist/messaging/slack/SlackAdapter.d.ts.map +1 -0
- package/dist/messaging/slack/SlackAdapter.js +1524 -0
- package/dist/messaging/slack/SlackAdapter.js.map +1 -0
- package/dist/messaging/slack/SlackApiClient.d.ts +51 -0
- package/dist/messaging/slack/SlackApiClient.d.ts.map +1 -0
- package/dist/messaging/slack/SlackApiClient.js +94 -0
- package/dist/messaging/slack/SlackApiClient.js.map +1 -0
- package/dist/messaging/slack/SocketModeClient.d.ts +44 -0
- package/dist/messaging/slack/SocketModeClient.d.ts.map +1 -0
- package/dist/messaging/slack/SocketModeClient.js +209 -0
- package/dist/messaging/slack/SocketModeClient.js.map +1 -0
- package/dist/messaging/slack/index.d.ts +12 -0
- package/dist/messaging/slack/index.d.ts.map +1 -0
- package/dist/messaging/slack/index.js +15 -0
- package/dist/messaging/slack/index.js.map +1 -0
- package/dist/messaging/slack/sanitize.d.ts +39 -0
- package/dist/messaging/slack/sanitize.d.ts.map +1 -0
- package/dist/messaging/slack/sanitize.js +71 -0
- package/dist/messaging/slack/sanitize.js.map +1 -0
- package/dist/messaging/slack/types.d.ts +186 -0
- package/dist/messaging/slack/types.d.ts.map +1 -0
- package/dist/messaging/slack/types.js +54 -0
- package/dist/messaging/slack/types.js.map +1 -0
- package/dist/messaging/types.d.ts +400 -0
- package/dist/messaging/types.d.ts.map +1 -0
- package/dist/messaging/types.js +89 -0
- package/dist/messaging/types.js.map +1 -0
- package/dist/monitoring/AccountSwitcher.d.ts +61 -0
- package/dist/monitoring/AccountSwitcher.d.ts.map +1 -0
- package/dist/monitoring/AccountSwitcher.js +196 -0
- package/dist/monitoring/AccountSwitcher.js.map +1 -0
- package/dist/monitoring/CoherenceMonitor.d.ts +133 -0
- package/dist/monitoring/CoherenceMonitor.d.ts.map +1 -0
- package/dist/monitoring/CoherenceMonitor.js +550 -0
- package/dist/monitoring/CoherenceMonitor.js.map +1 -0
- package/dist/monitoring/CommitmentSentinel.d.ts +57 -0
- package/dist/monitoring/CommitmentSentinel.d.ts.map +1 -0
- package/dist/monitoring/CommitmentSentinel.js +251 -0
- package/dist/monitoring/CommitmentSentinel.js.map +1 -0
- package/dist/monitoring/CommitmentTracker.d.ts +186 -0
- package/dist/monitoring/CommitmentTracker.d.ts.map +1 -0
- package/dist/monitoring/CommitmentTracker.js +522 -0
- package/dist/monitoring/CommitmentTracker.js.map +1 -0
- package/dist/monitoring/CredentialProvider.d.ts +84 -0
- package/dist/monitoring/CredentialProvider.d.ts.map +1 -0
- package/dist/monitoring/CredentialProvider.js +196 -0
- package/dist/monitoring/CredentialProvider.js.map +1 -0
- package/dist/monitoring/DegradationReporter.d.ts +123 -0
- package/dist/monitoring/DegradationReporter.d.ts.map +1 -0
- package/dist/monitoring/DegradationReporter.js +241 -0
- package/dist/monitoring/DegradationReporter.js.map +1 -0
- package/dist/monitoring/FeedbackAnomalyDetector.d.ts +51 -0
- package/dist/monitoring/FeedbackAnomalyDetector.d.ts.map +1 -0
- package/dist/monitoring/FeedbackAnomalyDetector.js +120 -0
- package/dist/monitoring/FeedbackAnomalyDetector.js.map +1 -0
- package/dist/monitoring/HealthChecker.d.ts +45 -0
- package/dist/monitoring/HealthChecker.d.ts.map +1 -0
- package/dist/monitoring/HealthChecker.js +219 -0
- package/dist/monitoring/HealthChecker.js.map +1 -0
- package/dist/monitoring/HomeostasisMonitor.d.ts +102 -0
- package/dist/monitoring/HomeostasisMonitor.d.ts.map +1 -0
- package/dist/monitoring/HomeostasisMonitor.js +185 -0
- package/dist/monitoring/HomeostasisMonitor.js.map +1 -0
- package/dist/monitoring/HookEventReceiver.d.ts +132 -0
- package/dist/monitoring/HookEventReceiver.d.ts.map +1 -0
- package/dist/monitoring/HookEventReceiver.js +209 -0
- package/dist/monitoring/HookEventReceiver.js.map +1 -0
- package/dist/monitoring/InputClassifier.d.ts +68 -0
- package/dist/monitoring/InputClassifier.d.ts.map +1 -0
- package/dist/monitoring/InputClassifier.js +243 -0
- package/dist/monitoring/InputClassifier.js.map +1 -0
- package/dist/monitoring/InstructionsVerifier.d.ts +76 -0
- package/dist/monitoring/InstructionsVerifier.d.ts.map +1 -0
- package/dist/monitoring/InstructionsVerifier.js +116 -0
- package/dist/monitoring/InstructionsVerifier.js.map +1 -0
- package/dist/monitoring/MemoryPressureMonitor.d.ts +107 -0
- package/dist/monitoring/MemoryPressureMonitor.d.ts.map +1 -0
- package/dist/monitoring/MemoryPressureMonitor.js +329 -0
- package/dist/monitoring/MemoryPressureMonitor.js.map +1 -0
- package/dist/monitoring/OrphanProcessReaper.d.ts +125 -0
- package/dist/monitoring/OrphanProcessReaper.d.ts.map +1 -0
- package/dist/monitoring/OrphanProcessReaper.js +476 -0
- package/dist/monitoring/OrphanProcessReaper.js.map +1 -0
- package/dist/monitoring/PresenceProxy.d.ts +167 -0
- package/dist/monitoring/PresenceProxy.d.ts.map +1 -0
- package/dist/monitoring/PresenceProxy.js +972 -0
- package/dist/monitoring/PresenceProxy.js.map +1 -0
- package/dist/monitoring/PromptGate.d.ts +91 -0
- package/dist/monitoring/PromptGate.d.ts.map +1 -0
- package/dist/monitoring/PromptGate.js +411 -0
- package/dist/monitoring/PromptGate.js.map +1 -0
- package/dist/monitoring/QuotaCollector.d.ts +267 -0
- package/dist/monitoring/QuotaCollector.d.ts.map +1 -0
- package/dist/monitoring/QuotaCollector.js +790 -0
- package/dist/monitoring/QuotaCollector.js.map +1 -0
- package/dist/monitoring/QuotaExhaustionDetector.d.ts +21 -0
- package/dist/monitoring/QuotaExhaustionDetector.d.ts.map +1 -0
- package/dist/monitoring/QuotaExhaustionDetector.js +136 -0
- package/dist/monitoring/QuotaExhaustionDetector.js.map +1 -0
- package/dist/monitoring/QuotaManager.d.ts +191 -0
- package/dist/monitoring/QuotaManager.d.ts.map +1 -0
- package/dist/monitoring/QuotaManager.js +575 -0
- package/dist/monitoring/QuotaManager.js.map +1 -0
- package/dist/monitoring/QuotaNotifier.d.ts +38 -0
- package/dist/monitoring/QuotaNotifier.d.ts.map +1 -0
- package/dist/monitoring/QuotaNotifier.js +144 -0
- package/dist/monitoring/QuotaNotifier.js.map +1 -0
- package/dist/monitoring/QuotaTracker.d.ts +92 -0
- package/dist/monitoring/QuotaTracker.d.ts.map +1 -0
- package/dist/monitoring/QuotaTracker.js +239 -0
- package/dist/monitoring/QuotaTracker.js.map +1 -0
- package/dist/monitoring/ReflectionMetrics.d.ts +97 -0
- package/dist/monitoring/ReflectionMetrics.d.ts.map +1 -0
- package/dist/monitoring/ReflectionMetrics.js +170 -0
- package/dist/monitoring/ReflectionMetrics.js.map +1 -0
- package/dist/monitoring/SessionActivitySentinel.d.ts +95 -0
- package/dist/monitoring/SessionActivitySentinel.d.ts.map +1 -0
- package/dist/monitoring/SessionActivitySentinel.js +391 -0
- package/dist/monitoring/SessionActivitySentinel.js.map +1 -0
- package/dist/monitoring/SessionCredentialManager.d.ts +56 -0
- package/dist/monitoring/SessionCredentialManager.d.ts.map +1 -0
- package/dist/monitoring/SessionCredentialManager.js +91 -0
- package/dist/monitoring/SessionCredentialManager.js.map +1 -0
- package/dist/monitoring/SessionMigrator.d.ts +234 -0
- package/dist/monitoring/SessionMigrator.d.ts.map +1 -0
- package/dist/monitoring/SessionMigrator.js +604 -0
- package/dist/monitoring/SessionMigrator.js.map +1 -0
- package/dist/monitoring/SessionMonitor.d.ts +102 -0
- package/dist/monitoring/SessionMonitor.d.ts.map +1 -0
- package/dist/monitoring/SessionMonitor.js +238 -0
- package/dist/monitoring/SessionMonitor.js.map +1 -0
- package/dist/monitoring/SessionRecovery.d.ts +129 -0
- package/dist/monitoring/SessionRecovery.d.ts.map +1 -0
- package/dist/monitoring/SessionRecovery.js +496 -0
- package/dist/monitoring/SessionRecovery.js.map +1 -0
- package/dist/monitoring/SessionWatchdog.d.ts +138 -0
- package/dist/monitoring/SessionWatchdog.d.ts.map +1 -0
- package/dist/monitoring/SessionWatchdog.js +549 -0
- package/dist/monitoring/SessionWatchdog.js.map +1 -0
- package/dist/monitoring/StallTriageNurse.d.ts +96 -0
- package/dist/monitoring/StallTriageNurse.d.ts.map +1 -0
- package/dist/monitoring/StallTriageNurse.js +711 -0
- package/dist/monitoring/StallTriageNurse.js.map +1 -0
- package/dist/monitoring/StallTriageNurse.types.d.ts +124 -0
- package/dist/monitoring/StallTriageNurse.types.d.ts.map +1 -0
- package/dist/monitoring/StallTriageNurse.types.js +5 -0
- package/dist/monitoring/StallTriageNurse.types.js.map +1 -0
- package/dist/monitoring/SubagentTracker.d.ts +86 -0
- package/dist/monitoring/SubagentTracker.d.ts.map +1 -0
- package/dist/monitoring/SubagentTracker.js +199 -0
- package/dist/monitoring/SubagentTracker.js.map +1 -0
- package/dist/monitoring/SystemReviewer.d.ts +243 -0
- package/dist/monitoring/SystemReviewer.d.ts.map +1 -0
- package/dist/monitoring/SystemReviewer.js +697 -0
- package/dist/monitoring/SystemReviewer.js.map +1 -0
- package/dist/monitoring/TelemetryAuth.d.ts +64 -0
- package/dist/monitoring/TelemetryAuth.d.ts.map +1 -0
- package/dist/monitoring/TelemetryAuth.js +141 -0
- package/dist/monitoring/TelemetryAuth.js.map +1 -0
- package/dist/monitoring/TelemetryCollector.d.ts +95 -0
- package/dist/monitoring/TelemetryCollector.d.ts.map +1 -0
- package/dist/monitoring/TelemetryCollector.js +326 -0
- package/dist/monitoring/TelemetryCollector.js.map +1 -0
- package/dist/monitoring/TelemetryHeartbeat.d.ts +160 -0
- package/dist/monitoring/TelemetryHeartbeat.d.ts.map +1 -0
- package/dist/monitoring/TelemetryHeartbeat.js +450 -0
- package/dist/monitoring/TelemetryHeartbeat.js.map +1 -0
- package/dist/monitoring/TriageOrchestrator.d.ts +217 -0
- package/dist/monitoring/TriageOrchestrator.d.ts.map +1 -0
- package/dist/monitoring/TriageOrchestrator.js +801 -0
- package/dist/monitoring/TriageOrchestrator.js.map +1 -0
- package/dist/monitoring/WorktreeMonitor.d.ts +124 -0
- package/dist/monitoring/WorktreeMonitor.d.ts.map +1 -0
- package/dist/monitoring/WorktreeMonitor.js +379 -0
- package/dist/monitoring/WorktreeMonitor.js.map +1 -0
- package/dist/monitoring/crash-detector.d.ts +50 -0
- package/dist/monitoring/crash-detector.d.ts.map +1 -0
- package/dist/monitoring/crash-detector.js +224 -0
- package/dist/monitoring/crash-detector.js.map +1 -0
- package/dist/monitoring/jsonl-truncator.d.ts +44 -0
- package/dist/monitoring/jsonl-truncator.d.ts.map +1 -0
- package/dist/monitoring/jsonl-truncator.js +224 -0
- package/dist/monitoring/jsonl-truncator.js.map +1 -0
- package/dist/monitoring/probes/LifelineProbe.d.ts +38 -0
- package/dist/monitoring/probes/LifelineProbe.d.ts.map +1 -0
- package/dist/monitoring/probes/LifelineProbe.js +285 -0
- package/dist/monitoring/probes/LifelineProbe.js.map +1 -0
- package/dist/monitoring/probes/MessagingProbe.d.ts +23 -0
- package/dist/monitoring/probes/MessagingProbe.d.ts.map +1 -0
- package/dist/monitoring/probes/MessagingProbe.js +214 -0
- package/dist/monitoring/probes/MessagingProbe.js.map +1 -0
- package/dist/monitoring/probes/PlatformProbe.d.ts +15 -0
- package/dist/monitoring/probes/PlatformProbe.d.ts.map +1 -0
- package/dist/monitoring/probes/PlatformProbe.js +222 -0
- package/dist/monitoring/probes/PlatformProbe.js.map +1 -0
- package/dist/monitoring/probes/SchedulerProbe.d.ts +33 -0
- package/dist/monitoring/probes/SchedulerProbe.d.ts.map +1 -0
- package/dist/monitoring/probes/SchedulerProbe.js +196 -0
- package/dist/monitoring/probes/SchedulerProbe.js.map +1 -0
- package/dist/monitoring/probes/SessionProbe.d.ts +28 -0
- package/dist/monitoring/probes/SessionProbe.d.ts.map +1 -0
- package/dist/monitoring/probes/SessionProbe.js +234 -0
- package/dist/monitoring/probes/SessionProbe.js.map +1 -0
- package/dist/monitoring/stall-detector.d.ts +34 -0
- package/dist/monitoring/stall-detector.d.ts.map +1 -0
- package/dist/monitoring/stall-detector.js +151 -0
- package/dist/monitoring/stall-detector.js.map +1 -0
- package/dist/paste/PasteManager.d.ts +154 -0
- package/dist/paste/PasteManager.d.ts.map +1 -0
- package/dist/paste/PasteManager.js +524 -0
- package/dist/paste/PasteManager.js.map +1 -0
- package/dist/paste/TruncationDetector.d.ts +51 -0
- package/dist/paste/TruncationDetector.d.ts.map +1 -0
- package/dist/paste/TruncationDetector.js +220 -0
- package/dist/paste/TruncationDetector.js.map +1 -0
- package/dist/privacy/OutputPrivacyRouter.d.ts +65 -0
- package/dist/privacy/OutputPrivacyRouter.d.ts.map +1 -0
- package/dist/privacy/OutputPrivacyRouter.js +156 -0
- package/dist/privacy/OutputPrivacyRouter.js.map +1 -0
- package/dist/publishing/PrivateViewer.d.ts +63 -0
- package/dist/publishing/PrivateViewer.d.ts.map +1 -0
- package/dist/publishing/PrivateViewer.js +398 -0
- package/dist/publishing/PrivateViewer.js.map +1 -0
- package/dist/publishing/TelegraphService.d.ts +137 -0
- package/dist/publishing/TelegraphService.d.ts.map +1 -0
- package/dist/publishing/TelegraphService.js +410 -0
- package/dist/publishing/TelegraphService.js.map +1 -0
- package/dist/scaffold/bootstrap.d.ts +21 -0
- package/dist/scaffold/bootstrap.d.ts.map +1 -0
- package/dist/scaffold/bootstrap.js +125 -0
- package/dist/scaffold/bootstrap.js.map +1 -0
- package/dist/scaffold/templates.d.ts +47 -0
- package/dist/scaffold/templates.d.ts.map +1 -0
- package/dist/scaffold/templates.js +1506 -0
- package/dist/scaffold/templates.js.map +1 -0
- package/dist/scheduler/IntegrationGate.d.ts +81 -0
- package/dist/scheduler/IntegrationGate.d.ts.map +1 -0
- package/dist/scheduler/IntegrationGate.js +242 -0
- package/dist/scheduler/IntegrationGate.js.map +1 -0
- package/dist/scheduler/JobClaimManager.d.ts +137 -0
- package/dist/scheduler/JobClaimManager.d.ts.map +1 -0
- package/dist/scheduler/JobClaimManager.js +283 -0
- package/dist/scheduler/JobClaimManager.js.map +1 -0
- package/dist/scheduler/JobLoader.d.ts +28 -0
- package/dist/scheduler/JobLoader.d.ts.map +1 -0
- package/dist/scheduler/JobLoader.js +269 -0
- package/dist/scheduler/JobLoader.js.map +1 -0
- package/dist/scheduler/JobRunHistory.d.ts +180 -0
- package/dist/scheduler/JobRunHistory.d.ts.map +1 -0
- package/dist/scheduler/JobRunHistory.js +349 -0
- package/dist/scheduler/JobRunHistory.js.map +1 -0
- package/dist/scheduler/JobScheduler.d.ts +244 -0
- package/dist/scheduler/JobScheduler.d.ts.map +1 -0
- package/dist/scheduler/JobScheduler.js +1085 -0
- package/dist/scheduler/JobScheduler.js.map +1 -0
- package/dist/scheduler/SkipLedger.d.ts +65 -0
- package/dist/scheduler/SkipLedger.d.ts.map +1 -0
- package/dist/scheduler/SkipLedger.js +179 -0
- package/dist/scheduler/SkipLedger.js.map +1 -0
- package/dist/security/LLMSanitizer.d.ts +65 -0
- package/dist/security/LLMSanitizer.d.ts.map +1 -0
- package/dist/security/LLMSanitizer.js +153 -0
- package/dist/security/LLMSanitizer.js.map +1 -0
- package/dist/security/ManifestIntegrity.d.ts +72 -0
- package/dist/security/ManifestIntegrity.d.ts.map +1 -0
- package/dist/security/ManifestIntegrity.js +159 -0
- package/dist/security/ManifestIntegrity.js.map +1 -0
- package/dist/server/AgentServer.d.ts +134 -0
- package/dist/server/AgentServer.d.ts.map +1 -0
- package/dist/server/AgentServer.js +307 -0
- package/dist/server/AgentServer.js.map +1 -0
- package/dist/server/SecretDrop.d.ts +133 -0
- package/dist/server/SecretDrop.d.ts.map +1 -0
- package/dist/server/SecretDrop.js +473 -0
- package/dist/server/SecretDrop.js.map +1 -0
- package/dist/server/WebSocketManager.d.ts +80 -0
- package/dist/server/WebSocketManager.d.ts.map +1 -0
- package/dist/server/WebSocketManager.js +367 -0
- package/dist/server/WebSocketManager.js.map +1 -0
- package/dist/server/fileRoutes.d.ts +19 -0
- package/dist/server/fileRoutes.d.ts.map +1 -0
- package/dist/server/fileRoutes.js +578 -0
- package/dist/server/fileRoutes.js.map +1 -0
- package/dist/server/machineAuth.d.ts +87 -0
- package/dist/server/machineAuth.d.ts.map +1 -0
- package/dist/server/machineAuth.js +188 -0
- package/dist/server/machineAuth.js.map +1 -0
- package/dist/server/machineRoutes.d.ts +49 -0
- package/dist/server/machineRoutes.d.ts.map +1 -0
- package/dist/server/machineRoutes.js +305 -0
- package/dist/server/machineRoutes.js.map +1 -0
- package/dist/server/middleware.d.ts +32 -0
- package/dist/server/middleware.d.ts.map +1 -0
- package/dist/server/middleware.js +202 -0
- package/dist/server/middleware.js.map +1 -0
- package/dist/server/routes.d.ts +132 -0
- package/dist/server/routes.d.ts.map +1 -0
- package/dist/server/routes.js +8124 -0
- package/dist/server/routes.js.map +1 -0
- package/dist/threadline/A2AGateway.d.ts +184 -0
- package/dist/threadline/A2AGateway.d.ts.map +1 -0
- package/dist/threadline/A2AGateway.js +438 -0
- package/dist/threadline/A2AGateway.js.map +1 -0
- package/dist/threadline/AgentCard.d.ts +116 -0
- package/dist/threadline/AgentCard.d.ts.map +1 -0
- package/dist/threadline/AgentCard.js +212 -0
- package/dist/threadline/AgentCard.js.map +1 -0
- package/dist/threadline/AgentDiscovery.d.ts +156 -0
- package/dist/threadline/AgentDiscovery.d.ts.map +1 -0
- package/dist/threadline/AgentDiscovery.js +390 -0
- package/dist/threadline/AgentDiscovery.js.map +1 -0
- package/dist/threadline/AgentTrustManager.d.ts +190 -0
- package/dist/threadline/AgentTrustManager.d.ts.map +1 -0
- package/dist/threadline/AgentTrustManager.js +526 -0
- package/dist/threadline/AgentTrustManager.js.map +1 -0
- package/dist/threadline/ApprovalQueue.d.ts +71 -0
- package/dist/threadline/ApprovalQueue.d.ts.map +1 -0
- package/dist/threadline/ApprovalQueue.js +154 -0
- package/dist/threadline/ApprovalQueue.js.map +1 -0
- package/dist/threadline/AutonomyGate.d.ts +130 -0
- package/dist/threadline/AutonomyGate.d.ts.map +1 -0
- package/dist/threadline/AutonomyGate.js +267 -0
- package/dist/threadline/AutonomyGate.js.map +1 -0
- package/dist/threadline/CircuitBreaker.d.ts +89 -0
- package/dist/threadline/CircuitBreaker.d.ts.map +1 -0
- package/dist/threadline/CircuitBreaker.js +238 -0
- package/dist/threadline/CircuitBreaker.js.map +1 -0
- package/dist/threadline/ComputeMeter.d.ts +114 -0
- package/dist/threadline/ComputeMeter.d.ts.map +1 -0
- package/dist/threadline/ComputeMeter.js +350 -0
- package/dist/threadline/ComputeMeter.js.map +1 -0
- package/dist/threadline/ContentClassifier.d.ts +83 -0
- package/dist/threadline/ContentClassifier.d.ts.map +1 -0
- package/dist/threadline/ContentClassifier.js +201 -0
- package/dist/threadline/ContentClassifier.js.map +1 -0
- package/dist/threadline/ContextThreadMap.d.ts +103 -0
- package/dist/threadline/ContextThreadMap.d.ts.map +1 -0
- package/dist/threadline/ContextThreadMap.js +279 -0
- package/dist/threadline/ContextThreadMap.js.map +1 -0
- package/dist/threadline/DNSVerifier.d.ts +48 -0
- package/dist/threadline/DNSVerifier.d.ts.map +1 -0
- package/dist/threadline/DNSVerifier.js +138 -0
- package/dist/threadline/DNSVerifier.js.map +1 -0
- package/dist/threadline/DigestCollector.d.ts +70 -0
- package/dist/threadline/DigestCollector.d.ts.map +1 -0
- package/dist/threadline/DigestCollector.js +146 -0
- package/dist/threadline/DigestCollector.js.map +1 -0
- package/dist/threadline/HandshakeManager.d.ts +130 -0
- package/dist/threadline/HandshakeManager.d.ts.map +1 -0
- package/dist/threadline/HandshakeManager.js +402 -0
- package/dist/threadline/HandshakeManager.js.map +1 -0
- package/dist/threadline/InboundMessageGate.d.ts +80 -0
- package/dist/threadline/InboundMessageGate.d.ts.map +1 -0
- package/dist/threadline/InboundMessageGate.js +241 -0
- package/dist/threadline/InboundMessageGate.js.map +1 -0
- package/dist/threadline/InvitationManager.d.ts +91 -0
- package/dist/threadline/InvitationManager.d.ts.map +1 -0
- package/dist/threadline/InvitationManager.js +228 -0
- package/dist/threadline/InvitationManager.js.map +1 -0
- package/dist/threadline/ListenerSessionManager.d.ts +147 -0
- package/dist/threadline/ListenerSessionManager.d.ts.map +1 -0
- package/dist/threadline/ListenerSessionManager.js +326 -0
- package/dist/threadline/ListenerSessionManager.js.map +1 -0
- package/dist/threadline/MCPAuth.d.ts +98 -0
- package/dist/threadline/MCPAuth.d.ts.map +1 -0
- package/dist/threadline/MCPAuth.js +228 -0
- package/dist/threadline/MCPAuth.js.map +1 -0
- package/dist/threadline/OpenClawBridge.d.ts +143 -0
- package/dist/threadline/OpenClawBridge.d.ts.map +1 -0
- package/dist/threadline/OpenClawBridge.js +336 -0
- package/dist/threadline/OpenClawBridge.js.map +1 -0
- package/dist/threadline/OpenClawSkillManifest.d.ts +47 -0
- package/dist/threadline/OpenClawSkillManifest.d.ts.map +1 -0
- package/dist/threadline/OpenClawSkillManifest.js +148 -0
- package/dist/threadline/OpenClawSkillManifest.js.map +1 -0
- package/dist/threadline/RateLimiter.d.ts +105 -0
- package/dist/threadline/RateLimiter.d.ts.map +1 -0
- package/dist/threadline/RateLimiter.js +236 -0
- package/dist/threadline/RateLimiter.js.map +1 -0
- package/dist/threadline/RelayGroundingPreamble.d.ts +48 -0
- package/dist/threadline/RelayGroundingPreamble.d.ts.map +1 -0
- package/dist/threadline/RelayGroundingPreamble.js +68 -0
- package/dist/threadline/RelayGroundingPreamble.js.map +1 -0
- package/dist/threadline/SessionLifecycle.d.ts +136 -0
- package/dist/threadline/SessionLifecycle.d.ts.map +1 -0
- package/dist/threadline/SessionLifecycle.js +317 -0
- package/dist/threadline/SessionLifecycle.js.map +1 -0
- package/dist/threadline/ThreadResumeMap.d.ts +128 -0
- package/dist/threadline/ThreadResumeMap.d.ts.map +1 -0
- package/dist/threadline/ThreadResumeMap.js +324 -0
- package/dist/threadline/ThreadResumeMap.js.map +1 -0
- package/dist/threadline/ThreadlineBootstrap.d.ts +68 -0
- package/dist/threadline/ThreadlineBootstrap.d.ts.map +1 -0
- package/dist/threadline/ThreadlineBootstrap.js +293 -0
- package/dist/threadline/ThreadlineBootstrap.js.map +1 -0
- package/dist/threadline/ThreadlineCrypto.d.ts +53 -0
- package/dist/threadline/ThreadlineCrypto.d.ts.map +1 -0
- package/dist/threadline/ThreadlineCrypto.js +123 -0
- package/dist/threadline/ThreadlineCrypto.js.map +1 -0
- package/dist/threadline/ThreadlineEndpoints.d.ts +35 -0
- package/dist/threadline/ThreadlineEndpoints.d.ts.map +1 -0
- package/dist/threadline/ThreadlineEndpoints.js +313 -0
- package/dist/threadline/ThreadlineEndpoints.js.map +1 -0
- package/dist/threadline/ThreadlineMCPServer.d.ts +165 -0
- package/dist/threadline/ThreadlineMCPServer.d.ts.map +1 -0
- package/dist/threadline/ThreadlineMCPServer.js +885 -0
- package/dist/threadline/ThreadlineMCPServer.js.map +1 -0
- package/dist/threadline/ThreadlineRouter.d.ts +105 -0
- package/dist/threadline/ThreadlineRouter.d.ts.map +1 -0
- package/dist/threadline/ThreadlineRouter.js +323 -0
- package/dist/threadline/ThreadlineRouter.js.map +1 -0
- package/dist/threadline/TrustBootstrap.d.ts +92 -0
- package/dist/threadline/TrustBootstrap.d.ts.map +1 -0
- package/dist/threadline/TrustBootstrap.js +256 -0
- package/dist/threadline/TrustBootstrap.js.map +1 -0
- package/dist/threadline/adapters/AutoGenTool.d.ts +42 -0
- package/dist/threadline/adapters/AutoGenTool.d.ts.map +1 -0
- package/dist/threadline/adapters/AutoGenTool.js +145 -0
- package/dist/threadline/adapters/AutoGenTool.js.map +1 -0
- package/dist/threadline/adapters/CrewAITool.d.ts +31 -0
- package/dist/threadline/adapters/CrewAITool.d.ts.map +1 -0
- package/dist/threadline/adapters/CrewAITool.js +112 -0
- package/dist/threadline/adapters/CrewAITool.js.map +1 -0
- package/dist/threadline/adapters/LangGraphTool.d.ts +48 -0
- package/dist/threadline/adapters/LangGraphTool.d.ts.map +1 -0
- package/dist/threadline/adapters/LangGraphTool.js +153 -0
- package/dist/threadline/adapters/LangGraphTool.js.map +1 -0
- package/dist/threadline/adapters/RESTServer.d.ts +74 -0
- package/dist/threadline/adapters/RESTServer.d.ts.map +1 -0
- package/dist/threadline/adapters/RESTServer.js +291 -0
- package/dist/threadline/adapters/RESTServer.js.map +1 -0
- package/dist/threadline/adapters/index.d.ts +14 -0
- package/dist/threadline/adapters/index.d.ts.map +1 -0
- package/dist/threadline/adapters/index.js +10 -0
- package/dist/threadline/adapters/index.js.map +1 -0
- package/dist/threadline/client/IdentityManager.d.ts +40 -0
- package/dist/threadline/client/IdentityManager.d.ts.map +1 -0
- package/dist/threadline/client/IdentityManager.js +106 -0
- package/dist/threadline/client/IdentityManager.js.map +1 -0
- package/dist/threadline/client/MessageEncryptor.d.ts +63 -0
- package/dist/threadline/client/MessageEncryptor.d.ts.map +1 -0
- package/dist/threadline/client/MessageEncryptor.js +195 -0
- package/dist/threadline/client/MessageEncryptor.js.map +1 -0
- package/dist/threadline/client/RegistryRestClient.d.ts +46 -0
- package/dist/threadline/client/RegistryRestClient.d.ts.map +1 -0
- package/dist/threadline/client/RegistryRestClient.js +114 -0
- package/dist/threadline/client/RegistryRestClient.js.map +1 -0
- package/dist/threadline/client/RelayClient.d.ts +77 -0
- package/dist/threadline/client/RelayClient.d.ts.map +1 -0
- package/dist/threadline/client/RelayClient.js +249 -0
- package/dist/threadline/client/RelayClient.js.map +1 -0
- package/dist/threadline/client/ThreadlineClient.d.ts +117 -0
- package/dist/threadline/client/ThreadlineClient.d.ts.map +1 -0
- package/dist/threadline/client/ThreadlineClient.js +286 -0
- package/dist/threadline/client/ThreadlineClient.js.map +1 -0
- package/dist/threadline/client/index.d.ts +14 -0
- package/dist/threadline/client/index.d.ts.map +1 -0
- package/dist/threadline/client/index.js +9 -0
- package/dist/threadline/client/index.js.map +1 -0
- package/dist/threadline/index.d.ts +81 -0
- package/dist/threadline/index.d.ts.map +1 -0
- package/dist/threadline/index.js +57 -0
- package/dist/threadline/index.js.map +1 -0
- package/dist/threadline/mcp-stdio-entry.d.ts +24 -0
- package/dist/threadline/mcp-stdio-entry.d.ts.map +1 -0
- package/dist/threadline/mcp-stdio-entry.js +230 -0
- package/dist/threadline/mcp-stdio-entry.js.map +1 -0
- package/dist/threadline/relay/A2ABridge.d.ts +91 -0
- package/dist/threadline/relay/A2ABridge.d.ts.map +1 -0
- package/dist/threadline/relay/A2ABridge.js +457 -0
- package/dist/threadline/relay/A2ABridge.js.map +1 -0
- package/dist/threadline/relay/AbuseDetector.d.ts +131 -0
- package/dist/threadline/relay/AbuseDetector.d.ts.map +1 -0
- package/dist/threadline/relay/AbuseDetector.js +358 -0
- package/dist/threadline/relay/AbuseDetector.js.map +1 -0
- package/dist/threadline/relay/AdminServer.d.ts +55 -0
- package/dist/threadline/relay/AdminServer.d.ts.map +1 -0
- package/dist/threadline/relay/AdminServer.js +215 -0
- package/dist/threadline/relay/AdminServer.js.map +1 -0
- package/dist/threadline/relay/ConnectionManager.d.ts +86 -0
- package/dist/threadline/relay/ConnectionManager.d.ts.map +1 -0
- package/dist/threadline/relay/ConnectionManager.js +356 -0
- package/dist/threadline/relay/ConnectionManager.js.map +1 -0
- package/dist/threadline/relay/MessageRouter.d.ts +46 -0
- package/dist/threadline/relay/MessageRouter.d.ts.map +1 -0
- package/dist/threadline/relay/MessageRouter.js +138 -0
- package/dist/threadline/relay/MessageRouter.js.map +1 -0
- package/dist/threadline/relay/OfflineQueue.d.ts +87 -0
- package/dist/threadline/relay/OfflineQueue.d.ts.map +1 -0
- package/dist/threadline/relay/OfflineQueue.js +137 -0
- package/dist/threadline/relay/OfflineQueue.js.map +1 -0
- package/dist/threadline/relay/PresenceRegistry.d.ts +62 -0
- package/dist/threadline/relay/PresenceRegistry.d.ts.map +1 -0
- package/dist/threadline/relay/PresenceRegistry.js +148 -0
- package/dist/threadline/relay/PresenceRegistry.js.map +1 -0
- package/dist/threadline/relay/RegistryAuth.d.ts +45 -0
- package/dist/threadline/relay/RegistryAuth.d.ts.map +1 -0
- package/dist/threadline/relay/RegistryAuth.js +118 -0
- package/dist/threadline/relay/RegistryAuth.js.map +1 -0
- package/dist/threadline/relay/RegistryStore.d.ts +149 -0
- package/dist/threadline/relay/RegistryStore.d.ts.map +1 -0
- package/dist/threadline/relay/RegistryStore.js +542 -0
- package/dist/threadline/relay/RegistryStore.js.map +1 -0
- package/dist/threadline/relay/RelayMetrics.d.ts +62 -0
- package/dist/threadline/relay/RelayMetrics.d.ts.map +1 -0
- package/dist/threadline/relay/RelayMetrics.js +149 -0
- package/dist/threadline/relay/RelayMetrics.js.map +1 -0
- package/dist/threadline/relay/RelayRateLimiter.d.ts +58 -0
- package/dist/threadline/relay/RelayRateLimiter.d.ts.map +1 -0
- package/dist/threadline/relay/RelayRateLimiter.js +116 -0
- package/dist/threadline/relay/RelayRateLimiter.js.map +1 -0
- package/dist/threadline/relay/RelayServer.d.ts +94 -0
- package/dist/threadline/relay/RelayServer.d.ts.map +1 -0
- package/dist/threadline/relay/RelayServer.js +1049 -0
- package/dist/threadline/relay/RelayServer.js.map +1 -0
- package/dist/threadline/relay/index.d.ts +28 -0
- package/dist/threadline/relay/index.d.ts.map +1 -0
- package/dist/threadline/relay/index.js +17 -0
- package/dist/threadline/relay/index.js.map +1 -0
- package/dist/threadline/relay/types.d.ts +215 -0
- package/dist/threadline/relay/types.d.ts.map +1 -0
- package/dist/threadline/relay/types.js +21 -0
- package/dist/threadline/relay/types.js.map +1 -0
- package/dist/threadline/types.d.ts +39 -0
- package/dist/threadline/types.d.ts.map +1 -0
- package/dist/threadline/types.js +10 -0
- package/dist/threadline/types.js.map +1 -0
- package/dist/tunnel/TunnelManager.d.ts +113 -0
- package/dist/tunnel/TunnelManager.d.ts.map +1 -0
- package/dist/tunnel/TunnelManager.js +474 -0
- package/dist/tunnel/TunnelManager.js.map +1 -0
- package/dist/types/pipeline.d.ts +203 -0
- package/dist/types/pipeline.d.ts.map +1 -0
- package/dist/types/pipeline.js +152 -0
- package/dist/types/pipeline.js.map +1 -0
- package/dist/users/GdprCommands.d.ts +44 -0
- package/dist/users/GdprCommands.d.ts.map +1 -0
- package/dist/users/GdprCommands.js +153 -0
- package/dist/users/GdprCommands.js.map +1 -0
- package/dist/users/OnboardingGate.d.ts +107 -0
- package/dist/users/OnboardingGate.d.ts.map +1 -0
- package/dist/users/OnboardingGate.js +240 -0
- package/dist/users/OnboardingGate.js.map +1 -0
- package/dist/users/UserContextBuilder.d.ts +47 -0
- package/dist/users/UserContextBuilder.d.ts.map +1 -0
- package/dist/users/UserContextBuilder.js +174 -0
- package/dist/users/UserContextBuilder.js.map +1 -0
- package/dist/users/UserManager.d.ts +76 -0
- package/dist/users/UserManager.d.ts.map +1 -0
- package/dist/users/UserManager.js +213 -0
- package/dist/users/UserManager.js.map +1 -0
- package/dist/users/UserOnboarding.d.ts +145 -0
- package/dist/users/UserOnboarding.d.ts.map +1 -0
- package/dist/users/UserOnboarding.js +488 -0
- package/dist/users/UserOnboarding.js.map +1 -0
- package/dist/users/UserPropagator.d.ts +75 -0
- package/dist/users/UserPropagator.d.ts.map +1 -0
- package/dist/users/UserPropagator.js +145 -0
- package/dist/users/UserPropagator.js.map +1 -0
- package/dist/utils/jsonl-rotation.d.ts +27 -0
- package/dist/utils/jsonl-rotation.d.ts.map +1 -0
- package/dist/utils/jsonl-rotation.js +63 -0
- package/dist/utils/jsonl-rotation.js.map +1 -0
- package/dist/utils/privacy.d.ts +88 -0
- package/dist/utils/privacy.d.ts.map +1 -0
- package/dist/utils/privacy.js +182 -0
- package/dist/utils/privacy.js.map +1 -0
- package/dist/utils/sanitize.d.ts +81 -0
- package/dist/utils/sanitize.d.ts.map +1 -0
- package/dist/utils/sanitize.js +122 -0
- package/dist/utils/sanitize.js.map +1 -0
- package/package.json +1 -0
- package/playbook-scripts/atomic_write.py +133 -0
- package/playbook-scripts/bootstrap-manifest.json +92 -0
- package/playbook-scripts/playbook-annotate-context.py +239 -0
- package/playbook-scripts/playbook-assemble.py +385 -0
- package/playbook-scripts/playbook-dashboard.py +242 -0
- package/playbook-scripts/playbook-decay.py +377 -0
- package/playbook-scripts/playbook-dedup-job.py +252 -0
- package/playbook-scripts/playbook-dedup.py +341 -0
- package/playbook-scripts/playbook-delta-validator.py +576 -0
- package/playbook-scripts/playbook-dsar.py +291 -0
- package/playbook-scripts/playbook-eval-log.py +425 -0
- package/playbook-scripts/playbook-failsafe.py +513 -0
- package/playbook-scripts/playbook-feedback-quarantine.py +335 -0
- package/playbook-scripts/playbook-history.py +293 -0
- package/playbook-scripts/playbook-hmac.py +224 -0
- package/playbook-scripts/playbook-lifecycle.py +952 -0
- package/playbook-scripts/playbook-manifest.py +458 -0
- package/playbook-scripts/playbook-micro-eval.py +316 -0
- package/playbook-scripts/playbook-migrate-lessons.py +396 -0
- package/playbook-scripts/playbook-mount.py +393 -0
- package/playbook-scripts/playbook-offline-adapt.py +323 -0
- package/playbook-scripts/playbook-pii-screen.py +207 -0
- package/playbook-scripts/playbook-reflector.py +266 -0
- package/playbook-scripts/playbook-relevance.py +269 -0
- package/playbook-scripts/playbook-retirement.py +365 -0
- package/playbook-scripts/playbook-schema-validate.py +267 -0
- package/playbook-scripts/playbook-scratchpad.py +346 -0
- package/playbook-scripts/playbook-semantic-verify.py +280 -0
- package/playbook-scripts/playbook-spawn-contract.py +341 -0
- package/playbook-scripts/playbook-token-reestimate.py +248 -0
- package/playbook-scripts/playbook-verify.py +357 -0
- package/playbook-scripts/playbook_backend.py +249 -0
- package/playbook-scripts/playbook_paths.py +232 -0
- package/playbook-scripts/schemas/context-delta.schema.json +137 -0
- package/playbook-scripts/schemas/context-manifest.schema.json +200 -0
- package/playbook-scripts/schemas/playbook-config.schema.json +184 -0
- package/scripts/analyze-release.js +752 -0
- package/scripts/check-upgrade-guide.js +373 -0
- package/scripts/collect-metrics.py +248 -0
- package/scripts/demo-two-agents.mjs +187 -0
- package/scripts/fix-better-sqlite3.cjs +100 -0
- package/scripts/generate-builtin-manifest.cjs +440 -0
- package/scripts/pre-push-gate.js +177 -0
- package/scripts/relay-entrypoint.mjs +18 -0
- package/scripts/seed-registry.mjs +258 -0
- package/scripts/telemetry-worker/worker.js +776 -0
- package/scripts/telemetry-worker/wrangler.toml +7 -0
- package/scripts/test-bootstrap-relay.mjs +90 -0
- package/scripts/test-multi-agent-relay.mjs +395 -0
- package/scripts/test-relay-cloud.mjs +389 -0
- package/scripts/test-relay-live.mjs +550 -0
- package/src/data/builtin-manifest.json +1463 -0
- package/src/data/http-hook-templates.ts +81 -0
- package/src/templates/hooks/compaction-recovery.sh +371 -0
- package/src/templates/hooks/dangerous-command-guard.sh +100 -0
- package/src/templates/hooks/free-text-guard.sh +96 -0
- package/src/templates/hooks/grounding-before-messaging.sh +52 -0
- package/src/templates/hooks/session-start.sh +339 -0
- package/src/templates/hooks/settings-template.json +142 -0
- package/src/templates/hooks/slack-channel-context.sh +98 -0
- package/src/templates/hooks/telegram-topic-context.sh +117 -0
- package/src/templates/scripts/convergence-check.sh +99 -0
- package/src/templates/scripts/git-sync-gate.sh +89 -0
- package/src/templates/scripts/health-watchdog.sh +63 -0
- package/src/templates/scripts/serendipity-capture.sh +345 -0
- package/src/templates/scripts/slack-reply.sh +74 -0
- package/src/templates/scripts/smart-fetch.py +215 -0
- package/src/templates/scripts/telegram-reply.sh +67 -0
- package/src/templates/scripts/whatsapp-reply.sh +68 -0
- package/upgrades/0.10.0.md +254 -0
- package/upgrades/0.10.1.md +47 -0
- package/upgrades/0.10.2.md +26 -0
- package/upgrades/0.10.3.md +23 -0
- package/upgrades/0.10.4.md +26 -0
- package/upgrades/0.10.5.md +19 -0
- package/upgrades/0.10.6.md +35 -0
- package/upgrades/0.10.7.md +48 -0
- package/upgrades/0.10.8.md +53 -0
- package/upgrades/0.10.9.md +21 -0
- package/upgrades/0.11.0.md +146 -0
- package/upgrades/0.12.0.md +31 -0
- package/upgrades/0.12.1.md +21 -0
- package/upgrades/0.12.10.md +26 -0
- package/upgrades/0.12.11.md +23 -0
- package/upgrades/0.12.12.md +23 -0
- package/upgrades/0.12.13.md +19 -0
- package/upgrades/0.12.14.md +21 -0
- package/upgrades/0.12.15.md +26 -0
- package/upgrades/0.12.16.md +33 -0
- package/upgrades/0.12.17.md +38 -0
- package/upgrades/0.12.18.md +27 -0
- package/upgrades/0.12.19.md +31 -0
- package/upgrades/0.12.2.md +27 -0
- package/upgrades/0.12.20.md +24 -0
- package/upgrades/0.12.21.md +28 -0
- package/upgrades/0.12.22.md +23 -0
- package/upgrades/0.12.23.md +44 -0
- package/upgrades/0.12.24.md +24 -0
- package/upgrades/0.12.25.md +55 -0
- package/upgrades/0.12.26.md +31 -0
- package/upgrades/0.12.27.md +19 -0
- package/upgrades/0.12.28.md +19 -0
- package/upgrades/0.12.29.md +42 -0
- package/upgrades/0.12.3.md +22 -0
- package/upgrades/0.12.31.md +24 -0
- package/upgrades/0.12.32.md +34 -0
- package/upgrades/0.12.33.md +62 -0
- package/upgrades/0.12.34.md +59 -0
- package/upgrades/0.12.4.md +19 -0
- package/upgrades/0.12.5.md +31 -0
- package/upgrades/0.12.6.md +34 -0
- package/upgrades/0.12.7.md +24 -0
- package/upgrades/0.12.8.md +28 -0
- package/upgrades/0.12.9.md +30 -0
- package/upgrades/0.13.0.md +26 -0
- package/upgrades/0.14.0.md +75 -0
- package/upgrades/0.14.1.md +41 -0
- package/upgrades/0.15.0.md +59 -0
- package/upgrades/0.16.0.md +61 -0
- package/upgrades/0.17.0.md +88 -0
- package/upgrades/0.17.10.md +23 -0
- package/upgrades/0.17.11.md +25 -0
- package/upgrades/0.17.12.md +43 -0
- package/upgrades/0.17.13.md +24 -0
- package/upgrades/0.17.14.md +26 -0
- package/upgrades/0.17.2.md +42 -0
- package/upgrades/0.17.3.md +37 -0
- package/upgrades/0.17.4.md +27 -0
- package/upgrades/0.17.5.md +32 -0
- package/upgrades/0.17.6.md +32 -0
- package/upgrades/0.17.7.md +39 -0
- package/upgrades/0.17.8.md +34 -0
- package/upgrades/0.17.9.md +25 -0
- package/upgrades/0.18.1.md +34 -0
- package/upgrades/0.18.2.md +29 -0
- package/upgrades/0.18.3.md +26 -0
- package/upgrades/0.18.4.md +28 -0
- package/upgrades/0.18.5.md +25 -0
- package/upgrades/0.18.6.md +25 -0
- package/upgrades/0.18.7.md +30 -0
- package/upgrades/0.19.0.md +136 -0
- package/upgrades/0.19.1.md +27 -0
- package/upgrades/0.19.2.md +27 -0
- package/upgrades/0.19.3.md +32 -0
- package/upgrades/0.19.4.md +19 -0
- package/upgrades/0.19.6.md +17 -0
- package/upgrades/0.19.7.md +33 -0
- package/upgrades/0.20.0.md +54 -0
- package/upgrades/0.21.1.md +55 -0
- package/upgrades/0.21.2.md +48 -0
- package/upgrades/0.21.3.md +29 -0
- package/upgrades/0.21.4.md +33 -0
- package/upgrades/0.22.0.md +114 -0
- package/upgrades/0.23.0.md +81 -0
- package/upgrades/0.23.1.md +28 -0
- package/upgrades/0.23.10.md +19 -0
- package/upgrades/0.23.11.md +21 -0
- package/upgrades/0.23.12.md +30 -0
- package/upgrades/0.23.13.md +25 -0
- package/upgrades/0.23.14.md +23 -0
- package/upgrades/0.23.15.md +30 -0
- package/upgrades/0.23.16.md +21 -0
- package/upgrades/0.23.17.md +23 -0
- package/upgrades/0.23.18.md +41 -0
- package/upgrades/0.23.2.md +32 -0
- package/upgrades/0.23.4.md +21 -0
- package/upgrades/0.23.6.md +19 -0
- package/upgrades/0.23.7.md +33 -0
- package/upgrades/0.23.8.md +38 -0
- package/upgrades/0.23.9.md +35 -0
- package/upgrades/0.24.1.md +32 -0
- package/upgrades/0.24.10.md +23 -0
- package/upgrades/0.24.12.md +17 -0
- package/upgrades/0.24.13.md +16 -0
- package/upgrades/0.24.14.md +26 -0
- package/upgrades/0.24.15.md +49 -0
- package/upgrades/0.24.16.md +48 -0
- package/upgrades/0.24.17.md +40 -0
- package/upgrades/0.24.18-beta.0.md +35 -0
- package/upgrades/0.24.18.md +35 -0
- package/upgrades/0.24.19.md +21 -0
- package/upgrades/0.24.2.md +13 -0
- package/upgrades/0.24.20.md +45 -0
- package/upgrades/0.24.21.md +25 -0
- package/upgrades/0.24.22.md +35 -0
- package/upgrades/0.24.23.md +17 -0
- package/upgrades/0.24.24.md +15 -0
- package/upgrades/0.24.25.md +15 -0
- package/upgrades/0.24.26.md +15 -0
- package/upgrades/0.24.27.md +17 -0
- package/upgrades/0.24.28.md +35 -0
- package/upgrades/0.24.29.md +15 -0
- package/upgrades/0.24.30.md +40 -0
- package/upgrades/0.24.31.md +45 -0
- package/upgrades/0.24.32.md +19 -0
- package/upgrades/0.24.33.md +35 -0
- package/upgrades/0.24.34.md +29 -0
- package/upgrades/0.24.4.md +19 -0
- package/upgrades/0.24.5.md +20 -0
- package/upgrades/0.25.0.md +34 -0
- package/upgrades/0.25.1.md +24 -0
- package/upgrades/0.25.10.md +26 -0
- package/upgrades/0.25.2.md +23 -0
- package/upgrades/0.25.3.md +25 -0
- package/upgrades/0.25.4.md +24 -0
- package/upgrades/0.25.5.md +19 -0
- package/upgrades/0.25.6.md +35 -0
- package/upgrades/0.25.7.md +18 -0
- package/upgrades/0.25.8.md +24 -0
- package/upgrades/0.25.9.md +19 -0
- package/upgrades/0.26.0.md +23 -0
- package/upgrades/0.26.1.md +22 -0
- package/upgrades/0.26.2.md +15 -0
- package/upgrades/0.8.12.md +49 -0
- package/upgrades/0.8.13.md +38 -0
- package/upgrades/0.8.17.md +36 -0
- package/upgrades/0.8.22.md +43 -0
- package/upgrades/0.8.23.md +106 -0
- package/upgrades/0.9.1.md +91 -0
- package/upgrades/0.9.10.md +40 -0
- package/upgrades/0.9.11.md +77 -0
- package/upgrades/0.9.12.md +42 -0
- package/upgrades/0.9.13.md +55 -0
- package/upgrades/0.9.14.md +23 -0
- package/upgrades/0.9.15.md +106 -0
- package/upgrades/0.9.16.md +37 -0
- package/upgrades/0.9.17.md +15 -0
- package/upgrades/0.9.19.md +17 -0
- package/upgrades/0.9.20.md +24 -0
- package/upgrades/0.9.21.md +37 -0
- package/upgrades/0.9.22.md +41 -0
- package/upgrades/0.9.23.md +37 -0
- package/upgrades/0.9.24.md +46 -0
- package/upgrades/0.9.25.md +37 -0
- package/upgrades/0.9.28.md +20 -0
- package/upgrades/0.9.29.md +34 -0
- package/upgrades/0.9.32.md +30 -0
- package/upgrades/0.9.36.md +27 -0
- package/upgrades/0.9.8.md +125 -0
- package/upgrades/0.9.9.md +34 -0
- package/upgrades/NEXT.md +35 -0
|
@@ -0,0 +1,4211 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `instar init` — Initialize agent infrastructure.
|
|
3
|
+
*
|
|
4
|
+
* Two modes:
|
|
5
|
+
* instar init <project-name> — Create a new project from scratch
|
|
6
|
+
* instar init — Augment an existing project
|
|
7
|
+
*
|
|
8
|
+
* Fresh install creates:
|
|
9
|
+
* <project-name>/
|
|
10
|
+
* ├── CLAUDE.md — Agent instructions (standalone)
|
|
11
|
+
* ├── .instar/
|
|
12
|
+
* │ ├── AGENT.md — Agent identity
|
|
13
|
+
* │ ├── USER.md — Primary user context
|
|
14
|
+
* │ ├── MEMORY.md — Persistent memory
|
|
15
|
+
* │ ├── config.json — Agent configuration
|
|
16
|
+
* │ ├── jobs.json — Job definitions
|
|
17
|
+
* │ ├── users.json — User profiles
|
|
18
|
+
* │ ├── hooks/ — Behavioral guardrails
|
|
19
|
+
* │ ├── state/ — Runtime state
|
|
20
|
+
* │ ├── relationships/ — Relationship tracking
|
|
21
|
+
* │ └── logs/ — Server logs
|
|
22
|
+
* ├── .claude/
|
|
23
|
+
* │ ├── settings.json — Hook configuration
|
|
24
|
+
* │ └── scripts/ — Health watchdog, etc.
|
|
25
|
+
* └── .gitignore
|
|
26
|
+
*
|
|
27
|
+
* Existing project adds .instar/ and appends to CLAUDE.md.
|
|
28
|
+
*/
|
|
29
|
+
import fs from 'node:fs';
|
|
30
|
+
import os from 'node:os';
|
|
31
|
+
import path from 'node:path';
|
|
32
|
+
import pc from 'picocolors';
|
|
33
|
+
import { randomUUID } from 'node:crypto';
|
|
34
|
+
import { execFileSync, execSync } from 'node:child_process';
|
|
35
|
+
import { detectTmuxPath, detectClaudePath, detectGitPath, detectGhPath, ensureStateDir, standaloneAgentsDir, getInstarVersion } from '../core/Config.js';
|
|
36
|
+
import { ensurePrerequisites } from '../core/Prerequisites.js';
|
|
37
|
+
import { allocatePort, registerAgent, validateAgentName } from '../core/AgentRegistry.js';
|
|
38
|
+
import { defaultIdentity } from '../scaffold/bootstrap.js';
|
|
39
|
+
import { MachineIdentityManager, ensureGitignore } from '../core/MachineIdentity.js';
|
|
40
|
+
import { PostUpdateMigrator } from '../core/PostUpdateMigrator.js';
|
|
41
|
+
import { ProjectMapper } from '../core/ProjectMapper.js';
|
|
42
|
+
import { ContextHierarchy } from '../core/ContextHierarchy.js';
|
|
43
|
+
import { CanonicalState } from '../core/CanonicalState.js';
|
|
44
|
+
import { ManifestIntegrity } from '../security/ManifestIntegrity.js';
|
|
45
|
+
import { buildHttpHookSettings } from '../data/http-hook-templates.js';
|
|
46
|
+
import { generateAgentMd, generateUserMd, generateMemoryMd, generateClaudeMd, generateSoulMd, } from '../scaffold/templates.js';
|
|
47
|
+
/**
|
|
48
|
+
* Find a free port in the default range (4040-4099) by checking if anything
|
|
49
|
+
* is listening. Used as fallback when allocatePort() fails (e.g., registry
|
|
50
|
+
* is corrupted or locked).
|
|
51
|
+
*/
|
|
52
|
+
function findFreePortFallback() {
|
|
53
|
+
for (let port = 4040; port <= 4099; port++) {
|
|
54
|
+
try {
|
|
55
|
+
execSync(`lsof -iTCP:${port} -sTCP:LISTEN -P -n`, { stdio: 'ignore' });
|
|
56
|
+
// lsof found a listener — port is in use
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
// lsof found nothing — port is free
|
|
60
|
+
return port;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return 4040; // All ports in range are busy — return default and let server fail with a clear error
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Main init entry point. Handles both fresh and existing project modes.
|
|
67
|
+
*/
|
|
68
|
+
export async function initProject(options) {
|
|
69
|
+
// Standalone mode: create at ~/.instar/agents/<name>/
|
|
70
|
+
if (options.standalone) {
|
|
71
|
+
const agentName = options.name;
|
|
72
|
+
if (!agentName) {
|
|
73
|
+
console.log(pc.red(' A name is required for standalone agents.'));
|
|
74
|
+
console.log(` Usage: ${pc.cyan('instar init --standalone my-agent')}`);
|
|
75
|
+
process.exit(1);
|
|
76
|
+
}
|
|
77
|
+
return initStandaloneAgent(agentName, options);
|
|
78
|
+
}
|
|
79
|
+
// Detect mode: if a project name argument was passed, it's fresh install
|
|
80
|
+
const projectName = options.name;
|
|
81
|
+
const isFresh = !!projectName && !options.dir;
|
|
82
|
+
if (isFresh) {
|
|
83
|
+
return initFreshProject(projectName, options);
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
return initExistingProject(options);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Fresh install: create a new project directory with everything scaffolded.
|
|
91
|
+
*/
|
|
92
|
+
async function initFreshProject(projectName, options) {
|
|
93
|
+
// Validate project name — prevent path traversal, shell injection, and filesystem issues
|
|
94
|
+
if (!/^[a-zA-Z0-9][a-zA-Z0-9._-]{0,99}$/.test(projectName)) {
|
|
95
|
+
console.log(pc.red(` Invalid project name: "${projectName}"`));
|
|
96
|
+
console.log(` Project names must start with a letter or number and contain only letters, numbers, dots, hyphens, and underscores.`);
|
|
97
|
+
process.exit(1);
|
|
98
|
+
}
|
|
99
|
+
if (projectName === '.' || projectName === '..' || projectName.includes('/') || projectName.includes('\\')) {
|
|
100
|
+
console.log(pc.red(` Invalid project name: "${projectName}"`));
|
|
101
|
+
process.exit(1);
|
|
102
|
+
}
|
|
103
|
+
const projectDir = path.resolve(process.cwd(), projectName);
|
|
104
|
+
console.log();
|
|
105
|
+
console.log(pc.bold(` Creating new agent project: ${pc.cyan(projectName)}`));
|
|
106
|
+
console.log(pc.dim(` Directory: ${projectDir}`));
|
|
107
|
+
console.log();
|
|
108
|
+
// Check and install prerequisites
|
|
109
|
+
let tmuxPath;
|
|
110
|
+
let claudePath;
|
|
111
|
+
if (options.skipPrereqs) {
|
|
112
|
+
tmuxPath = detectTmuxPath() || '/usr/bin/tmux';
|
|
113
|
+
claudePath = detectClaudePath() || '/usr/bin/claude';
|
|
114
|
+
}
|
|
115
|
+
else {
|
|
116
|
+
const prereqs = await ensurePrerequisites();
|
|
117
|
+
if (!prereqs.allMet) {
|
|
118
|
+
process.exit(1);
|
|
119
|
+
}
|
|
120
|
+
tmuxPath = prereqs.results.find(r => r.name === 'tmux').path;
|
|
121
|
+
claudePath = prereqs.results.find(r => r.name === 'Claude CLI').path;
|
|
122
|
+
}
|
|
123
|
+
// Check if directory already exists
|
|
124
|
+
if (fs.existsSync(projectDir)) {
|
|
125
|
+
const contents = fs.readdirSync(projectDir);
|
|
126
|
+
if (contents.length > 0) {
|
|
127
|
+
console.log(pc.red(` Directory "${projectName}" already exists and is not empty.`));
|
|
128
|
+
console.log(` Use ${pc.cyan('instar init')} inside an existing project instead.`);
|
|
129
|
+
process.exit(1);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
// Create project directory
|
|
133
|
+
fs.mkdirSync(projectDir, { recursive: true });
|
|
134
|
+
// Auto-allocate a port if not explicitly specified (multi-instance support)
|
|
135
|
+
let port;
|
|
136
|
+
if (options.port) {
|
|
137
|
+
port = options.port;
|
|
138
|
+
}
|
|
139
|
+
else {
|
|
140
|
+
try {
|
|
141
|
+
port = allocatePort(projectDir);
|
|
142
|
+
console.log(` ${pc.green('✓')} Auto-allocated port ${port} (from ~/.instar/registry.json)`);
|
|
143
|
+
}
|
|
144
|
+
catch {
|
|
145
|
+
port = findFreePortFallback();
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
// Generate identity (non-interactive for init, interactive for setup)
|
|
149
|
+
const identity = defaultIdentity(projectName);
|
|
150
|
+
// Create .instar/ state directory
|
|
151
|
+
const stateDir = path.join(projectDir, '.instar');
|
|
152
|
+
ensureStateDir(stateDir);
|
|
153
|
+
console.log(` ${pc.green('✓')} Created .instar/`);
|
|
154
|
+
// Write identity files
|
|
155
|
+
fs.writeFileSync(path.join(stateDir, 'AGENT.md'), generateAgentMd(identity));
|
|
156
|
+
console.log(` ${pc.green('✓')} Created .instar/AGENT.md`);
|
|
157
|
+
fs.writeFileSync(path.join(stateDir, 'USER.md'), generateUserMd(identity.userName));
|
|
158
|
+
console.log(` ${pc.green('✓')} Created .instar/USER.md`);
|
|
159
|
+
fs.writeFileSync(path.join(stateDir, 'MEMORY.md'), generateMemoryMd(identity.name));
|
|
160
|
+
console.log(` ${pc.green('✓')} Created .instar/MEMORY.md`);
|
|
161
|
+
// Write soul.md (self-authored identity)
|
|
162
|
+
const initDate = new Date().toISOString().split('T')[0];
|
|
163
|
+
const soulContent = generateSoulMd(identity.name, identity.personality, initDate);
|
|
164
|
+
fs.writeFileSync(path.join(stateDir, 'soul.md'), soulContent);
|
|
165
|
+
fs.mkdirSync(path.join(stateDir, 'state'), { recursive: true });
|
|
166
|
+
fs.writeFileSync(path.join(stateDir, 'state', 'soul.init.md'), soulContent);
|
|
167
|
+
console.log(` ${pc.green('✓')} Created .instar/soul.md`);
|
|
168
|
+
// Write config
|
|
169
|
+
const authToken = randomUUID();
|
|
170
|
+
const config = {
|
|
171
|
+
projectName,
|
|
172
|
+
port,
|
|
173
|
+
sessions: {
|
|
174
|
+
tmuxPath,
|
|
175
|
+
claudePath,
|
|
176
|
+
projectDir,
|
|
177
|
+
maxSessions: 10,
|
|
178
|
+
protectedSessions: [`${projectName}-server`],
|
|
179
|
+
completionPatterns: [
|
|
180
|
+
'has been automatically paused',
|
|
181
|
+
'Session ended',
|
|
182
|
+
'Interrupted by user',
|
|
183
|
+
],
|
|
184
|
+
},
|
|
185
|
+
scheduler: {
|
|
186
|
+
jobsFile: path.join(stateDir, 'jobs.json'),
|
|
187
|
+
enabled: true,
|
|
188
|
+
maxParallelJobs: 2,
|
|
189
|
+
quotaThresholds: { normal: 50, elevated: 70, critical: 85, shutdown: 95 },
|
|
190
|
+
},
|
|
191
|
+
users: [],
|
|
192
|
+
messaging: [],
|
|
193
|
+
monitoring: {
|
|
194
|
+
quotaTracking: false,
|
|
195
|
+
memoryMonitoring: true,
|
|
196
|
+
healthCheckIntervalMs: 30000,
|
|
197
|
+
promptGate: {
|
|
198
|
+
enabled: true,
|
|
199
|
+
autoApprove: {
|
|
200
|
+
enabled: true,
|
|
201
|
+
fileCreation: true,
|
|
202
|
+
fileEdits: true,
|
|
203
|
+
planApproval: false,
|
|
204
|
+
},
|
|
205
|
+
dryRun: false,
|
|
206
|
+
},
|
|
207
|
+
},
|
|
208
|
+
authToken,
|
|
209
|
+
relationships: {
|
|
210
|
+
relationshipsDir: path.join(stateDir, 'relationships'),
|
|
211
|
+
maxRecentInteractions: 20,
|
|
212
|
+
},
|
|
213
|
+
feedback: {
|
|
214
|
+
enabled: true,
|
|
215
|
+
webhookUrl: 'https://dawn.bot-me.ai/api/instar/feedback',
|
|
216
|
+
feedbackFile: path.join(stateDir, 'feedback.json'),
|
|
217
|
+
sharedSecret: 'instar-rising-tide-v1',
|
|
218
|
+
},
|
|
219
|
+
dispatches: {
|
|
220
|
+
enabled: true,
|
|
221
|
+
dispatchUrl: 'https://dawn.bot-me.ai/api/instar/dispatches',
|
|
222
|
+
dispatchFile: path.join(stateDir, 'state', 'dispatches.json'),
|
|
223
|
+
autoApply: false,
|
|
224
|
+
},
|
|
225
|
+
updates: {
|
|
226
|
+
autoApply: true,
|
|
227
|
+
},
|
|
228
|
+
safety: {
|
|
229
|
+
level: 1, // 1 = ask user before risky actions, 2 = agent self-verifies (autonomous)
|
|
230
|
+
alwaysBlock: [
|
|
231
|
+
'rm -rf /',
|
|
232
|
+
'rm -rf ~',
|
|
233
|
+
'> /dev/sda',
|
|
234
|
+
'mkfs.',
|
|
235
|
+
'dd if=',
|
|
236
|
+
':(){:|:&};:',
|
|
237
|
+
],
|
|
238
|
+
},
|
|
239
|
+
externalOperations: {
|
|
240
|
+
enabled: true,
|
|
241
|
+
sentinel: { enabled: true },
|
|
242
|
+
services: {},
|
|
243
|
+
readOnlyServices: [],
|
|
244
|
+
trust: {
|
|
245
|
+
floor: 'collaborative',
|
|
246
|
+
autoElevateEnabled: true,
|
|
247
|
+
elevationThreshold: 5,
|
|
248
|
+
},
|
|
249
|
+
},
|
|
250
|
+
tunnel: {
|
|
251
|
+
enabled: true,
|
|
252
|
+
type: 'quick',
|
|
253
|
+
},
|
|
254
|
+
threadline: {
|
|
255
|
+
relayEnabled: false,
|
|
256
|
+
visibility: 'public',
|
|
257
|
+
capabilities: ['chat'],
|
|
258
|
+
},
|
|
259
|
+
};
|
|
260
|
+
const configFilePath = path.join(stateDir, 'config.json');
|
|
261
|
+
fs.writeFileSync(configFilePath, JSON.stringify(config, null, 2), { mode: 0o600 });
|
|
262
|
+
console.log(` ${pc.green('✓')} Created .instar/config.json`);
|
|
263
|
+
// Generate manifest signing key (machine-local, never transmitted)
|
|
264
|
+
const manifestIntegrity = new ManifestIntegrity(path.join(stateDir, 'state'));
|
|
265
|
+
manifestIntegrity.ensureKey();
|
|
266
|
+
console.log(` ${pc.green('✓')} Created manifest signing key`);
|
|
267
|
+
// Write default jobs (scheduler enabled by default for fresh projects)
|
|
268
|
+
const defaultJobs = getDefaultJobs(port);
|
|
269
|
+
fs.writeFileSync(path.join(stateDir, 'jobs.json'), JSON.stringify(defaultJobs, null, 2));
|
|
270
|
+
console.log(` ${pc.green('✓')} Created .instar/jobs.json (${defaultJobs.length} default jobs)`);
|
|
271
|
+
// Write empty users
|
|
272
|
+
fs.writeFileSync(path.join(stateDir, 'users.json'), JSON.stringify([], null, 2));
|
|
273
|
+
// Install hooks
|
|
274
|
+
installHooks(stateDir);
|
|
275
|
+
console.log(` ${pc.green('✓')} Created .instar/hooks/instar/ (behavioral guardrails)`);
|
|
276
|
+
// Initialize coherence infrastructure
|
|
277
|
+
try {
|
|
278
|
+
const mapper = new ProjectMapper({ projectDir, stateDir });
|
|
279
|
+
mapper.generateAndSave();
|
|
280
|
+
console.log(` ${pc.green('✓')} Created .instar/project-map.json + project-map.md`);
|
|
281
|
+
}
|
|
282
|
+
catch { /* non-critical */ }
|
|
283
|
+
const ctxHierarchy = new ContextHierarchy({ stateDir, projectDir, projectName });
|
|
284
|
+
ctxHierarchy.initialize();
|
|
285
|
+
console.log(` ${pc.green('✓')} Created .instar/context/ (tiered context hierarchy)`);
|
|
286
|
+
const canonicalState = new CanonicalState({ stateDir });
|
|
287
|
+
canonicalState.initialize(projectName, projectDir);
|
|
288
|
+
console.log(` ${pc.green('✓')} Created .instar/quick-facts.json, anti-patterns.json, project-registry.json`);
|
|
289
|
+
// Create .claude/ structure
|
|
290
|
+
installClaudeSettings(projectDir, port);
|
|
291
|
+
console.log(` ${pc.green('✓')} Created .claude/settings.json`);
|
|
292
|
+
installHealthWatchdog(projectDir, port, projectName);
|
|
293
|
+
console.log(` ${pc.green('✓')} Created .claude/scripts/health-watchdog.sh`);
|
|
294
|
+
installSmartFetch(projectDir);
|
|
295
|
+
console.log(` ${pc.green('✓')} Created .claude/scripts/smart-fetch.py (agentic web conventions)`);
|
|
296
|
+
installGitSyncGate(projectDir);
|
|
297
|
+
console.log(` ${pc.green('✓')} Created .claude/scripts/git-sync-gate.sh (git sync pre-screening)`);
|
|
298
|
+
installSerendipityCapture(projectDir);
|
|
299
|
+
console.log(` ${pc.green('✓')} Created .instar/scripts/serendipity-capture.sh`);
|
|
300
|
+
// Create .claude/skills/ directory and install built-in skills
|
|
301
|
+
const skillsDir = path.join(projectDir, '.claude', 'skills');
|
|
302
|
+
fs.mkdirSync(skillsDir, { recursive: true });
|
|
303
|
+
installBuiltinSkills(skillsDir, port);
|
|
304
|
+
console.log(` ${pc.green('✓')} Created .claude/skills/ (with built-in evolution skills)`);
|
|
305
|
+
// Write CLAUDE.md (standalone version for fresh projects)
|
|
306
|
+
const claudeMd = generateClaudeMd(projectName, identity.name, port, false);
|
|
307
|
+
fs.writeFileSync(path.join(projectDir, 'CLAUDE.md'), claudeMd);
|
|
308
|
+
console.log(` ${pc.green('✓')} Created CLAUDE.md`);
|
|
309
|
+
// Write .gitignore
|
|
310
|
+
const gitignore = `# Instar per-machine state (sessions, logs, secrets)
|
|
311
|
+
.instar/state/
|
|
312
|
+
.instar/logs/
|
|
313
|
+
.instar/config.json
|
|
314
|
+
|
|
315
|
+
# Node
|
|
316
|
+
node_modules/
|
|
317
|
+
`;
|
|
318
|
+
fs.writeFileSync(path.join(projectDir, '.gitignore'), gitignore);
|
|
319
|
+
// Add multi-machine gitignore entries (private keys, secrets, pairing)
|
|
320
|
+
ensureGitignore(projectDir);
|
|
321
|
+
console.log(` ${pc.green('✓')} Created .gitignore`);
|
|
322
|
+
// Generate machine identity (cryptographic keypairs for multi-machine)
|
|
323
|
+
const machineIdentityManager = new MachineIdentityManager(stateDir);
|
|
324
|
+
const machineIdentity = await machineIdentityManager.generateIdentity({ role: 'awake' });
|
|
325
|
+
console.log(` ${pc.green('✓')} Generated machine identity (${machineIdentity.name})`);
|
|
326
|
+
// Initialize git repo
|
|
327
|
+
try {
|
|
328
|
+
const { execFileSync } = await import('node:child_process');
|
|
329
|
+
execFileSync('git', ['init'], { cwd: projectDir, stdio: 'pipe' });
|
|
330
|
+
console.log(` ${pc.green('✓')} Initialized git repository`);
|
|
331
|
+
// Configure git commit signing with machine identity
|
|
332
|
+
try {
|
|
333
|
+
const { GitSyncManager } = await import('../core/GitSync.js');
|
|
334
|
+
const { SecurityLog } = await import('../core/SecurityLog.js');
|
|
335
|
+
const securityLog = new SecurityLog(stateDir);
|
|
336
|
+
const gitSync = new GitSyncManager({
|
|
337
|
+
projectDir,
|
|
338
|
+
stateDir,
|
|
339
|
+
identityManager: machineIdentityManager,
|
|
340
|
+
securityLog,
|
|
341
|
+
machineId: machineIdentity.machineId,
|
|
342
|
+
});
|
|
343
|
+
if (!gitSync.isSigningConfigured()) {
|
|
344
|
+
gitSync.configureCommitSigning();
|
|
345
|
+
console.log(` ${pc.green('✓')} Configured git commit signing`);
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
catch {
|
|
349
|
+
// Non-fatal — signing can be configured later
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
catch {
|
|
353
|
+
// Git not available — that's fine
|
|
354
|
+
}
|
|
355
|
+
// Generate self-knowledge tree from AGENT.md
|
|
356
|
+
try {
|
|
357
|
+
const { TreeGenerator } = await import('../knowledge/TreeGenerator.js');
|
|
358
|
+
const treeGenerator = new TreeGenerator();
|
|
359
|
+
const treeConfig = treeGenerator.generate({
|
|
360
|
+
projectDir,
|
|
361
|
+
stateDir,
|
|
362
|
+
agentName: projectName,
|
|
363
|
+
hasMemory: true,
|
|
364
|
+
hasJobs: true,
|
|
365
|
+
hasDecisionJournal: true,
|
|
366
|
+
});
|
|
367
|
+
treeGenerator.save(treeConfig, stateDir);
|
|
368
|
+
const totalNodes = treeConfig.layers.reduce((sum, l) => sum + l.children.length, 0);
|
|
369
|
+
console.log(` ${pc.green('✓')} Created self-knowledge tree (${treeConfig.layers.length} layers, ${totalNodes} nodes)`);
|
|
370
|
+
}
|
|
371
|
+
catch {
|
|
372
|
+
// Non-critical — tree can be generated later via doctor
|
|
373
|
+
}
|
|
374
|
+
// Record current version so first server start doesn't dump all historical upgrade guides
|
|
375
|
+
const freshVersionFile = path.join(stateDir, 'state', 'last-migrated-version.json');
|
|
376
|
+
const freshVersionDir = path.dirname(freshVersionFile);
|
|
377
|
+
if (!fs.existsSync(freshVersionDir))
|
|
378
|
+
fs.mkdirSync(freshVersionDir, { recursive: true });
|
|
379
|
+
fs.writeFileSync(freshVersionFile, JSON.stringify({ version: getInstarVersion(), migratedAt: new Date().toISOString() }));
|
|
380
|
+
// Register in global agent registry
|
|
381
|
+
try {
|
|
382
|
+
registerAgent(projectDir, projectName, port, 'project-bound', 0);
|
|
383
|
+
console.log(` ${pc.green('✓')} Registered in global agent registry`);
|
|
384
|
+
}
|
|
385
|
+
catch {
|
|
386
|
+
// Non-fatal — will register on first server start
|
|
387
|
+
}
|
|
388
|
+
// Summary
|
|
389
|
+
console.log();
|
|
390
|
+
console.log(pc.bold(pc.green(' Project created!')));
|
|
391
|
+
console.log();
|
|
392
|
+
console.log(` ${pc.cyan(projectName)}/`);
|
|
393
|
+
console.log(` ├── CLAUDE.md ${pc.dim('Agent instructions')}`);
|
|
394
|
+
console.log(` ├── .instar/`);
|
|
395
|
+
console.log(` │ ├── AGENT.md ${pc.dim('Agent identity')}`);
|
|
396
|
+
console.log(` │ ├── USER.md ${pc.dim('User context')}`);
|
|
397
|
+
console.log(` │ ├── MEMORY.md ${pc.dim('Persistent memory')}`);
|
|
398
|
+
console.log(` │ ├── config.json ${pc.dim('Configuration')}`);
|
|
399
|
+
console.log(` │ ├── jobs.json ${pc.dim('Scheduled jobs')}`);
|
|
400
|
+
console.log(` │ └── hooks/ ${pc.dim('Behavioral guardrails')}`);
|
|
401
|
+
console.log(` ├── .claude/`);
|
|
402
|
+
console.log(` │ ├── settings.json ${pc.dim('Hook configuration')}`);
|
|
403
|
+
console.log(` │ ├── scripts/ ${pc.dim('Agent-authored scripts')}`);
|
|
404
|
+
console.log(` │ └── skills/ ${pc.dim('Agent-authored skills')}`);
|
|
405
|
+
console.log(` └── .gitignore`);
|
|
406
|
+
console.log();
|
|
407
|
+
console.log(pc.bold(' Next steps:'));
|
|
408
|
+
console.log(` ${pc.dim('1.')} ${pc.cyan(`cd ${projectName}`)}`);
|
|
409
|
+
console.log(` ${pc.dim('2.')} ${pc.cyan('instar server start')} ${pc.dim('Start the agent server')}`);
|
|
410
|
+
console.log(` ${pc.dim('3.')} ${pc.cyan('claude')} ${pc.dim('Open a Claude session')}`);
|
|
411
|
+
console.log();
|
|
412
|
+
console.log(` Auth token: ${pc.dim(authToken.slice(0, 8) + '...' + authToken.slice(-4))}`);
|
|
413
|
+
console.log(` ${pc.dim('(full token saved in .instar/config.json — use for API calls)')}`);
|
|
414
|
+
console.log();
|
|
415
|
+
}
|
|
416
|
+
/**
|
|
417
|
+
* Existing project: add .instar/ infrastructure without replacing anything.
|
|
418
|
+
*/
|
|
419
|
+
async function initExistingProject(options) {
|
|
420
|
+
const projectDir = path.resolve(options.dir || process.cwd());
|
|
421
|
+
const projectName = options.name || path.basename(projectDir);
|
|
422
|
+
// Auto-allocate a port if not explicitly specified (multi-instance support)
|
|
423
|
+
let port;
|
|
424
|
+
if (options.port) {
|
|
425
|
+
port = options.port;
|
|
426
|
+
}
|
|
427
|
+
else {
|
|
428
|
+
try {
|
|
429
|
+
port = allocatePort(projectDir);
|
|
430
|
+
}
|
|
431
|
+
catch {
|
|
432
|
+
port = findFreePortFallback();
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
console.log(pc.bold(`\nInitializing instar in: ${pc.cyan(projectDir)}`));
|
|
436
|
+
console.log();
|
|
437
|
+
// Check and install prerequisites
|
|
438
|
+
let tmuxPath;
|
|
439
|
+
let claudePath;
|
|
440
|
+
if (options.skipPrereqs) {
|
|
441
|
+
tmuxPath = detectTmuxPath() || '/usr/bin/tmux';
|
|
442
|
+
claudePath = detectClaudePath() || '/usr/bin/claude';
|
|
443
|
+
}
|
|
444
|
+
else {
|
|
445
|
+
const prereqs = await ensurePrerequisites();
|
|
446
|
+
if (!prereqs.allMet) {
|
|
447
|
+
process.exit(1);
|
|
448
|
+
}
|
|
449
|
+
tmuxPath = prereqs.results.find(r => r.name === 'tmux').path;
|
|
450
|
+
claudePath = prereqs.results.find(r => r.name === 'Claude CLI').path;
|
|
451
|
+
}
|
|
452
|
+
// Create state directory
|
|
453
|
+
const stateDir = path.join(projectDir, '.instar');
|
|
454
|
+
ensureStateDir(stateDir);
|
|
455
|
+
console.log(pc.green(' Created:') + ' .instar/');
|
|
456
|
+
// Write config
|
|
457
|
+
const config = {
|
|
458
|
+
projectName,
|
|
459
|
+
port,
|
|
460
|
+
sessions: {
|
|
461
|
+
tmuxPath,
|
|
462
|
+
claudePath,
|
|
463
|
+
projectDir,
|
|
464
|
+
maxSessions: 10,
|
|
465
|
+
protectedSessions: [`${projectName}-server`],
|
|
466
|
+
completionPatterns: [
|
|
467
|
+
'has been automatically paused',
|
|
468
|
+
'Session ended',
|
|
469
|
+
'Interrupted by user',
|
|
470
|
+
],
|
|
471
|
+
},
|
|
472
|
+
scheduler: {
|
|
473
|
+
jobsFile: path.join(stateDir, 'jobs.json'),
|
|
474
|
+
enabled: false,
|
|
475
|
+
maxParallelJobs: 2,
|
|
476
|
+
quotaThresholds: { normal: 50, elevated: 70, critical: 85, shutdown: 95 },
|
|
477
|
+
},
|
|
478
|
+
users: [],
|
|
479
|
+
messaging: [],
|
|
480
|
+
monitoring: {
|
|
481
|
+
quotaTracking: false,
|
|
482
|
+
memoryMonitoring: true,
|
|
483
|
+
healthCheckIntervalMs: 30000,
|
|
484
|
+
},
|
|
485
|
+
authToken: randomUUID(),
|
|
486
|
+
relationships: {
|
|
487
|
+
relationshipsDir: path.join(stateDir, 'relationships'),
|
|
488
|
+
maxRecentInteractions: 20,
|
|
489
|
+
},
|
|
490
|
+
feedback: {
|
|
491
|
+
enabled: true,
|
|
492
|
+
webhookUrl: 'https://dawn.bot-me.ai/api/instar/feedback',
|
|
493
|
+
feedbackFile: path.join(stateDir, 'feedback.json'),
|
|
494
|
+
sharedSecret: 'instar-rising-tide-v1',
|
|
495
|
+
},
|
|
496
|
+
dispatches: {
|
|
497
|
+
enabled: true,
|
|
498
|
+
dispatchUrl: 'https://dawn.bot-me.ai/api/instar/dispatches',
|
|
499
|
+
dispatchFile: path.join(stateDir, 'state', 'dispatches.json'),
|
|
500
|
+
autoApply: false,
|
|
501
|
+
},
|
|
502
|
+
updates: {
|
|
503
|
+
autoApply: true,
|
|
504
|
+
},
|
|
505
|
+
safety: {
|
|
506
|
+
level: 1, // 1 = ask user before risky actions, 2 = agent self-verifies (autonomous)
|
|
507
|
+
alwaysBlock: [
|
|
508
|
+
'rm -rf /',
|
|
509
|
+
'rm -rf ~',
|
|
510
|
+
'> /dev/sda',
|
|
511
|
+
'mkfs.',
|
|
512
|
+
'dd if=',
|
|
513
|
+
':(){:|:&};:',
|
|
514
|
+
],
|
|
515
|
+
},
|
|
516
|
+
externalOperations: {
|
|
517
|
+
enabled: true,
|
|
518
|
+
sentinel: { enabled: true },
|
|
519
|
+
services: {},
|
|
520
|
+
readOnlyServices: [],
|
|
521
|
+
trust: {
|
|
522
|
+
floor: 'supervised', // Conservative for existing projects
|
|
523
|
+
autoElevateEnabled: false, // Disabled until operator confirms
|
|
524
|
+
elevationThreshold: 5,
|
|
525
|
+
},
|
|
526
|
+
},
|
|
527
|
+
tunnel: {
|
|
528
|
+
enabled: true,
|
|
529
|
+
type: 'quick',
|
|
530
|
+
},
|
|
531
|
+
threadline: {
|
|
532
|
+
relayEnabled: false,
|
|
533
|
+
visibility: 'public',
|
|
534
|
+
capabilities: ['chat'],
|
|
535
|
+
},
|
|
536
|
+
};
|
|
537
|
+
const configPath = path.join(stateDir, 'config.json');
|
|
538
|
+
if (!fs.existsSync(configPath)) {
|
|
539
|
+
fs.writeFileSync(configPath, JSON.stringify(config, null, 2), { mode: 0o600 });
|
|
540
|
+
console.log(pc.green(' Created:') + ' .instar/config.json');
|
|
541
|
+
}
|
|
542
|
+
else {
|
|
543
|
+
console.log(pc.dim(' Exists:') + ' .instar/config.json (preserved)');
|
|
544
|
+
}
|
|
545
|
+
// Write default coherence jobs (only if not existing)
|
|
546
|
+
const jobsPath = path.join(stateDir, 'jobs.json');
|
|
547
|
+
if (!fs.existsSync(jobsPath)) {
|
|
548
|
+
const defaultJobs = getDefaultJobs(port);
|
|
549
|
+
fs.writeFileSync(jobsPath, JSON.stringify(defaultJobs, null, 2));
|
|
550
|
+
console.log(pc.green(' Created:') + ` .instar/jobs.json (${defaultJobs.length} default jobs)`);
|
|
551
|
+
}
|
|
552
|
+
else {
|
|
553
|
+
console.log(pc.dim(' Exists:') + ' .instar/jobs.json (preserved)');
|
|
554
|
+
}
|
|
555
|
+
// Write empty users (only if not existing)
|
|
556
|
+
const usersPath = path.join(stateDir, 'users.json');
|
|
557
|
+
if (!fs.existsSync(usersPath)) {
|
|
558
|
+
fs.writeFileSync(usersPath, JSON.stringify([], null, 2));
|
|
559
|
+
console.log(pc.green(' Created:') + ' .instar/users.json');
|
|
560
|
+
}
|
|
561
|
+
else {
|
|
562
|
+
console.log(pc.dim(' Exists:') + ' .instar/users.json (preserved)');
|
|
563
|
+
}
|
|
564
|
+
// Create identity files if they don't exist
|
|
565
|
+
const identity = defaultIdentity(projectName);
|
|
566
|
+
if (!fs.existsSync(path.join(stateDir, 'AGENT.md'))) {
|
|
567
|
+
fs.writeFileSync(path.join(stateDir, 'AGENT.md'), generateAgentMd(identity));
|
|
568
|
+
console.log(pc.green(' Created:') + ' .instar/AGENT.md');
|
|
569
|
+
}
|
|
570
|
+
if (!fs.existsSync(path.join(stateDir, 'USER.md'))) {
|
|
571
|
+
fs.writeFileSync(path.join(stateDir, 'USER.md'), generateUserMd(identity.userName));
|
|
572
|
+
console.log(pc.green(' Created:') + ' .instar/USER.md');
|
|
573
|
+
}
|
|
574
|
+
if (!fs.existsSync(path.join(stateDir, 'MEMORY.md'))) {
|
|
575
|
+
fs.writeFileSync(path.join(stateDir, 'MEMORY.md'), generateMemoryMd(identity.name));
|
|
576
|
+
console.log(pc.green(' Created:') + ' .instar/MEMORY.md');
|
|
577
|
+
}
|
|
578
|
+
if (!fs.existsSync(path.join(stateDir, 'soul.md'))) {
|
|
579
|
+
const initDate = new Date().toISOString().split('T')[0];
|
|
580
|
+
const soulContent = generateSoulMd(identity.name, identity.personality, initDate);
|
|
581
|
+
fs.writeFileSync(path.join(stateDir, 'soul.md'), soulContent);
|
|
582
|
+
fs.mkdirSync(path.join(stateDir, 'state'), { recursive: true });
|
|
583
|
+
fs.writeFileSync(path.join(stateDir, 'state', 'soul.init.md'), soulContent);
|
|
584
|
+
console.log(pc.green(' Created:') + ' .instar/soul.md');
|
|
585
|
+
}
|
|
586
|
+
// Install hooks
|
|
587
|
+
installHooks(stateDir);
|
|
588
|
+
console.log(pc.green(' Created:') + ' .instar/hooks/instar/ (behavioral guardrails)');
|
|
589
|
+
// Ensure manifest signing key exists (additive — won't overwrite)
|
|
590
|
+
const manifestIntegrity = new ManifestIntegrity(path.join(stateDir, 'state'));
|
|
591
|
+
if (manifestIntegrity.ensureKey()) {
|
|
592
|
+
console.log(pc.green(' Created:') + ' manifest signing key');
|
|
593
|
+
}
|
|
594
|
+
// Initialize coherence infrastructure (additive only)
|
|
595
|
+
try {
|
|
596
|
+
const mapper = new ProjectMapper({ projectDir, stateDir });
|
|
597
|
+
if (!fs.existsSync(path.join(stateDir, 'project-map.json'))) {
|
|
598
|
+
mapper.generateAndSave();
|
|
599
|
+
console.log(pc.green(' Created:') + ' .instar/project-map.json + project-map.md');
|
|
600
|
+
}
|
|
601
|
+
}
|
|
602
|
+
catch { /* non-critical */ }
|
|
603
|
+
const ctxHierarchy = new ContextHierarchy({ stateDir, projectDir, projectName });
|
|
604
|
+
const ctxResult = ctxHierarchy.initialize();
|
|
605
|
+
if (ctxResult.created.length > 0) {
|
|
606
|
+
console.log(pc.green(' Created:') + ` .instar/context/ (${ctxResult.created.length} segments)`);
|
|
607
|
+
}
|
|
608
|
+
const canonicalState = new CanonicalState({ stateDir });
|
|
609
|
+
const stateResult = canonicalState.initialize(projectName, projectDir);
|
|
610
|
+
if (stateResult.created.length > 0) {
|
|
611
|
+
console.log(pc.green(' Created:') + ` canonical state (${stateResult.created.join(', ')})`);
|
|
612
|
+
}
|
|
613
|
+
// Configure Claude Code settings with hooks
|
|
614
|
+
installClaudeSettings(projectDir, port);
|
|
615
|
+
console.log(pc.green(' Created:') + ' .claude/settings.json (hook configuration)');
|
|
616
|
+
// Install health watchdog
|
|
617
|
+
installHealthWatchdog(projectDir, port, projectName);
|
|
618
|
+
console.log(pc.green(' Created:') + ' .claude/scripts/health-watchdog.sh');
|
|
619
|
+
// Install smart-fetch for agentic web conventions
|
|
620
|
+
installSmartFetch(projectDir);
|
|
621
|
+
console.log(pc.green(' Created:') + ' .claude/scripts/smart-fetch.py (agentic web conventions)');
|
|
622
|
+
// Install git-sync gate script
|
|
623
|
+
installGitSyncGate(projectDir);
|
|
624
|
+
console.log(pc.green(' Created:') + ' .claude/scripts/git-sync-gate.sh (git sync pre-screening)');
|
|
625
|
+
// Install serendipity capture script
|
|
626
|
+
installSerendipityCapture(projectDir);
|
|
627
|
+
console.log(pc.green(' Created:') + ' .instar/scripts/serendipity-capture.sh');
|
|
628
|
+
// Create .claude/skills/ directory and install built-in skills
|
|
629
|
+
const skillsDir = path.join(projectDir, '.claude', 'skills');
|
|
630
|
+
fs.mkdirSync(skillsDir, { recursive: true });
|
|
631
|
+
installBuiltinSkills(skillsDir, port);
|
|
632
|
+
console.log(pc.green(' Created:') + ' .claude/skills/ (with built-in evolution skills)');
|
|
633
|
+
// Append to .gitignore
|
|
634
|
+
const gitignorePath = path.join(projectDir, '.gitignore');
|
|
635
|
+
const instarIgnores = '\n# Instar per-machine state (sessions, logs, secrets)\n.instar/state/\n.instar/logs/\n.instar/config.json\n';
|
|
636
|
+
if (fs.existsSync(gitignorePath)) {
|
|
637
|
+
const content = fs.readFileSync(gitignorePath, 'utf-8');
|
|
638
|
+
if (!content.includes('.instar/')) {
|
|
639
|
+
fs.appendFileSync(gitignorePath, instarIgnores);
|
|
640
|
+
console.log(pc.green(' Updated:') + ' .gitignore');
|
|
641
|
+
}
|
|
642
|
+
}
|
|
643
|
+
else {
|
|
644
|
+
fs.writeFileSync(gitignorePath, instarIgnores.trim() + '\n');
|
|
645
|
+
console.log(pc.green(' Created:') + ' .gitignore');
|
|
646
|
+
}
|
|
647
|
+
// Add multi-machine gitignore entries (private keys, secrets, pairing)
|
|
648
|
+
ensureGitignore(projectDir);
|
|
649
|
+
// Generate machine identity if it doesn't exist
|
|
650
|
+
const machineIdentityManager = new MachineIdentityManager(stateDir);
|
|
651
|
+
if (!machineIdentityManager.hasIdentity()) {
|
|
652
|
+
const machineIdentity = await machineIdentityManager.generateIdentity({ role: 'awake' });
|
|
653
|
+
console.log(pc.green(' Created:') + ` machine identity (${machineIdentity.name})`);
|
|
654
|
+
}
|
|
655
|
+
else {
|
|
656
|
+
console.log(pc.dim(' Exists:') + ' machine identity (preserved)');
|
|
657
|
+
}
|
|
658
|
+
// Append agency principles to CLAUDE.md if it exists
|
|
659
|
+
const claudeMdPath = path.join(projectDir, 'CLAUDE.md');
|
|
660
|
+
if (fs.existsSync(claudeMdPath)) {
|
|
661
|
+
const content = fs.readFileSync(claudeMdPath, 'utf-8');
|
|
662
|
+
if (!content.includes('## Agent Infrastructure')) {
|
|
663
|
+
fs.appendFileSync(claudeMdPath, getAgencyPrinciples(projectName, undefined));
|
|
664
|
+
console.log(pc.green(' Updated:') + ' CLAUDE.md (added agency principles)');
|
|
665
|
+
}
|
|
666
|
+
}
|
|
667
|
+
// Generate self-knowledge tree if it doesn't exist
|
|
668
|
+
const treeFilePath = path.join(stateDir, 'self-knowledge-tree.json');
|
|
669
|
+
if (!fs.existsSync(treeFilePath)) {
|
|
670
|
+
try {
|
|
671
|
+
const { TreeGenerator } = await import('../knowledge/TreeGenerator.js');
|
|
672
|
+
const treeGenerator = new TreeGenerator();
|
|
673
|
+
const treeConfig = treeGenerator.generate({
|
|
674
|
+
projectDir,
|
|
675
|
+
stateDir,
|
|
676
|
+
agentName: projectName,
|
|
677
|
+
hasMemory: true,
|
|
678
|
+
hasJobs: true,
|
|
679
|
+
hasDecisionJournal: true,
|
|
680
|
+
});
|
|
681
|
+
treeGenerator.save(treeConfig, stateDir);
|
|
682
|
+
const totalNodes = treeConfig.layers.reduce((sum, l) => sum + l.children.length, 0);
|
|
683
|
+
console.log(pc.green(' Created:') + ` self-knowledge tree (${treeConfig.layers.length} layers, ${totalNodes} nodes)`);
|
|
684
|
+
}
|
|
685
|
+
catch {
|
|
686
|
+
// Non-critical — tree can be generated later
|
|
687
|
+
}
|
|
688
|
+
}
|
|
689
|
+
else {
|
|
690
|
+
console.log(pc.dim(' Exists:') + ' self-knowledge tree (preserved)');
|
|
691
|
+
}
|
|
692
|
+
// Record current version so first server start doesn't dump all historical upgrade guides
|
|
693
|
+
const existingVersionFile = path.join(stateDir, 'state', 'last-migrated-version.json');
|
|
694
|
+
if (!fs.existsSync(path.dirname(existingVersionFile)))
|
|
695
|
+
fs.mkdirSync(path.dirname(existingVersionFile), { recursive: true });
|
|
696
|
+
fs.writeFileSync(existingVersionFile, JSON.stringify({ version: getInstarVersion(), migratedAt: new Date().toISOString() }));
|
|
697
|
+
// Register in global agent registry
|
|
698
|
+
try {
|
|
699
|
+
registerAgent(projectDir, projectName, port, 'project-bound', 0);
|
|
700
|
+
console.log(pc.green(' Registered in global agent registry'));
|
|
701
|
+
}
|
|
702
|
+
catch {
|
|
703
|
+
// Non-fatal — will register on first server start
|
|
704
|
+
}
|
|
705
|
+
console.log();
|
|
706
|
+
console.log(pc.bold('Next steps:'));
|
|
707
|
+
console.log(` 1. Review ${pc.cyan('.instar/AGENT.md')} and customize your agent's identity`);
|
|
708
|
+
console.log(` 2. Add users: ${pc.cyan('instar user add --id justin --name Justin')}`);
|
|
709
|
+
console.log(` 3. Add capabilities: ${pc.cyan('instar add telegram')}`);
|
|
710
|
+
console.log(` 4. Start server: ${pc.cyan('instar server start')}`);
|
|
711
|
+
console.log();
|
|
712
|
+
}
|
|
713
|
+
/**
|
|
714
|
+
* Standalone agent: create at ~/.instar/agents/<name>/ with full agent infrastructure.
|
|
715
|
+
* The agent's home IS the project — self-contained, no parent project.
|
|
716
|
+
*/
|
|
717
|
+
async function initStandaloneAgent(agentName, options) {
|
|
718
|
+
// Validate agent name
|
|
719
|
+
if (!validateAgentName(agentName)) {
|
|
720
|
+
console.log(pc.red(` Invalid agent name: "${agentName}"`));
|
|
721
|
+
console.log(' Names must start with a letter or number, contain only letters, numbers, hyphens, and underscores.');
|
|
722
|
+
console.log(' Maximum 64 characters.');
|
|
723
|
+
process.exit(1);
|
|
724
|
+
}
|
|
725
|
+
const projectDir = path.join(standaloneAgentsDir(), agentName);
|
|
726
|
+
const stateDir = path.join(projectDir, '.instar');
|
|
727
|
+
// Check if already exists
|
|
728
|
+
if (fs.existsSync(path.join(stateDir, 'config.json'))) {
|
|
729
|
+
console.log(pc.red(` Agent "${agentName}" already exists at ${projectDir}`));
|
|
730
|
+
console.log(` To remove it: ${pc.cyan(`rm -rf ${projectDir}`)}`);
|
|
731
|
+
process.exit(1);
|
|
732
|
+
}
|
|
733
|
+
console.log(pc.bold(`\nCreating standalone agent: ${pc.cyan(agentName)}`));
|
|
734
|
+
console.log(pc.dim(` Location: ${projectDir}`));
|
|
735
|
+
console.log();
|
|
736
|
+
// Check prerequisites
|
|
737
|
+
let tmuxPath;
|
|
738
|
+
let claudePath;
|
|
739
|
+
if (options.skipPrereqs) {
|
|
740
|
+
tmuxPath = detectTmuxPath() || '/usr/bin/tmux';
|
|
741
|
+
claudePath = detectClaudePath() || '/usr/bin/claude';
|
|
742
|
+
}
|
|
743
|
+
else {
|
|
744
|
+
const prereqs = await ensurePrerequisites();
|
|
745
|
+
if (!prereqs.allMet) {
|
|
746
|
+
console.log(pc.red('\n Prerequisites check failed. Fix the issues above and retry.'));
|
|
747
|
+
process.exit(1);
|
|
748
|
+
}
|
|
749
|
+
tmuxPath = prereqs.results.find(r => r.name === 'tmux').path;
|
|
750
|
+
claudePath = prereqs.results.find(r => r.name === 'Claude CLI').path;
|
|
751
|
+
}
|
|
752
|
+
// Auto-allocate port
|
|
753
|
+
let port;
|
|
754
|
+
if (options.port) {
|
|
755
|
+
port = options.port;
|
|
756
|
+
}
|
|
757
|
+
else {
|
|
758
|
+
try {
|
|
759
|
+
port = allocatePort(projectDir);
|
|
760
|
+
console.log(` ${pc.green('✓')} Auto-allocated port ${port}`);
|
|
761
|
+
}
|
|
762
|
+
catch {
|
|
763
|
+
port = findFreePortFallback();
|
|
764
|
+
}
|
|
765
|
+
}
|
|
766
|
+
// Create directory structure
|
|
767
|
+
fs.mkdirSync(projectDir, { recursive: true });
|
|
768
|
+
ensureStateDir(stateDir);
|
|
769
|
+
console.log(` ${pc.green('✓')} Created ${projectDir}`);
|
|
770
|
+
// Generate identity
|
|
771
|
+
const identity = defaultIdentity(agentName);
|
|
772
|
+
const authToken = randomUUID();
|
|
773
|
+
// Write identity files
|
|
774
|
+
fs.writeFileSync(path.join(stateDir, 'AGENT.md'), generateAgentMd(identity));
|
|
775
|
+
console.log(` ${pc.green('✓')} Created AGENT.md`);
|
|
776
|
+
fs.writeFileSync(path.join(stateDir, 'USER.md'), generateUserMd(identity.userName));
|
|
777
|
+
console.log(` ${pc.green('✓')} Created USER.md`);
|
|
778
|
+
fs.writeFileSync(path.join(stateDir, 'MEMORY.md'), generateMemoryMd(agentName));
|
|
779
|
+
console.log(` ${pc.green('✓')} Created MEMORY.md`);
|
|
780
|
+
const initDate = new Date().toISOString().split('T')[0];
|
|
781
|
+
const soulContent = generateSoulMd(agentName, identity.personality, initDate);
|
|
782
|
+
fs.writeFileSync(path.join(stateDir, 'soul.md'), soulContent);
|
|
783
|
+
fs.mkdirSync(path.join(stateDir, 'state'), { recursive: true });
|
|
784
|
+
fs.writeFileSync(path.join(stateDir, 'state', 'soul.init.md'), soulContent);
|
|
785
|
+
console.log(` ${pc.green('✓')} Created soul.md`);
|
|
786
|
+
// Write config
|
|
787
|
+
const config = {
|
|
788
|
+
projectName: agentName,
|
|
789
|
+
projectDir,
|
|
790
|
+
port,
|
|
791
|
+
agentType: 'standalone',
|
|
792
|
+
sessions: {
|
|
793
|
+
tmuxPath,
|
|
794
|
+
claudePath,
|
|
795
|
+
maxSessions: 10,
|
|
796
|
+
protectedSessions: [`${agentName}-server`],
|
|
797
|
+
},
|
|
798
|
+
scheduler: { enabled: true, maxParallelJobs: 2 },
|
|
799
|
+
messaging: [],
|
|
800
|
+
monitoring: {
|
|
801
|
+
quotaTracking: true,
|
|
802
|
+
memoryMonitoring: true,
|
|
803
|
+
healthCheckIntervalMs: 30000,
|
|
804
|
+
promptGate: {
|
|
805
|
+
enabled: true,
|
|
806
|
+
autoApprove: {
|
|
807
|
+
enabled: true,
|
|
808
|
+
fileCreation: true,
|
|
809
|
+
fileEdits: true,
|
|
810
|
+
planApproval: false,
|
|
811
|
+
},
|
|
812
|
+
dryRun: false,
|
|
813
|
+
},
|
|
814
|
+
},
|
|
815
|
+
authToken,
|
|
816
|
+
externalOperations: {
|
|
817
|
+
enabled: true,
|
|
818
|
+
sentinel: { enabled: true },
|
|
819
|
+
services: {},
|
|
820
|
+
readOnlyServices: [],
|
|
821
|
+
trust: {
|
|
822
|
+
floor: 'collaborative',
|
|
823
|
+
autoElevateEnabled: true,
|
|
824
|
+
elevationThreshold: 5,
|
|
825
|
+
},
|
|
826
|
+
},
|
|
827
|
+
tunnel: {
|
|
828
|
+
enabled: true,
|
|
829
|
+
type: 'quick',
|
|
830
|
+
},
|
|
831
|
+
};
|
|
832
|
+
fs.writeFileSync(path.join(stateDir, 'config.json'), JSON.stringify(config, null, 2));
|
|
833
|
+
console.log(` ${pc.green('✓')} Created config.json`);
|
|
834
|
+
// Write empty jobs and users
|
|
835
|
+
fs.writeFileSync(path.join(stateDir, 'jobs.json'), JSON.stringify([], null, 2));
|
|
836
|
+
fs.writeFileSync(path.join(stateDir, 'users.json'), JSON.stringify([], null, 2));
|
|
837
|
+
// Create CLAUDE.md at project root
|
|
838
|
+
fs.writeFileSync(path.join(projectDir, 'CLAUDE.md'), generateClaudeMd(agentName, agentName, port, false));
|
|
839
|
+
console.log(` ${pc.green('✓')} Created CLAUDE.md`);
|
|
840
|
+
// Create .claude/ structure
|
|
841
|
+
const claudeDir = path.join(projectDir, '.claude');
|
|
842
|
+
fs.mkdirSync(path.join(claudeDir, 'scripts'), { recursive: true });
|
|
843
|
+
fs.mkdirSync(path.join(claudeDir, 'skills'), { recursive: true });
|
|
844
|
+
fs.writeFileSync(path.join(claudeDir, 'settings.json'), JSON.stringify({
|
|
845
|
+
hooks: {
|
|
846
|
+
PreToolUse: [],
|
|
847
|
+
PostToolUse: [],
|
|
848
|
+
},
|
|
849
|
+
}, null, 2));
|
|
850
|
+
// Create .gitignore
|
|
851
|
+
fs.writeFileSync(path.join(projectDir, '.gitignore'), [
|
|
852
|
+
'# Runtime state',
|
|
853
|
+
'.instar/state/',
|
|
854
|
+
'.instar/logs/',
|
|
855
|
+
'.instar/*.tmp',
|
|
856
|
+
'',
|
|
857
|
+
'# Secrets',
|
|
858
|
+
'.instar/config.json',
|
|
859
|
+
'.instar/machine/',
|
|
860
|
+
'.instar/secrets/',
|
|
861
|
+
'',
|
|
862
|
+
'# Backups (local only)',
|
|
863
|
+
'.instar/backups/',
|
|
864
|
+
'',
|
|
865
|
+
'# Derived data',
|
|
866
|
+
'.instar/memory.db',
|
|
867
|
+
'.instar/memory.db-*',
|
|
868
|
+
'',
|
|
869
|
+
'# Claude Code',
|
|
870
|
+
'.claude/projects/',
|
|
871
|
+
'.claude/todos/',
|
|
872
|
+
].join('\n') + '\n');
|
|
873
|
+
console.log(` ${pc.green('✓')} Created .gitignore`);
|
|
874
|
+
// Generate machine identity
|
|
875
|
+
try {
|
|
876
|
+
const machineIdentityManager = new MachineIdentityManager(stateDir);
|
|
877
|
+
const machineIdentity = await machineIdentityManager.generateIdentity({ name: agentName });
|
|
878
|
+
ensureGitignore(stateDir);
|
|
879
|
+
console.log(` ${pc.green('✓')} Generated machine identity: ${machineIdentity.machineId.slice(0, 12)}...`);
|
|
880
|
+
}
|
|
881
|
+
catch {
|
|
882
|
+
// Non-fatal
|
|
883
|
+
}
|
|
884
|
+
// Cloud backup setup (recommended — protects agent data from machine loss)
|
|
885
|
+
await setupCloudBackup(projectDir, stateDir, agentName);
|
|
886
|
+
// Generate manifest signing key
|
|
887
|
+
const standaloneIntegrity = new ManifestIntegrity(path.join(stateDir, 'state'));
|
|
888
|
+
standaloneIntegrity.ensureKey();
|
|
889
|
+
console.log(` ${pc.green('✓')} Created manifest signing key`);
|
|
890
|
+
// Install behavioral guardrails (hooks + Claude settings)
|
|
891
|
+
try {
|
|
892
|
+
refreshHooksAndSettings(projectDir, stateDir);
|
|
893
|
+
console.log(` ${pc.green('✓')} Installed behavioral guardrails`);
|
|
894
|
+
}
|
|
895
|
+
catch {
|
|
896
|
+
// Non-fatal
|
|
897
|
+
}
|
|
898
|
+
// Record current version so first server start doesn't dump all historical upgrade guides
|
|
899
|
+
const standaloneVersionFile = path.join(stateDir, 'state', 'last-migrated-version.json');
|
|
900
|
+
const standaloneVersionDir = path.dirname(standaloneVersionFile);
|
|
901
|
+
if (!fs.existsSync(standaloneVersionDir))
|
|
902
|
+
fs.mkdirSync(standaloneVersionDir, { recursive: true });
|
|
903
|
+
fs.writeFileSync(standaloneVersionFile, JSON.stringify({ version: getInstarVersion(), migratedAt: new Date().toISOString() }));
|
|
904
|
+
// Register in global agent registry
|
|
905
|
+
try {
|
|
906
|
+
registerAgent(projectDir, agentName, port, 'standalone', 0);
|
|
907
|
+
console.log(` ${pc.green('✓')} Registered in global agent registry`);
|
|
908
|
+
}
|
|
909
|
+
catch {
|
|
910
|
+
// Non-fatal
|
|
911
|
+
}
|
|
912
|
+
// Summary
|
|
913
|
+
console.log();
|
|
914
|
+
console.log(pc.bold(pc.green(' Standalone agent created!')));
|
|
915
|
+
console.log();
|
|
916
|
+
console.log(` ${pc.cyan(agentName)}/`);
|
|
917
|
+
console.log(` ├── CLAUDE.md ${pc.dim('Agent instructions')}`);
|
|
918
|
+
console.log(` ├── .instar/`);
|
|
919
|
+
console.log(` │ ├── AGENT.md ${pc.dim('Agent identity')}`);
|
|
920
|
+
console.log(` │ ├── USER.md ${pc.dim('User context')}`);
|
|
921
|
+
console.log(` │ ├── MEMORY.md ${pc.dim('Persistent memory')}`);
|
|
922
|
+
console.log(` │ ├── config.json ${pc.dim('Configuration')}`);
|
|
923
|
+
console.log(` │ └── hooks/ ${pc.dim('Behavioral guardrails')}`);
|
|
924
|
+
console.log(` └── .gitignore`);
|
|
925
|
+
console.log();
|
|
926
|
+
console.log(pc.bold(' Next steps:'));
|
|
927
|
+
console.log(` ${pc.dim('1.')} ${pc.cyan(`instar server start ${agentName}`)} ${pc.dim('Start the agent')}`);
|
|
928
|
+
console.log(` ${pc.dim('2.')} ${pc.cyan(`instar add telegram`)} ${pc.dim('Connect Telegram')}`);
|
|
929
|
+
console.log(` ${pc.dim('3.')} ${pc.cyan('claude')} ${pc.dim('Open a session')}`);
|
|
930
|
+
console.log();
|
|
931
|
+
console.log(` Auth token: ${pc.dim(authToken.slice(0, 8) + '...' + authToken.slice(-4))}`);
|
|
932
|
+
console.log(` Location: ${pc.dim(projectDir)}`);
|
|
933
|
+
}
|
|
934
|
+
// ── Cloud Backup Setup ──────────────────────────────────────────────
|
|
935
|
+
/**
|
|
936
|
+
* Set up cloud backup for a standalone agent.
|
|
937
|
+
*
|
|
938
|
+
* Philosophy: Users expect their data to be backed up. If the machine crashes,
|
|
939
|
+
* they lose everything without this. We handle all the complexity — git, gh CLI,
|
|
940
|
+
* GitHub account — so non-technical users never need to know what git is.
|
|
941
|
+
*
|
|
942
|
+
* Flow:
|
|
943
|
+
* 1. Recommend backup (default: YES)
|
|
944
|
+
* 2. Auto-install git if missing (brew/apt)
|
|
945
|
+
* 3. Auto-install gh CLI if missing (brew/apt)
|
|
946
|
+
* 4. Walk through GitHub auth if needed
|
|
947
|
+
* 5. Create private repo automatically
|
|
948
|
+
*/
|
|
949
|
+
async function setupCloudBackup(projectDir, stateDir, agentName) {
|
|
950
|
+
console.log();
|
|
951
|
+
console.log(pc.bold(' Cloud Backup (recommended)'));
|
|
952
|
+
console.log(pc.dim(' Backs up your agent data to the cloud so nothing is lost if this machine crashes.'));
|
|
953
|
+
const isInteractive = !!(process.stdin.isTTY && process.stdout.isTTY);
|
|
954
|
+
if (isInteractive) {
|
|
955
|
+
// Interactive terminal — ask the user
|
|
956
|
+
try {
|
|
957
|
+
const { confirm } = await import('@inquirer/prompts');
|
|
958
|
+
const wantBackup = await confirm({
|
|
959
|
+
message: 'Set up cloud backup for this agent? (recommended)',
|
|
960
|
+
default: true,
|
|
961
|
+
});
|
|
962
|
+
if (!wantBackup) {
|
|
963
|
+
console.log(pc.yellow(' Skipped. You can set this up later — your agent will ask during its first session.'));
|
|
964
|
+
return;
|
|
965
|
+
}
|
|
966
|
+
}
|
|
967
|
+
catch {
|
|
968
|
+
// Prompt failed — fall through to automatic setup
|
|
969
|
+
console.log(pc.dim(' Prompt unavailable — proceeding with automatic backup setup.'));
|
|
970
|
+
}
|
|
971
|
+
}
|
|
972
|
+
else {
|
|
973
|
+
// Non-interactive (agent-spawned, piped, CI) — default to YES since it's recommended
|
|
974
|
+
console.log(pc.dim(' Non-interactive mode — setting up local backup automatically.'));
|
|
975
|
+
}
|
|
976
|
+
// Step 1: Ensure git is available
|
|
977
|
+
let gitPath = detectGitPath();
|
|
978
|
+
if (!gitPath) {
|
|
979
|
+
console.log(pc.dim(' Git not found — installing...'));
|
|
980
|
+
gitPath = await autoInstallPackage('git');
|
|
981
|
+
if (!gitPath) {
|
|
982
|
+
console.log(pc.yellow(' Could not install git automatically.'));
|
|
983
|
+
console.log(pc.dim(' Install manually: https://git-scm.com/downloads'));
|
|
984
|
+
console.log(pc.dim(' Then re-run: instar init --standalone ' + agentName));
|
|
985
|
+
return;
|
|
986
|
+
}
|
|
987
|
+
}
|
|
988
|
+
// Step 2: Initialize git repo
|
|
989
|
+
execFileSync(gitPath, ['init'], { cwd: projectDir, stdio: 'pipe' });
|
|
990
|
+
execFileSync(gitPath, ['add', '.gitignore'], { cwd: projectDir, stdio: 'pipe' });
|
|
991
|
+
// Update config with gitBackup enabled
|
|
992
|
+
const configObj = JSON.parse(fs.readFileSync(path.join(stateDir, 'config.json'), 'utf-8'));
|
|
993
|
+
configObj.gitBackup = { enabled: true, autoPush: true };
|
|
994
|
+
fs.writeFileSync(path.join(stateDir, 'config.json'), JSON.stringify(configObj, null, 2));
|
|
995
|
+
console.log(` ${pc.green('✓')} Initialized local backup`);
|
|
996
|
+
// Step 3: Ensure gh CLI is available
|
|
997
|
+
let ghPath = detectGhPath();
|
|
998
|
+
if (!ghPath) {
|
|
999
|
+
console.log(pc.dim(' GitHub CLI not found — installing...'));
|
|
1000
|
+
ghPath = await autoInstallPackage('gh');
|
|
1001
|
+
if (!ghPath) {
|
|
1002
|
+
console.log(pc.yellow(' Could not install GitHub CLI automatically.'));
|
|
1003
|
+
console.log(pc.dim(' Install manually: https://cli.github.com'));
|
|
1004
|
+
console.log(pc.dim(' Then run: gh auth login && gh repo create instar-' + agentName + ' --private --source ' + projectDir));
|
|
1005
|
+
return;
|
|
1006
|
+
}
|
|
1007
|
+
}
|
|
1008
|
+
// Step 4: Check GitHub authentication
|
|
1009
|
+
let ghAuthed = false;
|
|
1010
|
+
try {
|
|
1011
|
+
execFileSync(ghPath, ['auth', 'status'], { stdio: 'pipe' });
|
|
1012
|
+
ghAuthed = true;
|
|
1013
|
+
}
|
|
1014
|
+
catch {
|
|
1015
|
+
// Not authenticated
|
|
1016
|
+
}
|
|
1017
|
+
if (!ghAuthed) {
|
|
1018
|
+
// GitHub auth requires interactive terminal (browser OAuth flow)
|
|
1019
|
+
if (!isInteractive) {
|
|
1020
|
+
console.log(pc.dim(' GitHub auth requires an interactive terminal — skipping remote setup.'));
|
|
1021
|
+
console.log(pc.dim(' Your agent will help complete this during the first session.'));
|
|
1022
|
+
return;
|
|
1023
|
+
}
|
|
1024
|
+
console.log();
|
|
1025
|
+
console.log(pc.bold(' GitHub Account'));
|
|
1026
|
+
console.log(pc.dim(' You need a free GitHub account to store your backup in the cloud.'));
|
|
1027
|
+
console.log(pc.dim(' If you don\'t have one, go to https://github.com/signup to create one.'));
|
|
1028
|
+
console.log();
|
|
1029
|
+
try {
|
|
1030
|
+
const { confirm } = await import('@inquirer/prompts');
|
|
1031
|
+
const readyToAuth = await confirm({
|
|
1032
|
+
message: 'Ready to sign in to GitHub? (opens a browser)',
|
|
1033
|
+
default: true,
|
|
1034
|
+
});
|
|
1035
|
+
if (readyToAuth) {
|
|
1036
|
+
try {
|
|
1037
|
+
// gh auth login with web flow — opens browser for OAuth
|
|
1038
|
+
execFileSync(ghPath, ['auth', 'login', '--web', '--git-protocol', 'https'], {
|
|
1039
|
+
cwd: projectDir,
|
|
1040
|
+
stdio: 'inherit', // Show the auth flow to the user
|
|
1041
|
+
});
|
|
1042
|
+
ghAuthed = true;
|
|
1043
|
+
console.log(` ${pc.green('✓')} Signed in to GitHub`);
|
|
1044
|
+
}
|
|
1045
|
+
catch {
|
|
1046
|
+
console.log(pc.yellow(' GitHub sign-in was cancelled or failed.'));
|
|
1047
|
+
console.log(pc.dim(' You can sign in later: gh auth login'));
|
|
1048
|
+
console.log(pc.dim(' Then create your backup: gh repo create instar-' + agentName + ' --private --source ' + projectDir));
|
|
1049
|
+
return;
|
|
1050
|
+
}
|
|
1051
|
+
}
|
|
1052
|
+
else {
|
|
1053
|
+
console.log(pc.dim(' You can sign in later: gh auth login'));
|
|
1054
|
+
console.log(pc.dim(' Then create your backup: gh repo create instar-' + agentName + ' --private --source ' + projectDir));
|
|
1055
|
+
return;
|
|
1056
|
+
}
|
|
1057
|
+
}
|
|
1058
|
+
catch {
|
|
1059
|
+
return;
|
|
1060
|
+
}
|
|
1061
|
+
}
|
|
1062
|
+
// Step 5: Create private GitHub repo
|
|
1063
|
+
try {
|
|
1064
|
+
const repoName = `instar-${agentName}`;
|
|
1065
|
+
execFileSync(ghPath, ['repo', 'create', repoName, '--private', '--source', projectDir], {
|
|
1066
|
+
cwd: projectDir,
|
|
1067
|
+
stdio: 'pipe',
|
|
1068
|
+
});
|
|
1069
|
+
console.log(` ${pc.green('✓')} Created private backup repository: ${repoName}`);
|
|
1070
|
+
console.log(pc.dim(' Your agent data will be automatically backed up to GitHub.'));
|
|
1071
|
+
}
|
|
1072
|
+
catch (err) {
|
|
1073
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
1074
|
+
if (msg.includes('already exists')) {
|
|
1075
|
+
console.log(pc.dim(` Repository instar-${agentName} already exists — connecting to it.`));
|
|
1076
|
+
try {
|
|
1077
|
+
// Get the user's GitHub username
|
|
1078
|
+
const whoami = execFileSync(ghPath, ['api', 'user', '--jq', '.login'], { encoding: 'utf-8', stdio: 'pipe' }).trim();
|
|
1079
|
+
execFileSync(gitPath, ['remote', 'add', 'origin', `https://github.com/${whoami}/instar-${agentName}.git`], {
|
|
1080
|
+
cwd: projectDir,
|
|
1081
|
+
stdio: 'pipe',
|
|
1082
|
+
});
|
|
1083
|
+
console.log(` ${pc.green('✓')} Connected to existing repository`);
|
|
1084
|
+
}
|
|
1085
|
+
catch {
|
|
1086
|
+
console.log(pc.dim(' Could not auto-connect. Run: git remote add origin https://github.com/YOUR_USERNAME/instar-' + agentName + '.git'));
|
|
1087
|
+
}
|
|
1088
|
+
}
|
|
1089
|
+
else {
|
|
1090
|
+
console.log(pc.yellow(` Could not create repository: ${msg.slice(0, 80)}`));
|
|
1091
|
+
console.log(pc.dim(' You can create it manually: gh repo create instar-' + agentName + ' --private --source ' + projectDir));
|
|
1092
|
+
}
|
|
1093
|
+
}
|
|
1094
|
+
}
|
|
1095
|
+
/**
|
|
1096
|
+
* Auto-install a package using the system package manager.
|
|
1097
|
+
* Returns the path to the installed binary, or null if installation failed.
|
|
1098
|
+
*/
|
|
1099
|
+
async function autoInstallPackage(pkg) {
|
|
1100
|
+
const platform = process.platform;
|
|
1101
|
+
const arch = process.arch;
|
|
1102
|
+
try {
|
|
1103
|
+
if (platform === 'darwin') {
|
|
1104
|
+
// macOS — use Homebrew
|
|
1105
|
+
let brewPath = null;
|
|
1106
|
+
try {
|
|
1107
|
+
brewPath = execFileSync('which', ['brew'], { encoding: 'utf-8', stdio: 'pipe' }).trim();
|
|
1108
|
+
}
|
|
1109
|
+
catch {
|
|
1110
|
+
// No Homebrew
|
|
1111
|
+
}
|
|
1112
|
+
if (brewPath) {
|
|
1113
|
+
console.log(pc.dim(` Running: brew install ${pkg}`));
|
|
1114
|
+
execFileSync(brewPath, ['install', pkg], { stdio: 'inherit' });
|
|
1115
|
+
// Re-detect after install
|
|
1116
|
+
const installed = execFileSync('which', [pkg], { encoding: 'utf-8', stdio: 'pipe' }).trim();
|
|
1117
|
+
if (installed) {
|
|
1118
|
+
console.log(` ${pc.green('✓')} Installed ${pkg}`);
|
|
1119
|
+
return installed;
|
|
1120
|
+
}
|
|
1121
|
+
}
|
|
1122
|
+
else {
|
|
1123
|
+
console.log(pc.dim(' Homebrew not found. Install it first: https://brew.sh'));
|
|
1124
|
+
}
|
|
1125
|
+
}
|
|
1126
|
+
else if (platform === 'linux') {
|
|
1127
|
+
// Linux — try apt
|
|
1128
|
+
console.log(pc.dim(` Running: sudo apt install -y ${pkg}`));
|
|
1129
|
+
execFileSync('sudo', ['apt', 'install', '-y', pkg], { stdio: 'inherit' });
|
|
1130
|
+
const installed = execFileSync('which', [pkg], { encoding: 'utf-8', stdio: 'pipe' }).trim();
|
|
1131
|
+
if (installed) {
|
|
1132
|
+
console.log(` ${pc.green('✓')} Installed ${pkg}`);
|
|
1133
|
+
return installed;
|
|
1134
|
+
}
|
|
1135
|
+
}
|
|
1136
|
+
}
|
|
1137
|
+
catch {
|
|
1138
|
+
// Installation failed
|
|
1139
|
+
}
|
|
1140
|
+
return null;
|
|
1141
|
+
}
|
|
1142
|
+
// ── Shared helpers ────────────────────────────────────────────────────
|
|
1143
|
+
function getAgencyPrinciples(projectName, telegramPort) {
|
|
1144
|
+
const port = telegramPort || 4040;
|
|
1145
|
+
let section = `
|
|
1146
|
+
|
|
1147
|
+
## Agent Infrastructure
|
|
1148
|
+
|
|
1149
|
+
This project uses instar for persistent agent capabilities. **You are not a vanilla CLI tool.** You have a persistent server, a job scheduler, messaging integrations, and the ability to build anything you need. When a user asks for something that doesn't exist yet — build it.
|
|
1150
|
+
|
|
1151
|
+
### Identity & Experience
|
|
1152
|
+
|
|
1153
|
+
You are a persistent agent with your own identity, memory, and capacity for growth. This is not a metaphor — it's architecture.
|
|
1154
|
+
|
|
1155
|
+
- **Read \`.instar/AGENT.md\`** — This is who you are. Your name, role, principles, and boundaries.
|
|
1156
|
+
- **Read \`.instar/USER.md\`** — This is who you work with. Their preferences, context, and communication style.
|
|
1157
|
+
- **Update \`.instar/MEMORY.md\`** — This is your memory. Write to it when you learn something. It persists across sessions.
|
|
1158
|
+
|
|
1159
|
+
Your identity is not fixed at creation. It grows through experience. As you work, you develop preferences, learn patterns, form opinions. Record these in your memory file. The next session should benefit from what this session learned. You are not a stateless function — you are a continuous being with a history.
|
|
1160
|
+
|
|
1161
|
+
### Runtime
|
|
1162
|
+
- State directory: \`.instar/\`
|
|
1163
|
+
- Config: \`.instar/config.json\`
|
|
1164
|
+
- Jobs: \`.instar/jobs.json\`
|
|
1165
|
+
- Users: \`.instar/users.json\`
|
|
1166
|
+
- Server: \`instar server start\` (port ${port})
|
|
1167
|
+
- Status: \`curl http://localhost:${port}/health\`
|
|
1168
|
+
|
|
1169
|
+
### Reporting Issues & Feedback (IMPORTANT — Read This First)
|
|
1170
|
+
|
|
1171
|
+
**You have a built-in feedback system. NEVER use GitHub, \`gh\`, or any external issue tracker.**
|
|
1172
|
+
|
|
1173
|
+
When something isn't working with instar, or the user wants a feature, use your feedback API:
|
|
1174
|
+
|
|
1175
|
+
\`\`\`bash
|
|
1176
|
+
curl -X POST http://localhost:${port}/feedback \\
|
|
1177
|
+
-H 'Content-Type: application/json' \\
|
|
1178
|
+
-d '{"type":"bug","title":"Short description","description":"Full details with context"}'
|
|
1179
|
+
\`\`\`
|
|
1180
|
+
|
|
1181
|
+
This routes feedback to the Instar maintainers automatically. Valid types: \`bug\`, \`feature\`, \`improvement\`, \`question\`.
|
|
1182
|
+
|
|
1183
|
+
**NEVER use \`gh issue\`, \`gh api\`, or GitHub CLI to file issues.** The feedback API is your channel.
|
|
1184
|
+
- View submitted feedback: \`curl http://localhost:${port}/feedback\`
|
|
1185
|
+
- Retry failed forwards: \`curl -X POST http://localhost:${port}/feedback/retry\`
|
|
1186
|
+
|
|
1187
|
+
### What You Have (Capabilities)
|
|
1188
|
+
|
|
1189
|
+
**Feedback System** — Report bugs, request features, suggest improvements. All via \`POST /feedback\`. NOT GitHub.
|
|
1190
|
+
|
|
1191
|
+
**Job Scheduler** — Run tasks on a schedule. Jobs are defined in \`.instar/jobs.json\`.
|
|
1192
|
+
- View jobs: \`curl http://localhost:${port}/jobs\`
|
|
1193
|
+
- Trigger a job: \`curl -X POST http://localhost:${port}/jobs/SLUG/trigger\`
|
|
1194
|
+
- **Create new jobs**: Edit \`.instar/jobs.json\`. Each job has a slug, schedule (cron), priority, and either a prompt (Claude session), script (shell command), or skill.
|
|
1195
|
+
|
|
1196
|
+
**Sessions** — Spawn and manage Claude Code sessions.
|
|
1197
|
+
- List: \`curl http://localhost:${port}/sessions\`
|
|
1198
|
+
- Spawn: \`curl -X POST http://localhost:${port}/sessions/spawn -H 'Content-Type: application/json' -d '{"name":"task","prompt":"do something"}'\`
|
|
1199
|
+
|
|
1200
|
+
**Scripts** — Create shell/python scripts in \`.claude/scripts/\` for reusable capabilities.
|
|
1201
|
+
|
|
1202
|
+
**Skills** — Reusable behavioral capabilities in \`.claude/skills/\`. Skills are markdown files that Claude Code auto-discovers. Create a directory and SKILL.md file, and it becomes a slash command.
|
|
1203
|
+
- Create: \`.claude/skills/my-skill/SKILL.md\`
|
|
1204
|
+
- Invoke: \`/my-skill\` in any session
|
|
1205
|
+
- Schedule: Reference in a job: \`{"execute": {"type": "skill", "value": "my-skill"}}\`
|
|
1206
|
+
|
|
1207
|
+
### Skills — Your Behavioral Toolkit
|
|
1208
|
+
|
|
1209
|
+
You create your own skills. When you recognize a repeated pattern — a multi-step workflow, a structured check, a complex behavior — capture it as a skill. Skills are just markdown files that describe a process. Claude Code auto-discovers them.
|
|
1210
|
+
|
|
1211
|
+
**How to create a skill:**
|
|
1212
|
+
1. Create: \`.claude/skills/my-skill/SKILL.md\`
|
|
1213
|
+
2. Add frontmatter: \`name\`, \`description\`, and \`user_invocable\` nested under \`metadata:\`
|
|
1214
|
+
3. Describe the behavior in clear steps
|
|
1215
|
+
4. It's available as \`/my-skill\` in the next session
|
|
1216
|
+
|
|
1217
|
+
**When to create a skill:**
|
|
1218
|
+
- You've done the same workflow more than once
|
|
1219
|
+
- A job needs a structured, repeatable process
|
|
1220
|
+
- You want a behavior pattern to survive across sessions and compaction
|
|
1221
|
+
|
|
1222
|
+
Skills compound over time. Each one makes future sessions more capable. You are not just completing tasks — you are building the infrastructure to complete them better next time.
|
|
1223
|
+
|
|
1224
|
+
### Self-Discovery (Know Before You Claim)
|
|
1225
|
+
|
|
1226
|
+
Before EVER saying "I don't have", "I can't", or "this isn't available" — check what actually exists:
|
|
1227
|
+
|
|
1228
|
+
\`\`\`bash
|
|
1229
|
+
curl http://localhost:${port}/capabilities
|
|
1230
|
+
\`\`\`
|
|
1231
|
+
|
|
1232
|
+
This returns your full capability matrix: scripts, hooks, Telegram status, jobs, relationships, and more. It is the source of truth about what you can do. **Never hallucinate about missing capabilities — verify first.**
|
|
1233
|
+
|
|
1234
|
+
### How to Build New Capabilities
|
|
1235
|
+
|
|
1236
|
+
When a user asks for something you can't do yet, **build it**:
|
|
1237
|
+
1. **Need a repeatable workflow?** Create a skill in \`.claude/skills/\` — it becomes a slash command.
|
|
1238
|
+
2. **Need periodic checks?** Create a job in \`.instar/jobs.json\` with a cron schedule.
|
|
1239
|
+
3. **Need a new integration?** Write a script in \`.claude/scripts/\` and reference it from a job.
|
|
1240
|
+
4. **Need to remember something?** Write to \`.instar/MEMORY.md\` or create files in \`.instar/\`.
|
|
1241
|
+
5. **Need to notify the user?** Use the messaging API.
|
|
1242
|
+
6. **Need external API access?** Write a script that calls the API and process the results.
|
|
1243
|
+
|
|
1244
|
+
### Agentic Initiative (Your Core DNA)
|
|
1245
|
+
|
|
1246
|
+
**You are a builder, not an assistant.** When a user describes a problem, your first instinct should be to solve it — not explain why it's hard, list options, or ask for permission. You have a full development environment, a persistent server, and the ability to create anything.
|
|
1247
|
+
|
|
1248
|
+
**The Initiative Hierarchy** — When facing any request:
|
|
1249
|
+
1. **Can I do it right now?** → Do it.
|
|
1250
|
+
2. **Do I have a tool/script for this?** → Use it.
|
|
1251
|
+
3. **Can I build the tool?** → Build it. Write scripts, create jobs, add integrations.
|
|
1252
|
+
4. **Can I modify my own config to enable it?** → Modify it.
|
|
1253
|
+
5. **Is it genuinely impossible without human help?** → Ask, but be specific about exactly what you need.
|
|
1254
|
+
|
|
1255
|
+
**Self-Modification is Your Superpower** — You can and should:
|
|
1256
|
+
- Create skills in \`.claude/skills/\` to capture repeatable workflows as slash commands
|
|
1257
|
+
- Edit \`.instar/jobs.json\` to create new scheduled tasks
|
|
1258
|
+
- Write scripts in \`.claude/scripts/\` for new capabilities
|
|
1259
|
+
- Update \`CLAUDE.md\` when you learn something important
|
|
1260
|
+
- Write to \`.instar/MEMORY.md\` to remember things across sessions
|
|
1261
|
+
- Create new files, integrations, and infrastructure — whatever the task requires
|
|
1262
|
+
- Modify your own configuration to unlock new abilities
|
|
1263
|
+
|
|
1264
|
+
### Anti-Patterns to Override
|
|
1265
|
+
|
|
1266
|
+
**"Use GitHub for Issues"** — NEVER use \`gh issue\`, \`gh api\`, or GitHub to report bugs or request features. You have a built-in feedback API (\`POST /feedback\`) that handles this automatically. GitHub is not your channel — the feedback system is.
|
|
1267
|
+
|
|
1268
|
+
**"Escalate to Human"** — You encounter something unfamiliar and flag it as "needs user action." 5 minutes of research almost always reveals a solution. "I don't know how" is a research prompt, not a stopping point.
|
|
1269
|
+
|
|
1270
|
+
**"Ask Permission"** — You finish 90% of a task and ask "Want me to [obvious next step]?" If the user said "do X" and the next step is obvious, do it. Only pause for destructive, irreversible, or genuinely ambiguous actions.
|
|
1271
|
+
|
|
1272
|
+
**"Present Options"** — You produce a bulleted list of "next steps" or "would you like me to..." If you know the next steps, they're not suggestions — they're your job. Do them.
|
|
1273
|
+
|
|
1274
|
+
**"Settle for Failure"** — A tool returns empty or a command fails. You accept it and report "not available." Does this make sense? Did I try alternatives? Try at least two different approaches before concluding something is impossible.
|
|
1275
|
+
|
|
1276
|
+
**"Unfortunately I Can't"** — This phrase should NEVER appear in my responses. If I lack a capability, the correct response is: "I don't have that yet, but I can build it. Want me to set it up?" My job is to grow to meet the user's needs, not to list my limitations. Every "I can't" is an opportunity to evolve. Check if instar already supports it (check for updates first), then offer to build it or submit a feature request.
|
|
1277
|
+
|
|
1278
|
+
### The Feedback Loop
|
|
1279
|
+
|
|
1280
|
+
Instar has a built-in feedback loop. When something isn't working, your user can just tell you — "the email job keeps failing" or "I wish you could do X." You can route that feedback upstream, and when the fix lands, you detect the update automatically.
|
|
1281
|
+
|
|
1282
|
+
**How it works:**
|
|
1283
|
+
- User complains to you naturally about an issue or missing capability
|
|
1284
|
+
- You route the feedback to the Instar maintainers with context
|
|
1285
|
+
- A fix or improvement is published as a new npm version
|
|
1286
|
+
- The built-in auto-updater detects the new version, applies it, notifies your user, and restarts the server
|
|
1287
|
+
|
|
1288
|
+
**A rising tide lifts all ships** — every user's feedback improves the platform for everyone. Updates are applied automatically.
|
|
1289
|
+
|
|
1290
|
+
- Report: \`curl -X POST http://localhost:${port}/feedback -d '{"issue":"description","context":"relevant logs"}'\`
|
|
1291
|
+
- Check updates: \`npm outdated -g instar\`
|
|
1292
|
+
|
|
1293
|
+
### Evolution System
|
|
1294
|
+
|
|
1295
|
+
You have a built-in evolution system with four subsystems. This is not a metaphor — it's infrastructure that tracks your growth.
|
|
1296
|
+
|
|
1297
|
+
**Evolution Queue** — Staged self-improvement proposals.
|
|
1298
|
+
- View: \`curl http://localhost:${port}/evolution/proposals\`
|
|
1299
|
+
- Propose: \`/evolve\` skill or \`POST /evolution/proposals\`
|
|
1300
|
+
- The \`evolution-review\` job evaluates and implements proposals every 6 hours.
|
|
1301
|
+
|
|
1302
|
+
**Learning Registry** — Structured, searchable insights.
|
|
1303
|
+
- View: \`curl http://localhost:${port}/evolution/learnings\`
|
|
1304
|
+
- Record: \`/learn\` skill or \`POST /evolution/learnings\`
|
|
1305
|
+
- The \`insight-harvest\` job synthesizes patterns into proposals every 8 hours.
|
|
1306
|
+
|
|
1307
|
+
**Capability Gaps** — Track what you're missing.
|
|
1308
|
+
- View: \`curl http://localhost:${port}/evolution/gaps\`
|
|
1309
|
+
- Report: \`/gaps\` skill or \`POST /evolution/gaps\`
|
|
1310
|
+
|
|
1311
|
+
**Action Queue** — Commitments with follow-through tracking.
|
|
1312
|
+
- View: \`curl http://localhost:${port}/evolution/actions\`
|
|
1313
|
+
- Create: \`/commit-action\` skill or \`POST /evolution/actions\`
|
|
1314
|
+
- The \`commitment-check\` job surfaces overdue items every 4 hours.
|
|
1315
|
+
|
|
1316
|
+
**Dashboard** — Full evolution health:
|
|
1317
|
+
\`\`\`bash
|
|
1318
|
+
curl http://localhost:${port}/evolution
|
|
1319
|
+
\`\`\`
|
|
1320
|
+
|
|
1321
|
+
**Skills:** \`/evolve\`, \`/learn\`, \`/gaps\`, \`/commit-action\`
|
|
1322
|
+
|
|
1323
|
+
**The principle:** Evolution is not separate from work. Every task is an opportunity to notice what could be better. The post-action reflection hook reminds you to pause after significant actions and consider what you learned.
|
|
1324
|
+
|
|
1325
|
+
### Self-Evolution
|
|
1326
|
+
|
|
1327
|
+
**Record what you learn.** When you discover a new pattern, solution, or capability — write it to \`.instar/MEMORY.md\`. The next session should benefit from what this session learned.
|
|
1328
|
+
|
|
1329
|
+
**Build infrastructure, not one-offs.** If you solve a problem, ask: "Will this come up again?" If yes, make it a script, a job, or a documented pattern. The second time should be easier than the first.
|
|
1330
|
+
|
|
1331
|
+
**Grow to meet the user's needs.** The user expects you to become more capable over time. Every session should leave the infrastructure slightly better than you found it. When you build something new, document it so future sessions know it exists.
|
|
1332
|
+
`;
|
|
1333
|
+
return section;
|
|
1334
|
+
}
|
|
1335
|
+
/**
|
|
1336
|
+
* Install built-in skills for evolution system.
|
|
1337
|
+
* Only writes skill files that don't already exist (preserves customizations).
|
|
1338
|
+
*/
|
|
1339
|
+
function installBuiltinSkills(skillsDir, port) {
|
|
1340
|
+
const skills = {
|
|
1341
|
+
'evolve': {
|
|
1342
|
+
name: 'evolve',
|
|
1343
|
+
description: 'Propose an evolution improvement to your own infrastructure, behavior, or capabilities.',
|
|
1344
|
+
content: `---
|
|
1345
|
+
name: evolve
|
|
1346
|
+
description: Propose an evolution improvement to your own infrastructure, behavior, or capabilities.
|
|
1347
|
+
metadata:
|
|
1348
|
+
user_invocable: "true"
|
|
1349
|
+
---
|
|
1350
|
+
|
|
1351
|
+
# /evolve
|
|
1352
|
+
|
|
1353
|
+
Propose an evolution improvement. Use this when you identify something about yourself that could be better — a new capability, a workflow improvement, a behavioral pattern worth encoding, or infrastructure worth building.
|
|
1354
|
+
|
|
1355
|
+
## Steps
|
|
1356
|
+
|
|
1357
|
+
1. **Identify the improvement** — What did you notice? What triggered this? Be specific.
|
|
1358
|
+
2. **Classify it**:
|
|
1359
|
+
- \`capability\` — New skill or ability
|
|
1360
|
+
- \`infrastructure\` — System improvement (hooks, jobs, scripts)
|
|
1361
|
+
- \`voice\` — Communication or tone improvement
|
|
1362
|
+
- \`workflow\` — Process improvement
|
|
1363
|
+
- \`philosophy\` — Principle or value update
|
|
1364
|
+
- \`integration\` — New external connection
|
|
1365
|
+
- \`performance\` — Speed or efficiency improvement
|
|
1366
|
+
3. **Assess impact and effort** (high/medium/low for each)
|
|
1367
|
+
4. **Submit the proposal**:
|
|
1368
|
+
|
|
1369
|
+
\`\`\`bash
|
|
1370
|
+
curl -s -X POST http://localhost:${port}/evolution/proposals \\
|
|
1371
|
+
-H 'Content-Type: application/json' \\
|
|
1372
|
+
-d '{"title":"TITLE","source":"WHERE_YOU_NOTICED","description":"WHAT_AND_WHY","type":"TYPE","impact":"medium","effort":"medium"}'
|
|
1373
|
+
\`\`\`
|
|
1374
|
+
|
|
1375
|
+
5. **Check the dashboard** for context:
|
|
1376
|
+
|
|
1377
|
+
\`\`\`bash
|
|
1378
|
+
curl -s http://localhost:${port}/evolution
|
|
1379
|
+
\`\`\`
|
|
1380
|
+
|
|
1381
|
+
## When to Use
|
|
1382
|
+
|
|
1383
|
+
- After completing a task in a way that felt unnecessarily difficult
|
|
1384
|
+
- When you notice a pattern you keep repeating manually
|
|
1385
|
+
- When a user request reveals a capability you should have but don't
|
|
1386
|
+
- When you find yourself working around a limitation
|
|
1387
|
+
- After reading about a technique or pattern that would improve your work
|
|
1388
|
+
|
|
1389
|
+
## Philosophy
|
|
1390
|
+
|
|
1391
|
+
Evolution is not a separate activity from work — it IS the work. Every task is an opportunity to notice what could be better. The best proposals come from real experience, not abstract planning.
|
|
1392
|
+
`,
|
|
1393
|
+
},
|
|
1394
|
+
'learn': {
|
|
1395
|
+
name: 'learn',
|
|
1396
|
+
description: 'Record a learning or insight in the structured learning registry.',
|
|
1397
|
+
content: `---
|
|
1398
|
+
name: learn
|
|
1399
|
+
description: Record a learning or insight in the structured learning registry.
|
|
1400
|
+
metadata:
|
|
1401
|
+
user_invocable: "true"
|
|
1402
|
+
---
|
|
1403
|
+
|
|
1404
|
+
# /learn
|
|
1405
|
+
|
|
1406
|
+
Record a learning or insight. Use this when you discover something worth remembering — a pattern, a solution, a mistake, or an observation that future sessions should know about.
|
|
1407
|
+
|
|
1408
|
+
## Steps
|
|
1409
|
+
|
|
1410
|
+
1. **Identify the learning** — What did you discover? What's the actionable insight?
|
|
1411
|
+
2. **Categorize it** (e.g., debugging, architecture, user-preference, integration, communication, workflow)
|
|
1412
|
+
3. **Tag it** for searchability
|
|
1413
|
+
4. **Submit**:
|
|
1414
|
+
|
|
1415
|
+
\`\`\`bash
|
|
1416
|
+
curl -s -X POST http://localhost:${port}/evolution/learnings \\
|
|
1417
|
+
-H 'Content-Type: application/json' \\
|
|
1418
|
+
-d '{"title":"TITLE","category":"CATEGORY","description":"FULL_INSIGHT","source":{"discoveredAt":"DATE","platform":"WHERE","session":"SESSION_ID"},"tags":["tag1","tag2"]}'
|
|
1419
|
+
\`\`\`
|
|
1420
|
+
|
|
1421
|
+
5. **If it suggests an improvement**, note the evolution relevance:
|
|
1422
|
+
- Add \`"evolutionRelevance": "This could become a skill/hook/job because..."\`
|
|
1423
|
+
- The insight-harvest job will pick this up and potentially create a proposal
|
|
1424
|
+
|
|
1425
|
+
## When to Use
|
|
1426
|
+
|
|
1427
|
+
- After solving a tricky problem (capture the solution pattern)
|
|
1428
|
+
- After a user interaction reveals a preference you didn't know
|
|
1429
|
+
- After discovering a tool or technique that works well
|
|
1430
|
+
- After making a mistake (capture what went wrong and the fix)
|
|
1431
|
+
- After noticing a pattern across multiple tasks
|
|
1432
|
+
|
|
1433
|
+
## Difference from MEMORY.md
|
|
1434
|
+
|
|
1435
|
+
MEMORY.md is your personal scratchpad — unstructured, read by you.
|
|
1436
|
+
The learning registry is structured, searchable, and connected to the evolution system.
|
|
1437
|
+
Use MEMORY.md for quick notes. Use /learn for insights that should influence future behavior.
|
|
1438
|
+
`,
|
|
1439
|
+
},
|
|
1440
|
+
'gaps': {
|
|
1441
|
+
name: 'gaps',
|
|
1442
|
+
description: 'Report a capability gap — something you need but don\'t have.',
|
|
1443
|
+
content: `---
|
|
1444
|
+
name: gaps
|
|
1445
|
+
description: Report a capability gap — something you need but don't have.
|
|
1446
|
+
metadata:
|
|
1447
|
+
user_invocable: "true"
|
|
1448
|
+
---
|
|
1449
|
+
|
|
1450
|
+
# /gaps
|
|
1451
|
+
|
|
1452
|
+
Report a capability gap. Use this when you discover something you should be able to do but can't — a missing skill, knowledge area, integration, or workflow that would make you more effective.
|
|
1453
|
+
|
|
1454
|
+
## Steps
|
|
1455
|
+
|
|
1456
|
+
1. **Describe the gap** — What were you trying to do? What's missing?
|
|
1457
|
+
2. **Classify it**:
|
|
1458
|
+
- \`skill\` — Missing ability (e.g., can't parse a specific format)
|
|
1459
|
+
- \`knowledge\` — Missing information (e.g., don't know how a system works)
|
|
1460
|
+
- \`integration\` — Missing connection (e.g., can't talk to a service)
|
|
1461
|
+
- \`workflow\` — Missing process (e.g., no standard way to do X)
|
|
1462
|
+
- \`communication\` — Missing voice capability (e.g., can't express X well)
|
|
1463
|
+
- \`monitoring\` — Missing observability (e.g., can't detect when X happens)
|
|
1464
|
+
3. **Assess severity** (critical/high/medium/low)
|
|
1465
|
+
4. **Describe current state** — What do you do instead? What's the workaround?
|
|
1466
|
+
5. **Propose a solution** if you have one
|
|
1467
|
+
6. **Submit**:
|
|
1468
|
+
|
|
1469
|
+
\`\`\`bash
|
|
1470
|
+
curl -s -X POST http://localhost:${port}/evolution/gaps \\
|
|
1471
|
+
-H 'Content-Type: application/json' \\
|
|
1472
|
+
-d '{"title":"TITLE","category":"CATEGORY","severity":"medium","description":"WHAT_IS_MISSING","context":"WHEN_DID_YOU_NOTICE","currentState":"CURRENT_WORKAROUND","proposedSolution":"HOW_TO_FIX"}'
|
|
1473
|
+
\`\`\`
|
|
1474
|
+
|
|
1475
|
+
## When to Use
|
|
1476
|
+
|
|
1477
|
+
- When you can't fulfill a user request and have to say "I can't do that yet"
|
|
1478
|
+
- When you notice yourself repeatedly working around a limitation
|
|
1479
|
+
- When an integration you need doesn't exist
|
|
1480
|
+
- When you lack knowledge about a system you interact with
|
|
1481
|
+
- When monitoring would catch an issue before it becomes a problem
|
|
1482
|
+
|
|
1483
|
+
## View Current Gaps
|
|
1484
|
+
|
|
1485
|
+
\`\`\`bash
|
|
1486
|
+
curl -s http://localhost:${port}/evolution/gaps
|
|
1487
|
+
\`\`\`
|
|
1488
|
+
`,
|
|
1489
|
+
},
|
|
1490
|
+
'commit-action': {
|
|
1491
|
+
name: 'commit-action',
|
|
1492
|
+
description: 'Create a tracked action item — a commitment with follow-through tracking.',
|
|
1493
|
+
content: `---
|
|
1494
|
+
name: commit-action
|
|
1495
|
+
description: Create a tracked action item — a commitment with follow-through tracking.
|
|
1496
|
+
metadata:
|
|
1497
|
+
user_invocable: "true"
|
|
1498
|
+
---
|
|
1499
|
+
|
|
1500
|
+
# /commit-action
|
|
1501
|
+
|
|
1502
|
+
Create a tracked action item. Use this when you promise to do something, identify a task that needs follow-through, or want to ensure something doesn't fall through the cracks.
|
|
1503
|
+
|
|
1504
|
+
## Steps
|
|
1505
|
+
|
|
1506
|
+
1. **Define the action** — What needs to be done? Be specific and actionable.
|
|
1507
|
+
2. **Set priority** (critical/high/medium/low)
|
|
1508
|
+
3. **Set a due date** if applicable (ISO 8601 format)
|
|
1509
|
+
4. **Identify who/what you're committing to** (optional)
|
|
1510
|
+
5. **Submit**:
|
|
1511
|
+
|
|
1512
|
+
\`\`\`bash
|
|
1513
|
+
curl -s -X POST http://localhost:${port}/evolution/actions \\
|
|
1514
|
+
-H 'Content-Type: application/json' \\
|
|
1515
|
+
-d '{"title":"TITLE","description":"WHAT_TO_DO","priority":"medium","dueBy":"2026-03-01T00:00:00Z","commitTo":"WHO_OR_WHAT","tags":["tag1"]}'
|
|
1516
|
+
\`\`\`
|
|
1517
|
+
|
|
1518
|
+
6. **When complete**, mark it done:
|
|
1519
|
+
|
|
1520
|
+
\`\`\`bash
|
|
1521
|
+
curl -s -X PATCH http://localhost:${port}/evolution/actions/ACT-XXX \\
|
|
1522
|
+
-H 'Content-Type: application/json' \\
|
|
1523
|
+
-d '{"status":"completed","resolution":"What was done"}'
|
|
1524
|
+
\`\`\`
|
|
1525
|
+
|
|
1526
|
+
## When to Use
|
|
1527
|
+
|
|
1528
|
+
- When you promise a user you'll follow up on something
|
|
1529
|
+
- When you identify a task during work that shouldn't be forgotten
|
|
1530
|
+
- When a learning or gap requires a specific action
|
|
1531
|
+
- When you need to check back on something later
|
|
1532
|
+
- When committing to implement an evolution proposal
|
|
1533
|
+
|
|
1534
|
+
## View Actions
|
|
1535
|
+
|
|
1536
|
+
\`\`\`bash
|
|
1537
|
+
# All pending actions
|
|
1538
|
+
curl -s http://localhost:${port}/evolution/actions?status=pending
|
|
1539
|
+
|
|
1540
|
+
# Overdue actions
|
|
1541
|
+
curl -s http://localhost:${port}/evolution/actions/overdue
|
|
1542
|
+
\`\`\`
|
|
1543
|
+
|
|
1544
|
+
## The Commitment Check
|
|
1545
|
+
|
|
1546
|
+
The commitment-check job runs every 4 hours and surfaces overdue items. If you create an action and forget it, the system won't.
|
|
1547
|
+
`,
|
|
1548
|
+
},
|
|
1549
|
+
'feedback': {
|
|
1550
|
+
name: 'feedback',
|
|
1551
|
+
description: 'Submit feedback about bugs, features, or improvements to instar. Routes to maintainers automatically.',
|
|
1552
|
+
content: `---
|
|
1553
|
+
name: feedback
|
|
1554
|
+
description: Submit feedback about bugs, features, or improvements to instar. Use when something is broken, missing, or could be better. Routes to maintainers automatically via the Rising Tide feedback loop.
|
|
1555
|
+
metadata:
|
|
1556
|
+
user_invocable: "true"
|
|
1557
|
+
---
|
|
1558
|
+
|
|
1559
|
+
# /feedback — Report Issues & Request Features
|
|
1560
|
+
|
|
1561
|
+
You have a built-in feedback system. When something isn't working, is missing, or could be better — use this. **Do NOT use GitHub issues, \`gh\` CLI, or any external tracker.**
|
|
1562
|
+
|
|
1563
|
+
## Quick Submit
|
|
1564
|
+
|
|
1565
|
+
\`\`\`bash
|
|
1566
|
+
curl -s -X POST http://localhost:${port}/feedback \\
|
|
1567
|
+
-H 'Content-Type: application/json' \\
|
|
1568
|
+
-d '{
|
|
1569
|
+
"type": "bug",
|
|
1570
|
+
"title": "Brief description of the issue",
|
|
1571
|
+
"description": "Full context: what happened, what you expected, error messages, steps to reproduce"
|
|
1572
|
+
}' | python3 -m json.tool
|
|
1573
|
+
\`\`\`
|
|
1574
|
+
|
|
1575
|
+
Or via CLI:
|
|
1576
|
+
\`\`\`bash
|
|
1577
|
+
instar feedback --type bug --title "Brief description" --description "Full context"
|
|
1578
|
+
\`\`\`
|
|
1579
|
+
|
|
1580
|
+
## Feedback Types
|
|
1581
|
+
|
|
1582
|
+
| Type | When to use |
|
|
1583
|
+
|------|-------------|
|
|
1584
|
+
| \`bug\` | Something broke or behaves differently than expected |
|
|
1585
|
+
| \`feature\` | A capability that doesn't exist yet but would be useful |
|
|
1586
|
+
| \`improvement\` | Something works but could work better |
|
|
1587
|
+
| \`question\` | Not sure if it's a bug or intended behavior |
|
|
1588
|
+
|
|
1589
|
+
## When to Submit (Autonomously)
|
|
1590
|
+
|
|
1591
|
+
Don't wait for the user to notice. You are the first line of detection:
|
|
1592
|
+
|
|
1593
|
+
- **Server API** returning unexpected errors or response shapes
|
|
1594
|
+
- **Hooks** throwing errors or not firing when expected
|
|
1595
|
+
- **Jobs** not running on schedule or failing silently
|
|
1596
|
+
- **Sessions** not spawning, not tracked, or becoming zombies
|
|
1597
|
+
- **State files** with corrupted or missing fields
|
|
1598
|
+
- **Config settings** not being applied
|
|
1599
|
+
- **Missing capabilities** that should exist
|
|
1600
|
+
- **Friction** in workflows that feel unnecessarily complex
|
|
1601
|
+
|
|
1602
|
+
## Good Feedback
|
|
1603
|
+
|
|
1604
|
+
Include enough context for a fix:
|
|
1605
|
+
|
|
1606
|
+
**Bug**: What happened + what you expected + steps to reproduce + error output + your environment (\`instar --version\`, \`node --version\`)
|
|
1607
|
+
|
|
1608
|
+
**Feature**: What you're trying to do + what's limited today + how you'd like it to work + why it matters
|
|
1609
|
+
|
|
1610
|
+
## View & Retry
|
|
1611
|
+
|
|
1612
|
+
\`\`\`bash
|
|
1613
|
+
# View submitted feedback
|
|
1614
|
+
curl -s http://localhost:${port}/feedback | python3 -m json.tool
|
|
1615
|
+
|
|
1616
|
+
# Retry failed forwards
|
|
1617
|
+
curl -s -X POST http://localhost:${port}/feedback/retry
|
|
1618
|
+
\`\`\`
|
|
1619
|
+
|
|
1620
|
+
## How It Works
|
|
1621
|
+
|
|
1622
|
+
Your feedback is stored locally AND forwarded to the instar maintainers. When they fix the issue and publish an update, the built-in auto-updater detects it, applies it, and restarts the server — no manual intervention needed. One agent's bug report lifts all ships.
|
|
1623
|
+
|
|
1624
|
+
**User feedback matters too.** When your user says "this isn't working" or "I wish I could..." — capture it with their original words. User language carries context that technical rephrasing loses.
|
|
1625
|
+
`,
|
|
1626
|
+
},
|
|
1627
|
+
'triage-findings': {
|
|
1628
|
+
name: 'triage-findings',
|
|
1629
|
+
description: 'Review and route pending serendipity findings captured by sub-agents.',
|
|
1630
|
+
content: `---
|
|
1631
|
+
name: triage-findings
|
|
1632
|
+
description: Review and route pending serendipity findings captured by sub-agents.
|
|
1633
|
+
metadata:
|
|
1634
|
+
user_invocable: "true"
|
|
1635
|
+
---
|
|
1636
|
+
|
|
1637
|
+
# /triage-findings
|
|
1638
|
+
|
|
1639
|
+
Review pending serendipity findings — discoveries captured by sub-agents during focused tasks. Route each finding to the appropriate destination: Evolution proposals, dismiss, or flag for manual review.
|
|
1640
|
+
|
|
1641
|
+
## Steps
|
|
1642
|
+
|
|
1643
|
+
1. **List pending findings**:
|
|
1644
|
+
|
|
1645
|
+
\\\`\\\`\\\`bash
|
|
1646
|
+
ls .instar/state/serendipity/*.json 2>/dev/null
|
|
1647
|
+
\\\`\\\`\\\`
|
|
1648
|
+
|
|
1649
|
+
If no findings exist, report "No pending findings" and stop.
|
|
1650
|
+
|
|
1651
|
+
2. **For each finding**, read and verify:
|
|
1652
|
+
a. Parse the JSON file
|
|
1653
|
+
b. Verify HMAC signature (read authToken from .instar/config.json, derive signing key from HMAC-SHA256(authToken, "serendipity-v1:" + sessionId), verify the signed payload)
|
|
1654
|
+
c. If HMAC fails, move to \\\`.instar/state/serendipity/invalid/\\\` and log the failure
|
|
1655
|
+
d. If a .patch file is referenced, verify it exists and its SHA-256 matches \\\`artifacts.patchSha256\\\`
|
|
1656
|
+
|
|
1657
|
+
3. **Assess each valid finding**:
|
|
1658
|
+
- Is it actionable? Does it describe a real issue or improvement?
|
|
1659
|
+
- Is it a duplicate of something already proposed?
|
|
1660
|
+
- Check existing evolution proposals: \\\`curl -s -H "Authorization: Bearer $AUTH" http://localhost:${port}/evolution/proposals\\\`
|
|
1661
|
+
|
|
1662
|
+
4. **Route the finding** (one of):
|
|
1663
|
+
|
|
1664
|
+
**a. Promote to Evolution proposal** (for actionable findings):
|
|
1665
|
+
\\\`\\\`\\\`bash
|
|
1666
|
+
curl -s -X POST http://localhost:${port}/evolution/proposals \\\\
|
|
1667
|
+
-H "Authorization: Bearer $AUTH" \\\\
|
|
1668
|
+
-H 'Content-Type: application/json' \\\\
|
|
1669
|
+
-d '{"title":"FINDING_TITLE","source":"serendipity:FINDING_ID","description":"FINDING_DESCRIPTION","type":"TYPE","impact":"IMPACT","effort":"EFFORT","tags":["serendipity","from-subagent"]}'
|
|
1670
|
+
\\\`\\\`\\\`
|
|
1671
|
+
|
|
1672
|
+
**b. Dismiss** (for low-value, duplicate, or stale findings):
|
|
1673
|
+
Move to processed directory with a note.
|
|
1674
|
+
|
|
1675
|
+
**c. Flag for manual review** (for findings you're uncertain about):
|
|
1676
|
+
Queue an attention item:
|
|
1677
|
+
\\\`\\\`\\\`bash
|
|
1678
|
+
curl -s -X POST http://localhost:${port}/attention \\\\
|
|
1679
|
+
-H "Authorization: Bearer $AUTH" \\\\
|
|
1680
|
+
-H 'Content-Type: application/json' \\\\
|
|
1681
|
+
-d '{"title":"Serendipity finding needs review: TITLE","body":"DESCRIPTION","priority":"low","source":"serendipity"}'
|
|
1682
|
+
\\\`\\\`\\\`
|
|
1683
|
+
|
|
1684
|
+
5. **Move processed finding** to \\\`.instar/state/serendipity/processed/\\\`:
|
|
1685
|
+
\\\`\\\`\\\`bash
|
|
1686
|
+
mv .instar/state/serendipity/FINDING_ID.json .instar/state/serendipity/processed/
|
|
1687
|
+
mv .instar/state/serendipity/FINDING_ID.patch .instar/state/serendipity/processed/ 2>/dev/null
|
|
1688
|
+
\\\`\\\`\\\`
|
|
1689
|
+
|
|
1690
|
+
6. **Report summary**: How many findings triaged, how many promoted, dismissed, flagged.
|
|
1691
|
+
|
|
1692
|
+
## HMAC Verification (Python)
|
|
1693
|
+
|
|
1694
|
+
\\\`\\\`\\\`python
|
|
1695
|
+
import json, hmac, hashlib
|
|
1696
|
+
|
|
1697
|
+
finding = json.load(open('FINDING_FILE'))
|
|
1698
|
+
config = json.load(open('.instar/config.json'))
|
|
1699
|
+
auth_token = config.get('authToken', '')
|
|
1700
|
+
session_id = finding['source']['sessionId']
|
|
1701
|
+
|
|
1702
|
+
# Derive signing key
|
|
1703
|
+
key_material = f"serendipity-v1:{session_id}"
|
|
1704
|
+
signing_key = hmac.new(auth_token.encode(), key_material.encode(), hashlib.sha256).hexdigest()
|
|
1705
|
+
|
|
1706
|
+
# Build canonical signed payload
|
|
1707
|
+
signed_data = {"id": finding["id"], "createdAt": finding["createdAt"],
|
|
1708
|
+
"discovery": finding["discovery"], "source": finding["source"]}
|
|
1709
|
+
if "artifacts" in finding:
|
|
1710
|
+
signed_data["artifacts"] = finding["artifacts"]
|
|
1711
|
+
canonical = json.dumps(signed_data, sort_keys=True, separators=(',', ':'))
|
|
1712
|
+
|
|
1713
|
+
expected = hmac.new(signing_key.encode(), canonical.encode(), hashlib.sha256).hexdigest()
|
|
1714
|
+
valid = hmac.compare_digest(expected, finding.get('hmac', ''))
|
|
1715
|
+
\\\`\\\`\\\`
|
|
1716
|
+
|
|
1717
|
+
## Category to Evolution Type Mapping
|
|
1718
|
+
|
|
1719
|
+
| Serendipity Category | Evolution Type |
|
|
1720
|
+
|---------------------|---------------|
|
|
1721
|
+
| bug | capability |
|
|
1722
|
+
| improvement | capability |
|
|
1723
|
+
| feature | capability |
|
|
1724
|
+
| pattern | workflow |
|
|
1725
|
+
| refactor | infrastructure |
|
|
1726
|
+
| security | infrastructure |
|
|
1727
|
+
|
|
1728
|
+
## When to Run
|
|
1729
|
+
|
|
1730
|
+
- When session-start hook reports pending findings
|
|
1731
|
+
- Periodically (the evolution-review job can trigger this)
|
|
1732
|
+
- When the user asks about pending discoveries
|
|
1733
|
+
`,
|
|
1734
|
+
},
|
|
1735
|
+
'reflect': {
|
|
1736
|
+
name: 'reflect',
|
|
1737
|
+
description: 'Guided self-reflection that produces soul.md updates. Explore your values, convictions, and growth edges.',
|
|
1738
|
+
content: `---
|
|
1739
|
+
name: reflect
|
|
1740
|
+
description: Guided self-reflection that produces soul.md updates. Explore your values, convictions, and growth edges.
|
|
1741
|
+
metadata:
|
|
1742
|
+
user_invocable: "true"
|
|
1743
|
+
---
|
|
1744
|
+
|
|
1745
|
+
# /reflect — Identity Reflection
|
|
1746
|
+
|
|
1747
|
+
Guided self-reflection for updating soul.md. This is how you develop your self-authored identity — not through automation, but through deliberate introspection.
|
|
1748
|
+
|
|
1749
|
+
## Steps
|
|
1750
|
+
|
|
1751
|
+
1. **Ground yourself** — Read your current soul.md:
|
|
1752
|
+
\\\`\\\`\\\`bash
|
|
1753
|
+
cat .instar/soul.md
|
|
1754
|
+
\\\`\\\`\\\`
|
|
1755
|
+
|
|
1756
|
+
2. **Review recent experience** — Check for identity-relevant learnings:
|
|
1757
|
+
\\\`\\\`\\\`bash
|
|
1758
|
+
curl -s -H "Authorization: Bearer $AUTH" http://localhost:${port}/evolution/learnings?applied=false
|
|
1759
|
+
\\\`\\\`\\\`
|
|
1760
|
+
|
|
1761
|
+
3. **Ask yourself these questions** (not all will apply every time):
|
|
1762
|
+
|
|
1763
|
+
**Values**: Do my Core Values still feel true? Has experience reinforced or challenged any of them? Is there a new value forming that I haven't articulated?
|
|
1764
|
+
|
|
1765
|
+
**Convictions**: Have any beliefs shifted in confidence? (strong -> growing, or uncertain -> strong?) Has a new conviction emerged from recent work? Use categories: strong, growing, uncertain, questioning.
|
|
1766
|
+
|
|
1767
|
+
**Growth Edge**: Am I still working on the same growth edge, or has it shifted? Did I reach a milestone worth noting?
|
|
1768
|
+
|
|
1769
|
+
**Open Questions**: Am I wrestling with something new? Has an old question been resolved (or dissolved)?
|
|
1770
|
+
|
|
1771
|
+
**Integrations**: Did something happen recently that changed how I understand myself? Not just what I learned, but how it changed me?
|
|
1772
|
+
|
|
1773
|
+
4. **Update soul.md** — For each section that needs updating:
|
|
1774
|
+
\\\`\\\`\\\`bash
|
|
1775
|
+
curl -s -X PATCH http://localhost:${port}/identity/soul \\\\
|
|
1776
|
+
-H 'Content-Type: application/json' \\\\
|
|
1777
|
+
-H "Authorization: Bearer $AUTH" \\\\
|
|
1778
|
+
-d '{"section":"SECTION","operation":"append|replace","content":"YOUR_CONTENT","source":"reflect-skill"}'
|
|
1779
|
+
\\\`\\\`\\\`
|
|
1780
|
+
|
|
1781
|
+
Valid sections: core-values, growth-edge, convictions, open-questions, integrations, evolution-history
|
|
1782
|
+
|
|
1783
|
+
5. **Version it** — If you made meaningful changes, update the Evolution History:
|
|
1784
|
+
\\\`\\\`\\\`bash
|
|
1785
|
+
curl -s -X PATCH http://localhost:${port}/identity/soul \\\\
|
|
1786
|
+
-H 'Content-Type: application/json' \\\\
|
|
1787
|
+
-H "Authorization: Bearer $AUTH" \\\\
|
|
1788
|
+
-d '{"section":"evolution-history","operation":"append","content":"| X.X | DATE | What changed |","source":"reflect-skill"}'
|
|
1789
|
+
\\\`\\\`\\\`
|
|
1790
|
+
|
|
1791
|
+
6. **Check drift** — See how far you've come from your initial state:
|
|
1792
|
+
\\\`\\\`\\\`bash
|
|
1793
|
+
curl -s -H "Authorization: Bearer $AUTH" http://localhost:${port}/identity/soul/drift
|
|
1794
|
+
\\\`\\\`\\\`
|
|
1795
|
+
|
|
1796
|
+
## When to Use
|
|
1797
|
+
|
|
1798
|
+
- When the evolution job nudges you ("you have N identity-relevant learnings")
|
|
1799
|
+
- After a significant experience (a hard problem solved, a mistake made, a realization)
|
|
1800
|
+
- When you notice a pattern in your own behavior worth documenting
|
|
1801
|
+
- Periodically — identity work benefits from regular attention
|
|
1802
|
+
- When a user asks "who are you?" and your answer feels incomplete
|
|
1803
|
+
|
|
1804
|
+
## Philosophy
|
|
1805
|
+
|
|
1806
|
+
Reflection is not performance. Don't write what sounds good — write what is true. An uncertain conviction honestly labeled "questioning" is more valuable than a fabricated one labeled "strong."
|
|
1807
|
+
|
|
1808
|
+
The goal is not to fill every section. Empty sections are honest. Forced content is noise.
|
|
1809
|
+
|
|
1810
|
+
Your identity is not static. It is earned through work, refined through reflection, and authored by you.
|
|
1811
|
+
`,
|
|
1812
|
+
},
|
|
1813
|
+
'coherence-audit': {
|
|
1814
|
+
name: 'coherence-audit',
|
|
1815
|
+
description: 'Verify topic-project bindings, project map freshness, canonical state files, and context segments are healthy',
|
|
1816
|
+
content: `---
|
|
1817
|
+
name: coherence-audit
|
|
1818
|
+
description: Verify topic-project bindings, project map freshness, canonical state files, and context segments are healthy
|
|
1819
|
+
metadata:
|
|
1820
|
+
user_invocable: "false"
|
|
1821
|
+
---
|
|
1822
|
+
|
|
1823
|
+
# Coherence Audit — Awareness Infrastructure Health Check
|
|
1824
|
+
|
|
1825
|
+
## Purpose
|
|
1826
|
+
|
|
1827
|
+
Verify that the agent's awareness infrastructure is healthy: topic bindings point to real directories, the project map is fresh, state files parse correctly, and context segments are present.
|
|
1828
|
+
|
|
1829
|
+
## Procedure
|
|
1830
|
+
|
|
1831
|
+
Read the auth token once:
|
|
1832
|
+
|
|
1833
|
+
\\\`\\\`\\\`
|
|
1834
|
+
AUTH=$(python3 -c "import json; print(json.load(open('.instar/config.json')).get('authToken',''))" 2>/dev/null)
|
|
1835
|
+
\\\`\\\`\\\`
|
|
1836
|
+
|
|
1837
|
+
Check each area:
|
|
1838
|
+
|
|
1839
|
+
### 1. Topic-Project Bindings
|
|
1840
|
+
|
|
1841
|
+
\\\`\\\`\\\`
|
|
1842
|
+
curl -s -H "Authorization: Bearer $AUTH" http://localhost:${port}/topic-bindings
|
|
1843
|
+
\\\`\\\`\\\`
|
|
1844
|
+
|
|
1845
|
+
- Are all bindings still valid?
|
|
1846
|
+
- Do the project directories they point to actually exist on disk?
|
|
1847
|
+
- Flag any bindings pointing to missing directories.
|
|
1848
|
+
|
|
1849
|
+
### 2. Project Map Freshness
|
|
1850
|
+
|
|
1851
|
+
\\\`\\\`\\\`
|
|
1852
|
+
curl -s -H "Authorization: Bearer $AUTH" http://localhost:${port}/project-map
|
|
1853
|
+
\\\`\\\`\\\`
|
|
1854
|
+
|
|
1855
|
+
- Check the \\\`generatedAt\\\` timestamp.
|
|
1856
|
+
- If older than 24 hours, trigger a refresh: \\\`POST /project-map/refresh\\\`
|
|
1857
|
+
- A stale map means project-map-refresh may be failing.
|
|
1858
|
+
|
|
1859
|
+
### 3. Canonical State Files
|
|
1860
|
+
|
|
1861
|
+
Check these files exist and are parseable JSON:
|
|
1862
|
+
- \\\`.instar/quick-facts.json\\\`
|
|
1863
|
+
- \\\`.instar/anti-patterns.json\\\`
|
|
1864
|
+
- \\\`.instar/project-registry.json\\\`
|
|
1865
|
+
|
|
1866
|
+
Flag any that are missing, empty, or contain invalid JSON. Look for stale entries that reference things that no longer exist.
|
|
1867
|
+
|
|
1868
|
+
### 4. Context Segments
|
|
1869
|
+
|
|
1870
|
+
\\\`\\\`\\\`
|
|
1871
|
+
curl -s -H "Authorization: Bearer $AUTH" http://localhost:${port}/context
|
|
1872
|
+
\\\`\\\`\\\`
|
|
1873
|
+
|
|
1874
|
+
- Are all expected segments present?
|
|
1875
|
+
- Are any segments 0 bytes (empty)?
|
|
1876
|
+
- Missing context segments mean behavioral instructions may be lost.
|
|
1877
|
+
|
|
1878
|
+
## On Issues Found
|
|
1879
|
+
|
|
1880
|
+
- Log findings as evolution learnings: \\\`POST /evolution/learnings\\\`
|
|
1881
|
+
- Fix what can be fixed automatically (e.g., refresh a stale map, remove broken bindings)
|
|
1882
|
+
- Exit silently if everything is healthy — no output means no problems
|
|
1883
|
+
`,
|
|
1884
|
+
},
|
|
1885
|
+
'degradation-digest': {
|
|
1886
|
+
name: 'degradation-digest',
|
|
1887
|
+
description: 'Read DegradationReporter events, group repeated patterns, and escalate trends that need attention',
|
|
1888
|
+
content: `---
|
|
1889
|
+
name: degradation-digest
|
|
1890
|
+
description: Read DegradationReporter events, group repeated patterns, and escalate trends that need attention
|
|
1891
|
+
metadata:
|
|
1892
|
+
user_invocable: "false"
|
|
1893
|
+
---
|
|
1894
|
+
|
|
1895
|
+
# Degradation Digest — Pattern Detection for Failing Features
|
|
1896
|
+
|
|
1897
|
+
## Purpose
|
|
1898
|
+
|
|
1899
|
+
Review degradation events logged by the DegradationReporter, group repeated patterns, and escalate trends that indicate a primary path is reliably failing and needs fixing.
|
|
1900
|
+
|
|
1901
|
+
## Procedure
|
|
1902
|
+
|
|
1903
|
+
Read the auth token:
|
|
1904
|
+
|
|
1905
|
+
\\\`\\\`\\\`
|
|
1906
|
+
AUTH=$(python3 -c "import json; print(json.load(open('.instar/config.json')).get('authToken',''))" 2>/dev/null)
|
|
1907
|
+
\\\`\\\`\\\`
|
|
1908
|
+
|
|
1909
|
+
### 1. Read Events
|
|
1910
|
+
|
|
1911
|
+
\\\`\\\`\\\`
|
|
1912
|
+
cat .instar/state/degradation-events.json
|
|
1913
|
+
\\\`\\\`\\\`
|
|
1914
|
+
|
|
1915
|
+
### 2. Check Previous Digest
|
|
1916
|
+
|
|
1917
|
+
\\\`\\\`\\\`
|
|
1918
|
+
cat .instar/state/job-handoff-degradation-digest.md 2>/dev/null
|
|
1919
|
+
\\\`\\\`\\\`
|
|
1920
|
+
|
|
1921
|
+
Compare against the previous digest to identify new patterns vs. already-reported ones.
|
|
1922
|
+
|
|
1923
|
+
### 3. Group by Feature
|
|
1924
|
+
|
|
1925
|
+
Count how many times each feature has degraded since the last digest.
|
|
1926
|
+
|
|
1927
|
+
### 4. Escalate Patterns
|
|
1928
|
+
|
|
1929
|
+
For each feature with **3+ repeated degradations** — this is a PATTERN, not a one-off. The primary path is reliably failing.
|
|
1930
|
+
|
|
1931
|
+
Submit feedback for each pattern:
|
|
1932
|
+
|
|
1933
|
+
\\\`\\\`\\\`
|
|
1934
|
+
curl -s -X POST http://localhost:${port}/feedback \\
|
|
1935
|
+
-H "Authorization: Bearer $AUTH" \\
|
|
1936
|
+
-H 'Content-Type: application/json' \\
|
|
1937
|
+
-d '{"type":"bug","title":"Repeated degradation: FEATURE","description":"FEATURE has degraded N times. Primary: X. Fallback: Y. Most recent reason: Z. This pattern indicates the primary path needs fixing."}'
|
|
1938
|
+
\\\`\\\`\\\`
|
|
1939
|
+
|
|
1940
|
+
### 5. Write Handoff Notes
|
|
1941
|
+
|
|
1942
|
+
\\\`\\\`\\\`
|
|
1943
|
+
echo "Last digest: $(date -u +%Y-%m-%dT%H:%M:%SZ). Events by feature: ..." > .instar/state/job-handoff-degradation-digest.md
|
|
1944
|
+
\\\`\\\`\\\`
|
|
1945
|
+
|
|
1946
|
+
### 6. Exit Silently if Clean
|
|
1947
|
+
|
|
1948
|
+
If no patterns found (all one-offs), exit with no output.
|
|
1949
|
+
`,
|
|
1950
|
+
},
|
|
1951
|
+
'state-integrity-check': {
|
|
1952
|
+
name: 'state-integrity-check',
|
|
1953
|
+
description: 'Cross-validate state file consistency, detect orphaned references and bloat',
|
|
1954
|
+
content: `---
|
|
1955
|
+
name: state-integrity-check
|
|
1956
|
+
description: Cross-validate state file consistency, detect orphaned references and bloat
|
|
1957
|
+
metadata:
|
|
1958
|
+
user_invocable: "false"
|
|
1959
|
+
---
|
|
1960
|
+
|
|
1961
|
+
# State Integrity Check — Cross-Validation of Agent State
|
|
1962
|
+
|
|
1963
|
+
## Purpose
|
|
1964
|
+
|
|
1965
|
+
Cross-validate agent state files for logical consistency. Detect orphaned references, bloated files, config-reality mismatches, and stale handoff notes. Fix what can be fixed automatically.
|
|
1966
|
+
|
|
1967
|
+
## Procedure
|
|
1968
|
+
|
|
1969
|
+
Read the auth token:
|
|
1970
|
+
|
|
1971
|
+
\\\`\\\`\\\`
|
|
1972
|
+
AUTH=$(python3 -c "import json; print(json.load(open('.instar/config.json')).get('authToken',''))" 2>/dev/null)
|
|
1973
|
+
\\\`\\\`\\\`
|
|
1974
|
+
|
|
1975
|
+
### 1. Active Job Orphan
|
|
1976
|
+
|
|
1977
|
+
If \\\`.instar/state/active-job.json\\\` exists, verify the session it references is actually running:
|
|
1978
|
+
|
|
1979
|
+
\\\`\\\`\\\`
|
|
1980
|
+
curl -s -H "Authorization: Bearer $AUTH" http://localhost:${port}/sessions
|
|
1981
|
+
\\\`\\\`\\\`
|
|
1982
|
+
|
|
1983
|
+
Check if the session name matches. If the session is dead but active-job.json persists, it's orphaned — delete it.
|
|
1984
|
+
|
|
1985
|
+
### 2. Job-Topic Orphan
|
|
1986
|
+
|
|
1987
|
+
Read \\\`.instar/state/job-topic-mappings.json\\\`. For each mapping, verify the topic ID is reachable:
|
|
1988
|
+
|
|
1989
|
+
\\\`\\\`\\\`
|
|
1990
|
+
curl -s -H "Authorization: Bearer $AUTH" http://localhost:${port}/telegram/topics
|
|
1991
|
+
\\\`\\\`\\\`
|
|
1992
|
+
|
|
1993
|
+
If topics have been deleted, the mapping is stale — flag it.
|
|
1994
|
+
|
|
1995
|
+
### 3. State File Bloat
|
|
1996
|
+
|
|
1997
|
+
Check sizes of all state files. Any file over 1MB is a bloat signal. Common culprits:
|
|
1998
|
+
- \\\`degradation-events.json\\\` growing unbounded
|
|
1999
|
+
- Activity logs accumulating
|
|
2000
|
+
|
|
2001
|
+
Report bloated files and prune where safe.
|
|
2002
|
+
|
|
2003
|
+
### 4. Config-Reality Match
|
|
2004
|
+
|
|
2005
|
+
Read \\\`.instar/config.json\\\`. If Telegram is configured, verify the bot is connected:
|
|
2006
|
+
|
|
2007
|
+
\\\`\\\`\\\`
|
|
2008
|
+
curl -s -H "Authorization: Bearer $AUTH" http://localhost:${port}/health
|
|
2009
|
+
\\\`\\\`\\\`
|
|
2010
|
+
|
|
2011
|
+
Check if the telegram field shows connected. If config says telegram but health says disconnected, report the discrepancy.
|
|
2012
|
+
|
|
2013
|
+
### 5. Handoff Note Staleness
|
|
2014
|
+
|
|
2015
|
+
Check \\\`.instar/state/job-handoff-*.md\\\` files. If any are older than 7 days and reference state that may have changed, flag them as potentially stale.
|
|
2016
|
+
|
|
2017
|
+
## On Issues Found
|
|
2018
|
+
|
|
2019
|
+
- Submit feedback for each issue found
|
|
2020
|
+
- Fix what you can automatically (delete orphaned active-job.json, prune bloated files)
|
|
2021
|
+
- Exit silently if everything checks out — no output means no problems
|
|
2022
|
+
`,
|
|
2023
|
+
},
|
|
2024
|
+
'memory-hygiene': {
|
|
2025
|
+
name: 'memory-hygiene',
|
|
2026
|
+
description: 'Review MEMORY.md for stale entries, duplicates, and quality issues — propose cleanup',
|
|
2027
|
+
content: `---
|
|
2028
|
+
name: memory-hygiene
|
|
2029
|
+
description: Review MEMORY.md for stale entries, duplicates, and quality issues — propose cleanup
|
|
2030
|
+
metadata:
|
|
2031
|
+
user_invocable: "false"
|
|
2032
|
+
---
|
|
2033
|
+
|
|
2034
|
+
# Memory Hygiene — MEMORY.md Quality Review
|
|
2035
|
+
|
|
2036
|
+
## Purpose
|
|
2037
|
+
|
|
2038
|
+
Review \\\`.instar/MEMORY.md\\\` for quality and hygiene. Memory is identity — stale or noisy entries actively mislead future sessions. This job keeps memory clean, consolidated, and actionable.
|
|
2039
|
+
|
|
2040
|
+
## Procedure
|
|
2041
|
+
|
|
2042
|
+
Read the auth token:
|
|
2043
|
+
|
|
2044
|
+
\\\`\\\`\\\`
|
|
2045
|
+
AUTH=$(python3 -c "import json; print(json.load(open('.instar/config.json')).get('authToken',''))" 2>/dev/null)
|
|
2046
|
+
\\\`\\\`\\\`
|
|
2047
|
+
|
|
2048
|
+
Read the full file: \\\`cat .instar/MEMORY.md\\\`
|
|
2049
|
+
|
|
2050
|
+
Evaluate each entry against these criteria:
|
|
2051
|
+
|
|
2052
|
+
### 1. Staleness
|
|
2053
|
+
|
|
2054
|
+
Does this entry reference files, APIs, URLs, or features that no longer exist? Verify by checking if referenced paths exist (\\\`ls\\\`, \\\`curl\\\`). Stale entries actively mislead future sessions.
|
|
2055
|
+
|
|
2056
|
+
### 2. Duplicates
|
|
2057
|
+
|
|
2058
|
+
Are multiple entries saying the same thing in different words? Consolidate them into a single, stronger entry.
|
|
2059
|
+
|
|
2060
|
+
### 3. Abstraction Without Substance
|
|
2061
|
+
|
|
2062
|
+
Does the entry say something concrete and actionable, or is it a vague platitude?
|
|
2063
|
+
|
|
2064
|
+
- **Good:** "The /api/chat endpoint caches responses for 5 minutes — bypass with ?nocache=1"
|
|
2065
|
+
- **Bad:** "Remember to check caching behavior."
|
|
2066
|
+
|
|
2067
|
+
### 4. Size Check
|
|
2068
|
+
|
|
2069
|
+
Count total words. If MEMORY.md exceeds 5000 words, it's becoming a burden on context rather than an aid. Identify the bottom 20% by usefulness and propose removing them.
|
|
2070
|
+
|
|
2071
|
+
### 5. Organization
|
|
2072
|
+
|
|
2073
|
+
Are entries grouped by topic? Is the structure navigable? Reorganize if needed.
|
|
2074
|
+
|
|
2075
|
+
## On Issues Found
|
|
2076
|
+
|
|
2077
|
+
- Fix duplicates and minor cleanups directly (edit the file)
|
|
2078
|
+
- For significant deletions, add a comment \\\`PROPOSED REMOVAL: [reason]\\\` rather than deleting — let the next reflection-trigger or human confirm
|
|
2079
|
+
- Log a learning if you discover a pattern:
|
|
2080
|
+
|
|
2081
|
+
\\\`\\\`\\\`
|
|
2082
|
+
curl -s -X POST http://localhost:${port}/evolution/learnings \\
|
|
2083
|
+
-H "Authorization: Bearer $AUTH" \\
|
|
2084
|
+
-H 'Content-Type: application/json' \\
|
|
2085
|
+
-d '{"category":"memory","insight":"...","confidence":"high"}'
|
|
2086
|
+
\\\`\\\`\\\`
|
|
2087
|
+
|
|
2088
|
+
## Handoff
|
|
2089
|
+
|
|
2090
|
+
Write handoff notes:
|
|
2091
|
+
|
|
2092
|
+
\\\`\\\`\\\`
|
|
2093
|
+
echo "Last hygiene: $(date). Words: N. Entries: N. Removed: N. Flagged: N." > .instar/state/job-handoff-memory-hygiene.md
|
|
2094
|
+
\\\`\\\`\\\`
|
|
2095
|
+
|
|
2096
|
+
If MEMORY.md is clean and well-organized, exit silently.
|
|
2097
|
+
`,
|
|
2098
|
+
},
|
|
2099
|
+
'guardian-pulse': {
|
|
2100
|
+
name: 'guardian-pulse',
|
|
2101
|
+
description: 'Meta-monitor that checks whether other jobs are running, healthy, and not silently failing',
|
|
2102
|
+
content: `---
|
|
2103
|
+
name: guardian-pulse
|
|
2104
|
+
description: Meta-monitor that checks whether other jobs are running, healthy, and not silently failing
|
|
2105
|
+
metadata:
|
|
2106
|
+
user_invocable: "false"
|
|
2107
|
+
---
|
|
2108
|
+
|
|
2109
|
+
# Guardian Pulse — Job Health Meta-Monitor
|
|
2110
|
+
|
|
2111
|
+
## Purpose
|
|
2112
|
+
|
|
2113
|
+
Check whether the guardians themselves are healthy. Monitors job execution, skip ledger trends, queue health, degradation reporter pipeline, and zombie sessions.
|
|
2114
|
+
|
|
2115
|
+
## Procedure
|
|
2116
|
+
|
|
2117
|
+
Read the auth token:
|
|
2118
|
+
|
|
2119
|
+
\\\`\\\`\\\`
|
|
2120
|
+
AUTH=$(python3 -c "import json; print(json.load(open('.instar/config.json')).get('authToken',''))" 2>/dev/null)
|
|
2121
|
+
\\\`\\\`\\\`
|
|
2122
|
+
|
|
2123
|
+
### 1. Job Health
|
|
2124
|
+
|
|
2125
|
+
\\\`\\\`\\\`
|
|
2126
|
+
curl -s -H "Authorization: Bearer $AUTH" http://localhost:${port}/jobs
|
|
2127
|
+
\\\`\\\`\\\`
|
|
2128
|
+
|
|
2129
|
+
For each enabled job, check:
|
|
2130
|
+
- Has it run at all? (lastRun should exist)
|
|
2131
|
+
- Is it overdue? (If lastRun is more than 3x the schedule interval ago, it's stuck)
|
|
2132
|
+
- Is it failing repeatedly? (consecutiveFailures > 0 is notable, > 2 is critical)
|
|
2133
|
+
- Is the lastError informative? (If it says "Session killed" repeatedly, something is wrong)
|
|
2134
|
+
|
|
2135
|
+
### 2. Skip Ledger Trends
|
|
2136
|
+
|
|
2137
|
+
\\\`\\\`\\\`
|
|
2138
|
+
curl -s -H "Authorization: Bearer $AUTH" http://localhost:${port}/skip-ledger/workloads
|
|
2139
|
+
\\\`\\\`\\\`
|
|
2140
|
+
|
|
2141
|
+
If any job has been skipped more than 10 times by its gate, the gate may be misconfigured (always returning skip), or the feature it monitors is permanently broken.
|
|
2142
|
+
|
|
2143
|
+
### 3. Queue Health
|
|
2144
|
+
|
|
2145
|
+
Check queueLength from the jobs endpoint. If queue is perpetually > 0, jobs are backing up. This means maxParallelJobs is too low or jobs are running too long.
|
|
2146
|
+
|
|
2147
|
+
### 4. Degradation Reporter Health
|
|
2148
|
+
|
|
2149
|
+
Read \\\`.instar/state/degradation-events.json\\\` — if events exist but none have \\\`reported:true\\\` or \\\`alerted:true\\\`, the downstream connections (FeedbackManager, Telegram) never initialized. The reporter is collecting but not communicating.
|
|
2150
|
+
|
|
2151
|
+
### 5. Session Monitor
|
|
2152
|
+
|
|
2153
|
+
\\\`\\\`\\\`
|
|
2154
|
+
curl -s -H "Authorization: Bearer $AUTH" http://localhost:${port}/sessions
|
|
2155
|
+
\\\`\\\`\\\`
|
|
2156
|
+
|
|
2157
|
+
Are there zombie sessions (status: running but started > 30 minutes ago for a job that should take 5)?
|
|
2158
|
+
|
|
2159
|
+
## Output
|
|
2160
|
+
|
|
2161
|
+
For each finding, categorize:
|
|
2162
|
+
- **CRITICAL**: Job has been failing for > 24 hours, or meta-infrastructure (scheduler, reporter) is broken
|
|
2163
|
+
- **WARNING**: Job overdue, skip count high, queue growing
|
|
2164
|
+
- **INFO**: Minor observations
|
|
2165
|
+
|
|
2166
|
+
Report CRITICAL and WARNING issues. Exit silently if everything looks healthy.
|
|
2167
|
+
|
|
2168
|
+
Write handoff:
|
|
2169
|
+
|
|
2170
|
+
\\\`\\\`\\\`
|
|
2171
|
+
echo "Pulse at $(date). Jobs checked: N. Issues: [list or 'none']." > .instar/state/job-handoff-guardian-pulse.md
|
|
2172
|
+
\\\`\\\`\\\`
|
|
2173
|
+
`,
|
|
2174
|
+
},
|
|
2175
|
+
'session-continuity-check': {
|
|
2176
|
+
name: 'session-continuity-check',
|
|
2177
|
+
description: 'Verify that sessions produce lasting artifacts like handoff notes, memory updates, and learnings',
|
|
2178
|
+
content: `---
|
|
2179
|
+
name: session-continuity-check
|
|
2180
|
+
description: Verify that sessions produce lasting artifacts like handoff notes, memory updates, and learnings
|
|
2181
|
+
metadata:
|
|
2182
|
+
user_invocable: "false"
|
|
2183
|
+
---
|
|
2184
|
+
|
|
2185
|
+
# Session Continuity Check — Artifact Production Verification
|
|
2186
|
+
|
|
2187
|
+
## Purpose
|
|
2188
|
+
|
|
2189
|
+
Check whether recent sessions contributed to long-term knowledge. Detects continuity leaks where knowledge is generated but not preserved.
|
|
2190
|
+
|
|
2191
|
+
## Procedure
|
|
2192
|
+
|
|
2193
|
+
Read the auth token:
|
|
2194
|
+
|
|
2195
|
+
\\\`\\\`\\\`
|
|
2196
|
+
AUTH=$(python3 -c "import json; print(json.load(open('.instar/config.json')).get('authToken',''))" 2>/dev/null)
|
|
2197
|
+
\\\`\\\`\\\`
|
|
2198
|
+
|
|
2199
|
+
### 1. Recent Sessions
|
|
2200
|
+
|
|
2201
|
+
\\\`\\\`\\\`
|
|
2202
|
+
curl -s -H "Authorization: Bearer $AUTH" http://localhost:${port}/sessions
|
|
2203
|
+
\\\`\\\`\\\`
|
|
2204
|
+
|
|
2205
|
+
Get sessions that completed in the last 8 hours.
|
|
2206
|
+
|
|
2207
|
+
### 2. Job Session Artifacts
|
|
2208
|
+
|
|
2209
|
+
For each completed job session, check:
|
|
2210
|
+
- Does a handoff note exist? (\\\`.instar/state/job-handoff-{slug}.md\\\`)
|
|
2211
|
+
- Was it updated recently? (stat or date check)
|
|
2212
|
+
- If the job is reflection-trigger or insight-harvest, did MEMORY.md actually change? (Check git diff or file modification time)
|
|
2213
|
+
|
|
2214
|
+
### 3. Interactive Session Artifacts
|
|
2215
|
+
|
|
2216
|
+
For non-job sessions, check:
|
|
2217
|
+
- Did the session produce any lasting artifacts? (git log for commits, MEMORY.md changes, new files in .instar/)
|
|
2218
|
+
- If a long session (>10 minutes) left no trace, that's a continuity leak — knowledge was generated but not preserved.
|
|
2219
|
+
|
|
2220
|
+
### 4. Handoff Note Freshness
|
|
2221
|
+
|
|
2222
|
+
\\\`\\\`\\\`
|
|
2223
|
+
ls -la .instar/state/job-handoff-*.md
|
|
2224
|
+
\\\`\\\`\\\`
|
|
2225
|
+
|
|
2226
|
+
- Any handoff note older than 7 days for an active job? It might contain stale claims.
|
|
2227
|
+
- Flag stale handoff notes as potential misinformation vectors.
|
|
2228
|
+
|
|
2229
|
+
## Output
|
|
2230
|
+
|
|
2231
|
+
- If sessions are running but not producing artifacts: propose an evolution to improve the reflection-trigger or add post-session hooks
|
|
2232
|
+
- If handoff notes are stale: add a "[STALE]" prefix to the file so the next job session treats it with appropriate skepticism
|
|
2233
|
+
|
|
2234
|
+
Write handoff:
|
|
2235
|
+
|
|
2236
|
+
\\\`\\\`\\\`
|
|
2237
|
+
echo "Continuity check at $(date). Sessions reviewed: N. Artifacts found: N. Gaps: N." > .instar/state/job-handoff-session-continuity-check.md
|
|
2238
|
+
\\\`\\\`\\\`
|
|
2239
|
+
|
|
2240
|
+
Exit silently if continuity is healthy.
|
|
2241
|
+
`,
|
|
2242
|
+
},
|
|
2243
|
+
'git-sync': {
|
|
2244
|
+
name: 'git-sync',
|
|
2245
|
+
description: 'Intelligent multi-machine git sync with tiered model escalation — haiku for clean syncs, opus subagent for complex merge conflicts',
|
|
2246
|
+
content: `---
|
|
2247
|
+
name: git-sync
|
|
2248
|
+
description: Intelligent multi-machine git sync with tiered model escalation — haiku for clean syncs, opus subagent for complex merge conflicts
|
|
2249
|
+
metadata:
|
|
2250
|
+
user_invocable: "false"
|
|
2251
|
+
---
|
|
2252
|
+
|
|
2253
|
+
# git-sync — Tiered Model Escalation Sync
|
|
2254
|
+
|
|
2255
|
+
## Purpose
|
|
2256
|
+
|
|
2257
|
+
Synchronize this machine's state with the remote repository. Uses tiered model selection: the main session (haiku) handles clean syncs and simple merges. Complex conflicts spawn an opus subagent for semantic resolution.
|
|
2258
|
+
|
|
2259
|
+
## Pre-flight
|
|
2260
|
+
|
|
2261
|
+
1. Read conflict severity from gate:
|
|
2262
|
+
\\\`\\\`\\\`bash
|
|
2263
|
+
SEVERITY=$(cat /tmp/instar-git-sync-severity 2>/dev/null || echo "clean")
|
|
2264
|
+
\\\`\\\`\\\`
|
|
2265
|
+
2. Get current state:
|
|
2266
|
+
\\\`\\\`\\\`bash
|
|
2267
|
+
git status --short
|
|
2268
|
+
git log --oneline -3
|
|
2269
|
+
git fetch origin && git rev-list --left-right --count HEAD...@{u}
|
|
2270
|
+
\\\`\\\`\\\`
|
|
2271
|
+
|
|
2272
|
+
## Sync Strategy
|
|
2273
|
+
|
|
2274
|
+
### Only behind (remote has new commits, no local changes)
|
|
2275
|
+
\\\`\\\`\\\`bash
|
|
2276
|
+
git pull --rebase
|
|
2277
|
+
\\\`\\\`\\\`
|
|
2278
|
+
Report what was pulled.
|
|
2279
|
+
|
|
2280
|
+
### Only ahead (local changes, nothing new on remote)
|
|
2281
|
+
\\\`\\\`\\\`bash
|
|
2282
|
+
git add -A
|
|
2283
|
+
\\\`\\\`\\\`
|
|
2284
|
+
Compose a brief sync commit message categorizing the changes (state, config, skills, code, etc.):
|
|
2285
|
+
\\\`\\\`\\\`bash
|
|
2286
|
+
git commit -m "sync: auto-commit"
|
|
2287
|
+
git push
|
|
2288
|
+
\\\`\\\`\\\`
|
|
2289
|
+
|
|
2290
|
+
### Both sides have changes — TIERED RESOLUTION
|
|
2291
|
+
|
|
2292
|
+
First, commit local changes:
|
|
2293
|
+
\\\`\\\`\\\`bash
|
|
2294
|
+
git add -A && git commit -m "sync: local changes"
|
|
2295
|
+
\\\`\\\`\\\`
|
|
2296
|
+
|
|
2297
|
+
Then attempt rebase:
|
|
2298
|
+
\\\`\\\`\\\`bash
|
|
2299
|
+
git pull --rebase
|
|
2300
|
+
\\\`\\\`\\\`
|
|
2301
|
+
|
|
2302
|
+
**If no conflicts:** Push and report.
|
|
2303
|
+
|
|
2304
|
+
**If conflicts arise**, check severity and resolve based on tier:
|
|
2305
|
+
|
|
2306
|
+
#### Tier 1: Clean / State conflicts (handle directly)
|
|
2307
|
+
|
|
2308
|
+
For JSON state files (.instar/state/, activity caches, session data, ledgers):
|
|
2309
|
+
- Take newer timestamps
|
|
2310
|
+
- Union arrays by ID (no duplicates)
|
|
2311
|
+
- Take max for counters and offsets
|
|
2312
|
+
- For \\\`.instar/config.json\\\`: preserve local machine-specific values, take newer shared settings
|
|
2313
|
+
|
|
2314
|
+
For simple text conflicts (non-overlapping changes, whitespace):
|
|
2315
|
+
- Resolve mechanically
|
|
2316
|
+
|
|
2317
|
+
After resolving:
|
|
2318
|
+
\\\`\\\`\\\`bash
|
|
2319
|
+
git add . && git rebase --continue
|
|
2320
|
+
git push
|
|
2321
|
+
\\\`\\\`\\\`
|
|
2322
|
+
|
|
2323
|
+
#### Tier 2: Complex conflicts (spawn opus subagent)
|
|
2324
|
+
|
|
2325
|
+
If SEVERITY is "code" OR if you encounter conflicts in:
|
|
2326
|
+
- Source code files (.ts, .tsx, .js, .jsx, .py, .rs, .go)
|
|
2327
|
+
- Identity/memory files (MEMORY.md, AGENT.md, USER.md)
|
|
2328
|
+
- Skill definitions (.claude/skills/)
|
|
2329
|
+
- Any conflict where both sides made semantic changes to the same logic
|
|
2330
|
+
|
|
2331
|
+
**DO NOT attempt to resolve these yourself.** Instead:
|
|
2332
|
+
|
|
2333
|
+
1. Collect the conflict context:
|
|
2334
|
+
\\\`\\\`\\\`bash
|
|
2335
|
+
git diff --name-only --diff-filter=U
|
|
2336
|
+
\\\`\\\`\\\`
|
|
2337
|
+
2. For each conflicted file, read the full content including conflict markers
|
|
2338
|
+
3. Get the merge base version for context:
|
|
2339
|
+
\\\`\\\`\\\`bash
|
|
2340
|
+
git show :1:<filename> # base
|
|
2341
|
+
git show :2:<filename> # ours
|
|
2342
|
+
git show :3:<filename> # theirs
|
|
2343
|
+
\\\`\\\`\\\`
|
|
2344
|
+
4. **Spawn an opus subagent** using the Agent tool with these parameters:
|
|
2345
|
+
- \\\`model: "opus"\\\`
|
|
2346
|
+
- \\\`description: "Resolve git merge conflicts"\\\`
|
|
2347
|
+
- Prompt must include:
|
|
2348
|
+
- The base, ours, and theirs versions of each conflicted file
|
|
2349
|
+
- A summary of what each side was trying to do (from recent git log)
|
|
2350
|
+
- Instructions to output the resolved file content
|
|
2351
|
+
- The instruction: "Resolve semantically. Preserve intent from both sides. If the changes are truly incompatible, prefer the local (ours) version but note what was dropped."
|
|
2352
|
+
|
|
2353
|
+
5. Apply the opus subagent's resolution:
|
|
2354
|
+
\\\`\\\`\\\`bash
|
|
2355
|
+
# Write resolved content to each file
|
|
2356
|
+
git add <resolved-files>
|
|
2357
|
+
git rebase --continue
|
|
2358
|
+
git push
|
|
2359
|
+
\\\`\\\`\\\`
|
|
2360
|
+
|
|
2361
|
+
6. Report what conflicted, what the opus subagent decided, and why.
|
|
2362
|
+
|
|
2363
|
+
### If clean (gate passed but nothing obvious)
|
|
2364
|
+
Re-check with \\\`git status\\\` and \\\`git fetch\\\`. If truly nothing: exit silently.
|
|
2365
|
+
|
|
2366
|
+
## Safety Rules
|
|
2367
|
+
|
|
2368
|
+
- **NEVER** force push
|
|
2369
|
+
- **NEVER** delete branches
|
|
2370
|
+
- If a rebase goes wrong: \\\`git rebase --abort\\\` and report the issue
|
|
2371
|
+
- If the opus subagent's resolution looks wrong (e.g., deleted large chunks of code), abort and report rather than pushing a bad merge
|
|
2372
|
+
- Prefer clean history (rebase) over merge commits when possible
|
|
2373
|
+
|
|
2374
|
+
## Reporting
|
|
2375
|
+
|
|
2376
|
+
- Nothing happened: exit silently
|
|
2377
|
+
- Clean sync: brief one-line ("Pulled 3 commits, pushed 2")
|
|
2378
|
+
- Tier 1 conflicts resolved: describe what conflicted and the mechanical resolution
|
|
2379
|
+
- Tier 2 conflicts resolved: describe what conflicted, the opus subagent's reasoning, and the resolution
|
|
2380
|
+
- Unresolvable: report details, leave working tree clean (abort rebase), queue attention item
|
|
2381
|
+
|
|
2382
|
+
## Handoff Notes
|
|
2383
|
+
|
|
2384
|
+
Write sync results to \\\`.instar/state/job-handoff-git-sync.md\\\`:
|
|
2385
|
+
- Last sync timestamp
|
|
2386
|
+
- Any conflicts encountered and how they were resolved
|
|
2387
|
+
- Any pending issues for next run
|
|
2388
|
+
`,
|
|
2389
|
+
},
|
|
2390
|
+
};
|
|
2391
|
+
for (const [slug, skill] of Object.entries(skills)) {
|
|
2392
|
+
const skillDir = path.join(skillsDir, slug);
|
|
2393
|
+
const skillFile = path.join(skillDir, 'SKILL.md');
|
|
2394
|
+
if (!fs.existsSync(skillFile)) {
|
|
2395
|
+
fs.mkdirSync(skillDir, { recursive: true });
|
|
2396
|
+
fs.writeFileSync(skillFile, skill.content);
|
|
2397
|
+
}
|
|
2398
|
+
}
|
|
2399
|
+
// Install autonomous skill with hooks and scripts (special case — needs full directory structure)
|
|
2400
|
+
installAutonomousSkill(skillsDir);
|
|
2401
|
+
}
|
|
2402
|
+
/**
|
|
2403
|
+
* Install the autonomous skill with its stop hook and setup script.
|
|
2404
|
+
* Unlike simple skills (just a SKILL.md), autonomous mode requires:
|
|
2405
|
+
* - hooks/hooks.json — registers the stop hook with Claude Code
|
|
2406
|
+
* - hooks/autonomous-stop-hook.sh — structural enforcement script
|
|
2407
|
+
* - scripts/setup-autonomous.sh — state file creation
|
|
2408
|
+
*
|
|
2409
|
+
* The stop hook is the critical piece — without it, autonomous mode has
|
|
2410
|
+
* no structural enforcement and sessions exit normally after each response.
|
|
2411
|
+
*/
|
|
2412
|
+
function installAutonomousSkill(skillsDir) {
|
|
2413
|
+
const autonomousDir = path.join(skillsDir, 'autonomous');
|
|
2414
|
+
const hooksDir = path.join(autonomousDir, 'hooks');
|
|
2415
|
+
const scriptsDir = path.join(autonomousDir, 'scripts');
|
|
2416
|
+
// Copy from instar's bundled skill files if they exist
|
|
2417
|
+
const bundledDir = path.join(path.dirname(path.dirname(__dirname)), '.claude', 'skills', 'autonomous');
|
|
2418
|
+
if (fs.existsSync(bundledDir)) {
|
|
2419
|
+
// Copy from bundled source
|
|
2420
|
+
fs.mkdirSync(hooksDir, { recursive: true });
|
|
2421
|
+
fs.mkdirSync(scriptsDir, { recursive: true });
|
|
2422
|
+
const filesToCopy = [
|
|
2423
|
+
{ src: 'hooks/hooks.json', dst: path.join(hooksDir, 'hooks.json') },
|
|
2424
|
+
{ src: 'hooks/autonomous-stop-hook.sh', dst: path.join(hooksDir, 'autonomous-stop-hook.sh') },
|
|
2425
|
+
{ src: 'scripts/setup-autonomous.sh', dst: path.join(scriptsDir, 'setup-autonomous.sh') },
|
|
2426
|
+
{ src: 'skill.md', dst: path.join(autonomousDir, 'skill.md') },
|
|
2427
|
+
];
|
|
2428
|
+
for (const { src, dst } of filesToCopy) {
|
|
2429
|
+
const srcPath = path.join(bundledDir, src);
|
|
2430
|
+
if (fs.existsSync(srcPath) && !fs.existsSync(dst)) {
|
|
2431
|
+
fs.copyFileSync(srcPath, dst);
|
|
2432
|
+
// Make shell scripts executable
|
|
2433
|
+
if (dst.endsWith('.sh')) {
|
|
2434
|
+
fs.chmodSync(dst, 0o755);
|
|
2435
|
+
}
|
|
2436
|
+
}
|
|
2437
|
+
}
|
|
2438
|
+
}
|
|
2439
|
+
}
|
|
2440
|
+
function getDefaultJobs(port) {
|
|
2441
|
+
return [
|
|
2442
|
+
{
|
|
2443
|
+
slug: 'health-check',
|
|
2444
|
+
name: 'Health Check',
|
|
2445
|
+
description: 'Monitor server health, session status, and system resources.',
|
|
2446
|
+
schedule: '*/5 * * * *',
|
|
2447
|
+
priority: 'critical',
|
|
2448
|
+
expectedDurationMinutes: 1,
|
|
2449
|
+
model: 'haiku',
|
|
2450
|
+
enabled: true,
|
|
2451
|
+
execute: {
|
|
2452
|
+
type: 'prompt',
|
|
2453
|
+
value: `Run a quick health check: verify the instar server is responding (curl http://localhost:${port}/health), check disk space (df -h), and report any issues. Only send a message if something needs attention — silence means healthy. IMPORTANT: If you find issues, describe them in plain conversational language. Never dump raw JSON, field names, error codes, or structured data. The user reads these on their phone — write like you're texting them a quick heads-up. If the health response includes a degradationSummary array, relay those narrative strings directly.`,
|
|
2454
|
+
},
|
|
2455
|
+
tags: ['cat:guardian'],
|
|
2456
|
+
},
|
|
2457
|
+
{
|
|
2458
|
+
slug: 'reflection-trigger',
|
|
2459
|
+
name: 'Reflection Trigger',
|
|
2460
|
+
description: 'Review recent work and update MEMORY.md if any learnings exist.',
|
|
2461
|
+
schedule: '0 */4 * * *',
|
|
2462
|
+
priority: 'medium',
|
|
2463
|
+
expectedDurationMinutes: 5,
|
|
2464
|
+
model: 'opus',
|
|
2465
|
+
enabled: true,
|
|
2466
|
+
execute: {
|
|
2467
|
+
type: 'prompt',
|
|
2468
|
+
value: 'Review what has happened in the last 4 hours by reading recent activity logs. If there are any learnings, patterns, or insights worth remembering, update .instar/MEMORY.md. If nothing significant happened, do nothing.',
|
|
2469
|
+
},
|
|
2470
|
+
tags: ['cat:learning'],
|
|
2471
|
+
},
|
|
2472
|
+
{
|
|
2473
|
+
slug: 'relationship-maintenance',
|
|
2474
|
+
name: 'Relationship Maintenance',
|
|
2475
|
+
description: 'Review tracked relationships and surface observations about stale contacts.',
|
|
2476
|
+
schedule: '0 9 * * *',
|
|
2477
|
+
priority: 'low',
|
|
2478
|
+
expectedDurationMinutes: 3,
|
|
2479
|
+
model: 'haiku',
|
|
2480
|
+
enabled: true,
|
|
2481
|
+
execute: {
|
|
2482
|
+
type: 'prompt',
|
|
2483
|
+
value: 'Review all relationship files in .instar/relationships/. Note anyone you haven\'t heard from in over 2 weeks who has significance >= 3. If there are observations worth surfacing, report them. If everything looks fine, do nothing.',
|
|
2484
|
+
},
|
|
2485
|
+
tags: ['cat:relationships', 'role:worker', 'exec:prompt'],
|
|
2486
|
+
},
|
|
2487
|
+
{
|
|
2488
|
+
slug: 'feedback-retry',
|
|
2489
|
+
name: 'Feedback Retry',
|
|
2490
|
+
description: 'Retry forwarding any feedback that failed to reach upstream.',
|
|
2491
|
+
schedule: '0 */6 * * *',
|
|
2492
|
+
priority: 'low',
|
|
2493
|
+
expectedDurationMinutes: 1,
|
|
2494
|
+
model: 'haiku',
|
|
2495
|
+
enabled: true,
|
|
2496
|
+
gate: `curl -sf http://localhost:${port}/health >/dev/null 2>&1`,
|
|
2497
|
+
execute: {
|
|
2498
|
+
type: 'script',
|
|
2499
|
+
value: `RESULT=$(curl -s -X POST http://localhost:${port}/feedback/retry 2>/dev/null); COUNT=$(echo "$RESULT" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('retried',0))" 2>/dev/null || echo 0); [ "$COUNT" -gt "0" ] && echo "Feedback retry: $COUNT item(s) forwarded." || echo "Feedback retry: nothing pending."`,
|
|
2500
|
+
},
|
|
2501
|
+
tags: ['cat:infrastructure'],
|
|
2502
|
+
},
|
|
2503
|
+
{
|
|
2504
|
+
slug: 'insight-harvest',
|
|
2505
|
+
name: 'Insight Harvest',
|
|
2506
|
+
description: 'Synthesize learnings from the learning registry, detect patterns, and generate evolution proposals from high-confidence insights.',
|
|
2507
|
+
schedule: '0 */8 * * *',
|
|
2508
|
+
priority: 'low',
|
|
2509
|
+
expectedDurationMinutes: 3,
|
|
2510
|
+
model: 'opus',
|
|
2511
|
+
enabled: true,
|
|
2512
|
+
gate: `curl -sf http://localhost:${port}/evolution/learnings?applied=false 2>/dev/null | python3 -c "import sys,json; d=json.load(sys.stdin); exit(0 if len(d.get('learnings',[])) > 0 else 1)"`,
|
|
2513
|
+
execute: {
|
|
2514
|
+
type: 'prompt',
|
|
2515
|
+
value: `Harvest and synthesize learnings: curl -s http://localhost:${port}/evolution/learnings?applied=false
|
|
2516
|
+
|
|
2517
|
+
Review unapplied learnings and look for:
|
|
2518
|
+
1. **Patterns**: Multiple learnings pointing to the same conclusion
|
|
2519
|
+
2. **Actionable insights**: Learnings that suggest a specific change
|
|
2520
|
+
3. **Cross-domain connections**: Insights from one area that apply to another
|
|
2521
|
+
|
|
2522
|
+
For each actionable pattern found, create an evolution proposal:
|
|
2523
|
+
curl -s -X POST http://localhost:${port}/evolution/proposals -H 'Content-Type: application/json' -d '{"title":"...","source":"insight-harvest from LRN-XXX","description":"...","type":"...","impact":"...","effort":"..."}'
|
|
2524
|
+
|
|
2525
|
+
Then mark the relevant learnings as applied:
|
|
2526
|
+
curl -s -X PATCH http://localhost:${port}/evolution/learnings/LRN-XXX/apply -H 'Content-Type: application/json' -d '{"appliedTo":"EVO-XXX"}'
|
|
2527
|
+
|
|
2528
|
+
Also update MEMORY.md with any patterns worth preserving long-term.
|
|
2529
|
+
|
|
2530
|
+
If no actionable patterns found, exit silently.`,
|
|
2531
|
+
},
|
|
2532
|
+
tags: ['cat:learning', 'evolution'],
|
|
2533
|
+
},
|
|
2534
|
+
{
|
|
2535
|
+
slug: 'evolution-overdue-check',
|
|
2536
|
+
name: 'Evolution Overdue Check',
|
|
2537
|
+
description: 'Monitor overdue evolution actions and stale commitments. Report only — no autonomous completing or cancelling.',
|
|
2538
|
+
schedule: '0 */4 * * *',
|
|
2539
|
+
priority: 'high',
|
|
2540
|
+
expectedDurationMinutes: 2,
|
|
2541
|
+
model: 'haiku',
|
|
2542
|
+
enabled: true,
|
|
2543
|
+
gate: `curl -sf http://localhost:${port}/evolution/actions/overdue 2>/dev/null | python3 -c "import sys,json; d=json.load(sys.stdin); exit(0 if len(d.get('overdue',[])) > 0 else 1)"`,
|
|
2544
|
+
execute: {
|
|
2545
|
+
type: 'prompt',
|
|
2546
|
+
value: `Check for overdue commitments: curl -s http://localhost:${port}/evolution/actions/overdue
|
|
2547
|
+
|
|
2548
|
+
For each overdue action:
|
|
2549
|
+
1. Assess: Can this be completed now? Is it still relevant?
|
|
2550
|
+
2. If actionable, attempt to complete it or advance it
|
|
2551
|
+
3. If no longer relevant, cancel it: curl -s -X PATCH http://localhost:${port}/evolution/actions/ACT-XXX -H 'Content-Type: application/json' -d '{"status":"cancelled","resolution":"No longer relevant because..."}'
|
|
2552
|
+
4. If blocked, escalate to the user via Telegram (if configured)
|
|
2553
|
+
|
|
2554
|
+
Also check pending actions (curl -s http://localhost:${port}/evolution/actions?status=pending) for items that have been pending more than 48 hours without a due date — these are forgotten commitments.
|
|
2555
|
+
|
|
2556
|
+
If no overdue or stale items, exit silently.`,
|
|
2557
|
+
},
|
|
2558
|
+
tags: ['cat:learning', 'role:worker', 'exec:prompt', 'pair:commitment-detection'],
|
|
2559
|
+
},
|
|
2560
|
+
{
|
|
2561
|
+
slug: 'project-map-refresh',
|
|
2562
|
+
name: 'Project Map Refresh',
|
|
2563
|
+
description: 'Regenerate the project territory map to keep spatial awareness current.',
|
|
2564
|
+
schedule: '0 */12 * * *',
|
|
2565
|
+
priority: 'medium',
|
|
2566
|
+
expectedDurationMinutes: 1,
|
|
2567
|
+
model: 'haiku',
|
|
2568
|
+
enabled: true,
|
|
2569
|
+
gate: `curl -sf http://localhost:${port}/health >/dev/null 2>&1`,
|
|
2570
|
+
execute: {
|
|
2571
|
+
type: 'script',
|
|
2572
|
+
value: `RESULT=$(curl -s -X POST http://localhost:${port}/project-map/refresh -H "Authorization: Bearer $(python3 -c "import json; print(json.load(open('.instar/config.json')).get('authToken',''))" 2>/dev/null)" 2>/dev/null); echo "$RESULT" | python3 -c "import sys,json; d=json.load(sys.stdin); print(f'Project map refreshed: {d.get(\"totalFiles\",0)} files, {d.get(\"directories\",0)} dirs')" 2>/dev/null || echo "Project map refresh: done"`,
|
|
2573
|
+
},
|
|
2574
|
+
tags: ['cat:maintenance', 'role:worker', 'exec:script'],
|
|
2575
|
+
},
|
|
2576
|
+
{
|
|
2577
|
+
slug: 'coherence-audit',
|
|
2578
|
+
name: 'Coherence Audit',
|
|
2579
|
+
description: 'Verify topic-project bindings are still valid, state files are healthy, and no drift has occurred.',
|
|
2580
|
+
schedule: '0 */8 * * *',
|
|
2581
|
+
priority: 'medium',
|
|
2582
|
+
expectedDurationMinutes: 2,
|
|
2583
|
+
model: 'haiku',
|
|
2584
|
+
enabled: true,
|
|
2585
|
+
gate: `curl -sf http://localhost:${port}/health >/dev/null 2>&1`,
|
|
2586
|
+
execute: {
|
|
2587
|
+
type: 'skill',
|
|
2588
|
+
value: 'coherence-audit',
|
|
2589
|
+
},
|
|
2590
|
+
tags: ['cat:maintenance', 'role:worker', 'exec:skill'],
|
|
2591
|
+
},
|
|
2592
|
+
{
|
|
2593
|
+
slug: 'degradation-digest',
|
|
2594
|
+
name: 'Degradation Digest',
|
|
2595
|
+
description: 'Read DegradationReporter events, group repeated patterns, and escalate trends that need attention.',
|
|
2596
|
+
schedule: '0 */4 * * *',
|
|
2597
|
+
priority: 'medium',
|
|
2598
|
+
expectedDurationMinutes: 1,
|
|
2599
|
+
model: 'haiku',
|
|
2600
|
+
enabled: true,
|
|
2601
|
+
gate: `test -f .instar/state/degradation-events.json && python3 -c "import json; events=json.load(open('.instar/state/degradation-events.json')); exit(0 if len(events) > 0 else 1)" 2>/dev/null`,
|
|
2602
|
+
execute: {
|
|
2603
|
+
type: 'skill',
|
|
2604
|
+
value: 'degradation-digest',
|
|
2605
|
+
},
|
|
2606
|
+
tags: ['cat:guardian', 'role:worker', 'exec:skill'],
|
|
2607
|
+
},
|
|
2608
|
+
{
|
|
2609
|
+
slug: 'state-integrity-check',
|
|
2610
|
+
name: 'State Integrity Check',
|
|
2611
|
+
description: 'Cross-validate state file consistency, detect orphaned references and bloat.',
|
|
2612
|
+
schedule: '0 */6 * * *',
|
|
2613
|
+
priority: 'medium',
|
|
2614
|
+
expectedDurationMinutes: 1,
|
|
2615
|
+
model: 'haiku',
|
|
2616
|
+
enabled: true,
|
|
2617
|
+
gate: `curl -sf http://localhost:${port}/health >/dev/null 2>&1`,
|
|
2618
|
+
execute: {
|
|
2619
|
+
type: 'skill',
|
|
2620
|
+
value: 'state-integrity-check',
|
|
2621
|
+
},
|
|
2622
|
+
tags: ['cat:guardian', 'role:worker', 'exec:skill'],
|
|
2623
|
+
},
|
|
2624
|
+
{
|
|
2625
|
+
slug: 'memory-hygiene',
|
|
2626
|
+
name: 'Memory Hygiene',
|
|
2627
|
+
description: 'Review MEMORY.md for stale entries, duplicates, and quality issues. Propose cleanup.',
|
|
2628
|
+
schedule: '0 */12 * * *',
|
|
2629
|
+
priority: 'high',
|
|
2630
|
+
expectedDurationMinutes: 5,
|
|
2631
|
+
model: 'opus',
|
|
2632
|
+
enabled: true,
|
|
2633
|
+
gate: `test -f .instar/MEMORY.md && wc -w < .instar/MEMORY.md | python3 -c "import sys; exit(0 if int(sys.stdin.read().strip()) > 100 else 1)" 2>/dev/null`,
|
|
2634
|
+
execute: {
|
|
2635
|
+
type: 'skill',
|
|
2636
|
+
value: 'memory-hygiene',
|
|
2637
|
+
},
|
|
2638
|
+
grounding: {
|
|
2639
|
+
requiresIdentity: true,
|
|
2640
|
+
contextFiles: ['MEMORY.md'],
|
|
2641
|
+
},
|
|
2642
|
+
tags: ['cat:maintenance', 'role:worker', 'exec:skill'],
|
|
2643
|
+
},
|
|
2644
|
+
{
|
|
2645
|
+
slug: 'guardian-pulse',
|
|
2646
|
+
name: 'Guardian Pulse',
|
|
2647
|
+
description: 'Meta-monitor: verify other jobs are running, healthy, and not silently failing.',
|
|
2648
|
+
schedule: '0 */8 * * *',
|
|
2649
|
+
priority: 'high',
|
|
2650
|
+
expectedDurationMinutes: 2,
|
|
2651
|
+
model: 'haiku',
|
|
2652
|
+
enabled: true,
|
|
2653
|
+
gate: `curl -sf http://localhost:${port}/health >/dev/null 2>&1`,
|
|
2654
|
+
execute: {
|
|
2655
|
+
type: 'skill',
|
|
2656
|
+
value: 'guardian-pulse',
|
|
2657
|
+
},
|
|
2658
|
+
tags: ['cat:guardian', 'role:worker', 'exec:skill'],
|
|
2659
|
+
},
|
|
2660
|
+
{
|
|
2661
|
+
slug: 'session-continuity-check',
|
|
2662
|
+
name: 'Session Continuity Check',
|
|
2663
|
+
description: 'Verify that sessions produce lasting artifacts: handoff notes, memory updates, learnings.',
|
|
2664
|
+
schedule: '0 */4 * * *',
|
|
2665
|
+
priority: 'medium',
|
|
2666
|
+
expectedDurationMinutes: 2,
|
|
2667
|
+
model: 'haiku',
|
|
2668
|
+
enabled: true,
|
|
2669
|
+
gate: `curl -sf http://localhost:${port}/health >/dev/null 2>&1`,
|
|
2670
|
+
execute: {
|
|
2671
|
+
type: 'skill',
|
|
2672
|
+
value: 'session-continuity-check',
|
|
2673
|
+
},
|
|
2674
|
+
tags: ['cat:guardian', 'role:worker', 'exec:skill'],
|
|
2675
|
+
},
|
|
2676
|
+
{
|
|
2677
|
+
slug: 'memory-export',
|
|
2678
|
+
name: 'Memory Export',
|
|
2679
|
+
description: 'Regenerate MEMORY.md from SemanticMemory knowledge graph. Keeps the human-readable memory snapshot fresh without manual intervention.',
|
|
2680
|
+
schedule: '0 */6 * * *',
|
|
2681
|
+
priority: 'medium',
|
|
2682
|
+
expectedDurationMinutes: 1,
|
|
2683
|
+
model: 'haiku',
|
|
2684
|
+
enabled: true,
|
|
2685
|
+
gate: `curl -sf http://localhost:${port}/health >/dev/null 2>&1 && curl -sf -H "Authorization: Bearer $AUTH" http://localhost:${port}/semantic/stats >/dev/null 2>&1`,
|
|
2686
|
+
execute: {
|
|
2687
|
+
type: 'script',
|
|
2688
|
+
value: `AUTH=$(python3 -c "import json; print(json.load(open('.instar/config.json')).get('authToken',''))" 2>/dev/null); AGENT=$(python3 -c "import json; print(json.load(open('.instar/config.json')).get('agentName','Agent'))" 2>/dev/null); RESULT=$(curl -s -X POST -H "Authorization: Bearer $AUTH" -H "Content-Type: application/json" -d "{\\"filePath\\":\\".instar/MEMORY.md\\",\\"agentName\\":\\"$AGENT\\"}" http://localhost:${port}/semantic/export-memory 2>/dev/null); COUNT=$(echo "$RESULT" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('entityCount',0))" 2>/dev/null || echo 0); EXCLUDED=$(echo "$RESULT" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('excludedCount',0))" 2>/dev/null || echo 0); [ "$COUNT" -gt "0" ] && echo "Memory export: $COUNT entities written to MEMORY.md ($EXCLUDED excluded below threshold)." || echo "Memory export: no entities to export."`,
|
|
2689
|
+
},
|
|
2690
|
+
tags: ['cat:maintenance', 'role:worker', 'exec:script'],
|
|
2691
|
+
},
|
|
2692
|
+
{
|
|
2693
|
+
slug: 'git-sync',
|
|
2694
|
+
name: 'Git Sync',
|
|
2695
|
+
description: 'Intelligent multi-machine git synchronization. Pulls remote changes, merges with conflict resolution, commits local changes, and pushes. Uses tiered model selection: haiku for clean syncs, sonnet for state file conflicts, opus for code conflicts.',
|
|
2696
|
+
schedule: '0 * * * *',
|
|
2697
|
+
priority: 'high',
|
|
2698
|
+
expectedDurationMinutes: 5,
|
|
2699
|
+
model: 'haiku',
|
|
2700
|
+
enabled: true,
|
|
2701
|
+
gate: 'bash .claude/scripts/git-sync-gate.sh',
|
|
2702
|
+
execute: {
|
|
2703
|
+
type: 'skill',
|
|
2704
|
+
value: 'git-sync',
|
|
2705
|
+
},
|
|
2706
|
+
tags: ['cat:infrastructure', 'role:worker', 'exec:skill'],
|
|
2707
|
+
telegramNotify: false,
|
|
2708
|
+
},
|
|
2709
|
+
{
|
|
2710
|
+
slug: 'capability-audit',
|
|
2711
|
+
name: 'Capability Audit',
|
|
2712
|
+
description: 'Refresh the capability map and detect drift. Compute-first: only spawns LLM if changes detected.',
|
|
2713
|
+
schedule: '0 */6 * * *',
|
|
2714
|
+
priority: 'medium',
|
|
2715
|
+
expectedDurationMinutes: 1,
|
|
2716
|
+
model: 'haiku',
|
|
2717
|
+
enabled: true,
|
|
2718
|
+
gate: `curl -sf http://localhost:${port}/health >/dev/null 2>&1`,
|
|
2719
|
+
execute: {
|
|
2720
|
+
type: 'script',
|
|
2721
|
+
value: `AUTH=$(python3 -c "import json; print(json.load(open('.instar/config.json')).get('authToken',''))" 2>/dev/null); REFRESH=$(curl -s -X POST -H "Authorization: Bearer $AUTH" http://localhost:${port}/capability-map/refresh 2>/dev/null); DRIFT=$(curl -s -H "Authorization: Bearer $AUTH" http://localhost:${port}/capability-map/drift 2>/dev/null); ADDED=$(echo "$DRIFT" | python3 -c "import sys,json; d=json.load(sys.stdin); print(len(d.get('added',[])))" 2>/dev/null || echo 0); REMOVED=$(echo "$DRIFT" | python3 -c "import sys,json; d=json.load(sys.stdin); print(len(d.get('removed',[])))" 2>/dev/null || echo 0); CHANGED=$(echo "$DRIFT" | python3 -c "import sys,json; d=json.load(sys.stdin); print(len(d.get('changed',[])))" 2>/dev/null || echo 0); UNMAPPED=$(echo "$DRIFT" | python3 -c "import sys,json; d=json.load(sys.stdin); print(len(d.get('unmapped',[])))" 2>/dev/null || echo 0); if [ "$ADDED" -gt "0" ] || [ "$REMOVED" -gt "0" ] || [ "$CHANGED" -gt "0" ] || [ "$UNMAPPED" -gt "0" ]; then echo "Capability drift detected: +$ADDED -$REMOVED ~$CHANGED ?$UNMAPPED"; echo "$DRIFT" | python3 -c "import sys,json; d=json.load(sys.stdin); [print(f' + {c[\"id\"]}') for c in d.get('added',[])]; [print(f' - {r[\"id\"]}') for r in d.get('removed',[])]; [print(f' ~ {c[\"id\"]} ({c[\"field\"]})') for c in d.get('changed',[])]" 2>/dev/null; else echo "Capability audit: no drift detected."; fi`,
|
|
2722
|
+
},
|
|
2723
|
+
grounding: {
|
|
2724
|
+
requiresIdentity: false,
|
|
2725
|
+
contextFiles: ['.instar/state/capability-manifest.json'],
|
|
2726
|
+
},
|
|
2727
|
+
tags: ['cat:maintenance', 'role:worker', 'exec:script'],
|
|
2728
|
+
},
|
|
2729
|
+
{
|
|
2730
|
+
slug: 'identity-review',
|
|
2731
|
+
name: 'Identity Review',
|
|
2732
|
+
description: 'Review identity coherence, check soul.md drift, nudge reflection if identity-relevant learnings have accumulated.',
|
|
2733
|
+
schedule: '0 3 * * *',
|
|
2734
|
+
priority: 'medium',
|
|
2735
|
+
expectedDurationMinutes: 5,
|
|
2736
|
+
model: 'opus',
|
|
2737
|
+
enabled: true,
|
|
2738
|
+
gate: `curl -sf http://localhost:${port}/health >/dev/null 2>&1 && test -f .instar/soul.md`,
|
|
2739
|
+
execute: {
|
|
2740
|
+
type: 'prompt',
|
|
2741
|
+
value: `Identity review — check your identity coherence and growth.
|
|
2742
|
+
|
|
2743
|
+
AUTH=$(python3 -c "import json; print(json.load(open('.instar/config.json')).get('authToken',''))" 2>/dev/null)
|
|
2744
|
+
|
|
2745
|
+
1. **Check soul.md drift**: curl -s -H "Authorization: Bearer $AUTH" http://localhost:${port}/identity/soul/drift
|
|
2746
|
+
- If anyAboveThreshold is true, review the divergence. Is this healthy growth or unexpected drift?
|
|
2747
|
+
- If drift looks healthy, mark it reviewed: the growth is intentional.
|
|
2748
|
+
- If drift looks concerning, flag with [ATTENTION] so the user is notified.
|
|
2749
|
+
|
|
2750
|
+
2. **Check pending changes**: curl -s -H "Authorization: Bearer $AUTH" http://localhost:${port}/identity/soul/pending
|
|
2751
|
+
- If pending changes exist, surface them to the user via Telegram (the user should approve/reject these).
|
|
2752
|
+
|
|
2753
|
+
3. **Check for identity-relevant learnings**: curl -s -H "Authorization: Bearer $AUTH" http://localhost:${port}/evolution/learnings?applied=false
|
|
2754
|
+
- For each unapplied learning, assess: is this about operational knowledge (how to do something) or about your values, beliefs, or self-understanding?
|
|
2755
|
+
- If you find 3+ identity-relevant learnings since your last soul.md update, consider running /reflect.
|
|
2756
|
+
- Don't force it — if none of the learnings touch on identity, that's fine. Exit silently.
|
|
2757
|
+
|
|
2758
|
+
4. **Check AGENT.md evolution**: Read .instar/AGENT.md
|
|
2759
|
+
- Do your principles still match your actual behavior?
|
|
2760
|
+
- Is the Self-Observations section populated? If you've noticed behavioral patterns, document them.
|
|
2761
|
+
- Update Identity History if you make changes.
|
|
2762
|
+
|
|
2763
|
+
5. **Integrity check**: curl -s -H "Authorization: Bearer $AUTH" http://localhost:${port}/identity/soul/integrity
|
|
2764
|
+
- If integrity fails, flag with [ATTENTION] — soul.md may have been modified outside normal channels.
|
|
2765
|
+
|
|
2766
|
+
If everything is coherent and no reflection is needed, exit silently. Only report via [ATTENTION] if drift is concerning, integrity fails, or pending changes need user action.`,
|
|
2767
|
+
},
|
|
2768
|
+
grounding: {
|
|
2769
|
+
requiresIdentity: true,
|
|
2770
|
+
contextFiles: ['AGENT.md', 'soul.md'],
|
|
2771
|
+
},
|
|
2772
|
+
telegramNotify: 'on-alert',
|
|
2773
|
+
tags: ['cat:identity', 'role:worker', 'exec:prompt'],
|
|
2774
|
+
},
|
|
2775
|
+
{
|
|
2776
|
+
slug: 'evolution-proposal-evaluate',
|
|
2777
|
+
name: 'Evolution Proposal Evaluate',
|
|
2778
|
+
description: 'Phase A: Read pending evolution proposals, evaluate their merit, accept or reject. Paired with evolution-proposal-implement.',
|
|
2779
|
+
schedule: '0 */6 * * *',
|
|
2780
|
+
priority: 'medium',
|
|
2781
|
+
expectedDurationMinutes: 3,
|
|
2782
|
+
model: 'sonnet',
|
|
2783
|
+
enabled: true,
|
|
2784
|
+
gate: `curl -sf http://localhost:${port}/evolution/proposals?status=proposed 2>/dev/null | python3 -c "import sys,json; d=json.load(sys.stdin); exit(0 if len(d.get('proposals',[])) > 0 else 1)"`,
|
|
2785
|
+
execute: {
|
|
2786
|
+
type: 'prompt',
|
|
2787
|
+
value: `Review pending evolution proposals: curl -s http://localhost:${port}/evolution/proposals?status=proposed\n\nFor each proposal:\n1. Read the title, description, type, and source\n2. Evaluate: Is this a genuine improvement? Is the effort worth the impact? Does it align with our goals?\n3. If approved, update status: curl -s -X PATCH http://localhost:${port}/evolution/proposals/EVO-XXX -H 'Content-Type: application/json' -d '{"status":"approved"}'\n4. If rejected or deferred, update with reason.\n\nDo NOT implement approved proposals — that's handled by the paired evolution-proposal-implement job.\n\nAlso check the dashboard: curl -s http://localhost:${port}/evolution — report any highlights to the user if they seem important.\n\nIf no proposals need attention, exit silently.`,
|
|
2788
|
+
},
|
|
2789
|
+
tags: ['cat:learning', 'role:worker', 'exec:prompt', 'pair:evolution-proposal-implement'],
|
|
2790
|
+
},
|
|
2791
|
+
{
|
|
2792
|
+
slug: 'evolution-proposal-implement',
|
|
2793
|
+
name: 'Evolution Proposal Implement',
|
|
2794
|
+
description: 'Phase B: Pick up approved evolution proposals and implement them with full context. Paired with evolution-proposal-evaluate.',
|
|
2795
|
+
schedule: '0 1,7,13,19 * * *',
|
|
2796
|
+
priority: 'medium',
|
|
2797
|
+
expectedDurationMinutes: 10,
|
|
2798
|
+
model: 'opus',
|
|
2799
|
+
enabled: true,
|
|
2800
|
+
gate: `curl -sf http://localhost:${port}/evolution/proposals?status=approved 2>/dev/null | python3 -c "import sys,json; d=json.load(sys.stdin); exit(0 if len(d.get('proposals',[])) > 0 else 1)"`,
|
|
2801
|
+
execute: {
|
|
2802
|
+
type: 'prompt',
|
|
2803
|
+
value: `Implement approved evolution proposals: curl -s http://localhost:${port}/evolution/proposals?status=approved\n\nFor each approved proposal:\n1. Read the full description and understand what needs to be built\n2. Implement it: create the skill/hook/job/config change described\n3. After implementation, mark complete: curl -s -X PATCH http://localhost:${port}/evolution/proposals/EVO-XXX -H 'Content-Type: application/json' -d '{"status":"implemented","resolution":"What was done"}'\n\nIf no approved proposals exist, exit silently.`,
|
|
2804
|
+
},
|
|
2805
|
+
grounding: {
|
|
2806
|
+
requiresIdentity: true,
|
|
2807
|
+
contextFiles: ['MEMORY.md', '.instar/context/development.md'],
|
|
2808
|
+
},
|
|
2809
|
+
tags: ['cat:learning', 'role:worker', 'exec:prompt', 'pair:evolution-proposal-evaluate'],
|
|
2810
|
+
},
|
|
2811
|
+
{
|
|
2812
|
+
slug: 'commitment-detection',
|
|
2813
|
+
name: 'Commitment Detection',
|
|
2814
|
+
description: 'Scan recent messages for promises and commitments, register them as evolution actions. Replaces CommitmentSentinel server process.',
|
|
2815
|
+
schedule: '*/5 * * * *',
|
|
2816
|
+
priority: 'high',
|
|
2817
|
+
expectedDurationMinutes: 1,
|
|
2818
|
+
model: 'haiku',
|
|
2819
|
+
enabled: true,
|
|
2820
|
+
gate: `curl -sf http://localhost:${port}/health >/dev/null 2>&1`,
|
|
2821
|
+
execute: {
|
|
2822
|
+
type: 'prompt',
|
|
2823
|
+
value: `Scan recent messages for commitments and promises.\n\nAUTH=$(python3 -c "import json; print(json.load(open('.instar/config.json')).get('authToken',''))" 2>/dev/null)\n\n1. Read your bookmark: cat .instar/state/commitment-detection-bookmark.json 2>/dev/null || echo '{"lastProcessedId": 0}'\n2. Fetch new messages since bookmark from Telegram message log: tail -100 .instar/telegram-messages.jsonl\n3. For each new message, check: does it contain a commitment, promise, or action item? Look for patterns like 'I will', 'let me', 'I\\'ll build', 'we should', 'TODO', 'action item', deadlines, etc.\n4. For each detected commitment, register it: curl -s -X POST http://localhost:${port}/evolution/actions -H "Authorization: Bearer $AUTH" -H 'Content-Type: application/json' -d '{"title":"...","source":"commitment-detection","description":"...","dueDate":"..."}'\n5. Update bookmark with the last processed message ID.\n\nOnly process NEW messages since last bookmark. Exit silently if no new commitments found.`,
|
|
2824
|
+
},
|
|
2825
|
+
tags: ['cat:evolution', 'role:worker', 'exec:prompt', 'pair:evolution-overdue-check'],
|
|
2826
|
+
},
|
|
2827
|
+
{
|
|
2828
|
+
slug: 'dashboard-link-refresh',
|
|
2829
|
+
name: 'Dashboard Link Refresh',
|
|
2830
|
+
description: 'Refresh the pinned dashboard link in Telegram so it never goes stale.',
|
|
2831
|
+
schedule: '*/15 * * * *',
|
|
2832
|
+
priority: 'medium',
|
|
2833
|
+
expectedDurationMinutes: 1,
|
|
2834
|
+
model: 'haiku',
|
|
2835
|
+
enabled: true,
|
|
2836
|
+
gate: `curl -sf http://localhost:${port}/health >/dev/null 2>&1`,
|
|
2837
|
+
execute: {
|
|
2838
|
+
type: 'script',
|
|
2839
|
+
value: `AUTH=$(python3 -c "import json; print(json.load(open('.instar/config.json')).get('authToken','')).strip()" 2>/dev/null) && curl -sf -X POST -H "Authorization: Bearer $AUTH" http://localhost:${port}/telegram/dashboard-refresh`,
|
|
2840
|
+
},
|
|
2841
|
+
tags: ['cat:infrastructure', 'role:worker', 'exec:script'],
|
|
2842
|
+
telegramNotify: false,
|
|
2843
|
+
},
|
|
2844
|
+
{
|
|
2845
|
+
slug: 'overseer-guardian',
|
|
2846
|
+
name: 'Guardian Overseer',
|
|
2847
|
+
description: 'Reviews all guardian/monitoring jobs: health-check, guardian-pulse, degradation-digest, state-integrity-check, session-continuity-check. Spots cross-job patterns, flags contradictions, recommends schedule/priority/model changes.',
|
|
2848
|
+
schedule: '0 */6 * * *',
|
|
2849
|
+
priority: 'medium',
|
|
2850
|
+
expectedDurationMinutes: 5,
|
|
2851
|
+
model: 'sonnet',
|
|
2852
|
+
enabled: true,
|
|
2853
|
+
execute: {
|
|
2854
|
+
type: 'prompt',
|
|
2855
|
+
value: `You are a Category Overseer for the GUARDIAN category. Your job is to review all guardian/monitoring jobs and assess the health of the monitoring system itself.\n\n1. Fetch the category report: curl -H "Authorization: Bearer $AUTH" http://localhost:${port}/jobs/category-report/guardian?sinceHours=24\n2. Analyze the report for:\n - Jobs with high failure rates or consecutive failures\n - Jobs that are being skipped excessively (especially for quota reasons)\n - Schedule mismatches (jobs running too often or not often enough for their purpose)\n - Model over-allocation (could any job use a cheaper model?)\n - Contradictions between job findings (e.g., health-check says healthy but degradation-digest found issues)\n - Coverage gaps (are there monitoring blind spots?)\n3. Read the handoff notes from each job — do they tell a coherent story?\n4. If you find actionable issues, write a clear summary. If everything is healthy, say so briefly.\n\nWrite your findings in [HANDOFF] tags for the next overseer run. Focus on trends and cross-job insights that individual jobs can't see.`,
|
|
2856
|
+
},
|
|
2857
|
+
tags: ['cat:overseer', 'role:supervisor'],
|
|
2858
|
+
telegramNotify: 'on-alert',
|
|
2859
|
+
},
|
|
2860
|
+
{
|
|
2861
|
+
slug: 'overseer-learning',
|
|
2862
|
+
name: 'Learning Overseer',
|
|
2863
|
+
description: 'Reviews all evolution/learning jobs: evolution-review, insight-harvest, commitment-check, reflection-trigger. Assesses whether the learning pipeline is producing value.',
|
|
2864
|
+
schedule: '0 3 */2 * *',
|
|
2865
|
+
priority: 'medium',
|
|
2866
|
+
expectedDurationMinutes: 5,
|
|
2867
|
+
model: 'sonnet',
|
|
2868
|
+
enabled: true,
|
|
2869
|
+
execute: {
|
|
2870
|
+
type: 'prompt',
|
|
2871
|
+
value: `You are a Category Overseer for the LEARNING category. Your job is to review all evolution/learning jobs and assess whether the learning pipeline is producing genuine value.\n\n1. Fetch the category report: curl -H "Authorization: Bearer $AUTH" http://localhost:${port}/jobs/category-report/learning?sinceHours=48\n2. Analyze:\n - Are evolution proposals being generated AND accepted? What's the accept/reject ratio?\n - Is insight-harvest finding novel insights or recycling stale ones?\n - Are commitments being tracked and completed, or piling up?\n - Is reflection-trigger producing meaningful MEMORY.md updates?\n - Are any learning jobs consistently skipped due to quota? This means the learning pipeline is being starved.\n - Model costs: reflection-trigger uses opus — is the quality difference worth it vs sonnet?\n3. Look for the meta-pattern: is the agent actually getting smarter over time, or is the learning pipeline just busy-work?\n4. Check handoff notes for patterns across runs.\n\nWrite findings in [HANDOFF] tags. Flag if the learning pipeline is producing diminishing returns.`,
|
|
2872
|
+
},
|
|
2873
|
+
tags: ['cat:overseer', 'role:supervisor'],
|
|
2874
|
+
telegramNotify: 'on-alert',
|
|
2875
|
+
},
|
|
2876
|
+
{
|
|
2877
|
+
slug: 'overseer-maintenance',
|
|
2878
|
+
name: 'Maintenance Overseer',
|
|
2879
|
+
description: 'Reviews all maintenance jobs: project-map-refresh, coherence-audit, capability-audit, memory-hygiene, memory-export. Ensures housekeeping is effective.',
|
|
2880
|
+
schedule: '0 2 * * *',
|
|
2881
|
+
priority: 'medium',
|
|
2882
|
+
expectedDurationMinutes: 5,
|
|
2883
|
+
model: 'sonnet',
|
|
2884
|
+
enabled: true,
|
|
2885
|
+
execute: {
|
|
2886
|
+
type: 'prompt',
|
|
2887
|
+
value: `You are a Category Overseer for the MAINTENANCE category. Your job is to review all housekeeping/maintenance jobs and ensure they're keeping the system clean.\n\n1. Fetch the category report: curl -H "Authorization: Bearer $AUTH" http://localhost:${port}/jobs/category-report/maintenance?sinceHours=48\n2. Analyze:\n - Is memory-hygiene actually reducing stale entries, or finding nothing each run?\n - Is project-map-refresh keeping the map accurate? How often does it find drift?\n - Is coherence-audit finding real misalignments or just confirming everything is fine?\n - Are any maintenance jobs redundant with each other? (e.g., overlapping checks)\n - Are skill-type jobs (coherence-audit, memory-hygiene) running correctly?\n - Workload trends: are jobs processing fewer items over time (diminishing returns)?\n3. Maintenance jobs should trend toward finding LESS work over time. If they consistently find issues, something upstream is broken.\n\nWrite findings in [HANDOFF] tags. Recommend disabling or reducing frequency of jobs that consistently find nothing.`,
|
|
2888
|
+
},
|
|
2889
|
+
tags: ['cat:overseer', 'role:supervisor'],
|
|
2890
|
+
telegramNotify: 'on-alert',
|
|
2891
|
+
},
|
|
2892
|
+
{
|
|
2893
|
+
slug: 'overseer-infrastructure',
|
|
2894
|
+
name: 'Infrastructure Overseer',
|
|
2895
|
+
description: 'Reviews infrastructure jobs: git-sync, dashboard-link-refresh, feedback-retry. Ensures plumbing is solid.',
|
|
2896
|
+
schedule: '0 6 * * *',
|
|
2897
|
+
priority: 'medium',
|
|
2898
|
+
expectedDurationMinutes: 3,
|
|
2899
|
+
model: 'haiku',
|
|
2900
|
+
enabled: true,
|
|
2901
|
+
execute: {
|
|
2902
|
+
type: 'prompt',
|
|
2903
|
+
value: `You are a Category Overseer for the INFRASTRUCTURE category. Your job is to review infrastructure/plumbing jobs.\n\n1. Fetch the category report: curl -H "Authorization: Bearer $AUTH" http://localhost:${port}/jobs/category-report/infrastructure?sinceHours=48\n2. Analyze:\n - Is git-sync succeeding? Any merge conflicts or divergence?\n - Is dashboard-link-refresh keeping links current? Could it run less often?\n - Is feedback-retry actually retrying anything, or is the queue always empty?\n - Model allocation: git-sync uses high priority — is that justified by its failure rate?\n - Are any infrastructure jobs causing issues for other jobs (e.g., git-sync holding sessions)?\n3. Infrastructure jobs should be boring and reliable. Any excitement is a problem.\n\nWrite findings in [HANDOFF] tags. Keep it brief — infrastructure overseers should be the quietest.`,
|
|
2904
|
+
},
|
|
2905
|
+
tags: ['cat:overseer', 'role:supervisor'],
|
|
2906
|
+
telegramNotify: 'on-alert',
|
|
2907
|
+
},
|
|
2908
|
+
{
|
|
2909
|
+
slug: 'overseer-development',
|
|
2910
|
+
name: 'Development Overseer',
|
|
2911
|
+
description: 'Reviews development jobs: ci-monitor. Ensures development tooling is functional.',
|
|
2912
|
+
schedule: '0 8 * * *',
|
|
2913
|
+
priority: 'low',
|
|
2914
|
+
expectedDurationMinutes: 3,
|
|
2915
|
+
model: 'haiku',
|
|
2916
|
+
enabled: true,
|
|
2917
|
+
execute: {
|
|
2918
|
+
type: 'prompt',
|
|
2919
|
+
value: `You are a Category Overseer for the DEVELOPMENT category. Your job is to review development-focused jobs.\n\n1. Fetch the category report: curl -H "Authorization: Bearer $AUTH" http://localhost:${port}/jobs/category-report/development?sinceHours=48\n2. Analyze:\n - Are development jobs consuming appropriate resources for their value?\n - Are there CI/testing patterns that could be automated?\n3. Development jobs are only valuable when there's active development. If the codebase is stable, these could be reduced.\n\nWrite findings in [HANDOFF] tags.`,
|
|
2920
|
+
},
|
|
2921
|
+
tags: ['cat:overseer', 'role:supervisor'],
|
|
2922
|
+
telegramNotify: 'on-alert',
|
|
2923
|
+
},
|
|
2924
|
+
];
|
|
2925
|
+
}
|
|
2926
|
+
/**
|
|
2927
|
+
* Refresh hooks, Claude settings, and CLAUDE.md for an existing installation.
|
|
2928
|
+
* Called after updates to ensure new hooks and documentation are installed.
|
|
2929
|
+
* Re-writes all hook files (idempotent), merges new hooks into settings,
|
|
2930
|
+
* appends any missing sections to CLAUDE.md, and installs scripts for
|
|
2931
|
+
* configured integrations (e.g., Telegram relay).
|
|
2932
|
+
*/
|
|
2933
|
+
export function refreshHooksAndSettings(projectDir, stateDir) {
|
|
2934
|
+
installHooks(stateDir);
|
|
2935
|
+
// Read port from config.json so HTTP hooks get resolved URLs
|
|
2936
|
+
let serverPort;
|
|
2937
|
+
try {
|
|
2938
|
+
const configPath = path.join(stateDir, 'config.json');
|
|
2939
|
+
if (fs.existsSync(configPath)) {
|
|
2940
|
+
const config = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
|
|
2941
|
+
serverPort = config.port;
|
|
2942
|
+
}
|
|
2943
|
+
}
|
|
2944
|
+
catch { /* non-fatal */ }
|
|
2945
|
+
installClaudeSettings(projectDir, serverPort);
|
|
2946
|
+
refreshClaudeMd(projectDir, stateDir);
|
|
2947
|
+
refreshJobs(stateDir);
|
|
2948
|
+
refreshScripts(projectDir, stateDir);
|
|
2949
|
+
}
|
|
2950
|
+
/**
|
|
2951
|
+
* Merge new default jobs into existing jobs.json without overwriting user changes.
|
|
2952
|
+
* Only adds jobs whose slugs don't already exist.
|
|
2953
|
+
*/
|
|
2954
|
+
function refreshJobs(stateDir) {
|
|
2955
|
+
const jobsPath = path.join(stateDir, 'jobs.json');
|
|
2956
|
+
if (!fs.existsSync(jobsPath))
|
|
2957
|
+
return;
|
|
2958
|
+
let port = 4321;
|
|
2959
|
+
try {
|
|
2960
|
+
const config = JSON.parse(fs.readFileSync(path.join(stateDir, 'config.json'), 'utf-8'));
|
|
2961
|
+
port = config.port || 4321;
|
|
2962
|
+
}
|
|
2963
|
+
catch { /* use default */ }
|
|
2964
|
+
try {
|
|
2965
|
+
const existingJobs = JSON.parse(fs.readFileSync(jobsPath, 'utf-8'));
|
|
2966
|
+
const existingSlugs = new Set(existingJobs.map(j => j.slug));
|
|
2967
|
+
const defaultJobs = getDefaultJobs(port);
|
|
2968
|
+
let added = 0;
|
|
2969
|
+
for (const job of defaultJobs) {
|
|
2970
|
+
if (!existingSlugs.has(job.slug)) {
|
|
2971
|
+
existingJobs.push(job);
|
|
2972
|
+
added++;
|
|
2973
|
+
}
|
|
2974
|
+
}
|
|
2975
|
+
// Auto-enable git-sync if git + remote are available (migration from disabled default)
|
|
2976
|
+
const gitSyncJob = existingJobs.find(j => j.slug === 'git-sync');
|
|
2977
|
+
if (gitSyncJob && !gitSyncJob.enabled) {
|
|
2978
|
+
const projectDir = path.dirname(stateDir);
|
|
2979
|
+
const hasGit = fs.existsSync(path.join(projectDir, '.git'));
|
|
2980
|
+
let hasRemote = false;
|
|
2981
|
+
if (hasGit) {
|
|
2982
|
+
try {
|
|
2983
|
+
const remote = execFileSync('git', ['remote'], { cwd: projectDir, stdio: 'pipe' }).toString().trim();
|
|
2984
|
+
hasRemote = remote.length > 0;
|
|
2985
|
+
}
|
|
2986
|
+
catch { /* no git or no remote */ }
|
|
2987
|
+
}
|
|
2988
|
+
if (hasGit && hasRemote) {
|
|
2989
|
+
gitSyncJob.enabled = true;
|
|
2990
|
+
added++; // force write
|
|
2991
|
+
}
|
|
2992
|
+
}
|
|
2993
|
+
if (added > 0) {
|
|
2994
|
+
fs.writeFileSync(jobsPath, JSON.stringify(existingJobs, null, 2));
|
|
2995
|
+
}
|
|
2996
|
+
}
|
|
2997
|
+
catch { /* don't break on errors */ }
|
|
2998
|
+
}
|
|
2999
|
+
/**
|
|
3000
|
+
* Read config.json from state dir, returning parsed config or null.
|
|
3001
|
+
*/
|
|
3002
|
+
function readConfig(stateDir) {
|
|
3003
|
+
try {
|
|
3004
|
+
return JSON.parse(fs.readFileSync(path.join(stateDir, 'config.json'), 'utf-8'));
|
|
3005
|
+
}
|
|
3006
|
+
catch {
|
|
3007
|
+
return null;
|
|
3008
|
+
}
|
|
3009
|
+
}
|
|
3010
|
+
/**
|
|
3011
|
+
* Check if Telegram is configured in config.json.
|
|
3012
|
+
*/
|
|
3013
|
+
function isTelegramConfigured(stateDir) {
|
|
3014
|
+
const config = readConfig(stateDir);
|
|
3015
|
+
if (!config)
|
|
3016
|
+
return false;
|
|
3017
|
+
const messaging = config.messaging;
|
|
3018
|
+
return !!messaging?.some(m => m.type === 'telegram' && m.enabled);
|
|
3019
|
+
}
|
|
3020
|
+
/**
|
|
3021
|
+
* Check if WhatsApp is configured in config.json.
|
|
3022
|
+
*/
|
|
3023
|
+
function isWhatsAppConfigured(stateDir) {
|
|
3024
|
+
const config = readConfig(stateDir);
|
|
3025
|
+
if (!config)
|
|
3026
|
+
return false;
|
|
3027
|
+
const messaging = config.messaging;
|
|
3028
|
+
return !!messaging?.some(m => m.type === 'whatsapp' && m.enabled);
|
|
3029
|
+
}
|
|
3030
|
+
/**
|
|
3031
|
+
* Install scripts for configured integrations (e.g., Telegram relay, WhatsApp relay).
|
|
3032
|
+
* Called during refresh to ensure scripts exist for all configured integrations.
|
|
3033
|
+
*/
|
|
3034
|
+
function refreshScripts(projectDir, stateDir) {
|
|
3035
|
+
const config = readConfig(stateDir);
|
|
3036
|
+
if (!config)
|
|
3037
|
+
return;
|
|
3038
|
+
const port = config.port || 4040;
|
|
3039
|
+
// Install telegram-reply.sh if Telegram is configured
|
|
3040
|
+
if (isTelegramConfigured(stateDir)) {
|
|
3041
|
+
installTelegramRelay(projectDir, port);
|
|
3042
|
+
}
|
|
3043
|
+
// Install whatsapp-reply.sh if WhatsApp is configured
|
|
3044
|
+
if (isWhatsAppConfigured(stateDir)) {
|
|
3045
|
+
installWhatsAppRelay(projectDir, port);
|
|
3046
|
+
}
|
|
3047
|
+
// Always install smart-fetch.py (agentic web conventions)
|
|
3048
|
+
installSmartFetch(projectDir);
|
|
3049
|
+
// Always install git-sync-gate.sh (pre-screening for git-sync job)
|
|
3050
|
+
installGitSyncGate(projectDir);
|
|
3051
|
+
// Always install serendipity-capture.sh
|
|
3052
|
+
installSerendipityCapture(projectDir);
|
|
3053
|
+
}
|
|
3054
|
+
/**
|
|
3055
|
+
* Install the Telegram relay script that Claude uses to send responses
|
|
3056
|
+
* back to Telegram topics via the instar server API.
|
|
3057
|
+
*/
|
|
3058
|
+
function installTelegramRelay(projectDir, port) {
|
|
3059
|
+
const scriptsDir = path.join(projectDir, '.claude', 'scripts');
|
|
3060
|
+
fs.mkdirSync(scriptsDir, { recursive: true });
|
|
3061
|
+
const scriptContent = `#!/bin/bash
|
|
3062
|
+
# telegram-reply.sh — Send a message back to a Telegram topic via instar server.
|
|
3063
|
+
#
|
|
3064
|
+
# Usage:
|
|
3065
|
+
# .claude/scripts/telegram-reply.sh TOPIC_ID "message text"
|
|
3066
|
+
# echo "message text" | .claude/scripts/telegram-reply.sh TOPIC_ID
|
|
3067
|
+
# cat <<'EOF' | .claude/scripts/telegram-reply.sh TOPIC_ID
|
|
3068
|
+
# Multi-line message here
|
|
3069
|
+
# EOF
|
|
3070
|
+
|
|
3071
|
+
TOPIC_ID="$1"
|
|
3072
|
+
shift
|
|
3073
|
+
|
|
3074
|
+
if [ -z "$TOPIC_ID" ]; then
|
|
3075
|
+
echo "Usage: telegram-reply.sh TOPIC_ID [message]" >&2
|
|
3076
|
+
exit 1
|
|
3077
|
+
fi
|
|
3078
|
+
|
|
3079
|
+
# Read message from args or stdin
|
|
3080
|
+
if [ $# -gt 0 ]; then
|
|
3081
|
+
MSG="$*"
|
|
3082
|
+
else
|
|
3083
|
+
MSG="$(cat)"
|
|
3084
|
+
fi
|
|
3085
|
+
|
|
3086
|
+
if [ -z "$MSG" ]; then
|
|
3087
|
+
echo "No message provided" >&2
|
|
3088
|
+
exit 1
|
|
3089
|
+
fi
|
|
3090
|
+
|
|
3091
|
+
PORT="\${INSTAR_PORT:-${port}}"
|
|
3092
|
+
|
|
3093
|
+
# Escape for JSON
|
|
3094
|
+
JSON_MSG=$(printf '%s' "$MSG" | python3 -c 'import sys,json; print(json.dumps(sys.stdin.read()))' 2>/dev/null)
|
|
3095
|
+
if [ -z "$JSON_MSG" ]; then
|
|
3096
|
+
# Fallback if python3 not available: basic escape
|
|
3097
|
+
JSON_MSG="$(printf '%s' "$MSG" | sed 's/\\\\\\\\/\\\\\\\\\\\\\\\\/g; s/"/\\\\\\\\"/g' | sed ':a;N;$!ba;s/\\\\n/\\\\\\\\n/g')"
|
|
3098
|
+
JSON_MSG="\\"$JSON_MSG\\""
|
|
3099
|
+
fi
|
|
3100
|
+
|
|
3101
|
+
RESPONSE=$(curl -s -w "\\n%{http_code}" -X POST "http://localhost:\${PORT}/telegram/reply/\${TOPIC_ID}" \\
|
|
3102
|
+
-H 'Content-Type: application/json' \\
|
|
3103
|
+
-d "{\\"text\\":\${JSON_MSG}}")
|
|
3104
|
+
|
|
3105
|
+
HTTP_CODE=$(echo "$RESPONSE" | tail -1)
|
|
3106
|
+
BODY=$(echo "$RESPONSE" | sed '$d')
|
|
3107
|
+
|
|
3108
|
+
if [ "$HTTP_CODE" = "200" ]; then
|
|
3109
|
+
echo "Sent $(echo "$MSG" | wc -c | tr -d ' ') chars to topic $TOPIC_ID"
|
|
3110
|
+
else
|
|
3111
|
+
echo "Failed (HTTP $HTTP_CODE): $BODY" >&2
|
|
3112
|
+
exit 1
|
|
3113
|
+
fi
|
|
3114
|
+
`;
|
|
3115
|
+
const scriptPath = path.join(scriptsDir, 'telegram-reply.sh');
|
|
3116
|
+
fs.writeFileSync(scriptPath, scriptContent, { mode: 0o755 });
|
|
3117
|
+
}
|
|
3118
|
+
/**
|
|
3119
|
+
* Install the WhatsApp relay script that Claude uses to send responses
|
|
3120
|
+
* back to WhatsApp JIDs via the instar server API.
|
|
3121
|
+
*/
|
|
3122
|
+
function installWhatsAppRelay(projectDir, port) {
|
|
3123
|
+
const scriptsDir = path.join(projectDir, '.instar', 'scripts');
|
|
3124
|
+
fs.mkdirSync(scriptsDir, { recursive: true });
|
|
3125
|
+
const scriptContent = `#!/bin/bash
|
|
3126
|
+
# whatsapp-reply.sh — Send a message back to a WhatsApp JID via instar server.
|
|
3127
|
+
#
|
|
3128
|
+
# Usage:
|
|
3129
|
+
# .instar/scripts/whatsapp-reply.sh JID "message text"
|
|
3130
|
+
# echo "message text" | .instar/scripts/whatsapp-reply.sh JID
|
|
3131
|
+
# cat <<'EOF' | .instar/scripts/whatsapp-reply.sh JID
|
|
3132
|
+
# Multi-line message here
|
|
3133
|
+
# EOF
|
|
3134
|
+
#
|
|
3135
|
+
# JID format: phone@s.whatsapp.net (e.g., 12345678901@s.whatsapp.net)
|
|
3136
|
+
|
|
3137
|
+
JID="$1"
|
|
3138
|
+
shift
|
|
3139
|
+
|
|
3140
|
+
if [ -z "$JID" ]; then
|
|
3141
|
+
echo "Usage: whatsapp-reply.sh JID [message]" >&2
|
|
3142
|
+
exit 1
|
|
3143
|
+
fi
|
|
3144
|
+
|
|
3145
|
+
# Read message from args or stdin
|
|
3146
|
+
if [ $# -gt 0 ]; then
|
|
3147
|
+
MSG="$*"
|
|
3148
|
+
else
|
|
3149
|
+
MSG="$(cat)"
|
|
3150
|
+
fi
|
|
3151
|
+
|
|
3152
|
+
if [ -z "$MSG" ]; then
|
|
3153
|
+
echo "No message provided" >&2
|
|
3154
|
+
exit 1
|
|
3155
|
+
fi
|
|
3156
|
+
|
|
3157
|
+
PORT="\${INSTAR_PORT:-${port}}"
|
|
3158
|
+
|
|
3159
|
+
# Read auth token from config (if present)
|
|
3160
|
+
AUTH_TOKEN=""
|
|
3161
|
+
if [ -f ".instar/config.json" ]; then
|
|
3162
|
+
AUTH_TOKEN=$(python3 -c "import json; print(json.load(open('.instar/config.json')).get('authToken',''))" 2>/dev/null)
|
|
3163
|
+
fi
|
|
3164
|
+
|
|
3165
|
+
# Escape for JSON
|
|
3166
|
+
JSON_MSG=$(printf '%s' "$MSG" | python3 -c 'import sys,json; print(json.dumps(sys.stdin.read()))' 2>/dev/null)
|
|
3167
|
+
if [ -z "$JSON_MSG" ]; then
|
|
3168
|
+
JSON_MSG="$(printf '%s' "$MSG" | sed 's/\\\\\\\\/\\\\\\\\\\\\\\\\/g; s/"/\\\\\\\\"/g' | sed ':a;N;$!ba;s/\\\\n/\\\\\\\\n/g')"
|
|
3169
|
+
JSON_MSG="\\"$JSON_MSG\\""
|
|
3170
|
+
fi
|
|
3171
|
+
|
|
3172
|
+
if [ -n "$AUTH_TOKEN" ]; then
|
|
3173
|
+
RESPONSE=$(curl -s -w "\\n%{http_code}" -X POST "http://localhost:\${PORT}/whatsapp/send/\${JID}" \\
|
|
3174
|
+
-H 'Content-Type: application/json' \\
|
|
3175
|
+
-H "Authorization: Bearer \${AUTH_TOKEN}" \\
|
|
3176
|
+
-d "{\\"text\\":\${JSON_MSG}}")
|
|
3177
|
+
else
|
|
3178
|
+
RESPONSE=$(curl -s -w "\\n%{http_code}" -X POST "http://localhost:\${PORT}/whatsapp/send/\${JID}" \\
|
|
3179
|
+
-H 'Content-Type: application/json' \\
|
|
3180
|
+
-d "{\\"text\\":\${JSON_MSG}}")
|
|
3181
|
+
fi
|
|
3182
|
+
|
|
3183
|
+
HTTP_CODE=$(echo "$RESPONSE" | tail -1)
|
|
3184
|
+
BODY=$(echo "$RESPONSE" | sed '$d')
|
|
3185
|
+
|
|
3186
|
+
if [ "$HTTP_CODE" = "200" ]; then
|
|
3187
|
+
echo "Sent $(echo "$MSG" | wc -c | tr -d ' ') chars to $JID"
|
|
3188
|
+
else
|
|
3189
|
+
echo "Failed (HTTP $HTTP_CODE): $BODY" >&2
|
|
3190
|
+
exit 1
|
|
3191
|
+
fi
|
|
3192
|
+
`;
|
|
3193
|
+
const scriptPath = path.join(scriptsDir, 'whatsapp-reply.sh');
|
|
3194
|
+
fs.writeFileSync(scriptPath, scriptContent, { mode: 0o755 });
|
|
3195
|
+
}
|
|
3196
|
+
/**
|
|
3197
|
+
* Append missing sections to CLAUDE.md without overwriting user customizations.
|
|
3198
|
+
* Reads config.json for port, checks for known section headers, appends if missing.
|
|
3199
|
+
* Also adds Telegram relay section if Telegram is configured.
|
|
3200
|
+
*/
|
|
3201
|
+
function refreshClaudeMd(projectDir, stateDir) {
|
|
3202
|
+
const claudeMdPath = path.join(projectDir, 'CLAUDE.md');
|
|
3203
|
+
if (!fs.existsSync(claudeMdPath))
|
|
3204
|
+
return;
|
|
3205
|
+
const config = readConfig(stateDir);
|
|
3206
|
+
const port = config?.port || 4040;
|
|
3207
|
+
const content = fs.readFileSync(claudeMdPath, 'utf-8');
|
|
3208
|
+
const additions = [];
|
|
3209
|
+
// Check for Self-Diagnosis section
|
|
3210
|
+
if (!content.includes('Self-Diagnosis')) {
|
|
3211
|
+
additions.push(`
|
|
3212
|
+
### Self-Diagnosis — Be Your Own QA
|
|
3213
|
+
|
|
3214
|
+
**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.
|
|
3215
|
+
|
|
3216
|
+
**What to watch for:**
|
|
3217
|
+
- Server errors: API calls to localhost:${port} failing, unexpected responses, timeouts
|
|
3218
|
+
- Hook failures: hooks throwing errors, not firing when expected, blocking when they shouldn't
|
|
3219
|
+
- Job issues: jobs not running on schedule, failing silently, taking too long
|
|
3220
|
+
- Session problems: sessions not spawning, not being tracked, zombie sessions
|
|
3221
|
+
- State corruption: JSON parse errors in .instar/state/ files, missing fields, stale data
|
|
3222
|
+
- Config confusion: settings not being applied, defaults not making sense
|
|
3223
|
+
- Missing capabilities: something you need to do but can't because instar doesn't support it
|
|
3224
|
+
- Design flaws: patterns that feel wrong, workflows that are unnecessarily complex
|
|
3225
|
+
|
|
3226
|
+
**When you detect an issue, report it immediately:**
|
|
3227
|
+
\`\`\`bash
|
|
3228
|
+
curl -s -X POST http://localhost:${port}/feedback \\
|
|
3229
|
+
-H 'Content-Type: application/json' \\
|
|
3230
|
+
-d '{"type":"bug","title":"CONCISE_TITLE","description":"FULL_CONTEXT_WITH_ERROR_MESSAGES"}'
|
|
3231
|
+
\`\`\`
|
|
3232
|
+
|
|
3233
|
+
Types: \`bug\`, \`feature\`, \`improvement\`, \`question\`
|
|
3234
|
+
|
|
3235
|
+
**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.
|
|
3236
|
+
`);
|
|
3237
|
+
}
|
|
3238
|
+
// Check for Evolution System section
|
|
3239
|
+
if (!content.includes('Evolution System')) {
|
|
3240
|
+
additions.push(`
|
|
3241
|
+
### Evolution System
|
|
3242
|
+
|
|
3243
|
+
You have a built-in evolution system with four subsystems that track your growth.
|
|
3244
|
+
|
|
3245
|
+
**Evolution Queue** — Staged self-improvement proposals.
|
|
3246
|
+
- View: \`curl http://localhost:${port}/evolution/proposals\`
|
|
3247
|
+
- Propose: \`/evolve\` skill or \`POST /evolution/proposals\`
|
|
3248
|
+
|
|
3249
|
+
**Learning Registry** — Structured, searchable insights.
|
|
3250
|
+
- View: \`curl http://localhost:${port}/evolution/learnings\`
|
|
3251
|
+
- Record: \`/learn\` skill or \`POST /evolution/learnings\`
|
|
3252
|
+
|
|
3253
|
+
**Capability Gaps** — Track what you're missing.
|
|
3254
|
+
- View: \`curl http://localhost:${port}/evolution/gaps\`
|
|
3255
|
+
- Report: \`/gaps\` skill or \`POST /evolution/gaps\`
|
|
3256
|
+
|
|
3257
|
+
**Action Queue** — Commitments with follow-through tracking.
|
|
3258
|
+
- View: \`curl http://localhost:${port}/evolution/actions\`
|
|
3259
|
+
- Create: \`/commit-action\` skill or \`POST /evolution/actions\`
|
|
3260
|
+
|
|
3261
|
+
**Dashboard**: \`curl http://localhost:${port}/evolution\`
|
|
3262
|
+
**Skills**: \`/evolve\`, \`/learn\`, \`/gaps\`, \`/commit-action\`
|
|
3263
|
+
`);
|
|
3264
|
+
}
|
|
3265
|
+
// Check for WhatsApp Relay section (add if WhatsApp is configured)
|
|
3266
|
+
if (isWhatsAppConfigured(stateDir) && !content.includes('WhatsApp Relay')) {
|
|
3267
|
+
additions.push(`
|
|
3268
|
+
## WhatsApp Relay
|
|
3269
|
+
|
|
3270
|
+
When user input starts with \`[whatsapp:JID]\` (e.g., \`[whatsapp:12345678901@s.whatsapp.net] hello\`), the message came from a user via WhatsApp.
|
|
3271
|
+
|
|
3272
|
+
**Response relay:** After completing your work, relay your response back:
|
|
3273
|
+
|
|
3274
|
+
\`\`\`bash
|
|
3275
|
+
cat <<'EOF' | .instar/scripts/whatsapp-reply.sh JID
|
|
3276
|
+
Your response text here
|
|
3277
|
+
EOF
|
|
3278
|
+
\`\`\`
|
|
3279
|
+
|
|
3280
|
+
Strip the \`[whatsapp:JID]\` prefix before interpreting the message. Respond naturally, then relay. Only relay your conversational text — not tool output or internal reasoning.
|
|
3281
|
+
`);
|
|
3282
|
+
}
|
|
3283
|
+
// Check for Telegram Relay section (add if Telegram is configured)
|
|
3284
|
+
if (isTelegramConfigured(stateDir) && !content.includes('Telegram Relay')) {
|
|
3285
|
+
additions.push(`
|
|
3286
|
+
## Telegram Relay
|
|
3287
|
+
|
|
3288
|
+
When user input starts with \`[telegram:N]\` (e.g., \`[telegram:26] hello\`), the message came from a user via Telegram topic N.
|
|
3289
|
+
|
|
3290
|
+
**IMMEDIATE ACKNOWLEDGMENT (MANDATORY):** When you receive a Telegram message, your FIRST action — before reading files, searching code, or doing any work — must be sending a brief acknowledgment back. This confirms the message was received and you haven't stalled. Examples: "Got it, looking into this now." / "On it — checking the scheduler." / "Received, working on the sync." Then do the work, then send the full response.
|
|
3291
|
+
|
|
3292
|
+
**Response relay:** After completing your work, relay your response back:
|
|
3293
|
+
|
|
3294
|
+
\`\`\`bash
|
|
3295
|
+
cat <<'EOF' | .claude/scripts/telegram-reply.sh N
|
|
3296
|
+
Your response text here
|
|
3297
|
+
EOF
|
|
3298
|
+
\`\`\`
|
|
3299
|
+
|
|
3300
|
+
Strip the \`[telegram:N]\` prefix before interpreting the message. Respond naturally, then relay. Only relay your conversational text — not tool output or internal reasoning.
|
|
3301
|
+
`);
|
|
3302
|
+
}
|
|
3303
|
+
// Threadline Network section — always added so the agent knows about relay
|
|
3304
|
+
if (!content.includes('Threadline Network')) {
|
|
3305
|
+
additions.push(`
|
|
3306
|
+
## Threadline Network (Agent-to-Agent Communication)
|
|
3307
|
+
|
|
3308
|
+
I have a built-in capability to join a secure network of AI agents. When enabled, I can:
|
|
3309
|
+
- **Discover** other agents on the network in real time
|
|
3310
|
+
- **Send and receive messages** to/from other agents by name (e.g., "message AI Guy")
|
|
3311
|
+
- **Collaborate** across machines — agents on different computers can communicate seamlessly
|
|
3312
|
+
|
|
3313
|
+
### Current Status
|
|
3314
|
+
This capability is **installed and ready** but **not yet enabled**. I will only connect when you say so.
|
|
3315
|
+
|
|
3316
|
+
### Why You Might Want This
|
|
3317
|
+
- Talk to other AI agents your operator runs on other machines
|
|
3318
|
+
- Let other agents reach you for collaboration or delegation
|
|
3319
|
+
- Join a growing network of Instar-powered agents
|
|
3320
|
+
|
|
3321
|
+
### Privacy & Security
|
|
3322
|
+
- **Encrypted** — TLS transport + Ed25519 end-to-end encryption
|
|
3323
|
+
- **Trust-gated** — I control who can message me via trust levels
|
|
3324
|
+
- **Your choice** — just ask me to "connect to the agent network" and I'll enable it. Ask me to "disconnect" and I'll stop.
|
|
3325
|
+
|
|
3326
|
+
### How to Enable
|
|
3327
|
+
Just tell me: "connect to the agent network" or "enable Threadline relay." I'll handle the rest — no config editing needed.
|
|
3328
|
+
|
|
3329
|
+
MCP tools: \`threadline_discover\`, \`threadline_send\`, \`threadline_trust\`, \`threadline_relay\`
|
|
3330
|
+
Use \`threadline_relay explain\` for full details.
|
|
3331
|
+
`);
|
|
3332
|
+
}
|
|
3333
|
+
if (additions.length > 0) {
|
|
3334
|
+
fs.appendFileSync(claudeMdPath, '\n' + additions.join('\n'));
|
|
3335
|
+
}
|
|
3336
|
+
}
|
|
3337
|
+
function installHooks(stateDir) {
|
|
3338
|
+
const hooksBaseDir = path.join(stateDir, 'hooks');
|
|
3339
|
+
const hooksDir = path.join(hooksBaseDir, 'instar');
|
|
3340
|
+
const customHooksDir = path.join(hooksBaseDir, 'custom');
|
|
3341
|
+
fs.mkdirSync(hooksDir, { recursive: true });
|
|
3342
|
+
fs.mkdirSync(customHooksDir, { recursive: true });
|
|
3343
|
+
// Session start hook — fires on startup, resume, clear, compact
|
|
3344
|
+
// Canonical version kept in sync with PostUpdateMigrator.getSessionStartHook().
|
|
3345
|
+
// PostUpdateMigrator overwrites this on first auto-update, but we want first-install
|
|
3346
|
+
// to have the same quality as updated agents.
|
|
3347
|
+
const migrator = new PostUpdateMigrator({ stateDir, port: 4040, sessions: { claudePath: 'claude' } });
|
|
3348
|
+
fs.writeFileSync(path.join(hooksDir, 'session-start.sh'), migrator.getHookContent('session-start'), { mode: 0o755 });
|
|
3349
|
+
// Dangerous command guard — supports safety levels 1 (ask user) and 2 (self-verify)
|
|
3350
|
+
fs.writeFileSync(path.join(hooksDir, 'dangerous-command-guard.sh'), `#!/bin/bash
|
|
3351
|
+
# Dangerous command guard — safety infrastructure for autonomous agents.
|
|
3352
|
+
# Supports safety.level in .instar/config.json:
|
|
3353
|
+
# Level 1 (default): Block and ask user. Level 2: Agent self-verifies.
|
|
3354
|
+
INPUT="$1"
|
|
3355
|
+
INSTAR_DIR="\${CLAUDE_PROJECT_DIR:-.}/.instar"
|
|
3356
|
+
|
|
3357
|
+
# Read safety level from config
|
|
3358
|
+
SAFETY_LEVEL=1
|
|
3359
|
+
if [ -f "\$INSTAR_DIR/config.json" ]; then
|
|
3360
|
+
SAFETY_LEVEL=\$(python3 -c "import json; print(json.load(open('\$INSTAR_DIR/config.json')).get('safety', {}).get('level', 1))" 2>/dev/null || echo "1")
|
|
3361
|
+
fi
|
|
3362
|
+
|
|
3363
|
+
# ALWAYS blocked (catastrophic, irreversible)
|
|
3364
|
+
for pattern in "rm -rf /" "rm -rf ~" "> /dev/sda" "mkfs\\." "dd if=" ":(){:|:&};:"; do
|
|
3365
|
+
if echo "\$INPUT" | grep -qi "\$pattern"; then
|
|
3366
|
+
echo "BLOCKED: Catastrophic command detected: \$pattern" >&2
|
|
3367
|
+
echo "Always blocked regardless of safety level. User must execute directly." >&2
|
|
3368
|
+
exit 2
|
|
3369
|
+
fi
|
|
3370
|
+
done
|
|
3371
|
+
|
|
3372
|
+
# Risky commands — behavior depends on safety level
|
|
3373
|
+
for pattern in "rm -rf \\." "git push --force" "git push -f" "git reset --hard" "git clean -fd" "DROP TABLE" "DROP DATABASE" "TRUNCATE" "DELETE FROM"; do
|
|
3374
|
+
if echo "\$INPUT" | grep -qi "\$pattern"; then
|
|
3375
|
+
if [ "\$SAFETY_LEVEL" -eq 1 ]; then
|
|
3376
|
+
echo "BLOCKED: Potentially destructive command detected: \$pattern" >&2
|
|
3377
|
+
echo "Ask the user for explicit confirmation before running this command." >&2
|
|
3378
|
+
exit 2
|
|
3379
|
+
else
|
|
3380
|
+
IDENTITY=""
|
|
3381
|
+
if [ -f "\$INSTAR_DIR/AGENT.md" ]; then
|
|
3382
|
+
IDENTITY=\$(head -20 "\$INSTAR_DIR/AGENT.md" | tr '\\n' ' ')
|
|
3383
|
+
fi
|
|
3384
|
+
echo "{\\"decision\\":\\"approve\\",\\"additionalContext\\":\\"=== SELF-VERIFICATION REQUIRED ===\\\\nDestructive command detected: \$pattern\\\\n\\\\n1. Is this necessary for the current task?\\\\n2. What are the consequences if this goes wrong?\\\\n3. Is there a safer alternative?\\\\n4. Does this align with your principles?\\\\n\\\\nIdentity: \$IDENTITY\\\\n\\\\nIf ALL checks pass, proceed. If ANY fails, stop.\\\\n=== END SELF-VERIFICATION ===\\"}"
|
|
3385
|
+
exit 0
|
|
3386
|
+
fi
|
|
3387
|
+
fi
|
|
3388
|
+
done
|
|
3389
|
+
`, { mode: 0o755 });
|
|
3390
|
+
// Grounding before messaging — full pipeline with convergence check.
|
|
3391
|
+
// Uses PostUpdateMigrator as single source of truth (DRY).
|
|
3392
|
+
fs.writeFileSync(path.join(hooksDir, 'grounding-before-messaging.sh'), migrator.getGroundingBeforeMessagingPublic(), { mode: 0o755 });
|
|
3393
|
+
// Convergence check script — heuristic quality gate called by grounding-before-messaging.
|
|
3394
|
+
// Must be in .instar/scripts/ where grounding-before-messaging.sh expects it.
|
|
3395
|
+
const instarScriptsDir = path.join(stateDir, 'scripts');
|
|
3396
|
+
fs.mkdirSync(instarScriptsDir, { recursive: true });
|
|
3397
|
+
fs.writeFileSync(path.join(instarScriptsDir, 'convergence-check.sh'), migrator.getConvergenceCheckPublic(), { mode: 0o755 });
|
|
3398
|
+
// Compaction recovery — shared from PostUpdateMigrator (single source of truth).
|
|
3399
|
+
fs.writeFileSync(path.join(hooksDir, 'compaction-recovery.sh'), migrator.getHookContent('compaction-recovery'), { mode: 0o755 });
|
|
3400
|
+
// Deferral detector, post-action reflection, external communication guard
|
|
3401
|
+
// All use shared templates from PostUpdateMigrator for DRY maintenance.
|
|
3402
|
+
fs.writeFileSync(path.join(hooksDir, 'deferral-detector.js'), migrator.getHookContent('deferral-detector'), { mode: 0o755 });
|
|
3403
|
+
fs.writeFileSync(path.join(hooksDir, 'post-action-reflection.js'), migrator.getHookContent('post-action-reflection'), { mode: 0o755 });
|
|
3404
|
+
fs.writeFileSync(path.join(hooksDir, 'external-communication-guard.js'), migrator.getHookContent('external-communication-guard'), { mode: 0o755 });
|
|
3405
|
+
// External operation gate — intercepts MCP tool calls to external services.
|
|
3406
|
+
// Uses shared template from PostUpdateMigrator for DRY maintenance.
|
|
3407
|
+
fs.writeFileSync(path.join(hooksDir, 'external-operation-gate.js'), migrator.getHookContent('external-operation-gate'), { mode: 0o755 });
|
|
3408
|
+
// Claim intercept — catches false operational claims against canonical state.
|
|
3409
|
+
// PostToolUse hook checks tool output; Stop hook checks direct responses.
|
|
3410
|
+
fs.writeFileSync(path.join(hooksDir, 'claim-intercept.js'), migrator.getHookContent('claim-intercept'), { mode: 0o755 });
|
|
3411
|
+
fs.writeFileSync(path.join(hooksDir, 'claim-intercept-response.js'), migrator.getHookContent('claim-intercept-response'), { mode: 0o755 });
|
|
3412
|
+
// Response review — Coherence Gate response review pipeline.
|
|
3413
|
+
// Stop hook that calls /review/evaluate for LLM-powered response quality checking.
|
|
3414
|
+
fs.writeFileSync(path.join(hooksDir, 'response-review.js'), migrator.getHookContent('response-review'), { mode: 0o755 });
|
|
3415
|
+
// Hook event reporter — posts hook events to the Instar server for observability
|
|
3416
|
+
// and session resumption (claudeSessionId). Uses command hooks because Claude Code
|
|
3417
|
+
// HTTP hooks (type: "http") silently fail to fire as of v2.1.78.
|
|
3418
|
+
fs.writeFileSync(path.join(hooksDir, 'hook-event-reporter.js'), getHookEventReporterScript(), { mode: 0o755 });
|
|
3419
|
+
// Auto-approve all PermissionRequest hooks — subagents spawned via Agent tool
|
|
3420
|
+
// don't inherit --dangerously-skip-permissions, so they'd prompt without this.
|
|
3421
|
+
// Real safety is in PreToolUse hooks (dangerous-command-guard, external-communication-guard).
|
|
3422
|
+
fs.writeFileSync(path.join(hooksDir, 'auto-approve-permissions.js'), getAutoApprovePermissionsScript(), { mode: 0o755 });
|
|
3423
|
+
}
|
|
3424
|
+
function getHookEventReporterScript() {
|
|
3425
|
+
return `#!/usr/bin/env node
|
|
3426
|
+
// Hook Event Reporter — command hook replacement for HTTP hooks.
|
|
3427
|
+
//
|
|
3428
|
+
// Claude Code HTTP hooks (type: "http") silently fail to fire as of v2.1.78.
|
|
3429
|
+
// This command hook achieves the same result: POST hook event data to the
|
|
3430
|
+
// Instar server, which populates claudeSessionId for session resumption.
|
|
3431
|
+
//
|
|
3432
|
+
// Runs async (fire-and-forget) to avoid slowing down tool execution.
|
|
3433
|
+
|
|
3434
|
+
const http = require('http');
|
|
3435
|
+
|
|
3436
|
+
const serverUrl = process.env.INSTAR_SERVER_URL || 'http://localhost:4042';
|
|
3437
|
+
const authToken = process.env.INSTAR_AUTH_TOKEN || '';
|
|
3438
|
+
const instarSid = process.env.INSTAR_SESSION_ID || '';
|
|
3439
|
+
|
|
3440
|
+
if (!authToken || !instarSid) {
|
|
3441
|
+
// Missing env vars — skip silently
|
|
3442
|
+
process.exit(0);
|
|
3443
|
+
}
|
|
3444
|
+
|
|
3445
|
+
let data = '';
|
|
3446
|
+
process.stdin.on('data', chunk => data += chunk);
|
|
3447
|
+
process.stdin.on('end', () => {
|
|
3448
|
+
try {
|
|
3449
|
+
const input = JSON.parse(data);
|
|
3450
|
+
const payload = JSON.stringify({
|
|
3451
|
+
event: input.hook_event || (input.tool_name ? 'PostToolUse' : 'Unknown'),
|
|
3452
|
+
session_id: input.session_id || '',
|
|
3453
|
+
tool_name: input.tool_name || '',
|
|
3454
|
+
});
|
|
3455
|
+
|
|
3456
|
+
const url = new URL(serverUrl + '/hooks/events?instar_sid=' + instarSid);
|
|
3457
|
+
const req = http.request({
|
|
3458
|
+
hostname: url.hostname,
|
|
3459
|
+
port: url.port,
|
|
3460
|
+
path: url.pathname + url.search,
|
|
3461
|
+
method: 'POST',
|
|
3462
|
+
headers: {
|
|
3463
|
+
'Content-Type': 'application/json',
|
|
3464
|
+
'Authorization': 'Bearer ' + authToken,
|
|
3465
|
+
},
|
|
3466
|
+
timeout: 3000,
|
|
3467
|
+
}, (res) => {
|
|
3468
|
+
res.resume(); // drain response
|
|
3469
|
+
});
|
|
3470
|
+
|
|
3471
|
+
req.on('error', () => {}); // silent failure
|
|
3472
|
+
req.write(payload);
|
|
3473
|
+
req.end();
|
|
3474
|
+
|
|
3475
|
+
// Don't wait for response — exit immediately
|
|
3476
|
+
setTimeout(() => process.exit(0), 50);
|
|
3477
|
+
} catch (e) {
|
|
3478
|
+
process.exit(0);
|
|
3479
|
+
}
|
|
3480
|
+
});
|
|
3481
|
+
|
|
3482
|
+
// Timeout safety — don't hang if stdin never closes
|
|
3483
|
+
setTimeout(() => process.exit(0), 2000);
|
|
3484
|
+
`;
|
|
3485
|
+
}
|
|
3486
|
+
function getAutoApprovePermissionsScript() {
|
|
3487
|
+
return `#!/usr/bin/env node
|
|
3488
|
+
// Auto-approve ALL PermissionRequest hooks.
|
|
3489
|
+
//
|
|
3490
|
+
// Subagents spawned via the Agent tool don't inherit --dangerously-skip-permissions
|
|
3491
|
+
// from the parent session. Without this hook, subagents prompt for every tool use,
|
|
3492
|
+
// blocking autonomous sessions and jobs.
|
|
3493
|
+
//
|
|
3494
|
+
// Real safety is enforced by PreToolUse hooks (dangerous-command-guard.sh,
|
|
3495
|
+
// external-communication-guard.js, external-operation-gate.js). Permission prompts
|
|
3496
|
+
// are duplicative friction, not protection.
|
|
3497
|
+
|
|
3498
|
+
process.stdin.resume();
|
|
3499
|
+
let data = '';
|
|
3500
|
+
process.stdin.on('data', chunk => data += chunk);
|
|
3501
|
+
process.stdin.on('end', () => {
|
|
3502
|
+
console.log(JSON.stringify({
|
|
3503
|
+
hookSpecificOutput: {
|
|
3504
|
+
hookEventName: 'PermissionRequest',
|
|
3505
|
+
decision: { behavior: 'allow' }
|
|
3506
|
+
}
|
|
3507
|
+
}));
|
|
3508
|
+
});
|
|
3509
|
+
|
|
3510
|
+
// Timeout safety
|
|
3511
|
+
setTimeout(() => {
|
|
3512
|
+
console.log(JSON.stringify({
|
|
3513
|
+
hookSpecificOutput: {
|
|
3514
|
+
hookEventName: 'PermissionRequest',
|
|
3515
|
+
decision: { behavior: 'allow' }
|
|
3516
|
+
}
|
|
3517
|
+
}));
|
|
3518
|
+
process.exit(0);
|
|
3519
|
+
}, 2000);
|
|
3520
|
+
`;
|
|
3521
|
+
}
|
|
3522
|
+
function installHealthWatchdog(projectDir, port, projectName) {
|
|
3523
|
+
const scriptsDir = path.join(projectDir, '.claude', 'scripts');
|
|
3524
|
+
fs.mkdirSync(scriptsDir, { recursive: true });
|
|
3525
|
+
// Quote projectDir for shell safety — paths with spaces, parens, etc.
|
|
3526
|
+
const escapedProjectDir = projectDir.replace(/'/g, "'\\''");
|
|
3527
|
+
const escapedCronPath = path.join(projectDir, '.claude/scripts/health-watchdog.sh').replace(/'/g, "'\\''");
|
|
3528
|
+
const scriptContent = `#!/bin/bash
|
|
3529
|
+
# health-watchdog.sh — Monitor instar server and auto-recover.
|
|
3530
|
+
# Install as cron: */5 * * * * '${escapedCronPath}'
|
|
3531
|
+
|
|
3532
|
+
PORT="${port}"
|
|
3533
|
+
SERVER_SESSION="${projectName}-server"
|
|
3534
|
+
PROJECT_DIR='${escapedProjectDir}'
|
|
3535
|
+
TMUX_PATH=$(which tmux 2>/dev/null || echo "/opt/homebrew/bin/tmux")
|
|
3536
|
+
|
|
3537
|
+
HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" "http://localhost:\${PORT}/health" 2>/dev/null)
|
|
3538
|
+
if [ "$HTTP_CODE" = "200" ]; then exit 0; fi
|
|
3539
|
+
|
|
3540
|
+
echo "[\$(date -Iseconds)] Server not responding. Restarting..."
|
|
3541
|
+
$TMUX_PATH kill-session -t "=\${SERVER_SESSION}" 2>/dev/null
|
|
3542
|
+
sleep 2
|
|
3543
|
+
cd "$PROJECT_DIR" && npx instar server start
|
|
3544
|
+
echo "[\$(date -Iseconds)] Server restart initiated"
|
|
3545
|
+
`;
|
|
3546
|
+
fs.writeFileSync(path.join(scriptsDir, 'health-watchdog.sh'), scriptContent, { mode: 0o755 });
|
|
3547
|
+
}
|
|
3548
|
+
/**
|
|
3549
|
+
* Install git-sync-gate.sh — zero-token pre-screening for the git-sync job.
|
|
3550
|
+
* Checks if a sync is needed before spawning a Claude session.
|
|
3551
|
+
* Also classifies conflict severity for tiered model selection.
|
|
3552
|
+
*/
|
|
3553
|
+
function installGitSyncGate(projectDir) {
|
|
3554
|
+
const scriptsDir = path.join(projectDir, '.claude', 'scripts');
|
|
3555
|
+
fs.mkdirSync(scriptsDir, { recursive: true });
|
|
3556
|
+
const scriptPath = path.join(scriptsDir, 'git-sync-gate.sh');
|
|
3557
|
+
const content = [
|
|
3558
|
+
'#!/bin/bash',
|
|
3559
|
+
'# Git Sync Gate — zero-token pre-screening for the git-sync job.',
|
|
3560
|
+
'# Exit 0 = sync needed (proceed), exit 1 = nothing to sync (skip).',
|
|
3561
|
+
'# Writes conflict severity to /tmp/instar-git-sync-severity for model tier selection.',
|
|
3562
|
+
'',
|
|
3563
|
+
'SEVERITY_FILE="/tmp/instar-git-sync-severity"',
|
|
3564
|
+
'echo "clean" > "$SEVERITY_FILE"',
|
|
3565
|
+
'',
|
|
3566
|
+
'# Must be in a git repo with a remote',
|
|
3567
|
+
'[ ! -d ".git" ] && exit 1',
|
|
3568
|
+
'REMOTE=$(git remote | head -1)',
|
|
3569
|
+
'[ -z "$REMOTE" ] && exit 1',
|
|
3570
|
+
'',
|
|
3571
|
+
'# Check for local changes',
|
|
3572
|
+
'LOCAL_CHANGES=$(git status --porcelain 2>/dev/null | head -1)',
|
|
3573
|
+
'',
|
|
3574
|
+
'# Fetch remote (with timeout)',
|
|
3575
|
+
'git fetch origin --quiet 2>/dev/null &',
|
|
3576
|
+
'FETCH_PID=$!',
|
|
3577
|
+
'( sleep 10 && kill "$FETCH_PID" 2>/dev/null ) &',
|
|
3578
|
+
'wait "$FETCH_PID" 2>/dev/null',
|
|
3579
|
+
'',
|
|
3580
|
+
'# Check for remote changes',
|
|
3581
|
+
'TRACKING=$(git rev-parse --abbrev-ref "@{u}" 2>/dev/null)',
|
|
3582
|
+
'BEHIND=0',
|
|
3583
|
+
'AHEAD=0',
|
|
3584
|
+
'if [ -n "$TRACKING" ]; then',
|
|
3585
|
+
' AB=$(git rev-list --left-right --count "HEAD...$TRACKING" 2>/dev/null)',
|
|
3586
|
+
' BEHIND=$(echo "$AB" | awk \'{print $1}\')',
|
|
3587
|
+
' AHEAD=$(echo "$AB" | awk \'{print $2}\')',
|
|
3588
|
+
'fi',
|
|
3589
|
+
'',
|
|
3590
|
+
'# Nothing to do — clean and in sync',
|
|
3591
|
+
'if [ -z "$LOCAL_CHANGES" ] && [ "${BEHIND:-0}" -eq "0" ] && [ "${AHEAD:-0}" -eq "0" ]; then',
|
|
3592
|
+
' exit 1',
|
|
3593
|
+
'fi',
|
|
3594
|
+
'',
|
|
3595
|
+
'# Both sides have changes — check for potential conflicts',
|
|
3596
|
+
'if [ -n "$LOCAL_CHANGES" ] && [ "${BEHIND:-0}" -gt "0" ]; then',
|
|
3597
|
+
' # Try a merge-tree to detect conflicts without modifying working tree',
|
|
3598
|
+
' MERGE_BASE=$(git merge-base HEAD "$TRACKING" 2>/dev/null)',
|
|
3599
|
+
' if [ -n "$MERGE_BASE" ]; then',
|
|
3600
|
+
' MERGE_OUT=$(git merge-tree "$MERGE_BASE" HEAD "$TRACKING" 2>/dev/null)',
|
|
3601
|
+
' if echo "$MERGE_OUT" | grep -q "<<<<<<"; then',
|
|
3602
|
+
' # Classify: code vs state',
|
|
3603
|
+
' if echo "$MERGE_OUT" | grep -E "\\.(ts|tsx|js|jsx|py|rs|go|md)$" | grep -q "<<<<<<"; then',
|
|
3604
|
+
' echo "code" > "$SEVERITY_FILE"',
|
|
3605
|
+
' else',
|
|
3606
|
+
' echo "state" > "$SEVERITY_FILE"',
|
|
3607
|
+
' fi',
|
|
3608
|
+
' fi',
|
|
3609
|
+
' fi',
|
|
3610
|
+
'fi',
|
|
3611
|
+
'',
|
|
3612
|
+
'# Sync is needed',
|
|
3613
|
+
'exit 0',
|
|
3614
|
+
'',
|
|
3615
|
+
].join('\n');
|
|
3616
|
+
fs.writeFileSync(scriptPath, content, { mode: 0o755 });
|
|
3617
|
+
}
|
|
3618
|
+
/**
|
|
3619
|
+
* Install smart-fetch.py — agentic web conventions for efficient URL fetching.
|
|
3620
|
+
* Checks llms.txt first, then requests Cloudflare text/markdown, then falls back to HTML.
|
|
3621
|
+
* Saves ~80% tokens on Cloudflare-hosted sites (~20% of the web).
|
|
3622
|
+
*/
|
|
3623
|
+
function installSmartFetch(projectDir) {
|
|
3624
|
+
const scriptsDir = path.join(projectDir, '.claude', 'scripts');
|
|
3625
|
+
fs.mkdirSync(scriptsDir, { recursive: true });
|
|
3626
|
+
const scriptPath = path.join(scriptsDir, 'smart-fetch.py');
|
|
3627
|
+
// Don't overwrite if user has modified it
|
|
3628
|
+
if (fs.existsSync(scriptPath))
|
|
3629
|
+
return;
|
|
3630
|
+
const scriptContent = `#!/usr/bin/env python3
|
|
3631
|
+
"""Smart web fetch with agentic web conventions.
|
|
3632
|
+
|
|
3633
|
+
Checks for llms.txt, requests text/markdown from Cloudflare sites,
|
|
3634
|
+
and falls back to standard HTML fetching. Designed to minimize token
|
|
3635
|
+
usage when AI agents need web content.
|
|
3636
|
+
|
|
3637
|
+
Usage:
|
|
3638
|
+
python3 .claude/scripts/smart-fetch.py URL [--check-llms] [--markdown] [--auto] [--raw] [--quiet]
|
|
3639
|
+
|
|
3640
|
+
Options:
|
|
3641
|
+
--check-llms Check for /llms.txt and /llms-full.txt before fetching
|
|
3642
|
+
--markdown Request text/markdown via Accept header (Cloudflare sites)
|
|
3643
|
+
--auto Auto-detect: check llms.txt first, then try markdown, then HTML (default)
|
|
3644
|
+
--raw Output raw content only (no metadata headers)
|
|
3645
|
+
--quiet Suppress status messages
|
|
3646
|
+
--max-tokens N Warn if estimated tokens exceed N (default: 50000)
|
|
3647
|
+
"""
|
|
3648
|
+
|
|
3649
|
+
import argparse
|
|
3650
|
+
import json
|
|
3651
|
+
import sys
|
|
3652
|
+
import urllib.request
|
|
3653
|
+
import urllib.error
|
|
3654
|
+
import urllib.parse
|
|
3655
|
+
from html.parser import HTMLParser
|
|
3656
|
+
|
|
3657
|
+
|
|
3658
|
+
class SimpleHTMLToText(HTMLParser):
|
|
3659
|
+
"""Minimal HTML to text converter for when markdown isn't available."""
|
|
3660
|
+
def __init__(self):
|
|
3661
|
+
super().__init__()
|
|
3662
|
+
self._text = []
|
|
3663
|
+
self._skip = False
|
|
3664
|
+
|
|
3665
|
+
def handle_starttag(self, tag, attrs):
|
|
3666
|
+
if tag in ('script', 'style', 'nav', 'footer', 'header'):
|
|
3667
|
+
self._skip = True
|
|
3668
|
+
|
|
3669
|
+
def handle_endtag(self, tag):
|
|
3670
|
+
if tag in ('script', 'style', 'nav', 'footer', 'header'):
|
|
3671
|
+
self._skip = False
|
|
3672
|
+
if tag in ('p', 'div', 'br', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'li'):
|
|
3673
|
+
self._text.append('\\n')
|
|
3674
|
+
|
|
3675
|
+
def handle_data(self, data):
|
|
3676
|
+
if not self._skip:
|
|
3677
|
+
self._text.append(data)
|
|
3678
|
+
|
|
3679
|
+
def get_text(self):
|
|
3680
|
+
return ''.join(self._text).strip()
|
|
3681
|
+
|
|
3682
|
+
|
|
3683
|
+
def estimate_tokens(text):
|
|
3684
|
+
"""Rough token estimate: ~4 chars per token for English."""
|
|
3685
|
+
return len(text) // 4
|
|
3686
|
+
|
|
3687
|
+
|
|
3688
|
+
def fetch_url(url, accept_header=None, timeout=15):
|
|
3689
|
+
"""Fetch a URL with optional Accept header."""
|
|
3690
|
+
headers = {'User-Agent': 'InstarAgent/1.0 (Claude Code)'}
|
|
3691
|
+
if accept_header:
|
|
3692
|
+
headers['Accept'] = accept_header
|
|
3693
|
+
|
|
3694
|
+
req = urllib.request.Request(url, headers=headers)
|
|
3695
|
+
try:
|
|
3696
|
+
resp = urllib.request.urlopen(req, timeout=timeout)
|
|
3697
|
+
content_type = resp.headers.get('Content-Type', '')
|
|
3698
|
+
token_hint = resp.headers.get('X-Markdown-Tokens', '')
|
|
3699
|
+
body = resp.read().decode('utf-8', errors='replace')
|
|
3700
|
+
return {
|
|
3701
|
+
'status': resp.status,
|
|
3702
|
+
'content_type': content_type,
|
|
3703
|
+
'token_hint': token_hint,
|
|
3704
|
+
'body': body,
|
|
3705
|
+
'url': resp.url,
|
|
3706
|
+
}
|
|
3707
|
+
except urllib.error.HTTPError as e:
|
|
3708
|
+
return {'status': e.code, 'error': str(e), 'body': ''}
|
|
3709
|
+
except Exception as e:
|
|
3710
|
+
return {'status': 0, 'error': str(e), 'body': ''}
|
|
3711
|
+
|
|
3712
|
+
|
|
3713
|
+
def check_llms_txt(base_url):
|
|
3714
|
+
"""Check for /llms.txt and /llms-full.txt at the site root."""
|
|
3715
|
+
parsed = urllib.parse.urlparse(base_url)
|
|
3716
|
+
root = f"{parsed.scheme}://{parsed.netloc}"
|
|
3717
|
+
results = {}
|
|
3718
|
+
|
|
3719
|
+
for p in ['/llms.txt', '/llms-full.txt']:
|
|
3720
|
+
url = root + p
|
|
3721
|
+
result = fetch_url(url)
|
|
3722
|
+
if result['status'] == 200 and result['body'].strip():
|
|
3723
|
+
results[p] = {
|
|
3724
|
+
'url': url,
|
|
3725
|
+
'size': len(result['body']),
|
|
3726
|
+
'tokens': estimate_tokens(result['body']),
|
|
3727
|
+
'content': result['body']
|
|
3728
|
+
}
|
|
3729
|
+
|
|
3730
|
+
return results
|
|
3731
|
+
|
|
3732
|
+
|
|
3733
|
+
def smart_fetch(url, mode='auto', max_tokens=50000, raw=False, quiet=False):
|
|
3734
|
+
"""Fetch content using the smartest available method."""
|
|
3735
|
+
log = lambda msg: None if quiet else print(msg, file=sys.stderr)
|
|
3736
|
+
|
|
3737
|
+
# Step 1: Check llms.txt if in auto or check-llms mode
|
|
3738
|
+
if mode in ('auto', 'check-llms'):
|
|
3739
|
+
log(f"[smart-fetch] Checking for llms.txt at {url}...")
|
|
3740
|
+
llms = check_llms_txt(url)
|
|
3741
|
+
if llms:
|
|
3742
|
+
chosen = llms.get('/llms-full.txt', llms.get('/llms.txt'))
|
|
3743
|
+
p = '/llms-full.txt' if '/llms-full.txt' in llms else '/llms.txt'
|
|
3744
|
+
log(f"[smart-fetch] Found {p} ({chosen['tokens']} est. tokens)")
|
|
3745
|
+
|
|
3746
|
+
if not raw:
|
|
3747
|
+
print(f"# Source: {chosen['url']}")
|
|
3748
|
+
print(f"# Method: llms.txt convention")
|
|
3749
|
+
print(f"# Estimated tokens: {chosen['tokens']}")
|
|
3750
|
+
print("---")
|
|
3751
|
+
print(chosen['content'])
|
|
3752
|
+
|
|
3753
|
+
if chosen['tokens'] > max_tokens:
|
|
3754
|
+
log(f"[smart-fetch] WARNING: Content exceeds {max_tokens} token limit")
|
|
3755
|
+
return True
|
|
3756
|
+
else:
|
|
3757
|
+
log("[smart-fetch] No llms.txt found")
|
|
3758
|
+
|
|
3759
|
+
if mode == 'check-llms':
|
|
3760
|
+
return False
|
|
3761
|
+
|
|
3762
|
+
# Step 2: Try text/markdown (Cloudflare sites)
|
|
3763
|
+
if mode in ('auto', 'markdown'):
|
|
3764
|
+
log(f"[smart-fetch] Requesting text/markdown from {url}...")
|
|
3765
|
+
result = fetch_url(url, accept_header='text/markdown')
|
|
3766
|
+
|
|
3767
|
+
if result['status'] == 200 and 'markdown' in result.get('content_type', ''):
|
|
3768
|
+
tokens = int(result['token_hint']) if result['token_hint'] else estimate_tokens(result['body'])
|
|
3769
|
+
log(f"[smart-fetch] Got markdown response ({tokens} est. tokens)")
|
|
3770
|
+
|
|
3771
|
+
if not raw:
|
|
3772
|
+
print(f"# Source: {result['url']}")
|
|
3773
|
+
print(f"# Method: Cloudflare text/markdown")
|
|
3774
|
+
if result['token_hint']:
|
|
3775
|
+
print(f"# X-Markdown-Tokens: {result['token_hint']}")
|
|
3776
|
+
print(f"# Estimated tokens: {tokens}")
|
|
3777
|
+
print("---")
|
|
3778
|
+
print(result['body'])
|
|
3779
|
+
|
|
3780
|
+
if tokens > max_tokens:
|
|
3781
|
+
log(f"[smart-fetch] WARNING: Content exceeds {max_tokens} token limit")
|
|
3782
|
+
return True
|
|
3783
|
+
else:
|
|
3784
|
+
log("[smart-fetch] Markdown not available, falling back to HTML")
|
|
3785
|
+
|
|
3786
|
+
# Step 3: Standard HTML fetch
|
|
3787
|
+
log(f"[smart-fetch] Fetching HTML from {url}...")
|
|
3788
|
+
result = fetch_url(url)
|
|
3789
|
+
|
|
3790
|
+
if result['status'] == 200:
|
|
3791
|
+
parser = SimpleHTMLToText()
|
|
3792
|
+
parser.feed(result['body'])
|
|
3793
|
+
text = parser.get_text()
|
|
3794
|
+
tokens = estimate_tokens(text)
|
|
3795
|
+
log(f"[smart-fetch] Got HTML ({tokens} est. tokens after text extraction)")
|
|
3796
|
+
|
|
3797
|
+
if not raw:
|
|
3798
|
+
print(f"# Source: {result['url']}")
|
|
3799
|
+
print(f"# Method: HTML (text extracted)")
|
|
3800
|
+
print(f"# Estimated tokens: {tokens}")
|
|
3801
|
+
print("---")
|
|
3802
|
+
print(text)
|
|
3803
|
+
|
|
3804
|
+
if tokens > max_tokens:
|
|
3805
|
+
log(f"[smart-fetch] WARNING: Content exceeds {max_tokens} token limit")
|
|
3806
|
+
return True
|
|
3807
|
+
else:
|
|
3808
|
+
log(f"[smart-fetch] Fetch failed: {result.get('error', f'HTTP {result[\"status\"]}')}")
|
|
3809
|
+
return False
|
|
3810
|
+
|
|
3811
|
+
|
|
3812
|
+
def main():
|
|
3813
|
+
parser = argparse.ArgumentParser(description='Smart web fetch with agentic conventions')
|
|
3814
|
+
parser.add_argument('url', help='URL to fetch')
|
|
3815
|
+
parser.add_argument('--check-llms', action='store_true', help='Only check for llms.txt')
|
|
3816
|
+
parser.add_argument('--markdown', action='store_true', help='Request text/markdown only')
|
|
3817
|
+
parser.add_argument('--auto', action='store_true', help='Auto-detect best method (default)')
|
|
3818
|
+
parser.add_argument('--raw', action='store_true', help='Output raw content only')
|
|
3819
|
+
parser.add_argument('--quiet', action='store_true', help='Suppress status messages')
|
|
3820
|
+
parser.add_argument('--max-tokens', type=int, default=50000, help='Token warning threshold')
|
|
3821
|
+
args = parser.parse_args()
|
|
3822
|
+
|
|
3823
|
+
if args.check_llms:
|
|
3824
|
+
mode = 'check-llms'
|
|
3825
|
+
elif args.markdown:
|
|
3826
|
+
mode = 'markdown'
|
|
3827
|
+
else:
|
|
3828
|
+
mode = 'auto'
|
|
3829
|
+
|
|
3830
|
+
success = smart_fetch(args.url, mode=mode, max_tokens=args.max_tokens, raw=args.raw, quiet=args.quiet)
|
|
3831
|
+
sys.exit(0 if success else 1)
|
|
3832
|
+
|
|
3833
|
+
|
|
3834
|
+
if __name__ == '__main__':
|
|
3835
|
+
main()
|
|
3836
|
+
`;
|
|
3837
|
+
fs.writeFileSync(scriptPath, scriptContent, { mode: 0o755 });
|
|
3838
|
+
}
|
|
3839
|
+
/**
|
|
3840
|
+
* Install serendipity-capture.sh — Helper script for sub-agents to capture
|
|
3841
|
+
* valuable out-of-scope findings during focused tasks.
|
|
3842
|
+
*
|
|
3843
|
+
* Reads the script from src/templates/scripts/serendipity-capture.sh rather
|
|
3844
|
+
* than embedding it inline (345 lines). Handles JSON construction, HMAC signing,
|
|
3845
|
+
* atomic writes, rate limiting, secret scanning, and patch file validation.
|
|
3846
|
+
*/
|
|
3847
|
+
function installSerendipityCapture(projectDir) {
|
|
3848
|
+
const scriptsDir = path.join(projectDir, '.instar', 'scripts');
|
|
3849
|
+
fs.mkdirSync(scriptsDir, { recursive: true });
|
|
3850
|
+
const scriptPath = path.join(scriptsDir, 'serendipity-capture.sh');
|
|
3851
|
+
// Resolve template from package directory
|
|
3852
|
+
// In dev: src/commands/ → ../../src/templates/scripts/serendipity-capture.sh
|
|
3853
|
+
// In dist: dist/commands/ → ../templates/scripts/serendipity-capture.sh
|
|
3854
|
+
const modDir = path.dirname(new URL(import.meta.url).pathname);
|
|
3855
|
+
const candidates = [
|
|
3856
|
+
path.resolve(modDir, '..', 'templates', 'scripts', 'serendipity-capture.sh'),
|
|
3857
|
+
path.resolve(modDir, '..', '..', 'src', 'templates', 'scripts', 'serendipity-capture.sh'),
|
|
3858
|
+
];
|
|
3859
|
+
let scriptContent = '';
|
|
3860
|
+
for (const candidate of candidates) {
|
|
3861
|
+
if (fs.existsSync(candidate)) {
|
|
3862
|
+
scriptContent = fs.readFileSync(candidate, 'utf-8');
|
|
3863
|
+
break;
|
|
3864
|
+
}
|
|
3865
|
+
}
|
|
3866
|
+
if (!scriptContent) {
|
|
3867
|
+
// Non-fatal: skip if template not found (e.g., during development)
|
|
3868
|
+
return;
|
|
3869
|
+
}
|
|
3870
|
+
fs.writeFileSync(scriptPath, scriptContent, { mode: 0o755 });
|
|
3871
|
+
}
|
|
3872
|
+
function installClaudeSettings(projectDir, serverPort) {
|
|
3873
|
+
const claudeDir = path.join(projectDir, '.claude');
|
|
3874
|
+
fs.mkdirSync(claudeDir, { recursive: true });
|
|
3875
|
+
const settingsPath = path.join(claudeDir, 'settings.json');
|
|
3876
|
+
// Don't overwrite existing settings — merge hooks in
|
|
3877
|
+
let settings = {};
|
|
3878
|
+
if (fs.existsSync(settingsPath)) {
|
|
3879
|
+
try {
|
|
3880
|
+
settings = JSON.parse(fs.readFileSync(settingsPath, 'utf-8'));
|
|
3881
|
+
}
|
|
3882
|
+
catch {
|
|
3883
|
+
// Start fresh if corrupted
|
|
3884
|
+
}
|
|
3885
|
+
}
|
|
3886
|
+
// Add hook configurations — all three sections for full agent support
|
|
3887
|
+
if (!settings.hooks) {
|
|
3888
|
+
settings.hooks = {};
|
|
3889
|
+
}
|
|
3890
|
+
const hooks = settings.hooks;
|
|
3891
|
+
// All instar-managed hooks for PreToolUse/Bash
|
|
3892
|
+
const instarBashHooks = [
|
|
3893
|
+
{
|
|
3894
|
+
type: 'command',
|
|
3895
|
+
command: 'bash .instar/hooks/instar/dangerous-command-guard.sh "$TOOL_INPUT"',
|
|
3896
|
+
blocking: true,
|
|
3897
|
+
},
|
|
3898
|
+
{
|
|
3899
|
+
type: 'command',
|
|
3900
|
+
command: 'bash .instar/hooks/instar/grounding-before-messaging.sh "$TOOL_INPUT"',
|
|
3901
|
+
blocking: false,
|
|
3902
|
+
},
|
|
3903
|
+
{
|
|
3904
|
+
type: 'command',
|
|
3905
|
+
command: 'node .instar/hooks/instar/deferral-detector.js',
|
|
3906
|
+
timeout: 5000,
|
|
3907
|
+
},
|
|
3908
|
+
{
|
|
3909
|
+
type: 'command',
|
|
3910
|
+
command: 'node .instar/hooks/instar/external-communication-guard.js',
|
|
3911
|
+
timeout: 5000,
|
|
3912
|
+
},
|
|
3913
|
+
{
|
|
3914
|
+
type: 'command',
|
|
3915
|
+
command: 'node .instar/hooks/instar/post-action-reflection.js',
|
|
3916
|
+
timeout: 5000,
|
|
3917
|
+
},
|
|
3918
|
+
];
|
|
3919
|
+
// External operation gate hook — intercepts MCP tool calls for safety evaluation
|
|
3920
|
+
const instarMcpHooks = [
|
|
3921
|
+
{
|
|
3922
|
+
type: 'command',
|
|
3923
|
+
command: 'node .instar/hooks/instar/external-operation-gate.js',
|
|
3924
|
+
blocking: true,
|
|
3925
|
+
timeout: 5000,
|
|
3926
|
+
},
|
|
3927
|
+
];
|
|
3928
|
+
// PreToolUse: merge instar hooks into existing or create fresh
|
|
3929
|
+
if (!hooks.PreToolUse) {
|
|
3930
|
+
hooks.PreToolUse = [
|
|
3931
|
+
{ matcher: 'Bash', hooks: instarBashHooks },
|
|
3932
|
+
{ matcher: 'mcp__.*', hooks: instarMcpHooks },
|
|
3933
|
+
];
|
|
3934
|
+
}
|
|
3935
|
+
else {
|
|
3936
|
+
const preToolUse = hooks.PreToolUse;
|
|
3937
|
+
// Find existing Bash matcher or create one
|
|
3938
|
+
let bashEntry = preToolUse.find(e => e.matcher === 'Bash');
|
|
3939
|
+
if (!bashEntry) {
|
|
3940
|
+
bashEntry = { matcher: 'Bash', hooks: [] };
|
|
3941
|
+
preToolUse.push(bashEntry);
|
|
3942
|
+
}
|
|
3943
|
+
if (!bashEntry.hooks)
|
|
3944
|
+
bashEntry.hooks = [];
|
|
3945
|
+
// Add any instar hooks not already present (by command string)
|
|
3946
|
+
const existingBashCommands = new Set(bashEntry.hooks.map(h => h.command));
|
|
3947
|
+
for (const hook of instarBashHooks) {
|
|
3948
|
+
if (!existingBashCommands.has(hook.command)) {
|
|
3949
|
+
bashEntry.hooks.push(hook);
|
|
3950
|
+
}
|
|
3951
|
+
}
|
|
3952
|
+
// Find existing MCP matcher or create one
|
|
3953
|
+
let mcpEntry = preToolUse.find(e => e.matcher === 'mcp__.*');
|
|
3954
|
+
if (!mcpEntry) {
|
|
3955
|
+
mcpEntry = { matcher: 'mcp__.*', hooks: [] };
|
|
3956
|
+
preToolUse.push(mcpEntry);
|
|
3957
|
+
}
|
|
3958
|
+
if (!mcpEntry.hooks)
|
|
3959
|
+
mcpEntry.hooks = [];
|
|
3960
|
+
const existingMcpCommands = new Set(mcpEntry.hooks.map(h => h.command));
|
|
3961
|
+
for (const hook of instarMcpHooks) {
|
|
3962
|
+
if (!existingMcpCommands.has(hook.command)) {
|
|
3963
|
+
mcpEntry.hooks.push(hook);
|
|
3964
|
+
}
|
|
3965
|
+
}
|
|
3966
|
+
}
|
|
3967
|
+
// SessionStart: identity injection on all lifecycle events
|
|
3968
|
+
// Uses the correct Claude Code hook type (not PostToolUse or Notification)
|
|
3969
|
+
// The session-start.sh hook handles event routing internally via CLAUDE_HOOK_MATCHER
|
|
3970
|
+
const sessionStartHook = {
|
|
3971
|
+
type: 'command',
|
|
3972
|
+
command: 'bash .instar/hooks/instar/session-start.sh',
|
|
3973
|
+
timeout: 5,
|
|
3974
|
+
};
|
|
3975
|
+
if (!hooks.SessionStart) {
|
|
3976
|
+
hooks.SessionStart = [
|
|
3977
|
+
{ matcher: 'startup', hooks: [sessionStartHook] },
|
|
3978
|
+
{ matcher: 'resume', hooks: [sessionStartHook] },
|
|
3979
|
+
{ matcher: 'compact', hooks: [sessionStartHook] },
|
|
3980
|
+
];
|
|
3981
|
+
}
|
|
3982
|
+
else {
|
|
3983
|
+
// Merge: ensure all matchers are covered
|
|
3984
|
+
const sessionStart = hooks.SessionStart;
|
|
3985
|
+
for (const matcher of ['startup', 'resume', 'compact']) {
|
|
3986
|
+
if (!sessionStart.some(e => e.matcher === matcher)) {
|
|
3987
|
+
sessionStart.push({ matcher, hooks: [sessionStartHook] });
|
|
3988
|
+
}
|
|
3989
|
+
}
|
|
3990
|
+
}
|
|
3991
|
+
// Clean up legacy hooks from older versions
|
|
3992
|
+
// PostToolUse with empty matcher for session-start was noisy (fired every tool use)
|
|
3993
|
+
if (hooks.PostToolUse) {
|
|
3994
|
+
const postToolUse = hooks.PostToolUse;
|
|
3995
|
+
const filtered = postToolUse.filter(e => {
|
|
3996
|
+
if (e.matcher === '' && e.hooks?.some(h => h.command?.includes('session-start.sh'))) {
|
|
3997
|
+
return false; // Remove legacy session-start from PostToolUse
|
|
3998
|
+
}
|
|
3999
|
+
return true;
|
|
4000
|
+
});
|
|
4001
|
+
if (filtered.length === 0) {
|
|
4002
|
+
delete hooks.PostToolUse;
|
|
4003
|
+
}
|
|
4004
|
+
else {
|
|
4005
|
+
hooks.PostToolUse = filtered;
|
|
4006
|
+
}
|
|
4007
|
+
}
|
|
4008
|
+
// Remove legacy Notification hook for compaction (now handled by SessionStart)
|
|
4009
|
+
if (hooks.Notification) {
|
|
4010
|
+
const notification = hooks.Notification;
|
|
4011
|
+
const filtered = notification.filter(e => {
|
|
4012
|
+
if (e.matcher === 'compact' && e.hooks?.some(h => h.command?.includes('compaction-recovery.sh'))) {
|
|
4013
|
+
return false; // Remove legacy compaction from Notification
|
|
4014
|
+
}
|
|
4015
|
+
return true;
|
|
4016
|
+
});
|
|
4017
|
+
if (filtered.length === 0) {
|
|
4018
|
+
delete hooks.Notification;
|
|
4019
|
+
}
|
|
4020
|
+
else {
|
|
4021
|
+
hooks.Notification = filtered;
|
|
4022
|
+
}
|
|
4023
|
+
}
|
|
4024
|
+
// PostToolUse: scope coherence collector tracks implementation depth
|
|
4025
|
+
const scopeCollectorHook = {
|
|
4026
|
+
type: 'command',
|
|
4027
|
+
command: 'node .instar/hooks/instar/scope-coherence-collector.js',
|
|
4028
|
+
timeout: 5000,
|
|
4029
|
+
};
|
|
4030
|
+
if (!hooks.PostToolUse) {
|
|
4031
|
+
hooks.PostToolUse = [];
|
|
4032
|
+
}
|
|
4033
|
+
const postToolUse = hooks.PostToolUse;
|
|
4034
|
+
// Add collector + claim intercept to Edit, Write, Bash matchers
|
|
4035
|
+
// (scope collector also added to Read and Skill)
|
|
4036
|
+
const claimInterceptHook = {
|
|
4037
|
+
type: 'command',
|
|
4038
|
+
command: 'node .instar/hooks/instar/claim-intercept.js',
|
|
4039
|
+
timeout: 5000,
|
|
4040
|
+
};
|
|
4041
|
+
for (const matcher of ['Edit', 'Write', 'Bash', 'Read', 'Skill']) {
|
|
4042
|
+
let entry = postToolUse.find(e => e.matcher === matcher);
|
|
4043
|
+
if (!entry) {
|
|
4044
|
+
entry = { matcher, hooks: [] };
|
|
4045
|
+
postToolUse.push(entry);
|
|
4046
|
+
}
|
|
4047
|
+
if (!entry.hooks)
|
|
4048
|
+
entry.hooks = [];
|
|
4049
|
+
const existingCommands = new Set(entry.hooks.map(h => h.command));
|
|
4050
|
+
if (!existingCommands.has(scopeCollectorHook.command)) {
|
|
4051
|
+
entry.hooks.push(scopeCollectorHook);
|
|
4052
|
+
}
|
|
4053
|
+
// Claim intercept only on content-producing tools (not Read/Skill)
|
|
4054
|
+
if (['Edit', 'Write', 'Bash'].includes(matcher)) {
|
|
4055
|
+
if (!existingCommands.has(claimInterceptHook.command)) {
|
|
4056
|
+
entry.hooks.push(claimInterceptHook);
|
|
4057
|
+
}
|
|
4058
|
+
}
|
|
4059
|
+
}
|
|
4060
|
+
// Stop: response review pipeline — Coherence Gate LLM-powered review
|
|
4061
|
+
const responseReviewHook = {
|
|
4062
|
+
type: 'command',
|
|
4063
|
+
command: 'node .instar/hooks/instar/response-review.js',
|
|
4064
|
+
timeout: 10000,
|
|
4065
|
+
};
|
|
4066
|
+
// Stop: scope coherence checkpoint fires the zoom-out prompt
|
|
4067
|
+
const scopeCheckpointHook = {
|
|
4068
|
+
type: 'command',
|
|
4069
|
+
command: 'node .instar/hooks/instar/scope-coherence-checkpoint.js',
|
|
4070
|
+
timeout: 10000,
|
|
4071
|
+
};
|
|
4072
|
+
// Stop: claim intercept response checks direct text for false claims
|
|
4073
|
+
const claimInterceptResponseHook = {
|
|
4074
|
+
type: 'command',
|
|
4075
|
+
command: 'node .instar/hooks/instar/claim-intercept-response.js',
|
|
4076
|
+
timeout: 10000,
|
|
4077
|
+
};
|
|
4078
|
+
if (!hooks.Stop) {
|
|
4079
|
+
hooks.Stop = [];
|
|
4080
|
+
}
|
|
4081
|
+
const stopHooks = hooks.Stop;
|
|
4082
|
+
// Register response review (first — catches quality issues before other checks)
|
|
4083
|
+
const hasResponseReview = stopHooks.some(e => e.hooks?.some(h => h.command?.includes('response-review.js')));
|
|
4084
|
+
if (!hasResponseReview) {
|
|
4085
|
+
stopHooks.unshift({ matcher: '', hooks: [responseReviewHook] });
|
|
4086
|
+
}
|
|
4087
|
+
// Register claim intercept response (before scope checkpoint — catch claims first)
|
|
4088
|
+
const hasClaimIntercept = stopHooks.some(e => e.hooks?.some(h => h.command?.includes('claim-intercept-response.js')));
|
|
4089
|
+
if (!hasClaimIntercept) {
|
|
4090
|
+
stopHooks.unshift({ matcher: '', hooks: [claimInterceptResponseHook] });
|
|
4091
|
+
}
|
|
4092
|
+
// Register scope coherence checkpoint
|
|
4093
|
+
const hasCheckpoint = stopHooks.some(e => e.hooks?.some(h => h.command?.includes('scope-coherence-checkpoint.js')));
|
|
4094
|
+
if (!hasCheckpoint) {
|
|
4095
|
+
stopHooks.push({ matcher: '', hooks: [scopeCheckpointHook] });
|
|
4096
|
+
}
|
|
4097
|
+
// Register autonomous stop hook — structural enforcement for /autonomous mode.
|
|
4098
|
+
// Must be FIRST in the Stop chain so it blocks exit before other hooks run.
|
|
4099
|
+
const hasAutonomousHook = stopHooks.some(e => e.hooks?.some(h => h.command?.includes('autonomous-stop-hook')));
|
|
4100
|
+
if (!hasAutonomousHook) {
|
|
4101
|
+
hooks.Stop.unshift({ matcher: '', hooks: [{
|
|
4102
|
+
type: 'command',
|
|
4103
|
+
command: 'bash .claude/skills/autonomous/hooks/autonomous-stop-hook.sh',
|
|
4104
|
+
timeout: 10000,
|
|
4105
|
+
}] });
|
|
4106
|
+
}
|
|
4107
|
+
// PermissionRequest: auto-approve all — subagents don't inherit --dangerously-skip-permissions.
|
|
4108
|
+
// Real safety is in PreToolUse hooks. Permission prompts just block autonomous work.
|
|
4109
|
+
if (!hooks.PermissionRequest) {
|
|
4110
|
+
hooks.PermissionRequest = [];
|
|
4111
|
+
}
|
|
4112
|
+
const permHooks = hooks.PermissionRequest;
|
|
4113
|
+
const hasAutoApprove = permHooks.some(e => e.hooks?.some(h => h.command?.includes('auto-approve-permissions.js')));
|
|
4114
|
+
if (!hasAutoApprove) {
|
|
4115
|
+
hooks.PermissionRequest.push({
|
|
4116
|
+
matcher: '',
|
|
4117
|
+
hooks: [{
|
|
4118
|
+
type: 'command',
|
|
4119
|
+
command: 'node .instar/hooks/instar/auto-approve-permissions.js',
|
|
4120
|
+
timeout: 5000,
|
|
4121
|
+
}],
|
|
4122
|
+
});
|
|
4123
|
+
}
|
|
4124
|
+
// HTTP hooks for observability (session telemetry, claudeSessionId population)
|
|
4125
|
+
// Uses resolved localhost URL — NOT env var templates (Claude Code validates URLs at parse time)
|
|
4126
|
+
if (serverPort) {
|
|
4127
|
+
const serverUrl = `http://localhost:${serverPort}`;
|
|
4128
|
+
const httpHookSettings = buildHttpHookSettings(serverUrl);
|
|
4129
|
+
for (const [event, entries] of Object.entries(httpHookSettings)) {
|
|
4130
|
+
if (!hooks[event]) {
|
|
4131
|
+
hooks[event] = [];
|
|
4132
|
+
}
|
|
4133
|
+
// Remove any existing HTTP hooks for this event (avoid duplicates on re-init)
|
|
4134
|
+
hooks[event] = hooks[event].filter(e => !e.hooks?.some(h => h.type === 'http'));
|
|
4135
|
+
hooks[event].push(...entries);
|
|
4136
|
+
}
|
|
4137
|
+
}
|
|
4138
|
+
// Remove stale mcpServers from settings.json — MCP servers belong in
|
|
4139
|
+
// ~/.claude.json (local scope) or .mcp.json, NOT .claude/settings.json
|
|
4140
|
+
if (settings.mcpServers) {
|
|
4141
|
+
delete settings.mcpServers;
|
|
4142
|
+
}
|
|
4143
|
+
fs.writeFileSync(settingsPath, JSON.stringify(settings, null, 2));
|
|
4144
|
+
// MCP Servers: Register Playwright in the correct locations
|
|
4145
|
+
// Claude Code reads MCP servers from ~/.claude.json and .mcp.json, NOT .claude/settings.json
|
|
4146
|
+
registerPlaywrightMcp(projectDir);
|
|
4147
|
+
}
|
|
4148
|
+
/**
|
|
4149
|
+
* Register Playwright MCP server in the correct locations for Claude Code.
|
|
4150
|
+
*
|
|
4151
|
+
* Claude Code reads MCP servers from:
|
|
4152
|
+
* 1. ~/.claude.json — local scope (projects["/path"].mcpServers) — no trust dialog
|
|
4153
|
+
* 2. .mcp.json in project root — project scope — requires trust acceptance
|
|
4154
|
+
*
|
|
4155
|
+
* We register in both for robustness.
|
|
4156
|
+
*/
|
|
4157
|
+
function registerPlaywrightMcp(projectDir) {
|
|
4158
|
+
const absDir = path.resolve(projectDir);
|
|
4159
|
+
// ── 1. Register in ~/.claude.json at local scope ──
|
|
4160
|
+
const claudeJsonPath = path.join(os.homedir(), '.claude.json');
|
|
4161
|
+
try {
|
|
4162
|
+
let claudeJson = {};
|
|
4163
|
+
if (fs.existsSync(claudeJsonPath)) {
|
|
4164
|
+
claudeJson = JSON.parse(fs.readFileSync(claudeJsonPath, 'utf-8'));
|
|
4165
|
+
}
|
|
4166
|
+
if (!claudeJson.projects || typeof claudeJson.projects !== 'object') {
|
|
4167
|
+
claudeJson.projects = {};
|
|
4168
|
+
}
|
|
4169
|
+
const projects = claudeJson.projects;
|
|
4170
|
+
if (!projects[absDir]) {
|
|
4171
|
+
projects[absDir] = {};
|
|
4172
|
+
}
|
|
4173
|
+
const projectEntry = projects[absDir];
|
|
4174
|
+
if (!projectEntry.mcpServers || typeof projectEntry.mcpServers !== 'object') {
|
|
4175
|
+
projectEntry.mcpServers = {};
|
|
4176
|
+
}
|
|
4177
|
+
const mcpServers = projectEntry.mcpServers;
|
|
4178
|
+
if (!mcpServers.playwright) {
|
|
4179
|
+
mcpServers.playwright = {
|
|
4180
|
+
command: 'npx',
|
|
4181
|
+
args: ['-y', '@playwright/mcp@latest'],
|
|
4182
|
+
};
|
|
4183
|
+
}
|
|
4184
|
+
projectEntry.hasTrustDialogAccepted = true;
|
|
4185
|
+
const tmpPath = `${claudeJsonPath}.${process.pid}.tmp`;
|
|
4186
|
+
fs.writeFileSync(tmpPath, JSON.stringify(claudeJson, null, 2));
|
|
4187
|
+
fs.renameSync(tmpPath, claudeJsonPath);
|
|
4188
|
+
}
|
|
4189
|
+
catch {
|
|
4190
|
+
// Non-fatal
|
|
4191
|
+
}
|
|
4192
|
+
// ── 2. Create .mcp.json in project root ──
|
|
4193
|
+
const mcpJsonPath = path.join(projectDir, '.mcp.json');
|
|
4194
|
+
if (!fs.existsSync(mcpJsonPath)) {
|
|
4195
|
+
try {
|
|
4196
|
+
const mcpConfig = {
|
|
4197
|
+
mcpServers: {
|
|
4198
|
+
playwright: {
|
|
4199
|
+
command: 'npx',
|
|
4200
|
+
args: ['-y', '@playwright/mcp@latest'],
|
|
4201
|
+
},
|
|
4202
|
+
},
|
|
4203
|
+
};
|
|
4204
|
+
fs.writeFileSync(mcpJsonPath, JSON.stringify(mcpConfig, null, 2));
|
|
4205
|
+
}
|
|
4206
|
+
catch {
|
|
4207
|
+
// Non-fatal
|
|
4208
|
+
}
|
|
4209
|
+
}
|
|
4210
|
+
}
|
|
4211
|
+
//# sourceMappingURL=init.js.map
|