@ulpi/cli 0.1.5 → 0.1.6

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 (109) hide show
  1. package/LICENSE +21 -0
  2. package/dist/{auth-PN7TMQHV-2W4ICG64.js → auth-FWM7MM4Q-VZC3U2XZ.js} +1 -1
  3. package/dist/{auth-BFFBUJUC.js → auth-HDK7ECJL.js} +2 -1
  4. package/dist/{chunk-RJIRWQJD.js → chunk-3BCW6ABU.js} +402 -142
  5. package/dist/{chunk-L3PWNHSA.js → chunk-3WB5CXH4.js} +180 -5
  6. package/dist/{chunk-K4OVPFY2.js → chunk-4UCJIAOU.js} +2 -2
  7. package/dist/chunk-4XTHZVDS.js +109 -0
  8. package/dist/chunk-4ZPOZULQ.js +6522 -0
  9. package/dist/{chunk-SIAQVRKG.js → chunk-5MI5GIXM.js} +48 -2
  10. package/dist/{chunk-KLEASXUR.js → chunk-6ZL6NXMV.js} +1 -1
  11. package/dist/{chunk-AV5RB3N2.js → chunk-76D3BYJD.js} +48 -0
  12. package/dist/{chunk-DOIKS6C5.js → chunk-AWOSRA5F.js} +1 -1
  13. package/dist/{chunk-UCMT5OKP.js → chunk-BFEKZZHM.js} +274 -57
  14. package/dist/chunk-C7CLUQI6.js +1286 -0
  15. package/dist/{chunk-ELTGWMDE.js → chunk-E3B5NROU.js} +7 -7
  16. package/dist/chunk-EJ7TW77N.js +1418 -0
  17. package/dist/{chunk-6OURRFP7.js → chunk-IV6MWETF.js} +383 -168
  18. package/dist/chunk-IZPJHSPX.js +1478 -0
  19. package/dist/chunk-JLHNLM3C.js +228 -0
  20. package/dist/{chunk-P2RESJRN.js → chunk-KYYI23AQ.js} +2 -2
  21. package/dist/chunk-S6ANCSYO.js +1271 -0
  22. package/dist/chunk-SEU7WWNQ.js +1251 -0
  23. package/dist/chunk-SNQ7NAIS.js +453 -0
  24. package/dist/{ulpi-RMMCUAGP-EWYUE7RU.js → chunk-TSLDGT5O.js} +73 -35
  25. package/dist/{chunk-EIWYSP3A.js → chunk-UXHCHOWQ.js} +83 -62
  26. package/dist/chunk-V2H5D6Y3.js +146 -0
  27. package/dist/{chunk-5SCG7UYM.js → chunk-VVEDXI7E.js} +1 -1
  28. package/dist/chunk-VXH5Y4FO.js +6761 -0
  29. package/dist/chunk-WED4LM5N.js +322 -0
  30. package/dist/{chunk-74WVVWJ4.js → chunk-YOKL7RB5.js} +184 -15
  31. package/dist/chunk-Z53CAR7G.js +298 -0
  32. package/dist/{ci-JQ56YIKC.js → ci-X3U2W4HC.js} +124 -26
  33. package/dist/cloud-2F3NLVHN.js +274 -0
  34. package/dist/{codemap-HMYBXJL2.js → codemap-XNGMAF3F.js} +37 -37
  35. package/dist/codex-MB5YTMRT.js +132 -0
  36. package/dist/{config-YYWEN7U2.js → config-OOELBYTH.js} +1 -1
  37. package/dist/dist-2BJYR5EI.js +59 -0
  38. package/dist/dist-3EIQTZHT.js +1380 -0
  39. package/dist/{dist-WAMAQVPK.js → dist-4U5L2X2C.js} +2 -2
  40. package/dist/{dist-4XTJ6HLM.js → dist-54KAMNLO.js} +16 -15
  41. package/dist/dist-6M4MZWZW.js +58 -0
  42. package/dist/dist-6X576SU2.js +27 -0
  43. package/dist/dist-7QOEYLFX.js +103 -0
  44. package/dist/dist-AYBGHEDY.js +2541 -0
  45. package/dist/dist-EK45QNEM.js +45 -0
  46. package/dist/{dist-U7ZIJMZD.js → dist-FKFEJRPX.js} +16 -15
  47. package/dist/dist-GTEJUBBT.js +66 -0
  48. package/dist/dist-HA74OKJZ.js +40 -0
  49. package/dist/{dist-XG2GG5SD.js → dist-HU5RZAON.js} +14 -2
  50. package/dist/dist-IYE3OBRB.js +374 -0
  51. package/dist/{dist-7WLLPWWB.js → dist-JLU26AB6.js} +12 -9
  52. package/dist/{dist-6G7JC2RA.js → dist-KUCI6JFE.js} +49 -9
  53. package/dist/dist-NUEMFZFL.js +33 -0
  54. package/dist/{dist-GWGTAHNM.js → dist-NUXMDXZ3.js} +31 -3
  55. package/dist/{dist-5R4RYNQO.js → dist-YCNWHSLN.js} +15 -5
  56. package/dist/{dist-6MFVWIFF.js → dist-YFFG2ZD6.js} +9 -16
  57. package/dist/dist-ZG4OKCSR.js +15 -0
  58. package/dist/doctor-SI4LLLDZ.js +345 -0
  59. package/dist/{export-import-4A5MWLIA.js → export-import-JFQH4KSJ.js} +1 -1
  60. package/dist/{history-RNUWO4JZ.js → history-5NE46ZAH.js} +7 -7
  61. package/dist/{hooks-installer-K2JXEBNN.js → hooks-installer-UN5JZLDQ.js} +2 -2
  62. package/dist/index.js +394 -618
  63. package/dist/{init-NQWFZPKO.js → init-5FK3VKRT.js} +76 -10
  64. package/dist/job-HIDMAFW2.js +376 -0
  65. package/dist/jobs.memory-PLMMSFHB-VBECCTHN.js +33 -0
  66. package/dist/kiro-VMUHDFGK.js +153 -0
  67. package/dist/{launchd-OYXUAVW6.js → launchd-6AWT54HR.js} +9 -17
  68. package/dist/mcp-PDUD7SGP.js +249 -0
  69. package/dist/mcp-installer-PQU3XOGO.js +259 -0
  70. package/dist/mcp-setup-OA7IB3H3.js +263 -0
  71. package/dist/{memory-D6ZFFCI2.js → memory-ZNAEAK3B.js} +17 -17
  72. package/dist/{ollama-3XCUZMZT-FYKHW4TZ.js → ollama-3XCUZMZT-4JMH6B7P.js} +1 -1
  73. package/dist/{openai-E7G2YAHU-IG33BFYF.js → openai-E7G2YAHU-T3HMBPH7.js} +2 -2
  74. package/dist/portal-JYWVHXDU.js +210 -0
  75. package/dist/prd-Q4J5NVAR.js +408 -0
  76. package/dist/repos-WWZXNN3P.js +271 -0
  77. package/dist/review-integration-5WHEJU2A.js +14 -0
  78. package/dist/{rules-3OFGWHP4.js → rules-Y4VSOY5Y.js} +3 -3
  79. package/dist/run-VPNXEIBY.js +687 -0
  80. package/dist/server-COL4AXKU-P7S7NNF6.js +11 -0
  81. package/dist/server-KKSETHDV-XSSLEENT.js +20 -0
  82. package/dist/{skills-GY2CTPWN.js → skills-QEYU2N27.js} +4 -2
  83. package/dist/start-JYOEL7AJ.js +303 -0
  84. package/dist/{status-SE43TIFJ.js → status-BHQYYGAL.js} +2 -2
  85. package/dist/{templates-O2XDKB5R.js → templates-CBRUJ66V.js} +6 -5
  86. package/dist/tui-DP7736EX.js +61 -0
  87. package/dist/ulpi-5EN6JCAS-LFE3WSL4.js +10 -0
  88. package/dist/{uninstall-KWGSGZTI.js → uninstall-ICUV6DDV.js} +3 -3
  89. package/dist/{update-QYZA4D23.js → update-7ZMAYRBH.js} +3 -3
  90. package/dist/{version-checker-MVB74DEX.js → version-checker-4ZFMZA7Y.js} +2 -2
  91. package/package.json +39 -31
  92. package/dist/chunk-26LLDX2T.js +0 -553
  93. package/dist/chunk-DDRLI6JU.js +0 -331
  94. package/dist/chunk-IFATANHR.js +0 -453
  95. package/dist/chunk-JWUUVXIV.js +0 -13694
  96. package/dist/chunk-LD52XG3X.js +0 -4273
  97. package/dist/chunk-MIAQVCFW.js +0 -39
  98. package/dist/chunk-YYZOFYS6.js +0 -415
  99. package/dist/dist-XD4YI27T.js +0 -26
  100. package/dist/mcp-installer-TOYDP77X.js +0 -124
  101. package/dist/projects-COUJP4ZC.js +0 -271
  102. package/dist/review-KMGP2S25.js +0 -152
  103. package/dist/server-USLHY6GH-F4JSXCWA.js +0 -18
  104. package/dist/server-X5P6WH2M-ULZF5WHZ.js +0 -11
  105. package/dist/skills/ulpi-generate-guardian/SKILL.md +0 -750
  106. package/dist/skills/ulpi-generate-guardian/references/framework-rules.md +0 -849
  107. package/dist/skills/ulpi-generate-guardian/references/language-rules.md +0 -591
  108. package/dist/ui-4SM2SUI6.js +0 -167
  109. package/dist/ui.html +0 -698
