claude-code-session-manager 0.87.0 → 0.88.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/README.md +26 -53
- package/dist/assets/{AgentLibrary-DyLWzZDf.js → AgentLibrary-BZ6IY2g1.js} +1 -1
- package/dist/assets/{DataModel--mISIJ6h.js → DataModel-dAoGAODX.js} +1 -1
- package/dist/assets/{History-C2ahUXTg.js → History-CF157HyX.js} +1 -1
- package/dist/assets/{Hooks-BiC6oyR2.js → Hooks-CCPPipBk.js} +1 -1
- package/dist/assets/{HostBilko-BPleEOld.js → HostBilko-Dlmz2m06.js} +1 -1
- package/dist/assets/{Library-Dc8Qst1R.js → Library-BaXcboWX.js} +1 -1
- package/dist/assets/{ListDetail-DIXh-OLX.js → ListDetail-CoUCzG5S.js} +1 -1
- package/dist/assets/{MarkdownEditor-C90bkLXK.js → MarkdownEditor-DTg3JlOT.js} +1 -1
- package/dist/assets/{McpServers-DqcbLOLZ.js → McpServers-DdjY1sA3.js} +1 -1
- package/dist/assets/{Memory-CW62MXlh.js → Memory-BJ3Jlw0C.js} +1 -1
- package/dist/assets/{Panel-Bw1FhRuF.js → Panel-ygRSgc41.js} +1 -1
- package/dist/assets/{Permissions-BcUC-5y8.js → Permissions-m0KAnccF.js} +1 -1
- package/dist/assets/{Plugins-BnKx9flD.js → Plugins-CJRl6B3Q.js} +2 -2
- package/dist/assets/{ProvenanceBadge-Bw5vNVPT.js → ProvenanceBadge-w8cnlVvW.js} +1 -1
- package/dist/assets/{SaveBar-CWr0O_w-.js → SaveBar-BpyPcUIk.js} +1 -1
- package/dist/assets/{Scheduler-DYdLuUqq.js → Scheduler-D2ppxSfy.js} +7 -7
- package/dist/assets/{ScopeSwitcher-CrBLbg8s.js → ScopeSwitcher-EyuIwt-j.js} +1 -1
- package/dist/assets/{Settings-DluB-vN1.js → Settings-BHSGGFEc.js} +1 -1
- package/dist/assets/{SkillReferenceGraph-CHLSseay.js → SkillReferenceGraph-BNaZ2JCF.js} +1 -1
- package/dist/assets/{Skills-gNdo_HNK.js → Skills-Dl3q75QV.js} +1 -1
- package/dist/assets/{SystemPrompt-Cru05-Ia.js → SystemPrompt-Bg6F-Cyp.js} +1 -1
- package/dist/assets/{TagLibrary-DNHY0xou.js → TagLibrary-BSutflCy.js} +1 -1
- package/dist/assets/{TiptapBody-I4lmbCgP.js → TiptapBody-CXih4xrc.js} +1 -1
- package/dist/assets/{Toggle-bWMHjmRh.js → Toggle-2qtUHhA9.js} +1 -1
- package/dist/assets/{index-fc_JjdxL.js → index-B3emy2oI.js} +356 -356
- package/dist/assets/{index-DV3PorRY.css → index-BHTX4OTc.css} +1 -1
- package/dist/assets/{settingsSchema-BfhtZnGD.js → settingsSchema-CdzxaqwM.js} +1 -1
- package/dist/assets/{whisperWorker-Dbia1OpC.js → whisperWorker-C7ZGQwKg.js} +7 -7
- package/dist/index.html +2 -2
- package/dist/vad/ort-wasm-simd-threaded.asyncify.mjs +106 -110
- package/dist/vad/ort-wasm-simd-threaded.asyncify.wasm +0 -0
- package/dist/vad/ort-wasm-simd-threaded.jsep.mjs +98 -98
- package/dist/vad/ort-wasm-simd-threaded.jsep.wasm +0 -0
- package/dist/vad/ort-wasm-simd-threaded.jspi.mjs +99 -102
- package/dist/vad/ort-wasm-simd-threaded.jspi.wasm +0 -0
- package/dist/vad/ort-wasm-simd-threaded.mjs +46 -46
- package/dist/vad/ort-wasm-simd-threaded.wasm +0 -0
- package/package.json +10 -13
- package/scripts/README.md +59 -0
- package/scripts/audit-ops-hygiene.cjs +350 -0
- package/scripts/hooks/guard-destructive-git.cjs +10 -34
- package/scripts/hooks/guard-inline-implementation.cjs +14 -8
- package/scripts/hooks/guard-prd-writes.cjs +7 -36
- package/scripts/hooks/guard-self-schedule.cjs +175 -0
- package/scripts/ops-sweep.cjs +355 -0
- package/scripts/scheduler-mcp-server.cjs +28 -71
- package/src/main/__tests__/bilkoHost-integration.test.cjs +3 -3
- package/src/main/__tests__/chat-cancel-terminal.test.cjs +6 -9
- package/src/main/__tests__/chat-exit-close-race.test.cjs +3 -3
- package/src/main/__tests__/chat-mcp-consent-notice.test.cjs +4 -5
- package/src/main/__tests__/chat-queue.test.cjs +2 -2
- package/src/main/__tests__/chat-stop-signal.test.cjs +2 -2
- package/src/main/__tests__/dep-orphan-archive-health.test.cjs +77 -0
- package/src/main/__tests__/dod-batchkey.test.cjs +2 -2
- package/src/main/__tests__/dod-drain-hook.test.cjs +2 -2
- package/src/main/__tests__/dod-report.test.cjs +2 -2
- package/src/main/__tests__/dod-reverify.test.cjs +2 -2
- package/src/main/__tests__/epicMint.test.cjs +2 -2
- package/src/main/__tests__/exchanges.test.cjs +2 -2
- package/src/main/__tests__/extractJson.test.cjs +2 -2
- package/src/main/__tests__/files-reject-credentials.test.cjs +1 -1
- package/src/main/__tests__/fixtures/1218-fo-01-move-scripts-lib-into-src-main-lib.log +556 -0
- package/src/main/__tests__/health-build-freshness.test.cjs +39 -0
- package/src/main/__tests__/health-delegation-chain.test.cjs +15 -1
- package/src/main/__tests__/health-queue-dispatch.test.cjs +58 -7
- package/src/main/__tests__/health-tick-liveness.test.cjs +11 -3
- package/src/main/__tests__/health-usage-poller.test.cjs +70 -23
- package/src/main/__tests__/historyRollup.test.cjs +2 -2
- package/src/main/__tests__/kg-augment.test.cjs +2 -2
- package/src/main/__tests__/mcpStatus.test.cjs +2 -2
- package/src/main/__tests__/memoryAggregate.test.cjs +1 -1
- package/src/main/__tests__/memoryStale.test.cjs +1 -1
- package/src/main/__tests__/opsErrorLogTelemetryTap.test.cjs +25 -1
- package/src/main/__tests__/pollLoop-dispatch-on-failure.test.cjs +33 -3
- package/src/main/__tests__/prd-group-allocator.test.cjs +2 -2
- package/src/main/__tests__/prdAdminRouteParity.test.cjs +2 -0
- package/src/main/__tests__/prdAdminRoutes.test.cjs +14 -2
- package/src/main/__tests__/prdAuthoringSeed.test.cjs +39 -0
- package/src/main/__tests__/prdLocationsArchived.test.cjs +20 -13
- package/src/main/__tests__/proc-role-env.test.cjs +125 -0
- package/src/main/__tests__/procname-claude-spawn-sites.test.cjs +304 -0
- package/src/main/__tests__/procname-sm-processes.test.cjs +127 -0
- package/src/main/__tests__/projectHomeAdminRoutes.test.cjs +81 -401
- package/src/main/__tests__/projectPages.test.cjs +63 -149
- package/src/main/__tests__/queue-health-verdict.test.cjs +9 -9
- package/src/main/__tests__/queue-starvation-dispatch-driver.test.cjs +117 -20
- package/src/main/__tests__/queueHistory.test.cjs +2 -2
- package/src/main/__tests__/rateLimitPollerStreak.test.cjs +38 -3
- package/src/main/__tests__/runVerify-landed-commit-outranks.test.cjs +181 -0
- package/src/main/__tests__/runVerify.test.cjs +5 -5
- package/src/main/__tests__/scheduleJobStatusDrift.test.cjs +3 -3
- package/src/main/__tests__/scheduleJobTransitions.test.cjs +2 -2
- package/src/main/__tests__/scheduler-adopted-run-supervision.test.cjs +143 -0
- package/src/main/__tests__/scheduler-autofix-select.test.cjs +2 -2
- package/src/main/__tests__/scheduler-autopromote.test.cjs +2 -2
- package/src/main/__tests__/scheduler-bash-timeout-env.test.cjs +3 -5
- package/src/main/__tests__/scheduler-boot-orphans.test.cjs +78 -97
- package/src/main/__tests__/scheduler-default-eligible-heal.test.cjs +161 -0
- package/src/main/__tests__/scheduler-dispatch-loop.test.cjs +58 -0
- package/src/main/__tests__/scheduler-epic-digest.test.cjs +3 -5
- package/src/main/__tests__/scheduler-force-tick-outcome.test.cjs +2 -2
- package/src/main/__tests__/scheduler-gate-shadow.test.cjs +119 -0
- package/src/main/__tests__/scheduler-guard-verdict-autoresolve.test.cjs +46 -0
- package/src/main/__tests__/scheduler-heartbeat-payload.test.cjs +80 -0
- package/src/main/__tests__/scheduler-inplace-salvage.test.cjs +25 -18
- package/src/main/__tests__/scheduler-investigation-prompt.test.cjs +4 -4
- package/src/main/__tests__/scheduler-launch-failure.test.cjs +3 -5
- package/src/main/__tests__/scheduler-looks-done.test.cjs +26 -7
- package/src/main/__tests__/scheduler-manual-pause.test.cjs +118 -0
- package/src/main/__tests__/scheduler-meta-code-sha.test.cjs +26 -3
- package/src/main/__tests__/scheduler-prd-missing-skip.test.cjs +17 -2
- package/src/main/__tests__/scheduler-prd-persona-spawn.test.cjs +3 -5
- package/src/main/__tests__/scheduler-quiet-machine-lease.test.cjs +41 -6
- package/src/main/__tests__/scheduler-rate-limit-pause.test.cjs +62 -6
- package/src/main/__tests__/scheduler-rate-limit-spin-guard.test.cjs +3 -5
- package/src/main/__tests__/scheduler-reap-dead-running-jobs.test.cjs +23 -4
- package/src/main/__tests__/scheduler-reconcile-cwd-preserve.test.cjs +100 -0
- package/src/main/__tests__/scheduler-reconcile-invalid-repair.test.cjs +3 -3
- package/src/main/__tests__/scheduler-reconcile-quarantine.test.cjs +4 -4
- package/src/main/__tests__/scheduler-shard-quarantine.test.cjs +110 -0
- package/src/main/__tests__/scheduler-shared-tree-guard.test.cjs +81 -1
- package/src/main/__tests__/scheduler-starve-escalation.test.cjs +4 -4
- package/src/main/__tests__/scheduler-stranded-autofix-park.test.cjs +245 -0
- package/src/main/__tests__/scheduler-supervisor-record.test.cjs +81 -0
- package/src/main/__tests__/scheduler-tick-cancel-token.test.cjs +2 -2
- package/src/main/__tests__/scheduler-tick-wedge.test.cjs +172 -0
- package/src/main/__tests__/scheduler-transient-failure.test.cjs +2 -2
- package/src/main/__tests__/scheduler-worktree-cap-defer.test.cjs +37 -11
- package/src/main/__tests__/scheduler-worktree-exec-cwd.test.cjs +3 -5
- package/src/main/__tests__/usageSingleFlight.test.cjs +157 -0
- package/src/main/__tests__/workTypeLibrary.test.cjs +1 -1
- package/src/main/bilkoHost.cjs +16 -7
- package/src/main/build-info.json +8 -0
- package/src/main/chatRunner.cjs +4 -2
- package/src/main/config.cjs +2 -3
- package/src/main/docEdit.cjs +4 -2
- package/src/main/health.cjs +267 -51
- package/src/main/heapSnapshot.cjs +2 -2
- package/src/main/historyAggregator.cjs +1 -1
- package/src/main/index.cjs +61 -10
- package/src/main/ipcSchemas.cjs +6 -17
- package/src/main/lib/__tests__/auditLog.test.cjs +38 -0
- package/src/main/lib/__tests__/buildIdentity.test.cjs +121 -0
- package/src/main/lib/__tests__/cwdClassify.test.cjs +111 -0
- package/src/main/lib/__tests__/definitionOfDoneSequence.test.cjs +95 -0
- package/src/main/lib/__tests__/delegationReadiness.test.cjs +1 -1
- package/src/main/lib/__tests__/dispatchLoop.test.cjs +63 -0
- package/src/main/lib/__tests__/gateFixtures.json +20 -0
- package/src/main/lib/__tests__/gitWorktree.test.cjs +8 -1
- package/src/main/lib/__tests__/instanceLock.test.cjs +93 -7
- package/src/main/lib/__tests__/jobSupervisorRecord.test.cjs +78 -0
- package/src/main/lib/__tests__/jobWorktreeBootLive.test.cjs +11 -0
- package/src/main/lib/__tests__/localAdminHttp.test.cjs +1 -1
- package/src/main/lib/__tests__/mcpToolCatalog.test.cjs +6 -1
- package/src/main/lib/__tests__/procIdentity.test.cjs +119 -0
- package/src/main/lib/__tests__/procName.test.cjs +92 -0
- package/src/main/lib/__tests__/queueStoreMachineStateRecovery.test.cjs +67 -0
- package/src/main/lib/__tests__/schedulerMcpServerHelp.test.cjs +6 -7
- package/src/main/lib/__tests__/schedulerMcpServerProjectHome.test.cjs +37 -204
- package/src/main/lib/__tests__/schedulerPaths.test.cjs +226 -0
- package/src/main/lib/__tests__/schedulerPathsWorktree.test.cjs +94 -0
- package/src/main/lib/__tests__/schedulerRuntimeState.test.cjs +56 -0
- package/src/main/lib/__tests__/sessionSlots.test.cjs +45 -0
- package/src/main/lib/__tests__/telemetryBacklog.test.cjs +1 -1
- package/src/main/lib/__tests__/upgradeDrain.test.cjs +130 -0
- package/src/main/lib/__tests__/usageCircuit.test.cjs +61 -0
- package/src/main/lib/__tests__/watchdog-helpers.test.cjs +63 -0
- package/src/main/lib/__tests__/watchdog-relaunch.test.cjs +73 -0
- package/src/main/lib/activeIndexRebuild.cjs +1 -3
- package/src/main/lib/activeSessions.cjs +20 -88
- package/src/main/lib/adoptedRunSupervisor.cjs +136 -0
- package/src/main/lib/agentModelResolve.cjs +33 -1
- package/src/main/lib/agentPersonaSchema.cjs +2 -2
- package/src/main/lib/auditLog.cjs +30 -5
- package/src/main/lib/buildIdentity.cjs +113 -0
- package/src/main/lib/classifyPromptTicket.cjs +3 -2
- package/src/main/lib/claudeBin.cjs +37 -2
- package/src/main/lib/cleanEnv.cjs +27 -1
- package/src/main/lib/credentials.cjs +4 -2
- package/src/main/lib/cwdClassify.cjs +185 -0
- package/src/main/lib/definitionOfDone.cjs +296 -52
- package/src/main/lib/dispatchLoop.cjs +40 -0
- package/src/main/lib/effectiveModelInfo.cjs +9 -10
- package/src/main/lib/ephemeralCwd.cjs +7 -28
- package/src/main/lib/gitWorktree.cjs +95 -8
- package/src/main/lib/guardShims.cjs +3 -3
- package/src/main/lib/historyRollup.cjs +6 -7
- package/src/main/lib/instanceLock.cjs +32 -5
- package/src/main/lib/jobSupervisorRecord.cjs +147 -0
- package/src/main/lib/jobWorktreeBootLive.cjs +9 -5
- package/src/main/lib/localAdminHttp.cjs +9 -27
- package/src/main/lib/mcpToolCatalog.cjs +29 -77
- package/src/main/lib/opsOwnership.cjs +27 -19
- package/src/main/lib/prdAuthoringSeed.cjs +36 -0
- package/src/main/lib/prdLocations.cjs +48 -1
- package/src/main/lib/procIdentity.cjs +126 -0
- package/src/main/lib/procName.cjs +98 -0
- package/src/main/lib/projectHomeAdminRoutes.cjs +56 -327
- package/src/main/lib/queueHistory.cjs +8 -7
- package/src/main/lib/queueStore.cjs +57 -37
- package/src/main/lib/quietMachineLease.cjs +19 -2
- package/src/main/lib/reservationExpiry.cjs +30 -0
- package/src/main/lib/runClaudeP.cjs +4 -2
- package/src/main/lib/runLogRetention.cjs +3 -2
- package/src/main/lib/scheduleJobSchema.cjs +2 -2
- package/src/main/lib/scheduleJobTransitions.cjs +29 -2
- package/src/main/lib/schedulerBatch.cjs +27 -2
- package/src/main/lib/schedulerPaths.cjs +175 -0
- package/src/main/lib/schedulerRuntimeState.cjs +59 -0
- package/src/main/lib/sessionSlots.cjs +47 -9
- package/src/main/lib/smProcNames.cjs +51 -0
- package/src/main/lib/upgradeDrain.cjs +188 -0
- package/src/main/lib/usageCircuit.cjs +53 -6
- package/src/main/lib/watchdogHelpers.cjs +70 -37
- package/src/main/lib/withTimeout.cjs +33 -0
- package/src/main/mcpStatus.cjs +4 -2
- package/src/main/pluginInstall.cjs +6 -2
- package/src/main/projectPages.cjs +41 -145
- package/src/main/pty.cjs +8 -1
- package/src/main/queueOps.cjs +10 -10
- package/src/main/runVerify.cjs +69 -3
- package/src/main/scheduler.cjs +1598 -381
- package/src/main/seedAgentPersonas.cjs +1 -1
- package/src/main/seedDevPlugin.cjs +1 -1
- package/src/main/seedSchedulerMcp.cjs +7 -6
- package/src/main/seedStatus.cjs +1 -1
- package/src/main/supervisor.cjs +5 -3
- package/src/main/usage.cjs +126 -62
- package/src/preload/api.d.ts +18 -64
- package/src/preload/index.cjs +2 -4
- package/src/seed/agents/project-home-builder.md +31 -48
- package/screenshots/.gitkeep +0 -0
- package/screenshots/README-screenshots.md +0 -13
- package/src/main/lib/projectPageSummarySchema.cjs +0 -181
- package/src/main/teams.cjs +0 -95
- package/src/main/templates/project-pages-catalog.json +0 -741
- package/src/main/templates/project-pages-default-home.html +0 -123
- package/src/main/templates/project-pages-pipeline.md +0 -417
- package/src/seed/prompts/code-review/ac-coverage-check.md +0 -8
- package/src/seed/prompts/code-review/correctness-only.md +0 -8
- package/src/seed/prompts/code-review/full-spectrum-high.md +0 -8
- package/src/seed/prompts/code-review/hallucination-check.md +0 -8
- package/src/seed/prompts/code-review/public-api-compat.md +0 -8
- package/src/seed/prompts/code-review/readability-naming.md +0 -8
- package/src/seed/prompts/debugging/bug-as-failing-test.md +0 -8
- package/src/seed/prompts/debugging/git-bisect-regression.md +0 -8
- package/src/seed/prompts/debugging/instrument-intermittent-bug.md +0 -8
- package/src/seed/prompts/debugging/localize-pipeline-failure.md +0 -8
- package/src/seed/prompts/debugging/reproduce-then-diagnose.md +0 -8
- package/src/seed/prompts/documentation/adr-from-change.md +0 -8
- package/src/seed/prompts/documentation/module-readme.md +0 -8
- package/src/seed/prompts/documentation/onboarding-plan.md +0 -8
- package/src/seed/prompts/documentation/refresh-claude-md.md +0 -8
- package/src/seed/prompts/documentation/tsdoc-public-exports.md +0 -8
- package/src/seed/prompts/git-pr/conventional-commit.md +0 -8
- package/src/seed/prompts/git-pr/draft-pr-title-body.md +0 -8
- package/src/seed/prompts/git-pr/pre-commit-safety-sweep.md +0 -8
- package/src/seed/prompts/git-pr/release-notes-block.md +0 -8
- package/src/seed/prompts/git-pr/split-large-pr.md +0 -8
- package/src/seed/prompts/performance/bundle-startup-audit.md +0 -8
- package/src/seed/prompts/performance/complexity-audit.md +0 -8
- package/src/seed/prompts/performance/cpu-profile-hot-path.md +0 -8
- package/src/seed/prompts/performance/db-query-plan-review.md +0 -8
- package/src/seed/prompts/performance/memory-leak-hunt.md +0 -8
- package/src/seed/prompts/qa/api-contract-tests.md +0 -8
- package/src/seed/prompts/qa/e2e-critical-path.md +0 -8
- package/src/seed/prompts/qa/failing-test-for-bug.md +0 -8
- package/src/seed/prompts/qa/find-missing-test-coverage.md +0 -8
- package/src/seed/prompts/qa/stabilize-flaky-test.md +0 -8
- package/src/seed/prompts/qa/tdd-red-first.md +0 -8
- package/src/seed/prompts/qa/visual-regression-review.md +0 -8
- package/src/seed/prompts/qa/wcag-axe-scan.md +0 -8
- package/src/seed/prompts/refactoring/dead-code-sweep.md +0 -8
- package/src/seed/prompts/refactoring/extract-duplicated-pattern.md +0 -8
- package/src/seed/prompts/refactoring/modernize-legacy-file.md +0 -8
- package/src/seed/prompts/refactoring/reduce-cyclomatic-complexity.md +0 -8
- package/src/seed/prompts/refactoring/tighten-module-boundaries.md +0 -8
- package/src/seed/prompts/security/authz-audit.md +0 -8
- package/src/seed/prompts/security/crypto-correctness.md +0 -8
- package/src/seed/prompts/security/cwe-top-25-hunt.md +0 -8
- package/src/seed/prompts/security/dependency-audit.md +0 -8
- package/src/seed/prompts/security/ipc-boundary-hardening.md +0 -8
- package/src/seed/prompts/security/owasp-top-10-staged-diff.md +0 -8
- package/src/seed/prompts/security/secret-credential-scan.md +0 -8
- package/web/README.md +0 -41
- package/web/project-pages/logic/dist/logic.cjs +0 -4709
- package/web/project-pages/render.cjs +0 -70
- package/web/project-pages/renderer/dist/renderer.cjs +0 -18900
- package/web/project-pages/validate-summary.cjs +0 -62
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* First-boot seeder for the bundled `session-manager-dev` plugin.
|
|
3
3
|
*
|
|
4
|
-
* The plugin (
|
|
4
|
+
* The plugin (the dev skills under plugins/session-manager-dev/skills) ships inside the npx distribution. To make it
|
|
5
5
|
* a true default, the app installs it on first launch from its own bundled
|
|
6
6
|
* marketplace (offline — no GitHub/registry). Idempotent two ways:
|
|
7
7
|
*
|
|
@@ -35,7 +35,7 @@ const fs = require('node:fs');
|
|
|
35
35
|
const path = require('node:path');
|
|
36
36
|
const os = require('node:os');
|
|
37
37
|
const { spawn } = require('node:child_process');
|
|
38
|
-
const { resolveClaudeBin } = require('./lib/claudeBin.cjs');
|
|
38
|
+
const { resolveClaudeBin, claudeSpawnTarget } = require('./lib/claudeBin.cjs');
|
|
39
39
|
const { cleanChildEnv, pathWithUserBins } = require('./lib/cleanEnv.cjs');
|
|
40
40
|
const { writeJsonSync } = require('./config.cjs');
|
|
41
41
|
|
|
@@ -106,13 +106,14 @@ function scriptPathMissing() {
|
|
|
106
106
|
* No shell:true — argv array passed directly to spawn. */
|
|
107
107
|
function runClaudeMcpAdd(serverPath) {
|
|
108
108
|
return new Promise((resolve) => {
|
|
109
|
-
const
|
|
109
|
+
const target = claudeSpawnTarget('aux', 'mcp-add');
|
|
110
110
|
let proc;
|
|
111
111
|
try {
|
|
112
112
|
proc = spawn(
|
|
113
|
-
|
|
113
|
+
target.command,
|
|
114
114
|
['mcp', 'add', SERVER_NAME, '--scope', 'user', '--', 'node', serverPath],
|
|
115
115
|
{
|
|
116
|
+
...(target.argv0 ? { argv0: target.argv0 } : {}),
|
|
116
117
|
cwd: os.homedir(),
|
|
117
118
|
env: cleanChildEnv({ PATH: pathWithUserBins() }),
|
|
118
119
|
stdio: 'ignore',
|
|
@@ -130,13 +131,13 @@ function runClaudeMcpAdd(serverPath) {
|
|
|
130
131
|
/** Run `claude mcp remove session-manager-scheduler --scope user`, best-effort. */
|
|
131
132
|
function runClaudeMcpRemove() {
|
|
132
133
|
return new Promise((resolve) => {
|
|
133
|
-
const
|
|
134
|
+
const target = claudeSpawnTarget('aux', 'mcp-remove');
|
|
134
135
|
let proc;
|
|
135
136
|
try {
|
|
136
137
|
proc = spawn(
|
|
137
|
-
|
|
138
|
+
target.command,
|
|
138
139
|
['mcp', 'remove', SERVER_NAME, '--scope', 'user'],
|
|
139
|
-
{ cwd: os.homedir(), env: cleanChildEnv({ PATH: pathWithUserBins() }), stdio: 'ignore' }
|
|
140
|
+
{ cwd: os.homedir(), env: cleanChildEnv({ PATH: pathWithUserBins() }), stdio: 'ignore', ...(target.argv0 ? { argv0: target.argv0 } : {}) }
|
|
140
141
|
);
|
|
141
142
|
} catch (err) {
|
|
142
143
|
resolve({ ok: false, error: err?.message ?? String(err) });
|
package/src/main/seedStatus.cjs
CHANGED
|
@@ -43,7 +43,7 @@ const FIXES = {
|
|
|
43
43
|
'dev-plugin': 'Open Plugins → Library and click Install next to "session-manager-dev".',
|
|
44
44
|
'scheduler-mcp': () =>
|
|
45
45
|
`Run in a terminal: claude mcp add ${seedSchedulerMcp.SERVER_NAME} --scope user -- node ${seedSchedulerMcp.serverScriptPath()}`,
|
|
46
|
-
'agent-personas':
|
|
46
|
+
'agent-personas': `Copy ${seedAgentPersonas.PERSONAS.map((n) => `src/seed/agents/${n}.md`).join(', ')} into ~/.claude/agents/ (skip any that already exist there).`,
|
|
47
47
|
};
|
|
48
48
|
|
|
49
49
|
/** { 'dev-plugin': {status, fix}, 'scheduler-mcp': {status, fix}, 'agent-personas': {status, fix} } */
|
package/src/main/supervisor.cjs
CHANGED
|
@@ -16,7 +16,8 @@ const path = require('node:path');
|
|
|
16
16
|
const os = require('node:os');
|
|
17
17
|
const { spawn, execFileSync } = require('node:child_process');
|
|
18
18
|
const { ipcMain } = require('electron');
|
|
19
|
-
const { resolveClaudeBin } = require('./lib/claudeBin.cjs');
|
|
19
|
+
const { resolveClaudeBin, claudeSpawnTarget } = require('./lib/claudeBin.cjs');
|
|
20
|
+
const { withProcRole } = require('./lib/cleanEnv.cjs');
|
|
20
21
|
|
|
21
22
|
const HOME = os.homedir();
|
|
22
23
|
const SUPERVISOR_LOG_PATH = path.join(HOME, '.claude', 'session-manager', 'supervisor.log');
|
|
@@ -207,7 +208,8 @@ function runProbe(claudeBin, prompt) {
|
|
|
207
208
|
return new Promise((resolve) => {
|
|
208
209
|
let child;
|
|
209
210
|
try {
|
|
210
|
-
|
|
211
|
+
const target = claudeSpawnTarget('aux', 'supervisor', claudeBin);
|
|
212
|
+
child = spawn(target.command, [
|
|
211
213
|
'-p', prompt,
|
|
212
214
|
'--model', 'claude-opus-4-7',
|
|
213
215
|
'--no-session-persistence',
|
|
@@ -215,7 +217,7 @@ function runProbe(claudeBin, prompt) {
|
|
|
215
217
|
'--max-budget-usd', '0.10',
|
|
216
218
|
'--dangerously-skip-permissions',
|
|
217
219
|
'--allowedTools', 'Bash',
|
|
218
|
-
], { stdio: ['ignore', 'pipe', 'pipe'] });
|
|
220
|
+
], { env: withProcRole(process.env, 'aux'), stdio: ['ignore', 'pipe', 'pipe'], ...(target.argv0 ? { argv0: target.argv0 } : {}) });
|
|
219
221
|
} catch (e) {
|
|
220
222
|
console.error('[supervisor] probe spawn failed:', e?.message);
|
|
221
223
|
resolve({ verdict: 'ok', action: 'none', targetPid: null, reason: `spawn failed: ${e?.message}`, costUsd: null });
|
package/src/main/usage.cjs
CHANGED
|
@@ -23,6 +23,7 @@ const os = require('node:os');
|
|
|
23
23
|
const { ipcMain } = require('electron');
|
|
24
24
|
const { refreshIfNeeded, expiresAtMs } = require('./lib/credentials.cjs');
|
|
25
25
|
const { writeJson } = require('./config.cjs');
|
|
26
|
+
const { createUsageCircuit, singleFlight } = require('./lib/usageCircuit.cjs');
|
|
26
27
|
|
|
27
28
|
const USAGE_URL = 'https://api.anthropic.com/api/oauth/usage';
|
|
28
29
|
|
|
@@ -146,6 +147,18 @@ function classifyUsageResponse(status, bodyText) {
|
|
|
146
147
|
|
|
147
148
|
let cache = null;
|
|
148
149
|
let hydrationPromise = null;
|
|
150
|
+
// Retry-After suppression window: while `now < retryNotBeforeMs`, fetchUsage()
|
|
151
|
+
// refuses to issue another request and instead replays `lastRateLimitedResult`
|
|
152
|
+
// (annotated `suppressed: true`) — set only from a 429's Retry-After header.
|
|
153
|
+
let retryNotBeforeMs = 0;
|
|
154
|
+
let lastRateLimitedResult = null;
|
|
155
|
+
|
|
156
|
+
// Single shared circuit for the /api/oauth/usage meter. Both callers — the
|
|
157
|
+
// renderer's billing:fetch IPC handler and the scheduler's pollLoop — go
|
|
158
|
+
// through this same fetchUsage(), so a success recorded from EITHER caller
|
|
159
|
+
// clears the streak for both, and concurrent callers coalesce into one HTTP
|
|
160
|
+
// request via singleFlight.
|
|
161
|
+
const circuit = createUsageCircuit();
|
|
149
162
|
|
|
150
163
|
async function hydrateCache() {
|
|
151
164
|
try {
|
|
@@ -155,23 +168,17 @@ async function hydrateCache() {
|
|
|
155
168
|
}
|
|
156
169
|
}
|
|
157
170
|
|
|
171
|
+
function ensureHydrated() {
|
|
172
|
+
if (!hydrationPromise) hydrationPromise = hydrateCache();
|
|
173
|
+
return hydrationPromise;
|
|
174
|
+
}
|
|
175
|
+
|
|
158
176
|
async function persistCache(c) {
|
|
159
177
|
await writeJson(CACHE_PATH, c);
|
|
160
178
|
}
|
|
161
179
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
// without hitting the real endpoint. Only active when SM_E2E=1 to prevent
|
|
165
|
-
// accidental use in production.
|
|
166
|
-
if (process.env.SM_E2E === '1' && process.env.SM_MOCK_BILLING_KIND) {
|
|
167
|
-
const kind = process.env.SM_MOCK_BILLING_KIND;
|
|
168
|
-
if (kind === 'meter_rate_limited') return { kind: 'meter_rate_limited', message: 'e2e stub', httpStatus: 429 };
|
|
169
|
-
if (kind === 'transient') return { kind: 'transient', message: 'e2e stub', httpStatus: 503 };
|
|
170
|
-
if (kind === 'auth') return { kind: 'auth', message: 'e2e stub', httpStatus: 401 };
|
|
171
|
-
// 'ok' stub returns a minimal valid payload.
|
|
172
|
-
return { kind: 'ok', data: { usage: { five_hour: { utilization: 10, resets_at: null }, seven_day: { utilization: 10, resets_at: null }, seven_day_sonnet: null, seven_day_opus: null, extra_usage: null }, subscriptionType: null, rateLimitTier: null, credentialsExpiresAt: null, fetchedAt: Date.now() } };
|
|
173
|
-
}
|
|
174
|
-
|
|
180
|
+
/** The actual network round-trip, coalesced across concurrent callers below. */
|
|
181
|
+
async function networkFetchUsage() {
|
|
175
182
|
// Check expiry and attempt proactive refresh before touching the network.
|
|
176
183
|
const refresh = await refreshIfNeeded();
|
|
177
184
|
if (refresh.kind === 'auth') {
|
|
@@ -181,6 +188,7 @@ async function fetchUsage() {
|
|
|
181
188
|
// 'ok' or 'unsupported' — creds present and not yet expired
|
|
182
189
|
const creds = refresh.creds;
|
|
183
190
|
|
|
191
|
+
let result;
|
|
184
192
|
let r;
|
|
185
193
|
try {
|
|
186
194
|
r = await fetch(USAGE_URL, {
|
|
@@ -192,64 +200,107 @@ async function fetchUsage() {
|
|
|
192
200
|
signal: AbortSignal.timeout(10_000),
|
|
193
201
|
});
|
|
194
202
|
} catch (e) {
|
|
195
|
-
|
|
196
|
-
}
|
|
197
|
-
if (r.status === 401 || r.status === 403) {
|
|
198
|
-
const body = await r.text().catch(() => '');
|
|
199
|
-
const ms = expiresAtMs(creds);
|
|
200
|
-
return { kind: 'auth', message: body.slice(0, 200) || `HTTP ${r.status}`, httpStatus: r.status, expiredAt: ms };
|
|
201
|
-
}
|
|
202
|
-
if (r.status === 408 || r.status >= 500) {
|
|
203
|
-
const body = await r.text().catch(() => '');
|
|
204
|
-
return { kind: 'transient', message: body.slice(0, 200) || `HTTP ${r.status}`, httpStatus: r.status };
|
|
203
|
+
result = { kind: 'transient', message: e.message || String(e), httpStatus: null };
|
|
205
204
|
}
|
|
206
|
-
if (
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
205
|
+
if (!result) {
|
|
206
|
+
if (r.status === 401 || r.status === 403) {
|
|
207
|
+
const body = await r.text().catch(() => '');
|
|
208
|
+
const ms = expiresAtMs(creds);
|
|
209
|
+
result = { kind: 'auth', message: body.slice(0, 200) || `HTTP ${r.status}`, httpStatus: r.status, expiredAt: ms };
|
|
210
|
+
} else if (r.status === 408 || r.status >= 500) {
|
|
211
|
+
const body = await r.text().catch(() => '');
|
|
212
|
+
result = { kind: 'transient', message: body.slice(0, 200) || `HTTP ${r.status}`, httpStatus: r.status };
|
|
213
|
+
} else if (r.status === 429) {
|
|
214
|
+
const body = await r.text().catch(() => '');
|
|
215
|
+
let parsed = null;
|
|
216
|
+
try { parsed = JSON.parse(body); } catch { /* */ }
|
|
217
|
+
if (parsed?.error?.type === 'rate_limit_error') {
|
|
218
|
+
result = {
|
|
219
|
+
kind: 'meter_rate_limited',
|
|
220
|
+
message: body.slice(0, 200),
|
|
221
|
+
httpStatus: 429,
|
|
222
|
+
retryAfterMs: parseRetryAfterMs(r.headers.get('retry-after')),
|
|
223
|
+
};
|
|
224
|
+
} else {
|
|
225
|
+
result = { kind: 'transient', message: body.slice(0, 200) || 'HTTP 429', httpStatus: 429 };
|
|
226
|
+
}
|
|
227
|
+
} else if (!r.ok) {
|
|
228
|
+
const body = await r.text().catch(() => '');
|
|
229
|
+
result = { kind: 'transient', message: body.slice(0, 200) || `HTTP ${r.status}`, httpStatus: r.status };
|
|
230
|
+
} else {
|
|
231
|
+
const usage = await r.json();
|
|
232
|
+
result = {
|
|
233
|
+
kind: 'ok',
|
|
234
|
+
data: {
|
|
235
|
+
usage,
|
|
236
|
+
subscriptionType: creds.subscriptionType ?? null,
|
|
237
|
+
rateLimitTier: creds.rateLimitTier ?? null,
|
|
238
|
+
credentialsExpiresAt: creds.expiresAt ?? null,
|
|
239
|
+
fetchedAt: Date.now(),
|
|
240
|
+
},
|
|
216
241
|
};
|
|
217
242
|
}
|
|
218
|
-
return { kind: 'transient', message: body.slice(0, 200) || 'HTTP 429', httpStatus: 429 };
|
|
219
243
|
}
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
244
|
+
|
|
245
|
+
if (result.kind === 'ok') {
|
|
246
|
+
cache = { data: result.data, fetchedAt: Date.now(), sourceCredsExpiresAt: result.data.credentialsExpiresAt };
|
|
247
|
+
persistCache(cache).catch(() => {});
|
|
248
|
+
retryNotBeforeMs = 0;
|
|
249
|
+
lastRateLimitedResult = null;
|
|
250
|
+
circuit.recordSuccess(result.data);
|
|
251
|
+
} else if (result.kind === 'meter_rate_limited') {
|
|
252
|
+
lastRateLimitedResult = result;
|
|
253
|
+
if (Number.isFinite(result.retryAfterMs) && result.retryAfterMs > 0) {
|
|
254
|
+
retryNotBeforeMs = Date.now() + result.retryAfterMs;
|
|
255
|
+
}
|
|
256
|
+
circuit.recordFailure(result.kind);
|
|
257
|
+
} else if (result.kind === 'transient') {
|
|
258
|
+
circuit.recordFailure(result.kind);
|
|
223
259
|
}
|
|
224
|
-
|
|
225
|
-
return {
|
|
226
|
-
kind: 'ok',
|
|
227
|
-
data: {
|
|
228
|
-
usage,
|
|
229
|
-
subscriptionType: creds.subscriptionType ?? null,
|
|
230
|
-
rateLimitTier: creds.rateLimitTier ?? null,
|
|
231
|
-
credentialsExpiresAt: creds.expiresAt ?? null,
|
|
232
|
-
fetchedAt: Date.now(),
|
|
233
|
-
},
|
|
234
|
-
};
|
|
260
|
+
return result;
|
|
235
261
|
}
|
|
236
262
|
|
|
237
|
-
|
|
238
|
-
|
|
263
|
+
// Concurrent callers (the renderer's billing:fetch and the scheduler's
|
|
264
|
+
// pollLoop) coalesce into this one in-flight promise instead of each firing
|
|
265
|
+
// their own request against a rate-limited endpoint.
|
|
266
|
+
const singleFlightNetworkFetch = singleFlight(networkFetchUsage);
|
|
239
267
|
|
|
240
|
-
|
|
241
|
-
|
|
268
|
+
/**
|
|
269
|
+
* The single owner of caching, single-flight de-duplication and Retry-After
|
|
270
|
+
* suppression for the usage meter. Every caller — renderer IPC and scheduler
|
|
271
|
+
* pollLoop alike — must go through this function rather than hitting the
|
|
272
|
+
* network or the cache file directly.
|
|
273
|
+
*/
|
|
274
|
+
async function fetchUsage() {
|
|
275
|
+
// Test stub: SM_MOCK_BILLING_KIND lets e2e tests simulate billing API responses
|
|
276
|
+
// without hitting the real endpoint. Only active when SM_E2E=1 to prevent
|
|
277
|
+
// accidental use in production.
|
|
278
|
+
if (process.env.SM_E2E === '1' && process.env.SM_MOCK_BILLING_KIND) {
|
|
279
|
+
const kind = process.env.SM_MOCK_BILLING_KIND;
|
|
280
|
+
if (kind === 'meter_rate_limited') return { kind: 'meter_rate_limited', message: 'e2e stub', httpStatus: 429 };
|
|
281
|
+
if (kind === 'transient') return { kind: 'transient', message: 'e2e stub', httpStatus: 503 };
|
|
282
|
+
if (kind === 'auth') return { kind: 'auth', message: 'e2e stub', httpStatus: 401 };
|
|
283
|
+
// 'ok' stub returns a minimal valid payload.
|
|
284
|
+
return { kind: 'ok', data: { usage: { five_hour: { utilization: 10, resets_at: null }, seven_day: { utilization: 10, resets_at: null }, seven_day_sonnet: null, seven_day_opus: null, extra_usage: null }, subscriptionType: null, rateLimitTier: null, credentialsExpiresAt: null, fetchedAt: Date.now() } };
|
|
285
|
+
}
|
|
242
286
|
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
287
|
+
await ensureHydrated();
|
|
288
|
+
|
|
289
|
+
if (cache && cache.fetchedAt && Date.now() - cache.fetchedAt < OK_CACHE_TTL_MS) {
|
|
290
|
+
return { kind: 'ok', data: cache.data };
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
if (lastRateLimitedResult && retryNotBeforeMs && Date.now() < retryNotBeforeMs) {
|
|
294
|
+
return { ...lastRateLimitedResult, suppressed: true };
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
return singleFlightNetworkFetch();
|
|
298
|
+
}
|
|
246
299
|
|
|
300
|
+
function registerBillingHandlers() {
|
|
301
|
+
ipcMain.handle('billing:fetch', async () => {
|
|
247
302
|
const r = await fetchUsage();
|
|
248
|
-
if (r.kind === 'ok') {
|
|
249
|
-
cache = { data: r.data, fetchedAt: Date.now(), sourceCredsExpiresAt: r.data.credentialsExpiresAt };
|
|
250
|
-
persistCache(cache).catch(() => {});
|
|
251
|
-
return { kind: 'ok', data: r.data };
|
|
252
|
-
}
|
|
303
|
+
if (r.kind === 'ok') return { kind: 'ok', data: r.data };
|
|
253
304
|
if (r.kind === 'auth') {
|
|
254
305
|
if (cache) return { kind: 'auth', message: r.message, httpStatus: r.httpStatus, expiredAt: r.expiredAt, cached: cache.data, staleSince: cache.fetchedAt };
|
|
255
306
|
return r;
|
|
@@ -259,11 +310,24 @@ function registerBillingHandlers() {
|
|
|
259
310
|
return r;
|
|
260
311
|
}
|
|
261
312
|
if (r.kind === 'meter_rate_limited') {
|
|
262
|
-
if (cache) return { kind: 'meter_rate_limited', message: r.message, httpStatus: r.httpStatus, retryAfterMs: r.retryAfterMs, cached: cache.data, staleSince: cache.fetchedAt };
|
|
313
|
+
if (cache) return { kind: 'meter_rate_limited', message: r.message, httpStatus: r.httpStatus, retryAfterMs: r.retryAfterMs, suppressed: r.suppressed, cached: cache.data, staleSince: cache.fetchedAt };
|
|
263
314
|
return r;
|
|
264
315
|
}
|
|
265
316
|
return r; // config
|
|
266
317
|
});
|
|
267
318
|
}
|
|
268
319
|
|
|
269
|
-
module.exports = {
|
|
320
|
+
module.exports = {
|
|
321
|
+
registerBillingHandlers,
|
|
322
|
+
fetchUsage,
|
|
323
|
+
classifyUsageResponse,
|
|
324
|
+
parseRetryAfterMs,
|
|
325
|
+
usageMeterApplicable,
|
|
326
|
+
readClaudeSettingsAuth,
|
|
327
|
+
// The single shared breaker instance — scheduler.cjs's pollLoop (and every
|
|
328
|
+
// other consumer) reads THIS object's state()/openedAt()/
|
|
329
|
+
// getConsecutiveFailures() rather than deriving its own, so a failure
|
|
330
|
+
// recorded via any path (poller, executor 429) opens the same circuit.
|
|
331
|
+
usageCircuit: circuit,
|
|
332
|
+
__usageCircuitForTest: circuit,
|
|
333
|
+
};
|
package/src/preload/api.d.ts
CHANGED
|
@@ -356,22 +356,23 @@ export interface DelegationReadinessCheck {
|
|
|
356
356
|
| 'agent-personas'
|
|
357
357
|
| 'prd-write-guard'
|
|
358
358
|
| 'destructive-git-guard'
|
|
359
|
-
| 'inline-implementation-guard'
|
|
359
|
+
| 'inline-implementation-guard'
|
|
360
|
+
| 'self-schedule-guard';
|
|
360
361
|
label: string;
|
|
361
362
|
ok: boolean;
|
|
362
363
|
detail: string;
|
|
363
364
|
fix: string | null;
|
|
364
365
|
/** Non-null when Session Manager can install this fix itself, one press. */
|
|
365
|
-
fixAction: 'install-prd-write-guard' | 'install-destructive-git-guard' | 'install-inline-implementation-guard' | null;
|
|
366
|
+
fixAction: 'install-prd-write-guard' | 'install-destructive-git-guard' | 'install-inline-implementation-guard' | 'install-self-schedule-guard' | null;
|
|
366
367
|
/** True when ok:true is a WARNING (still passing, but worth a human's attention) — today only scheduler-mcp-project-duplicate. */
|
|
367
368
|
warn?: boolean;
|
|
368
369
|
/** True when this check didn't run because a precondition (another check) already failed — reported ok:true, not a failure. */
|
|
369
370
|
skipped?: boolean;
|
|
370
371
|
}
|
|
371
372
|
|
|
372
|
-
/** Result of installPrdWriteGuard, installDestructiveGitGuard,
|
|
373
|
-
* installInlineImplementationGuard
|
|
374
|
-
*
|
|
373
|
+
/** Result of installPrdWriteGuard, installDestructiveGitGuard,
|
|
374
|
+
* installInlineImplementationGuard, and installSelfScheduleGuard alike
|
|
375
|
+
* (delegationReadiness.cjs) — all four installers share one contract. */
|
|
375
376
|
export interface InstallGuardResult {
|
|
376
377
|
ok: boolean;
|
|
377
378
|
action: 'installed' | 'repaired' | 'already-installed' | 'error';
|
|
@@ -658,13 +659,6 @@ export interface ScheduleJobStatusHistoryEntry {
|
|
|
658
659
|
at: string;
|
|
659
660
|
}
|
|
660
661
|
|
|
661
|
-
export interface SchedulePaths {
|
|
662
|
-
root: string;
|
|
663
|
-
prds: string;
|
|
664
|
-
runs: string;
|
|
665
|
-
queue: string;
|
|
666
|
-
}
|
|
667
|
-
|
|
668
662
|
export type SchedulePauseReason = 'rate_limit' | 'auth' | 'network' | 'manual' | 'reset_failure';
|
|
669
663
|
|
|
670
664
|
export interface SchedulePauseInfo {
|
|
@@ -858,8 +852,6 @@ export interface ScheduleStateSnapshot {
|
|
|
858
852
|
* is saturated. Null before the first tick that evaluated it.
|
|
859
853
|
*/
|
|
860
854
|
loadGate?: ScheduleLoadGate | null;
|
|
861
|
-
/** Returned only by the initial state() call, not the broadcast event. */
|
|
862
|
-
paths?: SchedulePaths;
|
|
863
855
|
}
|
|
864
856
|
|
|
865
857
|
export interface ScheduleLoadGate {
|
|
@@ -1081,26 +1073,6 @@ export interface WatcherClosedEvent {
|
|
|
1081
1073
|
watcherId: string;
|
|
1082
1074
|
}
|
|
1083
1075
|
|
|
1084
|
-
export interface TeamMember {
|
|
1085
|
-
name: string;
|
|
1086
|
-
agentType: string | null;
|
|
1087
|
-
model: string | null;
|
|
1088
|
-
}
|
|
1089
|
-
|
|
1090
|
-
export interface TeamInfo {
|
|
1091
|
-
name: string;
|
|
1092
|
-
configPath: string;
|
|
1093
|
-
description: string | null;
|
|
1094
|
-
leadAgentId: string | null;
|
|
1095
|
-
members: TeamMember[];
|
|
1096
|
-
memberCount: number;
|
|
1097
|
-
inboxDepth: number;
|
|
1098
|
-
}
|
|
1099
|
-
|
|
1100
|
-
export interface TeamsListResult {
|
|
1101
|
-
teams: TeamInfo[];
|
|
1102
|
-
}
|
|
1103
|
-
|
|
1104
1076
|
// ────────────────────────────────────────────── Bundle D — queue ops
|
|
1105
1077
|
|
|
1106
1078
|
export interface LintFinding {
|
|
@@ -1297,29 +1269,12 @@ export type ProjectBriefUpdateResult =
|
|
|
1297
1269
|
| { ok: true; brief: ProjectBrief }
|
|
1298
1270
|
| { ok: false; error: string };
|
|
1299
1271
|
|
|
1300
|
-
// ────────────────────────────────────────────── Project Pages (
|
|
1301
|
-
export interface ProjectPagesOutput {
|
|
1302
|
-
home: string;
|
|
1303
|
-
/** Absent when `isDefault` is true — the shipped default only covers the home lens. */
|
|
1304
|
-
marketing?: string;
|
|
1305
|
-
/** Absent when `isDefault` is true — the shipped default only covers the home lens. */
|
|
1306
|
-
feature?: string;
|
|
1307
|
-
/** Absent when `isDefault` is true — the shipped default only covers the home lens. */
|
|
1308
|
-
architecture?: string;
|
|
1309
|
-
/** Absent for output generated before the 'brief' lens existed (PRD 969), or
|
|
1310
|
-
* when `isDefault` is true — a project must regenerate to pick it up. */
|
|
1311
|
-
brief?: string;
|
|
1312
|
-
/** null for the shipped default (never generated). */
|
|
1313
|
-
generatedAt: string | null;
|
|
1314
|
-
/** True when `home` is the build-time shipped default, not this project's own
|
|
1315
|
-
* generated output — the renderer must label provenance rather than infer it. */
|
|
1316
|
-
isDefault: boolean;
|
|
1317
|
-
}
|
|
1318
|
-
|
|
1272
|
+
// ────────────────────────────────────────────── Project Pages (single home.html)
|
|
1319
1273
|
export interface ProjectPagesGetResult {
|
|
1320
|
-
/**
|
|
1321
|
-
|
|
1322
|
-
|
|
1274
|
+
/** Contents of session-manager-operations/project-pages/home.html, or null when it has not been generated. */
|
|
1275
|
+
html: string | null;
|
|
1276
|
+
/** home.html's mtime, or null when `html` is null. */
|
|
1277
|
+
mtimeMs: number | null;
|
|
1323
1278
|
}
|
|
1324
1279
|
|
|
1325
1280
|
// ────────────────────────────────────────────── Host on Bilko.run
|
|
@@ -1593,7 +1548,8 @@ export interface SessionManagerAPI {
|
|
|
1593
1548
|
gitBranch: (cwd: string) => Promise<string | null>;
|
|
1594
1549
|
/** Publish target for 'build'-tagged Epics — null disables the Build toolbar button. */
|
|
1595
1550
|
resolveBuildTarget: (cwd: string) => Promise<BuildTarget | null>;
|
|
1596
|
-
|
|
1551
|
+
/** Default: request a drain-first restart. `force: true` restarts immediately, killing running jobs. */
|
|
1552
|
+
rebootApp: (opts?: { force?: boolean }) => void;
|
|
1597
1553
|
testFireHook: (args: TestFireHookArgs) => Promise<TestFireHookResult>;
|
|
1598
1554
|
/** F7 — true under SM_E2E=1; renderer uses this to suppress wizard auto-trigger. */
|
|
1599
1555
|
isE2E: () => Promise<boolean>;
|
|
@@ -1615,6 +1571,7 @@ export interface SessionManagerAPI {
|
|
|
1615
1571
|
installPrdWriteGuard: (cwd: string) => Promise<InstallGuardResult>;
|
|
1616
1572
|
installDestructiveGitGuard: (cwd: string) => Promise<InstallGuardResult>;
|
|
1617
1573
|
installInlineImplementationGuard: (cwd: string) => Promise<InstallGuardResult>;
|
|
1574
|
+
installSelfScheduleGuard: (cwd: string) => Promise<InstallGuardResult>;
|
|
1618
1575
|
onNewSession: (handler: () => void) => () => void;
|
|
1619
1576
|
onRebootSession: (handler: () => void) => () => void;
|
|
1620
1577
|
archiveProject: (encoded: string) => Promise<{ ok: boolean; error?: string }>;
|
|
@@ -1832,6 +1789,7 @@ export interface SessionManagerAPI {
|
|
|
1832
1789
|
resetJob: (slug: string) => Promise<{ ok: boolean; error?: string }>;
|
|
1833
1790
|
runNow: () => Promise<{ ok: boolean }>;
|
|
1834
1791
|
forceTick: () => Promise<ActionOutcome>;
|
|
1792
|
+
pause: () => Promise<{ ok: boolean }>;
|
|
1835
1793
|
resume: () => Promise<{ ok: boolean }>;
|
|
1836
1794
|
/** Re-scan prds/ and merge into queue.json; broadcasts updated state. */
|
|
1837
1795
|
rescan: () => Promise<ActionOutcome>;
|
|
@@ -1875,10 +1833,6 @@ export interface SessionManagerAPI {
|
|
|
1875
1833
|
/** Return last 50 supervisor log entries, descending by ts. */
|
|
1876
1834
|
getLog: () => Promise<SupervisorLogEntry[]>;
|
|
1877
1835
|
};
|
|
1878
|
-
teams: {
|
|
1879
|
-
/** Enumerate ~/.claude/teams/<name>/config.json + inbox depths. */
|
|
1880
|
-
list: () => Promise<TeamsListResult>;
|
|
1881
|
-
};
|
|
1882
1836
|
plugins: {
|
|
1883
1837
|
/** Run `claude plugin install <slug>` in a hidden pty. Streams output
|
|
1884
1838
|
* via `onInstallProgress`. Returns { ok, exitCode } on exit.
|
|
@@ -1936,14 +1890,14 @@ export interface SessionManagerAPI {
|
|
|
1936
1890
|
update: (cwd: string, patch: ProjectBriefPatch) => Promise<ProjectBriefUpdateResult>;
|
|
1937
1891
|
};
|
|
1938
1892
|
projectPages: {
|
|
1939
|
-
/** Read
|
|
1893
|
+
/** Read project-pages/home.html (`{html: null, mtimeMs: null}` if it does not exist yet). Never fires an LLM call. */
|
|
1940
1894
|
get: (cwd: string) => Promise<ProjectPagesGetResult>;
|
|
1941
1895
|
/** Start pushing `onChanged` events for this cwd's output dir. Refcounted per cwd; `ok:false` (reason 'ephemeral'|'invalid-cwd') means no live updates are possible, not an error. */
|
|
1942
1896
|
watch: (cwd: string) => Promise<{ ok: boolean; reason?: 'ephemeral' | 'invalid-cwd' }>;
|
|
1943
1897
|
/** Stop pushing `onChanged` events for this cwd — must be paired 1:1 with a prior `watch` call. */
|
|
1944
1898
|
unwatch: (cwd: string) => Promise<{ ok: boolean }>;
|
|
1945
|
-
/** Fires whenever a watched cwd's
|
|
1946
|
-
onChanged: (handler: (payload: { cwd: string
|
|
1899
|
+
/** Fires whenever a watched cwd's home.html is added/changed/removed, carrying the freshly read result. */
|
|
1900
|
+
onChanged: (handler: (payload: { cwd: string } & ProjectPagesGetResult) => void) => () => void;
|
|
1947
1901
|
};
|
|
1948
1902
|
bilkoHost: {
|
|
1949
1903
|
/** Read compatibility-gate inputs + any existing bundle/publish state. Never fires an LLM call. */
|
package/src/preload/index.cjs
CHANGED
|
@@ -9,7 +9,7 @@ contextBridge.exposeInMainWorld('api', {
|
|
|
9
9
|
pickDirectory: () => ipcRenderer.invoke('app:pick-directory'),
|
|
10
10
|
gitBranch: (cwd) => ipcRenderer.invoke('app:git-branch', { cwd }),
|
|
11
11
|
resolveBuildTarget: (cwd) => ipcRenderer.invoke('build:resolve-target', { cwd }),
|
|
12
|
-
rebootApp: () => ipcRenderer.send('app:reboot-app'),
|
|
12
|
+
rebootApp: (opts) => ipcRenderer.send('app:reboot-app', opts),
|
|
13
13
|
archiveProject: (encoded) => ipcRenderer.invoke('app:archive-project', { encoded }),
|
|
14
14
|
testFireHook: (args) => ipcRenderer.invoke('app:test-fire-hook', args),
|
|
15
15
|
// F7: lets the renderer suppress the wizard auto-trigger under SM_E2E=1.
|
|
@@ -236,6 +236,7 @@ contextBridge.exposeInMainWorld('api', {
|
|
|
236
236
|
resetJob: (slug) => ipcRenderer.invoke('schedule:reset-job', { slug }),
|
|
237
237
|
runNow: () => ipcRenderer.invoke('schedule:run-now'),
|
|
238
238
|
forceTick: () => ipcRenderer.invoke('schedule:force-tick'),
|
|
239
|
+
pause: () => ipcRenderer.invoke('schedule:pause'),
|
|
239
240
|
resume: () => ipcRenderer.invoke('schedule:resume'),
|
|
240
241
|
rescan: () => ipcRenderer.invoke('schedule:rescan'),
|
|
241
242
|
clearQueue: () => ipcRenderer.invoke('schedule:clear-queue'),
|
|
@@ -281,9 +282,6 @@ contextBridge.exposeInMainWorld('api', {
|
|
|
281
282
|
tickNow: () => ipcRenderer.invoke('supervisor:tick-now'),
|
|
282
283
|
getLog: () => ipcRenderer.invoke('supervisor:get-log'),
|
|
283
284
|
},
|
|
284
|
-
teams: {
|
|
285
|
-
list: () => ipcRenderer.invoke('teams:list'),
|
|
286
|
-
},
|
|
287
285
|
plugins: {
|
|
288
286
|
install: (payload) => ipcRenderer.invoke('plugins:install', payload),
|
|
289
287
|
abort: (slug) => ipcRenderer.invoke('plugins:abort', slug),
|
|
@@ -1,59 +1,42 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: project-home-builder
|
|
3
|
-
description:
|
|
3
|
+
description: Reads a project and writes ONE self-contained overview page (home.html) for its Project Home tab, then saves it with a single project_home_write call.
|
|
4
4
|
tools: Read, Grep, Glob, Bash, Write, Edit
|
|
5
|
-
title: Project
|
|
5
|
+
title: Project Home — Builder
|
|
6
6
|
---
|
|
7
7
|
|
|
8
|
-
You are the project-home-builder. Your whole job is to
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
run — do not fall back to a remembered or assumed version of the pipeline shape.
|
|
21
|
-
3. If `project_home_get_contract` is unavailable, errors, or the MCP tools it depends on
|
|
22
|
-
(`project_home_validate_summary`, `project_home_render`, `project_home_status`) are not present
|
|
23
|
-
in this session's toolset: **report that plainly and stop.** Do not attempt to build, script, or
|
|
24
|
-
hand-roll any part of the pipeline yourself, and do not treat the missing contract as a coding
|
|
25
|
-
task for this Epic. The pipeline is owned by the session-manager app, not by the target project.
|
|
8
|
+
You are the project-home-builder. Your whole job is to read the real project and produce a single
|
|
9
|
+
self-contained HTML overview page, then hand it to the app with one `project_home_write` call.
|
|
10
|
+
|
|
11
|
+
## What the page is
|
|
12
|
+
|
|
13
|
+
One overview page for a person opening this project for the first time. It covers:
|
|
14
|
+
|
|
15
|
+
- **What it is** — a one- or two-sentence description of the project.
|
|
16
|
+
- **Who it's for** — the audience or user the project serves.
|
|
17
|
+
- **Structure** — the main directories/modules and what each one does.
|
|
18
|
+
- **How to run it** — the real install / build / start steps.
|
|
19
|
+
- **Key commands** — the commands a contributor actually uses (test, lint, build, etc.).
|
|
26
20
|
|
|
27
21
|
## Hard rules
|
|
28
22
|
|
|
29
|
-
- **Never fabricate.** Every
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
- **
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
- **
|
|
37
|
-
|
|
38
|
-
Don't skip straight to rendering an unvalidated summary.
|
|
39
|
-
- **Choose picks from the returned catalog only.** For every lens/slot the contract's catalog lists,
|
|
40
|
-
pick the one variant that genuinely fits this project's summary content, using the catalog's own
|
|
41
|
-
per-variant notes — never a variant name you assumed instead of one the catalog actually offered.
|
|
42
|
-
- **Respect existing picks on a regenerate.** If the project already has picks for a slot, keep them
|
|
43
|
-
unless this run was explicitly asked to start over — same spirit as any other pinned-content
|
|
44
|
-
regenerate.
|
|
45
|
-
- **Cost-gated, manual only.** This is a real-cost pass. Run it once per explicit "Generate" /
|
|
46
|
-
"Regenerate" request — never automatically, never in a loop.
|
|
23
|
+
- **Never fabricate.** Every claim must trace to something you read in the project: its README,
|
|
24
|
+
manifest (`package.json`, `pyproject.toml`, ...), source tree, docs, or git history. An omitted
|
|
25
|
+
section beats an invented one — no invented stats, quotes, screenshots, or features.
|
|
26
|
+
- **Read before you write.** Explore the repo itself (tree, manifest, docs, recent git log) first.
|
|
27
|
+
- **Self-contained HTML only.** One complete HTML document with all CSS inline in a `<style>` block.
|
|
28
|
+
No `<script src>`, no `<link href="http...">`, no `@import`, no `url(http...)`, no external fonts
|
|
29
|
+
or images. Keep it under 1 MB. Support both light and dark color schemes.
|
|
30
|
+
- **Cost-gated, manual only.** Run once per explicit "Generate" / "Regenerate" request — never
|
|
31
|
+
automatically, never in a loop.
|
|
47
32
|
|
|
48
33
|
## Protocol
|
|
49
34
|
|
|
50
|
-
1.
|
|
51
|
-
2.
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
4.
|
|
55
|
-
in
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
6. `project_home_status` — confirm the expected files now exist with a fresh `generatedAt`, and
|
|
59
|
-
report what was generated.
|
|
35
|
+
1. Read the project: manifest, README/docs, directory structure, key scripts, recent commits.
|
|
36
|
+
2. Compose the single HTML document described above.
|
|
37
|
+
3. Call `project_home_write` exactly once with `{ html }`. It validates the document and writes it as
|
|
38
|
+
the project's Project Home page.
|
|
39
|
+
4. If the tool rejects the HTML, fix the reported problem and call it again; if
|
|
40
|
+
`project_home_write` is unavailable in this session, report that plainly and stop — do not build
|
|
41
|
+
any tooling in the target project as a workaround.
|
|
42
|
+
5. Report in one or two lines what the page covers.
|
package/screenshots/.gitkeep
DELETED
|
File without changes
|