instar 0.28.76 → 0.28.78
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/dashboard/index.html +486 -0
- package/dist/cli.js +5 -8
- package/dist/cli.js.map +1 -1
- package/dist/commands/discovery.d.ts.map +1 -1
- package/dist/commands/discovery.js +2 -2
- package/dist/commands/discovery.js.map +1 -1
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +22 -4
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/job.d.ts.map +1 -1
- package/dist/commands/job.js +2 -2
- package/dist/commands/job.js.map +1 -1
- package/dist/commands/ledgerCleanup.d.ts.map +1 -1
- package/dist/commands/ledgerCleanup.js +2 -2
- package/dist/commands/ledgerCleanup.js.map +1 -1
- package/dist/commands/listener.d.ts.map +1 -1
- package/dist/commands/listener.js +7 -12
- package/dist/commands/listener.js.map +1 -1
- package/dist/commands/nuke.d.ts.map +1 -1
- package/dist/commands/nuke.js +11 -21
- package/dist/commands/nuke.js.map +1 -1
- package/dist/commands/server.d.ts.map +1 -1
- package/dist/commands/server.js +79 -5
- package/dist/commands/server.js.map +1 -1
- package/dist/commands/setup.d.ts.map +1 -1
- package/dist/commands/setup.js +11 -15
- package/dist/commands/setup.js.map +1 -1
- package/dist/commands/slack-cli.d.ts.map +1 -1
- package/dist/commands/slack-cli.js +5 -8
- package/dist/commands/slack-cli.js.map +1 -1
- package/dist/commands/whatsapp.d.ts.map +1 -1
- package/dist/commands/whatsapp.js +2 -2
- package/dist/commands/whatsapp.js.map +1 -1
- package/dist/commands/worktree.d.ts.map +1 -1
- package/dist/commands/worktree.js +2 -2
- package/dist/commands/worktree.js.map +1 -1
- package/dist/core/AgentConnector.d.ts.map +1 -1
- package/dist/core/AgentConnector.js +9 -10
- package/dist/core/AgentConnector.js.map +1 -1
- package/dist/core/AgentRegistry.d.ts.map +1 -1
- package/dist/core/AgentRegistry.js +3 -4
- package/dist/core/AgentRegistry.js.map +1 -1
- package/dist/core/AutoDispatcher.d.ts.map +1 -1
- package/dist/core/AutoDispatcher.js +2 -2
- package/dist/core/AutoDispatcher.js.map +1 -1
- package/dist/core/AutoUpdater.d.ts.map +1 -1
- package/dist/core/AutoUpdater.js +2 -2
- package/dist/core/AutoUpdater.js.map +1 -1
- package/dist/core/AutonomousEvolution.d.ts.map +1 -1
- package/dist/core/AutonomousEvolution.js +2 -2
- package/dist/core/AutonomousEvolution.js.map +1 -1
- package/dist/core/BackupManager.d.ts.map +1 -1
- package/dist/core/BackupManager.js +2 -2
- package/dist/core/BackupManager.js.map +1 -1
- package/dist/core/BranchManager.d.ts.map +1 -1
- package/dist/core/BranchManager.js +3 -3
- package/dist/core/BranchManager.js.map +1 -1
- package/dist/core/CaffeinateManager.d.ts.map +1 -1
- package/dist/core/CaffeinateManager.js +2 -2
- package/dist/core/CaffeinateManager.js.map +1 -1
- package/dist/core/DeferredDispatchTracker.d.ts.map +1 -1
- package/dist/core/DeferredDispatchTracker.js +2 -2
- package/dist/core/DeferredDispatchTracker.js.map +1 -1
- package/dist/core/DispatchManager.d.ts.map +1 -1
- package/dist/core/DispatchManager.js +3 -4
- package/dist/core/DispatchManager.js.map +1 -1
- package/dist/core/EvolutionManager.d.ts.map +1 -1
- package/dist/core/EvolutionManager.js +2 -2
- package/dist/core/EvolutionManager.js.map +1 -1
- package/dist/core/ExecutionJournal.d.ts.map +1 -1
- package/dist/core/ExecutionJournal.js +2 -2
- package/dist/core/ExecutionJournal.js.map +1 -1
- package/dist/core/FeedbackManager.d.ts.map +1 -1
- package/dist/core/FeedbackManager.js +2 -2
- package/dist/core/FeedbackManager.js.map +1 -1
- package/dist/core/FileClassifier.d.ts.map +1 -1
- package/dist/core/FileClassifier.js +8 -17
- package/dist/core/FileClassifier.js.map +1 -1
- package/dist/core/ForegroundRestartWatcher.d.ts.map +1 -1
- package/dist/core/ForegroundRestartWatcher.js +3 -4
- package/dist/core/ForegroundRestartWatcher.js.map +1 -1
- package/dist/core/GitStateManager.d.ts.map +1 -1
- package/dist/core/GitStateManager.js +3 -12
- package/dist/core/GitStateManager.js.map +1 -1
- package/dist/core/GitSync.d.ts.map +1 -1
- package/dist/core/GitSync.js +6 -6
- package/dist/core/GitSync.js.map +1 -1
- package/dist/core/GlobalInstallCleanup.d.ts.map +1 -1
- package/dist/core/GlobalInstallCleanup.js +3 -4
- package/dist/core/GlobalInstallCleanup.js.map +1 -1
- package/dist/core/GlobalSecretStore.d.ts.map +1 -1
- package/dist/core/GlobalSecretStore.js +3 -4
- package/dist/core/GlobalSecretStore.js.map +1 -1
- package/dist/core/HandoffManager.d.ts.map +1 -1
- package/dist/core/HandoffManager.js +5 -5
- package/dist/core/HandoffManager.js.map +1 -1
- package/dist/core/JargonDetector.d.ts +28 -0
- package/dist/core/JargonDetector.d.ts.map +1 -0
- package/dist/core/JargonDetector.js +59 -0
- package/dist/core/JargonDetector.js.map +1 -0
- package/dist/core/LedgerSessionRegistry.d.ts.map +1 -1
- package/dist/core/LedgerSessionRegistry.js +2 -2
- package/dist/core/LedgerSessionRegistry.js.map +1 -1
- package/dist/core/MachineIdentity.d.ts.map +1 -1
- package/dist/core/MachineIdentity.js +2 -2
- package/dist/core/MachineIdentity.js.map +1 -1
- package/dist/core/MessagingToneGate.d.ts +42 -5
- package/dist/core/MessagingToneGate.d.ts.map +1 -1
- package/dist/core/MessagingToneGate.js +40 -6
- package/dist/core/MessagingToneGate.js.map +1 -1
- package/dist/core/ParallelDevWiring.d.ts.map +1 -1
- package/dist/core/ParallelDevWiring.js +3 -6
- package/dist/core/ParallelDevWiring.js.map +1 -1
- package/dist/core/PostUpdateMigrator.d.ts +26 -0
- package/dist/core/PostUpdateMigrator.d.ts.map +1 -1
- package/dist/core/PostUpdateMigrator.js +249 -46
- package/dist/core/PostUpdateMigrator.js.map +1 -1
- package/dist/core/ProjectMapper.d.ts.map +1 -1
- package/dist/core/ProjectMapper.js +5 -11
- package/dist/core/ProjectMapper.js.map +1 -1
- package/dist/core/RelationshipManager.d.ts.map +1 -1
- package/dist/core/RelationshipManager.js +4 -5
- package/dist/core/RelationshipManager.js.map +1 -1
- package/dist/core/SafeGitExecutor.d.ts +11 -5
- package/dist/core/SafeGitExecutor.d.ts.map +1 -1
- package/dist/core/SafeGitExecutor.js +87 -1
- package/dist/core/SafeGitExecutor.js.map +1 -1
- package/dist/core/ScopeVerifier.d.ts.map +1 -1
- package/dist/core/ScopeVerifier.js +3 -6
- package/dist/core/ScopeVerifier.js.map +1 -1
- package/dist/core/SecretStore.d.ts.map +1 -1
- package/dist/core/SecretStore.js +2 -2
- package/dist/core/SecretStore.js.map +1 -1
- package/dist/core/SharedStateLedger.d.ts.map +1 -1
- package/dist/core/SharedStateLedger.js +2 -2
- package/dist/core/SharedStateLedger.js.map +1 -1
- package/dist/core/SoulManager.d.ts.map +1 -1
- package/dist/core/SoulManager.js +3 -4
- package/dist/core/SoulManager.js.map +1 -1
- package/dist/core/StateManager.d.ts.map +1 -1
- package/dist/core/StateManager.js +4 -6
- package/dist/core/StateManager.js.map +1 -1
- package/dist/core/SyncOrchestrator.d.ts.map +1 -1
- package/dist/core/SyncOrchestrator.js +6 -7
- package/dist/core/SyncOrchestrator.js.map +1 -1
- package/dist/core/UpdateChecker.d.ts.map +1 -1
- package/dist/core/UpdateChecker.js +3 -4
- package/dist/core/UpdateChecker.js.map +1 -1
- package/dist/core/UpgradeGuideProcessor.d.ts.map +1 -1
- package/dist/core/UpgradeGuideProcessor.js +3 -4
- package/dist/core/UpgradeGuideProcessor.js.map +1 -1
- package/dist/core/WorktreeManager.d.ts.map +1 -1
- package/dist/core/WorktreeManager.js +9 -14
- package/dist/core/WorktreeManager.js.map +1 -1
- package/dist/knowledge/KnowledgeManager.d.ts.map +1 -1
- package/dist/knowledge/KnowledgeManager.js +2 -2
- package/dist/knowledge/KnowledgeManager.js.map +1 -1
- package/dist/lifeline/ServerSupervisor.d.ts +28 -0
- package/dist/lifeline/ServerSupervisor.d.ts.map +1 -1
- package/dist/lifeline/ServerSupervisor.js +171 -73
- package/dist/lifeline/ServerSupervisor.js.map +1 -1
- package/dist/lifeline/TelegramLifeline.d.ts.map +1 -1
- package/dist/lifeline/TelegramLifeline.js +10 -4
- package/dist/lifeline/TelegramLifeline.js.map +1 -1
- package/dist/lifeline/detectLaunchdSupervised.d.ts +43 -0
- package/dist/lifeline/detectLaunchdSupervised.d.ts.map +1 -0
- package/dist/lifeline/detectLaunchdSupervised.js +106 -0
- package/dist/lifeline/detectLaunchdSupervised.js.map +1 -0
- package/dist/lifeline/droppedMessages.d.ts.map +1 -1
- package/dist/lifeline/droppedMessages.js +2 -2
- package/dist/lifeline/droppedMessages.js.map +1 -1
- package/dist/memory/EpisodicMemory.d.ts.map +1 -1
- package/dist/memory/EpisodicMemory.js +2 -2
- package/dist/memory/EpisodicMemory.js.map +1 -1
- package/dist/memory/TopicMemory.d.ts.map +1 -1
- package/dist/memory/TopicMemory.js +5 -8
- package/dist/memory/TopicMemory.js.map +1 -1
- package/dist/messaging/AgentTokenManager.d.ts.map +1 -1
- package/dist/messaging/AgentTokenManager.js +2 -2
- package/dist/messaging/AgentTokenManager.js.map +1 -1
- package/dist/messaging/DropPickup.d.ts.map +1 -1
- package/dist/messaging/DropPickup.js +2 -2
- package/dist/messaging/DropPickup.js.map +1 -1
- package/dist/messaging/GitSyncTransport.d.ts.map +1 -1
- package/dist/messaging/GitSyncTransport.js +4 -6
- package/dist/messaging/GitSyncTransport.js.map +1 -1
- package/dist/messaging/MessageStore.d.ts.map +1 -1
- package/dist/messaging/MessageStore.js +3 -4
- package/dist/messaging/MessageStore.js.map +1 -1
- package/dist/messaging/TelegramAdapter.d.ts.map +1 -1
- package/dist/messaging/TelegramAdapter.js +5 -8
- package/dist/messaging/TelegramAdapter.js.map +1 -1
- package/dist/messaging/backends/BaileysBackend.d.ts.map +1 -1
- package/dist/messaging/backends/BaileysBackend.js +3 -4
- package/dist/messaging/backends/BaileysBackend.js.map +1 -1
- package/dist/messaging/local-tone-check.d.ts +61 -0
- package/dist/messaging/local-tone-check.d.ts.map +1 -0
- package/dist/messaging/local-tone-check.js +78 -0
- package/dist/messaging/local-tone-check.js.map +1 -0
- package/dist/messaging/pending-relay-store.d.ts +153 -0
- package/dist/messaging/pending-relay-store.d.ts.map +1 -0
- package/dist/messaging/pending-relay-store.js +351 -0
- package/dist/messaging/pending-relay-store.js.map +1 -0
- package/dist/messaging/secret-patterns.d.ts +35 -0
- package/dist/messaging/secret-patterns.d.ts.map +1 -0
- package/dist/messaging/secret-patterns.js +70 -0
- package/dist/messaging/secret-patterns.js.map +1 -0
- package/dist/messaging/shared/EncryptedAuthStore.d.ts.map +1 -1
- package/dist/messaging/shared/EncryptedAuthStore.js +3 -4
- package/dist/messaging/shared/EncryptedAuthStore.js.map +1 -1
- package/dist/messaging/shared/MessageLogger.d.ts.map +1 -1
- package/dist/messaging/shared/MessageLogger.js +2 -2
- package/dist/messaging/shared/MessageLogger.js.map +1 -1
- package/dist/messaging/shared/PrivacyConsent.d.ts.map +1 -1
- package/dist/messaging/shared/PrivacyConsent.js +2 -2
- package/dist/messaging/shared/PrivacyConsent.js.map +1 -1
- package/dist/messaging/shared/SessionChannelRegistry.d.ts.map +1 -1
- package/dist/messaging/shared/SessionChannelRegistry.js +2 -2
- package/dist/messaging/shared/SessionChannelRegistry.js.map +1 -1
- package/dist/messaging/system-templates.d.ts +87 -0
- package/dist/messaging/system-templates.d.ts.map +1 -0
- package/dist/messaging/system-templates.js +236 -0
- package/dist/messaging/system-templates.js.map +1 -0
- package/dist/messaging/whoami-cache.d.ts +66 -0
- package/dist/messaging/whoami-cache.d.ts.map +1 -0
- package/dist/messaging/whoami-cache.js +149 -0
- package/dist/messaging/whoami-cache.js.map +1 -0
- package/dist/moltbridge/ProfileCompiler.d.ts.map +1 -1
- package/dist/moltbridge/ProfileCompiler.js +13 -7
- package/dist/moltbridge/ProfileCompiler.js.map +1 -1
- package/dist/monitoring/CommitmentTracker.d.ts.map +1 -1
- package/dist/monitoring/CommitmentTracker.js +2 -2
- package/dist/monitoring/CommitmentTracker.js.map +1 -1
- package/dist/monitoring/CredentialProvider.d.ts.map +1 -1
- package/dist/monitoring/CredentialProvider.js +2 -2
- package/dist/monitoring/CredentialProvider.js.map +1 -1
- package/dist/monitoring/DegradationReporter.d.ts +41 -0
- package/dist/monitoring/DegradationReporter.d.ts.map +1 -1
- package/dist/monitoring/DegradationReporter.js +96 -4
- package/dist/monitoring/DegradationReporter.js.map +1 -1
- package/dist/monitoring/HealthChecker.d.ts.map +1 -1
- package/dist/monitoring/HealthChecker.js +2 -2
- package/dist/monitoring/HealthChecker.js.map +1 -1
- package/dist/monitoring/HookEventReceiver.d.ts.map +1 -1
- package/dist/monitoring/HookEventReceiver.js +2 -2
- package/dist/monitoring/HookEventReceiver.js.map +1 -1
- package/dist/monitoring/InstructionsVerifier.d.ts.map +1 -1
- package/dist/monitoring/InstructionsVerifier.js +2 -2
- package/dist/monitoring/InstructionsVerifier.js.map +1 -1
- package/dist/monitoring/PresenceProxy.d.ts.map +1 -1
- package/dist/monitoring/PresenceProxy.js +5 -8
- package/dist/monitoring/PresenceProxy.js.map +1 -1
- package/dist/monitoring/QuotaTracker.d.ts.map +1 -1
- package/dist/monitoring/QuotaTracker.js +2 -2
- package/dist/monitoring/QuotaTracker.js.map +1 -1
- package/dist/monitoring/SessionMigrator.d.ts.map +1 -1
- package/dist/monitoring/SessionMigrator.js +2 -2
- package/dist/monitoring/SessionMigrator.js.map +1 -1
- package/dist/monitoring/SessionRecovery.d.ts.map +1 -1
- package/dist/monitoring/SessionRecovery.js +2 -2
- package/dist/monitoring/SessionRecovery.js.map +1 -1
- package/dist/monitoring/TelemetryAuth.d.ts.map +1 -1
- package/dist/monitoring/TelemetryAuth.js +3 -4
- package/dist/monitoring/TelemetryAuth.js.map +1 -1
- package/dist/monitoring/TokenLedger.d.ts +130 -0
- package/dist/monitoring/TokenLedger.d.ts.map +1 -0
- package/dist/monitoring/TokenLedger.js +523 -0
- package/dist/monitoring/TokenLedger.js.map +1 -0
- package/dist/monitoring/TokenLedgerPoller.d.ts +26 -0
- package/dist/monitoring/TokenLedgerPoller.d.ts.map +1 -0
- package/dist/monitoring/TokenLedgerPoller.js +44 -0
- package/dist/monitoring/TokenLedgerPoller.js.map +1 -0
- package/dist/monitoring/TriageOrchestrator.d.ts.map +1 -1
- package/dist/monitoring/TriageOrchestrator.js +3 -4
- package/dist/monitoring/TriageOrchestrator.js.map +1 -1
- package/dist/monitoring/WorktreeReaper.d.ts.map +1 -1
- package/dist/monitoring/WorktreeReaper.js +5 -7
- package/dist/monitoring/WorktreeReaper.js.map +1 -1
- package/dist/monitoring/delivery-failure-sentinel/recovery-policy.d.ts +83 -0
- package/dist/monitoring/delivery-failure-sentinel/recovery-policy.d.ts.map +1 -0
- package/dist/monitoring/delivery-failure-sentinel/recovery-policy.js +218 -0
- package/dist/monitoring/delivery-failure-sentinel/recovery-policy.js.map +1 -0
- package/dist/monitoring/delivery-failure-sentinel.d.ts +177 -0
- package/dist/monitoring/delivery-failure-sentinel.d.ts.map +1 -0
- package/dist/monitoring/delivery-failure-sentinel.js +598 -0
- package/dist/monitoring/delivery-failure-sentinel.js.map +1 -0
- package/dist/monitoring/probes/PlatformProbe.d.ts.map +1 -1
- package/dist/monitoring/probes/PlatformProbe.js +3 -4
- package/dist/monitoring/probes/PlatformProbe.js.map +1 -1
- package/dist/monitoring/templates-drift-verifier.d.ts +109 -0
- package/dist/monitoring/templates-drift-verifier.d.ts.map +1 -0
- package/dist/monitoring/templates-drift-verifier.js +324 -0
- package/dist/monitoring/templates-drift-verifier.js.map +1 -0
- package/dist/paste/PasteManager.d.ts.map +1 -1
- package/dist/paste/PasteManager.js +5 -8
- package/dist/paste/PasteManager.js.map +1 -1
- package/dist/publishing/PrivateViewer.d.ts.map +1 -1
- package/dist/publishing/PrivateViewer.js +2 -2
- package/dist/publishing/PrivateViewer.js.map +1 -1
- package/dist/scheduler/JobScheduler.d.ts.map +1 -1
- package/dist/scheduler/JobScheduler.js +2 -2
- package/dist/scheduler/JobScheduler.js.map +1 -1
- package/dist/server/AgentServer.d.ts +22 -0
- package/dist/server/AgentServer.d.ts.map +1 -1
- package/dist/server/AgentServer.js +199 -1
- package/dist/server/AgentServer.js.map +1 -1
- package/dist/server/WebSocketManager.d.ts +11 -0
- package/dist/server/WebSocketManager.d.ts.map +1 -1
- package/dist/server/WebSocketManager.js +28 -0
- package/dist/server/WebSocketManager.js.map +1 -1
- package/dist/server/boot-id.d.ts +58 -0
- package/dist/server/boot-id.d.ts.map +1 -0
- package/dist/server/boot-id.js +121 -0
- package/dist/server/boot-id.js.map +1 -0
- package/dist/server/middleware.d.ts +14 -1
- package/dist/server/middleware.d.ts.map +1 -1
- package/dist/server/middleware.js +81 -1
- package/dist/server/middleware.js.map +1 -1
- package/dist/server/routes.d.ts +76 -0
- package/dist/server/routes.d.ts.map +1 -1
- package/dist/server/routes.js +626 -11
- package/dist/server/routes.js.map +1 -1
- package/dist/threadline/AgentDiscovery.d.ts.map +1 -1
- package/dist/threadline/AgentDiscovery.js +2 -2
- package/dist/threadline/AgentDiscovery.js.map +1 -1
- package/dist/threadline/AgentTrustManager.d.ts.map +1 -1
- package/dist/threadline/AgentTrustManager.js +2 -2
- package/dist/threadline/AgentTrustManager.js.map +1 -1
- package/dist/threadline/BackfillCore.d.ts +70 -0
- package/dist/threadline/BackfillCore.d.ts.map +1 -0
- package/dist/threadline/BackfillCore.js +117 -0
- package/dist/threadline/BackfillCore.js.map +1 -0
- package/dist/threadline/CircuitBreaker.d.ts.map +1 -1
- package/dist/threadline/CircuitBreaker.js +2 -2
- package/dist/threadline/CircuitBreaker.js.map +1 -1
- package/dist/threadline/ComputeMeter.d.ts.map +1 -1
- package/dist/threadline/ComputeMeter.js +2 -2
- package/dist/threadline/ComputeMeter.js.map +1 -1
- package/dist/threadline/ContextThreadMap.d.ts.map +1 -1
- package/dist/threadline/ContextThreadMap.js +2 -2
- package/dist/threadline/ContextThreadMap.js.map +1 -1
- package/dist/threadline/HeartbeatWatchdog.d.ts +78 -0
- package/dist/threadline/HeartbeatWatchdog.d.ts.map +1 -0
- package/dist/threadline/HeartbeatWatchdog.js +212 -0
- package/dist/threadline/HeartbeatWatchdog.js.map +1 -0
- package/dist/threadline/HeartbeatWriter.d.ts +79 -0
- package/dist/threadline/HeartbeatWriter.d.ts.map +1 -0
- package/dist/threadline/HeartbeatWriter.js +109 -0
- package/dist/threadline/HeartbeatWriter.js.map +1 -0
- package/dist/threadline/InvitationManager.d.ts.map +1 -1
- package/dist/threadline/InvitationManager.js +2 -2
- package/dist/threadline/InvitationManager.js.map +1 -1
- package/dist/threadline/ListenerSessionManager.d.ts +59 -0
- package/dist/threadline/ListenerSessionManager.d.ts.map +1 -1
- package/dist/threadline/ListenerSessionManager.js +79 -0
- package/dist/threadline/ListenerSessionManager.js.map +1 -1
- package/dist/threadline/MCPAuth.d.ts.map +1 -1
- package/dist/threadline/MCPAuth.js +2 -2
- package/dist/threadline/MCPAuth.js.map +1 -1
- package/dist/threadline/PipeSessionSpawner.d.ts.map +1 -1
- package/dist/threadline/PipeSessionSpawner.js +3 -4
- package/dist/threadline/PipeSessionSpawner.js.map +1 -1
- package/dist/threadline/RateLimiter.d.ts.map +1 -1
- package/dist/threadline/RateLimiter.js +2 -2
- package/dist/threadline/RateLimiter.js.map +1 -1
- package/dist/threadline/RelaySpawnFailureHandler.d.ts +53 -0
- package/dist/threadline/RelaySpawnFailureHandler.d.ts.map +1 -0
- package/dist/threadline/RelaySpawnFailureHandler.js +73 -0
- package/dist/threadline/RelaySpawnFailureHandler.js.map +1 -0
- package/dist/threadline/SessionLifecycle.d.ts.map +1 -1
- package/dist/threadline/SessionLifecycle.js +2 -2
- package/dist/threadline/SessionLifecycle.js.map +1 -1
- package/dist/threadline/SpawnLedger.d.ts +94 -0
- package/dist/threadline/SpawnLedger.d.ts.map +1 -0
- package/dist/threadline/SpawnLedger.js +194 -0
- package/dist/threadline/SpawnLedger.js.map +1 -0
- package/dist/threadline/SpawnNonce.d.ts +49 -0
- package/dist/threadline/SpawnNonce.d.ts.map +1 -0
- package/dist/threadline/SpawnNonce.js +99 -0
- package/dist/threadline/SpawnNonce.js.map +1 -0
- package/dist/threadline/TelegramBridge.d.ts +140 -0
- package/dist/threadline/TelegramBridge.d.ts.map +1 -0
- package/dist/threadline/TelegramBridge.js +224 -0
- package/dist/threadline/TelegramBridge.js.map +1 -0
- package/dist/threadline/TelegramBridgeConfig.d.ts +79 -0
- package/dist/threadline/TelegramBridgeConfig.d.ts.map +1 -0
- package/dist/threadline/TelegramBridgeConfig.js +168 -0
- package/dist/threadline/TelegramBridgeConfig.js.map +1 -0
- package/dist/threadline/ThreadlineBootstrap.d.ts.map +1 -1
- package/dist/threadline/ThreadlineBootstrap.js +2 -2
- package/dist/threadline/ThreadlineBootstrap.js.map +1 -1
- package/dist/threadline/ThreadlineMCPServer.d.ts.map +1 -1
- package/dist/threadline/ThreadlineMCPServer.js +5 -0
- package/dist/threadline/ThreadlineMCPServer.js.map +1 -1
- package/dist/threadline/ThreadlineObservability.d.ts +95 -0
- package/dist/threadline/ThreadlineObservability.d.ts.map +1 -0
- package/dist/threadline/ThreadlineObservability.js +310 -0
- package/dist/threadline/ThreadlineObservability.js.map +1 -0
- package/dist/threadline/WakeSocketServer.d.ts.map +1 -1
- package/dist/threadline/WakeSocketServer.js +3 -4
- package/dist/threadline/WakeSocketServer.js.map +1 -1
- package/dist/threadline/listener-daemon.d.ts.map +1 -1
- package/dist/threadline/listener-daemon.js +3 -4
- package/dist/threadline/listener-daemon.js.map +1 -1
- package/dist/users/UserManager.d.ts.map +1 -1
- package/dist/users/UserManager.js +2 -2
- package/dist/users/UserManager.js.map +1 -1
- package/dist/users/UserOnboarding.d.ts.map +1 -1
- package/dist/users/UserOnboarding.js +2 -2
- package/dist/users/UserOnboarding.js.map +1 -1
- package/dist/utils/jsonl-rotation.d.ts.map +1 -1
- package/dist/utils/jsonl-rotation.js +2 -2
- package/dist/utils/jsonl-rotation.js.map +1 -1
- package/package.json +1 -1
- package/scripts/analyze-release.js +7 -12
- package/scripts/check-contract-evidence.js +27 -10
- package/scripts/fix-better-sqlite3.cjs +0 -2
- package/scripts/instar-dev-precommit.js +0 -2
- package/scripts/lint-no-direct-destructive.js +24 -4
- package/scripts/lint-template-sha-history.ts +183 -0
- package/scripts/migrate-incident-2026-04-17.mjs +2 -2
- package/scripts/run-migration.js +500 -0
- package/scripts/test-bootstrap-relay.mjs +2 -2
- package/scripts/threadline-bridge-backfill.mjs +379 -0
- package/scripts/verify-deployed-templates.ts +87 -0
- package/src/data/builtin-manifest.json +140 -132
- package/src/templates/scripts/git-sync-gate.sh +0 -4
- package/src/templates/scripts/telegram-reply.sh +318 -13
- package/upgrades/0.28.77.md +133 -0
- package/upgrades/0.28.78.md +90 -0
- package/upgrades/side-effects/agent-health-alert-authority-routing.md +121 -0
- package/upgrades/side-effects/comprehensive-destructive-tool-containment-migration.md +82 -0
- package/upgrades/side-effects/deferral-detector-orphan-todo.md +101 -0
- package/upgrades/side-effects/lifeline-self-heal-hardening.md +151 -0
- package/upgrades/side-effects/relay-spawn-ghost-reply-phase1.md +139 -0
- package/upgrades/side-effects/telegram-delivery-robustness-layer-2.md +320 -0
- package/upgrades/side-effects/telegram-delivery-robustness-layer-3.md +202 -0
- package/upgrades/side-effects/telegram-delivery-robustness-layer-7.md +339 -0
- package/upgrades/side-effects/telegram-delivery-robustness.md +178 -0
- package/upgrades/side-effects/threadline-bridge-backfill.md +203 -0
- package/upgrades/side-effects/threadline-canonical-inbox-write.md +218 -0
- package/upgrades/side-effects/threadline-observability-tab.md +206 -0
- package/upgrades/side-effects/threadline-tg-bridge-module.md +196 -0
- package/upgrades/side-effects/threadline-tg-bridge-settings-surface.md +208 -0
- package/upgrades/side-effects/token-ledger-bounded-scan.md +230 -0
- package/upgrades/side-effects/token-ledger-phase1.md +123 -0
- package/upgrades/NEXT.md +0 -53
- /package/upgrades/side-effects/{telegram-lifeline-version-missing-info.md → 0.28.76.md} +0 -0
|
@@ -0,0 +1,500 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* run-migration.js — codemod for commitment://incremental-migration.
|
|
4
|
+
*
|
|
5
|
+
* Replaces marked direct destructive callsites with SafeFsExecutor /
|
|
6
|
+
* SafeGitExecutor equivalents. Runs in idempotent passes; safe to re-run.
|
|
7
|
+
*
|
|
8
|
+
* Usage:
|
|
9
|
+
* node scripts/run-migration.js [--dry-run] [--filter <regex>]
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import fs from 'node:fs';
|
|
13
|
+
import path from 'node:path';
|
|
14
|
+
import { execSync } from 'node:child_process';
|
|
15
|
+
|
|
16
|
+
const ROOT = process.cwd();
|
|
17
|
+
const args = process.argv.slice(2);
|
|
18
|
+
const DRY = args.includes('--dry-run');
|
|
19
|
+
const filterIdx = args.indexOf('--filter');
|
|
20
|
+
const FILTER = filterIdx >= 0 ? new RegExp(args[filterIdx + 1]) : null;
|
|
21
|
+
|
|
22
|
+
const MARKER_RE = /^\s*\/\/\s*safe-git-allow:\s*incremental-migration\s*$/;
|
|
23
|
+
|
|
24
|
+
function listMarkedFiles() {
|
|
25
|
+
const out = execSync(
|
|
26
|
+
`grep -rln "safe-git-allow: incremental-migration" src/ scripts/ tests/`,
|
|
27
|
+
{ encoding: 'utf8' },
|
|
28
|
+
);
|
|
29
|
+
return out.split('\n').filter(Boolean).filter((f) => !FILTER || FILTER.test(f));
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function relImport(filePath, target) {
|
|
33
|
+
// target is repo-relative, e.g. "src/core/SafeFsExecutor.js"
|
|
34
|
+
const fromDir = path.dirname(path.resolve(ROOT, filePath));
|
|
35
|
+
const toFile = path.resolve(ROOT, target);
|
|
36
|
+
let rel = path.relative(fromDir, toFile);
|
|
37
|
+
if (!rel.startsWith('.')) rel = './' + rel;
|
|
38
|
+
return rel.replace(/\\/g, '/');
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function ensureImport(content, filePath, importName, importPath) {
|
|
42
|
+
// already imported?
|
|
43
|
+
const importRe = new RegExp(
|
|
44
|
+
`import\\s+\\{[^}]*\\b${importName}\\b[^}]*\\}\\s+from\\s+['"][^'"]*${importPath.split('/').pop()}['"]`,
|
|
45
|
+
);
|
|
46
|
+
if (importRe.test(content)) return content;
|
|
47
|
+
|
|
48
|
+
const rel = relImport(filePath, importPath);
|
|
49
|
+
const stmt = `import { ${importName} } from '${rel}';\n`;
|
|
50
|
+
|
|
51
|
+
// insert after the last existing import line at the top of file.
|
|
52
|
+
// Handle multi-line `import { ... } from '...';` by tracking until the
|
|
53
|
+
// statement-terminating `from '...';` line.
|
|
54
|
+
const lines = content.split('\n');
|
|
55
|
+
let lastImportEnd = -1; // index of last LINE that ENDS an import statement
|
|
56
|
+
let inImportBlock = false;
|
|
57
|
+
for (let i = 0; i < Math.min(lines.length, 200); i++) {
|
|
58
|
+
const ln = lines[i];
|
|
59
|
+
if (!inImportBlock) {
|
|
60
|
+
if (/^import\s/.test(ln)) {
|
|
61
|
+
// single-line import? must contain `from '...'` and end with `;` or be self-terminating.
|
|
62
|
+
if (/\bfrom\s+['"][^'"]+['"]\s*;?\s*$/.test(ln) || /^import\s+['"][^'"]+['"]\s*;?\s*$/.test(ln)) {
|
|
63
|
+
lastImportEnd = i;
|
|
64
|
+
} else {
|
|
65
|
+
inImportBlock = true;
|
|
66
|
+
}
|
|
67
|
+
} else if (lastImportEnd >= 0 && ln.trim() === '') {
|
|
68
|
+
// blank line after imports — keep looking for more imports though
|
|
69
|
+
continue;
|
|
70
|
+
} else if (lastImportEnd >= 0 && !/^import\s/.test(ln) && ln.trim() !== '') {
|
|
71
|
+
// non-import content after seeing imports — stop scanning
|
|
72
|
+
break;
|
|
73
|
+
}
|
|
74
|
+
} else {
|
|
75
|
+
// inside multi-line import block — look for closing `} from '...';`
|
|
76
|
+
if (/\bfrom\s+['"][^'"]+['"]\s*;?\s*$/.test(ln)) {
|
|
77
|
+
inImportBlock = false;
|
|
78
|
+
lastImportEnd = i;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
if (lastImportEnd >= 0) {
|
|
83
|
+
lines.splice(lastImportEnd + 1, 0, stmt.trimEnd());
|
|
84
|
+
return lines.join('\n');
|
|
85
|
+
}
|
|
86
|
+
// No imports — add at top after any leading comments
|
|
87
|
+
let i = 0;
|
|
88
|
+
while (i < lines.length && (lines[i].startsWith('//') || lines[i].startsWith('/*') || lines[i].trim() === '')) i++;
|
|
89
|
+
lines.splice(i, 0, stmt.trimEnd());
|
|
90
|
+
return lines.join('\n');
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// ─── Transformers ──────────────────────────────────────────────────
|
|
94
|
+
|
|
95
|
+
// Single-line transforms removed; all patterns go through the paren-balanced
|
|
96
|
+
// reader to handle nested calls (e.g., `fs.unlinkSync(path.join(a, b))`).
|
|
97
|
+
const transforms = [];
|
|
98
|
+
|
|
99
|
+
// Read a multi-line span starting at line `start` whose first line contains
|
|
100
|
+
// the opening `(` of a call expression. Returns {span: full text, endLine}.
|
|
101
|
+
// Walks until parens are balanced. Strings/comments are NOT escaped — works
|
|
102
|
+
// for the typical well-formed source we have.
|
|
103
|
+
function readBalancedCall(lines, startLine, openIdx) {
|
|
104
|
+
let depth = 0;
|
|
105
|
+
let started = false;
|
|
106
|
+
let endLine = startLine;
|
|
107
|
+
let endCol = openIdx;
|
|
108
|
+
let inSingle = false, inDouble = false, inTpl = false, inLineComment = false, inBlockComment = false;
|
|
109
|
+
outer: for (let i = startLine; i < lines.length; i++) {
|
|
110
|
+
const ln = lines[i];
|
|
111
|
+
const start = i === startLine ? openIdx : 0;
|
|
112
|
+
inLineComment = false;
|
|
113
|
+
for (let j = start; j < ln.length; j++) {
|
|
114
|
+
const c = ln[j], n = ln[j + 1];
|
|
115
|
+
if (inLineComment) break;
|
|
116
|
+
if (inBlockComment) {
|
|
117
|
+
if (c === '*' && n === '/') { inBlockComment = false; j++; }
|
|
118
|
+
continue;
|
|
119
|
+
}
|
|
120
|
+
if (inSingle) { if (c === '\\') { j++; continue; } if (c === "'") inSingle = false; continue; }
|
|
121
|
+
if (inDouble) { if (c === '\\') { j++; continue; } if (c === '"') inDouble = false; continue; }
|
|
122
|
+
if (inTpl) { if (c === '\\') { j++; continue; } if (c === '`') inTpl = false; continue; }
|
|
123
|
+
if (c === '/' && n === '/') { inLineComment = true; break; }
|
|
124
|
+
if (c === '/' && n === '*') { inBlockComment = true; j++; continue; }
|
|
125
|
+
if (c === "'") { inSingle = true; continue; }
|
|
126
|
+
if (c === '"') { inDouble = true; continue; }
|
|
127
|
+
if (c === '`') { inTpl = true; continue; }
|
|
128
|
+
if (c === '(') { depth++; started = true; }
|
|
129
|
+
else if (c === ')') {
|
|
130
|
+
depth--;
|
|
131
|
+
if (started && depth === 0) {
|
|
132
|
+
endLine = i; endCol = j;
|
|
133
|
+
break outer;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
if (depth !== 0) return null;
|
|
139
|
+
const parts = [];
|
|
140
|
+
for (let i = startLine; i <= endLine; i++) {
|
|
141
|
+
if (i === startLine && i === endLine) parts.push(lines[i].slice(openIdx, endCol + 1));
|
|
142
|
+
else if (i === startLine) parts.push(lines[i].slice(openIdx));
|
|
143
|
+
else if (i === endLine) parts.push(lines[i].slice(0, endCol + 1));
|
|
144
|
+
else parts.push(lines[i]);
|
|
145
|
+
}
|
|
146
|
+
return { span: parts.join('\n'), endLine, endCol };
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// Verb classification (mirrors SafeGitExecutor)
|
|
150
|
+
const DESTRUCTIVE_GIT_VERBS = new Set([
|
|
151
|
+
'add','am','apply','branch','checkout','cherry-pick','clean','clone','commit',
|
|
152
|
+
'fetch','gc','init','merge','mv','pull','push','rebase','reset','restore',
|
|
153
|
+
'revert','rm','stash','submodule','switch','tag','update-ref','worktree',
|
|
154
|
+
'prune','notes','replace','filter-branch','remote','config','format-patch',
|
|
155
|
+
]);
|
|
156
|
+
|
|
157
|
+
// Extract verb + verb-args (raw string list) from args text like
|
|
158
|
+
// "['rev-parse', '--abbrev-ref', 'HEAD']". Returns {verb, verbArgs} or null.
|
|
159
|
+
function extractVerbFromArgs(argsText) {
|
|
160
|
+
const arrMatch = argsText.match(/^\s*\[([\s\S]*)\]\s*$/);
|
|
161
|
+
if (!arrMatch) return null;
|
|
162
|
+
const items = splitTopArgs(arrMatch[1]);
|
|
163
|
+
// Each item is the source text of an arg expression. Pick the first
|
|
164
|
+
// string-literal as the verb. Skip a leading -C <dir> pair.
|
|
165
|
+
let i = 0;
|
|
166
|
+
if (items[i] && /^['"]-C['"]$/.test(items[i].trim())) i += 2;
|
|
167
|
+
if (!items[i]) return null;
|
|
168
|
+
const m = items[i].trim().match(/^['"]([^'"]+)['"]$/);
|
|
169
|
+
if (!m) return null;
|
|
170
|
+
const verb = m[1];
|
|
171
|
+
// Build verbArgs from remaining string-literal items only (drop expressions).
|
|
172
|
+
const verbArgs = [];
|
|
173
|
+
for (let j = i + 1; j < items.length; j++) {
|
|
174
|
+
const sm = items[j].trim().match(/^['"]([^'"]+)['"]$/);
|
|
175
|
+
if (sm) verbArgs.push(sm[1]);
|
|
176
|
+
else verbArgs.push(null); // expression — unknown
|
|
177
|
+
}
|
|
178
|
+
return { verb, verbArgs };
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
// Mirrors SafeGitExecutor.isReadOnlyShape for ambiguous verbs.
|
|
182
|
+
function isReadOnlyShape(verb, verbArgs) {
|
|
183
|
+
switch (verb) {
|
|
184
|
+
case 'branch':
|
|
185
|
+
if (verbArgs.length === 0) return true;
|
|
186
|
+
const destBranchFlags = new Set(['-d','-D','--delete','-m','-M','--move','-c','-C','--copy','--set-upstream-to','-u','--unset-upstream','-f','--force','--edit-description','--track','--no-track']);
|
|
187
|
+
for (const a of verbArgs) {
|
|
188
|
+
if (!a) continue;
|
|
189
|
+
if (destBranchFlags.has(a)) return false;
|
|
190
|
+
if (typeof a === 'string' && a.startsWith('--set-upstream')) return false;
|
|
191
|
+
// Bare positional (not starting with '-') = create-branch = destructive.
|
|
192
|
+
if (typeof a === 'string' && !a.startsWith('-')) return false;
|
|
193
|
+
}
|
|
194
|
+
return true;
|
|
195
|
+
case 'remote':
|
|
196
|
+
if (verbArgs.length === 0) return true;
|
|
197
|
+
const sub = verbArgs[0];
|
|
198
|
+
if (sub === '-v' || sub === '--verbose') return true;
|
|
199
|
+
if (sub === 'show' || sub === 'get-url') return true;
|
|
200
|
+
return false;
|
|
201
|
+
case 'worktree':
|
|
202
|
+
if (verbArgs.length === 0) return false;
|
|
203
|
+
return verbArgs[0] === 'list';
|
|
204
|
+
case 'config':
|
|
205
|
+
for (const a of verbArgs) {
|
|
206
|
+
if (!a) continue;
|
|
207
|
+
if (a === '--get' || a === '--get-all' || a === '--get-regexp') return true;
|
|
208
|
+
if (a === '--list' || a === '-l') return true;
|
|
209
|
+
if (a === '--get-color' || a === '--get-colorbool' || a === '--get-urlmatch') return true;
|
|
210
|
+
}
|
|
211
|
+
return false;
|
|
212
|
+
case 'format-patch':
|
|
213
|
+
// --inline is destructive; otherwise read-only.
|
|
214
|
+
for (const a of verbArgs) if (a === '--inline') return false;
|
|
215
|
+
return true;
|
|
216
|
+
case 'stash':
|
|
217
|
+
if (verbArgs.length === 0) return false;
|
|
218
|
+
const ss = verbArgs[0];
|
|
219
|
+
return ss === 'list' || ss === 'show';
|
|
220
|
+
default:
|
|
221
|
+
return null;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
// Parse top-level args of a call. Returns array of arg-text spans.
|
|
226
|
+
function splitTopArgs(inner) {
|
|
227
|
+
const out = [];
|
|
228
|
+
let depth = 0, last = 0;
|
|
229
|
+
let inS=false,inD=false,inT=false;
|
|
230
|
+
for (let i = 0; i < inner.length; i++) {
|
|
231
|
+
const c = inner[i];
|
|
232
|
+
if (inS) { if (c === '\\') { i++; continue; } if (c === "'") inS = false; continue; }
|
|
233
|
+
if (inD) { if (c === '\\') { i++; continue; } if (c === '"') inD = false; continue; }
|
|
234
|
+
if (inT) { if (c === '\\') { i++; continue; } if (c === '`') inT = false; continue; }
|
|
235
|
+
if (c === "'") { inS = true; continue; }
|
|
236
|
+
if (c === '"') { inD = true; continue; }
|
|
237
|
+
if (c === '`') { inT = true; continue; }
|
|
238
|
+
if (c === '(' || c === '[' || c === '{') depth++;
|
|
239
|
+
else if (c === ')' || c === ']' || c === '}') depth--;
|
|
240
|
+
else if (c === ',' && depth === 0) {
|
|
241
|
+
out.push(inner.slice(last, i));
|
|
242
|
+
last = i + 1;
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
if (last <= inner.length) out.push(inner.slice(last));
|
|
246
|
+
return out.map((s) => s.trim()).filter((s) => s.length > 0);
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
// Inject `operation: '<op>'` into an options object literal text.
|
|
250
|
+
// If text is a `{ ... }` literal, merge. Otherwise wrap as `{ ...EXPR, operation }`.
|
|
251
|
+
function injectOperation(optsText, op) {
|
|
252
|
+
if (!optsText) return `{ operation: ${op} }`;
|
|
253
|
+
const t = optsText.trim();
|
|
254
|
+
if (t.startsWith('{') && t.endsWith('}')) {
|
|
255
|
+
let inner = t.slice(1, -1).trim();
|
|
256
|
+
// Strip trailing comma so we don't produce ",, operation:"
|
|
257
|
+
if (inner.endsWith(',')) inner = inner.slice(0, -1).trim();
|
|
258
|
+
if (!inner) return `{ operation: ${op} }`;
|
|
259
|
+
// already has operation? skip
|
|
260
|
+
if (/\boperation\s*:/.test(inner)) return t;
|
|
261
|
+
return `{ ${inner}, operation: ${op} }`;
|
|
262
|
+
}
|
|
263
|
+
return `{ ...${t}, operation: ${op} }`;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
// Try to migrate a multi-line execFileSync('git', argsExpr, optsExpr?) call.
|
|
267
|
+
// Returns { newSpan, classifier } or null.
|
|
268
|
+
function migrateExecFileSyncGit(span, op) {
|
|
269
|
+
// span is "(args)" starting at the open paren.
|
|
270
|
+
const m = span.match(/^\(([\s\S]*)\)$/);
|
|
271
|
+
if (!m) return null;
|
|
272
|
+
const inner = m[1];
|
|
273
|
+
const args = splitTopArgs(inner);
|
|
274
|
+
if (args.length < 2) return null;
|
|
275
|
+
if (!/^['"]git['"]$/.test(args[0])) return null;
|
|
276
|
+
const argsExpr = args[1];
|
|
277
|
+
const optsExpr = args[2] || '';
|
|
278
|
+
const ext = extractVerbFromArgs(argsExpr);
|
|
279
|
+
const verb = ext ? ext.verb : null;
|
|
280
|
+
const verbArgs = ext ? ext.verbArgs : [];
|
|
281
|
+
// Classify: read-only if (a) verb not in DESTRUCTIVE_GIT_VERBS, or
|
|
282
|
+
// (b) ambiguous verb in destructive set but shape is read-only.
|
|
283
|
+
let useRead = false;
|
|
284
|
+
if (verb && !DESTRUCTIVE_GIT_VERBS.has(verb)) {
|
|
285
|
+
useRead = true;
|
|
286
|
+
} else if (verb) {
|
|
287
|
+
const shape = isReadOnlyShape(verb, verbArgs);
|
|
288
|
+
if (shape === true) useRead = true;
|
|
289
|
+
}
|
|
290
|
+
const method = useRead ? 'readSync' : 'execSync';
|
|
291
|
+
// The opts must include cwd. We require operation. Don't try to extract cwd
|
|
292
|
+
// separately — pass through and let SafeGitExecutor use opts.cwd.
|
|
293
|
+
const newOpts = injectOperation(optsExpr, op);
|
|
294
|
+
return { newSpan: `SafeGitExecutor.${method}(${argsExpr}, ${newOpts})` };
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
// Migrate a paren-balanced fs.rmSync/fs.rmdirSync span: span is "(target, opts?)".
|
|
298
|
+
function migrateFsRm(span, op, methodName) {
|
|
299
|
+
const m = span.match(/^\(([\s\S]*)\)$/);
|
|
300
|
+
if (!m) return null;
|
|
301
|
+
const args = splitTopArgs(m[1]);
|
|
302
|
+
if (args.length < 1) return null;
|
|
303
|
+
const target = args[0];
|
|
304
|
+
const opts = args[1] || '';
|
|
305
|
+
const newOpts = injectOperation(opts, op);
|
|
306
|
+
return { newSpan: `SafeFsExecutor.${methodName}(${target}, ${newOpts})` };
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
// Migrate fs.unlinkSync(target) span (single arg).
|
|
310
|
+
function migrateFsUnlink(span, op) {
|
|
311
|
+
const m = span.match(/^\(([\s\S]*)\)$/);
|
|
312
|
+
if (!m) return null;
|
|
313
|
+
const args = splitTopArgs(m[1]);
|
|
314
|
+
if (args.length < 1) return null;
|
|
315
|
+
return { newSpan: `SafeFsExecutor.safeUnlinkSync(${args[0]}, { operation: ${op} })` };
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
// Try to migrate a multi-line execSync('git ...', optsExpr?) call.
|
|
319
|
+
function migrateExecSyncGit(span, op) {
|
|
320
|
+
const m = span.match(/^\(([\s\S]*)\)$/);
|
|
321
|
+
if (!m) return null;
|
|
322
|
+
const inner = m[1];
|
|
323
|
+
const args = splitTopArgs(inner);
|
|
324
|
+
if (args.length < 1) return null;
|
|
325
|
+
// First arg must be a string literal starting with `git ` or `git\n`.
|
|
326
|
+
const first = args[0].trim();
|
|
327
|
+
// Handle template literals separately (rare).
|
|
328
|
+
let cmd;
|
|
329
|
+
if (/^['"]/.test(first)) cmd = first.slice(1, -1);
|
|
330
|
+
else if (first.startsWith('`')) cmd = first.slice(1, -1);
|
|
331
|
+
else return null;
|
|
332
|
+
if (!/^git[\s$]/.test(cmd) && cmd !== 'git') return null;
|
|
333
|
+
// Tokenize the command after `git`. Naive split — works for the calls in
|
|
334
|
+
// this repo (no shell quoting beyond simple strings).
|
|
335
|
+
const tail = cmd.replace(/^git\s+/, '').trim();
|
|
336
|
+
if (!tail) return null;
|
|
337
|
+
// If tail contains `${...}` template interpolation, leave the original
|
|
338
|
+
// string mostly intact and pass [tail-split-by-space] won't work cleanly.
|
|
339
|
+
// For simplicity: only migrate when there's no `${`.
|
|
340
|
+
if (tail.includes('${')) return null;
|
|
341
|
+
const tokens = tail.split(/\s+/).filter(Boolean);
|
|
342
|
+
const verbIdx = tokens[0] === '-C' ? 2 : 0;
|
|
343
|
+
const verb = tokens[verbIdx];
|
|
344
|
+
const verbArgs = tokens.slice(verbIdx + 1);
|
|
345
|
+
let useRead = false;
|
|
346
|
+
if (verb && !DESTRUCTIVE_GIT_VERBS.has(verb)) useRead = true;
|
|
347
|
+
else if (verb) {
|
|
348
|
+
const shape = isReadOnlyShape(verb, verbArgs);
|
|
349
|
+
if (shape === true) useRead = true;
|
|
350
|
+
}
|
|
351
|
+
const method = useRead ? 'readSync' : 'execSync';
|
|
352
|
+
const argsArrayLit = '[' + tokens.map((t) => `'${t}'`).join(', ') + ']';
|
|
353
|
+
const optsExpr = args[1] || '';
|
|
354
|
+
const newOpts = injectOperation(optsExpr, op);
|
|
355
|
+
return { newSpan: `SafeGitExecutor.${method}(${argsArrayLit}, ${newOpts})` };
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
// ─── Process a file ────────────────────────────────────────────────
|
|
359
|
+
|
|
360
|
+
function processFile(filePath) {
|
|
361
|
+
const orig = fs.readFileSync(filePath, 'utf8');
|
|
362
|
+
let content = orig;
|
|
363
|
+
const lines = content.split('\n');
|
|
364
|
+
const out = [];
|
|
365
|
+
const importsNeeded = new Set();
|
|
366
|
+
let migrated = 0;
|
|
367
|
+
let skipped = 0;
|
|
368
|
+
|
|
369
|
+
for (let i = 0; i < lines.length; i++) {
|
|
370
|
+
const line = lines[i];
|
|
371
|
+
if (MARKER_RE.test(line) && i + 1 < lines.length) {
|
|
372
|
+
const next = lines[i + 1];
|
|
373
|
+
const opLabel = `'${path.relative(ROOT, filePath)}:${i + 2}'`;
|
|
374
|
+
let transformed = null;
|
|
375
|
+
let usedTransform = null;
|
|
376
|
+
let consumedLines = 1;
|
|
377
|
+
|
|
378
|
+
// First try single-line transforms.
|
|
379
|
+
for (const t of transforms) {
|
|
380
|
+
const m = next.match(t.re);
|
|
381
|
+
if (m) {
|
|
382
|
+
const replacement = t.apply(m, opLabel);
|
|
383
|
+
transformed = next.replace(t.re, replacement);
|
|
384
|
+
usedTransform = t;
|
|
385
|
+
break;
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
// If not, try multi-line patterns via paren-balanced reader.
|
|
390
|
+
if (transformed === null) {
|
|
391
|
+
// Each pattern: a regex that matches the FULL callable name +
|
|
392
|
+
// optional whitespace + the open paren. The first capture group is
|
|
393
|
+
// text to PRESERVE before the call (e.g., a non-word leading char for
|
|
394
|
+
// bare forms). The whole regex match (m[0]) is the text we replace.
|
|
395
|
+
const patterns = [
|
|
396
|
+
{ kind: 'git', needs: 'SafeGitExecutor', re: /(^|[^.\w])(execFileSync)\s*\(/ },
|
|
397
|
+
{ kind: 'git', needs: 'SafeGitExecutor', re: /(^|[^.\w])(spawnSync)\s*\(/ },
|
|
398
|
+
{ kind: 'git-string', needs: 'SafeGitExecutor', re: /(^|[^.\w])(execSync)\s*\(/ },
|
|
399
|
+
{ kind: 'fs-rm', needs: 'SafeFsExecutor', re: /()\b(fs\.rmSync)\s*\(/ },
|
|
400
|
+
{ kind: 'fs-unlink', needs: 'SafeFsExecutor', re: /()\b(fs\.unlinkSync)\s*\(/ },
|
|
401
|
+
{ kind: 'fs-rmdir', needs: 'SafeFsExecutor', re: /()\b(fs\.rmdirSync)\s*\(/ },
|
|
402
|
+
{ kind: 'fs-unlink', needs: 'SafeFsExecutor', re: /()(require\s*\(\s*['"]fs['"]\s*\)\s*\.unlinkSync)\s*\(/ },
|
|
403
|
+
{ kind: 'fs-rm', needs: 'SafeFsExecutor', re: /()(require\s*\(\s*['"]fs['"]\s*\)\s*\.rmSync)\s*\(/ },
|
|
404
|
+
{ kind: 'fs-rm', needs: 'SafeFsExecutor', re: /(^|[^.\w])(rmSync)\s*\(/ },
|
|
405
|
+
{ kind: 'fs-unlink', needs: 'SafeFsExecutor', re: /(^|[^.\w])(unlinkSync)\s*\(/ },
|
|
406
|
+
{ kind: 'fs-rmdir', needs: 'SafeFsExecutor', re: /(^|[^.\w])(rmdirSync)\s*\(/ },
|
|
407
|
+
];
|
|
408
|
+
for (const p of patterns) {
|
|
409
|
+
const cm = next.match(p.re);
|
|
410
|
+
if (!cm) continue;
|
|
411
|
+
// The leading character (kept) is cm[1]; the callable head is cm[2].
|
|
412
|
+
const lead = cm[1] || '';
|
|
413
|
+
const callableName = cm[2];
|
|
414
|
+
const callableStart = cm.index + lead.length;
|
|
415
|
+
const openIdx = next.indexOf('(', callableStart + callableName.length - 1);
|
|
416
|
+
if (openIdx < 0) continue;
|
|
417
|
+
const balanced = readBalancedCall(lines, i + 1, openIdx);
|
|
418
|
+
if (!balanced) continue;
|
|
419
|
+
const span = balanced.span;
|
|
420
|
+
let result = null;
|
|
421
|
+
if (p.kind === 'git' || (p.name === 'spawnSync')) {
|
|
422
|
+
result = migrateExecFileSyncGit(span, opLabel);
|
|
423
|
+
} else if (p.kind === 'git-string') {
|
|
424
|
+
result = migrateExecSyncGit(span, opLabel);
|
|
425
|
+
} else if (p.kind === 'fs-rm') {
|
|
426
|
+
result = migrateFsRm(span, opLabel, 'safeRmSync');
|
|
427
|
+
} else if (p.kind === 'fs-unlink') {
|
|
428
|
+
result = migrateFsUnlink(span, opLabel);
|
|
429
|
+
} else if (p.kind === 'fs-rmdir') {
|
|
430
|
+
result = migrateFsRm(span, opLabel, 'safeRmdirSync');
|
|
431
|
+
}
|
|
432
|
+
if (!result) continue;
|
|
433
|
+
// For spawnSync the migrated form should remain spawnSync semantics
|
|
434
|
+
// through SafeGitExecutor.spawn — but spawn returns ChildProcess, not
|
|
435
|
+
// a SpawnSyncReturns. Fall back to: leave as spawn (SafeGitExecutor.spawn).
|
|
436
|
+
// For now, treat spawnSync the same as execFileSync (they both have
|
|
437
|
+
// {stdio,cwd} signatures). Callers using the return value as
|
|
438
|
+
// SpawnSyncReturns will need manual fix-up.
|
|
439
|
+
const firstLine = lines[i + 1];
|
|
440
|
+
const prefix = firstLine.slice(0, callableStart);
|
|
441
|
+
const lastLine = lines[balanced.endLine];
|
|
442
|
+
const suffix = lastLine.slice(balanced.endCol + 1);
|
|
443
|
+
transformed = prefix + result.newSpan + suffix;
|
|
444
|
+
consumedLines = balanced.endLine - i;
|
|
445
|
+
usedTransform = { needsImport: { name: p.needs, path: p.needs === 'SafeGitExecutor' ? 'src/core/SafeGitExecutor.js' : 'src/core/SafeFsExecutor.js' } };
|
|
446
|
+
break;
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
if (transformed !== null) {
|
|
451
|
+
importsNeeded.add(usedTransform.needsImport);
|
|
452
|
+
out.push(transformed);
|
|
453
|
+
i += consumedLines;
|
|
454
|
+
migrated += 1;
|
|
455
|
+
continue;
|
|
456
|
+
}
|
|
457
|
+
// unknown pattern — keep marker + line untouched
|
|
458
|
+
out.push(line);
|
|
459
|
+
skipped += 1;
|
|
460
|
+
continue;
|
|
461
|
+
}
|
|
462
|
+
out.push(line);
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
if (migrated === 0) return { migrated, skipped, changed: false };
|
|
466
|
+
|
|
467
|
+
let result = out.join('\n');
|
|
468
|
+
for (const imp of importsNeeded) {
|
|
469
|
+
result = ensureImport(result, filePath, imp.name, imp.path);
|
|
470
|
+
}
|
|
471
|
+
if (result !== orig) {
|
|
472
|
+
if (!DRY) fs.writeFileSync(filePath, result);
|
|
473
|
+
return { migrated, skipped, changed: true };
|
|
474
|
+
}
|
|
475
|
+
return { migrated, skipped, changed: false };
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
// ─── Main ──────────────────────────────────────────────────────────
|
|
479
|
+
|
|
480
|
+
const files = listMarkedFiles();
|
|
481
|
+
console.log(`Found ${files.length} files with migration markers.`);
|
|
482
|
+
|
|
483
|
+
let totalMigrated = 0;
|
|
484
|
+
let totalSkipped = 0;
|
|
485
|
+
let totalFiles = 0;
|
|
486
|
+
for (const f of files) {
|
|
487
|
+
try {
|
|
488
|
+
const r = processFile(f);
|
|
489
|
+
if (r.changed) totalFiles += 1;
|
|
490
|
+
totalMigrated += r.migrated;
|
|
491
|
+
totalSkipped += r.skipped;
|
|
492
|
+
if (r.changed || r.skipped > 0) {
|
|
493
|
+
console.log(` ${f}: migrated=${r.migrated}, skipped=${r.skipped}`);
|
|
494
|
+
}
|
|
495
|
+
} catch (err) {
|
|
496
|
+
console.error(` ${f}: ERROR ${err.message}`);
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
console.log(`\nTotal: migrated=${totalMigrated}, skipped=${totalSkipped}, files-changed=${totalFiles}`);
|
|
500
|
+
if (DRY) console.log('(dry run — no files written)');
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
import fs from 'node:fs';
|
|
10
10
|
import os from 'node:os';
|
|
11
11
|
import path from 'node:path';
|
|
12
|
+
import { SafeFsExecutor } from '../src/core/SafeFsExecutor.js';
|
|
12
13
|
|
|
13
14
|
// Create a temporary state directory
|
|
14
15
|
const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'bootstrap-relay-test-'));
|
|
@@ -85,7 +86,6 @@ try {
|
|
|
85
86
|
} finally {
|
|
86
87
|
// Cleanup
|
|
87
88
|
try {
|
|
88
|
-
|
|
89
|
-
fs.rmSync(tmpDir, { recursive: true, force: true });
|
|
89
|
+
SafeFsExecutor.safeRmSync(tmpDir, { recursive: true, force: true, operation: 'scripts/test-bootstrap-relay.mjs:89' });
|
|
90
90
|
} catch {}
|
|
91
91
|
}
|