cuelo 0.5.2 → 0.5.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.
Files changed (76) hide show
  1. package/.next/BUILD_ID +1 -1
  2. package/.next/app-path-routes-manifest.json +10 -10
  3. package/.next/build-manifest.json +2 -2
  4. package/.next/prerender-manifest.json +3 -3
  5. package/.next/required-server-files.js +2 -2
  6. package/.next/required-server-files.json +2 -2
  7. package/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  8. package/.next/server/app/_global-error.html +1 -1
  9. package/.next/server/app/_global-error.rsc +1 -1
  10. package/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  11. package/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  12. package/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  13. package/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  14. package/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  15. package/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  16. package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  17. package/.next/server/app/_not-found.html +1 -1
  18. package/.next/server/app/_not-found.rsc +2 -2
  19. package/.next/server/app/_not-found.segments/_full.segment.rsc +2 -2
  20. package/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  21. package/.next/server/app/_not-found.segments/_index.segment.rsc +2 -2
  22. package/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  23. package/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  24. package/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  25. package/.next/server/app/api/updates/route.js +1 -1
  26. package/.next/server/app/index.html +1 -1
  27. package/.next/server/app/index.rsc +4 -4
  28. package/.next/server/app/index.segments/__PAGE__.segment.rsc +3 -3
  29. package/.next/server/app/index.segments/_full.segment.rsc +4 -4
  30. package/.next/server/app/index.segments/_head.segment.rsc +1 -1
  31. package/.next/server/app/index.segments/_index.segment.rsc +2 -2
  32. package/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  33. package/.next/server/app/page.js +3 -3
  34. package/.next/server/app/page_client-reference-manifest.js +1 -1
  35. package/.next/server/app/recover/page_client-reference-manifest.js +1 -1
  36. package/.next/server/app/recover.html +1 -1
  37. package/.next/server/app/recover.rsc +2 -2
  38. package/.next/server/app/recover.segments/_full.segment.rsc +2 -2
  39. package/.next/server/app/recover.segments/_head.segment.rsc +1 -1
  40. package/.next/server/app/recover.segments/_index.segment.rsc +2 -2
  41. package/.next/server/app/recover.segments/_tree.segment.rsc +1 -1
  42. package/.next/server/app/recover.segments/recover/__PAGE__.segment.rsc +1 -1
  43. package/.next/server/app/recover.segments/recover.segment.rsc +1 -1
  44. package/.next/server/app-paths-manifest.json +10 -10
  45. package/.next/server/middleware-build-manifest.js +1 -1
  46. package/.next/server/pages/404.html +1 -1
  47. package/.next/server/pages/500.html +1 -1
  48. package/.next/server/server-reference-manifest.json +1 -1
  49. package/.next/static/chunks/app/{layout-5217e6f9b3d4a4b8.js → layout-61356b8386302172.js} +1 -1
  50. package/.next/static/chunks/app/{page-28b47a94fe58eaba.js → page-d1291e02ffa77a51.js} +3 -3
  51. package/.next/trace +104 -104
  52. package/.next/trace-build +1 -1
  53. package/README.md +3 -3
  54. package/Tools/CUELO_Setup/files/native-runtime-patch.js +5 -5
  55. package/Tools/OMP_Global_Config/agent/RULES.md +12 -0
  56. package/Tools/OMP_Global_Config/agent/agents/maker.md +11 -8
  57. package/Tools/OMP_Global_Config/agent/extensions/character-voice.ts +26 -45
  58. package/Tools/OMP_Global_Config/agent/extensions/external-advice-check.ts +138 -0
  59. package/Tools/OMP_Global_Config/agent/extensions/jev-runtime.ts +154 -10
  60. package/Tools/OMP_Global_Config/agent/extensions/lib/maker-routing.ts +24 -4
  61. package/Tools/OMP_Global_Config/agent/extensions/lib/routing-ledger.ts +2 -0
  62. package/Tools/OMP_Global_Config/agent/extensions/steering-reply-gate.ts +164 -52
  63. package/Tools/OMP_Global_Config/agent/extensions/todo-nudge.ts +137 -45
  64. package/Tools/OMP_Global_Config/agent/extensions/turn-end-guard.ts +249 -18
  65. package/Tools/OMP_Global_Config/agent/prompt-copies/AGENTS.en.md +1 -1
  66. package/Tools/OMP_Global_Config/agent/prompt-copies/RULES.en.md +2 -1
  67. package/Tools/OMP_Global_Config/agent/rules/harness-policy.json +78 -10
  68. package/Tools/OMP_Global_Config/agent/rules/subagent.md +29 -2
  69. package/Tools/OMP_Global_Config/agent/rules/verdict.md +10 -3
  70. package/Tools/OMP_Global_Config/agent/sop/_common.md +10 -7
  71. package/Tools/OMP_Global_Config/agent/tools/git-finalizer/index.ts +101 -2
  72. package/Tools/OMP_Global_Config/patches/apply-core-patch.mjs +322 -95
  73. package/install.mjs +1 -1
  74. package/package.json +9 -9
  75. /package/.next/static/{bGz6gPjG3dJqXPXBB1JeP → Xey7BdddcpqFxM5-ikcal}/_buildManifest.js +0 -0
  76. /package/.next/static/{bGz6gPjG3dJqXPXBB1JeP → Xey7BdddcpqFxM5-ikcal}/_ssgManifest.js +0 -0
