panopticon-cli 0.4.28 → 0.4.31
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-ND4NKCK2.js → agents-GQDAKTEQ.js} +5 -4
- package/dist/{chunk-SIAUVHVO.js → chunk-3XAB4IXF.js} +4 -2
- package/dist/{chunk-SIAUVHVO.js.map → chunk-3XAB4IXF.js.map} +1 -1
- package/dist/chunk-ELK6Q7QI.js +545 -0
- package/dist/chunk-ELK6Q7QI.js.map +1 -0
- package/dist/{chunk-ZLB6G4NW.js → chunk-HNEWTIR3.js} +41 -9
- package/dist/chunk-HNEWTIR3.js.map +1 -0
- package/dist/chunk-LYSBSZYV.js +1523 -0
- package/dist/chunk-LYSBSZYV.js.map +1 -0
- package/dist/{chunk-4KNEZGKZ.js → chunk-TMXN7THF.js} +45 -24
- package/dist/chunk-TMXN7THF.js.map +1 -0
- package/dist/{chunk-ON5NIBGW.js → chunk-VIWUCJ4V.js} +37 -8
- package/dist/chunk-VIWUCJ4V.js.map +1 -0
- package/dist/{chunk-VTMXR7JF.js → chunk-VU4FLXV5.js} +47 -40
- package/dist/{chunk-VTMXR7JF.js.map → chunk-VU4FLXV5.js.map} +1 -1
- package/dist/cli/index.js +153 -86
- package/dist/cli/index.js.map +1 -1
- package/dist/{config-QWTS63TU.js → config-BOAMSKTF.js} +4 -2
- package/dist/dashboard/public/assets/{index--VPaQ2VU.css → index-C7X6LP5Z.css} +1 -1
- package/dist/dashboard/public/assets/{index-GYQaqwVS.js → index-izWbAt7V.js} +152 -152
- package/dist/dashboard/public/index.html +2 -2
- package/dist/dashboard/server.js +94706 -24017
- package/dist/feedback-writer-AAKF5BTK.js +111 -0
- package/dist/feedback-writer-AAKF5BTK.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +16 -14
- package/dist/index.js.map +1 -1
- package/dist/{remote-workspace-FNXLMNBG.js → remote-workspace-2G6V2KNP.js} +7 -5
- package/dist/{remote-workspace-FNXLMNBG.js.map → remote-workspace-2G6V2KNP.js.map} +1 -1
- package/dist/{specialist-context-WXO3FKIB.js → specialist-context-6SE5VRRC.js} +3 -3
- package/dist/{specialist-logs-SJWLETJT.js → specialist-logs-EXLOQHQ2.js} +3 -3
- package/dist/{specialists-5YJIDRW6.js → specialists-BRUHPAXE.js} +3 -3
- package/dist/{traefik-7OLLXUD7.js → traefik-CUJM6K5Z.js} +3 -3
- package/package.json +3 -2
- package/scripts/record-cost-event.js +243 -79
- package/scripts/record-cost-event.ts +128 -68
- package/templates/traefik/docker-compose.yml +7 -4
- package/templates/traefik/dynamic/panopticon.yml.template +3 -1
- package/dist/chunk-46DPNFMW.js +0 -278
- package/dist/chunk-46DPNFMW.js.map +0 -1
- package/dist/chunk-4KNEZGKZ.js.map +0 -1
- package/dist/chunk-ON5NIBGW.js.map +0 -1
- package/dist/chunk-SUMIHS2B.js +0 -1714
- package/dist/chunk-SUMIHS2B.js.map +0 -1
- package/dist/chunk-ZLB6G4NW.js.map +0 -1
- /package/dist/{agents-ND4NKCK2.js.map → agents-GQDAKTEQ.js.map} +0 -0
- /package/dist/{config-QWTS63TU.js.map → config-BOAMSKTF.js.map} +0 -0
- /package/dist/{specialist-context-WXO3FKIB.js.map → specialist-context-6SE5VRRC.js.map} +0 -0
- /package/dist/{specialist-logs-SJWLETJT.js.map → specialist-logs-EXLOQHQ2.js.map} +0 -0
- /package/dist/{specialists-5YJIDRW6.js.map → specialists-BRUHPAXE.js.map} +0 -0
- /package/dist/{traefik-7OLLXUD7.js.map → traefik-CUJM6K5Z.js.map} +0 -0
package/dist/cli/index.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import {
|
|
3
3
|
cleanupTemplateFiles,
|
|
4
4
|
generatePanopticonTraefikConfig
|
|
5
|
-
} from "../chunk-
|
|
5
|
+
} from "../chunk-3XAB4IXF.js";
|
|
6
6
|
import {
|
|
7
7
|
checkSpecialistQueue,
|
|
8
8
|
clearSessionId,
|
|
@@ -25,12 +25,11 @@ import {
|
|
|
25
25
|
recordWake,
|
|
26
26
|
wakeSpecialistOrQueue,
|
|
27
27
|
wakeSpecialistWithTask
|
|
28
|
-
} from "../chunk-
|
|
28
|
+
} from "../chunk-TMXN7THF.js";
|
|
29
29
|
import {
|
|
30
30
|
addAlias,
|
|
31
31
|
cleanOldBackups,
|
|
32
32
|
createBackup,
|
|
33
|
-
createTracker,
|
|
34
33
|
detectShell,
|
|
35
34
|
executeSync,
|
|
36
35
|
getAliasInstructions,
|
|
@@ -40,7 +39,7 @@ import {
|
|
|
40
39
|
planSync,
|
|
41
40
|
restoreBackup,
|
|
42
41
|
syncHooks
|
|
43
|
-
} from "../chunk-
|
|
42
|
+
} from "../chunk-ELK6Q7QI.js";
|
|
44
43
|
import {
|
|
45
44
|
init_remote_agents,
|
|
46
45
|
isRemoteAgentRunning,
|
|
@@ -57,7 +56,7 @@ import {
|
|
|
57
56
|
getAgentState,
|
|
58
57
|
getHealthThresholdsMs,
|
|
59
58
|
init_agents,
|
|
60
|
-
init_config,
|
|
59
|
+
init_config as init_config2,
|
|
61
60
|
init_cv,
|
|
62
61
|
listRunningAgents,
|
|
63
62
|
loadCloisterConfig,
|
|
@@ -68,7 +67,7 @@ import {
|
|
|
68
67
|
saveSessionId,
|
|
69
68
|
spawnAgent,
|
|
70
69
|
stopAgent
|
|
71
|
-
} from "../chunk-
|
|
70
|
+
} from "../chunk-HNEWTIR3.js";
|
|
72
71
|
import {
|
|
73
72
|
checkHook,
|
|
74
73
|
clearHook,
|
|
@@ -82,13 +81,15 @@ import {
|
|
|
82
81
|
popFromHook,
|
|
83
82
|
pushToHook,
|
|
84
83
|
sendKeys,
|
|
84
|
+
sendKeysAsync,
|
|
85
85
|
sendMail,
|
|
86
86
|
sessionExists
|
|
87
|
-
} from "../chunk-
|
|
87
|
+
} from "../chunk-VIWUCJ4V.js";
|
|
88
88
|
import {
|
|
89
|
+
createTracker,
|
|
89
90
|
init_settings,
|
|
90
91
|
loadSettings
|
|
91
|
-
} from "../chunk-
|
|
92
|
+
} from "../chunk-LYSBSZYV.js";
|
|
92
93
|
import {
|
|
93
94
|
init_config_yaml,
|
|
94
95
|
loadConfig as loadConfig2
|
|
@@ -100,12 +101,6 @@ import {
|
|
|
100
101
|
loadWorkspaceMetadata,
|
|
101
102
|
saveWorkspaceMetadata
|
|
102
103
|
} from "../chunk-44EOY2ZL.js";
|
|
103
|
-
import {
|
|
104
|
-
getDashboardApiUrl,
|
|
105
|
-
getDefaultConfig,
|
|
106
|
-
loadConfig,
|
|
107
|
-
saveConfig
|
|
108
|
-
} from "../chunk-VTMXR7JF.js";
|
|
109
104
|
import {
|
|
110
105
|
PROJECTS_CONFIG_FILE,
|
|
111
106
|
extractTeamPrefix,
|
|
@@ -124,6 +119,13 @@ import {
|
|
|
124
119
|
createExeProvider,
|
|
125
120
|
init_exe_provider
|
|
126
121
|
} from "../chunk-JM6V62LT.js";
|
|
122
|
+
import {
|
|
123
|
+
getDashboardApiUrl,
|
|
124
|
+
getDefaultConfig,
|
|
125
|
+
init_config,
|
|
126
|
+
loadConfig,
|
|
127
|
+
saveConfig
|
|
128
|
+
} from "../chunk-VU4FLXV5.js";
|
|
127
129
|
import {
|
|
128
130
|
AGENTS_DIR,
|
|
129
131
|
CERTS_DIR,
|
|
@@ -166,6 +168,7 @@ import chalk56 from "chalk";
|
|
|
166
168
|
// src/cli/commands/init.ts
|
|
167
169
|
init_esm_shims();
|
|
168
170
|
init_paths();
|
|
171
|
+
init_config();
|
|
169
172
|
import { existsSync, mkdirSync, readdirSync, cpSync } from "fs";
|
|
170
173
|
import { join, dirname } from "path";
|
|
171
174
|
import { fileURLToPath } from "url";
|
|
@@ -275,6 +278,7 @@ async function initCommand() {
|
|
|
275
278
|
|
|
276
279
|
// src/cli/commands/sync.ts
|
|
277
280
|
init_esm_shims();
|
|
281
|
+
init_config();
|
|
278
282
|
import chalk2 from "chalk";
|
|
279
283
|
import ora2 from "ora";
|
|
280
284
|
import { execSync } from "child_process";
|
|
@@ -501,6 +505,7 @@ init_esm_shims();
|
|
|
501
505
|
import chalk3 from "chalk";
|
|
502
506
|
import ora3 from "ora";
|
|
503
507
|
import inquirer from "inquirer";
|
|
508
|
+
init_config();
|
|
504
509
|
init_paths();
|
|
505
510
|
async function restoreCommand(timestamp) {
|
|
506
511
|
const backups = listBackups();
|
|
@@ -868,6 +873,9 @@ function shouldSkipTrackerUpdate(issueId, cliFlag, trackerType = "linear") {
|
|
|
868
873
|
});
|
|
869
874
|
}
|
|
870
875
|
|
|
876
|
+
// src/cli/commands/work/issue.ts
|
|
877
|
+
init_config();
|
|
878
|
+
|
|
871
879
|
// src/lib/remote/index.ts
|
|
872
880
|
init_esm_shims();
|
|
873
881
|
init_exe_provider();
|
|
@@ -894,7 +902,7 @@ async function isRemoteAvailable() {
|
|
|
894
902
|
|
|
895
903
|
// src/lib/cloister/work-agent-prompt.ts
|
|
896
904
|
init_esm_shims();
|
|
897
|
-
import { existsSync as existsSync6, readFileSync as readFileSync4 } from "fs";
|
|
905
|
+
import { existsSync as existsSync6, readFileSync as readFileSync4, readdirSync as readdirSync6 } from "fs";
|
|
898
906
|
import { join as join6, dirname as dirname3 } from "path";
|
|
899
907
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
900
908
|
|
|
@@ -1008,6 +1016,7 @@ function buildWorkAgentPrompt(ctx) {
|
|
|
1008
1016
|
let beadsTasksStr = "";
|
|
1009
1017
|
let stitchDesignsStr = "";
|
|
1010
1018
|
let polyrepoContextStr = "";
|
|
1019
|
+
let pendingFeedbackStr = "";
|
|
1011
1020
|
if (!ctx.skipDynamicContext && ctx.projectRoot) {
|
|
1012
1021
|
const planningContent = readPlanningContext(ctx.workspacePath);
|
|
1013
1022
|
const beadsTasks = readBeadsTasks(ctx.workspacePath, ctx.projectRoot, ctx.issueId);
|
|
@@ -1019,6 +1028,7 @@ function buildWorkAgentPrompt(ctx) {
|
|
|
1019
1028
|
stitchDesignsStr = stitchDesigns;
|
|
1020
1029
|
}
|
|
1021
1030
|
polyrepoContextStr = buildPolyrepoContext(ctx.issueId, ctx.workspacePath);
|
|
1031
|
+
pendingFeedbackStr = readPendingFeedback(ctx.workspacePath);
|
|
1022
1032
|
}
|
|
1023
1033
|
const apiUrl = process.env.DASHBOARD_URL || `http://localhost:${process.env.API_PORT || process.env.PORT || "3011"}`;
|
|
1024
1034
|
const vars = {
|
|
@@ -1029,13 +1039,36 @@ function buildWorkAgentPrompt(ctx) {
|
|
|
1029
1039
|
API_URL: apiUrl,
|
|
1030
1040
|
BEADS_TASKS: beadsTasksStr,
|
|
1031
1041
|
STITCH_DESIGNS: stitchDesignsStr,
|
|
1032
|
-
POLYREPO_CONTEXT: polyrepoContextStr
|
|
1042
|
+
POLYREPO_CONTEXT: polyrepoContextStr,
|
|
1043
|
+
PENDING_FEEDBACK: pendingFeedbackStr
|
|
1033
1044
|
};
|
|
1034
1045
|
template = processEnvBlocks(template, ctx.env);
|
|
1035
1046
|
template = processIfBlocks(template, vars);
|
|
1036
1047
|
template = substituteVariables(template, vars);
|
|
1037
1048
|
return template;
|
|
1038
1049
|
}
|
|
1050
|
+
function readPendingFeedback(workspacePath) {
|
|
1051
|
+
const feedbackDir = join6(workspacePath, ".planning", "feedback");
|
|
1052
|
+
if (!existsSync6(feedbackDir)) return "";
|
|
1053
|
+
try {
|
|
1054
|
+
const files = readdirSync6(feedbackDir).filter((f) => f.endsWith(".md")).sort();
|
|
1055
|
+
if (files.length === 0) return "";
|
|
1056
|
+
const latest = files[files.length - 1];
|
|
1057
|
+
const lines = [
|
|
1058
|
+
`**${files.length} feedback file(s) in \`.planning/feedback/\`:**`,
|
|
1059
|
+
""
|
|
1060
|
+
];
|
|
1061
|
+
for (const file of files) {
|
|
1062
|
+
const marker = file === latest ? " \u2190 **latest, read this first**" : "";
|
|
1063
|
+
lines.push(`- \`.planning/feedback/${file}\`${marker}`);
|
|
1064
|
+
}
|
|
1065
|
+
lines.push("");
|
|
1066
|
+
lines.push("Read the latest feedback file and address any issues before continuing other work.");
|
|
1067
|
+
return lines.join("\n");
|
|
1068
|
+
} catch {
|
|
1069
|
+
return "";
|
|
1070
|
+
}
|
|
1071
|
+
}
|
|
1039
1072
|
function readPlanningContext(workspacePath) {
|
|
1040
1073
|
const statePath = join6(workspacePath, ".planning", "STATE.md");
|
|
1041
1074
|
if (existsSync6(statePath)) {
|
|
@@ -1289,7 +1322,7 @@ async function handleRemoteWorkspace(issueId, options, spinner) {
|
|
|
1289
1322
|
if (!remoteMetadata) {
|
|
1290
1323
|
spinner.text = "Remote workspace not found, creating...";
|
|
1291
1324
|
try {
|
|
1292
|
-
const { createRemoteWorkspace: createRemoteWorkspace2 } = await import("../remote-workspace-
|
|
1325
|
+
const { createRemoteWorkspace: createRemoteWorkspace2 } = await import("../remote-workspace-2G6V2KNP.js");
|
|
1293
1326
|
remoteMetadata = await createRemoteWorkspace2(issueId, { spinner });
|
|
1294
1327
|
} catch (error) {
|
|
1295
1328
|
spinner.fail(`Failed to create remote workspace: ${error.message}`);
|
|
@@ -2072,7 +2105,7 @@ async function doneCommand(id, options = {}) {
|
|
|
2072
2105
|
console.log(chalk12.dim(` pan work approve ${issueId}`));
|
|
2073
2106
|
console.log("");
|
|
2074
2107
|
try {
|
|
2075
|
-
const { getDashboardApiUrl: getDashboardApiUrl2 } = await import("../config-
|
|
2108
|
+
const { getDashboardApiUrl: getDashboardApiUrl2 } = await import("../config-BOAMSKTF.js");
|
|
2076
2109
|
const dashboardUrl = getDashboardApiUrl2();
|
|
2077
2110
|
const http = await import("http");
|
|
2078
2111
|
const checkDashboard = () => new Promise((resolve2) => {
|
|
@@ -2748,6 +2781,7 @@ async function planCommand(id, options = {}) {
|
|
|
2748
2781
|
|
|
2749
2782
|
// src/cli/commands/work/list.ts
|
|
2750
2783
|
init_esm_shims();
|
|
2784
|
+
init_config();
|
|
2751
2785
|
import chalk14 from "chalk";
|
|
2752
2786
|
import ora8 from "ora";
|
|
2753
2787
|
var PRIORITY_LABELS = {
|
|
@@ -2916,6 +2950,7 @@ ${tracker.toUpperCase()} (${issues.length} shadowed issues)
|
|
|
2916
2950
|
|
|
2917
2951
|
// src/cli/commands/work/triage.ts
|
|
2918
2952
|
init_esm_shims();
|
|
2953
|
+
init_config();
|
|
2919
2954
|
import chalk15 from "chalk";
|
|
2920
2955
|
import ora9 from "ora";
|
|
2921
2956
|
import { readFileSync as readFileSync10, writeFileSync as writeFileSync5, existsSync as existsSync12, mkdirSync as mkdirSync6 } from "fs";
|
|
@@ -3338,7 +3373,7 @@ import chalk19 from "chalk";
|
|
|
3338
3373
|
// src/lib/context.ts
|
|
3339
3374
|
init_esm_shims();
|
|
3340
3375
|
init_paths();
|
|
3341
|
-
import { existsSync as existsSync13, mkdirSync as mkdirSync7, readFileSync as readFileSync11, writeFileSync as writeFileSync6, appendFileSync, readdirSync as
|
|
3376
|
+
import { existsSync as existsSync13, mkdirSync as mkdirSync7, readFileSync as readFileSync11, writeFileSync as writeFileSync6, appendFileSync, readdirSync as readdirSync9 } from "fs";
|
|
3342
3377
|
import { join as join13 } from "path";
|
|
3343
3378
|
function getStateFile(agentId) {
|
|
3344
3379
|
return join13(AGENTS_DIR, agentId, "STATE.md");
|
|
@@ -3498,7 +3533,7 @@ function searchHistory(agentId, pattern) {
|
|
|
3498
3533
|
if (!existsSync13(historyDir)) return [];
|
|
3499
3534
|
const results = [];
|
|
3500
3535
|
const regex = new RegExp(pattern, "i");
|
|
3501
|
-
const files =
|
|
3536
|
+
const files = readdirSync9(historyDir).filter((f) => f.endsWith(".log"));
|
|
3502
3537
|
files.sort().reverse();
|
|
3503
3538
|
for (const file of files) {
|
|
3504
3539
|
const content = readFileSync11(join13(historyDir, file), "utf-8");
|
|
@@ -3515,7 +3550,7 @@ function getRecentHistory(agentId, limit = 20) {
|
|
|
3515
3550
|
const historyDir = getHistoryDir(agentId);
|
|
3516
3551
|
if (!existsSync13(historyDir)) return [];
|
|
3517
3552
|
const results = [];
|
|
3518
|
-
const files =
|
|
3553
|
+
const files = readdirSync9(historyDir).filter((f) => f.endsWith(".log"));
|
|
3519
3554
|
files.sort().reverse();
|
|
3520
3555
|
for (const file of files) {
|
|
3521
3556
|
if (results.length >= limit) break;
|
|
@@ -3537,7 +3572,7 @@ function getMaterializedDir(agentId) {
|
|
|
3537
3572
|
function listMaterialized(agentId) {
|
|
3538
3573
|
const dir = getMaterializedDir(agentId);
|
|
3539
3574
|
if (!existsSync13(dir)) return [];
|
|
3540
|
-
return
|
|
3575
|
+
return readdirSync9(dir).filter((f) => f.endsWith(".md")).map((f) => {
|
|
3541
3576
|
const match = f.match(/^(.+)-(\d+)\.md$/);
|
|
3542
3577
|
if (!match) return null;
|
|
3543
3578
|
return {
|
|
@@ -3882,8 +3917,8 @@ async function runHealthCheck(config2 = {
|
|
|
3882
3917
|
} catch {
|
|
3883
3918
|
}
|
|
3884
3919
|
if (existsSync15(AGENTS_DIR)) {
|
|
3885
|
-
const { readdirSync:
|
|
3886
|
-
const dirs =
|
|
3920
|
+
const { readdirSync: readdirSync20 } = await import("fs");
|
|
3921
|
+
const dirs = readdirSync20(AGENTS_DIR, { withFileTypes: true }).filter((d) => d.isDirectory() && d.name.startsWith("agent-")).map((d) => d.name);
|
|
3887
3922
|
for (const dir of dirs) {
|
|
3888
3923
|
if (!sessions.includes(dir)) {
|
|
3889
3924
|
sessions.push(dir);
|
|
@@ -4289,6 +4324,7 @@ Previous state: ${issue.state}`
|
|
|
4289
4324
|
|
|
4290
4325
|
// src/cli/commands/work/request-review.ts
|
|
4291
4326
|
init_esm_shims();
|
|
4327
|
+
init_config();
|
|
4292
4328
|
import chalk22 from "chalk";
|
|
4293
4329
|
var DASHBOARD_URL = getDashboardApiUrl();
|
|
4294
4330
|
async function requestReviewCommand(id, options) {
|
|
@@ -5069,7 +5105,7 @@ init_esm_shims();
|
|
|
5069
5105
|
init_paths();
|
|
5070
5106
|
import {
|
|
5071
5107
|
existsSync as existsSync20,
|
|
5072
|
-
readdirSync as
|
|
5108
|
+
readdirSync as readdirSync11,
|
|
5073
5109
|
lstatSync,
|
|
5074
5110
|
readlinkSync,
|
|
5075
5111
|
symlinkSync as symlinkSync2,
|
|
@@ -5108,12 +5144,12 @@ function mergeSkillsIntoWorkspace(workspacePath) {
|
|
|
5108
5144
|
mkdirSync11(skillsTarget, { recursive: true });
|
|
5109
5145
|
const existingSkills = /* @__PURE__ */ new Set();
|
|
5110
5146
|
if (existsSync20(skillsTarget)) {
|
|
5111
|
-
for (const item of
|
|
5147
|
+
for (const item of readdirSync11(skillsTarget)) {
|
|
5112
5148
|
existingSkills.add(item);
|
|
5113
5149
|
}
|
|
5114
5150
|
}
|
|
5115
5151
|
if (!existsSync20(SKILLS_DIR)) return { added, skipped };
|
|
5116
|
-
const panopticonSkills =
|
|
5152
|
+
const panopticonSkills = readdirSync11(SKILLS_DIR, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name);
|
|
5117
5153
|
for (const skill of panopticonSkills) {
|
|
5118
5154
|
const targetPath = join19(skillsTarget, skill);
|
|
5119
5155
|
const sourcePath = join19(SKILLS_DIR, skill);
|
|
@@ -5216,7 +5252,7 @@ init_projects();
|
|
|
5216
5252
|
|
|
5217
5253
|
// src/lib/workspace-manager.ts
|
|
5218
5254
|
init_esm_shims();
|
|
5219
|
-
import { existsSync as existsSync21, mkdirSync as mkdirSync12, writeFileSync as writeFileSync10, readFileSync as readFileSync19, readdirSync as
|
|
5255
|
+
import { existsSync as existsSync21, mkdirSync as mkdirSync12, writeFileSync as writeFileSync10, readFileSync as readFileSync19, readdirSync as readdirSync12, copyFileSync, symlinkSync as symlinkSync3, chmodSync, realpathSync } from "fs";
|
|
5220
5256
|
import { join as join20, dirname as dirname8, basename as basename2 } from "path";
|
|
5221
5257
|
import { homedir as homedir11 } from "os";
|
|
5222
5258
|
import { exec as exec4 } from "child_process";
|
|
@@ -5355,7 +5391,7 @@ function processTemplates(templateDir, targetDir, placeholders, templates) {
|
|
|
5355
5391
|
}
|
|
5356
5392
|
}
|
|
5357
5393
|
} else {
|
|
5358
|
-
const files =
|
|
5394
|
+
const files = readdirSync12(templateDir);
|
|
5359
5395
|
for (const file of files) {
|
|
5360
5396
|
if (file.endsWith(".template")) {
|
|
5361
5397
|
const sourcePath = join20(templateDir, file);
|
|
@@ -5449,7 +5485,7 @@ async function createWorkspace(options) {
|
|
|
5449
5485
|
}
|
|
5450
5486
|
const devcontainerDir = join20(workspacePath, ".devcontainer");
|
|
5451
5487
|
if (existsSync21(devcontainerDir)) {
|
|
5452
|
-
const composeFiles =
|
|
5488
|
+
const composeFiles = readdirSync12(devcontainerDir).filter((f) => f.includes("compose") && (f.endsWith(".yml") || f.endsWith(".yaml")));
|
|
5453
5489
|
for (const composeFile of composeFiles) {
|
|
5454
5490
|
sanitizeComposeFile(join20(devcontainerDir, composeFile));
|
|
5455
5491
|
}
|
|
@@ -5510,7 +5546,7 @@ async function createWorkspace(options) {
|
|
|
5510
5546
|
const templateSteps = processTemplates(templateDir, devcontainerDir2, placeholders);
|
|
5511
5547
|
result.steps.push(...templateSteps);
|
|
5512
5548
|
if (existsSync21(templateDir)) {
|
|
5513
|
-
const files =
|
|
5549
|
+
const files = readdirSync12(templateDir);
|
|
5514
5550
|
for (const file of files) {
|
|
5515
5551
|
if (!file.endsWith(".template")) {
|
|
5516
5552
|
const sourcePath = join20(templateDir, file);
|
|
@@ -5519,7 +5555,7 @@ async function createWorkspace(options) {
|
|
|
5519
5555
|
}
|
|
5520
5556
|
}
|
|
5521
5557
|
}
|
|
5522
|
-
const composeFiles =
|
|
5558
|
+
const composeFiles = readdirSync12(devcontainerDir2).filter((f) => f.includes("compose") && (f.endsWith(".yml") || f.endsWith(".yaml")));
|
|
5523
5559
|
for (const composeFile of composeFiles) {
|
|
5524
5560
|
sanitizeComposeFile(join20(devcontainerDir2, composeFile));
|
|
5525
5561
|
}
|
|
@@ -5691,6 +5727,7 @@ async function removeWorkspace(options) {
|
|
|
5691
5727
|
}
|
|
5692
5728
|
|
|
5693
5729
|
// src/cli/commands/workspace.ts
|
|
5730
|
+
init_config();
|
|
5694
5731
|
import { exec as exec5 } from "child_process";
|
|
5695
5732
|
import { promisify as promisify5 } from "util";
|
|
5696
5733
|
import { homedir as homedir12 } from "os";
|
|
@@ -6982,11 +7019,12 @@ ${config2.name || key}`));
|
|
|
6982
7019
|
// src/cli/commands/install.ts
|
|
6983
7020
|
init_esm_shims();
|
|
6984
7021
|
init_paths();
|
|
7022
|
+
init_config();
|
|
6985
7023
|
import chalk30 from "chalk";
|
|
6986
7024
|
import ora17 from "ora";
|
|
6987
7025
|
import inquirer5 from "inquirer";
|
|
6988
7026
|
import { execSync as execSync5 } from "child_process";
|
|
6989
|
-
import { existsSync as existsSync24, mkdirSync as mkdirSync15, writeFileSync as writeFileSync13, readFileSync as readFileSync21, copyFileSync as copyFileSync2, readdirSync as
|
|
7027
|
+
import { existsSync as existsSync24, mkdirSync as mkdirSync15, writeFileSync as writeFileSync13, readFileSync as readFileSync21, copyFileSync as copyFileSync2, readdirSync as readdirSync13, statSync as statSync2 } from "fs";
|
|
6990
7028
|
import { join as join23 } from "path";
|
|
6991
7029
|
import { homedir as homedir14 } from "os";
|
|
6992
7030
|
function registerInstallCommand(program2) {
|
|
@@ -6997,7 +7035,7 @@ function copyDirectoryRecursive(source, dest) {
|
|
|
6997
7035
|
throw new Error(`Source directory not found: ${source}`);
|
|
6998
7036
|
}
|
|
6999
7037
|
mkdirSync15(dest, { recursive: true });
|
|
7000
|
-
const entries =
|
|
7038
|
+
const entries = readdirSync13(source);
|
|
7001
7039
|
for (const entry of entries) {
|
|
7002
7040
|
const sourcePath = join23(source, entry);
|
|
7003
7041
|
const destPath = join23(dest, entry);
|
|
@@ -7135,7 +7173,7 @@ async function installCommand(options) {
|
|
|
7135
7173
|
if (existsSync24(SOURCE_SKILLS_DIR)) {
|
|
7136
7174
|
spinner.start("Installing bundled skills...");
|
|
7137
7175
|
try {
|
|
7138
|
-
const skillDirs =
|
|
7176
|
+
const skillDirs = readdirSync13(SOURCE_SKILLS_DIR, { withFileTypes: true }).filter((d) => d.isDirectory());
|
|
7139
7177
|
let installed = 0;
|
|
7140
7178
|
let skipped = 0;
|
|
7141
7179
|
for (const skillDir of skillDirs) {
|
|
@@ -7445,11 +7483,11 @@ import chalk31 from "chalk";
|
|
|
7445
7483
|
|
|
7446
7484
|
// src/lib/cloister/service.ts
|
|
7447
7485
|
init_esm_shims();
|
|
7448
|
-
|
|
7486
|
+
init_config2();
|
|
7449
7487
|
|
|
7450
7488
|
// src/lib/cloister/health.ts
|
|
7451
7489
|
init_esm_shims();
|
|
7452
|
-
|
|
7490
|
+
init_config2();
|
|
7453
7491
|
function evaluateHealthState(timeSinceActivityMs, thresholds) {
|
|
7454
7492
|
if (timeSinceActivityMs < thresholds.stale) {
|
|
7455
7493
|
return "active";
|
|
@@ -7838,11 +7876,11 @@ var ClaudeCodeRuntime = class {
|
|
|
7838
7876
|
/**
|
|
7839
7877
|
* Send a message to a running agent
|
|
7840
7878
|
*/
|
|
7841
|
-
sendMessage(agentId, message) {
|
|
7879
|
+
async sendMessage(agentId, message) {
|
|
7842
7880
|
if (!sessionExists(agentId)) {
|
|
7843
7881
|
throw new Error(`Agent ${agentId} is not running`);
|
|
7844
7882
|
}
|
|
7845
|
-
|
|
7883
|
+
await sendKeysAsync(agentId, message);
|
|
7846
7884
|
const mailDir = join25(getAgentDir(agentId), "mail");
|
|
7847
7885
|
mkdirSync17(mailDir, { recursive: true });
|
|
7848
7886
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
@@ -8018,7 +8056,7 @@ init_agents();
|
|
|
8018
8056
|
|
|
8019
8057
|
// src/lib/cloister/triggers.ts
|
|
8020
8058
|
init_esm_shims();
|
|
8021
|
-
|
|
8059
|
+
init_config2();
|
|
8022
8060
|
import { existsSync as existsSync27 } from "fs";
|
|
8023
8061
|
import { join as join26 } from "path";
|
|
8024
8062
|
import { exec as exec7 } from "child_process";
|
|
@@ -8766,7 +8804,7 @@ function clearOldViolations(hoursOld = 24) {
|
|
|
8766
8804
|
// src/lib/cloister/cost-monitor.ts
|
|
8767
8805
|
init_esm_shims();
|
|
8768
8806
|
init_paths();
|
|
8769
|
-
|
|
8807
|
+
init_config2();
|
|
8770
8808
|
import { readFileSync as readFileSync26, existsSync as existsSync32, writeFileSync as writeFileSync18, mkdirSync as mkdirSync21, unlinkSync as unlinkSync3 } from "fs";
|
|
8771
8809
|
import { join as join31, dirname as dirname10 } from "path";
|
|
8772
8810
|
var COST_DATA_FILE = join31(PANOPTICON_HOME, "cost-data.json");
|
|
@@ -9119,17 +9157,32 @@ async function checkAndRotateIfNeeded(specialistName, workingDir) {
|
|
|
9119
9157
|
// src/lib/cloister/deacon.ts
|
|
9120
9158
|
init_esm_shims();
|
|
9121
9159
|
init_paths();
|
|
9122
|
-
|
|
9160
|
+
init_config2();
|
|
9123
9161
|
init_specialists();
|
|
9124
9162
|
init_agents();
|
|
9125
9163
|
init_tmux();
|
|
9126
|
-
import { readFileSync as readFileSync28, writeFileSync as writeFileSync20, existsSync as existsSync34, mkdirSync as mkdirSync22, readdirSync as
|
|
9164
|
+
import { readFileSync as readFileSync28, writeFileSync as writeFileSync20, existsSync as existsSync34, mkdirSync as mkdirSync22, readdirSync as readdirSync15, statSync as statSync4, rmSync as rmSync3 } from "fs";
|
|
9127
9165
|
import { join as join33 } from "path";
|
|
9128
9166
|
import { exec as exec9 } from "child_process";
|
|
9129
9167
|
import { promisify as promisify9 } from "util";
|
|
9130
9168
|
import { homedir as homedir16 } from "os";
|
|
9131
9169
|
var execAsync9 = promisify9(exec9);
|
|
9132
9170
|
var REVIEW_STATUS_FILE = join33(homedir16(), ".panopticon", "review-status.json");
|
|
9171
|
+
function updateTestStatusToTesting(issueId) {
|
|
9172
|
+
try {
|
|
9173
|
+
if (!existsSync34(REVIEW_STATUS_FILE)) return;
|
|
9174
|
+
const data = JSON.parse(readFileSync28(REVIEW_STATUS_FILE, "utf-8"));
|
|
9175
|
+
const upper = issueId.toUpperCase();
|
|
9176
|
+
if (data[upper]) {
|
|
9177
|
+
data[upper].testStatus = "testing";
|
|
9178
|
+
data[upper].updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
9179
|
+
writeFileSync20(REVIEW_STATUS_FILE, JSON.stringify(data, null, 2), "utf-8");
|
|
9180
|
+
console.log(`[deacon] Updated testStatus to 'testing' for ${upper}`);
|
|
9181
|
+
}
|
|
9182
|
+
} catch (error) {
|
|
9183
|
+
console.error(`[deacon] Failed to update testStatus for ${issueId}:`, error);
|
|
9184
|
+
}
|
|
9185
|
+
}
|
|
9133
9186
|
var DEFAULT_CONFIG = {
|
|
9134
9187
|
pingTimeoutMs: 3e4,
|
|
9135
9188
|
// How long to wait for response
|
|
@@ -9238,12 +9291,13 @@ function checkHeartbeat(name) {
|
|
|
9238
9291
|
return { isResponsive: false };
|
|
9239
9292
|
}
|
|
9240
9293
|
}
|
|
9241
|
-
function checkSpecialistHealth(name) {
|
|
9242
|
-
const state = loadState();
|
|
9294
|
+
async function checkSpecialistHealth(name, sharedState) {
|
|
9295
|
+
const state = sharedState ?? loadState();
|
|
9243
9296
|
const healthState = getSpecialistState(state, name);
|
|
9244
|
-
const wasRunning = isRunning(name);
|
|
9297
|
+
const wasRunning = await isRunning(name);
|
|
9245
9298
|
healthState.lastPingTime = (/* @__PURE__ */ new Date()).toISOString();
|
|
9246
9299
|
if (!wasRunning) {
|
|
9300
|
+
if (!sharedState) saveState(state);
|
|
9247
9301
|
return {
|
|
9248
9302
|
specialistName: name,
|
|
9249
9303
|
isResponsive: false,
|
|
@@ -9260,7 +9314,7 @@ function checkSpecialistHealth(name) {
|
|
|
9260
9314
|
if (heartbeatResult.isResponsive) {
|
|
9261
9315
|
healthState.consecutiveFailures = 0;
|
|
9262
9316
|
healthState.lastResponseTime = (/* @__PURE__ */ new Date()).toISOString();
|
|
9263
|
-
saveState(state);
|
|
9317
|
+
if (!sharedState) saveState(state);
|
|
9264
9318
|
return {
|
|
9265
9319
|
specialistName: name,
|
|
9266
9320
|
isResponsive: true,
|
|
@@ -9272,7 +9326,7 @@ function checkSpecialistHealth(name) {
|
|
|
9272
9326
|
};
|
|
9273
9327
|
}
|
|
9274
9328
|
healthState.consecutiveFailures++;
|
|
9275
|
-
saveState(state);
|
|
9329
|
+
if (!sharedState) saveState(state);
|
|
9276
9330
|
const shouldForceKill = healthState.consecutiveFailures >= config.consecutiveFailures && !isInCooldown(healthState);
|
|
9277
9331
|
return {
|
|
9278
9332
|
specialistName: name,
|
|
@@ -9284,9 +9338,9 @@ function checkSpecialistHealth(name) {
|
|
|
9284
9338
|
cooldownRemainingMs: getCooldownRemaining(healthState)
|
|
9285
9339
|
};
|
|
9286
9340
|
}
|
|
9287
|
-
async function forceKillSpecialist(name) {
|
|
9341
|
+
async function forceKillSpecialist(name, sharedState) {
|
|
9288
9342
|
const tmuxSession = getTmuxSessionName(name);
|
|
9289
|
-
const state = loadState();
|
|
9343
|
+
const state = sharedState ?? loadState();
|
|
9290
9344
|
const healthState = getSpecialistState(state, name);
|
|
9291
9345
|
if (isInCooldown(healthState)) {
|
|
9292
9346
|
const remaining = getCooldownRemaining(healthState);
|
|
@@ -9305,7 +9359,7 @@ async function forceKillSpecialist(name) {
|
|
|
9305
9359
|
state.recentDeaths = state.recentDeaths.filter(
|
|
9306
9360
|
(d) => new Date(d).getTime() > windowStart
|
|
9307
9361
|
);
|
|
9308
|
-
saveState(state);
|
|
9362
|
+
if (!sharedState) saveState(state);
|
|
9309
9363
|
console.log(`[deacon] Force-killed specialist ${name}`);
|
|
9310
9364
|
return {
|
|
9311
9365
|
success: true,
|
|
@@ -9319,19 +9373,19 @@ async function forceKillSpecialist(name) {
|
|
|
9319
9373
|
};
|
|
9320
9374
|
}
|
|
9321
9375
|
}
|
|
9322
|
-
function checkMassDeath() {
|
|
9323
|
-
const state = loadState();
|
|
9376
|
+
function checkMassDeath(sharedState) {
|
|
9377
|
+
const state = sharedState ?? loadState();
|
|
9324
9378
|
const windowStart = Date.now() - config.massDeathWindowMs;
|
|
9325
9379
|
state.recentDeaths = state.recentDeaths.filter(
|
|
9326
9380
|
(d) => new Date(d).getTime() > windowStart
|
|
9327
9381
|
);
|
|
9328
|
-
saveState(state);
|
|
9329
9382
|
const deathCount = state.recentDeaths.length;
|
|
9330
9383
|
if (deathCount >= config.massDeathThreshold) {
|
|
9331
9384
|
if (state.lastMassDeathAlert) {
|
|
9332
9385
|
const lastAlert = new Date(state.lastMassDeathAlert).getTime();
|
|
9333
9386
|
const alertCooldown = 5 * 6e4;
|
|
9334
9387
|
if (Date.now() - lastAlert < alertCooldown) {
|
|
9388
|
+
if (!sharedState) saveState(state);
|
|
9335
9389
|
return {
|
|
9336
9390
|
isMassDeath: true,
|
|
9337
9391
|
deathCount,
|
|
@@ -9340,13 +9394,14 @@ function checkMassDeath() {
|
|
|
9340
9394
|
}
|
|
9341
9395
|
}
|
|
9342
9396
|
state.lastMassDeathAlert = (/* @__PURE__ */ new Date()).toISOString();
|
|
9343
|
-
saveState(state);
|
|
9397
|
+
if (!sharedState) saveState(state);
|
|
9344
9398
|
return {
|
|
9345
9399
|
isMassDeath: true,
|
|
9346
9400
|
deathCount,
|
|
9347
9401
|
message: `ALERT: ${deathCount} specialist deaths in ${config.massDeathWindowMs / 1e3}s - possible infrastructure issue`
|
|
9348
9402
|
};
|
|
9349
9403
|
}
|
|
9404
|
+
if (!sharedState) saveState(state);
|
|
9350
9405
|
return {
|
|
9351
9406
|
isMassDeath: false,
|
|
9352
9407
|
deathCount
|
|
@@ -9384,14 +9439,11 @@ async function checkAndSuspendIdleAgents() {
|
|
|
9384
9439
|
const idleMs = Date.now() - lastActivity.getTime();
|
|
9385
9440
|
const idleMinutes = idleMs / (1e3 * 60);
|
|
9386
9441
|
const isSpecialist = specialistNames.has(agent.id);
|
|
9387
|
-
const timeoutMinutes = isSpecialist ? 5 : 10;
|
|
9388
9442
|
const isWorkAgent = agent.id.startsWith("agent-") && !isSpecialist;
|
|
9389
9443
|
if (isWorkAgent) {
|
|
9390
|
-
|
|
9391
|
-
if (existsSync34(completedFile)) {
|
|
9392
|
-
continue;
|
|
9393
|
-
}
|
|
9444
|
+
continue;
|
|
9394
9445
|
}
|
|
9446
|
+
const timeoutMinutes = 5;
|
|
9395
9447
|
if (idleMinutes > timeoutMinutes) {
|
|
9396
9448
|
console.log(`[deacon] Auto-suspending ${agent.id} (idle for ${Math.round(idleMinutes)} minutes)`);
|
|
9397
9449
|
try {
|
|
@@ -9574,7 +9626,7 @@ async function cleanupStaleAgentState() {
|
|
|
9574
9626
|
return actions;
|
|
9575
9627
|
}
|
|
9576
9628
|
try {
|
|
9577
|
-
const dirs =
|
|
9629
|
+
const dirs = readdirSync15(AGENTS_DIR, { withFileTypes: true }).filter((d) => d.isDirectory());
|
|
9578
9630
|
for (const dir of dirs) {
|
|
9579
9631
|
const agentDir = join33(AGENTS_DIR, dir.name);
|
|
9580
9632
|
try {
|
|
@@ -9637,13 +9689,19 @@ async function checkOrphanedReviewStatuses() {
|
|
|
9637
9689
|
const testAgentActive = testAgentRunning && testAgentState?.state === "active";
|
|
9638
9690
|
let modified = false;
|
|
9639
9691
|
for (const [issueId, status] of Object.entries(statuses)) {
|
|
9640
|
-
|
|
9692
|
+
const hasPassedReview = status.history?.some(
|
|
9693
|
+
(h) => h.type === "review" && h.status === "passed"
|
|
9694
|
+
);
|
|
9695
|
+
const hasPassedTest = status.history?.some(
|
|
9696
|
+
(h) => h.type === "test" && (h.status === "passed" || h.status === "failed")
|
|
9697
|
+
);
|
|
9698
|
+
if (status.reviewStatus === "reviewing" && !reviewAgentActive && !hasPassedReview) {
|
|
9641
9699
|
console.log(`[deacon] Orphaned review detected: ${issueId} shows 'reviewing' but review-agent is not active`);
|
|
9642
9700
|
status.reviewStatus = "pending";
|
|
9643
9701
|
modified = true;
|
|
9644
9702
|
actions.push(`Reset orphaned review for ${issueId} (review-agent not active)`);
|
|
9645
9703
|
}
|
|
9646
|
-
if (status.testStatus === "testing" && !testAgentActive) {
|
|
9704
|
+
if (status.testStatus === "testing" && !testAgentActive && !hasPassedTest && !status.readyForMerge) {
|
|
9647
9705
|
console.log(`[deacon] Orphaned test detected: ${issueId} shows 'testing' but test-agent is not active`);
|
|
9648
9706
|
status.testStatus = "pending";
|
|
9649
9707
|
modified = true;
|
|
@@ -9668,11 +9726,11 @@ async function runPatrol() {
|
|
|
9668
9726
|
const actions = [];
|
|
9669
9727
|
console.log(`[deacon] Patrol cycle ${state.patrolCycle} - checking ${enabled.length} specialists`);
|
|
9670
9728
|
for (const specialist of enabled) {
|
|
9671
|
-
const result = checkSpecialistHealth(specialist.name);
|
|
9729
|
+
const result = await checkSpecialistHealth(specialist.name, state);
|
|
9672
9730
|
results.push(result);
|
|
9673
9731
|
if (result.shouldForceKill) {
|
|
9674
9732
|
console.log(`[deacon] ${specialist.name} stuck (${result.consecutiveFailures} failures), force-killing`);
|
|
9675
|
-
const killResult = await forceKillSpecialist(specialist.name);
|
|
9733
|
+
const killResult = await forceKillSpecialist(specialist.name, state);
|
|
9676
9734
|
actions.push(`Force-killed ${specialist.name}: ${killResult.message}`);
|
|
9677
9735
|
if (killResult.success) {
|
|
9678
9736
|
console.log(`[deacon] Auto-restarting ${specialist.name}...`);
|
|
@@ -9700,7 +9758,7 @@ async function runPatrol() {
|
|
|
9700
9758
|
if (nextTask) {
|
|
9701
9759
|
console.log(`[deacon] Auto-resuming suspended ${specialist.name} for queued task: ${nextTask.payload.issueId}`);
|
|
9702
9760
|
try {
|
|
9703
|
-
const { resumeAgent } = await import("../agents-
|
|
9761
|
+
const { resumeAgent } = await import("../agents-GQDAKTEQ.js");
|
|
9704
9762
|
const message = `# Queued Work
|
|
9705
9763
|
|
|
9706
9764
|
Processing queued task: ${nextTask.payload.issueId}`;
|
|
@@ -9731,6 +9789,9 @@ Processing queued task: ${nextTask.payload.issueId}`;
|
|
|
9731
9789
|
const wakeResult = await wakeSpecialistWithTask(specialist.name, taskDetails);
|
|
9732
9790
|
if (wakeResult.success) {
|
|
9733
9791
|
completeSpecialistTask(specialist.name, nextTask.id);
|
|
9792
|
+
if (specialist.name === "test-agent" && nextTask.payload.issueId) {
|
|
9793
|
+
updateTestStatusToTesting(nextTask.payload.issueId);
|
|
9794
|
+
}
|
|
9734
9795
|
actions.push(`Processed queued task for ${specialist.name}: ${nextTask.payload.issueId}`);
|
|
9735
9796
|
} else {
|
|
9736
9797
|
console.error(`[deacon] Failed to wake ${specialist.name} for queued task: ${wakeResult.error}`);
|
|
@@ -9752,12 +9813,12 @@ Processing queued task: ${nextTask.payload.issueId}`;
|
|
|
9752
9813
|
const cleanupActions = await cleanupStaleAgentState();
|
|
9753
9814
|
actions.push(...cleanupActions);
|
|
9754
9815
|
}
|
|
9755
|
-
|
|
9756
|
-
const massDeathCheck = checkMassDeath();
|
|
9816
|
+
const massDeathCheck = checkMassDeath(state);
|
|
9757
9817
|
if (massDeathCheck.isMassDeath && massDeathCheck.message) {
|
|
9758
9818
|
console.error(`[deacon] ${massDeathCheck.message}`);
|
|
9759
9819
|
actions.push(massDeathCheck.message);
|
|
9760
9820
|
}
|
|
9821
|
+
saveState(state);
|
|
9761
9822
|
return {
|
|
9762
9823
|
cycle: state.patrolCycle,
|
|
9763
9824
|
timestamp: state.lastPatrol,
|
|
@@ -9799,7 +9860,7 @@ function getDeaconStatus() {
|
|
|
9799
9860
|
// src/lib/cloister/service.ts
|
|
9800
9861
|
init_paths();
|
|
9801
9862
|
init_paths();
|
|
9802
|
-
import { existsSync as existsSync35, writeFileSync as writeFileSync21, unlinkSync as unlinkSync4, readFileSync as readFileSync29, readdirSync as
|
|
9863
|
+
import { existsSync as existsSync35, writeFileSync as writeFileSync21, unlinkSync as unlinkSync4, readFileSync as readFileSync29, readdirSync as readdirSync16, renameSync } from "fs";
|
|
9803
9864
|
import { join as join34 } from "path";
|
|
9804
9865
|
var CLOISTER_STATE_FILE = join34(PANOPTICON_HOME, "cloister.state");
|
|
9805
9866
|
function writeStateFile(running, pid) {
|
|
@@ -10041,7 +10102,7 @@ var CloisterService = class {
|
|
|
10041
10102
|
async checkCompletionMarkers() {
|
|
10042
10103
|
try {
|
|
10043
10104
|
if (!existsSync35(AGENTS_DIR)) return;
|
|
10044
|
-
const agentDirs =
|
|
10105
|
+
const agentDirs = readdirSync16(AGENTS_DIR, { withFileTypes: true }).filter((d) => d.isDirectory() && d.name.startsWith("agent-"));
|
|
10045
10106
|
for (const dir of agentDirs) {
|
|
10046
10107
|
const completedFile = join34(AGENTS_DIR, dir.name, "completed");
|
|
10047
10108
|
const processedFile = join34(AGENTS_DIR, dir.name, "completed.processed");
|
|
@@ -11522,7 +11583,7 @@ import { promisify as promisify12 } from "util";
|
|
|
11522
11583
|
var execAsync12 = promisify12(exec12);
|
|
11523
11584
|
async function listLogsCommand(project2, type, options) {
|
|
11524
11585
|
try {
|
|
11525
|
-
const { listRunLogs } = await import("../specialist-logs-
|
|
11586
|
+
const { listRunLogs } = await import("../specialist-logs-EXLOQHQ2.js");
|
|
11526
11587
|
const limit = options.limit ? parseInt(options.limit) : 10;
|
|
11527
11588
|
const runs = listRunLogs(project2, type, { limit });
|
|
11528
11589
|
if (options.json) {
|
|
@@ -11567,7 +11628,7 @@ View a specific run: pan specialists logs ${project2} ${type} <runId>
|
|
|
11567
11628
|
}
|
|
11568
11629
|
async function viewLogCommand(project2, type, runId, options) {
|
|
11569
11630
|
try {
|
|
11570
|
-
const { getRunLog, parseLogMetadata, getRunLogPath } = await import("../specialist-logs-
|
|
11631
|
+
const { getRunLog, parseLogMetadata, getRunLogPath } = await import("../specialist-logs-EXLOQHQ2.js");
|
|
11571
11632
|
const content = getRunLog(project2, type, runId);
|
|
11572
11633
|
if (!content) {
|
|
11573
11634
|
console.error(`\u274C Run log not found: ${runId}`);
|
|
@@ -11591,8 +11652,8 @@ async function viewLogCommand(project2, type, runId, options) {
|
|
|
11591
11652
|
}
|
|
11592
11653
|
async function tailLogCommand(project2, type) {
|
|
11593
11654
|
try {
|
|
11594
|
-
const { getRunLogPath } = await import("../specialist-logs-
|
|
11595
|
-
const { getProjectSpecialistMetadata } = await import("../specialists-
|
|
11655
|
+
const { getRunLogPath } = await import("../specialist-logs-EXLOQHQ2.js");
|
|
11656
|
+
const { getProjectSpecialistMetadata } = await import("../specialists-BRUHPAXE.js");
|
|
11596
11657
|
const metadata = getProjectSpecialistMetadata(project2, type);
|
|
11597
11658
|
if (!metadata.currentRun) {
|
|
11598
11659
|
console.error(`\u274C No active run for ${project2}/${type}`);
|
|
@@ -11661,7 +11722,7 @@ async function cleanupLogsCommand(projectOrAll, type, options) {
|
|
|
11661
11722
|
console.log(" Use --force to confirm.");
|
|
11662
11723
|
process.exit(1);
|
|
11663
11724
|
}
|
|
11664
|
-
const { cleanupAllLogs } = await import("../specialist-logs-
|
|
11725
|
+
const { cleanupAllLogs } = await import("../specialist-logs-EXLOQHQ2.js");
|
|
11665
11726
|
console.log("\u{1F9F9} Cleaning up old logs for all projects...\n");
|
|
11666
11727
|
const results = cleanupAllLogs();
|
|
11667
11728
|
console.log(`
|
|
@@ -11688,7 +11749,7 @@ async function cleanupLogsCommand(projectOrAll, type, options) {
|
|
|
11688
11749
|
console.log(" Use --force to confirm.");
|
|
11689
11750
|
process.exit(1);
|
|
11690
11751
|
}
|
|
11691
|
-
const { cleanupOldLogs } = await import("../specialist-logs-
|
|
11752
|
+
const { cleanupOldLogs } = await import("../specialist-logs-EXLOQHQ2.js");
|
|
11692
11753
|
const { getSpecialistRetention } = await import("../projects-VXRUCMLM.js");
|
|
11693
11754
|
const retention = getSpecialistRetention(projectOrAll);
|
|
11694
11755
|
console.log(`\u{1F9F9} Cleaning up old logs for ${projectOrAll}/${type}...`);
|
|
@@ -11727,7 +11788,7 @@ import ora18 from "ora";
|
|
|
11727
11788
|
// src/lib/convoy.ts
|
|
11728
11789
|
init_esm_shims();
|
|
11729
11790
|
init_tmux();
|
|
11730
|
-
import { existsSync as existsSync41, mkdirSync as mkdirSync25, writeFileSync as writeFileSync26, readFileSync as readFileSync34, readdirSync as
|
|
11791
|
+
import { existsSync as existsSync41, mkdirSync as mkdirSync25, writeFileSync as writeFileSync26, readFileSync as readFileSync34, readdirSync as readdirSync17 } from "fs";
|
|
11731
11792
|
import { join as join39 } from "path";
|
|
11732
11793
|
import { homedir as homedir19 } from "os";
|
|
11733
11794
|
import { exec as exec13 } from "child_process";
|
|
@@ -11885,7 +11946,7 @@ function listConvoys(filter) {
|
|
|
11885
11946
|
if (!existsSync41(CONVOY_DIR)) {
|
|
11886
11947
|
return [];
|
|
11887
11948
|
}
|
|
11888
|
-
const files =
|
|
11949
|
+
const files = readdirSync17(CONVOY_DIR).filter((f) => f.endsWith(".json"));
|
|
11889
11950
|
const convoys = [];
|
|
11890
11951
|
for (const file of files) {
|
|
11891
11952
|
const convoyId = file.replace(".json", "");
|
|
@@ -12352,7 +12413,7 @@ function registerConvoyCommands(program2) {
|
|
|
12352
12413
|
init_esm_shims();
|
|
12353
12414
|
init_projects();
|
|
12354
12415
|
import chalk45 from "chalk";
|
|
12355
|
-
import { existsSync as existsSync42, readFileSync as readFileSync35, symlinkSync as symlinkSync4, mkdirSync as mkdirSync26, readdirSync as
|
|
12416
|
+
import { existsSync as existsSync42, readFileSync as readFileSync35, symlinkSync as symlinkSync4, mkdirSync as mkdirSync26, readdirSync as readdirSync18, statSync as statSync6 } from "fs";
|
|
12356
12417
|
import { join as join40, resolve, dirname as dirname11 } from "path";
|
|
12357
12418
|
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
12358
12419
|
var __filename5 = fileURLToPath4(import.meta.url);
|
|
@@ -12368,7 +12429,7 @@ function installGitHooks(gitDir) {
|
|
|
12368
12429
|
return 0;
|
|
12369
12430
|
}
|
|
12370
12431
|
try {
|
|
12371
|
-
const hooks =
|
|
12432
|
+
const hooks = readdirSync18(BUNDLED_HOOKS_DIR).filter((f) => {
|
|
12372
12433
|
const p = join40(BUNDLED_HOOKS_DIR, f);
|
|
12373
12434
|
return existsSync42(p) && statSync6(p).isFile();
|
|
12374
12435
|
});
|
|
@@ -12446,9 +12507,9 @@ async function projectAddCommand(projectPath, options = {}) {
|
|
|
12446
12507
|
const hasRootGit = existsSync42(join40(fullPath, ".git"));
|
|
12447
12508
|
const subRepos = [];
|
|
12448
12509
|
if (!hasRootGit) {
|
|
12449
|
-
const { readdirSync:
|
|
12510
|
+
const { readdirSync: readdirSync20, statSync: statSync8 } = await import("fs");
|
|
12450
12511
|
try {
|
|
12451
|
-
const entries =
|
|
12512
|
+
const entries = readdirSync20(fullPath);
|
|
12452
12513
|
for (const entry of entries) {
|
|
12453
12514
|
const entryPath = join40(fullPath, entry);
|
|
12454
12515
|
try {
|
|
@@ -12642,7 +12703,7 @@ Project: ${foundKey}
|
|
|
12642
12703
|
init_esm_shims();
|
|
12643
12704
|
init_paths();
|
|
12644
12705
|
import chalk46 from "chalk";
|
|
12645
|
-
import { existsSync as existsSync43, readdirSync as
|
|
12706
|
+
import { existsSync as existsSync43, readdirSync as readdirSync19, readFileSync as readFileSync36 } from "fs";
|
|
12646
12707
|
import { execSync as execSync8 } from "child_process";
|
|
12647
12708
|
import { homedir as homedir20 } from "os";
|
|
12648
12709
|
import { join as join41 } from "path";
|
|
@@ -12660,7 +12721,7 @@ function checkDirectory(path) {
|
|
|
12660
12721
|
function countItems(path) {
|
|
12661
12722
|
if (!existsSync43(path)) return 0;
|
|
12662
12723
|
try {
|
|
12663
|
-
return
|
|
12724
|
+
return readdirSync19(path).length;
|
|
12664
12725
|
} catch {
|
|
12665
12726
|
return 0;
|
|
12666
12727
|
}
|
|
@@ -12810,6 +12871,7 @@ async function doctorCommand() {
|
|
|
12810
12871
|
|
|
12811
12872
|
// src/cli/commands/update.ts
|
|
12812
12873
|
init_esm_shims();
|
|
12874
|
+
init_config();
|
|
12813
12875
|
import { execSync as execSync9 } from "child_process";
|
|
12814
12876
|
import chalk47 from "chalk";
|
|
12815
12877
|
import { readFileSync as readFileSync37 } from "fs";
|
|
@@ -13810,6 +13872,7 @@ init_esm_shims();
|
|
|
13810
13872
|
|
|
13811
13873
|
// src/cli/commands/remote/status.ts
|
|
13812
13874
|
init_esm_shims();
|
|
13875
|
+
init_config();
|
|
13813
13876
|
import chalk51 from "chalk";
|
|
13814
13877
|
import ora23 from "ora";
|
|
13815
13878
|
async function statusCommand5(options) {
|
|
@@ -13889,6 +13952,7 @@ async function statusCommand5(options) {
|
|
|
13889
13952
|
|
|
13890
13953
|
// src/cli/commands/remote/init.ts
|
|
13891
13954
|
init_esm_shims();
|
|
13955
|
+
init_config();
|
|
13892
13956
|
import chalk52 from "chalk";
|
|
13893
13957
|
import ora24 from "ora";
|
|
13894
13958
|
async function initCommand2(options) {
|
|
@@ -14050,6 +14114,7 @@ COMPOSE_EOF`);
|
|
|
14050
14114
|
|
|
14051
14115
|
// src/cli/commands/remote/resources.ts
|
|
14052
14116
|
init_esm_shims();
|
|
14117
|
+
init_config();
|
|
14053
14118
|
import chalk53 from "chalk";
|
|
14054
14119
|
import ora25 from "ora";
|
|
14055
14120
|
async function resourcesCommand(options) {
|
|
@@ -14178,6 +14243,7 @@ async function resourcesCommand(options) {
|
|
|
14178
14243
|
|
|
14179
14244
|
// src/cli/commands/remote/setup.ts
|
|
14180
14245
|
init_esm_shims();
|
|
14246
|
+
init_config();
|
|
14181
14247
|
import chalk54 from "chalk";
|
|
14182
14248
|
import ora26 from "ora";
|
|
14183
14249
|
import { exec as exec16 } from "child_process";
|
|
@@ -14328,6 +14394,7 @@ function registerRemoteCommands(program2) {
|
|
|
14328
14394
|
|
|
14329
14395
|
// src/cli/commands/config.ts
|
|
14330
14396
|
init_esm_shims();
|
|
14397
|
+
init_config();
|
|
14331
14398
|
import chalk55 from "chalk";
|
|
14332
14399
|
|
|
14333
14400
|
// src/lib/env-loader.ts
|
|
@@ -14449,7 +14516,7 @@ if (existsSync48(PANOPTICON_ENV_FILE)) {
|
|
|
14449
14516
|
}
|
|
14450
14517
|
}
|
|
14451
14518
|
var program = new Command();
|
|
14452
|
-
program.name("pan").description("Multi-agent orchestration for AI coding assistants").version(
|
|
14519
|
+
program.name("pan").description("Multi-agent orchestration for AI coding assistants").version(JSON.parse(readFileSync42(join48(import.meta.dirname, "../../package.json"), "utf-8")).version);
|
|
14453
14520
|
program.command("init").description("Initialize Panopticon (~/.panopticon/)").action(initCommand);
|
|
14454
14521
|
program.command("sync").description("Sync skills/commands to AI tools").option("--dry-run", "Show what would be synced").option("--force", "Overwrite without prompts").option("--backup-only", "Only create backup").action(syncCommand);
|
|
14455
14522
|
program.command("restore [timestamp]").description("Restore from backup").action(restoreCommand);
|
|
@@ -14500,7 +14567,7 @@ program.command("up").description("Start dashboard (and Traefik if enabled)").op
|
|
|
14500
14567
|
console.log(chalk56.bold("Starting Panopticon...\n"));
|
|
14501
14568
|
if (traefikEnabled && !options.skipTraefik) {
|
|
14502
14569
|
try {
|
|
14503
|
-
const { generatePanopticonTraefikConfig: generatePanopticonTraefikConfig2 } = await import("../traefik-
|
|
14570
|
+
const { generatePanopticonTraefikConfig: generatePanopticonTraefikConfig2 } = await import("../traefik-CUJM6K5Z.js");
|
|
14504
14571
|
if (generatePanopticonTraefikConfig2()) {
|
|
14505
14572
|
console.log(chalk56.dim(" Regenerated Traefik config from template"));
|
|
14506
14573
|
}
|