@h-rig/runtime 0.0.6-alpha.34 → 0.0.6-alpha.35

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.
@@ -1,5 +1,7 @@
1
1
  // @bun
2
2
  // packages/runtime/src/control-plane/plugin-host-context.ts
3
+ import { existsSync as existsSync5 } from "fs";
4
+ import { resolve as resolvePath } from "path";
3
5
  import { createPluginHost } from "@rig/core";
4
6
  import { loadConfig } from "@rig/core/load-config";
5
7
 
@@ -326,6 +328,55 @@ async function materializeSkills(projectRoot, entries) {
326
328
  return written;
327
329
  }
328
330
 
331
+ // packages/runtime/src/control-plane/pi-settings-materializer.ts
332
+ import { existsSync as existsSync4, mkdirSync as mkdirSync3, readFileSync as readFileSync3, writeFileSync as writeFileSync3 } from "fs";
333
+ import { dirname as dirname2, resolve as resolve3 } from "path";
334
+ var SETTINGS_RELATIVE_PATH = ".pi/settings.json";
335
+ var MANAGED_RECORD_RELATIVE_PATH = ".rig/state/pi-managed-packages.json";
336
+ function readJson(path, fallback) {
337
+ if (!existsSync4(path))
338
+ return fallback;
339
+ try {
340
+ return JSON.parse(readFileSync3(path, "utf-8"));
341
+ } catch {
342
+ return fallback;
343
+ }
344
+ }
345
+ function packageKey(entry) {
346
+ if (typeof entry === "string")
347
+ return entry;
348
+ if (entry && typeof entry === "object" && typeof entry.source === "string") {
349
+ return entry.source;
350
+ }
351
+ return JSON.stringify(entry);
352
+ }
353
+ function materializePiPackages(projectRoot, declaredPackages) {
354
+ const settingsPath = resolve3(projectRoot, SETTINGS_RELATIVE_PATH);
355
+ const managedRecordPath = resolve3(projectRoot, MANAGED_RECORD_RELATIVE_PATH);
356
+ const settings = readJson(settingsPath, {});
357
+ const previouslyManaged = new Set(readJson(managedRecordPath, []));
358
+ const existing = Array.isArray(settings.packages) ? settings.packages : [];
359
+ const operatorEntries = existing.filter((entry) => !previouslyManaged.has(packageKey(entry)));
360
+ const operatorKeys = new Set(operatorEntries.map(packageKey));
361
+ const managedToAdd = declaredPackages.filter((pkg) => !operatorKeys.has(pkg));
362
+ const nextPackages = [...operatorEntries, ...managedToAdd];
363
+ if (nextPackages.length > 0 || existsSync4(settingsPath)) {
364
+ const nextSettings = { ...settings };
365
+ if (nextPackages.length > 0) {
366
+ nextSettings.packages = nextPackages;
367
+ } else {
368
+ delete nextSettings.packages;
369
+ }
370
+ mkdirSync3(dirname2(settingsPath), { recursive: true });
371
+ writeFileSync3(settingsPath, `${JSON.stringify(nextSettings, null, 2)}
372
+ `, "utf-8");
373
+ }
374
+ mkdirSync3(dirname2(managedRecordPath), { recursive: true });
375
+ writeFileSync3(managedRecordPath, `${JSON.stringify(managedToAdd, null, 2)}
376
+ `, "utf-8");
377
+ return { settingsPath, packages: managedToAdd };
378
+ }
379
+
329
380
  // packages/runtime/src/control-plane/plugin-host-context.ts
