claude-code-session-manager 0.110.0 → 0.112.0
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-plugin/marketplace.json +2 -2
- package/dist/assets/{AgentLibrary-Cm6MrOnF.js → AgentLibrary-RwPvEgqm.js} +2 -2
- package/dist/assets/{Button-CGVncJ6a.js → Button-36j3PzYv.js} +1 -1
- package/dist/assets/{DataModel-C3hlMoa8.js → DataModel-DUhANo4l.js} +1 -1
- package/dist/assets/{History-CTyfGNKn.js → History-BeZzNjmv.js} +2 -2
- package/dist/assets/{Hooks-BXxCBibx.js → Hooks-iQ8845Hp.js} +3 -3
- package/dist/assets/{Library-aCs7zxAg.js → Library-DPE1h-1L.js} +6 -6
- package/dist/assets/{ListDetail-B9Hqk1_f.js → ListDetail-PStOuQAo.js} +1 -1
- package/dist/assets/{MarkdownEditor-Djfgp32k.js → MarkdownEditor-DPw-N2-m.js} +1 -1
- package/dist/assets/{McpServers-8HQC6QgR.js → McpServers-CUyRTNep.js} +2 -2
- package/dist/assets/{Memory-c4SVE3l2.js → Memory-bZ2xjBGy.js} +3 -3
- package/dist/assets/{Panel-BEQTwE4z.js → Panel-_VZ_uXNg.js} +1 -1
- package/dist/assets/{Permissions-BaYzgZtc.js → Permissions-PPRmfNbK.js} +3 -3
- package/dist/assets/{Plugins-DnXsVau7.js → Plugins-BFcvfvlx.js} +2 -2
- package/dist/assets/{ProvenanceBadge-CT2vWps1.js → ProvenanceBadge-B1WUknak.js} +1 -1
- package/dist/assets/RemoteMachines-D5V0lzgW.js +3 -0
- package/dist/assets/{SaveBar-DwcHt3iR.js → SaveBar-Dw64FVdM.js} +1 -1
- package/dist/assets/{Scheduler-D6Gcuo0M.js → Scheduler-C8s_pJ3I.js} +9 -9
- package/dist/assets/{ScopeSwitcher-CgvWDc9Y.js → ScopeSwitcher-D-nKDMAE.js} +1 -1
- package/dist/assets/{Settings-CJoogVAB.js → Settings-CQSrR4mO.js} +4 -4
- package/dist/assets/{SkillReferenceGraph-4fq01kxq.js → SkillReferenceGraph-BbZFMHim.js} +1 -1
- package/dist/assets/{Skills-BU4ZX4h4.js → Skills-Bzyrh6EQ.js} +1 -1
- package/dist/assets/SystemPrompt-DP6i3Dx0.js +1 -0
- package/dist/assets/TagLibrary-iip0C6Bl.js +1 -0
- package/dist/assets/{TiptapBody-DVyBsfsT.js → TiptapBody-Cr-hxX8L.js} +1 -1
- package/dist/assets/Toggle-7WpPzcZH.js +1 -0
- package/dist/assets/{ViewTabs-BLHjKUv-.js → ViewTabs-9lQCRwWJ.js} +1 -1
- package/dist/assets/{historyTotals-BXDd3EzP.js → historyTotals-BrFxw5J1.js} +1 -1
- package/dist/assets/{index-CuiU3I-8.js → index-CTBpf-26.js} +250 -249
- package/dist/assets/{settingsSchema-DD4bc5cT.js → settingsSchema-Dh5Kl7VO.js} +1 -1
- package/dist/assets/{useAgentsDirWatch-DMQ_XZtr.js → useAgentsDirWatch-CMpx0d04.js} +1 -1
- package/dist/assets/{useRemotePeers-C9NfteSD.js → useRemotePeers-CI2axd-L.js} +1 -1
- package/dist/index.html +1 -1
- package/package.json +3 -2
- package/plugins/CLAUDE.md +5 -8
- package/plugins/session-manager-dev/.claude-plugin/plugin.json +3 -6
- package/plugins/session-manager-dev/skills/builder/1-classify-and-bump/SKILL.md +2 -2
- package/plugins/session-manager-dev/skills/builder/SKILL.md +2 -3
- package/plugins/session-manager-dev/skills/develop/SKILL.md +1 -1
- package/plugins/session-manager-dev/skills/develop/standards.md +3 -3
- package/scripts/README.md +3 -3
- package/scripts/audit-ops-hygiene.cjs +4 -4
- package/scripts/hooks/guard-destructive-git.cjs +4 -4
- package/scripts/hooks/guard-inline-implementation.cjs +1 -1
- package/scripts/hooks/guard-prd-writes.cjs +2 -2
- package/scripts/hooks/lib/guard-destructive-git-policy.cjs +1 -1
- package/scripts/mint-epic.cjs +2 -2
- package/scripts/scheduler-mcp-server.cjs +4 -4
- package/src/main/agentLibrary.cjs +5 -5
- package/src/main/agentsIpc.cjs +76 -0
- package/src/main/build-info.json +4 -4
- package/src/main/chatRunner.cjs +12 -12
- package/src/main/config.cjs +2 -2
- package/src/main/crashDiagnostics.cjs +2 -2
- package/src/main/docEdit.cjs +5 -5
- package/src/main/files.cjs +2 -2
- package/src/main/git.cjs +1 -1
- package/src/main/health.cjs +20 -18
- package/src/main/heapSnapshot.cjs +1 -1
- package/src/main/historyAggregator.cjs +2 -2
- package/src/main/index.cjs +44 -132
- package/src/main/ipcSchemas.cjs +10 -10
- package/src/main/lib/CLAUDE.md +48 -0
- package/src/main/lib/activeSessions.cjs +1 -1
- package/src/main/lib/classifyPromptTicket.cjs +2 -2
- package/src/main/lib/{agentModelResolve.cjs → claude/agentModelResolve.cjs} +7 -7
- package/src/main/lib/{claudeBin.cjs → claude/claudeBin.cjs} +4 -4
- package/src/main/lib/{effectiveModelInfo.cjs → claude/effectiveModelInfo.cjs} +9 -9
- package/src/main/lib/{modelCatalog.cjs → claude/modelCatalog.cjs} +3 -3
- package/src/main/lib/{rateLimitDetect.cjs → claude/rateLimitDetect.cjs} +1 -1
- package/src/main/lib/{rateLimitWindow.cjs → claude/rateLimitWindow.cjs} +1 -1
- package/src/main/lib/{runClaudeP.cjs → claude/runClaudeP.cjs} +1 -1
- package/src/main/lib/credentials.cjs +3 -3
- package/src/main/lib/cwdClassify.cjs +1 -1
- package/src/main/lib/{activeIndexMerge.cjs → epic/activeIndexMerge.cjs} +3 -3
- package/src/main/lib/{activeIndexRebuild.cjs → epic/activeIndexRebuild.cjs} +1 -1
- package/src/main/lib/{delegationReadiness.cjs → epic/delegationReadiness.cjs} +21 -29
- package/src/main/lib/{epicContextDigest.cjs → epic/epicContextDigest.cjs} +1 -1
- package/src/main/lib/{epicDelegationStats.cjs → epic/epicDelegationStats.cjs} +2 -2
- package/src/main/lib/{epicMint.cjs → epic/epicMint.cjs} +11 -11
- package/src/main/lib/{epicSpawnPlan.cjs → epic/epicSpawnPlan.cjs} +3 -3
- package/src/main/lib/{epicStatusMirror.cjs → epic/epicStatusMirror.cjs} +2 -2
- package/src/main/lib/{epicTranscriptDiagnostic.cjs → epic/epicTranscriptDiagnostic.cjs} +2 -2
- package/src/main/lib/{epicTranscriptPath.cjs → epic/epicTranscriptPath.cjs} +2 -2
- package/src/main/lib/{epicValidationHook.cjs → epic/epicValidationHook.cjs} +3 -3
- package/src/main/lib/{epicWorktreeBoot.cjs → epic/epicWorktreeBoot.cjs} +1 -1
- package/src/main/lib/{epicWorktreeMerge.cjs → epic/epicWorktreeMerge.cjs} +3 -3
- package/src/main/lib/{epicWorktreeMint.cjs → epic/epicWorktreeMint.cjs} +3 -3
- package/src/main/lib/{epicWorktreeProjectConfig.cjs → epic/epicWorktreeProjectConfig.cjs} +4 -4
- package/src/main/lib/{promptSessionsCreateEpic.cjs → epic/promptSessionsCreateEpic.cjs} +4 -4
- package/src/main/lib/{crossProjectFeedback.cjs → feedback-remote/crossProjectFeedback.cjs} +7 -7
- package/src/main/lib/{customerFeedbackClient.cjs → feedback-remote/customerFeedbackClient.cjs} +3 -3
- package/src/main/lib/{customerFeedbackInbox.cjs → feedback-remote/customerFeedbackInbox.cjs} +2 -2
- package/src/main/lib/{customerFeedbackIpc.cjs → feedback-remote/customerFeedbackIpc.cjs} +1 -1
- package/src/main/lib/{localAdminHttp.cjs → feedback-remote/localAdminHttp.cjs} +2 -2
- package/src/main/lib/{macroAdminRoutes.cjs → feedback-remote/macroAdminRoutes.cjs} +1 -1
- package/src/main/lib/{projectHomeAdminRoutes.cjs → feedback-remote/projectHomeAdminRoutes.cjs} +4 -4
- package/src/main/lib/{relayClientAuth.cjs → feedback-remote/relayClientAuth.cjs} +2 -2
- package/src/main/lib/{remoteClientSessions.cjs → feedback-remote/remoteClientSessions.cjs} +1 -1
- package/src/main/lib/{gitWorktree.cjs → git/gitWorktree.cjs} +7 -7
- package/src/main/lib/historyRollup.cjs +1 -1
- package/src/main/lib/importReferences.cjs +1 -1
- package/src/main/lib/machineProfile.cjs +1 -1
- package/src/main/lib/openExternalApp.cjs +1 -1
- package/src/main/lib/opsOwnership.cjs +3 -3
- package/src/main/lib/{agentPersonaSchema.cjs → persona-macro/agentPersonaSchema.cjs} +2 -2
- package/src/main/lib/{builtinMacros.cjs → persona-macro/builtinMacros.cjs} +2 -2
- package/src/main/lib/{macroLibrary.cjs → persona-macro/macroLibrary.cjs} +5 -5
- package/src/main/lib/{personaMerge.cjs → persona-macro/personaMerge.cjs} +4 -4
- package/src/main/lib/{shippedPersonaSeeds.cjs → persona-macro/shippedPersonaSeeds.cjs} +11 -0
- package/src/main/lib/{prdAdminRoutes.cjs → prd/prdAdminRoutes.cjs} +7 -7
- package/src/main/lib/{prdAgentType.cjs → prd/prdAgentType.cjs} +3 -3
- package/src/main/lib/{prdCreate.cjs → prd/prdCreate.cjs} +12 -12
- package/src/main/lib/{prdDeclaredPaths.cjs → prd/prdDeclaredPaths.cjs} +1 -1
- package/src/main/lib/{prdGateFiles.cjs → prd/prdGateFiles.cjs} +1 -1
- package/src/main/lib/{prdLocations.cjs → prd/prdLocations.cjs} +2 -2
- package/src/main/lib/{prdMigration.cjs → prd/prdMigration.cjs} +3 -3
- package/src/main/lib/prereqs.cjs +2 -2
- package/src/main/lib/{instanceLock.cjs → process/instanceLock.cjs} +4 -11
- package/src/main/lib/{pidAlive.cjs → process/pidAlive.cjs} +1 -1
- package/src/main/lib/{procName.cjs → process/procName.cjs} +2 -2
- package/src/main/lib/{timeoutShim.cjs → process/timeoutShim.cjs} +1 -1
- package/src/main/lib/projectRootResolve.cjs +1 -1
- package/src/main/lib/promptSessionSchema.cjs +1 -1
- package/src/main/lib/{definitionOfDone.cjs → scheduler/definitionOfDone.cjs} +6 -12
- package/src/main/lib/{fixChainDepth.cjs → scheduler/fixChainDepth.cjs} +1 -1
- package/src/main/lib/{jobDirtFilter.cjs → scheduler/jobDirtFilter.cjs} +1 -1
- package/src/main/lib/{jobSupervisorRecord.cjs → scheduler/jobSupervisorRecord.cjs} +1 -1
- package/src/main/lib/{launchFailure.cjs → scheduler/launchFailure.cjs} +2 -2
- package/src/main/lib/{queueStore.cjs → scheduler/queueStore.cjs} +6 -6
- package/src/main/lib/{quietMachineLease.cjs → scheduler/quietMachineLease.cjs} +1 -1
- package/src/main/lib/{rcaReport.cjs → scheduler/rcaReport.cjs} +4 -4
- package/src/main/lib/{reaperHelpers.cjs → scheduler/reaperHelpers.cjs} +3 -3
- package/src/main/lib/{reservationExpiry.cjs → scheduler/reservationExpiry.cjs} +4 -11
- package/src/main/lib/{reviewNotice.cjs → scheduler/reviewNotice.cjs} +1 -1
- package/src/main/lib/{scheduleJobTransitions.cjs → scheduler/scheduleJobTransitions.cjs} +3 -3
- package/src/main/lib/{schedulerBatch.cjs → scheduler/schedulerBatch.cjs} +2 -2
- package/src/main/lib/{schedulerConfig.cjs → scheduler/schedulerConfig.cjs} +1 -1
- package/src/main/lib/{schedulerRuntimeState.cjs → scheduler/schedulerRuntimeState.cjs} +1 -1
- package/src/main/lib/{sessionSlots.cjs → scheduler/sessionSlots.cjs} +2 -2
- package/src/main/lib/{upgradeDrain.cjs → scheduler/upgradeDrain.cjs} +8 -11
- package/src/main/lib/{watchdogHelpers.cjs → scheduler/watchdogHelpers.cjs} +5 -19
- package/src/main/lib/{auditLog.cjs → telemetry/auditLog.cjs} +1 -1
- package/src/main/lib/{opsErrorLog.cjs → telemetry/opsErrorLog.cjs} +4 -4
- package/src/main/lib/{telemetryBacklog.cjs → telemetry/telemetryBacklog.cjs} +4 -4
- package/src/main/lib/{telemetryBoot.cjs → telemetry/telemetryBoot.cjs} +1 -1
- package/src/main/lib/{telemetryClient.cjs → telemetry/telemetryClient.cjs} +4 -4
- package/src/main/lib/{telemetrySettings.cjs → telemetry/telemetrySettings.cjs} +1 -1
- package/src/main/logs.cjs +1 -1
- package/src/main/mcpStatus.cjs +2 -2
- package/src/main/memoryAggregate.cjs +3 -3
- package/src/main/memoryTool.cjs +1 -1
- package/src/main/otel.cjs +2 -2
- package/src/main/pluginInstall.cjs +29 -3
- package/src/main/projectBrief.cjs +6 -6
- package/src/main/projectPages.cjs +1 -1
- package/src/main/promptSessionEvents.cjs +2 -2
- package/src/main/pty.cjs +7 -7
- package/src/main/queueOps.cjs +6 -6
- package/src/main/remoteClient.cjs +4 -4
- package/src/main/remoteClientIpc.cjs +1 -1
- package/src/main/runVerify.cjs +1 -1
- package/src/main/scheduler/CLAUDE.md +26 -0
- package/src/main/scheduler/budget.cjs +576 -0
- package/src/main/scheduler/gitTreeGuard.cjs +672 -0
- package/src/main/scheduler/prdParser.cjs +4 -4
- package/src/main/scheduler/prdPaths.cjs +487 -0
- package/src/main/scheduler/reviewLadder.cjs +1011 -0
- package/src/main/scheduler/starvation.cjs +390 -0
- package/src/main/scheduler.cjs +289 -3311
- package/src/main/seedAgentPersonas.cjs +5 -5
- package/src/main/seedDevPlugin.cjs +70 -3
- package/src/main/seedSchedulerMcp.cjs +2 -2
- package/src/main/supervisor.cjs +5 -5
- package/src/main/telemetryIpc.cjs +51 -0
- package/src/main/transcripts.cjs +3 -3
- package/src/main/updaterIpc.cjs +1 -1
- package/src/main/usage.cjs +1 -1
- package/src/main/watchers.cjs +1 -1
- package/src/main/webRemote.cjs +7 -7
- package/src/preload/api.d.ts +8 -8
- package/src/preload/index.cjs +3 -3
- package/src/seed/agents/demo-video-builder.md +62 -19
- package/dist/assets/RemoteMachines-DHJZfdJC.js +0 -3
- package/dist/assets/SystemPrompt-BCEyMSEq.js +0 -1
- package/dist/assets/TagLibrary-m3It8Oal.js +0 -1
- package/dist/assets/Toggle-In_AExPV.js +0 -1
- package/plugins/session-manager-dev/skills/blog-for-project-feature/0-select/SKILL.md +0 -39
- package/plugins/session-manager-dev/skills/blog-for-project-feature/1-research/SKILL.md +0 -37
- package/plugins/session-manager-dev/skills/blog-for-project-feature/2-storyboard/SKILL.md +0 -64
- package/plugins/session-manager-dev/skills/blog-for-project-feature/3-capture/SKILL.md +0 -52
- package/plugins/session-manager-dev/skills/blog-for-project-feature/4-draft-copy/SKILL.md +0 -37
- package/plugins/session-manager-dev/skills/blog-for-project-feature/5-illustrate/SKILL.md +0 -50
- package/plugins/session-manager-dev/skills/blog-for-project-feature/6-compose/SKILL.md +0 -51
- package/plugins/session-manager-dev/skills/blog-for-project-feature/7-review/SKILL.md +0 -54
- package/plugins/session-manager-dev/skills/blog-for-project-feature/SKILL.md +0 -144
- package/plugins/session-manager-dev/skills/blog-for-project-feature/feature.config.yaml +0 -90
- package/plugins/session-manager-dev/skills/discover-features/SKILL.md +0 -95
- package/plugins/session-manager-dev/skills/explain-to-me/SKILL.md +0 -205
- package/plugins/session-manager-dev/skills/explain-to-me/assets/style-reference.html +0 -163
- package/plugins/session-manager-dev/skills/find-opportunity/SKILL.md +0 -83
- package/plugins/session-manager-dev/skills/issue-address/0-select/0-fetch-pool/SKILL.md +0 -38
- package/plugins/session-manager-dev/skills/issue-address/0-select/1-reject-fixed/SKILL.md +0 -64
- package/plugins/session-manager-dev/skills/issue-address/0-select/2-reject-claimed/SKILL.md +0 -71
- package/plugins/session-manager-dev/skills/issue-address/0-select/3-rank-impact/SKILL.md +0 -39
- package/plugins/session-manager-dev/skills/issue-address/0-select/SKILL.md +0 -75
- package/plugins/session-manager-dev/skills/issue-address/1-confirm-open/SKILL.md +0 -39
- package/plugins/session-manager-dev/skills/issue-address/2-claim/SKILL.md +0 -57
- package/plugins/session-manager-dev/skills/issue-address/3-reproduce/SKILL.md +0 -40
- package/plugins/session-manager-dev/skills/issue-address/4-fix/SKILL.md +0 -33
- package/plugins/session-manager-dev/skills/issue-address/5-verify/SKILL.md +0 -40
- package/plugins/session-manager-dev/skills/issue-address/SKILL.md +0 -120
- package/plugins/session-manager-dev/skills/local-project-health/SKILL.md +0 -58
- package/plugins/session-manager-dev/skills/memory-sanitation/SKILL.md +0 -147
- package/plugins/session-manager-dev/skills/ops-sweep/SKILL.md +0 -137
- package/plugins/session-manager-dev/skills/pr-review-sweep/0-fetch/SKILL.md +0 -41
- package/plugins/session-manager-dev/skills/pr-review-sweep/1-classify/SKILL.md +0 -56
- package/plugins/session-manager-dev/skills/pr-review-sweep/2-check-fixed/SKILL.md +0 -49
- package/plugins/session-manager-dev/skills/pr-review-sweep/3-queue/SKILL.md +0 -57
- package/plugins/session-manager-dev/skills/pr-review-sweep/4-land-and-resolve/SKILL.md +0 -60
- package/plugins/session-manager-dev/skills/pr-review-sweep/SKILL.md +0 -124
- package/plugins/session-manager-dev/skills/pr-signal/SKILL.md +0 -67
- package/plugins/session-manager-dev/skills/project-status/SKILL.md +0 -243
- package/plugins/session-manager-dev/skills/requesting-code-review/SKILL.md +0 -98
- package/plugins/session-manager-dev/skills/requesting-code-review/code-reviewer.md +0 -146
- /package/src/main/lib/{agentEffortResolve.cjs → claude/agentEffortResolve.cjs} +0 -0
- /package/src/main/lib/{claudeCliCaps.cjs → claude/claudeCliCaps.cjs} +0 -0
- /package/src/main/lib/{usageCircuit.cjs → claude/usageCircuit.cjs} +0 -0
- /package/src/main/lib/{epicSpawnCwd.cjs → epic/epicSpawnCwd.cjs} +0 -0
- /package/src/main/lib/{customerFeedbackAdminRoutes.cjs → feedback-remote/customerFeedbackAdminRoutes.cjs} +0 -0
- /package/src/main/lib/{remoteE2eCrypto.cjs → feedback-remote/remoteE2eCrypto.cjs} +0 -0
- /package/src/main/lib/{branchSweep.cjs → git/branchSweep.cjs} +0 -0
- /package/src/main/lib/{gitExec.cjs → git/gitExec.cjs} +0 -0
- /package/src/main/lib/{jobWorktree.cjs → git/jobWorktree.cjs} +0 -0
- /package/src/main/lib/{jobWorktreeBootLive.cjs → git/jobWorktreeBootLive.cjs} +0 -0
- /package/src/main/lib/{jobWorktreeTerminalOrphanLive.cjs → git/jobWorktreeTerminalOrphanLive.cjs} +0 -0
- /package/src/main/lib/{personaImportHealth.cjs → persona-macro/personaImportHealth.cjs} +0 -0
- /package/src/main/lib/{depSlugResolve.cjs → prd/depSlugResolve.cjs} +0 -0
- /package/src/main/lib/{planValidator.cjs → prd/planValidator.cjs} +0 -0
- /package/src/main/lib/{prdAuthoringSeed.cjs → prd/prdAuthoringSeed.cjs} +0 -0
- /package/src/main/lib/{prdDisposition.cjs → prd/prdDisposition.cjs} +0 -0
- /package/src/main/lib/{prdFrontmatter.cjs → prd/prdFrontmatter.cjs} +0 -0
- /package/src/main/lib/{prdSizing.cjs → prd/prdSizing.cjs} +0 -0
- /package/src/main/lib/{workTypeLibrary.cjs → prd/workTypeLibrary.cjs} +0 -0
- /package/src/main/lib/{childWithLog.cjs → process/childWithLog.cjs} +0 -0
- /package/src/main/lib/{cleanEnv.cjs → process/cleanEnv.cjs} +0 -0
- /package/src/main/lib/{defaultShell.cjs → process/defaultShell.cjs} +0 -0
- /package/src/main/lib/{killTree.cjs → process/killTree.cjs} +0 -0
- /package/src/main/lib/{loginShellPath.cjs → process/loginShellPath.cjs} +0 -0
- /package/src/main/lib/{procIdentity.cjs → process/procIdentity.cjs} +0 -0
- /package/src/main/lib/{singleInstanceGuard.cjs → process/singleInstanceGuard.cjs} +0 -0
- /package/src/main/lib/{smProcNames.cjs → process/smProcNames.cjs} +0 -0
- /package/src/main/lib/{timeoutShimScript.cjs → process/timeoutShimScript.cjs} +0 -0
- /package/src/main/lib/{winSpawn.cjs → process/winSpawn.cjs} +0 -0
- /package/src/main/lib/{adoptedRunSupervisor.cjs → scheduler/adoptedRunSupervisor.cjs} +0 -0
- /package/src/main/lib/{dispatchLoop.cjs → scheduler/dispatchLoop.cjs} +0 -0
- /package/src/main/lib/{dodDrainHook.cjs → scheduler/dodDrainHook.cjs} +0 -0
- /package/src/main/lib/{fixPlanSlug.cjs → scheduler/fixPlanSlug.cjs} +0 -0
- /package/src/main/lib/{gateAuthority.cjs → scheduler/gateAuthority.cjs} +0 -0
- /package/src/main/lib/{landedSinceRun.cjs → scheduler/landedSinceRun.cjs} +0 -0
- /package/src/main/lib/{loadGate.cjs → scheduler/loadGate.cjs} +0 -0
- /package/src/main/lib/{needsReviewLedger.cjs → scheduler/needsReviewLedger.cjs} +0 -0
- /package/src/main/lib/{queueHealth.cjs → scheduler/queueHealth.cjs} +0 -0
- /package/src/main/lib/{queueHistory.cjs → scheduler/queueHistory.cjs} +0 -0
- /package/src/main/lib/{runLogRetention.cjs → scheduler/runLogRetention.cjs} +0 -0
- /package/src/main/lib/{scheduleJobSchema.cjs → scheduler/scheduleJobSchema.cjs} +0 -0
- /package/src/main/lib/{schedulerPaths.cjs → scheduler/schedulerPaths.cjs} +0 -0
- /package/src/main/lib/{terminalRunOutcome.cjs → scheduler/terminalRunOutcome.cjs} +0 -0
- /package/src/main/lib/{validationSentinels.cjs → scheduler/validationSentinels.cjs} +0 -0
- /package/src/main/lib/{crashTelemetry.cjs → telemetry/crashTelemetry.cjs} +0 -0
- /package/src/main/lib/{otlpTraceExporter.cjs → telemetry/otlpTraceExporter.cjs} +0 -0
- /package/src/main/lib/{telemetryConsent.cjs → telemetry/telemetryConsent.cjs} +0 -0
- /package/src/main/lib/{telemetryCounters.cjs → telemetry/telemetryCounters.cjs} +0 -0
- /package/src/main/lib/{atomicFs.cjs → util/atomicFs.cjs} +0 -0
- /package/src/main/lib/{encodeCwd.cjs → util/encodeCwd.cjs} +0 -0
- /package/src/main/lib/{expandHome.cjs → util/expandHome.cjs} +0 -0
- /package/src/main/lib/{extractJson.cjs → util/extractJson.cjs} +0 -0
- /package/src/main/lib/{fileTail.cjs → util/fileTail.cjs} +0 -0
- /package/src/main/lib/{headTailBuffer.cjs → util/headTailBuffer.cjs} +0 -0
- /package/src/main/lib/{kebabCase.cjs → util/kebabCase.cjs} +0 -0
- /package/src/main/lib/{loopDelay.cjs → util/loopDelay.cjs} +0 -0
- /package/src/main/lib/{lruCache.cjs → util/lruCache.cjs} +0 -0
- /package/src/main/lib/{withTimeout.cjs → util/withTimeout.cjs} +0 -0
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# src/main/lib/ — scoped context
|
|
2
|
+
|
|
3
|
+
Shared main-process helpers (CommonJS `.cjs`). Layout source of truth: `scripts/lib-layout.json`.
|
|
4
|
+
|
|
5
|
+
## What's here
|
|
6
|
+
|
|
7
|
+
- `claude/` — claude CLI binary, caps, model/effort resolution.
|
|
8
|
+
- `epic/` — Epic mint, worktrees, active index, spawn plan/cwd, transcripts.
|
|
9
|
+
- `feedback-remote/` — cross-project and customer feedback conduits.
|
|
10
|
+
- `git/` — git exec, worktrees, branch sweeps, job worktrees.
|
|
11
|
+
- `persona-macro/` — agent persona schema/merge, macro library, builtin macros.
|
|
12
|
+
- `prd/` — PRD parsing helpers, admin routes, dep-slug resolution, plan validation.
|
|
13
|
+
- `process/` — child processes, kill tree, env cleaning, pid liveness, instance lock.
|
|
14
|
+
- `scheduler/` — dispatch loop, session slots, gates, supervisors, queue helpers.
|
|
15
|
+
- `telemetry/` — audit/ops error logs, crash and OTLP telemetry.
|
|
16
|
+
- `util/` — generic pure helpers (atomic fs, kebab, home/cwd encoding, JSON extract, tail).
|
|
17
|
+
- top-level files — cross-cutting modules that fit no domain (`opsOwnership`, `activeSessions`, `projectRootResolve`, `cwdClassify`).
|
|
18
|
+
- `__tests__/` — tests for top-level modules; subfolders carry their own.
|
|
19
|
+
|
|
20
|
+
## Where a new module goes
|
|
21
|
+
|
|
22
|
+
Put it in the subfolder whose domain it serves; pure and domain-free goes in `util/`.
|
|
23
|
+
A new top-level `lib/` module needs a stated reason (no domain fits) in its header comment,
|
|
24
|
+
and a `scripts/lib-layout.json` entry. Never add a subfolder for one file.
|
|
25
|
+
|
|
26
|
+
## Reuse before writing
|
|
27
|
+
|
|
28
|
+
Each of these was found duplicated once. Grep first; extend the canonical one.
|
|
29
|
+
|
|
30
|
+
| Need | Canonical | Function |
|
|
31
|
+
| --- | --- | --- |
|
|
32
|
+
| Atomic write (tmp+rename) | `util/atomicFs.cjs` | `writeTextAtomic[Sync]`, `writeJsonAtomic[Sync]` |
|
|
33
|
+
| JSON read with fallback | `util/atomicFs.cjs` | `readJsonOr`, `readJsonOrSync` |
|
|
34
|
+
| PID liveness | `process/pidAlive.cjs` | `pidAlive` |
|
|
35
|
+
| Kebab / slug | `util/kebabCase.cjs` | `kebabCase` |
|
|
36
|
+
| Project root, read-only/total (never throws) | `activeSessions.cjs` | `projectRootOf` |
|
|
37
|
+
| Project root, validated; `opsInternal:'refuse'` for writers | `opsOwnership.cjs` | `resolveProjectRoot` |
|
|
38
|
+
| Project root + Epic from session/epic hints | `projectRootResolve.cjs` | `resolveProjectContext` |
|
|
39
|
+
| Ops-root path (single-writer law) | `opsOwnership.cjs` | `opsPath` |
|
|
40
|
+
| Run git | `git/gitExec.cjs` | `execGit` |
|
|
41
|
+
| Spawn `claude -p` (only machine-wide cap) | `scheduler/sessionSlots.cjs` | `acquire`, `release` |
|
|
42
|
+
|
|
43
|
+
Pin `--model` on every `claude -p` spawn.
|
|
44
|
+
|
|
45
|
+
## What must NOT be assumed
|
|
46
|
+
|
|
47
|
+
- Never `path.join` an agent cwd to build an ops path — use `opsPath`.
|
|
48
|
+
- No private process caps, no hand-rolled tmp+rename, no new `JSON.parse(readFileSync)` fallbacks.
|
|
@@ -12,7 +12,7 @@ const fs = require('node:fs');
|
|
|
12
12
|
const fsp = require('node:fs/promises');
|
|
13
13
|
const os = require('node:os');
|
|
14
14
|
const path = require('node:path');
|
|
15
|
-
const { KIND_CONFIG: WORKTREE_KIND_CONFIG } = require('./gitWorktree.cjs');
|
|
15
|
+
const { KIND_CONFIG: WORKTREE_KIND_CONFIG } = require('./git/gitWorktree.cjs');
|
|
16
16
|
const { OPS_ROOT_DIR } = require('./opsOwnership.cjs');
|
|
17
17
|
const { classifyCwd, worktreeMainRootOf } = require('./cwdClassify.cjs');
|
|
18
18
|
|
|
@@ -16,8 +16,8 @@
|
|
|
16
16
|
*/
|
|
17
17
|
|
|
18
18
|
const { spawn } = require('node:child_process');
|
|
19
|
-
const { resolveClaudeBin, claudeSpawnTarget } = require('./claudeBin.cjs');
|
|
20
|
-
const { cleanChildEnv, pathWithUserBins } = require('./cleanEnv.cjs');
|
|
19
|
+
const { resolveClaudeBin, claudeSpawnTarget } = require('./claude/claudeBin.cjs');
|
|
20
|
+
const { cleanChildEnv, pathWithUserBins } = require('./process/cleanEnv.cjs');
|
|
21
21
|
|
|
22
22
|
const CLASSIFY_TIMEOUT_MS = 30_000;
|
|
23
23
|
const CLASSIFY_MODEL = 'sonnet';
|
|
@@ -29,10 +29,10 @@
|
|
|
29
29
|
|
|
30
30
|
const path = require('node:path');
|
|
31
31
|
const os = require('node:os');
|
|
32
|
-
const { splitFrontmatter } = require('
|
|
33
|
-
const { readActiveIndex, resolvePersonaPaths } = require('
|
|
34
|
-
const { resolveMergedPersona, PERSONA_NAME_RE } = require('
|
|
35
|
-
const configMgr = require('
|
|
32
|
+
const { splitFrontmatter } = require('../prd/prdFrontmatter.cjs');
|
|
33
|
+
const { readActiveIndex, resolvePersonaPaths } = require('../epic/epicMint.cjs');
|
|
34
|
+
const { resolveMergedPersona, PERSONA_NAME_RE } = require('../persona-macro/personaMerge.cjs');
|
|
35
|
+
const configMgr = require('../../config.cjs');
|
|
36
36
|
|
|
37
37
|
/** The hardcoded floor every branch of resolveEpicModel falls back to — --model must never be omitted (CLAUDE.md "Automation model pinning"). */
|
|
38
38
|
const FALLBACK_MODEL = 'sonnet';
|
|
@@ -55,7 +55,7 @@ function logDanglingPersonaOnce(cwd, agentType) {
|
|
|
55
55
|
// Required lazily: opsErrorLog.cjs is a leaf module with no Electron
|
|
56
56
|
// dependency, but keeping this require inside the miss path avoids
|
|
57
57
|
// paying for it on the (overwhelmingly common) hit path.
|
|
58
|
-
const { appendError } = require('
|
|
58
|
+
const { appendError } = require('../telemetry/opsErrorLog.cjs');
|
|
59
59
|
appendError({
|
|
60
60
|
cwd,
|
|
61
61
|
scope: 'agentModelResolve',
|
|
@@ -218,10 +218,10 @@ async function resolvePrdPersonaForSpawn({ cwd, agentType, fallbackModel = FALLB
|
|
|
218
218
|
const miss = { model: fallbackModel, systemPrompt: null, personaPath: null };
|
|
219
219
|
if (!agentType) return miss;
|
|
220
220
|
try {
|
|
221
|
-
const getBody = deps.getPersonaBody || require('
|
|
221
|
+
const getBody = deps.getPersonaBody || require('../../agentLibrary.cjs').getPersonaBody;
|
|
222
222
|
const persona = await getBody({ cwd, name: agentType });
|
|
223
223
|
if (!persona) {
|
|
224
|
-
const reportOnce = deps.reportDanglingAgentTypeOnce || require('
|
|
224
|
+
const reportOnce = deps.reportDanglingAgentTypeOnce || require('../prd/prdAgentType.cjs').reportDanglingAgentTypeOnce;
|
|
225
225
|
reportOnce(cwd, agentType, deps);
|
|
226
226
|
return miss;
|
|
227
227
|
}
|
|
@@ -68,7 +68,7 @@ function __resetForTests() { cached = null; }
|
|
|
68
68
|
//
|
|
69
69
|
// Every `claude` spawn goes through claudeSpawnTarget so GNOME System Monitor
|
|
70
70
|
// shows a distinct comm per role (sm-claude-job / -chat / -aux) and a labelled
|
|
71
|
-
// argv0. See lib/procName.cjs for the mechanics. Invariants:
|
|
71
|
+
// argv0. See lib/process/procName.cjs for the mechanics. Invariants:
|
|
72
72
|
// - SM_CLAUDE_BIN set → aliasing SKIPPED, raw value used verbatim (tests point
|
|
73
73
|
// it at self-locating stubs; it must stay ONE binary, no path splitting).
|
|
74
74
|
// - aliasBinFor fails open (returns realBin) → no argv0 is set either, so the
|
|
@@ -92,7 +92,7 @@ function claudeSpawnTarget(role, detail, realBin = resolveClaudeBin(), args = []
|
|
|
92
92
|
const platform = winOpts.platform || process.platform;
|
|
93
93
|
if (platform !== 'win32' || !/\.(cmd|bat)$/i.test(base.command)) return base;
|
|
94
94
|
// Node refuses to spawn a .cmd/.bat without a shell (EINVAL) — wrap in cmd.exe argv.
|
|
95
|
-
const { resolveSpawn } = require('
|
|
95
|
+
const { resolveSpawn } = require('../process/winSpawn.cjs');
|
|
96
96
|
const wrapped = resolveSpawn(base.command, args, { platform, ...(winOpts.env ? { env: winOpts.env } : {}), ...(winOpts.exists ? { exists: winOpts.exists } : {}) });
|
|
97
97
|
return { ...base, ...wrapped };
|
|
98
98
|
}
|
|
@@ -102,7 +102,7 @@ function baseSpawnTarget(role, detail, realBin) {
|
|
|
102
102
|
const alias = ROLE_ALIASES[role];
|
|
103
103
|
if (!alias) return { command: realBin };
|
|
104
104
|
try {
|
|
105
|
-
const { aliasBinFor, smArgv0 } = require('
|
|
105
|
+
const { aliasBinFor, smArgv0 } = require('../process/procName.cjs');
|
|
106
106
|
const command = aliasBinFor(realBin, alias);
|
|
107
107
|
if (command === realBin) return { command: realBin };
|
|
108
108
|
return { command, argv0: smArgv0(role, detail) };
|
|
@@ -114,7 +114,7 @@ function baseSpawnTarget(role, detail, realBin) {
|
|
|
114
114
|
// ---------- version probe ----------
|
|
115
115
|
//
|
|
116
116
|
// `claude --version`, cached. The scheduler's launch circuit breaker
|
|
117
|
-
// (lib/launchFailure.cjs) records the CLI version a launch block was armed
|
|
117
|
+
// (lib/scheduler/launchFailure.cjs) records the CLI version a launch block was armed
|
|
118
118
|
// under and drops the block the moment the version changes — the incident
|
|
119
119
|
// behind it (issue #11: an outdated CLI sending a thinking parameter the
|
|
120
120
|
// model rejects) is fixed by `claude update`, and the queue must notice
|
|
@@ -26,9 +26,9 @@
|
|
|
26
26
|
const fs = require('node:fs');
|
|
27
27
|
const path = require('node:path');
|
|
28
28
|
const os = require('node:os');
|
|
29
|
-
const { splitFrontmatter } = require('
|
|
30
|
-
const { resolveEpicTranscriptPath } = require('
|
|
31
|
-
const schedulerPaths = require('
|
|
29
|
+
const { splitFrontmatter } = require('../prd/prdFrontmatter.cjs');
|
|
30
|
+
const { resolveEpicTranscriptPath } = require('../epic/epicTranscriptPath.cjs');
|
|
31
|
+
const schedulerPaths = require('../scheduler/schedulerPaths.cjs');
|
|
32
32
|
|
|
33
33
|
// Deliberately stays a FIXED alias set (reviewed against the catalog-driven raw picker): it answers
|
|
34
34
|
// "alias vs concrete id", not "which options to offer", so live catalog ids must not enter it.
|
|
@@ -70,7 +70,7 @@ function isConcreteModelId(modelAlias) {
|
|
|
70
70
|
*/
|
|
71
71
|
function computeEffortEnvReachable(deps) {
|
|
72
72
|
try {
|
|
73
|
-
const { cleanChildEnv } = deps.cleanEnv || require('
|
|
73
|
+
const { cleanChildEnv } = deps.cleanEnv || require('../process/cleanEnv.cjs');
|
|
74
74
|
const probe = cleanChildEnv({ CLAUDE_EFFORT: 'high', CLAUDE_CODE_EFFORT_LEVEL: 'high' });
|
|
75
75
|
return Boolean(probe.CLAUDE_EFFORT || probe.CLAUDE_CODE_EFFORT_LEVEL);
|
|
76
76
|
} catch {
|
|
@@ -93,7 +93,7 @@ function computeEffortEnvReachable(deps) {
|
|
|
93
93
|
* for the same dangling reference.
|
|
94
94
|
*/
|
|
95
95
|
async function resolvePersonaModelAlias(cwd, agentType, deps) {
|
|
96
|
-
const getPersonaBody = deps.getPersonaBody || require('
|
|
96
|
+
const getPersonaBody = deps.getPersonaBody || require('../../agentLibrary.cjs').getPersonaBody;
|
|
97
97
|
// The overlay-vs-global provenance question itself ("which of
|
|
98
98
|
// resolvePersonaPaths' two candidates won") is answered by
|
|
99
99
|
// agentModelResolve.cjs's isProjectOverlayPersonaPath, not re-derived here
|
|
@@ -125,7 +125,7 @@ async function resolvePersonaModelAlias(cwd, agentType, deps) {
|
|
|
125
125
|
|
|
126
126
|
/** Best-effort read of `<cwd>/session-manager-operations/scheduler/state/queue.json`'s hot jobs[]. */
|
|
127
127
|
function readHotJobsForCwd(cwd, deps) {
|
|
128
|
-
const { projectQueuePath } = deps.queueStore || require('
|
|
128
|
+
const { projectQueuePath } = deps.queueStore || require('../scheduler/queueStore.cjs');
|
|
129
129
|
try {
|
|
130
130
|
const data = JSON.parse(fs.readFileSync(projectQueuePath(cwd), 'utf8'));
|
|
131
131
|
return Array.isArray(data.jobs) ? data.jobs : [];
|
|
@@ -136,7 +136,7 @@ function readHotJobsForCwd(cwd, deps) {
|
|
|
136
136
|
|
|
137
137
|
/** Best-effort read of `<cwd>/session-manager-operations/scheduler/state/history.jsonl`'s archived rows. */
|
|
138
138
|
function readHistoryEntriesForCwd(cwd, deps) {
|
|
139
|
-
const { projectHistoryPath } = deps.queueStore || require('
|
|
139
|
+
const { projectHistoryPath } = deps.queueStore || require('../scheduler/queueStore.cjs');
|
|
140
140
|
let text;
|
|
141
141
|
try {
|
|
142
142
|
text = fs.readFileSync(projectHistoryPath(cwd), 'utf8');
|
|
@@ -246,7 +246,7 @@ function findLatestSchedulerModel(cwd, agentType, deps) {
|
|
|
246
246
|
* O(min(transcriptSize, cap)) per transcript read.
|
|
247
247
|
*/
|
|
248
248
|
function findLatestTranscriptModel(cwd, agentType, deps) {
|
|
249
|
-
const readActiveIndex = deps.readActiveIndex || require('
|
|
249
|
+
const readActiveIndex = deps.readActiveIndex || require('../epic/epicMint.cjs').readActiveIndex;
|
|
250
250
|
let sessions;
|
|
251
251
|
try {
|
|
252
252
|
({ sessions } = readActiveIndex(cwd));
|
|
@@ -296,7 +296,7 @@ async function resolveEffectiveModelInfo({ cwd, agentType, deps = {} } = {}) {
|
|
|
296
296
|
if (!cwd || !agentType) return miss;
|
|
297
297
|
|
|
298
298
|
try {
|
|
299
|
-
const { projectRootOf } = deps.activeSessions || require('
|
|
299
|
+
const { projectRootOf } = deps.activeSessions || require('../activeSessions.cjs');
|
|
300
300
|
const normalizedCwd = projectRootOf(path.resolve(cwd));
|
|
301
301
|
if (!normalizedCwd) return miss;
|
|
302
302
|
|
|
@@ -29,7 +29,7 @@ const SCAN_OVERLAP_BYTES = 128;
|
|
|
29
29
|
const MODEL_ID_RE = /claude-(?:opus|sonnet|haiku|fable)-[0-9][0-9-]*/g;
|
|
30
30
|
// A real CLI binary is tens of MB; test stubs and launcher shims are tiny shell scripts.
|
|
31
31
|
const MIN_SCAN_BYTES = 1024 * 1024;
|
|
32
|
-
const SCHEMA_PATH = path.join(__dirname, '..', '..', 'renderer', 'data', 'claude-settings-schema.json');
|
|
32
|
+
const SCHEMA_PATH = path.join(__dirname, '..', '..', '..', 'renderer', 'data', 'claude-settings-schema.json');
|
|
33
33
|
|
|
34
34
|
const CATALOG_FLOOR = Object.freeze({
|
|
35
35
|
aliases: Object.freeze(['haiku', 'sonnet', 'opus', 'fable']),
|
|
@@ -118,7 +118,7 @@ function readAvailableModels(cwd, d, fsImpl) {
|
|
|
118
118
|
const home = d.homeDir ? d.homeDir() : os.homedir();
|
|
119
119
|
let root = null;
|
|
120
120
|
if (cwd) {
|
|
121
|
-
try { root = (d.projectRootOf || require('
|
|
121
|
+
try { root = (d.projectRootOf || require('../activeSessions.cjs').projectRootOf)(path.resolve(cwd)); } catch { root = path.resolve(cwd); }
|
|
122
122
|
}
|
|
123
123
|
const files = [path.join(home, '.claude', 'settings.json')];
|
|
124
124
|
if (root) files.push(path.join(root, '.claude', 'settings.json'), path.join(root, '.claude', 'settings.local.json'));
|
|
@@ -221,7 +221,7 @@ async function doResolve({ cwd, force, deps }) {
|
|
|
221
221
|
};
|
|
222
222
|
// Unknown version = unknown cache key: writing it would stamp `claudeVersion: null` over a real entry.
|
|
223
223
|
if (!degraded && cacheFile && claudeVersion) {
|
|
224
|
-
try { await (d.writeJson || require('
|
|
224
|
+
try { await (d.writeJson || require('../../config.cjs').writeJson)(cacheFile, catalog); } catch { /* cache is best-effort */ }
|
|
225
225
|
}
|
|
226
226
|
return catalog;
|
|
227
227
|
}
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
* never be a second, independently-drifting regex set at either call site.
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
|
-
const { readTail } = require('
|
|
14
|
+
const { readTail } = require('../util/fileTail.cjs');
|
|
15
15
|
|
|
16
16
|
/** Scan the tail of a job's log for the canonical rate-limit signal. We look
|
|
17
17
|
* at the last 16 KB — final result event always lands at the end. Covers
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
* unit-testable without scheduler.cjs (mirrors reaperHelpers.cjs's split).
|
|
14
14
|
*/
|
|
15
15
|
|
|
16
|
-
const { readTail } = require('
|
|
16
|
+
const { readTail } = require('../util/fileTail.cjs');
|
|
17
17
|
|
|
18
18
|
// Authoritative window block rides on the LAST rate_limit_event in the log
|
|
19
19
|
// (often the one attached to the final result), so mirror classifyRunOutcome's
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
const { spawn } = require('node:child_process');
|
|
18
18
|
const { resolveClaudeBin, claudeSpawnTarget } = require('./claudeBin.cjs');
|
|
19
19
|
const { headlessPermissionArgs, ensureCliCapsProbed } = require('./claudeCliCaps.cjs');
|
|
20
|
-
const { withProcRole } = require('
|
|
20
|
+
const { withProcRole } = require('../process/cleanEnv.cjs');
|
|
21
21
|
|
|
22
22
|
const MAX_OUT_BYTES = 8 * 1024 * 1024;
|
|
23
23
|
|
|
@@ -5,9 +5,9 @@ const fs = require('node:fs');
|
|
|
5
5
|
const path = require('node:path');
|
|
6
6
|
const os = require('node:os');
|
|
7
7
|
const { spawn, execFileSync } = require('node:child_process');
|
|
8
|
-
const { cleanChildEnv, pathWithUserBins } = require('./cleanEnv.cjs');
|
|
9
|
-
const atomicFs = require('./atomicFs.cjs');
|
|
10
|
-
const { resolveClaudeBin, claudeSpawnTarget } = require('./claudeBin.cjs');
|
|
8
|
+
const { cleanChildEnv, pathWithUserBins } = require('./process/cleanEnv.cjs');
|
|
9
|
+
const atomicFs = require('./util/atomicFs.cjs');
|
|
10
|
+
const { resolveClaudeBin, claudeSpawnTarget } = require('./claude/claudeBin.cjs');
|
|
11
11
|
|
|
12
12
|
const CREDS_PATH = path.join(os.homedir(), '.claude', '.credentials.json');
|
|
13
13
|
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
const fs = require('node:fs');
|
|
42
42
|
const os = require('node:os');
|
|
43
43
|
const path = require('node:path');
|
|
44
|
-
const schedulerPaths = require('./schedulerPaths.cjs');
|
|
44
|
+
const schedulerPaths = require('./scheduler/schedulerPaths.cjs');
|
|
45
45
|
|
|
46
46
|
const OPS_DIRNAME = 'session-manager-operations';
|
|
47
47
|
const WORKTREES_MARKER = `${path.sep}.git${path.sep}worktrees${path.sep}`;
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
|
|
36
36
|
const path = require('path');
|
|
37
37
|
const { activeIndexPath, withPathLock } = require('./epicMint.cjs');
|
|
38
|
-
const config = require('
|
|
38
|
+
const config = require('../../config.cjs');
|
|
39
39
|
const { mirrorEpicStatus } = require('./epicStatusMirror.cjs');
|
|
40
40
|
|
|
41
41
|
function hasOwn(obj, key) {
|
|
@@ -73,7 +73,7 @@ async function mergeActiveIndex(cwd, { sessions: rawMemorySessions = {}, events:
|
|
|
73
73
|
if (!cwd || typeof cwd !== 'string') throw new Error('mergeActiveIndex: cwd is required');
|
|
74
74
|
// Register this project's cwd as a write-allowed root (config.cjs's
|
|
75
75
|
// validateWrite gate) — mirrors the precedent + comment in
|
|
76
|
-
// lib/prdCreate.cjs:152-155. A chat-only Epic (headless claude -p, no
|
|
76
|
+
// lib/prd/prdCreate.cjs:152-155. A chat-only Epic (headless claude -p, no
|
|
77
77
|
// Terminal PTY ever spawned for this cwd) reaches this merge on a cold
|
|
78
78
|
// boot before pty.cjs's addAllowedRoot call has ever run for it — without
|
|
79
79
|
// this, every active-index.json write for such a project fails with
|
|
@@ -181,7 +181,7 @@ async function mergeActiveIndex(cwd, { sessions: rawMemorySessions = {}, events:
|
|
|
181
181
|
|
|
182
182
|
function registerActiveIndexMergeHandlers() {
|
|
183
183
|
const { ipcMain } = require('electron');
|
|
184
|
-
const { schemas: s, validated: v } = require('
|
|
184
|
+
const { schemas: s, validated: v } = require('../../ipcSchemas.cjs');
|
|
185
185
|
ipcMain.handle(
|
|
186
186
|
'promptSessions:merge-active-index',
|
|
187
187
|
v(s.promptSessionsMergeActiveIndex, ({ cwd, sessions, events, removedIds }) =>
|
|
@@ -20,7 +20,7 @@ const path = require('node:path');
|
|
|
20
20
|
const { activeIndexPath, readActiveIndex, writeActiveIndex, withPathLock } = require('./epicMint.cjs');
|
|
21
21
|
|
|
22
22
|
function promptSessionsDir(cwd) {
|
|
23
|
-
const { opsPath } = require('
|
|
23
|
+
const { opsPath } = require('../opsOwnership.cjs');
|
|
24
24
|
return opsPath(cwd, 'prompt-sessions');
|
|
25
25
|
}
|
|
26
26
|
|
|
@@ -20,36 +20,28 @@ const fs = require('node:fs');
|
|
|
20
20
|
const path = require('node:path');
|
|
21
21
|
const os = require('node:os');
|
|
22
22
|
const { spawn } = require('node:child_process');
|
|
23
|
-
const { writeJson, addAllowedRoot } = require('
|
|
24
|
-
const { cleanChildEnv, pathWithUserBins } = require('
|
|
25
|
-
const { shimPath: guardShimPath, resolveShimTarget, ensureGuardShimsOrError } = require('
|
|
26
|
-
const { resolveProjectRoot } = require('
|
|
27
|
-
const { nodeShellCommand } = require('
|
|
23
|
+
const { writeJson, addAllowedRoot } = require('../../config.cjs');
|
|
24
|
+
const { cleanChildEnv, pathWithUserBins } = require('../process/cleanEnv.cjs');
|
|
25
|
+
const { shimPath: guardShimPath, resolveShimTarget, ensureGuardShimsOrError } = require('../guardShims.cjs');
|
|
26
|
+
const { resolveProjectRoot } = require('../opsOwnership.cjs');
|
|
27
|
+
const { nodeShellCommand } = require('../appRuntime.cjs');
|
|
28
|
+
const { readJsonOrSync } = require('../util/atomicFs.cjs');
|
|
28
29
|
|
|
29
30
|
const SCHEDULER_MCP_NAME = 'session-manager-scheduler';
|
|
30
31
|
const DEV_PLUGIN_ENABLED_KEY = 'session-manager-dev@session-manager';
|
|
31
|
-
const SCHEDULER_MCP_SERVER_SCRIPT = path.resolve(__dirname, '..', '..', '..', 'scripts', 'scheduler-mcp-server.cjs');
|
|
32
|
-
const PRD_WRITE_GUARD_SCRIPT = path.resolve(__dirname, '..', '..', '..', 'scripts', 'hooks', 'guard-prd-writes.cjs');
|
|
32
|
+
const SCHEDULER_MCP_SERVER_SCRIPT = path.resolve(__dirname, '..', '..', '..', '..', 'scripts', 'scheduler-mcp-server.cjs');
|
|
33
|
+
const PRD_WRITE_GUARD_SCRIPT = path.resolve(__dirname, '..', '..', '..', '..', 'scripts', 'hooks', 'guard-prd-writes.cjs');
|
|
33
34
|
const PRD_WRITE_GUARD_MATCHER = 'Write|Edit|NotebookEdit';
|
|
34
|
-
const DESTRUCTIVE_GIT_GUARD_SCRIPT = path.resolve(__dirname, '..', '..', '..', 'scripts', 'hooks', 'guard-destructive-git.cjs');
|
|
35
|
+
const DESTRUCTIVE_GIT_GUARD_SCRIPT = path.resolve(__dirname, '..', '..', '..', '..', 'scripts', 'hooks', 'guard-destructive-git.cjs');
|
|
35
36
|
const DESTRUCTIVE_GIT_GUARD_MATCHER = 'Bash';
|
|
36
|
-
const INLINE_IMPLEMENTATION_GUARD_SCRIPT = path.resolve(__dirname, '..', '..', '..', 'scripts', 'hooks', 'guard-inline-implementation.cjs');
|
|
37
|
+
const INLINE_IMPLEMENTATION_GUARD_SCRIPT = path.resolve(__dirname, '..', '..', '..', '..', 'scripts', 'hooks', 'guard-inline-implementation.cjs');
|
|
37
38
|
const INLINE_IMPLEMENTATION_GUARD_MATCHER = 'Write|Edit|NotebookEdit';
|
|
38
|
-
const SELF_SCHEDULE_GUARD_SCRIPT = path.resolve(__dirname, '..', '..', '..', 'scripts', 'hooks', 'guard-self-schedule.cjs');
|
|
39
|
+
const SELF_SCHEDULE_GUARD_SCRIPT = path.resolve(__dirname, '..', '..', '..', '..', 'scripts', 'hooks', 'guard-self-schedule.cjs');
|
|
39
40
|
const SELF_SCHEDULE_GUARD_MATCHER = 'ScheduleWakeup|CronCreate|Task|Agent';
|
|
40
41
|
const LIVE_PROBE_TIMEOUT_MS = 10_000;
|
|
41
42
|
const LIVE_PROBE_TTL_MS = 60_000;
|
|
42
43
|
const REQUIRED_LIVE_TOOLS = ['scheduler_create_prd', 'session_manager_help'];
|
|
43
44
|
|
|
44
|
-
/** Read + JSON.parse a file, returning `fallback` on any read/parse failure. */
|
|
45
|
-
function readJsonSafe(absPath, fallback) {
|
|
46
|
-
try {
|
|
47
|
-
return JSON.parse(fs.readFileSync(absPath, 'utf8'));
|
|
48
|
-
} catch {
|
|
49
|
-
return fallback;
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
|
|
53
45
|
/** Lazy (not a module-load constant) so tests can toggle packaged mode. */
|
|
54
46
|
function schedulerMcpFixCmd() {
|
|
55
47
|
const cmd = nodeShellCommand(SCHEDULER_MCP_SERVER_SCRIPT);
|
|
@@ -68,10 +60,10 @@ function schedulerMcpFixCmd() {
|
|
|
68
60
|
* which is the incident this PRD closes.
|
|
69
61
|
*/
|
|
70
62
|
function checkSchedulerMcp({ cwd, homeDir }) {
|
|
71
|
-
const userConfig =
|
|
63
|
+
const userConfig = readJsonOrSync(path.join(homeDir, '.claude.json'), null);
|
|
72
64
|
const userEntry = userConfig?.mcpServers?.[SCHEDULER_MCP_NAME];
|
|
73
65
|
|
|
74
|
-
const projectConfig =
|
|
66
|
+
const projectConfig = readJsonOrSync(path.join(cwd, '.mcp.json'), null);
|
|
75
67
|
const projectHas = !!projectConfig?.mcpServers?.[SCHEDULER_MCP_NAME];
|
|
76
68
|
|
|
77
69
|
if (userEntry) {
|
|
@@ -129,10 +121,10 @@ function checkSchedulerMcp({ cwd, homeDir }) {
|
|
|
129
121
|
* (enableAllProjectMcpServers), not something this probe decides.
|
|
130
122
|
*/
|
|
131
123
|
function checkSchedulerMcpProjectDuplicate({ cwd, homeDir }) {
|
|
132
|
-
const userConfig =
|
|
124
|
+
const userConfig = readJsonOrSync(path.join(homeDir, '.claude.json'), null);
|
|
133
125
|
const userHas = !!userConfig?.mcpServers?.[SCHEDULER_MCP_NAME];
|
|
134
126
|
|
|
135
|
-
const projectConfig =
|
|
127
|
+
const projectConfig = readJsonOrSync(path.join(cwd, '.mcp.json'), null);
|
|
136
128
|
const projectHas = !!projectConfig?.mcpServers?.[SCHEDULER_MCP_NAME];
|
|
137
129
|
|
|
138
130
|
const warn = userHas && projectHas;
|
|
@@ -289,7 +281,7 @@ async function checkSchedulerMcpLive({ cwd, homeDir, schedulerMcpCheck }) {
|
|
|
289
281
|
// executed the moment its cwd is merely probed, bypassing that approval
|
|
290
282
|
// entirely. Auto-approving project-scope servers is explicitly out of
|
|
291
283
|
// scope for this probe — see this PRD's "Out of scope".
|
|
292
|
-
const userConfig =
|
|
284
|
+
const userConfig = readJsonOrSync(path.join(homeDir, '.claude.json'), null);
|
|
293
285
|
const entry = userConfig?.mcpServers?.[SCHEDULER_MCP_NAME];
|
|
294
286
|
|
|
295
287
|
if (!entry?.command) {
|
|
@@ -312,7 +304,7 @@ async function checkSchedulerMcpLive({ cwd, homeDir, schedulerMcpCheck }) {
|
|
|
312
304
|
}
|
|
313
305
|
|
|
314
306
|
function checkDevPlugin({ homeDir }) {
|
|
315
|
-
const settings =
|
|
307
|
+
const settings = readJsonOrSync(path.join(homeDir, '.claude', 'settings.json'), null);
|
|
316
308
|
const ok = settings?.enabledPlugins?.[DEV_PLUGIN_ENABLED_KEY] === true;
|
|
317
309
|
|
|
318
310
|
return {
|
|
@@ -444,7 +436,7 @@ const GUARD_DEFS = {
|
|
|
444
436
|
* while reporting green" failure mode, one hop downstream of the hook command.
|
|
445
437
|
*/
|
|
446
438
|
function checkGuard(def, { cwd, homeDir = os.homedir() }) {
|
|
447
|
-
const settings =
|
|
439
|
+
const settings = readJsonOrSync(path.join(cwd, '.claude', 'settings.json'), null);
|
|
448
440
|
const preToolUse = Array.isArray(settings?.hooks?.PreToolUse) ? settings.hooks.PreToolUse : [];
|
|
449
441
|
|
|
450
442
|
let mentioned = false;
|
|
@@ -536,7 +528,7 @@ async function installGuard(def, { cwd, homeDir = os.homedir(), skipShimEnsure =
|
|
|
536
528
|
// documents for PromptSession archive writes. `cwd` here IS a project root.
|
|
537
529
|
addAllowedRoot(cwd);
|
|
538
530
|
|
|
539
|
-
const existing = fs.existsSync(settingsPath) ?
|
|
531
|
+
const existing = fs.existsSync(settingsPath) ? readJsonOrSync(settingsPath, undefined) : {};
|
|
540
532
|
if (existing === undefined) {
|
|
541
533
|
// Unparseable settings — refuse rather than silently discarding whatever
|
|
542
534
|
// the human has in there.
|
|
@@ -629,7 +621,7 @@ async function installSelfScheduleGuard({ cwd, homeDir = os.homedir(), skipShimE
|
|
|
629
621
|
|
|
630
622
|
/**
|
|
631
623
|
* Runs all eight delegation-readiness checks for `cwd`. Every filesystem read
|
|
632
|
-
* is wrapped (
|
|
624
|
+
* is wrapped (readJsonOrSync / try-catch) so a missing or unparseable file
|
|
633
625
|
* yields ok:false with a detail, never a thrown exception. Async because
|
|
634
626
|
* scheduler-mcp-live genuinely spawns a process and waits on it (bounded by
|
|
635
627
|
* LIVE_PROBE_TIMEOUT_MS, and memoized per registration signature so repeat
|
|
@@ -673,7 +665,7 @@ function logAutoInstallEvent({ cwd, guard, action, error }) {
|
|
|
673
665
|
// A no-op outcome is not an event worth an error-log row (24 rows/3 days of boot noise).
|
|
674
666
|
if (action === 'already-installed') return;
|
|
675
667
|
try {
|
|
676
|
-
const opsErrorLog = require('
|
|
668
|
+
const opsErrorLog = require('../telemetry/opsErrorLog.cjs');
|
|
677
669
|
opsErrorLog.appendError({
|
|
678
670
|
cwd,
|
|
679
671
|
scope: 'delegationReadiness',
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
* scheduler.cjs.
|
|
14
14
|
*/
|
|
15
15
|
|
|
16
|
-
const { readTurns } = require('
|
|
16
|
+
const { readTurns } = require('../../promptSessionTranscript.cjs');
|
|
17
17
|
const { readActiveIndex } = require('./epicMint.cjs');
|
|
18
18
|
|
|
19
19
|
const DEFAULT_MAX_CHARS = 4000;
|
|
@@ -28,7 +28,7 @@ const fs = require('node:fs');
|
|
|
28
28
|
const os = require('node:os');
|
|
29
29
|
const path = require('node:path');
|
|
30
30
|
const { resolveEpicTranscriptPath } = require('./epicTranscriptPath.cjs');
|
|
31
|
-
const { classifyLine } = require('
|
|
31
|
+
const { classifyLine } = require('../classifyTranscriptLine.cjs');
|
|
32
32
|
|
|
33
33
|
// Same cap transcripts.cjs's readDelta uses for a single pass — bounds
|
|
34
34
|
// memory/time on a very large transcript instead of reading it whole.
|
|
@@ -40,7 +40,7 @@ const APPLICATION_SOURCE_PREFIXES = ['src/', 'scripts/', 'plugins/', 'bin/'];
|
|
|
40
40
|
function countPrdsQueued(cwd, epicId, deps = {}) {
|
|
41
41
|
const readdirSync = deps.readdirSync || fs.readdirSync;
|
|
42
42
|
try {
|
|
43
|
-
const { opsPath } = require('
|
|
43
|
+
const { opsPath } = require('../opsOwnership.cjs');
|
|
44
44
|
const dir = opsPath(cwd, 'scheduler', 'epics', epicId, 'prds');
|
|
45
45
|
return readdirSync(dir).filter((name) => name.endsWith('.md')).length;
|
|
46
46
|
} catch {
|
|
@@ -31,20 +31,20 @@ const fs = require('node:fs');
|
|
|
31
31
|
const os = require('node:os');
|
|
32
32
|
const path = require('node:path');
|
|
33
33
|
const crypto = require('node:crypto');
|
|
34
|
-
const { resolveEpicPrdWriteDir } = require('
|
|
35
|
-
const { assertOpsWrite } = require('
|
|
36
|
-
const { appendAuditEvent } = require('
|
|
34
|
+
const { resolveEpicPrdWriteDir } = require('../prd/prdLocations.cjs');
|
|
35
|
+
const { assertOpsWrite } = require('../opsOwnership.cjs');
|
|
36
|
+
const { appendAuditEvent } = require('../telemetry/auditLog.cjs');
|
|
37
37
|
const { mirrorEpicStatus, removeEpicMirror } = require('./epicStatusMirror.cjs');
|
|
38
|
-
const atomicFs = require('
|
|
39
|
-
const telemetryCounters = require('
|
|
38
|
+
const atomicFs = require('../util/atomicFs.cjs');
|
|
39
|
+
const telemetryCounters = require('../telemetry/telemetryCounters.cjs');
|
|
40
40
|
// Required as the module object (not destructured) so a test can
|
|
41
41
|
// monkeypatch promptSessionSchema.assertValidPromptSession in place to
|
|
42
42
|
// simulate a corrupted construction — the real construction below is
|
|
43
43
|
// hardcoded and always valid.
|
|
44
|
-
const promptSessionSchema = require('
|
|
44
|
+
const promptSessionSchema = require('../promptSessionSchema.cjs');
|
|
45
45
|
|
|
46
46
|
// The one token that unlocks ensureEpic's mint branch. Held by
|
|
47
|
-
// lib/promptSessionsCreateEpic.cjs (the New Epic card's IPC handler) and
|
|
47
|
+
// lib/epic/promptSessionsCreateEpic.cjs (the New Epic card's IPC handler) and
|
|
48
48
|
// nothing else — grep for it before adding a second holder, that is a
|
|
49
49
|
// deliberate domain-model change, not a convenience.
|
|
50
50
|
const MINT_AUTHORITY_NEW_EPIC_UI = 'new-epic-ui';
|
|
@@ -56,7 +56,7 @@ const MINT_AUTHORITY_NEW_EPIC_UI = 'new-epic-ui';
|
|
|
56
56
|
// the `feedback/` folder retired (2026-08-02) and the scheduler correctly
|
|
57
57
|
// locked down to join-only, an agent working in Project-A had NO way to hand
|
|
58
58
|
// a finding to Project-B — the finding either died in a transcript or the
|
|
59
|
-
// human had to relay it by hand. `lib/crossProjectFeedback.cjs` restores that
|
|
59
|
+
// human had to relay it by hand. `lib/feedback-remote/crossProjectFeedback.cjs` restores that
|
|
60
60
|
// conduit, and it is the sole holder of this token.
|
|
61
61
|
//
|
|
62
62
|
// What makes it safe is the part of the SINGLE-CREATOR LAW that actually
|
|
@@ -79,7 +79,7 @@ const MINT_AUTHORITIES = Object.freeze([
|
|
|
79
79
|
function activeIndexPath(cwd) {
|
|
80
80
|
// Lazy: opsOwnership → ephemeralCwd → activeSessions; this module is
|
|
81
81
|
// required early by several of those neighbours.
|
|
82
|
-
const { opsPath } = require('
|
|
82
|
+
const { opsPath } = require('../opsOwnership.cjs');
|
|
83
83
|
return opsPath(cwd, 'prompt-sessions', 'active-index.json');
|
|
84
84
|
}
|
|
85
85
|
|
|
@@ -93,7 +93,7 @@ function readActiveIndex(cwd) {
|
|
|
93
93
|
// doesn't resurrect completed/deleted Epics on its own), but every
|
|
94
94
|
// caller here does read-modify-write on the object this returns, so
|
|
95
95
|
// dropping the field would silently erase the removal tombstones
|
|
96
|
-
// lib/activeIndexMerge.cjs's mergeActiveIndex records the next time any
|
|
96
|
+
// lib/epic/activeIndexMerge.cjs's mergeActiveIndex records the next time any
|
|
97
97
|
// of ensureEpic/appendPrdCreatedEvent/removeEpic writes this file.
|
|
98
98
|
tombstones: parsed && typeof parsed.tombstones === 'object' && parsed.tombstones ? parsed.tombstones : {},
|
|
99
99
|
};
|
|
@@ -450,7 +450,7 @@ module.exports = {
|
|
|
450
450
|
writeActiveIndex,
|
|
451
451
|
personaFileExists,
|
|
452
452
|
resolvePersonaPaths,
|
|
453
|
-
// Exported so lib/activeIndexMerge.cjs's renderer-facing merge IPC handler
|
|
453
|
+
// Exported so lib/epic/activeIndexMerge.cjs's renderer-facing merge IPC handler
|
|
454
454
|
// serializes through the SAME lock instance as ensureEpic/
|
|
455
455
|
// appendPrdCreatedEvent (module-level Map, shared via Node's require
|
|
456
456
|
// cache) — one lock per active-index.json path across both callers, not
|
|
@@ -27,8 +27,8 @@
|
|
|
27
27
|
const fs = require('node:fs');
|
|
28
28
|
const os = require('node:os');
|
|
29
29
|
const path = require('node:path');
|
|
30
|
-
const { encodeCwd } = require('
|
|
31
|
-
const { projectRootOf } = require('
|
|
30
|
+
const { encodeCwd } = require('../util/encodeCwd.cjs');
|
|
31
|
+
const { projectRootOf } = require('../activeSessions.cjs');
|
|
32
32
|
const { readActiveIndex } = require('./epicMint.cjs');
|
|
33
33
|
const { resolveEpicSpawnCwd } = require('./epicSpawnCwd.cjs');
|
|
34
34
|
const { resolveEpicTranscriptPath } = require('./epicTranscriptPath.cjs');
|
|
@@ -56,7 +56,7 @@ function findEpic(cwd, claudeSessionId, deps) {
|
|
|
56
56
|
}
|
|
57
57
|
} catch { /* unreadable index → try archives */ }
|
|
58
58
|
try {
|
|
59
|
-
const { opsPath } = require('
|
|
59
|
+
const { opsPath } = require('../opsOwnership.cjs');
|
|
60
60
|
const dir = opsPath(cwd, 'prompt-sessions');
|
|
61
61
|
for (const name of fs.readdirSync(dir)) {
|
|
62
62
|
if (!name.endsWith('.json') || name === 'active-index.json') continue;
|
|
@@ -26,8 +26,8 @@
|
|
|
26
26
|
*/
|
|
27
27
|
|
|
28
28
|
const fs = require('node:fs');
|
|
29
|
-
const { assertOpsWrite, opsPath } = require('
|
|
30
|
-
const atomicFs = require('
|
|
29
|
+
const { assertOpsWrite, opsPath } = require('../opsOwnership.cjs');
|
|
30
|
+
const atomicFs = require('../util/atomicFs.cjs');
|
|
31
31
|
|
|
32
32
|
function epicMirrorPath(cwd, epicId) {
|
|
33
33
|
return opsPath(cwd, 'prompt-sessions', `${epicId}.json`);
|
|
@@ -17,9 +17,9 @@
|
|
|
17
17
|
const fs = require('node:fs');
|
|
18
18
|
const os = require('node:os');
|
|
19
19
|
const path = require('node:path');
|
|
20
|
-
const { encodeCwd } = require('
|
|
20
|
+
const { encodeCwd } = require('../util/encodeCwd.cjs');
|
|
21
21
|
const { readActiveIndex } = require('./epicMint.cjs');
|
|
22
|
-
const { opsPath } = require('
|
|
22
|
+
const { opsPath } = require('../opsOwnership.cjs');
|
|
23
23
|
const { resolveEpicTranscriptPath } = require('./epicTranscriptPath.cjs');
|
|
24
24
|
|
|
25
25
|
/** [epicId, session] pairs: active-index rows plus archived per-Epic `<id>.json` records. */
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
const fs = require('node:fs');
|
|
26
26
|
const os = require('node:os');
|
|
27
27
|
const path = require('node:path');
|
|
28
|
-
const { encodeCwd } = require('
|
|
28
|
+
const { encodeCwd } = require('../util/encodeCwd.cjs');
|
|
29
29
|
const { readActiveIndex } = require('./epicMint.cjs');
|
|
30
30
|
const { resolveEpicSpawnCwd } = require('./epicSpawnCwd.cjs');
|
|
31
31
|
|
|
@@ -53,7 +53,7 @@ function statKey(statSync, p) {
|
|
|
53
53
|
}
|
|
54
54
|
|
|
55
55
|
function opsFile(cwd, ...segments) {
|
|
56
|
-
const { opsPath } = require('
|
|
56
|
+
const { opsPath } = require('../opsOwnership.cjs');
|
|
57
57
|
return opsPath(cwd, 'prompt-sessions', ...segments);
|
|
58
58
|
}
|
|
59
59
|
|