opencode-acp 1.15.0-pr.381.116 → 1.16.0-pr.297.127
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 +13 -0
- package/README.zh-CN.md +13 -0
- package/dist/index.js +103 -62
- package/dist/index.js.map +1 -1
- package/dist/lib/config-validation.d.ts.map +1 -1
- package/dist/lib/config.d.ts +7 -0
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/hooks.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 +3 -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/package.json +1 -1
package/README.md
CHANGED
|
@@ -41,6 +41,19 @@ This brings two concrete effects:
|
|
|
41
41
|
|
|
42
42
|
---
|
|
43
43
|
|
|
44
|
+
## Which do I need?
|
|
45
|
+
|
|
46
|
+
Pick by your client:
|
|
47
|
+
|
|
48
|
+
| Client | Use |
|
|
49
|
+
|---|---|
|
|
50
|
+
| **pi** | [`billion-context-pi`](https://github.com/ranxianglei/billion-context-pi) (in-process extension) |
|
|
51
|
+
| **opencode** | [`opencode-acp`](https://github.com/ranxianglei/opencode-acp) (in-process extension) |
|
|
52
|
+
| **omp** | [`billion-context`](https://github.com/ranxianglei/billion-context) via `bili omp` (built-in plugin) |
|
|
53
|
+
| **everything else** (no context hook) | [`billion-context`](https://github.com/ranxianglei/billion-context) — `bili <client>` (launcher, preferred) or `/bili/` prefix |
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
44
57
|
## Proven at scale
|
|
45
58
|
|
|
46
59
|
Real engineering context, in practice.
|
package/README.zh-CN.md
CHANGED
|
@@ -33,6 +33,19 @@ ACP 将上下文管理的所有权限全部交给模型自己,而不依靠外
|
|
|
33
33
|
|
|
34
34
|
---
|
|
35
35
|
|
|
36
|
+
## 该选哪个?
|
|
37
|
+
|
|
38
|
+
按客户端选:
|
|
39
|
+
|
|
40
|
+
| 客户端 | 用这个 |
|
|
41
|
+
|---|---|
|
|
42
|
+
| **pi** | [`billion-context-pi`](https://github.com/ranxianglei/billion-context-pi)(进程内扩展) |
|
|
43
|
+
| **opencode** | [`opencode-acp`](https://github.com/ranxianglei/opencode-acp)(进程内扩展) |
|
|
44
|
+
| **omp** | [`billion-context`](https://github.com/ranxianglei/billion-context),`bili omp`(内置插件) |
|
|
45
|
+
| **其余所有**(没有上下文 hook) | [`billion-context`](https://github.com/ranxianglei/billion-context) —— `bili <client>`(启动器,优先)或 `/bili/` 前缀 |
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
36
49
|
## 实战验证
|
|
37
50
|
|
|
38
51
|
真实工程中的上下文情况。
|
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",
|
|
@@ -959,6 +960,9 @@ function validateConfigTypes(config) {
|
|
|
959
960
|
if (config.debug !== void 0 && typeof config.debug !== "boolean") {
|
|
960
961
|
errors.push({ key: "debug", expected: "boolean", actual: typeof config.debug });
|
|
961
962
|
}
|
|
963
|
+
if (config.storagePath !== void 0 && typeof config.storagePath !== "string") {
|
|
964
|
+
errors.push({ key: "storagePath", expected: "string", actual: typeof config.storagePath });
|
|
965
|
+
}
|
|
962
966
|
if (config.allowSubAgents !== void 0 && typeof config.allowSubAgents !== "boolean") {
|
|
963
967
|
errors.push({ key: "allowSubAgents", expected: "boolean", actual: typeof config.allowSubAgents });
|
|
964
968
|
}
|
|
@@ -1995,6 +1999,7 @@ function mergeLayer(config, data) {
|
|
|
1995
1999
|
autoUpdate: data.autoUpdate ?? config.autoUpdate,
|
|
1996
2000
|
debug: data.debug ?? config.debug,
|
|
1997
2001
|
logLevel: data.logLevel ?? config.logLevel,
|
|
2002
|
+
storagePath: data.storagePath ?? config.storagePath,
|
|
1998
2003
|
allowSubAgents: data.allowSubAgents ?? data.experimental?.allowSubAgents ?? config.allowSubAgents,
|
|
1999
2004
|
pruneNotification: data.pruneNotification ?? config.pruneNotification,
|
|
2000
2005
|
pruneNotificationType: data.pruneNotificationType ?? config.pruneNotificationType,
|
|
@@ -2349,7 +2354,7 @@ Each entry needs a topic \u2014 either its own or the top-level fallback.`;
|
|
|
2349
2354
|
import * as fs from "fs/promises";
|
|
2350
2355
|
import { existsSync as existsSync2 } from "fs";
|
|
2351
2356
|
import { homedir as homedir2 } from "os";
|
|
2352
|
-
import { join as join2 } from "path";
|
|
2357
|
+
import { isAbsolute, join as join2 } from "path";
|
|
2353
2358
|
|
|
2354
2359
|
// lib/state/utils.ts
|
|
2355
2360
|
var isMessageCompacted = (state, msg) => {
|
|
@@ -2632,7 +2637,7 @@ function resetOnCompaction(state) {
|
|
|
2632
2637
|
}
|
|
2633
2638
|
|
|
2634
2639
|
// lib/state/persistence.ts
|
|
2635
|
-
function
|
|
2640
|
+
function getDefaultStorageDir() {
|
|
2636
2641
|
return join2(
|
|
2637
2642
|
process.env.XDG_DATA_HOME || join2(homedir2(), ".local", "share"),
|
|
2638
2643
|
"opencode",
|
|
@@ -2641,14 +2646,33 @@ function getStorageDir() {
|
|
|
2641
2646
|
"acp"
|
|
2642
2647
|
);
|
|
2643
2648
|
}
|
|
2644
|
-
function
|
|
2645
|
-
|
|
2649
|
+
function resolveStorageDir(configured, projectDir) {
|
|
2650
|
+
const trimmed = configured?.trim();
|
|
2651
|
+
if (!trimmed) {
|
|
2652
|
+
return getDefaultStorageDir();
|
|
2653
|
+
}
|
|
2654
|
+
if (trimmed === "~") {
|
|
2655
|
+
return homedir2();
|
|
2656
|
+
}
|
|
2657
|
+
if (trimmed.startsWith("~/")) {
|
|
2658
|
+
return join2(homedir2(), trimmed.slice(2));
|
|
2659
|
+
}
|
|
2660
|
+
if (isAbsolute(trimmed)) {
|
|
2661
|
+
return trimmed;
|
|
2662
|
+
}
|
|
2663
|
+
return join2(projectDir, trimmed);
|
|
2664
|
+
}
|
|
2665
|
+
function getStorageDir(override) {
|
|
2666
|
+
return override || getDefaultStorageDir();
|
|
2667
|
+
}
|
|
2668
|
+
function getSessionFilePath(sessionId, storageDir) {
|
|
2669
|
+
return join2(getStorageDir(storageDir), `${sessionId}.json`);
|
|
2646
2670
|
}
|
|
2647
|
-
async function writePersistedSessionState(sessionId, state, logger) {
|
|
2648
|
-
const filePath = getSessionFilePath(sessionId);
|
|
2649
|
-
const
|
|
2650
|
-
if (!existsSync2(
|
|
2651
|
-
await fs.mkdir(
|
|
2671
|
+
async function writePersistedSessionState(sessionId, state, logger, storageDir) {
|
|
2672
|
+
const filePath = getSessionFilePath(sessionId, storageDir);
|
|
2673
|
+
const dir = getStorageDir(storageDir);
|
|
2674
|
+
if (!existsSync2(dir)) {
|
|
2675
|
+
await fs.mkdir(dir, { recursive: true });
|
|
2652
2676
|
}
|
|
2653
2677
|
const content = JSON.stringify(state, null, 2);
|
|
2654
2678
|
await fs.writeFile(filePath, content, "utf-8");
|
|
@@ -2690,11 +2714,11 @@ async function saveSessionState(sessionState, logger, sessionName) {
|
|
|
2690
2714
|
modelProviderID: sessionState.modelProviderID,
|
|
2691
2715
|
modelID: sessionState.modelID
|
|
2692
2716
|
};
|
|
2693
|
-
await writePersistedSessionState(sessionState.sessionId, state, logger);
|
|
2717
|
+
await writePersistedSessionState(sessionState.sessionId, state, logger, sessionState.storageDir);
|
|
2694
2718
|
}
|
|
2695
|
-
async function loadSessionState(sessionId, logger) {
|
|
2719
|
+
async function loadSessionState(sessionId, logger, storageDir) {
|
|
2696
2720
|
try {
|
|
2697
|
-
const filePath = getSessionFilePath(sessionId);
|
|
2721
|
+
const filePath = getSessionFilePath(sessionId, storageDir);
|
|
2698
2722
|
if (!existsSync2(filePath)) {
|
|
2699
2723
|
return null;
|
|
2700
2724
|
}
|
|
@@ -2770,6 +2794,11 @@ async function loadSessionState(sessionId, logger) {
|
|
|
2770
2794
|
}
|
|
2771
2795
|
}
|
|
2772
2796
|
|
|
2797
|
+
// lib/state/state.ts
|
|
2798
|
+
import { existsSync as existsSync3 } from "fs";
|
|
2799
|
+
import { join as join3 } from "path";
|
|
2800
|
+
import { cwd } from "process";
|
|
2801
|
+
|
|
2773
2802
|
// lib/message-ids.ts
|
|
2774
2803
|
var MESSAGE_REF_REGEX = /^m(\d{4,5})$/;
|
|
2775
2804
|
var BLOCK_REF_REGEX = /^b([1-9]\d*)$/;
|
|
@@ -4446,10 +4475,12 @@ async function updatePerTurnState(state, logger, messages) {
|
|
|
4446
4475
|
}
|
|
4447
4476
|
var REGISTRY_SOFT_CAP = 32;
|
|
4448
4477
|
var SessionStateRegistry = class {
|
|
4449
|
-
constructor(logger) {
|
|
4478
|
+
constructor(logger, projectDir) {
|
|
4450
4479
|
this.logger = logger;
|
|
4480
|
+
this.projectDir = projectDir;
|
|
4451
4481
|
}
|
|
4452
4482
|
logger;
|
|
4483
|
+
projectDir;
|
|
4453
4484
|
states = /* @__PURE__ */ new Map();
|
|
4454
4485
|
compressionTiming = {
|
|
4455
4486
|
startsByCallId: /* @__PURE__ */ new Map(),
|
|
@@ -4502,7 +4533,8 @@ var SessionStateRegistry = class {
|
|
|
4502
4533
|
sessionId,
|
|
4503
4534
|
this.logger,
|
|
4504
4535
|
messages,
|
|
4505
|
-
config
|
|
4536
|
+
config,
|
|
4537
|
+
this.projectDir
|
|
4506
4538
|
);
|
|
4507
4539
|
} catch (err) {
|
|
4508
4540
|
this.logger.error("Failed to initialize session state", {
|
|
@@ -4566,6 +4598,7 @@ function createSessionState() {
|
|
|
4566
4598
|
modelProviderID: void 0,
|
|
4567
4599
|
modelID: void 0,
|
|
4568
4600
|
systemPromptTokens: void 0,
|
|
4601
|
+
storageDir: void 0,
|
|
4569
4602
|
qualityGateRetryPending: false
|
|
4570
4603
|
};
|
|
4571
4604
|
}
|
|
@@ -4607,21 +4640,30 @@ function resetSessionState(state) {
|
|
|
4607
4640
|
state.modelProviderID = void 0;
|
|
4608
4641
|
state.modelID = void 0;
|
|
4609
4642
|
state.systemPromptTokens = void 0;
|
|
4643
|
+
state.storageDir = void 0;
|
|
4610
4644
|
state.qualityGateRetryPending = false;
|
|
4611
4645
|
}
|
|
4612
|
-
async function ensureSessionInitialized(client, state, sessionId, logger, messages, config) {
|
|
4646
|
+
async function ensureSessionInitialized(client, state, sessionId, logger, messages, config, projectDir) {
|
|
4613
4647
|
if (state.sessionId === sessionId) {
|
|
4614
4648
|
return;
|
|
4615
4649
|
}
|
|
4616
4650
|
resetSessionState(state);
|
|
4617
4651
|
state.sessionId = sessionId;
|
|
4652
|
+
state.storageDir = config?.storagePath ? resolveStorageDir(config.storagePath, projectDir ?? cwd()) : void 0;
|
|
4618
4653
|
const isSubAgent = await isSubAgentSession(client, sessionId);
|
|
4619
4654
|
state.isSubAgent = isSubAgent;
|
|
4620
4655
|
state.lastCompaction = findLastCompactionTimestamp(messages);
|
|
4621
4656
|
state.currentTurn = countTurns(state, messages);
|
|
4622
4657
|
state.nudges.turnNudgeAnchors = collectTurnNudgeAnchors(messages);
|
|
4623
|
-
const persisted = await loadSessionState(sessionId, logger);
|
|
4658
|
+
const persisted = await loadSessionState(sessionId, logger, state.storageDir);
|
|
4624
4659
|
if (persisted === null) {
|
|
4660
|
+
const defaultPath = join3(getDefaultStorageDir(), `${sessionId}.json`);
|
|
4661
|
+
if (state.storageDir && existsSync3(defaultPath)) {
|
|
4662
|
+
logger.warn(
|
|
4663
|
+
"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",
|
|
4664
|
+
{ sessionId, storageDir: state.storageDir, defaultPath }
|
|
4665
|
+
);
|
|
4666
|
+
}
|
|
4625
4667
|
if (config) {
|
|
4626
4668
|
const rebuilt = rebuildCompressionState(state, messages, config, logger);
|
|
4627
4669
|
if (rebuilt > 0) {
|
|
@@ -9485,10 +9527,10 @@ function hideFailedCompressCalls(messages) {
|
|
|
9485
9527
|
|
|
9486
9528
|
// lib/logger.ts
|
|
9487
9529
|
import { writeFile as writeFile2, mkdir as mkdir2 } from "fs/promises";
|
|
9488
|
-
import { join as
|
|
9489
|
-
import { existsSync as
|
|
9530
|
+
import { join as join4 } from "path";
|
|
9531
|
+
import { existsSync as existsSync4 } from "fs";
|
|
9490
9532
|
import { homedir as homedir3 } from "os";
|
|
9491
|
-
var LOG_VERSION = true ? "1.
|
|
9533
|
+
var LOG_VERSION = true ? "1.16.0-pr.297.127" : "dev";
|
|
9492
9534
|
var LEVEL_RANK = {
|
|
9493
9535
|
debug: 10,
|
|
9494
9536
|
info: 20,
|
|
@@ -9508,8 +9550,8 @@ var Logger = class {
|
|
|
9508
9550
|
constructor(enabled, level) {
|
|
9509
9551
|
const resolved = level !== void 0 && LEVEL_RANK[level] !== void 0 ? level : void 0;
|
|
9510
9552
|
this.level = resolved ?? (enabled ? "debug" : "warn");
|
|
9511
|
-
const configHome = process.env.XDG_CONFIG_HOME ||
|
|
9512
|
-
this.logDir =
|
|
9553
|
+
const configHome = process.env.XDG_CONFIG_HOME || join4(homedir3(), ".config");
|
|
9554
|
+
this.logDir = join4(configHome, "opencode", "logs", "acp");
|
|
9513
9555
|
}
|
|
9514
9556
|
/** Back-compat view of the old flag: true only at full debug verbosity. */
|
|
9515
9557
|
get enabled() {
|
|
@@ -9519,7 +9561,7 @@ var Logger = class {
|
|
|
9519
9561
|
return LEVEL_RANK[level] >= LEVEL_RANK[this.level];
|
|
9520
9562
|
}
|
|
9521
9563
|
async ensureLogDir() {
|
|
9522
|
-
if (!
|
|
9564
|
+
if (!existsSync4(this.logDir)) {
|
|
9523
9565
|
await mkdir2(this.logDir, { recursive: true });
|
|
9524
9566
|
}
|
|
9525
9567
|
}
|
|
@@ -9571,11 +9613,11 @@ var Logger = class {
|
|
|
9571
9613
|
const dataStr = this.formatData(data);
|
|
9572
9614
|
const logLine = `${timestamp} ${level.padEnd(5)} ${component}: ${message}${dataStr ? " | " + dataStr : ""} | v=${LOG_VERSION}
|
|
9573
9615
|
`;
|
|
9574
|
-
const dailyLogDir =
|
|
9575
|
-
if (!
|
|
9616
|
+
const dailyLogDir = join4(this.logDir, "daily");
|
|
9617
|
+
if (!existsSync4(dailyLogDir)) {
|
|
9576
9618
|
await mkdir2(dailyLogDir, { recursive: true });
|
|
9577
9619
|
}
|
|
9578
|
-
const logFile =
|
|
9620
|
+
const logFile = join4(dailyLogDir, `${(/* @__PURE__ */ new Date()).toISOString().split("T")[0]}.log`);
|
|
9579
9621
|
await writeFile2(logFile, logLine, { flag: "a" });
|
|
9580
9622
|
} catch (error) {
|
|
9581
9623
|
}
|
|
@@ -9686,18 +9728,18 @@ var Logger = class {
|
|
|
9686
9728
|
async saveContext(sessionId, messages) {
|
|
9687
9729
|
if (this.level !== "debug") return;
|
|
9688
9730
|
try {
|
|
9689
|
-
const contextDir =
|
|
9690
|
-
if (!
|
|
9731
|
+
const contextDir = join4(this.logDir, "context", sessionId);
|
|
9732
|
+
if (!existsSync4(contextDir)) {
|
|
9691
9733
|
await mkdir2(contextDir, { recursive: true });
|
|
9692
9734
|
}
|
|
9693
9735
|
const minimized = this.minimizeForDebug(messages).filter(
|
|
9694
9736
|
(msg) => msg.parts && msg.parts.length > 0
|
|
9695
9737
|
);
|
|
9696
9738
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
9697
|
-
const contextFile =
|
|
9739
|
+
const contextFile = join4(contextDir, `${timestamp}.json`);
|
|
9698
9740
|
await writeFile2(contextFile, JSON.stringify(minimized, null, 2));
|
|
9699
|
-
const versionFile =
|
|
9700
|
-
if (!
|
|
9741
|
+
const versionFile = join4(contextDir, "_version");
|
|
9742
|
+
if (!existsSync4(versionFile)) {
|
|
9701
9743
|
await writeFile2(versionFile, LOG_VERSION);
|
|
9702
9744
|
}
|
|
9703
9745
|
} catch (error) {
|
|
@@ -9706,8 +9748,8 @@ var Logger = class {
|
|
|
9706
9748
|
};
|
|
9707
9749
|
|
|
9708
9750
|
// lib/prompts/store.ts
|
|
9709
|
-
import { existsSync as
|
|
9710
|
-
import { join as
|
|
9751
|
+
import { existsSync as existsSync5, mkdirSync as mkdirSync2, readFileSync as readFileSync2, writeFileSync as writeFileSync2, statSync as statSync2 } from "fs";
|
|
9752
|
+
import { join as join5, dirname as dirname2 } from "path";
|
|
9711
9753
|
import { homedir as homedir4 } from "os";
|
|
9712
9754
|
|
|
9713
9755
|
// lib/prompts/system.ts
|
|
@@ -10037,8 +10079,8 @@ function createBundledRuntimePrompts() {
|
|
|
10037
10079
|
function findOpencodeDir2(startDir) {
|
|
10038
10080
|
let current = startDir;
|
|
10039
10081
|
while (current !== "/") {
|
|
10040
|
-
const candidate =
|
|
10041
|
-
if (
|
|
10082
|
+
const candidate = join5(current, ".opencode");
|
|
10083
|
+
if (existsSync5(candidate)) {
|
|
10042
10084
|
try {
|
|
10043
10085
|
if (statSync2(candidate).isDirectory()) {
|
|
10044
10086
|
return candidate;
|
|
@@ -10055,13 +10097,13 @@ function findOpencodeDir2(startDir) {
|
|
|
10055
10097
|
return null;
|
|
10056
10098
|
}
|
|
10057
10099
|
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 ?
|
|
10100
|
+
const configHome = process.env.XDG_CONFIG_HOME || join5(homedir4(), ".config");
|
|
10101
|
+
const globalRoot = join5(configHome, "opencode", "acp-prompts");
|
|
10102
|
+
const defaultsDir = join5(globalRoot, "defaults");
|
|
10103
|
+
const globalOverridesDir = join5(globalRoot, "overrides");
|
|
10104
|
+
const configDirOverridesDir = process.env.OPENCODE_CONFIG_DIR ? join5(process.env.OPENCODE_CONFIG_DIR, "acp-prompts", "overrides") : null;
|
|
10063
10105
|
const opencodeDir = findOpencodeDir2(workingDirectory);
|
|
10064
|
-
const projectOverridesDir = opencodeDir ?
|
|
10106
|
+
const projectOverridesDir = opencodeDir ? join5(opencodeDir, "acp-prompts", "overrides") : null;
|
|
10065
10107
|
return {
|
|
10066
10108
|
defaultsDir,
|
|
10067
10109
|
globalOverridesDir,
|
|
@@ -10161,7 +10203,7 @@ function buildDefaultsReadmeContent() {
|
|
|
10161
10203
|
`;
|
|
10162
10204
|
}
|
|
10163
10205
|
function readFileIfExists(filePath) {
|
|
10164
|
-
if (!
|
|
10206
|
+
if (!existsSync5(filePath)) {
|
|
10165
10207
|
return null;
|
|
10166
10208
|
}
|
|
10167
10209
|
try {
|
|
@@ -10232,16 +10274,16 @@ var PromptStore = class {
|
|
|
10232
10274
|
const candidates = [];
|
|
10233
10275
|
if (this.paths.projectOverridesDir) {
|
|
10234
10276
|
candidates.push({
|
|
10235
|
-
path:
|
|
10277
|
+
path: join5(this.paths.projectOverridesDir, fileName)
|
|
10236
10278
|
});
|
|
10237
10279
|
}
|
|
10238
10280
|
if (this.paths.configDirOverridesDir) {
|
|
10239
10281
|
candidates.push({
|
|
10240
|
-
path:
|
|
10282
|
+
path: join5(this.paths.configDirOverridesDir, fileName)
|
|
10241
10283
|
});
|
|
10242
10284
|
}
|
|
10243
10285
|
candidates.push({
|
|
10244
|
-
path:
|
|
10286
|
+
path: join5(this.paths.globalOverridesDir, fileName)
|
|
10245
10287
|
});
|
|
10246
10288
|
return candidates;
|
|
10247
10289
|
}
|
|
@@ -10264,7 +10306,7 @@ var PromptStore = class {
|
|
|
10264
10306
|
const managedContent = buildDefaultPromptFileContent(
|
|
10265
10307
|
bundledEditable || BUNDLED_EDITABLE_PROMPTS[definition.runtimeField]
|
|
10266
10308
|
);
|
|
10267
|
-
const filePath =
|
|
10309
|
+
const filePath = join5(this.paths.defaultsDir, definition.fileName);
|
|
10268
10310
|
try {
|
|
10269
10311
|
const existing = readFileIfExists(filePath);
|
|
10270
10312
|
if (existing === managedContent) {
|
|
@@ -10278,7 +10320,7 @@ var PromptStore = class {
|
|
|
10278
10320
|
});
|
|
10279
10321
|
}
|
|
10280
10322
|
}
|
|
10281
|
-
const readmePath =
|
|
10323
|
+
const readmePath = join5(this.paths.defaultsDir, DEFAULTS_README_FILE);
|
|
10282
10324
|
const readmeContent = buildDefaultsReadmeContent();
|
|
10283
10325
|
try {
|
|
10284
10326
|
const existing = readFileIfExists(readmePath);
|
|
@@ -10575,8 +10617,8 @@ ${report}`;
|
|
|
10575
10617
|
|
|
10576
10618
|
// lib/commands/export.ts
|
|
10577
10619
|
import * as fs2 from "fs/promises";
|
|
10578
|
-
import { existsSync as
|
|
10579
|
-
import { dirname as dirname3, isAbsolute, join as
|
|
10620
|
+
import { existsSync as existsSync6 } from "fs";
|
|
10621
|
+
import { dirname as dirname3, isAbsolute as isAbsolute2, join as join6, resolve } from "path";
|
|
10580
10622
|
var ALL_TIERS = [1, 2, 3];
|
|
10581
10623
|
var TIER_NAMES = {
|
|
10582
10624
|
1: "Tier 1 \u2014 Capture",
|
|
@@ -10687,9 +10729,9 @@ function parseTiers(raw) {
|
|
|
10687
10729
|
}
|
|
10688
10730
|
return result;
|
|
10689
10731
|
}
|
|
10690
|
-
function resolveDefaultOutputPath(sessionId,
|
|
10732
|
+
function resolveDefaultOutputPath(sessionId, cwd2) {
|
|
10691
10733
|
const short = (sessionId || "session").slice(0, 8);
|
|
10692
|
-
return
|
|
10734
|
+
return join6(cwd2, ".opencode", `acp-export-${short}.md`);
|
|
10693
10735
|
}
|
|
10694
10736
|
function formatTokens2(n) {
|
|
10695
10737
|
if (!Number.isFinite(n) || n <= 0) return "0";
|
|
@@ -10816,15 +10858,15 @@ async function handleExportCommand(ctx, args) {
|
|
|
10816
10858
|
await sendExportNotice(client, sessionId, ctx, markdown);
|
|
10817
10859
|
return;
|
|
10818
10860
|
}
|
|
10819
|
-
const
|
|
10820
|
-
const targetPath = options.outputPath !== "" ?
|
|
10861
|
+
const cwd2 = ctx.workingDirectory || process.cwd();
|
|
10862
|
+
const targetPath = options.outputPath !== "" ? isAbsolute2(options.outputPath) ? options.outputPath : resolve(cwd2, options.outputPath) : resolveDefaultOutputPath(sessionId, cwd2);
|
|
10821
10863
|
try {
|
|
10822
10864
|
const dir = dirname3(targetPath);
|
|
10823
|
-
if (!
|
|
10865
|
+
if (!existsSync6(dir)) {
|
|
10824
10866
|
await fs2.mkdir(dir, { recursive: true });
|
|
10825
10867
|
}
|
|
10826
10868
|
const flag = options.append ? "a" : "w";
|
|
10827
|
-
if (options.append &&
|
|
10869
|
+
if (options.append && existsSync6(targetPath)) {
|
|
10828
10870
|
await fs2.appendFile(targetPath, `
|
|
10829
10871
|
|
|
10830
10872
|
---
|
|
@@ -11611,7 +11653,7 @@ function createCommandExecuteHandler(client, registry4, logger, config, workingD
|
|
|
11611
11653
|
const sub = input.arguments?.trim().toLowerCase();
|
|
11612
11654
|
if (sub === "stats" || sub === "status" || sub === "") {
|
|
11613
11655
|
await handleStatsCommand(commandCtx);
|
|
11614
|
-
|
|
11656
|
+
return;
|
|
11615
11657
|
}
|
|
11616
11658
|
if (sub === "export" || sub.startsWith("export ")) {
|
|
11617
11659
|
const exportArgs = input.arguments?.trim().slice("export".length).trim() || "";
|
|
@@ -11629,7 +11671,6 @@ function createCommandExecuteHandler(client, registry4, logger, config, workingD
|
|
|
11629
11671
|
throw new Error("__DCP_CONTEXT_HANDLED__");
|
|
11630
11672
|
}
|
|
11631
11673
|
await handleContextCommand(commandCtx);
|
|
11632
|
-
throw new Error("__DCP_CONTEXT_HANDLED__");
|
|
11633
11674
|
}
|
|
11634
11675
|
};
|
|
11635
11676
|
}
|
|
@@ -11767,7 +11808,7 @@ function findBiliProxyProviders(provider) {
|
|
|
11767
11808
|
|
|
11768
11809
|
// lib/update.ts
|
|
11769
11810
|
import { readFile as readFile2, rm } from "fs/promises";
|
|
11770
|
-
import { basename, dirname as dirname4, join as
|
|
11811
|
+
import { basename, dirname as dirname4, join as join7 } from "path";
|
|
11771
11812
|
import { fileURLToPath } from "url";
|
|
11772
11813
|
var PACKAGE_NAME = "opencode-acp";
|
|
11773
11814
|
function startAutoUpdate(ctx, enabled, logger) {
|
|
@@ -11814,7 +11855,7 @@ async function checkAutoUpdate(signal, logger) {
|
|
|
11814
11855
|
logger?.info("Auto-update skipped: package dir not found");
|
|
11815
11856
|
return { updated: false };
|
|
11816
11857
|
}
|
|
11817
|
-
const pkg = await readPackageJson(
|
|
11858
|
+
const pkg = await readPackageJson(join7(packageDir, "package.json"));
|
|
11818
11859
|
if (!pkg?.name || !pkg.version) {
|
|
11819
11860
|
logger?.info("Auto-update skipped: package.json unreadable", { packageDir });
|
|
11820
11861
|
return { updated: false };
|
|
@@ -11855,7 +11896,7 @@ async function checkAutoUpdate(signal, logger) {
|
|
|
11855
11896
|
async function findPackageDir(name) {
|
|
11856
11897
|
let dir = dirname4(fileURLToPath(import.meta.url));
|
|
11857
11898
|
for (; ; ) {
|
|
11858
|
-
const pkg = await readPackageJson(
|
|
11899
|
+
const pkg = await readPackageJson(join7(dir, "package.json"));
|
|
11859
11900
|
if (pkg?.name === name) return dir;
|
|
11860
11901
|
const parent = dirname4(dir);
|
|
11861
11902
|
if (parent === dir) return void 0;
|
|
@@ -11867,7 +11908,7 @@ async function updateTarget(packageDir, name) {
|
|
|
11867
11908
|
const nodeModulesDir = basename(packageParent).startsWith("@") ? dirname4(packageParent) : packageParent;
|
|
11868
11909
|
if (basename(nodeModulesDir) !== "node_modules") return void 0;
|
|
11869
11910
|
const wrapperDir = dirname4(nodeModulesDir);
|
|
11870
|
-
const wrapperPkg = await readPackageJson(
|
|
11911
|
+
const wrapperPkg = await readPackageJson(join7(wrapperDir, "package.json"));
|
|
11871
11912
|
const spec = wrapperSpec(wrapperDir, name) ?? wrapperPkg?.dependencies?.[name];
|
|
11872
11913
|
if (!spec || !isAutoUpdatableSpec(spec)) return void 0;
|
|
11873
11914
|
return { removeDir: wrapperDir, spec };
|
|
@@ -11979,14 +12020,14 @@ var server = (async (ctx) => {
|
|
|
11979
12020
|
}
|
|
11980
12021
|
const logger = new Logger(config.debug, config.debug ? "debug" : config.logLevel);
|
|
11981
12022
|
logger.info("ACP plugin initialized", {
|
|
11982
|
-
version: true ? "1.
|
|
12023
|
+
version: true ? "1.16.0-pr.297.127" : "dev",
|
|
11983
12024
|
workspace: ctx.directory,
|
|
11984
12025
|
logLevel: logger.level,
|
|
11985
12026
|
debug: config.debug,
|
|
11986
12027
|
autoUpdate: config.autoUpdate,
|
|
11987
12028
|
secureMode: isSecureMode()
|
|
11988
12029
|
});
|
|
11989
|
-
const registry4 = new SessionStateRegistry(logger);
|
|
12030
|
+
const registry4 = new SessionStateRegistry(logger, ctx.directory);
|
|
11990
12031
|
const prompts = new PromptStore(logger, ctx.directory, config.experimental.customPrompts);
|
|
11991
12032
|
const hostPermissions = {
|
|
11992
12033
|
global: void 0,
|