panopticon-cli 0.5.3 → 0.5.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (122) hide show
  1. package/dist/{agents-DMPT32H7.js → agents-5HWTDR4S.js} +12 -9
  2. package/dist/archive-planning-U3AZAKWI.js +16 -0
  3. package/dist/{chunk-KBHRXV5T.js → chunk-43F4LDZ4.js} +3 -3
  4. package/dist/chunk-6OYUJ4AJ.js +146 -0
  5. package/dist/chunk-6OYUJ4AJ.js.map +1 -0
  6. package/dist/{chunk-MOPGR3CL.js → chunk-AAP4G6U7.js} +1 -1
  7. package/dist/chunk-AAP4G6U7.js.map +1 -0
  8. package/dist/{chunk-4HST45MO.js → chunk-BYWVPPAZ.js} +19 -12
  9. package/dist/chunk-BYWVPPAZ.js.map +1 -0
  10. package/dist/{chunk-CFCUOV3Q.js → chunk-DMRTN432.js} +4 -1
  11. package/dist/chunk-DMRTN432.js.map +1 -0
  12. package/dist/{chunk-HOGYHJ2G.js → chunk-DW3PKGIS.js} +2 -2
  13. package/dist/{chunk-D67AQTHF.js → chunk-FUUP55PE.js} +108 -46
  14. package/dist/chunk-FUUP55PE.js.map +1 -0
  15. package/dist/chunk-GUV2EPBG.js +692 -0
  16. package/dist/chunk-GUV2EPBG.js.map +1 -0
  17. package/dist/{chunk-44EOY2ZL.js → chunk-HHL3AWXA.js} +46 -2
  18. package/dist/chunk-HHL3AWXA.js.map +1 -0
  19. package/dist/{chunk-6N2KBSJA.js → chunk-IZIXJYXZ.js} +40 -6
  20. package/dist/chunk-IZIXJYXZ.js.map +1 -0
  21. package/dist/chunk-MJXYTGK5.js +64 -0
  22. package/dist/chunk-MJXYTGK5.js.map +1 -0
  23. package/dist/chunk-OJF4QS3S.js +269 -0
  24. package/dist/chunk-OJF4QS3S.js.map +1 -0
  25. package/dist/{chunk-FQ66DECN.js → chunk-QAJAJBFW.js} +1 -1
  26. package/dist/chunk-QAJAJBFW.js.map +1 -0
  27. package/dist/chunk-R4KPLLRB.js +36 -0
  28. package/dist/chunk-R4KPLLRB.js.map +1 -0
  29. package/dist/{chunk-DFNVHK3N.js → chunk-SUM2WVPF.js} +4 -4
  30. package/dist/{chunk-T7BBPDEJ.js → chunk-UKSGE6RH.js} +45 -15
  31. package/dist/chunk-UKSGE6RH.js.map +1 -0
  32. package/dist/chunk-W2OTF6OS.js +201 -0
  33. package/dist/chunk-W2OTF6OS.js.map +1 -0
  34. package/dist/chunk-WEQW3EAT.js +78 -0
  35. package/dist/chunk-WEQW3EAT.js.map +1 -0
  36. package/dist/{chunk-2V2DQ3IX.js → chunk-WJJ3ZIQ6.js} +112 -45
  37. package/dist/chunk-WJJ3ZIQ6.js.map +1 -0
  38. package/dist/chunk-YAAT66RT.js +70 -0
  39. package/dist/chunk-YAAT66RT.js.map +1 -0
  40. package/dist/{chunk-RLZQB7HS.js → chunk-ZMJFEHGF.js} +13 -1
  41. package/dist/chunk-ZMJFEHGF.js.map +1 -0
  42. package/dist/{chunk-HRU7S4TA.js → chunk-ZN5RHWGR.js} +18 -208
  43. package/dist/{chunk-HRU7S4TA.js.map → chunk-ZN5RHWGR.js.map} +1 -1
  44. package/dist/{chunk-ZTYHZMEC.js → chunk-ZWZNEA26.js} +2 -2
  45. package/dist/clean-planning-7Z5YY64X.js +9 -0
  46. package/dist/cli/index.js +1314 -2146
  47. package/dist/cli/index.js.map +1 -1
  48. package/dist/close-issue-CTZK777I.js +9 -0
  49. package/dist/compact-beads-72SHALOL.js +9 -0
  50. package/dist/{config-4CJNUE3O.js → config-FFTMBVHM.js} +2 -2
  51. package/dist/dashboard/public/assets/{index-BJKEp64j.css → index-Bx4NCn9A.css} +1 -1
  52. package/dist/dashboard/public/assets/index-Db9NOz4z.js +756 -0
  53. package/dist/dashboard/public/index.html +3 -2
  54. package/dist/dashboard/server.js +34785 -34330
  55. package/dist/{feedback-writer-T43PI5S2.js → feedback-writer-T2WCT6EZ.js} +2 -2
  56. package/dist/{hume-CKJJ3OUU.js → hume-GVTB5BKW.js} +3 -3
  57. package/dist/index.d.ts +24 -16
  58. package/dist/index.js +4 -4
  59. package/dist/label-cleanup-4HJVX6NP.js +103 -0
  60. package/dist/label-cleanup-4HJVX6NP.js.map +1 -0
  61. package/dist/merge-agent-WM7ZKUET.js +1725 -0
  62. package/dist/merge-agent-WM7ZKUET.js.map +1 -0
  63. package/dist/{projects-KVM3MN3Y.js → projects-3CRF57ZU.js} +2 -2
  64. package/dist/{rally-RKFSWC7E.js → rally-LBY24P4C.js} +2 -2
  65. package/dist/{remote-agents-ULPD6C5U.js → remote-agents-3NZPSHYG.js} +2 -3
  66. package/dist/{remote-workspace-XX6ARE6I.js → remote-workspace-M4IULGFZ.js} +24 -49
  67. package/dist/remote-workspace-M4IULGFZ.js.map +1 -0
  68. package/dist/{review-status-XKUKZF6J.js → review-status-J2YJGL3E.js} +2 -2
  69. package/dist/{specialist-context-53AWO6AE.js → specialist-context-74RQF5SR.js} +7 -5
  70. package/dist/{specialist-context-53AWO6AE.js.map → specialist-context-74RQF5SR.js.map} +1 -1
  71. package/dist/{specialist-logs-QREUJ4HN.js → specialist-logs-T5GW7CSU.js} +6 -4
  72. package/dist/{specialists-2DBBXRCK.js → specialists-HTYYFXHQ.js} +6 -4
  73. package/dist/specialists-HTYYFXHQ.js.map +1 -0
  74. package/dist/tmux-X2I5SAIJ.js +31 -0
  75. package/dist/tmux-X2I5SAIJ.js.map +1 -0
  76. package/dist/{traefik-5GL3Q7DJ.js → traefik-QXLZ4PO2.js} +4 -4
  77. package/dist/traefik-QXLZ4PO2.js.map +1 -0
  78. package/dist/{tunnel-BKC7KLBX.js → tunnel-7IOSRZVH.js} +3 -3
  79. package/dist/tunnel-7IOSRZVH.js.map +1 -0
  80. package/dist/{workspace-manager-ALBR62AS.js → workspace-manager-G6TTBPC3.js} +6 -6
  81. package/dist/workspace-manager-G6TTBPC3.js.map +1 -0
  82. package/package.json +2 -2
  83. package/scripts/build-cost-script.mjs +17 -0
  84. package/scripts/heartbeat-hook +28 -8
  85. package/scripts/record-cost-event.js +46 -7
  86. package/scripts/record-cost-event.ts +2 -1
  87. package/scripts/recover-costs-deep.mjs +209 -0
  88. package/scripts/recover-costs-proportional.mjs +206 -0
  89. package/scripts/recover-costs.mjs +169 -0
  90. package/dist/chunk-2V2DQ3IX.js.map +0 -1
  91. package/dist/chunk-44EOY2ZL.js.map +0 -1
  92. package/dist/chunk-4HST45MO.js.map +0 -1
  93. package/dist/chunk-565HZ6VV.js +0 -159
  94. package/dist/chunk-565HZ6VV.js.map +0 -1
  95. package/dist/chunk-6N2KBSJA.js.map +0 -1
  96. package/dist/chunk-CFCUOV3Q.js.map +0 -1
  97. package/dist/chunk-D67AQTHF.js.map +0 -1
  98. package/dist/chunk-FQ66DECN.js.map +0 -1
  99. package/dist/chunk-MOPGR3CL.js.map +0 -1
  100. package/dist/chunk-RLZQB7HS.js.map +0 -1
  101. package/dist/chunk-T7BBPDEJ.js.map +0 -1
  102. package/dist/chunk-ZDNQFWR5.js +0 -650
  103. package/dist/chunk-ZDNQFWR5.js.map +0 -1
  104. package/dist/dashboard/public/assets/index-CgJjqjAV.js +0 -767
  105. package/dist/remote-workspace-XX6ARE6I.js.map +0 -1
  106. /package/dist/{agents-DMPT32H7.js.map → agents-5HWTDR4S.js.map} +0 -0
  107. /package/dist/{config-4CJNUE3O.js.map → archive-planning-U3AZAKWI.js.map} +0 -0
  108. /package/dist/{chunk-KBHRXV5T.js.map → chunk-43F4LDZ4.js.map} +0 -0
  109. /package/dist/{chunk-HOGYHJ2G.js.map → chunk-DW3PKGIS.js.map} +0 -0
  110. /package/dist/{chunk-DFNVHK3N.js.map → chunk-SUM2WVPF.js.map} +0 -0
  111. /package/dist/{chunk-ZTYHZMEC.js.map → chunk-ZWZNEA26.js.map} +0 -0
  112. /package/dist/{hume-CKJJ3OUU.js.map → clean-planning-7Z5YY64X.js.map} +0 -0
  113. /package/dist/{projects-KVM3MN3Y.js.map → close-issue-CTZK777I.js.map} +0 -0
  114. /package/dist/{rally-RKFSWC7E.js.map → compact-beads-72SHALOL.js.map} +0 -0
  115. /package/dist/{remote-agents-ULPD6C5U.js.map → config-FFTMBVHM.js.map} +0 -0
  116. /package/dist/{feedback-writer-T43PI5S2.js.map → feedback-writer-T2WCT6EZ.js.map} +0 -0
  117. /package/dist/{review-status-XKUKZF6J.js.map → hume-GVTB5BKW.js.map} +0 -0
  118. /package/dist/{specialist-logs-QREUJ4HN.js.map → projects-3CRF57ZU.js.map} +0 -0
  119. /package/dist/{specialists-2DBBXRCK.js.map → rally-LBY24P4C.js.map} +0 -0
  120. /package/dist/{traefik-5GL3Q7DJ.js.map → remote-agents-3NZPSHYG.js.map} +0 -0
  121. /package/dist/{tunnel-BKC7KLBX.js.map → review-status-J2YJGL3E.js.map} +0 -0
  122. /package/dist/{workspace-manager-ALBR62AS.js.map → specialist-logs-T5GW7CSU.js.map} +0 -0
