panopticon-cli 0.5.6 → 0.5.8

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/dist/cli/index.js CHANGED
@@ -16,7 +16,8 @@ import {
16
16
  init_database,
17
17
  init_review_status,
18
18
  loadReviewStatuses,
19
- saveReviewStatuses
19
+ saveReviewStatuses,
20
+ setReviewStatus
20
21
  } from "../chunk-IZIXJYXZ.js";
21
22
  import {
22
23
  checkBudget,
@@ -49,7 +50,7 @@ import {
49
50
  setSessionId,
50
51
  summarizeCosts,
51
52
  wakeSpecialistOrQueue
52
- } from "../chunk-WJJ3ZIQ6.js";
53
+ } from "../chunk-M6ZVVKZ3.js";
53
54
  import "../chunk-JQBV3Q2W.js";
54
55
  import {
55
56
  archivePlanning,
@@ -108,7 +109,7 @@ import {
108
109
  saveSessionId,
109
110
  spawnAgent,
110
111
  stopAgent
111
- } from "../chunk-FUUP55PE.js";
112
+ } from "../chunk-NYOGHGIW.js";
112
113
  import {
113
114
  checkHook,
114
115
  clearHook,
@@ -244,9 +245,9 @@ import {
244
245
 
245
246
  // src/cli/index.ts
246
247
  init_esm_shims();
247
- import { readFileSync as readFileSync46, existsSync as existsSync52 } from "fs";
248
- import { join as join52 } from "path";
249
- import { homedir as homedir24 } from "os";
248
+ import { readFileSync as readFileSync45, existsSync as existsSync51 } from "fs";
249
+ import { join as join51 } from "path";
250
+ import { homedir as homedir23 } from "os";
250
251
  import { Command as Command2 } from "commander";
251
252
  import chalk62 from "chalk";
252
253
 
@@ -2557,7 +2558,7 @@ async function doneCommand(id, options = {}) {
2557
2558
  const issueId = id.replace(/^agent-/i, "").toUpperCase();
2558
2559
  const agentId = `agent-${issueId.toLowerCase()}`;
2559
2560
  if (!options.force) {
2560
- const { getAgentState: getAgentState2 } = await import("../agents-5HWTDR4S.js");
2561
+ const { getAgentState: getAgentState2 } = await import("../agents-I6RAEGL5.js");
2561
2562
  const agentState = getAgentState2(agentId);
2562
2563
  const workspacePath = agentState?.workspace;
2563
2564
  if (workspacePath && existsSync12(workspacePath)) {
@@ -2656,7 +2657,7 @@ async function doneCommand(id, options = {}) {
2656
2657
  console.log(chalk12.dim(" LINEAR_API_KEY not set - skipping status update"));
2657
2658
  }
2658
2659
  }
2659
- const { getAgentState: getAgentState2, saveAgentState: saveAgentState2 } = await import("../agents-5HWTDR4S.js");
2660
+ const { getAgentState: getAgentState2, saveAgentState: saveAgentState2 } = await import("../agents-I6RAEGL5.js");
2660
2661
  const existingState = getAgentState2(agentId);
2661
2662
  if (existingState) {
2662
2663
  existingState.status = "stopped";
@@ -5201,7 +5202,7 @@ Previous state: ${issue.state}`
5201
5202
  console.log(chalk21.green(`\u2713 ${issue.identifier} reopened and ready for re-work`));
5202
5203
  console.log("");
5203
5204
  try {
5204
- const { getAgentState: getAgentState2 } = await import("../agents-5HWTDR4S.js");
5205
+ const { getAgentState: getAgentState2 } = await import("../agents-I6RAEGL5.js");
5205
5206
  const agentId = `agent-${id.toLowerCase()}`;
5206
5207
  const agentState = getAgentState2(agentId);
5207
5208
  const agentRunning = agentState?.status === "running" || agentState?.status === "starting";
@@ -6523,8 +6524,8 @@ async function verifyBranchMerged(ctx) {
6523
6524
  const branchName = `feature/${issueLower}`;
6524
6525
  try {
6525
6526
  try {
6526
- const { loadReviewStatuses: loadReviewStatuses3 } = await import("../review-status-J2YJGL3E.js");
6527
- const statuses = loadReviewStatuses3();
6527
+ const { loadReviewStatuses: loadReviewStatuses2 } = await import("../review-status-J2YJGL3E.js");
6528
+ const statuses = loadReviewStatuses2();
6528
6529
  const issueKey = ctx.issueId.toUpperCase();
6529
6530
  if (statuses[issueKey]?.mergeStatus === "merged") {
6530
6531
  return stepOk(step, ["Merge specialist confirmed merge completed"]);
@@ -6592,8 +6593,8 @@ async function clearReviewStatusStep(issueId) {
6592
6593
  const upperKey = issueId.toUpperCase();
6593
6594
  if (data[upperKey]) {
6594
6595
  delete data[upperKey];
6595
- const { writeFileSync: writeFileSync27 } = await import("fs");
6596
- writeFileSync27(statusFile, JSON.stringify(data, null, 2));
6596
+ const { writeFileSync: writeFileSync26 } = await import("fs");
6597
+ writeFileSync26(statusFile, JSON.stringify(data, null, 2));
6597
6598
  }
6598
6599
  }
6599
6600
  return stepOk(step, ["Review status cleared (direct)"]);
@@ -10849,7 +10850,7 @@ async function checkOrphanedReviewStatuses() {
10849
10850
  (h) => h.type === "review" && h.status === "passed"
10850
10851
  );
10851
10852
  const hasPassedTest = status.history?.some(
10852
- (h) => h.type === "test" && (h.status === "passed" || h.status === "failed")
10853
+ (h) => h.type === "test" && h.status === "passed"
10853
10854
  );
10854
10855
  const reviewAgentActive = activeReviewSessions.has(issueId.toUpperCase());
10855
10856
  if (status.reviewStatus === "reviewing" && !reviewAgentActive && !hasPassedReview) {
@@ -10885,7 +10886,7 @@ async function checkOrphanedReviewStatuses() {
10885
10886
  const { resolveProjectFromIssue: resolveProjectFromIssue2 } = await import("../projects-3CRF57ZU.js");
10886
10887
  const resolved = resolveProjectFromIssue2(issueId);
10887
10888
  if (resolved) {
10888
- const { spawnEphemeralSpecialist } = await import("../specialists-HTYYFXHQ.js");
10889
+ const { spawnEphemeralSpecialist } = await import("../specialists-H4LGYR7R.js");
10889
10890
  const result = await spawnEphemeralSpecialist(resolved.projectKey, "test-agent", {
10890
10891
  issueId,
10891
10892
  workspace,
@@ -11287,7 +11288,7 @@ async function runPatrol() {
11287
11288
  statuses[issueId].mergeStatus = "merged";
11288
11289
  statuses[issueId].readyForMerge = false;
11289
11290
  writeFileSync19(REVIEW_STATUS_FILE, JSON.stringify(statuses, null, 2), "utf-8");
11290
- const { postMergeLifecycle } = await import("../merge-agent-WM7ZKUET.js");
11291
+ const { postMergeLifecycle } = await import("../merge-agent-ZITLVF2B.js");
11291
11292
  postMergeLifecycle(issueId, resolved.projectPath).catch(
11292
11293
  (err) => console.warn(`[deacon] postMergeLifecycle failed for ${issueId}: ${err}`)
11293
11294
  );
@@ -11738,6 +11739,10 @@ var CloisterService = class {
11738
11739
  console.log(`\u{1F514} Agent ${agentId} is suspended, skipping restart`);
11739
11740
  return;
11740
11741
  }
11742
+ if (runtimeState?.state === "stopped") {
11743
+ console.log(`\u{1F514} Agent ${agentId} runtime is stopped, skipping restart`);
11744
+ return;
11745
+ }
11741
11746
  const now = /* @__PURE__ */ new Date();
11742
11747
  this.deathTimestamps.push(now);
11743
11748
  this.checkForMassDeaths();
@@ -13049,24 +13054,8 @@ function confirm2(question) {
13049
13054
 
13050
13055
  // src/cli/commands/specialists/done.ts
13051
13056
  init_esm_shims();
13057
+ init_review_status();
13052
13058
  import chalk45 from "chalk";
13053
- import { existsSync as existsSync44, readFileSync as readFileSync38, writeFileSync as writeFileSync24 } from "fs";
13054
- import { join as join43 } from "path";
13055
- import { homedir as homedir20 } from "os";
13056
- var REVIEW_STATUS_FILE3 = join43(homedir20(), ".panopticon", "review-status.json");
13057
- function loadReviewStatuses2() {
13058
- try {
13059
- if (existsSync44(REVIEW_STATUS_FILE3)) {
13060
- return JSON.parse(readFileSync38(REVIEW_STATUS_FILE3, "utf-8"));
13061
- }
13062
- } catch (error) {
13063
- console.error(chalk45.yellow("Warning: Could not load review statuses"));
13064
- }
13065
- return {};
13066
- }
13067
- function saveReviewStatuses2(statuses) {
13068
- writeFileSync24(REVIEW_STATUS_FILE3, JSON.stringify(statuses, null, 2));
13069
- }
13070
13059
  async function doneCommand2(specialist, issueId, options) {
13071
13060
  const validSpecialists = ["review", "test", "merge"];
13072
13061
  if (!validSpecialists.includes(specialist)) {
@@ -13084,57 +13073,39 @@ async function doneCommand2(specialist, issueId, options) {
13084
13073
  process.exit(1);
13085
13074
  }
13086
13075
  const normalizedIssueId = issueId.toUpperCase();
13087
- const statuses = loadReviewStatuses2();
13088
- let status = statuses[normalizedIssueId];
13089
- if (!status) {
13090
- status = {
13091
- issueId: normalizedIssueId,
13092
- reviewStatus: "pending",
13093
- testStatus: "pending",
13094
- updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
13095
- readyForMerge: false
13096
- };
13097
- }
13076
+ const update = {};
13098
13077
  switch (specialist) {
13099
13078
  case "review":
13100
- status.reviewStatus = options.status;
13101
- if (options.notes) {
13102
- status.reviewNotes = options.notes;
13103
- }
13079
+ update.reviewStatus = options.status;
13080
+ if (options.notes) update.reviewNotes = options.notes;
13104
13081
  console.log(chalk45.green(`\u2713 Review ${options.status} for ${normalizedIssueId}`));
13105
13082
  if (options.status === "passed") {
13106
13083
  console.log(chalk45.dim(" Test agent can now proceed"));
13107
13084
  }
13108
13085
  break;
13109
13086
  case "test":
13110
- status.testStatus = options.status;
13111
- if (options.notes) {
13112
- status.testNotes = options.notes;
13113
- }
13114
- if (options.status === "passed" && status.reviewStatus === "passed") {
13115
- status.readyForMerge = true;
13116
- console.log(chalk45.green(`\u2713 Tests ${options.status} for ${normalizedIssueId}`));
13117
- console.log(chalk45.green("\u2713 Ready for merge!"));
13118
- } else if (options.status === "passed") {
13087
+ update.testStatus = options.status;
13088
+ if (options.notes) update.testNotes = options.notes;
13089
+ if (options.status === "passed") {
13119
13090
  console.log(chalk45.green(`\u2713 Tests ${options.status} for ${normalizedIssueId}`));
13120
13091
  } else {
13121
13092
  console.log(chalk45.yellow(`\u2717 Tests ${options.status} for ${normalizedIssueId}`));
13122
- status.readyForMerge = false;
13123
13093
  }
13124
13094
  break;
13125
13095
  case "merge":
13126
- status.mergeStatus = options.status === "passed" ? "merged" : "failed";
13096
+ update.mergeStatus = options.status === "passed" ? "merged" : "failed";
13127
13097
  if (options.status === "passed") {
13098
+ update.readyForMerge = false;
13128
13099
  console.log(chalk45.green(`\u2713 Merge completed for ${normalizedIssueId}`));
13129
- status.readyForMerge = false;
13130
13100
  } else {
13131
13101
  console.log(chalk45.red(`\u2717 Merge failed for ${normalizedIssueId}`));
13132
13102
  }
13133
13103
  break;
13134
13104
  }
13135
- status.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
13136
- statuses[normalizedIssueId] = status;
13137
- saveReviewStatuses2(statuses);
13105
+ const status = setReviewStatus(normalizedIssueId, update);
13106
+ if (specialist === "test" && status.readyForMerge) {
13107
+ console.log(chalk45.green("\u2713 Ready for merge!"));
13108
+ }
13138
13109
  if (options.notes) {
13139
13110
  console.log(chalk45.dim(` Notes: ${options.notes}`));
13140
13111
  }
@@ -13166,13 +13137,13 @@ function formatStatus(status) {
13166
13137
 
13167
13138
  // src/cli/commands/specialists/logs.ts
13168
13139
  init_esm_shims();
13169
- import { existsSync as existsSync45 } from "fs";
13140
+ import { existsSync as existsSync44 } from "fs";
13170
13141
  import { exec as exec15 } from "child_process";
13171
13142
  import { promisify as promisify15 } from "util";
13172
13143
  var execAsync15 = promisify15(exec15);
13173
13144
  async function listLogsCommand(project2, type, options) {
13174
13145
  try {
13175
- const { listRunLogs } = await import("../specialist-logs-T5GW7CSU.js");
13146
+ const { listRunLogs } = await import("../specialist-logs-KPC45SZN.js");
13176
13147
  const limit = options.limit ? parseInt(options.limit) : 10;
13177
13148
  const runs = listRunLogs(project2, type, { limit });
13178
13149
  if (options.json) {
@@ -13217,7 +13188,7 @@ View a specific run: pan specialists logs ${project2} ${type} <runId>
13217
13188
  }
13218
13189
  async function viewLogCommand(project2, type, runId, options) {
13219
13190
  try {
13220
- const { getRunLog, parseLogMetadata, getRunLogPath } = await import("../specialist-logs-T5GW7CSU.js");
13191
+ const { getRunLog, parseLogMetadata, getRunLogPath } = await import("../specialist-logs-KPC45SZN.js");
13221
13192
  const content = getRunLog(project2, type, runId);
13222
13193
  if (!content) {
13223
13194
  console.error(`\u274C Run log not found: ${runId}`);
@@ -13241,15 +13212,15 @@ async function viewLogCommand(project2, type, runId, options) {
13241
13212
  }
13242
13213
  async function tailLogCommand(project2, type) {
13243
13214
  try {
13244
- const { getRunLogPath } = await import("../specialist-logs-T5GW7CSU.js");
13245
- const { getProjectSpecialistMetadata } = await import("../specialists-HTYYFXHQ.js");
13215
+ const { getRunLogPath } = await import("../specialist-logs-KPC45SZN.js");
13216
+ const { getProjectSpecialistMetadata } = await import("../specialists-H4LGYR7R.js");
13246
13217
  const metadata = getProjectSpecialistMetadata(project2, type);
13247
13218
  if (!metadata.currentRun) {
13248
13219
  console.error(`\u274C No active run for ${project2}/${type}`);
13249
13220
  process.exit(1);
13250
13221
  }
13251
13222
  const logPath = getRunLogPath(project2, type, metadata.currentRun);
13252
- if (!existsSync45(logPath)) {
13223
+ if (!existsSync44(logPath)) {
13253
13224
  console.error(`\u274C Log file not found: ${logPath}`);
13254
13225
  process.exit(1);
13255
13226
  }
@@ -13311,7 +13282,7 @@ async function cleanupLogsCommand(projectOrAll, type, options) {
13311
13282
  console.log(" Use --force to confirm.");
13312
13283
  process.exit(1);
13313
13284
  }
13314
- const { cleanupAllLogs } = await import("../specialist-logs-T5GW7CSU.js");
13285
+ const { cleanupAllLogs } = await import("../specialist-logs-KPC45SZN.js");
13315
13286
  console.log("\u{1F9F9} Cleaning up old logs for all projects...\n");
13316
13287
  const results = cleanupAllLogs();
13317
13288
  console.log(`
@@ -13338,7 +13309,7 @@ async function cleanupLogsCommand(projectOrAll, type, options) {
13338
13309
  console.log(" Use --force to confirm.");
13339
13310
  process.exit(1);
13340
13311
  }
13341
- const { cleanupOldLogs } = await import("../specialist-logs-T5GW7CSU.js");
13312
+ const { cleanupOldLogs } = await import("../specialist-logs-KPC45SZN.js");
13342
13313
  const { getSpecialistRetention } = await import("../projects-3CRF57ZU.js");
13343
13314
  const retention = getSpecialistRetention(projectOrAll);
13344
13315
  console.log(`\u{1F9F9} Cleaning up old logs for ${projectOrAll}/${type}...`);
@@ -13377,9 +13348,9 @@ import ora19 from "ora";
13377
13348
  // src/lib/convoy.ts
13378
13349
  init_esm_shims();
13379
13350
  init_tmux();
13380
- import { existsSync as existsSync46, mkdirSync as mkdirSync22, writeFileSync as writeFileSync25, readFileSync as readFileSync40, readdirSync as readdirSync19 } from "fs";
13381
- import { join as join44 } from "path";
13382
- import { homedir as homedir21 } from "os";
13351
+ import { existsSync as existsSync45, mkdirSync as mkdirSync22, writeFileSync as writeFileSync24, readFileSync as readFileSync39, readdirSync as readdirSync19 } from "fs";
13352
+ import { join as join43 } from "path";
13353
+ import { homedir as homedir20 } from "os";
13383
13354
  import { exec as exec16 } from "child_process";
13384
13355
  import { promisify as promisify16 } from "util";
13385
13356
  import { parse as parseYaml } from "yaml";
@@ -13487,25 +13458,25 @@ function getExecutionOrder(template) {
13487
13458
  init_paths();
13488
13459
  init_work_type_router();
13489
13460
  var execAsync16 = promisify16(exec16);
13490
- var CONVOY_DIR = join44(homedir21(), ".panopticon", "convoys");
13461
+ var CONVOY_DIR = join43(homedir20(), ".panopticon", "convoys");
13491
13462
  function getConvoyStateFile(convoyId) {
13492
- return join44(CONVOY_DIR, `${convoyId}.json`);
13463
+ return join43(CONVOY_DIR, `${convoyId}.json`);
13493
13464
  }
13494
13465
  function getConvoyOutputDir(convoyId, template) {
13495
13466
  const baseDir = template.config?.outputDir || ".panopticon/convoy-output";
13496
- return join44(process.cwd(), baseDir, convoyId);
13467
+ return join43(process.cwd(), baseDir, convoyId);
13497
13468
  }
13498
13469
  function saveConvoyState(state) {
13499
13470
  mkdirSync22(CONVOY_DIR, { recursive: true });
13500
- writeFileSync25(getConvoyStateFile(state.id), JSON.stringify(state, null, 2));
13471
+ writeFileSync24(getConvoyStateFile(state.id), JSON.stringify(state, null, 2));
13501
13472
  }
13502
13473
  function loadConvoyState(convoyId) {
13503
13474
  const stateFile = getConvoyStateFile(convoyId);
13504
- if (!existsSync46(stateFile)) {
13475
+ if (!existsSync45(stateFile)) {
13505
13476
  return void 0;
13506
13477
  }
13507
13478
  try {
13508
- const content = readFileSync40(stateFile, "utf-8");
13479
+ const content = readFileSync39(stateFile, "utf-8");
13509
13480
  return JSON.parse(content);
13510
13481
  } catch {
13511
13482
  return void 0;
@@ -13515,7 +13486,7 @@ function getConvoyStatus(convoyId) {
13515
13486
  return loadConvoyState(convoyId);
13516
13487
  }
13517
13488
  function listConvoys(filter) {
13518
- if (!existsSync46(CONVOY_DIR)) {
13489
+ if (!existsSync45(CONVOY_DIR)) {
13519
13490
  return [];
13520
13491
  }
13521
13492
  const files = readdirSync19(CONVOY_DIR).filter((f) => f.endsWith(".json"));
@@ -13534,10 +13505,10 @@ function listConvoys(filter) {
13534
13505
  );
13535
13506
  }
13536
13507
  function parseAgentTemplate(templatePath) {
13537
- if (!existsSync46(templatePath)) {
13508
+ if (!existsSync45(templatePath)) {
13538
13509
  throw new Error(`Agent template not found: ${templatePath}`);
13539
13510
  }
13540
- const content = readFileSync40(templatePath, "utf-8");
13511
+ const content = readFileSync39(templatePath, "utf-8");
13541
13512
  const frontmatterMatch = content.match(/^---\n([\s\S]+?)\n---\n([\s\S]*)$/);
13542
13513
  if (!frontmatterMatch) {
13543
13514
  throw new Error(`Invalid agent template format (missing frontmatter): ${templatePath}`);
@@ -13563,7 +13534,7 @@ function mapConvoyRoleToWorkType(role) {
13563
13534
  }
13564
13535
  async function spawnConvoyAgent(convoy, agent, agentState, context) {
13565
13536
  const { role, subagent } = agent;
13566
- const templatePath = join44(AGENTS_DIR, `${subagent}.md`);
13537
+ const templatePath = join43(AGENTS_DIR, `${subagent}.md`);
13567
13538
  const template = parseAgentTemplate(templatePath);
13568
13539
  let model = template.model;
13569
13540
  try {
@@ -13602,8 +13573,8 @@ ${context.issueId ? `**Issue ID**: ${context.issueId}` : ""}
13602
13573
  `;
13603
13574
  prompt = contextInstructions + prompt;
13604
13575
  mkdirSync22(convoy.outputDir, { recursive: true });
13605
- const promptFile = join44(convoy.outputDir, `${role}-prompt.md`);
13606
- writeFileSync25(promptFile, prompt);
13576
+ const promptFile = join43(convoy.outputDir, `${role}-prompt.md`);
13577
+ writeFileSync24(promptFile, prompt);
13607
13578
  const claudeCmd = `claude --dangerously-skip-permissions --model ${model}`;
13608
13579
  createSession(agentState.tmuxSession, convoy.context.projectPath, claudeCmd, {
13609
13580
  env: {
@@ -13641,7 +13612,7 @@ async function startConvoy(templateName, context) {
13641
13612
  };
13642
13613
  for (const agent of template.agents) {
13643
13614
  const tmuxSession = `${convoyId}-${agent.role}`;
13644
- const outputFile = join44(outputDir, `${agent.role}.md`);
13615
+ const outputFile = join43(outputDir, `${agent.role}.md`);
13645
13616
  state.agents.push({
13646
13617
  role: agent.role,
13647
13618
  subagent: agent.subagent,
@@ -13676,8 +13647,8 @@ async function executePhase(convoy, template, phaseAgents, context) {
13676
13647
  const agentContext = { ...context };
13677
13648
  for (const depRole of deps) {
13678
13649
  const depAgent = convoy.agents.find((a) => a.role === depRole);
13679
- if (depAgent?.outputFile && existsSync46(depAgent.outputFile)) {
13680
- agentContext[`${depRole}_output`] = readFileSync40(depAgent.outputFile, "utf-8");
13650
+ if (depAgent?.outputFile && existsSync45(depAgent.outputFile)) {
13651
+ agentContext[`${depRole}_output`] = readFileSync39(depAgent.outputFile, "utf-8");
13681
13652
  }
13682
13653
  }
13683
13654
  spawnPromises.push(spawnConvoyAgent(convoy, agent, agentState, agentContext));
@@ -13740,7 +13711,7 @@ function updateAgentStatuses(convoy) {
13740
13711
  agent.status = "completed";
13741
13712
  agent.completedAt = (/* @__PURE__ */ new Date()).toISOString();
13742
13713
  updated = true;
13743
- if (agent.outputFile && existsSync46(agent.outputFile)) {
13714
+ if (agent.outputFile && existsSync45(agent.outputFile)) {
13744
13715
  agent.exitCode = 0;
13745
13716
  } else {
13746
13717
  agent.exitCode = 1;
@@ -13986,30 +13957,30 @@ function registerConvoyCommands(program2) {
13986
13957
  init_esm_shims();
13987
13958
  init_projects();
13988
13959
  import chalk50 from "chalk";
13989
- import { existsSync as existsSync47, readFileSync as readFileSync41, symlinkSync as symlinkSync2, mkdirSync as mkdirSync23, readdirSync as readdirSync20, statSync as statSync10 } from "fs";
13990
- import { join as join45, resolve as resolve2, dirname as dirname13 } from "path";
13960
+ import { existsSync as existsSync46, readFileSync as readFileSync40, symlinkSync as symlinkSync2, mkdirSync as mkdirSync23, readdirSync as readdirSync20, statSync as statSync10 } from "fs";
13961
+ import { join as join44, resolve as resolve2, dirname as dirname13 } from "path";
13991
13962
  import { fileURLToPath as fileURLToPath4 } from "url";
13992
13963
  var __filename5 = fileURLToPath4(import.meta.url);
13993
13964
  var __dirname5 = dirname13(__filename5);
13994
- var BUNDLED_HOOKS_DIR = join45(__dirname5, "..", "..", "scripts", "git-hooks");
13965
+ var BUNDLED_HOOKS_DIR = join44(__dirname5, "..", "..", "scripts", "git-hooks");
13995
13966
  function installGitHooks(gitDir) {
13996
- const hooksTarget = join45(gitDir, "hooks");
13967
+ const hooksTarget = join44(gitDir, "hooks");
13997
13968
  let installed = 0;
13998
- if (!existsSync47(hooksTarget)) {
13969
+ if (!existsSync46(hooksTarget)) {
13999
13970
  mkdirSync23(hooksTarget, { recursive: true });
14000
13971
  }
14001
- if (!existsSync47(BUNDLED_HOOKS_DIR)) {
13972
+ if (!existsSync46(BUNDLED_HOOKS_DIR)) {
14002
13973
  return 0;
14003
13974
  }
14004
13975
  try {
14005
13976
  const hooks = readdirSync20(BUNDLED_HOOKS_DIR).filter((f) => {
14006
- const p = join45(BUNDLED_HOOKS_DIR, f);
14007
- return existsSync47(p) && statSync10(p).isFile();
13977
+ const p = join44(BUNDLED_HOOKS_DIR, f);
13978
+ return existsSync46(p) && statSync10(p).isFile();
14008
13979
  });
14009
13980
  for (const hook of hooks) {
14010
- const source = join45(BUNDLED_HOOKS_DIR, hook);
14011
- const target = join45(hooksTarget, hook);
14012
- if (existsSync47(target)) {
13981
+ const source = join44(BUNDLED_HOOKS_DIR, hook);
13982
+ const target = join44(hooksTarget, hook);
13983
+ if (existsSync46(target)) {
14013
13984
  try {
14014
13985
  const { readlinkSync: readlinkSync2 } = __require("fs");
14015
13986
  if (readlinkSync2(target) === source) {
@@ -14018,7 +13989,7 @@ function installGitHooks(gitDir) {
14018
13989
  } catch {
14019
13990
  }
14020
13991
  }
14021
- if (existsSync47(target)) {
13992
+ if (existsSync46(target)) {
14022
13993
  const { renameSync: renameSync4 } = __require("fs");
14023
13994
  renameSync4(target, `${target}.backup`);
14024
13995
  }
@@ -14031,7 +14002,7 @@ function installGitHooks(gitDir) {
14031
14002
  }
14032
14003
  async function projectAddCommand(projectPath, options = {}) {
14033
14004
  const fullPath = resolve2(projectPath);
14034
- if (!existsSync47(fullPath)) {
14005
+ if (!existsSync46(fullPath)) {
14035
14006
  console.log(chalk50.red(`Path does not exist: ${fullPath}`));
14036
14007
  return;
14037
14008
  }
@@ -14046,9 +14017,9 @@ async function projectAddCommand(projectPath, options = {}) {
14046
14017
  }
14047
14018
  let linearTeam = options.linearTeam;
14048
14019
  if (!linearTeam) {
14049
- const projectToml = join45(fullPath, ".panopticon", "project.toml");
14050
- if (existsSync47(projectToml)) {
14051
- const content = readFileSync41(projectToml, "utf-8");
14020
+ const projectToml = join44(fullPath, ".panopticon", "project.toml");
14021
+ if (existsSync46(projectToml)) {
14022
+ const content = readFileSync40(projectToml, "utf-8");
14052
14023
  const match = content.match(/team\s*=\s*"([^"]+)"/);
14053
14024
  if (match) linearTeam = match[1];
14054
14025
  }
@@ -14074,19 +14045,19 @@ async function projectAddCommand(projectPath, options = {}) {
14074
14045
  console.log(chalk50.dim(` Rally project: ${options.rallyProject}`));
14075
14046
  }
14076
14047
  console.log("");
14077
- const hasDevcontainer = existsSync47(join45(fullPath, ".devcontainer"));
14078
- const hasInfra = existsSync47(join45(fullPath, "infra"));
14079
- const hasDevcontainerTemplate = existsSync47(join45(fullPath, "infra", ".devcontainer-template")) || existsSync47(join45(fullPath, ".devcontainer-template"));
14080
- const hasRootGit = existsSync47(join45(fullPath, ".git"));
14048
+ const hasDevcontainer = existsSync46(join44(fullPath, ".devcontainer"));
14049
+ const hasInfra = existsSync46(join44(fullPath, "infra"));
14050
+ const hasDevcontainerTemplate = existsSync46(join44(fullPath, "infra", ".devcontainer-template")) || existsSync46(join44(fullPath, ".devcontainer-template"));
14051
+ const hasRootGit = existsSync46(join44(fullPath, ".git"));
14081
14052
  const subRepos = [];
14082
14053
  if (!hasRootGit) {
14083
14054
  const { readdirSync: readdirSync22, statSync: statSync12 } = await import("fs");
14084
14055
  try {
14085
14056
  const entries = readdirSync22(fullPath);
14086
14057
  for (const entry of entries) {
14087
- const entryPath = join45(fullPath, entry);
14058
+ const entryPath = join44(fullPath, entry);
14088
14059
  try {
14089
- if (statSync12(entryPath).isDirectory() && existsSync47(join45(entryPath, ".git"))) {
14060
+ if (statSync12(entryPath).isDirectory() && existsSync46(join44(entryPath, ".git"))) {
14090
14061
  subRepos.push(entry);
14091
14062
  }
14092
14063
  } catch {
@@ -14103,13 +14074,13 @@ async function projectAddCommand(projectPath, options = {}) {
14103
14074
  }
14104
14075
  let hooksInstalled = 0;
14105
14076
  if (hasRootGit) {
14106
- hooksInstalled = installGitHooks(join45(fullPath, ".git"));
14077
+ hooksInstalled = installGitHooks(join44(fullPath, ".git"));
14107
14078
  if (hooksInstalled > 0) {
14108
14079
  console.log(chalk50.green(`\u2713 Installed ${hooksInstalled} git hook(s) for branch protection`));
14109
14080
  }
14110
14081
  } else if (isPolyrepo) {
14111
14082
  for (const repo of subRepos) {
14112
- const count = installGitHooks(join45(fullPath, repo, ".git"));
14083
+ const count = installGitHooks(join44(fullPath, repo, ".git"));
14113
14084
  hooksInstalled += count;
14114
14085
  }
14115
14086
  if (hooksInstalled > 0) {
@@ -14181,7 +14152,7 @@ async function projectListCommand(options = {}) {
14181
14152
  }
14182
14153
  console.log(chalk50.bold("\nRegistered Projects:\n"));
14183
14154
  for (const { key, config: config2 } of projects) {
14184
- const exists = existsSync47(config2.path);
14155
+ const exists = existsSync46(config2.path);
14185
14156
  const statusIcon = exists ? chalk50.green("\u2713") : chalk50.red("\u2717");
14186
14157
  console.log(`${statusIcon} ${chalk50.bold(config2.name)} ${chalk50.dim(`(${key})`)}`);
14187
14158
  console.log(` ${chalk50.dim(config2.path)}`);
@@ -14215,7 +14186,7 @@ async function projectRemoveCommand(nameOrPath) {
14215
14186
  console.log(chalk50.dim(`Use 'pan project list' to see registered projects.`));
14216
14187
  }
14217
14188
  async function projectInitCommand() {
14218
- if (existsSync47(PROJECTS_CONFIG_FILE)) {
14189
+ if (existsSync46(PROJECTS_CONFIG_FILE)) {
14219
14190
  console.log(chalk50.yellow(`Config already exists: ${PROJECTS_CONFIG_FILE}`));
14220
14191
  return;
14221
14192
  }
@@ -14249,7 +14220,7 @@ async function projectShowCommand(keyOrName) {
14249
14220
  console.log(chalk50.dim(`Use 'pan project list' to see registered projects.`));
14250
14221
  process.exit(1);
14251
14222
  }
14252
- const pathExists = existsSync47(found.path);
14223
+ const pathExists = existsSync46(found.path);
14253
14224
  const pathStatus = pathExists ? chalk50.green("\u2713") : chalk50.red("\u2717");
14254
14225
  console.log(chalk50.bold(`
14255
14226
  Project: ${foundKey}
@@ -14281,10 +14252,10 @@ Project: ${foundKey}
14281
14252
  init_esm_shims();
14282
14253
  init_paths();
14283
14254
  import chalk51 from "chalk";
14284
- import { existsSync as existsSync48, readdirSync as readdirSync21, readFileSync as readFileSync42 } from "fs";
14255
+ import { existsSync as existsSync47, readdirSync as readdirSync21, readFileSync as readFileSync41 } from "fs";
14285
14256
  import { execSync as execSync6 } from "child_process";
14286
- import { homedir as homedir22 } from "os";
14287
- import { join as join46 } from "path";
14257
+ import { homedir as homedir21 } from "os";
14258
+ import { join as join45 } from "path";
14288
14259
  function checkCommand3(cmd) {
14289
14260
  try {
14290
14261
  execSync6(`which ${cmd}`, { encoding: "utf-8", stdio: "pipe" });
@@ -14294,10 +14265,10 @@ function checkCommand3(cmd) {
14294
14265
  }
14295
14266
  }
14296
14267
  function checkDirectory(path) {
14297
- return existsSync48(path);
14268
+ return existsSync47(path);
14298
14269
  }
14299
14270
  function countItems(path) {
14300
- if (!existsSync48(path)) return 0;
14271
+ if (!existsSync47(path)) return 0;
14301
14272
  try {
14302
14273
  return readdirSync21(path).length;
14303
14274
  } catch {
@@ -14348,8 +14319,8 @@ async function doctorCommand() {
14348
14319
  }
14349
14320
  }
14350
14321
  if (checkDirectory(CLAUDE_DIR)) {
14351
- const skillsCount = countItems(join46(CLAUDE_DIR, "skills"));
14352
- const commandsCount = countItems(join46(CLAUDE_DIR, "commands"));
14322
+ const skillsCount = countItems(join45(CLAUDE_DIR, "skills"));
14323
+ const commandsCount = countItems(join45(CLAUDE_DIR, "commands"));
14353
14324
  checks.push({
14354
14325
  name: "Claude Code Skills",
14355
14326
  status: skillsCount > 0 ? "ok" : "warn",
@@ -14370,8 +14341,8 @@ async function doctorCommand() {
14370
14341
  fix: "Install Claude Code first"
14371
14342
  });
14372
14343
  }
14373
- const envFile = join46(homedir22(), ".panopticon.env");
14374
- if (existsSync48(envFile)) {
14344
+ const envFile = join45(homedir21(), ".panopticon.env");
14345
+ if (existsSync47(envFile)) {
14375
14346
  checks.push({ name: "Config File", status: "ok", message: "~/.panopticon.env exists" });
14376
14347
  } else {
14377
14348
  checks.push({
@@ -14383,8 +14354,8 @@ async function doctorCommand() {
14383
14354
  }
14384
14355
  if (process.env.LINEAR_API_KEY) {
14385
14356
  checks.push({ name: "LINEAR_API_KEY", status: "ok", message: "Set in environment" });
14386
- } else if (existsSync48(envFile)) {
14387
- const content = readFileSync42(envFile, "utf-8");
14357
+ } else if (existsSync47(envFile)) {
14358
+ const content = readFileSync41(envFile, "utf-8");
14388
14359
  if (content.includes("LINEAR_API_KEY")) {
14389
14360
  checks.push({ name: "LINEAR_API_KEY", status: "ok", message: "Set in config file" });
14390
14361
  } else {
@@ -14452,15 +14423,15 @@ init_esm_shims();
14452
14423
  init_config();
14453
14424
  import { execSync as execSync7 } from "child_process";
14454
14425
  import chalk52 from "chalk";
14455
- import { readFileSync as readFileSync43 } from "fs";
14426
+ import { readFileSync as readFileSync42 } from "fs";
14456
14427
  import { fileURLToPath as fileURLToPath5 } from "url";
14457
- import { dirname as dirname14, join as join47 } from "path";
14428
+ import { dirname as dirname14, join as join46 } from "path";
14458
14429
  function getCurrentVersion() {
14459
14430
  try {
14460
14431
  const __filename6 = fileURLToPath5(import.meta.url);
14461
14432
  const __dirname6 = dirname14(__filename6);
14462
- const pkgPath = join47(__dirname6, "..", "..", "..", "package.json");
14463
- const pkg = JSON.parse(readFileSync43(pkgPath, "utf-8"));
14433
+ const pkgPath = join46(__dirname6, "..", "..", "..", "package.json");
14434
+ const pkg = JSON.parse(readFileSync42(pkgPath, "utf-8"));
14464
14435
  return pkg.version;
14465
14436
  } catch {
14466
14437
  return "unknown";
@@ -14546,8 +14517,8 @@ init_esm_shims();
14546
14517
  init_projects();
14547
14518
  import chalk53 from "chalk";
14548
14519
  import ora21 from "ora";
14549
- import { existsSync as existsSync49, readFileSync as readFileSync44, writeFileSync as writeFileSync26, mkdirSync as mkdirSync24, statSync as statSync11 } from "fs";
14550
- import { join as join48, dirname as dirname15 } from "path";
14520
+ import { existsSync as existsSync48, readFileSync as readFileSync43, writeFileSync as writeFileSync25, mkdirSync as mkdirSync24, statSync as statSync11 } from "fs";
14521
+ import { join as join47, dirname as dirname15 } from "path";
14551
14522
  import { exec as exec17 } from "child_process";
14552
14523
  import { promisify as promisify17 } from "util";
14553
14524
  var execAsync17 = promisify17(exec17);
@@ -14609,9 +14580,9 @@ async function snapshotCommand(options) {
14609
14580
  `));
14610
14581
  return;
14611
14582
  }
14612
- const outputPath = options.output || dbConfig.seed_file || join48(projectConfig.path, "infra", "seed", "seed.sql");
14583
+ const outputPath = options.output || dbConfig.seed_file || join47(projectConfig.path, "infra", "seed", "seed.sql");
14613
14584
  const outputDir = dirname15(outputPath);
14614
- if (!existsSync49(outputDir)) {
14585
+ if (!existsSync48(outputDir)) {
14615
14586
  mkdirSync24(outputDir, { recursive: true });
14616
14587
  }
14617
14588
  spinner.text = "Running snapshot command...";
@@ -14634,8 +14605,8 @@ async function snapshotCommand(options) {
14634
14605
  try {
14635
14606
  await execAsync17(fullCmd, { timeout: 3e5 });
14636
14607
  } catch (error) {
14637
- if (existsSync49(outputPath)) {
14638
- const content2 = readFileSync44(outputPath, "utf-8");
14608
+ if (existsSync48(outputPath)) {
14609
+ const content2 = readFileSync43(outputPath, "utf-8");
14639
14610
  if (content2.includes("PostgreSQL database dump")) {
14640
14611
  spinner.warn("Snapshot completed with warnings (stderr captured)");
14641
14612
  console.log(chalk53.dim(" Run `pan db clean` to remove stderr noise from the file"));
@@ -14648,7 +14619,7 @@ async function snapshotCommand(options) {
14648
14619
  return;
14649
14620
  }
14650
14621
  }
14651
- const content = readFileSync44(outputPath, "utf-8");
14622
+ const content = readFileSync43(outputPath, "utf-8");
14652
14623
  if (content.includes("Defaulted container") || content.includes("Unable to use a TTY")) {
14653
14624
  spinner.text = "Cleaning kubectl output from snapshot...";
14654
14625
  await cleanFile(outputPath);
@@ -14680,14 +14651,14 @@ async function seedCommand(workspaceOrIssue, options) {
14680
14651
  spinner.fail("Could not find project workspace configuration");
14681
14652
  return;
14682
14653
  }
14683
- const workspacePath = join48(projectConfig.path, projectConfig.workspace.workspaces_dir || "workspaces", folderName);
14684
- if (!existsSync49(workspacePath)) {
14654
+ const workspacePath = join47(projectConfig.path, projectConfig.workspace.workspaces_dir || "workspaces", folderName);
14655
+ if (!existsSync48(workspacePath)) {
14685
14656
  spinner.fail(`Workspace not found: ${workspacePath}`);
14686
14657
  return;
14687
14658
  }
14688
14659
  const dbConfig = projectConfig.workspace.database;
14689
14660
  const seedFile = options.file || dbConfig?.seed_file;
14690
- if (!seedFile || !existsSync49(seedFile)) {
14661
+ if (!seedFile || !existsSync48(seedFile)) {
14691
14662
  spinner.fail(`Seed file not found: ${seedFile || "(not configured)"}`);
14692
14663
  console.log(chalk53.dim("\nConfigure seed_file in projects.yaml or use --file"));
14693
14664
  return;
@@ -14829,11 +14800,11 @@ async function statusCommand5(workspaceOrIssue) {
14829
14800
  async function cleanCommand(file, options) {
14830
14801
  const spinner = ora21("Cleaning database dump file...").start();
14831
14802
  try {
14832
- if (!existsSync49(file)) {
14803
+ if (!existsSync48(file)) {
14833
14804
  spinner.fail(`File not found: ${file}`);
14834
14805
  return;
14835
14806
  }
14836
- const content = readFileSync44(file, "utf-8");
14807
+ const content = readFileSync43(file, "utf-8");
14837
14808
  const lines = content.split("\n");
14838
14809
  const patternsToRemove = [
14839
14810
  /^Defaulted container/,
@@ -14893,7 +14864,7 @@ async function cleanCommand(file, options) {
14893
14864
  return;
14894
14865
  }
14895
14866
  const outputPath = options.output || file;
14896
- writeFileSync26(outputPath, cleanedContent);
14867
+ writeFileSync25(outputPath, cleanedContent);
14897
14868
  spinner.succeed(`Cleaned ${removedLines} lines`);
14898
14869
  console.log(chalk53.dim(` Output: ${outputPath}`));
14899
14870
  console.log(chalk53.dim(` Original: ${lines.length} lines`));
@@ -14903,7 +14874,7 @@ async function cleanCommand(file, options) {
14903
14874
  }
14904
14875
  }
14905
14876
  async function cleanFile(filePath) {
14906
- const content = readFileSync44(filePath, "utf-8");
14877
+ const content = readFileSync43(filePath, "utf-8");
14907
14878
  const lines = content.split("\n");
14908
14879
  let startIndex = 0;
14909
14880
  for (let i = 0; i < lines.length; i++) {
@@ -14923,7 +14894,7 @@ async function cleanFile(filePath) {
14923
14894
  /^error: timed out waiting/
14924
14895
  ];
14925
14896
  const cleanedLines = lines.slice(startIndex).filter((line) => !patternsToRemove.some((p) => p.test(line)));
14926
- writeFileSync26(filePath, cleanedLines.join("\n"));
14897
+ writeFileSync25(filePath, cleanedLines.join("\n"));
14927
14898
  }
14928
14899
  async function configCommand(project2) {
14929
14900
  const projects = loadFullProjects();
@@ -14957,7 +14928,7 @@ async function configCommand(project2) {
14957
14928
  return;
14958
14929
  }
14959
14930
  if (dbConfig.seed_file) {
14960
- const exists = existsSync49(dbConfig.seed_file);
14931
+ const exists = existsSync48(dbConfig.seed_file);
14961
14932
  console.log(` Seed file: ${dbConfig.seed_file}`);
14962
14933
  console.log(chalk53.dim(` Status: ${exists ? chalk53.green("exists") : chalk53.red("not found")}`));
14963
14934
  if (exists) {
@@ -14986,8 +14957,8 @@ async function configCommand(project2) {
14986
14957
  init_esm_shims();
14987
14958
  import chalk54 from "chalk";
14988
14959
  import ora22 from "ora";
14989
- import { existsSync as existsSync50, readFileSync as readFileSync45 } from "fs";
14990
- import { join as join49 } from "path";
14960
+ import { existsSync as existsSync49, readFileSync as readFileSync44 } from "fs";
14961
+ import { join as join48 } from "path";
14991
14962
  import { exec as exec18, execSync as execSync8 } from "child_process";
14992
14963
  import { promisify as promisify18 } from "util";
14993
14964
  import { platform } from "os";
@@ -14996,7 +14967,7 @@ function detectPlatform2() {
14996
14967
  const os = platform();
14997
14968
  if (os === "linux") {
14998
14969
  try {
14999
- const release = readFileSync45("/proc/version", "utf8").toLowerCase();
14970
+ const release = readFileSync44("/proc/version", "utf8").toLowerCase();
15000
14971
  if (release.includes("microsoft") || release.includes("wsl")) {
15001
14972
  return "wsl";
15002
14973
  }
@@ -15034,8 +15005,8 @@ async function compactCommand(options) {
15034
15005
  console.log(chalk54.dim("Install beads: https://github.com/steveyegge/beads"));
15035
15006
  process.exit(1);
15036
15007
  }
15037
- const beadsDir = join49(cwd, ".beads");
15038
- if (!existsSync50(beadsDir)) {
15008
+ const beadsDir = join48(cwd, ".beads");
15009
+ if (!existsSync49(beadsDir)) {
15039
15010
  console.error(chalk54.red("Error: No .beads directory found in current directory"));
15040
15011
  console.log(chalk54.dim("Run bd init to initialize beads"));
15041
15012
  process.exit(1);
@@ -15094,8 +15065,8 @@ async function statsCommand() {
15094
15065
  console.error(chalk54.red("Error: bd (beads) CLI not found"));
15095
15066
  process.exit(1);
15096
15067
  }
15097
- const beadsDir = join49(cwd, ".beads");
15098
- if (!existsSync50(beadsDir)) {
15068
+ const beadsDir = join48(cwd, ".beads");
15069
+ if (!existsSync49(beadsDir)) {
15099
15070
  console.error(chalk54.red("Error: No .beads directory found"));
15100
15071
  process.exit(1);
15101
15072
  }
@@ -15739,9 +15710,9 @@ import chalk60 from "chalk";
15739
15710
 
15740
15711
  // src/lib/env-loader.ts
15741
15712
  init_esm_shims();
15742
- import { join as join50 } from "path";
15743
- import { homedir as homedir23 } from "os";
15744
- var ENV_FILE_PATH = join50(homedir23(), ".panopticon.env");
15713
+ import { join as join49 } from "path";
15714
+ import { homedir as homedir22 } from "os";
15715
+ var ENV_FILE_PATH = join49(homedir22(), ".panopticon.env");
15745
15716
  function getShadowModeFromEnv() {
15746
15717
  const value = process.env.SHADOW_MODE;
15747
15718
  if (!value) return false;
@@ -15844,9 +15815,9 @@ import chalk61 from "chalk";
15844
15815
  // src/lib/costs/sync-wal.ts
15845
15816
  init_esm_shims();
15846
15817
  init_projects();
15847
- import { existsSync as existsSync51 } from "fs";
15818
+ import { existsSync as existsSync50 } from "fs";
15848
15819
  import { readdir, readFile } from "fs/promises";
15849
- import { join as join51 } from "path";
15820
+ import { join as join50 } from "path";
15850
15821
 
15851
15822
  // src/lib/database/cost-events-db.ts
15852
15823
  init_esm_shims();
@@ -15911,8 +15882,8 @@ async function syncWalFromAllProjects() {
15911
15882
  for (const { key, config: config2 } of projects) {
15912
15883
  const repoPath = config2.events_repo ?? config2.path;
15913
15884
  const eventsSubdir = config2.events_path ?? DEFAULT_EVENTS_SUBDIR;
15914
- const eventsDir = join51(repoPath, eventsSubdir);
15915
- if (!existsSync51(eventsDir)) continue;
15885
+ const eventsDir = join50(repoPath, eventsSubdir);
15886
+ if (!existsSync50(eventsDir)) continue;
15916
15887
  const projectStats = { imported: 0, duplicates: 0, files: 0 };
15917
15888
  let files;
15918
15889
  try {
@@ -15922,7 +15893,7 @@ async function syncWalFromAllProjects() {
15922
15893
  continue;
15923
15894
  }
15924
15895
  for (const file of files) {
15925
- const filePath = join51(eventsDir, file);
15896
+ const filePath = join50(eventsDir, file);
15926
15897
  const events = await parseWalFile(filePath, result.errors);
15927
15898
  if (events.length === 0) continue;
15928
15899
  try {
@@ -16249,10 +16220,10 @@ function createCostCommand() {
16249
16220
  }
16250
16221
 
16251
16222
  // src/cli/index.ts
16252
- var PANOPTICON_ENV_FILE = join52(homedir24(), ".panopticon.env");
16253
- if (existsSync52(PANOPTICON_ENV_FILE)) {
16223
+ var PANOPTICON_ENV_FILE = join51(homedir23(), ".panopticon.env");
16224
+ if (existsSync51(PANOPTICON_ENV_FILE)) {
16254
16225
  try {
16255
- const envContent = readFileSync46(PANOPTICON_ENV_FILE, "utf-8");
16226
+ const envContent = readFileSync45(PANOPTICON_ENV_FILE, "utf-8");
16256
16227
  for (const line of envContent.split("\n")) {
16257
16228
  const trimmed = line.trim();
16258
16229
  if (!trimmed || trimmed.startsWith("#")) continue;
@@ -16269,7 +16240,7 @@ if (existsSync52(PANOPTICON_ENV_FILE)) {
16269
16240
  }
16270
16241
  }
16271
16242
  var program = new Command2();
16272
- program.name("pan").description("Multi-agent orchestration for AI coding assistants").version(JSON.parse(readFileSync46(join52(import.meta.dirname, "../../package.json"), "utf-8")).version);
16243
+ program.name("pan").description("Multi-agent orchestration for AI coding assistants").version(JSON.parse(readFileSync45(join51(import.meta.dirname, "../../package.json"), "utf-8")).version);
16273
16244
  program.command("init").description("Initialize Panopticon (~/.panopticon/)").action(initCommand);
16274
16245
  program.command("sync").description("Sync skills/agents/rules to devroot").option("--dry-run", "Show what would be synced").option("--force", "Overwrite files modified since Panopticon installed them").option("--diff", "Show diff for modified files").option("--backup-only", "Only create backup").action(syncCommand);
16275
16246
  program.command("restore [timestamp]").description("Restore from backup").action(restoreCommand);
@@ -16293,21 +16264,21 @@ program.command("migrate-config").description("Migrate from settings.json to con
16293
16264
  program.command("status").description("Show running agents (shorthand for work status)").option("--json", "Output as JSON").option("--tldr", "Show TLDR index health across all workspaces").option("--context", "Show context window usage % for each agent").action(statusCommand);
16294
16265
  program.command("up").description("Start dashboard (and Traefik if enabled)").option("--detach", "Run in background").option("--skip-traefik", "Skip Traefik startup").action(async (options) => {
16295
16266
  const { spawn: spawn2, execSync: execSync9 } = await import("child_process");
16296
- const { join: join53, dirname: dirname16 } = await import("path");
16267
+ const { join: join52, dirname: dirname16 } = await import("path");
16297
16268
  const { fileURLToPath: fileURLToPath6 } = await import("url");
16298
- const { readFileSync: readFileSync47, existsSync: existsSync53 } = await import("fs");
16269
+ const { readFileSync: readFileSync46, existsSync: existsSync52 } = await import("fs");
16299
16270
  const { parse } = await import("@iarna/toml");
16300
16271
  const __dirname6 = dirname16(fileURLToPath6(import.meta.url));
16301
- const bundledServer = join53(__dirname6, "..", "dashboard", "server.js");
16302
- const srcDashboard = join53(__dirname6, "..", "..", "src", "dashboard");
16303
- const configFile = join53(process.env.HOME || "", ".panopticon", "config.toml");
16272
+ const bundledServer = join52(__dirname6, "..", "dashboard", "server.js");
16273
+ const srcDashboard = join52(__dirname6, "..", "..", "src", "dashboard");
16274
+ const configFile = join52(process.env.HOME || "", ".panopticon", "config.toml");
16304
16275
  let traefikEnabled = false;
16305
16276
  let traefikDomain = "pan.localhost";
16306
16277
  let dashboardPort = 3010;
16307
16278
  let dashboardApiPort = 3011;
16308
- if (existsSync53(configFile)) {
16279
+ if (existsSync52(configFile)) {
16309
16280
  try {
16310
- const configContent = readFileSync47(configFile, "utf-8");
16281
+ const configContent = readFileSync46(configFile, "utf-8");
16311
16282
  const config2 = parse(configContent);
16312
16283
  traefikEnabled = config2.traefik?.enabled === true;
16313
16284
  traefikDomain = config2.traefik?.domain || "pan.localhost";
@@ -16337,7 +16308,7 @@ program.command("up").description("Start dashboard (and Traefik if enabled)").op
16337
16308
  }
16338
16309
  try {
16339
16310
  const { ensureBaseDomain: ensureBaseDomain2, detectDnsSyncMethod: detectDnsSyncMethod2, syncDnsToWindows: syncDnsToWindows2 } = await import("../dns-7BDJSD3E.js");
16340
- const dnsMethod = (existsSync53(configFile) ? parse(readFileSync47(configFile, "utf-8")).traefik?.dns_sync_method : null) || detectDnsSyncMethod2();
16311
+ const dnsMethod = (existsSync52(configFile) ? parse(readFileSync46(configFile, "utf-8")).traefik?.dns_sync_method : null) || detectDnsSyncMethod2();
16341
16312
  ensureBaseDomain2(dnsMethod, traefikDomain);
16342
16313
  if (dnsMethod === "wsl2hosts") {
16343
16314
  syncDnsToWindows2().catch(() => {
@@ -16360,19 +16331,19 @@ program.command("up").description("Start dashboard (and Traefik if enabled)").op
16360
16331
  }
16361
16332
  }
16362
16333
  if (traefikEnabled && !options.skipTraefik) {
16363
- const traefikDir = join53(process.env.HOME || "", ".panopticon", "traefik");
16364
- if (existsSync53(traefikDir)) {
16334
+ const traefikDir = join52(process.env.HOME || "", ".panopticon", "traefik");
16335
+ if (existsSync52(traefikDir)) {
16365
16336
  try {
16366
- const composeFile = join53(traefikDir, "docker-compose.yml");
16367
- if (existsSync53(composeFile)) {
16368
- const content = readFileSync47(composeFile, "utf-8");
16337
+ const composeFile = join52(traefikDir, "docker-compose.yml");
16338
+ if (existsSync52(composeFile)) {
16339
+ const content = readFileSync46(composeFile, "utf-8");
16369
16340
  if (!content.includes("external: true") && content.includes("panopticon:")) {
16370
16341
  const patched = content.replace(
16371
16342
  /networks:\s*\n\s*panopticon:\s*\n\s*name: panopticon\s*\n\s*driver: bridge/,
16372
16343
  "networks:\n panopticon:\n name: panopticon\n external: true # Network created by 'pan install'"
16373
16344
  );
16374
- const { writeFileSync: writeFileSync27 } = await import("fs");
16375
- writeFileSync27(composeFile, patched);
16345
+ const { writeFileSync: writeFileSync26 } = await import("fs");
16346
+ writeFileSync26(composeFile, patched);
16376
16347
  console.log(chalk62.dim(" (migrated network config)"));
16377
16348
  }
16378
16349
  }
@@ -16390,8 +16361,8 @@ program.command("up").description("Start dashboard (and Traefik if enabled)").op
16390
16361
  }
16391
16362
  }
16392
16363
  }
16393
- const isProduction = existsSync53(bundledServer);
16394
- const isDevelopment = existsSync53(srcDashboard);
16364
+ const isProduction = existsSync52(bundledServer);
16365
+ const isDevelopment = existsSync52(srcDashboard);
16395
16366
  if (!isProduction && !isDevelopment) {
16396
16367
  console.error(chalk62.red("Error: Dashboard not found"));
16397
16368
  console.error(chalk62.dim("This may be a corrupted installation. Try reinstalling panopticon-cli."));
@@ -16466,8 +16437,8 @@ program.command("up").description("Start dashboard (and Traefik if enabled)").op
16466
16437
  try {
16467
16438
  const { getTldrDaemonService: getTldrDaemonService2 } = await import("../tldr-daemon-T3THOUGT.js");
16468
16439
  const projectRoot = process.cwd();
16469
- const venvPath = join53(projectRoot, ".venv");
16470
- if (existsSync53(venvPath)) {
16440
+ const venvPath = join52(projectRoot, ".venv");
16441
+ if (existsSync52(venvPath)) {
16471
16442
  console.log(chalk62.dim("\nStarting TLDR daemon for project root..."));
16472
16443
  const tldrService = getTldrDaemonService2(projectRoot, venvPath);
16473
16444
  await tldrService.start(true);
@@ -16483,17 +16454,17 @@ program.command("up").description("Start dashboard (and Traefik if enabled)").op
16483
16454
  });
16484
16455
  program.command("down").description("Stop dashboard (and Traefik if enabled)").option("--skip-traefik", "Skip Traefik shutdown").action(async (options) => {
16485
16456
  const { execSync: execSync9 } = await import("child_process");
16486
- const { join: join53 } = await import("path");
16487
- const { readFileSync: readFileSync47, existsSync: existsSync53 } = await import("fs");
16457
+ const { join: join52 } = await import("path");
16458
+ const { readFileSync: readFileSync46, existsSync: existsSync52 } = await import("fs");
16488
16459
  const { parse } = await import("@iarna/toml");
16489
16460
  console.log(chalk62.bold("Stopping Panopticon...\n"));
16490
- const configFile = join53(process.env.HOME || "", ".panopticon", "config.toml");
16461
+ const configFile = join52(process.env.HOME || "", ".panopticon", "config.toml");
16491
16462
  let traefikEnabled = false;
16492
16463
  let dashboardPort = 3010;
16493
16464
  let dashboardApiPort = 3011;
16494
- if (existsSync53(configFile)) {
16465
+ if (existsSync52(configFile)) {
16495
16466
  try {
16496
- const configContent = readFileSync47(configFile, "utf-8");
16467
+ const configContent = readFileSync46(configFile, "utf-8");
16497
16468
  const config2 = parse(configContent);
16498
16469
  traefikEnabled = config2.traefik?.enabled === true;
16499
16470
  dashboardPort = config2.dashboard?.port || 3010;
@@ -16510,8 +16481,8 @@ program.command("down").description("Stop dashboard (and Traefik if enabled)").o
16510
16481
  console.log(chalk62.dim(" No dashboard processes found"));
16511
16482
  }
16512
16483
  if (traefikEnabled && !options.skipTraefik) {
16513
- const traefikDir = join53(process.env.HOME || "", ".panopticon", "traefik");
16514
- if (existsSync53(traefikDir)) {
16484
+ const traefikDir = join52(process.env.HOME || "", ".panopticon", "traefik");
16485
+ if (existsSync52(traefikDir)) {
16515
16486
  console.log(chalk62.dim("Stopping Traefik..."));
16516
16487
  try {
16517
16488
  execSync9("docker compose down", {
@@ -16530,8 +16501,8 @@ program.command("down").description("Stop dashboard (and Traefik if enabled)").o
16530
16501
  const { promisify: promisify21 } = await import("util");
16531
16502
  const execAsync21 = promisify21(exec21);
16532
16503
  const projectRoot = process.cwd();
16533
- const venvPath = join53(projectRoot, ".venv");
16534
- if (existsSync53(venvPath)) {
16504
+ const venvPath = join52(projectRoot, ".venv");
16505
+ if (existsSync52(venvPath)) {
16535
16506
  console.log(chalk62.dim("\nStopping TLDR daemon..."));
16536
16507
  const tldrService = getTldrDaemonService2(projectRoot, venvPath);
16537
16508
  await tldrService.stop();