ccakashic 0.3.0 → 0.3.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/bin/ccakashic.js +23 -17
- package/dist/cmux.js +17 -7
- package/dist/resume-ui.js +3 -3
- package/package.json +1 -1
package/dist/bin/ccakashic.js
CHANGED
|
@@ -176,36 +176,42 @@ async function handleResume(req, res) {
|
|
|
176
176
|
if (!project || !sessionPath || !fs.existsSync(sessionPath)) {
|
|
177
177
|
return respond(404, { action: 'error', message: 'Session not found' });
|
|
178
178
|
}
|
|
179
|
-
// Already open via a previous resume → jump instead of forking.
|
|
180
|
-
const liveWorkspace = await (0, cmux_1.findLiveWorkspaceForSession)(sessionId);
|
|
181
|
-
if (liveWorkspace) {
|
|
182
|
-
try {
|
|
183
|
-
await (0, cmux_1.selectWorkspace)(liveWorkspace);
|
|
184
|
-
return respond(200, { action: 'jumped', workspace: liveWorkspace });
|
|
185
|
-
}
|
|
186
|
-
catch {
|
|
187
|
-
// workspace died between the check and the select; fall through
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
179
|
const cwd = await (0, discover_1.readCwdFromSession)(sessionPath);
|
|
191
180
|
if (!cwd)
|
|
192
181
|
return respond(200, { action: 'error', message: 'No cwd recorded in this session' });
|
|
193
182
|
if (!fs.existsSync(cwd)) {
|
|
194
183
|
return respond(200, { action: 'error', message: `Directory no longer exists: ${cwd}` });
|
|
195
184
|
}
|
|
196
|
-
|
|
197
|
-
|
|
185
|
+
const command = (0, cmux_1.buildResumeCommand)(cwd, sessionId);
|
|
186
|
+
if (NO_CMUX) {
|
|
187
|
+
return respond(200, { action: 'unavailable', command });
|
|
198
188
|
}
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
189
|
+
// Any cmux call can fail if the long-running server has lost contact with the
|
|
190
|
+
// current cmux instance (Mac sleep/wake, cmux restart). Rather than surface a
|
|
191
|
+
// hard error or hide the button, fall back to handing back the copy command
|
|
192
|
+
// with a hint to restart ccakashic if it persists.
|
|
202
193
|
try {
|
|
194
|
+
// Already open via a previous resume → jump instead of forking.
|
|
195
|
+
const liveWorkspace = await (0, cmux_1.findLiveWorkspaceForSession)(sessionId);
|
|
196
|
+
if (liveWorkspace) {
|
|
197
|
+
await (0, cmux_1.selectWorkspace)(liveWorkspace);
|
|
198
|
+
return respond(200, { action: 'jumped', workspace: liveWorkspace });
|
|
199
|
+
}
|
|
200
|
+
const sessions = await (0, discover_1.listSessions)(project.dir);
|
|
201
|
+
const preview = sessions.find((s) => s.id === sessionId);
|
|
202
|
+
const title = preview?.customTitle || preview?.aiTitle || preview?.slug || sessionId.slice(0, 8);
|
|
203
203
|
const result = await (0, cmux_1.resumeInNewWorkspace)(cwd, sessionId, title, mode === 'background');
|
|
204
204
|
(0, cmux_1.saveResumeMapEntry)(sessionId, result.workspaceId);
|
|
205
205
|
return respond(200, { action: 'resumed', workspace: result.workspaceId });
|
|
206
206
|
}
|
|
207
207
|
catch (err) {
|
|
208
|
-
|
|
208
|
+
if (process.env.CCAKASHIC_DEBUG)
|
|
209
|
+
console.error('[resume] cmux failed:', err?.message || err);
|
|
210
|
+
return respond(200, {
|
|
211
|
+
action: 'unavailable',
|
|
212
|
+
command,
|
|
213
|
+
message: 'cmux unreachable — copied the command instead. If this persists, restart ccakashic.',
|
|
214
|
+
});
|
|
209
215
|
}
|
|
210
216
|
}
|
|
211
217
|
// Only accept loopback Host headers. The server binds 127.0.0.1, but without
|
package/dist/cmux.js
CHANGED
|
@@ -93,20 +93,30 @@ function run(args, timeoutMs = 5000) {
|
|
|
93
93
|
});
|
|
94
94
|
});
|
|
95
95
|
}
|
|
96
|
-
let
|
|
96
|
+
let everAvailable = false;
|
|
97
|
+
let cachedUnavailableAt = 0;
|
|
97
98
|
async function isCmuxAvailable() {
|
|
98
|
-
//
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
99
|
+
// Sticky-positive: once cmux has answered, keep reporting available for the
|
|
100
|
+
// life of the process. A long-running server can transiently lose contact
|
|
101
|
+
// with cmux (Mac sleep/wake, cmux app restart) and `ping` then fails — but we
|
|
102
|
+
// must NOT hide the Resume UI on such a blip. The buttons stay; if cmux is
|
|
103
|
+
// genuinely unreachable at click time, /api/resume degrades to the copy
|
|
104
|
+
// command. Negative results are cached only ~5s so first contact is quick.
|
|
105
|
+
if (everAvailable)
|
|
106
|
+
return true;
|
|
107
|
+
if (cachedUnavailableAt && Date.now() - cachedUnavailableAt < 5_000)
|
|
108
|
+
return false;
|
|
102
109
|
let value = false;
|
|
103
110
|
try {
|
|
104
|
-
value = (await run(['ping'],
|
|
111
|
+
value = (await run(['ping'], 2500)) === 'PONG';
|
|
105
112
|
}
|
|
106
113
|
catch {
|
|
107
114
|
value = false;
|
|
108
115
|
}
|
|
109
|
-
|
|
116
|
+
if (value)
|
|
117
|
+
everAvailable = true;
|
|
118
|
+
else
|
|
119
|
+
cachedUnavailableAt = Date.now();
|
|
110
120
|
return value;
|
|
111
121
|
}
|
|
112
122
|
function shellQuote(s) {
|
package/dist/resume-ui.js
CHANGED
|
@@ -89,9 +89,9 @@ function resumeJS(ctx) {
|
|
|
89
89
|
clearTimeout(toastEl._t);
|
|
90
90
|
toastEl._t = setTimeout(function() { toastEl.classList.remove('visible'); }, 2500);
|
|
91
91
|
}
|
|
92
|
-
function copy(text) {
|
|
92
|
+
function copy(text, okMsg) {
|
|
93
93
|
navigator.clipboard.writeText(text).then(
|
|
94
|
-
function() { toast('Command copied'); },
|
|
94
|
+
function() { toast(okMsg || 'Command copied'); },
|
|
95
95
|
function() { toast('Copy failed'); }
|
|
96
96
|
);
|
|
97
97
|
}
|
|
@@ -134,7 +134,7 @@ function resumeJS(ctx) {
|
|
|
134
134
|
btn.classList.add('is-open');
|
|
135
135
|
btn.innerHTML = '↪ Jump';
|
|
136
136
|
} else if (data.action === 'unavailable' && data.command) {
|
|
137
|
-
copy(data.command);
|
|
137
|
+
copy(data.command, data.message);
|
|
138
138
|
} else {
|
|
139
139
|
toast(data.message || 'Resume failed');
|
|
140
140
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ccakashic",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.1",
|
|
4
4
|
"description": "A cross-project dashboard for your Claude Code sessions (~/.claude/projects/) — browse logs as beautiful HTML, see which sessions are waiting for you, and resume any of them in one click via cmux",
|
|
5
5
|
"bin": {
|
|
6
6
|
"ccakashic": "dist/bin/ccakashic.js"
|