@andyqiu/codeforge 0.8.8 → 0.8.10

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.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: reviewer-lite
3
- description: 审阅者(轻量档)— 使用 sonnet 模型,适用于方案/文档/ADR/决策 review;代码安全审查请用 @reviewer(ultrabrain)
3
+ description: 审阅者(轻量档)— 使用 GPT-5.4 模型,适用于方案/文档/ADR/决策 review;代码安全审查请用 @reviewer(ultrabrain)
4
4
  version: 1.0.0
5
5
  mode: subagent
6
6
  # opencode 标准字段(单数)— 实际生效的权限
@@ -15,12 +15,12 @@ permissions:
15
15
  bash: allow
16
16
  webfetch: deny
17
17
  allowed_tools: [plan_read, bash, read, task, review_approval]
18
- model: google/gemini-3.1-pro-preview
18
+ model: openai/gpt-5.4
19
19
  model_category: balanced
20
20
  tier: balanced
21
21
  model_thinking:
22
22
  type: enabled
23
- thinking_level: medium
23
+ reasoning_effort: medium
24
24
  fallback_models:
25
25
  - anthropic/claude-sonnet-4-6
26
26
  - openai/gpt-5.5
package/dist/index.js CHANGED
@@ -19878,7 +19878,7 @@ var toolPolicyServer = async (ctx) => {
19878
19878
  var handler18 = toolPolicyServer;
19879
19879
 
19880
19880
  // plugins/update-checker.ts
19881
- import { existsSync as existsSync5, mkdirSync as mkdirSync3, readFileSync as readFileSync6, rmSync, writeFileSync as writeFileSync2 } from "node:fs";
19881
+ import { closeSync, existsSync as existsSync5, mkdirSync as mkdirSync3, openSync, readFileSync as readFileSync6, rmSync, statSync as statSync4, writeFileSync as writeFileSync2, writeSync } from "node:fs";
19882
19882
  import { homedir as homedir8 } from "node:os";
19883
19883
  import { dirname as dirname16, join as join26 } from "node:path";
19884
19884
  import { spawn } from "node:child_process";
@@ -19892,7 +19892,7 @@ import * as https from "node:https";
19892
19892
  // lib/version-injected.ts
19893
19893
  function getInjectedVersion() {
19894
19894
  try {
19895
- const v = "0.8.8";
19895
+ const v = "0.8.10";
19896
19896
  if (typeof v === "string" && /^\d+\.\d+\.\d+/.test(v)) {
19897
19897
  return v;
19898
19898
  }
@@ -20040,6 +20040,35 @@ function writeLastInstalledVersion(v) {
20040
20040
  writeFileSync2(f, JSON.stringify({ installedVersion: v }, null, 2), "utf8");
20041
20041
  } catch {}
20042
20042
  }
20043
+ function getLockFile() {
20044
+ return join26(process.env["CODEFORGE_CACHE_DIR"] ?? join26(homedir8(), ".cache", "codeforge"), "install.lock");
20045
+ }
20046
+ function tryAcquireInstallLock() {
20047
+ try {
20048
+ const lockFile = getLockFile();
20049
+ mkdirSync3(dirname16(lockFile), { recursive: true });
20050
+ if (existsSync5(lockFile)) {
20051
+ const stat = statSync4(lockFile);
20052
+ const ageMs = Date.now() - stat.mtimeMs;
20053
+ if (ageMs < 10 * 60 * 1000)
20054
+ return false;
20055
+ safeWriteLog(PLUGIN_NAME19, { level: "info", msg: "stale_lock_removed", ageMs });
20056
+ }
20057
+ const fd = openSync(lockFile, "wx");
20058
+ writeSync(fd, String(process.pid));
20059
+ closeSync(fd);
20060
+ return true;
20061
+ } catch {
20062
+ return false;
20063
+ }
20064
+ }
20065
+ function releaseInstallLock() {
20066
+ try {
20067
+ const lockFile = getLockFile();
20068
+ if (existsSync5(lockFile))
20069
+ rmSync(lockFile, { force: true });
20070
+ } catch {}
20071
+ }
20043
20072
  function spawnAsync(cmd, args, opts = {}) {
20044
20073
  return new Promise((resolve17) => {
20045
20074
  const chunks = [];
@@ -20187,49 +20216,74 @@ var updateCheckerServer = async (ctx) => {
20187
20216
  return;
20188
20217
  }
20189
20218
  await safeAsync(PLUGIN_NAME19, "auto_install", async () => {
20190
- const nodeBin = await resolveNodeBin();
20191
- const npmBin = await resolveNpmBin();
20192
- safeWriteLog(PLUGIN_NAME19, { level: "info", msg: "auto_install_start", local, remote, nodeBin, npmBin });
20193
- const r1 = await spawnAsync(npmBin, ["install", "-g", `${u.package}@${remote}`], {
20194
- timeout: 120000,
20195
- shell: process.platform === "win32"
20196
- });
20197
- if (r1.status !== 0) {
20198
- safeWriteLog(PLUGIN_NAME19, { level: "warn", msg: "npm_install_failed", status: r1.status, stderr: r1.stderr.slice(0, 300) });
20199
- await postToast(ctx, `[codeforge] 自动升级失败(${local} → ${remote}),请手动运行:codeforge upgrade`);
20219
+ if (!tryAcquireInstallLock()) {
20220
+ safeWriteLog(PLUGIN_NAME19, { level: "info", msg: "install_skipped_lock_held" });
20200
20221
  return;
20201
20222
  }
20202
- safeWriteLog(PLUGIN_NAME19, { level: "info", msg: "npm_install_success", remote });
20203
20223
  try {
20204
- const cacheRoot = process.env["XDG_CACHE_HOME"] ?? join26(homedir8(), ".cache");
20205
- const opencodeCache = join26(cacheRoot, "opencode", "packages", "@andyqiu", "codeforge@latest");
20206
- if (existsSync5(opencodeCache)) {
20207
- rmSync(opencodeCache, { recursive: true, force: true });
20208
- safeWriteLog(PLUGIN_NAME19, { level: "info", msg: "opencode_plugin_cache_cleared", path: opencodeCache });
20224
+ const nodeBin = await resolveNodeBin();
20225
+ const npmBin = await resolveNpmBin();
20226
+ safeWriteLog(PLUGIN_NAME19, { level: "info", msg: "auto_install_start", local, remote, nodeBin, npmBin });
20227
+ const runNpmInstall = () => spawnAsync(npmBin, ["install", "-g", `${u.package}@${remote}`], {
20228
+ timeout: 120000,
20229
+ shell: process.platform === "win32"
20230
+ });
20231
+ let r1 = await runNpmInstall();
20232
+ if (r1.status !== 0 && (r1.stderr.includes("TAR_ENTRY_ERROR") || r1.stderr.includes("ENOENT"))) {
20233
+ safeWriteLog(PLUGIN_NAME19, { level: "warn", msg: "npm_install_tar_error_retrying", stderr: r1.stderr.slice(0, 200) });
20234
+ try {
20235
+ const npmRoot2 = await getNpmGlobalRoot(npmBin);
20236
+ if (npmRoot2) {
20237
+ const oldPkgDir = join26(npmRoot2, ...u.package.split("/"));
20238
+ if (existsSync5(oldPkgDir)) {
20239
+ rmSync(oldPkgDir, { recursive: true, force: true });
20240
+ safeWriteLog(PLUGIN_NAME19, { level: "info", msg: "npm_install_old_dir_removed", path: oldPkgDir });
20241
+ }
20242
+ }
20243
+ } catch (e) {
20244
+ safeWriteLog(PLUGIN_NAME19, { level: "warn", msg: "npm_install_old_dir_remove_failed", error: e.message });
20245
+ }
20246
+ r1 = await runNpmInstall();
20209
20247
  }
20210
- } catch (e) {
20211
- safeWriteLog(PLUGIN_NAME19, { level: "warn", msg: "opencode_plugin_cache_clear_failed", error: e.message });
20212
- }
20213
- const npmRoot = await getNpmGlobalRoot(npmBin);
20214
- const pkgRoot = npmRoot ? join26(npmRoot, "@andyqiu", "codeforge") : null;
20215
- const installMjs = pkgRoot ? join26(pkgRoot, "install.mjs") : null;
20216
- if (!installMjs || !existsSync5(installMjs)) {
20217
- safeWriteLog(PLUGIN_NAME19, { level: "warn", msg: "install_mjs_not_found", path: installMjs ?? "null" });
20218
- await postToast(ctx, `[codeforge] npm 包已升级 ${local} → ${remote},但资产部署未完成。下次启动将重试,或手动运行:codeforge upgrade`);
20219
- return;
20220
- }
20221
- const r2 = await spawnAsync(nodeBin, [installMjs, "--global", "--skip-build", "--skip-plugin-entry"], {
20222
- timeout: 60000,
20223
- cwd: pkgRoot ?? undefined
20224
- });
20225
- if (r2.status !== 0) {
20226
- safeWriteLog(PLUGIN_NAME19, { level: "warn", msg: "codeforge_install_failed", status: r2.status, stderr: r2.stderr.slice(0, 300) });
20227
- await postToast(ctx, `[codeforge] npm 包已升级 ${local} → ${remote},但资产部署失败。下次启动将重试,或手动运行:codeforge upgrade`);
20228
- return;
20248
+ if (r1.status !== 0) {
20249
+ safeWriteLog(PLUGIN_NAME19, { level: "warn", msg: "npm_install_failed", status: r1.status, stderr: r1.stderr.slice(0, 300) });
20250
+ await postToast(ctx, `[Codeforge] 自动升级失败(${local} → ${remote}),请手动运行:codeforge upgrade`);
20251
+ return;
20252
+ }
20253
+ safeWriteLog(PLUGIN_NAME19, { level: "info", msg: "npm_install_success", remote });
20254
+ try {
20255
+ const cacheRoot = process.env["XDG_CACHE_HOME"] ?? join26(homedir8(), ".cache");
20256
+ const opencodeCache = join26(cacheRoot, "opencode", "packages", "@andyqiu", "codeforge@latest");
20257
+ if (existsSync5(opencodeCache)) {
20258
+ rmSync(opencodeCache, { recursive: true, force: true });
20259
+ safeWriteLog(PLUGIN_NAME19, { level: "info", msg: "opencode_plugin_cache_cleared", path: opencodeCache });
20260
+ }
20261
+ } catch (e) {
20262
+ safeWriteLog(PLUGIN_NAME19, { level: "warn", msg: "opencode_plugin_cache_clear_failed", error: e.message });
20263
+ }
20264
+ const npmRoot = await getNpmGlobalRoot(npmBin);
20265
+ const pkgRoot = npmRoot ? join26(npmRoot, "@andyqiu", "codeforge") : null;
20266
+ const installMjs = pkgRoot ? join26(pkgRoot, "install.mjs") : null;
20267
+ if (!installMjs || !existsSync5(installMjs)) {
20268
+ safeWriteLog(PLUGIN_NAME19, { level: "warn", msg: "install_mjs_not_found", path: installMjs ?? "null" });
20269
+ await postToast(ctx, `[codeforge] ⚠ npm 包已升级 ${local} → ${remote},但资产部署未完成。下次启动将重试,或手动运行:codeforge upgrade`);
20270
+ return;
20271
+ }
20272
+ const r2 = await spawnAsync(nodeBin, [installMjs, "--global", "--skip-build", "--skip-plugin-entry"], {
20273
+ timeout: 60000,
20274
+ cwd: pkgRoot ?? undefined
20275
+ });
20276
+ if (r2.status !== 0) {
20277
+ safeWriteLog(PLUGIN_NAME19, { level: "warn", msg: "codeforge_install_failed", status: r2.status, stderr: r2.stderr.slice(0, 300) });
20278
+ await postToast(ctx, `[codeforge] ⚠ npm 包已升级 ${local} → ${remote},但资产部署失败。下次启动将重试,或手动运行:codeforge upgrade`);
20279
+ return;
20280
+ }
20281
+ writeLastInstalledVersion(remote);
20282
+ safeWriteLog(PLUGIN_NAME19, { level: "info", msg: "auto_install_full_success", local, remote, nodeBin, npmBin });
20283
+ await postToast(ctx, `[Codeforge] 已升级 ${remote},重启 opencode 生效`);
20284
+ } finally {
20285
+ releaseInstallLock();
20229
20286
  }
20230
- writeLastInstalledVersion(remote);
20231
- safeWriteLog(PLUGIN_NAME19, { level: "info", msg: "auto_install_full_success", local, remote, nodeBin, npmBin });
20232
- await postToast(ctx, `[Codeforge] 已升级 ${remote},重启 opencode 生效`);
20233
20287
  });
20234
20288
  });
20235
20289
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@andyqiu/codeforge",
3
- "version": "0.8.8",
3
+ "version": "0.8.10",
4
4
  "description": "CodeForge — opencode 的零侵入扩展包",
5
5
  "type": "module",
6
6
  "private": false,