@hachej/boring-agent 0.1.78 → 0.1.80

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.
@@ -0,0 +1,266 @@
1
+ import {
2
+ AgentDefinitionErrorCode,
3
+ AgentDeploymentErrorCode,
4
+ ErrorCode
5
+ } from "./chunk-CCNXYCD5.js";
6
+
7
+ // src/shared/agent-definition.ts
8
+ import { z } from "zod";
9
+ var SHA256_DIGEST_RE = /^sha256:[a-f0-9]{64}$/;
10
+ function hasWellFormedUnicode(value) {
11
+ for (let index = 0; index < value.length; index += 1) {
12
+ const code = value.charCodeAt(index);
13
+ if (code >= 55296 && code <= 56319) {
14
+ if (index + 1 >= value.length) return false;
15
+ const next = value.charCodeAt(index + 1);
16
+ if (next < 56320 || next > 57343) return false;
17
+ index += 1;
18
+ } else if (code >= 56320 && code <= 57343) {
19
+ return false;
20
+ }
21
+ }
22
+ return true;
23
+ }
24
+ function isOpaqueRef(value) {
25
+ return hasWellFormedUnicode(value) && value.trim() === value && !/[\0-\x1f\x7f]/.test(value);
26
+ }
27
+ function isSafeAssetPath(value) {
28
+ const segments = value.split("/");
29
+ return hasWellFormedUnicode(value) && value.normalize("NFC") === value && !/[\0-\x1f\x7f]/.test(value) && !value.includes("\\") && !value.startsWith("/") && !/^[A-Za-z]:[\\/]/.test(value) && !value.startsWith("./") && segments.every((segment) => segment !== "" && segment !== "." && segment !== "..");
30
+ }
31
+ var OpaqueRefSchema = z.string().min(1, "must be a non-empty reference").max(256, "must be at most 256 characters").refine(isOpaqueRef, "must be a non-empty reference");
32
+ var ReferenceArraySchema = z.array(OpaqueRefSchema).superRefine((refs, ctx) => {
33
+ const seen = /* @__PURE__ */ new Set();
34
+ refs.forEach((ref, index) => {
35
+ if (seen.has(ref)) {
36
+ ctx.addIssue({
37
+ code: z.ZodIssueCode.custom,
38
+ path: [index],
39
+ message: "must not contain duplicate references"
40
+ });
41
+ }
42
+ seen.add(ref);
43
+ });
44
+ });
45
+ var SafeAssetPathSchema = z.string().min(1).refine(isSafeAssetPath, "must be a safe relative asset path");
46
+ var Sha256DigestSchema = z.string().regex(SHA256_DIGEST_RE, "must be a lowercase sha256 digest").transform((value) => value);
47
+ var AgentDefinitionSchema = z.object({
48
+ schemaVersion: z.literal(1),
49
+ definitionId: OpaqueRefSchema,
50
+ version: OpaqueRefSchema,
51
+ label: z.string().refine(hasWellFormedUnicode, "must contain well-formed Unicode").optional(),
52
+ instructionsRef: SafeAssetPathSchema,
53
+ capabilityRequirements: ReferenceArraySchema.optional(),
54
+ toolRefs: ReferenceArraySchema.optional(),
55
+ skillRefs: ReferenceArraySchema.optional(),
56
+ mcpServerRefs: ReferenceArraySchema.optional()
57
+ }).strict();
58
+ var AgentDefinitionReferenceSchema = z.object({
59
+ definitionId: OpaqueRefSchema,
60
+ version: OpaqueRefSchema,
61
+ digest: Sha256DigestSchema
62
+ }).strict();
63
+ var AgentDeploymentSchema = z.object({
64
+ deploymentId: OpaqueRefSchema,
65
+ version: OpaqueRefSchema,
66
+ agentId: OpaqueRefSchema,
67
+ definition: AgentDefinitionReferenceSchema
68
+ }).strict();
69
+ var AgentDefinitionDigestAssetSchema = z.object({
70
+ path: SafeAssetPathSchema,
71
+ digest: Sha256DigestSchema,
72
+ content: z.string().refine(hasWellFormedUnicode, "must contain well-formed Unicode")
73
+ }).strict();
74
+ function formatPath(path) {
75
+ if (path.length === 0) return "<root>";
76
+ return path.reduce(
77
+ (result, part) => typeof part === "number" ? `${result}[${part}]` : result.length === 0 ? String(part) : `${result}.${String(part)}`,
78
+ ""
79
+ );
80
+ }
81
+ function mapZodIssues(issues, invalidCode, unsupportedCode) {
82
+ return issues.flatMap((issue) => {
83
+ if (issue.code === z.ZodIssueCode.unrecognized_keys) {
84
+ const parent = formatPath(issue.path);
85
+ return [...issue.keys].sort().map((key) => ({
86
+ code: unsupportedCode,
87
+ field: parent === "<root>" ? key : `${parent}.${key}`,
88
+ message: `${key} is not supported by schema version 1`
89
+ }));
90
+ }
91
+ const field = formatPath(issue.path);
92
+ return [{
93
+ code: invalidCode,
94
+ field,
95
+ message: field === "<root>" ? issue.message : `${field} ${issue.message}`
96
+ }];
97
+ });
98
+ }
99
+ function validateAgentDefinition(raw) {
100
+ const result = AgentDefinitionSchema.safeParse(raw);
101
+ if (!result.success) {
102
+ return {
103
+ valid: false,
104
+ issues: mapZodIssues(
105
+ result.error.issues,
106
+ AgentDefinitionErrorCode.enum.AGENT_DEFINITION_INVALID,
107
+ AgentDefinitionErrorCode.enum.AGENT_DEFINITION_UNSUPPORTED_FIELD
108
+ )
109
+ };
110
+ }
111
+ return { valid: true, value: result.data };
112
+ }
113
+ function validateAgentDeployment(raw) {
114
+ const result = AgentDeploymentSchema.safeParse(raw);
115
+ if (!result.success) {
116
+ return {
117
+ valid: false,
118
+ issues: mapZodIssues(
119
+ result.error.issues,
120
+ AgentDeploymentErrorCode.enum.AGENT_DEPLOYMENT_INVALID,
121
+ AgentDeploymentErrorCode.enum.AGENT_DEPLOYMENT_UNSUPPORTED_FIELD
122
+ )
123
+ };
124
+ }
125
+ return { valid: true, value: result.data };
126
+ }
127
+ function canonicalStringify(value) {
128
+ if (value === null || typeof value !== "object") {
129
+ const encoded = JSON.stringify(value);
130
+ if (encoded === void 0) throw new TypeError("Cannot canonicalize undefined");
131
+ return encoded;
132
+ }
133
+ if (Array.isArray(value)) return `[${value.map(canonicalStringify).join(",")}]`;
134
+ const record = value;
135
+ return `{${Object.keys(record).filter((key) => record[key] !== void 0).sort().map((key) => `${JSON.stringify(key)}:${canonicalStringify(record[key])}`).join(",")}}`;
136
+ }
137
+ async function sha256(value) {
138
+ const hash = await globalThis.crypto.subtle.digest(
139
+ "SHA-256",
140
+ new TextEncoder().encode(value)
141
+ );
142
+ const hex = Array.from(
143
+ new Uint8Array(hash),
144
+ (byte) => byte.toString(16).padStart(2, "0")
145
+ ).join("");
146
+ return `sha256:${hex}`;
147
+ }
148
+ async function createAgentAssetDigest(content) {
149
+ if (!hasWellFormedUnicode(content)) {
150
+ throw new AgentDefinitionValidationError({
151
+ code: AgentDefinitionErrorCode.enum.AGENT_DEFINITION_INVALID,
152
+ field: "content",
153
+ message: "content must contain well-formed Unicode"
154
+ });
155
+ }
156
+ return sha256(content);
157
+ }
158
+ var AgentDefinitionValidationError = class extends Error {
159
+ code = ErrorCode.enum.CONFIG_INVALID;
160
+ field;
161
+ validationCode;
162
+ constructor(issue) {
163
+ super(issue.message);
164
+ this.name = "AgentDefinitionValidationError";
165
+ this.field = issue.field;
166
+ this.validationCode = issue.code;
167
+ }
168
+ };
169
+ var AgentDeploymentValidationError = class extends Error {
170
+ code = ErrorCode.enum.CONFIG_INVALID;
171
+ field;
172
+ validationCode;
173
+ constructor(issue) {
174
+ super(issue.message);
175
+ this.name = "AgentDeploymentValidationError";
176
+ this.field = issue.field;
177
+ this.validationCode = issue.code;
178
+ }
179
+ };
180
+ async function validatedDefinitionAssets(definition, assets) {
181
+ if (!Array.isArray(assets)) {
182
+ throw new AgentDefinitionValidationError({
183
+ code: AgentDefinitionErrorCode.enum.AGENT_DEFINITION_INVALID,
184
+ field: "assets",
185
+ message: "assets must be an array"
186
+ });
187
+ }
188
+ const canonicalAssets = [];
189
+ for (const [index, input] of assets.entries()) {
190
+ const result = AgentDefinitionDigestAssetSchema.safeParse(input);
191
+ if (!result.success) {
192
+ const issue = mapZodIssues(
193
+ result.error.issues,
194
+ AgentDefinitionErrorCode.enum.AGENT_DEFINITION_INVALID,
195
+ AgentDefinitionErrorCode.enum.AGENT_DEFINITION_UNSUPPORTED_FIELD
196
+ )[0];
197
+ throw new AgentDefinitionValidationError({
198
+ ...issue,
199
+ field: `assets[${index}].${issue.field}`
200
+ });
201
+ }
202
+ if (await createAgentAssetDigest(result.data.content) !== result.data.digest) {
203
+ throw new AgentDefinitionValidationError({
204
+ code: AgentDefinitionErrorCode.enum.AGENT_DEFINITION_INVALID,
205
+ field: "assets.digest",
206
+ message: `asset digest does not match UTF-8 content: ${result.data.path}`
207
+ });
208
+ }
209
+ canonicalAssets.push(result.data);
210
+ }
211
+ canonicalAssets.sort(
212
+ (left, right) => left.path < right.path ? -1 : left.path > right.path ? 1 : 0
213
+ );
214
+ for (let index = 1; index < canonicalAssets.length; index += 1) {
215
+ if (canonicalAssets[index - 1].path === canonicalAssets[index].path) {
216
+ throw new AgentDefinitionValidationError({
217
+ code: AgentDefinitionErrorCode.enum.AGENT_DEFINITION_INVALID,
218
+ field: "assets.path",
219
+ message: `duplicate asset path: ${canonicalAssets[index].path}`
220
+ });
221
+ }
222
+ }
223
+ if (!canonicalAssets.some((asset) => asset.path === definition.instructionsRef)) {
224
+ throw new AgentDefinitionValidationError({
225
+ code: AgentDefinitionErrorCode.enum.AGENT_DEFINITION_INVALID,
226
+ field: "instructionsRef",
227
+ message: "instructionsRef must name an included verified asset"
228
+ });
229
+ }
230
+ return canonicalAssets;
231
+ }
232
+ async function createAgentDefinitionDigest(input) {
233
+ const validated = validateAgentDefinition(input.definition);
234
+ if (!validated.valid) throw new AgentDefinitionValidationError(validated.issues[0]);
235
+ const assets = await validatedDefinitionAssets(validated.value, input.assets);
236
+ return sha256(canonicalStringify({ definition: validated.value, assets }));
237
+ }
238
+ async function createAgentDeploymentDigest(deployment) {
239
+ const validated = validateAgentDeployment(deployment);
240
+ if (!validated.valid) throw new AgentDeploymentValidationError(validated.issues[0]);
241
+ return sha256(canonicalStringify(validated.value));
242
+ }
243
+
244
+ // src/shared/validateTool.ts
245
+ function validateTool(tool) {
246
+ if (typeof tool !== "object" || tool === null) return null;
247
+ const t = tool;
248
+ if (typeof t.name !== "string" || t.name.length === 0) return null;
249
+ if (typeof t.description !== "string") return null;
250
+ if (typeof t.parameters !== "object" || t.parameters === null) return null;
251
+ if (typeof t.execute !== "function") return null;
252
+ return t;
253
+ }
254
+
255
+ export {
256
+ OpaqueRefSchema,
257
+ Sha256DigestSchema,
258
+ validateAgentDefinition,
259
+ validateAgentDeployment,
260
+ createAgentAssetDigest,
261
+ AgentDefinitionValidationError,
262
+ AgentDeploymentValidationError,
263
+ createAgentDefinitionDigest,
264
+ createAgentDeploymentDigest,
265
+ validateTool
266
+ };
@@ -2,12 +2,9 @@ import {
2
2
  noopTelemetry,
3
3
  safeCapture
4
4
  } from "./chunk-AQBXNPMD.js";
