aicodeman 1.40.0 → 1.41.0
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 +25 -7
- package/dist/cli-agent.d.ts +225 -0
- package/dist/cli-agent.d.ts.map +1 -0
- package/dist/cli-agent.js +767 -0
- package/dist/cli-agent.js.map +1 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +6 -30
- package/dist/cli.js.map +1 -1
- package/dist/codeman-credentials.d.ts +27 -0
- package/dist/codeman-credentials.d.ts.map +1 -0
- package/dist/codeman-credentials.js +66 -0
- package/dist/codeman-credentials.js.map +1 -0
- package/dist/config/cli-registry/schema.d.ts +2 -0
- package/dist/config/cli-registry/schema.d.ts.map +1 -1
- package/dist/config/cli-registry/schema.js +3 -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 +5 -0
- package/dist/config/cli-registry/stock.js.map +1 -1
- package/dist/config/cli-registry/types.d.ts +12 -1
- package/dist/config/cli-registry/types.d.ts.map +1 -1
- package/dist/git-clone.d.ts.map +1 -1
- package/dist/git-clone.js +4 -0
- package/dist/git-clone.js.map +1 -1
- package/dist/image-watcher.d.ts.map +1 -1
- package/dist/image-watcher.js +6 -2
- package/dist/image-watcher.js.map +1 -1
- package/dist/mcp-sync-targets.d.ts +34 -0
- package/dist/mcp-sync-targets.d.ts.map +1 -0
- package/dist/mcp-sync-targets.js +55 -0
- package/dist/mcp-sync-targets.js.map +1 -0
- package/dist/mcp-sync.d.ts +2 -1
- package/dist/mcp-sync.d.ts.map +1 -1
- package/dist/mcp-sync.js +62 -1
- package/dist/mcp-sync.js.map +1 -1
- package/dist/session.d.ts.map +1 -1
- package/dist/session.js +10 -4
- package/dist/session.js.map +1 -1
- package/dist/subagent-watcher.d.ts.map +1 -1
- package/dist/subagent-watcher.js +29 -6
- package/dist/subagent-watcher.js.map +1 -1
- package/dist/templates/case-template.md +2 -0
- package/dist/tmux-manager.d.ts +5 -0
- package/dist/tmux-manager.d.ts.map +1 -1
- package/dist/tmux-manager.js +47 -22
- package/dist/tmux-manager.js.map +1 -1
- package/dist/tui/tui-client.d.ts +3 -17
- package/dist/tui/tui-client.d.ts.map +1 -1
- package/dist/tui/tui-client.js +3 -44
- package/dist/tui/tui-client.js.map +1 -1
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +1 -0
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/process-exit-wait.d.ts +40 -0
- package/dist/utils/process-exit-wait.d.ts.map +1 -0
- package/dist/utils/process-exit-wait.js +68 -0
- package/dist/utils/process-exit-wait.js.map +1 -0
- package/dist/web/paste-image-gc.d.ts +46 -6
- package/dist/web/paste-image-gc.d.ts.map +1 -1
- package/dist/web/paste-image-gc.js +106 -32
- package/dist/web/paste-image-gc.js.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.6f8552e1.js +43 -0
- package/dist/web/public/app.6f8552e1.js.br +0 -0
- package/dist/web/public/app.6f8552e1.js.gz +0 -0
- package/dist/web/public/approvals-ui.js.gz +0 -0
- package/dist/web/public/{constants.c0f8f9de.js → constants.bc9c1f63.js} +295 -28
- package/dist/web/public/constants.bc9c1f63.js.br +0 -0
- package/dist/web/public/constants.bc9c1f63.js.gz +0 -0
- package/dist/web/public/cron-ui.js.gz +0 -0
- package/dist/web/public/entrance-animations.js +490 -43
- package/dist/web/public/entrance-animations.js.br +0 -0
- package/dist/web/public/entrance-animations.js.gz +0 -0
- package/dist/web/public/git-status-ui.js.gz +0 -0
- package/dist/web/public/home-sessions.js +2 -1
- package/dist/web/public/home-sessions.js.br +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.a9840ea2.js +2 -0
- 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.898a538b.js → image-input.e00471c6.js} +3 -1
- 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/index.html +128 -33
- 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.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.gz +0 -0
- package/dist/web/public/mobile.111b187d.css.gz +0 -0
- package/dist/web/public/{notification-manager.50bb87d8.js → notification-manager.feb82c04.js} +19 -2
- package/dist/web/public/notification-manager.feb82c04.js.br +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.4735dfc2.js → panels-ui.71846fcb.js} +1 -1
- 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/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.gz +0 -0
- package/dist/web/public/settings-ui.4e33390f.js +97 -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-worker.js.gz +0 -0
- package/dist/web/public/spreadsheet-preview.af82fa2f.js.gz +0 -0
- package/dist/web/public/spreadsheet-xlsx-core.js.gz +0 -0
- package/dist/web/public/styles.81a72906.css +1 -0
- package/dist/web/public/styles.81a72906.css.br +0 -0
- package/dist/web/public/styles.81a72906.css.gz +0 -0
- package/dist/web/public/{subagent-windows.e6ca799f.js → subagent-windows.07277a58.js} +7 -5
- package/dist/web/public/subagent-windows.07277a58.js.br +0 -0
- package/dist/web/public/subagent-windows.07277a58.js.gz +0 -0
- package/dist/web/public/sw.js +2 -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.065fcba4.js.gz +0 -0
- package/dist/web/public/tab-rail-resize.a5867793.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 +92 -15
- 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.b7267005.js +2 -0
- package/dist/web/public/terminal-ui.b7267005.js.br +0 -0
- package/dist/web/public/terminal-ui.b7267005.js.gz +0 -0
- package/dist/web/public/tile-grid.js +330 -119
- 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 +9 -6
- package/dist/web/public/ultracode-windows.js.br +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 +4 -0
- package/dist/web/public/vendor/xterm-zerolag-input.0b69623c.js.br +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.gz +0 -0
- package/dist/web/routes/cli-registry-routes.d.ts +23 -4
- package/dist/web/routes/cli-registry-routes.d.ts.map +1 -1
- package/dist/web/routes/cli-registry-routes.js +92 -7
- package/dist/web/routes/cli-registry-routes.js.map +1 -1
- package/dist/web/routes/mcp-sync-routes.d.ts +7 -2
- package/dist/web/routes/mcp-sync-routes.d.ts.map +1 -1
- package/dist/web/routes/mcp-sync-routes.js +10 -3
- package/dist/web/routes/mcp-sync-routes.js.map +1 -1
- package/dist/web/routes/reboot-restore-routes.js +1 -1
- package/dist/web/routes/reboot-restore-routes.js.map +1 -1
- package/dist/web/routes/session-routes.d.ts.map +1 -1
- package/dist/web/routes/session-routes.js +68 -35
- package/dist/web/routes/session-routes.js.map +1 -1
- package/dist/web/schemas.d.ts +3 -0
- package/dist/web/schemas.d.ts.map +1 -1
- package/dist/web/schemas.js +9 -0
- package/dist/web/schemas.js.map +1 -1
- package/dist/web/server.d.ts +1 -1
- package/dist/web/server.d.ts.map +1 -1
- package/dist/web/server.js +15 -10
- package/dist/web/server.js.map +1 -1
- package/package.json +4 -4
- package/skills/codeman/SKILL.md +6 -0
- package/README.zh-CN.md +0 -1147
- package/dist/web/public/app.abadc970.js +0 -43
- package/dist/web/public/app.abadc970.js.br +0 -0
- package/dist/web/public/app.abadc970.js.gz +0 -0
- package/dist/web/public/constants.c0f8f9de.js.br +0 -0
- package/dist/web/public/constants.c0f8f9de.js.gz +0 -0
- package/dist/web/public/i18n.a31747a9.js +0 -2
- package/dist/web/public/i18n.a31747a9.js.br +0 -0
- package/dist/web/public/i18n.a31747a9.js.gz +0 -0
- package/dist/web/public/image-input.898a538b.js.br +0 -0
- package/dist/web/public/image-input.898a538b.js.gz +0 -0
- package/dist/web/public/notification-manager.50bb87d8.js.br +0 -0
- package/dist/web/public/notification-manager.50bb87d8.js.gz +0 -0
- package/dist/web/public/panels-ui.4735dfc2.js.br +0 -0
- package/dist/web/public/panels-ui.4735dfc2.js.gz +0 -0
- package/dist/web/public/settings-ui.a97ab16f.js +0 -97
- package/dist/web/public/settings-ui.a97ab16f.js.br +0 -0
- package/dist/web/public/settings-ui.a97ab16f.js.gz +0 -0
- package/dist/web/public/styles.8ee12666.css +0 -1
- package/dist/web/public/styles.8ee12666.css.br +0 -0
- package/dist/web/public/styles.8ee12666.css.gz +0 -0
- package/dist/web/public/subagent-windows.e6ca799f.js.br +0 -0
- package/dist/web/public/subagent-windows.e6ca799f.js.gz +0 -0
- package/dist/web/public/terminal-ui.5059b30e.js +0 -2
- package/dist/web/public/terminal-ui.5059b30e.js.br +0 -0
- package/dist/web/public/terminal-ui.5059b30e.js.gz +0 -0
- package/dist/web/public/vendor/xterm-zerolag-input.bbb5f84c.js +0 -4
- package/dist/web/public/vendor/xterm-zerolag-input.bbb5f84c.js.br +0 -0
- package/dist/web/public/vendor/xterm-zerolag-input.bbb5f84c.js.gz +0 -0
|
@@ -55,6 +55,7 @@ import { scanCodexSessionsHistory, codexThreadBySessionId } from '../../codex-tr
|
|
|
55
55
|
import { getLastTranscriptResponse, isExternalCliTranscriptMode, parseExternalCliTranscript, selectLastAnsweredTurn, } from '../response-viewer-transcript.js';
|
|
56
56
|
import { readDeepSeekLastResponse } from '../../deepseek-transcript.js';
|
|
57
57
|
import { appendClaudeCustomTitle } from '../../claude-session-title.js';
|
|
58
|
+
import { UPLOADS_DIR } from '../paste-image-gc.js';
|
|
58
59
|
// Path to linked-cases registry (same file used by case-routes resolveCasePath)
|
|
59
60
|
const LINKED_CASES_FILE = dataPath('linked-cases.json');
|
|
60
61
|
const CODEMAN_CONFIG_DIR = getDataDir();
|
|
@@ -222,6 +223,58 @@ export function imageMagicMatchesExt(data, ext) {
|
|
|
222
223
|
return false;
|
|
223
224
|
}
|
|
224
225
|
}
|
|
226
|
+
/**
|
|
227
|
+
* Create or re-verify `{workingDir}/.codeman-uploads` for a prompt upload, or
|
|
228
|
+
* null when something other than a regular directory sits there. An agent or
|
|
229
|
+
* postinstall script could plant `.codeman-uploads -> ~/.ssh/` and redirect
|
|
230
|
+
* future writes outside workingDir: lstat (not stat) sees the symlink itself,
|
|
231
|
+
* and mkdir without `recursive` does not follow one for the leaf either;
|
|
232
|
+
* O_EXCL|O_NOFOLLOW on the file open makes the write itself symlink-safe.
|
|
233
|
+
* The folder ignores itself: a `.gitignore` of `*`, written once with O_EXCL,
|
|
234
|
+
* so the user's repository never sees uploads, their own ignore file is never
|
|
235
|
+
* touched, and a file already there is theirs and stays as it is.
|
|
236
|
+
*/
|
|
237
|
+
async function ensureUploadDir(workingDir) {
|
|
238
|
+
// workingDir is guaranteed to exist (live session).
|
|
239
|
+
const uploadDir = join(workingDir, UPLOADS_DIR);
|
|
240
|
+
try {
|
|
241
|
+
const dirStat = await fs.lstat(uploadDir);
|
|
242
|
+
if (dirStat.isSymbolicLink() || !dirStat.isDirectory())
|
|
243
|
+
return null;
|
|
244
|
+
}
|
|
245
|
+
catch (err) {
|
|
246
|
+
if (err.code !== 'ENOENT')
|
|
247
|
+
throw err;
|
|
248
|
+
try {
|
|
249
|
+
await fs.mkdir(uploadDir);
|
|
250
|
+
}
|
|
251
|
+
catch (mkErr) {
|
|
252
|
+
// Concurrent uploads (a batch of photos) race to create the dir — the
|
|
253
|
+
// losers get EEXIST. Treat an already-present REAL directory as success,
|
|
254
|
+
// but re-verify it isn't a symlink a racing actor planted.
|
|
255
|
+
if (mkErr.code !== 'EEXIST')
|
|
256
|
+
throw mkErr;
|
|
257
|
+
const raceStat = await fs.lstat(uploadDir);
|
|
258
|
+
if (raceStat.isSymbolicLink() || !raceStat.isDirectory())
|
|
259
|
+
return null;
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
const ignoreFile = join(uploadDir, '.gitignore');
|
|
263
|
+
try {
|
|
264
|
+
// 'wx' = O_CREAT|O_EXCL, which also fails on a symlink at the path.
|
|
265
|
+
await fs.writeFile(ignoreFile, '*\n', { flag: 'wx' });
|
|
266
|
+
}
|
|
267
|
+
catch (err) {
|
|
268
|
+
if (err.code === 'EEXIST')
|
|
269
|
+
return uploadDir;
|
|
270
|
+
// The create can succeed before the write fails (ENOSPC): an empty ignore
|
|
271
|
+
// file would read as the user's on the next upload, so take it back; its own
|
|
272
|
+
// failure must not replace the cause.
|
|
273
|
+
await fs.rm(ignoreFile, { force: true }).catch(() => { });
|
|
274
|
+
throw err;
|
|
275
|
+
}
|
|
276
|
+
return uploadDir;
|
|
277
|
+
}
|
|
225
278
|
// Per-(IP, sessionId) token bucket for paste-image. 30 requests/minute.
|
|
226
279
|
// Bucket map entries are pruned when they drift > 1h stale to bound memory
|
|
227
280
|
// against a flood of unique IP keys.
|
|
@@ -4557,6 +4610,16 @@ options = {}) {
|
|
|
4557
4610
|
return createErrorResponse(ApiErrorCode.INVALID_INPUT, 'Rate limit exceeded (30 uploads/min per session)');
|
|
4558
4611
|
}
|
|
4559
4612
|
const session = findSessionOrFail(ctx, id, req);
|
|
4613
|
+
// The file lands on THIS host under the session's working directory, which
|
|
4614
|
+
// for a remote (SSH) session is the remote path: the agent there could never
|
|
4615
|
+
// read it, and the write would land in a same-named local directory or fail.
|
|
4616
|
+
// An owned Docker case is fine, its workspace is bind-mounted at the same
|
|
4617
|
+
// absolute path; an adopted container (owned: false) mounts nothing, so its
|
|
4618
|
+
// agent reads the file only if the container exposes that host path.
|
|
4619
|
+
if (session.remote) {
|
|
4620
|
+
reply.code(400);
|
|
4621
|
+
return createErrorResponse(ApiErrorCode.INVALID_INPUT, 'Prompt uploads are not supported for remote (SSH) sessions');
|
|
4622
|
+
}
|
|
4560
4623
|
if (!req.isMultipart()) {
|
|
4561
4624
|
reply.code(400);
|
|
4562
4625
|
return createErrorResponse(ApiErrorCode.INVALID_INPUT, 'Expected multipart/form-data');
|
|
@@ -4646,41 +4709,11 @@ options = {}) {
|
|
|
4646
4709
|
reply.code(415);
|
|
4647
4710
|
return createErrorResponse(ApiErrorCode.INVALID_INPUT, `Image bytes do not match declared type ${ext}`);
|
|
4648
4711
|
}
|
|
4649
|
-
//
|
|
4650
|
-
|
|
4651
|
-
|
|
4652
|
-
|
|
4653
|
-
|
|
4654
|
-
// O_EXCL|O_NOFOLLOW on the file open so the write itself is symlink-safe.
|
|
4655
|
-
const imageDir = join(session.workingDir, '.claude-images');
|
|
4656
|
-
try {
|
|
4657
|
-
const dirStat = await fs.lstat(imageDir);
|
|
4658
|
-
if (dirStat.isSymbolicLink() || !dirStat.isDirectory()) {
|
|
4659
|
-
reply.code(403);
|
|
4660
|
-
return createErrorResponse(ApiErrorCode.INVALID_INPUT, '.claude-images is not a regular directory');
|
|
4661
|
-
}
|
|
4662
|
-
}
|
|
4663
|
-
catch (err) {
|
|
4664
|
-
if (err.code !== 'ENOENT')
|
|
4665
|
-
throw err;
|
|
4666
|
-
// Non-recursive mkdir: does not follow symlinks for the leaf.
|
|
4667
|
-
// session.workingDir is guaranteed to exist (live session).
|
|
4668
|
-
try {
|
|
4669
|
-
await fs.mkdir(imageDir);
|
|
4670
|
-
}
|
|
4671
|
-
catch (mkErr) {
|
|
4672
|
-
// Concurrent uploads (a batch of photos) race to create .claude-images —
|
|
4673
|
-
// the losers get EEXIST. Treat an already-present REAL directory as
|
|
4674
|
-
// success, but re-verify it isn't a symlink a racing actor planted
|
|
4675
|
-
// (preserve the symlink-safety guarantee above).
|
|
4676
|
-
if (mkErr.code !== 'EEXIST')
|
|
4677
|
-
throw mkErr;
|
|
4678
|
-
const raceStat = await fs.lstat(imageDir);
|
|
4679
|
-
if (raceStat.isSymbolicLink() || !raceStat.isDirectory()) {
|
|
4680
|
-
reply.code(403);
|
|
4681
|
-
return createErrorResponse(ApiErrorCode.INVALID_INPUT, '.claude-images is not a regular directory');
|
|
4682
|
-
}
|
|
4683
|
-
}
|
|
4712
|
+
// {workingDir}/.codeman-uploads/, see ensureUploadDir.
|
|
4713
|
+
const imageDir = await ensureUploadDir(session.workingDir);
|
|
4714
|
+
if (!imageDir) {
|
|
4715
|
+
reply.code(403);
|
|
4716
|
+
return createErrorResponse(ApiErrorCode.INVALID_INPUT, `${UPLOADS_DIR} is not a regular directory`);
|
|
4684
4717
|
}
|
|
4685
4718
|
// Date.now() collides on same-ms uploads from two tabs (last-write wins
|
|
4686
4719
|
// silently). Append 8 hex chars so concurrent pastes get distinct names.
|