panopticon-cli 0.5.0 → 0.5.1
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/{agents-E43Y3HNU.js → agents-5OPQKM5K.js} +4 -3
- package/dist/{chunk-OMNXYPXC.js → chunk-2V4NF7J2.js} +14 -1
- package/dist/chunk-2V4NF7J2.js.map +1 -0
- package/dist/{chunk-WQG2TYCB.js → chunk-4YSYJ4HM.js} +2 -2
- package/dist/{chunk-NTO3EDB3.js → chunk-76F6DSVS.js} +47 -8
- package/dist/chunk-76F6DSVS.js.map +1 -0
- package/dist/{chunk-GR6ZZMCX.js → chunk-F5555J3A.js} +18 -1
- package/dist/chunk-F5555J3A.js.map +1 -0
- package/dist/{chunk-PPRFKTVC.js → chunk-NLQRED36.js} +2 -2
- package/dist/{chunk-AAFQANKW.js → chunk-OWHXCGVO.js} +29 -29
- package/dist/chunk-OWHXCGVO.js.map +1 -0
- package/dist/{chunk-HZT2AOPN.js → chunk-VHKSS7QX.js} +28 -5
- package/dist/chunk-VHKSS7QX.js.map +1 -0
- package/dist/{chunk-GFP3PIPB.js → chunk-YGJ54GW2.js} +1 -1
- package/dist/chunk-YGJ54GW2.js.map +1 -0
- package/dist/cli/index.js +401 -318
- package/dist/cli/index.js.map +1 -1
- package/dist/dashboard/public/assets/{index-DQHkwvvJ.js → index-Ce6q21Fm.js} +135 -135
- package/dist/dashboard/public/assets/{index-BxpjweAL.css → index-NzpI0ItZ.css} +1 -1
- package/dist/dashboard/public/index.html +2 -2
- package/dist/dashboard/server.js +1420 -1007
- package/dist/{feedback-writer-LVZ5TFYZ.js → feedback-writer-VRMMWWTW.js} +2 -2
- package/dist/git-utils-I2UDKNZH.js +131 -0
- package/dist/git-utils-I2UDKNZH.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -2
- package/dist/{projects-JEIVIYC6.js → projects-CFX3RTDL.js} +4 -2
- package/dist/{remote-workspace-AHVHQEES.js → remote-workspace-7FPGF2RM.js} +2 -2
- package/dist/{review-status-EPFG4XM7.js → review-status-TDPSOU5J.js} +2 -2
- package/dist/{specialist-context-ZC6A4M3I.js → specialist-context-WGUUYDWY.js} +3 -3
- package/dist/{specialist-logs-KLGJCEUL.js → specialist-logs-XJB5TCKJ.js} +3 -3
- package/dist/{specialists-O4HWDJL5.js → specialists-5LBRHYFA.js} +3 -3
- package/dist/{traefik-QN7R5I6V.js → traefik-WFMQX2LY.js} +3 -3
- package/dist/{workspace-manager-IE4JL2JP.js → workspace-manager-E434Z45T.js} +2 -2
- package/package.json +1 -1
- package/scripts/record-cost-event.js +5 -5
- package/skills/pan-new-project/SKILL.md +304 -0
- package/dist/chunk-AAFQANKW.js.map +0 -1
- package/dist/chunk-GFP3PIPB.js.map +0 -1
- package/dist/chunk-GR6ZZMCX.js.map +0 -1
- package/dist/chunk-HZT2AOPN.js.map +0 -1
- package/dist/chunk-NTO3EDB3.js.map +0 -1
- package/dist/chunk-OMNXYPXC.js.map +0 -1
- /package/dist/{agents-E43Y3HNU.js.map → agents-5OPQKM5K.js.map} +0 -0
- /package/dist/{chunk-WQG2TYCB.js.map → chunk-4YSYJ4HM.js.map} +0 -0
- /package/dist/{chunk-PPRFKTVC.js.map → chunk-NLQRED36.js.map} +0 -0
- /package/dist/{feedback-writer-LVZ5TFYZ.js.map → feedback-writer-VRMMWWTW.js.map} +0 -0
- /package/dist/{projects-JEIVIYC6.js.map → projects-CFX3RTDL.js.map} +0 -0
- /package/dist/{remote-workspace-AHVHQEES.js.map → remote-workspace-7FPGF2RM.js.map} +0 -0
- /package/dist/{review-status-EPFG4XM7.js.map → review-status-TDPSOU5J.js.map} +0 -0
- /package/dist/{specialist-context-ZC6A4M3I.js.map → specialist-context-WGUUYDWY.js.map} +0 -0
- /package/dist/{specialist-logs-KLGJCEUL.js.map → specialist-logs-XJB5TCKJ.js.map} +0 -0
- /package/dist/{specialists-O4HWDJL5.js.map → specialists-5LBRHYFA.js.map} +0 -0
- /package/dist/{traefik-QN7R5I6V.js.map → traefik-WFMQX2LY.js.map} +0 -0
- /package/dist/{workspace-manager-IE4JL2JP.js.map → workspace-manager-E434Z45T.js.map} +0 -0
package/dist/cli/index.js
CHANGED
|
@@ -1,18 +1,43 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
checkSpecialistQueue,
|
|
4
|
+
clearSessionId,
|
|
5
|
+
completeSpecialistTask,
|
|
6
|
+
getAllSpecialistStatus,
|
|
7
|
+
getEnabledSpecialists,
|
|
8
|
+
getNextSpecialistTask,
|
|
9
|
+
getProjectDirs,
|
|
10
|
+
getSessionFiles,
|
|
11
|
+
getSessionId,
|
|
12
|
+
getSpecialistMetadata,
|
|
13
|
+
getSpecialistStatus,
|
|
14
|
+
getTmuxSessionName,
|
|
15
|
+
init_jsonl_parser,
|
|
16
|
+
init_specialists,
|
|
17
|
+
initializeEnabledSpecialists,
|
|
18
|
+
isRunning,
|
|
19
|
+
parseClaudeSession,
|
|
20
|
+
recordWake,
|
|
21
|
+
setSessionId,
|
|
22
|
+
wakeSpecialist,
|
|
23
|
+
wakeSpecialistOrQueue,
|
|
24
|
+
wakeSpecialistWithTask
|
|
25
|
+
} from "../chunk-OWHXCGVO.js";
|
|
2
26
|
import {
|
|
3
27
|
cleanupTemplateFiles,
|
|
4
28
|
ensureProjectCerts,
|
|
5
29
|
generatePanopticonTraefikConfig,
|
|
6
30
|
generateTlsConfig
|
|
7
|
-
} from "../chunk-
|
|
31
|
+
} from "../chunk-NLQRED36.js";
|
|
8
32
|
import {
|
|
9
33
|
applyProjectTemplateOverlay,
|
|
10
34
|
createWorkspace,
|
|
11
35
|
init_skills_merge,
|
|
12
36
|
init_workspace_manager,
|
|
13
37
|
mergeSkillsIntoWorkspace,
|
|
14
|
-
removeWorkspace
|
|
15
|
-
|
|
38
|
+
removeWorkspace,
|
|
39
|
+
stopWorkspaceDocker
|
|
40
|
+
} from "../chunk-F5555J3A.js";
|
|
16
41
|
import "../chunk-7SN4L4PH.js";
|
|
17
42
|
import {
|
|
18
43
|
init_remote_agents,
|
|
@@ -41,7 +66,24 @@ import {
|
|
|
41
66
|
saveSessionId,
|
|
42
67
|
spawnAgent,
|
|
43
68
|
stopAgent
|
|
44
|
-
} from "../chunk-
|
|
69
|
+
} from "../chunk-VHKSS7QX.js";
|
|
70
|
+
import {
|
|
71
|
+
checkHook,
|
|
72
|
+
clearHook,
|
|
73
|
+
createSession,
|
|
74
|
+
generateFixedPointPrompt,
|
|
75
|
+
getModelId,
|
|
76
|
+
init_hooks,
|
|
77
|
+
init_tmux,
|
|
78
|
+
init_work_type_router,
|
|
79
|
+
killSession,
|
|
80
|
+
popFromHook,
|
|
81
|
+
pushToHook,
|
|
82
|
+
sendKeys,
|
|
83
|
+
sendKeysAsync,
|
|
84
|
+
sendMail,
|
|
85
|
+
sessionExists
|
|
86
|
+
} from "../chunk-FTCPTHIJ.js";
|
|
45
87
|
import {
|
|
46
88
|
createShadowState,
|
|
47
89
|
getPendingSyncCount,
|
|
@@ -69,48 +111,7 @@ import {
|
|
|
69
111
|
init_review_status,
|
|
70
112
|
loadReviewStatuses,
|
|
71
113
|
saveReviewStatuses
|
|
72
|
-
} from "../chunk-
|
|
73
|
-
import {
|
|
74
|
-
checkSpecialistQueue,
|
|
75
|
-
clearSessionId,
|
|
76
|
-
completeSpecialistTask,
|
|
77
|
-
getAllSpecialistStatus,
|
|
78
|
-
getEnabledSpecialists,
|
|
79
|
-
getNextSpecialistTask,
|
|
80
|
-
getProjectDirs,
|
|
81
|
-
getSessionFiles,
|
|
82
|
-
getSessionId,
|
|
83
|
-
getSpecialistMetadata,
|
|
84
|
-
getSpecialistStatus,
|
|
85
|
-
getTmuxSessionName,
|
|
86
|
-
init_jsonl_parser,
|
|
87
|
-
init_specialists,
|
|
88
|
-
initializeEnabledSpecialists,
|
|
89
|
-
isRunning,
|
|
90
|
-
parseClaudeSession,
|
|
91
|
-
recordWake,
|
|
92
|
-
setSessionId,
|
|
93
|
-
wakeSpecialist,
|
|
94
|
-
wakeSpecialistOrQueue,
|
|
95
|
-
wakeSpecialistWithTask
|
|
96
|
-
} from "../chunk-AAFQANKW.js";
|
|
97
|
-
import {
|
|
98
|
-
checkHook,
|
|
99
|
-
clearHook,
|
|
100
|
-
createSession,
|
|
101
|
-
generateFixedPointPrompt,
|
|
102
|
-
getModelId,
|
|
103
|
-
init_hooks,
|
|
104
|
-
init_tmux,
|
|
105
|
-
init_work_type_router,
|
|
106
|
-
killSession,
|
|
107
|
-
popFromHook,
|
|
108
|
-
pushToHook,
|
|
109
|
-
sendKeys,
|
|
110
|
-
sendKeysAsync,
|
|
111
|
-
sendMail,
|
|
112
|
-
sessionExists
|
|
113
|
-
} from "../chunk-FTCPTHIJ.js";
|
|
114
|
+
} from "../chunk-YGJ54GW2.js";
|
|
114
115
|
import "../chunk-JQBV3Q2W.js";
|
|
115
116
|
import {
|
|
116
117
|
addAlias,
|
|
@@ -128,13 +129,13 @@ import {
|
|
|
128
129
|
restoreBackup,
|
|
129
130
|
syncHooks,
|
|
130
131
|
syncStatusline
|
|
131
|
-
} from "../chunk-
|
|
132
|
+
} from "../chunk-4YSYJ4HM.js";
|
|
132
133
|
import "../chunk-AQXETQHW.js";
|
|
133
134
|
import {
|
|
134
135
|
createTracker,
|
|
135
136
|
createTrackerFromConfig,
|
|
136
137
|
init_factory
|
|
137
|
-
} from "../chunk-
|
|
138
|
+
} from "../chunk-76F6DSVS.js";
|
|
138
139
|
import {
|
|
139
140
|
init_config_yaml,
|
|
140
141
|
init_settings,
|
|
@@ -162,7 +163,7 @@ import {
|
|
|
162
163
|
registerProject,
|
|
163
164
|
resolveProjectFromIssue,
|
|
164
165
|
unregisterProject
|
|
165
|
-
} from "../chunk-
|
|
166
|
+
} from "../chunk-2V4NF7J2.js";
|
|
166
167
|
import {
|
|
167
168
|
NotImplementedError,
|
|
168
169
|
init_interface
|
|
@@ -1556,7 +1557,7 @@ async function handleRemoteWorkspace(issueId, options, spinner) {
|
|
|
1556
1557
|
if (!remoteMetadata) {
|
|
1557
1558
|
spinner.text = "Remote workspace not found, creating...";
|
|
1558
1559
|
try {
|
|
1559
|
-
const { createRemoteWorkspace: createRemoteWorkspace2 } = await import("../remote-workspace-
|
|
1560
|
+
const { createRemoteWorkspace: createRemoteWorkspace2 } = await import("../remote-workspace-7FPGF2RM.js");
|
|
1560
1561
|
remoteMetadata = await createRemoteWorkspace2(issueId, { spinner });
|
|
1561
1562
|
} catch (error) {
|
|
1562
1563
|
spinner.fail(`Failed to create remote workspace: ${error.message}`);
|
|
@@ -2289,9 +2290,9 @@ init_agents();
|
|
|
2289
2290
|
init_paths();
|
|
2290
2291
|
import chalk12 from "chalk";
|
|
2291
2292
|
import ora6 from "ora";
|
|
2292
|
-
import { existsSync as
|
|
2293
|
-
import { join as
|
|
2294
|
-
import { homedir as
|
|
2293
|
+
import { existsSync as existsSync13, writeFileSync as writeFileSync4, readFileSync as readFileSync11, mkdirSync as mkdirSync4, readdirSync as readdirSync11 } from "fs";
|
|
2294
|
+
import { join as join13 } from "path";
|
|
2295
|
+
import { homedir as homedir6 } from "os";
|
|
2295
2296
|
import { exec } from "child_process";
|
|
2296
2297
|
import { promisify } from "util";
|
|
2297
2298
|
|
|
@@ -2424,12 +2425,46 @@ function cleanupWorkflowLabels(currentLabels, targetState) {
|
|
|
2424
2425
|
return cleaned;
|
|
2425
2426
|
}
|
|
2426
2427
|
|
|
2428
|
+
// src/lib/tracker-utils.ts
|
|
2429
|
+
init_esm_shims();
|
|
2430
|
+
import { readFileSync as readFileSync10, existsSync as existsSync12 } from "fs";
|
|
2431
|
+
import { join as join12 } from "path";
|
|
2432
|
+
import { homedir as homedir5 } from "os";
|
|
2433
|
+
function parseGitHubRepos() {
|
|
2434
|
+
const envFile = join12(homedir5(), ".panopticon.env");
|
|
2435
|
+
if (!existsSync12(envFile)) return [];
|
|
2436
|
+
const content = readFileSync10(envFile, "utf-8");
|
|
2437
|
+
const reposMatch = content.match(/GITHUB_REPOS=(.+)/);
|
|
2438
|
+
if (!reposMatch) return [];
|
|
2439
|
+
return reposMatch[1].trim().split(",").map((r) => {
|
|
2440
|
+
const [repoPath, prefix] = r.trim().split(":");
|
|
2441
|
+
const [owner, repo] = (repoPath || "").split("/");
|
|
2442
|
+
return { owner: owner || "", repo: repo || "", prefix: (prefix || "").toUpperCase() };
|
|
2443
|
+
}).filter((r) => r.owner && r.repo && r.prefix);
|
|
2444
|
+
}
|
|
2445
|
+
function extractIssuePrefix(issueId) {
|
|
2446
|
+
return issueId.split("-")[0].toUpperCase();
|
|
2447
|
+
}
|
|
2448
|
+
function resolveGitHubIssue(issueId) {
|
|
2449
|
+
const prefix = extractIssuePrefix(issueId);
|
|
2450
|
+
const repos = parseGitHubRepos();
|
|
2451
|
+
for (const repoConfig of repos) {
|
|
2452
|
+
if (repoConfig.prefix === prefix) {
|
|
2453
|
+
const number = parseInt(issueId.split("-")[1], 10);
|
|
2454
|
+
if (!isNaN(number)) {
|
|
2455
|
+
return { isGitHub: true, ...repoConfig, number };
|
|
2456
|
+
}
|
|
2457
|
+
}
|
|
2458
|
+
}
|
|
2459
|
+
return { isGitHub: false };
|
|
2460
|
+
}
|
|
2461
|
+
|
|
2427
2462
|
// src/cli/commands/work/done.ts
|
|
2428
2463
|
var execAsync = promisify(exec);
|
|
2429
2464
|
function getLinearApiKey3() {
|
|
2430
|
-
const envFile =
|
|
2431
|
-
if (
|
|
2432
|
-
const content =
|
|
2465
|
+
const envFile = join13(homedir6(), ".panopticon.env");
|
|
2466
|
+
if (existsSync13(envFile)) {
|
|
2467
|
+
const content = readFileSync11(envFile, "utf-8");
|
|
2433
2468
|
const match = content.match(/LINEAR_API_KEY=(.+)/);
|
|
2434
2469
|
if (match) return match[1].trim();
|
|
2435
2470
|
}
|
|
@@ -2471,9 +2506,9 @@ ${comment}`
|
|
|
2471
2506
|
}
|
|
2472
2507
|
}
|
|
2473
2508
|
function getGitHubConfig() {
|
|
2474
|
-
const envFile =
|
|
2475
|
-
if (!
|
|
2476
|
-
const content =
|
|
2509
|
+
const envFile = join13(homedir6(), ".panopticon.env");
|
|
2510
|
+
if (!existsSync13(envFile)) return null;
|
|
2511
|
+
const content = readFileSync11(envFile, "utf-8");
|
|
2477
2512
|
const tokenMatch = content.match(/GITHUB_TOKEN=(.+)/);
|
|
2478
2513
|
if (!tokenMatch) return null;
|
|
2479
2514
|
const token = tokenMatch[1].trim();
|
|
@@ -2491,9 +2526,9 @@ async function updateGitHubToInReview(issueId, comment) {
|
|
|
2491
2526
|
try {
|
|
2492
2527
|
const ghConfig = getGitHubConfig();
|
|
2493
2528
|
if (!ghConfig) return false;
|
|
2494
|
-
const
|
|
2495
|
-
|
|
2496
|
-
const { owner, repo } =
|
|
2529
|
+
const resolved = resolveGitHubIssue(issueId);
|
|
2530
|
+
if (!resolved.isGitHub) return false;
|
|
2531
|
+
const { owner, repo, number } = resolved;
|
|
2497
2532
|
const token = ghConfig.token;
|
|
2498
2533
|
const headers = {
|
|
2499
2534
|
"Authorization": `token ${token}`,
|
|
@@ -2529,10 +2564,59 @@ async function doneCommand(id, options = {}) {
|
|
|
2529
2564
|
const issueId = id.replace(/^agent-/i, "").toUpperCase();
|
|
2530
2565
|
const agentId = `agent-${issueId.toLowerCase()}`;
|
|
2531
2566
|
if (!options.force) {
|
|
2532
|
-
const { getAgentState: getAgentState2 } = await import("../agents-
|
|
2567
|
+
const { getAgentState: getAgentState2 } = await import("../agents-5OPQKM5K.js");
|
|
2533
2568
|
const agentState = getAgentState2(agentId);
|
|
2534
2569
|
const workspacePath = agentState?.workspace;
|
|
2535
|
-
if (workspacePath &&
|
|
2570
|
+
if (workspacePath && existsSync13(workspacePath)) {
|
|
2571
|
+
try {
|
|
2572
|
+
const { getReviewStatus: getReviewStatus2 } = await import("../review-status-TDPSOU5J.js");
|
|
2573
|
+
const { getWorkspaceCommitHashes } = await import("../git-utils-I2UDKNZH.js");
|
|
2574
|
+
const { getDashboardApiUrl: getDashboardApiUrl2 } = await import("../config-4CJNUE3O.js");
|
|
2575
|
+
const reviewStatus = getReviewStatus2(issueId);
|
|
2576
|
+
if (reviewStatus) {
|
|
2577
|
+
const isBlockedOrFailed = ["blocked", "failed"].includes(reviewStatus.reviewStatus);
|
|
2578
|
+
if (isBlockedOrFailed) {
|
|
2579
|
+
const dashboardUrl = getDashboardApiUrl2();
|
|
2580
|
+
console.error(chalk12.red(`
|
|
2581
|
+
\u2716 Cannot mark work done \u2014 review is ${reviewStatus.reviewStatus} for ${issueId}
|
|
2582
|
+
`));
|
|
2583
|
+
console.error(" The review agent found issues that must be addressed before this issue can be completed.");
|
|
2584
|
+
console.error(" Fix the issues, commit your changes, then re-submit for review:\n");
|
|
2585
|
+
console.error(chalk12.cyan(` curl -X POST ${dashboardUrl}/api/workspaces/${issueId}/request-review \\`));
|
|
2586
|
+
console.error(chalk12.cyan(` -H "Content-Type: application/json" -d '{}'`));
|
|
2587
|
+
console.error("");
|
|
2588
|
+
console.error(chalk12.dim(" Use --force to skip this check."));
|
|
2589
|
+
console.error("");
|
|
2590
|
+
process.exit(1);
|
|
2591
|
+
}
|
|
2592
|
+
if (reviewStatus.lastReviewCommits) {
|
|
2593
|
+
const currentHashes = await getWorkspaceCommitHashes(workspacePath);
|
|
2594
|
+
const allKeys = /* @__PURE__ */ new Set([
|
|
2595
|
+
...Object.keys(currentHashes),
|
|
2596
|
+
...Object.keys(reviewStatus.lastReviewCommits)
|
|
2597
|
+
]);
|
|
2598
|
+
const commitsChanged = [...allKeys].some(
|
|
2599
|
+
(k) => currentHashes[k] !== reviewStatus.lastReviewCommits[k]
|
|
2600
|
+
);
|
|
2601
|
+
if (commitsChanged) {
|
|
2602
|
+
const dashboardUrl = getDashboardApiUrl2();
|
|
2603
|
+
console.error(chalk12.red(`
|
|
2604
|
+
\u2716 Cannot mark work done \u2014 commits changed since last review for ${issueId}
|
|
2605
|
+
`));
|
|
2606
|
+
console.error(" New commits were added after the last review/test run. The specialists");
|
|
2607
|
+
console.error(" must review and test your latest code before work can be marked done.");
|
|
2608
|
+
console.error(" Re-submit for review:\n");
|
|
2609
|
+
console.error(chalk12.cyan(` curl -X POST ${dashboardUrl}/api/workspaces/${issueId}/request-review \\`));
|
|
2610
|
+
console.error(chalk12.cyan(` -H "Content-Type: application/json" -d '{}'`));
|
|
2611
|
+
console.error("");
|
|
2612
|
+
console.error(chalk12.dim(" Use --force to skip this check."));
|
|
2613
|
+
console.error("");
|
|
2614
|
+
process.exit(1);
|
|
2615
|
+
}
|
|
2616
|
+
}
|
|
2617
|
+
}
|
|
2618
|
+
} catch {
|
|
2619
|
+
}
|
|
2536
2620
|
const failures = [];
|
|
2537
2621
|
try {
|
|
2538
2622
|
const { stdout } = await execAsync("bd list --status open --limit 0 --json", { cwd: workspacePath });
|
|
@@ -2547,7 +2631,7 @@ async function doneCommand(id, options = {}) {
|
|
|
2547
2631
|
}
|
|
2548
2632
|
} catch {
|
|
2549
2633
|
}
|
|
2550
|
-
const hasTopLevelGit =
|
|
2634
|
+
const hasTopLevelGit = existsSync13(join13(workspacePath, ".git"));
|
|
2551
2635
|
if (hasTopLevelGit) {
|
|
2552
2636
|
try {
|
|
2553
2637
|
const { stdout } = await execAsync("git status --porcelain", { cwd: workspacePath });
|
|
@@ -2564,8 +2648,8 @@ async function doneCommand(id, options = {}) {
|
|
|
2564
2648
|
const entries = readdirSync11(workspacePath, { withFileTypes: true });
|
|
2565
2649
|
for (const entry of entries) {
|
|
2566
2650
|
if (!entry.isDirectory() || entry.name.startsWith(".")) continue;
|
|
2567
|
-
const subPath =
|
|
2568
|
-
if (!
|
|
2651
|
+
const subPath = join13(workspacePath, entry.name);
|
|
2652
|
+
if (!existsSync13(join13(subPath, ".git"))) continue;
|
|
2569
2653
|
try {
|
|
2570
2654
|
const { stdout } = await execAsync("git status --porcelain", { cwd: subPath });
|
|
2571
2655
|
if (stdout.trim()) {
|
|
@@ -2599,14 +2683,14 @@ async function doneCommand(id, options = {}) {
|
|
|
2599
2683
|
try {
|
|
2600
2684
|
let trackerUpdated = false;
|
|
2601
2685
|
let shadowModeActive = false;
|
|
2602
|
-
const
|
|
2686
|
+
const ghResolution = resolveGitHubIssue(issueId);
|
|
2603
2687
|
const skipTrackerUpdate = shouldSkipTrackerUpdate(issueId, options.shadow);
|
|
2604
2688
|
if (skipTrackerUpdate) {
|
|
2605
2689
|
shadowModeActive = true;
|
|
2606
2690
|
spinner.text = "Updating shadow state...";
|
|
2607
2691
|
updateShadowState(issueId, "closed", "pan work done");
|
|
2608
2692
|
console.log(chalk12.cyan(` \u{1F47B} Shadow mode: status updated locally`));
|
|
2609
|
-
} else if (
|
|
2693
|
+
} else if (ghResolution.isGitHub) {
|
|
2610
2694
|
spinner.text = "Updating GitHub labels...";
|
|
2611
2695
|
trackerUpdated = await updateGitHubToInReview(issueId, options.comment);
|
|
2612
2696
|
if (trackerUpdated) {
|
|
@@ -2628,7 +2712,7 @@ async function doneCommand(id, options = {}) {
|
|
|
2628
2712
|
console.log(chalk12.dim(" LINEAR_API_KEY not set - skipping status update"));
|
|
2629
2713
|
}
|
|
2630
2714
|
}
|
|
2631
|
-
const { getAgentState: getAgentState2, saveAgentState: saveAgentState2 } = await import("../agents-
|
|
2715
|
+
const { getAgentState: getAgentState2, saveAgentState: saveAgentState2 } = await import("../agents-5OPQKM5K.js");
|
|
2632
2716
|
const existingState = getAgentState2(agentId);
|
|
2633
2717
|
if (existingState) {
|
|
2634
2718
|
existingState.status = "stopped";
|
|
@@ -2639,8 +2723,8 @@ async function doneCommand(id, options = {}) {
|
|
|
2639
2723
|
state: "idle",
|
|
2640
2724
|
lastActivity: (/* @__PURE__ */ new Date()).toISOString()
|
|
2641
2725
|
});
|
|
2642
|
-
mkdirSync4(
|
|
2643
|
-
const completedFile =
|
|
2726
|
+
mkdirSync4(join13(AGENTS_DIR, agentId), { recursive: true });
|
|
2727
|
+
const completedFile = join13(AGENTS_DIR, agentId, "completed");
|
|
2644
2728
|
writeFileSync4(completedFile, JSON.stringify({
|
|
2645
2729
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
2646
2730
|
trackerUpdated,
|
|
@@ -2767,14 +2851,14 @@ init_esm_shims();
|
|
|
2767
2851
|
import chalk13 from "chalk";
|
|
2768
2852
|
import ora7 from "ora";
|
|
2769
2853
|
import inquirer2 from "inquirer";
|
|
2770
|
-
import { readFileSync as
|
|
2771
|
-
import { join as
|
|
2772
|
-
import { homedir as
|
|
2854
|
+
import { readFileSync as readFileSync13, existsSync as existsSync15 } from "fs";
|
|
2855
|
+
import { join as join15, dirname as dirname5 } from "path";
|
|
2856
|
+
import { homedir as homedir7 } from "os";
|
|
2773
2857
|
|
|
2774
2858
|
// src/lib/planning/plan-utils.ts
|
|
2775
2859
|
init_esm_shims();
|
|
2776
|
-
import { existsSync as
|
|
2777
|
-
import { join as
|
|
2860
|
+
import { existsSync as existsSync14, mkdirSync as mkdirSync5, writeFileSync as writeFileSync5 } from "fs";
|
|
2861
|
+
import { join as join14 } from "path";
|
|
2778
2862
|
import { exec as exec2, spawn } from "child_process";
|
|
2779
2863
|
import { promisify as promisify2 } from "util";
|
|
2780
2864
|
init_paths();
|
|
@@ -2786,17 +2870,17 @@ async function findPRDFiles(issueId, cwd) {
|
|
|
2786
2870
|
found.push(getPRDDraftPath(issueId));
|
|
2787
2871
|
}
|
|
2788
2872
|
const searchPaths = [
|
|
2789
|
-
|
|
2790
|
-
|
|
2791
|
-
|
|
2792
|
-
|
|
2873
|
+
join14(PROJECT_DOCS_SUBDIR, PROJECT_PRDS_SUBDIR, PROJECT_PRDS_ACTIVE_SUBDIR),
|
|
2874
|
+
join14(PROJECT_DOCS_SUBDIR, PROJECT_PRDS_SUBDIR, "planned"),
|
|
2875
|
+
join14(PROJECT_DOCS_SUBDIR, PROJECT_PRDS_SUBDIR),
|
|
2876
|
+
join14(PROJECT_DOCS_SUBDIR, "prd"),
|
|
2793
2877
|
PROJECT_PRDS_SUBDIR,
|
|
2794
2878
|
PROJECT_DOCS_SUBDIR
|
|
2795
2879
|
];
|
|
2796
2880
|
const issueIdLower = issueId.toLowerCase();
|
|
2797
2881
|
for (const searchPath of searchPaths) {
|
|
2798
|
-
const fullPath =
|
|
2799
|
-
if (!
|
|
2882
|
+
const fullPath = join14(searchRoot, searchPath);
|
|
2883
|
+
if (!existsSync14(fullPath)) continue;
|
|
2800
2884
|
try {
|
|
2801
2885
|
const { stdout: result } = await execAsync2(
|
|
2802
2886
|
`find "${fullPath}" -type f -name "*.md" 2>/dev/null | xargs grep -l -i "${issueIdLower}" 2>/dev/null || true`,
|
|
@@ -3039,25 +3123,25 @@ async function createBeadsTasks(issue, tasks, cwd) {
|
|
|
3039
3123
|
return { success: errors.length === 0, created, errors };
|
|
3040
3124
|
}
|
|
3041
3125
|
function writePlanFiles(projectPath, stateContent, workspaceContent) {
|
|
3042
|
-
const planningDir =
|
|
3126
|
+
const planningDir = join14(projectPath, ".planning");
|
|
3043
3127
|
mkdirSync5(planningDir, { recursive: true });
|
|
3044
|
-
const statePath =
|
|
3045
|
-
const workspacePath =
|
|
3128
|
+
const statePath = join14(planningDir, "STATE.md");
|
|
3129
|
+
const workspacePath = join14(planningDir, "WORKSPACE.md");
|
|
3046
3130
|
writeFileSync5(statePath, stateContent);
|
|
3047
3131
|
writeFileSync5(workspacePath, workspaceContent);
|
|
3048
3132
|
return { statePath, workspacePath };
|
|
3049
3133
|
}
|
|
3050
3134
|
async function copyToPRDDirectory(projectPath, issue, content, options) {
|
|
3051
|
-
const prdDir =
|
|
3135
|
+
const prdDir = join14(projectPath, PROJECT_DOCS_SUBDIR, PROJECT_PRDS_SUBDIR, PROJECT_PRDS_ACTIVE_SUBDIR);
|
|
3052
3136
|
try {
|
|
3053
3137
|
mkdirSync5(prdDir, { recursive: true });
|
|
3054
3138
|
const filename = `${issue.identifier.toLowerCase()}-plan.md`;
|
|
3055
|
-
const prdPath =
|
|
3139
|
+
const prdPath = join14(prdDir, filename);
|
|
3056
3140
|
writeFileSync5(prdPath, content);
|
|
3057
3141
|
let committed = false;
|
|
3058
3142
|
if (options?.commitAndPush) {
|
|
3059
3143
|
try {
|
|
3060
|
-
const relativePrdPath =
|
|
3144
|
+
const relativePrdPath = join14(PROJECT_DOCS_SUBDIR, PROJECT_PRDS_SUBDIR, PROJECT_PRDS_ACTIVE_SUBDIR, filename);
|
|
3061
3145
|
await execAsync2(`git add ${relativePrdPath}`, { cwd: projectPath, encoding: "utf-8" });
|
|
3062
3146
|
try {
|
|
3063
3147
|
await execAsync2("git diff --cached --quiet", { cwd: projectPath, encoding: "utf-8" });
|
|
@@ -3104,9 +3188,9 @@ async function executePlan(issue, tasks, decisions, projectPath, options) {
|
|
|
3104
3188
|
|
|
3105
3189
|
// src/cli/commands/work/plan.ts
|
|
3106
3190
|
function getLinearApiKey4() {
|
|
3107
|
-
const envFile =
|
|
3108
|
-
if (
|
|
3109
|
-
const content =
|
|
3191
|
+
const envFile = join15(homedir7(), ".panopticon.env");
|
|
3192
|
+
if (existsSync15(envFile)) {
|
|
3193
|
+
const content = readFileSync13(envFile, "utf-8");
|
|
3110
3194
|
const match = content.match(/LINEAR_API_KEY=(.+)/);
|
|
3111
3195
|
if (match) return match[1].trim();
|
|
3112
3196
|
}
|
|
@@ -3589,9 +3673,9 @@ init_esm_shims();
|
|
|
3589
3673
|
init_config();
|
|
3590
3674
|
import chalk15 from "chalk";
|
|
3591
3675
|
import ora9 from "ora";
|
|
3592
|
-
import { readFileSync as
|
|
3593
|
-
import { join as
|
|
3594
|
-
import { homedir as
|
|
3676
|
+
import { readFileSync as readFileSync14, writeFileSync as writeFileSync6, existsSync as existsSync16, mkdirSync as mkdirSync6 } from "fs";
|
|
3677
|
+
import { join as join16 } from "path";
|
|
3678
|
+
import { homedir as homedir8 } from "os";
|
|
3595
3679
|
function getTrackerConfig2(trackerType) {
|
|
3596
3680
|
const config2 = loadConfig();
|
|
3597
3681
|
const trackerConfig = config2.trackers[trackerType];
|
|
@@ -3609,13 +3693,13 @@ function getTrackerConfig2(trackerType) {
|
|
|
3609
3693
|
};
|
|
3610
3694
|
}
|
|
3611
3695
|
function getTriageStatePath() {
|
|
3612
|
-
return
|
|
3696
|
+
return join16(homedir8(), ".panopticon", "triage-state.json");
|
|
3613
3697
|
}
|
|
3614
3698
|
function loadTriageState() {
|
|
3615
3699
|
const path = getTriageStatePath();
|
|
3616
|
-
if (
|
|
3700
|
+
if (existsSync16(path)) {
|
|
3617
3701
|
try {
|
|
3618
|
-
return JSON.parse(
|
|
3702
|
+
return JSON.parse(readFileSync14(path, "utf-8"));
|
|
3619
3703
|
} catch {
|
|
3620
3704
|
return { dismissed: [], created: {} };
|
|
3621
3705
|
}
|
|
@@ -3623,8 +3707,8 @@ function loadTriageState() {
|
|
|
3623
3707
|
return { dismissed: [], created: {} };
|
|
3624
3708
|
}
|
|
3625
3709
|
function saveTriageState(state) {
|
|
3626
|
-
const dir =
|
|
3627
|
-
if (!
|
|
3710
|
+
const dir = join16(homedir8(), ".panopticon");
|
|
3711
|
+
if (!existsSync16(dir)) {
|
|
3628
3712
|
mkdirSync6(dir, { recursive: true });
|
|
3629
3713
|
}
|
|
3630
3714
|
const path = getTriageStatePath();
|
|
@@ -4009,23 +4093,23 @@ import chalk19 from "chalk";
|
|
|
4009
4093
|
// src/lib/context.ts
|
|
4010
4094
|
init_esm_shims();
|
|
4011
4095
|
init_paths();
|
|
4012
|
-
import { existsSync as
|
|
4013
|
-
import { join as
|
|
4096
|
+
import { existsSync as existsSync17, mkdirSync as mkdirSync7, readFileSync as readFileSync15, writeFileSync as writeFileSync7, appendFileSync, readdirSync as readdirSync12 } from "fs";
|
|
4097
|
+
import { join as join17 } from "path";
|
|
4014
4098
|
function getStateFile(agentId) {
|
|
4015
|
-
return
|
|
4099
|
+
return join17(AGENTS_DIR, agentId, "STATE.md");
|
|
4016
4100
|
}
|
|
4017
4101
|
function readAgentState(agentId) {
|
|
4018
4102
|
const stateFile = getStateFile(agentId);
|
|
4019
|
-
if (!
|
|
4103
|
+
if (!existsSync17(stateFile)) return null;
|
|
4020
4104
|
try {
|
|
4021
|
-
const content =
|
|
4105
|
+
const content = readFileSync15(stateFile, "utf-8");
|
|
4022
4106
|
return parseStateMd(content);
|
|
4023
4107
|
} catch {
|
|
4024
4108
|
return null;
|
|
4025
4109
|
}
|
|
4026
4110
|
}
|
|
4027
4111
|
function writeAgentState(agentId, state) {
|
|
4028
|
-
const dir =
|
|
4112
|
+
const dir = join17(AGENTS_DIR, agentId);
|
|
4029
4113
|
mkdirSync7(dir, { recursive: true });
|
|
4030
4114
|
const content = generateStateMd(state);
|
|
4031
4115
|
writeFileSync7(getStateFile(agentId), content);
|
|
@@ -4102,14 +4186,14 @@ function parseStateMd(content) {
|
|
|
4102
4186
|
return state;
|
|
4103
4187
|
}
|
|
4104
4188
|
function getSummaryFile(agentId) {
|
|
4105
|
-
return
|
|
4189
|
+
return join17(AGENTS_DIR, agentId, "SUMMARY.md");
|
|
4106
4190
|
}
|
|
4107
4191
|
function appendSummary(agentId, summary) {
|
|
4108
|
-
const dir =
|
|
4192
|
+
const dir = join17(AGENTS_DIR, agentId);
|
|
4109
4193
|
mkdirSync7(dir, { recursive: true });
|
|
4110
4194
|
const summaryFile = getSummaryFile(agentId);
|
|
4111
4195
|
const content = generateSummaryEntry(summary);
|
|
4112
|
-
if (
|
|
4196
|
+
if (existsSync17(summaryFile)) {
|
|
4113
4197
|
appendFileSync(summaryFile, "\n---\n\n" + content);
|
|
4114
4198
|
} else {
|
|
4115
4199
|
writeFileSync7(summaryFile, "# Work Summaries\n\n" + content);
|
|
@@ -4150,14 +4234,14 @@ function generateSummaryEntry(summary) {
|
|
|
4150
4234
|
return lines.join("\n");
|
|
4151
4235
|
}
|
|
4152
4236
|
function getHistoryDir(agentId) {
|
|
4153
|
-
return
|
|
4237
|
+
return join17(AGENTS_DIR, agentId, "history");
|
|
4154
4238
|
}
|
|
4155
4239
|
function logHistory(agentId, action, details) {
|
|
4156
4240
|
const historyDir = getHistoryDir(agentId);
|
|
4157
4241
|
mkdirSync7(historyDir, { recursive: true });
|
|
4158
4242
|
const date = /* @__PURE__ */ new Date();
|
|
4159
4243
|
const dateStr = date.toISOString().split("T")[0];
|
|
4160
|
-
const historyFile =
|
|
4244
|
+
const historyFile = join17(historyDir, `${dateStr}.log`);
|
|
4161
4245
|
const timestamp = date.toISOString();
|
|
4162
4246
|
const detailsStr = details ? ` ${JSON.stringify(details)}` : "";
|
|
4163
4247
|
const logLine = `[${timestamp}] ${action}${detailsStr}
|
|
@@ -4166,13 +4250,13 @@ function logHistory(agentId, action, details) {
|
|
|
4166
4250
|
}
|
|
4167
4251
|
function searchHistory(agentId, pattern) {
|
|
4168
4252
|
const historyDir = getHistoryDir(agentId);
|
|
4169
|
-
if (!
|
|
4253
|
+
if (!existsSync17(historyDir)) return [];
|
|
4170
4254
|
const results = [];
|
|
4171
4255
|
const regex = new RegExp(pattern, "i");
|
|
4172
4256
|
const files = readdirSync12(historyDir).filter((f) => f.endsWith(".log"));
|
|
4173
4257
|
files.sort().reverse();
|
|
4174
4258
|
for (const file of files) {
|
|
4175
|
-
const content =
|
|
4259
|
+
const content = readFileSync15(join17(historyDir, file), "utf-8");
|
|
4176
4260
|
const lines = content.split("\n");
|
|
4177
4261
|
for (const line of lines) {
|
|
4178
4262
|
if (regex.test(line)) {
|
|
@@ -4184,13 +4268,13 @@ function searchHistory(agentId, pattern) {
|
|
|
4184
4268
|
}
|
|
4185
4269
|
function getRecentHistory(agentId, limit = 20) {
|
|
4186
4270
|
const historyDir = getHistoryDir(agentId);
|
|
4187
|
-
if (!
|
|
4271
|
+
if (!existsSync17(historyDir)) return [];
|
|
4188
4272
|
const results = [];
|
|
4189
4273
|
const files = readdirSync12(historyDir).filter((f) => f.endsWith(".log"));
|
|
4190
4274
|
files.sort().reverse();
|
|
4191
4275
|
for (const file of files) {
|
|
4192
4276
|
if (results.length >= limit) break;
|
|
4193
|
-
const content =
|
|
4277
|
+
const content = readFileSync15(join17(historyDir, file), "utf-8");
|
|
4194
4278
|
const lines = content.split("\n").filter((l) => l.trim());
|
|
4195
4279
|
for (const line of lines.reverse()) {
|
|
4196
4280
|
if (results.length >= limit) break;
|
|
@@ -4203,28 +4287,28 @@ function estimateTokens(text) {
|
|
|
4203
4287
|
return Math.ceil(text.length / 4);
|
|
4204
4288
|
}
|
|
4205
4289
|
function getMaterializedDir(agentId) {
|
|
4206
|
-
return
|
|
4290
|
+
return join17(AGENTS_DIR, agentId, "materialized");
|
|
4207
4291
|
}
|
|
4208
4292
|
function listMaterialized(agentId) {
|
|
4209
4293
|
const dir = getMaterializedDir(agentId);
|
|
4210
|
-
if (!
|
|
4294
|
+
if (!existsSync17(dir)) return [];
|
|
4211
4295
|
return readdirSync12(dir).filter((f) => f.endsWith(".md")).map((f) => {
|
|
4212
4296
|
const match = f.match(/^(.+)-(\d+)\.md$/);
|
|
4213
4297
|
if (!match) return null;
|
|
4214
4298
|
return {
|
|
4215
4299
|
tool: match[1],
|
|
4216
4300
|
timestamp: parseInt(match[2], 10),
|
|
4217
|
-
file:
|
|
4301
|
+
file: join17(dir, f)
|
|
4218
4302
|
};
|
|
4219
4303
|
}).filter(Boolean);
|
|
4220
4304
|
}
|
|
4221
4305
|
function readMaterialized(filepath) {
|
|
4222
|
-
if (!
|
|
4223
|
-
return
|
|
4306
|
+
if (!existsSync17(filepath)) return null;
|
|
4307
|
+
return readFileSync15(filepath, "utf-8");
|
|
4224
4308
|
}
|
|
4225
4309
|
|
|
4226
4310
|
// src/cli/commands/work/context.ts
|
|
4227
|
-
import { readFileSync as
|
|
4311
|
+
import { readFileSync as readFileSync16, existsSync as existsSync18 } from "fs";
|
|
4228
4312
|
async function contextCommand(action, arg1, arg2, options = {}) {
|
|
4229
4313
|
const agentId = process.env.PANOPTICON_AGENT_ID || arg1 || "default";
|
|
4230
4314
|
switch (action) {
|
|
@@ -4340,7 +4424,7 @@ History matches for "${pattern}":
|
|
|
4340
4424
|
}
|
|
4341
4425
|
case "materialize": {
|
|
4342
4426
|
const filepath = arg1;
|
|
4343
|
-
if (filepath &&
|
|
4427
|
+
if (filepath && existsSync18(filepath)) {
|
|
4344
4428
|
const content = readMaterialized(filepath);
|
|
4345
4429
|
if (content) {
|
|
4346
4430
|
console.log(content);
|
|
@@ -4368,8 +4452,8 @@ History matches for "${pattern}":
|
|
|
4368
4452
|
return;
|
|
4369
4453
|
}
|
|
4370
4454
|
let text = target;
|
|
4371
|
-
if (
|
|
4372
|
-
text =
|
|
4455
|
+
if (existsSync18(target)) {
|
|
4456
|
+
text = readFileSync16(target, "utf-8");
|
|
4373
4457
|
}
|
|
4374
4458
|
const tokens = estimateTokens(text);
|
|
4375
4459
|
console.log(`Estimated tokens: ${chalk19.cyan(tokens.toLocaleString())}`);
|
|
@@ -4397,8 +4481,8 @@ import chalk20 from "chalk";
|
|
|
4397
4481
|
init_esm_shims();
|
|
4398
4482
|
init_paths();
|
|
4399
4483
|
init_agents();
|
|
4400
|
-
import { existsSync as
|
|
4401
|
-
import { join as
|
|
4484
|
+
import { existsSync as existsSync19, mkdirSync as mkdirSync8, readFileSync as readFileSync17, writeFileSync as writeFileSync8 } from "fs";
|
|
4485
|
+
import { join as join18 } from "path";
|
|
4402
4486
|
import { exec as exec3 } from "child_process";
|
|
4403
4487
|
import { promisify as promisify3 } from "util";
|
|
4404
4488
|
var execAsync3 = promisify3(exec3);
|
|
@@ -4407,7 +4491,7 @@ var DEFAULT_CONSECUTIVE_FAILURES = 3;
|
|
|
4407
4491
|
var DEFAULT_COOLDOWN_MS = 5 * 60 * 1e3;
|
|
4408
4492
|
var DEFAULT_CHECK_INTERVAL_MS = 30 * 1e3;
|
|
4409
4493
|
function getHealthFile(agentId) {
|
|
4410
|
-
return
|
|
4494
|
+
return join18(AGENTS_DIR, agentId, "health.json");
|
|
4411
4495
|
}
|
|
4412
4496
|
function getAgentHealth(agentId) {
|
|
4413
4497
|
const healthFile = getHealthFile(agentId);
|
|
@@ -4419,9 +4503,9 @@ function getAgentHealth(agentId) {
|
|
|
4419
4503
|
recoveryCount: 0,
|
|
4420
4504
|
inCooldown: false
|
|
4421
4505
|
};
|
|
4422
|
-
if (
|
|
4506
|
+
if (existsSync19(healthFile)) {
|
|
4423
4507
|
try {
|
|
4424
|
-
const stored = JSON.parse(
|
|
4508
|
+
const stored = JSON.parse(readFileSync17(healthFile, "utf-8"));
|
|
4425
4509
|
return { ...defaultHealth, ...stored };
|
|
4426
4510
|
} catch {
|
|
4427
4511
|
}
|
|
@@ -4429,7 +4513,7 @@ function getAgentHealth(agentId) {
|
|
|
4429
4513
|
return defaultHealth;
|
|
4430
4514
|
}
|
|
4431
4515
|
function saveAgentHealth(health) {
|
|
4432
|
-
const dir =
|
|
4516
|
+
const dir = join18(AGENTS_DIR, health.agentId);
|
|
4433
4517
|
mkdirSync8(dir, { recursive: true });
|
|
4434
4518
|
writeFileSync8(getHealthFile(health.agentId), JSON.stringify(health, null, 2));
|
|
4435
4519
|
}
|
|
@@ -4552,7 +4636,7 @@ async function runHealthCheck(config2 = {
|
|
|
4552
4636
|
sessions = output.trim().split("\n").filter((s) => s.startsWith("agent-"));
|
|
4553
4637
|
} catch {
|
|
4554
4638
|
}
|
|
4555
|
-
if (
|
|
4639
|
+
if (existsSync19(AGENTS_DIR)) {
|
|
4556
4640
|
const { readdirSync: readdirSync22 } = await import("fs");
|
|
4557
4641
|
const dirs = readdirSync22(AGENTS_DIR, { withFileTypes: true }).filter((d) => d.isDirectory() && d.name.startsWith("agent-")).map((d) => d.name);
|
|
4558
4642
|
for (const dir of dirs) {
|
|
@@ -4790,15 +4874,15 @@ init_esm_shims();
|
|
|
4790
4874
|
import chalk21 from "chalk";
|
|
4791
4875
|
import ora11 from "ora";
|
|
4792
4876
|
import inquirer3 from "inquirer";
|
|
4793
|
-
import { existsSync as
|
|
4794
|
-
import { join as
|
|
4795
|
-
import { homedir as
|
|
4877
|
+
import { existsSync as existsSync21, readFileSync as readFileSync19 } from "fs";
|
|
4878
|
+
import { join as join20, dirname as dirname6 } from "path";
|
|
4879
|
+
import { homedir as homedir9 } from "os";
|
|
4796
4880
|
import { LinearClient } from "@linear/sdk";
|
|
4797
4881
|
|
|
4798
4882
|
// src/lib/reopen.ts
|
|
4799
4883
|
init_esm_shims();
|
|
4800
|
-
import { existsSync as
|
|
4801
|
-
import { join as
|
|
4884
|
+
import { existsSync as existsSync20, readFileSync as readFileSync18, appendFileSync as appendFileSync2 } from "fs";
|
|
4885
|
+
import { join as join19 } from "path";
|
|
4802
4886
|
|
|
4803
4887
|
// src/dashboard/server/review-status.ts
|
|
4804
4888
|
init_esm_shims();
|
|
@@ -4864,9 +4948,9 @@ function reopenWorkspaceState(issueId, workspacePath, options = {}) {
|
|
|
4864
4948
|
result.queueItemsRemoved[specialistName] = removed;
|
|
4865
4949
|
}
|
|
4866
4950
|
}
|
|
4867
|
-
const statePath =
|
|
4868
|
-
if (
|
|
4869
|
-
const previousContent =
|
|
4951
|
+
const statePath = join19(workspacePath, ".planning", "STATE.md");
|
|
4952
|
+
if (existsSync20(statePath)) {
|
|
4953
|
+
const previousContent = readFileSync18(statePath, "utf-8");
|
|
4870
4954
|
const lastStatusMatch = previousContent.match(/\*\*STATUS:\s*([^*\n]+)\*\*/);
|
|
4871
4955
|
const previousStatus = lastStatusMatch ? lastStatusMatch[1].trim() : "Unknown";
|
|
4872
4956
|
const date = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
@@ -4902,9 +4986,9 @@ function reopenWorkspaceState(issueId, workspacePath, options = {}) {
|
|
|
4902
4986
|
// src/cli/commands/work/reopen.ts
|
|
4903
4987
|
init_projects();
|
|
4904
4988
|
function getLinearApiKey5() {
|
|
4905
|
-
const envFile =
|
|
4906
|
-
if (
|
|
4907
|
-
const content =
|
|
4989
|
+
const envFile = join20(homedir9(), ".panopticon.env");
|
|
4990
|
+
if (existsSync21(envFile)) {
|
|
4991
|
+
const content = readFileSync19(envFile, "utf-8");
|
|
4908
4992
|
const match = content.match(/LINEAR_API_KEY=(.+)/);
|
|
4909
4993
|
if (match) return match[1].trim();
|
|
4910
4994
|
}
|
|
@@ -4977,15 +5061,15 @@ function findLocalWorkspace2(issueId, startDir) {
|
|
|
4977
5061
|
const normalizedId = issueId.toLowerCase();
|
|
4978
5062
|
const resolved = resolveProjectFromIssue(issueId, []);
|
|
4979
5063
|
if (resolved) {
|
|
4980
|
-
const workspacePath =
|
|
4981
|
-
if (
|
|
5064
|
+
const workspacePath = join20(resolved.projectPath, "workspaces", `feature-${normalizedId}`);
|
|
5065
|
+
if (existsSync21(workspacePath)) return workspacePath;
|
|
4982
5066
|
}
|
|
4983
5067
|
let dir = startDir ?? process.cwd();
|
|
4984
5068
|
for (let i = 0; i < 10; i++) {
|
|
4985
|
-
const workspacesDir =
|
|
4986
|
-
if (
|
|
4987
|
-
const workspacePath =
|
|
4988
|
-
if (
|
|
5069
|
+
const workspacesDir = join20(dir, "workspaces");
|
|
5070
|
+
if (existsSync21(workspacesDir)) {
|
|
5071
|
+
const workspacePath = join20(workspacesDir, `feature-${normalizedId}`);
|
|
5072
|
+
if (existsSync21(workspacePath)) return workspacePath;
|
|
4989
5073
|
}
|
|
4990
5074
|
const parent = dirname6(dir);
|
|
4991
5075
|
if (parent === dir) break;
|
|
@@ -5112,7 +5196,7 @@ Previous state: ${issue.state}`
|
|
|
5112
5196
|
console.log(chalk21.green(`\u2713 ${issue.identifier} reopened and ready for re-work`));
|
|
5113
5197
|
console.log("");
|
|
5114
5198
|
try {
|
|
5115
|
-
const { getAgentState: getAgentState2 } = await import("../agents-
|
|
5199
|
+
const { getAgentState: getAgentState2 } = await import("../agents-5OPQKM5K.js");
|
|
5116
5200
|
const agentId = `agent-${id.toLowerCase()}`;
|
|
5117
5201
|
const agentState = getAgentState2(agentId);
|
|
5118
5202
|
const agentRunning = agentState?.status === "active" || agentState?.status === "running";
|
|
@@ -5228,11 +5312,12 @@ init_esm_shims();
|
|
|
5228
5312
|
init_agents();
|
|
5229
5313
|
init_tmux();
|
|
5230
5314
|
import chalk24 from "chalk";
|
|
5231
|
-
import { homedir as
|
|
5232
|
-
import { join as
|
|
5233
|
-
import { existsSync as
|
|
5315
|
+
import { homedir as homedir10 } from "os";
|
|
5316
|
+
import { join as join21 } from "path";
|
|
5317
|
+
import { existsSync as existsSync22, rmSync, readFileSync as readFileSync20 } from "fs";
|
|
5234
5318
|
import { exec as exec4 } from "child_process";
|
|
5235
5319
|
import { promisify as promisify4 } from "util";
|
|
5320
|
+
init_workspace_manager();
|
|
5236
5321
|
var execAsync4 = promisify4(exec4);
|
|
5237
5322
|
async function wipeCommand(issueId, options) {
|
|
5238
5323
|
const issueLower = issueId.toLowerCase();
|
|
@@ -5319,22 +5404,22 @@ async function wipeCommand(issueId, options) {
|
|
|
5319
5404
|
}
|
|
5320
5405
|
}
|
|
5321
5406
|
const agentDirs = [
|
|
5322
|
-
|
|
5407
|
+
join21(homedir10(), ".panopticon", "agents", `agent-${issueLower}`)
|
|
5323
5408
|
];
|
|
5324
5409
|
for (const dir of agentDirs) {
|
|
5325
|
-
if (
|
|
5410
|
+
if (existsSync22(dir)) {
|
|
5326
5411
|
rmSync(dir, { recursive: true, force: true });
|
|
5327
5412
|
cleanupLog.push(`Deleted agent state: ${dir}`);
|
|
5328
|
-
console.log(chalk24.green(` \u2713 Deleted agent state: ${dir.replace(
|
|
5413
|
+
console.log(chalk24.green(` \u2713 Deleted agent state: ${dir.replace(homedir10(), "~")}`));
|
|
5329
5414
|
}
|
|
5330
5415
|
}
|
|
5331
5416
|
let projectPath;
|
|
5332
5417
|
const prefix = issueId.split("-")[0].toUpperCase();
|
|
5333
|
-
const projectsYamlPath =
|
|
5334
|
-
if (
|
|
5418
|
+
const projectsYamlPath = join21(homedir10(), ".panopticon", "projects.yaml");
|
|
5419
|
+
if (existsSync22(projectsYamlPath)) {
|
|
5335
5420
|
try {
|
|
5336
5421
|
const yaml2 = await import("js-yaml");
|
|
5337
|
-
const projectsConfig = yaml2.load(
|
|
5422
|
+
const projectsConfig = yaml2.load(readFileSync20(projectsYamlPath, "utf-8"));
|
|
5338
5423
|
for (const [, config2] of Object.entries(projectsConfig.projects || {})) {
|
|
5339
5424
|
const projConfig = config2;
|
|
5340
5425
|
if (projConfig.linear_team?.toUpperCase() === prefix) {
|
|
@@ -5345,20 +5430,37 @@ async function wipeCommand(issueId, options) {
|
|
|
5345
5430
|
} catch (e) {
|
|
5346
5431
|
}
|
|
5347
5432
|
}
|
|
5433
|
+
if (projectPath) {
|
|
5434
|
+
const workspacePath = join21(projectPath, "workspaces", `feature-${issueLower}`);
|
|
5435
|
+
if (existsSync22(workspacePath)) {
|
|
5436
|
+
try {
|
|
5437
|
+
const projName = projectPath.split("/").pop() || "";
|
|
5438
|
+
const dockerResult = await stopWorkspaceDocker(workspacePath, projName, issueLower);
|
|
5439
|
+
if (dockerResult.steps.length > 0) {
|
|
5440
|
+
for (const step of dockerResult.steps) {
|
|
5441
|
+
cleanupLog.push(step);
|
|
5442
|
+
console.log(chalk24.green(` \u2713 ${step}`));
|
|
5443
|
+
}
|
|
5444
|
+
}
|
|
5445
|
+
} catch (e) {
|
|
5446
|
+
console.log(chalk24.yellow(` \u26A0 Docker cleanup: ${e.message}`));
|
|
5447
|
+
}
|
|
5448
|
+
}
|
|
5449
|
+
}
|
|
5348
5450
|
if (options.workspace && projectPath) {
|
|
5349
|
-
const workspacePath =
|
|
5350
|
-
if (
|
|
5451
|
+
const workspacePath = join21(projectPath, "workspaces", `feature-${issueLower}`);
|
|
5452
|
+
if (existsSync22(workspacePath)) {
|
|
5351
5453
|
try {
|
|
5352
5454
|
const gitDirs = ["api", "frontend", "fe", "."];
|
|
5353
5455
|
for (const gitDir of gitDirs) {
|
|
5354
|
-
const gitPath =
|
|
5355
|
-
if (
|
|
5456
|
+
const gitPath = join21(projectPath, gitDir);
|
|
5457
|
+
if (existsSync22(join21(gitPath, ".git"))) {
|
|
5356
5458
|
await execAsync4(`cd "${gitPath}" && git worktree remove "${workspacePath}" --force 2>/dev/null || true`);
|
|
5357
5459
|
}
|
|
5358
5460
|
}
|
|
5359
5461
|
} catch (e) {
|
|
5360
5462
|
}
|
|
5361
|
-
if (
|
|
5463
|
+
if (existsSync22(workspacePath)) {
|
|
5362
5464
|
rmSync(workspacePath, { recursive: true, force: true });
|
|
5363
5465
|
}
|
|
5364
5466
|
cleanupLog.push(`Deleted workspace: ${workspacePath}`);
|
|
@@ -5416,14 +5518,14 @@ import ora12 from "ora";
|
|
|
5416
5518
|
|
|
5417
5519
|
// src/lib/shadow-utils.ts
|
|
5418
5520
|
init_esm_shims();
|
|
5419
|
-
import { existsSync as
|
|
5420
|
-
import { join as
|
|
5421
|
-
import { homedir as
|
|
5521
|
+
import { existsSync as existsSync23, readFileSync as readFileSync21 } from "fs";
|
|
5522
|
+
import { join as join22 } from "path";
|
|
5523
|
+
import { homedir as homedir11 } from "os";
|
|
5422
5524
|
import chalk25 from "chalk";
|
|
5423
5525
|
function getLinearApiKey6() {
|
|
5424
|
-
const envFile =
|
|
5425
|
-
if (
|
|
5426
|
-
const content =
|
|
5526
|
+
const envFile = join22(homedir11(), ".panopticon.env");
|
|
5527
|
+
if (existsSync23(envFile)) {
|
|
5528
|
+
const content = readFileSync21(envFile, "utf-8");
|
|
5427
5529
|
const match = content.match(/LINEAR_API_KEY=(.+)/);
|
|
5428
5530
|
if (match) return match[1].trim();
|
|
5429
5531
|
}
|
|
@@ -5522,10 +5624,10 @@ init_esm_shims();
|
|
|
5522
5624
|
import chalk27 from "chalk";
|
|
5523
5625
|
import ora13 from "ora";
|
|
5524
5626
|
import inquirer4 from "inquirer";
|
|
5525
|
-
import { existsSync as
|
|
5526
|
-
import { join as
|
|
5527
|
-
import { homedir as
|
|
5528
|
-
var SYNC_QUEUE_FILE =
|
|
5627
|
+
import { existsSync as existsSync24, readFileSync as readFileSync22, writeFileSync as writeFileSync9, mkdirSync as mkdirSync9 } from "fs";
|
|
5628
|
+
import { join as join23, dirname as dirname7 } from "path";
|
|
5629
|
+
import { homedir as homedir12 } from "os";
|
|
5630
|
+
var SYNC_QUEUE_FILE = join23(homedir12(), ".panopticon", "sync-queue.json");
|
|
5529
5631
|
async function syncToLinear(apiKey, issueId, targetState) {
|
|
5530
5632
|
try {
|
|
5531
5633
|
const { LinearClient: LinearClient2 } = await import("@linear/sdk");
|
|
@@ -5697,11 +5799,11 @@ async function syncCommand2(id, options = {}) {
|
|
|
5697
5799
|
}
|
|
5698
5800
|
}
|
|
5699
5801
|
function loadSyncQueue() {
|
|
5700
|
-
if (!
|
|
5802
|
+
if (!existsSync24(SYNC_QUEUE_FILE)) {
|
|
5701
5803
|
return [];
|
|
5702
5804
|
}
|
|
5703
5805
|
try {
|
|
5704
|
-
const content =
|
|
5806
|
+
const content = readFileSync22(SYNC_QUEUE_FILE, "utf-8");
|
|
5705
5807
|
return JSON.parse(content);
|
|
5706
5808
|
} catch (error) {
|
|
5707
5809
|
console.error(chalk27.yellow("Warning: Failed to load sync queue"));
|
|
@@ -5710,7 +5812,7 @@ function loadSyncQueue() {
|
|
|
5710
5812
|
}
|
|
5711
5813
|
function saveSyncQueue(queue) {
|
|
5712
5814
|
const dir = dirname7(SYNC_QUEUE_FILE);
|
|
5713
|
-
if (!
|
|
5815
|
+
if (!existsSync24(dir)) {
|
|
5714
5816
|
mkdirSync9(dir, { recursive: true });
|
|
5715
5817
|
}
|
|
5716
5818
|
try {
|
|
@@ -5837,8 +5939,8 @@ async function refreshCommand(id, options = {}) {
|
|
|
5837
5939
|
init_esm_shims();
|
|
5838
5940
|
init_tldr_daemon();
|
|
5839
5941
|
import chalk29 from "chalk";
|
|
5840
|
-
import { existsSync as
|
|
5841
|
-
import { join as
|
|
5942
|
+
import { existsSync as existsSync25, readdirSync as readdirSync14, readFileSync as readFileSync23, statSync as statSync5 } from "fs";
|
|
5943
|
+
import { join as join24 } from "path";
|
|
5842
5944
|
async function tldrCommand(action, workspace, options = {}) {
|
|
5843
5945
|
switch (action) {
|
|
5844
5946
|
case "status":
|
|
@@ -5861,19 +5963,19 @@ async function tldrCommand(action, workspace, options = {}) {
|
|
|
5861
5963
|
}
|
|
5862
5964
|
async function statusCommand2(options) {
|
|
5863
5965
|
const projectRoot = process.cwd();
|
|
5864
|
-
const venvPath =
|
|
5966
|
+
const venvPath = join24(projectRoot, ".venv");
|
|
5865
5967
|
const results = [];
|
|
5866
|
-
if (
|
|
5968
|
+
if (existsSync25(venvPath)) {
|
|
5867
5969
|
const service = getTldrDaemonService(projectRoot, venvPath);
|
|
5868
5970
|
const status = await service.getStatus();
|
|
5869
|
-
const tldrPath =
|
|
5971
|
+
const tldrPath = join24(projectRoot, ".tldr");
|
|
5870
5972
|
let indexAge = "N/A";
|
|
5871
5973
|
let fileCount = "N/A";
|
|
5872
|
-
if (
|
|
5974
|
+
if (existsSync25(tldrPath)) {
|
|
5873
5975
|
try {
|
|
5874
|
-
const langPath =
|
|
5875
|
-
if (
|
|
5876
|
-
const langData = JSON.parse(
|
|
5976
|
+
const langPath = join24(tldrPath, "languages.json");
|
|
5977
|
+
if (existsSync25(langPath)) {
|
|
5978
|
+
const langData = JSON.parse(readFileSync23(langPath, "utf-8"));
|
|
5877
5979
|
if (langData.timestamp) {
|
|
5878
5980
|
const ageMs = Date.now() - langData.timestamp * 1e3;
|
|
5879
5981
|
const ageDays = Math.floor(ageMs / (1e3 * 60 * 60 * 24));
|
|
@@ -5886,9 +5988,9 @@ async function statusCommand2(options) {
|
|
|
5886
5988
|
const ageDays = Math.floor(ageMs / (1e3 * 60 * 60 * 24));
|
|
5887
5989
|
indexAge = ageDays === 0 ? "today" : `${ageDays}d ago`;
|
|
5888
5990
|
}
|
|
5889
|
-
const cgPath =
|
|
5890
|
-
if (
|
|
5891
|
-
const cg = JSON.parse(
|
|
5991
|
+
const cgPath = join24(tldrPath, "cache", "call_graph.json");
|
|
5992
|
+
if (existsSync25(cgPath)) {
|
|
5993
|
+
const cg = JSON.parse(readFileSync23(cgPath, "utf-8"));
|
|
5892
5994
|
if (Array.isArray(cg.edges)) {
|
|
5893
5995
|
const files = /* @__PURE__ */ new Set();
|
|
5894
5996
|
for (const e of cg.edges) {
|
|
@@ -5910,23 +6012,23 @@ async function statusCommand2(options) {
|
|
|
5910
6012
|
fileCount
|
|
5911
6013
|
});
|
|
5912
6014
|
}
|
|
5913
|
-
const workspacesDir =
|
|
5914
|
-
if (
|
|
6015
|
+
const workspacesDir = join24(projectRoot, "workspaces");
|
|
6016
|
+
if (existsSync25(workspacesDir)) {
|
|
5915
6017
|
const workspaces = readdirSync14(workspacesDir, { withFileTypes: true }).filter((d) => d.isDirectory() && d.name.startsWith("feature-"));
|
|
5916
6018
|
for (const ws of workspaces) {
|
|
5917
|
-
const wsPath =
|
|
5918
|
-
const wsVenvPath =
|
|
5919
|
-
if (
|
|
6019
|
+
const wsPath = join24(workspacesDir, ws.name);
|
|
6020
|
+
const wsVenvPath = join24(wsPath, ".venv");
|
|
6021
|
+
if (existsSync25(wsVenvPath)) {
|
|
5920
6022
|
const service = getTldrDaemonService(wsPath, wsVenvPath);
|
|
5921
6023
|
const status = await service.getStatus();
|
|
5922
|
-
const tldrPath =
|
|
6024
|
+
const tldrPath = join24(wsPath, ".tldr");
|
|
5923
6025
|
let indexAge = "N/A";
|
|
5924
6026
|
let fileCount = "N/A";
|
|
5925
|
-
if (
|
|
6027
|
+
if (existsSync25(tldrPath)) {
|
|
5926
6028
|
try {
|
|
5927
|
-
const langPath =
|
|
5928
|
-
if (
|
|
5929
|
-
const langData = JSON.parse(
|
|
6029
|
+
const langPath = join24(tldrPath, "languages.json");
|
|
6030
|
+
if (existsSync25(langPath)) {
|
|
6031
|
+
const langData = JSON.parse(readFileSync23(langPath, "utf-8"));
|
|
5930
6032
|
if (langData.timestamp) {
|
|
5931
6033
|
const ageMs = Date.now() - langData.timestamp * 1e3;
|
|
5932
6034
|
const ageHours = Math.floor(ageMs / (1e3 * 60 * 60));
|
|
@@ -5939,9 +6041,9 @@ async function statusCommand2(options) {
|
|
|
5939
6041
|
const ageHours = Math.floor(ageMs / (1e3 * 60 * 60));
|
|
5940
6042
|
indexAge = ageHours === 0 ? "now" : ageHours < 24 ? `${ageHours}h ago` : `${Math.floor(ageHours / 24)}d ago`;
|
|
5941
6043
|
}
|
|
5942
|
-
const cgPath =
|
|
5943
|
-
if (
|
|
5944
|
-
const cg = JSON.parse(
|
|
6044
|
+
const cgPath = join24(tldrPath, "cache", "call_graph.json");
|
|
6045
|
+
if (existsSync25(cgPath)) {
|
|
6046
|
+
const cg = JSON.parse(readFileSync23(cgPath, "utf-8"));
|
|
5945
6047
|
if (Array.isArray(cg.edges)) {
|
|
5946
6048
|
const files = /* @__PURE__ */ new Set();
|
|
5947
6049
|
for (const e of cg.edges) {
|
|
@@ -5991,13 +6093,13 @@ async function statusCommand2(options) {
|
|
|
5991
6093
|
async function startCommand(workspace, options) {
|
|
5992
6094
|
const projectRoot = process.cwd();
|
|
5993
6095
|
if (workspace) {
|
|
5994
|
-
const wsPath =
|
|
5995
|
-
const venvPath =
|
|
5996
|
-
if (!
|
|
6096
|
+
const wsPath = join24(projectRoot, "workspaces", workspace);
|
|
6097
|
+
const venvPath = join24(wsPath, ".venv");
|
|
6098
|
+
if (!existsSync25(wsPath)) {
|
|
5997
6099
|
console.error(chalk29.red(`Error: Workspace not found: ${workspace}`));
|
|
5998
6100
|
process.exit(1);
|
|
5999
6101
|
}
|
|
6000
|
-
if (!
|
|
6102
|
+
if (!existsSync25(venvPath)) {
|
|
6001
6103
|
console.error(chalk29.red(`Error: No .venv found in workspace: ${workspace}`));
|
|
6002
6104
|
console.error(chalk29.dim("Workspace needs to be recreated with TLDR support"));
|
|
6003
6105
|
process.exit(1);
|
|
@@ -6008,8 +6110,8 @@ async function startCommand(workspace, options) {
|
|
|
6008
6110
|
console.log(chalk29.green(`\u2713 Started TLDR daemon for ${workspace}`));
|
|
6009
6111
|
}
|
|
6010
6112
|
} else {
|
|
6011
|
-
const venvPath =
|
|
6012
|
-
if (!
|
|
6113
|
+
const venvPath = join24(projectRoot, ".venv");
|
|
6114
|
+
if (!existsSync25(venvPath)) {
|
|
6013
6115
|
console.error(chalk29.red("Error: No .venv found in project root"));
|
|
6014
6116
|
console.error(chalk29.dim("Run `pan setup` to configure TLDR"));
|
|
6015
6117
|
process.exit(1);
|
|
@@ -6024,13 +6126,13 @@ async function startCommand(workspace, options) {
|
|
|
6024
6126
|
async function stopCommand(workspace, options) {
|
|
6025
6127
|
const projectRoot = process.cwd();
|
|
6026
6128
|
if (workspace) {
|
|
6027
|
-
const wsPath =
|
|
6028
|
-
const venvPath =
|
|
6029
|
-
if (!
|
|
6129
|
+
const wsPath = join24(projectRoot, "workspaces", workspace);
|
|
6130
|
+
const venvPath = join24(wsPath, ".venv");
|
|
6131
|
+
if (!existsSync25(wsPath)) {
|
|
6030
6132
|
console.error(chalk29.red(`Error: Workspace not found: ${workspace}`));
|
|
6031
6133
|
process.exit(1);
|
|
6032
6134
|
}
|
|
6033
|
-
if (!
|
|
6135
|
+
if (!existsSync25(venvPath)) {
|
|
6034
6136
|
console.error(chalk29.red(`Error: No .venv found in workspace: ${workspace}`));
|
|
6035
6137
|
process.exit(1);
|
|
6036
6138
|
}
|
|
@@ -6040,8 +6142,8 @@ async function stopCommand(workspace, options) {
|
|
|
6040
6142
|
console.log(chalk29.green(`\u2713 Stopped TLDR daemon for ${workspace}`));
|
|
6041
6143
|
}
|
|
6042
6144
|
} else {
|
|
6043
|
-
const venvPath =
|
|
6044
|
-
if (!
|
|
6145
|
+
const venvPath = join24(projectRoot, ".venv");
|
|
6146
|
+
if (!existsSync25(venvPath)) {
|
|
6045
6147
|
console.error(chalk29.red("Error: No .venv found in project root"));
|
|
6046
6148
|
process.exit(1);
|
|
6047
6149
|
}
|
|
@@ -6055,13 +6157,13 @@ async function stopCommand(workspace, options) {
|
|
|
6055
6157
|
async function warmCommand(workspace, options) {
|
|
6056
6158
|
const projectRoot = process.cwd();
|
|
6057
6159
|
if (workspace) {
|
|
6058
|
-
const wsPath =
|
|
6059
|
-
const venvPath =
|
|
6060
|
-
if (!
|
|
6160
|
+
const wsPath = join24(projectRoot, "workspaces", workspace);
|
|
6161
|
+
const venvPath = join24(wsPath, ".venv");
|
|
6162
|
+
if (!existsSync25(wsPath)) {
|
|
6061
6163
|
console.error(chalk29.red(`Error: Workspace not found: ${workspace}`));
|
|
6062
6164
|
process.exit(1);
|
|
6063
6165
|
}
|
|
6064
|
-
if (!
|
|
6166
|
+
if (!existsSync25(venvPath)) {
|
|
6065
6167
|
console.error(chalk29.red(`Error: No .venv found in workspace: ${workspace}`));
|
|
6066
6168
|
process.exit(1);
|
|
6067
6169
|
}
|
|
@@ -6075,8 +6177,8 @@ async function warmCommand(workspace, options) {
|
|
|
6075
6177
|
console.log(chalk29.green(`\u2713 Index warming complete for ${workspace}`));
|
|
6076
6178
|
}
|
|
6077
6179
|
} else {
|
|
6078
|
-
const venvPath =
|
|
6079
|
-
if (!
|
|
6180
|
+
const venvPath = join24(projectRoot, ".venv");
|
|
6181
|
+
if (!existsSync25(venvPath)) {
|
|
6080
6182
|
console.error(chalk29.red("Error: No .venv found in project root"));
|
|
6081
6183
|
console.error(chalk29.dim("Run `pan setup` to configure TLDR"));
|
|
6082
6184
|
process.exit(1);
|
|
@@ -6159,18 +6261,15 @@ async function syncMainCommand(id) {
|
|
|
6159
6261
|
// src/cli/commands/work/close-out.ts
|
|
6160
6262
|
init_esm_shims();
|
|
6161
6263
|
import chalk31 from "chalk";
|
|
6162
|
-
import { existsSync as existsSync29, readFileSync as readFileSync25 } from "fs";
|
|
6163
|
-
import { join as join28 } from "path";
|
|
6164
|
-
import { homedir as homedir13 } from "os";
|
|
6165
6264
|
|
|
6166
6265
|
// src/lib/lifecycle/index.ts
|
|
6167
6266
|
init_esm_shims();
|
|
6168
6267
|
|
|
6169
6268
|
// src/lib/lifecycle/types.ts
|
|
6170
6269
|
init_esm_shims();
|
|
6171
|
-
import { existsSync as
|
|
6172
|
-
import { join as
|
|
6173
|
-
import { homedir as
|
|
6270
|
+
import { existsSync as existsSync26, readFileSync as readFileSync24 } from "fs";
|
|
6271
|
+
import { join as join25 } from "path";
|
|
6272
|
+
import { homedir as homedir13 } from "os";
|
|
6174
6273
|
function stepOk(step, details) {
|
|
6175
6274
|
return { step, success: true, skipped: false, details };
|
|
6176
6275
|
}
|
|
@@ -6182,9 +6281,9 @@ function stepFailed(step, error, details) {
|
|
|
6182
6281
|
}
|
|
6183
6282
|
function getLinearApiKey7() {
|
|
6184
6283
|
if (process.env.LINEAR_API_KEY) return process.env.LINEAR_API_KEY;
|
|
6185
|
-
const envFile =
|
|
6186
|
-
if (
|
|
6187
|
-
const content =
|
|
6284
|
+
const envFile = join25(homedir13(), ".panopticon.env");
|
|
6285
|
+
if (existsSync26(envFile)) {
|
|
6286
|
+
const content = readFileSync24(envFile, "utf-8");
|
|
6188
6287
|
const match = content.match(/LINEAR_API_KEY=(.+)/);
|
|
6189
6288
|
if (match) return match[1].trim();
|
|
6190
6289
|
}
|
|
@@ -6194,20 +6293,20 @@ function getLinearApiKey7() {
|
|
|
6194
6293
|
// src/lib/lifecycle/archive-planning.ts
|
|
6195
6294
|
init_esm_shims();
|
|
6196
6295
|
init_paths();
|
|
6197
|
-
import { existsSync as
|
|
6198
|
-
import { join as
|
|
6296
|
+
import { existsSync as existsSync27, mkdirSync as mkdirSync10, cpSync as cpSync2, rmSync as rmSync2 } from "fs";
|
|
6297
|
+
import { join as join26, dirname as dirname8 } from "path";
|
|
6199
6298
|
import { exec as exec5 } from "child_process";
|
|
6200
6299
|
import { promisify as promisify5 } from "util";
|
|
6201
6300
|
var execAsync5 = promisify5(exec5);
|
|
6202
6301
|
function findWorkspacePath(projectPath, issueLower) {
|
|
6203
6302
|
const candidates = [
|
|
6204
|
-
|
|
6205
|
-
|
|
6206
|
-
|
|
6207
|
-
|
|
6303
|
+
join26(projectPath, "workspaces", `feature-${issueLower}`),
|
|
6304
|
+
join26(projectPath, "workspaces", issueLower),
|
|
6305
|
+
join26(projectPath, ".worktrees", issueLower),
|
|
6306
|
+
join26(dirname8(projectPath), `feature-${issueLower}`)
|
|
6208
6307
|
];
|
|
6209
6308
|
for (const p of candidates) {
|
|
6210
|
-
if (
|
|
6309
|
+
if (existsSync27(p)) return p;
|
|
6211
6310
|
}
|
|
6212
6311
|
return null;
|
|
6213
6312
|
}
|
|
@@ -6215,28 +6314,28 @@ async function movePrd(ctx, opts = {}) {
|
|
|
6215
6314
|
const { pushToRemote = true } = opts;
|
|
6216
6315
|
const issueLower = ctx.issueId.toLowerCase();
|
|
6217
6316
|
const step = "archive-planning:move-prd";
|
|
6218
|
-
const completedPrdPath =
|
|
6317
|
+
const completedPrdPath = join26(
|
|
6219
6318
|
ctx.projectPath,
|
|
6220
6319
|
PROJECT_DOCS_SUBDIR,
|
|
6221
6320
|
PROJECT_PRDS_SUBDIR,
|
|
6222
6321
|
PROJECT_PRDS_COMPLETED_SUBDIR,
|
|
6223
6322
|
`${issueLower}-plan.md`
|
|
6224
6323
|
);
|
|
6225
|
-
const activePrdPath =
|
|
6324
|
+
const activePrdPath = join26(
|
|
6226
6325
|
ctx.projectPath,
|
|
6227
6326
|
PROJECT_DOCS_SUBDIR,
|
|
6228
6327
|
PROJECT_PRDS_SUBDIR,
|
|
6229
6328
|
PROJECT_PRDS_ACTIVE_SUBDIR,
|
|
6230
6329
|
`${issueLower}-plan.md`
|
|
6231
6330
|
);
|
|
6232
|
-
if (
|
|
6331
|
+
if (existsSync27(completedPrdPath)) {
|
|
6233
6332
|
return stepSkipped(step, ["PRD already in completed/"]);
|
|
6234
6333
|
}
|
|
6235
|
-
if (!
|
|
6334
|
+
if (!existsSync27(activePrdPath)) {
|
|
6236
6335
|
return stepSkipped(step, ["No PRD found in active/ (may not have had one)"]);
|
|
6237
6336
|
}
|
|
6238
6337
|
const completedDir = dirname8(completedPrdPath);
|
|
6239
|
-
if (!
|
|
6338
|
+
if (!existsSync27(completedDir)) {
|
|
6240
6339
|
mkdirSync10(completedDir, { recursive: true });
|
|
6241
6340
|
}
|
|
6242
6341
|
try {
|
|
@@ -6250,7 +6349,7 @@ async function movePrd(ctx, opts = {}) {
|
|
|
6250
6349
|
}
|
|
6251
6350
|
try {
|
|
6252
6351
|
cpSync2(activePrdPath, completedPrdPath);
|
|
6253
|
-
if (!
|
|
6352
|
+
if (!existsSync27(completedPrdPath)) {
|
|
6254
6353
|
return stepFailed(step, "PRD copy appeared to succeed but file not found at destination");
|
|
6255
6354
|
}
|
|
6256
6355
|
return stepOk(step, ["Copied PRD to completed/ (git mv failed, plain copy succeeded)"]);
|
|
@@ -6262,14 +6361,14 @@ async function archiveWorkspaceArtifacts(ctx) {
|
|
|
6262
6361
|
const issueLower = ctx.issueId.toLowerCase();
|
|
6263
6362
|
const step = "archive-planning:archive-artifacts";
|
|
6264
6363
|
const workspacePath = findWorkspacePath(ctx.projectPath, issueLower);
|
|
6265
|
-
if (!workspacePath || !
|
|
6364
|
+
if (!workspacePath || !existsSync27(workspacePath)) {
|
|
6266
6365
|
return stepSkipped(step, ["No workspace found to archive"]);
|
|
6267
6366
|
}
|
|
6268
6367
|
try {
|
|
6269
|
-
let archiveDir =
|
|
6270
|
-
if (
|
|
6368
|
+
let archiveDir = join26(ARCHIVES_DIR, issueLower);
|
|
6369
|
+
if (existsSync27(archiveDir)) {
|
|
6271
6370
|
let version = 1;
|
|
6272
|
-
while (
|
|
6371
|
+
while (existsSync27(`${archiveDir}.${version}`)) {
|
|
6273
6372
|
version++;
|
|
6274
6373
|
}
|
|
6275
6374
|
const rotatedDir = `${archiveDir}.${version}`;
|
|
@@ -6278,24 +6377,24 @@ async function archiveWorkspaceArtifacts(ctx) {
|
|
|
6278
6377
|
}
|
|
6279
6378
|
mkdirSync10(archiveDir, { recursive: true });
|
|
6280
6379
|
const details = [];
|
|
6281
|
-
const feedbackDir =
|
|
6282
|
-
if (
|
|
6283
|
-
cpSync2(feedbackDir,
|
|
6380
|
+
const feedbackDir = join26(workspacePath, ".planning", "feedback");
|
|
6381
|
+
if (existsSync27(feedbackDir)) {
|
|
6382
|
+
cpSync2(feedbackDir, join26(archiveDir, "feedback"), { recursive: true });
|
|
6284
6383
|
details.push("Archived feedback/");
|
|
6285
6384
|
}
|
|
6286
|
-
const stateMd =
|
|
6287
|
-
if (
|
|
6288
|
-
cpSync2(stateMd,
|
|
6385
|
+
const stateMd = join26(workspacePath, ".planning", "STATE.md");
|
|
6386
|
+
if (existsSync27(stateMd)) {
|
|
6387
|
+
cpSync2(stateMd, join26(archiveDir, "STATE.md"));
|
|
6289
6388
|
details.push("Archived STATE.md");
|
|
6290
6389
|
}
|
|
6291
|
-
const beadsDir =
|
|
6292
|
-
if (
|
|
6293
|
-
cpSync2(beadsDir,
|
|
6390
|
+
const beadsDir = join26(workspacePath, ".planning", "beads");
|
|
6391
|
+
if (existsSync27(beadsDir)) {
|
|
6392
|
+
cpSync2(beadsDir, join26(archiveDir, "beads"), { recursive: true });
|
|
6294
6393
|
details.push("Archived beads/");
|
|
6295
6394
|
}
|
|
6296
|
-
const prdMd =
|
|
6297
|
-
if (
|
|
6298
|
-
cpSync2(prdMd,
|
|
6395
|
+
const prdMd = join26(workspacePath, ".planning", "PRD.md");
|
|
6396
|
+
if (existsSync27(prdMd)) {
|
|
6397
|
+
cpSync2(prdMd, join26(archiveDir, "PRD.md"));
|
|
6299
6398
|
details.push("Archived workspace PRD.md");
|
|
6300
6399
|
}
|
|
6301
6400
|
details.push(`Archived to ${archiveDir}`);
|
|
@@ -6560,8 +6659,8 @@ async function applyLabelLinear(ctx, apiKey) {
|
|
|
6560
6659
|
init_esm_shims();
|
|
6561
6660
|
init_paths();
|
|
6562
6661
|
init_tmux();
|
|
6563
|
-
import { existsSync as
|
|
6564
|
-
import { join as
|
|
6662
|
+
import { existsSync as existsSync28, rmSync as rmSync3, unlinkSync as unlinkSync2 } from "fs";
|
|
6663
|
+
import { join as join27, basename as basename5 } from "path";
|
|
6565
6664
|
import { exec as exec7 } from "child_process";
|
|
6566
6665
|
import { promisify as promisify7 } from "util";
|
|
6567
6666
|
var execAsync7 = promisify7(exec7);
|
|
@@ -6591,8 +6690,8 @@ async function killTmuxSessions(issueLower) {
|
|
|
6591
6690
|
}
|
|
6592
6691
|
async function stopTldrDaemon(workspacePath) {
|
|
6593
6692
|
const step = "teardown:tldr-daemon";
|
|
6594
|
-
const venvPath =
|
|
6595
|
-
if (!
|
|
6693
|
+
const venvPath = join27(workspacePath, ".venv");
|
|
6694
|
+
if (!existsSync28(venvPath)) {
|
|
6596
6695
|
return stepSkipped(step, ["No .venv found"]);
|
|
6597
6696
|
}
|
|
6598
6697
|
try {
|
|
@@ -6607,8 +6706,8 @@ async function stopTldrDaemon(workspacePath) {
|
|
|
6607
6706
|
async function stopDocker(workspacePath, projectName, issueLower) {
|
|
6608
6707
|
const step = "teardown:docker";
|
|
6609
6708
|
try {
|
|
6610
|
-
const { stopWorkspaceDocker } = await import("../workspace-manager-
|
|
6611
|
-
await
|
|
6709
|
+
const { stopWorkspaceDocker: stopWorkspaceDocker2 } = await import("../workspace-manager-E434Z45T.js");
|
|
6710
|
+
await stopWorkspaceDocker2(workspacePath, projectName, issueLower);
|
|
6612
6711
|
return stepOk(step, ["Stopped Docker containers"]);
|
|
6613
6712
|
} catch {
|
|
6614
6713
|
return stepSkipped(step, ["Docker cleanup skipped (not running or failed)"]);
|
|
@@ -6616,7 +6715,7 @@ async function stopDocker(workspacePath, projectName, issueLower) {
|
|
|
6616
6715
|
}
|
|
6617
6716
|
async function removeWorktree(projectPath, workspacePath) {
|
|
6618
6717
|
const step = "teardown:worktree";
|
|
6619
|
-
if (!
|
|
6718
|
+
if (!existsSync28(workspacePath)) {
|
|
6620
6719
|
return stepSkipped(step, ["Workspace directory does not exist"]);
|
|
6621
6720
|
}
|
|
6622
6721
|
try {
|
|
@@ -6634,12 +6733,12 @@ async function removeWorktree(projectPath, workspacePath) {
|
|
|
6634
6733
|
async function removeAgentState(issueLower) {
|
|
6635
6734
|
const step = "teardown:agent-state";
|
|
6636
6735
|
const dirs = [
|
|
6637
|
-
|
|
6638
|
-
|
|
6736
|
+
join27(AGENTS_DIR, `agent-${issueLower}`),
|
|
6737
|
+
join27(AGENTS_DIR, `planning-${issueLower}`)
|
|
6639
6738
|
];
|
|
6640
6739
|
let removed = 0;
|
|
6641
6740
|
for (const dir of dirs) {
|
|
6642
|
-
if (
|
|
6741
|
+
if (existsSync28(dir)) {
|
|
6643
6742
|
rmSync3(dir, { recursive: true, force: true });
|
|
6644
6743
|
removed++;
|
|
6645
6744
|
}
|
|
@@ -6682,8 +6781,8 @@ async function clearShadowState(issueId) {
|
|
|
6682
6781
|
}
|
|
6683
6782
|
async function clearLegacyPlanningDir(projectPath, issueLower) {
|
|
6684
6783
|
const step = "teardown:legacy-planning-dir";
|
|
6685
|
-
const legacyDir =
|
|
6686
|
-
if (
|
|
6784
|
+
const legacyDir = join27(projectPath, ".planning", issueLower);
|
|
6785
|
+
if (existsSync28(legacyDir)) {
|
|
6687
6786
|
rmSync3(legacyDir, { recursive: true, force: true });
|
|
6688
6787
|
return stepOk(step, [`Deleted legacy planning dir: ${legacyDir}`]);
|
|
6689
6788
|
}
|
|
@@ -6691,8 +6790,8 @@ async function clearLegacyPlanningDir(projectPath, issueLower) {
|
|
|
6691
6790
|
}
|
|
6692
6791
|
async function clearPlanningMarker(workspacePath) {
|
|
6693
6792
|
const step = "teardown:planning-marker";
|
|
6694
|
-
const markerPath =
|
|
6695
|
-
if (
|
|
6793
|
+
const markerPath = join27(workspacePath, ".planning", ".planning-complete");
|
|
6794
|
+
if (existsSync28(markerPath)) {
|
|
6696
6795
|
unlinkSync2(markerPath);
|
|
6697
6796
|
return stepOk(step, ["Cleared .planning-complete marker"]);
|
|
6698
6797
|
}
|
|
@@ -6743,7 +6842,7 @@ async function teardownWorkspace(ctx, opts = {}) {
|
|
|
6743
6842
|
results.push(await killTmuxSessions(issueLower));
|
|
6744
6843
|
results.push(await clearShadowState(ctx.issueId));
|
|
6745
6844
|
results.push(await clearLegacyPlanningDir(ctx.projectPath, issueLower));
|
|
6746
|
-
if (workspacePath &&
|
|
6845
|
+
if (workspacePath && existsSync28(workspacePath)) {
|
|
6747
6846
|
if (shouldDeleteWorkspace) {
|
|
6748
6847
|
results.push(await stopTldrDaemon(workspacePath));
|
|
6749
6848
|
}
|
|
@@ -6782,8 +6881,8 @@ var execAsync8 = promisify8(exec8);
|
|
|
6782
6881
|
// src/lib/lifecycle/workflows.ts
|
|
6783
6882
|
init_esm_shims();
|
|
6784
6883
|
init_paths();
|
|
6785
|
-
import { existsSync as
|
|
6786
|
-
import { join as
|
|
6884
|
+
import { existsSync as existsSync29, readFileSync as readFileSync25 } from "fs";
|
|
6885
|
+
import { join as join28 } from "path";
|
|
6787
6886
|
import { exec as exec9 } from "child_process";
|
|
6788
6887
|
import { promisify as promisify9 } from "util";
|
|
6789
6888
|
var execAsync9 = promisify9(exec9);
|
|
@@ -6829,7 +6928,7 @@ async function verifyBranchMerged(ctx) {
|
|
|
6829
6928
|
const branchName = `feature/${issueLower}`;
|
|
6830
6929
|
try {
|
|
6831
6930
|
try {
|
|
6832
|
-
const { loadReviewStatuses: loadReviewStatuses3 } = await import("../review-status-
|
|
6931
|
+
const { loadReviewStatuses: loadReviewStatuses3 } = await import("../review-status-TDPSOU5J.js");
|
|
6833
6932
|
const statuses = loadReviewStatuses3();
|
|
6834
6933
|
const issueKey = ctx.issueId.toUpperCase();
|
|
6835
6934
|
if (statuses[issueKey]?.mergeStatus === "merged") {
|
|
@@ -6887,14 +6986,14 @@ async function verifyBranchMerged(ctx) {
|
|
|
6887
6986
|
async function clearReviewStatusStep(issueId) {
|
|
6888
6987
|
const step = "clear-review-status";
|
|
6889
6988
|
try {
|
|
6890
|
-
const { clearReviewStatus: clearReviewStatus2 } = await import("../review-status-
|
|
6989
|
+
const { clearReviewStatus: clearReviewStatus2 } = await import("../review-status-TDPSOU5J.js");
|
|
6891
6990
|
clearReviewStatus2(issueId.toUpperCase());
|
|
6892
6991
|
return stepOk(step, ["Review status cleared"]);
|
|
6893
6992
|
} catch {
|
|
6894
6993
|
try {
|
|
6895
|
-
const statusFile =
|
|
6896
|
-
if (
|
|
6897
|
-
const data = JSON.parse(
|
|
6994
|
+
const statusFile = join28(PANOPTICON_HOME, "review-status.json");
|
|
6995
|
+
if (existsSync29(statusFile)) {
|
|
6996
|
+
const data = JSON.parse(readFileSync25(statusFile, "utf-8"));
|
|
6898
6997
|
const upperKey = issueId.toUpperCase();
|
|
6899
6998
|
if (data[upperKey]) {
|
|
6900
6999
|
delete data[upperKey];
|
|
@@ -6911,20 +7010,6 @@ async function clearReviewStatusStep(issueId) {
|
|
|
6911
7010
|
|
|
6912
7011
|
// src/cli/commands/work/close-out.ts
|
|
6913
7012
|
init_projects();
|
|
6914
|
-
function getGitHubConfig2() {
|
|
6915
|
-
const envFile = join28(homedir13(), ".panopticon.env");
|
|
6916
|
-
if (!existsSync29(envFile)) return null;
|
|
6917
|
-
const content = readFileSync25(envFile, "utf-8");
|
|
6918
|
-
const reposMatch = content.match(/GITHUB_REPOS=(.+)/);
|
|
6919
|
-
if (!reposMatch) return null;
|
|
6920
|
-
const repoStr = reposMatch[1].trim();
|
|
6921
|
-
const parts = repoStr.split(",")[0];
|
|
6922
|
-
if (!parts) return null;
|
|
6923
|
-
const [ownerRepo, prefix] = parts.split(":");
|
|
6924
|
-
const [owner, repo] = ownerRepo.split("/");
|
|
6925
|
-
if (!owner || !repo) return null;
|
|
6926
|
-
return { owner, repo, prefix: prefix || repo.toUpperCase().replace(/-CLI$/, "").replace(/-/g, "") };
|
|
6927
|
-
}
|
|
6928
7013
|
async function closeOutCommand(issueId, options) {
|
|
6929
7014
|
if (process.env.PANOPTICON_AGENT_ID) {
|
|
6930
7015
|
console.error(chalk31.red("Close-out is a human-only operation. Agents cannot close out issues."));
|
|
@@ -6947,22 +7032,11 @@ async function closeOutCommand(issueId, options) {
|
|
|
6947
7032
|
console.error(chalk31.red(`Could not resolve project for ${issueId}`));
|
|
6948
7033
|
process.exit(1);
|
|
6949
7034
|
}
|
|
6950
|
-
const
|
|
6951
|
-
|
|
6952
|
-
|
|
6953
|
-
|
|
6954
|
-
|
|
6955
|
-
const ghConfig = getGitHubConfig2();
|
|
6956
|
-
if (ghConfig) {
|
|
6957
|
-
owner = ghConfig.owner;
|
|
6958
|
-
repo = ghConfig.repo;
|
|
6959
|
-
number = parseInt(issueId.replace(/^PAN-/i, ""), 10);
|
|
6960
|
-
} else {
|
|
6961
|
-
owner = "eltmon";
|
|
6962
|
-
repo = "panopticon-cli";
|
|
6963
|
-
number = parseInt(issueId.replace(/^PAN-/i, ""), 10);
|
|
6964
|
-
}
|
|
6965
|
-
}
|
|
7035
|
+
const ghResolution = resolveGitHubIssue(issueId);
|
|
7036
|
+
const isGitHub = ghResolution.isGitHub;
|
|
7037
|
+
const owner = ghResolution.isGitHub ? ghResolution.owner : void 0;
|
|
7038
|
+
const repo = ghResolution.isGitHub ? ghResolution.repo : void 0;
|
|
7039
|
+
const number = ghResolution.isGitHub ? ghResolution.number : void 0;
|
|
6966
7040
|
if (!options.force) {
|
|
6967
7041
|
console.log(chalk31.yellow(`
|
|
6968
7042
|
Close-out ceremony for ${issueUpper}
|
|
@@ -7262,6 +7336,10 @@ function createWorktree(repoPath, targetPath, branchName) {
|
|
|
7262
7336
|
stdio: "pipe"
|
|
7263
7337
|
});
|
|
7264
7338
|
}
|
|
7339
|
+
try {
|
|
7340
|
+
execSync3("git config beads.role agent", { cwd: targetPath, stdio: "pipe" });
|
|
7341
|
+
} catch {
|
|
7342
|
+
}
|
|
7265
7343
|
}
|
|
7266
7344
|
function removeWorktree2(repoPath, worktreePath) {
|
|
7267
7345
|
execSync3(`git worktree remove "${worktreePath}" --force`, {
|
|
@@ -11669,7 +11747,7 @@ async function runPatrol() {
|
|
|
11669
11747
|
if (nextTask) {
|
|
11670
11748
|
console.log(`[deacon] Auto-resuming suspended ${specialist.name} for queued task: ${nextTask.payload.issueId}`);
|
|
11671
11749
|
try {
|
|
11672
|
-
const { resumeAgent } = await import("../agents-
|
|
11750
|
+
const { resumeAgent } = await import("../agents-5OPQKM5K.js");
|
|
11673
11751
|
const message = `# Queued Work
|
|
11674
11752
|
|
|
11675
11753
|
Processing queued task: ${nextTask.payload.issueId}`;
|
|
@@ -13604,7 +13682,7 @@ import { promisify as promisify18 } from "util";
|
|
|
13604
13682
|
var execAsync18 = promisify18(exec18);
|
|
13605
13683
|
async function listLogsCommand(project2, type, options) {
|
|
13606
13684
|
try {
|
|
13607
|
-
const { listRunLogs } = await import("../specialist-logs-
|
|
13685
|
+
const { listRunLogs } = await import("../specialist-logs-XJB5TCKJ.js");
|
|
13608
13686
|
const limit = options.limit ? parseInt(options.limit) : 10;
|
|
13609
13687
|
const runs = listRunLogs(project2, type, { limit });
|
|
13610
13688
|
if (options.json) {
|
|
@@ -13649,7 +13727,7 @@ View a specific run: pan specialists logs ${project2} ${type} <runId>
|
|
|
13649
13727
|
}
|
|
13650
13728
|
async function viewLogCommand(project2, type, runId, options) {
|
|
13651
13729
|
try {
|
|
13652
|
-
const { getRunLog, parseLogMetadata, getRunLogPath } = await import("../specialist-logs-
|
|
13730
|
+
const { getRunLog, parseLogMetadata, getRunLogPath } = await import("../specialist-logs-XJB5TCKJ.js");
|
|
13653
13731
|
const content = getRunLog(project2, type, runId);
|
|
13654
13732
|
if (!content) {
|
|
13655
13733
|
console.error(`\u274C Run log not found: ${runId}`);
|
|
@@ -13673,8 +13751,8 @@ async function viewLogCommand(project2, type, runId, options) {
|
|
|
13673
13751
|
}
|
|
13674
13752
|
async function tailLogCommand(project2, type) {
|
|
13675
13753
|
try {
|
|
13676
|
-
const { getRunLogPath } = await import("../specialist-logs-
|
|
13677
|
-
const { getProjectSpecialistMetadata } = await import("../specialists-
|
|
13754
|
+
const { getRunLogPath } = await import("../specialist-logs-XJB5TCKJ.js");
|
|
13755
|
+
const { getProjectSpecialistMetadata } = await import("../specialists-5LBRHYFA.js");
|
|
13678
13756
|
const metadata = getProjectSpecialistMetadata(project2, type);
|
|
13679
13757
|
if (!metadata.currentRun) {
|
|
13680
13758
|
console.error(`\u274C No active run for ${project2}/${type}`);
|
|
@@ -13743,7 +13821,7 @@ async function cleanupLogsCommand(projectOrAll, type, options) {
|
|
|
13743
13821
|
console.log(" Use --force to confirm.");
|
|
13744
13822
|
process.exit(1);
|
|
13745
13823
|
}
|
|
13746
|
-
const { cleanupAllLogs } = await import("../specialist-logs-
|
|
13824
|
+
const { cleanupAllLogs } = await import("../specialist-logs-XJB5TCKJ.js");
|
|
13747
13825
|
console.log("\u{1F9F9} Cleaning up old logs for all projects...\n");
|
|
13748
13826
|
const results = cleanupAllLogs();
|
|
13749
13827
|
console.log(`
|
|
@@ -13770,8 +13848,8 @@ async function cleanupLogsCommand(projectOrAll, type, options) {
|
|
|
13770
13848
|
console.log(" Use --force to confirm.");
|
|
13771
13849
|
process.exit(1);
|
|
13772
13850
|
}
|
|
13773
|
-
const { cleanupOldLogs } = await import("../specialist-logs-
|
|
13774
|
-
const { getSpecialistRetention } = await import("../projects-
|
|
13851
|
+
const { cleanupOldLogs } = await import("../specialist-logs-XJB5TCKJ.js");
|
|
13852
|
+
const { getSpecialistRetention } = await import("../projects-CFX3RTDL.js");
|
|
13775
13853
|
const retention = getSpecialistRetention(projectOrAll);
|
|
13776
13854
|
console.log(`\u{1F9F9} Cleaning up old logs for ${projectOrAll}/${type}...`);
|
|
13777
13855
|
console.log(` Retention: ${retention.max_days} days or ${retention.max_runs} runs
|
|
@@ -14528,6 +14606,11 @@ async function projectAddCommand(projectPath, options = {}) {
|
|
|
14528
14606
|
}
|
|
14529
14607
|
}
|
|
14530
14608
|
const isPolyrepo = !hasRootGit && subRepos.length > 0;
|
|
14609
|
+
try {
|
|
14610
|
+
const { preTrustDirectory } = await import("../workspace-manager-E434Z45T.js");
|
|
14611
|
+
preTrustDirectory(fullPath);
|
|
14612
|
+
} catch {
|
|
14613
|
+
}
|
|
14531
14614
|
let hooksInstalled = 0;
|
|
14532
14615
|
if (hasRootGit) {
|
|
14533
14616
|
hooksInstalled = installGitHooks(join48(fullPath, ".git"));
|
|
@@ -16469,7 +16552,7 @@ program.command("up").description("Start dashboard (and Traefik if enabled)").op
|
|
|
16469
16552
|
console.log(chalk61.bold("Starting Panopticon...\n"));
|
|
16470
16553
|
if (traefikEnabled && !options.skipTraefik) {
|
|
16471
16554
|
try {
|
|
16472
|
-
const { generatePanopticonTraefikConfig: generatePanopticonTraefikConfig2, ensureProjectCerts: ensureProjectCerts2, generateTlsConfig: generateTlsConfig2, cleanupStaleTlsSections } = await import("../traefik-
|
|
16555
|
+
const { generatePanopticonTraefikConfig: generatePanopticonTraefikConfig2, ensureProjectCerts: ensureProjectCerts2, generateTlsConfig: generateTlsConfig2, cleanupStaleTlsSections } = await import("../traefik-WFMQX2LY.js");
|
|
16473
16556
|
cleanupStaleTlsSections();
|
|
16474
16557
|
if (generatePanopticonTraefikConfig2()) {
|
|
16475
16558
|
console.log(chalk61.dim(" Regenerated Traefik config from template"));
|