5
- import {
6
- createLogger
7
- } from "./chunk-AJZHR626.js";
8
5
  import {
9
6
  ErrorCode
10
- } from "./chunk-6AEK34XU.js";
7
+ } from "./chunk-CCNXYCD5.js";
11
8
 
12
9
  // src/server/harness/pi-coding-agent/createHarness.ts
13
10
  import { AsyncLocalStorage } from "async_hooks";
@@ -24,6 +21,88 @@ import {
24
21
  loadSkills
25
22
  } from "@mariozechner/pi-coding-agent";
26
23
 
24
+ // src/server/logging.ts
25
+ var SENSITIVE_KEYS = new Set([
26
+ "apiKey",
27
+ "api_key",
28
+ "token",
29
+ "secret",
30
+ "password",
31
+ "authorization",
32
+ "cookie",
33
+ "oidcToken",
34
+ "accessToken",
35
+ "refreshToken",
36
+ "ANTHROPIC_API_KEY",
37
+ "OPENAI_API_KEY",
38
+ "VERCEL_OIDC_TOKEN",
39
+ "VERCEL_TEAM_ID"
40
+ ].map((key) => key.toLowerCase()));
41
+ function isSensitiveKey(key) {
42
+ return SENSITIVE_KEYS.has(key.toLowerCase());
43
+ }
44
+ function redactValue(key, value, seen) {
45
+ if (key && isSensitiveKey(key) && value != null) return "***";
46
+ if (value == null || typeof value !== "object") return value;
47
+ if (value instanceof Date) return value;
48
+ if (seen.has(value)) return "[Circular]";
49
+ seen.add(value);
50
+ if (Array.isArray(value)) {
51
+ const out2 = value.map((item) => redactValue(void 0, item, seen));
52
+ seen.delete(value);
53
+ return out2;
54
+ }
55
+ const out = {};
56
+ for (const [childKey, childValue] of Object.entries(value)) {
57
+ out[childKey] = redactValue(childKey, childValue, seen);
58
+ }
59
+ seen.delete(value);
60
+ return out;
61
+ }
62
+ function redact(fields) {
63
+ const out = {};
64
+ const seen = /* @__PURE__ */ new WeakSet();
65
+ for (const [k, v] of Object.entries(fields)) {
66
+ out[k] = redactValue(k, v, seen);
67
+ }
68
+ return out;
69
+ }
70
+ function isVerbose() {
71
+ return typeof process !== "undefined" && process.env?.BORING_AGENT_VERBOSE === "1";
72
+ }
73
+ function createLogger(prefix) {
74
+ function emit(level, msg, fields) {
75
+ const entry = {
76
+ level,
77
+ prefix,
78
+ msg,
79
+ ...fields ? redact(fields) : {},
80
+ t: (/* @__PURE__ */ new Date()).toISOString()
81
+ };
82
+ if (level === "error") {
83
+ console.error(JSON.stringify(entry));
84
+ } else if (level === "warn") {
85
+ console.warn(JSON.stringify(entry));
86
+ } else {
87
+ console.log(JSON.stringify(entry));
88
+ }
89
+ }
90
+ return {
91
+ debug(msg, fields) {
92
+ if (isVerbose()) emit("debug", msg, fields);
93
+ },
94
+ info(msg, fields) {
95
+ emit("info", msg, fields);
96
+ },
97
+ warn(msg, fields) {
98
+ emit("warn", msg, fields);
99
+ },
100
+ error(msg, fields) {
101
+ emit("error", msg, fields);
102
+ }
103
+ };
104
+ }
105
+
27
106
  // src/server/harness/pi-coding-agent/tool-adapter.ts