@@ -2,14 +2,15 @@ import {
2
2
  ULPI_GLOBAL_DIR,
3
3
  projectGuardsFile,
4
4
  projectGuardsFileAlt
5
- } from "./chunk-DDRLI6JU.js";
5
+ } from "./chunk-C7CLUQI6.js";
6
6
 
7
- // ../../packages/projects-engine/dist/index.js
7
+ // ../../packages/repos-engine/dist/index.js
8
8
  import * as fs from "fs";
9
9
  import * as path from "path";
10
10
  import * as crypto from "crypto";
11
11
  var DEFAULT_BASE_DIR = ULPI_GLOBAL_DIR;
12
- var REGISTRY_FILE = "projects.json";
12
+ var REGISTRY_FILE = "repos.json";
13
+ var LEGACY_REGISTRY_FILE = "projects.json";
13
14
  function registryPath(baseDir) {
14
15
  return path.join(baseDir, REGISTRY_FILE);
15
16
  }
@@ -18,7 +19,7 @@ function atomicWrite(filePath, data) {
18
19
  fs.writeFileSync(tmpPath, data, "utf-8");
19
20
  fs.renameSync(tmpPath, filePath);
20
21
  }
21
- function generateProjectId(projectPath) {
22
+ function generateRepoId(projectPath) {
22
23
  const normalized = path.resolve(projectPath);
23
24
  const hash = crypto.createHash("sha256").update(normalized).digest("hex");
24
25
  return hash.slice(0, 12);
@@ -26,11 +27,31 @@ function generateProjectId(projectPath) {
26
27
  function createEmptyRegistry() {
27
28
  return {
28
29
  version: 1,
29
- projects: {},
30
- defaultProject: void 0
30
+ repos: {},
31
+ defaultRepo: void 0
31
32
  };
32
33
  }
33
- function loadProjectRegistry(baseDir = DEFAULT_BASE_DIR) {
34
+ function migrateIfNeeded(baseDir) {
35
+ const newPath = registryPath(baseDir);
36
+ if (fs.existsSync(newPath)) return;
37
+ const legacyPath = path.join(baseDir, LEGACY_REGISTRY_FILE);
38
+ if (!fs.existsSync(legacyPath)) return;
39
+ try {
40
+ const raw = fs.readFileSync(legacyPath, "utf-8");
41
+ const parsed = JSON.parse(raw);
42
+ const migrated = {
43
+ version: 1,
44
+ repos: parsed.projects ?? parsed.repos ?? {},
45
+ defaultRepo: parsed.defaultProject ?? parsed.defaultRepo
46
+ };
47
+ fs.mkdirSync(path.dirname(newPath), { recursive: true });
48
+ atomicWrite(newPath, JSON.stringify(migrated, null, 2));
49
+ fs.unlinkSync(legacyPath);
50
+ } catch {
51
+ }
52
+ }
53
+ function loadRepoRegistry(baseDir = DEFAULT_BASE_DIR) {
54
+ migrateIfNeeded(baseDir);
34
55
  const filePath = registryPath(baseDir);
35
56
  if (!fs.existsSync(filePath)) {
36
57
  return createEmptyRegistry();
@@ -38,7 +59,7 @@ function loadProjectRegistry(baseDir = DEFAULT_BASE_DIR) {
38
59
  try {
39
60
  const raw = fs.readFileSync(filePath, "utf-8");
40
61
  const parsed = JSON.parse(raw);
41
- if (parsed && typeof parsed === "object" && parsed.version === 1 && typeof parsed.projects === "object") {
62
+ if (parsed && typeof parsed === "object" && parsed.version === 1 && typeof parsed.repos === "object") {
42
63
  return parsed;
43
64
  }
44
65
  return createEmptyRegistry();
@@ -46,17 +67,17 @@ function loadProjectRegistry(baseDir = DEFAULT_BASE_DIR) {
46
67
  return createEmptyRegistry();
47
68
  }
48
69
  }
49
- function saveProjectRegistry(registry, baseDir = DEFAULT_BASE_DIR) {
70
+ function saveRepoRegistry(registry, baseDir = DEFAULT_BASE_DIR) {
50
71
  const filePath = registryPath(baseDir);
51
72
  const dir = path.dirname(filePath);
52
73
  fs.mkdirSync(dir, { recursive: true });
53
74
  atomicWrite(filePath, JSON.stringify(registry, null, 2));
54
75
  }
55
- function registerProject(projectDir, options = {}, baseDir = DEFAULT_BASE_DIR) {
76
+ function registerRepo(projectDir, options = {}, baseDir = DEFAULT_BASE_DIR) {
56
77
  const absPath = path.resolve(projectDir);
57
- const id = generateProjectId(absPath);
58
- const registry = loadProjectRegistry(baseDir);
59
- const existing = registry.projects[id];
78
+ const id = generateRepoId(absPath);
79
+ const registry = loadRepoRegistry(baseDir);
80
+ const existing = registry.repos[id];
60
81
  let configStatus = "none";
61
82
  const rulesPath = projectGuardsFile(absPath);
62
83
  const rulesYamlPath = projectGuardsFileAlt(absPath);
@@ -88,80 +109,80 @@ function registerProject(projectDir, options = {}, baseDir = DEFAULT_BASE_DIR) {
88
109
  hooksInstalled: options.hooksInstalled ?? hooksInstalled,
89
110
  stack: options.stack ?? existing?.stack
90
111
  };
91
- registry.projects[id] = entry;
92
- saveProjectRegistry(registry, baseDir);
112
+ registry.repos[id] = entry;
113
+ saveRepoRegistry(registry, baseDir);
93
114
  return entry;
94
115
  }
95
- function unregisterProject(idOrPath, baseDir = DEFAULT_BASE_DIR) {
96
- const registry = loadProjectRegistry(baseDir);
97
- if (registry.projects[idOrPath]) {
98
- delete registry.projects[idOrPath];
99
- if (registry.defaultProject === idOrPath) {
100
- registry.defaultProject = void 0;
116
+ function unregisterRepo(idOrPath, baseDir = DEFAULT_BASE_DIR) {
117
+ const registry = loadRepoRegistry(baseDir);
118
+ if (registry.repos[idOrPath]) {
119
+ delete registry.repos[idOrPath];
120
+ if (registry.defaultRepo === idOrPath) {
121
+ registry.defaultRepo = void 0;
101
122
  }
102
- saveProjectRegistry(registry, baseDir);
123
+ saveRepoRegistry(registry, baseDir);
103
124
  return true;
104
125
  }
105
126
  const absPath = path.resolve(idOrPath);
106
- const id = generateProjectId(absPath);
107
- if (registry.projects[id]) {
108
- delete registry.projects[id];
109
- if (registry.defaultProject === id) {
110
- registry.defaultProject = void 0;
127
+ const id = generateRepoId(absPath);
128
+ if (registry.repos[id]) {
129
+ delete registry.repos[id];
130
+ if (registry.defaultRepo === id) {
131
+ registry.defaultRepo = void 0;
111
132
  }
112
- saveProjectRegistry(registry, baseDir);
133
+ saveRepoRegistry(registry, baseDir);
113
134
  return true;
114
135
  }
115
136
  return false;
116
137
  }
117
- function getProject(idOrPath, baseDir = DEFAULT_BASE_DIR) {
118
- const registry = loadProjectRegistry(baseDir);
119
- if (registry.projects[idOrPath]) {
120
- return registry.projects[idOrPath];
138
+ function getRepo(idOrPath, baseDir = DEFAULT_BASE_DIR) {
139
+ const registry = loadRepoRegistry(baseDir);
140
+ if (registry.repos[idOrPath]) {
141
+ return registry.repos[idOrPath];
121
142
  }
122
143
  const absPath = path.resolve(idOrPath);
123
- const id = generateProjectId(absPath);
124
- return registry.projects[id] ?? null;
144
+ const id = generateRepoId(absPath);
145
+ return registry.repos[id] ?? null;
125
146
  }
126
- function listProjects(baseDir = DEFAULT_BASE_DIR) {
127
- const registry = loadProjectRegistry(baseDir);
128
- return Object.values(registry.projects).sort((a, b) => {
147
+ function listRepos(baseDir = DEFAULT_BASE_DIR) {
148
+ const registry = loadRepoRegistry(baseDir);
149
+ return Object.values(registry.repos).sort((a, b) => {
129
150
  return new Date(b.lastAccessed).getTime() - new Date(a.lastAccessed).getTime();
130
151
  });
131
152
  }
132
- function setDefaultProject(idOrPath, baseDir = DEFAULT_BASE_DIR) {
133
- const registry = loadProjectRegistry(baseDir);
153
+ function setDefaultRepo(idOrPath, baseDir = DEFAULT_BASE_DIR) {
154
+ const registry = loadRepoRegistry(baseDir);
134
155
  if (!idOrPath) {
135
- registry.defaultProject = void 0;
136
- saveProjectRegistry(registry, baseDir);
156
+ registry.defaultRepo = void 0;
157
+ saveRepoRegistry(registry, baseDir);
137
158
  return true;
138
159
  }
139
160
  let id = idOrPath;
140
- if (!registry.projects[id]) {
161
+ if (!registry.repos[id]) {
141
162
  const absPath = path.resolve(idOrPath);
142
- id = generateProjectId(absPath);
163
+ id = generateRepoId(absPath);
143
164
  }
144
- if (!registry.projects[id]) {
165
+ if (!registry.repos[id]) {
145
166
  return false;
146
167
  }
147
- registry.defaultProject = id;
148
- saveProjectRegistry(registry, baseDir);
168
+ registry.defaultRepo = id;
169
+ saveRepoRegistry(registry, baseDir);
149
170
  return true;
150
171
  }
151
- function getDefaultProject(baseDir = DEFAULT_BASE_DIR) {
152
- const registry = loadProjectRegistry(baseDir);
153
- if (!registry.defaultProject) {
172
+ function getDefaultRepo(baseDir = DEFAULT_BASE_DIR) {
173
+ const registry = loadRepoRegistry(baseDir);
174
+ if (!registry.defaultRepo) {
154
175
  return null;
155
176
  }
156
- return registry.projects[registry.defaultProject] ?? null;
177
+ return registry.repos[registry.defaultRepo] ?? null;
157
178
  }
158
- function scanForProjects(rootDir, maxDepth = 3) {
159
- const projects = [];
179
+ function scanForRepos(rootDir, maxDepth = 3) {
180
+ const repos = [];
160
181
  function scan(dir, depth) {
161
182
  if (depth > maxDepth) return;
162
183
  const ulpiPath = path.join(dir, ".ulpi");
163
184
  if (fs.existsSync(path.join(ulpiPath, "guards.yml")) || fs.existsSync(path.join(ulpiPath, "guards.yaml"))) {
164
- projects.push(dir);
185
+ repos.push(dir);
165
186
  return;
166
187
  }
167
188
  try {
@@ -182,16 +203,16 @@ function scanForProjects(rootDir, maxDepth = 3) {
182
203
  }
183
204
  }
184
205
  scan(path.resolve(rootDir), 0);
185
- return projects;
206
+ return repos;
186
207
  }
187
208
 
188
209
  export {
189
- loadProjectRegistry,
190
- registerProject,
191
- unregisterProject,
192
- getProject,
193
- listProjects,
194
- setDefaultProject,
195
- getDefaultProject,
196
- scanForProjects
210
+ loadRepoRegistry,
211
+ registerRepo,
212
+ unregisterRepo,
213
+ getRepo,
214
+ listRepos,
215
+ setDefaultRepo,
216
+ getDefaultRepo,
217
+ scanForRepos
197
218
  };
@@ -0,0 +1,146 @@
1
+ import {
2
+ REVIEW_FLAGS_DIR,
3
+ loadUlpiSettings
4
+ } from "./chunk-C7CLUQI6.js";
5
+
6
+ // src/hooks/review-integration.ts
7
+ import * as fs from "fs";
8
+ import * as path from "path";
9
+ import { execFileSync } from "child_process";
10
+ function isReviewEnabled(type, rules) {
11
+ const runMode = process.env.ULPI_RUN_MODE;
12
+ if (runMode === "loop" || runMode === "parallel" || runMode === "ci") {
13
+ return false;
14
+ }
15
+ const reviewConfig = rules.review;
16
+ if (reviewConfig) {
17
+ if (reviewConfig.enabled === false) return false;
18
+ if (type === "plan" && reviewConfig.plan_review === false) return false;
19
+ if (type === "code" && reviewConfig.code_review === false) return false;
20
+ }
21
+ try {
22
+ const settings = loadUlpiSettings();
23
+ if (!settings.review.enabled) return false;
24
+ if (type === "plan" && !settings.review.plan_review) return false;
25
+ if (type === "code" && !settings.review.code_review) return false;
26
+ } catch {
27
+ }
28
+ return true;
29
+ }
30
+ function extractPlanForReview(input) {
31
+ const toolInput = input.tool_input;
32
+ if (toolInput?.plan && typeof toolInput.plan === "string") {
33
+ return toolInput.plan;
34
+ }
35
+ if (toolInput?.content && typeof toolInput.content === "string") {
36
+ return toolInput.content;
37
+ }
38
+ try {
39
+ const plansDir = path.join(input.cwd, ".claude", "plans");
40
+ if (!fs.existsSync(plansDir)) return null;
41
+ const entries = fs.readdirSync(plansDir);
42
+ let newest = null;
43
+ for (const entry of entries) {
44
+ if (!entry.endsWith(".md")) continue;
45
+ const fullPath = path.join(plansDir, entry);
46
+ const stat = fs.statSync(fullPath);
47
+ if (!newest || stat.mtimeMs > newest.mtime) {
48
+ newest = { name: entry, mtime: stat.mtimeMs };
49
+ }
50
+ }
51
+ if (newest) {
52
+ return fs.readFileSync(path.join(plansDir, newest.name), "utf-8");
53
+ }
54
+ } catch {
55
+ }
56
+ return null;
57
+ }
58
+ async function runPlanReviewSession(plan, projectDir, sessionId) {
59
+ try {
60
+ const { discoverUlpiServer, registerWithServer, waitForServerDecision } = await import("./dist-ZG4OKCSR.js");
61
+ const server = await discoverUlpiServer();
62
+ if (!server) return null;
63
+ const settings = loadUlpiSettings();
64
+ const registration = await registerWithServer(
65
+ server.port,
66
+ { type: "plan", projectPath: projectDir, plan },
67
+ server.secret
68
+ );
69
+ if (!registration?.success) return null;
70
+ const reviewSessionId = registration.sessionId;
71
+ if (settings.review.auto_open_browser) {
72
+ const url = `http://127.0.0.1:${server.port}/review/plan?session=${reviewSessionId}`;
73
+ try {
74
+ execFileSync("open", [url], { timeout: 5e3 });
75
+ } catch {
76
+ }
77
+ }
78
+ const maxWaitMs = settings.review.review_timeout_seconds > 0 ? settings.review.review_timeout_seconds * 1e3 : void 0;
79
+ const decision = await waitForServerDecision(
80
+ server.port,
81
+ reviewSessionId,
82
+ 3e4,
83
+ maxWaitMs,
84
+ registration.token,
85
+ server.secret
86
+ );
87
+ if (!decision) {
88
+ if (settings.review.timeout_behavior === "deny") {
89
+ return { behavior: "deny", feedback: "Plan review timed out." };
90
+ }
91
+ return null;
92
+ }
93
+ const planDecision = decision;
94
+ const behavior = planDecision.behavior === "deny" ? "deny" : "allow";
95
+ const feedback = planDecision.feedback || planDecision.message || void 0;
96
+ const clearContext = planDecision.clearContext ?? false;
97
+ writeFlagFiles(sessionId, { feedback, clearContext });
98
+ return { behavior, feedback, clearContext };
99
+ } catch {
100
+ return null;
101
+ }
102
+ }
103
+ function writeFlagFiles(sessionId, ctx) {
104
+ try {
105
+ const dir = path.join(REVIEW_FLAGS_DIR, sessionId);
106
+ fs.mkdirSync(dir, { recursive: true });
107
+ if (ctx.feedback) {
108
+ fs.writeFileSync(path.join(dir, "review-feedback.flag"), ctx.feedback, "utf-8");
109
+ }
110
+ if (ctx.clearContext) {
111
+ fs.writeFileSync(path.join(dir, "clear-context.flag"), "1", "utf-8");
112
+ }
113
+ } catch {
114
+ }
115
+ }
116
+ function collectPostReviewContexts(sessionId) {
117
+ const result = {};
118
+ try {
119
+ const dir = path.join(REVIEW_FLAGS_DIR, sessionId);
120
+ if (!fs.existsSync(dir)) return result;
121
+ const feedbackPath = path.join(dir, "review-feedback.flag");
122
+ if (fs.existsSync(feedbackPath)) {
123
+ result.feedback = fs.readFileSync(feedbackPath, "utf-8");
124
+ fs.unlinkSync(feedbackPath);
125
+ }
126
+ const clearPath = path.join(dir, "clear-context.flag");
127
+ if (fs.existsSync(clearPath)) {
128
+ result.clearContext = true;
129
+ fs.unlinkSync(clearPath);
130
+ }
131
+ try {
132
+ const remaining = fs.readdirSync(dir);
133
+ if (remaining.length === 0) fs.rmdirSync(dir);
134
+ } catch {
135
+ }
136
+ } catch {
137
+ }
138
+ return result;
139
+ }
140
+
141
+ export {
142
+ isReviewEnabled,
143
+ extractPlanForReview,
144
+ runPlanReviewSession,
145
+ collectPostReviewContexts
146
+ };
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  CLI_BIN_NAME,
3
3
  getBinaryPath
4
- } from "./chunk-DDRLI6JU.js";
4
+ } from "./chunk-C7CLUQI6.js";
5
5
 
6
6
  // src/hooks-installer.ts
7
7
  import * as fs from "fs";