owlrunkit 0.21.0 → 0.22.1
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/CHANGELOG.md +70 -0
- package/README.md +66 -11
- package/integrations/codex/skills/owlcoda-runkit/SKILL.md +60 -18
- package/integrations/codex/skills/owlcoda-runkit/assets/templates/config.json +3 -3
- package/package.json +1 -1
- package/packages/attest/distribution-manifest-v1.json +15 -0
- package/packages/attest/src/quick.mjs +15 -0
- package/registry-release-policy-v2.json +5 -5
- package/sbom.spdx.json +4 -4
- package/scripts/runkit-contract/core-contract.mjs +6 -1
- package/scripts/runkit-contract/fleet-skill-plan.mjs +14 -66
- package/scripts/runkit-contract/formal-workflow.mjs +1 -1
- package/scripts/runkit-contract/hook-recovery.mjs +496 -0
- package/scripts/runkit-contract/inspect-presentation.mjs +131 -0
- package/scripts/runkit-contract/install-codex-skill.mjs +2097 -196
- package/scripts/runkit-contract/onboarding-doctor.mjs +179 -4
- package/scripts/runkit-contract/project-cli-resolver.mjs +12 -0
- package/scripts/runkit-contract/registry-adoption.mjs +4 -4
- package/scripts/runkit-contract/runkit-bootstrap.mjs +1 -0
- package/scripts/runkit-contract/runkit-cli.mjs +62 -30
- package/scripts/runkit-contract/schemas/fleet-skill-upgrade-plan-v1.schema.json +16 -3
- package/scripts/runkit-contract/schemas/hook-recovery-v1.schema.json +592 -0
- package/scripts/runkit-contract/schemas/inspect-compact-v2.schema.json +122 -0
- package/scripts/runkit-contract/schemas/team-delivery-status-v3.schema.json +113 -0
- package/scripts/runkit-contract/schemas/team-recommendation-v2.schema.json +120 -0
- package/scripts/runkit-contract/sync-release-identity.mjs +1 -1
- package/scripts/runkit-contract/team-delivery.mjs +75 -0
- package/scripts/runkit-contract/team-project.mjs +62 -2
|
@@ -563,6 +563,75 @@ function ignoreFileCoversRuntime(root, ignoreFile) {
|
|
|
563
563
|
return ignored;
|
|
564
564
|
}
|
|
565
565
|
|
|
566
|
+
const ESLINT_FLAT_CONFIG_FILES = Object.freeze([
|
|
567
|
+
"eslint.config.js",
|
|
568
|
+
"eslint.config.mjs",
|
|
569
|
+
"eslint.config.cjs",
|
|
570
|
+
"eslint.config.ts",
|
|
571
|
+
"eslint.config.mts",
|
|
572
|
+
"eslint.config.cts",
|
|
573
|
+
]);
|
|
574
|
+
|
|
575
|
+
function eslintIgnoreListCoversRuntime(listText) {
|
|
576
|
+
let ignored = false;
|
|
577
|
+
for (const match of listText.matchAll(/(["'])([^"']*)\1/gu)) {
|
|
578
|
+
const negated = match[2].startsWith("!");
|
|
579
|
+
const pattern = (negated ? match[2].slice(1) : match[2])
|
|
580
|
+
.replace(/^\.\//u, "")
|
|
581
|
+
.replace(/^\*\*\//u, "");
|
|
582
|
+
if (new Set([
|
|
583
|
+
".owlcoda/",
|
|
584
|
+
".owlcoda/**",
|
|
585
|
+
".owlcoda/runkit/",
|
|
586
|
+
".owlcoda/runkit/**",
|
|
587
|
+
]).has(pattern)) {
|
|
588
|
+
ignored = !negated;
|
|
589
|
+
} else if (negated && pattern.startsWith(".owlcoda/runkit/")) {
|
|
590
|
+
ignored = false;
|
|
591
|
+
}
|
|
592
|
+
}
|
|
593
|
+
return ignored;
|
|
594
|
+
}
|
|
595
|
+
|
|
596
|
+
function eslintFlatConfigCoversRuntime(text) {
|
|
597
|
+
const importsGlobalHelper = /(?:import\s*\{[^}]*\bglobalIgnores\b[^}]*\}\s*from|(?:const|let|var)\s*\{[^}]*\bglobalIgnores\b[^}]*\}\s*=\s*require\s*\()\s*["'](?:eslint\/config|@eslint\/config-helpers)["']/su.test(text);
|
|
598
|
+
if (importsGlobalHelper) {
|
|
599
|
+
for (const match of text.matchAll(/\bglobalIgnores\s*\(\s*\[([^\]]*)\]/gsu)) {
|
|
600
|
+
if (eslintIgnoreListCoversRuntime(match[1])) return true;
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
for (const match of text.matchAll(/\{([^{}]*)\}/gsu)) {
|
|
604
|
+
const body = match[1];
|
|
605
|
+
const withoutOptionalName = body.replace(
|
|
606
|
+
/(?:^|,)\s*name\s*:\s*(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*')\s*(?=,|$)/su,
|
|
607
|
+
"",
|
|
608
|
+
);
|
|
609
|
+
const ignores = /^\s*,?\s*ignores\s*:\s*\[([^\]]*)\]\s*,?\s*$/su.exec(
|
|
610
|
+
withoutOptionalName,
|
|
611
|
+
);
|
|
612
|
+
if (ignores === null) continue;
|
|
613
|
+
if (eslintIgnoreListCoversRuntime(ignores[1])) return true;
|
|
614
|
+
}
|
|
615
|
+
return false;
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
function eslintFlatConfig(root) {
|
|
619
|
+
for (const relative of ESLINT_FLAT_CONFIG_FILES) {
|
|
620
|
+
if (!existsSync(path.join(root, relative))) continue;
|
|
621
|
+
let text;
|
|
622
|
+
try {
|
|
623
|
+
text = readWorkspaceFileBounded(root, relative);
|
|
624
|
+
} catch {
|
|
625
|
+
return { relative, coversRuntime: false };
|
|
626
|
+
}
|
|
627
|
+
return {
|
|
628
|
+
relative,
|
|
629
|
+
coversRuntime: eslintFlatConfigCoversRuntime(text),
|
|
630
|
+
};
|
|
631
|
+
}
|
|
632
|
+
return null;
|
|
633
|
+
}
|
|
634
|
+
|
|
566
635
|
const BROAD_COLLECTION_TOOLS = Object.freeze([
|
|
567
636
|
{
|
|
568
637
|
tool: "biome",
|
|
@@ -629,14 +698,18 @@ function runtimeIsolationCheck(root) {
|
|
|
629
698
|
if (typeof value !== "string" || !hasBroadDotTarget(value)) continue;
|
|
630
699
|
for (const descriptor of BROAD_COLLECTION_TOOLS) {
|
|
631
700
|
if (!descriptor.command.test(value)) continue;
|
|
701
|
+
const flatConfig = descriptor.tool === "eslint" ? eslintFlatConfig(root) : null;
|
|
702
|
+
if (flatConfig?.coversRuntime) continue;
|
|
632
703
|
if (
|
|
704
|
+
flatConfig === null
|
|
705
|
+
&&
|
|
633
706
|
descriptor.ignoreFileSupported
|
|
634
707
|
&& ignoreFileCoversRuntime(root, descriptor.ignoreFile)
|
|
635
708
|
) {
|
|
636
709
|
continue;
|
|
637
710
|
}
|
|
638
711
|
affectedScripts.push({
|
|
639
|
-
ignoreFile: descriptor.ignoreFile,
|
|
712
|
+
ignoreFile: flatConfig?.relative ?? descriptor.ignoreFile,
|
|
640
713
|
script,
|
|
641
714
|
tool: descriptor.tool,
|
|
642
715
|
});
|
|
@@ -653,6 +726,21 @@ export function inspectRuntimeIsolationV1({ workspaceRoot } = {}) {
|
|
|
653
726
|
return runtimeIsolationCheck(resolveBoundedWorkspaceRoot(workspaceRoot));
|
|
654
727
|
}
|
|
655
728
|
|
|
729
|
+
export function inspectLocalMaintenanceV1({
|
|
730
|
+
workspaceRoot,
|
|
731
|
+
packageRoot,
|
|
732
|
+
sharedSkillRoot,
|
|
733
|
+
} = {}) {
|
|
734
|
+
const root = resolveBoundedWorkspaceRoot(workspaceRoot);
|
|
735
|
+
return {
|
|
736
|
+
schemaVersion: "OwlCodaRunKitLocalMaintenanceV1",
|
|
737
|
+
profileLaunchers: readProfileLauncherReadiness({ workspaceRoot: root }),
|
|
738
|
+
runtimeIsolation: runtimeIsolationCheck(root),
|
|
739
|
+
skill: inspectDoctorSkillStateV1({ packageRoot, sharedSkillRoot }),
|
|
740
|
+
authorizationGranted: false,
|
|
741
|
+
};
|
|
742
|
+
}
|
|
743
|
+
|
|
656
744
|
function configCheck(root) {
|
|
657
745
|
try {
|
|
658
746
|
const config = readWorkspaceJsonBounded(
|
|
@@ -850,8 +938,12 @@ async function buildDoctorReport({
|
|
|
850
938
|
issues: [error instanceof Error ? error.message : String(error)],
|
|
851
939
|
};
|
|
852
940
|
}
|
|
853
|
-
let activationBlockedReason =
|
|
854
|
-
|
|
941
|
+
let activationBlockedReason = new Set(["unmanaged", "drifted"]).has(
|
|
942
|
+
inspectedSkill.status,
|
|
943
|
+
)
|
|
944
|
+
? `shared_skill_integrity_invalid:${inspectedSkill.status}`
|
|
945
|
+
: null;
|
|
946
|
+
if (inspectedSkill.status !== "valid" && activationBlockedReason === null) {
|
|
855
947
|
try {
|
|
856
948
|
await skillFleetInspector();
|
|
857
949
|
} catch (error) {
|
|
@@ -1000,6 +1092,77 @@ export async function runDoctorV2(options = {}) {
|
|
|
1000
1092
|
return buildDoctorReport({ ...options, includeSharedSkill: true });
|
|
1001
1093
|
}
|
|
1002
1094
|
|
|
1095
|
+
function shellQuote(value) {
|
|
1096
|
+
return `'${String(value).replaceAll("'", `'"'"'`)}'`;
|
|
1097
|
+
}
|
|
1098
|
+
|
|
1099
|
+
function doctorRuntimeIsolationGuidance(runtimeIsolation) {
|
|
1100
|
+
return runtimeIsolation.affectedScripts.map((affected) => ({
|
|
1101
|
+
configurationFile: affected.ignoreFile,
|
|
1102
|
+
configurationStyle: affected.tool === "eslint"
|
|
1103
|
+
&& affected.ignoreFile.startsWith("eslint.config.")
|
|
1104
|
+
? "flat_config_global_ignores"
|
|
1105
|
+
: "ignore_file",
|
|
1106
|
+
recommendedPattern: affected.tool === "eslint"
|
|
1107
|
+
&& affected.ignoreFile.startsWith("eslint.config.")
|
|
1108
|
+
? ".owlcoda/runkit/**"
|
|
1109
|
+
: ".owlcoda/runkit/",
|
|
1110
|
+
script: affected.script,
|
|
1111
|
+
tool: affected.tool,
|
|
1112
|
+
}));
|
|
1113
|
+
}
|
|
1114
|
+
|
|
1115
|
+
export async function runDoctorV3(options = {}) {
|
|
1116
|
+
const report = await buildDoctorReport({ ...options, includeSharedSkill: true });
|
|
1117
|
+
const skillRoot = options.skillRoot
|
|
1118
|
+
?? path.join(userInfo().homedir, ".agents", "skills", "owlcoda-runkit");
|
|
1119
|
+
const archiveRoot = path.join(
|
|
1120
|
+
userInfo().homedir,
|
|
1121
|
+
".agents",
|
|
1122
|
+
"skill-archives",
|
|
1123
|
+
"owlcoda-runkit",
|
|
1124
|
+
);
|
|
1125
|
+
const sharedSkill = report.checks.sharedSkill;
|
|
1126
|
+
const activation = sharedSkill.status === "valid"
|
|
1127
|
+
? {
|
|
1128
|
+
status: "not_evaluated",
|
|
1129
|
+
reason: "shared_skill_already_current",
|
|
1130
|
+
}
|
|
1131
|
+
: sharedSkill.activationBlockedReason
|
|
1132
|
+
? {
|
|
1133
|
+
status: "blocked",
|
|
1134
|
+
reason: sharedSkill.activationBlockedReason,
|
|
1135
|
+
}
|
|
1136
|
+
: {
|
|
1137
|
+
status: "eligible",
|
|
1138
|
+
reason: "fleet_check_passed",
|
|
1139
|
+
};
|
|
1140
|
+
return {
|
|
1141
|
+
...report,
|
|
1142
|
+
schemaVersion: "OwlCodaRunKitDoctorReportV3",
|
|
1143
|
+
checks: {
|
|
1144
|
+
...report.checks,
|
|
1145
|
+
runtimeIsolation: {
|
|
1146
|
+
...report.checks.runtimeIsolation,
|
|
1147
|
+
guidance: doctorRuntimeIsolationGuidance(report.checks.runtimeIsolation),
|
|
1148
|
+
},
|
|
1149
|
+
sharedSkill: {
|
|
1150
|
+
...sharedSkill,
|
|
1151
|
+
activation: {
|
|
1152
|
+
...activation,
|
|
1153
|
+
checkCommand: `npx --no-install owlrunkit fleet skill-plan --skill-root ${shellQuote(skillRoot)} --archive-root ${shellQuote(archiveRoot)}`,
|
|
1154
|
+
},
|
|
1155
|
+
},
|
|
1156
|
+
},
|
|
1157
|
+
profileLauncherWarnings: {
|
|
1158
|
+
...report.profileLauncherWarnings,
|
|
1159
|
+
diagnosticCommand: report.profileLauncherWarnings.count > 0
|
|
1160
|
+
? "npx --no-install owlrunkit profiles reconcile --workspace . --dry-run"
|
|
1161
|
+
: null,
|
|
1162
|
+
},
|
|
1163
|
+
};
|
|
1164
|
+
}
|
|
1165
|
+
|
|
1003
1166
|
export function formatDoctorHuman(report) {
|
|
1004
1167
|
const otherWarnings = report.warningCodes.filter(
|
|
1005
1168
|
(code) => code !== "profile_launcher_warnings",
|
|
@@ -1023,12 +1186,24 @@ export function formatDoctorHuman(report) {
|
|
|
1023
1186
|
? [`Shared Skill: ${report.checks.sharedSkill.status} (${report.checks.sharedSkill.sharedSkillVersion ?? "missing"}; project Core ${report.checks.sharedSkill.projectCoreVersion})`]
|
|
1024
1187
|
: []),
|
|
1025
1188
|
...(report.checks.sharedSkill?.activationBlockedReason
|
|
1189
|
+
&& !report.checks.sharedSkill?.activation
|
|
1026
1190
|
? [`Shared Skill activation: ${report.checks.sharedSkill.activationBlockedReason}`]
|
|
1027
1191
|
: []),
|
|
1192
|
+
...(report.checks.sharedSkill?.activation
|
|
1193
|
+
? [
|
|
1194
|
+
`Shared Skill activation: ${report.checks.sharedSkill.activation.status} (${report.checks.sharedSkill.activation.reason})`,
|
|
1195
|
+
`Fleet-safe check: ${report.checks.sharedSkill.activation.checkCommand}`,
|
|
1196
|
+
]
|
|
1197
|
+
: []),
|
|
1028
1198
|
`Lifecycle: ${report.checks.lifecycle.status}`,
|
|
1029
1199
|
...(report.issueCodes.length > 0 ? [`Issues: ${report.issueCodes.join(", ")}`] : []),
|
|
1030
1200
|
...(report.profileLauncherWarnings.count > 0
|
|
1031
|
-
? [
|
|
1201
|
+
? [
|
|
1202
|
+
`Profile launcher warnings: ${report.profileLauncherWarnings.count} (non-blocking)`,
|
|
1203
|
+
...(report.profileLauncherWarnings.diagnosticCommand
|
|
1204
|
+
? [`Profile launcher diagnostic: ${report.profileLauncherWarnings.diagnosticCommand}`]
|
|
1205
|
+
: []),
|
|
1206
|
+
]
|
|
1032
1207
|
: []),
|
|
1033
1208
|
...(otherWarnings.length > 0 ? [`Warnings: ${otherWarnings.join(", ")}`] : []),
|
|
1034
1209
|
`Next: ${report.nextAllowedAction === "adopt_current_release"
|
|
@@ -20,10 +20,22 @@ const SELF_NORMALIZED_QUICK_CORE_VERSIONS = new Set([
|
|
|
20
20
|
"0.20.0",
|
|
21
21
|
"0.20.1",
|
|
22
22
|
"0.21.0",
|
|
23
|
+
"0.21.1",
|
|
24
|
+
"0.22.0",
|
|
25
|
+
"0.22.1",
|
|
23
26
|
]);
|
|
24
27
|
const EXACT_VERSION = /^[0-9]+\.[0-9]+\.[0-9]+(?:-[0-9A-Za-z.-]+)?$/;
|
|
25
28
|
const SHA256_REF = /^sha256:[a-f0-9]{64}$/;
|
|
26
29
|
const TRUSTED_PRIOR_CORE_IDENTITIES = new Map([
|
|
30
|
+
["0.22.0", new Set([
|
|
31
|
+
"sha256:e79d2123d88ada0e2e31f62fabee83b1d661ca02e93a383691a502f721ae1e7e",
|
|
32
|
+
])],
|
|
33
|
+
["0.21.0", new Set([
|
|
34
|
+
"sha256:f85b9bf8c32705d5f5dfebdb653e83ac8d1ac0468214c17f230cbd2de04246fd",
|
|
35
|
+
])],
|
|
36
|
+
["0.20.1", new Set([
|
|
37
|
+
"sha256:8af2b9792731efa37f596255a7677dcec6e2fd3cc079dfdb0e6ff29e8017e784",
|
|
38
|
+
])],
|
|
27
39
|
["0.20.0", new Set([
|
|
28
40
|
"sha256:30098aa9344c17c1ed0b5ed45ef1c590b3214b824402f584029c1ecb38ca7a70",
|
|
29
41
|
])],
|
|
@@ -47,10 +47,10 @@ const POLICY = Object.freeze({
|
|
|
47
47
|
],
|
|
48
48
|
rollbackRelease: {
|
|
49
49
|
packageName: PACKAGE_NAME,
|
|
50
|
-
version: "0.
|
|
51
|
-
shasum: "
|
|
52
|
-
integrity: "sha512-
|
|
53
|
-
tarballUrl: "https://registry.npmjs.org/owlrunkit/-/owlrunkit-0.
|
|
50
|
+
version: "0.21.0",
|
|
51
|
+
shasum: "f9ecfa41ad2ba3140258234b49d98798675651f2",
|
|
52
|
+
integrity: "sha512-hopLyvN5vp0y3xu0H0jQbMI6DxaDSWcGYcn7tAbCa0m2OqW2G8n5kJvnr217jqPYlArQwJ2TDPRLNmp4vPEhVQ==",
|
|
53
|
+
tarballUrl: "https://registry.npmjs.org/owlrunkit/-/owlrunkit-0.21.0.tgz",
|
|
54
54
|
},
|
|
55
55
|
registryEvidenceMustBeExternal: true,
|
|
56
56
|
registryEvidenceSchemaVersion: "OwlCodaRunKitRegistryReleaseEvidenceV1",
|
|
@@ -87,10 +87,11 @@ import {
|
|
|
87
87
|
verifySourceCandidateV2,
|
|
88
88
|
} from "./source-candidate.mjs";
|
|
89
89
|
import {
|
|
90
|
-
|
|
90
|
+
buildInspectCompactV2,
|
|
91
91
|
buildInspectSummary,
|
|
92
92
|
formatInspectHuman,
|
|
93
93
|
} from "./inspect-presentation.mjs";
|
|
94
|
+
import { buildHookRecoveryV1 } from "./hook-recovery.mjs";
|
|
94
95
|
import { attestQuickReceiptDetails } from "./quick-attest.mjs";
|
|
95
96
|
import { readLocalQuickMetrics } from "./quick-metrics.mjs";
|
|
96
97
|
import { runQuickEvidenceReuse } from "./quick-evidence-reuse.mjs";
|
|
@@ -163,9 +164,10 @@ import {
|
|
|
163
164
|
} from "./core-successor.mjs";
|
|
164
165
|
import {
|
|
165
166
|
formatDoctorHuman,
|
|
167
|
+
inspectLocalMaintenanceV1,
|
|
166
168
|
readAdoptionReadiness,
|
|
167
169
|
readProfileLauncherReadiness,
|
|
168
|
-
|
|
170
|
+
runDoctorV3,
|
|
169
171
|
} from "./onboarding-doctor.mjs";
|
|
170
172
|
import {
|
|
171
173
|
applyOnboardingBootstrapV1,
|
|
@@ -180,7 +182,7 @@ import { OFFICIAL_NPM_REGISTRY } from "./registry-adoption-gate.mjs";
|
|
|
180
182
|
import {
|
|
181
183
|
appendTeamProjectEventV1,
|
|
182
184
|
assignTeamProjectV1,
|
|
183
|
-
|
|
185
|
+
buildTeamProjectTakeoverV4,
|
|
184
186
|
checkpointTeamProjectV1,
|
|
185
187
|
checkpointTeamProjectFromQuickReceiptV1,
|
|
186
188
|
closeTeamProjectVerificationV1,
|
|
@@ -212,13 +214,11 @@ import {
|
|
|
212
214
|
importExternalDeliveryV1,
|
|
213
215
|
} from "./project-external-delivery.mjs";
|
|
214
216
|
import {
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
formatTeamDeliveryStatusHumanV2,
|
|
217
|
+
formatTeamDeliveryRecommendationHumanV2,
|
|
218
|
+
formatTeamDeliveryStatusHumanV3,
|
|
218
219
|
formatTeamPacketValidationHumanV1,
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
recommendTeamDeliveryV1,
|
|
220
|
+
readTeamDeliveryStatusV3,
|
|
221
|
+
recommendTeamDeliveryV2,
|
|
222
222
|
validateTeamPacketFileV1,
|
|
223
223
|
} from "./team-delivery.mjs";
|
|
224
224
|
|
|
@@ -256,12 +256,12 @@ Fleet and status
|
|
|
256
256
|
npx --no-install owlrunkit fleet rollback-registry --receipt <file> --rollback-receipt <file>
|
|
257
257
|
npx --no-install owlrunkit fleet skill-plan --skill-root <directory> --archive-root <directory>
|
|
258
258
|
npx --no-install owlrunkit fleet discover; npx --no-install owlrunkit status --workspace .
|
|
259
|
+
npx --no-install owlrunkit hook recovery --workspace . --json
|
|
259
260
|
Agent team projects
|
|
260
261
|
npx --no-install owlrunkit project <init|assign|checkpoint|handoff|reject-and-return|reopen-upstream|transfer|work-item revise-scope|work-item require-evidence|reconcile|delivery record|decision|verification|capture|target-snapshot|import-delivery|status|takeover|successor> [options]
|
|
261
262
|
npx --no-install owlrunkit team <recommend|status|packet validate> [options]
|
|
262
263
|
Durable project truth plus read-only Team recommendation and packet validation. No Agent dispatch.
|
|
263
|
-
Core successor
|
|
264
|
-
npx --no-install owlrunkit core-successor <plan|apply|resume> --workspace . [...]
|
|
264
|
+
Core successor: npx --no-install owlrunkit core-successor <plan|apply|resume> --workspace . [...]
|
|
265
265
|
Other onboarding commands:
|
|
266
266
|
npx --no-install owlrunkit profiles validate --workspace .; npx --no-install owlrunkit profiles impact --workspace . --changed <path>
|
|
267
267
|
npx --no-install owlrunkit inspect --workspace . --json
|
|
@@ -295,9 +295,31 @@ grants no Git, release, deployment, production, or business authority.
|
|
|
295
295
|
npx --no-install owlrunkit inspect --workspace <directory> --run-id <id> [--verbose] [--json]
|
|
296
296
|
|
|
297
297
|
--compact returns only current project truth, progress, dominant gap, owner,
|
|
298
|
-
|
|
298
|
+
separate lifecycle/project/maintenance actions, actionable warning groups,
|
|
299
|
+
advisories, execution counts, and the authority boundary.
|
|
299
300
|
It never grants Git, release, deployment, production, or business authority.
|
|
300
301
|
`,
|
|
302
|
+
hook: `Usage:
|
|
303
|
+
npx --no-install owlrunkit hook recovery --workspace <directory> --json
|
|
304
|
+
|
|
305
|
+
Returns a deterministic, read-only, strictly bounded recovery projection for
|
|
306
|
+
SessionStart(source=compact). Project text remains escaped untrusted data.
|
|
307
|
+
The consumer must compare its current Goal/Done-when with projectId and the
|
|
308
|
+
objective digest/preview before considering nextAction. This command never
|
|
309
|
+
changes project, execution, lease, assurance, Agent, Git, release, deployment,
|
|
310
|
+
production, or business state.
|
|
311
|
+
`,
|
|
312
|
+
"hook recovery": `Usage:
|
|
313
|
+
npx --no-install owlrunkit hook recovery --workspace <directory> --json
|
|
314
|
+
|
|
315
|
+
Returns a deterministic, read-only, strictly bounded recovery projection for
|
|
316
|
+
SessionStart(source=compact). Project text remains escaped untrusted data.
|
|
317
|
+
The consumer must compare its current Goal/Done-when with projectId and the
|
|
318
|
+
objective digest/preview before considering nextAction. This command never
|
|
319
|
+
changes project, execution, lease, assurance, Agent, Git, release, deployment,
|
|
320
|
+
production, or business state.
|
|
321
|
+
`,
|
|
322
|
+
|
|
301
323
|
doctor: `Usage:
|
|
302
324
|
npx --no-install owlrunkit doctor --workspace <directory>
|
|
303
325
|
[--registry <url>] [--timeout-ms <milliseconds>]
|
|
@@ -313,16 +335,6 @@ non-blocking; it never changes project authority.
|
|
|
313
335
|
|
|
314
336
|
Verifies the exact registry release against the project-local install and writes
|
|
315
337
|
project-owned adoption evidence. It grants no Git or release authority.
|
|
316
|
-
`,
|
|
317
|
-
doctor: `Usage:
|
|
318
|
-
npx --no-install owlrunkit doctor --workspace <directory>
|
|
319
|
-
[--skill-root <shared-skill-directory>] [--registry <url>]
|
|
320
|
-
[--timeout-ms <milliseconds>] [--json]
|
|
321
|
-
|
|
322
|
-
Diagnoses the project package, Core, registry, profiles, lifecycle, and the
|
|
323
|
-
package-bound versus shared Skill version. A shared Skill mismatch is a visible
|
|
324
|
-
non-blocking warning because the CLI cannot prove which Skill the active Agent
|
|
325
|
-
session already loaded.
|
|
326
338
|
`,
|
|
327
339
|
assurance: `Usage:
|
|
328
340
|
npx --no-install owlrunkit assurance route --workspace <directory> --request <risk-facts.json>
|
|
@@ -2159,6 +2171,13 @@ function inspect(options) {
|
|
|
2159
2171
|
const projectDriver = pathEntryExists(projectDefinitionPath)
|
|
2160
2172
|
? readTeamProjectStatusV3({ workspaceRoot: root })
|
|
2161
2173
|
: null;
|
|
2174
|
+
const localMaintenance = options.compact === true
|
|
2175
|
+
? inspectLocalMaintenanceV1({
|
|
2176
|
+
workspaceRoot: root,
|
|
2177
|
+
packageRoot: path.resolve(path.dirname(fileURLToPath(import.meta.url)), "../.."),
|
|
2178
|
+
sharedSkillRoot: process.env.OWLCODA_RUNKIT_PROCESS_SKILL_ROOT,
|
|
2179
|
+
})
|
|
2180
|
+
: null;
|
|
2162
2181
|
const summary = buildInspectSummary(result, {
|
|
2163
2182
|
maintenanceNextAction: onboarding.maintenanceNextAction ?? null,
|
|
2164
2183
|
projectDriver,
|
|
@@ -2178,9 +2197,10 @@ function inspect(options) {
|
|
|
2178
2197
|
summary,
|
|
2179
2198
|
view,
|
|
2180
2199
|
onboarding,
|
|
2200
|
+
...(localMaintenance === null ? {} : { localMaintenance }),
|
|
2181
2201
|
...(projectDriver === null ? {} : { projectDriver }),
|
|
2182
2202
|
};
|
|
2183
|
-
return options.compact === true ?
|
|
2203
|
+
return options.compact === true ? buildInspectCompactV2(inspected) : inspected;
|
|
2184
2204
|
}
|
|
2185
2205
|
|
|
2186
2206
|
function closeout(options) {
|
|
@@ -2444,6 +2464,7 @@ export async function runCli(argv = process.argv.slice(2), runtimeHooks = {}) {
|
|
|
2444
2464
|
"efficiency",
|
|
2445
2465
|
"fleet",
|
|
2446
2466
|
"formal",
|
|
2467
|
+
"hook",
|
|
2447
2468
|
"lease",
|
|
2448
2469
|
"mode",
|
|
2449
2470
|
"profiles",
|
|
@@ -2555,6 +2576,8 @@ export async function runCli(argv = process.argv.slice(2), runtimeHooks = {}) {
|
|
|
2555
2576
|
? ["json"]
|
|
2556
2577
|
: command === "team"
|
|
2557
2578
|
? ["json"]
|
|
2579
|
+
: command === "hook"
|
|
2580
|
+
? ["json"]
|
|
2558
2581
|
: command === "inspect"
|
|
2559
2582
|
? ["json", "compact", "verbose", "history"]
|
|
2560
2583
|
: command === "init"
|
|
@@ -2637,7 +2660,7 @@ export async function runCli(argv = process.argv.slice(2), runtimeHooks = {}) {
|
|
|
2637
2660
|
if (!Number.isSafeInteger(timeoutMs) || timeoutMs < 25 || timeoutMs > 10_000) {
|
|
2638
2661
|
throw new Error("--timeout-ms must be an integer from 25 to 10000.");
|
|
2639
2662
|
}
|
|
2640
|
-
const report = await
|
|
2663
|
+
const report = await runDoctorV3({
|
|
2641
2664
|
workspaceRoot: requireOption(options, "workspace"),
|
|
2642
2665
|
sharedSkillRoot: options["skill-root"],
|
|
2643
2666
|
discoverSharedSkill: true,
|
|
@@ -2772,20 +2795,20 @@ export async function runCli(argv = process.argv.slice(2), runtimeHooks = {}) {
|
|
|
2772
2795
|
const root = workspace(options);
|
|
2773
2796
|
if (action === "recommend") {
|
|
2774
2797
|
assertOnlyOptions(options, ["workspace", "json"]);
|
|
2775
|
-
const recommendation =
|
|
2798
|
+
const recommendation = recommendTeamDeliveryV2({ workspaceRoot: root });
|
|
2776
2799
|
return options.json === true
|
|
2777
2800
|
? recommendation
|
|
2778
2801
|
: withHumanOutput(
|
|
2779
2802
|
recommendation,
|
|
2780
|
-
|
|
2803
|
+
formatTeamDeliveryRecommendationHumanV2(recommendation),
|
|
2781
2804
|
);
|
|
2782
2805
|
}
|
|
2783
2806
|
if (action === "status") {
|
|
2784
2807
|
assertOnlyOptions(options, ["workspace", "json"]);
|
|
2785
|
-
const status =
|
|
2808
|
+
const status = readTeamDeliveryStatusV3({ workspaceRoot: root });
|
|
2786
2809
|
return options.json === true
|
|
2787
2810
|
? status
|
|
2788
|
-
: withHumanOutput(status,
|
|
2811
|
+
: withHumanOutput(status, formatTeamDeliveryStatusHumanV3(status));
|
|
2789
2812
|
}
|
|
2790
2813
|
if (action === "packet validate") {
|
|
2791
2814
|
assertOnlyOptions(options, ["workspace", "packet", "json"]);
|
|
@@ -3598,6 +3621,15 @@ export async function runCli(argv = process.argv.slice(2), runtimeHooks = {}) {
|
|
|
3598
3621
|
const root = workspace(options);
|
|
3599
3622
|
return withControlTransaction(root, () => plan(options));
|
|
3600
3623
|
}
|
|
3624
|
+
if (command === "hook") {
|
|
3625
|
+
if (action !== "recovery") {
|
|
3626
|
+
throw new Error("Usage: npx --no-install owlrunkit hook recovery --workspace <directory> --json");
|
|
3627
|
+
}
|
|
3628
|
+
assertOnlyOptions(options, ["workspace", "json"]);
|
|
3629
|
+
return buildHookRecoveryV1({
|
|
3630
|
+
workspaceRoot: requireOption(options, "workspace"),
|
|
3631
|
+
});
|
|
3632
|
+
}
|
|
3601
3633
|
if (command === "inspect") return inspect(options);
|
|
3602
3634
|
if (command === "status") {
|
|
3603
3635
|
const inspected = inspect({ ...options, json: true });
|
|
@@ -4335,7 +4367,7 @@ export async function runCli(argv = process.argv.slice(2), runtimeHooks = {}) {
|
|
|
4335
4367
|
: withHumanOutput(status, formatTeamProjectStatusHumanV2(status));
|
|
4336
4368
|
}
|
|
4337
4369
|
if (action === "takeover") {
|
|
4338
|
-
const takeover =
|
|
4370
|
+
const takeover = buildTeamProjectTakeoverV4({
|
|
4339
4371
|
workspaceRoot: root,
|
|
4340
4372
|
agentId: requireOption(options, "agent"),
|
|
4341
4373
|
});
|
|
@@ -4600,7 +4632,7 @@ export async function runCli(argv = process.argv.slice(2), runtimeHooks = {}) {
|
|
|
4600
4632
|
return withControlTransaction(root, () => closeout(options));
|
|
4601
4633
|
}
|
|
4602
4634
|
if (command === "finish") return finishExecution(options);
|
|
4603
|
-
throw new Error("Usage: npx --no-install owlrunkit <bootstrap|init|doctor|adopt|mode|team|assurance|fleet|profiles|project|status|formal|candidate|deployment|core-successor|start|verify|repair|offline-export|offline-import|quick-verify|quick-reuse|quick-runtime-verify|quick-attest|quick-metrics|efficiency|finish|plan|inspect|lease|delivery|coverage-adopt|resume|verify-plan|resource-preflight|snapshot|visual-smoke|finalize|ready-for-commit|closeout> [options]");
|
|
4635
|
+
throw new Error("Usage: npx --no-install owlrunkit <bootstrap|init|doctor|adopt|mode|team|hook|assurance|fleet|profiles|project|status|formal|candidate|deployment|core-successor|start|verify|repair|offline-export|offline-import|quick-verify|quick-reuse|quick-runtime-verify|quick-attest|quick-metrics|efficiency|finish|plan|inspect|lease|delivery|coverage-adopt|resume|verify-plan|resource-preflight|snapshot|visual-smoke|finalize|ready-for-commit|closeout> [options]");
|
|
4604
4636
|
} catch (error) {
|
|
4605
4637
|
return {
|
|
4606
4638
|
status: "invalid_input",
|
|
@@ -42,7 +42,20 @@
|
|
|
42
42
|
"source": { "type": "string", "minLength": 1 },
|
|
43
43
|
"complete": { "type": "boolean" },
|
|
44
44
|
"workspaceCount": { "type": "integer", "minimum": 0 },
|
|
45
|
-
"unreachableRoots": { "$ref": "#/$defs/strings" }
|
|
45
|
+
"unreachableRoots": { "$ref": "#/$defs/strings" },
|
|
46
|
+
"issues": {
|
|
47
|
+
"type": "array",
|
|
48
|
+
"items": {
|
|
49
|
+
"type": "object",
|
|
50
|
+
"additionalProperties": false,
|
|
51
|
+
"required": ["code", "path", "coverageRoot"],
|
|
52
|
+
"properties": {
|
|
53
|
+
"code": { "type": "string", "minLength": 1 },
|
|
54
|
+
"path": { "type": "string", "minLength": 1 },
|
|
55
|
+
"coverageRoot": { "type": "string", "minLength": 1 }
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
46
59
|
}
|
|
47
60
|
}
|
|
48
61
|
]
|
|
@@ -102,7 +115,7 @@
|
|
|
102
115
|
"status": "blocked",
|
|
103
116
|
"expectedCore": {
|
|
104
117
|
"contractVersion": "0.2",
|
|
105
|
-
"coreVersion": "0.
|
|
118
|
+
"coreVersion": "0.22.1",
|
|
106
119
|
"coreManifestSha256": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
|
107
120
|
"coreSourceRef": "artifact:sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
|
108
121
|
},
|
|
@@ -113,7 +126,7 @@
|
|
|
113
126
|
"installedConfigCoreVersion": "0.20.0",
|
|
114
127
|
"issues": ["installed_skill_core_version_mismatch"]
|
|
115
128
|
},
|
|
116
|
-
"discovery": { "source": "fleet_registry", "complete": true, "workspaceCount": 1, "unreachableRoots": [] },
|
|
129
|
+
"discovery": { "source": "fleet_registry", "complete": true, "workspaceCount": 1, "unreachableRoots": [], "issues": [] },
|
|
117
130
|
"affectedProjects": [
|
|
118
131
|
{
|
|
119
132
|
"workspaceRoot": "/projects/example",
|