panopticon-cli 0.4.32 → 0.4.33
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-BDFHF4T3.js → agents-VLK4BMVA.js} +10 -7
- package/dist/chunk-7SN4L4PH.js +150 -0
- package/dist/chunk-7SN4L4PH.js.map +1 -0
- package/dist/chunk-7XNJJBH6.js +538 -0
- package/dist/chunk-7XNJJBH6.js.map +1 -0
- package/dist/chunk-AQXETQHW.js +113 -0
- package/dist/chunk-AQXETQHW.js.map +1 -0
- package/dist/{chunk-2NIAOCIC.js → chunk-ASY7T35E.js} +170 -64
- package/dist/chunk-ASY7T35E.js.map +1 -0
- package/dist/chunk-B3PF6JPQ.js +212 -0
- package/dist/chunk-B3PF6JPQ.js.map +1 -0
- package/dist/{chunk-XP2DXWYP.js → chunk-BKCWRMUX.js} +88 -35
- package/dist/chunk-BKCWRMUX.js.map +1 -0
- package/dist/chunk-CFCUOV3Q.js +669 -0
- package/dist/chunk-CFCUOV3Q.js.map +1 -0
- package/dist/chunk-CWELWPWQ.js +32 -0
- package/dist/chunk-CWELWPWQ.js.map +1 -0
- package/dist/chunk-DI7ABPNQ.js +352 -0
- package/dist/chunk-DI7ABPNQ.js.map +1 -0
- package/dist/{chunk-VU4FLXV5.js → chunk-FQ66DECN.js} +31 -4
- package/dist/chunk-FQ66DECN.js.map +1 -0
- package/dist/{review-status-GWQYY77L.js → chunk-GFP3PIPB.js} +14 -7
- package/dist/chunk-GFP3PIPB.js.map +1 -0
- package/dist/chunk-JQBV3Q2W.js +29 -0
- package/dist/chunk-JQBV3Q2W.js.map +1 -0
- package/dist/{chunk-BWGFN44T.js → chunk-JT4O4YVM.js} +28 -16
- package/dist/chunk-JT4O4YVM.js.map +1 -0
- package/dist/{chunk-VIWUCJ4V.js → chunk-KJ2TRXNK.js} +34 -36
- package/dist/chunk-KJ2TRXNK.js.map +1 -0
- package/dist/{chunk-JY7R7V4G.js → chunk-OMNXYPXC.js} +2 -2
- package/dist/chunk-OMNXYPXC.js.map +1 -0
- package/dist/chunk-PELXV435.js +215 -0
- package/dist/chunk-PELXV435.js.map +1 -0
- package/dist/chunk-PI7Y3PSN.js +797 -0
- package/dist/chunk-PI7Y3PSN.js.map +1 -0
- package/dist/chunk-RBUO57TC.js +154 -0
- package/dist/chunk-RBUO57TC.js.map +1 -0
- package/dist/chunk-XFR2DLMR.js +600 -0
- package/dist/chunk-XFR2DLMR.js.map +1 -0
- package/dist/chunk-XKT5MHPT.js +677 -0
- package/dist/chunk-XKT5MHPT.js.map +1 -0
- package/dist/{chunk-HCTJFIJJ.js → chunk-YLPSQAM2.js} +2 -2
- package/dist/{chunk-HCTJFIJJ.js.map → chunk-YLPSQAM2.js.map} +1 -1
- package/dist/{chunk-6HXKTOD7.js → chunk-ZTFNYOC7.js} +53 -38
- package/dist/chunk-ZTFNYOC7.js.map +1 -0
- package/dist/cli/index.js +4362 -2927
- package/dist/cli/index.js.map +1 -1
- package/dist/{config-BOAMSKTF.js → config-4CJNUE3O.js} +7 -3
- package/dist/dashboard/prompts/merge-agent.md +217 -0
- package/dist/dashboard/prompts/review-agent.md +409 -0
- package/dist/dashboard/prompts/sync-main.md +84 -0
- package/dist/dashboard/prompts/test-agent.md +283 -0
- package/dist/dashboard/prompts/work-agent.md +247 -0
- package/dist/dashboard/public/assets/index-UjZq6ykz.css +32 -0
- package/dist/dashboard/public/assets/index-kAJqtLDO.js +708 -0
- package/dist/dashboard/public/index.html +2 -2
- package/dist/dashboard/server.js +15194 -3160
- package/dist/{dns-L3L2BB27.js → dns-7BDJSD3E.js} +4 -2
- package/dist/{feedback-writer-AAKF5BTK.js → feedback-writer-LVZ5TFYZ.js} +8 -4
- package/dist/feedback-writer-LVZ5TFYZ.js.map +1 -0
- package/dist/hume-WMAUBBV2.js +13 -0
- package/dist/index.d.ts +153 -40
- package/dist/index.js +65 -23
- package/dist/index.js.map +1 -1
- package/dist/{projects-VXRUCMLM.js → projects-JEIVIYC6.js} +3 -3
- package/dist/rally-RKFSWC7E.js +10 -0
- package/dist/{remote-agents-Z3R2A5BN.js → remote-agents-TFSMW7GN.js} +2 -2
- package/dist/{remote-workspace-2G6V2KNP.js → remote-workspace-AHVHQEES.js} +8 -8
- package/dist/review-status-EPFG4XM7.js +19 -0
- package/dist/shadow-state-5MDP6YXH.js +30 -0
- package/dist/shadow-state-5MDP6YXH.js.map +1 -0
- package/dist/{specialist-context-N32QBNNQ.js → specialist-context-T3NBMCIE.js} +8 -7
- package/dist/{specialist-context-N32QBNNQ.js.map → specialist-context-T3NBMCIE.js.map} +1 -1
- package/dist/{specialist-logs-GF3YV4KL.js → specialist-logs-CVKD3YJ3.js} +7 -6
- package/dist/specialist-logs-CVKD3YJ3.js.map +1 -0
- package/dist/{specialists-JBIW6MP4.js → specialists-TKAP6T6Z.js} +7 -6
- package/dist/specialists-TKAP6T6Z.js.map +1 -0
- package/dist/tldr-daemon-T3THOUGT.js +21 -0
- package/dist/tldr-daemon-T3THOUGT.js.map +1 -0
- package/dist/traefik-QX4ZV4YG.js +19 -0
- package/dist/traefik-QX4ZV4YG.js.map +1 -0
- package/dist/tunnel-W2GZBLEV.js +13 -0
- package/dist/tunnel-W2GZBLEV.js.map +1 -0
- package/dist/workspace-manager-KLHUCIZV.js +22 -0
- package/dist/workspace-manager-KLHUCIZV.js.map +1 -0
- package/package.json +2 -2
- package/scripts/heartbeat-hook +37 -10
- package/scripts/patches/llm-tldr-tsx-support.py +109 -0
- package/scripts/pre-tool-hook +26 -15
- package/scripts/record-cost-event.js +177 -43
- package/scripts/record-cost-event.ts +87 -3
- package/scripts/statusline.sh +169 -0
- package/scripts/stop-hook +14 -11
- package/scripts/tldr-post-edit +72 -0
- package/scripts/tldr-read-enforcer +275 -0
- package/skills/check-merged/SKILL.md +143 -0
- package/skills/crash-investigation/SKILL.md +301 -0
- package/skills/github-cli/SKILL.md +185 -0
- package/skills/pan-reopen/SKILL.md +65 -0
- package/skills/pan-sync-main/SKILL.md +87 -0
- package/skills/pan-tldr/SKILL.md +149 -0
- package/skills/react-best-practices/SKILL.md +125 -0
- package/skills/spec-readiness/REPORT-TEMPLATE.md +158 -0
- package/skills/spec-readiness/SCORING-REFERENCE.md +369 -0
- package/skills/spec-readiness/SKILL.md +400 -0
- package/skills/spec-readiness-setup/SKILL.md +361 -0
- package/skills/workspace-status/SKILL.md +56 -0
- package/templates/traefik/dynamic/panopticon.yml.template +0 -5
- package/templates/traefik/traefik.yml +0 -8
- package/dist/chunk-2NIAOCIC.js.map +0 -1
- package/dist/chunk-3XAB4IXF.js +0 -51
- package/dist/chunk-3XAB4IXF.js.map +0 -1
- package/dist/chunk-6HXKTOD7.js.map +0 -1
- package/dist/chunk-BBCUK6N2.js +0 -241
- package/dist/chunk-BBCUK6N2.js.map +0 -1
- package/dist/chunk-BWGFN44T.js.map +0 -1
- package/dist/chunk-ELK6Q7QI.js +0 -545
- package/dist/chunk-ELK6Q7QI.js.map +0 -1
- package/dist/chunk-JY7R7V4G.js.map +0 -1
- package/dist/chunk-LYSBSZYV.js +0 -1523
- package/dist/chunk-LYSBSZYV.js.map +0 -1
- package/dist/chunk-VIWUCJ4V.js.map +0 -1
- package/dist/chunk-VU4FLXV5.js.map +0 -1
- package/dist/chunk-XP2DXWYP.js.map +0 -1
- package/dist/dashboard/public/assets/index-C7X6LP5Z.css +0 -32
- package/dist/dashboard/public/assets/index-ClYqpcAJ.js +0 -645
- package/dist/feedback-writer-AAKF5BTK.js.map +0 -1
- package/dist/review-status-GWQYY77L.js.map +0 -1
- package/dist/traefik-CUJM6K5Z.js +0 -12
- /package/dist/{agents-BDFHF4T3.js.map → agents-VLK4BMVA.js.map} +0 -0
- /package/dist/{config-BOAMSKTF.js.map → config-4CJNUE3O.js.map} +0 -0
- /package/dist/{dns-L3L2BB27.js.map → dns-7BDJSD3E.js.map} +0 -0
- /package/dist/{projects-VXRUCMLM.js.map → hume-WMAUBBV2.js.map} +0 -0
- /package/dist/{remote-agents-Z3R2A5BN.js.map → projects-JEIVIYC6.js.map} +0 -0
- /package/dist/{specialist-logs-GF3YV4KL.js.map → rally-RKFSWC7E.js.map} +0 -0
- /package/dist/{specialists-JBIW6MP4.js.map → remote-agents-TFSMW7GN.js.map} +0 -0
- /package/dist/{remote-workspace-2G6V2KNP.js.map → remote-workspace-AHVHQEES.js.map} +0 -0
- /package/dist/{traefik-CUJM6K5Z.js.map → review-status-EPFG4XM7.js.map} +0 -0
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
import {
|
|
2
|
+
init_esm_shims
|
|
3
|
+
} from "./chunk-ZHC57RCV.js";
|
|
4
|
+
|
|
5
|
+
// src/lib/shadow-state.ts
|
|
6
|
+
init_esm_shims();
|
|
7
|
+
import { readFileSync, writeFileSync, existsSync, mkdirSync, readdirSync, unlinkSync } from "fs";
|
|
8
|
+
import { join } from "path";
|
|
9
|
+
import { homedir } from "os";
|
|
10
|
+
var SHADOW_STATE_DIR = join(homedir(), ".panopticon", "shadow-state");
|
|
11
|
+
function ensureShadowStateDir() {
|
|
12
|
+
if (!existsSync(SHADOW_STATE_DIR)) {
|
|
13
|
+
mkdirSync(SHADOW_STATE_DIR, { recursive: true });
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
function getShadowStatePath(issueId) {
|
|
17
|
+
const normalizedId = issueId.toUpperCase().replace(/[^A-Z0-9-]/g, "");
|
|
18
|
+
return join(SHADOW_STATE_DIR, `${normalizedId}.json`);
|
|
19
|
+
}
|
|
20
|
+
function getShadowState(issueId) {
|
|
21
|
+
const filePath = getShadowStatePath(issueId);
|
|
22
|
+
if (!existsSync(filePath)) {
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
try {
|
|
26
|
+
const content = readFileSync(filePath, "utf-8");
|
|
27
|
+
return JSON.parse(content);
|
|
28
|
+
} catch (error) {
|
|
29
|
+
console.error(`Error reading shadow state for ${issueId}:`, error);
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
function isShadowed(issueId) {
|
|
34
|
+
return getShadowState(issueId) !== null;
|
|
35
|
+
}
|
|
36
|
+
function createShadowState(issueId, initialTrackerStatus = "open", triggeredBy = "unknown") {
|
|
37
|
+
ensureShadowStateDir();
|
|
38
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
39
|
+
const shadowState = {
|
|
40
|
+
issueId: issueId.toUpperCase(),
|
|
41
|
+
shadowStatus: initialTrackerStatus,
|
|
42
|
+
trackerStatus: initialTrackerStatus,
|
|
43
|
+
trackerStatusUpdatedAt: now,
|
|
44
|
+
shadowedAt: now,
|
|
45
|
+
history: []
|
|
46
|
+
};
|
|
47
|
+
const filePath = getShadowStatePath(issueId);
|
|
48
|
+
writeFileSync(filePath, JSON.stringify(shadowState, null, 2), "utf-8");
|
|
49
|
+
return shadowState;
|
|
50
|
+
}
|
|
51
|
+
function updateShadowState(issueId, newStatus, triggeredBy, targetCanonicalState) {
|
|
52
|
+
ensureShadowStateDir();
|
|
53
|
+
let state = getShadowState(issueId);
|
|
54
|
+
if (!state) {
|
|
55
|
+
state = {
|
|
56
|
+
issueId: issueId.toUpperCase(),
|
|
57
|
+
shadowStatus: newStatus,
|
|
58
|
+
targetCanonicalState,
|
|
59
|
+
trackerStatus: newStatus,
|
|
60
|
+
trackerStatusUpdatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
61
|
+
shadowedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
62
|
+
history: []
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
if (state.shadowStatus !== newStatus) {
|
|
66
|
+
const transition = {
|
|
67
|
+
from: state.shadowStatus,
|
|
68
|
+
to: newStatus,
|
|
69
|
+
at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
70
|
+
by: triggeredBy,
|
|
71
|
+
syncedToTracker: false
|
|
72
|
+
};
|
|
73
|
+
state.history.push(transition);
|
|
74
|
+
state.shadowStatus = newStatus;
|
|
75
|
+
}
|
|
76
|
+
if (targetCanonicalState) {
|
|
77
|
+
state.targetCanonicalState = targetCanonicalState;
|
|
78
|
+
}
|
|
79
|
+
const filePath = getShadowStatePath(issueId);
|
|
80
|
+
writeFileSync(filePath, JSON.stringify(state, null, 2), "utf-8");
|
|
81
|
+
return state;
|
|
82
|
+
}
|
|
83
|
+
function updateTrackerStatusCache(issueId, trackerStatus) {
|
|
84
|
+
const state = getShadowState(issueId);
|
|
85
|
+
if (!state) {
|
|
86
|
+
throw new Error(`Cannot update tracker status: ${issueId} is not in shadow mode`);
|
|
87
|
+
}
|
|
88
|
+
state.trackerStatus = trackerStatus;
|
|
89
|
+
state.trackerStatusUpdatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
90
|
+
const filePath = getShadowStatePath(issueId);
|
|
91
|
+
writeFileSync(filePath, JSON.stringify(state, null, 2), "utf-8");
|
|
92
|
+
return state;
|
|
93
|
+
}
|
|
94
|
+
function markAsSynced(issueId, syncedState, previousTrackerState) {
|
|
95
|
+
const state = getShadowState(issueId);
|
|
96
|
+
if (!state) {
|
|
97
|
+
return {
|
|
98
|
+
success: false,
|
|
99
|
+
error: `Issue ${issueId} is not in shadow mode`
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
103
|
+
let entriesSynced = 0;
|
|
104
|
+
for (const entry of state.history) {
|
|
105
|
+
if (!entry.syncedToTracker) {
|
|
106
|
+
entry.syncedToTracker = true;
|
|
107
|
+
entriesSynced++;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
state.syncedAt = now;
|
|
111
|
+
state.trackerStatus = syncedState;
|
|
112
|
+
state.trackerStatusUpdatedAt = now;
|
|
113
|
+
const filePath = getShadowStatePath(issueId);
|
|
114
|
+
writeFileSync(filePath, JSON.stringify(state, null, 2), "utf-8");
|
|
115
|
+
return {
|
|
116
|
+
success: true,
|
|
117
|
+
syncedState,
|
|
118
|
+
previousState: previousTrackerState,
|
|
119
|
+
entriesSynced
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
function listShadowedIssues() {
|
|
123
|
+
if (!existsSync(SHADOW_STATE_DIR)) {
|
|
124
|
+
return [];
|
|
125
|
+
}
|
|
126
|
+
const files = readdirSync(SHADOW_STATE_DIR);
|
|
127
|
+
const states = [];
|
|
128
|
+
for (const file of files) {
|
|
129
|
+
if (!file.endsWith(".json")) continue;
|
|
130
|
+
try {
|
|
131
|
+
const content = readFileSync(join(SHADOW_STATE_DIR, file), "utf-8");
|
|
132
|
+
const state = JSON.parse(content);
|
|
133
|
+
states.push(state);
|
|
134
|
+
} catch (error) {
|
|
135
|
+
console.error(`Error reading shadow state file ${file}:`, error);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
return states.sort(
|
|
139
|
+
(a, b) => new Date(b.shadowedAt).getTime() - new Date(a.shadowedAt).getTime()
|
|
140
|
+
);
|
|
141
|
+
}
|
|
142
|
+
function removeShadowState(issueId, syncFirst = false) {
|
|
143
|
+
const filePath = getShadowStatePath(issueId);
|
|
144
|
+
if (!existsSync(filePath)) {
|
|
145
|
+
return {
|
|
146
|
+
success: false,
|
|
147
|
+
error: `Issue ${issueId} is not in shadow mode`
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
try {
|
|
151
|
+
unlinkSync(filePath);
|
|
152
|
+
return {
|
|
153
|
+
success: true,
|
|
154
|
+
synced: syncFirst
|
|
155
|
+
};
|
|
156
|
+
} catch (error) {
|
|
157
|
+
return {
|
|
158
|
+
success: false,
|
|
159
|
+
error: `Failed to remove shadow state: ${error.message}`
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
function getDisplayStatus(issueId, trackerStatus) {
|
|
164
|
+
const state = getShadowState(issueId);
|
|
165
|
+
if (!state) {
|
|
166
|
+
return {
|
|
167
|
+
status: trackerStatus,
|
|
168
|
+
isShadowed: false
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
return {
|
|
172
|
+
status: state.shadowStatus,
|
|
173
|
+
isShadowed: true,
|
|
174
|
+
trackerStatus: state.trackerStatus,
|
|
175
|
+
outOfSync: state.shadowStatus !== state.trackerStatus
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
function needsSync(issueId) {
|
|
179
|
+
const state = getShadowState(issueId);
|
|
180
|
+
if (!state) {
|
|
181
|
+
return false;
|
|
182
|
+
}
|
|
183
|
+
return state.shadowStatus !== state.trackerStatus;
|
|
184
|
+
}
|
|
185
|
+
function getUnsyncedHistory(issueId) {
|
|
186
|
+
const state = getShadowState(issueId);
|
|
187
|
+
if (!state) {
|
|
188
|
+
return [];
|
|
189
|
+
}
|
|
190
|
+
return state.history.filter((entry) => !entry.syncedToTracker);
|
|
191
|
+
}
|
|
192
|
+
function getPendingSyncCount() {
|
|
193
|
+
return listShadowedIssues().filter(
|
|
194
|
+
(state) => state.shadowStatus !== state.trackerStatus
|
|
195
|
+
).length;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
export {
|
|
199
|
+
getShadowState,
|
|
200
|
+
isShadowed,
|
|
201
|
+
createShadowState,
|
|
202
|
+
updateShadowState,
|
|
203
|
+
updateTrackerStatusCache,
|
|
204
|
+
markAsSynced,
|
|
205
|
+
listShadowedIssues,
|
|
206
|
+
removeShadowState,
|
|
207
|
+
getDisplayStatus,
|
|
208
|
+
needsSync,
|
|
209
|
+
getUnsyncedHistory,
|
|
210
|
+
getPendingSyncCount
|
|
211
|
+
};
|
|
212
|
+
//# sourceMappingURL=chunk-B3PF6JPQ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/lib/shadow-state.ts"],"sourcesContent":["/**\n * Shadow State Storage Module\n *\n * Manages shadow state for issues - tracking status locally without updating\n * the issue tracker until explicitly synced.\n *\n * Storage Location: ~/.panopticon/shadow-state/\n */\n\nimport { readFileSync, writeFileSync, existsSync, mkdirSync, readdirSync, unlinkSync } from 'fs';\nimport { join } from 'path';\nimport { homedir } from 'os';\nimport type { IssueState } from './tracker/interface.js';\n\n// Storage directory for shadow state files\nconst SHADOW_STATE_DIR = join(homedir(), '.panopticon', 'shadow-state');\n\n/**\n * Shadow history entry - tracks state transitions\n */\nexport interface ShadowHistoryEntry {\n /** Previous state */\n from: IssueState;\n /** New state */\n to: IssueState;\n /** When the transition occurred */\n at: string;\n /** Command that triggered the transition (e.g., \"pan work plan\", \"dashboard\") */\n by: string;\n /** Whether this transition was synced to the tracker */\n syncedToTracker: boolean;\n}\n\n/**\n * Canonical state for Kanban column placement\n */\nexport type CanonicalState = 'backlog' | 'todo' | 'in_progress' | 'in_review' | 'done' | 'canceled';\n\n/**\n * Shadow state for an issue\n */\nexport interface ShadowState {\n /** Issue ID (e.g., \"MIN-123\") */\n issueId: string;\n /** Panopticon's view of the issue status */\n shadowStatus: IssueState;\n /** Target canonical state for Kanban column placement */\n targetCanonicalState?: CanonicalState;\n /** Last known tracker status (cached) */\n trackerStatus: IssueState;\n /** When tracker status was last fetched */\n trackerStatusUpdatedAt: string;\n /** When shadow mode was enabled for this issue */\n shadowedAt: string;\n /** When shadow state was last synced to tracker */\n syncedAt?: string;\n /** Audit trail of state transitions */\n history: ShadowHistoryEntry[];\n}\n\n/**\n * Result of a sync operation\n */\nexport interface SyncResult {\n success: boolean;\n /** The state that was synced */\n syncedState?: IssueState;\n /** Previous tracker state */\n previousState?: IssueState;\n /** Error message if sync failed */\n error?: string;\n /** Number of history entries marked as synced */\n entriesSynced?: number;\n}\n\n/**\n * Ensure the shadow state directory exists\n */\nfunction ensureShadowStateDir(): void {\n if (!existsSync(SHADOW_STATE_DIR)) {\n mkdirSync(SHADOW_STATE_DIR, { recursive: true });\n }\n}\n\n/**\n * Get the file path for a shadow state file\n */\nfunction getShadowStatePath(issueId: string): string {\n // Normalize issue ID for filename (uppercase, replace special chars)\n const normalizedId = issueId.toUpperCase().replace(/[^A-Z0-9-]/g, '');\n return join(SHADOW_STATE_DIR, `${normalizedId}.json`);\n}\n\n/**\n * Get shadow state for an issue\n * @returns ShadowState or null if not shadowed\n */\nexport function getShadowState(issueId: string): ShadowState | null {\n const filePath = getShadowStatePath(issueId);\n\n if (!existsSync(filePath)) {\n return null;\n }\n\n try {\n const content = readFileSync(filePath, 'utf-8');\n return JSON.parse(content) as ShadowState;\n } catch (error) {\n console.error(`Error reading shadow state for ${issueId}:`, error);\n return null;\n }\n}\n\n/**\n * Check if an issue is in shadow mode\n */\nexport function isShadowed(issueId: string): boolean {\n return getShadowState(issueId) !== null;\n}\n\n/**\n * Create a new shadow state for an issue\n */\nexport function createShadowState(\n issueId: string,\n initialTrackerStatus: IssueState = 'open',\n triggeredBy: string = 'unknown'\n): ShadowState {\n ensureShadowStateDir();\n\n const now = new Date().toISOString();\n\n const shadowState: ShadowState = {\n issueId: issueId.toUpperCase(),\n shadowStatus: initialTrackerStatus,\n trackerStatus: initialTrackerStatus,\n trackerStatusUpdatedAt: now,\n shadowedAt: now,\n history: [],\n };\n\n const filePath = getShadowStatePath(issueId);\n writeFileSync(filePath, JSON.stringify(shadowState, null, 2), 'utf-8');\n\n return shadowState;\n}\n\n/**\n * Update shadow state for an issue\n */\nexport function updateShadowState(\n issueId: string,\n newStatus: IssueState,\n triggeredBy: string,\n targetCanonicalState?: CanonicalState\n): ShadowState {\n ensureShadowStateDir();\n\n let state = getShadowState(issueId);\n\n // Create new shadow state if it doesn't exist\n if (!state) {\n state = {\n issueId: issueId.toUpperCase(),\n shadowStatus: newStatus,\n targetCanonicalState,\n trackerStatus: newStatus,\n trackerStatusUpdatedAt: new Date().toISOString(),\n shadowedAt: new Date().toISOString(),\n history: [],\n };\n }\n\n // Only record transition if status changed\n if (state.shadowStatus !== newStatus) {\n const transition: ShadowHistoryEntry = {\n from: state.shadowStatus,\n to: newStatus,\n at: new Date().toISOString(),\n by: triggeredBy,\n syncedToTracker: false,\n };\n\n state.history.push(transition);\n state.shadowStatus = newStatus;\n }\n\n // Always update target canonical state if provided\n if (targetCanonicalState) {\n state.targetCanonicalState = targetCanonicalState;\n }\n\n const filePath = getShadowStatePath(issueId);\n writeFileSync(filePath, JSON.stringify(state, null, 2), 'utf-8');\n\n return state;\n}\n\n/**\n * Update tracker status cache (refresh from tracker)\n */\nexport function updateTrackerStatusCache(\n issueId: string,\n trackerStatus: IssueState\n): ShadowState {\n const state = getShadowState(issueId);\n\n if (!state) {\n throw new Error(`Cannot update tracker status: ${issueId} is not in shadow mode`);\n }\n\n state.trackerStatus = trackerStatus;\n state.trackerStatusUpdatedAt = new Date().toISOString();\n\n const filePath = getShadowStatePath(issueId);\n writeFileSync(filePath, JSON.stringify(state, null, 2), 'utf-8');\n\n return state;\n}\n\n/**\n * Sync shadow state to tracker (mark as synced)\n * This is called after successfully updating the tracker\n */\nexport function markAsSynced(\n issueId: string,\n syncedState: IssueState,\n previousTrackerState?: IssueState\n): SyncResult {\n const state = getShadowState(issueId);\n\n if (!state) {\n return {\n success: false,\n error: `Issue ${issueId} is not in shadow mode`,\n };\n }\n\n const now = new Date().toISOString();\n let entriesSynced = 0;\n\n // Mark all unsynced history entries as synced\n for (const entry of state.history) {\n if (!entry.syncedToTracker) {\n entry.syncedToTracker = true;\n entriesSynced++;\n }\n }\n\n // Update sync timestamp and tracker status\n state.syncedAt = now;\n state.trackerStatus = syncedState;\n state.trackerStatusUpdatedAt = now;\n\n const filePath = getShadowStatePath(issueId);\n writeFileSync(filePath, JSON.stringify(state, null, 2), 'utf-8');\n\n return {\n success: true,\n syncedState,\n previousState: previousTrackerState,\n entriesSynced,\n };\n}\n\n/**\n * List all shadowed issues\n */\nexport function listShadowedIssues(): ShadowState[] {\n if (!existsSync(SHADOW_STATE_DIR)) {\n return [];\n }\n\n const files = readdirSync(SHADOW_STATE_DIR);\n const states: ShadowState[] = [];\n\n for (const file of files) {\n if (!file.endsWith('.json')) continue;\n\n try {\n const content = readFileSync(join(SHADOW_STATE_DIR, file), 'utf-8');\n const state = JSON.parse(content) as ShadowState;\n states.push(state);\n } catch (error) {\n console.error(`Error reading shadow state file ${file}:`, error);\n }\n }\n\n // Sort by shadowedAt (newest first)\n return states.sort((a, b) =>\n new Date(b.shadowedAt).getTime() - new Date(a.shadowedAt).getTime()\n );\n}\n\n/**\n * Remove shadow state for an issue (unshadow)\n * @param syncFirst - If true, attempts to sync to tracker before removing\n */\nexport function removeShadowState(\n issueId: string,\n syncFirst: boolean = false\n): { success: boolean; error?: string; synced?: boolean } {\n const filePath = getShadowStatePath(issueId);\n\n if (!existsSync(filePath)) {\n return {\n success: false,\n error: `Issue ${issueId} is not in shadow mode`,\n };\n }\n\n try {\n // If syncFirst is true, we should have already synced by this point\n // This parameter is just for API clarity\n\n unlinkSync(filePath);\n return {\n success: true,\n synced: syncFirst,\n };\n } catch (error: any) {\n return {\n success: false,\n error: `Failed to remove shadow state: ${error.message}`,\n };\n }\n}\n\n/**\n * Get the display status for an issue\n * Returns shadow status with tracker status info if in shadow mode\n */\nexport function getDisplayStatus(\n issueId: string,\n trackerStatus: IssueState\n): {\n status: IssueState;\n isShadowed: boolean;\n trackerStatus?: IssueState;\n outOfSync?: boolean;\n} {\n const state = getShadowState(issueId);\n\n if (!state) {\n return {\n status: trackerStatus,\n isShadowed: false,\n };\n }\n\n return {\n status: state.shadowStatus,\n isShadowed: true,\n trackerStatus: state.trackerStatus,\n outOfSync: state.shadowStatus !== state.trackerStatus,\n };\n}\n\n/**\n * Check if an issue needs to be synced to tracker\n * (shadow status differs from tracker status)\n */\nexport function needsSync(issueId: string): boolean {\n const state = getShadowState(issueId);\n\n if (!state) {\n return false;\n }\n\n return state.shadowStatus !== state.trackerStatus;\n}\n\n/**\n * Get unsynced history entries for an issue\n */\nexport function getUnsyncedHistory(issueId: string): ShadowHistoryEntry[] {\n const state = getShadowState(issueId);\n\n if (!state) {\n return [];\n }\n\n return state.history.filter(entry => !entry.syncedToTracker);\n}\n\n/**\n * Get the count of issues that need sync\n */\nexport function getPendingSyncCount(): number {\n return listShadowedIssues().filter(state =>\n state.shadowStatus !== state.trackerStatus\n ).length;\n}\n"],"mappings":"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","names":[]}
|
|
@@ -12,25 +12,28 @@ import {
|
|
|
12
12
|
killSession,
|
|
13
13
|
sendKeysAsync,
|
|
14
14
|
sessionExists
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-KJ2TRXNK.js";
|
|
16
16
|
import {
|
|
17
17
|
createTrackerFromConfig,
|
|
18
|
+
init_factory
|
|
19
|
+
} from "./chunk-XFR2DLMR.js";
|
|
20
|
+
import {
|
|
18
21
|
getProviderEnv,
|
|
19
22
|
getProviderForModel,
|
|
20
|
-
init_factory,
|
|
21
23
|
init_providers,
|
|
22
24
|
init_settings,
|
|
23
|
-
loadSettings
|
|
24
|
-
|
|
25
|
+
loadSettings,
|
|
26
|
+
setupCredentialFileAuth
|
|
27
|
+
} from "./chunk-7XNJJBH6.js";
|
|
25
28
|
import {
|
|
26
29
|
init_config,
|
|
27
30
|
loadConfig
|
|
28
|
-
} from "./chunk-
|
|
31
|
+
} from "./chunk-FQ66DECN.js";
|
|
29
32
|
import {
|
|
30
33
|
AGENTS_DIR,
|
|
31
34
|
PANOPTICON_HOME,
|
|
32
35
|
init_paths
|
|
33
|
-
} from "./chunk-
|
|
36
|
+
} from "./chunk-ZTFNYOC7.js";
|
|
34
37
|
import {
|
|
35
38
|
__esm,
|
|
36
39
|
init_esm_shims
|
|
@@ -291,17 +294,11 @@ var init_config2 = __esm({
|
|
|
291
294
|
specialist_models: {
|
|
292
295
|
merge_agent: "sonnet",
|
|
293
296
|
review_agent: "sonnet",
|
|
294
|
-
test_agent: "haiku"
|
|
295
|
-
planning_agent: "opus"
|
|
297
|
+
test_agent: "haiku"
|
|
296
298
|
}
|
|
297
299
|
},
|
|
298
300
|
handoffs: {
|
|
299
301
|
auto_triggers: {
|
|
300
|
-
planning_complete: {
|
|
301
|
-
enabled: true,
|
|
302
|
-
from_model: "opus",
|
|
303
|
-
to_model: "sonnet"
|
|
304
|
-
},
|
|
305
302
|
stuck_escalation: {
|
|
306
303
|
enabled: true,
|
|
307
304
|
haiku_to_sonnet_minutes: 10,
|
|
@@ -383,7 +380,7 @@ function clearReadySignal(agentId) {
|
|
|
383
380
|
async function waitForReadySignal(agentId, timeoutSeconds = 30) {
|
|
384
381
|
const readyPath = getReadySignalPath(agentId);
|
|
385
382
|
for (let i = 0; i < timeoutSeconds; i++) {
|
|
386
|
-
await new Promise((
|
|
383
|
+
await new Promise((resolve2) => setTimeout(resolve2, 1e3));
|
|
387
384
|
if (existsSync3(readyPath)) {
|
|
388
385
|
try {
|
|
389
386
|
const content = readFileSync3(readyPath, "utf-8");
|
|
@@ -414,33 +411,53 @@ function saveAgentState(state) {
|
|
|
414
411
|
JSON.stringify(state, null, 2)
|
|
415
412
|
);
|
|
416
413
|
}
|
|
414
|
+
function getAgentRuntimeFile(agentId) {
|
|
415
|
+
return join3(getAgentDir(agentId), "runtime.json");
|
|
416
|
+
}
|
|
417
417
|
function getAgentRuntimeState(agentId) {
|
|
418
|
+
const runtimeFile = getAgentRuntimeFile(agentId);
|
|
418
419
|
const stateFile = join3(getAgentDir(agentId), "state.json");
|
|
419
|
-
if (
|
|
420
|
+
if (existsSync3(runtimeFile)) {
|
|
421
|
+
try {
|
|
422
|
+
const content = readFileSync3(runtimeFile, "utf8");
|
|
423
|
+
return JSON.parse(content);
|
|
424
|
+
} catch {
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
if (existsSync3(stateFile)) {
|
|
428
|
+
try {
|
|
429
|
+
const content = readFileSync3(stateFile, "utf8");
|
|
430
|
+
const parsed = JSON.parse(content);
|
|
431
|
+
if (parsed.state && parsed.lastActivity) {
|
|
432
|
+
return parsed;
|
|
433
|
+
}
|
|
434
|
+
} catch {
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
if (!existsSync3(stateFile) && !existsSync3(runtimeFile)) {
|
|
420
438
|
return {
|
|
421
439
|
state: "uninitialized",
|
|
422
440
|
lastActivity: (/* @__PURE__ */ new Date()).toISOString()
|
|
423
441
|
};
|
|
424
442
|
}
|
|
425
|
-
|
|
426
|
-
const content = readFileSync3(stateFile, "utf8");
|
|
427
|
-
return JSON.parse(content);
|
|
428
|
-
} catch {
|
|
429
|
-
return null;
|
|
430
|
-
}
|
|
443
|
+
return null;
|
|
431
444
|
}
|
|
432
445
|
function saveAgentRuntimeState(agentId, state) {
|
|
433
446
|
const dir = getAgentDir(agentId);
|
|
434
447
|
mkdirSync3(dir, { recursive: true });
|
|
435
|
-
const
|
|
448
|
+
const runtimeFile = getAgentRuntimeFile(agentId);
|
|
449
|
+
let existing = null;
|
|
450
|
+
if (existsSync3(runtimeFile)) {
|
|
451
|
+
try {
|
|
452
|
+
existing = JSON.parse(readFileSync3(runtimeFile, "utf8"));
|
|
453
|
+
} catch {
|
|
454
|
+
}
|
|
455
|
+
}
|
|
436
456
|
const merged = {
|
|
437
457
|
...existing || { state: "uninitialized", lastActivity: (/* @__PURE__ */ new Date()).toISOString() },
|
|
438
458
|
...state
|
|
439
459
|
};
|
|
440
|
-
writeFileSync3(
|
|
441
|
-
join3(dir, "state.json"),
|
|
442
|
-
JSON.stringify(merged, null, 2)
|
|
443
|
-
);
|
|
460
|
+
writeFileSync3(runtimeFile, JSON.stringify(merged, null, 2));
|
|
444
461
|
}
|
|
445
462
|
function appendActivity(agentId, entry) {
|
|
446
463
|
const dir = getAgentDir(agentId);
|
|
@@ -502,9 +519,6 @@ function determineModel(options) {
|
|
|
502
519
|
return getModelId(workType);
|
|
503
520
|
}
|
|
504
521
|
if (options.agentType && options.agentType !== "work-agent") {
|
|
505
|
-
if (options.agentType === "planning-agent") {
|
|
506
|
-
return getModelId("planning-agent");
|
|
507
|
-
}
|
|
508
522
|
const workType = `specialist-${options.agentType}`;
|
|
509
523
|
return getModelId(workType);
|
|
510
524
|
}
|
|
@@ -520,16 +534,16 @@ function determineModel(options) {
|
|
|
520
534
|
const defaultModel = cloisterConfig.model_selection?.default_model || "sonnet";
|
|
521
535
|
const modelMap = {
|
|
522
536
|
"opus": "claude-opus-4-6",
|
|
523
|
-
"sonnet": "claude-sonnet-4-
|
|
537
|
+
"sonnet": "claude-sonnet-4-6",
|
|
524
538
|
"haiku": "claude-haiku-4-5"
|
|
525
539
|
};
|
|
526
|
-
return modelMap[defaultModel] || "claude-sonnet-4-
|
|
540
|
+
return modelMap[defaultModel] || "claude-sonnet-4-6";
|
|
527
541
|
} catch {
|
|
528
|
-
return "claude-sonnet-4-
|
|
542
|
+
return "claude-sonnet-4-6";
|
|
529
543
|
}
|
|
530
544
|
} catch (error) {
|
|
531
545
|
console.warn("Warning: Could not resolve model using work type router, using default");
|
|
532
|
-
return options.model || "claude-sonnet-4-
|
|
546
|
+
return options.model || "claude-sonnet-4-6";
|
|
533
547
|
}
|
|
534
548
|
}
|
|
535
549
|
async function transitionIssueToInProgress(issueId) {
|
|
@@ -587,9 +601,26 @@ async function spawnAgent(options) {
|
|
|
587
601
|
writeFileSync3(promptFile, prompt);
|
|
588
602
|
}
|
|
589
603
|
checkAndSetupHooks();
|
|
604
|
+
try {
|
|
605
|
+
const venvPath = join3(options.workspace, ".venv");
|
|
606
|
+
if (existsSync3(venvPath)) {
|
|
607
|
+
const { getTldrDaemonService } = await import("./tldr-daemon-T3THOUGT.js");
|
|
608
|
+
const tldrService = getTldrDaemonService(options.workspace, venvPath);
|
|
609
|
+
const status = await tldrService.getStatus();
|
|
610
|
+
if (!status.running) {
|
|
611
|
+
await tldrService.start(true);
|
|
612
|
+
console.log(`[${agentId}] Started TLDR daemon for workspace`);
|
|
613
|
+
}
|
|
614
|
+
}
|
|
615
|
+
} catch {
|
|
616
|
+
}
|
|
590
617
|
writeTaskCache(agentId, options.issueId);
|
|
591
618
|
clearReadySignal(agentId);
|
|
592
619
|
const providerEnv = getProviderEnvForModel(selectedModel);
|
|
620
|
+
const provider = getProviderForModel(selectedModel);
|
|
621
|
+
if (provider.authType === "credential-file") {
|
|
622
|
+
setupCredentialFileAuth(provider, options.workspace);
|
|
623
|
+
}
|
|
593
624
|
let claudeCmd;
|
|
594
625
|
if (prompt) {
|
|
595
626
|
const launcherScript = join3(getAgentDir(agentId), "launcher.sh");
|
|
@@ -602,11 +633,18 @@ exec claude --dangerously-skip-permissions --model ${state.model} "$prompt"
|
|
|
602
633
|
} else {
|
|
603
634
|
claudeCmd = `claude --dangerously-skip-permissions --model ${state.model}`;
|
|
604
635
|
}
|
|
636
|
+
try {
|
|
637
|
+
const { preTrustDirectory } = await import("./workspace-manager-KLHUCIZV.js");
|
|
638
|
+
preTrustDirectory(options.workspace);
|
|
639
|
+
} catch {
|
|
640
|
+
}
|
|
605
641
|
createSession(agentId, options.workspace, claudeCmd, {
|
|
606
642
|
env: {
|
|
607
643
|
PANOPTICON_AGENT_ID: agentId,
|
|
608
644
|
PANOPTICON_ISSUE_ID: options.issueId,
|
|
609
645
|
PANOPTICON_SESSION_TYPE: options.phase || "implementation",
|
|
646
|
+
CLAUDE_CODE_ENABLE_PROMPT_SUGGESTION: "false",
|
|
647
|
+
// Disable suggested prompts for autonomous agents (PAN-251)
|
|
610
648
|
...providerEnv
|
|
611
649
|
// Add provider-specific env vars (BASE_URL, AUTH_TOKEN, etc.)
|
|
612
650
|
}
|
|
@@ -670,7 +708,7 @@ async function messageAgent(agentId, message) {
|
|
|
670
708
|
}
|
|
671
709
|
return;
|
|
672
710
|
}
|
|
673
|
-
const { loadRemoteAgentState, sendToRemoteAgent } = await import("./remote-agents-
|
|
711
|
+
const { loadRemoteAgentState, sendToRemoteAgent } = await import("./remote-agents-TFSMW7GN.js");
|
|
674
712
|
const remoteState = loadRemoteAgentState(normalizedId);
|
|
675
713
|
if (remoteState && remoteState.vmName) {
|
|
676
714
|
console.log(`[agents] Sending message to remote agent ${normalizedId} on ${remoteState.vmName}`);
|
|
@@ -734,10 +772,17 @@ async function resumeAgent(agentId, message) {
|
|
|
734
772
|
try {
|
|
735
773
|
clearReadySignal(normalizedId);
|
|
736
774
|
const providerEnv = agentState.model ? getProviderEnvForModel(agentState.model) : {};
|
|
775
|
+
if (agentState.model) {
|
|
776
|
+
const provider = getProviderForModel(agentState.model);
|
|
777
|
+
if (provider.authType === "credential-file") {
|
|
778
|
+
setupCredentialFileAuth(provider, agentState.workspace);
|
|
779
|
+
}
|
|
780
|
+
}
|
|
737
781
|
const claudeCmd = `claude --resume "${sessionId}" --dangerously-skip-permissions`;
|
|
738
782
|
createSession(normalizedId, agentState.workspace, claudeCmd, {
|
|
739
783
|
env: {
|
|
740
784
|
PANOPTICON_AGENT_ID: normalizedId,
|
|
785
|
+
CLAUDE_CODE_ENABLE_PROMPT_SUGGESTION: "false",
|
|
741
786
|
...providerEnv
|
|
742
787
|
}
|
|
743
788
|
});
|
|
@@ -799,10 +844,17 @@ function recoverAgent(agentId) {
|
|
|
799
844
|
writeFileSync3(healthFile, JSON.stringify(health, null, 2));
|
|
800
845
|
const recoveryPrompt = generateRecoveryPrompt(state);
|
|
801
846
|
const providerEnv = state.model ? getProviderEnvForModel(state.model) : {};
|
|
847
|
+
if (state.model) {
|
|
848
|
+
const provider = getProviderForModel(state.model);
|
|
849
|
+
if (provider.authType === "credential-file") {
|
|
850
|
+
setupCredentialFileAuth(provider, state.workspace);
|
|
851
|
+
}
|
|
852
|
+
}
|
|
802
853
|
const claudeCmd = `claude --dangerously-skip-permissions --model ${state.model} "${recoveryPrompt.replace(/"/g, '\\"').replace(/\n/g, "\\n")}"`;
|
|
803
854
|
createSession(normalizedId, state.workspace, claudeCmd, {
|
|
804
855
|
env: {
|
|
805
856
|
PANOPTICON_AGENT_ID: normalizedId,
|
|
857
|
+
CLAUDE_CODE_ENABLE_PROMPT_SUGGESTION: "false",
|
|
806
858
|
...providerEnv
|
|
807
859
|
}
|
|
808
860
|
});
|
|
@@ -936,6 +988,7 @@ export {
|
|
|
936
988
|
getAgentDir,
|
|
937
989
|
getAgentState,
|
|
938
990
|
saveAgentState,
|
|
991
|
+
getAgentRuntimeFile,
|
|
939
992
|
getAgentRuntimeState,
|
|
940
993
|
saveAgentRuntimeState,
|
|
941
994
|
appendActivity,
|
|
@@ -952,4 +1005,4 @@ export {
|
|
|
952
1005
|
autoRecoverAgents,
|
|
953
1006
|
init_agents
|
|
954
1007
|
};
|
|
955
|
-
//# sourceMappingURL=chunk-
|
|
1008
|
+
//# sourceMappingURL=chunk-BKCWRMUX.js.map
|