@@ -1,20 +1,15 @@
1
1
  import {
2
- capturePaneAsync,
2
+ init_pipeline_notifier,
3
+ notifyPipeline
4
+ } from "./chunk-JQBV3Q2W.js";
5
+ import {
3
6
  checkHook,
4
- confirmDelivery,
5
7
  getModelId,
6
8
  init_hooks,
7
- init_tmux,
8
9
  init_work_type_router,
9
10
  popFromHook,
10
- pushToHook,
11
- sendKeysAsync,
12
- waitForClaudePrompt
13
- } from "./chunk-HRU7S4TA.js";
14
- import {
15
- init_pipeline_notifier,
16
- notifyPipeline
17
- } from "./chunk-JQBV3Q2W.js";
11
+ pushToHook
12
+ } from "./chunk-ZN5RHWGR.js";
18
13
  import {
19
14
  clearCredentialFileAuth,
20
15
  getProviderEnv,
@@ -25,9 +20,21 @@ import {
25
20
  setupCredentialFileAuth
26
21
  } from "./chunk-USYP2SBE.js";
27
22
  import {
23
+ getDevrootPath,
24
+ init_config
25
+ } from "./chunk-QAJAJBFW.js";
26
+ import {
27
+ getProject,
28
28
  init_projects,
29
29
  projects_exports
30
- } from "./chunk-RLZQB7HS.js";
30
+ } from "./chunk-ZMJFEHGF.js";
31
+ import {
32
+ capturePaneAsync,
33
+ confirmDelivery,
34
+ init_tmux,
35
+ sendKeysAsync,
36
+ waitForClaudePrompt
37
+ } from "./chunk-W2OTF6OS.js";
31
38
  import {
32
39
  COSTS_DIR,
33
40
  PANOPTICON_HOME,
@@ -609,7 +616,7 @@ import { join as join4, basename as basename2 } from "path";
609
616
  import { homedir as homedir2 } from "os";
610
617
  import { exec } from "child_process";
611
618
  import { promisify } from "util";
612
- import { randomUUID } from "crypto";
619
+ import { randomUUID, createHash } from "crypto";
613
620
  async function resolveWorkspaceGitInfo(workspace, taskBranch) {
614
621
  const gitDirs = [];
615
622
  let branch = taskBranch || "unknown";
@@ -750,6 +757,10 @@ function saveRegistry(registry) {
750
757
  throw error;
751
758
  }
752
759
  }
760
+ function deterministicUUID(input) {
761
+ const hash = createHash("sha256").update(input).digest("hex");
762
+ return `${hash.slice(0, 8)}-${hash.slice(8, 12)}-${hash.slice(12, 16)}-${hash.slice(16, 20)}-${hash.slice(20, 32)}`;
763
+ }
753
764
  function getSessionFilePath(name, projectKey) {
754
765
  if (projectKey) {
755
766
  return join4(SPECIALISTS_DIR, "projects", projectKey, `${name}.session`);
@@ -762,7 +773,14 @@ function getSessionId(name, projectKey) {
762
773
  return null;
763
774
  }
764
775
  try {
765
- return readFileSync4(sessionFile, "utf-8").trim();
776
+ const sessionId = readFileSync4(sessionFile, "utf-8").trim();
777
+ const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
778
+ if (!uuidRegex.test(sessionId)) {
779
+ console.warn(`[specialist] Invalid session ID format for ${name} (${projectKey ?? "global"}): ${sessionId} \u2014 discarding`);
780
+ unlinkSync(sessionFile);
781
+ return null;
782
+ }
783
+ return sessionId;
766
784
  } catch (error) {
767
785
  console.error(`Failed to read session file for ${name} (${projectKey ?? "global"}):`, error);
768
786
  return null;
@@ -841,9 +859,9 @@ function recordWake(name, sessionId) {
841
859
  }
842
860
  async function spawnEphemeralSpecialist(projectKey, specialistType, task) {
843
861
  ensureProjectSpecialistDir(projectKey, specialistType);
844
- const { loadContextDigest } = await import("./specialist-context-53AWO6AE.js");
862
+ const { loadContextDigest } = await import("./specialist-context-74RQF5SR.js");
845
863
  const contextDigest = loadContextDigest(projectKey, specialistType);
846
- const { createRunLog: createRunLog2 } = await import("./specialist-logs-QREUJ4HN.js");
864
+ const { createRunLog: createRunLog2 } = await import("./specialist-logs-T5GW7CSU.js");
847
865
  const { runId, filePath: logFilePath } = createRunLog2(
848
866
  projectKey,
849
867
  specialistType,
@@ -852,17 +870,26 @@ async function spawnEphemeralSpecialist(projectKey, specialistType, task) {
852
870
  );
853
871
  setCurrentRun(projectKey, specialistType, runId);
854
872
  incrementProjectRunCount(projectKey, specialistType);
855
- const taskPrompt = task.promptOverride ?? await buildTaskPrompt(projectKey, specialistType, task, contextDigest);
873
+ const basePrompt = task.promptOverride ?? await buildTaskPrompt(projectKey, specialistType, task, contextDigest);
856
874
  if (task.promptOverride) {
857
- console.log(`[specialist] Using promptOverride for ${projectKey}/${task.issueId} (${taskPrompt.length} chars)`);
875
+ console.log(`[specialist] Using promptOverride for ${projectKey}/${task.issueId} (${basePrompt.length} chars)`);
858
876
  }
877
+ const taskPrompt = `IMPORTANT: This is a NEW task dispatch. You may have context from prior runs in this session \u2014 that is useful background knowledge, but you MUST execute this task fresh RIGHT NOW. Do NOT skip steps or report cached results. Read the code, run the commands, and call the status update APIs as instructed below. Prior results are stale \u2014 the code may have changed.
878
+
879
+ ${basePrompt}`;
859
880
  const tmuxSession = getTmuxSessionName(specialistType, projectKey);
860
- const cwd = homedir2();
881
+ const project = getProject(projectKey);
882
+ const cwd = project?.path || getDevrootPath() || homedir2();
883
+ try {
884
+ const { preTrustDirectory } = await import("./workspace-manager-G6TTBPC3.js");
885
+ preTrustDirectory(cwd);
886
+ } catch {
887
+ }
861
888
  try {
862
889
  try {
863
890
  const { stdout: sessions } = await execAsync('tmux list-sessions -F "#{session_name}" 2>/dev/null || echo ""', { encoding: "utf-8" });
864
891
  if (sessions.split("\n").map((s) => s.trim()).includes(tmuxSession)) {
865
- const { getAgentRuntimeState } = await import("./agents-DMPT32H7.js");
892
+ const { getAgentRuntimeState } = await import("./agents-5HWTDR4S.js");
866
893
  const existingState = getAgentRuntimeState(tmuxSession);
867
894
  if (existingState?.state === "active") {
868
895
  return {
@@ -885,7 +912,13 @@ async function spawnEphemeralSpecialist(projectKey, specialistType, task) {
885
912
  console.warn(`Warning: Could not resolve model for ${specialistType}, using default`);
886
913
  }
887
914
  const providerEnv = getProviderEnvForModel(model);
888
- const envFlags = buildTmuxEnvFlags(providerEnv);
915
+ const sessionTypeLabel = specialistType.replace("-agent", "");
916
+ const panopticonEnv = {
917
+ PANOPTICON_AGENT_ID: tmuxSession,
918
+ PANOPTICON_ISSUE_ID: task.issueId,
919
+ PANOPTICON_SESSION_TYPE: sessionTypeLabel
920
+ };
921
+ const envFlags = buildTmuxEnvFlags({ ...providerEnv, ...panopticonEnv });
889
922
  const providerConfig = getProviderForModel(model);
890
923
  if (providerConfig.authType === "credential-file") {
891
924
  setupCredentialFileAuth(providerConfig, cwd);
@@ -897,29 +930,48 @@ async function spawnEphemeralSpecialist(projectKey, specialistType, task) {
897
930
  await execAsync(`mkdir -p "${agentDir}"`, { encoding: "utf-8" });
898
931
  const promptFile = join4(agentDir, "task-prompt.md");
899
932
  writeFileSync2(promptFile, taskPrompt);
933
+ const sessionName = `specialist-${projectKey}-${specialistType}`;
934
+ const sessionId = deterministicUUID(sessionName);
935
+ setSessionId(specialistType, sessionId, projectKey);
936
+ console.log(`[specialist] Dispatching ${specialistType} for ${projectKey}/${task.issueId} (session: ${sessionId.slice(0, 8)}...)`);
900
937
  const launcherScript = join4(agentDir, "launcher.sh");
901
- writeFileSync2(launcherScript, `#!/bin/bash
938
+ const innerScript = join4(agentDir, "run-claude.sh");
939
+ writeFileSync2(innerScript, `#!/bin/bash
940
+ set -o pipefail
902
941
  cd "${cwd}"
942
+ export PANOPTICON_AGENT_ID="${tmuxSession}"
943
+ export PANOPTICON_ISSUE_ID="${task.issueId}"
944
+ export PANOPTICON_SESSION_TYPE="${sessionTypeLabel}"
903
945
  prompt=$(cat "${promptFile}")
904
946
 
905
- # Run Claude and tee output to log file
906
- claude ${permissionFlags} --model ${model} "$prompt" 2>&1 | tee -a "${logFilePath}"
947
+ # Resume existing session (normal case \u2014 accumulates context over time)
948
+ claude ${permissionFlags} --resume "${sessionId}" --model ${model} "$prompt"
949
+ exit_code=$?
950
+
951
+ # First cold start: session doesn't exist yet in Claude's storage
952
+ if [ $exit_code -ne 0 ]; then
953
+ echo "[launcher] First run \u2014 creating session"
954
+ claude ${permissionFlags} --session-id "${sessionId}" --model ${model} "$prompt"
955
+ fi
907
956
 
908
957
  # Signal completion
909
958
  echo ""
910
959
  echo "## Specialist completed task"
960
+ `, { mode: 493 });
961
+ writeFileSync2(launcherScript, `#!/bin/bash
962
+ script -qfec "bash '${innerScript}'" /dev/null 2>&1 | tee -a "${logFilePath}"
911
963
  `, { mode: 493 });
912
964
  await execAsync(
913
965
  `tmux new-session -d -s "${tmuxSession}"${envFlags} "bash '${launcherScript}'"`,
914
966
  { encoding: "utf-8" }
915
967
  );
916
- const { saveAgentRuntimeState } = await import("./agents-DMPT32H7.js");
968
+ const { saveAgentRuntimeState } = await import("./agents-5HWTDR4S.js");
917
969
  saveAgentRuntimeState(tmuxSession, {
918
970
  state: "active",
919
971
  lastActivity: (/* @__PURE__ */ new Date()).toISOString(),
920
972
  currentIssue: task.issueId
921
973
  });
922
- console.log(`[specialist] Spawned ephemeral ${specialistType} for ${projectKey}/${task.issueId} (run: ${runId})`);
974
+ console.log(`[specialist] Spawned ${specialistType} for ${projectKey}/${task.issueId} (run: ${runId})`);
923
975
  return {
924
976
  success: true,
925
977
  runId,
@@ -937,7 +989,7 @@ echo "## Specialist completed task"
937
989
  }
938
990
  }
939
991
  async function buildTaskPrompt(projectKey, specialistType, task, contextDigest) {
940
- const { getSpecialistPromptOverride } = await import("./projects-KVM3MN3Y.js");
992
+ const { getSpecialistPromptOverride } = await import("./projects-3CRF57ZU.js");
941
993
  const customPrompt = getSpecialistPromptOverride(projectKey, specialistType);
942
994
  let prompt = `# ${specialistType} Task - ${task.issueId}
943
995
 
@@ -1107,7 +1159,7 @@ async function terminateSpecialist(projectKey, specialistType) {
1107
1159
  console.error(`[specialist] Failed to kill tmux session ${tmuxSession}:`, error);
1108
1160
  }
1109
1161
  if (metadata.currentRun) {
1110
- const { finalizeRunLog: finalizeRunLog2 } = await import("./specialist-logs-QREUJ4HN.js");
1162
+ const { finalizeRunLog: finalizeRunLog2 } = await import("./specialist-logs-T5GW7CSU.js");
1111
1163
  try {
1112
1164
  finalizeRunLog2(projectKey, specialistType, metadata.currentRun, {
1113
1165
  status: metadata.lastRunStatus || "incomplete",
@@ -1120,20 +1172,20 @@ async function terminateSpecialist(projectKey, specialistType) {
1120
1172
  }
1121
1173
  const key = `${projectKey}-${specialistType}`;
1122
1174
  gracePeriodStates.delete(key);
1123
- const { saveAgentRuntimeState } = await import("./agents-DMPT32H7.js");
1175
+ const { saveAgentRuntimeState } = await import("./agents-5HWTDR4S.js");
1124
1176
  saveAgentRuntimeState(tmuxSession, {
1125
1177
  state: "suspended",
1126
1178
  lastActivity: (/* @__PURE__ */ new Date()).toISOString()
1127
1179
  });
1128
- const { scheduleDigestGeneration } = await import("./specialist-context-53AWO6AE.js");
1180
+ const { scheduleDigestGeneration } = await import("./specialist-context-74RQF5SR.js");
1129
1181
  scheduleDigestGeneration(projectKey, specialistType);
1130
1182
  scheduleLogCleanup(projectKey, specialistType);
1131
1183
  }
1132
1184
  function scheduleLogCleanup(projectKey, specialistType) {
1133
1185
  Promise.resolve().then(async () => {
1134
1186
  try {
1135
- const { cleanupOldLogs: cleanupOldLogs2 } = await import("./specialist-logs-QREUJ4HN.js");
1136
- const { getSpecialistRetention } = await import("./projects-KVM3MN3Y.js");
1187
+ const { cleanupOldLogs: cleanupOldLogs2 } = await import("./specialist-logs-T5GW7CSU.js");
1188
+ const { getSpecialistRetention } = await import("./projects-3CRF57ZU.js");
1137
1189
  const retention = getSpecialistRetention(projectKey);
1138
1190
  const deleted = cleanupOldLogs2(projectKey, specialistType, { maxDays: retention.max_days, maxRuns: retention.max_runs });
1139
1191
  if (deleted > 0) {
@@ -1321,7 +1373,7 @@ async function getSpecialistStatus(name, projectKey) {
1321
1373
  const sessionId = getSessionId(name, projectKey);
1322
1374
  const running = await isRunning(name, projectKey);
1323
1375
  const contextTokens = countContextTokens(name);
1324
- const { getAgentRuntimeState } = await import("./agents-DMPT32H7.js");
1376
+ const { getAgentRuntimeState } = await import("./agents-5HWTDR4S.js");
1325
1377
  const tmuxSession = getTmuxSessionName(name, projectKey);
1326
1378
  const runtimeState = getAgentRuntimeState(tmuxSession);
1327
1379
  let state;
@@ -1476,7 +1528,7 @@ async function wakeSpecialist(name, taskPrompt, options = {}) {
1476
1528
  const sessionId = getSessionId(name);
1477
1529
  const wasAlreadyRunning = await isRunning(name);
1478
1530
  if (wasAlreadyRunning && !options.skipBusyGuard) {
1479
- const { getAgentRuntimeState } = await import("./agents-DMPT32H7.js");
1531
+ const { getAgentRuntimeState } = await import("./agents-5HWTDR4S.js");
1480
1532
  const runtimeState = getAgentRuntimeState(tmuxSession);
1481
1533
  if (runtimeState?.state === "active") {
1482
1534
  console.warn(`[specialist] ${name} is busy (working on ${runtimeState.currentIssue}), refusing to interrupt`);
@@ -1498,7 +1550,12 @@ async function wakeSpecialist(name, taskPrompt, options = {}) {
1498
1550
  error: "not_running"
1499
1551
  };
1500
1552
  }
1501
- const cwd = process.env.HOME || "/home/eltmon";
1553
+ const cwd = getDevrootPath() || join4(process.env.HOME || "/home/eltmon", "Projects");
1554
+ try {
1555
+ const { preTrustDirectory } = await import("./workspace-manager-G6TTBPC3.js");
1556
+ preTrustDirectory(cwd);
1557
+ } catch {
1558
+ }
1502
1559
  try {
1503
1560
  let model = "claude-sonnet-4-6";
1504
1561
  try {
@@ -1509,7 +1566,15 @@ async function wakeSpecialist(name, taskPrompt, options = {}) {
1509
1566
  }
1510
1567
  const modelFlag = `--model ${model}`;
1511
1568
  const providerEnv = getProviderEnvForModel(model);
1512
- const envFlags = buildTmuxEnvFlags(providerEnv);
1569
+ const wakeSessionType = name.replace("-agent", "");
1570
+ const wakePanEnv = {
1571
+ PANOPTICON_AGENT_ID: tmuxSession,
1572
+ PANOPTICON_SESSION_TYPE: wakeSessionType
1573
+ };
1574
+ if (issueId) {
1575
+ wakePanEnv.PANOPTICON_ISSUE_ID = issueId;
1576
+ }
1577
+ const envFlags = buildTmuxEnvFlags({ ...providerEnv, ...wakePanEnv });
1513
1578
  const provCfg = getProviderForModel(model);
1514
1579
  if (provCfg.authType === "credential-file") {
1515
1580
  setupCredentialFileAuth(provCfg, cwd);
@@ -1582,7 +1647,7 @@ async function wakeSpecialist(name, taskPrompt, options = {}) {
1582
1647
  }
1583
1648
  }
1584
1649
  recordWake(name, sessionId || void 0);
1585
- const { saveAgentRuntimeState } = await import("./agents-DMPT32H7.js");
1650
+ const { saveAgentRuntimeState } = await import("./agents-5HWTDR4S.js");
1586
1651
  saveAgentRuntimeState(tmuxSession, {
1587
1652
  state: "active",
1588
1653
  lastActivity: (/* @__PURE__ */ new Date()).toISOString(),
@@ -1684,14 +1749,14 @@ CRITICAL: Do NOT delete the feature branch.`;
1684
1749
  if (totalChangedFiles === 0) {
1685
1750
  staleBranch = true;
1686
1751
  console.log(`[specialist] review-agent: stale branch detected for ${task.issueId} \u2014 0 files changed vs main`);
1687
- const { setReviewStatus } = await import("./review-status-XKUKZF6J.js");
1752
+ const { setReviewStatus } = await import("./review-status-J2YJGL3E.js");
1688
1753
  setReviewStatus(task.issueId.toUpperCase(), {
1689
1754
  reviewStatus: "passed",
1690
1755
  reviewNotes: "No changes to review \u2014 branch identical to main (already merged or stale)"
1691
1756
  });
1692
1757
  console.log(`[specialist] review-agent: auto-passed ${task.issueId} (stale branch)`);
1693
1758
  const tmuxSession = getTmuxSessionName("review-agent");
1694
- const { saveAgentRuntimeState } = await import("./agents-DMPT32H7.js");
1759
+ const { saveAgentRuntimeState } = await import("./agents-5HWTDR4S.js");
1695
1760
  saveAgentRuntimeState(tmuxSession, {
1696
1761
  state: "idle",
1697
1762
  lastActivity: (/* @__PURE__ */ new Date()).toISOString()
@@ -1796,7 +1861,7 @@ curl -s -X POST ${apiUrl}/api/specialists/test-agent/queue -H "Content-Type: app
1796
1861
  const testWorkspace = task.workspace || "unknown";
1797
1862
  const testGitInfo = await resolveWorkspaceGitInfo(task.workspace, task.branch);
1798
1863
  const testIsPolyrepo = testGitInfo.isPolyrepo;
1799
- const { extractTeamPrefix, findProjectByTeam } = await import("./projects-KVM3MN3Y.js");
1864
+ const { extractTeamPrefix, findProjectByTeam } = await import("./projects-3CRF57ZU.js");
1800
1865
  const testTeamPrefix = extractTeamPrefix(task.issueId);
1801
1866
  const testProjectConfig = testTeamPrefix ? findProjectByTeam(testTeamPrefix) : null;
1802
1867
  const testConfigs = testProjectConfig?.tests;
@@ -1935,7 +2000,7 @@ IMPORTANT: Do NOT hand off to merge-agent. Human clicks Merge button when ready.
1935
2000
  async function wakeSpecialistOrQueue(name, task, options = {}) {
1936
2001
  const { priority = "normal", source = "handoff" } = options;
1937
2002
  const running = await isRunning(name);
1938
- const { getAgentRuntimeState } = await import("./agents-DMPT32H7.js");
2003
+ const { getAgentRuntimeState } = await import("./agents-5HWTDR4S.js");
1939
2004
  const tmuxSession = getTmuxSessionName(name);
1940
2005
  const runtimeState = getAgentRuntimeState(tmuxSession);
1941
2006
  const idle = runtimeState?.state === "idle" || runtimeState?.state === "suspended";
@@ -1966,7 +2031,7 @@ async function wakeSpecialistOrQueue(name, task, options = {}) {
1966
2031
  };
1967
2032
  }
1968
2033
  }
1969
- const { saveAgentRuntimeState } = await import("./agents-DMPT32H7.js");
2034
+ const { saveAgentRuntimeState } = await import("./agents-5HWTDR4S.js");
1970
2035
  saveAgentRuntimeState(tmuxSession, {
1971
2036
  state: "active",
1972
2037
  lastActivity: (/* @__PURE__ */ new Date()).toISOString(),
@@ -2066,7 +2131,7 @@ async function sendFeedbackToAgent(feedback) {
2066
2131
  }
2067
2132
  const agentSession = `agent-${toIssueId.toLowerCase()}`;
2068
2133
  const feedbackMessage = formatFeedbackForAgent(fullFeedback);
2069
- const { writeFeedbackFile } = await import("./feedback-writer-T43PI5S2.js");
2134
+ const { writeFeedbackFile } = await import("./feedback-writer-T2WCT6EZ.js");
2070
2135
  const specialistMap = {
2071
2136
  "review-agent": "review-agent",
2072
2137
  "test-agent": "test-agent",
@@ -2086,7 +2151,7 @@ async function sendFeedbackToAgent(feedback) {
2086
2151
  return false;
2087
2152
  }
2088
2153
  try {
2089
- const { messageAgent } = await import("./agents-DMPT32H7.js");
2154
+ const { messageAgent } = await import("./agents-5HWTDR4S.js");
2090
2155
  const msg = `SPECIALIST FEEDBACK: ${fromSpecialist} reported ${feedback.feedbackType.toUpperCase()} for ${toIssueId}.
2091
2156
  Read and address: ${fileResult.relativePath}`;
2092
2157
  await messageAgent(agentSession, msg);
@@ -2190,6 +2255,8 @@ var init_specialists = __esm({
2190
2255
  "src/lib/cloister/specialists.ts"() {
2191
2256
  init_esm_shims();
2192
2257
  init_paths();
2258
+ init_config();
2259
+ init_projects();
2193
2260
  init_jsonl_parser();
2194
2261
  init_specialist_handoff_logger();
2195
2262
  init_settings();
@@ -2593,4 +2660,4 @@ export {
2593
2660
  getFeedbackStats,
2594
2661
  init_specialists
2595
2662
  };
2596
- //# sourceMappingURL=chunk-2V2DQ3IX.js.map
2663
+ //# sourceMappingURL=chunk-WJJ3ZIQ6.js.map