@@ -1,7 +1,8 @@
1
1
  import type { CustomToolFactory } from "@oh-my-pi/pi-coding-agent";
2
- import { mkdtemp, rm, writeFile } from "node:fs/promises";
2
+ import { createHash } from "node:crypto";
3
+ import { mkdtemp, readFile, rm, stat, writeFile } from "node:fs/promises";
3
4
  import { tmpdir } from "node:os";
4
- import { join } from "node:path";
5
+ import { dirname, isAbsolute, join, relative, resolve, sep } from "node:path";
5
6
  import { fileURLToPath } from "node:url";
6
7
 
7
8
  interface FinalizerResult {
@@ -14,6 +15,102 @@ interface FinalizerResult {
14
15
  }
15
16
 
16
17
  const scriptPath = fileURLToPath(new URL("./finalizer.ps1", import.meta.url));
18
+ const helperPath = "Tools/CUELO_Setup/files/source-build-helper.js";
19
+ const manifestPath = "Tools/CUELO_Setup/files/source-integrity.json";
20
+ const excludedSourcePaths: Record<string, true> = {
21
+ "HANDOFF.md": true, "PC-SETUP.md": true, ".publicignore": true, ".publicdeny": true,
22
+ ".github/workflows/publish-public.yml": true,
23
+ };
24
+ const generatedSourceSegments: Record<string, true> = { ".git": true, ".next": true, ".omp": true, node_modules: true };
25
+ // helper.buildFileMap()은 전체 트리를 검사하므로 무관한 writer의 변경까지 읽는다.
26
+ // 여기서는 helper의 source 경계와 LF 해시 규칙을 선택된 파일에만 적용한다.
27
+ const manifestInstructions = `From cwd Tools/CUELO_Setup, run:
28
+ node files/source-build-helper.js create-manifest ../.. files/runtime-integrity.json --output files/source-integrity.json
29
+ node files/source-build-helper.js verify-source ../.. files/source-integrity.json files/runtime-integrity.json
30
+ Then include Tools/CUELO_Setup/files/source-integrity.json in the same commit.`;
31
+
32
+ function isSourcePath(path: string, packagedTools: string[]): boolean {
33
+ if (path.split("/").some((segment) => generatedSourceSegments[segment] || segment.endsWith(".tsbuildinfo"))) return false;
34
+ if (path === "doc" || path.startsWith("doc/") || excludedSourcePaths[path]) return false;
35
+ if (path.startsWith("Tools/")) {
36
+ return packagedTools.some((entry) => path === entry || path.startsWith(`${entry}/`));
37
+ }
38
+ return true;
39
+ }
40
+
41
+ async function checkSourceManifest(
42
+ cwd: string,
43
+ files: string[],
44
+ exec: (command: string, args: string[], options: { cwd: string }) => Promise<{ code: number; stdout: string }>,
45
+ ): Promise<void> {
46
+ const targets: { root: string; path: string }[] = [];
47
+ for (const input of files) {
48
+ if (isAbsolute(input) || /[\0\r\n]/.test(input)) return; // 잘못된 경로의 최종 판정은 finalizer.ps1에 둔다.
49
+ const absolute = resolve(cwd, input);
50
+ let directory = dirname(absolute);
51
+ while (true) {
52
+ try {
53
+ if ((await stat(directory)).isDirectory()) break;
54
+ } catch { /* finalizer.ps1과 같이 가장 가까운 기존 부모를 찾는다. */ }
55
+ const parent = dirname(directory);
56
+ if (parent === directory) return;
57
+ directory = parent;
58
+ }
59
+ const result = await exec("git", ["-C", directory, "rev-parse", "--show-prefix"], { cwd });
60
+ if (result.code !== 0) return; // 저장소 밖·잘못된 대상은 finalizer.ps1이 판정한다.
61
+ const prefix = result.stdout.trim().split("/").filter(Boolean);
62
+ const root = resolve(directory, ...prefix.map(() => ".."));
63
+ const path = relative(root, absolute).split(sep).join("/");
64
+ if (!path || path === ".." || path.startsWith("../")) return;
65
+ targets.push({ root, path });
66
+ }
67
+ if (!targets.length || targets.some(({ root }) => root.toLowerCase() !== targets[0].root.toLowerCase())) return;
68
+
69
+ const root = targets[0].root;
70
+ try {
71
+ await stat(join(root, ...helperPath.split("/")));
72
+ } catch (error) {
73
+ if ((error as NodeJS.ErrnoException).code === "ENOENT") return;
74
+ throw error;
75
+ }
76
+ if (targets.some(({ path }) => path.toLowerCase() === manifestPath.toLowerCase())) return;
77
+
78
+ let packagedTools: string[] = [];
79
+ try {
80
+ const pkg = JSON.parse(await readFile(join(root, "package.json"), "utf8")) as { files?: unknown };
81
+ if (Array.isArray(pkg.files)) {
82
+ packagedTools = pkg.files
83
+ .filter((entry): entry is string => typeof entry === "string" && entry.startsWith("Tools/"))
84
+ .map((entry) => entry.replace(/\/+$/, ""));
85
+ }
86
+ } catch (error) {
87
+ if ((error as NodeJS.ErrnoException).code !== "ENOENT") throw error;
88
+ }
89
+ const sourcePaths = targets.map(({ path }) => path).filter((path) => isSourcePath(path, packagedTools));
90
+ if (!sourcePaths.length) return;
91
+
92
+ let manifest: { files?: Record<string, string> } = {};
93
+ try {
94
+ manifest = JSON.parse(await readFile(join(root, ...manifestPath.split("/")), "utf8"));
95
+ } catch (error) {
96
+ if ((error as NodeJS.ErrnoException).code !== "ENOENT") throw error;
97
+ }
98
+ for (const path of sourcePaths) {
99
+ let bytes: Buffer | undefined;
100
+ try {
101
+ bytes = await readFile(join(root, ...path.split("/")));
102
+ } catch (error) {
103
+ if ((error as NodeJS.ErrnoException).code !== "ENOENT") throw error;
104
+ }
105
+ const content = bytes && !bytes.includes(0) && bytes.includes("\r\n")
106
+ ? Buffer.from(bytes.toString("latin1").replace(/\r\n/g, "\n"), "latin1")
107
+ : bytes;
108
+ const hash = content && createHash("sha256").update(content).digest("hex");
109
+ if (!hash || manifest.files?.[path] !== hash) {
110
+ throw new Error(`git_finalize: source manifest is stale for ${path}. ${manifestInstructions}`);
111
+ }
112
+ }
113
+ }
17
114
 
18
115
  function parseResult(stdout: string): FinalizerResult | undefined {
19
116
  const lines = stdout.split(/\r?\n/).map((line) => line.trim()).filter(Boolean);
@@ -46,6 +143,8 @@ const factory: CustomToolFactory = (pi) => ({
46
143
  if (!message) throw new Error("git_finalize requires a non-empty commit message.");
47
144
  if (process.platform !== "win32") throw new Error("git_finalize currently requires Windows PowerShell.");
48
145
 
146
+ await checkSourceManifest(pi.cwd, files, (command, args, options) => pi.exec(command, args, { ...options, signal }));
147
+
49
148
  onUpdate?.({
50
149
  content: [{ type: "text", text: "Repository finalizer lock을 획득하고 변경 경계를 확인하는 중입니다." }],
51
150
  details: { phase: "preflight", files },