28
107
  var BORING_TOOL_ERROR_MARKER = "__boringToolError";
29
108
  function markToolResultErrorDetails(details) {
@@ -1506,7 +1585,7 @@ function createPiCodingAgentHarness(opts) {
1506
1585
  sessionNamespace: opts.sessionNamespace,
1507
1586
  sessionRoot: opts.sessionRoot,
1508
1587
  sessionDir: opts.sessionDir,
1509
- storageCwd: opts.sessionStorageCwd ?? opts.cwd
1588
+ storageCwd: opts.cwd
1510
1589
  });
1511
1590
  const piSessions = /* @__PURE__ */ new Map();
1512
1591
  const runContextStorage = new AsyncLocalStorage();
@@ -1799,7 +1878,7 @@ export {
1799
1878
  getEnv,
1800
1879
  getEnvSnapshot,
1801
1880
  setEnvDefault,
1802
- PiSessionStore,
1881
+ createLogger,
1803
1882
  registerConfiguredModelProviders,
1804
1883
  readConfiguredDefaultModel,
1805
1884
  PI_PACKAGE_RESOURCE_FILTERS,
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  ErrorCode
3
- } from "./chunk-6AEK34XU.js";
3
+ } from "./chunk-CCNXYCD5.js";
4
4
 
5
5
  // src/shared/tool-ui.ts
6
6
  function isRecord(value) {