easy-coding-harness 0.5.2-beta.0 → 0.5.3
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/CHANGELOG.md +7 -0
- package/dist/cli.js +22 -2
- package/dist/cli.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,13 @@
|
|
|
6
6
|
- `y`:常规功能升级
|
|
7
7
|
- `z`:日常 bug 修复
|
|
8
8
|
|
|
9
|
+
## 0.5.3
|
|
10
|
+
|
|
11
|
+
- 根治 `task.json` 绝对路径泄漏:`.easy-coding/tasks/project-init/task.json` 不再写入本机仓库绝对路径。该 `project_path` 字段无任何消费方,直接移除,可提交产物彻底去本地化。
|
|
12
|
+
- `easy-coding upgrade` 会自动剥离存量项目中遗留的 `project_path` 字段,让老项目也随升级变干净。
|
|
13
|
+
- 根治 hook 编译产物:hook launcher 设置 `sys.dont_write_bytecode=True`,运行时不再在 `.claude/hooks/`、`.codex/hooks/`、`.qoder/hooks/` 旁生成 `__pycache__/*.pyc`;同时 `init` / `add-agent` / `upgrade` 会向项目 `.gitignore` 追加 `__pycache__/` 作为兜底防御。launcher 内容变化会触发 `upgrade` 刷新存量 hook 注册。
|
|
14
|
+
- 版本自 `0.5.2-beta.0` 升级为 `0.5.3`,合并 beta.0 的全部 portable hook 修复。跳过 `0.5.2` 正式版:升级检测的 `compareVersions` 会截断预发布后缀,若发 `0.5.2` 会把已安装 `0.5.2-beta.0` 的项目误判为已最新而不提示本次迁移;递增到 `0.5.3` 可让 beta 用户正确检测到升级。
|
|
15
|
+
|
|
9
16
|
## 0.5.2-beta.0
|
|
10
17
|
|
|
11
18
|
- 修复 Claude Code hook 命令使用直接相对路径导致在子目录 cwd 下找不到 `.claude/hooks/*.py` 的问题;Claude、Codex、Qoder 的 hook 配置现在使用可共享的 portable relative launcher,并绑定 `.easy-coding/config.yaml` 的 `project.id`,避免把本机仓库绝对路径写入可提交配置,同时防止 supermodule 父仓 hook 被子仓 cwd 错路由。
|
package/dist/cli.js
CHANGED
|
@@ -208,6 +208,7 @@ var MAIN_SPEC_DIR = "main";
|
|
|
208
208
|
var DEV_SPEC_DIR = "dev";
|
|
209
209
|
var TEMPLATES_DIR = "templates";
|
|
210
210
|
var SESSIONS_GITIGNORE_ENTRY = ".easy-coding/sessions/";
|
|
211
|
+
var HOOK_BYTECODE_GITIGNORE_ENTRY = "__pycache__/";
|
|
211
212
|
var GENERATED_REGION_START = "<!-- \u2550\u2550\u2550 easy-coding-harness generated (DO NOT EDIT BETWEEN MARKERS) \u2550\u2550\u2550 -->";
|
|
212
213
|
var GENERATED_REGION_END = "<!-- \u2550\u2550\u2550 end easy-coding-harness generated \u2550\u2550\u2550 -->";
|
|
213
214
|
|
|
@@ -227,6 +228,13 @@ async function ensureGitignoreEntry(cwd, entry, heading = "# \u2550\u2550\u2550
|
|
|
227
228
|
async function ensureEasyCodingSessionsIgnored(cwd) {
|
|
228
229
|
return ensureGitignoreEntry(cwd, SESSIONS_GITIGNORE_ENTRY);
|
|
229
230
|
}
|
|
231
|
+
async function ensureHookBytecodeIgnored(cwd) {
|
|
232
|
+
return ensureGitignoreEntry(
|
|
233
|
+
cwd,
|
|
234
|
+
HOOK_BYTECODE_GITIGNORE_ENTRY,
|
|
235
|
+
"# \u2550\u2550\u2550 easy-coding-harness (auto-generated) \u2550\u2550\u2550\n# Python bytecode from hook scripts; do not commit"
|
|
236
|
+
);
|
|
237
|
+
}
|
|
230
238
|
|
|
231
239
|
// src/utils/install-manifest.ts
|
|
232
240
|
import { createHash } from "crypto";
|
|
@@ -658,7 +666,6 @@ function createProjectInitTask(params) {
|
|
|
658
666
|
context: {
|
|
659
667
|
agents_installed: params.agents,
|
|
660
668
|
cli_version: VERSION,
|
|
661
|
-
project_path: params.cwd,
|
|
662
669
|
init_source: params.initSource ?? "fresh",
|
|
663
670
|
...params.legacyAssets ? { legacy_assets: params.legacyAssets } : {},
|
|
664
671
|
...params.legacyMissingHarnessFiles ? { legacy_missing_harness_files: params.legacyMissingHarnessFiles } : {}
|
|
@@ -679,7 +686,6 @@ async function writeProjectInitTask(cwd, agents, options = {}) {
|
|
|
679
686
|
await writeTaskJson(
|
|
680
687
|
getTaskJsonPath(cwd, PROJECT_INIT_TASK_ID),
|
|
681
688
|
createProjectInitTask({
|
|
682
|
-
cwd,
|
|
683
689
|
agents,
|
|
684
690
|
initSource: options.initSource,
|
|
685
691
|
legacyAssets: options.legacyAssets,
|
|
@@ -687,6 +693,15 @@ async function writeProjectInitTask(cwd, agents, options = {}) {
|
|
|
687
693
|
})
|
|
688
694
|
);
|
|
689
695
|
}
|
|
696
|
+
async function stripInitTaskProjectPath(cwd) {
|
|
697
|
+
const filePath = getTaskJsonPath(cwd, PROJECT_INIT_TASK_ID);
|
|
698
|
+
if (!await pathExists(filePath)) return false;
|
|
699
|
+
const task = await readTaskJson(filePath);
|
|
700
|
+
if (!task.context || !("project_path" in task.context)) return false;
|
|
701
|
+
task.context.project_path = void 0;
|
|
702
|
+
await writeTaskJson(filePath, task);
|
|
703
|
+
return true;
|
|
704
|
+
}
|
|
690
705
|
async function setPendingInitSince(cwd, version) {
|
|
691
706
|
const filePath = getTaskJsonPath(cwd, PROJECT_INIT_TASK_ID);
|
|
692
707
|
if (!await pathExists(filePath)) return;
|
|
@@ -830,6 +845,7 @@ function jsonStringContent(value) {
|
|
|
830
845
|
}
|
|
831
846
|
var HOOK_LAUNCHER_PYTHON = [
|
|
832
847
|
"import io,json,os,re,runpy,sys",
|
|
848
|
+
"sys.dont_write_bytecode=True",
|
|
833
849
|
"from pathlib import Path",
|
|
834
850
|
"payload=sys.stdin.read()",
|
|
835
851
|
"try:",
|
|
@@ -1264,6 +1280,7 @@ async function installHarnessToDir(targetDir, platforms, ctx) {
|
|
|
1264
1280
|
legacyMissingHarnessFiles: ctx.legacyMissingHarnessFiles
|
|
1265
1281
|
});
|
|
1266
1282
|
await ensureEasyCodingSessionsIgnored(targetDir);
|
|
1283
|
+
await ensureHookBytecodeIgnored(targetDir);
|
|
1267
1284
|
return artifacts;
|
|
1268
1285
|
}
|
|
1269
1286
|
function supermoduleConfigFromContext(ctx) {
|
|
@@ -1759,6 +1776,7 @@ async function addAgent(opts) {
|
|
|
1759
1776
|
mode: "merge"
|
|
1760
1777
|
});
|
|
1761
1778
|
await ensureEasyCodingSessionsIgnored(target.dir);
|
|
1779
|
+
await ensureHookBytecodeIgnored(target.dir);
|
|
1762
1780
|
await addAgentsToConfig(target.configPath, toInstall);
|
|
1763
1781
|
await setPendingInitSince(target.dir, VERSION);
|
|
1764
1782
|
installedLabels.push(`${target.label}: ${toInstall.join(", ")}`);
|
|
@@ -2861,9 +2879,11 @@ async function upgrade(opts) {
|
|
|
2861
2879
|
artifacts
|
|
2862
2880
|
});
|
|
2863
2881
|
await ensureEasyCodingSessionsIgnored(target.dir);
|
|
2882
|
+
await ensureHookBytecodeIgnored(target.dir);
|
|
2864
2883
|
await updateHarnessVersion(target.configPath, VERSION);
|
|
2865
2884
|
await updateSupermoduleConfig(target.configPath, target.supermodule);
|
|
2866
2885
|
await setPendingInitSince(target.dir, VERSION);
|
|
2886
|
+
await stripInitTaskProjectPath(target.dir);
|
|
2867
2887
|
}
|
|
2868
2888
|
if (parentTopologyRefresh) {
|
|
2869
2889
|
await refreshSupermoduleParent(
|