330
381
  async function buildPluginHostContext(projectRoot) {
331
382
  let config;
@@ -373,6 +424,14 @@ async function buildPluginHostContext(projectRoot) {
373
424
  } catch (err) {
374
425
  console.warn(`[plugin-host] skill materialization failed: ${err instanceof Error ? err.message : err}`);
375
426
  }
427
+ try {
428
+ const piPackages = config.runtime?.pi?.packages ?? [];
429
+ if (piPackages.length > 0 || existsSync5(resolvePath(projectRoot, ".rig/state/pi-managed-packages.json"))) {
430
+ materializePiPackages(projectRoot, piPackages);
431
+ }
432
+ } catch (err) {
433
+ console.warn(`[plugin-host] Pi package materialization failed: ${err instanceof Error ? err.message : err}`);
434
+ }
376
435
  return {
377
436
  config,
378
437
  pluginHost,
@@ -386,12 +445,12 @@ async function buildPluginHostContext(projectRoot) {
386
445
 
387
446
  // packages/runtime/src/control-plane/tasks/source-aware-task-config-source.ts
388
447
  import { spawnSync } from "child_process";
389
- import { existsSync as existsSync5, readFileSync as readFileSync4, readdirSync as readdirSync2, statSync, writeFileSync as writeFileSync3 } from "fs";
390
- import { basename, join as join2, resolve as resolve4 } from "path";
448
+ import { existsSync as existsSync7, readFileSync as readFileSync5, readdirSync as readdirSync2, statSync, writeFileSync as writeFileSync4 } from "fs";
449
+ import { basename, join as join2, resolve as resolve5 } from "path";
391
450
 
392
451
  // packages/runtime/src/control-plane/tasks/legacy-task-config-source.ts
393
- import { existsSync as existsSync4, readFileSync as readFileSync3 } from "fs";
394
- import { resolve as resolve3 } from "path";
452
+ import { existsSync as existsSync6, readFileSync as readFileSync4 } from "fs";
453
+ import { resolve as resolve4 } from "path";
395
454
 
396
455
  // packages/runtime/src/control-plane/tasks/task-record-reader.ts
397
456
  async function findTaskById(reader, id) {
@@ -414,7 +473,7 @@ class LegacyTaskConfigReadError extends Error {
414
473
  }
415
474
  }
416
475
  function createLegacyTaskConfigRecordReader(projectRoot, options = {}) {
417
- const configPath = options.configPath ?? resolve3(projectRoot, ".rig", "task-config.json");
476
+ const configPath = options.configPath ?? resolve4(projectRoot, ".rig", "task-config.json");
418
477
  const reader = {
419
478
  async listTasks() {
420
479
  return readLegacyTaskRecords(projectRoot, configPath);
@@ -425,8 +484,8 @@ function createLegacyTaskConfigRecordReader(projectRoot, options = {}) {
425
484
  };
426
485
  return reader;
427
486
  }
428
- function readLegacyTaskRecords(projectRoot, configPath = resolve3(projectRoot, ".rig", "task-config.json")) {
429
- if (!existsSync4(configPath)) {
487
+ function readLegacyTaskRecords(projectRoot, configPath = resolve4(projectRoot, ".rig", "task-config.json")) {
488
+ if (!existsSync6(configPath)) {
430
489
  return [];
431
490
  }
432
491
  const rawConfig = readLegacyTaskConfigJson(projectRoot, configPath);
@@ -434,7 +493,7 @@ function readLegacyTaskRecords(projectRoot, configPath = resolve3(projectRoot, "
434
493
  }
435
494
  function readLegacyTaskConfigJson(projectRoot, configPath) {
436
495
  try {
437
- const parsed = JSON.parse(readFileSync3(configPath, "utf8"));
496
+ const parsed = JSON.parse(readFileSync4(configPath, "utf8"));
438
497
  if (isPlainRecord(parsed)) {
439
498
  return parsed;
440
499
  }
@@ -518,7 +577,7 @@ function isPlainRecord(candidate) {
518
577
  var STATUS_LABELS = new Set(["ready", "blocked", "in-progress", "under-review", "failed", "cancelled"]);
519
578
  var FILE_TASK_PATTERN = /\.(task\.)?json$/;
520
579
  function createSourceAwareTaskConfigRecordReader(projectRoot, options = {}) {
521
- const configPath = options.configPath ?? resolve4(projectRoot, ".rig", "task-config.json");
580
+ const configPath = options.configPath ?? resolve5(projectRoot, ".rig", "task-config.json");
522
581
  const legacy = createLegacyTaskConfigRecordReader(projectRoot, { configPath });
523
582
  const spawnFn = options.spawn ?? spawnSync;
524
583
  const ghBinary = options.ghBinary ?? "gh";
@@ -584,7 +643,7 @@ async function readSourceAwareTaskStatus(projectRoot, taskId, options = {}) {
584
643
  }
585
644
  }
586
645
  function updateSourceAwareTaskConfigTask(projectRoot, taskId, update, options = {}) {
587
- const configPath = options.configPath ?? resolve4(projectRoot, ".rig", "task-config.json");
646
+ const configPath = options.configPath ?? resolve5(projectRoot, ".rig", "task-config.json");
588
647
  const rawEntry = readRawTaskEntry(configPath, taskId);
589
648
  if (!rawEntry) {
590
649
  const configuredFilesPath = readConfiguredFilesTaskSourcePath(projectRoot);
@@ -637,10 +696,10 @@ function readMaterializedTaskMetadata(entry) {
637
696
  return metadata;
638
697
  }
639
698
  function readConfiguredFilesTaskSourcePath(projectRoot) {
640
- const jsonPath = resolve4(projectRoot, "rig.config.json");
641
- if (existsSync5(jsonPath)) {
699
+ const jsonPath = resolve5(projectRoot, "rig.config.json");
700
+ if (existsSync7(jsonPath)) {
642
701
  try {
643
- const parsed = JSON.parse(readFileSync4(jsonPath, "utf8"));
702
+ const parsed = JSON.parse(readFileSync5(jsonPath, "utf8"));
644
703
  if (isPlainRecord2(parsed) && isPlainRecord2(parsed.taskSource)) {
645
704
  const source = parsed.taskSource;
646
705
  return source.kind === "files" && typeof source.path === "string" ? source.path : null;
@@ -649,12 +708,12 @@ function readConfiguredFilesTaskSourcePath(projectRoot) {
649
708
  return null;
650
709
  }
651
710
  }
652
- const tsPath = resolve4(projectRoot, "rig.config.ts");
653
- if (!existsSync5(tsPath)) {
711
+ const tsPath = resolve5(projectRoot, "rig.config.ts");
712
+ if (!existsSync7(tsPath)) {
654
713
  return null;
655
714
  }
656
715
  try {
657
- const source = readFileSync4(tsPath, "utf8");
716
+ const source = readFileSync5(tsPath, "utf8");
658
717
  const taskSourceBlock = source.match(/taskSource\s*:\s*\{[\s\S]*?\}/m)?.[0] ?? "";
659
718
  const kind = taskSourceBlock.match(/kind\s*:\s*["']([^"']+)["']/)?.[1];
660
719
  if (kind !== "files") {
@@ -674,10 +733,10 @@ function readRawTaskEntry(configPath, taskId) {
674
733
  return isPlainRecord2(entry) ? entry : null;
675
734
  }
676
735
  function readRawTaskConfig(configPath) {
677
- if (!existsSync5(configPath)) {
736
+ if (!existsSync7(configPath)) {
678
737
  return null;
679
738
  }
680
- const parsed = JSON.parse(readFileSync4(configPath, "utf8"));
739
+ const parsed = JSON.parse(readFileSync5(configPath, "utf8"));
681
740
  return isPlainRecord2(parsed) ? parsed : null;
682
741
  }
683
742
  function stripLegacyTaskConfigMetadata2(raw) {
@@ -694,16 +753,16 @@ function writeLegacyTaskStatus(configPath, taskId, status) {
694
753
  return;
695
754
  }
696
755
  entry.status = status;
697
- writeFileSync3(configPath, `${JSON.stringify(rawConfig, null, 2)}
756
+ writeFileSync4(configPath, `${JSON.stringify(rawConfig, null, 2)}
698
757
  `, "utf8");
699
758
  }
700
759
  function updateFileBackedTask(projectRoot, sourcePath, taskId, update) {
701
- const directory = resolve4(projectRoot, sourcePath);
760
+ const directory = resolve5(projectRoot, sourcePath);
702
761
  const file = findFileBackedTaskFile(directory, taskId);
703
762
  if (!file) {
704
763
  return false;
705
764
  }
706
- const raw = JSON.parse(readFileSync4(file, "utf8"));
765
+ const raw = JSON.parse(readFileSync5(file, "utf8"));
707
766
  if (!isPlainRecord2(raw)) {
708
767
  return false;
709
768
  }
@@ -720,13 +779,13 @@ function updateFileBackedTask(projectRoot, sourcePath, taskId, update) {
720
779
  { body: update.comment, createdAt: new Date().toISOString(), source: "rig" }
721
780
  ];
722
781
  }
723
- writeFileSync3(file, `${JSON.stringify(raw, null, 2)}
782
+ writeFileSync4(file, `${JSON.stringify(raw, null, 2)}
724
783
  `, "utf8");
725
784
  return true;
726
785
  }
727
786
  function listFileBackedTasks(projectRoot, sourcePath) {
728
- const directory = resolve4(projectRoot, sourcePath);
729
- if (!existsSync5(directory)) {
787
+ const directory = resolve5(projectRoot, sourcePath);
788
+ if (!existsSync7(directory)) {
730
789
  return [];
731
790
  }
732
791
  const tasks = [];
@@ -741,11 +800,11 @@ function listFileBackedTasks(projectRoot, sourcePath) {
741
800
  return tasks;
742
801
  }
743
802
  function readFileBackedTask(projectRoot, sourcePath, taskId, rawEntry) {
744
- const file = findFileBackedTaskFile(resolve4(projectRoot, sourcePath), taskId);
803
+ const file = findFileBackedTaskFile(resolve5(projectRoot, sourcePath), taskId);
745
804
  if (!file) {
746
805
  return null;
747
806
  }
748
- const raw = JSON.parse(readFileSync4(file, "utf8"));
807
+ const raw = JSON.parse(readFileSync5(file, "utf8"));
749
808
  if (!isPlainRecord2(raw)) {
750
809
  return null;
751
810
  }
@@ -758,7 +817,7 @@ function readFileBackedTask(projectRoot, sourcePath, taskId, rawEntry) {
758
817
  };
759
818
  }
760
819
  function findFileBackedTaskFile(directory, taskId) {
761
- if (!existsSync5(directory)) {
820
+ if (!existsSync7(directory)) {
762
821
  return null;
763
822
  }
764
823
  for (const name of readdirSync2(directory)) {
@@ -768,7 +827,7 @@ function findFileBackedTaskFile(directory, taskId) {
768
827
  try {
769
828
  if (!statSync(file).isFile())
770
829
  continue;
771
- const raw = JSON.parse(readFileSync4(file, "utf8"));
830
+ const raw = JSON.parse(readFileSync5(file, "utf8"));
772
831
  const inferredId = basename(file).replace(FILE_TASK_PATTERN, "");
773
832
  const id = isPlainRecord2(raw) && typeof raw.id === "string" ? raw.id : inferredId;
774
833
  if (id === taskId) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@h-rig/runtime",
3
- "version": "0.0.6-alpha.34",
3
+ "version": "0.0.6-alpha.35",
4
4
  "type": "module",
5
5
  "description": "Rig package",
6
6
  "license": "UNLICENSED",
@@ -63,14 +63,14 @@
63
63
  "main": "./dist/src/index.js",
64
64
  "module": "./dist/src/index.js",
65
65
  "dependencies": {
66
- "@earendil-works/pi-coding-agent": "npm:@h-rig/pi-coding-agent@0.0.6-alpha.34",
66
+ "@earendil-works/pi-coding-agent": "npm:@h-rig/pi-coding-agent@0.0.6-alpha.35",
67
67
  "@libsql/client": "^0.17.2",
68
- "@rig/contracts": "npm:@h-rig/contracts@0.0.6-alpha.34",
69
- "@rig/core": "npm:@h-rig/core@0.0.6-alpha.34",
70
- "@rig/hook-kit": "npm:@h-rig/hook-kit@0.0.6-alpha.34",
71
- "@rig/shared": "npm:@h-rig/shared@0.0.6-alpha.34",
72
- "@rig/skill-loader": "npm:@h-rig/skill-loader@0.0.6-alpha.34",
73
- "@rig/validator-kit": "npm:@h-rig/validator-kit@0.0.6-alpha.34",
68
+ "@rig/contracts": "npm:@h-rig/contracts@0.0.6-alpha.35",
69
+ "@rig/core": "npm:@h-rig/core@0.0.6-alpha.35",
70
+ "@rig/hook-kit": "npm:@h-rig/hook-kit@0.0.6-alpha.35",
71
+ "@rig/shared": "npm:@h-rig/shared@0.0.6-alpha.35",
72
+ "@rig/skill-loader": "npm:@h-rig/skill-loader@0.0.6-alpha.35",
73
+ "@rig/validator-kit": "npm:@h-rig/validator-kit@0.0.6-alpha.35",
74
74
  "effect": "4.0.0-beta.78",
75
75
  "smol-toml": "^1.6.0"
76
76
  }