@autohq/cli 0.1.149 → 0.1.151
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/agent-bridge.js +1 -1
- package/dist/index.js +1105 -387
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -18510,8 +18510,8 @@ function isSafePathUnderHome(value, home) {
|
|
|
18510
18510
|
if (!value.startsWith(prefix)) {
|
|
18511
18511
|
return false;
|
|
18512
18512
|
}
|
|
18513
|
-
const
|
|
18514
|
-
return
|
|
18513
|
+
const relative2 = value.slice(prefix.length);
|
|
18514
|
+
return relative2.split("/").every((segment) => segment !== "" && segment !== "." && segment !== "..");
|
|
18515
18515
|
}
|
|
18516
18516
|
function isSafeRelativePath(value) {
|
|
18517
18517
|
if (!value || value.startsWith("/")) {
|
|
@@ -21306,7 +21306,7 @@ var init_package = __esm({
|
|
|
21306
21306
|
"package.json"() {
|
|
21307
21307
|
package_default = {
|
|
21308
21308
|
name: "@autohq/cli",
|
|
21309
|
-
version: "0.1.
|
|
21309
|
+
version: "0.1.151",
|
|
21310
21310
|
license: "SEE LICENSE IN README.md",
|
|
21311
21311
|
publishConfig: {
|
|
21312
21312
|
access: "public"
|
|
@@ -21403,28 +21403,6 @@ function compileAgentFile(path2) {
|
|
|
21403
21403
|
removals: context.removals
|
|
21404
21404
|
};
|
|
21405
21405
|
}
|
|
21406
|
-
function compileAgentDocumentValue(document, path2) {
|
|
21407
|
-
const context = { graph: /* @__PURE__ */ new Map(), removals: [] };
|
|
21408
|
-
const compiled = finalizeAgentApplyShape(
|
|
21409
|
-
compileAgentDocument(document, path2, [], context),
|
|
21410
|
-
path2
|
|
21411
|
-
);
|
|
21412
|
-
const parsed = ProjectApplyResourceSchema.safeParse(compiled.resource);
|
|
21413
|
-
if (!parsed.success) {
|
|
21414
|
-
throw new Error(`Invalid compiled agent ${path2}: ${parsed.error.message}`);
|
|
21415
|
-
}
|
|
21416
|
-
if (parsed.data.kind !== RESOURCE_KIND_AGENT) {
|
|
21417
|
-
throw new Error(
|
|
21418
|
-
`Invalid compiled agent ${path2}: expected kind "agent", got "${parsed.data.kind}"`
|
|
21419
|
-
);
|
|
21420
|
-
}
|
|
21421
|
-
return {
|
|
21422
|
-
resource: parsed.data,
|
|
21423
|
-
resources: [...compiled.resources, parsed.data],
|
|
21424
|
-
graph: [...context.graph.values()],
|
|
21425
|
-
removals: context.removals
|
|
21426
|
-
};
|
|
21427
|
-
}
|
|
21428
21406
|
function renderCompiledAgentYaml(result) {
|
|
21429
21407
|
return stringify(result.resource).trimEnd();
|
|
21430
21408
|
}
|
|
@@ -21481,9 +21459,6 @@ function readLocalAgentAuthoringStatuses(input) {
|
|
|
21481
21459
|
}
|
|
21482
21460
|
});
|
|
21483
21461
|
}
|
|
21484
|
-
function validateAgentFragmentFile(path2) {
|
|
21485
|
-
validateAgentFragmentDocument(readSingleDocument(path2), path2, []);
|
|
21486
|
-
}
|
|
21487
21462
|
function agentAuthoringFiles(directory) {
|
|
21488
21463
|
let entries;
|
|
21489
21464
|
try {
|
|
@@ -21566,29 +21541,6 @@ function compileAgentDocument(document, path2, stack, context) {
|
|
|
21566
21541
|
[]
|
|
21567
21542
|
);
|
|
21568
21543
|
}
|
|
21569
|
-
function validateAgentFragmentDocument(document, path2, stack) {
|
|
21570
|
-
const resolvedPath = resolve(path2);
|
|
21571
|
-
if (stack.includes(resolvedPath)) {
|
|
21572
|
-
throw new Error(
|
|
21573
|
-
`Agent import cycle detected: ${[...stack, resolvedPath].join(" -> ")}`
|
|
21574
|
-
);
|
|
21575
|
-
}
|
|
21576
|
-
if (!isRecord(document)) {
|
|
21577
|
-
throw new Error(`Invalid agent fragment file ${path2}: expected object`);
|
|
21578
|
-
}
|
|
21579
|
-
for (const imported of importPaths(document).map(
|
|
21580
|
-
(importPath) => resolveImportPath(importPath, resolvedPath)
|
|
21581
|
-
)) {
|
|
21582
|
-
validateAgentFragmentDocument(readSingleDocument(imported), imported, [
|
|
21583
|
-
...stack,
|
|
21584
|
-
resolvedPath
|
|
21585
|
-
]);
|
|
21586
|
-
}
|
|
21587
|
-
for (const removal of removalDirectives(document, resolvedPath)) {
|
|
21588
|
-
assertSupportedRemovalTarget(removal.target);
|
|
21589
|
-
}
|
|
21590
|
-
authoringDocumentApplyShape(document, resolvedPath);
|
|
21591
|
-
}
|
|
21592
21544
|
function readSingleDocument(path2) {
|
|
21593
21545
|
const documents = readDocuments(path2);
|
|
21594
21546
|
if (documents.length !== 1) {
|
|
@@ -22298,112 +22250,201 @@ var init_assets = __esm({
|
|
|
22298
22250
|
}
|
|
22299
22251
|
});
|
|
22300
22252
|
|
|
22301
|
-
// src/
|
|
22302
|
-
import { createHash as createHash3 } from "crypto";
|
|
22303
|
-
import {
|
|
22304
|
-
readFileSync as readFileSync4,
|
|
22305
|
-
readdirSync as readdirSync3,
|
|
22306
|
-
realpathSync,
|
|
22307
|
-
statSync as statSync2
|
|
22308
|
-
} from "fs";
|
|
22309
|
-
import {
|
|
22310
|
-
basename as basename3,
|
|
22311
|
-
dirname as dirname5,
|
|
22312
|
-
extname as extname2,
|
|
22313
|
-
isAbsolute as isAbsolute2,
|
|
22314
|
-
join as join5,
|
|
22315
|
-
resolve as resolve2
|
|
22316
|
-
} from "path";
|
|
22253
|
+
// ../../packages/schemas/src/project-apply-files/source.ts
|
|
22317
22254
|
import { parseAllDocuments as parseYamlDocuments2 } from "yaml";
|
|
22318
|
-
function
|
|
22319
|
-
|
|
22320
|
-
|
|
22321
|
-
|
|
22322
|
-
|
|
22323
|
-
|
|
22324
|
-
|
|
22325
|
-
|
|
22326
|
-
|
|
22327
|
-
|
|
22255
|
+
function readDocumentsFromSource(file2) {
|
|
22256
|
+
const source = Buffer.from(file2.contentBase64, "base64").toString("utf8");
|
|
22257
|
+
try {
|
|
22258
|
+
const parsedDocuments = parseYamlDocuments2(source);
|
|
22259
|
+
const parseError = parsedDocuments.flatMap((document) => document.errors).at(0);
|
|
22260
|
+
if (parseError) {
|
|
22261
|
+
throw parseError;
|
|
22262
|
+
}
|
|
22263
|
+
return parsedDocuments.filter((document) => document.contents !== null).map((document) => document.toJSON());
|
|
22264
|
+
} catch (error51) {
|
|
22265
|
+
throw new Error(
|
|
22266
|
+
`Invalid apply file ${file2.path}: ${error51 instanceof Error ? error51.message : String(error51)}`
|
|
22328
22267
|
);
|
|
22329
|
-
|
|
22330
|
-
|
|
22331
|
-
|
|
22332
|
-
|
|
22333
|
-
|
|
22334
|
-
|
|
22268
|
+
}
|
|
22269
|
+
}
|
|
22270
|
+
function primaryApplyDirectory() {
|
|
22271
|
+
return APPLY_DIRECTORIES[RESOURCE_KIND_AGENT];
|
|
22272
|
+
}
|
|
22273
|
+
function isResourceFileUnderDirectory(path2, directory) {
|
|
22274
|
+
const normalizedPath = normalizeSourcePath(path2);
|
|
22275
|
+
const normalizedDirectory = normalizeSourcePath(directory);
|
|
22276
|
+
return normalizedPath.startsWith(`${normalizedDirectory}/`) && /\.(json|ya?ml)$/i.test(normalizedPath);
|
|
22277
|
+
}
|
|
22278
|
+
function sourcePathJoin(...parts) {
|
|
22279
|
+
return parts.map(normalizeSourcePath).filter(Boolean).join("/");
|
|
22280
|
+
}
|
|
22281
|
+
function normalizeSourcePath(path2) {
|
|
22282
|
+
return path2.replaceAll("\\", "/").replace(/^\/+|\/+$/g, "");
|
|
22283
|
+
}
|
|
22284
|
+
function sourceFileIndex(files) {
|
|
22285
|
+
return new Map(files.map((file2) => [normalizeSourcePath(file2.path), file2]));
|
|
22286
|
+
}
|
|
22287
|
+
function isAbsoluteSourcePath(path2) {
|
|
22288
|
+
return path2.startsWith("/");
|
|
22289
|
+
}
|
|
22290
|
+
function isRecord2(value) {
|
|
22291
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
22292
|
+
}
|
|
22293
|
+
var APPLY_DIRECTORIES, PROJECT_APPLY_RESOURCE_DIRECTORIES;
|
|
22294
|
+
var init_source = __esm({
|
|
22295
|
+
"../../packages/schemas/src/project-apply-files/source.ts"() {
|
|
22296
|
+
"use strict";
|
|
22297
|
+
init_agents();
|
|
22298
|
+
APPLY_DIRECTORIES = {
|
|
22299
|
+
[RESOURCE_KIND_AGENT]: "agents"
|
|
22335
22300
|
};
|
|
22301
|
+
PROJECT_APPLY_RESOURCE_DIRECTORIES = Object.freeze([
|
|
22302
|
+
APPLY_DIRECTORIES[RESOURCE_KIND_AGENT]
|
|
22303
|
+
]);
|
|
22336
22304
|
}
|
|
22337
|
-
|
|
22338
|
-
|
|
22339
|
-
|
|
22340
|
-
|
|
22341
|
-
|
|
22342
|
-
|
|
22343
|
-
|
|
22305
|
+
});
|
|
22306
|
+
|
|
22307
|
+
// ../../packages/schemas/src/project-apply-files/agent-document-merge.ts
|
|
22308
|
+
import { posix } from "path";
|
|
22309
|
+
function readSingleDocument2(path2, fileIndex) {
|
|
22310
|
+
const file2 = fileIndex.get(normalizeSourcePath(path2));
|
|
22311
|
+
if (!file2) {
|
|
22312
|
+
throw new Error(`Agent import not found: ${path2}`);
|
|
22313
|
+
}
|
|
22314
|
+
const documents = readDocumentsFromSource(file2);
|
|
22315
|
+
if (documents.length !== 1) {
|
|
22316
|
+
throw new Error(
|
|
22317
|
+
`Agent authoring file ${file2.path} must contain exactly one document`
|
|
22318
|
+
);
|
|
22344
22319
|
}
|
|
22345
|
-
|
|
22346
|
-
|
|
22347
|
-
|
|
22348
|
-
|
|
22349
|
-
|
|
22350
|
-
|
|
22351
|
-
|
|
22352
|
-
|
|
22353
|
-
|
|
22354
|
-
|
|
22320
|
+
return documents[0];
|
|
22321
|
+
}
|
|
22322
|
+
function importPaths2(document) {
|
|
22323
|
+
const value = document.imports ?? document.import;
|
|
22324
|
+
if (value === void 0) {
|
|
22325
|
+
return [];
|
|
22326
|
+
}
|
|
22327
|
+
const values = Array.isArray(value) ? value : [value];
|
|
22328
|
+
return values.map((item) => {
|
|
22329
|
+
if (typeof item !== "string" || item.trim().length === 0) {
|
|
22330
|
+
throw new Error("Agent imports must be non-empty string paths");
|
|
22355
22331
|
}
|
|
22332
|
+
return item.trim();
|
|
22333
|
+
});
|
|
22334
|
+
}
|
|
22335
|
+
function resolveImportPath2(importPath, importerPath, fileIndex) {
|
|
22336
|
+
if (isAbsoluteSourcePath(importPath) || /^[A-Za-z]+:\/\//.test(importPath)) {
|
|
22337
|
+
throw new Error(`Agent import must be a relative path: ${importPath}`);
|
|
22356
22338
|
}
|
|
22357
|
-
const
|
|
22358
|
-
|
|
22339
|
+
const resolved = normalizeSourcePath(
|
|
22340
|
+
posix.normalize(posix.join(posix.dirname(importerPath), importPath))
|
|
22341
|
+
);
|
|
22342
|
+
if (!fileIndex.has(resolved)) {
|
|
22343
|
+
throw new Error(
|
|
22344
|
+
`Agent import not found: ${importPath} from ${importerPath}`
|
|
22345
|
+
);
|
|
22346
|
+
}
|
|
22347
|
+
return resolved;
|
|
22348
|
+
}
|
|
22349
|
+
function removalDirectives2(document, path2) {
|
|
22350
|
+
const raw = isRecord2(document.remove) ? document.remove : {};
|
|
22351
|
+
const directives = [];
|
|
22352
|
+
for (const [target, value] of Object.entries(raw)) {
|
|
22353
|
+
const names = stringList2(value, `remove.${target}`);
|
|
22354
|
+
if (names.length > 0) {
|
|
22355
|
+
directives.push({ path: path2, target, names });
|
|
22356
|
+
}
|
|
22357
|
+
}
|
|
22358
|
+
return directives;
|
|
22359
|
+
}
|
|
22360
|
+
function stringList2(value, label) {
|
|
22361
|
+
const values = Array.isArray(value) ? value : [value];
|
|
22362
|
+
return values.map((item) => {
|
|
22363
|
+
if (typeof item !== "string" || item.trim().length === 0) {
|
|
22364
|
+
throw new Error(`${label} entries must be non-empty strings`);
|
|
22365
|
+
}
|
|
22366
|
+
return item.trim();
|
|
22367
|
+
});
|
|
22368
|
+
}
|
|
22369
|
+
var init_agent_document_merge = __esm({
|
|
22370
|
+
"../../packages/schemas/src/project-apply-files/agent-document-merge.ts"() {
|
|
22371
|
+
"use strict";
|
|
22372
|
+
init_source();
|
|
22373
|
+
}
|
|
22374
|
+
});
|
|
22375
|
+
|
|
22376
|
+
// ../../packages/schemas/src/project-apply-files/agent-fields/file-backed-string.ts
|
|
22377
|
+
import { posix as posix2 } from "path";
|
|
22378
|
+
function fileBackedStringField() {
|
|
22359
22379
|
return {
|
|
22360
|
-
|
|
22361
|
-
|
|
22362
|
-
prune: true,
|
|
22363
|
-
resources,
|
|
22364
|
-
assets
|
|
22380
|
+
target: "spec",
|
|
22381
|
+
read: (value, context) => resolveFileBackedString2(value, context)
|
|
22365
22382
|
};
|
|
22366
22383
|
}
|
|
22367
|
-
function
|
|
22368
|
-
if (
|
|
22369
|
-
return
|
|
22384
|
+
function resolveFileBackedString2(value, input) {
|
|
22385
|
+
if (!isRecord2(value) || !("file" in value)) {
|
|
22386
|
+
return value;
|
|
22387
|
+
}
|
|
22388
|
+
const file2 = value.file;
|
|
22389
|
+
if (typeof file2 !== "string" || file2.trim().length === 0) {
|
|
22390
|
+
throw new Error(
|
|
22391
|
+
`Invalid agent authoring file ${input.path}: ${input.field}.file must be a non-empty string`
|
|
22392
|
+
);
|
|
22393
|
+
}
|
|
22394
|
+
const filePath = file2.trim();
|
|
22395
|
+
if (isAbsoluteSourcePath(filePath) || /^[A-Za-z]+:\/\//.test(filePath)) {
|
|
22396
|
+
throw new Error(
|
|
22397
|
+
`Invalid agent authoring file ${input.path}: ${input.field}.file must be a relative path`
|
|
22398
|
+
);
|
|
22399
|
+
}
|
|
22400
|
+
const resolved = normalizeSourcePath(
|
|
22401
|
+
posix2.normalize(posix2.join(posix2.dirname(input.path), filePath))
|
|
22402
|
+
);
|
|
22403
|
+
const source = input.fileIndex.get(resolved);
|
|
22404
|
+
if (!source) {
|
|
22405
|
+
throw new Error(
|
|
22406
|
+
`Invalid agent authoring file ${input.path}: ${input.field}.file not found: ${filePath}`
|
|
22407
|
+
);
|
|
22370
22408
|
}
|
|
22371
|
-
return
|
|
22409
|
+
return Buffer.from(source.contentBase64, "base64").toString("utf8");
|
|
22372
22410
|
}
|
|
22373
|
-
|
|
22374
|
-
|
|
22375
|
-
|
|
22376
|
-
|
|
22377
|
-
|
|
22378
|
-
|
|
22379
|
-
|
|
22380
|
-
|
|
22381
|
-
|
|
22382
|
-
|
|
22383
|
-
|
|
22384
|
-
|
|
22385
|
-
|
|
22386
|
-
|
|
22387
|
-
|
|
22388
|
-
|
|
22389
|
-
|
|
22390
|
-
|
|
22391
|
-
|
|
22392
|
-
|
|
22411
|
+
var init_file_backed_string = __esm({
|
|
22412
|
+
"../../packages/schemas/src/project-apply-files/agent-fields/file-backed-string.ts"() {
|
|
22413
|
+
"use strict";
|
|
22414
|
+
init_source();
|
|
22415
|
+
}
|
|
22416
|
+
});
|
|
22417
|
+
|
|
22418
|
+
// ../../packages/schemas/src/project-apply-files/agent-fields/helpers.ts
|
|
22419
|
+
function emptyAgentDraft() {
|
|
22420
|
+
return { metadata: {}, spec: {} };
|
|
22421
|
+
}
|
|
22422
|
+
function cloneAgentDraft(draft) {
|
|
22423
|
+
return structuredClone(draft);
|
|
22424
|
+
}
|
|
22425
|
+
function isMetadataFieldKey(key) {
|
|
22426
|
+
return AGENT_METADATA_FIELD_KEYS.includes(key);
|
|
22427
|
+
}
|
|
22428
|
+
function mergeValues3(base, override) {
|
|
22429
|
+
if (override === void 0) {
|
|
22430
|
+
return base;
|
|
22431
|
+
}
|
|
22432
|
+
if (isRecord2(base) && isRecord2(override)) {
|
|
22433
|
+
const merged = { ...base };
|
|
22434
|
+
for (const [key, value] of Object.entries(override)) {
|
|
22435
|
+
merged[key] = mergeValues3(merged[key], value);
|
|
22393
22436
|
}
|
|
22437
|
+
return merged;
|
|
22394
22438
|
}
|
|
22395
|
-
return
|
|
22439
|
+
return override;
|
|
22396
22440
|
}
|
|
22397
22441
|
function stableResource(resource) {
|
|
22398
22442
|
return JSON.stringify({
|
|
22399
22443
|
kind: resource.kind,
|
|
22400
|
-
metadata:
|
|
22444
|
+
metadata: sortJson(resource.metadata),
|
|
22401
22445
|
spec: sortJson(resource.spec)
|
|
22402
22446
|
});
|
|
22403
22447
|
}
|
|
22404
|
-
function metadataComparable(metadata) {
|
|
22405
|
-
return sortJson(metadata);
|
|
22406
|
-
}
|
|
22407
22448
|
function sortJson(value) {
|
|
22408
22449
|
if (Array.isArray(value)) {
|
|
22409
22450
|
return value.map(sortJson);
|
|
@@ -22415,65 +22456,801 @@ function sortJson(value) {
|
|
|
22415
22456
|
}
|
|
22416
22457
|
return value;
|
|
22417
22458
|
}
|
|
22418
|
-
|
|
22419
|
-
|
|
22420
|
-
|
|
22421
|
-
|
|
22422
|
-
|
|
22423
|
-
|
|
22459
|
+
var CONTROL_FIELDS, AGENT_METADATA_FIELD_KEYS;
|
|
22460
|
+
var init_helpers = __esm({
|
|
22461
|
+
"../../packages/schemas/src/project-apply-files/agent-fields/helpers.ts"() {
|
|
22462
|
+
"use strict";
|
|
22463
|
+
init_source();
|
|
22464
|
+
CONTROL_FIELDS = /* @__PURE__ */ new Set(["import", "imports", "remove"]);
|
|
22465
|
+
AGENT_METADATA_FIELD_KEYS = ["name", "labels", "annotations"];
|
|
22466
|
+
}
|
|
22467
|
+
});
|
|
22468
|
+
|
|
22469
|
+
// ../../packages/schemas/src/project-apply-files/agent-fields/inline-resource.ts
|
|
22470
|
+
function inlineEnvironmentField() {
|
|
22471
|
+
return {
|
|
22472
|
+
target: "spec",
|
|
22473
|
+
merge: (base, override) => mergeValues3(base, override),
|
|
22474
|
+
compile: (value, context) => {
|
|
22475
|
+
if (!isRecord2(value)) {
|
|
22476
|
+
return { resources: [], value };
|
|
22477
|
+
}
|
|
22478
|
+
const resource = inlineEnvironmentResource2(value, context.path);
|
|
22479
|
+
return { resources: [resource], value: resource.metadata.name };
|
|
22480
|
+
}
|
|
22481
|
+
};
|
|
22482
|
+
}
|
|
22483
|
+
function inlineIdentityField() {
|
|
22484
|
+
return {
|
|
22485
|
+
target: "spec",
|
|
22486
|
+
merge: (base, override) => mergeValues3(base, override),
|
|
22487
|
+
compile: (value, context) => {
|
|
22488
|
+
if (!isRecord2(value)) {
|
|
22489
|
+
return { resources: [], value };
|
|
22490
|
+
}
|
|
22491
|
+
const resource = inlineIdentityResource2(
|
|
22492
|
+
value,
|
|
22493
|
+
context.draft,
|
|
22494
|
+
context.path
|
|
22495
|
+
);
|
|
22496
|
+
return { resources: [resource], value: resource.metadata.name };
|
|
22497
|
+
}
|
|
22498
|
+
};
|
|
22499
|
+
}
|
|
22500
|
+
function assertAgentAuthoringDocument(document, path2) {
|
|
22501
|
+
if (!isRecord2(document) || !("kind" in document)) {
|
|
22502
|
+
return;
|
|
22503
|
+
}
|
|
22504
|
+
if (document.kind === "session") {
|
|
22424
22505
|
throw new Error(
|
|
22425
|
-
|
|
22506
|
+
'Legacy resource kind "session" is no longer supported. Use .auto/agents with the root-level Agent facade format.'
|
|
22426
22507
|
);
|
|
22427
22508
|
}
|
|
22428
|
-
|
|
22429
|
-
|
|
22430
|
-
|
|
22431
|
-
|
|
22432
|
-
|
|
22433
|
-
|
|
22434
|
-
|
|
22435
|
-
|
|
22509
|
+
if (document.kind === RESOURCE_KIND_ENVIRONMENT || document.kind === RESOURCE_KIND_IDENTITY) {
|
|
22510
|
+
throw standaloneResourceError(document.kind, path2);
|
|
22511
|
+
}
|
|
22512
|
+
if (document.kind !== RESOURCE_KIND_AGENT) {
|
|
22513
|
+
throw new Error(
|
|
22514
|
+
`Unsupported apply resource kind "${String(document.kind)}"; supported kind is "${RESOURCE_KIND_AGENT}"`
|
|
22515
|
+
);
|
|
22516
|
+
}
|
|
22517
|
+
const parsed = AgentApplyRequestSchema.safeParse({
|
|
22518
|
+
metadata: document.metadata,
|
|
22519
|
+
spec: document.spec
|
|
22436
22520
|
});
|
|
22521
|
+
if (parsed.success) {
|
|
22522
|
+
throw new Error(
|
|
22523
|
+
`Legacy agent resource envelopes are no longer supported in ${path2}. Use the root-level Agent facade format under .auto/agents.`
|
|
22524
|
+
);
|
|
22525
|
+
}
|
|
22437
22526
|
}
|
|
22438
|
-
function
|
|
22439
|
-
|
|
22440
|
-
|
|
22441
|
-
|
|
22442
|
-
agent: resource.metadata.name,
|
|
22443
|
-
tools: resource.spec.tools
|
|
22444
|
-
});
|
|
22527
|
+
function parseAgentResource(draft, path2) {
|
|
22528
|
+
const parsed = AgentApplyRequestSchema.safeParse({
|
|
22529
|
+
metadata: draft.metadata,
|
|
22530
|
+
spec: draft.spec
|
|
22445
22531
|
});
|
|
22446
|
-
|
|
22447
|
-
|
|
22448
|
-
const agentsRoot = join5(root, primaryApplyDirectory(RESOURCE_KIND_AGENT));
|
|
22449
|
-
let entries;
|
|
22450
|
-
try {
|
|
22451
|
-
entries = readdirSync3(agentsRoot, { withFileTypes: true });
|
|
22452
|
-
} catch {
|
|
22453
|
-
return [];
|
|
22532
|
+
if (!parsed.success) {
|
|
22533
|
+
throw new Error(`Invalid compiled agent ${path2}: ${parsed.error.message}`);
|
|
22454
22534
|
}
|
|
22455
|
-
return
|
|
22535
|
+
return {
|
|
22456
22536
|
kind: RESOURCE_KIND_AGENT,
|
|
22457
|
-
|
|
22458
|
-
|
|
22459
|
-
}
|
|
22460
|
-
|
|
22461
|
-
|
|
22462
|
-
|
|
22463
|
-
|
|
22464
|
-
|
|
22465
|
-
|
|
22466
|
-
|
|
22537
|
+
metadata: parsed.data.metadata,
|
|
22538
|
+
spec: parsed.data.spec
|
|
22539
|
+
};
|
|
22540
|
+
}
|
|
22541
|
+
function inlineEnvironmentResource2(document, path2) {
|
|
22542
|
+
const parsed = EnvironmentApplyRequestSchema.safeParse(
|
|
22543
|
+
splitMetadataAndSpec(document)
|
|
22544
|
+
);
|
|
22545
|
+
if (!parsed.success) {
|
|
22546
|
+
throw new Error(
|
|
22547
|
+
`Invalid inline environment in ${path2}: ${parsed.error.message}`
|
|
22548
|
+
);
|
|
22549
|
+
}
|
|
22550
|
+
return {
|
|
22551
|
+
kind: RESOURCE_KIND_ENVIRONMENT,
|
|
22552
|
+
metadata: parsed.data.metadata,
|
|
22553
|
+
spec: parsed.data.spec
|
|
22554
|
+
};
|
|
22555
|
+
}
|
|
22556
|
+
function inlineIdentityResource2(document, agentDraft, path2) {
|
|
22557
|
+
const input = splitMetadataAndSpec(document);
|
|
22558
|
+
if (input.metadata.name === void 0 && typeof agentDraft.metadata.name === "string") {
|
|
22559
|
+
input.metadata.name = agentDraft.metadata.name;
|
|
22560
|
+
}
|
|
22561
|
+
const parsed = IdentityApplyRequestSchema.safeParse(input);
|
|
22562
|
+
if (!parsed.success) {
|
|
22563
|
+
throw new Error(
|
|
22564
|
+
`Invalid inline identity in ${path2}: ${parsed.error.message}`
|
|
22565
|
+
);
|
|
22566
|
+
}
|
|
22567
|
+
return {
|
|
22568
|
+
kind: RESOURCE_KIND_IDENTITY,
|
|
22569
|
+
metadata: parsed.data.metadata,
|
|
22570
|
+
spec: parsed.data.spec
|
|
22571
|
+
};
|
|
22572
|
+
}
|
|
22573
|
+
function splitMetadataAndSpec(document) {
|
|
22574
|
+
const metadata = {};
|
|
22575
|
+
const spec = {};
|
|
22576
|
+
for (const [key, value] of Object.entries(document)) {
|
|
22577
|
+
if (value === void 0) {
|
|
22578
|
+
continue;
|
|
22579
|
+
}
|
|
22580
|
+
if (isMetadataFieldKey(key)) {
|
|
22581
|
+
metadata[key] = value;
|
|
22582
|
+
continue;
|
|
22583
|
+
}
|
|
22584
|
+
spec[key] = value;
|
|
22585
|
+
}
|
|
22586
|
+
return { metadata, spec };
|
|
22587
|
+
}
|
|
22588
|
+
function standaloneResourceError(kind, path2) {
|
|
22589
|
+
if (kind === RESOURCE_KIND_ENVIRONMENT) {
|
|
22590
|
+
return new Error(
|
|
22591
|
+
`Standalone environment resources are no longer supported in ${path2}. Define environments inline in .auto/agents YAML, using fragment imports under .auto/fragments/environments for reused runtimes.`
|
|
22592
|
+
);
|
|
22593
|
+
}
|
|
22594
|
+
return new Error(
|
|
22595
|
+
`Standalone identity resources are no longer supported in ${path2}. Define identities inline on the owning .auto/agents YAML file.`
|
|
22596
|
+
);
|
|
22597
|
+
}
|
|
22598
|
+
var init_inline_resource = __esm({
|
|
22599
|
+
"../../packages/schemas/src/project-apply-files/agent-fields/inline-resource.ts"() {
|
|
22600
|
+
"use strict";
|
|
22601
|
+
init_agents();
|
|
22602
|
+
init_environments();
|
|
22603
|
+
init_identities();
|
|
22604
|
+
init_source();
|
|
22605
|
+
init_helpers();
|
|
22606
|
+
}
|
|
22607
|
+
});
|
|
22608
|
+
|
|
22609
|
+
// ../../packages/schemas/src/project-apply-files/agent-fields/named-array.ts
|
|
22610
|
+
function namedArrayField(options) {
|
|
22611
|
+
const remove = options.removable === false ? void 0 : removeNamedArray;
|
|
22612
|
+
return {
|
|
22613
|
+
target: "spec",
|
|
22614
|
+
merge: (base, override) => {
|
|
22615
|
+
if (!Array.isArray(base) || !Array.isArray(override)) {
|
|
22616
|
+
return mergeValues3(base, override);
|
|
22617
|
+
}
|
|
22618
|
+
return mergeNamedArray(base, override, options.itemKey);
|
|
22619
|
+
},
|
|
22620
|
+
remove: remove ? (value, names) => remove(value, names, options.itemKey) : void 0
|
|
22621
|
+
};
|
|
22622
|
+
}
|
|
22623
|
+
function mountsField() {
|
|
22624
|
+
return namedArrayField({
|
|
22625
|
+
itemKey: mountItemKey,
|
|
22626
|
+
removable: false
|
|
22627
|
+
});
|
|
22628
|
+
}
|
|
22629
|
+
function triggersField() {
|
|
22630
|
+
return {
|
|
22631
|
+
...namedArrayField({ itemKey: triggerItemKey }),
|
|
22632
|
+
compile: (value) => {
|
|
22633
|
+
return {
|
|
22634
|
+
resources: [],
|
|
22635
|
+
value: removeAuthoringTriggerNames(value)
|
|
22636
|
+
};
|
|
22637
|
+
}
|
|
22638
|
+
};
|
|
22639
|
+
}
|
|
22640
|
+
function mountItemKey(item) {
|
|
22641
|
+
if (!isRecord2(item)) {
|
|
22642
|
+
return void 0;
|
|
22643
|
+
}
|
|
22644
|
+
if (typeof item.name === "string") {
|
|
22645
|
+
return item.name;
|
|
22646
|
+
}
|
|
22647
|
+
if (typeof item.mountPath === "string") {
|
|
22648
|
+
return item.mountPath;
|
|
22649
|
+
}
|
|
22650
|
+
return void 0;
|
|
22651
|
+
}
|
|
22652
|
+
function triggerItemKey(item) {
|
|
22653
|
+
if (!isRecord2(item)) {
|
|
22654
|
+
return void 0;
|
|
22655
|
+
}
|
|
22656
|
+
if (typeof item.name === "string") {
|
|
22657
|
+
return item.name;
|
|
22658
|
+
}
|
|
22659
|
+
if (typeof item.event === "string") {
|
|
22660
|
+
return item.event;
|
|
22661
|
+
}
|
|
22662
|
+
if (Array.isArray(item.events)) {
|
|
22663
|
+
return item.events.filter((event) => typeof event === "string").join(",");
|
|
22664
|
+
}
|
|
22665
|
+
if (typeof item.cron === "string") {
|
|
22666
|
+
return `cron:${item.cron}:${typeof item.timezone === "string" ? item.timezone : ""}`;
|
|
22667
|
+
}
|
|
22668
|
+
return void 0;
|
|
22669
|
+
}
|
|
22670
|
+
function mergeNamedArray(base, override, itemKey) {
|
|
22671
|
+
const merged = [...base];
|
|
22672
|
+
const indexByKey = /* @__PURE__ */ new Map();
|
|
22673
|
+
for (const [index, item] of merged.entries()) {
|
|
22674
|
+
const key = itemKey(item);
|
|
22675
|
+
if (key) {
|
|
22676
|
+
indexByKey.set(key, index);
|
|
22677
|
+
}
|
|
22678
|
+
}
|
|
22679
|
+
for (const item of override) {
|
|
22680
|
+
const key = itemKey(item);
|
|
22681
|
+
if (key && indexByKey.has(key)) {
|
|
22682
|
+
merged[indexByKey.get(key) ?? 0] = mergeValues3(
|
|
22683
|
+
merged[indexByKey.get(key) ?? 0],
|
|
22684
|
+
item
|
|
22685
|
+
);
|
|
22686
|
+
continue;
|
|
22687
|
+
}
|
|
22688
|
+
if (key) {
|
|
22689
|
+
indexByKey.set(key, merged.length);
|
|
22690
|
+
}
|
|
22691
|
+
merged.push(item);
|
|
22692
|
+
}
|
|
22693
|
+
return merged;
|
|
22694
|
+
}
|
|
22695
|
+
function removeNamedArray(value, names, itemKey) {
|
|
22696
|
+
if (!Array.isArray(value)) {
|
|
22697
|
+
return value;
|
|
22698
|
+
}
|
|
22699
|
+
return value.filter((item) => !names.includes(itemKey(item) ?? ""));
|
|
22700
|
+
}
|
|
22701
|
+
function removeAuthoringTriggerNames(value) {
|
|
22702
|
+
if (!Array.isArray(value)) {
|
|
22703
|
+
return value;
|
|
22704
|
+
}
|
|
22705
|
+
return value.map((trigger) => {
|
|
22706
|
+
if (!isRecord2(trigger) || !("name" in trigger)) {
|
|
22707
|
+
return trigger;
|
|
22708
|
+
}
|
|
22709
|
+
const next = { ...trigger };
|
|
22710
|
+
delete next.name;
|
|
22711
|
+
return next;
|
|
22712
|
+
});
|
|
22713
|
+
}
|
|
22714
|
+
var init_named_array = __esm({
|
|
22715
|
+
"../../packages/schemas/src/project-apply-files/agent-fields/named-array.ts"() {
|
|
22716
|
+
"use strict";
|
|
22717
|
+
init_source();
|
|
22718
|
+
init_helpers();
|
|
22719
|
+
}
|
|
22720
|
+
});
|
|
22721
|
+
|
|
22722
|
+
// ../../packages/schemas/src/project-apply-files/agent-fields/named-map.ts
|
|
22723
|
+
function namedMapField() {
|
|
22724
|
+
return {
|
|
22725
|
+
target: "spec",
|
|
22726
|
+
merge: (base, override) => mergeValues3(base, override),
|
|
22727
|
+
remove: (value, names) => {
|
|
22728
|
+
if (!isRecord2(value)) {
|
|
22729
|
+
return value;
|
|
22730
|
+
}
|
|
22731
|
+
const next = { ...value };
|
|
22732
|
+
for (const name of names) {
|
|
22733
|
+
delete next[name];
|
|
22734
|
+
}
|
|
22735
|
+
return next;
|
|
22736
|
+
}
|
|
22737
|
+
};
|
|
22738
|
+
}
|
|
22739
|
+
var init_named_map = __esm({
|
|
22740
|
+
"../../packages/schemas/src/project-apply-files/agent-fields/named-map.ts"() {
|
|
22741
|
+
"use strict";
|
|
22742
|
+
init_source();
|
|
22743
|
+
init_helpers();
|
|
22744
|
+
}
|
|
22745
|
+
});
|
|
22746
|
+
|
|
22747
|
+
// ../../packages/schemas/src/project-apply-files/agent-fields/scalar.ts
|
|
22748
|
+
function metadataField() {
|
|
22749
|
+
return { target: "metadata" };
|
|
22750
|
+
}
|
|
22751
|
+
function specField() {
|
|
22752
|
+
return { target: "spec" };
|
|
22753
|
+
}
|
|
22754
|
+
var init_scalar = __esm({
|
|
22755
|
+
"../../packages/schemas/src/project-apply-files/agent-fields/scalar.ts"() {
|
|
22756
|
+
"use strict";
|
|
22757
|
+
}
|
|
22758
|
+
});
|
|
22759
|
+
|
|
22760
|
+
// ../../packages/schemas/src/project-apply-files/agent-fields/index.ts
|
|
22761
|
+
function parseAgentDraft(document, path2, fileIndex) {
|
|
22762
|
+
assertAgentAuthoringDocument(document, path2);
|
|
22763
|
+
const sanitized = sanitizedAgentDocument2(document);
|
|
22764
|
+
assertNoLegacyEnvelopeFields(sanitized, path2);
|
|
22765
|
+
const draft = emptyAgentDraft();
|
|
22766
|
+
for (const [key, value] of Object.entries(sanitized)) {
|
|
22767
|
+
if (value === void 0) {
|
|
22768
|
+
continue;
|
|
22769
|
+
}
|
|
22770
|
+
const field = AGENT_FIELDS[key];
|
|
22771
|
+
if (!field) {
|
|
22772
|
+
continue;
|
|
22773
|
+
}
|
|
22774
|
+
const target = draft[field.target];
|
|
22775
|
+
assertNoDuplicateFacadeField2({
|
|
22776
|
+
path: path2,
|
|
22777
|
+
field: key,
|
|
22778
|
+
target: `${field.target}.${key}`,
|
|
22779
|
+
targetValue: target[key]
|
|
22780
|
+
});
|
|
22781
|
+
target[key] = field.read ? field.read(value, { path: path2, field: key, fileIndex }) : value;
|
|
22782
|
+
}
|
|
22783
|
+
return draft;
|
|
22784
|
+
}
|
|
22785
|
+
function mergeAgentDrafts(base, override) {
|
|
22786
|
+
return {
|
|
22787
|
+
metadata: mergeDraftTarget("metadata", base.metadata, override.metadata),
|
|
22788
|
+
spec: mergeDraftTarget("spec", base.spec, override.spec)
|
|
22789
|
+
};
|
|
22790
|
+
}
|
|
22791
|
+
function applyAgentDraftRemoval(draft, removal) {
|
|
22792
|
+
const field = AGENT_FIELDS[removal.target];
|
|
22793
|
+
if (!field?.remove) {
|
|
22794
|
+
assertSupportedAgentRemovalTarget(removal.target);
|
|
22795
|
+
return draft;
|
|
22796
|
+
}
|
|
22797
|
+
const next = cloneAgentDraft(draft);
|
|
22798
|
+
const target = next[field.target];
|
|
22799
|
+
const current = target[removal.target];
|
|
22800
|
+
const updated = field.remove(current, removal.names, {
|
|
22801
|
+
field: removal.target
|
|
22802
|
+
});
|
|
22803
|
+
if (updated !== void 0 || current !== void 0) {
|
|
22804
|
+
target[removal.target] = updated;
|
|
22805
|
+
}
|
|
22806
|
+
return next;
|
|
22807
|
+
}
|
|
22808
|
+
function assertSupportedAgentRemovalTarget(target) {
|
|
22809
|
+
const supported = supportedRemovalTargets();
|
|
22810
|
+
if (!supported.includes(target)) {
|
|
22811
|
+
throw new Error(
|
|
22812
|
+
`Unsupported agent remove target "${target}"; supported targets are ${supported.join(", ")}`
|
|
22813
|
+
);
|
|
22814
|
+
}
|
|
22815
|
+
}
|
|
22816
|
+
function compileAgentDraftResources(draft, path2) {
|
|
22817
|
+
const next = cloneAgentDraft(draft);
|
|
22818
|
+
const resources = [];
|
|
22819
|
+
for (const [key, field] of Object.entries(AGENT_FIELDS)) {
|
|
22820
|
+
if (field.target !== "spec") {
|
|
22821
|
+
continue;
|
|
22822
|
+
}
|
|
22823
|
+
const value = next.spec[key];
|
|
22824
|
+
if (value === void 0) {
|
|
22825
|
+
continue;
|
|
22826
|
+
}
|
|
22827
|
+
const context = { path: path2, draft: next };
|
|
22828
|
+
if (field.compile) {
|
|
22829
|
+
const compiled = field.compile(value, context);
|
|
22830
|
+
resources.push(...compiled.resources);
|
|
22831
|
+
next.spec[key] = compiled.value;
|
|
22832
|
+
}
|
|
22833
|
+
}
|
|
22834
|
+
const resource = parseAgentResource(next, path2);
|
|
22835
|
+
return { resource, resources: [...resources, resource] };
|
|
22836
|
+
}
|
|
22837
|
+
function sanitizedAgentDocument2(document) {
|
|
22838
|
+
return Object.fromEntries(
|
|
22839
|
+
Object.entries(document).filter(([key]) => !CONTROL_FIELDS.has(key))
|
|
22840
|
+
);
|
|
22841
|
+
}
|
|
22842
|
+
function assertNoLegacyEnvelopeFields(document, path2) {
|
|
22843
|
+
const legacyEnvelopeFields = ["kind", "metadata", "spec"].filter(
|
|
22844
|
+
(field) => field in document
|
|
22845
|
+
);
|
|
22846
|
+
if (legacyEnvelopeFields.length > 0) {
|
|
22847
|
+
throw new Error(
|
|
22848
|
+
`Invalid agent authoring file ${path2}: legacy resource envelope fields are no longer supported (${legacyEnvelopeFields.join(", ")}). Use root-level Agent facade fields instead.`
|
|
22849
|
+
);
|
|
22850
|
+
}
|
|
22851
|
+
}
|
|
22852
|
+
function mergeDraftTarget(target, base, override) {
|
|
22853
|
+
const merged = { ...base };
|
|
22854
|
+
for (const [key, value] of Object.entries(override)) {
|
|
22855
|
+
const field = AGENT_FIELDS[key];
|
|
22856
|
+
const merge2 = field?.target === target ? field.merge : void 0;
|
|
22857
|
+
merged[key] = merge2 ? merge2(merged[key], value, { field: key }) : mergeValues3(merged[key], value);
|
|
22858
|
+
}
|
|
22859
|
+
return merged;
|
|
22860
|
+
}
|
|
22861
|
+
function assertNoDuplicateFacadeField2(input) {
|
|
22862
|
+
if (input.targetValue !== void 0) {
|
|
22863
|
+
throw new Error(
|
|
22864
|
+
`Invalid agent authoring file ${input.path}: ${input.field} duplicates ${input.target}`
|
|
22865
|
+
);
|
|
22866
|
+
}
|
|
22867
|
+
}
|
|
22868
|
+
function supportedRemovalTargets() {
|
|
22869
|
+
return ["tools", "triggers"].filter((key) => AGENT_FIELDS[key]?.remove);
|
|
22870
|
+
}
|
|
22871
|
+
var AGENT_FIELDS;
|
|
22872
|
+
var init_agent_fields = __esm({
|
|
22873
|
+
"../../packages/schemas/src/project-apply-files/agent-fields/index.ts"() {
|
|
22874
|
+
"use strict";
|
|
22875
|
+
init_file_backed_string();
|
|
22876
|
+
init_helpers();
|
|
22877
|
+
init_inline_resource();
|
|
22878
|
+
init_named_array();
|
|
22879
|
+
init_named_map();
|
|
22880
|
+
init_scalar();
|
|
22881
|
+
AGENT_FIELDS = {
|
|
22882
|
+
name: metadataField(),
|
|
22883
|
+
labels: metadataField(),
|
|
22884
|
+
annotations: metadataField(),
|
|
22885
|
+
harness: specField(),
|
|
22886
|
+
systemPrompt: fileBackedStringField(),
|
|
22887
|
+
environment: inlineEnvironmentField(),
|
|
22888
|
+
identity: inlineIdentityField(),
|
|
22889
|
+
initialPrompt: fileBackedStringField(),
|
|
22890
|
+
env: specField(),
|
|
22891
|
+
mounts: mountsField(),
|
|
22892
|
+
triggers: triggersField(),
|
|
22893
|
+
workingDirectory: specField(),
|
|
22894
|
+
tools: namedMapField()
|
|
22895
|
+
};
|
|
22896
|
+
}
|
|
22897
|
+
});
|
|
22898
|
+
|
|
22899
|
+
// ../../packages/schemas/src/project-apply-files/agent-authoring.ts
|
|
22900
|
+
function readApplyDocument(path2, document, fileIndex) {
|
|
22901
|
+
assertAgentAuthoringDocument(document, path2);
|
|
22902
|
+
const result = compileAgentDocumentValue(document, path2, fileIndex);
|
|
22903
|
+
return result.resources.map((resource) => ({
|
|
22904
|
+
resource,
|
|
22905
|
+
generatedFromAgent: resource !== result.resource
|
|
22906
|
+
}));
|
|
22907
|
+
}
|
|
22908
|
+
function validateAgentFragmentDocument(document, path2, context) {
|
|
22909
|
+
const normalizedPath = normalizeSourcePath(path2);
|
|
22910
|
+
if (context.stack.includes(normalizedPath)) {
|
|
22911
|
+
throw new Error(
|
|
22912
|
+
`Agent import cycle detected: ${[...context.stack, normalizedPath].join(" -> ")}`
|
|
22913
|
+
);
|
|
22914
|
+
}
|
|
22915
|
+
if (!isRecord2(document)) {
|
|
22916
|
+
throw new Error(`Invalid agent fragment file ${path2}: expected object`);
|
|
22917
|
+
}
|
|
22918
|
+
for (const imported of importPaths2(document).map(
|
|
22919
|
+
(importPath) => resolveImportPath2(importPath, normalizedPath, context.fileIndex)
|
|
22920
|
+
)) {
|
|
22921
|
+
validateAgentFragmentDocument(
|
|
22922
|
+
readSingleDocument2(imported, context.fileIndex),
|
|
22923
|
+
imported,
|
|
22924
|
+
{
|
|
22925
|
+
fileIndex: context.fileIndex,
|
|
22926
|
+
stack: [...context.stack, normalizedPath]
|
|
22927
|
+
}
|
|
22928
|
+
);
|
|
22929
|
+
}
|
|
22930
|
+
for (const removal of removalDirectives2(document, normalizedPath)) {
|
|
22931
|
+
assertSupportedAgentRemovalTarget(removal.target);
|
|
22932
|
+
}
|
|
22933
|
+
parseAgentDraft(document, normalizedPath, context.fileIndex);
|
|
22934
|
+
}
|
|
22935
|
+
function dedupeGeneratedResources(records) {
|
|
22936
|
+
const recordsByKey = /* @__PURE__ */ new Map();
|
|
22937
|
+
const deduped = [];
|
|
22938
|
+
for (const record2 of records) {
|
|
22939
|
+
const { resource } = record2;
|
|
22940
|
+
const key = `${resource.kind}/${resource.metadata.name}`;
|
|
22941
|
+
const existing = recordsByKey.get(key);
|
|
22942
|
+
if (!existing) {
|
|
22943
|
+
recordsByKey.set(key, record2);
|
|
22944
|
+
deduped.push(record2);
|
|
22945
|
+
continue;
|
|
22946
|
+
}
|
|
22947
|
+
if (!record2.generatedFromAgent && !existing.generatedFromAgent) {
|
|
22948
|
+
deduped.push(record2);
|
|
22949
|
+
continue;
|
|
22950
|
+
}
|
|
22951
|
+
if (stableResource(resource) !== stableResource(existing.resource)) {
|
|
22952
|
+
throw new Error(
|
|
22953
|
+
`Conflicting generated resource "${key}" from agent authoring. Inline generated resources must be identical when they share a name.`
|
|
22954
|
+
);
|
|
22955
|
+
}
|
|
22956
|
+
}
|
|
22957
|
+
return deduped.map((record2) => record2.resource);
|
|
22958
|
+
}
|
|
22959
|
+
function compileAgentDocumentValue(document, path2, fileIndex) {
|
|
22960
|
+
return compileAgentDraftResources(
|
|
22961
|
+
compileAgentDocument2(document, path2, {
|
|
22962
|
+
fileIndex,
|
|
22963
|
+
stack: []
|
|
22964
|
+
}),
|
|
22965
|
+
path2
|
|
22966
|
+
);
|
|
22967
|
+
}
|
|
22968
|
+
function compileAgentDocument2(document, path2, context) {
|
|
22969
|
+
const normalizedPath = normalizeSourcePath(path2);
|
|
22970
|
+
if (context.stack.includes(normalizedPath)) {
|
|
22971
|
+
throw new Error(
|
|
22972
|
+
`Agent import cycle detected: ${[...context.stack, normalizedPath].join(" -> ")}`
|
|
22973
|
+
);
|
|
22974
|
+
}
|
|
22975
|
+
if (!isRecord2(document)) {
|
|
22976
|
+
throw new Error(`Invalid agent authoring file ${path2}: expected object`);
|
|
22977
|
+
}
|
|
22978
|
+
let merged = emptyAgentDraft();
|
|
22979
|
+
for (const imported of importPaths2(document).map(
|
|
22980
|
+
(importPath) => resolveImportPath2(importPath, normalizedPath, context.fileIndex)
|
|
22981
|
+
)) {
|
|
22982
|
+
merged = mergeAgentDrafts(
|
|
22983
|
+
merged,
|
|
22984
|
+
compileAgentDocument2(
|
|
22985
|
+
readSingleDocument2(imported, context.fileIndex),
|
|
22986
|
+
imported,
|
|
22987
|
+
{
|
|
22988
|
+
fileIndex: context.fileIndex,
|
|
22989
|
+
stack: [...context.stack, normalizedPath]
|
|
22990
|
+
}
|
|
22991
|
+
)
|
|
22992
|
+
);
|
|
22993
|
+
}
|
|
22994
|
+
for (const removal of removalDirectives2(document, normalizedPath)) {
|
|
22995
|
+
merged = applyAgentDraftRemoval(merged, removal);
|
|
22996
|
+
}
|
|
22997
|
+
return mergeAgentDrafts(
|
|
22998
|
+
merged,
|
|
22999
|
+
parseAgentDraft(document, normalizedPath, context.fileIndex)
|
|
23000
|
+
);
|
|
23001
|
+
}
|
|
23002
|
+
var init_agent_authoring = __esm({
|
|
23003
|
+
"../../packages/schemas/src/project-apply-files/agent-authoring.ts"() {
|
|
23004
|
+
"use strict";
|
|
23005
|
+
init_agent_document_merge();
|
|
23006
|
+
init_agent_fields();
|
|
23007
|
+
init_source();
|
|
23008
|
+
}
|
|
23009
|
+
});
|
|
23010
|
+
|
|
23011
|
+
// ../../packages/schemas/src/project-apply-files/apply-result.ts
|
|
23012
|
+
function appliedResourceKind(request, response, index) {
|
|
23013
|
+
const plannedResources = response.plan.filter(
|
|
23014
|
+
(item) => item.action !== "archive" && isProjectApplyResourceKind(item.kind)
|
|
23015
|
+
);
|
|
23016
|
+
const kind = plannedResources[index]?.kind ?? request.resources[index]?.kind;
|
|
23017
|
+
if (!kind) {
|
|
23018
|
+
throw new Error(
|
|
23019
|
+
applyResourceKindError(request, response, plannedResources, index)
|
|
23020
|
+
);
|
|
23021
|
+
}
|
|
23022
|
+
return kind;
|
|
23023
|
+
}
|
|
23024
|
+
function mcpOAuthAgentToolConnectionsFromApplyRequest(request) {
|
|
23025
|
+
return request.resources.filter((resource) => resource.kind === RESOURCE_KIND_AGENT).flatMap((resource) => {
|
|
23026
|
+
return mcpOAuthAgentToolConnectionsFromAgentTools({
|
|
23027
|
+
agent: resource.metadata.name,
|
|
23028
|
+
tools: resource.spec.tools
|
|
23029
|
+
});
|
|
23030
|
+
});
|
|
23031
|
+
}
|
|
23032
|
+
function mcpOAuthAgentToolConnectionsFromAppliedResources(resources) {
|
|
23033
|
+
return resources.filter((item) => item.kind === RESOURCE_KIND_AGENT).flatMap((item) => {
|
|
23034
|
+
const resource = item.resource;
|
|
23035
|
+
return mcpOAuthAgentToolConnectionsFromAgentTools({
|
|
23036
|
+
agent: resource.metadata.name,
|
|
23037
|
+
tools: resource.spec.tools
|
|
23038
|
+
});
|
|
23039
|
+
});
|
|
23040
|
+
}
|
|
23041
|
+
function isProjectApplyResourceKind(kind) {
|
|
23042
|
+
return kind === RESOURCE_KIND_CONNECTION || kind === RESOURCE_KIND_IDENTITY || kind === RESOURCE_KIND_ENVIRONMENT || kind === RESOURCE_KIND_AGENT;
|
|
23043
|
+
}
|
|
23044
|
+
function applyResourceKindError(request, response, plannedResources, index) {
|
|
23045
|
+
const planLabels = plannedResources.map(
|
|
23046
|
+
(resource) => `${resource.kind}/${resource.name}`
|
|
23047
|
+
);
|
|
23048
|
+
const requestLabels = request.resources.map(resourceLabel);
|
|
23049
|
+
return [
|
|
23050
|
+
`Apply response did not include a resource kind for item ${index}.`,
|
|
23051
|
+
`Unable to infer from ${planLabels.length} non-archived plan item(s) or ${requestLabels.length} request resource(s).`,
|
|
23052
|
+
`Apply response contained ${response.resources.length} applied resource item(s).`,
|
|
23053
|
+
`Nearby plan items: ${nearbyLabels(planLabels, index)}.`,
|
|
23054
|
+
`Nearby request resources: ${nearbyLabels(requestLabels, index)}.`,
|
|
23055
|
+
"This usually means the server returned an applied resource that was not represented in the apply plan or original request."
|
|
23056
|
+
].join(" ");
|
|
23057
|
+
}
|
|
23058
|
+
function nearbyLabels(labels, index) {
|
|
23059
|
+
if (labels.length === 0) {
|
|
23060
|
+
return "none";
|
|
23061
|
+
}
|
|
23062
|
+
const start = Math.max(0, Math.min(index - 2, labels.length - 3));
|
|
23063
|
+
const end = Math.min(labels.length, index + 3);
|
|
23064
|
+
return labels.slice(start, end).map((label, offset) => `${start + offset} ${label}`).join(", ");
|
|
23065
|
+
}
|
|
23066
|
+
function resourceLabel(resource) {
|
|
23067
|
+
return `${resource.kind}/${resource.metadata.name}`;
|
|
23068
|
+
}
|
|
23069
|
+
function mcpOAuthAgentToolConnectionsFromAgentTools(input) {
|
|
23070
|
+
return Object.entries(input.tools).flatMap(([alias, tool]) => {
|
|
23071
|
+
if (tool.kind !== "mcp_remote" || tool.disabled || tool.auth.kind !== "mcp_oauth") {
|
|
23072
|
+
return [];
|
|
23073
|
+
}
|
|
23074
|
+
return [
|
|
23075
|
+
{
|
|
23076
|
+
agent: input.agent,
|
|
23077
|
+
tool: alias,
|
|
23078
|
+
connection: tool.auth.connection
|
|
23079
|
+
}
|
|
23080
|
+
];
|
|
23081
|
+
});
|
|
23082
|
+
}
|
|
23083
|
+
var init_apply_result = __esm({
|
|
23084
|
+
"../../packages/schemas/src/project-apply-files/apply-result.ts"() {
|
|
23085
|
+
"use strict";
|
|
23086
|
+
init_agents();
|
|
23087
|
+
init_connections();
|
|
23088
|
+
init_environments();
|
|
23089
|
+
init_identities();
|
|
23090
|
+
}
|
|
23091
|
+
});
|
|
23092
|
+
|
|
23093
|
+
// ../../packages/schemas/src/project-apply-files/assets.ts
|
|
23094
|
+
import { createHash as createHash3 } from "crypto";
|
|
23095
|
+
import { extname as extname2 } from "path";
|
|
23096
|
+
function readApplyAssets(resources, readAsset) {
|
|
23097
|
+
const assets = {};
|
|
23098
|
+
for (const resource of resources) {
|
|
23099
|
+
const target = avatarAssetTarget(resource);
|
|
23100
|
+
if (!target || assets[target.asset]) {
|
|
23101
|
+
continue;
|
|
23102
|
+
}
|
|
23103
|
+
if (!isAvatarAssetPathShapeValid(target.asset)) {
|
|
23104
|
+
throw new Error(
|
|
23105
|
+
`Invalid identity avatar asset for "${target.resourceName}": asset path must be under .auto/assets`
|
|
23106
|
+
);
|
|
23107
|
+
}
|
|
23108
|
+
const source = readAsset(target);
|
|
23109
|
+
if (!source) {
|
|
23110
|
+
throw new Error(
|
|
23111
|
+
`Invalid identity avatar asset for "${target.resourceName}": ${target.asset} does not exist`
|
|
23112
|
+
);
|
|
23113
|
+
}
|
|
23114
|
+
assets[target.asset] = projectApplyAssetFromSource({
|
|
23115
|
+
resourceName: target.resourceName,
|
|
23116
|
+
source
|
|
23117
|
+
});
|
|
23118
|
+
}
|
|
23119
|
+
return assets;
|
|
23120
|
+
}
|
|
23121
|
+
function projectApplyAssetFromSource(input) {
|
|
23122
|
+
const bytes = Buffer.from(input.source.bytes);
|
|
23123
|
+
if (bytes.length === 0 || bytes.length > MAX_AVATAR_ASSET_BYTES) {
|
|
23124
|
+
throw new Error(
|
|
23125
|
+
`Invalid identity avatar asset for "${input.resourceName}": asset must be ${MAX_AVATAR_ASSET_BYTES} bytes or smaller`
|
|
23126
|
+
);
|
|
23127
|
+
}
|
|
23128
|
+
const extension = extname2(input.source.path).toLowerCase();
|
|
23129
|
+
if (!ALLOWED_AVATAR_EXTENSIONS.has(extension)) {
|
|
23130
|
+
throw new Error(
|
|
23131
|
+
`Invalid identity avatar asset for "${input.resourceName}": asset must be a PNG or JPEG image`
|
|
23132
|
+
);
|
|
23133
|
+
}
|
|
23134
|
+
const dimensionsProblem = avatarAssetDimensionsProblem(bytes);
|
|
23135
|
+
if (dimensionsProblem) {
|
|
23136
|
+
throw new Error(
|
|
23137
|
+
`Invalid identity avatar asset for "${input.resourceName}": ${dimensionsProblem}`
|
|
23138
|
+
);
|
|
23139
|
+
}
|
|
23140
|
+
return {
|
|
23141
|
+
sha256: createHash3("sha256").update(bytes).digest("hex"),
|
|
23142
|
+
contentType: extension === ".png" ? "image/png" : "image/jpeg",
|
|
23143
|
+
dataBase64: bytes.toString("base64")
|
|
23144
|
+
};
|
|
23145
|
+
}
|
|
23146
|
+
function avatarAssetTarget(resource) {
|
|
23147
|
+
if (resource.kind === RESOURCE_KIND_IDENTITY) {
|
|
23148
|
+
const asset = resource.spec.avatar?.asset;
|
|
23149
|
+
return asset ? { asset, resourceName: resource.metadata.name } : void 0;
|
|
23150
|
+
}
|
|
23151
|
+
if (resource.kind === RESOURCE_KIND_AGENT && typeof resource.spec.identity === "object" && resource.spec.identity !== null && !Array.isArray(resource.spec.identity)) {
|
|
23152
|
+
const asset = resource.spec.identity.avatar?.asset;
|
|
23153
|
+
return asset ? { asset, resourceName: resource.metadata.name } : void 0;
|
|
23154
|
+
}
|
|
23155
|
+
return void 0;
|
|
23156
|
+
}
|
|
23157
|
+
var ALLOWED_AVATAR_EXTENSIONS;
|
|
23158
|
+
var init_assets2 = __esm({
|
|
23159
|
+
"../../packages/schemas/src/project-apply-files/assets.ts"() {
|
|
23160
|
+
"use strict";
|
|
23161
|
+
init_agents();
|
|
23162
|
+
init_identities();
|
|
23163
|
+
ALLOWED_AVATAR_EXTENSIONS = /* @__PURE__ */ new Set([".jpg", ".jpeg", ".png"]);
|
|
23164
|
+
}
|
|
23165
|
+
});
|
|
23166
|
+
|
|
23167
|
+
// ../../packages/schemas/src/project-apply-files/index.ts
|
|
23168
|
+
function readProjectApplyDirectorySource(input) {
|
|
23169
|
+
const resourceRoot = normalizeSourcePath(input.resourceRoot ?? "");
|
|
23170
|
+
const displayResourceRoot2 = input.displayResourceRoot ?? (resourceRoot || ".auto");
|
|
23171
|
+
const fileIndex = sourceFileIndex(input.files);
|
|
23172
|
+
assertNoLegacySessionSourceFiles(
|
|
23173
|
+
input.files,
|
|
23174
|
+
resourceRoot,
|
|
23175
|
+
displayResourceRoot2
|
|
23176
|
+
);
|
|
23177
|
+
assertNoStandaloneSourceFiles(input.files, resourceRoot, displayResourceRoot2);
|
|
23178
|
+
assertValidFragmentSourceFiles(input.files, resourceRoot, fileIndex);
|
|
23179
|
+
const agentFiles = input.files.filter(
|
|
23180
|
+
(file2) => isResourceFileUnderDirectory(
|
|
23181
|
+
file2.path,
|
|
23182
|
+
sourcePathJoin(resourceRoot, primaryApplyDirectory())
|
|
23183
|
+
)
|
|
23184
|
+
).sort((left, right) => left.path.localeCompare(right.path));
|
|
23185
|
+
const resourceRecords = [];
|
|
23186
|
+
for (const file2 of agentFiles) {
|
|
23187
|
+
const request = readProjectApplyDocumentSourceFile(file2, { fileIndex });
|
|
23188
|
+
resourceRecords.push(
|
|
23189
|
+
...request.resources.map((resource) => ({
|
|
23190
|
+
resource,
|
|
23191
|
+
generatedFromAgent: resource.kind !== RESOURCE_KIND_AGENT
|
|
23192
|
+
}))
|
|
23193
|
+
);
|
|
23194
|
+
}
|
|
23195
|
+
const resources = dedupeGeneratedResources(resourceRecords);
|
|
23196
|
+
if (agentFiles.length === 0 && !input.allowEmpty) {
|
|
23197
|
+
throw new Error(input.emptyMessage ?? "No resource files found");
|
|
23198
|
+
}
|
|
23199
|
+
return ProjectApplyRequestSchema.parse({
|
|
23200
|
+
delete: [],
|
|
23201
|
+
dryRun: input.dryRun ?? false,
|
|
23202
|
+
prune: input.prune ?? true,
|
|
23203
|
+
resources,
|
|
23204
|
+
assets: readApplyAssets(resources, input.readAsset)
|
|
23205
|
+
});
|
|
23206
|
+
}
|
|
23207
|
+
function readProjectApplyFileSource(input) {
|
|
23208
|
+
const request = readProjectApplyDocumentSourceFile(input.file, {
|
|
23209
|
+
fileIndex: sourceFileIndex(input.files ?? [input.file])
|
|
23210
|
+
});
|
|
23211
|
+
return ProjectApplyRequestSchema.parse({
|
|
23212
|
+
...request,
|
|
23213
|
+
assets: readApplyAssets(request.resources, input.readAsset)
|
|
23214
|
+
});
|
|
23215
|
+
}
|
|
23216
|
+
function readProjectApplyDocumentSourceFile(file2, options = {}) {
|
|
23217
|
+
const fileIndex = options.fileIndex ?? sourceFileIndex([file2]);
|
|
23218
|
+
const documents = readDocumentsFromSource(file2);
|
|
23219
|
+
if (documents.length === 0) {
|
|
23220
|
+
throw new Error(`Invalid apply file: ${file2.path} is empty`);
|
|
23221
|
+
}
|
|
23222
|
+
if (documents.length === 1) {
|
|
23223
|
+
const system = ProjectApplySystemConfigSchema.safeParse(documents[0]);
|
|
23224
|
+
if (system.success) {
|
|
23225
|
+
return ProjectApplyRequestSchema.parse(system.data.spec);
|
|
23226
|
+
}
|
|
22467
23227
|
}
|
|
22468
|
-
const
|
|
22469
|
-
|
|
23228
|
+
const resourceRecords = documents.flatMap(
|
|
23229
|
+
(document) => readApplyDocument(file2.path, document, fileIndex)
|
|
23230
|
+
);
|
|
23231
|
+
return ProjectApplyRequestSchema.parse({
|
|
23232
|
+
delete: [],
|
|
23233
|
+
dryRun: false,
|
|
23234
|
+
prune: false,
|
|
23235
|
+
resources: dedupeGeneratedResources(resourceRecords),
|
|
23236
|
+
assets: {}
|
|
23237
|
+
});
|
|
23238
|
+
}
|
|
23239
|
+
function assertNoLegacySessionSourceFiles(files, resourceRoot, displayResourceRoot2) {
|
|
23240
|
+
const legacyFiles = files.filter(
|
|
23241
|
+
(file2) => isResourceFileUnderDirectory(
|
|
23242
|
+
file2.path,
|
|
23243
|
+
sourcePathJoin(resourceRoot, "sessions")
|
|
23244
|
+
)
|
|
23245
|
+
);
|
|
23246
|
+
if (legacyFiles.length === 0) {
|
|
22470
23247
|
return;
|
|
22471
23248
|
}
|
|
22472
23249
|
throw new Error(
|
|
22473
|
-
`Legacy
|
|
23250
|
+
`Legacy ${sourcePathJoin(displayResourceRoot2, "sessions")} files are no longer supported. Move ${legacyFiles.length === 1 ? "this file" : "these files"} to ${sourcePathJoin(displayResourceRoot2, "agents")} and use the root-level Agent facade format: ${legacyFiles.map((file2) => file2.path).join(", ")}`
|
|
22474
23251
|
);
|
|
22475
23252
|
}
|
|
22476
|
-
function
|
|
23253
|
+
function assertNoStandaloneSourceFiles(files, resourceRoot, displayResourceRoot2) {
|
|
22477
23254
|
for (const { directory, kind, guidance } of [
|
|
22478
23255
|
{
|
|
22479
23256
|
directory: "environments",
|
|
@@ -22486,151 +23263,174 @@ function assertNoStandaloneResourceFiles(root) {
|
|
|
22486
23263
|
guidance: "Define identities inline on the owning .auto/agents YAML file."
|
|
22487
23264
|
}
|
|
22488
23265
|
]) {
|
|
22489
|
-
const
|
|
22490
|
-
|
|
22491
|
-
|
|
22492
|
-
|
|
22493
|
-
|
|
22494
|
-
|
|
22495
|
-
|
|
22496
|
-
const files = resourceApplyFiles(path2, entries);
|
|
22497
|
-
if (files.length === 0) {
|
|
23266
|
+
const standaloneFiles = files.filter(
|
|
23267
|
+
(file2) => isResourceFileUnderDirectory(
|
|
23268
|
+
file2.path,
|
|
23269
|
+
sourcePathJoin(resourceRoot, directory)
|
|
23270
|
+
)
|
|
23271
|
+
);
|
|
23272
|
+
if (standaloneFiles.length === 0) {
|
|
22498
23273
|
continue;
|
|
22499
23274
|
}
|
|
22500
23275
|
throw new Error(
|
|
22501
|
-
`Standalone
|
|
23276
|
+
`Standalone ${sourcePathJoin(displayResourceRoot2, directory)} ${kind} resources are no longer supported. ${guidance} Move ${standaloneFiles.length === 1 ? "this file" : "these files"}: ${standaloneFiles.map((file2) => file2.path).join(", ")}`
|
|
22502
23277
|
);
|
|
22503
23278
|
}
|
|
22504
23279
|
}
|
|
22505
|
-
function
|
|
22506
|
-
const
|
|
22507
|
-
|
|
22508
|
-
|
|
22509
|
-
|
|
22510
|
-
|
|
22511
|
-
|
|
22512
|
-
|
|
22513
|
-
for (const path2 of resourceApplyFiles(fragmentsRoot, entries)) {
|
|
23280
|
+
function assertValidFragmentSourceFiles(files, resourceRoot, fileIndex) {
|
|
23281
|
+
const fragments = files.filter(
|
|
23282
|
+
(file2) => isResourceFileUnderDirectory(
|
|
23283
|
+
file2.path,
|
|
23284
|
+
sourcePathJoin(resourceRoot, "fragments")
|
|
23285
|
+
)
|
|
23286
|
+
);
|
|
23287
|
+
for (const file2 of fragments) {
|
|
22514
23288
|
try {
|
|
22515
|
-
|
|
23289
|
+
const documents = readDocumentsFromSource(file2);
|
|
23290
|
+
if (documents.length !== 1) {
|
|
23291
|
+
throw new Error(
|
|
23292
|
+
`Agent authoring file ${file2.path} must contain exactly one document`
|
|
23293
|
+
);
|
|
23294
|
+
}
|
|
23295
|
+
validateAgentFragmentDocument(documents[0], file2.path, {
|
|
23296
|
+
fileIndex,
|
|
23297
|
+
stack: []
|
|
23298
|
+
});
|
|
22516
23299
|
} catch (error51) {
|
|
22517
23300
|
throw new Error(
|
|
22518
|
-
`Invalid fragment file ${
|
|
23301
|
+
`Invalid fragment file ${file2.path}: ${error51 instanceof Error ? error51.message : String(error51)}`
|
|
22519
23302
|
);
|
|
22520
23303
|
}
|
|
22521
23304
|
}
|
|
22522
23305
|
}
|
|
22523
|
-
|
|
22524
|
-
|
|
22525
|
-
|
|
23306
|
+
var init_project_apply_files = __esm({
|
|
23307
|
+
"../../packages/schemas/src/project-apply-files/index.ts"() {
|
|
23308
|
+
"use strict";
|
|
23309
|
+
init_agents();
|
|
23310
|
+
init_environments();
|
|
23311
|
+
init_identities();
|
|
23312
|
+
init_project_resources();
|
|
23313
|
+
init_agent_authoring();
|
|
23314
|
+
init_apply_result();
|
|
23315
|
+
init_assets2();
|
|
23316
|
+
init_source();
|
|
23317
|
+
}
|
|
23318
|
+
});
|
|
23319
|
+
|
|
23320
|
+
// ../../packages/schemas/src/project-apply-files.ts
|
|
23321
|
+
var init_project_apply_files2 = __esm({
|
|
23322
|
+
"../../packages/schemas/src/project-apply-files.ts"() {
|
|
23323
|
+
"use strict";
|
|
23324
|
+
init_project_apply_files();
|
|
23325
|
+
}
|
|
23326
|
+
});
|
|
23327
|
+
|
|
23328
|
+
// src/commands/apply/files.ts
|
|
23329
|
+
import {
|
|
23330
|
+
readFileSync as readFileSync4,
|
|
23331
|
+
readdirSync as readdirSync3,
|
|
23332
|
+
realpathSync,
|
|
23333
|
+
statSync as statSync2
|
|
23334
|
+
} from "fs";
|
|
23335
|
+
import {
|
|
23336
|
+
basename as basename3,
|
|
23337
|
+
dirname as dirname5,
|
|
23338
|
+
extname as extname3,
|
|
23339
|
+
isAbsolute as isAbsolute2,
|
|
23340
|
+
join as join5,
|
|
23341
|
+
relative,
|
|
23342
|
+
resolve as resolve2
|
|
23343
|
+
} from "path";
|
|
23344
|
+
function readProjectApplyRequest(options) {
|
|
23345
|
+
if (options.file && options.directory) {
|
|
23346
|
+
throw new Error("Cannot use --file with --directory.");
|
|
23347
|
+
}
|
|
23348
|
+
if (options.file) {
|
|
23349
|
+
const file2 = resolve2(options.file);
|
|
23350
|
+
const projectRoot2 = applyFileProjectRoot(file2);
|
|
23351
|
+
const sourceRoot = applyFileSourceRoot(file2, projectRoot2);
|
|
23352
|
+
return readProjectApplyFileSource({
|
|
23353
|
+
file: sourceFile(file2, projectRoot2),
|
|
23354
|
+
files: sourceFiles(sourceRoot, projectRoot2),
|
|
23355
|
+
readAsset: filesystemAssetReader(projectRoot2)
|
|
23356
|
+
});
|
|
23357
|
+
}
|
|
23358
|
+
const directory = resolve2(options.directory ?? join5(process.cwd(), ".auto"));
|
|
23359
|
+
const projectRoot = applyProjectRoot(directory);
|
|
23360
|
+
return readProjectApplyDirectorySource({
|
|
23361
|
+
files: sourceFiles(directory, projectRoot),
|
|
23362
|
+
resourceRoot: sourcePathRelative(projectRoot, directory),
|
|
23363
|
+
displayResourceRoot: displayResourceRoot(directory),
|
|
23364
|
+
emptyMessage: `No resource files found in ${directory}`,
|
|
23365
|
+
readAsset: filesystemAssetReader(projectRoot)
|
|
23366
|
+
});
|
|
23367
|
+
}
|
|
23368
|
+
function sourceFiles(root, projectRoot) {
|
|
23369
|
+
let entries;
|
|
23370
|
+
try {
|
|
23371
|
+
entries = readdirSync3(root, { withFileTypes: true });
|
|
23372
|
+
} catch {
|
|
23373
|
+
return [];
|
|
23374
|
+
}
|
|
23375
|
+
return entries.flatMap((entry) => {
|
|
23376
|
+
const path2 = join5(root, entry.name);
|
|
23377
|
+
if (entry.isDirectory()) {
|
|
23378
|
+
return sourceFiles(path2, projectRoot);
|
|
23379
|
+
}
|
|
23380
|
+
if (!entry.isFile()) {
|
|
22526
23381
|
return [];
|
|
22527
23382
|
}
|
|
22528
|
-
return [
|
|
22529
|
-
{
|
|
22530
|
-
agent: input.agent,
|
|
22531
|
-
tool: alias,
|
|
22532
|
-
connection: tool.auth.connection
|
|
22533
|
-
}
|
|
22534
|
-
];
|
|
23383
|
+
return [sourceFile(path2, projectRoot)];
|
|
22535
23384
|
});
|
|
22536
23385
|
}
|
|
22537
|
-
function
|
|
22538
|
-
const source = readFileSync4(path2, "utf8");
|
|
22539
|
-
let documents;
|
|
22540
|
-
try {
|
|
22541
|
-
const parsedDocuments = parseYamlDocuments2(source);
|
|
22542
|
-
const parseError = parsedDocuments.flatMap((document) => document.errors).at(0);
|
|
22543
|
-
if (parseError) {
|
|
22544
|
-
throw parseError;
|
|
22545
|
-
}
|
|
22546
|
-
documents = parsedDocuments.filter((document) => document.contents !== null).map((document) => document.toJSON());
|
|
22547
|
-
} catch (error51) {
|
|
22548
|
-
throw new Error(
|
|
22549
|
-
`Invalid apply file: ${error51 instanceof Error ? error51.message : String(error51)}`
|
|
22550
|
-
);
|
|
22551
|
-
}
|
|
22552
|
-
if (documents.length === 0) {
|
|
22553
|
-
throw new Error(`Invalid apply file: ${path2} is empty`);
|
|
22554
|
-
}
|
|
22555
|
-
if (documents.length === 1) {
|
|
22556
|
-
const system = ProjectApplySystemConfigSchema.safeParse(documents[0]);
|
|
22557
|
-
if (system.success) {
|
|
22558
|
-
const resources = system.data.spec.resources;
|
|
22559
|
-
assertNoExplicitStandaloneResources(resources, path2);
|
|
22560
|
-
return {
|
|
22561
|
-
...system.data.spec,
|
|
22562
|
-
resourceRecords: resources.map((resource) => ({
|
|
22563
|
-
resource,
|
|
22564
|
-
generatedFromAgent: false
|
|
22565
|
-
}))
|
|
22566
|
-
};
|
|
22567
|
-
}
|
|
22568
|
-
}
|
|
22569
|
-
const resourceRecords = documents.flatMap(
|
|
22570
|
-
(document) => readApplyDocument(document, path2)
|
|
22571
|
-
);
|
|
23386
|
+
function sourceFile(path2, projectRoot) {
|
|
22572
23387
|
return {
|
|
22573
|
-
|
|
22574
|
-
|
|
22575
|
-
prune: false,
|
|
22576
|
-
resources: resourceRecords.map((record2) => record2.resource),
|
|
22577
|
-
resourceRecords,
|
|
22578
|
-
assets: {}
|
|
23388
|
+
path: sourcePathRelative(projectRoot, path2),
|
|
23389
|
+
contentBase64: readFileSync4(path2).toString("base64")
|
|
22579
23390
|
};
|
|
22580
23391
|
}
|
|
22581
|
-
function
|
|
22582
|
-
|
|
22583
|
-
|
|
22584
|
-
|
|
22585
|
-
|
|
22586
|
-
|
|
22587
|
-
|
|
23392
|
+
function filesystemAssetReader(projectRoot) {
|
|
23393
|
+
return ({ asset, resourceName }) => {
|
|
23394
|
+
const path2 = validateAgentAvatarAsset({
|
|
23395
|
+
asset,
|
|
23396
|
+
resourceName,
|
|
23397
|
+
projectRoot
|
|
23398
|
+
});
|
|
23399
|
+
return {
|
|
23400
|
+
path: path2,
|
|
23401
|
+
bytes: readFileSync4(path2)
|
|
23402
|
+
};
|
|
23403
|
+
};
|
|
22588
23404
|
}
|
|
22589
|
-
function
|
|
22590
|
-
|
|
22591
|
-
|
|
22592
|
-
continue;
|
|
22593
|
-
}
|
|
22594
|
-
throw standaloneResourceError(resource.kind, path2);
|
|
22595
|
-
}
|
|
23405
|
+
function applyProjectRoot(directory) {
|
|
23406
|
+
const resolved = resolve2(directory);
|
|
23407
|
+
return basename3(resolved) === ".auto" ? dirname5(resolved) : resolved;
|
|
22596
23408
|
}
|
|
22597
|
-
function
|
|
22598
|
-
|
|
22599
|
-
|
|
22600
|
-
|
|
22601
|
-
|
|
22602
|
-
continue;
|
|
23409
|
+
function applyFileProjectRoot(file2) {
|
|
23410
|
+
let dir = dirname5(resolve2(file2));
|
|
23411
|
+
while (true) {
|
|
23412
|
+
if (basename3(dir) === ".auto") {
|
|
23413
|
+
return dirname5(dir);
|
|
22603
23414
|
}
|
|
22604
|
-
const
|
|
22605
|
-
|
|
22606
|
-
|
|
22607
|
-
projectRoot
|
|
22608
|
-
});
|
|
22609
|
-
const bytes = readFileSync4(resolvedPath);
|
|
22610
|
-
const dimensionsProblem = avatarAssetDimensionsProblem(bytes);
|
|
22611
|
-
if (dimensionsProblem) {
|
|
22612
|
-
throw new Error(
|
|
22613
|
-
`Invalid identity avatar asset for "${target.resourceName}": ${dimensionsProblem}`
|
|
22614
|
-
);
|
|
23415
|
+
const parent = dirname5(dir);
|
|
23416
|
+
if (parent === dir) {
|
|
23417
|
+
return process.cwd();
|
|
22615
23418
|
}
|
|
22616
|
-
|
|
22617
|
-
sha256: createHash3("sha256").update(bytes).digest("hex"),
|
|
22618
|
-
contentType: extname2(resolvedPath).toLowerCase() === ".png" ? "image/png" : "image/jpeg",
|
|
22619
|
-
dataBase64: bytes.toString("base64")
|
|
22620
|
-
};
|
|
23419
|
+
dir = parent;
|
|
22621
23420
|
}
|
|
22622
|
-
return assets;
|
|
22623
23421
|
}
|
|
22624
|
-
function
|
|
22625
|
-
|
|
22626
|
-
|
|
22627
|
-
|
|
22628
|
-
|
|
22629
|
-
|
|
22630
|
-
|
|
22631
|
-
|
|
22632
|
-
|
|
22633
|
-
|
|
23422
|
+
function applyFileSourceRoot(file2, projectRoot) {
|
|
23423
|
+
const autoRoot = resolve2(projectRoot, ".auto");
|
|
23424
|
+
return file2 === autoRoot || isInside(file2, autoRoot) ? autoRoot : dirname5(file2);
|
|
23425
|
+
}
|
|
23426
|
+
function displayResourceRoot(directory) {
|
|
23427
|
+
return basename3(directory) === ".auto" ? ".auto" : directory;
|
|
23428
|
+
}
|
|
23429
|
+
function sourcePathRelative(from, to) {
|
|
23430
|
+
return relative(from, to).replaceAll("\\", "/");
|
|
23431
|
+
}
|
|
23432
|
+
function isInside(path2, parent) {
|
|
23433
|
+
return path2.startsWith(`${parent}/`);
|
|
22634
23434
|
}
|
|
22635
23435
|
function validateAgentAvatarAsset(input) {
|
|
22636
23436
|
if (isAbsolute2(input.asset)) {
|
|
@@ -22679,103 +23479,21 @@ function validateAgentAvatarAsset(input) {
|
|
|
22679
23479
|
`Invalid identity avatar asset for "${input.resourceName}": asset must be ${MAX_AVATAR_ASSET_BYTES} bytes or smaller`
|
|
22680
23480
|
);
|
|
22681
23481
|
}
|
|
22682
|
-
const extension =
|
|
22683
|
-
if (!
|
|
23482
|
+
const extension = extname3(resolvedAssetPath).toLowerCase();
|
|
23483
|
+
if (!ALLOWED_AVATAR_EXTENSIONS2.has(extension)) {
|
|
22684
23484
|
throw new Error(
|
|
22685
23485
|
`Invalid identity avatar asset for "${input.resourceName}": asset must be a PNG or JPEG image`
|
|
22686
23486
|
);
|
|
22687
23487
|
}
|
|
22688
23488
|
return resolvedAssetPath;
|
|
22689
23489
|
}
|
|
22690
|
-
|
|
22691
|
-
const resolved = resolve2(directory);
|
|
22692
|
-
return basename3(resolved) === ".auto" ? dirname5(resolved) : resolved;
|
|
22693
|
-
}
|
|
22694
|
-
function applyFileProjectRoot(file2) {
|
|
22695
|
-
let dir = dirname5(resolve2(file2));
|
|
22696
|
-
while (true) {
|
|
22697
|
-
if (basename3(dir) === ".auto") {
|
|
22698
|
-
return dirname5(dir);
|
|
22699
|
-
}
|
|
22700
|
-
const parent = dirname5(dir);
|
|
22701
|
-
if (parent === dir) {
|
|
22702
|
-
return process.cwd();
|
|
22703
|
-
}
|
|
22704
|
-
dir = parent;
|
|
22705
|
-
}
|
|
22706
|
-
}
|
|
22707
|
-
function isInside(path2, parent) {
|
|
22708
|
-
return path2.startsWith(`${parent}/`);
|
|
22709
|
-
}
|
|
22710
|
-
function assertAgentAuthoringDocument(document, path2) {
|
|
22711
|
-
if (!isRecord2(document) || !("kind" in document)) {
|
|
22712
|
-
return;
|
|
22713
|
-
}
|
|
22714
|
-
if (document.kind === "session") {
|
|
22715
|
-
throw new Error(
|
|
22716
|
-
'Legacy resource kind "session" is no longer supported. Use .auto/agents with the root-level Agent facade format.'
|
|
22717
|
-
);
|
|
22718
|
-
}
|
|
22719
|
-
if (document.kind === RESOURCE_KIND_ENVIRONMENT || document.kind === RESOURCE_KIND_IDENTITY) {
|
|
22720
|
-
throw standaloneResourceError(document.kind, path2);
|
|
22721
|
-
}
|
|
22722
|
-
if (document.kind !== RESOURCE_KIND_AGENT) {
|
|
22723
|
-
throw new Error(
|
|
22724
|
-
`Unsupported apply resource kind "${String(document.kind)}"; supported kind is "${RESOURCE_KIND_AGENT}"`
|
|
22725
|
-
);
|
|
22726
|
-
}
|
|
22727
|
-
const parsed = AgentApplyRequestSchema.safeParse({
|
|
22728
|
-
metadata: document.metadata,
|
|
22729
|
-
spec: document.spec
|
|
22730
|
-
});
|
|
22731
|
-
if (parsed.success) {
|
|
22732
|
-
throw new Error(
|
|
22733
|
-
`Legacy agent resource envelopes are no longer supported in ${path2}. Use the root-level Agent facade format under .auto/agents.`
|
|
22734
|
-
);
|
|
22735
|
-
}
|
|
22736
|
-
}
|
|
22737
|
-
function standaloneResourceError(kind, path2) {
|
|
22738
|
-
if (kind === RESOURCE_KIND_ENVIRONMENT) {
|
|
22739
|
-
return new Error(
|
|
22740
|
-
`Standalone environment resources are no longer supported in ${path2}. Define environments inline in .auto/agents YAML, using fragment imports under .auto/fragments/environments for reused runtimes.`
|
|
22741
|
-
);
|
|
22742
|
-
}
|
|
22743
|
-
return new Error(
|
|
22744
|
-
`Standalone identity resources are no longer supported in ${path2}. Define identities inline on the owning .auto/agents YAML file.`
|
|
22745
|
-
);
|
|
22746
|
-
}
|
|
22747
|
-
function primaryApplyDirectory(kind) {
|
|
22748
|
-
return APPLY_DIRECTORIES[kind];
|
|
22749
|
-
}
|
|
22750
|
-
function isRecord2(value) {
|
|
22751
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
22752
|
-
}
|
|
22753
|
-
function resourceApplyFiles(directory, entries) {
|
|
22754
|
-
const files = [];
|
|
22755
|
-
for (const entry of entries) {
|
|
22756
|
-
const path2 = join5(directory, entry.name);
|
|
22757
|
-
if (entry.isDirectory()) {
|
|
22758
|
-
files.push(
|
|
22759
|
-
...resourceApplyFiles(path2, readdirSync3(path2, { withFileTypes: true }))
|
|
22760
|
-
);
|
|
22761
|
-
continue;
|
|
22762
|
-
}
|
|
22763
|
-
if (entry.isFile() && /\.(json|ya?ml)$/i.test(entry.name)) {
|
|
22764
|
-
files.push(path2);
|
|
22765
|
-
}
|
|
22766
|
-
}
|
|
22767
|
-
return files.sort((left, right) => left.localeCompare(right));
|
|
22768
|
-
}
|
|
22769
|
-
var APPLY_DIRECTORIES, ALLOWED_AVATAR_EXTENSIONS;
|
|
23490
|
+
var ALLOWED_AVATAR_EXTENSIONS2;
|
|
22770
23491
|
var init_files = __esm({
|
|
22771
23492
|
"src/commands/apply/files.ts"() {
|
|
22772
23493
|
"use strict";
|
|
22773
23494
|
init_src();
|
|
22774
|
-
|
|
22775
|
-
|
|
22776
|
-
agent: "agents"
|
|
22777
|
-
};
|
|
22778
|
-
ALLOWED_AVATAR_EXTENSIONS = /* @__PURE__ */ new Set([".jpg", ".jpeg", ".png"]);
|
|
23495
|
+
init_project_apply_files2();
|
|
23496
|
+
ALLOWED_AVATAR_EXTENSIONS2 = /* @__PURE__ */ new Set([".jpg", ".jpeg", ".png"]);
|
|
22779
23497
|
}
|
|
22780
23498
|
});
|
|
22781
23499
|
|