@h-rig/core 0.0.6-alpha.176 → 0.0.6-alpha.177
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/src/baked-secrets.d.ts +3 -6
- package/dist/src/baked-secrets.js +9 -67
- package/dist/src/capability-loaders.js +132 -20
- package/dist/src/declarative-config.js +5 -2
- package/dist/src/harness-paths.d.ts +0 -9
- package/dist/src/harness-paths.js +1 -16
- package/dist/src/hook-materializer.d.ts +9 -60
- package/dist/src/hook-materializer.js +3 -132
- package/dist/src/hook-protocol.js +1 -31
- package/dist/src/hook-runner.d.ts +3 -3
- package/dist/src/hook-runner.js +132 -20
- package/dist/src/hook-runtime.js +1 -31
- package/dist/src/json-files.js +0 -1
- package/dist/src/kernel-entrypoint.js +132 -20
- package/dist/src/layout.d.ts +2 -2
- package/dist/src/layout.js +2 -8
- package/dist/src/load-config.js +132 -20
- package/dist/src/placement.d.ts +16 -8
- package/dist/src/placement.js +18 -961
- package/dist/src/plugin-host-context.d.ts +2 -3
- package/dist/src/plugin-host-context.js +170 -294
- package/dist/src/project-plugins.js +132 -20
- package/dist/src/remote-config.d.ts +38 -96
- package/dist/src/remote-config.js +35 -524
- package/dist/src/root-resolver.js +0 -1
- package/dist/src/run-provisioning.d.ts +17 -38
- package/dist/src/run-provisioning.js +19 -112
- package/dist/src/runtime-events.js +0 -4
- package/dist/src/runtime-overlay.js +0 -2
- package/dist/src/server-paths.d.ts +0 -4
- package/dist/src/server-paths.js +36 -125
- package/package.json +3 -7
- package/dist/src/profile-ops.d.ts +0 -9
- package/dist/src/profile-ops.js +0 -252
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// @bun
|
|
2
2
|
// packages/core/src/hook-materializer.ts
|
|
3
|
-
import { existsSync as existsSync2
|
|
4
|
-
import {
|
|
3
|
+
import { existsSync as existsSync2 } from "fs";
|
|
4
|
+
import { resolve as resolve2 } from "path";
|
|
5
5
|
|
|
6
6
|
// packages/core/src/hook-runtime.ts
|
|
7
7
|
import { appendFileSync, existsSync, mkdirSync, readFileSync, realpathSync, writeSync } from "fs";
|
|
@@ -116,18 +116,6 @@ function resolveBunCliInvocation() {
|
|
|
116
116
|
}
|
|
117
117
|
|
|
118
118
|
// packages/core/src/hook-materializer.ts
|
|
119
|
-
var MARKER_PLUGIN = "_rigPlugin";
|
|
120
|
-
var MARKER_HOOK_ID = "_rigHookId";
|
|
121
|
-
function matcherToString(matcher) {
|
|
122
|
-
if (matcher.kind === "all")
|
|
123
|
-
return;
|
|
124
|
-
if (matcher.kind === "tool")
|
|
125
|
-
return matcher.name;
|
|
126
|
-
return matcher.pattern;
|
|
127
|
-
}
|
|
128
|
-
function isPluginOwned(cmd) {
|
|
129
|
-
return typeof cmd[MARKER_PLUGIN] === "string";
|
|
130
|
-
}
|
|
131
119
|
function shellQuote(value) {
|
|
132
120
|
return `'${value.replaceAll("'", `'\\''`)}'`;
|
|
133
121
|
}
|
|
@@ -158,124 +146,7 @@ function buildTypedHookShimCommand(pluginName, hook, projectRoot) {
|
|
|
158
146
|
].filter(Boolean);
|
|
159
147
|
return parts.join(" ");
|
|
160
148
|
}
|
|
161
|
-
function createPiNoopSessionHookAdapter() {
|
|
162
|
-
return {
|
|
163
|
-
id: "pi",
|
|
164
|
-
materialize() {
|
|
165
|
-
return {
|
|
166
|
-
adapterId: "pi",
|
|
167
|
-
status: "skipped",
|
|
168
|
-
reason: "Pi sessions do not consume Claude Code settings hooks."
|
|
169
|
-
};
|
|
170
|
-
}
|
|
171
|
-
};
|
|
172
|
-
}
|
|
173
|
-
function createClaudeCodeSessionHookAdapter() {
|
|
174
|
-
return {
|
|
175
|
-
id: "claude-code",
|
|
176
|
-
materialize(projectRoot, entries) {
|
|
177
|
-
return writeClaudeCodeHookSettings(projectRoot, entries);
|
|
178
|
-
}
|
|
179
|
-
};
|
|
180
|
-
}
|
|
181
|
-
function defaultAgentSessionHookAdapters(env = process.env) {
|
|
182
|
-
if (env.RIG_AGENT_SESSION_HOOK_ADAPTER === "claude-code") {
|
|
183
|
-
return [createClaudeCodeSessionHookAdapter()];
|
|
184
|
-
}
|
|
185
|
-
if (env.RIG_AGENT_SESSION_HOOK_ADAPTER === "pi" || typeof env.PI_CODING_AGENT_SESSION_DIR === "string" && env.PI_CODING_AGENT_SESSION_DIR.trim().length > 0 || env.RIG_RUN_PROCESS === "1") {
|
|
186
|
-
return [createPiNoopSessionHookAdapter()];
|
|
187
|
-
}
|
|
188
|
-
return [createClaudeCodeSessionHookAdapter()];
|
|
189
|
-
}
|
|
190
|
-
function materializeSessionHookAdapters(projectRoot, entries, adapters = [createClaudeCodeSessionHookAdapter()]) {
|
|
191
|
-
return adapters.map((adapter) => adapter.materialize(projectRoot, entries));
|
|
192
|
-
}
|
|
193
|
-
function materializeHooks(projectRoot, entries) {
|
|
194
|
-
const result = createClaudeCodeSessionHookAdapter().materialize(projectRoot, entries);
|
|
195
|
-
return result.status === "materialized" ? result.path : resolve2(projectRoot, ".claude", "settings.json");
|
|
196
|
-
}
|
|
197
|
-
function applyClaudeCodeSessionHooksToSettings(existing, entries, projectRoot, options = {}) {
|
|
198
|
-
const hooks = typeof existing.hooks === "object" && existing.hooks !== null && !Array.isArray(existing.hooks) ? existing.hooks : {};
|
|
199
|
-
const replacePluginOwned = options.replacePluginOwned ?? true;
|
|
200
|
-
if (replacePluginOwned) {
|
|
201
|
-
for (const event of Object.keys(hooks)) {
|
|
202
|
-
const groups = hooks[event] ?? [];
|
|
203
|
-
const cleaned = [];
|
|
204
|
-
for (const group of groups) {
|
|
205
|
-
const operatorHooks = group.hooks.filter((h) => !isPluginOwned(h));
|
|
206
|
-
if (operatorHooks.length > 0) {
|
|
207
|
-
cleaned.push({ ...group, hooks: operatorHooks });
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
if (cleaned.length > 0) {
|
|
211
|
-
hooks[event] = cleaned;
|
|
212
|
-
} else {
|
|
213
|
-
delete hooks[event];
|
|
214
|
-
}
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
const materializedEvents = new Set;
|
|
218
|
-
for (const { pluginName, hook, typed } of entries) {
|
|
219
|
-
const command = hook.command ?? (typed ? buildTypedHookShimCommand(pluginName, hook, projectRoot) : undefined);
|
|
220
|
-
if (!command) {
|
|
221
|
-
continue;
|
|
222
|
-
}
|
|
223
|
-
const event = hook.event;
|
|
224
|
-
materializedEvents.add(event);
|
|
225
|
-
const matcherString = matcherToString(hook.matcher);
|
|
226
|
-
const groups = hooks[event] ??= [];
|
|
227
|
-
let group = groups.find((g) => g.matcher === matcherString);
|
|
228
|
-
if (!group) {
|
|
229
|
-
group = matcherString === undefined ? { hooks: [] } : { matcher: matcherString, hooks: [] };
|
|
230
|
-
groups.push(group);
|
|
231
|
-
}
|
|
232
|
-
const alreadyPresent = group.hooks.some((candidate) => candidate[MARKER_PLUGIN] === pluginName && candidate[MARKER_HOOK_ID] === hook.id);
|
|
233
|
-
if (alreadyPresent) {
|
|
234
|
-
continue;
|
|
235
|
-
}
|
|
236
|
-
group.hooks.push({
|
|
237
|
-
type: "command",
|
|
238
|
-
command,
|
|
239
|
-
[MARKER_PLUGIN]: pluginName,
|
|
240
|
-
[MARKER_HOOK_ID]: hook.id
|
|
241
|
-
});
|
|
242
|
-
}
|
|
243
|
-
const next = { ...existing };
|
|
244
|
-
if (Object.keys(hooks).length > 0) {
|
|
245
|
-
next.hooks = hooks;
|
|
246
|
-
} else {
|
|
247
|
-
delete next.hooks;
|
|
248
|
-
}
|
|
249
|
-
return { settings: next, events: [...materializedEvents].sort() };
|
|
250
|
-
}
|
|
251
|
-
function writeClaudeCodeHookSettings(projectRoot, entries) {
|
|
252
|
-
const settingsPath = resolve2(projectRoot, ".claude", "settings.json");
|
|
253
|
-
const existing = existsSync2(settingsPath) ? safeReadJson(settingsPath) : {};
|
|
254
|
-
const { settings, events } = applyClaudeCodeSessionHooksToSettings(existing, entries, projectRoot);
|
|
255
|
-
mkdirSync2(dirname(settingsPath), { recursive: true });
|
|
256
|
-
writeFileSync(settingsPath, `${JSON.stringify(settings, null, 2)}
|
|
257
|
-
`, "utf-8");
|
|
258
|
-
return {
|
|
259
|
-
adapterId: "claude-code",
|
|
260
|
-
status: "materialized",
|
|
261
|
-
path: settingsPath,
|
|
262
|
-
events
|
|
263
|
-
};
|
|
264
|
-
}
|
|
265
|
-
function safeReadJson(path) {
|
|
266
|
-
try {
|
|
267
|
-
return JSON.parse(readFileSync2(path, "utf-8"));
|
|
268
|
-
} catch {
|
|
269
|
-
return {};
|
|
270
|
-
}
|
|
271
|
-
}
|
|
272
149
|
export {
|
|
273
150
|
resolveHookRunnerPath,
|
|
274
|
-
|
|
275
|
-
materializeHooks,
|
|
276
|
-
defaultAgentSessionHookAdapters,
|
|
277
|
-
createPiNoopSessionHookAdapter,
|
|
278
|
-
createClaudeCodeSessionHookAdapter,
|
|
279
|
-
buildTypedHookShimCommand,
|
|
280
|
-
applyClaudeCodeSessionHooksToSettings
|
|
151
|
+
buildTypedHookShimCommand
|
|
281
152
|
};
|
|
@@ -151,26 +151,6 @@ function isTaskConfigEntry(value) {
|
|
|
151
151
|
}
|
|
152
152
|
return true;
|
|
153
153
|
}
|
|
154
|
-
async function readTaskConfigFromDisk(configPath) {
|
|
155
|
-
if (!existsSync(configPath)) {
|
|
156
|
-
return null;
|
|
157
|
-
}
|
|
158
|
-
try {
|
|
159
|
-
const bunFile = bunRuntime()?.file;
|
|
160
|
-
const content = bunFile ? await bunFile(configPath).json() : JSON.parse(readFileSync(configPath, "utf-8"));
|
|
161
|
-
return isPlainObject(content) ? content : null;
|
|
162
|
-
} catch {
|
|
163
|
-
return null;
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
function taskConfigCandidates(ctx) {
|
|
167
|
-
const taskWorkspace = process.env.RIG_TASK_WORKSPACE?.trim();
|
|
168
|
-
return [
|
|
169
|
-
ctx?.monorepoMainRoot ? resolve(ctx.monorepoMainRoot, ".rig", "task-config.json") : "",
|
|
170
|
-
process.env.MONOREPO_MAIN_ROOT?.trim() ? resolve(process.env.MONOREPO_MAIN_ROOT.trim(), ".rig", "task-config.json") : "",
|
|
171
|
-
taskWorkspace ? resolve(taskWorkspace, ".rig", "task-config.json") : ""
|
|
172
|
-
].filter(Boolean);
|
|
173
|
-
}
|
|
174
154
|
async function resolveTaskConfig(_projectRoot, _taskId) {
|
|
175
155
|
const ctx = getContext();
|
|
176
156
|
if (ctx) {
|
|
@@ -188,16 +168,6 @@ async function resolveTaskConfig(_projectRoot, _taskId) {
|
|
|
188
168
|
}
|
|
189
169
|
} catch {}
|
|
190
170
|
}
|
|
191
|
-
for (const configPath of taskConfigCandidates(ctx)) {
|
|
192
|
-
const config = await readTaskConfigFromDisk(configPath);
|
|
193
|
-
if (!config) {
|
|
194
|
-
continue;
|
|
195
|
-
}
|
|
196
|
-
const taskEntry = config[_taskId];
|
|
197
|
-
if (isTaskConfigEntry(taskEntry)) {
|
|
198
|
-
return taskEntry;
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
171
|
return {};
|
|
202
172
|
}
|
|
203
173
|
async function resolveTaskScopes(projectRoot, taskId) {
|
|
@@ -327,7 +297,7 @@ function block(hookName, message, projectRoot) {
|
|
|
327
297
|
lines.push("");
|
|
328
298
|
lines.push(`REPEATED VIOLATION (${count}x ${hookName}).`);
|
|
329
299
|
lines.push("STOP. Read the FULL CLAUDE.md from top to bottom.");
|
|
330
|
-
lines.push("If stuck,
|
|
300
|
+
lines.push("If stuck, record the failed approach in the task-state failure log and request help.");
|
|
331
301
|
}
|
|
332
302
|
writeSync(1, `${lines.join(`
|
|
333
303
|
`)}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* hook-runner.ts — entrypoint for typed plugin hooks.
|
|
3
3
|
*
|
|
4
|
-
* The hook
|
|
5
|
-
* for every plugin hook that ships a typed
|
|
6
|
-
* command string:
|
|
4
|
+
* The provider-owned session-hook materializer writes a shim command into
|
|
5
|
+
* the active session host for every plugin hook that ships a typed
|
|
6
|
+
* implementation instead of a raw command string:
|
|
7
7
|
*
|
|
8
8
|
* <bun> <this file> --plugin <name> --hook <id> [--event <event>] [--project-root <dir>]
|
|
9
9
|
*
|
package/dist/src/hook-runner.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// packages/core/src/load-config.ts
|
|
3
3
|
import { existsSync as existsSync2, mkdirSync, mkdtempSync, readFileSync as readFileSync2, readdirSync, rmSync, statSync } from "fs";
|
|
4
4
|
import { isBuiltin } from "module";
|
|
5
|
-
import { dirname, isAbsolute, join as join2, relative, resolve } from "path";
|
|
5
|
+
import { basename, dirname, isAbsolute, join as join2, relative, resolve } from "path";
|
|
6
6
|
import { pathToFileURL } from "url";
|
|
7
7
|
import { Schema as Schema3 } from "effect";
|
|
8
8
|
import { RigConfig as RigConfig3 } from "@rig/contracts";
|
|
@@ -69,8 +69,11 @@ function parseDeclarativeFile(path) {
|
|
|
69
69
|
}
|
|
70
70
|
function loadDeclarativeConfig(path) {
|
|
71
71
|
const data = parseDeclarativeFile(path);
|
|
72
|
-
const standardSection = data.standard && typeof data.standard === "object" && !Array.isArray(data.standard) ? data.standard :
|
|
73
|
-
|
|
72
|
+
const standardSection = data.standard && typeof data.standard === "object" && !Array.isArray(data.standard) ? data.standard : null;
|
|
73
|
+
if (standardSection?.enabled !== true && standardSection?.enabled !== false) {
|
|
74
|
+
throw new Error(`Declarative config ${path} must explicitly set [standard] enabled = true or false.`);
|
|
75
|
+
}
|
|
76
|
+
const useStandard = standardSection.enabled === true;
|
|
74
77
|
let plugins = [];
|
|
75
78
|
if (useStandard) {
|
|
76
79
|
const resolver = getStandardPluginsResolver();
|
|
@@ -112,19 +115,27 @@ function packageNameAndSubpath(specifier) {
|
|
|
112
115
|
function exportTargetFromEntry(entry) {
|
|
113
116
|
if (typeof entry === "string")
|
|
114
117
|
return entry;
|
|
115
|
-
if (
|
|
118
|
+
if (Array.isArray(entry)) {
|
|
119
|
+
for (const candidate of entry) {
|
|
120
|
+
const target = exportTargetFromEntry(candidate);
|
|
121
|
+
if (target)
|
|
122
|
+
return target;
|
|
123
|
+
}
|
|
124
|
+
return null;
|
|
125
|
+
}
|
|
126
|
+
if (entry && typeof entry === "object") {
|
|
116
127
|
const conditions = entry;
|
|
117
|
-
for (const key of ["bun", "import", "default", "require"]) {
|
|
118
|
-
|
|
119
|
-
|
|
128
|
+
for (const key of ["bun", "node", "import", "default", "require"]) {
|
|
129
|
+
const target = exportTargetFromEntry(conditions[key]);
|
|
130
|
+
if (target)
|
|
131
|
+
return target;
|
|
120
132
|
}
|
|
121
133
|
}
|
|
122
134
|
return null;
|
|
123
135
|
}
|
|
124
136
|
function patternExportTarget(record, subpath) {
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
continue;
|
|
137
|
+
const entries = Object.entries(record).filter(([pattern]) => pattern.includes("*")).sort(([a], [b]) => b.replace("*", "").length - a.replace("*", "").length);
|
|
138
|
+
for (const [pattern, entry] of entries) {
|
|
128
139
|
const [prefix = "", suffix = ""] = pattern.split("*");
|
|
129
140
|
if (!subpath.startsWith(prefix) || !subpath.endsWith(suffix))
|
|
130
141
|
continue;
|
|
@@ -149,6 +160,49 @@ function exportTargetFromPackageJson(pkg, subpath) {
|
|
|
149
160
|
return target;
|
|
150
161
|
return subpath === "." && typeof pkg.module === "string" ? pkg.module : subpath === "." && typeof pkg.main === "string" ? pkg.main : null;
|
|
151
162
|
}
|
|
163
|
+
function patternImportTarget(record, specifier) {
|
|
164
|
+
for (const [pattern, entry] of Object.entries(record)) {
|
|
165
|
+
if (!pattern.includes("*"))
|
|
166
|
+
continue;
|
|
167
|
+
const [prefix = "", suffix = ""] = pattern.split("*");
|
|
168
|
+
if (!specifier.startsWith(prefix) || !specifier.endsWith(suffix))
|
|
169
|
+
continue;
|
|
170
|
+
const replacement = specifier.slice(prefix.length, specifier.length - suffix.length);
|
|
171
|
+
const target = exportTargetFromEntry(entry);
|
|
172
|
+
if (target)
|
|
173
|
+
return target.replace("*", replacement);
|
|
174
|
+
}
|
|
175
|
+
return null;
|
|
176
|
+
}
|
|
177
|
+
function resolvePackagePrivateImport(specifier, importer, projectRoot) {
|
|
178
|
+
if (!specifier.startsWith("#") || !importer || !isAbsolute(importer))
|
|
179
|
+
return null;
|
|
180
|
+
let dir = dirname(importer);
|
|
181
|
+
const stop = resolve(projectRoot);
|
|
182
|
+
while (isWithinDir(dir, stop)) {
|
|
183
|
+
const packageJsonPath = join2(dir, "package.json");
|
|
184
|
+
if (existsSync2(packageJsonPath)) {
|
|
185
|
+
try {
|
|
186
|
+
const pkg = JSON.parse(readFileSync2(packageJsonPath, "utf8"));
|
|
187
|
+
const imports = pkg.imports;
|
|
188
|
+
if (imports && typeof imports === "object" && !Array.isArray(imports)) {
|
|
189
|
+
const record = imports;
|
|
190
|
+
const target = exportTargetFromEntry(record[specifier]) ?? patternImportTarget(record, specifier);
|
|
191
|
+
if (target)
|
|
192
|
+
return resolveModulePath(join2(dir, target));
|
|
193
|
+
}
|
|
194
|
+
} catch {
|
|
195
|
+
return null;
|
|
196
|
+
}
|
|
197
|
+
return null;
|
|
198
|
+
}
|
|
199
|
+
const parent = dirname(dir);
|
|
200
|
+
if (parent === dir)
|
|
201
|
+
return null;
|
|
202
|
+
dir = parent;
|
|
203
|
+
}
|
|
204
|
+
return null;
|
|
205
|
+
}
|
|
152
206
|
function resolvePackageDirFromBunStore(packageName, nodeModulesDir) {
|
|
153
207
|
const storeDir = join2(nodeModulesDir, ".bun");
|
|
154
208
|
if (!existsSync2(storeDir))
|
|
@@ -223,8 +277,15 @@ function resolvePackageExportFromDir(packageDir, subpath) {
|
|
|
223
277
|
if (existsSync2(packageJsonPath)) {
|
|
224
278
|
try {
|
|
225
279
|
const pkg = JSON.parse(readFileSync2(packageJsonPath, "utf8"));
|
|
226
|
-
const
|
|
227
|
-
|
|
280
|
+
const targets = [
|
|
281
|
+
exportTargetFromPackageJson(pkg, subpath),
|
|
282
|
+
...subpath === "." ? [typeof pkg.module === "string" ? pkg.module : null, typeof pkg.main === "string" ? pkg.main : null] : []
|
|
283
|
+
];
|
|
284
|
+
const seen = new Set;
|
|
285
|
+
for (const target of targets) {
|
|
286
|
+
if (!target || seen.has(target))
|
|
287
|
+
continue;
|
|
288
|
+
seen.add(target);
|
|
228
289
|
const resolved = resolveModulePath(join2(packageDir, target));
|
|
229
290
|
if (resolved)
|
|
230
291
|
return resolved;
|
|
@@ -312,10 +373,17 @@ async function importConfigViaRuntimeBundleUnserialized(configPath) {
|
|
|
312
373
|
}
|
|
313
374
|
const RUNTIME_ONLY_EXTERNAL_PACKAGES = new Set(["effect", "mupdf", "fastembed", "onnxruntime-node", "markit-ai"]);
|
|
314
375
|
const configDir = dirname(configPath);
|
|
376
|
+
const configProjectRoot = basename(configDir) === ".rig" ? dirname(configDir) : configDir;
|
|
315
377
|
const UNRESOLVED_NAMESPACE = "rig-config-unresolved";
|
|
378
|
+
const ABSOLUTE_EXTERNAL_NAMESPACE = "rig-config-absolute-external";
|
|
316
379
|
const unresolvedLocalPlugin = {
|
|
317
380
|
name: "rig-config-unresolved-local",
|
|
318
381
|
setup(build) {
|
|
382
|
+
build.onLoad({ filter: /[\\/]@oh-my-pi[\\/]pi-coding-agent[\\/]src[\\/]export[\\/]html[\\/](?:template\.css|template\.html|template\.js|tool-views\.generated\.js)$/ }, (args) => ({
|
|
383
|
+
loader: "js",
|
|
384
|
+
contents: `export default ${JSON.stringify(readFileSync2(args.path, "utf8"))};
|
|
385
|
+
`
|
|
386
|
+
}));
|
|
319
387
|
build.onLoad({ filter: /\.(?:html|txt)$/ }, (args) => ({
|
|
320
388
|
loader: "js",
|
|
321
389
|
contents: `export default ${JSON.stringify(readFileSync2(args.path, "utf8"))};
|
|
@@ -325,32 +393,77 @@ async function importConfigViaRuntimeBundleUnserialized(configPath) {
|
|
|
325
393
|
const directFilePath = resolvedFilePath(args.path, configDir);
|
|
326
394
|
if (directFilePath)
|
|
327
395
|
return { path: directFilePath };
|
|
396
|
+
if (args.path.startsWith("#")) {
|
|
397
|
+
const packagePrivatePath = resolvePackagePrivateImport(args.path, args.importer, configProjectRoot);
|
|
398
|
+
if (packagePrivatePath)
|
|
399
|
+
return { path: packagePrivatePath };
|
|
400
|
+
try {
|
|
401
|
+
const parent2 = args.importer && isAbsolute(args.importer) ? dirname(args.importer) : configProjectRoot;
|
|
402
|
+
const resolved = bun.resolveSync?.(args.path, parent2);
|
|
403
|
+
const filePath = resolvedFilePath(resolved, configProjectRoot);
|
|
404
|
+
if (filePath)
|
|
405
|
+
return { path: filePath };
|
|
406
|
+
} catch {}
|
|
407
|
+
return;
|
|
408
|
+
}
|
|
328
409
|
const packageImport = packageNameAndSubpath(args.path);
|
|
329
|
-
if (packageImport &&
|
|
330
|
-
|
|
410
|
+
if (packageImport?.packageName === "uhyphen" && packageImport.subpath === ".") {
|
|
411
|
+
const uhyphenPath = resolveProjectPackageImport("uhyphen", configProjectRoot);
|
|
412
|
+
if (uhyphenPath)
|
|
413
|
+
return { path: uhyphenPath };
|
|
331
414
|
}
|
|
332
|
-
|
|
415
|
+
if (packageImport && packageImport.packageName !== "uhyphen") {
|
|
416
|
+
try {
|
|
417
|
+
const parent2 = args.importer && isAbsolute(args.importer) ? dirname(args.importer) : configProjectRoot;
|
|
418
|
+
const resolved = bun.resolveSync?.(args.path, parent2);
|
|
419
|
+
const filePath = resolvedFilePath(resolved, configProjectRoot);
|
|
420
|
+
if (filePath)
|
|
421
|
+
return { path: filePath };
|
|
422
|
+
} catch {}
|
|
423
|
+
}
|
|
424
|
+
const projectPackagePath = packageImport ? resolveProjectPackageImport(args.path, configProjectRoot) : null;
|
|
333
425
|
if (projectPackagePath)
|
|
334
426
|
return { path: projectPackagePath };
|
|
427
|
+
if (packageImport && (packageImport.packageName.startsWith("@rig/") || RUNTIME_ONLY_EXTERNAL_PACKAGES.has(packageImport.packageName))) {
|
|
428
|
+
return { path: args.path, external: true };
|
|
429
|
+
}
|
|
335
430
|
if (/^(?:node|bun):/.test(args.path) || isBuiltin(args.path))
|
|
336
431
|
return;
|
|
337
432
|
if (packageImport)
|
|
338
433
|
return { path: args.path, external: true };
|
|
339
|
-
const
|
|
434
|
+
const importerDir = args.importer && isAbsolute(args.importer) ? dirname(args.importer) : null;
|
|
435
|
+
if (args.path.startsWith(".") && importerDir) {
|
|
436
|
+
const fromImporter = resolveModulePath(resolve(importerDir, args.path));
|
|
437
|
+
if (fromImporter)
|
|
438
|
+
return { path: fromImporter };
|
|
439
|
+
if (/[\\/]node_modules[\\/]/.test(args.importer ?? ""))
|
|
440
|
+
return;
|
|
441
|
+
}
|
|
442
|
+
const parentCandidates = args.path.startsWith(".") ? [importerDir, configDir].filter((value) => Boolean(value)) : [importerDir ?? configDir];
|
|
340
443
|
for (const parent2 of parentCandidates) {
|
|
341
|
-
const filePath = resolvedFilePath(resolve(parent2, args.path),
|
|
444
|
+
const filePath = resolvedFilePath(resolve(parent2, args.path), configProjectRoot);
|
|
342
445
|
if (filePath)
|
|
343
446
|
return { path: filePath };
|
|
344
447
|
}
|
|
345
448
|
const parent = parentCandidates[0] ?? configDir;
|
|
346
449
|
try {
|
|
347
450
|
const resolved = bun.resolveSync?.(args.path, parent) ?? resolve(parent, args.path);
|
|
348
|
-
const filePath = resolvedFilePath(resolved,
|
|
451
|
+
const filePath = resolvedFilePath(resolved, configProjectRoot);
|
|
349
452
|
if (filePath)
|
|
350
453
|
return { path: filePath };
|
|
351
454
|
} catch {}
|
|
352
455
|
return { path: args.path, namespace: UNRESOLVED_NAMESPACE };
|
|
353
456
|
});
|
|
457
|
+
build.onLoad({ filter: /.*/, namespace: ABSOLUTE_EXTERNAL_NAMESPACE }, (args) => {
|
|
458
|
+
const href = pathToFileURL(args.path).href;
|
|
459
|
+
return {
|
|
460
|
+
loader: "js",
|
|
461
|
+
contents: `export * from ${JSON.stringify(href)};
|
|
462
|
+
const mod = await import(${JSON.stringify(href)});
|
|
463
|
+
export default (mod && "default" in mod) ? mod.default : mod;
|
|
464
|
+
`
|
|
465
|
+
};
|
|
466
|
+
});
|
|
354
467
|
build.onLoad({ filter: /.*/, namespace: UNRESOLVED_NAMESPACE }, (args) => ({
|
|
355
468
|
loader: "js",
|
|
356
469
|
contents: `module.exports = {};
|
|
@@ -362,7 +475,6 @@ throw new Error(${JSON.stringify(`Failed to bundle ${configPath}: Could not reso
|
|
|
362
475
|
const result = await bun.build({
|
|
363
476
|
entrypoints: [configPath],
|
|
364
477
|
target: "bun",
|
|
365
|
-
external: ["effect", "mupdf", "fastembed", "onnxruntime-node", "markit-ai"],
|
|
366
478
|
format: "esm",
|
|
367
479
|
throw: false,
|
|
368
480
|
packages: "bundle",
|
|
@@ -373,7 +485,7 @@ throw new Error(${JSON.stringify(`Failed to bundle ${configPath}: Could not reso
|
|
|
373
485
|
`);
|
|
374
486
|
throw new Error(`Failed to bundle ${configPath}: ${detail || "unknown bundler error"}`);
|
|
375
487
|
}
|
|
376
|
-
const bundleParentDir = join2(
|
|
488
|
+
const bundleParentDir = join2(configProjectRoot, ".rig", "tmp");
|
|
377
489
|
mkdirSync(bundleParentDir, { recursive: true });
|
|
378
490
|
const dir = mkdtempSync(join2(bundleParentDir, "rig-config-bundle-"));
|
|
379
491
|
try {
|
package/dist/src/hook-runtime.js
CHANGED
|
@@ -151,26 +151,6 @@ function isTaskConfigEntry(value) {
|
|
|
151
151
|
}
|
|
152
152
|
return true;
|
|
153
153
|
}
|
|
154
|
-
async function readTaskConfigFromDisk(configPath) {
|
|
155
|
-
if (!existsSync(configPath)) {
|
|
156
|
-
return null;
|
|
157
|
-
}
|
|
158
|
-
try {
|
|
159
|
-
const bunFile = bunRuntime()?.file;
|
|
160
|
-
const content = bunFile ? await bunFile(configPath).json() : JSON.parse(readFileSync(configPath, "utf-8"));
|
|
161
|
-
return isPlainObject(content) ? content : null;
|
|
162
|
-
} catch {
|
|
163
|
-
return null;
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
function taskConfigCandidates(ctx) {
|
|
167
|
-
const taskWorkspace = process.env.RIG_TASK_WORKSPACE?.trim();
|
|
168
|
-
return [
|
|
169
|
-
ctx?.monorepoMainRoot ? resolve(ctx.monorepoMainRoot, ".rig", "task-config.json") : "",
|
|
170
|
-
process.env.MONOREPO_MAIN_ROOT?.trim() ? resolve(process.env.MONOREPO_MAIN_ROOT.trim(), ".rig", "task-config.json") : "",
|
|
171
|
-
taskWorkspace ? resolve(taskWorkspace, ".rig", "task-config.json") : ""
|
|
172
|
-
].filter(Boolean);
|
|
173
|
-
}
|
|
174
154
|
async function resolveTaskConfig(_projectRoot, _taskId) {
|
|
175
155
|
const ctx = getContext();
|
|
176
156
|
if (ctx) {
|
|
@@ -188,16 +168,6 @@ async function resolveTaskConfig(_projectRoot, _taskId) {
|
|
|
188
168
|
}
|
|
189
169
|
} catch {}
|
|
190
170
|
}
|
|
191
|
-
for (const configPath of taskConfigCandidates(ctx)) {
|
|
192
|
-
const config = await readTaskConfigFromDisk(configPath);
|
|
193
|
-
if (!config) {
|
|
194
|
-
continue;
|
|
195
|
-
}
|
|
196
|
-
const taskEntry = config[_taskId];
|
|
197
|
-
if (isTaskConfigEntry(taskEntry)) {
|
|
198
|
-
return taskEntry;
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
171
|
return {};
|
|
202
172
|
}
|
|
203
173
|
async function resolveTaskScopes(projectRoot, taskId) {
|
|
@@ -327,7 +297,7 @@ function block(hookName, message, projectRoot) {
|
|
|
327
297
|
lines.push("");
|
|
328
298
|
lines.push(`REPEATED VIOLATION (${count}x ${hookName}).`);
|
|
329
299
|
lines.push("STOP. Read the FULL CLAUDE.md from top to bottom.");
|
|
330
|
-
lines.push("If stuck,
|
|
300
|
+
lines.push("If stuck, record the failed approach in the task-state failure log and request help.");
|
|
331
301
|
}
|
|
332
302
|
writeSync(1, `${lines.join(`
|
|
333
303
|
`)}
|