refactor: split app.js into focused frontend modules (phase 5)

Extract 8 modules from the 15K-line app.js monolith:
- constants.js: shared constants, timing, escapeHtml(), extractSyncSegments()
- mobile-handlers.js: MobileDetection, KeyboardHandler, SwipeHandler
- voice-input.js: DeepgramProvider, VoiceInput
- notification-manager.js: NotificationManager class
- keyboard-accessory.js: KeyboardAccessoryBar, FocusTrap
- api-client.js: _api(), _apiJson(), _apiPost(), _apiDelete() helpers
- subagent-windows.js: 13 subagent window methods (open, close, drag, lines)
- vendor/xterm-zerolag-input.js: IIFE build replacing inlined copy

app.js reduced from ~15,200 to ~11,500 lines. All modules use global
scope with <script defer> ordering. Prototype extensions use
Object.assign(CodemanApp.prototype, {...}) pattern.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
arkon
2026-03-01 04:57:37 +01:00
co-authored by Claude Opus 4.6
parent e7a9cbe442
commit f44f0a912f
14 changed files with 4660 additions and 3800 deletions
+60
View File
@@ -0,0 +1,60 @@
// Codeman — Centralized API fetch helpers for CodemanApp
// Loaded after app.js (needs CodemanApp class defined)
Object.assign(CodemanApp.prototype, {
/**
* Send a JSON API request. Handles Content-Type, JSON serialization, and error swallowing.
* @param {string} path - API path (e.g., '/api/sessions/123/input')
* @param {object} [opts] - { method, body, signal }
* @returns {Promise<Response|null>} Response or null on error
*/
async _api(path, opts = {}) {
const { method = 'GET', body, signal } = opts;
const fetchOpts = { method, signal };
if (body !== undefined) {
fetchOpts.headers = { 'Content-Type': 'application/json' };
fetchOpts.body = JSON.stringify(body);
}
try {
const res = await fetch(path, fetchOpts);
return res;
} catch {
return null;
}
},
/**
* Send a JSON API request and parse the response as JSON.
* @param {string} path - API path
* @param {object} [opts] - { method, body, signal }
* @returns {Promise<any|null>} Parsed JSON or null on error
*/
async _apiJson(path, opts = {}) {
const res = await this._api(path, opts);
if (!res || !res.ok) return null;
try {
return await res.json();
} catch {
return null;
}
},
/**
* POST JSON to an API endpoint (most common pattern).
* @param {string} path - API path
* @param {object} body - JSON body
* @returns {Promise<Response|null>}
*/
async _apiPost(path, body) {
return this._api(path, { method: 'POST', body });
},
/**
* DELETE an API resource.
* @param {string} path - API path
* @returns {Promise<Response|null>}
*/
async _apiDelete(path) {
return this._api(path, { method: 'DELETE' });
},
});