@cortexkit/opencode-magic-context 0.22.3 → 0.22.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/README.md +1 -1
- package/dist/agents/magic-context-prompt.d.ts.map +1 -1
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/project-security.d.ts +25 -0
- package/dist/config/project-security.d.ts.map +1 -0
- package/dist/config/prune-config-leaf.d.ts +27 -0
- package/dist/config/prune-config-leaf.d.ts.map +1 -0
- package/dist/config/schema/magic-context.d.ts +7 -0
- package/dist/config/schema/magic-context.d.ts.map +1 -1
- package/dist/config/variable.d.ts.map +1 -1
- package/dist/features/magic-context/compartment-storage.d.ts +9 -6
- package/dist/features/magic-context/compartment-storage.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/runner.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/scheduler.d.ts.map +1 -1
- package/dist/features/magic-context/key-files/aft-availability.d.ts.map +1 -1
- package/dist/features/magic-context/key-files/identify-key-files.d.ts.map +1 -1
- package/dist/features/magic-context/key-files/read-stats.d.ts +0 -2
- package/dist/features/magic-context/key-files/read-stats.d.ts.map +1 -1
- package/dist/features/magic-context/memory/embedding-openai.d.ts.map +1 -1
- package/dist/features/magic-context/memory/embedding-ssrf.d.ts +29 -0
- package/dist/features/magic-context/memory/embedding-ssrf.d.ts.map +1 -0
- package/dist/features/magic-context/memory/memory-migration.d.ts.map +1 -1
- package/dist/features/magic-context/memory/project-identity.d.ts +10 -0
- package/dist/features/magic-context/memory/project-identity.d.ts.map +1 -1
- package/dist/features/magic-context/migrations.d.ts.map +1 -1
- package/dist/features/magic-context/project-docs-hash.d.ts.map +1 -1
- package/dist/features/magic-context/project-embedding-registry.d.ts.map +1 -1
- package/dist/features/magic-context/range-parser.d.ts +6 -0
- package/dist/features/magic-context/range-parser.d.ts.map +1 -1
- package/dist/features/magic-context/sidekick/agent.d.ts.map +1 -1
- package/dist/features/magic-context/storage-db.d.ts +1 -1
- package/dist/features/magic-context/storage-db.d.ts.map +1 -1
- package/dist/features/magic-context/storage-meta-persisted.d.ts +41 -1
- package/dist/features/magic-context/storage-meta-persisted.d.ts.map +1 -1
- package/dist/features/magic-context/storage-meta-session.d.ts.map +1 -1
- package/dist/features/magic-context/storage-meta-shared.d.ts +7 -1
- package/dist/features/magic-context/storage-meta-shared.d.ts.map +1 -1
- package/dist/features/magic-context/storage-meta.d.ts +1 -1
- package/dist/features/magic-context/storage-meta.d.ts.map +1 -1
- package/dist/features/magic-context/storage.d.ts +2 -2
- package/dist/features/magic-context/storage.d.ts.map +1 -1
- package/dist/features/magic-context/tool-definition-tokens.d.ts +21 -0
- package/dist/features/magic-context/tool-definition-tokens.d.ts.map +1 -1
- package/dist/features/magic-context/types.d.ts +4 -0
- package/dist/features/magic-context/types.d.ts.map +1 -1
- package/dist/features/magic-context/user-memory/review-user-memories.d.ts.map +1 -1
- package/dist/hooks/auto-update-checker/cache.d.ts.map +1 -1
- package/dist/hooks/auto-update-checker/checker.d.ts.map +1 -1
- package/dist/hooks/auto-update-checker/semver.d.ts +17 -0
- package/dist/hooks/auto-update-checker/semver.d.ts.map +1 -0
- package/dist/hooks/magic-context/command-handler.d.ts +1 -6
- package/dist/hooks/magic-context/command-handler.d.ts.map +1 -1
- package/dist/hooks/magic-context/compaction-marker-manager.d.ts +1 -1
- package/dist/hooks/magic-context/compaction-marker-manager.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-runner-historian.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-runner-incremental.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-runner-partial-recomp.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-runner-recomp.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-runner-validation.d.ts +25 -0
- package/dist/hooks/magic-context/compartment-runner-validation.d.ts.map +1 -1
- package/dist/hooks/magic-context/decay-render.d.ts.map +1 -1
- package/dist/hooks/magic-context/drop-stale-reduce-calls.d.ts +36 -1
- package/dist/hooks/magic-context/drop-stale-reduce-calls.d.ts.map +1 -1
- package/dist/hooks/magic-context/hook-handlers.d.ts.map +1 -1
- package/dist/hooks/magic-context/hook.d.ts.map +1 -1
- package/dist/hooks/magic-context/inject-compartments.d.ts +41 -0
- package/dist/hooks/magic-context/inject-compartments.d.ts.map +1 -1
- package/dist/hooks/magic-context/reference-retrieval.d.ts.map +1 -1
- package/dist/hooks/magic-context/transform-postprocess-phase.d.ts +2 -1
- package/dist/hooks/magic-context/transform-postprocess-phase.d.ts.map +1 -1
- package/dist/hooks/magic-context/transform.d.ts +8 -0
- package/dist/hooks/magic-context/transform.d.ts.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +818 -259
- package/dist/plugin/embedding-bootstrap-helpers.d.ts.map +1 -1
- package/dist/plugin/hooks/create-session-hooks.d.ts.map +1 -1
- package/dist/shared/keep-subagents.d.ts +7 -0
- package/dist/shared/keep-subagents.d.ts.map +1 -0
- package/dist/shared/rpc-server.d.ts.map +1 -1
- package/dist/tools/ctx-memory/tools.d.ts.map +1 -1
- package/dist/tools/ctx-search/tools.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/shared/keep-subagents.test.ts +39 -0
- package/src/shared/keep-subagents.ts +33 -0
- package/src/shared/rpc-server.ts +18 -2
- package/src/tui/index.tsx +9 -5
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"embedding-bootstrap-helpers.d.ts","sourceRoot":"","sources":["../../src/plugin/embedding-bootstrap-helpers.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AAMtE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAEjD,MAAM,MAAM,WAAW,GACjB,IAAI,GACJ,0BAA0B,GAC1B,uBAAuB,GACvB,iBAAiB,GACjB,sBAAsB,CAAC;AAE7B,MAAM,WAAW,2BAA2B,CAAC,OAAO,SAAS;IAAE,SAAS,EAAE,eAAe,CAAA;CAAE;IACvF,MAAM,EAAE,OAAO,CAAC;IAChB,WAAW,EAAE,WAAW,CAAC;IACzB,OAAO,EAAE;QACL,UAAU,EAAE,WAAW,CAAC;QACxB,aAAa,EAAE,WAAW,CAAC;KAC9B,CAAC;IACF,oBAAoB,EAAE,KAAK,CAAC;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC9F,qBAAqB,EAAE,MAAM,EAAE,CAAC;CACnC;AAED,eAAO,MAAM,wBAAwB,
|
|
1
|
+
{"version":3,"file":"embedding-bootstrap-helpers.d.ts","sourceRoot":"","sources":["../../src/plugin/embedding-bootstrap-helpers.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AAMtE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAEjD,MAAM,MAAM,WAAW,GACjB,IAAI,GACJ,0BAA0B,GAC1B,uBAAuB,GACvB,iBAAiB,GACjB,sBAAsB,CAAC;AAE7B,MAAM,WAAW,2BAA2B,CAAC,OAAO,SAAS;IAAE,SAAS,EAAE,eAAe,CAAA;CAAE;IACvF,MAAM,EAAE,OAAO,CAAC;IAChB,WAAW,EAAE,WAAW,CAAC;IACzB,OAAO,EAAE;QACL,UAAU,EAAE,WAAW,CAAC;QACxB,aAAa,EAAE,WAAW,CAAC;KAC9B,CAAC;IACF,oBAAoB,EAAE,KAAK,CAAC;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC9F,qBAAqB,EAAE,MAAM,EAAE,CAAC;CACnC;AAED,eAAO,MAAM,wBAAwB,aAWnC,CAAC;AAEH,eAAO,MAAM,kCAAkC,aAAmD,CAAC;AAsBnG,wBAAgB,qBAAqB,CACjC,QAAQ,EAAE,2BAA2B,CAAC;IAAE,SAAS,EAAE,eAAe,CAAA;CAAE,CAAC,GACtE,OAAO,CA0BT;AAED,wBAAgB,eAAe,CAC3B,QAAQ,EAAE,2BAA2B,CAAC;IAAE,SAAS,EAAE,eAAe,CAAA;CAAE,CAAC,GACtE,MAAM,CAkBR;AAED,wBAAgB,oBAAoB,CAChC,eAAe,EAAE,MAAM,EACvB,QAAQ,EAAE,2BAA2B,CAAC;IAAE,SAAS,EAAE,eAAe,CAAA;CAAE,CAAC,GACtE,IAAI,CAiBN;AAED,wBAAgB,mBAAmB,CAC/B,EAAE,EAAE,QAAQ,EACZ,eAAe,EAAE,MAAM,EACvB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,2BAA2B,CAAC;IAAE,SAAS,EAAE,eAAe,CAAA;CAAE,CAAC,GACtE,OAAO,CAeT;AAED,wBAAgB,wCAAwC,IAAI,IAAI,CAE/D"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create-session-hooks.d.ts","sourceRoot":"","sources":["../../../src/plugin/hooks/create-session-hooks.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,cAAc,CAAC;AAU7D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,8CAA8C,CAAC;AACrF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAE9C,wBAAgB,kBAAkB,CAAC,IAAI,EAAE;IACrC,GAAG,EAAE,aAAa,CAAC;IACnB,YAAY,EAAE,wBAAwB,CAAC;IACvC,gBAAgB,EAAE,gBAAgB,CAAC;CACtC;;;;;;qBAwDwlK,CAAC;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"create-session-hooks.d.ts","sourceRoot":"","sources":["../../../src/plugin/hooks/create-session-hooks.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,cAAc,CAAC;AAU7D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,8CAA8C,CAAC;AACrF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAE9C,wBAAgB,kBAAkB,CAAC,IAAI,EAAE;IACrC,GAAG,EAAE,aAAa,CAAC;IACnB,YAAY,EAAE,wBAAwB,CAAC;IACvC,gBAAgB,EAAE,gBAAgB,CAAC;CACtC;;;;;;qBAwDwlK,CAAC;;;;;;;;;;;;qBAA9nD,CAAC;mBAAyB,CAAC;iBAAuB,CAAC;iBAAuB,CAAC;0BAAc,CAAC;uBAAiB,CAAC;;;;;;0BAAmk1B,CAAC;;;;;;EAD3o8B"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/** Set at plugin boot from `keep_subagents` config. */
|
|
2
|
+
export declare function setKeepSubagents(value: boolean): void;
|
|
3
|
+
/** True when subagent child sessions should be retained (not deleted). */
|
|
4
|
+
export declare function shouldKeepSubagents(): boolean;
|
|
5
|
+
/** Test-only reset. Do NOT call from production paths. */
|
|
6
|
+
export declare function _resetKeepSubagentsForTesting(): void;
|
|
7
|
+
//# sourceMappingURL=keep-subagents.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"keep-subagents.d.ts","sourceRoot":"","sources":["../../src/shared/keep-subagents.ts"],"names":[],"mappings":"AAmBA,uDAAuD;AACvD,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAErD;AAED,0EAA0E;AAC1E,wBAAgB,mBAAmB,IAAI,OAAO,CAE7C;AAED,0DAA0D;AAC1D,wBAAgB,6BAA6B,IAAI,IAAI,CAEpD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rpc-server.d.ts","sourceRoot":"","sources":["../../src/shared/rpc-server.ts"],"names":[],"mappings":"AAcA,KAAK,UAAU,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"rpc-server.d.ts","sourceRoot":"","sources":["../../src/shared/rpc-server.ts"],"names":[],"mappings":"AAcA,KAAK,UAAU,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;AAexF,qBAAa,qBAAqB;IAC9B,OAAO,CAAC,MAAM,CAAuB;IACrC,OAAO,CAAC,IAAI,CAAK;IACjB,OAAO,CAAC,QAAQ,CAAiC;IACjD,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,SAAS,CAAc;IAK/B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAmC;gBAE7C,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM;IAKjD,sCAAsC;IACtC,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,GAAG,IAAI;IAIjD,6DAA6D;IACvD,KAAK,IAAI,OAAO,CAAC,MAAM,CAAC;IA2D9B,OAAO,CAAC,uBAAuB;IAgB/B,8CAA8C;IAC9C,IAAI,IAAI,IAAI;IAYZ,OAAO,CAAC,QAAQ;CA6EnB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../../../src/tools/ctx-memory/tools.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,cAAc,EAAQ,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../../../src/tools/ctx-memory/tools.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,cAAc,EAAQ,MAAM,qBAAqB,CAAC;AA6BhE,OAAO,EAIH,KAAK,iBAAiB,EACzB,MAAM,SAAS,CAAC;AAsjBjB,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,iBAAiB,GAAG,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAI5F"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../../../src/tools/ctx-search/tools.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,cAAc,EAAQ,MAAM,qBAAqB,CAAC;AAahE,OAAO,KAAK,EAAkC,iBAAiB,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../../../src/tools/ctx-search/tools.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,cAAc,EAAQ,MAAM,qBAAqB,CAAC;AAahE,OAAO,KAAK,EAAkC,iBAAiB,EAAE,MAAM,SAAS,CAAC;AA4KjF,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,iBAAiB,GAAG,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAI5F"}
|
package/package.json
CHANGED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { afterEach, describe, expect, it } from "bun:test";
|
|
2
|
+
import {
|
|
3
|
+
_resetKeepSubagentsForTesting,
|
|
4
|
+
setKeepSubagents,
|
|
5
|
+
shouldKeepSubagents,
|
|
6
|
+
} from "./keep-subagents";
|
|
7
|
+
|
|
8
|
+
afterEach(() => {
|
|
9
|
+
_resetKeepSubagentsForTesting();
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
describe("keep-subagents flag", () => {
|
|
13
|
+
it("#given default #then subagent sessions are NOT kept (deleted on success)", () => {
|
|
14
|
+
expect(shouldKeepSubagents()).toBe(false);
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
it("#given setKeepSubagents(true) #then sessions are kept", () => {
|
|
18
|
+
setKeepSubagents(true);
|
|
19
|
+
expect(shouldKeepSubagents()).toBe(true);
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
it("#given setKeepSubagents(false) #then sessions are not kept", () => {
|
|
23
|
+
setKeepSubagents(true);
|
|
24
|
+
setKeepSubagents(false);
|
|
25
|
+
expect(shouldKeepSubagents()).toBe(false);
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
it("#given a non-true value #then coerces to false (only strict true keeps)", () => {
|
|
29
|
+
// boot wiring passes `config.keep_subagents === true`, but guard anyway.
|
|
30
|
+
setKeepSubagents(undefined as unknown as boolean);
|
|
31
|
+
expect(shouldKeepSubagents()).toBe(false);
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
it("#given reset helper #then returns to default false", () => {
|
|
35
|
+
setKeepSubagents(true);
|
|
36
|
+
_resetKeepSubagentsForTesting();
|
|
37
|
+
expect(shouldKeepSubagents()).toBe(false);
|
|
38
|
+
});
|
|
39
|
+
});
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Debug / data-collection switch: when enabled, Magic Context does NOT delete
|
|
3
|
+
* the child sessions it spawns for its own subagents (historian, dreamer,
|
|
4
|
+
* sidekick, memory-migration, key-files, user-memory review, recomp).
|
|
5
|
+
*
|
|
6
|
+
* By default these child sessions are deleted on success (only FAILED ones are
|
|
7
|
+
* kept for debugging). With `keep_subagents: true` ALL of them are retained, so
|
|
8
|
+
* their full transcript — prompt, tool calls, token usage, model output — stays
|
|
9
|
+
* inspectable in OpenCode's session store / the dashboard. Intended for
|
|
10
|
+
* short-term data collection (e.g. profiling what the dreamer actually does)
|
|
11
|
+
* before the dreamer v2 overhaul, NOT for steady-state use — kept sessions
|
|
12
|
+
* accumulate in the host's session DB until manually cleared.
|
|
13
|
+
*
|
|
14
|
+
* Process-global, set once at boot from config (mirrors `harness.ts`). A
|
|
15
|
+
* config change requires a restart to take effect. NEVER thread this through
|
|
16
|
+
* per-call args — it's a coarse, boot-time debug toggle.
|
|
17
|
+
*/
|
|
18
|
+
let keepSubagents = false;
|
|
19
|
+
|
|
20
|
+
/** Set at plugin boot from `keep_subagents` config. */
|
|
21
|
+
export function setKeepSubagents(value: boolean): void {
|
|
22
|
+
keepSubagents = value === true;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/** True when subagent child sessions should be retained (not deleted). */
|
|
26
|
+
export function shouldKeepSubagents(): boolean {
|
|
27
|
+
return keepSubagents;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/** Test-only reset. Do NOT call from production paths. */
|
|
31
|
+
export function _resetKeepSubagentsForTesting(): void {
|
|
32
|
+
keepSubagents = false;
|
|
33
|
+
}
|
package/src/shared/rpc-server.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { randomBytes } from "node:crypto";
|
|
1
|
+
import { randomBytes, timingSafeEqual } from "node:crypto";
|
|
2
2
|
import {
|
|
3
3
|
mkdirSync,
|
|
4
4
|
readdirSync,
|
|
@@ -14,6 +14,19 @@ import { isPidAlive, parseRpcPortFile, rpcPortDir, rpcPortFilePath } from "./rpc
|
|
|
14
14
|
|
|
15
15
|
type RpcHandler = (params: Record<string, unknown>) => Promise<Record<string, unknown>>;
|
|
16
16
|
|
|
17
|
+
/**
|
|
18
|
+
* Constant-time bearer-token comparison. `timingSafeEqual` throws on
|
|
19
|
+
* length-mismatched buffers, so guard on length first (the length itself is not
|
|
20
|
+
* secret — the token bytes are). Avoids leaking the token via response-timing on
|
|
21
|
+
* the loopback auth check.
|
|
22
|
+
*/
|
|
23
|
+
function tokensMatch(presented: string, expected: string): boolean {
|
|
24
|
+
const a = Buffer.from(presented, "utf8");
|
|
25
|
+
const b = Buffer.from(expected, "utf8");
|
|
26
|
+
if (a.length !== b.length) return false;
|
|
27
|
+
return timingSafeEqual(a, b);
|
|
28
|
+
}
|
|
29
|
+
|
|
17
30
|
export class MagicContextRpcServer {
|
|
18
31
|
private server: Server | null = null;
|
|
19
32
|
private port = 0;
|
|
@@ -149,9 +162,12 @@ export class MagicContextRpcServer {
|
|
|
149
162
|
// Require the per-process bearer token on every side-effecting call.
|
|
150
163
|
// The legitimate TUI client reads it from the same port file it used to
|
|
151
164
|
// discover the port; a process that only guessed the port cannot.
|
|
165
|
+
// Constant-time compare so a local attacker can't byte-probe the token
|
|
166
|
+
// via response-timing (length-guard first, since timingSafeEqual throws
|
|
167
|
+
// on length mismatch).
|
|
152
168
|
const auth = req.headers.authorization;
|
|
153
169
|
const presented = typeof auth === "string" ? auth.replace(/^Bearer\s+/i, "") : "";
|
|
154
|
-
if (presented
|
|
170
|
+
if (!tokensMatch(presented, this.token)) {
|
|
155
171
|
res.writeHead(401, { "Content-Type": "application/json" });
|
|
156
172
|
res.end(JSON.stringify({ error: "Unauthorized" }));
|
|
157
173
|
req.resume();
|
package/src/tui/index.tsx
CHANGED
|
@@ -532,11 +532,6 @@ function showUpgradeDialog(
|
|
|
532
532
|
title={title}
|
|
533
533
|
message={message}
|
|
534
534
|
onConfirm={() => {
|
|
535
|
-
// Explicit choice → dismiss the fresh reminder durably so it
|
|
536
|
-
// won't re-show. (Resume prompts are staging-driven and still
|
|
537
|
-
// fire if this run is later interrupted.)
|
|
538
|
-
void dismissUpgradeReminder(sessionId)
|
|
539
|
-
void requestUpgrade(sessionId)
|
|
540
535
|
// Start the sidebar's recomp self-poll immediately — the RPC
|
|
541
536
|
// call fires no message event, so without this the progress
|
|
542
537
|
// bar wouldn't appear until the upgrade finished.
|
|
@@ -548,6 +543,15 @@ function showUpgradeDialog(
|
|
|
548
543
|
variant: "info",
|
|
549
544
|
duration: 5000,
|
|
550
545
|
})
|
|
546
|
+
// Dismiss the durable reminder ONLY after the upgrade request
|
|
547
|
+
// actually started. If requestUpgrade() returns false (RPC /
|
|
548
|
+
// server / db / auth failure, restart race), the session stays
|
|
549
|
+
// legacy — dismissing first would set upgradeRemindedAt and
|
|
550
|
+
// suppress all future reminders for a session that never
|
|
551
|
+
// upgraded. (Resume prompts are staging-driven and unaffected.)
|
|
552
|
+
void requestUpgrade(sessionId).then((started) => {
|
|
553
|
+
if (started) void dismissUpgradeReminder(sessionId)
|
|
554
|
+
})
|
|
551
555
|
}}
|
|
552
556
|
onCancel={() => {
|
|
553
557
|
// Explicit decline → set the durable stamp so we don't re-prompt
|