aicodeman 0.9.3 → 0.9.5
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/dist/types/index.d.ts +1 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +1 -0
- package/dist/types/index.js.map +1 -1
- package/dist/types/update.d.ts +79 -0
- package/dist/types/update.d.ts.map +1 -0
- package/dist/types/update.js +16 -0
- package/dist/types/update.js.map +1 -0
- package/dist/web/middleware/auth.d.ts +18 -0
- 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/network-auth-policy.d.ts +38 -0
- package/dist/web/network-auth-policy.d.ts.map +1 -1
- package/dist/web/network-auth-policy.js +108 -0
- package/dist/web/network-auth-policy.js.map +1 -1
- package/dist/web/public/api-client.3adebdc2.js.gz +0 -0
- package/dist/web/public/app.c860ea08.js.gz +0 -0
- package/dist/web/public/{constants.cb6426c4.js → constants.5b68d2de.js} +39 -3
- package/dist/web/public/constants.5b68d2de.js.br +0 -0
- package/dist/web/public/constants.5b68d2de.js.gz +0 -0
- package/dist/web/public/image-input.7cade6a8.js.gz +0 -0
- package/dist/web/public/index.html +22 -4
- package/dist/web/public/index.html.br +0 -0
- package/dist/web/public/index.html.gz +0 -0
- package/dist/web/public/input-cjk.88082175.js.gz +0 -0
- package/dist/web/public/keyboard-accessory.cdfd8c04.js.gz +0 -0
- package/dist/web/public/mobile-handlers.1e2a8ef8.js.gz +0 -0
- package/dist/web/public/mobile.26dc30d6.css.gz +0 -0
- package/dist/web/public/notification-manager.9c984ac2.js.gz +0 -0
- package/dist/web/public/orchestrator-panel.js.gz +0 -0
- package/dist/web/public/{panels-ui.3e304caf.js → panels-ui.5192a2c0.js} +8 -8
- package/dist/web/public/panels-ui.5192a2c0.js.br +0 -0
- package/dist/web/public/panels-ui.5192a2c0.js.gz +0 -0
- package/dist/web/public/ralph-panel.61076370.js.gz +0 -0
- package/dist/web/public/ralph-wizard.52d533d2.js.gz +0 -0
- package/dist/web/public/respawn-ui.5377f958.js.gz +0 -0
- package/dist/web/public/session-ui.3e0cf024.js.gz +0 -0
- package/dist/web/public/{settings-ui.c06be9c3.js → settings-ui.da0621e1.js} +8 -8
- package/dist/web/public/settings-ui.da0621e1.js.br +0 -0
- package/dist/web/public/settings-ui.da0621e1.js.gz +0 -0
- package/dist/web/public/styles.e87cb785.css.gz +0 -0
- package/dist/web/public/subagent-windows.a366a4ad.js.gz +0 -0
- package/dist/web/public/sw.js.gz +0 -0
- package/dist/web/public/terminal-ui.37caa926.js.gz +0 -0
- package/dist/web/public/upload.html.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-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-zerolag-input.137ad9f0.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.085e9e73.js.gz +0 -0
- package/dist/web/routes/system-routes.d.ts.map +1 -1
- package/dist/web/routes/system-routes.js +30 -0
- package/dist/web/routes/system-routes.js.map +1 -1
- package/dist/web/routes/ws-routes.d.ts +2 -1
- package/dist/web/routes/ws-routes.d.ts.map +1 -1
- package/dist/web/routes/ws-routes.js +12 -1
- package/dist/web/routes/ws-routes.js.map +1 -1
- package/dist/web/self-update.d.ts +112 -0
- package/dist/web/self-update.d.ts.map +1 -0
- package/dist/web/self-update.js +518 -0
- package/dist/web/self-update.js.map +1 -0
- package/dist/web/server.d.ts +5 -0
- package/dist/web/server.d.ts.map +1 -1
- package/dist/web/server.js +45 -15
- package/dist/web/server.js.map +1 -1
- package/dist/web/sse-events.d.ts +5 -3
- package/dist/web/sse-events.d.ts.map +1 -1
- package/dist/web/sse-events.js +5 -3
- package/dist/web/sse-events.js.map +1 -1
- package/package.json +1 -1
- package/dist/web/public/constants.cb6426c4.js.br +0 -0
- package/dist/web/public/constants.cb6426c4.js.gz +0 -0
- package/dist/web/public/panels-ui.3e304caf.js.br +0 -0
- package/dist/web/public/panels-ui.3e304caf.js.gz +0 -0
- package/dist/web/public/settings-ui.c06be9c3.js.br +0 -0
- package/dist/web/public/settings-ui.c06be9c3.js.gz +0 -0
package/dist/types/index.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoDG;AAEH,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,WAAW,CAAC;AAC1B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,cAAc,CAAC;AAC7B,cAAc,YAAY,CAAC;AAC3B,cAAc,UAAU,CAAC;AACzB,cAAc,gBAAgB,CAAC;AAC/B,cAAc,kBAAkB,CAAC;AACjC,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC;AAC3B,cAAc,WAAW,CAAC;AAC1B,cAAc,WAAW,CAAC;AAC1B,cAAc,mBAAmB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoDG;AAEH,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,WAAW,CAAC;AAC1B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,cAAc,CAAC;AAC7B,cAAc,YAAY,CAAC;AAC3B,cAAc,UAAU,CAAC;AACzB,cAAc,gBAAgB,CAAC;AAC/B,cAAc,kBAAkB,CAAC;AACjC,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC;AAC3B,cAAc,WAAW,CAAC;AAC1B,cAAc,WAAW,CAAC;AAC1B,cAAc,mBAAmB,CAAC;AAClC,cAAc,aAAa,CAAC"}
|
package/dist/types/index.js
CHANGED
package/dist/types/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoDG;AAEH,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,WAAW,CAAC;AAC1B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,cAAc,CAAC;AAC7B,cAAc,YAAY,CAAC;AAC3B,cAAc,UAAU,CAAC;AACzB,cAAc,gBAAgB,CAAC;AAC/B,cAAc,kBAAkB,CAAC;AACjC,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC;AAC3B,cAAc,WAAW,CAAC;AAC1B,cAAc,WAAW,CAAC;AAC1B,cAAc,mBAAmB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoDG;AAEH,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,WAAW,CAAC;AAC1B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,cAAc,CAAC;AAC7B,cAAc,YAAY,CAAC;AAC3B,cAAc,UAAU,CAAC;AACzB,cAAc,gBAAgB,CAAC;AAC/B,cAAc,kBAAkB,CAAC;AACjC,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC;AAC3B,cAAc,WAAW,CAAC;AAC1B,cAAc,WAAW,CAAC;AAC1B,cAAc,mBAAmB,CAAC;AAClC,cAAc,aAAa,CAAC"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Types for the in-app self-updater.
|
|
3
|
+
*
|
|
4
|
+
* Codeman can update itself from the web UI (App Settings → Updates). The flow
|
|
5
|
+
* is driven by a detached `scripts/self-update.sh` that outlives the service
|
|
6
|
+
* restart it triggers, and a status file at `~/.codeman/update-status.json`
|
|
7
|
+
* (see `dataPath('update-status.json')`) that the browser polls across the
|
|
8
|
+
* restart boundary.
|
|
9
|
+
*
|
|
10
|
+
* Backend logic: `src/web/self-update.ts`. Routes: `src/web/routes/system-routes.ts`
|
|
11
|
+
* (`/api/system/update/check`, `POST /api/system/update`, `/api/system/update/status`).
|
|
12
|
+
*
|
|
13
|
+
* @module types/update
|
|
14
|
+
*/
|
|
15
|
+
/** Which init system supervises the running server (decides how we restart it). */
|
|
16
|
+
export type SupervisorKind = 'systemd' | 'launchd' | 'none';
|
|
17
|
+
/** How Codeman was installed — only `git` installs can self-update in place. */
|
|
18
|
+
export type InstallKind = 'git' | 'npm' | 'unknown';
|
|
19
|
+
/**
|
|
20
|
+
* Lifecycle of a single update run. `idle`/`completed`/`failed`/
|
|
21
|
+
* `completed-needs-manual-restart` are terminal; the rest are in-flight.
|
|
22
|
+
*/
|
|
23
|
+
export type UpdatePhase = 'idle' | 'queued' | 'preparing' | 'stashing' | 'fetching' | 'checkout' | 'installing' | 'building' | 'restarting' | 'completed' | 'completed-needs-manual-restart' | 'failed';
|
|
24
|
+
/** Persisted update progress, written atomically by the updater + boot reconcile. */
|
|
25
|
+
export interface UpdateStatus {
|
|
26
|
+
/** Nonce identifying this run; guards boot-reconcile against stale/foreign status. */
|
|
27
|
+
updateId: string;
|
|
28
|
+
phase: UpdatePhase;
|
|
29
|
+
/** Human-readable one-liner for the UI. */
|
|
30
|
+
message: string;
|
|
31
|
+
/** Version the server was on when the update started. */
|
|
32
|
+
fromVersion: string;
|
|
33
|
+
/** Target version (parsed from the release tag). */
|
|
34
|
+
toVersion?: string;
|
|
35
|
+
/** Target git tag, e.g. `codeman@0.9.4`. */
|
|
36
|
+
toTag?: string;
|
|
37
|
+
/** Commit the repo was on before the update, for rollback. */
|
|
38
|
+
prevSha?: string;
|
|
39
|
+
/** Name of the stash holding local changes (when the tree was dirty), else null. */
|
|
40
|
+
stashRef?: string | null;
|
|
41
|
+
supervisor?: SupervisorKind;
|
|
42
|
+
/** epoch ms — update start (freshness guard for boot reconcile). */
|
|
43
|
+
startedAt: number;
|
|
44
|
+
/** epoch ms — last write. */
|
|
45
|
+
updatedAt: number;
|
|
46
|
+
/** Populated on failure. */
|
|
47
|
+
error?: string;
|
|
48
|
+
/** Shown for the `none` supervisor — the command the user must run by hand. */
|
|
49
|
+
manualRestartCommand?: string;
|
|
50
|
+
}
|
|
51
|
+
/** Describes the running install — drives whether/how the Updates UI is shown. */
|
|
52
|
+
export interface InstallInfo {
|
|
53
|
+
installKind: InstallKind;
|
|
54
|
+
installDir: string;
|
|
55
|
+
/** Current git branch, or `HEAD` when detached (e.g. pinned to a release tag). */
|
|
56
|
+
branch?: string;
|
|
57
|
+
/** Uncommitted local changes present (true → updater will auto-stash). */
|
|
58
|
+
dirty: boolean;
|
|
59
|
+
supervisor: SupervisorKind;
|
|
60
|
+
currentVersion: string;
|
|
61
|
+
/** False when `CODEMAN_DISABLE_SELF_UPDATE=1`. */
|
|
62
|
+
selfUpdateEnabled: boolean;
|
|
63
|
+
}
|
|
64
|
+
/** Result of "check for updates" — current vs. latest release. */
|
|
65
|
+
export interface UpdateCheckResult {
|
|
66
|
+
currentVersion: string;
|
|
67
|
+
latestVersion: string | null;
|
|
68
|
+
latestTag: string | null;
|
|
69
|
+
updateAvailable: boolean;
|
|
70
|
+
/** Release notes (markdown) when available from the GitHub API. */
|
|
71
|
+
notes?: string | null;
|
|
72
|
+
/** Link to the release page. */
|
|
73
|
+
htmlUrl?: string | null;
|
|
74
|
+
/** epoch ms of the check. */
|
|
75
|
+
checkedAt: number;
|
|
76
|
+
source: 'github-api' | 'git-ls-remote' | 'none';
|
|
77
|
+
error?: string;
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=update.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"update.d.ts","sourceRoot":"","sources":["../../src/types/update.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,mFAAmF;AACnF,MAAM,MAAM,cAAc,GAAG,SAAS,GAAG,SAAS,GAAG,MAAM,CAAC;AAE5D,gFAAgF;AAChF,MAAM,MAAM,WAAW,GAAG,KAAK,GAAG,KAAK,GAAG,SAAS,CAAC;AAEpD;;;GAGG;AACH,MAAM,MAAM,WAAW,GACnB,MAAM,GACN,QAAQ,GACR,WAAW,GACX,UAAU,GACV,UAAU,GACV,UAAU,GACV,YAAY,GACZ,UAAU,GACV,YAAY,GACZ,WAAW,GACX,gCAAgC,GAChC,QAAQ,CAAC;AAEb,qFAAqF;AACrF,MAAM,WAAW,YAAY;IAC3B,sFAAsF;IACtF,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,WAAW,CAAC;IACnB,2CAA2C;IAC3C,OAAO,EAAE,MAAM,CAAC;IAChB,yDAAyD;IACzD,WAAW,EAAE,MAAM,CAAC;IACpB,oDAAoD;IACpD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,4CAA4C;IAC5C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,8DAA8D;IAC9D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,oFAAoF;IACpF,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,UAAU,CAAC,EAAE,cAAc,CAAC;IAC5B,oEAAoE;IACpE,SAAS,EAAE,MAAM,CAAC;IAClB,6BAA6B;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,4BAA4B;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,+EAA+E;IAC/E,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED,kFAAkF;AAClF,MAAM,WAAW,WAAW;IAC1B,WAAW,EAAE,WAAW,CAAC;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,kFAAkF;IAClF,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,0EAA0E;IAC1E,KAAK,EAAE,OAAO,CAAC;IACf,UAAU,EAAE,cAAc,CAAC;IAC3B,cAAc,EAAE,MAAM,CAAC;IACvB,kDAAkD;IAClD,iBAAiB,EAAE,OAAO,CAAC;CAC5B;AAED,kEAAkE;AAClE,MAAM,WAAW,iBAAiB;IAChC,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,eAAe,EAAE,OAAO,CAAC;IACzB,mEAAmE;IACnE,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,gCAAgC;IAChC,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,6BAA6B;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,YAAY,GAAG,eAAe,GAAG,MAAM,CAAC;IAChD,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Types for the in-app self-updater.
|
|
3
|
+
*
|
|
4
|
+
* Codeman can update itself from the web UI (App Settings → Updates). The flow
|
|
5
|
+
* is driven by a detached `scripts/self-update.sh` that outlives the service
|
|
6
|
+
* restart it triggers, and a status file at `~/.codeman/update-status.json`
|
|
7
|
+
* (see `dataPath('update-status.json')`) that the browser polls across the
|
|
8
|
+
* restart boundary.
|
|
9
|
+
*
|
|
10
|
+
* Backend logic: `src/web/self-update.ts`. Routes: `src/web/routes/system-routes.ts`
|
|
11
|
+
* (`/api/system/update/check`, `POST /api/system/update`, `/api/system/update/status`).
|
|
12
|
+
*
|
|
13
|
+
* @module types/update
|
|
14
|
+
*/
|
|
15
|
+
export {};
|
|
16
|
+
//# sourceMappingURL=update.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"update.js","sourceRoot":"","sources":["../../src/types/update.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG"}
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
import type { FastifyInstance } from 'fastify';
|
|
11
11
|
import { StaleExpirationMap } from '../../utils/index.js';
|
|
12
12
|
import type { AuthSessionRecord } from '../ports/auth-port.js';
|
|
13
|
+
import { type HostPolicy } from '../network-auth-policy.js';
|
|
13
14
|
export declare const AUTH_COOKIE_NAME = "codeman_session";
|
|
14
15
|
/** State returned from registerAuthMiddleware for cleanup in server stop() */
|
|
15
16
|
interface AuthState {
|
|
@@ -24,6 +25,23 @@ interface AuthState {
|
|
|
24
25
|
* @returns AuthState for lifecycle management (dispose on server stop)
|
|
25
26
|
*/
|
|
26
27
|
export declare function registerAuthMiddleware(app: FastifyInstance, https: boolean): AuthState;
|
|
28
|
+
/**
|
|
29
|
+
* Register the anti-DNS-rebinding Host allowlist + cross-site (CSRF) Origin guard.
|
|
30
|
+
*
|
|
31
|
+
* This protects the API even on the default no-password install, where there is no
|
|
32
|
+
* cookie/credential to gate on. It must be registered BEFORE the auth middleware so
|
|
33
|
+
* forged cross-site or DNS-rebound requests are rejected up front. `getPolicy` is
|
|
34
|
+
* evaluated per request so a tunnel started at runtime is reflected immediately.
|
|
35
|
+
*
|
|
36
|
+
* - Every request: the `Host` header must be in the allowlist (blocks DNS rebinding,
|
|
37
|
+
* where a custom domain is rebound to 127.0.0.1 but still sends its own name).
|
|
38
|
+
* - State-changing methods: the `Origin` (when the client sends one — i.e. a browser)
|
|
39
|
+
* must be same-site (blocks cross-site CSRF, including the text/plain simple-request
|
|
40
|
+
* trick). Non-browser clients (curl, Claude Code hooks) omit Origin and pass.
|
|
41
|
+
*
|
|
42
|
+
* WebSocket upgrades are validated separately in the ws route handler.
|
|
43
|
+
*/
|
|
44
|
+
export declare function registerHostGuard(app: FastifyInstance, getPolicy: () => HostPolicy): void;
|
|
27
45
|
/**
|
|
28
46
|
* Register security headers and CORS middleware on every response.
|
|
29
47
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../../src/web/middleware/auth.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAgB,MAAM,SAAS,CAAC;AAE7D,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../../src/web/middleware/auth.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAgB,MAAM,SAAS,CAAC;AAE7D,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,EAAgD,KAAK,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAS1G,eAAO,MAAM,gBAAgB,oBAAoB,CAAC;AAElD,8EAA8E;AAC9E,UAAU,SAAS;IACjB,YAAY,EAAE,kBAAkB,CAAC,MAAM,EAAE,iBAAiB,CAAC,GAAG,IAAI,CAAC;IACnE,YAAY,EAAE,kBAAkB,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC;IACxD,cAAc,EAAE,kBAAkB,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC;CAC3D;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,eAAe,EAAE,KAAK,EAAE,OAAO,GAAG,SAAS,CAwHtF;AAKD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,UAAU,GAAG,IAAI,CAazF;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,eAAe,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI,CAgDlF"}
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
*/
|
|
10
10
|
import { randomBytes, timingSafeEqual } from 'node:crypto';
|
|
11
11
|
import { StaleExpirationMap } from '../../utils/index.js';
|
|
12
|
+
import { isAllowedRequestHost, isAllowedRequestOrigin } from '../network-auth-policy.js';
|
|
12
13
|
import { AUTH_SESSION_TTL_MS, MAX_AUTH_SESSIONS, AUTH_FAILURE_MAX, AUTH_FAILURE_WINDOW_MS, } from '../../config/auth-config.js';
|
|
13
14
|
// Auth session cookie name
|
|
14
15
|
export const AUTH_COOKIE_NAME = 'codeman_session';
|
|
@@ -121,6 +122,38 @@ export function registerAuthMiddleware(app, https) {
|
|
|
121
122
|
});
|
|
122
123
|
return state;
|
|
123
124
|
}
|
|
125
|
+
/** Methods that don't change server state and so skip the cross-site Origin check. */
|
|
126
|
+
const SAFE_HTTP_METHODS = new Set(['GET', 'HEAD', 'OPTIONS']);
|
|
127
|
+
/**
|
|
128
|
+
* Register the anti-DNS-rebinding Host allowlist + cross-site (CSRF) Origin guard.
|
|
129
|
+
*
|
|
130
|
+
* This protects the API even on the default no-password install, where there is no
|
|
131
|
+
* cookie/credential to gate on. It must be registered BEFORE the auth middleware so
|
|
132
|
+
* forged cross-site or DNS-rebound requests are rejected up front. `getPolicy` is
|
|
133
|
+
* evaluated per request so a tunnel started at runtime is reflected immediately.
|
|
134
|
+
*
|
|
135
|
+
* - Every request: the `Host` header must be in the allowlist (blocks DNS rebinding,
|
|
136
|
+
* where a custom domain is rebound to 127.0.0.1 but still sends its own name).
|
|
137
|
+
* - State-changing methods: the `Origin` (when the client sends one — i.e. a browser)
|
|
138
|
+
* must be same-site (blocks cross-site CSRF, including the text/plain simple-request
|
|
139
|
+
* trick). Non-browser clients (curl, Claude Code hooks) omit Origin and pass.
|
|
140
|
+
*
|
|
141
|
+
* WebSocket upgrades are validated separately in the ws route handler.
|
|
142
|
+
*/
|
|
143
|
+
export function registerHostGuard(app, getPolicy) {
|
|
144
|
+
app.addHook('onRequest', (req, reply, done) => {
|
|
145
|
+
const policy = getPolicy();
|
|
146
|
+
if (!isAllowedRequestHost(req.headers.host, policy)) {
|
|
147
|
+
reply.code(403).send('Forbidden: host not allowed');
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
if (!SAFE_HTTP_METHODS.has(req.method) && !isAllowedRequestOrigin(req.headers.origin, policy)) {
|
|
151
|
+
reply.code(403).send('Forbidden: cross-site request blocked');
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
done();
|
|
155
|
+
});
|
|
156
|
+
}
|
|
124
157
|
/**
|
|
125
158
|
* Register security headers and CORS middleware on every response.
|
|
126
159
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../../src/web/middleware/auth.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../../src/web/middleware/auth.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,3 +1,41 @@
|
|
|
1
1
|
export declare function isExplicitlyEnabled(value: string | undefined): boolean;
|
|
2
2
|
export declare function isLoopbackBindHost(host: string): boolean;
|
|
3
|
+
/**
|
|
4
|
+
* Hostname suffixes that are always accepted by the Host/Origin allowlist. These
|
|
5
|
+
* are namespaces an external attacker cannot register DNS-rebinding records under
|
|
6
|
+
* (tailscale MagicDNS, Cloudflare quick/named tunnels), so accepting them keeps
|
|
7
|
+
* the project's documented tunnel access paths working without reopening the
|
|
8
|
+
* rebinding hole. Extend per-deployment via CODEMAN_ALLOWED_HOSTS.
|
|
9
|
+
*/
|
|
10
|
+
export declare const DEFAULT_TRUSTED_HOST_SUFFIXES: string[];
|
|
11
|
+
/** Policy inputs for the anti-DNS-rebinding Host allowlist + cross-site Origin guard. */
|
|
12
|
+
export interface HostPolicy {
|
|
13
|
+
/** The host the server is bound to (e.g. '127.0.0.1', '0.0.0.0', or a hostname). */
|
|
14
|
+
bindHost: string;
|
|
15
|
+
/** Extra allowed hosts: exact lowercased names, or a leading-dot '.suffix' for suffix matches. */
|
|
16
|
+
allowedHosts: string[];
|
|
17
|
+
/** Hostname of the currently-active Codeman-managed tunnel, if any. */
|
|
18
|
+
tunnelHost?: string | null;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Extract the lowercased hostname from a Host/authority value, stripping the port
|
|
22
|
+
* and IPv6 brackets. Returns null for empty/garbage input.
|
|
23
|
+
*/
|
|
24
|
+
export declare function parseAuthorityHostname(authority: string | undefined): string | null;
|
|
25
|
+
/** Build a HostPolicy from the bind host, CODEMAN_ALLOWED_HOSTS, and an active tunnel URL. */
|
|
26
|
+
export declare function buildHostPolicy(bindHost: string, tunnelUrl?: string | null): HostPolicy;
|
|
27
|
+
/**
|
|
28
|
+
* True if a request's Host header is allowed. Blocks DNS-rebinding: a custom
|
|
29
|
+
* domain rebound to a loopback/LAN address still carries its own name in Host,
|
|
30
|
+
* which will not be in the allowlist.
|
|
31
|
+
*/
|
|
32
|
+
export declare function isAllowedRequestHost(hostHeader: string | undefined, policy: HostPolicy): boolean;
|
|
33
|
+
/**
|
|
34
|
+
* True if a request's Origin is allowed for a state-changing / WebSocket request.
|
|
35
|
+
* A MISSING Origin is allowed: non-browser clients (curl, Claude Code hooks) omit
|
|
36
|
+
* it, while browsers always attach it on cross-origin state-changing/WS requests —
|
|
37
|
+
* so a forged cross-site request is caught while local automation keeps working.
|
|
38
|
+
* The opaque origin 'null' (sandboxed iframe, data: URL) is rejected.
|
|
39
|
+
*/
|
|
40
|
+
export declare function isAllowedRequestOrigin(originHeader: string | undefined, policy: HostPolicy): boolean;
|
|
3
41
|
//# sourceMappingURL=network-auth-policy.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"network-auth-policy.d.ts","sourceRoot":"","sources":["../../src/web/network-auth-policy.ts"],"names":[],"mappings":"AAIA,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAEtE;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAYxD"}
|
|
1
|
+
{"version":3,"file":"network-auth-policy.d.ts","sourceRoot":"","sources":["../../src/web/network-auth-policy.ts"],"names":[],"mappings":"AAIA,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAEtE;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAYxD;AAED;;;;;;GAMG;AACH,eAAO,MAAM,6BAA6B,UAAyD,CAAC;AAEpG,yFAAyF;AACzF,MAAM,WAAW,UAAU;IACzB,oFAAoF;IACpF,QAAQ,EAAE,MAAM,CAAC;IACjB,kGAAkG;IAClG,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,uEAAuE;IACvE,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAiBnF;AAED,8FAA8F;AAC9F,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,UAAU,CAcvF;AAwBD;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,EAAE,MAAM,EAAE,UAAU,GAAG,OAAO,CAIhG;AAED;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CAAC,YAAY,EAAE,MAAM,GAAG,SAAS,EAAE,MAAM,EAAE,UAAU,GAAG,OAAO,CAQpG"}
|
|
@@ -16,4 +16,112 @@ export function isLoopbackBindHost(host) {
|
|
|
16
16
|
}
|
|
17
17
|
return normalized.startsWith('::ffff:127.');
|
|
18
18
|
}
|
|
19
|
+
/**
|
|
20
|
+
* Hostname suffixes that are always accepted by the Host/Origin allowlist. These
|
|
21
|
+
* are namespaces an external attacker cannot register DNS-rebinding records under
|
|
22
|
+
* (tailscale MagicDNS, Cloudflare quick/named tunnels), so accepting them keeps
|
|
23
|
+
* the project's documented tunnel access paths working without reopening the
|
|
24
|
+
* rebinding hole. Extend per-deployment via CODEMAN_ALLOWED_HOSTS.
|
|
25
|
+
*/
|
|
26
|
+
export const DEFAULT_TRUSTED_HOST_SUFFIXES = ['.ts.net', '.trycloudflare.com', '.cfargotunnel.com'];
|
|
27
|
+
/**
|
|
28
|
+
* Extract the lowercased hostname from a Host/authority value, stripping the port
|
|
29
|
+
* and IPv6 brackets. Returns null for empty/garbage input.
|
|
30
|
+
*/
|
|
31
|
+
export function parseAuthorityHostname(authority) {
|
|
32
|
+
if (!authority)
|
|
33
|
+
return null;
|
|
34
|
+
let h = authority.trim();
|
|
35
|
+
if (!h)
|
|
36
|
+
return null;
|
|
37
|
+
if (h.startsWith('[')) {
|
|
38
|
+
// [::1] or [::1]:3000
|
|
39
|
+
const end = h.indexOf(']');
|
|
40
|
+
if (end === -1)
|
|
41
|
+
return null;
|
|
42
|
+
return h.slice(1, end).toLowerCase() || null;
|
|
43
|
+
}
|
|
44
|
+
// host:port — only treat a single trailing colon as a port separator so a
|
|
45
|
+
// bracketless IPv6 literal (multiple colons) is left intact.
|
|
46
|
+
const first = h.indexOf(':');
|
|
47
|
+
if (first !== -1 && first === h.lastIndexOf(':')) {
|
|
48
|
+
h = h.slice(0, first);
|
|
49
|
+
}
|
|
50
|
+
return h.toLowerCase() || null;
|
|
51
|
+
}
|
|
52
|
+
/** Build a HostPolicy from the bind host, CODEMAN_ALLOWED_HOSTS, and an active tunnel URL. */
|
|
53
|
+
export function buildHostPolicy(bindHost, tunnelUrl) {
|
|
54
|
+
const allowedHosts = (process.env.CODEMAN_ALLOWED_HOSTS || '')
|
|
55
|
+
.split(',')
|
|
56
|
+
.map((s) => s.trim().toLowerCase())
|
|
57
|
+
.filter(Boolean);
|
|
58
|
+
let tunnelHost = null;
|
|
59
|
+
if (tunnelUrl) {
|
|
60
|
+
try {
|
|
61
|
+
tunnelHost = new URL(tunnelUrl).hostname.toLowerCase();
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
tunnelHost = null;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return { bindHost, allowedHosts, tunnelHost };
|
|
68
|
+
}
|
|
69
|
+
function matchesHost(hostname, policy) {
|
|
70
|
+
// localhost is reserved (always resolves to loopback, not rebindable).
|
|
71
|
+
if (hostname === 'localhost')
|
|
72
|
+
return true;
|
|
73
|
+
// Any IP literal: a literal address cannot be the target of DNS rebinding — the
|
|
74
|
+
// browser connected straight to it, there is no name to re-point.
|
|
75
|
+
if (isIP(hostname) !== 0)
|
|
76
|
+
return true;
|
|
77
|
+
const bind = parseAuthorityHostname(policy.bindHost);
|
|
78
|
+
if (bind && hostname === bind)
|
|
79
|
+
return true;
|
|
80
|
+
if (policy.tunnelHost && hostname === policy.tunnelHost)
|
|
81
|
+
return true;
|
|
82
|
+
for (const suffix of DEFAULT_TRUSTED_HOST_SUFFIXES) {
|
|
83
|
+
if (hostname === suffix.slice(1) || hostname.endsWith(suffix))
|
|
84
|
+
return true;
|
|
85
|
+
}
|
|
86
|
+
for (const entry of policy.allowedHosts) {
|
|
87
|
+
if (entry.startsWith('.')) {
|
|
88
|
+
if (hostname === entry.slice(1) || hostname.endsWith(entry))
|
|
89
|
+
return true;
|
|
90
|
+
}
|
|
91
|
+
else if (hostname === entry) {
|
|
92
|
+
return true;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
return false;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* True if a request's Host header is allowed. Blocks DNS-rebinding: a custom
|
|
99
|
+
* domain rebound to a loopback/LAN address still carries its own name in Host,
|
|
100
|
+
* which will not be in the allowlist.
|
|
101
|
+
*/
|
|
102
|
+
export function isAllowedRequestHost(hostHeader, policy) {
|
|
103
|
+
const hostname = parseAuthorityHostname(hostHeader);
|
|
104
|
+
if (!hostname)
|
|
105
|
+
return false;
|
|
106
|
+
return matchesHost(hostname, policy);
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* True if a request's Origin is allowed for a state-changing / WebSocket request.
|
|
110
|
+
* A MISSING Origin is allowed: non-browser clients (curl, Claude Code hooks) omit
|
|
111
|
+
* it, while browsers always attach it on cross-origin state-changing/WS requests —
|
|
112
|
+
* so a forged cross-site request is caught while local automation keeps working.
|
|
113
|
+
* The opaque origin 'null' (sandboxed iframe, data: URL) is rejected.
|
|
114
|
+
*/
|
|
115
|
+
export function isAllowedRequestOrigin(originHeader, policy) {
|
|
116
|
+
if (originHeader === undefined || originHeader === '')
|
|
117
|
+
return true;
|
|
118
|
+
if (originHeader === 'null')
|
|
119
|
+
return false;
|
|
120
|
+
try {
|
|
121
|
+
return matchesHost(new URL(originHeader).hostname.toLowerCase(), policy);
|
|
122
|
+
}
|
|
123
|
+
catch {
|
|
124
|
+
return false;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
19
127
|
//# sourceMappingURL=network-auth-policy.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"network-auth-policy.js","sourceRoot":"","sources":["../../src/web/network-auth-policy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAEhC,MAAM,oBAAoB,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC;AAEjE,MAAM,UAAU,mBAAmB,CAAC,KAAyB;IAC3D,OAAO,KAAK,KAAK,SAAS,IAAI,oBAAoB,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,CAAC;AACrF,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,IAAY;IAC7C,MAAM,UAAU,GAAG,IAAI;SACpB,IAAI,EAAE;SACN,WAAW,EAAE;SACb,OAAO,CAAC,YAAY,EAAE,IAAI,CAAC,CAAC;IAC/B,IAAI,UAAU,KAAK,WAAW,IAAI,UAAU,KAAK,KAAK,IAAI,UAAU,KAAK,iBAAiB,EAAE,CAAC;QAC3F,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,UAAU,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;QAC5D,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,UAAU,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;AAC9C,CAAC"}
|
|
1
|
+
{"version":3,"file":"network-auth-policy.js","sourceRoot":"","sources":["../../src/web/network-auth-policy.ts"],"names":[],"mappings":"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"}
|
|
Binary file
|
|
Binary file
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
* @globals {function} scheduleBackground - scheduler.postTask wrapper (background priority)
|
|
11
11
|
* @globals {function} getEventCoords - Unified mouse/touch coordinate extractor
|
|
12
12
|
* @globals {function} escapeHtml - XSS-safe HTML escaping
|
|
13
|
-
* @globals {object} SSE_EVENTS - Centralized SSE event type constants (
|
|
13
|
+
* @globals {object} SSE_EVENTS - Centralized SSE event type constants (120 event types; must match backend src/web/sse-events.ts)
|
|
14
14
|
* @globals {Array} BUILTIN_RESPAWN_PRESETS - Built-in respawn configuration presets
|
|
15
15
|
*
|
|
16
16
|
* @dependency None (first in load order)
|
|
@@ -241,27 +241,45 @@ const SSE_EVENTS = {
|
|
|
241
241
|
SESSION_IDLE: 'session:idle',
|
|
242
242
|
SESSION_WORKING: 'session:working',
|
|
243
243
|
SESSION_AUTO_CLEAR: 'session:autoClear',
|
|
244
|
+
SESSION_AUTO_COMPACT: 'session:autoCompact',
|
|
244
245
|
SESSION_CLI_INFO: 'session:cliInfo',
|
|
246
|
+
SESSION_MESSAGE: 'session:message',
|
|
247
|
+
SESSION_INTERACTIVE: 'session:interactive',
|
|
248
|
+
SESSION_RUNNING: 'session:running',
|
|
245
249
|
|
|
246
250
|
// Scheduled runs
|
|
247
251
|
SCHEDULED_CREATED: 'scheduled:created',
|
|
248
252
|
SCHEDULED_UPDATED: 'scheduled:updated',
|
|
249
253
|
SCHEDULED_COMPLETED: 'scheduled:completed',
|
|
250
254
|
SCHEDULED_STOPPED: 'scheduled:stopped',
|
|
255
|
+
SCHEDULED_LOG: 'scheduled:log',
|
|
256
|
+
SCHEDULED_DELETED: 'scheduled:deleted',
|
|
251
257
|
|
|
252
258
|
// Respawn
|
|
253
259
|
RESPAWN_STARTED: 'respawn:started',
|
|
254
260
|
RESPAWN_STOPPED: 'respawn:stopped',
|
|
255
261
|
RESPAWN_STATE_CHANGED: 'respawn:stateChanged',
|
|
256
262
|
RESPAWN_CYCLE_STARTED: 'respawn:cycleStarted',
|
|
263
|
+
RESPAWN_CYCLE_COMPLETED: 'respawn:cycleCompleted',
|
|
257
264
|
RESPAWN_BLOCKED: 'respawn:blocked',
|
|
258
|
-
|
|
265
|
+
RESPAWN_STEP_SENT: 'respawn:stepSent',
|
|
266
|
+
RESPAWN_STEP_COMPLETED: 'respawn:stepCompleted',
|
|
259
267
|
RESPAWN_DETECTION_UPDATE: 'respawn:detectionUpdate',
|
|
268
|
+
RESPAWN_AUTO_ACCEPT_SENT: 'respawn:autoAcceptSent',
|
|
269
|
+
RESPAWN_AI_CHECK_STARTED: 'respawn:aiCheckStarted',
|
|
270
|
+
RESPAWN_AI_CHECK_COMPLETED: 'respawn:aiCheckCompleted',
|
|
271
|
+
RESPAWN_AI_CHECK_FAILED: 'respawn:aiCheckFailed',
|
|
272
|
+
RESPAWN_AI_CHECK_COOLDOWN: 'respawn:aiCheckCooldown',
|
|
273
|
+
RESPAWN_PLAN_CHECK_STARTED: 'respawn:planCheckStarted',
|
|
274
|
+
RESPAWN_PLAN_CHECK_COMPLETED: 'respawn:planCheckCompleted',
|
|
275
|
+
RESPAWN_PLAN_CHECK_FAILED: 'respawn:planCheckFailed',
|
|
260
276
|
RESPAWN_TIMER_STARTED: 'respawn:timerStarted',
|
|
261
277
|
RESPAWN_TIMER_CANCELLED: 'respawn:timerCancelled',
|
|
262
278
|
RESPAWN_TIMER_COMPLETED: 'respawn:timerCompleted',
|
|
263
|
-
RESPAWN_ERROR: 'respawn:error',
|
|
264
279
|
RESPAWN_ACTION_LOG: 'respawn:actionLog',
|
|
280
|
+
RESPAWN_LOG: 'respawn:log',
|
|
281
|
+
RESPAWN_ERROR: 'respawn:error',
|
|
282
|
+
RESPAWN_CONFIG_UPDATED: 'respawn:configUpdated',
|
|
265
283
|
|
|
266
284
|
// Tasks
|
|
267
285
|
TASK_CREATED: 'task:created',
|
|
@@ -288,6 +306,12 @@ const SSE_EVENTS = {
|
|
|
288
306
|
SESSION_BASH_TOOL_END: 'session:bashToolEnd',
|
|
289
307
|
SESSION_BASH_TOOLS_UPDATE: 'session:bashToolsUpdate',
|
|
290
308
|
|
|
309
|
+
// Session: Plan
|
|
310
|
+
SESSION_PLAN_TASK_UPDATE: 'session:planTaskUpdate',
|
|
311
|
+
SESSION_PLAN_CHECKPOINT: 'session:planCheckpoint',
|
|
312
|
+
SESSION_PLAN_ROLLBACK: 'session:planRollback',
|
|
313
|
+
SESSION_PLAN_TASK_ADDED: 'session:planTaskAdded',
|
|
314
|
+
|
|
291
315
|
// Hooks (Claude Code hook events)
|
|
292
316
|
HOOK_IDLE_PROMPT: 'hook:idle_prompt',
|
|
293
317
|
HOOK_PERMISSION_PROMPT: 'hook:permission_prompt',
|
|
@@ -338,6 +362,18 @@ const SSE_EVENTS = {
|
|
|
338
362
|
ORCHESTRATOR_COMPLETED: 'orchestrator:completed',
|
|
339
363
|
ORCHESTRATOR_ERROR: 'orchestrator:error',
|
|
340
364
|
|
|
365
|
+
// Teams (agent teams)
|
|
366
|
+
TEAM_CREATED: 'team:created',
|
|
367
|
+
TEAM_UPDATED: 'team:updated',
|
|
368
|
+
TEAM_REMOVED: 'team:removed',
|
|
369
|
+
TEAM_TASK_UPDATED: 'team:taskUpdated',
|
|
370
|
+
|
|
371
|
+
// Transcript
|
|
372
|
+
TRANSCRIPT_COMPLETE: 'transcript:complete',
|
|
373
|
+
TRANSCRIPT_PLAN_MODE: 'transcript:plan_mode',
|
|
374
|
+
TRANSCRIPT_TOOL_START: 'transcript:tool_start',
|
|
375
|
+
TRANSCRIPT_TOOL_END: 'transcript:tool_end',
|
|
376
|
+
|
|
341
377
|
// Clipboard
|
|
342
378
|
CLIPBOARD_WRITE: 'clipboard:write',
|
|
343
379
|
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
<!-- Preload critical resources — lets browser discover these during HTML parse
|
|
25
25
|
instead of waiting until <script> tags at bottom-of-body are reached. -->
|
|
26
26
|
<link rel="preload" href="vendor/xterm.min.js" as="script">
|
|
27
|
-
<link rel="preload" href="constants.
|
|
27
|
+
<link rel="preload" href="constants.5b68d2de.js" as="script">
|
|
28
28
|
<link rel="preload" href="app.c860ea08.js" as="script">
|
|
29
29
|
<!-- Self-hosted xterm.js — eliminates CDN DNS/TLS latency (~100ms).
|
|
30
30
|
'defer' preserves execution order (xterm loads before fit addon). -->
|
|
@@ -1078,6 +1078,24 @@
|
|
|
1078
1078
|
<span id="tunnelUploadUrlDisplay" class="settings-item-value" style="cursor:pointer; text-decoration:underline; font-family:monospace; font-size:12px" title="Click to copy"></span>
|
|
1079
1079
|
</div>
|
|
1080
1080
|
|
|
1081
|
+
<!-- Updates Section -->
|
|
1082
|
+
<div class="settings-section-header">Updates</div>
|
|
1083
|
+
<div class="settings-item" title="Codeman version currently running">
|
|
1084
|
+
<span class="settings-item-label">Current Version</span>
|
|
1085
|
+
<span class="settings-item-value" id="updateCurrentVersion" style="font-family:monospace">—</span>
|
|
1086
|
+
</div>
|
|
1087
|
+
<div class="settings-item" id="updateCheckRow" title="Check GitHub for a newer Codeman release">
|
|
1088
|
+
<span class="settings-item-label">Check for Updates</span>
|
|
1089
|
+
<button class="btn-toolbar btn-sm" id="updateCheckBtn" onclick="app.checkForUpdate()">Check now</button>
|
|
1090
|
+
</div>
|
|
1091
|
+
<div id="updateResult" style="display:none; padding:4px 2px 8px; font-size:13px; color:var(--text-secondary)"></div>
|
|
1092
|
+
<div class="settings-item" id="updateActionRow" style="display:none">
|
|
1093
|
+
<span class="settings-item-label" id="updateActionLabel">Update available</span>
|
|
1094
|
+
<button class="btn-toolbar btn-sm btn-primary" id="updateNowBtn" onclick="app.startSelfUpdate()">Update now</button>
|
|
1095
|
+
</div>
|
|
1096
|
+
<div id="updateNotes" style="display:none; max-height:160px; overflow:auto; padding:8px 10px; margin:4px 0 8px; font-size:12px; line-height:1.45; white-space:pre-wrap; word-break:break-word; background:rgba(127,127,127,0.08); border:1px solid var(--border); border-radius:6px"></div>
|
|
1097
|
+
<div id="updateProgress" style="display:none; padding:8px 10px; margin:4px 0 8px; font-size:13px; border:1px solid var(--border); border-radius:6px"></div>
|
|
1098
|
+
|
|
1081
1099
|
</div>
|
|
1082
1100
|
</div>
|
|
1083
1101
|
<!-- Tab-Switch Tab -->
|
|
@@ -1816,7 +1834,7 @@
|
|
|
1816
1834
|
<!-- Lines drawn dynamically -->
|
|
1817
1835
|
</svg>
|
|
1818
1836
|
|
|
1819
|
-
<script defer src="constants.
|
|
1837
|
+
<script defer src="constants.5b68d2de.js"></script>
|
|
1820
1838
|
<script defer src="mobile-handlers.1e2a8ef8.js"></script>
|
|
1821
1839
|
<script defer src="voice-input.085e9e73.js"></script>
|
|
1822
1840
|
<script defer src="notification-manager.9c984ac2.js"></script>
|
|
@@ -1827,8 +1845,8 @@
|
|
|
1827
1845
|
<script defer src="respawn-ui.5377f958.js"></script>
|
|
1828
1846
|
<script defer src="ralph-panel.61076370.js"></script>
|
|
1829
1847
|
<script defer src="orchestrator-panel.js"></script>
|
|
1830
|
-
<script defer src="settings-ui.
|
|
1831
|
-
<script defer src="panels-ui.
|
|
1848
|
+
<script defer src="settings-ui.da0621e1.js"></script>
|
|
1849
|
+
<script defer src="panels-ui.5192a2c0.js"></script>
|
|
1832
1850
|
<script defer src="session-ui.3e0cf024.js"></script>
|
|
1833
1851
|
<script defer src="ralph-wizard.52d533d2.js"></script>
|
|
1834
1852
|
<script defer src="api-client.3adebdc2.js"></script>
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|