hunter-harness 0.2.19 → 0.2.20
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.js +399 -111
- package/package.json +36 -36
package/dist/bin.js
CHANGED
|
@@ -164,7 +164,15 @@ var requestMetadataSchema = z2.object({
|
|
|
164
164
|
}).strict();
|
|
165
165
|
|
|
166
166
|
// ../contracts/dist/registry.js
|
|
167
|
-
var
|
|
167
|
+
var skillTargetAgentSchema = z3.enum(["claude-code", "codex", "cursor", "codebuddy"]);
|
|
168
|
+
var registryAgentSchema = z3.enum([
|
|
169
|
+
"claude-code",
|
|
170
|
+
"codex",
|
|
171
|
+
"cursor",
|
|
172
|
+
"codebuddy",
|
|
173
|
+
"generic",
|
|
174
|
+
"mcp"
|
|
175
|
+
]);
|
|
168
176
|
var registrySkillStatusSchema = z3.enum([
|
|
169
177
|
"draft",
|
|
170
178
|
"pending_review",
|
|
@@ -180,6 +188,7 @@ var registrySkillProposalStatusSchema = z3.enum([
|
|
|
180
188
|
var registrySemverSchema = z3.string().regex(/^\d+\.\d+\.\d+$/);
|
|
181
189
|
var registrySlugSchema = z3.string().regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/);
|
|
182
190
|
var checkStatusSchema = z3.enum(["green", "yellow", "red"]);
|
|
191
|
+
var skillVariantStatusSchema = z3.enum(["ready", "degraded", "unsupported"]);
|
|
183
192
|
var sourceFileSchema = z3.object({
|
|
184
193
|
path: z3.string(),
|
|
185
194
|
content: z3.string()
|
|
@@ -204,6 +213,39 @@ var skillUsageExampleSchema = z3.object({
|
|
|
204
213
|
result: z3.string(),
|
|
205
214
|
files: z3.array(z3.string()).default([])
|
|
206
215
|
}).strict();
|
|
216
|
+
var sensitiveFindingViewSchema = z3.object({
|
|
217
|
+
rule_id: z3.string().min(1),
|
|
218
|
+
severity: z3.enum(["high", "medium", "low"]),
|
|
219
|
+
path: z3.string().min(1),
|
|
220
|
+
line: z3.number().int().positive(),
|
|
221
|
+
column: z3.number().int().positive(),
|
|
222
|
+
fingerprint: sha256Schema,
|
|
223
|
+
redacted_preview: z3.string(),
|
|
224
|
+
overridable: z3.boolean()
|
|
225
|
+
}).strict();
|
|
226
|
+
var sensitiveReviewSubmissionSchema = z3.object({
|
|
227
|
+
scanner_version: z3.string().min(1),
|
|
228
|
+
finding_fingerprints: z3.array(sha256Schema).min(1),
|
|
229
|
+
reason: z3.string().trim().min(3).max(500)
|
|
230
|
+
}).strict();
|
|
231
|
+
var sensitiveReviewEvidenceSchema = sensitiveReviewSubmissionSchema.extend({
|
|
232
|
+
actor: z3.string().min(1),
|
|
233
|
+
accepted_at: z3.iso.datetime()
|
|
234
|
+
}).strict();
|
|
235
|
+
var skillVariantSchema = z3.object({
|
|
236
|
+
agent: skillTargetAgentSchema,
|
|
237
|
+
status: skillVariantStatusSchema,
|
|
238
|
+
buildHash: sha256Schema.nullable(),
|
|
239
|
+
adapterVersion: z3.string().min(1),
|
|
240
|
+
components: z3.array(z3.string().min(1))
|
|
241
|
+
}).strict();
|
|
242
|
+
var skillReleaseSchema = z3.object({
|
|
243
|
+
version: registrySemverSchema,
|
|
244
|
+
packageName: z3.string().min(1),
|
|
245
|
+
packageDigest: z3.string().min(1),
|
|
246
|
+
variants: z3.partialRecord(skillTargetAgentSchema, skillVariantSchema),
|
|
247
|
+
created_at: z3.iso.datetime()
|
|
248
|
+
}).strict();
|
|
207
249
|
var agentSkillConfigSchema = z3.object({
|
|
208
250
|
agent: registryAgentSchema,
|
|
209
251
|
enabled: z3.boolean(),
|
|
@@ -250,6 +292,24 @@ var publishSkillRequestSchema = z3.object({
|
|
|
250
292
|
version: registrySemverSchema,
|
|
251
293
|
releaseNote: z3.string().optional()
|
|
252
294
|
}).strict();
|
|
295
|
+
var publishUnifiedSkillRequestSchema = z3.object({
|
|
296
|
+
version: registrySemverSchema,
|
|
297
|
+
sourceAgent: skillTargetAgentSchema,
|
|
298
|
+
draftRevision: z3.number().int().positive(),
|
|
299
|
+
releaseNote: z3.string().trim().min(1).max(2e3).optional()
|
|
300
|
+
}).strict();
|
|
301
|
+
var publishSkillResponseSchema = z3.object({
|
|
302
|
+
release: z3.object({
|
|
303
|
+
slug: registrySlugSchema,
|
|
304
|
+
version: registrySemverSchema
|
|
305
|
+
}).strict(),
|
|
306
|
+
npmRelease: z3.object({
|
|
307
|
+
status: z3.enum(["published", "idempotent"]),
|
|
308
|
+
packageName: z3.string().min(1),
|
|
309
|
+
version: registrySemverSchema,
|
|
310
|
+
tarballHash: z3.string().min(1)
|
|
311
|
+
}).strict()
|
|
312
|
+
}).strict();
|
|
253
313
|
var setDefaultAgentRequestSchema = z3.object({
|
|
254
314
|
defaultAgent: registryAgentSchema,
|
|
255
315
|
revision: z3.number().int().positive()
|
|
@@ -931,94 +991,148 @@ var semanticSearchHitSchema = z12.object({
|
|
|
931
991
|
project_id: z12.string()
|
|
932
992
|
}).strict();
|
|
933
993
|
|
|
934
|
-
// ../contracts/dist/
|
|
994
|
+
// ../contracts/dist/skill-package.js
|
|
935
995
|
import { z as z13 } from "zod";
|
|
936
|
-
var
|
|
937
|
-
|
|
996
|
+
var skillComponentRoleSchema = z13.enum(["skill", "subagent"]);
|
|
997
|
+
var skillBundlePathSchema = z13.string().min(1).refine((value) => {
|
|
998
|
+
if (value === ".")
|
|
999
|
+
return true;
|
|
1000
|
+
return !value.includes("\0") && !value.includes("\\") && !value.startsWith("/") && !/^[A-Za-z]:/.test(value) && value.split("/").every((part) => part !== "" && part !== "." && part !== "..");
|
|
1001
|
+
}, "path must be a normalized relative POSIX path");
|
|
1002
|
+
var skillBundleComponentSchema = z13.object({
|
|
1003
|
+
role: skillComponentRoleSchema,
|
|
1004
|
+
source: skillBundlePathSchema,
|
|
1005
|
+
name: registrySlugSchema.optional(),
|
|
1006
|
+
variants: z13.partialRecord(skillTargetAgentSchema, skillBundlePathSchema).optional()
|
|
1007
|
+
}).strict().superRefine((component, context) => {
|
|
1008
|
+
if (component.role === "skill" && component.variants !== void 0) {
|
|
1009
|
+
context.addIssue({ code: "custom", message: "skill components cannot define agent variants" });
|
|
1010
|
+
}
|
|
1011
|
+
if (component.role === "subagent" && (component.name === void 0 || component.variants === void 0 || Object.keys(component.variants).length === 0)) {
|
|
1012
|
+
context.addIssue({ code: "custom", message: "subagent components require a name and variants" });
|
|
1013
|
+
}
|
|
1014
|
+
}).superRefine((component, context) => {
|
|
1015
|
+
if (component.role === "subagent" && component.source !== ".") {
|
|
1016
|
+
context.addIssue({ code: "custom", message: "subagent source must be '.'; variants select native files" });
|
|
1017
|
+
}
|
|
1018
|
+
});
|
|
1019
|
+
var authorSkillBundleManifestSchema = z13.object({
|
|
1020
|
+
apiVersion: z13.literal("hunter-harness/v1"),
|
|
1021
|
+
kind: z13.literal("SkillBundle"),
|
|
1022
|
+
components: z13.array(skillBundleComponentSchema).min(1)
|
|
1023
|
+
}).strict().superRefine((manifest, context) => {
|
|
1024
|
+
if (!manifest.components.some((component) => component.role === "skill")) {
|
|
1025
|
+
context.addIssue({ code: "custom", message: "bundle requires a skill component" });
|
|
1026
|
+
}
|
|
1027
|
+
});
|
|
1028
|
+
var skillPackageFileSchema = z13.object({
|
|
1029
|
+
path: skillBundlePathSchema,
|
|
1030
|
+
sha256: sha256Schema,
|
|
1031
|
+
size: z13.number().int().nonnegative()
|
|
1032
|
+
}).strict();
|
|
1033
|
+
var skillPackageVariantSchema = z13.object({
|
|
1034
|
+
status: skillVariantStatusSchema,
|
|
1035
|
+
adapterVersion: z13.string().min(1),
|
|
1036
|
+
buildHash: sha256Schema.nullable(),
|
|
1037
|
+
components: z13.array(z13.string().min(1))
|
|
1038
|
+
}).strict();
|
|
1039
|
+
var skillPackageManifestV3Schema = z13.object({
|
|
1040
|
+
schema_version: z13.literal(3),
|
|
1041
|
+
slug: registrySlugSchema,
|
|
1042
|
+
version: registrySemverSchema,
|
|
1043
|
+
files: z13.array(skillPackageFileSchema),
|
|
1044
|
+
components: z13.array(skillBundleComponentSchema).min(1),
|
|
1045
|
+
variants: z13.record(skillTargetAgentSchema, skillPackageVariantSchema)
|
|
1046
|
+
}).strict();
|
|
1047
|
+
|
|
1048
|
+
// ../contracts/dist/workflow-family.js
|
|
1049
|
+
import { z as z14 } from "zod";
|
|
1050
|
+
var workflowBundleManifestSchema = z14.object({
|
|
1051
|
+
schema_version: z14.literal(1),
|
|
938
1052
|
profile: registrySlugSchema,
|
|
939
|
-
files:
|
|
940
|
-
path:
|
|
1053
|
+
files: z14.array(z14.object({
|
|
1054
|
+
path: z14.string().min(1),
|
|
941
1055
|
sha256: sha256Schema
|
|
942
1056
|
}).strict()).min(1)
|
|
943
1057
|
}).strict();
|
|
944
|
-
var workflowFamilyBundleArtifactSchema =
|
|
945
|
-
artifact_id:
|
|
1058
|
+
var workflowFamilyBundleArtifactSchema = z14.object({
|
|
1059
|
+
artifact_id: z14.string().regex(/^wfb_/),
|
|
946
1060
|
family_slug: registrySlugSchema,
|
|
947
1061
|
profile: registrySlugSchema,
|
|
948
1062
|
version: registrySemverSchema,
|
|
949
1063
|
content_sha256: sha256Schema,
|
|
950
|
-
size_bytes:
|
|
1064
|
+
size_bytes: z14.number().int().nonnegative(),
|
|
951
1065
|
bundle_manifest: workflowBundleManifestSchema,
|
|
952
|
-
created_at:
|
|
1066
|
+
created_at: z14.iso.datetime()
|
|
953
1067
|
}).strict();
|
|
954
|
-
var workflowFamilyVersionProfileSchema =
|
|
1068
|
+
var workflowFamilyVersionProfileSchema = z14.object({
|
|
955
1069
|
profile: registrySlugSchema,
|
|
956
1070
|
bundle_manifest: workflowBundleManifestSchema,
|
|
957
|
-
artifact_id:
|
|
958
|
-
sourceFiles:
|
|
1071
|
+
artifact_id: z14.string().regex(/^wfb_/),
|
|
1072
|
+
sourceFiles: z14.array(sourceFileSchema).default([])
|
|
959
1073
|
}).strict();
|
|
960
|
-
var workflowFamilyVersionSchema =
|
|
1074
|
+
var workflowFamilyVersionSchema = z14.object({
|
|
961
1075
|
family_slug: registrySlugSchema,
|
|
962
1076
|
version: registrySemverSchema,
|
|
963
|
-
profiles:
|
|
964
|
-
artifacts:
|
|
965
|
-
changeNote:
|
|
966
|
-
created_at:
|
|
1077
|
+
profiles: z14.array(workflowFamilyVersionProfileSchema).min(1),
|
|
1078
|
+
artifacts: z14.array(workflowFamilyBundleArtifactSchema),
|
|
1079
|
+
changeNote: z14.string().nullable(),
|
|
1080
|
+
created_at: z14.iso.datetime()
|
|
967
1081
|
}).strict();
|
|
968
|
-
var workflowFamilyDraftProfileSchema =
|
|
1082
|
+
var workflowFamilyDraftProfileSchema = z14.object({
|
|
969
1083
|
profile: registrySlugSchema,
|
|
970
|
-
sourceFiles:
|
|
1084
|
+
sourceFiles: z14.array(sourceFileSchema),
|
|
971
1085
|
bundle_manifest: workflowBundleManifestSchema
|
|
972
1086
|
}).strict();
|
|
973
|
-
var workflowFamilyDraftStateSchema =
|
|
1087
|
+
var workflowFamilyDraftStateSchema = z14.object({
|
|
974
1088
|
family_slug: registrySlugSchema,
|
|
975
|
-
profiles:
|
|
976
|
-
required_profiles:
|
|
1089
|
+
profiles: z14.array(workflowFamilyDraftProfileSchema),
|
|
1090
|
+
required_profiles: z14.array(registrySlugSchema),
|
|
977
1091
|
draftVersion: registrySemverSchema.nullable(),
|
|
978
1092
|
checks: skillCheckResultSchema.nullable(),
|
|
979
|
-
releaseNote:
|
|
980
|
-
revision:
|
|
981
|
-
created_at:
|
|
982
|
-
updated_at:
|
|
1093
|
+
releaseNote: z14.string().nullable(),
|
|
1094
|
+
revision: z14.number().int(),
|
|
1095
|
+
created_at: z14.string(),
|
|
1096
|
+
updated_at: z14.string()
|
|
983
1097
|
}).strict();
|
|
984
|
-
var workflowFamilySchema =
|
|
985
|
-
family_id:
|
|
1098
|
+
var workflowFamilySchema = z14.object({
|
|
1099
|
+
family_id: z14.string().regex(/^wff_/),
|
|
986
1100
|
slug: registrySlugSchema,
|
|
987
|
-
displayName:
|
|
988
|
-
description:
|
|
989
|
-
tags:
|
|
1101
|
+
displayName: z14.string().min(1).max(120),
|
|
1102
|
+
description: z14.string().min(1).max(1e3),
|
|
1103
|
+
tags: z14.array(registrySlugSchema).default([]),
|
|
990
1104
|
latest_version: registrySemverSchema.nullable(),
|
|
991
|
-
required_profiles:
|
|
992
|
-
revision:
|
|
993
|
-
npmReleases:
|
|
994
|
-
created_at:
|
|
995
|
-
updated_at:
|
|
1105
|
+
required_profiles: z14.array(registrySlugSchema).min(1),
|
|
1106
|
+
revision: z14.number().int().positive(),
|
|
1107
|
+
npmReleases: z14.array(npmReleaseRecordSchema).optional().default([]),
|
|
1108
|
+
created_at: z14.iso.datetime(),
|
|
1109
|
+
updated_at: z14.iso.datetime()
|
|
996
1110
|
}).strict();
|
|
997
|
-
var workflowFamilyMutationSchema =
|
|
1111
|
+
var workflowFamilyMutationSchema = z14.object({
|
|
998
1112
|
slug: registrySlugSchema,
|
|
999
|
-
displayName:
|
|
1000
|
-
description:
|
|
1001
|
-
tags:
|
|
1002
|
-
required_profiles:
|
|
1113
|
+
displayName: z14.string().min(1).max(120),
|
|
1114
|
+
description: z14.string().min(1).max(1e3),
|
|
1115
|
+
tags: z14.array(registrySlugSchema).default([]),
|
|
1116
|
+
required_profiles: z14.array(registrySlugSchema).min(1)
|
|
1003
1117
|
}).strict();
|
|
1004
|
-
var publishWorkflowFamilyRequestSchema =
|
|
1118
|
+
var publishWorkflowFamilyRequestSchema = z14.object({
|
|
1005
1119
|
version: registrySemverSchema,
|
|
1006
|
-
releaseNote:
|
|
1120
|
+
releaseNote: z14.string().optional()
|
|
1007
1121
|
}).strict();
|
|
1008
|
-
var registryProjectWorkflowBindingSchema =
|
|
1009
|
-
project_id:
|
|
1122
|
+
var registryProjectWorkflowBindingSchema = z14.object({
|
|
1123
|
+
project_id: z14.string().regex(/^prj_/),
|
|
1010
1124
|
family_slug: registrySlugSchema,
|
|
1011
1125
|
profile: registrySlugSchema,
|
|
1012
1126
|
version: registrySemverSchema.nullable().optional(),
|
|
1013
|
-
revision:
|
|
1014
|
-
updated_at:
|
|
1127
|
+
revision: z14.number().int().positive(),
|
|
1128
|
+
updated_at: z14.iso.datetime()
|
|
1015
1129
|
}).strict();
|
|
1016
|
-
var bindProjectWorkflowFamilyRequestSchema =
|
|
1017
|
-
schema_version:
|
|
1130
|
+
var bindProjectWorkflowFamilyRequestSchema = z14.object({
|
|
1131
|
+
schema_version: z14.literal(1),
|
|
1018
1132
|
family_slug: registrySlugSchema,
|
|
1019
1133
|
profile: registrySlugSchema,
|
|
1020
1134
|
version: registrySemverSchema.nullable().optional(),
|
|
1021
|
-
revision:
|
|
1135
|
+
revision: z14.number().int().nullable()
|
|
1022
1136
|
}).strict();
|
|
1023
1137
|
|
|
1024
1138
|
// ../core/dist/fs/hash.js
|
|
@@ -1030,6 +1144,10 @@ function sha256Bytes(content) {
|
|
|
1030
1144
|
async function sha256File(path) {
|
|
1031
1145
|
return sha256Bytes(await readFile(path));
|
|
1032
1146
|
}
|
|
1147
|
+
function aggregateInstalledContentHash(files) {
|
|
1148
|
+
const lines = [...files].sort((a, b) => a.relpath.localeCompare(b.relpath)).map((entry) => `${entry.relpath}:${entry.sha256}`);
|
|
1149
|
+
return createHash("sha256").update(lines.join("\n"), "utf8").digest("hex");
|
|
1150
|
+
}
|
|
1033
1151
|
|
|
1034
1152
|
// ../core/dist/fs/path-safety.js
|
|
1035
1153
|
import { lstat } from "node:fs/promises";
|
|
@@ -1613,7 +1731,7 @@ function decideUpdate(policy, dirty) {
|
|
|
1613
1731
|
|
|
1614
1732
|
// ../core/dist/project/initialize.js
|
|
1615
1733
|
import { createHash as createHash4 } from "node:crypto";
|
|
1616
|
-
import { readFile as readFile4, stat as stat2 } from "node:fs/promises";
|
|
1734
|
+
import { readFile as readFile4, stat as stat2, writeFile as writeFile3 } from "node:fs/promises";
|
|
1617
1735
|
import { basename, join as join5, resolve as resolve3 } from "node:path";
|
|
1618
1736
|
import { parse as parseYaml2, stringify as stringifyYaml } from "yaml";
|
|
1619
1737
|
|
|
@@ -2311,6 +2429,27 @@ function uuidV7(now = Date.now()) {
|
|
|
2311
2429
|
}
|
|
2312
2430
|
|
|
2313
2431
|
// ../core/dist/project/initialize.js
|
|
2432
|
+
var CONTEXT_INDEX_PATH = ".harness/context-index.json";
|
|
2433
|
+
async function fileHex(path) {
|
|
2434
|
+
try {
|
|
2435
|
+
const data = await readFile4(path);
|
|
2436
|
+
return createHash4("sha256").update(data).digest("hex");
|
|
2437
|
+
} catch {
|
|
2438
|
+
return null;
|
|
2439
|
+
}
|
|
2440
|
+
}
|
|
2441
|
+
async function readExistingSkillBundles(root) {
|
|
2442
|
+
const text = await readOptional(join5(root, CONTEXT_INDEX_PATH));
|
|
2443
|
+
if (text === "")
|
|
2444
|
+
return /* @__PURE__ */ new Map();
|
|
2445
|
+
try {
|
|
2446
|
+
const parsed = JSON.parse(text);
|
|
2447
|
+
const bundles = parsed.skill_bundles ?? {};
|
|
2448
|
+
return new Map(Object.entries(bundles));
|
|
2449
|
+
} catch {
|
|
2450
|
+
return /* @__PURE__ */ new Map();
|
|
2451
|
+
}
|
|
2452
|
+
}
|
|
2314
2453
|
var TargetCollisionError = class extends Error {
|
|
2315
2454
|
code = "TARGET_COLLISION";
|
|
2316
2455
|
exitCode = 7;
|
|
@@ -2405,6 +2544,7 @@ async function initializeProject(options) {
|
|
|
2405
2544
|
const manifests = [];
|
|
2406
2545
|
const adaptersIndex = {};
|
|
2407
2546
|
const skillBundles = {};
|
|
2547
|
+
const existingContextBundles = await readExistingSkillBundles(root);
|
|
2408
2548
|
let primaryBundleHash = "";
|
|
2409
2549
|
let primaryRegistryVersion = "";
|
|
2410
2550
|
for (const agent of enabledAgents) {
|
|
@@ -2424,7 +2564,8 @@ async function initializeProject(options) {
|
|
|
2424
2564
|
});
|
|
2425
2565
|
skillBundles[agent] = {
|
|
2426
2566
|
registry_version: bundle.manifest.bundle_version,
|
|
2427
|
-
bundle_hash: bundleHash
|
|
2567
|
+
bundle_hash: bundleHash,
|
|
2568
|
+
...existingContextBundles.get(agent) ?? {}
|
|
2428
2569
|
};
|
|
2429
2570
|
adaptersIndex[agent] = adapter.contextIndex(adapterContext);
|
|
2430
2571
|
for (const target of targets) {
|
|
@@ -2541,6 +2682,7 @@ async function initializeProject(options) {
|
|
|
2541
2682
|
if (!options.dryRun) {
|
|
2542
2683
|
const writeOperations = await Promise.all([...files.entries()].map(async ([path, content]) => operationFor(root, path, content)));
|
|
2543
2684
|
await runTransaction(root, writeOperations, { kind: "init" });
|
|
2685
|
+
await enrichContextIndexWithVerification(root, enabledAgents, profile, options.resourcesRoot, adapterContext);
|
|
2544
2686
|
}
|
|
2545
2687
|
return {
|
|
2546
2688
|
projectConfig,
|
|
@@ -2549,6 +2691,52 @@ async function initializeProject(options) {
|
|
|
2549
2691
|
registryVersion: primaryRegistryVersion
|
|
2550
2692
|
};
|
|
2551
2693
|
}
|
|
2694
|
+
async function enrichContextIndexWithVerification(root, agents, profile, resourcesRoot, adapterContext) {
|
|
2695
|
+
const contextPath = join5(root, CONTEXT_INDEX_PATH);
|
|
2696
|
+
const existing = await readOptional(join5(contextPath));
|
|
2697
|
+
if (existing === "")
|
|
2698
|
+
return;
|
|
2699
|
+
let parsed;
|
|
2700
|
+
try {
|
|
2701
|
+
parsed = JSON.parse(existing);
|
|
2702
|
+
} catch {
|
|
2703
|
+
return;
|
|
2704
|
+
}
|
|
2705
|
+
const bundles = parsed.skill_bundles ?? {};
|
|
2706
|
+
for (const agent of agents) {
|
|
2707
|
+
const entry = bundles[agent];
|
|
2708
|
+
if (!entry)
|
|
2709
|
+
continue;
|
|
2710
|
+
let loadedBundle;
|
|
2711
|
+
try {
|
|
2712
|
+
loadedBundle = await loadAgentBundle(resourcesRoot, profile, agent);
|
|
2713
|
+
} catch {
|
|
2714
|
+
continue;
|
|
2715
|
+
}
|
|
2716
|
+
const targets = managedTargetsFor(getAdapter(agent), loadedBundle, adapterContext);
|
|
2717
|
+
const mismatches = [];
|
|
2718
|
+
const entries = [];
|
|
2719
|
+
for (const target of targets) {
|
|
2720
|
+
const rel = target.target_path.replace(/\\/g, "/");
|
|
2721
|
+
const actual = await fileHex(join5(root, target.target_path));
|
|
2722
|
+
entries.push({ relpath: rel, sha256: actual ?? "" });
|
|
2723
|
+
if (actual === null) {
|
|
2724
|
+
mismatches.push({ relpath: rel, expected: target.sha256, actual: "<missing>" });
|
|
2725
|
+
} else if (actual !== target.sha256) {
|
|
2726
|
+
mismatches.push({ relpath: rel, expected: target.sha256, actual });
|
|
2727
|
+
}
|
|
2728
|
+
}
|
|
2729
|
+
entry.installedContentHash = aggregateInstalledContentHash(entries);
|
|
2730
|
+
const newStatus = mismatches.length === 0 ? "verified" : "degraded";
|
|
2731
|
+
if (newStatus === "verified" && typeof entry.verifiedAt === "string" && entry.verifiedAt !== "") {
|
|
2732
|
+
} else {
|
|
2733
|
+
entry.verifiedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
2734
|
+
}
|
|
2735
|
+
entry.verificationStatus = newStatus;
|
|
2736
|
+
entry.mismatchDetails = mismatches;
|
|
2737
|
+
}
|
|
2738
|
+
await writeFile3(contextPath, JSON.stringify(parsed, null, 2) + "\n", "utf8");
|
|
2739
|
+
}
|
|
2552
2740
|
|
|
2553
2741
|
// ../core/dist/project/refresh.js
|
|
2554
2742
|
import { createHash as createHash5 } from "node:crypto";
|
|
@@ -2556,8 +2744,8 @@ import { readFile as readFile5, readdir as readdir3, rmdir } from "node:fs/promi
|
|
|
2556
2744
|
import { dirname as dirname3, join as join6, resolve as resolve4 } from "node:path";
|
|
2557
2745
|
import { parse as parseYaml3, stringify as stringifyYaml2 } from "yaml";
|
|
2558
2746
|
var INSTALLED_STATE_PATH = ".harness/state/local/installed-harness-bundle.json";
|
|
2559
|
-
var
|
|
2560
|
-
async function
|
|
2747
|
+
var CONTEXT_INDEX_PATH2 = ".harness/context-index.json";
|
|
2748
|
+
async function fileHex2(path) {
|
|
2561
2749
|
try {
|
|
2562
2750
|
return createHash5("sha256").update(await readFile5(path)).digest("hex");
|
|
2563
2751
|
} catch (error) {
|
|
@@ -2658,7 +2846,7 @@ async function readInstalledAgentConfiguration(projectRoot) {
|
|
|
2658
2846
|
};
|
|
2659
2847
|
}
|
|
2660
2848
|
async function readContextIndexBundleHash(root) {
|
|
2661
|
-
const content = await readOptionalText(join6(root,
|
|
2849
|
+
const content = await readOptionalText(join6(root, CONTEXT_INDEX_PATH2));
|
|
2662
2850
|
if (content === "")
|
|
2663
2851
|
return null;
|
|
2664
2852
|
try {
|
|
@@ -2713,8 +2901,8 @@ function conflict(target, reason, oldSha, incomingSha) {
|
|
|
2713
2901
|
function sortByTarget(items) {
|
|
2714
2902
|
return [...items].sort((left, right) => left.target_path.localeCompare(right.target_path));
|
|
2715
2903
|
}
|
|
2716
|
-
async function reconcileContextIndex(root, agents, profiles, manifests, codebuddySurface2) {
|
|
2717
|
-
const existing = await readOptionalText(join6(root,
|
|
2904
|
+
async function reconcileContextIndex(root, agents, profiles, manifests, codebuddySurface2, verifications) {
|
|
2905
|
+
const existing = await readOptionalText(join6(root, CONTEXT_INDEX_PATH2));
|
|
2718
2906
|
let codebase = {
|
|
2719
2907
|
map: ".harness/codebase/map",
|
|
2720
2908
|
status: "missing"
|
|
@@ -2741,17 +2929,27 @@ async function reconcileContextIndex(root, agents, profiles, manifests, codebudd
|
|
|
2741
2929
|
},
|
|
2742
2930
|
knowledge: { index: ".harness/knowledge/index.json" },
|
|
2743
2931
|
codebase,
|
|
2744
|
-
skill_bundles: Object.fromEntries(manifests.map((manifest) =>
|
|
2745
|
-
manifest.adapter
|
|
2746
|
-
|
|
2747
|
-
|
|
2932
|
+
skill_bundles: Object.fromEntries(manifests.map((manifest) => {
|
|
2933
|
+
const ver = verifications.get(manifest.adapter);
|
|
2934
|
+
return [
|
|
2935
|
+
manifest.adapter,
|
|
2936
|
+
{
|
|
2937
|
+
registry_version: manifest.bundle_version,
|
|
2938
|
+
bundle_hash: manifest.bundle_manifest_hash,
|
|
2939
|
+
installedContentHash: ver?.installedContentHash ?? null,
|
|
2940
|
+
verifiedAt: ver?.verifiedAt ?? null,
|
|
2941
|
+
verificationStatus: ver?.verificationStatus ?? "unknown",
|
|
2942
|
+
mismatchDetails: ver?.mismatchDetails ?? []
|
|
2943
|
+
}
|
|
2944
|
+
];
|
|
2945
|
+
}))
|
|
2748
2946
|
};
|
|
2749
2947
|
const next = JSON.stringify(record, null, 2) + "\n";
|
|
2750
2948
|
if (existing === next)
|
|
2751
2949
|
return null;
|
|
2752
2950
|
return {
|
|
2753
2951
|
operation: existing === "" ? "add" : "modify",
|
|
2754
|
-
path:
|
|
2952
|
+
path: CONTEXT_INDEX_PATH2,
|
|
2755
2953
|
content: next
|
|
2756
2954
|
};
|
|
2757
2955
|
}
|
|
@@ -2915,7 +3113,7 @@ async function refreshProject(options) {
|
|
|
2915
3113
|
const newStateFiles = installed.files.filter((entry) => entry.owner === "shared" || !selectedSet.has(entry.owner));
|
|
2916
3114
|
for (const target of newManaged) {
|
|
2917
3115
|
const incoming = target.sha256;
|
|
2918
|
-
const current = await
|
|
3116
|
+
const current = await fileHex2(join6(root, target.target_path));
|
|
2919
3117
|
if (current === null) {
|
|
2920
3118
|
applied.push(item(target, "add", "MISSING_TARGET", null, incoming));
|
|
2921
3119
|
ops.push({ operation: "add", path: target.target_path, content: target.bytes });
|
|
@@ -2943,7 +3141,7 @@ async function refreshProject(options) {
|
|
|
2943
3141
|
}
|
|
2944
3142
|
}
|
|
2945
3143
|
for (const target of oldOnly) {
|
|
2946
|
-
const current = await
|
|
3144
|
+
const current = await fileHex2(join6(root, target.target_path));
|
|
2947
3145
|
if (current === null) {
|
|
2948
3146
|
continue;
|
|
2949
3147
|
}
|
|
@@ -2969,7 +3167,48 @@ async function refreshProject(options) {
|
|
|
2969
3167
|
const projectOperation = await projectTransitionOperation(root, agents, profiles, codebuddySurface2);
|
|
2970
3168
|
if (projectOperation !== null)
|
|
2971
3169
|
ops.push(projectOperation);
|
|
2972
|
-
const
|
|
3170
|
+
const verifications = /* @__PURE__ */ new Map();
|
|
3171
|
+
for (const agent of selectedAgents) {
|
|
3172
|
+
const agentProfile = profiles.get(agent) ?? profile;
|
|
3173
|
+
let bundleForVerify;
|
|
3174
|
+
try {
|
|
3175
|
+
bundleForVerify = await loadAgentBundle(options.resourcesRoot, agentProfile, agent);
|
|
3176
|
+
} catch {
|
|
3177
|
+
continue;
|
|
3178
|
+
}
|
|
3179
|
+
const verifyTargets = managedTargetsFor(getAdapter(agent), bundleForVerify, {
|
|
3180
|
+
profile: agentProfile,
|
|
3181
|
+
codebuddySurface: codebuddySurface2
|
|
3182
|
+
});
|
|
3183
|
+
const verifyMismatches = [];
|
|
3184
|
+
const verifyEntries = [];
|
|
3185
|
+
for (const target of verifyTargets) {
|
|
3186
|
+
const rel = target.target_path.replace(/\\/g, "/");
|
|
3187
|
+
const actual = await fileHex2(join6(root, target.target_path));
|
|
3188
|
+
verifyEntries.push({ relpath: rel, sha256: actual ?? "" });
|
|
3189
|
+
if (actual === null) {
|
|
3190
|
+
verifyMismatches.push({ relpath: rel, expected: target.sha256, actual: "<missing>" });
|
|
3191
|
+
} else if (actual !== target.sha256) {
|
|
3192
|
+
verifyMismatches.push({ relpath: rel, expected: target.sha256, actual });
|
|
3193
|
+
}
|
|
3194
|
+
}
|
|
3195
|
+
verifications.set(agent, {
|
|
3196
|
+
adapter: agent,
|
|
3197
|
+
bundleVersion: bundleForVerify.manifest.bundle_version,
|
|
3198
|
+
installedBundleVersion: null,
|
|
3199
|
+
manifestHash: null,
|
|
3200
|
+
installedManifestHash: null,
|
|
3201
|
+
coreHash: null,
|
|
3202
|
+
installedCoreHash: null,
|
|
3203
|
+
adapterHash: null,
|
|
3204
|
+
installedAdapterHash: null,
|
|
3205
|
+
installedContentHash: aggregateInstalledContentHash(verifyEntries),
|
|
3206
|
+
verifiedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
3207
|
+
verificationStatus: verifyMismatches.length === 0 ? "verified" : "degraded",
|
|
3208
|
+
mismatchDetails: verifyMismatches
|
|
3209
|
+
});
|
|
3210
|
+
}
|
|
3211
|
+
const contextOperation = await reconcileContextIndex(root, agents, profiles, manifests, codebuddySurface2, verifications);
|
|
2973
3212
|
if (contextOperation !== null)
|
|
2974
3213
|
ops.push(contextOperation);
|
|
2975
3214
|
const managedBlocks = [
|
|
@@ -3040,6 +3279,14 @@ async function refreshProject(options) {
|
|
|
3040
3279
|
function freshnessEntry(agent, profile, status, identity) {
|
|
3041
3280
|
return { agent, profile, status, identity, driftedFiles: [], missingFiles: [] };
|
|
3042
3281
|
}
|
|
3282
|
+
function emptyVerification() {
|
|
3283
|
+
return {
|
|
3284
|
+
installedContentHash: null,
|
|
3285
|
+
verifiedAt: null,
|
|
3286
|
+
verificationStatus: "unknown",
|
|
3287
|
+
mismatchDetails: []
|
|
3288
|
+
};
|
|
3289
|
+
}
|
|
3043
3290
|
var BUILD_MARKER_BUNDLE_PATH = ".harness-build.json";
|
|
3044
3291
|
function buildMarkerCoreHash(text) {
|
|
3045
3292
|
if (text === null || text === "")
|
|
@@ -3069,7 +3316,8 @@ async function collectFreshness(options) {
|
|
|
3069
3316
|
coreHash: null,
|
|
3070
3317
|
installedCoreHash: null,
|
|
3071
3318
|
adapterHash: null,
|
|
3072
|
-
installedAdapterHash: null
|
|
3319
|
+
installedAdapterHash: null,
|
|
3320
|
+
...emptyVerification()
|
|
3073
3321
|
};
|
|
3074
3322
|
let officialHash = null;
|
|
3075
3323
|
let officialVersion = null;
|
|
@@ -3096,13 +3344,29 @@ async function collectFreshness(options) {
|
|
|
3096
3344
|
identity.adapterHash = sha256Bytes(canonicalJson(targets.map((target) => ({ path: target.target_path.replace(/\\/g, "/"), sha256: target.sha256 })).sort((a, b) => a.path.localeCompare(b.path))));
|
|
3097
3345
|
const installedProjection = await Promise.all(targets.map(async (target) => ({
|
|
3098
3346
|
path: target.target_path.replace(/\\/g, "/"),
|
|
3099
|
-
sha256: await
|
|
3347
|
+
sha256: await fileHex2(join6(root, target.target_path))
|
|
3100
3348
|
})));
|
|
3101
3349
|
identity.installedAdapterHash = sha256Bytes(canonicalJson(installedProjection.sort((a, b) => a.path.localeCompare(b.path))));
|
|
3102
3350
|
const markerTarget = targets.find((target) => target.target_path.replace(/\\/g, "/").endsWith(`/${BUILD_MARKER_BUNDLE_PATH}`) || target.target_path === BUILD_MARKER_BUNDLE_PATH);
|
|
3103
3351
|
if (markerTarget !== void 0) {
|
|
3104
3352
|
identity.installedCoreHash = buildMarkerCoreHash(await readOptionalText(join6(root, markerTarget.target_path)));
|
|
3105
3353
|
}
|
|
3354
|
+
const mismatchDetails = [];
|
|
3355
|
+
const contentEntries = [];
|
|
3356
|
+
for (const target of targets) {
|
|
3357
|
+
const rel = target.target_path.replace(/\\/g, "/");
|
|
3358
|
+
const actual = await fileHex2(join6(root, target.target_path));
|
|
3359
|
+
contentEntries.push({ relpath: rel, sha256: actual ?? "" });
|
|
3360
|
+
if (actual === null) {
|
|
3361
|
+
mismatchDetails.push({ relpath: rel, expected: target.sha256, actual: "<missing>" });
|
|
3362
|
+
} else if (actual !== target.sha256) {
|
|
3363
|
+
mismatchDetails.push({ relpath: rel, expected: target.sha256, actual });
|
|
3364
|
+
}
|
|
3365
|
+
}
|
|
3366
|
+
identity.installedContentHash = aggregateInstalledContentHash(contentEntries);
|
|
3367
|
+
identity.verifiedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
3368
|
+
identity.verificationStatus = mismatchDetails.length === 0 ? "verified" : "degraded";
|
|
3369
|
+
identity.mismatchDetails = mismatchDetails;
|
|
3106
3370
|
if (requestedProfile !== installedProfile) {
|
|
3107
3371
|
agents.push(freshnessEntry(agent, installedProfile, "PROFILE_MISMATCH", identity));
|
|
3108
3372
|
continue;
|
|
@@ -3114,7 +3378,7 @@ async function collectFreshness(options) {
|
|
|
3114
3378
|
const drifted = [];
|
|
3115
3379
|
const missing = [];
|
|
3116
3380
|
for (const target of targets) {
|
|
3117
|
-
const current = await
|
|
3381
|
+
const current = await fileHex2(join6(root, target.target_path));
|
|
3118
3382
|
if (current === null) {
|
|
3119
3383
|
missing.push(target.target_path);
|
|
3120
3384
|
} else if (current !== target.sha256) {
|
|
@@ -3304,7 +3568,7 @@ function highEntropyCandidates(content) {
|
|
|
3304
3568
|
}
|
|
3305
3569
|
|
|
3306
3570
|
// ../core/dist/security/scanner.js
|
|
3307
|
-
var SENSITIVE_SCANNER_VERSION = "1.
|
|
3571
|
+
var SENSITIVE_SCANNER_VERSION = "1.1.0";
|
|
3308
3572
|
var RULES = [
|
|
3309
3573
|
{
|
|
3310
3574
|
id: "HH_PRIVATE_KEY",
|
|
@@ -3359,6 +3623,9 @@ function rawFindings(content) {
|
|
|
3359
3623
|
for (const rule of RULES) {
|
|
3360
3624
|
for (const match of content.matchAll(rule.pattern)) {
|
|
3361
3625
|
const value = match[rule.valueGroup ?? 0] ?? match[0];
|
|
3626
|
+
if (rule.id === "HH_PASSWORD_VALUE" && isObviousPlaceholder(value)) {
|
|
3627
|
+
continue;
|
|
3628
|
+
}
|
|
3362
3629
|
const relative3 = match[0].indexOf(value);
|
|
3363
3630
|
findings.push({
|
|
3364
3631
|
ruleId: rule.id,
|
|
@@ -3369,6 +3636,8 @@ function rawFindings(content) {
|
|
|
3369
3636
|
}
|
|
3370
3637
|
}
|
|
3371
3638
|
for (const candidate of highEntropyCandidates(content)) {
|
|
3639
|
+
if (!hasSensitiveLexicalContext(content, candidate.offset))
|
|
3640
|
+
continue;
|
|
3372
3641
|
findings.push({
|
|
3373
3642
|
ruleId: "HH_HIGH_ENTROPY",
|
|
3374
3643
|
severity: "high",
|
|
@@ -3378,6 +3647,17 @@ function rawFindings(content) {
|
|
|
3378
3647
|
}
|
|
3379
3648
|
return findings;
|
|
3380
3649
|
}
|
|
3650
|
+
function isObviousPlaceholder(value) {
|
|
3651
|
+
const trimmed = value.trim();
|
|
3652
|
+
return /^\$\([^)]+\)$/.test(trimmed) || /^\$\{[A-Za-z_][A-Za-z0-9_]*\}$/.test(trimmed) || /^\{\{[^{}]+\}\}$/.test(trimmed) || /^<[^<>]+>$/.test(trimmed) || /^(?:example|placeholder|your[-_][a-z0-9_-]+)$/i.test(trimmed);
|
|
3653
|
+
}
|
|
3654
|
+
function hasSensitiveLexicalContext(content, offset) {
|
|
3655
|
+
const lineStart = content.lastIndexOf("\n", Math.max(0, offset - 1)) + 1;
|
|
3656
|
+
const nextLineBreak = content.indexOf("\n", offset);
|
|
3657
|
+
const lineEnd = nextLineBreak === -1 ? content.length : nextLineBreak;
|
|
3658
|
+
const line = content.slice(lineStart, lineEnd);
|
|
3659
|
+
return /(?:secret|token|password|passwd|pwd|api[_-]?key|credential|authorization|bearer)\s*[:=]\s*["']?[A-Za-z0-9._~+/-]{8,}/i.test(line);
|
|
3660
|
+
}
|
|
3381
3661
|
function scanSensitiveFiles(files, options = {}) {
|
|
3382
3662
|
const findings = [];
|
|
3383
3663
|
const evidence = [];
|
|
@@ -3436,6 +3716,8 @@ function scanSensitiveFiles(files, options = {}) {
|
|
|
3436
3716
|
return {
|
|
3437
3717
|
scanner_version: SENSITIVE_SCANNER_VERSION,
|
|
3438
3718
|
blocked: findings.some((finding) => finding.disposition === "blocked"),
|
|
3719
|
+
hard_blocked: findings.some((finding) => finding.disposition === "blocked" && finding.severity === "high"),
|
|
3720
|
+
review_required: findings.some((finding) => finding.disposition === "blocked" && finding.severity !== "high"),
|
|
3439
3721
|
findings,
|
|
3440
3722
|
override_evidence: Object.freeze(evidence)
|
|
3441
3723
|
};
|
|
@@ -3460,7 +3742,7 @@ function generateProposalPreview(input, scanOptions = {}) {
|
|
|
3460
3742
|
}
|
|
3461
3743
|
|
|
3462
3744
|
// ../core/dist/push/credentials.js
|
|
3463
|
-
import { readFile as readFile6, writeFile as
|
|
3745
|
+
import { readFile as readFile6, writeFile as writeFile4 } from "node:fs/promises";
|
|
3464
3746
|
import { join as join7 } from "node:path";
|
|
3465
3747
|
import { parse as parseYaml4, stringify as stringifyYaml3 } from "yaml";
|
|
3466
3748
|
var CREDENTIALS_LOCAL_RELATIVE = ".harness/credentials.local.yaml";
|
|
@@ -3542,7 +3824,7 @@ async function readLocalCredentials(projectRoot) {
|
|
|
3542
3824
|
}
|
|
3543
3825
|
async function writeLocalCredentials(projectRoot, credentials) {
|
|
3544
3826
|
const normalized = validateLocalCredentials(credentials);
|
|
3545
|
-
await
|
|
3827
|
+
await writeFile4(join7(projectRoot, CREDENTIALS_LOCAL_RELATIVE), stringifyYaml3(normalized, { sortMapEntries: true }) + "\n", "utf8");
|
|
3546
3828
|
}
|
|
3547
3829
|
async function ensureCredentialsGitignore(projectRoot) {
|
|
3548
3830
|
const gitignorePath = join7(projectRoot, ".gitignore");
|
|
@@ -3571,7 +3853,7 @@ async function ensureCredentialsGitignore(projectRoot) {
|
|
|
3571
3853
|
return;
|
|
3572
3854
|
}
|
|
3573
3855
|
const suffix = content.length === 0 || content.endsWith("\n") ? "" : "\n";
|
|
3574
|
-
await
|
|
3856
|
+
await writeFile4(gitignorePath, content + suffix + missing.join("\n") + "\n", "utf8");
|
|
3575
3857
|
}
|
|
3576
3858
|
function resolvePushAuth(input) {
|
|
3577
3859
|
const tokenEnv = input.tokenEnv ?? input.projectTokenEnv;
|
|
@@ -3613,7 +3895,7 @@ async function readBaseline(projectRoot) {
|
|
|
3613
3895
|
|
|
3614
3896
|
// ../core/dist/state/locks.js
|
|
3615
3897
|
import { randomUUID as randomUUID3 } from "node:crypto";
|
|
3616
|
-
import { readFile as readFile8, rename as rename3, rm as rm3, writeFile as
|
|
3898
|
+
import { readFile as readFile8, rename as rename3, rm as rm3, writeFile as writeFile5 } from "node:fs/promises";
|
|
3617
3899
|
import { join as join9 } from "node:path";
|
|
3618
3900
|
async function readLock(path) {
|
|
3619
3901
|
return JSON.parse(await readFile8(path, "utf8"));
|
|
@@ -3633,7 +3915,7 @@ async function acquireProtocolLock(projectRoot, operation, options = {}) {
|
|
|
3633
3915
|
};
|
|
3634
3916
|
for (let attempt = 0; attempt < 2; attempt += 1) {
|
|
3635
3917
|
try {
|
|
3636
|
-
await
|
|
3918
|
+
await writeFile5(lockPath, JSON.stringify(record, null, 2), { flag: "wx" });
|
|
3637
3919
|
return {
|
|
3638
3920
|
path: lockPath,
|
|
3639
3921
|
operation,
|
|
@@ -4998,46 +5280,52 @@ async function cleanupProject(options) {
|
|
|
4998
5280
|
|
|
4999
5281
|
// ../core/dist/skill/frontmatter.js
|
|
5000
5282
|
import { parse as parseYaml6 } from "yaml";
|
|
5001
|
-
import { z as
|
|
5283
|
+
import { z as z15 } from "zod";
|
|
5002
5284
|
|
|
5003
5285
|
// ../core/dist/skill/fixer.js
|
|
5004
5286
|
import { parse as parseYaml7, stringify as stringifyYaml5 } from "yaml";
|
|
5005
5287
|
|
|
5006
|
-
// ../core/dist/skill/
|
|
5007
|
-
var
|
|
5008
|
-
"claude-code": {
|
|
5288
|
+
// ../core/dist/skill/agent-surfaces.js
|
|
5289
|
+
var SURFACES = Object.freeze({
|
|
5290
|
+
"claude-code": Object.freeze({
|
|
5009
5291
|
agent: "claude-code",
|
|
5010
|
-
|
|
5011
|
-
|
|
5012
|
-
|
|
5013
|
-
|
|
5014
|
-
|
|
5292
|
+
skillRoots: Object.freeze({ project: ".claude/skills", user: ".claude/skills" }),
|
|
5293
|
+
subagentRoots: Object.freeze({ project: ".claude/agents", user: ".claude/agents" }),
|
|
5294
|
+
subagentFormat: "markdown",
|
|
5295
|
+
subagentExtension: ".md",
|
|
5296
|
+
nativeSkillAliases: Object.freeze([])
|
|
5297
|
+
}),
|
|
5298
|
+
codex: Object.freeze({
|
|
5015
5299
|
agent: "codex",
|
|
5016
|
-
|
|
5017
|
-
|
|
5018
|
-
|
|
5019
|
-
|
|
5020
|
-
|
|
5021
|
-
|
|
5300
|
+
skillRoots: Object.freeze({ project: ".agents/skills", user: ".agents/skills" }),
|
|
5301
|
+
subagentRoots: Object.freeze({ project: ".codex/agents", user: ".codex/agents" }),
|
|
5302
|
+
subagentFormat: "toml",
|
|
5303
|
+
subagentExtension: ".toml",
|
|
5304
|
+
nativeSkillAliases: Object.freeze([])
|
|
5305
|
+
}),
|
|
5306
|
+
cursor: Object.freeze({
|
|
5022
5307
|
agent: "cursor",
|
|
5023
|
-
|
|
5024
|
-
|
|
5025
|
-
|
|
5026
|
-
|
|
5027
|
-
|
|
5028
|
-
|
|
5029
|
-
|
|
5030
|
-
|
|
5031
|
-
|
|
5032
|
-
|
|
5033
|
-
|
|
5034
|
-
|
|
5035
|
-
|
|
5036
|
-
|
|
5037
|
-
|
|
5038
|
-
|
|
5039
|
-
|
|
5040
|
-
|
|
5308
|
+
skillRoots: Object.freeze({ project: ".cursor/skills", user: ".cursor/skills" }),
|
|
5309
|
+
subagentRoots: Object.freeze({ project: ".cursor/agents", user: ".cursor/agents" }),
|
|
5310
|
+
subagentFormat: "markdown",
|
|
5311
|
+
subagentExtension: ".md",
|
|
5312
|
+
nativeSkillAliases: Object.freeze([".agents/skills"])
|
|
5313
|
+
}),
|
|
5314
|
+
codebuddy: Object.freeze({
|
|
5315
|
+
agent: "codebuddy",
|
|
5316
|
+
skillRoots: Object.freeze({ project: ".codebuddy/skills", user: ".codebuddy/skills" }),
|
|
5317
|
+
subagentRoots: Object.freeze({ project: ".codebuddy/agents", user: ".codebuddy/agents" }),
|
|
5318
|
+
subagentFormat: "markdown",
|
|
5319
|
+
subagentExtension: ".md",
|
|
5320
|
+
nativeSkillAliases: Object.freeze([])
|
|
5321
|
+
})
|
|
5322
|
+
});
|
|
5323
|
+
var SKILL_TARGET_AGENTS = Object.freeze([
|
|
5324
|
+
"claude-code",
|
|
5325
|
+
"codex",
|
|
5326
|
+
"cursor",
|
|
5327
|
+
"codebuddy"
|
|
5328
|
+
]);
|
|
5041
5329
|
|
|
5042
5330
|
// ../core/dist/transaction/recovery.js
|
|
5043
5331
|
import { readFile as readFile12, readdir as readdir6, rm as rm7, stat as stat3 } from "node:fs/promises";
|
|
@@ -5420,7 +5708,7 @@ function serializeCliResult(result) {
|
|
|
5420
5708
|
}
|
|
5421
5709
|
|
|
5422
5710
|
// src/config/codebuddy-setup.ts
|
|
5423
|
-
import { mkdir as mkdir4, readFile as readFile15, readdir as readdir7, stat as stat4, writeFile as
|
|
5711
|
+
import { mkdir as mkdir4, readFile as readFile15, readdir as readdir7, stat as stat4, writeFile as writeFile6 } from "node:fs/promises";
|
|
5424
5712
|
import { basename as basename2, dirname as dirname4, extname, join as join16 } from "node:path";
|
|
5425
5713
|
var MANAGED_RULE_NAMES = /* @__PURE__ */ new Set([
|
|
5426
5714
|
"harness-general.md",
|
|
@@ -5494,7 +5782,7 @@ async function applyCodeBuddySetup(options) {
|
|
|
5494
5782
|
continue;
|
|
5495
5783
|
}
|
|
5496
5784
|
await mkdir4(dirname4(target), { recursive: true });
|
|
5497
|
-
await
|
|
5785
|
+
await writeFile6(target, content, { encoding: "utf8", flag: "wx" });
|
|
5498
5786
|
result.copied.push(target);
|
|
5499
5787
|
}
|
|
5500
5788
|
}
|
|
@@ -5515,7 +5803,7 @@ async function applyCodeBuddySetup(options) {
|
|
|
5515
5803
|
codegraph: { command: "codegraph", args: ["serve", "--mcp"] }
|
|
5516
5804
|
}
|
|
5517
5805
|
};
|
|
5518
|
-
await
|
|
5806
|
+
await writeFile6(path, JSON.stringify(next, null, 2) + "\n", "utf8");
|
|
5519
5807
|
result.mcpUpdated = true;
|
|
5520
5808
|
}
|
|
5521
5809
|
}
|
package/package.json
CHANGED
|
@@ -1,36 +1,36 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "hunter-harness",
|
|
3
|
-
"version": "0.2.
|
|
4
|
-
"description": "Local-first, server-governed agent harness",
|
|
5
|
-
"license": "MIT",
|
|
6
|
-
"type": "module",
|
|
7
|
-
"engines": {
|
|
8
|
-
"node": ">=22.12.0"
|
|
9
|
-
},
|
|
10
|
-
"bin": {
|
|
11
|
-
"hunter-harness": "dist/bin.js"
|
|
12
|
-
},
|
|
13
|
-
"files": [
|
|
14
|
-
"dist/bin.js"
|
|
15
|
-
],
|
|
16
|
-
"scripts": {
|
|
17
|
-
"build": "node ../../node_modules/typescript/bin/tsc -p tsconfig.json && npm run bundle",
|
|
18
|
-
"bundle": "node ../../scripts/bundle-cli.mjs",
|
|
19
|
-
"typecheck": "node ../../node_modules/typescript/bin/tsc -p tsconfig.json --noEmit",
|
|
20
|
-
"prepack": "npm run build"
|
|
21
|
-
},
|
|
22
|
-
"dependencies": {
|
|
23
|
-
"commander": "15.0.0",
|
|
24
|
-
"yaml": "2.9.0",
|
|
25
|
-
"zod": "4.4.3"
|
|
26
|
-
},
|
|
27
|
-
"optionalDependencies": {
|
|
28
|
-
"pacote": "21.4.0"
|
|
29
|
-
},
|
|
30
|
-
"devDependencies": {
|
|
31
|
-
"@hunter-harness/contracts": "*",
|
|
32
|
-
"@hunter-harness/core": "*",
|
|
33
|
-
"@types/pacote": "^11.1.8",
|
|
34
|
-
"esbuild": "^0.25.12"
|
|
35
|
-
}
|
|
36
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "hunter-harness",
|
|
3
|
+
"version": "0.2.20",
|
|
4
|
+
"description": "Local-first, server-governed agent harness",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"engines": {
|
|
8
|
+
"node": ">=22.12.0"
|
|
9
|
+
},
|
|
10
|
+
"bin": {
|
|
11
|
+
"hunter-harness": "dist/bin.js"
|
|
12
|
+
},
|
|
13
|
+
"files": [
|
|
14
|
+
"dist/bin.js"
|
|
15
|
+
],
|
|
16
|
+
"scripts": {
|
|
17
|
+
"build": "node ../../node_modules/typescript/bin/tsc -p tsconfig.json && npm run bundle",
|
|
18
|
+
"bundle": "node ../../scripts/bundle-cli.mjs",
|
|
19
|
+
"typecheck": "node ../../node_modules/typescript/bin/tsc -p tsconfig.json --noEmit",
|
|
20
|
+
"prepack": "npm run build"
|
|
21
|
+
},
|
|
22
|
+
"dependencies": {
|
|
23
|
+
"commander": "15.0.0",
|
|
24
|
+
"yaml": "2.9.0",
|
|
25
|
+
"zod": "4.4.3"
|
|
26
|
+
},
|
|
27
|
+
"optionalDependencies": {
|
|
28
|
+
"pacote": "21.4.0"
|
|
29
|
+
},
|
|
30
|
+
"devDependencies": {
|
|
31
|
+
"@hunter-harness/contracts": "*",
|
|
32
|
+
"@hunter-harness/core": "*",
|
|
33
|
+
"@types/pacote": "^11.1.8",
|
|
34
|
+
"esbuild": "^0.25.12"
|
|
35
|
+
}
|
|
36
|
+
}
|