opencode-acp 1.15.0 → 1.16.0-pr.349.122
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 +28 -0
- package/README.zh-CN.md +27 -0
- package/dist/index.js +232 -82
- package/dist/index.js.map +1 -1
- package/dist/lib/compress/decompress.d.ts.map +1 -1
- package/dist/lib/config-validation.d.ts.map +1 -1
- package/dist/lib/config.d.ts +16 -0
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/gc/merge.d.ts.map +1 -1
- package/dist/lib/hooks.d.ts.map +1 -1
- package/dist/lib/messages/inject/utils.d.ts.map +1 -1
- package/dist/lib/messages/truncate-tools.d.ts +1 -0
- package/dist/lib/messages/truncate-tools.d.ts.map +1 -1
- package/dist/lib/state/persistence.d.ts +14 -3
- package/dist/lib/state/persistence.d.ts.map +1 -1
- package/dist/lib/state/state.d.ts +5 -2
- package/dist/lib/state/state.d.ts.map +1 -1
- package/dist/lib/state/types.d.ts +6 -0
- package/dist/lib/state/types.d.ts.map +1 -1
- package/dist/lib/state/utils.d.ts +16 -0
- package/dist/lib/state/utils.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -869,6 +869,7 @@ var VALID_CONFIG_KEYS = /* @__PURE__ */ new Set([
|
|
|
869
869
|
"autoUpdate",
|
|
870
870
|
"debug",
|
|
871
871
|
"logLevel",
|
|
872
|
+
"storagePath",
|
|
872
873
|
"showUpdateToasts",
|
|
873
874
|
"allowSubAgents",
|
|
874
875
|
"pruneNotification",
|
|
@@ -889,6 +890,7 @@ var VALID_CONFIG_KEYS = /* @__PURE__ */ new Set([
|
|
|
889
890
|
"compress.modelMaxLimits",
|
|
890
891
|
"compress.modelMinLimits",
|
|
891
892
|
"compress.providers",
|
|
893
|
+
"compress.contextLimitFallback",
|
|
892
894
|
"compress.nudgeFrequency",
|
|
893
895
|
"compress.minNudgeContextPercent",
|
|
894
896
|
"compress.nudgeGrowthTokens",
|
|
@@ -959,6 +961,9 @@ function validateConfigTypes(config) {
|
|
|
959
961
|
if (config.debug !== void 0 && typeof config.debug !== "boolean") {
|
|
960
962
|
errors.push({ key: "debug", expected: "boolean", actual: typeof config.debug });
|
|
961
963
|
}
|
|
964
|
+
if (config.storagePath !== void 0 && typeof config.storagePath !== "string") {
|
|
965
|
+
errors.push({ key: "storagePath", expected: "string", actual: typeof config.storagePath });
|
|
966
|
+
}
|
|
962
967
|
if (config.allowSubAgents !== void 0 && typeof config.allowSubAgents !== "boolean") {
|
|
963
968
|
errors.push({ key: "allowSubAgents", expected: "boolean", actual: typeof config.allowSubAgents });
|
|
964
969
|
}
|
|
@@ -1517,6 +1522,20 @@ function validateConfigTypes(config) {
|
|
|
1517
1522
|
}
|
|
1518
1523
|
};
|
|
1519
1524
|
validateProviderOverrides(compress.providers);
|
|
1525
|
+
if (compress.contextLimitFallback !== void 0 && typeof compress.contextLimitFallback !== "number") {
|
|
1526
|
+
errors.push({
|
|
1527
|
+
key: "compress.contextLimitFallback",
|
|
1528
|
+
expected: "number",
|
|
1529
|
+
actual: typeof compress.contextLimitFallback
|
|
1530
|
+
});
|
|
1531
|
+
}
|
|
1532
|
+
if (typeof compress.contextLimitFallback === "number" && compress.contextLimitFallback < 0) {
|
|
1533
|
+
errors.push({
|
|
1534
|
+
key: "compress.contextLimitFallback",
|
|
1535
|
+
expected: "non-negative number (0 disables the fallback)",
|
|
1536
|
+
actual: `${compress.contextLimitFallback}`
|
|
1537
|
+
});
|
|
1538
|
+
}
|
|
1520
1539
|
const validValues = ["ask", "allow", "deny"];
|
|
1521
1540
|
if (compress.permission !== void 0 && !validValues.includes(compress.permission)) {
|
|
1522
1541
|
errors.push({
|
|
@@ -1698,6 +1717,7 @@ var defaultConfig = {
|
|
|
1698
1717
|
summaryBuffer: true,
|
|
1699
1718
|
maxContextLimit: "80%",
|
|
1700
1719
|
minContextLimit: "80%",
|
|
1720
|
+
contextLimitFallback: 128e3,
|
|
1701
1721
|
nudgeFrequency: 5,
|
|
1702
1722
|
minNudgeContextPercent: 5,
|
|
1703
1723
|
iterationNudgeThreshold: 15,
|
|
@@ -1868,6 +1888,7 @@ function mergeCompress(base, override) {
|
|
|
1868
1888
|
modelMaxLimits: override.modelMaxLimits ?? base.modelMaxLimits,
|
|
1869
1889
|
modelMinLimits: override.modelMinLimits ?? base.modelMinLimits,
|
|
1870
1890
|
providers: mergeProviderOverrides(base.providers, override.providers),
|
|
1891
|
+
contextLimitFallback: override.contextLimitFallback ?? base.contextLimitFallback,
|
|
1871
1892
|
nudgeFrequency: override.nudgeFrequency ?? base.nudgeFrequency,
|
|
1872
1893
|
minNudgeContextPercent: override.minNudgeContextPercent ?? base.minNudgeContextPercent,
|
|
1873
1894
|
nudgeGrowthTokens: override.nudgeGrowthTokens,
|
|
@@ -1995,6 +2016,7 @@ function mergeLayer(config, data) {
|
|
|
1995
2016
|
autoUpdate: data.autoUpdate ?? config.autoUpdate,
|
|
1996
2017
|
debug: data.debug ?? config.debug,
|
|
1997
2018
|
logLevel: data.logLevel ?? config.logLevel,
|
|
2019
|
+
storagePath: data.storagePath ?? config.storagePath,
|
|
1998
2020
|
allowSubAgents: data.allowSubAgents ?? data.experimental?.allowSubAgents ?? config.allowSubAgents,
|
|
1999
2021
|
pruneNotification: data.pruneNotification ?? config.pruneNotification,
|
|
2000
2022
|
pruneNotificationType: data.pruneNotificationType ?? config.pruneNotificationType,
|
|
@@ -2349,7 +2371,7 @@ Each entry needs a topic \u2014 either its own or the top-level fallback.`;
|
|
|
2349
2371
|
import * as fs from "fs/promises";
|
|
2350
2372
|
import { existsSync as existsSync2 } from "fs";
|
|
2351
2373
|
import { homedir as homedir2 } from "os";
|
|
2352
|
-
import { join as join2 } from "path";
|
|
2374
|
+
import { isAbsolute, join as join2 } from "path";
|
|
2353
2375
|
|
|
2354
2376
|
// lib/state/utils.ts
|
|
2355
2377
|
var isMessageCompacted = (state, msg) => {
|
|
@@ -2630,9 +2652,19 @@ function resetOnCompaction(state) {
|
|
|
2630
2652
|
nextRef: 1
|
|
2631
2653
|
};
|
|
2632
2654
|
}
|
|
2655
|
+
function resolveEffectiveContextLimit(state, config) {
|
|
2656
|
+
if (typeof state.modelContextLimit === "number" && state.modelContextLimit > 0) {
|
|
2657
|
+
return { limit: state.modelContextLimit, source: "model" };
|
|
2658
|
+
}
|
|
2659
|
+
const fallback = config.compress.contextLimitFallback;
|
|
2660
|
+
if (typeof fallback === "number" && fallback > 0) {
|
|
2661
|
+
return { limit: fallback, source: "fallback" };
|
|
2662
|
+
}
|
|
2663
|
+
return void 0;
|
|
2664
|
+
}
|
|
2633
2665
|
|
|
2634
2666
|
// lib/state/persistence.ts
|
|
2635
|
-
function
|
|
2667
|
+
function getDefaultStorageDir() {
|
|
2636
2668
|
return join2(
|
|
2637
2669
|
process.env.XDG_DATA_HOME || join2(homedir2(), ".local", "share"),
|
|
2638
2670
|
"opencode",
|
|
@@ -2641,14 +2673,33 @@ function getStorageDir() {
|
|
|
2641
2673
|
"acp"
|
|
2642
2674
|
);
|
|
2643
2675
|
}
|
|
2644
|
-
function
|
|
2645
|
-
|
|
2676
|
+
function resolveStorageDir(configured, projectDir) {
|
|
2677
|
+
const trimmed = configured?.trim();
|
|
2678
|
+
if (!trimmed) {
|
|
2679
|
+
return getDefaultStorageDir();
|
|
2680
|
+
}
|
|
2681
|
+
if (trimmed === "~") {
|
|
2682
|
+
return homedir2();
|
|
2683
|
+
}
|
|
2684
|
+
if (trimmed.startsWith("~/")) {
|
|
2685
|
+
return join2(homedir2(), trimmed.slice(2));
|
|
2686
|
+
}
|
|
2687
|
+
if (isAbsolute(trimmed)) {
|
|
2688
|
+
return trimmed;
|
|
2689
|
+
}
|
|
2690
|
+
return join2(projectDir, trimmed);
|
|
2691
|
+
}
|
|
2692
|
+
function getStorageDir(override) {
|
|
2693
|
+
return override || getDefaultStorageDir();
|
|
2694
|
+
}
|
|
2695
|
+
function getSessionFilePath(sessionId, storageDir) {
|
|
2696
|
+
return join2(getStorageDir(storageDir), `${sessionId}.json`);
|
|
2646
2697
|
}
|
|
2647
|
-
async function writePersistedSessionState(sessionId, state, logger) {
|
|
2648
|
-
const filePath = getSessionFilePath(sessionId);
|
|
2649
|
-
const
|
|
2650
|
-
if (!existsSync2(
|
|
2651
|
-
await fs.mkdir(
|
|
2698
|
+
async function writePersistedSessionState(sessionId, state, logger, storageDir) {
|
|
2699
|
+
const filePath = getSessionFilePath(sessionId, storageDir);
|
|
2700
|
+
const dir = getStorageDir(storageDir);
|
|
2701
|
+
if (!existsSync2(dir)) {
|
|
2702
|
+
await fs.mkdir(dir, { recursive: true });
|
|
2652
2703
|
}
|
|
2653
2704
|
const content = JSON.stringify(state, null, 2);
|
|
2654
2705
|
await fs.writeFile(filePath, content, "utf-8");
|
|
@@ -2690,11 +2741,11 @@ async function saveSessionState(sessionState, logger, sessionName) {
|
|
|
2690
2741
|
modelProviderID: sessionState.modelProviderID,
|
|
2691
2742
|
modelID: sessionState.modelID
|
|
2692
2743
|
};
|
|
2693
|
-
await writePersistedSessionState(sessionState.sessionId, state, logger);
|
|
2744
|
+
await writePersistedSessionState(sessionState.sessionId, state, logger, sessionState.storageDir);
|
|
2694
2745
|
}
|
|
2695
|
-
async function loadSessionState(sessionId, logger) {
|
|
2746
|
+
async function loadSessionState(sessionId, logger, storageDir) {
|
|
2696
2747
|
try {
|
|
2697
|
-
const filePath = getSessionFilePath(sessionId);
|
|
2748
|
+
const filePath = getSessionFilePath(sessionId, storageDir);
|
|
2698
2749
|
if (!existsSync2(filePath)) {
|
|
2699
2750
|
return null;
|
|
2700
2751
|
}
|
|
@@ -2770,6 +2821,11 @@ async function loadSessionState(sessionId, logger) {
|
|
|
2770
2821
|
}
|
|
2771
2822
|
}
|
|
2772
2823
|
|
|
2824
|
+
// lib/state/state.ts
|
|
2825
|
+
import { existsSync as existsSync3 } from "fs";
|
|
2826
|
+
import { join as join3 } from "path";
|
|
2827
|
+
import { cwd } from "process";
|
|
2828
|
+
|
|
2773
2829
|
// lib/message-ids.ts
|
|
2774
2830
|
var MESSAGE_REF_REGEX = /^m(\d{4,5})$/;
|
|
2775
2831
|
var BLOCK_REF_REGEX = /^b([1-9]\d*)$/;
|
|
@@ -4446,10 +4502,12 @@ async function updatePerTurnState(state, logger, messages) {
|
|
|
4446
4502
|
}
|
|
4447
4503
|
var REGISTRY_SOFT_CAP = 32;
|
|
4448
4504
|
var SessionStateRegistry = class {
|
|
4449
|
-
constructor(logger) {
|
|
4505
|
+
constructor(logger, projectDir) {
|
|
4450
4506
|
this.logger = logger;
|
|
4507
|
+
this.projectDir = projectDir;
|
|
4451
4508
|
}
|
|
4452
4509
|
logger;
|
|
4510
|
+
projectDir;
|
|
4453
4511
|
states = /* @__PURE__ */ new Map();
|
|
4454
4512
|
compressionTiming = {
|
|
4455
4513
|
startsByCallId: /* @__PURE__ */ new Map(),
|
|
@@ -4475,6 +4533,24 @@ var SessionStateRegistry = class {
|
|
|
4475
4533
|
hydrateModelLimitsFromClient(client) {
|
|
4476
4534
|
return this.catalog.hydrateFromClient(client);
|
|
4477
4535
|
}
|
|
4536
|
+
// [FIX #346] The init-time seed (above) is fire-and-forget and races
|
|
4537
|
+
// server readiness: in headless spawn+resume mode the provider-config
|
|
4538
|
+
// call can fail before the server is up, leaving the catalog empty for
|
|
4539
|
+
// the process's lifetime. During a request the server is guaranteed up
|
|
4540
|
+
// (we are inside its pipeline), so on a catalog miss we retry hydration
|
|
4541
|
+
// once per process before giving up (the fallback limit then applies).
|
|
4542
|
+
// The in-flight promise (not a boolean) lets concurrent callers await the
|
|
4543
|
+
// same hydration instead of skipping it.
|
|
4544
|
+
lazyHydration;
|
|
4545
|
+
async hydrateAndResolve(client, providerId, modelId) {
|
|
4546
|
+
const existing = this.catalog.resolve(providerId, modelId);
|
|
4547
|
+
if (existing !== void 0) {
|
|
4548
|
+
return existing;
|
|
4549
|
+
}
|
|
4550
|
+
this.lazyHydration ??= this.catalog.hydrateFromClient(client);
|
|
4551
|
+
await this.lazyHydration;
|
|
4552
|
+
return this.catalog.resolve(providerId, modelId);
|
|
4553
|
+
}
|
|
4478
4554
|
get(sessionId) {
|
|
4479
4555
|
return this.states.get(sessionId);
|
|
4480
4556
|
}
|
|
@@ -4502,7 +4578,8 @@ var SessionStateRegistry = class {
|
|
|
4502
4578
|
sessionId,
|
|
4503
4579
|
this.logger,
|
|
4504
4580
|
messages,
|
|
4505
|
-
config
|
|
4581
|
+
config,
|
|
4582
|
+
this.projectDir
|
|
4506
4583
|
);
|
|
4507
4584
|
} catch (err) {
|
|
4508
4585
|
this.logger.error("Failed to initialize session state", {
|
|
@@ -4566,6 +4643,7 @@ function createSessionState() {
|
|
|
4566
4643
|
modelProviderID: void 0,
|
|
4567
4644
|
modelID: void 0,
|
|
4568
4645
|
systemPromptTokens: void 0,
|
|
4646
|
+
storageDir: void 0,
|
|
4569
4647
|
qualityGateRetryPending: false
|
|
4570
4648
|
};
|
|
4571
4649
|
}
|
|
@@ -4607,21 +4685,30 @@ function resetSessionState(state) {
|
|
|
4607
4685
|
state.modelProviderID = void 0;
|
|
4608
4686
|
state.modelID = void 0;
|
|
4609
4687
|
state.systemPromptTokens = void 0;
|
|
4688
|
+
state.storageDir = void 0;
|
|
4610
4689
|
state.qualityGateRetryPending = false;
|
|
4611
4690
|
}
|
|
4612
|
-
async function ensureSessionInitialized(client, state, sessionId, logger, messages, config) {
|
|
4691
|
+
async function ensureSessionInitialized(client, state, sessionId, logger, messages, config, projectDir) {
|
|
4613
4692
|
if (state.sessionId === sessionId) {
|
|
4614
4693
|
return;
|
|
4615
4694
|
}
|
|
4616
4695
|
resetSessionState(state);
|
|
4617
4696
|
state.sessionId = sessionId;
|
|
4697
|
+
state.storageDir = config?.storagePath ? resolveStorageDir(config.storagePath, projectDir ?? cwd()) : void 0;
|
|
4618
4698
|
const isSubAgent = await isSubAgentSession(client, sessionId);
|
|
4619
4699
|
state.isSubAgent = isSubAgent;
|
|
4620
4700
|
state.lastCompaction = findLastCompactionTimestamp(messages);
|
|
4621
4701
|
state.currentTurn = countTurns(state, messages);
|
|
4622
4702
|
state.nudges.turnNudgeAnchors = collectTurnNudgeAnchors(messages);
|
|
4623
|
-
const persisted = await loadSessionState(sessionId, logger);
|
|
4703
|
+
const persisted = await loadSessionState(sessionId, logger, state.storageDir);
|
|
4624
4704
|
if (persisted === null) {
|
|
4705
|
+
const defaultPath = join3(getDefaultStorageDir(), `${sessionId}.json`);
|
|
4706
|
+
if (state.storageDir && existsSync3(defaultPath)) {
|
|
4707
|
+
logger.warn(
|
|
4708
|
+
"storagePath is set but no valid state was found there; a state file exists at the default location \u2014 move it manually to keep history",
|
|
4709
|
+
{ sessionId, storageDir: state.storageDir, defaultPath }
|
|
4710
|
+
);
|
|
4711
|
+
}
|
|
4625
4712
|
if (config) {
|
|
4626
4713
|
const rebuilt = rebuildCompressionState(state, messages, config, logger);
|
|
4627
4714
|
if (rebuilt > 0) {
|
|
@@ -6615,6 +6702,7 @@ function getModelInfo(messages) {
|
|
|
6615
6702
|
};
|
|
6616
6703
|
}
|
|
6617
6704
|
function resolveContextTokenLimit(config, state, providerId, modelId, threshold) {
|
|
6705
|
+
const effectiveLimit = resolveEffectiveContextLimit(state, config);
|
|
6618
6706
|
const parseLimitValue = (limit) => {
|
|
6619
6707
|
if (limit === void 0) {
|
|
6620
6708
|
return void 0;
|
|
@@ -6622,7 +6710,7 @@ function resolveContextTokenLimit(config, state, providerId, modelId, threshold)
|
|
|
6622
6710
|
if (typeof limit === "number") {
|
|
6623
6711
|
return limit;
|
|
6624
6712
|
}
|
|
6625
|
-
if (!limit.endsWith("%") ||
|
|
6713
|
+
if (!limit.endsWith("%") || effectiveLimit === void 0) {
|
|
6626
6714
|
return void 0;
|
|
6627
6715
|
}
|
|
6628
6716
|
const parsedPercent = parseFloat(limit.slice(0, -1));
|
|
@@ -6631,7 +6719,7 @@ function resolveContextTokenLimit(config, state, providerId, modelId, threshold)
|
|
|
6631
6719
|
}
|
|
6632
6720
|
const roundedPercent = Math.round(parsedPercent);
|
|
6633
6721
|
const clampedPercent = Math.max(0, Math.min(100, roundedPercent));
|
|
6634
|
-
return Math.round(clampedPercent / 100 *
|
|
6722
|
+
return Math.round(clampedPercent / 100 * effectiveLimit.limit);
|
|
6635
6723
|
};
|
|
6636
6724
|
if (threshold === "max") {
|
|
6637
6725
|
const nestedLimit = resolveCompressOverrides(config, providerId, modelId).maxContextLimit;
|
|
@@ -6682,11 +6770,12 @@ function isContextOverLimits(config, state, providerId, modelId, messages) {
|
|
|
6682
6770
|
if (!overMaxLimit) break;
|
|
6683
6771
|
}
|
|
6684
6772
|
}
|
|
6773
|
+
const effectiveLimit = resolveEffectiveContextLimit(state, config);
|
|
6685
6774
|
return {
|
|
6686
6775
|
overMaxLimit,
|
|
6687
6776
|
overMinLimit,
|
|
6688
6777
|
currentTokens,
|
|
6689
|
-
modelContextLimit:
|
|
6778
|
+
modelContextLimit: effectiveLimit?.limit
|
|
6690
6779
|
};
|
|
6691
6780
|
}
|
|
6692
6781
|
ensureBuiltinTriggerPolicyRegistered();
|
|
@@ -8765,8 +8854,9 @@ function createDecompressTool(factoryCtx) {
|
|
|
8765
8854
|
async execute(args, toolCtx) {
|
|
8766
8855
|
const ctx = resolveToolContext(factoryCtx, toolCtx.sessionID);
|
|
8767
8856
|
const { rawMessages } = await prepareDecompressSession(ctx, toolCtx);
|
|
8768
|
-
const
|
|
8769
|
-
|
|
8857
|
+
const effectiveLimitBefore = resolveEffectiveContextLimit(ctx.state, ctx.config);
|
|
8858
|
+
const contextUsageBefore = effectiveLimitBefore ? Math.round(
|
|
8859
|
+
getCurrentTokenUsage(ctx.state, rawMessages) / effectiveLimitBefore.limit * 100
|
|
8770
8860
|
) : void 0;
|
|
8771
8861
|
const resolved = resolveTargets(args, ctx.state, rawMessages, ctx.logger);
|
|
8772
8862
|
if (!resolved.ok) {
|
|
@@ -8830,8 +8920,9 @@ function createDecompressTool(factoryCtx) {
|
|
|
8830
8920
|
0,
|
|
8831
8921
|
ctx.state.stats.totalPruneTokens - restoredTokens
|
|
8832
8922
|
);
|
|
8833
|
-
const
|
|
8834
|
-
|
|
8923
|
+
const effectiveLimitAfter = resolveEffectiveContextLimit(ctx.state, ctx.config);
|
|
8924
|
+
const contextUsageAfter = effectiveLimitAfter ? Math.round(
|
|
8925
|
+
getCurrentTokenUsage(ctx.state, rawMessages) / effectiveLimitAfter.limit * 100
|
|
8835
8926
|
) : void 0;
|
|
8836
8927
|
await finalizeDecompressSession(ctx);
|
|
8837
8928
|
const restoredContentPreview = buildRestoredContentPreview(
|
|
@@ -9485,10 +9576,10 @@ function hideFailedCompressCalls(messages) {
|
|
|
9485
9576
|
|
|
9486
9577
|
// lib/logger.ts
|
|
9487
9578
|
import { writeFile as writeFile2, mkdir as mkdir2 } from "fs/promises";
|
|
9488
|
-
import { join as
|
|
9489
|
-
import { existsSync as
|
|
9579
|
+
import { join as join4 } from "path";
|
|
9580
|
+
import { existsSync as existsSync4 } from "fs";
|
|
9490
9581
|
import { homedir as homedir3 } from "os";
|
|
9491
|
-
var LOG_VERSION = true ? "1.
|
|
9582
|
+
var LOG_VERSION = true ? "1.16.0-pr.349.122" : "dev";
|
|
9492
9583
|
var LEVEL_RANK = {
|
|
9493
9584
|
debug: 10,
|
|
9494
9585
|
info: 20,
|
|
@@ -9508,8 +9599,8 @@ var Logger = class {
|
|
|
9508
9599
|
constructor(enabled, level) {
|
|
9509
9600
|
const resolved = level !== void 0 && LEVEL_RANK[level] !== void 0 ? level : void 0;
|
|
9510
9601
|
this.level = resolved ?? (enabled ? "debug" : "warn");
|
|
9511
|
-
const configHome = process.env.XDG_CONFIG_HOME ||
|
|
9512
|
-
this.logDir =
|
|
9602
|
+
const configHome = process.env.XDG_CONFIG_HOME || join4(homedir3(), ".config");
|
|
9603
|
+
this.logDir = join4(configHome, "opencode", "logs", "acp");
|
|
9513
9604
|
}
|
|
9514
9605
|
/** Back-compat view of the old flag: true only at full debug verbosity. */
|
|
9515
9606
|
get enabled() {
|
|
@@ -9519,7 +9610,7 @@ var Logger = class {
|
|
|
9519
9610
|
return LEVEL_RANK[level] >= LEVEL_RANK[this.level];
|
|
9520
9611
|
}
|
|
9521
9612
|
async ensureLogDir() {
|
|
9522
|
-
if (!
|
|
9613
|
+
if (!existsSync4(this.logDir)) {
|
|
9523
9614
|
await mkdir2(this.logDir, { recursive: true });
|
|
9524
9615
|
}
|
|
9525
9616
|
}
|
|
@@ -9571,11 +9662,11 @@ var Logger = class {
|
|
|
9571
9662
|
const dataStr = this.formatData(data);
|
|
9572
9663
|
const logLine = `${timestamp} ${level.padEnd(5)} ${component}: ${message}${dataStr ? " | " + dataStr : ""} | v=${LOG_VERSION}
|
|
9573
9664
|
`;
|
|
9574
|
-
const dailyLogDir =
|
|
9575
|
-
if (!
|
|
9665
|
+
const dailyLogDir = join4(this.logDir, "daily");
|
|
9666
|
+
if (!existsSync4(dailyLogDir)) {
|
|
9576
9667
|
await mkdir2(dailyLogDir, { recursive: true });
|
|
9577
9668
|
}
|
|
9578
|
-
const logFile =
|
|
9669
|
+
const logFile = join4(dailyLogDir, `${(/* @__PURE__ */ new Date()).toISOString().split("T")[0]}.log`);
|
|
9579
9670
|
await writeFile2(logFile, logLine, { flag: "a" });
|
|
9580
9671
|
} catch (error) {
|
|
9581
9672
|
}
|
|
@@ -9686,18 +9777,18 @@ var Logger = class {
|
|
|
9686
9777
|
async saveContext(sessionId, messages) {
|
|
9687
9778
|
if (this.level !== "debug") return;
|
|
9688
9779
|
try {
|
|
9689
|
-
const contextDir =
|
|
9690
|
-
if (!
|
|
9780
|
+
const contextDir = join4(this.logDir, "context", sessionId);
|
|
9781
|
+
if (!existsSync4(contextDir)) {
|
|
9691
9782
|
await mkdir2(contextDir, { recursive: true });
|
|
9692
9783
|
}
|
|
9693
9784
|
const minimized = this.minimizeForDebug(messages).filter(
|
|
9694
9785
|
(msg) => msg.parts && msg.parts.length > 0
|
|
9695
9786
|
);
|
|
9696
9787
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
9697
|
-
const contextFile =
|
|
9788
|
+
const contextFile = join4(contextDir, `${timestamp}.json`);
|
|
9698
9789
|
await writeFile2(contextFile, JSON.stringify(minimized, null, 2));
|
|
9699
|
-
const versionFile =
|
|
9700
|
-
if (!
|
|
9790
|
+
const versionFile = join4(contextDir, "_version");
|
|
9791
|
+
if (!existsSync4(versionFile)) {
|
|
9701
9792
|
await writeFile2(versionFile, LOG_VERSION);
|
|
9702
9793
|
}
|
|
9703
9794
|
} catch (error) {
|
|
@@ -9706,8 +9797,8 @@ var Logger = class {
|
|
|
9706
9797
|
};
|
|
9707
9798
|
|
|
9708
9799
|
// lib/prompts/store.ts
|
|
9709
|
-
import { existsSync as
|
|
9710
|
-
import { join as
|
|
9800
|
+
import { existsSync as existsSync5, mkdirSync as mkdirSync2, readFileSync as readFileSync2, writeFileSync as writeFileSync2, statSync as statSync2 } from "fs";
|
|
9801
|
+
import { join as join5, dirname as dirname2 } from "path";
|
|
9711
9802
|
import { homedir as homedir4 } from "os";
|
|
9712
9803
|
|
|
9713
9804
|
// lib/prompts/system.ts
|
|
@@ -10037,8 +10128,8 @@ function createBundledRuntimePrompts() {
|
|
|
10037
10128
|
function findOpencodeDir2(startDir) {
|
|
10038
10129
|
let current = startDir;
|
|
10039
10130
|
while (current !== "/") {
|
|
10040
|
-
const candidate =
|
|
10041
|
-
if (
|
|
10131
|
+
const candidate = join5(current, ".opencode");
|
|
10132
|
+
if (existsSync5(candidate)) {
|
|
10042
10133
|
try {
|
|
10043
10134
|
if (statSync2(candidate).isDirectory()) {
|
|
10044
10135
|
return candidate;
|
|
@@ -10055,13 +10146,13 @@ function findOpencodeDir2(startDir) {
|
|
|
10055
10146
|
return null;
|
|
10056
10147
|
}
|
|
10057
10148
|
function resolvePromptPaths(workingDirectory) {
|
|
10058
|
-
const configHome = process.env.XDG_CONFIG_HOME ||
|
|
10059
|
-
const globalRoot =
|
|
10060
|
-
const defaultsDir =
|
|
10061
|
-
const globalOverridesDir =
|
|
10062
|
-
const configDirOverridesDir = process.env.OPENCODE_CONFIG_DIR ?
|
|
10149
|
+
const configHome = process.env.XDG_CONFIG_HOME || join5(homedir4(), ".config");
|
|
10150
|
+
const globalRoot = join5(configHome, "opencode", "acp-prompts");
|
|
10151
|
+
const defaultsDir = join5(globalRoot, "defaults");
|
|
10152
|
+
const globalOverridesDir = join5(globalRoot, "overrides");
|
|
10153
|
+
const configDirOverridesDir = process.env.OPENCODE_CONFIG_DIR ? join5(process.env.OPENCODE_CONFIG_DIR, "acp-prompts", "overrides") : null;
|
|
10063
10154
|
const opencodeDir = findOpencodeDir2(workingDirectory);
|
|
10064
|
-
const projectOverridesDir = opencodeDir ?
|
|
10155
|
+
const projectOverridesDir = opencodeDir ? join5(opencodeDir, "acp-prompts", "overrides") : null;
|
|
10065
10156
|
return {
|
|
10066
10157
|
defaultsDir,
|
|
10067
10158
|
globalOverridesDir,
|
|
@@ -10161,7 +10252,7 @@ function buildDefaultsReadmeContent() {
|
|
|
10161
10252
|
`;
|
|
10162
10253
|
}
|
|
10163
10254
|
function readFileIfExists(filePath) {
|
|
10164
|
-
if (!
|
|
10255
|
+
if (!existsSync5(filePath)) {
|
|
10165
10256
|
return null;
|
|
10166
10257
|
}
|
|
10167
10258
|
try {
|
|
@@ -10232,16 +10323,16 @@ var PromptStore = class {
|
|
|
10232
10323
|
const candidates = [];
|
|
10233
10324
|
if (this.paths.projectOverridesDir) {
|
|
10234
10325
|
candidates.push({
|
|
10235
|
-
path:
|
|
10326
|
+
path: join5(this.paths.projectOverridesDir, fileName)
|
|
10236
10327
|
});
|
|
10237
10328
|
}
|
|
10238
10329
|
if (this.paths.configDirOverridesDir) {
|
|
10239
10330
|
candidates.push({
|
|
10240
|
-
path:
|
|
10331
|
+
path: join5(this.paths.configDirOverridesDir, fileName)
|
|
10241
10332
|
});
|
|
10242
10333
|
}
|
|
10243
10334
|
candidates.push({
|
|
10244
|
-
path:
|
|
10335
|
+
path: join5(this.paths.globalOverridesDir, fileName)
|
|
10245
10336
|
});
|
|
10246
10337
|
return candidates;
|
|
10247
10338
|
}
|
|
@@ -10264,7 +10355,7 @@ var PromptStore = class {
|
|
|
10264
10355
|
const managedContent = buildDefaultPromptFileContent(
|
|
10265
10356
|
bundledEditable || BUNDLED_EDITABLE_PROMPTS[definition.runtimeField]
|
|
10266
10357
|
);
|
|
10267
|
-
const filePath =
|
|
10358
|
+
const filePath = join5(this.paths.defaultsDir, definition.fileName);
|
|
10268
10359
|
try {
|
|
10269
10360
|
const existing = readFileIfExists(filePath);
|
|
10270
10361
|
if (existing === managedContent) {
|
|
@@ -10278,7 +10369,7 @@ var PromptStore = class {
|
|
|
10278
10369
|
});
|
|
10279
10370
|
}
|
|
10280
10371
|
}
|
|
10281
|
-
const readmePath =
|
|
10372
|
+
const readmePath = join5(this.paths.defaultsDir, DEFAULTS_README_FILE);
|
|
10282
10373
|
const readmeContent = buildDefaultsReadmeContent();
|
|
10283
10374
|
try {
|
|
10284
10375
|
const existing = readFileIfExists(readmePath);
|
|
@@ -10312,6 +10403,8 @@ var MIN_OUTPUT_TOKENS = 1e3;
|
|
|
10312
10403
|
var KEEP_PREFIX_CHARS = 2e3;
|
|
10313
10404
|
var KEEP_SUFFIX_CHARS = 2e3;
|
|
10314
10405
|
var PROTECT_RECENT_MESSAGES = 3;
|
|
10406
|
+
var OUTPUT_RESERVE_TOKENS = 16384;
|
|
10407
|
+
var overheadErrorLogged = /* @__PURE__ */ new Set();
|
|
10315
10408
|
function parseGcThreshold(threshold, modelContextLimit) {
|
|
10316
10409
|
if (typeof threshold === "number") return threshold;
|
|
10317
10410
|
const str = threshold ?? "100%";
|
|
@@ -10320,10 +10413,26 @@ function parseGcThreshold(threshold, modelContextLimit) {
|
|
|
10320
10413
|
return modelContextLimit;
|
|
10321
10414
|
}
|
|
10322
10415
|
function truncateLargeToolOutputs(state, config, logger, messages) {
|
|
10323
|
-
|
|
10416
|
+
const effective = resolveEffectiveContextLimit(state, config);
|
|
10417
|
+
if (!effective) return;
|
|
10324
10418
|
const currentTokens = getCurrentTokenUsage(state, messages);
|
|
10325
10419
|
if (currentTokens === 0) return;
|
|
10326
|
-
const
|
|
10420
|
+
const configuredThreshold = parseGcThreshold(config.gc?.majorGcThresholdPercent, effective.limit);
|
|
10421
|
+
const overhead = (state.systemPromptTokens ?? 0) + OUTPUT_RESERVE_TOKENS;
|
|
10422
|
+
const threshold = Math.min(configuredThreshold, effective.limit - overhead);
|
|
10423
|
+
if (threshold <= 0) {
|
|
10424
|
+
const sessionKey = state.sessionId ?? "unknown";
|
|
10425
|
+
if (!overheadErrorLogged.has(sessionKey)) {
|
|
10426
|
+
overheadErrorLogged.add(sessionKey);
|
|
10427
|
+
logger.error("ACP: model context window too small to fit overhead", {
|
|
10428
|
+
session: state.sessionId,
|
|
10429
|
+
limit: effective.limit,
|
|
10430
|
+
contextLimitSource: effective.source,
|
|
10431
|
+
overhead
|
|
10432
|
+
});
|
|
10433
|
+
}
|
|
10434
|
+
return;
|
|
10435
|
+
}
|
|
10327
10436
|
if (currentTokens < threshold) return;
|
|
10328
10437
|
const protectedIndex = messages.length - PROTECT_RECENT_MESSAGES;
|
|
10329
10438
|
const candidates = [];
|
|
@@ -10368,7 +10477,9 @@ function truncateLargeToolOutputs(state, config, logger, messages) {
|
|
|
10368
10477
|
truncatedCount,
|
|
10369
10478
|
estimatedSavedTokens: Math.round(savedTokens),
|
|
10370
10479
|
currentTokens,
|
|
10371
|
-
threshold
|
|
10480
|
+
threshold,
|
|
10481
|
+
contextLimit: effective.limit,
|
|
10482
|
+
contextLimitSource: effective.source
|
|
10372
10483
|
});
|
|
10373
10484
|
}
|
|
10374
10485
|
}
|
|
@@ -10575,8 +10686,8 @@ ${report}`;
|
|
|
10575
10686
|
|
|
10576
10687
|
// lib/commands/export.ts
|
|
10577
10688
|
import * as fs2 from "fs/promises";
|
|
10578
|
-
import { existsSync as
|
|
10579
|
-
import { dirname as dirname3, isAbsolute, join as
|
|
10689
|
+
import { existsSync as existsSync6 } from "fs";
|
|
10690
|
+
import { dirname as dirname3, isAbsolute as isAbsolute2, join as join6, resolve } from "path";
|
|
10580
10691
|
var ALL_TIERS = [1, 2, 3];
|
|
10581
10692
|
var TIER_NAMES = {
|
|
10582
10693
|
1: "Tier 1 \u2014 Capture",
|
|
@@ -10687,9 +10798,9 @@ function parseTiers(raw) {
|
|
|
10687
10798
|
}
|
|
10688
10799
|
return result;
|
|
10689
10800
|
}
|
|
10690
|
-
function resolveDefaultOutputPath(sessionId,
|
|
10801
|
+
function resolveDefaultOutputPath(sessionId, cwd2) {
|
|
10691
10802
|
const short = (sessionId || "session").slice(0, 8);
|
|
10692
|
-
return
|
|
10803
|
+
return join6(cwd2, ".opencode", `acp-export-${short}.md`);
|
|
10693
10804
|
}
|
|
10694
10805
|
function formatTokens2(n) {
|
|
10695
10806
|
if (!Number.isFinite(n) || n <= 0) return "0";
|
|
@@ -10816,15 +10927,15 @@ async function handleExportCommand(ctx, args) {
|
|
|
10816
10927
|
await sendExportNotice(client, sessionId, ctx, markdown);
|
|
10817
10928
|
return;
|
|
10818
10929
|
}
|
|
10819
|
-
const
|
|
10820
|
-
const targetPath = options.outputPath !== "" ?
|
|
10930
|
+
const cwd2 = ctx.workingDirectory || process.cwd();
|
|
10931
|
+
const targetPath = options.outputPath !== "" ? isAbsolute2(options.outputPath) ? options.outputPath : resolve(cwd2, options.outputPath) : resolveDefaultOutputPath(sessionId, cwd2);
|
|
10821
10932
|
try {
|
|
10822
10933
|
const dir = dirname3(targetPath);
|
|
10823
|
-
if (!
|
|
10934
|
+
if (!existsSync6(dir)) {
|
|
10824
10935
|
await fs2.mkdir(dir, { recursive: true });
|
|
10825
10936
|
}
|
|
10826
10937
|
const flag = options.append ? "a" : "w";
|
|
10827
|
-
if (options.append &&
|
|
10938
|
+
if (options.append && existsSync6(targetPath)) {
|
|
10828
10939
|
await fs2.appendFile(targetPath, `
|
|
10829
10940
|
|
|
10830
10941
|
---
|
|
@@ -11329,11 +11440,12 @@ function runBatchCleanup(state, config, logger, messages) {
|
|
|
11329
11440
|
mergedCount: 0,
|
|
11330
11441
|
savedTokens: 0
|
|
11331
11442
|
};
|
|
11332
|
-
|
|
11443
|
+
const effective = resolveEffectiveContextLimit(state, config);
|
|
11444
|
+
if (!effective) {
|
|
11333
11445
|
return noop;
|
|
11334
11446
|
}
|
|
11335
11447
|
const currentTokens = getCurrentTokenUsage(state, messages);
|
|
11336
|
-
if (currentTokens <
|
|
11448
|
+
if (currentTokens < effective.limit) {
|
|
11337
11449
|
return noop;
|
|
11338
11450
|
}
|
|
11339
11451
|
const maxMergedLength = config.gc.maxOldGenSummaryLength;
|
|
@@ -11350,7 +11462,8 @@ function runBatchCleanup(state, config, logger, messages) {
|
|
|
11350
11462
|
mergedCount: result.mergedCount,
|
|
11351
11463
|
savedTokens: result.savedTokens,
|
|
11352
11464
|
currentTokens,
|
|
11353
|
-
contextLimit:
|
|
11465
|
+
contextLimit: effective.limit,
|
|
11466
|
+
contextLimitSource: effective.source
|
|
11354
11467
|
});
|
|
11355
11468
|
return {
|
|
11356
11469
|
tier: 3,
|
|
@@ -11384,11 +11497,6 @@ function createSystemPromptHandler(registry4, logger, config, prompts) {
|
|
|
11384
11497
|
input.model?.limit?.context
|
|
11385
11498
|
);
|
|
11386
11499
|
const state = input.sessionID ? registry4.get(input.sessionID) : void 0;
|
|
11387
|
-
if (state && input.model?.limit?.context) {
|
|
11388
|
-
state.modelContextLimit = input.model.limit.context;
|
|
11389
|
-
state.modelProviderID = input.model?.providerID;
|
|
11390
|
-
state.modelID = input.model?.id;
|
|
11391
|
-
}
|
|
11392
11500
|
if (!state || state.isSubAgent && !config.allowSubAgents) {
|
|
11393
11501
|
return;
|
|
11394
11502
|
}
|
|
@@ -11397,6 +11505,23 @@ function createSystemPromptHandler(registry4, logger, config, prompts) {
|
|
|
11397
11505
|
logger.info("Skipping DCP system prompt injection for internal agent");
|
|
11398
11506
|
return;
|
|
11399
11507
|
}
|
|
11508
|
+
if (input.model?.limit?.context) {
|
|
11509
|
+
const limit = input.model.limit.context;
|
|
11510
|
+
const providerID = input.model?.providerID;
|
|
11511
|
+
const modelID = input.model?.id;
|
|
11512
|
+
const changed = state.modelContextLimit !== limit || providerID !== void 0 && state.modelProviderID !== providerID || modelID !== void 0 && state.modelID !== modelID;
|
|
11513
|
+
state.modelContextLimit = limit;
|
|
11514
|
+
if (providerID !== void 0) {
|
|
11515
|
+
state.modelProviderID = providerID;
|
|
11516
|
+
}
|
|
11517
|
+
if (modelID !== void 0) {
|
|
11518
|
+
state.modelID = modelID;
|
|
11519
|
+
}
|
|
11520
|
+
if (changed) {
|
|
11521
|
+
saveSessionState(state, logger).catch(() => {
|
|
11522
|
+
});
|
|
11523
|
+
}
|
|
11524
|
+
}
|
|
11400
11525
|
const effectivePermission = compressPermission(state, config);
|
|
11401
11526
|
if (effectivePermission === "deny") {
|
|
11402
11527
|
return;
|
|
@@ -11441,10 +11566,17 @@ function createChatMessageTransformHandler(client, registry4, logger, config, pr
|
|
|
11441
11566
|
config
|
|
11442
11567
|
);
|
|
11443
11568
|
const requestModel = lastUserMessage.info.model;
|
|
11444
|
-
|
|
11569
|
+
let requestModelLimit = registry4.resolveModelLimit(
|
|
11445
11570
|
requestModel?.providerID,
|
|
11446
11571
|
requestModel?.modelID
|
|
11447
11572
|
);
|
|
11573
|
+
if (requestModelLimit === void 0 && requestModel?.providerID && requestModel?.modelID) {
|
|
11574
|
+
requestModelLimit = await registry4.hydrateAndResolve(
|
|
11575
|
+
client,
|
|
11576
|
+
requestModel.providerID,
|
|
11577
|
+
requestModel.modelID
|
|
11578
|
+
);
|
|
11579
|
+
}
|
|
11448
11580
|
const prevModelID = state.modelID;
|
|
11449
11581
|
if (requestModelLimit !== void 0) {
|
|
11450
11582
|
state.modelContextLimit = requestModelLimit;
|
|
@@ -11499,10 +11631,11 @@ function createChatMessageTransformHandler(client, registry4, logger, config, pr
|
|
|
11499
11631
|
}
|
|
11500
11632
|
}
|
|
11501
11633
|
ensureBuiltinFiltersRegistered();
|
|
11634
|
+
const effectiveLimit = resolveEffectiveContextLimit(state, config);
|
|
11502
11635
|
applyMessageFilters(output.messages, config.messageFilters, logger, {
|
|
11503
11636
|
sessionId: state.sessionId ?? "",
|
|
11504
11637
|
isSubAgent: state.isSubAgent,
|
|
11505
|
-
modelContextLimit:
|
|
11638
|
+
modelContextLimit: effectiveLimit?.limit
|
|
11506
11639
|
});
|
|
11507
11640
|
cacheSystemPromptTokens(state, output.messages);
|
|
11508
11641
|
assignMessageRefs(state, output.messages);
|
|
@@ -11553,14 +11686,31 @@ ${text}`);
|
|
|
11553
11686
|
stripStaleMetadata(output.messages);
|
|
11554
11687
|
dropEmptyMessages(output.messages);
|
|
11555
11688
|
const postTokens = getCurrentTokenUsage(state, output.messages);
|
|
11689
|
+
if (postTokens !== void 0 && effectiveLimit) {
|
|
11690
|
+
const budget = effectiveLimit.limit - (state.systemPromptTokens ?? 0) - OUTPUT_RESERVE_TOKENS;
|
|
11691
|
+
if (postTokens > budget) {
|
|
11692
|
+
logger.error(
|
|
11693
|
+
"ACP hard guard: context exceeds model budget after in-flight reduction",
|
|
11694
|
+
{
|
|
11695
|
+
session: state.sessionId,
|
|
11696
|
+
postTokens,
|
|
11697
|
+
budget,
|
|
11698
|
+
contextLimit: effectiveLimit.limit,
|
|
11699
|
+
contextLimitSource: effectiveLimit.source,
|
|
11700
|
+
hint: "request will likely be rejected; run /compact or start a new session"
|
|
11701
|
+
}
|
|
11702
|
+
);
|
|
11703
|
+
}
|
|
11704
|
+
}
|
|
11556
11705
|
logger.info("Chat transform complete", {
|
|
11557
11706
|
session: state.sessionId,
|
|
11558
11707
|
model: state.modelID,
|
|
11559
11708
|
messages: output.messages.length,
|
|
11560
11709
|
prePruneTokens,
|
|
11561
11710
|
postTokens,
|
|
11562
|
-
contextLimit:
|
|
11563
|
-
|
|
11711
|
+
contextLimit: effectiveLimit?.limit,
|
|
11712
|
+
contextLimitSource: effectiveLimit?.source,
|
|
11713
|
+
usagePct: postTokens !== void 0 && effectiveLimit ? `${(postTokens / effectiveLimit.limit * 100).toFixed(1)}%` : void 0,
|
|
11564
11714
|
nudged: state.nudges.shouldInjectThisTurn
|
|
11565
11715
|
});
|
|
11566
11716
|
if (state.sessionId) {
|
|
@@ -11767,7 +11917,7 @@ function findBiliProxyProviders(provider) {
|
|
|
11767
11917
|
|
|
11768
11918
|
// lib/update.ts
|
|
11769
11919
|
import { readFile as readFile2, rm } from "fs/promises";
|
|
11770
|
-
import { basename, dirname as dirname4, join as
|
|
11920
|
+
import { basename, dirname as dirname4, join as join7 } from "path";
|
|
11771
11921
|
import { fileURLToPath } from "url";
|
|
11772
11922
|
var PACKAGE_NAME = "opencode-acp";
|
|
11773
11923
|
function startAutoUpdate(ctx, enabled, logger) {
|
|
@@ -11814,7 +11964,7 @@ async function checkAutoUpdate(signal, logger) {
|
|
|
11814
11964
|
logger?.info("Auto-update skipped: package dir not found");
|
|
11815
11965
|
return { updated: false };
|
|
11816
11966
|
}
|
|
11817
|
-
const pkg = await readPackageJson(
|
|
11967
|
+
const pkg = await readPackageJson(join7(packageDir, "package.json"));
|
|
11818
11968
|
if (!pkg?.name || !pkg.version) {
|
|
11819
11969
|
logger?.info("Auto-update skipped: package.json unreadable", { packageDir });
|
|
11820
11970
|
return { updated: false };
|
|
@@ -11855,7 +12005,7 @@ async function checkAutoUpdate(signal, logger) {
|
|
|
11855
12005
|
async function findPackageDir(name) {
|
|
11856
12006
|
let dir = dirname4(fileURLToPath(import.meta.url));
|
|
11857
12007
|
for (; ; ) {
|
|
11858
|
-
const pkg = await readPackageJson(
|
|
12008
|
+
const pkg = await readPackageJson(join7(dir, "package.json"));
|
|
11859
12009
|
if (pkg?.name === name) return dir;
|
|
11860
12010
|
const parent = dirname4(dir);
|
|
11861
12011
|
if (parent === dir) return void 0;
|
|
@@ -11867,7 +12017,7 @@ async function updateTarget(packageDir, name) {
|
|
|
11867
12017
|
const nodeModulesDir = basename(packageParent).startsWith("@") ? dirname4(packageParent) : packageParent;
|
|
11868
12018
|
if (basename(nodeModulesDir) !== "node_modules") return void 0;
|
|
11869
12019
|
const wrapperDir = dirname4(nodeModulesDir);
|
|
11870
|
-
const wrapperPkg = await readPackageJson(
|
|
12020
|
+
const wrapperPkg = await readPackageJson(join7(wrapperDir, "package.json"));
|
|
11871
12021
|
const spec = wrapperSpec(wrapperDir, name) ?? wrapperPkg?.dependencies?.[name];
|
|
11872
12022
|
if (!spec || !isAutoUpdatableSpec(spec)) return void 0;
|
|
11873
12023
|
return { removeDir: wrapperDir, spec };
|
|
@@ -11979,14 +12129,14 @@ var server = (async (ctx) => {
|
|
|
11979
12129
|
}
|
|
11980
12130
|
const logger = new Logger(config.debug, config.debug ? "debug" : config.logLevel);
|
|
11981
12131
|
logger.info("ACP plugin initialized", {
|
|
11982
|
-
version: true ? "1.
|
|
12132
|
+
version: true ? "1.16.0-pr.349.122" : "dev",
|
|
11983
12133
|
workspace: ctx.directory,
|
|
11984
12134
|
logLevel: logger.level,
|
|
11985
12135
|
debug: config.debug,
|
|
11986
12136
|
autoUpdate: config.autoUpdate,
|
|
11987
12137
|
secureMode: isSecureMode()
|
|
11988
12138
|
});
|
|
11989
|
-
const registry4 = new SessionStateRegistry(logger);
|
|
12139
|
+
const registry4 = new SessionStateRegistry(logger, ctx.directory);
|
|
11990
12140
|
const prompts = new PromptStore(logger, ctx.directory, config.experimental.customPrompts);
|
|
11991
12141
|
const hostPermissions = {
|
|
11992
12142
|
global: void 0,
|