@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.
- package/dist/bin/rig-agent-dispatch.js +518 -459
- package/dist/bin/rig-agent.js +430 -361
- package/dist/src/control-plane/agent-wrapper.js +523 -464
- package/dist/src/control-plane/harness-main.js +528 -458
- package/dist/src/control-plane/hooks/completion-verification.js +353 -283
- package/dist/src/control-plane/hooks/inject-context.js +158 -99
- package/dist/src/control-plane/hooks/submodule-branch.js +538 -479
- package/dist/src/control-plane/hooks/task-runtime-start.js +538 -479
- package/dist/src/control-plane/materialize-task-config.js +68 -8
- package/dist/src/control-plane/native/git-ops.js +10 -0
- package/dist/src/control-plane/native/harness-cli.js +513 -443
- package/dist/src/control-plane/native/task-ops.js +392 -322
- package/dist/src/control-plane/native/validator.js +159 -100
- package/dist/src/control-plane/native/verifier.js +227 -166
- package/dist/src/control-plane/pi-settings-materializer.js +52 -0
- package/dist/src/control-plane/plugin-host-context.js +59 -0
- package/dist/src/control-plane/runtime/index.js +469 -410
- package/dist/src/control-plane/runtime/isolation/index.js +493 -434
- package/dist/src/control-plane/runtime/isolation.js +493 -434
- package/dist/src/control-plane/runtime/queue.js +411 -352
- package/dist/src/control-plane/tasks/source-lifecycle.js +87 -28
- package/package.json +8 -8
|
@@ -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
|
|
390
|
-
import { basename, join as join2, resolve as
|
|
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
|
|
394
|
-
import { resolve as
|
|
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 ??
|
|
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 =
|
|
429
|
-
if (!
|
|
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(
|
|
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 ??
|
|
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 ??
|
|
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 =
|
|
641
|
-
if (
|
|
699
|
+
const jsonPath = resolve5(projectRoot, "rig.config.json");
|
|
700
|
+
if (existsSync7(jsonPath)) {
|
|
642
701
|
try {
|
|
643
|
-
const parsed = JSON.parse(
|
|
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 =
|
|
653
|
-
if (!
|
|
711
|
+
const tsPath = resolve5(projectRoot, "rig.config.ts");
|
|
712
|
+
if (!existsSync7(tsPath)) {
|
|
654
713
|
return null;
|
|
655
714
|
}
|
|
656
715
|
try {
|
|
657
|
-
const source =
|
|
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 (!
|
|
736
|
+
if (!existsSync7(configPath)) {
|
|
678
737
|
return null;
|
|
679
738
|
}
|
|
680
|
-
const parsed = JSON.parse(
|
|
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
|
-
|
|
756
|
+
writeFileSync4(configPath, `${JSON.stringify(rawConfig, null, 2)}
|
|
698
757
|
`, "utf8");
|
|
699
758
|
}
|
|
700
759
|
function updateFileBackedTask(projectRoot, sourcePath, taskId, update) {
|
|
701
|
-
const directory =
|
|
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(
|
|
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
|
-
|
|
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 =
|
|
729
|
-
if (!
|
|
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(
|
|
803
|
+
const file = findFileBackedTaskFile(resolve5(projectRoot, sourcePath), taskId);
|
|
745
804
|
if (!file) {
|
|
746
805
|
return null;
|
|
747
806
|
}
|
|
748
|
-
const raw = JSON.parse(
|
|
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 (!
|
|
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(
|
|
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.
|
|
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.
|
|
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.
|
|
69
|
-
"@rig/core": "npm:@h-rig/core@0.0.6-alpha.
|
|
70
|
-
"@rig/hook-kit": "npm:@h-rig/hook-kit@0.0.6-alpha.
|
|
71
|
-
"@rig/shared": "npm:@h-rig/shared@0.0.6-alpha.
|
|
72
|
-
"@rig/skill-loader": "npm:@h-rig/skill-loader@0.0.6-alpha.
|
|
73
|
-
"@rig/validator-kit": "npm:@h-rig/validator-kit@0.0.6-alpha.
|
|
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
|
}
|