aicodeman 1.41.0 → 1.41.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/README.md +58 -8
- package/dist/attachment-registry.d.ts +2 -0
- package/dist/attachment-registry.d.ts.map +1 -1
- package/dist/attachment-registry.js +14 -3
- package/dist/attachment-registry.js.map +1 -1
- package/dist/cli-agent.d.ts +2 -0
- package/dist/cli-agent.d.ts.map +1 -1
- package/dist/cli-agent.js +12 -8
- package/dist/cli-agent.js.map +1 -1
- package/dist/cli.d.ts +25 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +97 -11
- package/dist/cli.js.map +1 -1
- package/dist/config/buffer-limits.d.ts +9 -0
- package/dist/config/buffer-limits.d.ts.map +1 -1
- package/dist/config/buffer-limits.js +9 -0
- package/dist/config/buffer-limits.js.map +1 -1
- package/dist/config/cli-registry/schema.d.ts +8 -0
- package/dist/config/cli-registry/schema.d.ts.map +1 -1
- package/dist/config/cli-registry/schema.js +12 -0
- package/dist/config/cli-registry/schema.js.map +1 -1
- package/dist/config/cli-registry/stock.d.ts.map +1 -1
- package/dist/config/cli-registry/stock.js +42 -0
- package/dist/config/cli-registry/stock.js.map +1 -1
- package/dist/config/cli-registry/types.d.ts +35 -0
- package/dist/config/cli-registry/types.d.ts.map +1 -1
- package/dist/folder-listing.d.ts +94 -0
- package/dist/folder-listing.d.ts.map +1 -0
- package/dist/folder-listing.js +241 -0
- package/dist/folder-listing.js.map +1 -0
- package/dist/hooks-config.d.ts +36 -16
- package/dist/hooks-config.d.ts.map +1 -1
- package/dist/hooks-config.js +45 -20
- package/dist/hooks-config.js.map +1 -1
- package/dist/html-view-capabilities.d.ts +54 -0
- package/dist/html-view-capabilities.d.ts.map +1 -0
- package/dist/html-view-capabilities.js +103 -0
- package/dist/html-view-capabilities.js.map +1 -0
- package/dist/mcp-server.d.ts +114 -0
- package/dist/mcp-server.d.ts.map +1 -0
- package/dist/mcp-server.js +917 -0
- package/dist/mcp-server.js.map +1 -0
- package/dist/mcp-sync.d.ts +5 -0
- package/dist/mcp-sync.d.ts.map +1 -1
- package/dist/mcp-sync.js +51 -5
- package/dist/mcp-sync.js.map +1 -1
- package/dist/mux-interface.d.ts +36 -1
- package/dist/mux-interface.d.ts.map +1 -1
- package/dist/remote-files.d.ts +37 -0
- package/dist/remote-files.d.ts.map +1 -1
- package/dist/remote-files.js +103 -0
- package/dist/remote-files.js.map +1 -1
- package/dist/remote-pane-history.d.ts +103 -0
- package/dist/remote-pane-history.d.ts.map +1 -0
- package/dist/remote-pane-history.js +258 -0
- package/dist/remote-pane-history.js.map +1 -0
- package/dist/remote-ssh-limiter.d.ts +16 -3
- package/dist/remote-ssh-limiter.d.ts.map +1 -1
- package/dist/remote-ssh-limiter.js +37 -6
- package/dist/remote-ssh-limiter.js.map +1 -1
- package/dist/session.d.ts +29 -1
- package/dist/session.d.ts.map +1 -1
- package/dist/session.js +53 -0
- package/dist/session.js.map +1 -1
- package/dist/tab-layout-legacy-order.d.ts.map +1 -1
- package/dist/tab-layout-legacy-order.js +72 -13
- package/dist/tab-layout-legacy-order.js.map +1 -1
- package/dist/tab-layout-service.d.ts +33 -2
- package/dist/tab-layout-service.d.ts.map +1 -1
- package/dist/tab-layout-service.js +102 -7
- package/dist/tab-layout-service.js.map +1 -1
- package/dist/tab-layout.d.ts +9 -0
- package/dist/tab-layout.d.ts.map +1 -1
- package/dist/tab-layout.js +15 -2
- package/dist/tab-layout.js.map +1 -1
- package/dist/tmux-manager.d.ts +71 -2
- package/dist/tmux-manager.d.ts.map +1 -1
- package/dist/tmux-manager.js +169 -18
- package/dist/tmux-manager.js.map +1 -1
- package/dist/types/session.d.ts +53 -0
- package/dist/types/session.d.ts.map +1 -1
- package/dist/types/session.js.map +1 -1
- package/dist/usage-telemetry.d.ts +44 -7
- package/dist/usage-telemetry.d.ts.map +1 -1
- package/dist/usage-telemetry.js +72 -7
- package/dist/usage-telemetry.js.map +1 -1
- package/dist/web/approval-inbox.d.ts +12 -0
- package/dist/web/approval-inbox.d.ts.map +1 -1
- package/dist/web/approval-inbox.js +1 -0
- package/dist/web/approval-inbox.js.map +1 -1
- package/dist/web/middleware/auth.d.ts.map +1 -1
- package/dist/web/middleware/auth.js +33 -0
- package/dist/web/middleware/auth.js.map +1 -1
- package/dist/web/ports/session-port.d.ts +8 -1
- package/dist/web/ports/session-port.d.ts.map +1 -1
- package/dist/web/public/admin-ui.js.gz +0 -0
- package/dist/web/public/api-client.c9b1cddc.js.gz +0 -0
- package/dist/web/public/app.24689381.js +43 -0
- package/dist/web/public/app.24689381.js.br +0 -0
- package/dist/web/public/app.24689381.js.gz +0 -0
- package/dist/web/public/approvals-ui.js +4 -0
- package/dist/web/public/approvals-ui.js.br +0 -0
- package/dist/web/public/approvals-ui.js.gz +0 -0
- package/dist/web/public/{constants.bc9c1f63.js → constants.17d77b65.js} +395 -7
- package/dist/web/public/constants.17d77b65.js.br +0 -0
- package/dist/web/public/constants.17d77b65.js.gz +0 -0
- package/dist/web/public/cron-ui.js.gz +0 -0
- package/dist/web/public/entrance-animations.js.gz +0 -0
- package/dist/web/public/gesture/gesture-codeman.js +112 -6
- package/dist/web/public/git-status-ui.js.gz +0 -0
- package/dist/web/public/home-sessions.js.gz +0 -0
- package/dist/web/public/host-wake-ui.js.gz +0 -0
- package/dist/web/public/i18n.9afd8e4d.js +2 -0
- package/dist/web/public/i18n.9afd8e4d.js.br +0 -0
- package/dist/web/public/i18n.9afd8e4d.js.gz +0 -0
- package/dist/web/public/{image-input.e00471c6.js → image-input.9ed1d0d2.js} +186 -16
- package/dist/web/public/image-input.9ed1d0d2.js.br +0 -0
- package/dist/web/public/image-input.9ed1d0d2.js.gz +0 -0
- package/dist/web/public/index.html +105 -23
- package/dist/web/public/index.html.br +0 -0
- package/dist/web/public/index.html.gz +0 -0
- package/dist/web/public/input-cjk.8bc46081.js.gz +0 -0
- package/dist/web/public/{keyboard-accessory.c1e7c7b7.js → keyboard-accessory.c458eea8.js} +115 -35
- package/dist/web/public/keyboard-accessory.c458eea8.js.br +0 -0
- package/dist/web/public/keyboard-accessory.c458eea8.js.gz +0 -0
- package/dist/web/public/mobile-handlers.0ef9c311.js.gz +0 -0
- package/dist/web/public/mobile-ime-preview.2dbaf262.js.gz +0 -0
- package/dist/web/public/mobile-overview.js +11 -2
- package/dist/web/public/mobile-overview.js.br +0 -0
- package/dist/web/public/mobile-overview.js.gz +0 -0
- package/dist/web/public/mobile.2dff1580.css +1 -0
- package/dist/web/public/mobile.2dff1580.css.br +0 -0
- package/dist/web/public/mobile.2dff1580.css.gz +0 -0
- package/dist/web/public/notification-manager.feb82c04.js.gz +0 -0
- package/dist/web/public/orchestrator-panel.js.gz +0 -0
- package/dist/web/public/{panels-ui.71846fcb.js → panels-ui.73ec0137.js} +87 -87
- package/dist/web/public/panels-ui.73ec0137.js.br +0 -0
- package/dist/web/public/panels-ui.73ec0137.js.gz +0 -0
- package/dist/web/public/ralph-panel.b350e2ef.js.gz +0 -0
- package/dist/web/public/ralph-wizard.b6c0dd19.js.gz +0 -0
- package/dist/web/public/readmymind-ui.js.gz +0 -0
- package/dist/web/public/reboot-restore-ui.js.gz +0 -0
- package/dist/web/public/respawn-ui.ff0dae4c.js.gz +0 -0
- package/dist/web/public/sanitize-html.e7147e76.js.gz +0 -0
- package/dist/web/public/session-lineage.js.gz +0 -0
- package/dist/web/public/{session-ui.f731602c.js → session-ui.dbc6819b.js} +33 -33
- package/dist/web/public/session-ui.dbc6819b.js.br +0 -0
- package/dist/web/public/session-ui.dbc6819b.js.gz +0 -0
- package/dist/web/public/{settings-ui.4e33390f.js → settings-ui.81ac264e.js} +9 -9
- package/dist/web/public/settings-ui.81ac264e.js.br +0 -0
- package/dist/web/public/settings-ui.81ac264e.js.gz +0 -0
- package/dist/web/public/spreadsheet-preview-worker.js +11 -0
- package/dist/web/public/spreadsheet-preview-worker.js.br +0 -0
- package/dist/web/public/spreadsheet-preview-worker.js.gz +0 -0
- package/dist/web/public/{spreadsheet-preview.af82fa2f.js → spreadsheet-preview.75c751de.js} +1 -1
- package/dist/web/public/spreadsheet-preview.75c751de.js.br +0 -0
- package/dist/web/public/spreadsheet-preview.75c751de.js.gz +0 -0
- package/dist/web/public/spreadsheet-xlsx-core.js +110 -0
- package/dist/web/public/spreadsheet-xlsx-core.js.br +0 -0
- package/dist/web/public/spreadsheet-xlsx-core.js.gz +0 -0
- package/dist/web/public/styles.900a28e4.css +1 -0
- package/dist/web/public/styles.900a28e4.css.br +0 -0
- package/dist/web/public/styles.900a28e4.css.gz +0 -0
- package/dist/web/public/subagent-windows.07277a58.js.gz +0 -0
- package/dist/web/public/sw.js +6 -2
- package/dist/web/public/sw.js.br +0 -0
- package/dist/web/public/sw.js.gz +0 -0
- package/dist/web/public/tab-layout-browser.2d6189f7.js +1 -0
- package/dist/web/public/tab-layout-browser.2d6189f7.js.br +0 -0
- package/dist/web/public/tab-layout-browser.2d6189f7.js.gz +0 -0
- package/dist/web/public/{tab-rail-resize.a5867793.js → tab-rail-resize.7157e0bd.js} +1 -1
- package/dist/web/public/tab-rail-resize.7157e0bd.js.br +0 -0
- package/dist/web/public/tab-rail-resize.7157e0bd.js.gz +0 -0
- package/dist/web/public/terminal-keycode229-recovery.af09f99a.js.gz +0 -0
- package/dist/web/public/terminal-split.js.gz +0 -0
- package/dist/web/public/terminal-tile.js +44 -24
- package/dist/web/public/terminal-tile.js.br +0 -0
- package/dist/web/public/terminal-tile.js.gz +0 -0
- package/dist/web/public/terminal-ui.858f5da5.js +2 -0
- package/dist/web/public/terminal-ui.858f5da5.js.br +0 -0
- package/dist/web/public/terminal-ui.858f5da5.js.gz +0 -0
- package/dist/web/public/tile-grid.js +439 -18
- package/dist/web/public/tile-grid.js.br +0 -0
- package/dist/web/public/tile-grid.js.gz +0 -0
- package/dist/web/public/ultracode-panel.js.gz +0 -0
- package/dist/web/public/ultracode-windows.js.gz +0 -0
- package/dist/web/public/vendor/dompurify.min.js.gz +0 -0
- package/dist/web/public/vendor/exceljs.min.js.gz +0 -0
- package/dist/web/public/vendor/fflate.min.js.gz +0 -0
- package/dist/web/public/vendor/marked.min.js.gz +0 -0
- package/dist/web/public/vendor/xterm-addon-fit.min.js.gz +0 -0
- package/dist/web/public/vendor/xterm-addon-serialize.min.js.gz +0 -0
- package/dist/web/public/vendor/xterm-addon-unicode11.min.js.gz +0 -0
- package/dist/web/public/vendor/xterm-addon-webgl.min.js.gz +0 -0
- package/dist/web/public/vendor/xterm-predictive-echo.ae5e3d5d.js.gz +0 -0
- package/dist/web/public/vendor/xterm-zerolag-input.0b69623c.js.gz +0 -0
- package/dist/web/public/vendor/xterm.css.gz +0 -0
- package/dist/web/public/vendor/xterm.min.js.gz +0 -0
- package/dist/web/public/voice-input.2342c37b.js.gz +0 -0
- package/dist/web/public/voice-pcm-worklet.js.gz +0 -0
- package/dist/web/public/webview-tabs.js +12 -0
- package/dist/web/public/webview-tabs.js.br +0 -0
- package/dist/web/public/webview-tabs.js.gz +0 -0
- package/dist/web/route-helpers.d.ts +8 -0
- package/dist/web/route-helpers.d.ts.map +1 -1
- package/dist/web/route-helpers.js +8 -0
- package/dist/web/route-helpers.js.map +1 -1
- package/dist/web/routes/admin-routes.d.ts.map +1 -1
- package/dist/web/routes/admin-routes.js +4 -1
- package/dist/web/routes/admin-routes.js.map +1 -1
- package/dist/web/routes/approval-routes.d.ts.map +1 -1
- package/dist/web/routes/approval-routes.js +6 -8
- package/dist/web/routes/approval-routes.js.map +1 -1
- package/dist/web/routes/case-routes.js +1 -1
- package/dist/web/routes/case-routes.js.map +1 -1
- package/dist/web/routes/file-routes.d.ts +46 -1
- package/dist/web/routes/file-routes.d.ts.map +1 -1
- package/dist/web/routes/file-routes.js +214 -27
- package/dist/web/routes/file-routes.js.map +1 -1
- package/dist/web/routes/hook-event-routes.d.ts.map +1 -1
- package/dist/web/routes/hook-event-routes.js +8 -1
- package/dist/web/routes/hook-event-routes.js.map +1 -1
- package/dist/web/routes/html-view-routes.d.ts +60 -0
- package/dist/web/routes/html-view-routes.d.ts.map +1 -0
- package/dist/web/routes/html-view-routes.js +288 -0
- package/dist/web/routes/html-view-routes.js.map +1 -0
- package/dist/web/routes/index.d.ts +1 -0
- package/dist/web/routes/index.d.ts.map +1 -1
- package/dist/web/routes/index.js +1 -0
- package/dist/web/routes/index.js.map +1 -1
- package/dist/web/routes/reboot-restore-routes.js +2 -2
- package/dist/web/routes/reboot-restore-routes.js.map +1 -1
- package/dist/web/routes/session-routes.d.ts +1 -0
- package/dist/web/routes/session-routes.d.ts.map +1 -1
- package/dist/web/routes/session-routes.js +278 -56
- package/dist/web/routes/session-routes.js.map +1 -1
- package/dist/web/routes/status-telemetry-routes.d.ts.map +1 -1
- package/dist/web/routes/status-telemetry-routes.js +16 -2
- package/dist/web/routes/status-telemetry-routes.js.map +1 -1
- package/dist/web/schemas.d.ts +29 -0
- package/dist/web/schemas.d.ts.map +1 -1
- package/dist/web/schemas.js +65 -0
- package/dist/web/schemas.js.map +1 -1
- package/dist/web/server.d.ts +6 -1
- package/dist/web/server.d.ts.map +1 -1
- package/dist/web/server.js +62 -14
- package/dist/web/server.js.map +1 -1
- package/dist/web/sse-events.d.ts +5 -2
- package/dist/web/sse-events.d.ts.map +1 -1
- package/dist/web/sse-events.js +5 -2
- package/dist/web/sse-events.js.map +1 -1
- package/package.json +2 -1
- package/skills/codeman/SKILL.md +29 -12
- package/dist/web/public/app.6f8552e1.js +0 -43
- package/dist/web/public/app.6f8552e1.js.br +0 -0
- package/dist/web/public/app.6f8552e1.js.gz +0 -0
- package/dist/web/public/constants.bc9c1f63.js.br +0 -0
- package/dist/web/public/constants.bc9c1f63.js.gz +0 -0
- package/dist/web/public/i18n.a9840ea2.js +0 -2
- package/dist/web/public/i18n.a9840ea2.js.br +0 -0
- package/dist/web/public/i18n.a9840ea2.js.gz +0 -0
- package/dist/web/public/image-input.e00471c6.js.br +0 -0
- package/dist/web/public/image-input.e00471c6.js.gz +0 -0
- package/dist/web/public/keyboard-accessory.c1e7c7b7.js.br +0 -0
- package/dist/web/public/keyboard-accessory.c1e7c7b7.js.gz +0 -0
- package/dist/web/public/mobile.111b187d.css +0 -1
- package/dist/web/public/mobile.111b187d.css.br +0 -0
- package/dist/web/public/mobile.111b187d.css.gz +0 -0
- package/dist/web/public/panels-ui.71846fcb.js.br +0 -0
- package/dist/web/public/panels-ui.71846fcb.js.gz +0 -0
- package/dist/web/public/session-ui.f731602c.js.br +0 -0
- package/dist/web/public/session-ui.f731602c.js.gz +0 -0
- package/dist/web/public/settings-ui.4e33390f.js.br +0 -0
- package/dist/web/public/settings-ui.4e33390f.js.gz +0 -0
- package/dist/web/public/spreadsheet-preview.af82fa2f.js.br +0 -0
- package/dist/web/public/spreadsheet-preview.af82fa2f.js.gz +0 -0
- package/dist/web/public/styles.81a72906.css +0 -1
- package/dist/web/public/styles.81a72906.css.br +0 -0
- package/dist/web/public/styles.81a72906.css.gz +0 -0
- package/dist/web/public/tab-layout-browser.065fcba4.js +0 -1
- package/dist/web/public/tab-layout-browser.065fcba4.js.br +0 -0
- package/dist/web/public/tab-layout-browser.065fcba4.js.gz +0 -0
- package/dist/web/public/tab-rail-resize.a5867793.js.br +0 -0
- package/dist/web/public/tab-rail-resize.a5867793.js.gz +0 -0
- package/dist/web/public/terminal-ui.b7267005.js +0 -2
- package/dist/web/public/terminal-ui.b7267005.js.br +0 -0
- package/dist/web/public/terminal-ui.b7267005.js.gz +0 -0
|
@@ -14,6 +14,69 @@
|
|
|
14
14
|
Object.assign(CodemanApp.prototype, {
|
|
15
15
|
|
|
16
16
|
initImageInput() {
|
|
17
|
+
// Phone toolbar Attach (index.html): the tap lands on the file INPUT, which
|
|
18
|
+
// sits invisibly over the button, and the browser opens the picker itself.
|
|
19
|
+
//
|
|
20
|
+
// Nothing here may open the picker from script. While the keyboard is up,
|
|
21
|
+
// app.js's keyboard tap shim cancels every touch on a toolbar BUTTON and
|
|
22
|
+
// re-dispatches it as a scripted click, and iOS will not open a file picker
|
|
23
|
+
// from an untrusted click: measured on iOS 17, `isTrusted: false` two
|
|
24
|
+
// milliseconds after pointerdown, no picker, no error, and no real click after
|
|
25
|
+
// it either because the gesture was cancelled. A native tap on the input is not
|
|
26
|
+
// a button tap, so the shim leaves it alone and the click stays trusted. It also
|
|
27
|
+
// anchors the picker popover to the input's own frame (a `hidden` input has
|
|
28
|
+
// none, which is why the composer's picker floated loose).
|
|
29
|
+
//
|
|
30
|
+
// Cancelling mousedown's default keeps focus on the terminal's hidden textarea,
|
|
31
|
+
// so the fixed toolbar never reflows out from under the finger mid-tap.
|
|
32
|
+
//
|
|
33
|
+
// It does NOT keep the keyboard up, and nothing here can: iOS resigns first
|
|
34
|
+
// responder to present the picker, and on DEVICE it does not hand the keyboard
|
|
35
|
+
// back when the picker closes, even though focus never left the textarea.
|
|
36
|
+
// (An iOS 27 simulator does hand it back, which is a simulator artifact, so do
|
|
37
|
+
// not take a keyboard measurement from one.) A blur-then-focus on the close
|
|
38
|
+
// of the picker, cancel and change alike, restores DOM focus and still leaves
|
|
39
|
+
// the keyboard down, because iOS only raises it inside a user gesture. So the
|
|
40
|
+
// user taps the prompt when ready to type, which is the keyboard policy
|
|
41
|
+
// everywhere else in the app.
|
|
42
|
+
//
|
|
43
|
+
// Do not try to hide the keyboard's exit by freezing the page's keyboard
|
|
44
|
+
// state across the picker. That was tried (holdKeyboardState, reverted) to
|
|
45
|
+
// avoid the reflow and the two PTY resizes the hide/show pair costs: with the
|
|
46
|
+
// keyboard gone and the layout still keyboard-sized, the toolbar and accessory
|
|
47
|
+
// bar strand in the MIDDLE of the screen over a dead black band, which is far
|
|
48
|
+
// worse than the reflow. The page must follow the keyboard out.
|
|
49
|
+
const attachBtn = document.getElementById('attachBtnMobile');
|
|
50
|
+
const attachInput = document.getElementById('attachFileInput');
|
|
51
|
+
if (attachBtn && attachInput) {
|
|
52
|
+
attachInput.addEventListener('mousedown', (event) => event.preventDefault());
|
|
53
|
+
// The button is the ACCESSIBLE control (the input is aria-hidden and not
|
|
54
|
+
// tabbable), so a keyboard or VoiceOver activation arrives here instead of on
|
|
55
|
+
// the input. That click is trusted, so opening the picker from it is allowed.
|
|
56
|
+
attachBtn.addEventListener('click', () => attachInput.click());
|
|
57
|
+
attachInput.addEventListener('click', (event) => {
|
|
58
|
+
if (!this.activeSessionId) {
|
|
59
|
+
event.preventDefault(); // refuse before the picker opens, not after a pick
|
|
60
|
+
this.showToast('Open a session to attach a file', 'error');
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
// Captured before the picker opens: the session can be deleted while it is
|
|
64
|
+
// up, and the pick must not land on whatever replaced it.
|
|
65
|
+
this._attachSessionId = this.activeSessionId;
|
|
66
|
+
});
|
|
67
|
+
attachInput.addEventListener('change', () => {
|
|
68
|
+
const files = Array.from(attachInput.files || []);
|
|
69
|
+
// Reset so picking the same file again still fires change.
|
|
70
|
+
attachInput.value = '';
|
|
71
|
+
// Captured when the picker opened (see the click handler above).
|
|
72
|
+
const sessionId = this._attachSessionId;
|
|
73
|
+
this._attachSessionId = null;
|
|
74
|
+
if (files.length > 0) {
|
|
75
|
+
void this._attachFromToolbar(files, sessionId).catch((err) => console.warn('Attach failed:', err));
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
|
|
17
80
|
// Drag-and-drop handlers on terminal container
|
|
18
81
|
const container = document.getElementById('terminalContainer');
|
|
19
82
|
if (!container) return;
|
|
@@ -38,15 +101,100 @@ Object.assign(CodemanApp.prototype, {
|
|
|
38
101
|
if (!this.activeSessionId) return;
|
|
39
102
|
if (!e.dataTransfer || !e.dataTransfer.files.length) return;
|
|
40
103
|
|
|
41
|
-
const
|
|
42
|
-
if (
|
|
43
|
-
this.showToast('Only image files are supported', 'error');
|
|
104
|
+
const mediaFiles = Array.from(e.dataTransfer.files).filter((f) => this._promptAttachKind(f));
|
|
105
|
+
if (mediaFiles.length === 0) {
|
|
106
|
+
this.showToast('Only image or video files are supported', 'error');
|
|
44
107
|
return;
|
|
45
108
|
}
|
|
46
|
-
this._uploadAndInsertImages(
|
|
109
|
+
this._uploadAndInsertImages(mediaFiles);
|
|
47
110
|
});
|
|
48
111
|
},
|
|
49
112
|
|
|
113
|
+
/** Upload the toolbar Attach selection and put the paths on the prompt. The
|
|
114
|
+
* Compose dialog is deliberately not involved (see initImageInput).
|
|
115
|
+
*
|
|
116
|
+
* With local echo on (every phone by default) the paths go into the OVERLAY as
|
|
117
|
+
* pending text rather than to the PTY. That is what makes them part of "what the
|
|
118
|
+
* user typed": they paint at the prompt, anything typed after them appends in
|
|
119
|
+
* order, Enter flushes the whole line, and opening Compose adopts path and prose
|
|
120
|
+
* together (_takePendingLocalEcho reads exactly this buffer). Writing to the PTY
|
|
121
|
+
* instead would strand the path on the terminal while Compose took only the prose.
|
|
122
|
+
* Without the overlay (local echo off) there is nothing to buffer into, so the
|
|
123
|
+
* text goes straight out. The trailing space keeps the next word off the path. */
|
|
124
|
+
async _attachFromToolbar(files, sessionId) {
|
|
125
|
+
const media = files.filter((f) => this._promptAttachKind(f));
|
|
126
|
+
if (media.length === 0) {
|
|
127
|
+
this.showToast('Only image or video files are supported', 'error');
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
if (!sessionId) return; // no captured session: refuse rather than guess at one
|
|
131
|
+
const paths = await this._uploadAndInsertImages(media, { insert: false, sessionId });
|
|
132
|
+
if (paths.length === 0) return;
|
|
133
|
+
// Deleted while the upload ran: a write would go to a dead session, and the
|
|
134
|
+
// flushed maps below would gain an entry whose cleanup has already run.
|
|
135
|
+
if (this.sessions && !this.sessions.has(sessionId)) return;
|
|
136
|
+
const text = paths.join(' ');
|
|
137
|
+
|
|
138
|
+
// The prompt composer, if it opened for this session while the upload ran, is
|
|
139
|
+
// where the prompt now lives: it took the terminal's pending text with it, so
|
|
140
|
+
// appending behind it would strand the path outside the text being composed.
|
|
141
|
+
// _insertComposerText adds its own separator and fires the draft save.
|
|
142
|
+
const openComposer = KeyboardAccessoryBar._composerOverlay;
|
|
143
|
+
const composerTextarea =
|
|
144
|
+
openComposer?.isConnected && openComposer.dataset.sessionId === sessionId
|
|
145
|
+
? openComposer.querySelector('.prompt-composer-textarea')
|
|
146
|
+
: null;
|
|
147
|
+
if (composerTextarea) {
|
|
148
|
+
KeyboardAccessoryBar._insertComposerText(composerTextarea, text);
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
const stillActive = this.activeSessionId === sessionId;
|
|
153
|
+
// The overlay holds the prompt only while local echo actually owns it. A
|
|
154
|
+
// session handed back to plain PTY echo by a composer nav key (echo
|
|
155
|
+
// passthrough) skips the whole overlay branch in onData, Enter included, so
|
|
156
|
+
// text buffered there would sit on screen and never be submitted. Nor while
|
|
157
|
+
// the tile grid owns the terminal area: the main terminal is parked and
|
|
158
|
+
// hidden then, and a tile's Enter never reaches its overlay, so the path
|
|
159
|
+
// goes to the PTY like any other background write.
|
|
160
|
+
const overlayOwnsPrompt =
|
|
161
|
+
stillActive &&
|
|
162
|
+
!this._tilesOwnTerminal?.() &&
|
|
163
|
+
this._localEchoEnabled &&
|
|
164
|
+
this._localEchoOverlay &&
|
|
165
|
+
!this._echoPassthroughSessions?.has(sessionId);
|
|
166
|
+
if (overlayOwnsPrompt) {
|
|
167
|
+
// Prompt text the overlay has not adopted yet (a tab completion, a restored
|
|
168
|
+
// tab) only lands in its flushed half once detection runs, and appendText
|
|
169
|
+
// runs it AFTER we would have measured. Detect first, or the separator is
|
|
170
|
+
// computed against an empty string and the path fuses onto a real word.
|
|
171
|
+
if (!this._localEchoOverlay.pendingText && !this._localEchoOverlay.getFlushed().count) {
|
|
172
|
+
this._localEchoOverlay.detectBufferText();
|
|
173
|
+
}
|
|
174
|
+
const flushed = this._localEchoOverlay.getFlushed().text || '';
|
|
175
|
+
const prompt = flushed + (this._localEchoOverlay.pendingText || '');
|
|
176
|
+
const gap = prompt && !/\s$/.test(prompt) ? ' ' : '';
|
|
177
|
+
this._localEchoOverlay.appendText(gap + text + ' ');
|
|
178
|
+
} else {
|
|
179
|
+
// No buffer to measure, so lead with a separator unconditionally rather than
|
|
180
|
+
// risk fusing onto whatever the CLI's own composer already holds.
|
|
181
|
+
const out = ` ${text} `;
|
|
182
|
+
this._sendInputAsync(sessionId, out);
|
|
183
|
+
// A background session's prompt is tracked in the flushed maps, which is what
|
|
184
|
+
// a later composer open adopts and erases. An untracked write leaves that
|
|
185
|
+
// count short, so the erase would eat the tail of this path instead. Not for
|
|
186
|
+
// a passthrough session: its cursor can sit mid-text, nothing tracks its
|
|
187
|
+
// composer, and Enter there never clears the maps, so a record would offset
|
|
188
|
+
// the overlay for the next prompt instead.
|
|
189
|
+
if (!stillActive && !this._echoPassthroughSessions?.has(sessionId)) {
|
|
190
|
+
if (!this._flushedOffsets) this._flushedOffsets = new Map();
|
|
191
|
+
if (!this._flushedTexts) this._flushedTexts = new Map();
|
|
192
|
+
this._flushedTexts.set(sessionId, (this._flushedTexts.get(sessionId) || '') + out);
|
|
193
|
+
this._flushedOffsets.set(sessionId, (this._flushedOffsets.get(sessionId) || 0) + out.length);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
},
|
|
197
|
+
|
|
50
198
|
// Called from customKeyEventHandler in terminal-ui.js on Ctrl+V keydown.
|
|
51
199
|
// Creates a hidden paste trap, lets the browser paste into it, then inspects
|
|
52
200
|
// the result for images. Works on plain HTTP (no Clipboard API needed).
|
|
@@ -82,15 +230,13 @@ Object.assign(CodemanApp.prototype, {
|
|
|
82
230
|
if (pasteConsumed) return;
|
|
83
231
|
pasteConsumed = true;
|
|
84
232
|
|
|
85
|
-
// Check for images in clipboard items
|
|
233
|
+
// Check for images or videos in clipboard items
|
|
86
234
|
var imageFiles = [];
|
|
87
235
|
var items = e.clipboardData && e.clipboardData.items;
|
|
88
236
|
if (items) {
|
|
89
237
|
for (var i = 0; i < items.length; i++) {
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
if (blob) imageFiles.push(blob);
|
|
93
|
-
}
|
|
238
|
+
var blob = items[i].getAsFile();
|
|
239
|
+
if (blob && self._promptAttachKind(blob)) imageFiles.push(blob);
|
|
94
240
|
}
|
|
95
241
|
}
|
|
96
242
|
|
|
@@ -120,6 +266,21 @@ Object.assign(CodemanApp.prototype, {
|
|
|
120
266
|
document.execCommand('paste');
|
|
121
267
|
},
|
|
122
268
|
|
|
269
|
+
/** What a pick or a paste may upload: 'image', or 'video' for the camera
|
|
270
|
+
* roll's clips (the server streams those to disk under their own cap), else
|
|
271
|
+
* null. The one filter behind Attach, drop, the Compose and paste-dialog
|
|
272
|
+
* pickers and the clipboard handlers. The MIME type decides; some Android
|
|
273
|
+
* file managers hand over a File with none, so the name's extension is the
|
|
274
|
+
* fallback, mirroring the server's own allowlists. */
|
|
275
|
+
_promptAttachKind(file) {
|
|
276
|
+
if (file.type.startsWith('image/')) return 'image';
|
|
277
|
+
if (file.type.startsWith('video/')) return 'video';
|
|
278
|
+
const ext = (file.name || '').toLowerCase().match(/\.([a-z0-9]+)$/)?.[1] || '';
|
|
279
|
+
if (['png', 'jpg', 'jpeg', 'gif', 'webp', 'bmp', 'heic', 'heif'].includes(ext)) return 'image';
|
|
280
|
+
if (['mp4', 'webm', 'mov', 'm4v', 'ogv'].includes(ext)) return 'video';
|
|
281
|
+
return null;
|
|
282
|
+
},
|
|
283
|
+
|
|
123
284
|
// Max images accepted in one batch (paste / drop / mobile picker). Each is
|
|
124
285
|
// uploaded as its own request, so 20 stays under the server's 30 uploads/min
|
|
125
286
|
// rate limit while covering "select a bunch of photos at once".
|
|
@@ -136,6 +297,7 @@ Object.assign(CodemanApp.prototype, {
|
|
|
136
297
|
async _uploadAndInsertImages(fileList, options = {}) {
|
|
137
298
|
const sessionId = options.sessionId || this.activeSessionId;
|
|
138
299
|
if (!sessionId) return [];
|
|
300
|
+
if (options.sessionId && this.sessions && !this.sessions.has(sessionId)) return [];
|
|
139
301
|
|
|
140
302
|
let files = Array.from(fileList || []);
|
|
141
303
|
if (files.length === 0) return [];
|
|
@@ -153,7 +315,7 @@ Object.assign(CodemanApp.prototype, {
|
|
|
153
315
|
let failReason = ''; // first server reason, shown in the toast so a failure is not just a count
|
|
154
316
|
const results = new Array(total); // preserve selection order for insertion
|
|
155
317
|
const progress = () =>
|
|
156
|
-
this.showToast(`Uploading ${Math.min(done + 1, total)}/${total}
|
|
318
|
+
this.showToast(`Uploading ${Math.min(done + 1, total)}/${total} file${total > 1 ? 's' : ''}…`, 'info');
|
|
157
319
|
progress();
|
|
158
320
|
|
|
159
321
|
// Bounded-concurrency worker pool over the file list.
|
|
@@ -197,11 +359,11 @@ Object.assign(CodemanApp.prototype, {
|
|
|
197
359
|
|
|
198
360
|
// Final status: successes, plus any failures / cap so nothing is silent.
|
|
199
361
|
const parts = [];
|
|
200
|
-
if (paths.length > 0) parts.push(`${paths.length}
|
|
362
|
+
if (paths.length > 0) parts.push(`${paths.length} file${paths.length > 1 ? 's' : ''} ready`);
|
|
201
363
|
if (failed > 0) parts.push(failReason ? `${failed} failed: ${failReason}` : `${failed} failed`);
|
|
202
364
|
if (capped) parts.push(`max ${this._maxBatchImages} per batch`);
|
|
203
365
|
const tone = paths.length > 0 ? (failed > 0 || capped ? 'info' : 'success') : 'error';
|
|
204
|
-
this.showToast(parts.join(' · ') || 'No
|
|
366
|
+
this.showToast(parts.join(' · ') || 'No files uploaded', tone);
|
|
205
367
|
return paths;
|
|
206
368
|
},
|
|
207
369
|
|
|
@@ -209,7 +371,10 @@ Object.assign(CodemanApp.prototype, {
|
|
|
209
371
|
const form = new FormData();
|
|
210
372
|
form.append('image', file);
|
|
211
373
|
|
|
212
|
-
|
|
374
|
+
// A video takes the server's disk-streamed path and its larger cap; the flag
|
|
375
|
+
// has to ride the URL because the size budget is fixed before the part is read.
|
|
376
|
+
const kind = this._promptAttachKind(file) === 'video' ? '?kind=video' : '';
|
|
377
|
+
const resp = await fetch('/api/sessions/' + sessionId + '/paste-image' + kind, {
|
|
213
378
|
method: 'POST',
|
|
214
379
|
body: form,
|
|
215
380
|
});
|
|
@@ -231,9 +396,14 @@ Object.assign(CodemanApp.prototype, {
|
|
|
231
396
|
// decode/encode failure the original file is returned unchanged so the server
|
|
232
397
|
// still gets a chance (and logs a precise diagnostic).
|
|
233
398
|
async _normalizeImageForUpload(file) {
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
399
|
+
// Only an image goes through the canvas; a video is uploaded as picked. With no
|
|
400
|
+
// MIME (some Android file managers) the name's extension stands in, as it does in
|
|
401
|
+
// _promptAttachKind, so a .gif keeps its frames and a .png its transparency.
|
|
402
|
+
const name = (file.name || '').toLowerCase();
|
|
403
|
+
const isGif = file.type === 'image/gif' || (!file.type && name.endsWith('.gif'));
|
|
404
|
+
if (this._promptAttachKind(file) !== 'image' || isGif) return file;
|
|
405
|
+
|
|
406
|
+
const toPng = file.type === 'image/png' || (!file.type && name.endsWith('.png'));
|
|
237
407
|
const url = URL.createObjectURL(file);
|
|
238
408
|
try {
|
|
239
409
|
const img = new Image();
|
|
Binary file
|
|
Binary file
|
|
@@ -16,8 +16,8 @@
|
|
|
16
16
|
<link rel="manifest" href="manifest.json">
|
|
17
17
|
<title>Codeman</title>
|
|
18
18
|
<link rel="icon" type="image/svg+xml" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'%3E%3Cdefs%3E%3ClinearGradient id='g' x1='0%25' y1='0%25' x2='100%25' y2='100%25'%3E%3Cstop offset='0%25' stop-color='%2360a5fa'/%3E%3Cstop offset='100%25' stop-color='%233b82f6'/%3E%3C/linearGradient%3E%3C/defs%3E%3Crect width='32' height='32' rx='6' fill='%230a0a0a'/%3E%3Cpath d='M18 4L8 18h6l-2 10 10-14h-6z' fill='url(%23g)'/%3E%3C/svg%3E">
|
|
19
|
-
<link rel="stylesheet" href="styles.
|
|
20
|
-
<link rel="stylesheet" href="mobile.
|
|
19
|
+
<link rel="stylesheet" href="styles.900a28e4.css">
|
|
20
|
+
<link rel="stylesheet" href="mobile.2dff1580.css" media="(max-width: 1023px)">
|
|
21
21
|
<!-- xterm.css loaded async — terminal won't display until xterm.js runs anyway -->
|
|
22
22
|
<link rel="preload" href="vendor/xterm.css" as="style" onload="this.onload=null;this.rel='stylesheet'">
|
|
23
23
|
<noscript><link rel="stylesheet" href="vendor/xterm.css"></noscript>
|
|
@@ -27,8 +27,8 @@
|
|
|
27
27
|
<!-- Symbols font before the terminal first paints — a late-loading icon font
|
|
28
28
|
leaves tofu in xterm's glyph atlas until something forces a re-render. -->
|
|
29
29
|
<link rel="preload" href="fonts/symbols-nerd-font-mono.woff2" as="font" type="font/woff2" crossorigin>
|
|
30
|
-
<link rel="preload" href="constants.
|
|
31
|
-
<link rel="preload" href="app.
|
|
30
|
+
<link rel="preload" href="constants.17d77b65.js" as="script">
|
|
31
|
+
<link rel="preload" href="app.24689381.js" as="script">
|
|
32
32
|
<!-- Self-hosted xterm.js — eliminates CDN DNS/TLS latency (~100ms).
|
|
33
33
|
'defer' preserves execution order (xterm loads before fit addon). -->
|
|
34
34
|
<script defer src="vendor/xterm.min.js"></script>
|
|
@@ -614,7 +614,11 @@
|
|
|
614
614
|
<div class="file-preview-header">
|
|
615
615
|
<span class="file-preview-title" id="filePreviewTitle">file.ts</span>
|
|
616
616
|
<div class="file-preview-actions">
|
|
617
|
+
<button class="btn-icon-sm" id="filePreviewPrevBtn" onclick="app.stepFolderPreview(-1)" title="Previous file in folder (←)" aria-label="Previous file in folder" hidden>‹</button>
|
|
618
|
+
<button class="btn-icon-sm" id="filePreviewNextBtn" onclick="app.stepFolderPreview(1)" title="Next file in folder (→)" aria-label="Next file in folder" hidden>›</button>
|
|
619
|
+
<button class="btn-icon-sm" id="filePreviewFolderBtn" onclick="app.openFolderOfPreview()" title="Show folder" aria-label="Show folder" hidden><svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z"/></svg></button>
|
|
617
620
|
<button class="btn-icon-sm file-preview-pill" id="filePreviewMdBtn" onclick="app.toggleFilePreviewMd()" title="Rendered markdown" aria-label="Rendered markdown" aria-pressed="true" hidden>MD</button>
|
|
621
|
+
<button class="btn-icon-sm file-preview-pill" id="filePreviewPageBtn" onclick="app.toggleFilePreviewPage()" title="Rendered page" aria-label="Rendered page" aria-pressed="true" hidden>Page</button>
|
|
618
622
|
<button class="btn-icon-sm" id="filePreviewLinesBtn" onclick="app.toggleFilePreviewLines()" title="Line numbers" aria-label="Line numbers" aria-pressed="false" hidden><svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><line x1="10" y1="6" x2="21" y2="6"/><line x1="10" y1="12" x2="21" y2="12"/><line x1="10" y1="18" x2="21" y2="18"/><path d="M4 6h1v4"/><path d="M4 10h2"/><path d="M6 18H4c0-1 2-2 2-3s-1-1.5-2-1"/></svg></button>
|
|
619
623
|
<button class="btn-icon-sm" id="filePreviewWrapBtn" onclick="app.toggleFilePreviewWrap()" title="Wrap lines" aria-label="Wrap lines" aria-pressed="true" hidden><svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><line x1="3" y1="6" x2="21" y2="6"/><path d="M3 12h15a3 3 0 1 1 0 6h-4"/><polyline points="16 16 14 18 16 20"/><line x1="3" y1="18" x2="10" y2="18"/></svg></button>
|
|
620
624
|
<button class="btn-icon-sm file-preview-edit-btn" id="filePreviewEditBtn" onclick="app.enterFilePreviewEdit()" title="Edit file" aria-label="Edit file" hidden><svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M17 3a2.85 2.83 0 1 1 4 4L7.5 20.5 2 22l1.5-5.5z"/></svg></button>
|
|
@@ -634,6 +638,22 @@
|
|
|
634
638
|
</div>
|
|
635
639
|
</div>
|
|
636
640
|
|
|
641
|
+
<!-- Folder Grid: every previewable file of one folder (panels-ui.js openFolderGrid) -->
|
|
642
|
+
<div class="folder-grid-overlay" id="folderGridOverlay">
|
|
643
|
+
<div class="folder-grid-window">
|
|
644
|
+
<div class="file-preview-header">
|
|
645
|
+
<span class="file-preview-title" id="folderGridTitle" data-i18n-skip></span>
|
|
646
|
+
<div class="file-preview-actions">
|
|
647
|
+
<button class="btn-icon-sm" id="folderGridUpBtn" onclick="app.folderGridUp()" title="Parent folder" aria-label="Parent folder">↑</button>
|
|
648
|
+
<button class="btn-icon-sm" onclick="app.closeFolderGrid()" title="Close" aria-label="Close">×</button>
|
|
649
|
+
</div>
|
|
650
|
+
</div>
|
|
651
|
+
<div class="folder-grid-folders" id="folderGridFolders" data-i18n-skip></div>
|
|
652
|
+
<div class="folder-grid-body" id="folderGridBody" data-i18n-skip></div>
|
|
653
|
+
<div class="file-preview-footer" id="folderGridFooter" data-i18n-skip></div>
|
|
654
|
+
</div>
|
|
655
|
+
</div>
|
|
656
|
+
|
|
637
657
|
<!-- Response Viewer (mobile: native-scroll overlay for reading full Claude responses) -->
|
|
638
658
|
<div class="response-viewer" id="responseViewer">
|
|
639
659
|
<div class="response-viewer-header">
|
|
@@ -757,6 +777,21 @@
|
|
|
757
777
|
</div>
|
|
758
778
|
</div>
|
|
759
779
|
<!-- Mobile-only case button + gear -->
|
|
780
|
+
<!-- Phone-only Attach (wired in image-input.js): the button opens its own file input,
|
|
781
|
+
which sits invisibly over the button so iOS anchors the picker popover to it. The
|
|
782
|
+
Compose dialog is deliberately not involved: it focuses its textarea, which raises
|
|
783
|
+
the keyboard under the picker sheet. Sits BEFORE the mic so the two share order: 5
|
|
784
|
+
and source order keeps Attach on the left. -->
|
|
785
|
+
<span class="btn-attach-mobile-wrap">
|
|
786
|
+
<button type="button" class="btn-attach-mobile" id="attachBtnMobile" title="Attach" aria-label="Attach">
|
|
787
|
+
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true">
|
|
788
|
+
<rect x="3" y="3" width="18" height="18" rx="2"/>
|
|
789
|
+
<circle cx="8.5" cy="8.5" r="1.5"/>
|
|
790
|
+
<path d="m21 15-5-5L5 21"/>
|
|
791
|
+
</svg>
|
|
792
|
+
</button>
|
|
793
|
+
<input type="file" class="btn-attach-mobile-input" id="attachFileInput" accept="image/*,video/*" multiple tabindex="-1" aria-hidden="true">
|
|
794
|
+
</span>
|
|
760
795
|
<button class="btn-voice-mobile" id="voiceInputBtnMobile" onclick="VoiceInput.toggle()"
|
|
761
796
|
title="Voice input" aria-label="Start voice input" aria-pressed="false">
|
|
762
797
|
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
@@ -860,6 +895,7 @@
|
|
|
860
895
|
<div><kbd>Alt/Option</kbd>+<kbd>Shift</kbd>+<kbd>Arrows</kbd></div><div>Focus Tile Left / Right / Up / Down</div>
|
|
861
896
|
<div><kbd>Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>Arrows</kbd></div><div>Move Tile Left / Right / Up / Down</div>
|
|
862
897
|
<div><kbd>Drag</kbd> a tile's header</div><div>Move the Tile (onto Another: Swap)</div>
|
|
898
|
+
<div><kbd>Drag</kbd> a tile's header out of the window</div><div>Open the Tile in Its Own Window (Detach Tiles)</div>
|
|
863
899
|
<div><kbd>Alt/Option</kbd>+<kbd>Shift</kbd>+<kbd>Enter</kbd></div><div>Zoom Focused Tile</div>
|
|
864
900
|
<div><kbd>Ctrl/Cmd</kbd>+<kbd>Click</kbd> a tab</div><div>Add the Session to the Tile Grid</div>
|
|
865
901
|
<div><kbd>Right-click</kbd> the Tiles button</div><div>Choose How Many Tiles (2, 4 or 6)</div>
|
|
@@ -1286,6 +1322,22 @@
|
|
|
1286
1322
|
<!-- Hidden wholesale for non-claude sessions and for a session with
|
|
1287
1323
|
no live process (session-ui.js: openSessionOptions). -->
|
|
1288
1324
|
<div id="sessionRespawnSection">
|
|
1325
|
+
<!-- Claude Code (v2.1.251+) reports the main conversation's prompt-cache
|
|
1326
|
+
state on the statusline; the exporter keeps it per session and this
|
|
1327
|
+
row shows it live (session-ui.js: updatePromptCacheStatus). -->
|
|
1328
|
+
<div class="set-group">
|
|
1329
|
+
<div class="set-group-head"><h4>Prompt cache</h4></div>
|
|
1330
|
+
<p class="set-group-hint">While the cached conversation is warm, a turn re-reads it at the cheap cached rate. Once it sits idle past the cache lifetime, the next turn re-processes the whole context at the cache-write rate.</p>
|
|
1331
|
+
<div class="set-group-body">
|
|
1332
|
+
<div class="set-row">
|
|
1333
|
+
<div class="set-row-text">
|
|
1334
|
+
<span class="set-row-label">Status</span>
|
|
1335
|
+
<span class="set-row-desc" id="promptCacheStatus" data-i18n-skip>Not reported yet.</span>
|
|
1336
|
+
</div>
|
|
1337
|
+
</div>
|
|
1338
|
+
</div>
|
|
1339
|
+
</div>
|
|
1340
|
+
|
|
1289
1341
|
<div class="set-group">
|
|
1290
1342
|
<div class="set-group-head"><h4>Loop control</h4></div>
|
|
1291
1343
|
<div class="set-group-body">
|
|
@@ -1407,6 +1459,16 @@
|
|
|
1407
1459
|
<input type="text" id="modalSessionName" class="set-input" maxlength="128" placeholder="Auto (directory name)" onblur="app.saveSessionName()">
|
|
1408
1460
|
</div>
|
|
1409
1461
|
</div>
|
|
1462
|
+
<div class="set-row set-row-block">
|
|
1463
|
+
<div class="set-row-text">
|
|
1464
|
+
<span class="set-row-label">Working folder</span>
|
|
1465
|
+
<span class="set-row-desc" id="modalSessionPathDesc">Where this session's CLI runs, on the machine hosting Codeman.</span>
|
|
1466
|
+
</div>
|
|
1467
|
+
<div class="set-row-actions">
|
|
1468
|
+
<code id="modalSessionPath" class="set-static mono" style="flex: 1; min-width: 0; word-break: break-all; user-select: all;"></code>
|
|
1469
|
+
<button type="button" class="btn-toolbar btn-sm" id="modalSessionPathCopy" onclick="app.copySessionPath()">Copy</button>
|
|
1470
|
+
</div>
|
|
1471
|
+
</div>
|
|
1410
1472
|
<div class="set-row set-row-block">
|
|
1411
1473
|
<div class="set-row-text">
|
|
1412
1474
|
<span class="set-row-label">Session color</span>
|
|
@@ -2233,6 +2295,13 @@
|
|
|
2233
2295
|
</div>
|
|
2234
2296
|
<label class="switch switch-sm"><input type="checkbox" id="appSettingsShowTabDetachButton"><span class="slider"></span></label>
|
|
2235
2297
|
</div>
|
|
2298
|
+
<div class="set-row" id="appSettingsTileDetachItem" data-search="detach tiles tile pop out window drag move another window">
|
|
2299
|
+
<div class="set-row-text">
|
|
2300
|
+
<span class="set-row-label">Detach Tiles <span class="set-tag">desktop</span> <span class="set-tag set-tag-beta">beta</span></span>
|
|
2301
|
+
<span class="set-row-desc">Drag a tile's header out of the browser to open it in its own window, or onto another Codeman window's tiles to move it there. A popped-out window's title drags back onto tiles.</span>
|
|
2302
|
+
</div>
|
|
2303
|
+
<label class="switch switch-sm"><input type="checkbox" id="appSettingsTileDetach"><span class="slider"></span></label>
|
|
2304
|
+
</div>
|
|
2236
2305
|
<div class="set-row" id="appSettingsLineageLinesItem" data-search="lineage lines spawned worker parent connection">
|
|
2237
2306
|
<div class="set-row-text">
|
|
2238
2307
|
<span class="set-row-label">Spawn Lineage Lines <span class="set-tag">desktop</span></span>
|
|
@@ -2247,6 +2316,13 @@
|
|
|
2247
2316
|
</div>
|
|
2248
2317
|
<label class="switch switch-sm"><input type="checkbox" id="appSettingsAutoNameSessions"><span class="slider"></span></label>
|
|
2249
2318
|
</div>
|
|
2319
|
+
<div class="set-row" id="appSettingsSpawnedTabsFollowParentItem" data-search="spawned child session follow parent tab group lineage move">
|
|
2320
|
+
<div class="set-row-text">
|
|
2321
|
+
<span class="set-row-label">Spawned Tabs Follow Their Parent <span class="set-tag">synced</span></span>
|
|
2322
|
+
<span class="set-row-desc">A session started by another one keeps following its parent's tab into its group and moves with it, until you move it by hand. Off: it starts next to its parent and stays where it is.</span>
|
|
2323
|
+
</div>
|
|
2324
|
+
<label class="switch switch-sm"><input type="checkbox" id="appSettingsSpawnedTabsFollowParent"><span class="slider"></span></label>
|
|
2325
|
+
</div>
|
|
2250
2326
|
<div class="set-row" id="appSettingsMobileOverviewItem" data-search="overview home screen phone logo">
|
|
2251
2327
|
<div class="set-row-text">
|
|
2252
2328
|
<span class="set-row-label">Overview Home Screen <span class="set-tag">phone</span></span>
|
|
@@ -2597,6 +2673,19 @@
|
|
|
2597
2673
|
</div>
|
|
2598
2674
|
</div>
|
|
2599
2675
|
|
|
2676
|
+
<div class="set-group" id="agentSkillGroup">
|
|
2677
|
+
<div class="set-group-head"><h4>All agent CLIs</h4><span class="set-scope">synced</span></div>
|
|
2678
|
+
<div class="set-group-body">
|
|
2679
|
+
<div class="set-row" data-search="agent skill codeman api workers codex gemini opencode pi grok deepseek omp antigravity">
|
|
2680
|
+
<div class="set-row-text">
|
|
2681
|
+
<span class="set-row-label">Codeman Agent Skill</span>
|
|
2682
|
+
<span class="set-row-desc">Write Codeman's agent skill into each new session's folder, where that CLI looks for skills, so the agent in it can start workers in any installed CLI, send them prompts and wait for results. Every CLI except Pi and a plain shell.</span>
|
|
2683
|
+
</div>
|
|
2684
|
+
<label class="switch switch-sm"><input type="checkbox" id="appSettingsAgentSkill"><span class="slider"></span></label>
|
|
2685
|
+
</div>
|
|
2686
|
+
</div>
|
|
2687
|
+
</div>
|
|
2688
|
+
|
|
2600
2689
|
<div class="set-group">
|
|
2601
2690
|
<div class="set-group-head"><h4>Claude</h4><span class="set-scope">synced</span></div>
|
|
2602
2691
|
<div class="set-group-body">
|
|
@@ -2633,13 +2722,6 @@
|
|
|
2633
2722
|
</div>
|
|
2634
2723
|
<label class="switch switch-sm"><input type="checkbox" id="appSettingsAgentTeams"><span class="slider"></span></label>
|
|
2635
2724
|
</div>
|
|
2636
|
-
<div class="set-row" data-search="agent skill codeman api workers">
|
|
2637
|
-
<div class="set-row-text">
|
|
2638
|
-
<span class="set-row-label">Codeman Agent Skill</span>
|
|
2639
|
-
<span class="set-row-desc">Let new sessions start workers, send prompts and wait for results over the API.</span>
|
|
2640
|
-
</div>
|
|
2641
|
-
<label class="switch switch-sm"><input type="checkbox" id="appSettingsAgentSkill"><span class="slider"></span></label>
|
|
2642
|
-
</div>
|
|
2643
2725
|
<div class="set-row" data-search="workspace hooks alerts approvals notifications settings.local.json">
|
|
2644
2726
|
<div class="set-row-text">
|
|
2645
2727
|
<span class="set-row-label">Workspace Hooks</span>
|
|
@@ -4089,12 +4171,12 @@
|
|
|
4089
4171
|
<div class="approvals-list"></div>
|
|
4090
4172
|
</div>
|
|
4091
4173
|
|
|
4092
|
-
<script defer src="constants.
|
|
4093
|
-
<script defer src="i18n.
|
|
4174
|
+
<script defer src="constants.17d77b65.js"></script>
|
|
4175
|
+
<script defer src="i18n.9afd8e4d.js"></script>
|
|
4094
4176
|
<script defer src="mobile-handlers.0ef9c311.js"></script>
|
|
4095
4177
|
<script defer src="voice-input.2342c37b.js"></script>
|
|
4096
4178
|
<script defer src="notification-manager.feb82c04.js"></script>
|
|
4097
|
-
<script defer src="keyboard-accessory.
|
|
4179
|
+
<script defer src="keyboard-accessory.c458eea8.js"></script>
|
|
4098
4180
|
<script defer src="input-cjk.8bc46081.js"></script>
|
|
4099
4181
|
<!-- Shows iOS Safari IME composition text inside the terminal. Must precede terminal-ui.js. -->
|
|
4100
4182
|
<script defer src="mobile-ime-preview.2dbaf262.js"></script>
|
|
@@ -4103,10 +4185,10 @@
|
|
|
4103
4185
|
<!-- Hardened markdown HTML sanitizer (wires DOMPurify). Must precede app.js. -->
|
|
4104
4186
|
<script defer src="sanitize-html.e7147e76.js"></script>
|
|
4105
4187
|
<!-- Owner tab layout projection (grouped vertical rail); pure, read by app.js. -->
|
|
4106
|
-
<script defer src="tab-layout-browser.
|
|
4107
|
-
<script defer src="app.
|
|
4108
|
-
<script defer src="tab-rail-resize.
|
|
4109
|
-
<script defer src="terminal-ui.
|
|
4188
|
+
<script defer src="tab-layout-browser.2d6189f7.js"></script>
|
|
4189
|
+
<script defer src="app.24689381.js"></script>
|
|
4190
|
+
<script defer src="tab-rail-resize.7157e0bd.js"></script>
|
|
4191
|
+
<script defer src="terminal-ui.858f5da5.js"></script>
|
|
4110
4192
|
<script defer src="terminal-tile.js"></script>
|
|
4111
4193
|
<script defer src="terminal-split.js"></script>
|
|
4112
4194
|
<script defer src="tile-grid.js"></script>
|
|
@@ -4114,14 +4196,14 @@
|
|
|
4114
4196
|
<script defer src="ralph-panel.b350e2ef.js"></script>
|
|
4115
4197
|
<script defer src="orchestrator-panel.js"></script>
|
|
4116
4198
|
<script defer src="cron-ui.js"></script>
|
|
4117
|
-
<script defer src="settings-ui.
|
|
4118
|
-
<script defer src="panels-ui.
|
|
4199
|
+
<script defer src="settings-ui.81ac264e.js"></script>
|
|
4200
|
+
<script defer src="panels-ui.73ec0137.js"></script>
|
|
4119
4201
|
<script defer src="readmymind-ui.js"></script>
|
|
4120
4202
|
<script defer src="ultracode-panel.js"></script>
|
|
4121
4203
|
<script defer src="approvals-ui.js"></script>
|
|
4122
4204
|
<script defer src="reboot-restore-ui.js"></script>
|
|
4123
4205
|
<script defer src="admin-ui.js"></script>
|
|
4124
|
-
<script defer src="session-ui.
|
|
4206
|
+
<script defer src="session-ui.dbc6819b.js"></script>
|
|
4125
4207
|
<script defer src="host-wake-ui.js"></script>
|
|
4126
4208
|
<script defer src="webview-tabs.js"></script>
|
|
4127
4209
|
<script defer src="mobile-overview.js"></script>
|
|
@@ -4133,7 +4215,7 @@
|
|
|
4133
4215
|
<script defer src="subagent-windows.07277a58.js"></script>
|
|
4134
4216
|
<script defer src="ultracode-windows.js"></script>
|
|
4135
4217
|
<script defer src="session-lineage.js"></script>
|
|
4136
|
-
<script defer src="image-input.
|
|
4137
|
-
<script defer src="spreadsheet-preview.
|
|
4218
|
+
<script defer src="image-input.9ed1d0d2.js"></script>
|
|
4219
|
+
<script defer src="spreadsheet-preview.75c751de.js"></script>
|
|
4138
4220
|
</body>
|
|
4139
4221
|
</html>
|
|
Binary file
|
|
Binary file
|
|
Binary file
|