@andyqiu/codeforge 0.7.2 → 0.7.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +89 -4
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -20166,7 +20166,7 @@ var toolPolicyServer = async (ctx) => {
|
|
|
20166
20166
|
var handler19 = toolPolicyServer;
|
|
20167
20167
|
|
|
20168
20168
|
// plugins/update-checker.ts
|
|
20169
|
-
import { existsSync as existsSync5, mkdirSync as mkdirSync3, readFileSync as readFileSync6, writeFileSync as writeFileSync2 } from "node:fs";
|
|
20169
|
+
import { existsSync as existsSync5, mkdirSync as mkdirSync3, readFileSync as readFileSync6, rmSync, writeFileSync as writeFileSync2 } from "node:fs";
|
|
20170
20170
|
import { homedir as homedir8 } from "node:os";
|
|
20171
20171
|
import { dirname as dirname15, join as join25 } from "node:path";
|
|
20172
20172
|
import { spawnSync as spawnSync2 } from "node:child_process";
|
|
@@ -20180,7 +20180,7 @@ import * as https from "node:https";
|
|
|
20180
20180
|
// lib/version-injected.ts
|
|
20181
20181
|
function getInjectedVersion() {
|
|
20182
20182
|
try {
|
|
20183
|
-
const v = "0.7.
|
|
20183
|
+
const v = "0.7.4";
|
|
20184
20184
|
if (typeof v === "string" && /^\d+\.\d+\.\d+/.test(v)) {
|
|
20185
20185
|
return v;
|
|
20186
20186
|
}
|
|
@@ -20474,6 +20474,15 @@ var updateCheckerServer = async (ctx) => {
|
|
|
20474
20474
|
await postToast(ctx, `[codeforge] ⚠ npm 包已升级 ${local} → ${remote},但资产部署失败。下次启动将重试,或手动运行:codeforge upgrade`);
|
|
20475
20475
|
return;
|
|
20476
20476
|
}
|
|
20477
|
+
try {
|
|
20478
|
+
const opencodeCache = join25(homedir8(), ".cache", "opencode", "packages", "@andyqiu", "codeforge@latest");
|
|
20479
|
+
if (existsSync5(opencodeCache)) {
|
|
20480
|
+
rmSync(opencodeCache, { recursive: true, force: true });
|
|
20481
|
+
safeWriteLog(PLUGIN_NAME20, { level: "info", msg: "opencode_cache_cleared", path: opencodeCache });
|
|
20482
|
+
}
|
|
20483
|
+
} catch (e) {
|
|
20484
|
+
safeWriteLog(PLUGIN_NAME20, { level: "warn", msg: "opencode_cache_clear_failed", error: e.message });
|
|
20485
|
+
}
|
|
20477
20486
|
writeLastInstalledVersion(remote);
|
|
20478
20487
|
safeWriteLog(PLUGIN_NAME20, { level: "info", msg: "auto_install_full_success", local, remote, nodeBin, npmBin });
|
|
20479
20488
|
await postToast(ctx, `[codeforge] ✅ 已升级 ${local} → ${remote}(重启 opencode 生效)
|
|
@@ -21073,7 +21082,7 @@ function escapeRegex(s) {
|
|
|
21073
21082
|
}
|
|
21074
21083
|
function buildGitVcsWriteRegex(mainRoot) {
|
|
21075
21084
|
const esc = escapeRegex(mainRoot);
|
|
21076
|
-
return new RegExp(`git\\b[^\\n]*(?:-C\\s+|--work-tree[=\\s])${esc}`);
|
|
21085
|
+
return new RegExp(`git\\b[^\\n]*(?:-C\\s+|--work-tree[=\\s])${esc}` + `(?:(?!/\\.git/codeforge-worktrees/)(?=$|[\\s'"\\x60)/])|(?=/\\.git/codeforge-worktrees/\\S*\\.\\.))`);
|
|
21077
21086
|
}
|
|
21078
21087
|
var WRITE_TOOLS = new Set(["write", "edit", "ast_edit"]);
|
|
21079
21088
|
var TOUCH_THROTTLE_MS = 5 * 60000;
|
|
@@ -21192,6 +21201,62 @@ function isInsideAnyWorktreeDir(absPath, mainRoot) {
|
|
|
21192
21201
|
const prefix = root.endsWith(path30.sep) ? root : root + path30.sep;
|
|
21193
21202
|
return absPath.startsWith(prefix);
|
|
21194
21203
|
}
|
|
21204
|
+
function worktreeRootOf(absPath, mainRoot) {
|
|
21205
|
+
const root = worktreesRoot(mainRoot);
|
|
21206
|
+
const prefix = root.endsWith(path30.sep) ? root : root + path30.sep;
|
|
21207
|
+
if (!absPath.startsWith(prefix))
|
|
21208
|
+
return null;
|
|
21209
|
+
const seg = absPath.slice(prefix.length).split(path30.sep)[0];
|
|
21210
|
+
if (!seg || seg === "..")
|
|
21211
|
+
return null;
|
|
21212
|
+
return path30.join(root, seg);
|
|
21213
|
+
}
|
|
21214
|
+
function stripPairedQuotes(raw) {
|
|
21215
|
+
if (raw.length >= 2) {
|
|
21216
|
+
const head = raw[0];
|
|
21217
|
+
const tail = raw[raw.length - 1];
|
|
21218
|
+
if (head === '"' && tail === '"' || head === "'" && tail === "'") {
|
|
21219
|
+
return raw.slice(1, -1);
|
|
21220
|
+
}
|
|
21221
|
+
}
|
|
21222
|
+
return raw;
|
|
21223
|
+
}
|
|
21224
|
+
function resolveExplicitWorktreeTarget(argsObj, mainRoot) {
|
|
21225
|
+
try {
|
|
21226
|
+
const candidates = [];
|
|
21227
|
+
const workdir = argsObj["workdir"];
|
|
21228
|
+
if (typeof workdir === "string" && workdir.length > 0) {
|
|
21229
|
+
candidates.push(stripPairedQuotes(workdir));
|
|
21230
|
+
}
|
|
21231
|
+
const command = argsObj["command"];
|
|
21232
|
+
if (typeof command === "string" && command.length > 0) {
|
|
21233
|
+
for (const m of command.matchAll(/--work-tree(?:=|\s+)('[^']*'|"[^"]*"|\S+)/g)) {
|
|
21234
|
+
candidates.push(stripPairedQuotes(m[1]));
|
|
21235
|
+
}
|
|
21236
|
+
for (const m of command.matchAll(/(?:^|\s)-C\s+('[^']*'|"[^"]*"|\S+)/g)) {
|
|
21237
|
+
candidates.push(stripPairedQuotes(m[1]));
|
|
21238
|
+
}
|
|
21239
|
+
}
|
|
21240
|
+
for (const cand of candidates) {
|
|
21241
|
+
if (!cand)
|
|
21242
|
+
continue;
|
|
21243
|
+
const abs = path30.resolve(mainRoot, cand);
|
|
21244
|
+
if (isInsideAnyWorktreeDir(abs, mainRoot)) {
|
|
21245
|
+
const wtRoot = worktreeRootOf(abs, mainRoot);
|
|
21246
|
+
if (wtRoot)
|
|
21247
|
+
return wtRoot;
|
|
21248
|
+
}
|
|
21249
|
+
}
|
|
21250
|
+
return null;
|
|
21251
|
+
} catch {
|
|
21252
|
+
return null;
|
|
21253
|
+
}
|
|
21254
|
+
}
|
|
21255
|
+
function stripSharedGitDirRef(command, mainRoot) {
|
|
21256
|
+
const escGitDir = escapeRegex(path30.join(mainRoot, ".git"));
|
|
21257
|
+
const re = new RegExp(`--git-dir(?:=|\\s+)['"]?${escGitDir}(?:/[^\\s'"\\x60)]*)?['"]?`, "g");
|
|
21258
|
+
return command.replace(re, " ");
|
|
21259
|
+
}
|
|
21195
21260
|
function rewritePath(value, mainRoot, worktreeRoot) {
|
|
21196
21261
|
if (!value)
|
|
21197
21262
|
return null;
|
|
@@ -21737,7 +21802,27 @@ var sessionWorktreeGuardPlugin = async (ctx) => {
|
|
|
21737
21802
|
}
|
|
21738
21803
|
if (toolName === "bash") {
|
|
21739
21804
|
const command = argsObj["command"];
|
|
21740
|
-
|
|
21805
|
+
const explicitWt = typeof command === "string" || typeof argsObj["workdir"] === "string" ? resolveExplicitWorktreeTarget(argsObj, mainRoot) : null;
|
|
21806
|
+
const effectiveWt = explicitWt ?? worktreePath;
|
|
21807
|
+
let hitMainRoot = typeof command === "string" && commandContainsMainRootExcludingWorktree(command, mainRoot, effectiveWt);
|
|
21808
|
+
if (hitMainRoot && explicitWt !== null && typeof command === "string") {
|
|
21809
|
+
const stillHit = commandContainsMainRootExcludingWorktree(stripSharedGitDirRef(command, mainRoot), mainRoot, effectiveWt);
|
|
21810
|
+
if (!stillHit) {
|
|
21811
|
+
hitMainRoot = false;
|
|
21812
|
+
if (detectBashWriteIntent(command, mainRoot)) {
|
|
21813
|
+
safeWriteLog(PLUGIN_NAME22, {
|
|
21814
|
+
hook: "tool.execute.before",
|
|
21815
|
+
tool: toolName,
|
|
21816
|
+
sessionID: input.sessionID,
|
|
21817
|
+
action: "allow-explicit-worktree",
|
|
21818
|
+
source: "explicit-worktree-target",
|
|
21819
|
+
explicitWorktree: explicitWt,
|
|
21820
|
+
command: command.slice(0, 200)
|
|
21821
|
+
});
|
|
21822
|
+
}
|
|
21823
|
+
}
|
|
21824
|
+
}
|
|
21825
|
+
if (typeof command === "string" && hitMainRoot && detectBashWriteIntent(command, mainRoot)) {
|
|
21741
21826
|
if (midMerge) {
|
|
21742
21827
|
const snippet = command.length > 60 ? command.slice(0, 60) + "…" : command;
|
|
21743
21828
|
emitMergeBypassNotice("classB", { command: snippet });
|