context-mode 1.0.134 → 1.0.136
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/.claude-plugin/marketplace.json +2 -2
- package/.claude-plugin/plugin.json +1 -1
- package/.codex-plugin/hooks.json +65 -0
- package/.codex-plugin/mcp.json +9 -0
- package/.codex-plugin/plugin.json +31 -0
- package/.openclaw-plugin/openclaw.plugin.json +1 -1
- package/.openclaw-plugin/package.json +1 -1
- package/README.md +60 -12
- package/build/adapters/detect.d.ts +3 -1
- package/build/adapters/detect.js +7 -2
- package/build/adapters/pi/mcp-bridge.d.ts +44 -0
- package/build/adapters/pi/mcp-bridge.js +149 -3
- package/build/cli.js +17 -0
- package/build/lifecycle.d.ts +13 -13
- package/build/lifecycle.js +14 -14
- package/build/runtime.js +8 -5
- package/build/session/analytics.d.ts +0 -13
- package/build/session/analytics.js +50 -1
- package/build/session/extract.js +39 -1
- package/build/util/claude-config.d.ts +12 -6
- package/build/util/claude-config.js +16 -23
- package/cli.bundle.mjs +135 -133
- package/configs/kilo/kilo.json +9 -2
- package/configs/opencode/opencode.json +9 -2
- package/hooks/codex/platform.mjs +1 -0
- package/hooks/codex/posttooluse.mjs +1 -0
- package/hooks/codex/precompact.mjs +1 -0
- package/hooks/codex/pretooluse.mjs +1 -0
- package/hooks/codex/sessionstart.mjs +24 -1
- package/hooks/codex/stop.mjs +1 -0
- package/hooks/codex/userpromptsubmit.mjs +1 -0
- package/hooks/core/platform-detect.mjs +1 -1
- package/hooks/core/routing.mjs +112 -10
- package/hooks/ensure-deps.mjs +14 -3
- package/hooks/normalize-hooks.mjs +5 -2
- package/hooks/security.bundle.mjs +1 -1
- package/hooks/session-extract.bundle.mjs +2 -2
- package/openclaw.plugin.json +1 -1
- package/package.json +2 -1
- package/scripts/heal-installed-plugins.mjs +67 -0
- package/server.bundle.mjs +99 -99
- package/start.mjs +73 -11
- package/build/openclaw-plugin.d.ts +0 -130
- package/build/openclaw-plugin.js +0 -626
- package/build/opencode-plugin.d.ts +0 -122
- package/build/opencode-plugin.js +0 -372
- package/build/pi-extension.d.ts +0 -14
- package/build/pi-extension.js +0 -451
- package/build/util/db-lock.d.ts +0 -65
- package/build/util/db-lock.js +0 -166
package/build/lifecycle.d.ts
CHANGED
|
@@ -23,7 +23,7 @@ export interface LifecycleGuardOptions {
|
|
|
23
23
|
/**
|
|
24
24
|
* Idle shutdown threshold in ms (#565). When the server has handled no
|
|
25
25
|
* MCP activity for this long, `onShutdown` fires. `0` disables.
|
|
26
|
-
* Default: env `CONTEXT_MODE_IDLE_TIMEOUT_MS`, else
|
|
26
|
+
* Default: env `CONTEXT_MODE_IDLE_TIMEOUT_MS`, else 0 (disabled).
|
|
27
27
|
* Skipped on TTY stdin (interactive dev / OpenCode ts-plugin standalone).
|
|
28
28
|
*
|
|
29
29
|
* Pair with the returned `recordActivity()` callback — call it on every
|
|
@@ -50,20 +50,20 @@ export interface LifecycleGuardHandle {
|
|
|
50
50
|
/**
|
|
51
51
|
* Resolve the idle-shutdown threshold (#565).
|
|
52
52
|
*
|
|
53
|
-
*
|
|
54
|
-
*
|
|
55
|
-
*
|
|
56
|
-
*
|
|
53
|
+
* Idle shutdown is OFF by default (#592) because most hosts (Claude
|
|
54
|
+
* Code, Codex, editor MCP clients) keep registered tool handles after a
|
|
55
|
+
* clean MCP child exit and do NOT transparently respawn on the next call.
|
|
56
|
+
* The global 15 min default introduced in #568 solved OpenCode's child
|
|
57
|
+
* accumulation, but stranded ctx_* tools in Claude Code/Codex-style
|
|
58
|
+
* hosts once the MCP server exited cleanly while the editor stayed alive.
|
|
57
59
|
*
|
|
58
|
-
*
|
|
59
|
-
*
|
|
60
|
-
*
|
|
60
|
+
* Hosts that are known to benefit from idle shutdown MUST opt in via
|
|
61
|
+
* CONTEXT_MODE_IDLE_TIMEOUT_MS in their MCP config. Today that is
|
|
62
|
+
* OpenCode/KiloCode (their configs set 900000 = 15 min). Users and test
|
|
63
|
+
* harnesses can also opt in explicitly with any positive integer.
|
|
61
64
|
*
|
|
62
|
-
*
|
|
63
|
-
*
|
|
64
|
-
* that 8 hours of unused sessions do not pin GB of RAM.
|
|
65
|
-
*
|
|
66
|
-
* Set env to `0` to disable entirely.
|
|
65
|
+
* Missing or malformed env = 0 (disabled, safe default). Set env to
|
|
66
|
+
* `0` to disable explicitly.
|
|
67
67
|
*
|
|
68
68
|
* Exported for unit-testing.
|
|
69
69
|
*/
|
package/build/lifecycle.js
CHANGED
|
@@ -17,30 +17,30 @@ import { execFileSync } from "node:child_process";
|
|
|
17
17
|
/**
|
|
18
18
|
* Resolve the idle-shutdown threshold (#565).
|
|
19
19
|
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
20
|
+
* Idle shutdown is OFF by default (#592) because most hosts (Claude
|
|
21
|
+
* Code, Codex, editor MCP clients) keep registered tool handles after a
|
|
22
|
+
* clean MCP child exit and do NOT transparently respawn on the next call.
|
|
23
|
+
* The global 15 min default introduced in #568 solved OpenCode's child
|
|
24
|
+
* accumulation, but stranded ctx_* tools in Claude Code/Codex-style
|
|
25
|
+
* hosts once the MCP server exited cleanly while the editor stayed alive.
|
|
24
26
|
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
27
|
+
* Hosts that are known to benefit from idle shutdown MUST opt in via
|
|
28
|
+
* CONTEXT_MODE_IDLE_TIMEOUT_MS in their MCP config. Today that is
|
|
29
|
+
* OpenCode/KiloCode (their configs set 900000 = 15 min). Users and test
|
|
30
|
+
* harnesses can also opt in explicitly with any positive integer.
|
|
28
31
|
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
* that 8 hours of unused sessions do not pin GB of RAM.
|
|
32
|
-
*
|
|
33
|
-
* Set env to `0` to disable entirely.
|
|
32
|
+
* Missing or malformed env = 0 (disabled, safe default). Set env to
|
|
33
|
+
* `0` to disable explicitly.
|
|
34
34
|
*
|
|
35
35
|
* Exported for unit-testing.
|
|
36
36
|
*/
|
|
37
37
|
export function idleTimeoutForEnv(env = process.env) {
|
|
38
38
|
const raw = env.CONTEXT_MODE_IDLE_TIMEOUT_MS;
|
|
39
39
|
if (raw === undefined)
|
|
40
|
-
return
|
|
40
|
+
return 0;
|
|
41
41
|
const n = Number.parseInt(raw, 10);
|
|
42
42
|
if (!Number.isFinite(n) || n < 0)
|
|
43
|
-
return
|
|
43
|
+
return 0;
|
|
44
44
|
return n;
|
|
45
45
|
}
|
|
46
46
|
/** Read grandparent PID via `ps -o ppid= -p $PPID`. Returns NaN on failure or Windows. */
|
package/build/runtime.js
CHANGED
|
@@ -12,11 +12,14 @@ import { existsSync } from "node:fs";
|
|
|
12
12
|
* Match is case-insensitive; `.exe` extension tolerated for Windows binaries.
|
|
13
13
|
*/
|
|
14
14
|
const ALLOWED_SHELL_BASENAMES = /^(bash|sh|zsh|dash|pwsh|powershell|cmd)(\.exe)?$/i;
|
|
15
|
+
const BUN_BASENAME = /^bun(\.exe)?$/i;
|
|
16
|
+
function runtimeBasename(runtimePath) {
|
|
17
|
+
const segments = runtimePath.split(/[\\/]/);
|
|
18
|
+
return segments[segments.length - 1] ?? runtimePath;
|
|
19
|
+
}
|
|
15
20
|
export function isAllowlistedShell(shellPath) {
|
|
16
21
|
// Cross-OS basename: split on either separator, take the last segment.
|
|
17
|
-
|
|
18
|
-
const base = segments[segments.length - 1];
|
|
19
|
-
return ALLOWED_SHELL_BASENAMES.test(base);
|
|
22
|
+
return ALLOWED_SHELL_BASENAMES.test(runtimeBasename(shellPath));
|
|
20
23
|
}
|
|
21
24
|
const isWindows = process.platform === "win32";
|
|
22
25
|
function commandExists(cmd) {
|
|
@@ -305,14 +308,14 @@ export function getAvailableLanguages(runtimes) {
|
|
|
305
308
|
export function buildCommand(runtimes, language, filePath) {
|
|
306
309
|
switch (language) {
|
|
307
310
|
case "javascript":
|
|
308
|
-
return runtimes.javascript
|
|
311
|
+
return BUN_BASENAME.test(runtimeBasename(runtimes.javascript))
|
|
309
312
|
? [runtimes.javascript, "run", filePath]
|
|
310
313
|
: [runtimes.javascript, filePath];
|
|
311
314
|
case "typescript":
|
|
312
315
|
if (!runtimes.typescript) {
|
|
313
316
|
throw new Error("No TypeScript runtime available. Install one of: bun (recommended), tsx (npm i -g tsx), or ts-node.");
|
|
314
317
|
}
|
|
315
|
-
if (runtimes.typescript
|
|
318
|
+
if (BUN_BASENAME.test(runtimeBasename(runtimes.typescript)))
|
|
316
319
|
return [runtimes.typescript, "run", filePath];
|
|
317
320
|
if (runtimes.typescript === "tsx")
|
|
318
321
|
return ["tsx", filePath];
|
|
@@ -557,19 +557,6 @@ export declare const adapterLabels: Record<string, string>;
|
|
|
557
557
|
* information. Scale awareness comes from the unit jump between rows.
|
|
558
558
|
*/
|
|
559
559
|
export declare function kb(b: number): string;
|
|
560
|
-
/**
|
|
561
|
-
* Locale + IANA-timezone detection for the narrative renderer.
|
|
562
|
-
*
|
|
563
|
-
* Cascade (each level overrides the next):
|
|
564
|
-
* 1. CONTEXT_MODE_LOCALE / CONTEXT_MODE_TZ env overrides
|
|
565
|
-
* (used by tests + by users who want to pin output regardless of OS).
|
|
566
|
-
* 2. macOS `defaults read -g AppleLocale` → `en_TR` style → `en-TR`.
|
|
567
|
-
* 3. Linux `LANG` / `LC_TIME` env vars.
|
|
568
|
-
* 4. Fallback: `Intl.DateTimeFormat().resolvedOptions().locale`.
|
|
569
|
-
*
|
|
570
|
-
* Timezone always uses `Intl.DateTimeFormat().resolvedOptions().timeZone`
|
|
571
|
-
* — that one's always available and correct regardless of platform.
|
|
572
|
-
*/
|
|
573
560
|
export declare function detectLocaleAndTz(): {
|
|
574
561
|
locale: string;
|
|
575
562
|
tz: string;
|
|
@@ -1217,9 +1217,45 @@ function formatDuration(uptimeMin) {
|
|
|
1217
1217
|
* Timezone always uses `Intl.DateTimeFormat().resolvedOptions().timeZone`
|
|
1218
1218
|
* — that one's always available and correct regardless of platform.
|
|
1219
1219
|
*/
|
|
1220
|
+
/**
|
|
1221
|
+
* Validate that a locale string is a usable BCP 47 tag.
|
|
1222
|
+
*
|
|
1223
|
+
* Ubuntu GHA runners default to `LANG=C.UTF-8`. The extractor below strips
|
|
1224
|
+
* that to `"C"` — a valid POSIX locale identifier but NOT a BCP 47 tag.
|
|
1225
|
+
* On macOS / Node 20, `new Intl.DateTimeFormat("C", …)` throws RangeError
|
|
1226
|
+
* outright. CI run 25887250971 caught this via the v1.0.134 SLICE B test.
|
|
1227
|
+
*
|
|
1228
|
+
* Earlier fix attempt used a permissive `supportedLocalesOf || construction`
|
|
1229
|
+
* OR check — that was wrong: on Linux + Node 22.5, `new Intl.DateTimeFormat
|
|
1230
|
+
* ("POSIX")` does NOT throw, it silently falls back to the root locale and
|
|
1231
|
+
* still emits garbage at format time. CI run 25904838577 surfaced that —
|
|
1232
|
+
* "POSIX" round-tripped through the validator unchanged.
|
|
1233
|
+
*
|
|
1234
|
+
* Strict gate: `Intl.DateTimeFormat.supportedLocalesOf(tag)` returns `[]` for
|
|
1235
|
+
* any tag that doesn't map to a real language (regardless of whether
|
|
1236
|
+
* construction with that tag throws). That's the contract we want — "is this
|
|
1237
|
+
* a BCP 47 tag the host actually has data for". Construction is an explicit
|
|
1238
|
+
* sanity check; both must pass.
|
|
1239
|
+
*/
|
|
1240
|
+
function isUsableBcp47Locale(raw) {
|
|
1241
|
+
if (!raw)
|
|
1242
|
+
return false;
|
|
1243
|
+
try {
|
|
1244
|
+
if (Intl.DateTimeFormat.supportedLocalesOf(raw).length === 0)
|
|
1245
|
+
return false;
|
|
1246
|
+
// Belt: confirm construction doesn't throw on this host either.
|
|
1247
|
+
new Intl.DateTimeFormat(raw);
|
|
1248
|
+
return true;
|
|
1249
|
+
}
|
|
1250
|
+
catch {
|
|
1251
|
+
return false;
|
|
1252
|
+
}
|
|
1253
|
+
}
|
|
1220
1254
|
export function detectLocaleAndTz() {
|
|
1221
1255
|
const env = (process.env ?? {});
|
|
1222
1256
|
let locale = env.CONTEXT_MODE_LOCALE ?? "";
|
|
1257
|
+
if (locale && !isUsableBcp47Locale(locale))
|
|
1258
|
+
locale = "";
|
|
1223
1259
|
if (!locale) {
|
|
1224
1260
|
if (process.platform === "darwin") {
|
|
1225
1261
|
try {
|
|
@@ -1234,11 +1270,18 @@ export function detectLocaleAndTz() {
|
|
|
1234
1270
|
locale = out.replace(/_/g, "-");
|
|
1235
1271
|
}
|
|
1236
1272
|
catch { /* defaults missing or sandbox */ }
|
|
1273
|
+
if (locale && !isUsableBcp47Locale(locale))
|
|
1274
|
+
locale = "";
|
|
1237
1275
|
}
|
|
1238
1276
|
if (!locale && (env.LC_TIME || env.LANG)) {
|
|
1239
1277
|
const raw = (env.LC_TIME || env.LANG || "").split(".")[0];
|
|
1240
1278
|
if (raw)
|
|
1241
1279
|
locale = raw.replace(/_/g, "-");
|
|
1280
|
+
// POSIX locale identifiers (`C`, `POSIX`) survive the simple extraction
|
|
1281
|
+
// above but blow up `new Intl.DateTimeFormat(locale, ...)`. Drop and
|
|
1282
|
+
// fall through to the host-default branch below.
|
|
1283
|
+
if (locale && !isUsableBcp47Locale(locale))
|
|
1284
|
+
locale = "";
|
|
1242
1285
|
}
|
|
1243
1286
|
if (!locale) {
|
|
1244
1287
|
try {
|
|
@@ -1258,7 +1301,13 @@ export function detectLocaleAndTz() {
|
|
|
1258
1301
|
tz = "UTC";
|
|
1259
1302
|
}
|
|
1260
1303
|
}
|
|
1261
|
-
|
|
1304
|
+
// Final belt-and-suspenders: if the locale we settled on is somehow still
|
|
1305
|
+
// unusable (env mutation between detection and return, contributor adding
|
|
1306
|
+
// a new extraction path that skips the validator), fall back to en-US so
|
|
1307
|
+
// formatLocalDateTime / monthDay / weekdayCap never throw at render time.
|
|
1308
|
+
if (!isUsableBcp47Locale(locale))
|
|
1309
|
+
locale = "en-US";
|
|
1310
|
+
return { locale, tz: tz || "UTC" };
|
|
1262
1311
|
}
|
|
1263
1312
|
/**
|
|
1264
1313
|
* Format an absolute path as a human-friendly display string by
|
package/build/session/extract.js
CHANGED
|
@@ -613,7 +613,45 @@ function extractDecision(input) {
|
|
|
613
613
|
const questionText = Array.isArray(questions) && questions.length > 0
|
|
614
614
|
? String(questions[0]["question"] ?? "")
|
|
615
615
|
: "";
|
|
616
|
-
|
|
616
|
+
// tool_response is a JSON string that echoes the full request payload
|
|
617
|
+
// alongside the answers map: {"questions":[...],"answers":{"<q>":"<label>"}}.
|
|
618
|
+
// Stringifying the raw blob leaks the echoed questions/options into the
|
|
619
|
+
// event row and surfaces as "Unhandled case: [object Object]" downstream.
|
|
620
|
+
const rawResponse = String(input.tool_response ?? "");
|
|
621
|
+
let answerText = "";
|
|
622
|
+
try {
|
|
623
|
+
const parsed = JSON.parse(rawResponse);
|
|
624
|
+
const answers = parsed?.answers;
|
|
625
|
+
if (answers && typeof answers === "object") {
|
|
626
|
+
// multiSelect: true answers arrive as string[]; single-select arrive as
|
|
627
|
+
// string. Normalize both into a `" | "`-joined string so neither shape
|
|
628
|
+
// silently produces an empty answer.
|
|
629
|
+
const toAnswerText = (value) => {
|
|
630
|
+
if (typeof value === "string")
|
|
631
|
+
return value;
|
|
632
|
+
if (Array.isArray(value)) {
|
|
633
|
+
return value.filter((v) => typeof v === "string").join(" | ");
|
|
634
|
+
}
|
|
635
|
+
return "";
|
|
636
|
+
};
|
|
637
|
+
const matched = questionText ? toAnswerText(answers[questionText]) : "";
|
|
638
|
+
if (matched) {
|
|
639
|
+
answerText = matched;
|
|
640
|
+
}
|
|
641
|
+
else {
|
|
642
|
+
const values = Object.values(answers)
|
|
643
|
+
.map(toAnswerText)
|
|
644
|
+
.filter((v) => v.length > 0);
|
|
645
|
+
answerText = values.join(" | ");
|
|
646
|
+
}
|
|
647
|
+
}
|
|
648
|
+
}
|
|
649
|
+
catch {
|
|
650
|
+
// Non-JSON tool_response — fail safe with empty answer rather than
|
|
651
|
+
// leaking the raw text (which would re-introduce the original bug
|
|
652
|
+
// for any future caller that sends a non-JSON payload).
|
|
653
|
+
}
|
|
654
|
+
const answer = safeString(answerText);
|
|
617
655
|
const summary = questionText
|
|
618
656
|
? `Q: ${safeString(questionText)} → A: ${answer}`
|
|
619
657
|
: `answer: ${answer}`;
|
|
@@ -13,12 +13,18 @@ export declare function resolveClaudeGlobalSettingsPath(env?: NodeJS.ProcessEnv)
|
|
|
13
13
|
* adapter is non-claude — claude is already covered by entry 2).
|
|
14
14
|
* 2. The claude global settings.json (always — defense in depth).
|
|
15
15
|
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
16
|
+
* Static import of `../adapters/detect.js` is safe — detect.ts only imports
|
|
17
|
+
* `node:` builtins, `./types.js` (type-only), and `./client-map.js` (pure
|
|
18
|
+
* data). It does NOT import claude-config back, so no cycle.
|
|
19
|
+
*
|
|
20
|
+
* History: this used `createRequire(import.meta.url).resolve(...)` to lazy-
|
|
21
|
+
* load detect at call time. That pattern requires `require(esm)`, which is
|
|
22
|
+
* flag-gated on Node 22.x before 22.12 (`--experimental-require-module`).
|
|
23
|
+
* CI run 25877550371 on Node 22.5 silently failed every detect.* call —
|
|
24
|
+
* the catch block ate the error and every cross-adapter deny-policy test
|
|
25
|
+
* returned an empty policy list. Static import sidesteps the require(esm)
|
|
26
|
+
* gate entirely, so the same code works on every supported Node version
|
|
27
|
+
* (20.x, 22.5, 22.12+, 24+) without needing the experimental flag.
|
|
22
28
|
*
|
|
23
29
|
* The returned array is deduplicated and order-stable: adapter-specific path
|
|
24
30
|
* first (most specific), claude global second (fallback).
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
*/
|
|
24
24
|
import { resolve } from "node:path";
|
|
25
25
|
import { homedir } from "node:os";
|
|
26
|
-
import {
|
|
26
|
+
import { detectPlatform, getSessionDirSegments } from "../adapters/detect.js";
|
|
27
27
|
export function resolveClaudeConfigDir(env = process.env) {
|
|
28
28
|
const envVal = env.CLAUDE_CONFIG_DIR;
|
|
29
29
|
if (envVal && envVal.trim() !== "") {
|
|
@@ -50,34 +50,27 @@ export function resolveClaudeGlobalSettingsPath(env = process.env) {
|
|
|
50
50
|
* adapter is non-claude — claude is already covered by entry 2).
|
|
51
51
|
* 2. The claude global settings.json (always — defense in depth).
|
|
52
52
|
*
|
|
53
|
-
*
|
|
54
|
-
*
|
|
55
|
-
*
|
|
56
|
-
*
|
|
57
|
-
*
|
|
58
|
-
*
|
|
53
|
+
* Static import of `../adapters/detect.js` is safe — detect.ts only imports
|
|
54
|
+
* `node:` builtins, `./types.js` (type-only), and `./client-map.js` (pure
|
|
55
|
+
* data). It does NOT import claude-config back, so no cycle.
|
|
56
|
+
*
|
|
57
|
+
* History: this used `createRequire(import.meta.url).resolve(...)` to lazy-
|
|
58
|
+
* load detect at call time. That pattern requires `require(esm)`, which is
|
|
59
|
+
* flag-gated on Node 22.x before 22.12 (`--experimental-require-module`).
|
|
60
|
+
* CI run 25877550371 on Node 22.5 silently failed every detect.* call —
|
|
61
|
+
* the catch block ate the error and every cross-adapter deny-policy test
|
|
62
|
+
* returned an empty policy list. Static import sidesteps the require(esm)
|
|
63
|
+
* gate entirely, so the same code works on every supported Node version
|
|
64
|
+
* (20.x, 22.5, 22.12+, 24+) without needing the experimental flag.
|
|
59
65
|
*
|
|
60
66
|
* The returned array is deduplicated and order-stable: adapter-specific path
|
|
61
67
|
* first (most specific), claude global second (fallback).
|
|
62
68
|
*/
|
|
63
69
|
export function resolveAdapterGlobalSettingsPaths(env = process.env) {
|
|
64
70
|
const paths = [];
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
let detected = null;
|
|
69
|
-
let segmentsFor = null;
|
|
70
|
-
try {
|
|
71
|
-
const lazyRequire = createRequire(import.meta.url);
|
|
72
|
-
const detect = lazyRequire("../adapters/detect.js");
|
|
73
|
-
detected = detect.detectPlatform();
|
|
74
|
-
segmentsFor = detect.getSessionDirSegments;
|
|
75
|
-
}
|
|
76
|
-
catch {
|
|
77
|
-
// If detection fails for any reason, fall back to claude-only behavior.
|
|
78
|
-
}
|
|
79
|
-
if (detected && segmentsFor && detected.platform !== "claude-code") {
|
|
80
|
-
const segments = segmentsFor(detected.platform);
|
|
71
|
+
const detected = detectPlatform();
|
|
72
|
+
if (detected.platform !== "claude-code") {
|
|
73
|
+
const segments = getSessionDirSegments(detected.platform);
|
|
81
74
|
if (segments && segments.length > 0) {
|
|
82
75
|
paths.push(resolve(homedir(), ...segments, "settings.json"));
|
|
83
76
|
}
|