@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.
@@ -37,7 +37,7 @@ function applyConfigEnv(config, env = process.env) {
37
37
  // packages/core/src/load-config.ts
38
38
  import { existsSync as existsSync2, mkdirSync, mkdtempSync, readFileSync as readFileSync2, readdirSync, rmSync, statSync } from "fs";
39
39
  import { isBuiltin } from "module";
40
- import { dirname, isAbsolute, join as join2, relative, resolve } from "path";
40
+ import { basename, dirname, isAbsolute, join as join2, relative, resolve } from "path";
41
41
  import { pathToFileURL } from "url";
42
42
  import { Schema as Schema3 } from "effect";
43
43
  import { RigConfig as RigConfig3 } from "@rig/contracts";
@@ -104,8 +104,11 @@ function parseDeclarativeFile(path) {
104
104
  }
105
105
  function loadDeclarativeConfig(path) {
106
106
  const data = parseDeclarativeFile(path);
107
- const standardSection = data.standard && typeof data.standard === "object" && !Array.isArray(data.standard) ? data.standard : {};
108
- const useStandard = standardSection.enabled !== false;
107
+ const standardSection = data.standard && typeof data.standard === "object" && !Array.isArray(data.standard) ? data.standard : null;
108
+ if (standardSection?.enabled !== true && standardSection?.enabled !== false) {
109
+ throw new Error(`Declarative config ${path} must explicitly set [standard] enabled = true or false.`);
110
+ }
111
+ const useStandard = standardSection.enabled === true;
109
112
  let plugins = [];
110
113
  if (useStandard) {
111
114
  const resolver = getStandardPluginsResolver();
@@ -147,19 +150,27 @@ function packageNameAndSubpath(specifier) {
147
150
  function exportTargetFromEntry(entry) {
148
151
  if (typeof entry === "string")
149
152
  return entry;
150
- if (entry && typeof entry === "object" && !Array.isArray(entry)) {
153
+ if (Array.isArray(entry)) {
154
+ for (const candidate of entry) {
155
+ const target = exportTargetFromEntry(candidate);
156
+ if (target)
157
+ return target;
158
+ }
159
+ return null;
160
+ }
161
+ if (entry && typeof entry === "object") {
151
162
  const conditions = entry;
152
- for (const key of ["bun", "import", "default", "require"]) {
153
- if (typeof conditions[key] === "string")
154
- return conditions[key];
163
+ for (const key of ["bun", "node", "import", "default", "require"]) {
164
+ const target = exportTargetFromEntry(conditions[key]);
165
+ if (target)
166
+ return target;
155
167
  }
156
168
  }
157
169
  return null;
158
170
  }
159
171
  function patternExportTarget(record, subpath) {
160
- for (const [pattern, entry] of Object.entries(record)) {
161
- if (!pattern.includes("*"))
162
- continue;
172
+ const entries = Object.entries(record).filter(([pattern]) => pattern.includes("*")).sort(([a], [b]) => b.replace("*", "").length - a.replace("*", "").length);
173
+ for (const [pattern, entry] of entries) {
163
174
  const [prefix = "", suffix = ""] = pattern.split("*");
164
175
  if (!subpath.startsWith(prefix) || !subpath.endsWith(suffix))
165
176
  continue;
@@ -184,6 +195,49 @@ function exportTargetFromPackageJson(pkg, subpath) {
184
195
  return target;
185
196
  return subpath === "." && typeof pkg.module === "string" ? pkg.module : subpath === "." && typeof pkg.main === "string" ? pkg.main : null;
186
197
  }
198
+ function patternImportTarget(record, specifier) {
199
+ for (const [pattern, entry] of Object.entries(record)) {
200
+ if (!pattern.includes("*"))
201
+ continue;
202
+ const [prefix = "", suffix = ""] = pattern.split("*");
203
+ if (!specifier.startsWith(prefix) || !specifier.endsWith(suffix))
204
+ continue;
205
+ const replacement = specifier.slice(prefix.length, specifier.length - suffix.length);
206
+ const target = exportTargetFromEntry(entry);
207
+ if (target)
208
+ return target.replace("*", replacement);
209
+ }
210
+ return null;
211
+ }
212
+ function resolvePackagePrivateImport(specifier, importer, projectRoot) {
213
+ if (!specifier.startsWith("#") || !importer || !isAbsolute(importer))
214
+ return null;
215
+ let dir = dirname(importer);
216
+ const stop = resolve(projectRoot);
217
+ while (isWithinDir(dir, stop)) {
218
+ const packageJsonPath = join2(dir, "package.json");
219
+ if (existsSync2(packageJsonPath)) {
220
+ try {
221
+ const pkg = JSON.parse(readFileSync2(packageJsonPath, "utf8"));
222
+ const imports = pkg.imports;
223
+ if (imports && typeof imports === "object" && !Array.isArray(imports)) {
224
+ const record = imports;
225
+ const target = exportTargetFromEntry(record[specifier]) ?? patternImportTarget(record, specifier);
226
+ if (target)
227
+ return resolveModulePath(join2(dir, target));
228
+ }
229
+ } catch {
230
+ return null;
231
+ }
232
+ return null;
233
+ }
234
+ const parent = dirname(dir);
235
+ if (parent === dir)
236
+ return null;
237
+ dir = parent;
238
+ }
239
+ return null;
240
+ }
187
241
  function resolvePackageDirFromBunStore(packageName, nodeModulesDir) {
188
242
  const storeDir = join2(nodeModulesDir, ".bun");
189
243
  if (!existsSync2(storeDir))
@@ -258,8 +312,15 @@ function resolvePackageExportFromDir(packageDir, subpath) {
258
312
  if (existsSync2(packageJsonPath)) {
259
313
  try {
260
314
  const pkg = JSON.parse(readFileSync2(packageJsonPath, "utf8"));
261
- const target = exportTargetFromPackageJson(pkg, subpath);
262
- if (target) {
315
+ const targets = [
316
+ exportTargetFromPackageJson(pkg, subpath),
317
+ ...subpath === "." ? [typeof pkg.module === "string" ? pkg.module : null, typeof pkg.main === "string" ? pkg.main : null] : []
318
+ ];
319
+ const seen = new Set;
320
+ for (const target of targets) {
321
+ if (!target || seen.has(target))
322
+ continue;
323
+ seen.add(target);
263
324
  const resolved = resolveModulePath(join2(packageDir, target));
264
325
  if (resolved)
265
326
  return resolved;
@@ -347,10 +408,17 @@ async function importConfigViaRuntimeBundleUnserialized(configPath) {
347
408
  }
348
409
  const RUNTIME_ONLY_EXTERNAL_PACKAGES = new Set(["effect", "mupdf", "fastembed", "onnxruntime-node", "markit-ai"]);
349
410
  const configDir = dirname(configPath);
411
+ const configProjectRoot = basename(configDir) === ".rig" ? dirname(configDir) : configDir;
350
412
  const UNRESOLVED_NAMESPACE = "rig-config-unresolved";
413
+ const ABSOLUTE_EXTERNAL_NAMESPACE = "rig-config-absolute-external";
351
414
  const unresolvedLocalPlugin = {
352
415
  name: "rig-config-unresolved-local",
353
416
  setup(build) {
417
+ build.onLoad({ filter: /[\\/]@oh-my-pi[\\/]pi-coding-agent[\\/]src[\\/]export[\\/]html[\\/](?:template\.css|template\.html|template\.js|tool-views\.generated\.js)$/ }, (args) => ({
418
+ loader: "js",
419
+ contents: `export default ${JSON.stringify(readFileSync2(args.path, "utf8"))};
420
+ `
421
+ }));
354
422
  build.onLoad({ filter: /\.(?:html|txt)$/ }, (args) => ({
355
423
  loader: "js",
356
424
  contents: `export default ${JSON.stringify(readFileSync2(args.path, "utf8"))};
@@ -360,32 +428,77 @@ async function importConfigViaRuntimeBundleUnserialized(configPath) {
360
428
  const directFilePath = resolvedFilePath(args.path, configDir);
361
429
  if (directFilePath)
362
430
  return { path: directFilePath };
431
+ if (args.path.startsWith("#")) {
432
+ const packagePrivatePath = resolvePackagePrivateImport(args.path, args.importer, configProjectRoot);
433
+ if (packagePrivatePath)
434
+ return { path: packagePrivatePath };
435
+ try {
436
+ const parent2 = args.importer && isAbsolute(args.importer) ? dirname(args.importer) : configProjectRoot;
437
+ const resolved = bun.resolveSync?.(args.path, parent2);
438
+ const filePath = resolvedFilePath(resolved, configProjectRoot);
439
+ if (filePath)
440
+ return { path: filePath };
441
+ } catch {}
442
+ return;
443
+ }
363
444
  const packageImport = packageNameAndSubpath(args.path);
364
- if (packageImport && (packageImport.packageName.startsWith("@rig/") || RUNTIME_ONLY_EXTERNAL_PACKAGES.has(packageImport.packageName))) {
365
- return { path: args.path, external: true };
445
+ if (packageImport?.packageName === "uhyphen" && packageImport.subpath === ".") {
446
+ const uhyphenPath = resolveProjectPackageImport("uhyphen", configProjectRoot);
447
+ if (uhyphenPath)
448
+ return { path: uhyphenPath };
366
449
  }
367
- const projectPackagePath = resolveProjectPackageImport(args.path, configDir);
450
+ if (packageImport && packageImport.packageName !== "uhyphen") {
451
+ try {
452
+ const parent2 = args.importer && isAbsolute(args.importer) ? dirname(args.importer) : configProjectRoot;
453
+ const resolved = bun.resolveSync?.(args.path, parent2);
454
+ const filePath = resolvedFilePath(resolved, configProjectRoot);
455
+ if (filePath)
456
+ return { path: filePath };
457
+ } catch {}
458
+ }
459
+ const projectPackagePath = packageImport ? resolveProjectPackageImport(args.path, configProjectRoot) : null;
368
460
  if (projectPackagePath)
369
461
  return { path: projectPackagePath };
462
+ if (packageImport && (packageImport.packageName.startsWith("@rig/") || RUNTIME_ONLY_EXTERNAL_PACKAGES.has(packageImport.packageName))) {
463
+ return { path: args.path, external: true };
464
+ }
370
465
  if (/^(?:node|bun):/.test(args.path) || isBuiltin(args.path))
371
466
  return;
372
467
  if (packageImport)
373
468
  return { path: args.path, external: true };
374
- const parentCandidates = args.path.startsWith(".") ? [args.importer && isAbsolute(args.importer) ? dirname(args.importer) : null, configDir].filter((value) => Boolean(value)) : [args.importer && isAbsolute(args.importer) ? dirname(args.importer) : configDir];
469
+ const importerDir = args.importer && isAbsolute(args.importer) ? dirname(args.importer) : null;
470
+ if (args.path.startsWith(".") && importerDir) {
471
+ const fromImporter = resolveModulePath(resolve(importerDir, args.path));
472
+ if (fromImporter)
473
+ return { path: fromImporter };
474
+ if (/[\\/]node_modules[\\/]/.test(args.importer ?? ""))
475
+ return;
476
+ }
477
+ const parentCandidates = args.path.startsWith(".") ? [importerDir, configDir].filter((value) => Boolean(value)) : [importerDir ?? configDir];
375
478
  for (const parent2 of parentCandidates) {
376
- const filePath = resolvedFilePath(resolve(parent2, args.path), configDir);
479
+ const filePath = resolvedFilePath(resolve(parent2, args.path), configProjectRoot);
377
480
  if (filePath)
378
481
  return { path: filePath };
379
482
  }
380
483
  const parent = parentCandidates[0] ?? configDir;
381
484
  try {
382
485
  const resolved = bun.resolveSync?.(args.path, parent) ?? resolve(parent, args.path);
383
- const filePath = resolvedFilePath(resolved, configDir);
486
+ const filePath = resolvedFilePath(resolved, configProjectRoot);
384
487
  if (filePath)
385
488
  return { path: filePath };
386
489
  } catch {}
387
490
  return { path: args.path, namespace: UNRESOLVED_NAMESPACE };
388
491
  });
492
+ build.onLoad({ filter: /.*/, namespace: ABSOLUTE_EXTERNAL_NAMESPACE }, (args) => {
493
+ const href = pathToFileURL(args.path).href;
494
+ return {
495
+ loader: "js",
496
+ contents: `export * from ${JSON.stringify(href)};
497
+ const mod = await import(${JSON.stringify(href)});
498
+ export default (mod && "default" in mod) ? mod.default : mod;
499
+ `
500
+ };
501
+ });
389
502
  build.onLoad({ filter: /.*/, namespace: UNRESOLVED_NAMESPACE }, (args) => ({
390
503
  loader: "js",
391
504
  contents: `module.exports = {};
@@ -397,7 +510,6 @@ throw new Error(${JSON.stringify(`Failed to bundle ${configPath}: Could not reso
397
510
  const result = await bun.build({
398
511
  entrypoints: [configPath],
399
512
  target: "bun",
400
- external: ["effect", "mupdf", "fastembed", "onnxruntime-node", "markit-ai"],
401
513
  format: "esm",
402
514
  throw: false,
403
515
  packages: "bundle",
@@ -408,7 +520,7 @@ throw new Error(${JSON.stringify(`Failed to bundle ${configPath}: Could not reso
408
520
  `);
409
521
  throw new Error(`Failed to bundle ${configPath}: ${detail || "unknown bundler error"}`);
410
522
  }
411
- const bundleParentDir = join2(configDir, ".rig", "tmp");
523
+ const bundleParentDir = join2(configProjectRoot, ".rig", "tmp");
412
524
  mkdirSync(bundleParentDir, { recursive: true });
413
525
  const dir = mkdtempSync(join2(bundleParentDir, "rig-config-bundle-"));
414
526
  try {
@@ -1,9 +1,9 @@
1
- import { RIG_ARTIFACTS_DIRNAME, RIG_DEFINITION_DIRNAME, RIG_STATE_DIRNAME, type RigLayout, type RuntimeWorkspaceLayout } from "@rig/contracts";
1
+ import { RIG_DEFINITION_DIRNAME, RIG_STATE_DIRNAME, type RigLayout, type RuntimeWorkspaceLayout } from "@rig/contracts";
2
2
  import { resolveCheckoutRoot } from "./checkout-root";
3
3
  declare const resolveMonorepoRoot: typeof resolveCheckoutRoot;
4
4
  export { resolveMonorepoRoot };
5
5
  export type { RigLayout, RuntimeWorkspaceLayout };
6
- export { RIG_ARTIFACTS_DIRNAME, RIG_DEFINITION_DIRNAME, RIG_STATE_DIRNAME };
6
+ export { RIG_DEFINITION_DIRNAME, RIG_STATE_DIRNAME };
7
7
  export declare function resolveNearestRigProjectRoot(startDir: string): string;
8
8
  export declare function resolveRigDataRoot(projectRoot: string): string;
9
9
  export declare function resolveRuntimeWorkspaceLayout(workspaceDir: string): RuntimeWorkspaceLayout;
@@ -3,7 +3,6 @@
3
3
  import { existsSync as existsSync2 } from "fs";
4
4
  import { resolve as resolve2 } from "path";
5
5
  import {
6
- RIG_ARTIFACTS_DIRNAME,
7
6
  RIG_DEFINITION_DIRNAME,
8
7
  RIG_STATE_DIRNAME
9
8
  } from "@rig/contracts";
@@ -44,14 +43,13 @@ function resolveNearestRigProjectRoot(startDir) {
44
43
  for (;; ) {
45
44
  const hasDefinition = existsSync2(resolve2(current, RIG_DEFINITION_DIRNAME));
46
45
  const hasState = existsSync2(resolve2(current, RIG_STATE_DIRNAME));
47
- const hasTaskConfig = existsSync2(resolve2(current, RIG_STATE_DIRNAME, "task-config.json"));
48
46
  const hasConfig = existsSync2(resolve2(current, ".rig", "rig.config.ts")) || existsSync2(resolve2(current, ".rig", "rig.config.json"));
49
47
  const hasGit = existsSync2(resolve2(current, ".git"));
50
48
  const hasControlPlane = existsSync2(resolve2(current, "packages", "cli", "bin", "rig.ts")) || existsSync2(resolve2(current, "packages", "server"));
51
49
  if ((hasDefinition || hasState || hasConfig) && weakMarkerCandidate === null) {
52
50
  weakMarkerCandidate = current;
53
51
  }
54
- if ((hasControlPlane || hasConfig || hasTaskConfig) && projectCandidate === null) {
52
+ if ((hasControlPlane || hasConfig) && projectCandidate === null) {
55
53
  projectCandidate = current;
56
54
  }
57
55
  if (hasGit) {
@@ -79,7 +77,6 @@ function resolveRuntimeWorkspaceLayout(workspaceDir) {
79
77
  rigRoot,
80
78
  stateDir,
81
79
  logsDir,
82
- artifactsRoot: resolve2(root, RIG_ARTIFACTS_DIRNAME),
83
80
  runtimeDir,
84
81
  homeDir: resolve2(rigRoot, "home"),
85
82
  tmpDir: resolve2(rigRoot, "tmp"),
@@ -111,9 +108,7 @@ function resolveRigLayout(projectRoot) {
111
108
  definitionRoot,
112
109
  runtimeWorkspaceRoot,
113
110
  stateRoot: runtimeLayout.rigRoot,
114
- artifactsRoot: runtimeLayout.artifactsRoot,
115
111
  configPath: resolve2(definitionRoot, "config.sh"),
116
- taskConfigPath: resolve2(runtimeWorkspaceRoot, ".rig", "task-config.json"),
117
112
  policyDir,
118
113
  policyFile: resolve2(policyDir, "policy.json"),
119
114
  pluginsDir: resolve2(definitionRoot, "plugins"),
@@ -139,6 +134,5 @@ export {
139
134
  resolveNearestRigProjectRoot,
140
135
  resolveMonorepoRoot,
141
136
  RIG_STATE_DIRNAME,
142
- RIG_DEFINITION_DIRNAME,
143
- RIG_ARTIFACTS_DIRNAME
137
+ RIG_DEFINITION_DIRNAME
144
138
  };
@@ -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
- const useStandard = standardSection.enabled !== false;
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 (entry && typeof entry === "object" && !Array.isArray(entry)) {
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
- if (typeof conditions[key] === "string")
119
- return conditions[key];
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
- for (const [pattern, entry] of Object.entries(record)) {
126
- if (!pattern.includes("*"))
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 target = exportTargetFromPackageJson(pkg, subpath);
227
- if (target) {
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 && (packageImport.packageName.startsWith("@rig/") || RUNTIME_ONLY_EXTERNAL_PACKAGES.has(packageImport.packageName))) {
330
- return { path: args.path, external: true };
410
+ if (packageImport?.packageName === "uhyphen" && packageImport.subpath === ".") {
411
+ const uhyphenPath = resolveProjectPackageImport("uhyphen", configProjectRoot);
412
+ if (uhyphenPath)
413
+ return { path: uhyphenPath };
331
414
  }
332
- const projectPackagePath = resolveProjectPackageImport(args.path, configDir);
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 parentCandidates = args.path.startsWith(".") ? [args.importer && isAbsolute(args.importer) ? dirname(args.importer) : null, configDir].filter((value) => Boolean(value)) : [args.importer && isAbsolute(args.importer) ? dirname(args.importer) : configDir];
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), configDir);
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, configDir);
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(configDir, ".rig", "tmp");
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 {
@@ -1,3 +1,11 @@
1
+ /**
2
+ * Deprecated compatibility subpath. Placement behavior is owned by
3
+ * @rig/transport-plugin and exposed through PLACEMENT_SERVICE.
4
+ *
5
+ * Core intentionally does not implement read/list/select/add/remove placement
6
+ * state; callers should resolve the typed capability from their project plugin
7
+ * host. These stubs remain only to make accidental direct imports fail loudly.
8
+ */
1
9
  export type PlacementKind = "local" | "remote";
2
10
  export type Placement = {
3
11
  readonly alias: string;
@@ -24,24 +32,24 @@ export type AddPlacementInput = {
24
32
  readonly token?: string | null;
25
33
  readonly select?: boolean;
26
34
  };
27
- export declare function resolveRepoConnectionPath(projectRoot: string): string;
28
- export declare function readSelection(projectRoot: string): RepoConnectionState | null;
35
+ export declare function resolveRepoConnectionPath(_projectRoot: string): string;
36
+ export declare function readSelection(_projectRoot: string): RepoConnectionState | null;
29
37
  export declare const readRepoConnection: typeof readSelection;
30
- export declare function writeSelection(projectRoot: string, state: RepoConnectionState): void;
38
+ export declare function writeSelection(_projectRoot: string, _state: RepoConnectionState): void;
31
39
  export declare const writeRepoConnection: typeof writeSelection;
32
- export declare function readPlacement(projectRoot: string, env?: NodeJS.ProcessEnv): Promise<Placement>;
40
+ export declare function readPlacement(_projectRoot: string, _env?: NodeJS.ProcessEnv): Promise<Placement>;
33
41
  export declare const readSelectedTarget: typeof readPlacement;
34
- export declare function listPlacements(projectRoot: string): Placement[];
42
+ export declare function listPlacements(_projectRoot: string): Placement[];
35
43
  export declare const listServerTargets: typeof listPlacements;
36
- export declare function selectPlacement(projectRoot: string, alias: string, options?: {
44
+ export declare function selectPlacement(_projectRoot: string, _alias: string, _options?: {
37
45
  dryRun?: boolean;
38
46
  }): Placement;
39
47
  export declare const selectServerTarget: typeof selectPlacement;
40
- export declare function addPlacement(projectRoot: string, input: AddPlacementInput, options?: {
48
+ export declare function addPlacement(_projectRoot: string, _input: AddPlacementInput, _options?: {
41
49
  dryRun?: boolean;
42
50
  }): Placement;
43
51
  export declare const addRemoteTarget: typeof addPlacement;
44
- export declare function removePlacement(projectRoot: string, alias: string, options?: {
52
+ export declare function removePlacement(_projectRoot: string, _alias: string, _options?: {
45
53
  dryRun?: boolean;
46
54
  }): {
47
55
  readonly alias: string;