mirror of
https://github.com/Ark0N/Codeman.git
synced 2026-10-08 08:29:42 +02:00
chore: version packages
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1452,6 +1452,26 @@ class CodemanApp {
|
||||
console.error('[SSE] docker export failed:', err);
|
||||
}
|
||||
});
|
||||
// Import + drift-recreate completions: refresh case lists in EVERY open tab
|
||||
// (the initiating tab already refreshes via its own fetch response).
|
||||
addListener(SSE_EVENTS.DOCKER_IMPORT_COMPLETE, (e) => {
|
||||
try {
|
||||
const d = e.data ? JSON.parse(e.data) : {};
|
||||
this.showToast(`Docker bundle imported as case "${d.name}"`, 'success');
|
||||
this.loadQuickStartCases?.();
|
||||
this.refreshDockerExports?.();
|
||||
} catch (err) {
|
||||
console.error('[SSE] docker import complete:', err);
|
||||
}
|
||||
});
|
||||
addListener(SSE_EVENTS.DOCKER_CONTAINER_RECREATED, (e) => {
|
||||
try {
|
||||
const d = e.data ? JSON.parse(e.data) : {};
|
||||
this.showToast(`Container for "${d.name}" removed — next launch recreates it with the new config`, 'info');
|
||||
} catch (err) {
|
||||
console.error('[SSE] docker container recreated:', err);
|
||||
}
|
||||
});
|
||||
// Base image auto-build on first Docker case (build-on-first-use). A single
|
||||
// multi-minute event; surface start/finish so the Run spinner is explained.
|
||||
addListener(SSE_EVENTS.DOCKER_IMAGE_BUILD_STARTED, () => {
|
||||
|
||||
@@ -481,6 +481,7 @@ const SSE_EVENTS = {
|
||||
DOCKER_IMAGE_BUILD_PROGRESS: 'docker:imageBuildProgress',
|
||||
DOCKER_IMAGE_BUILD_COMPLETE: 'docker:imageBuildComplete',
|
||||
DOCKER_IMAGE_BUILD_FAILED: 'docker:imageBuildFailed',
|
||||
DOCKER_CONTAINER_RECREATED: 'docker:containerRecreated',
|
||||
};
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════
|
||||
|
||||
@@ -1449,10 +1449,11 @@
|
||||
<label>Startup Mode</label>
|
||||
<select id="appSettingsClaudeMode" class="form-select">
|
||||
<option value="dangerously-skip-permissions">Skip Permissions (default)</option>
|
||||
<option value="auto">Auto Mode (safety classifier, recommended by Anthropic)</option>
|
||||
<option value="normal">Normal (with prompts)</option>
|
||||
<option value="allowedTools">Allowed Tools Only</option>
|
||||
</select>
|
||||
<span class="form-hint">How Claude CLI is started in screen sessions</span>
|
||||
<span class="form-hint">How Claude CLI is started in screen sessions. Auto Mode runs without routine prompts behind a background safety classifier (needs Claude Code 2.1.207+ and Opus 4.6+/Sonnet 4.6+/Fable 5)</span>
|
||||
</div>
|
||||
<div class="form-row" id="allowedToolsRow" style="display: none;">
|
||||
<label>Allowed Tools</label>
|
||||
@@ -1874,7 +1875,7 @@
|
||||
</div>
|
||||
<div class="form-row docker-quick-row">
|
||||
<label class="checkbox-row"><input type="checkbox" id="newCaseDocker"> 🐳 Run in an isolated Docker container</label>
|
||||
<span class="form-hint">Runs this case in a hardened, isolated container. The base image is built automatically on first use.</span>
|
||||
<span class="form-hint">Runs this case in a hardened, isolated container. The base image is built automatically on first use. Docker/Podman must be installed.</span>
|
||||
</div>
|
||||
<details class="advanced-options docker-quick-settings" id="dockerQuickSettings">
|
||||
<summary>Container settings (optional, sensible defaults)</summary>
|
||||
|
||||
@@ -459,16 +459,18 @@ html.mobile-init .file-browser-panel {
|
||||
height: 12px;
|
||||
}
|
||||
|
||||
/* Hide header settings gear, lifecycle log, away digest, and session manager on
|
||||
mobile - settings moved to toolbar; away digest and the session manager are
|
||||
secondary controls that don't belong on the cramped phone header (the session
|
||||
manager stays reachable via the Ctrl+K palette's "Browse all sessions" item).
|
||||
/* Hide header settings gear, lifecycle log, away digest, session manager, and
|
||||
file viewer on mobile - settings moved to toolbar; the others are secondary /
|
||||
desktop-oriented controls that don't belong on the cramped phone header (the
|
||||
session manager stays reachable via the Ctrl+K palette's "Browse all sessions"
|
||||
item; the file viewer button is opt-in but its panel is desktop-sized).
|
||||
(The attachments button is opt-in / default-hidden everywhere via its own
|
||||
--hidden marker, so it needs no mobile-specific rule here.) */
|
||||
.btn-icon-header.btn-settings,
|
||||
.btn-icon-header.btn-lifecycle-log,
|
||||
.btn-icon-header.btn-away-digest,
|
||||
.btn-icon-header.btn-session-manager {
|
||||
.btn-icon-header.btn-session-manager,
|
||||
.btn-icon-header.btn-file-viewer {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
|
||||
@@ -551,14 +551,50 @@ Object.assign(CodemanApp.prototype, {
|
||||
// Name remote/docker tabs with the same w<n>-<case> convention as local
|
||||
// sessions (quick-start would otherwise auto-generate codeman-<id>).
|
||||
const startNumber = this._nextCaseSessionStartNumber(caseName);
|
||||
// Docker (NOT remote): the App Settings Claude Model choice applies — the
|
||||
// workspace is a real host dir, so quick-start writes it to the case's
|
||||
// .claude/settings.local.json and the in-container claude reads it.
|
||||
// Remote quick-starts REJECT modelOverride (the file would land on the
|
||||
// wrong machine), so never send it there.
|
||||
let dockerModelOverride;
|
||||
if (caseData.location === 'docker') {
|
||||
const dockerGlobalSettings = this.loadAppSettingsFromStorage();
|
||||
const dockerCaseSettings = this.getCaseSettings(caseName);
|
||||
const dockerUseOpus1m = dockerCaseSettings.opusContext1m || dockerGlobalSettings.opusContext1mEnabled;
|
||||
dockerModelOverride = dockerGlobalSettings.claudeModel || (dockerUseOpus1m ? 'opus[1m]' : '');
|
||||
}
|
||||
const remoteIds = [];
|
||||
let driftHandled = false;
|
||||
for (let i = 0; i < tabCount; i++) {
|
||||
const res = await fetch('/api/quick-start', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ caseName, mode: 'claude', sessionName: `w${startNumber + i}-${caseName}` })
|
||||
const quickStartBody = JSON.stringify({
|
||||
caseName, mode: 'claude', sessionName: `w${startNumber + i}-${caseName}`,
|
||||
...(dockerModelOverride !== undefined ? { modelOverride: dockerModelOverride } : {})
|
||||
});
|
||||
const data = await res.json();
|
||||
const doQuickStart = async () => {
|
||||
const res = await fetch('/api/quick-start', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: quickStartBody
|
||||
});
|
||||
return res.json();
|
||||
};
|
||||
let data = await doQuickStart();
|
||||
// Docker config drift: the host config changed since the container was
|
||||
// created (CONFLICT from quick-start). Confirm once, recreate, retry.
|
||||
if (!data.success && data.errorCode === 'CONFLICT' && caseData.location === 'docker' && !driftHandled) {
|
||||
driftHandled = true;
|
||||
const recreate = confirm(
|
||||
`Container config for "${caseName}" changed since its container was created.\n\n` +
|
||||
'Recreate the container to apply the new config? Workspace files and the ' +
|
||||
'conversation survive (the conversation resumes on launch).'
|
||||
);
|
||||
if (recreate) {
|
||||
const recRes = await fetch(`/api/docker-cases/${encodeURIComponent(caseName)}/recreate`, { method: 'POST' });
|
||||
const recData = await recRes.json();
|
||||
if (!recData.success) throw new Error(recData.error || 'Failed to recreate container');
|
||||
data = await doQuickStart();
|
||||
}
|
||||
}
|
||||
if (!data.success) throw new Error(data.error || 'Failed to start remote Claude session');
|
||||
remoteIds.push(data.data.sessionId);
|
||||
}
|
||||
@@ -1958,7 +1994,8 @@ Object.assign(CodemanApp.prototype, {
|
||||
listEl.innerHTML = exports
|
||||
.map(e => {
|
||||
const mb = (e.sizeBytes / 1e6).toFixed(1);
|
||||
const nm = this.escapeHtml ? this.escapeHtml(e.name) : e.name;
|
||||
// escapeHtml is the free function from constants.js (never a method on `this`)
|
||||
const nm = escapeHtml(e.name);
|
||||
return `<div class="case-manage-item" style="display:flex; align-items:center; gap:8px; justify-content:space-between;">
|
||||
<span style="overflow:hidden; text-overflow:ellipsis; white-space:nowrap;" title="${nm}">${nm} <span class="form-hint">(${mb} MB)</span></span>
|
||||
<span style="flex-shrink:0;">
|
||||
|
||||
Reference in New Issue
Block a user