Merge pull request #593: feat(session-options): show the session's working folder with a copy button

This commit is contained in:
Codeman maintainer committed 2026-10-13 18:19:01 +02:00
commit 0ff9b798af
4 files changed
+39

No files matched your search

@@ -0,0 +1,5 @@
---
'aicodeman': patch
---
Session Options > Session now shows the working folder the session's CLI runs in on the Codeman host, with a Copy button.
+10
View File
@@ -1442,6 +1442,16 @@
<input type="text" id="modalSessionName" class="set-input" maxlength="128" placeholder="Auto (directory name)" onblur="app.saveSessionName()"> <input type="text" id="modalSessionName" class="set-input" maxlength="128" placeholder="Auto (directory name)" onblur="app.saveSessionName()">
</div> </div>
</div> </div>
<div class="set-row">
<div class="set-row-text">
<span class="set-row-label">Working folder</span>
<span class="set-row-desc">Where this session's CLI runs, on the machine hosting Codeman.</span>
</div>
<div class="set-row-actions">
<code id="modalSessionPath" class="set-static mono" style="word-break: break-all; user-select: all;"></code>
<button type="button" class="btn-toolbar btn-sm" id="modalSessionPathCopy" onclick="app.copySessionPath()">Copy</button>
</div>
</div>
<div class="set-row set-row-block"> <div class="set-row set-row-block">
<div class="set-row-text"> <div class="set-row-text">
<span class="set-row-label">Session color</span> <span class="set-row-label">Session color</span>
+14
View File
@@ -2486,6 +2486,14 @@ Object.assign(CodemanApp.prototype, {
if (tab) tab.classList.toggle('tab-show-detach', !!on); if (tab) tab.classList.toggle('tab-show-detach', !!on);
}, },
/** Copy the open session's working folder (Session Options > Session > Working folder). */
async copySessionPath() {
const session = this.sessions.get(this.editingSessionId);
if (!session?.workingDir) return;
const ok = await this._copyText(session.workingDir);
this.showToast(ok ? 'Path copied' : 'Copy failed', ok ? 'success' : 'error');
},
openSessionOptions(sessionId) { openSessionOptions(sessionId) {
const session = this.sessions.get(sessionId); const session = this.sessions.get(sessionId);
if (!session) return; if (!session) return;
@@ -2566,6 +2574,12 @@ Object.assign(CodemanApp.prototype, {
document.getElementById('modalSessionName').placeholder = 'Auto (directory name)'; document.getElementById('modalSessionName').placeholder = 'Auto (directory name)';
} }
// Working folder: the path the CLI was launched in on the Codeman host
const _pathEl = document.getElementById('modalSessionPath');
_pathEl.textContent = session.workingDir || '';
_pathEl.title = session.workingDir || '';
document.getElementById('modalSessionPathCopy').disabled = !session.workingDir;
// Initialize color picker with current session color // Initialize color picker with current session color
const currentColor = session.color || 'default'; const currentColor = session.color || 'default';
const colorPicker = document.getElementById('sessionColorPicker'); const colorPicker = document.getElementById('sessionColorPicker');
+10
View File
@@ -103,4 +103,14 @@ describe('Session Options modal structure', () => {
); );
expect(styles).not.toMatch(/@media \(min-width: 680px\)[\s\S]{0,1200}#sessionOptionsModal #context-tab/); expect(styles).not.toMatch(/@media \(min-width: 680px\)[\s\S]{0,1200}#sessionOptionsModal #context-tab/);
}); });
it('shows the session working folder with a copy button', () => {
const modal = optionsModal();
expect(modal).toContain('id="modalSessionPath"');
expect(modal).toContain('app.copySessionPath()');
const open = methodBody('openSessionOptions(sessionId)');
expect(open).toContain("getElementById('modalSessionPath')");
expect(open).toContain('session.workingDir');
expect(methodBody('async copySessionPath()')).toContain('_copyText(session.workingDir)');
});
}); });