@autohq/cli 0.1.137 → 0.1.139

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.
@@ -21253,7 +21253,6 @@ var EventRoutingTriggerResultSchema = external_exports.object({
21253
21253
 
21254
21254
  // ../../packages/schemas/src/sessions.ts
21255
21255
  var RESOURCE_KIND_AGENT = "agent";
21256
- var LEGACY_RESOURCE_KIND_SESSION = "session";
21257
21256
  var RESOURCE_KIND_SESSION = RESOURCE_KIND_AGENT;
21258
21257
  var SESSION_HARNESSES = ["claude-code"];
21259
21258
  var TriggerFilterScalarSchema = external_exports.union([
@@ -21909,14 +21908,11 @@ var SessionApplyDocumentSchema = resourceApplyDocumentSchema(
21909
21908
  RESOURCE_KIND_SESSION,
21910
21909
  SessionApplyRequestSchema.shape.spec
21911
21910
  );
21912
- var ProjectApplyResourceSchema = external_exports.preprocess(
21913
- normalizeLegacySessionKind,
21914
- external_exports.discriminatedUnion("kind", [
21915
- EnvironmentApplyDocumentSchema,
21916
- IdentityApplyDocumentSchema,
21917
- SessionApplyDocumentSchema
21918
- ])
21919
- );
21911
+ var ProjectApplyResourceSchema = external_exports.discriminatedUnion("kind", [
21912
+ EnvironmentApplyDocumentSchema,
21913
+ IdentityApplyDocumentSchema,
21914
+ SessionApplyDocumentSchema
21915
+ ]);
21920
21916
  var PROJECT_RESOURCE_APPLY_ORDER = [
21921
21917
  RESOURCE_KIND_CONNECTION,
21922
21918
  RESOURCE_KIND_IDENTITY,
@@ -21932,12 +21928,9 @@ var PROJECT_APPLY_RESOURCE_KINDS = [
21932
21928
  var ProjectDeleteResourceBaseSchema = external_exports.object({
21933
21929
  name: external_exports.string().trim().min(1)
21934
21930
  });
21935
- var ProjectDeleteResourceSchema = external_exports.preprocess(
21936
- normalizeLegacySessionKind,
21937
- ProjectDeleteResourceBaseSchema.extend({
21938
- kind: external_exports.enum(PROJECT_APPLY_RESOURCE_KINDS)
21939
- })
21940
- );
21931
+ var ProjectDeleteResourceSchema = ProjectDeleteResourceBaseSchema.extend({
21932
+ kind: external_exports.enum(PROJECT_APPLY_RESOURCE_KINDS)
21933
+ });
21941
21934
  var AVATAR_ASSET_CONTENT_TYPES = ["image/png", "image/jpeg"];
21942
21935
  var MAX_AVATAR_ASSET_BASE64_LENGTH = Math.ceil(MAX_AVATAR_ASSET_BYTES / 3) * 4 + 4;
21943
21936
  var ProjectApplyAssetSchema = external_exports.object({
@@ -21993,12 +21986,6 @@ var ProjectApplyDiagnosticSchema = external_exports.object({
21993
21986
  ]),
21994
21987
  name: external_exports.string().min(1)
21995
21988
  });
21996
- var ProjectApplyResponseResourceKindSchema = external_exports.union([
21997
- external_exports.enum(PROJECT_RESOURCE_KINDS),
21998
- external_exports.literal(LEGACY_RESOURCE_KIND_SESSION)
21999
- ]).transform(
22000
- (kind) => kind === LEGACY_RESOURCE_KIND_SESSION ? RESOURCE_KIND_SESSION : kind
22001
- );
22002
21989
  var ProjectApplyResponseSchema = external_exports.object({
22003
21990
  dryRun: external_exports.boolean().default(false),
22004
21991
  resources: external_exports.array(ProjectAppliedResourceSchema),
@@ -22007,28 +21994,19 @@ var ProjectApplyResponseSchema = external_exports.object({
22007
21994
  plan: external_exports.array(
22008
21995
  external_exports.object({
22009
21996
  action: external_exports.enum(["create", "update", "unchanged", "archive"]),
22010
- kind: ProjectApplyResponseResourceKindSchema,
21997
+ kind: external_exports.enum(PROJECT_RESOURCE_KINDS),
22011
21998
  name: external_exports.string().min(1),
22012
21999
  uid: external_exports.string().min(1).optional()
22013
22000
  })
22014
22001
  ).default([]),
22015
22002
  pruned: external_exports.array(
22016
22003
  external_exports.object({
22017
- kind: ProjectApplyResponseResourceKindSchema,
22004
+ kind: external_exports.enum(PROJECT_RESOURCE_KINDS),
22018
22005
  name: external_exports.string().min(1),
22019
22006
  uid: external_exports.string().min(1)
22020
22007
  })
22021
22008
  ).default([])
22022
22009
  });
22023
- function normalizeLegacySessionKind(value2) {
22024
- if (isRecord(value2) && value2.kind === LEGACY_RESOURCE_KIND_SESSION) {
22025
- return { ...value2, kind: RESOURCE_KIND_SESSION };
22026
- }
22027
- return value2;
22028
- }
22029
- function isRecord(value2) {
22030
- return typeof value2 === "object" && value2 !== null && !Array.isArray(value2);
22031
- }
22032
22010
 
22033
22011
  // ../../packages/schemas/src/run-diagnostics.ts
22034
22012
  var RUN_DIAGNOSTIC_REALTIME_EVENT = "run.diagnostic";
@@ -26290,7 +26268,7 @@ Object.assign(lookup, {
26290
26268
  // package.json
26291
26269
  var package_default = {
26292
26270
  name: "@autohq/cli",
26293
- version: "0.1.137",
26271
+ version: "0.1.139",
26294
26272
  license: "SEE LICENSE IN README.md",
26295
26273
  publishConfig: {
26296
26274
  access: "public"
package/dist/index.js CHANGED
@@ -18062,7 +18062,7 @@ function isChatMessageEvent(trigger) {
18062
18062
  function hasFilterValue(trigger, path2, expected) {
18063
18063
  return trigger.where?.[path2] === expected;
18064
18064
  }
18065
- var RESOURCE_KIND_AGENT, LEGACY_RESOURCE_KIND_SESSION, RESOURCE_KIND_SESSION, SESSION_HARNESSES, TriggerFilterScalarSchema, TriggerFilterPathSchema, TriggerFilterClauseSchema, TriggerFilterSchema, SessionTriggerCheckTimeoutSchema, TriggerEventSchema, TriggerEventsSchema, SessionTriggerSharedFields, SessionTriggerEventSourceFields, SessionTriggerBaseSchema, SessionTriggerDefinitionBaseSchema, SessionTriggerSchema, SessionApplyTriggerSchema, SessionHeartbeatTriggerBaseSchema, SessionHeartbeatTriggerSchema, SessionApplyHeartbeatTriggerSchema, SessionTriggerDefinitionSchema, SessionApplyTriggerDefinitionSchema, SessionTriggersSchema, SessionApplyTriggersSchema, AVATAR_ASSET_EXTENSIONS, MAX_AVATAR_ASSET_BYTES, MIN_AVATAR_ASSET_DIMENSION_PX, MAX_AVATAR_ASSET_DIMENSION_PX, PNG_SIGNATURE, SESSION_IDENTITY_DESCRIPTION_MAX_LENGTH, SHA256_HEX_PATTERN, SessionIdentitySchema, SessionSpecFieldsSchema, SessionSpecSchema, SessionApplySpecSchema, SessionStatusSchema, SessionResourceSchema, SessionApplyRequestSchema, SessionApplyTriggerReceiptSchema, SessionApplyResponseSchema, SESSION_TELEGRAM_IDENTITY_STATUSES, SessionTelegramIdentityStatusSchema, SessionPresenceIdentitySchema, SessionPresenceResponseSchema, SessionPresenceConnectRequestSchema, SessionPresenceConnectPendingSchema, SessionPresenceConnectResponseSchema, SessionPresenceIconRequestSchema, SessionPresenceIconResponseSchema, SessionPresenceCompleteResponseSchema;
18065
+ var RESOURCE_KIND_AGENT, RESOURCE_KIND_SESSION, SESSION_HARNESSES, TriggerFilterScalarSchema, TriggerFilterPathSchema, TriggerFilterClauseSchema, TriggerFilterSchema, SessionTriggerCheckTimeoutSchema, TriggerEventSchema, TriggerEventsSchema, SessionTriggerSharedFields, SessionTriggerEventSourceFields, SessionTriggerBaseSchema, SessionTriggerDefinitionBaseSchema, SessionTriggerSchema, SessionApplyTriggerSchema, SessionHeartbeatTriggerBaseSchema, SessionHeartbeatTriggerSchema, SessionApplyHeartbeatTriggerSchema, SessionTriggerDefinitionSchema, SessionApplyTriggerDefinitionSchema, SessionTriggersSchema, SessionApplyTriggersSchema, AVATAR_ASSET_EXTENSIONS, MAX_AVATAR_ASSET_BYTES, MIN_AVATAR_ASSET_DIMENSION_PX, MAX_AVATAR_ASSET_DIMENSION_PX, PNG_SIGNATURE, SESSION_IDENTITY_DESCRIPTION_MAX_LENGTH, SHA256_HEX_PATTERN, SessionIdentitySchema, SessionSpecFieldsSchema, SessionSpecSchema, SessionApplySpecSchema, SessionStatusSchema, SessionResourceSchema, SessionApplyRequestSchema, SessionApplyTriggerReceiptSchema, SessionApplyResponseSchema, SESSION_TELEGRAM_IDENTITY_STATUSES, SessionTelegramIdentityStatusSchema, SessionPresenceIdentitySchema, SessionPresenceResponseSchema, SessionPresenceConnectRequestSchema, SessionPresenceConnectPendingSchema, SessionPresenceConnectResponseSchema, SessionPresenceIconRequestSchema, SessionPresenceIconResponseSchema, SessionPresenceCompleteResponseSchema;
18066
18066
  var init_sessions = __esm({
18067
18067
  "../../packages/schemas/src/sessions.ts"() {
18068
18068
  "use strict";
@@ -18075,7 +18075,6 @@ var init_sessions = __esm({
18075
18075
  init_tools();
18076
18076
  init_trigger_router();
18077
18077
  RESOURCE_KIND_AGENT = "agent";
18078
- LEGACY_RESOURCE_KIND_SESSION = "session";
18079
18078
  RESOURCE_KIND_SESSION = RESOURCE_KIND_AGENT;
18080
18079
  SESSION_HARNESSES = ["claude-code"];
18081
18080
  TriggerFilterScalarSchema = external_exports.union([
@@ -18595,16 +18594,7 @@ var init_project_service_accounts = __esm({
18595
18594
  });
18596
18595
 
18597
18596
  // ../../packages/schemas/src/project-resources.ts
18598
- function normalizeLegacySessionKind(value) {
18599
- if (isRecord(value) && value.kind === LEGACY_RESOURCE_KIND_SESSION) {
18600
- return { ...value, kind: RESOURCE_KIND_SESSION };
18601
- }
18602
- return value;
18603
- }
18604
- function isRecord(value) {
18605
- return typeof value === "object" && value !== null && !Array.isArray(value);
18606
- }
18607
- var EnvironmentApplyDocumentSchema, IdentityApplyDocumentSchema, SessionApplyDocumentSchema, ProjectApplyResourceSchema, PROJECT_RESOURCE_APPLY_ORDER, PROJECT_RESOURCE_KINDS, PROJECT_APPLY_RESOURCE_KINDS, ProjectDeleteResourceBaseSchema, ProjectDeleteResourceSchema, AVATAR_ASSET_CONTENT_TYPES, MAX_AVATAR_ASSET_BASE64_LENGTH, ProjectApplyAssetSchema, ProjectApplyAssetsSchema, AvatarAssetUploadRequestSchema, AvatarAssetUploadResponseSchema, ProjectApplyRequestSchema, ProjectApplySystemConfigSchema, ProjectAppliedResourceSchema, ProjectApplyDiagnosticSchema, ProjectApplyResponseResourceKindSchema, ProjectApplyResponseSchema;
18597
+ var EnvironmentApplyDocumentSchema, IdentityApplyDocumentSchema, SessionApplyDocumentSchema, ProjectApplyResourceSchema, PROJECT_RESOURCE_APPLY_ORDER, PROJECT_RESOURCE_KINDS, PROJECT_APPLY_RESOURCE_KINDS, ProjectDeleteResourceBaseSchema, ProjectDeleteResourceSchema, AVATAR_ASSET_CONTENT_TYPES, MAX_AVATAR_ASSET_BASE64_LENGTH, ProjectApplyAssetSchema, ProjectApplyAssetsSchema, AvatarAssetUploadRequestSchema, AvatarAssetUploadResponseSchema, ProjectApplyRequestSchema, ProjectApplySystemConfigSchema, ProjectAppliedResourceSchema, ProjectApplyDiagnosticSchema, ProjectApplyResponseSchema;
18608
18598
  var init_project_resources = __esm({
18609
18599
  "../../packages/schemas/src/project-resources.ts"() {
18610
18600
  "use strict";
@@ -18626,14 +18616,11 @@ var init_project_resources = __esm({
18626
18616
  RESOURCE_KIND_SESSION,
18627
18617
  SessionApplyRequestSchema.shape.spec
18628
18618
  );
18629
- ProjectApplyResourceSchema = external_exports.preprocess(
18630
- normalizeLegacySessionKind,
18631
- external_exports.discriminatedUnion("kind", [
18632
- EnvironmentApplyDocumentSchema,
18633
- IdentityApplyDocumentSchema,
18634
- SessionApplyDocumentSchema
18635
- ])
18636
- );
18619
+ ProjectApplyResourceSchema = external_exports.discriminatedUnion("kind", [
18620
+ EnvironmentApplyDocumentSchema,
18621
+ IdentityApplyDocumentSchema,
18622
+ SessionApplyDocumentSchema
18623
+ ]);
18637
18624
  PROJECT_RESOURCE_APPLY_ORDER = [
18638
18625
  RESOURCE_KIND_CONNECTION,
18639
18626
  RESOURCE_KIND_IDENTITY,
@@ -18649,12 +18636,9 @@ var init_project_resources = __esm({
18649
18636
  ProjectDeleteResourceBaseSchema = external_exports.object({
18650
18637
  name: external_exports.string().trim().min(1)
18651
18638
  });
18652
- ProjectDeleteResourceSchema = external_exports.preprocess(
18653
- normalizeLegacySessionKind,
18654
- ProjectDeleteResourceBaseSchema.extend({
18655
- kind: external_exports.enum(PROJECT_APPLY_RESOURCE_KINDS)
18656
- })
18657
- );
18639
+ ProjectDeleteResourceSchema = ProjectDeleteResourceBaseSchema.extend({
18640
+ kind: external_exports.enum(PROJECT_APPLY_RESOURCE_KINDS)
18641
+ });
18658
18642
  AVATAR_ASSET_CONTENT_TYPES = ["image/png", "image/jpeg"];
18659
18643
  MAX_AVATAR_ASSET_BASE64_LENGTH = Math.ceil(MAX_AVATAR_ASSET_BYTES / 3) * 4 + 4;
18660
18644
  ProjectApplyAssetSchema = external_exports.object({
@@ -18710,12 +18694,6 @@ var init_project_resources = __esm({
18710
18694
  ]),
18711
18695
  name: external_exports.string().min(1)
18712
18696
  });
18713
- ProjectApplyResponseResourceKindSchema = external_exports.union([
18714
- external_exports.enum(PROJECT_RESOURCE_KINDS),
18715
- external_exports.literal(LEGACY_RESOURCE_KIND_SESSION)
18716
- ]).transform(
18717
- (kind) => kind === LEGACY_RESOURCE_KIND_SESSION ? RESOURCE_KIND_SESSION : kind
18718
- );
18719
18697
  ProjectApplyResponseSchema = external_exports.object({
18720
18698
  dryRun: external_exports.boolean().default(false),
18721
18699
  resources: external_exports.array(ProjectAppliedResourceSchema),
@@ -18724,14 +18702,14 @@ var init_project_resources = __esm({
18724
18702
  plan: external_exports.array(
18725
18703
  external_exports.object({
18726
18704
  action: external_exports.enum(["create", "update", "unchanged", "archive"]),
18727
- kind: ProjectApplyResponseResourceKindSchema,
18705
+ kind: external_exports.enum(PROJECT_RESOURCE_KINDS),
18728
18706
  name: external_exports.string().min(1),
18729
18707
  uid: external_exports.string().min(1).optional()
18730
18708
  })
18731
18709
  ).default([]),
18732
18710
  pruned: external_exports.array(
18733
18711
  external_exports.object({
18734
- kind: ProjectApplyResponseResourceKindSchema,
18712
+ kind: external_exports.enum(PROJECT_RESOURCE_KINDS),
18735
18713
  name: external_exports.string().min(1),
18736
18714
  uid: external_exports.string().min(1)
18737
18715
  })
@@ -21226,7 +21204,7 @@ var init_package = __esm({
21226
21204
  "package.json"() {
21227
21205
  package_default = {
21228
21206
  name: "@autohq/cli",
21229
- version: "0.1.137",
21207
+ version: "0.1.139",
21230
21208
  license: "SEE LICENSE IN README.md",
21231
21209
  publishConfig: {
21232
21210
  access: "public"
@@ -21408,9 +21386,10 @@ function compileAgentFile(path2) {
21408
21386
  const context = { graph: /* @__PURE__ */ new Map(), removals: [] };
21409
21387
  const document = readSingleDocument(path2);
21410
21388
  const compiled = finalizeAgentApplyShape(
21411
- compileAgentDocument(document, path2, [], context)
21389
+ compileAgentDocument(document, path2, [], context),
21390
+ path2
21412
21391
  );
21413
- const parsed = ProjectApplyResourceSchema.safeParse(compiled);
21392
+ const parsed = ProjectApplyResourceSchema.safeParse(compiled.resource);
21414
21393
  if (!parsed.success) {
21415
21394
  throw new Error(`Invalid compiled agent ${path2}: ${parsed.error.message}`);
21416
21395
  }
@@ -21421,6 +21400,7 @@ function compileAgentFile(path2) {
21421
21400
  }
21422
21401
  return {
21423
21402
  resource: parsed.data,
21403
+ resources: [...compiled.resources, parsed.data],
21424
21404
  graph: [...context.graph.values()],
21425
21405
  removals: context.removals
21426
21406
  };
@@ -21428,9 +21408,10 @@ function compileAgentFile(path2) {
21428
21408
  function compileAgentDocumentValue(document, path2) {
21429
21409
  const context = { graph: /* @__PURE__ */ new Map(), removals: [] };
21430
21410
  const compiled = finalizeAgentApplyShape(
21431
- compileAgentDocument(document, path2, [], context)
21411
+ compileAgentDocument(document, path2, [], context),
21412
+ path2
21432
21413
  );
21433
- const parsed = ProjectApplyResourceSchema.safeParse(compiled);
21414
+ const parsed = ProjectApplyResourceSchema.safeParse(compiled.resource);
21434
21415
  if (!parsed.success) {
21435
21416
  throw new Error(`Invalid compiled agent ${path2}: ${parsed.error.message}`);
21436
21417
  }
@@ -21441,6 +21422,7 @@ function compileAgentDocumentValue(document, path2) {
21441
21422
  }
21442
21423
  return {
21443
21424
  resource: parsed.data,
21425
+ resources: [...compiled.resources, parsed.data],
21444
21426
  graph: [...context.graph.values()],
21445
21427
  removals: context.removals
21446
21428
  };
@@ -21548,7 +21530,7 @@ function discoverImports(document, path2, stack, imported) {
21548
21530
  `Agent import cycle detected: ${[...stack, resolvedPath].join(" -> ")}`
21549
21531
  );
21550
21532
  }
21551
- if (!isRecord2(document)) {
21533
+ if (!isRecord(document)) {
21552
21534
  return;
21553
21535
  }
21554
21536
  for (const importPath of importPaths(document)) {
@@ -21569,7 +21551,7 @@ function compileAgentDocument(document, path2, stack, context) {
21569
21551
  `Agent import cycle detected: ${[...stack, resolvedPath].join(" -> ")}`
21570
21552
  );
21571
21553
  }
21572
- if (!isRecord2(document)) {
21554
+ if (!isRecord(document)) {
21573
21555
  throw new Error(`Invalid agent authoring file ${path2}: expected object`);
21574
21556
  }
21575
21557
  const imports = importPaths(document).map(
@@ -21644,31 +21626,32 @@ function sanitizedAgentDocument(document) {
21644
21626
  delete next.import;
21645
21627
  delete next.imports;
21646
21628
  delete next.remove;
21647
- if (isRecord2(next.spec) && "remove" in next.spec) {
21648
- const spec = { ...next.spec };
21649
- delete spec.remove;
21650
- next.spec = spec;
21651
- }
21652
21629
  return next;
21653
21630
  }
21654
21631
  function authoringDocumentApplyShape(document, path2) {
21655
21632
  const sanitized = sanitizedAgentDocument(document);
21656
- const kind = typeof sanitized.kind === "string" ? sanitized.kind : RESOURCE_KIND_SESSION;
21657
- const metadata = isRecord2(sanitized.metadata) ? { ...sanitized.metadata } : {};
21658
- const spec = isRecord2(sanitized.spec) ? { ...sanitized.spec } : {};
21633
+ const legacyEnvelopeFields = ["kind", "metadata", "spec"].filter(
21634
+ (field) => field in sanitized
21635
+ );
21636
+ if (legacyEnvelopeFields.length > 0) {
21637
+ throw new Error(
21638
+ `Invalid agent authoring file ${path2}: legacy resource envelope fields are no longer supported (${legacyEnvelopeFields.join(", ")}). Use root-level Agent facade fields instead.`
21639
+ );
21640
+ }
21641
+ const metadata = {};
21642
+ const spec = {};
21659
21643
  for (const [key, value] of Object.entries(sanitized)) {
21660
21644
  if (key === "kind" || key === "metadata" || key === "spec" || value === void 0) {
21661
21645
  continue;
21662
21646
  }
21663
21647
  if (AGENT_METADATA_FIELDS.has(key)) {
21664
- const metadataKey = key === "name" ? "name" : key;
21665
21648
  assertNoDuplicateFacadeField({
21666
21649
  path: path2,
21667
21650
  field: key,
21668
- target: `metadata.${metadataKey}`,
21669
- targetValue: metadata[metadataKey]
21651
+ target: `metadata.${key}`,
21652
+ targetValue: metadata[key]
21670
21653
  });
21671
- metadata[metadataKey] = value;
21654
+ metadata[key] = value;
21672
21655
  continue;
21673
21656
  }
21674
21657
  if (AGENT_SPEC_FIELDS.has(key)) {
@@ -21682,20 +21665,26 @@ function authoringDocumentApplyShape(document, path2) {
21682
21665
  }
21683
21666
  }
21684
21667
  return {
21685
- kind,
21668
+ kind: RESOURCE_KIND_SESSION,
21686
21669
  metadata,
21687
21670
  spec: resolveFileBackedFields(spec, path2)
21688
21671
  };
21689
21672
  }
21690
- function finalizeAgentApplyShape(document) {
21691
- if (!isRecord2(document) || !isRecord2(document.spec)) {
21692
- return document;
21673
+ function finalizeAgentApplyShape(document, path2) {
21674
+ if (!isRecord(document) || !isRecord(document.spec)) {
21675
+ return { resource: document, resources: [] };
21693
21676
  }
21694
21677
  const next = structuredClone(document);
21695
21678
  const spec = next.spec;
21679
+ const resources = [];
21680
+ if (isRecord(spec.environment)) {
21681
+ const environment = inlineEnvironmentResource(spec.environment, path2);
21682
+ spec.environment = environment.metadata.name;
21683
+ resources.push(environment);
21684
+ }
21696
21685
  if (Array.isArray(spec.triggers)) {
21697
21686
  spec.triggers = spec.triggers.map((trigger) => {
21698
- if (!isRecord2(trigger) || !("name" in trigger)) {
21687
+ if (!isRecord(trigger) || !("name" in trigger)) {
21699
21688
  return trigger;
21700
21689
  }
21701
21690
  const compiledTrigger = { ...trigger };
@@ -21703,7 +21692,32 @@ function finalizeAgentApplyShape(document) {
21703
21692
  return compiledTrigger;
21704
21693
  });
21705
21694
  }
21706
- return next;
21695
+ return { resource: next, resources };
21696
+ }
21697
+ function inlineEnvironmentResource(document, path2) {
21698
+ const metadata = {};
21699
+ const spec = {};
21700
+ for (const [key, value] of Object.entries(document)) {
21701
+ if (value === void 0) {
21702
+ continue;
21703
+ }
21704
+ if (AGENT_METADATA_FIELDS.has(key)) {
21705
+ metadata[key] = value;
21706
+ continue;
21707
+ }
21708
+ spec[key] = value;
21709
+ }
21710
+ const parsed = EnvironmentApplyRequestSchema.safeParse({ metadata, spec });
21711
+ if (!parsed.success) {
21712
+ throw new Error(
21713
+ `Invalid inline environment in ${path2}: ${parsed.error.message}`
21714
+ );
21715
+ }
21716
+ return {
21717
+ kind: RESOURCE_KIND_ENVIRONMENT,
21718
+ metadata: parsed.data.metadata,
21719
+ spec: parsed.data.spec
21720
+ };
21707
21721
  }
21708
21722
  function assertNoDuplicateFacadeField(input) {
21709
21723
  if (input.targetValue !== void 0) {
@@ -21726,7 +21740,7 @@ function resolveFileBackedFields(spec, path2) {
21726
21740
  };
21727
21741
  }
21728
21742
  function resolveFileBackedString(value, input) {
21729
- if (!isRecord2(value) || !("file" in value)) {
21743
+ if (!isRecord(value) || !("file" in value)) {
21730
21744
  return value;
21731
21745
  }
21732
21746
  const file2 = value.file;
@@ -21744,12 +21758,8 @@ function resolveFileBackedString(value, input) {
21744
21758
  return readFileSync3(resolve(dirname4(input.path), filePath), "utf8");
21745
21759
  }
21746
21760
  function removalDirectives(document, path2) {
21747
- const raw = mergeValues2(
21748
- isRecord2(document.remove) ? document.remove : {},
21749
- isRecord2(document.spec) && isRecord2(document.spec.remove) ? document.spec.remove : {},
21750
- []
21751
- );
21752
- if (!isRecord2(raw)) {
21761
+ const raw = isRecord(document.remove) ? document.remove : {};
21762
+ if (!isRecord(raw)) {
21753
21763
  return [];
21754
21764
  }
21755
21765
  const directives = [];
@@ -21771,18 +21781,18 @@ function stringList(value, label) {
21771
21781
  });
21772
21782
  }
21773
21783
  function applyRemoval(value, removal) {
21774
- if (!isRecord2(value)) {
21784
+ if (!isRecord(value)) {
21775
21785
  return value;
21776
21786
  }
21777
21787
  const next = structuredClone(value);
21778
- if (!isRecord2(next.spec)) {
21788
+ if (!isRecord(next.spec)) {
21779
21789
  return next;
21780
21790
  }
21781
21791
  const spec = { ...next.spec };
21782
21792
  next.spec = spec;
21783
21793
  switch (removal.target) {
21784
21794
  case "tools": {
21785
- if (!isRecord2(spec[removal.target])) {
21795
+ if (!isRecord(spec[removal.target])) {
21786
21796
  return next;
21787
21797
  }
21788
21798
  const collection = {
@@ -21820,7 +21830,7 @@ function mergeValues2(base, override, path2) {
21820
21830
  if (Array.isArray(base) && Array.isArray(override)) {
21821
21831
  return mergeArrays(base, override, path2);
21822
21832
  }
21823
- if (isRecord2(base) && isRecord2(override)) {
21833
+ if (isRecord(base) && isRecord(override)) {
21824
21834
  const merged = { ...base };
21825
21835
  for (const [key, value] of Object.entries(override)) {
21826
21836
  merged[key] = mergeValues2(merged[key], value, [...path2, key]);
@@ -21863,7 +21873,7 @@ function isNamedArrayMergePath(path2) {
21863
21873
  return path2 === "spec.mounts" || path2 === "spec.triggers";
21864
21874
  }
21865
21875
  function collectionItemKey(collection, item) {
21866
- if (!isRecord2(item)) {
21876
+ if (!isRecord(item)) {
21867
21877
  return void 0;
21868
21878
  }
21869
21879
  if (typeof item.name === "string") {
@@ -21895,7 +21905,7 @@ function isAgentFile(path2) {
21895
21905
  return false;
21896
21906
  }
21897
21907
  }
21898
- function isRecord2(value) {
21908
+ function isRecord(value) {
21899
21909
  return typeof value === "object" && value !== null && !Array.isArray(value);
21900
21910
  }
21901
21911
  var AGENT_FILE_EXTENSIONS, AGENT_SPEC_FIELDS, AGENT_METADATA_FIELDS;
@@ -21943,31 +21953,97 @@ function readProjectApplyRequest(options) {
21943
21953
  }
21944
21954
  if (options.file) {
21945
21955
  const request = readApplyDocumentFile(options.file);
21956
+ const resources2 = dedupeGeneratedResources(request.resourceRecords);
21946
21957
  const assets2 = readApplyAssets(
21947
- request.resources,
21958
+ resources2,
21948
21959
  applyFileProjectRoot(options.file)
21949
21960
  );
21950
- return { ...request, assets: assets2 };
21961
+ return {
21962
+ delete: request.delete,
21963
+ dryRun: request.dryRun,
21964
+ prune: request.prune,
21965
+ resources: resources2,
21966
+ assets: assets2
21967
+ };
21951
21968
  }
21952
21969
  const directory = options.directory ?? join4(process.cwd(), ".auto");
21970
+ assertNoLegacySessionFiles(directory);
21953
21971
  const files = applyFiles(directory);
21954
21972
  if (files.length === 0) {
21955
21973
  throw new Error(`No resource files found in ${directory}`);
21956
21974
  }
21957
- const resources = [];
21975
+ const resourceRecords = [];
21958
21976
  for (const { kind, path: path2 } of files) {
21959
21977
  const request = readApplyDocumentFile(path2);
21960
- for (const resource of request.resources) {
21961
- if (resource.kind !== kind) {
21978
+ for (const { resource, generatedFromAgent } of request.resourceRecords) {
21979
+ if (!isAllowedDirectoryResourceKind(kind, resource, generatedFromAgent)) {
21962
21980
  throw new Error(
21963
21981
  `Resource kind "${resource.kind}" in ${path2} does not match .auto/${primaryApplyDirectory(kind)}`
21964
21982
  );
21965
21983
  }
21966
- resources.push(resource);
21984
+ resourceRecords.push({ resource, generatedFromAgent });
21967
21985
  }
21968
21986
  }
21987
+ const resources = dedupeGeneratedResources(resourceRecords);
21969
21988
  const assets = readApplyAssets(resources, applyProjectRoot(directory));
21970
- return { delete: [], dryRun: false, prune: true, resources, assets };
21989
+ return {
21990
+ delete: [],
21991
+ dryRun: false,
21992
+ prune: true,
21993
+ resources,
21994
+ assets
21995
+ };
21996
+ }
21997
+ function isAllowedDirectoryResourceKind(directoryKind, resource, generatedFromAgent) {
21998
+ if (resource.kind === directoryKind) {
21999
+ return true;
22000
+ }
22001
+ return directoryKind === RESOURCE_KIND_SESSION && resource.kind === RESOURCE_KIND_ENVIRONMENT && generatedFromAgent;
22002
+ }
22003
+ function dedupeGeneratedResources(records) {
22004
+ const recordsByKey = /* @__PURE__ */ new Map();
22005
+ const deduped = [];
22006
+ for (const record2 of records) {
22007
+ const { resource } = record2;
22008
+ const key = `${resource.kind}/${resource.metadata.name}`;
22009
+ const existing = recordsByKey.get(key);
22010
+ if (!existing) {
22011
+ recordsByKey.set(key, record2);
22012
+ deduped.push(record2);
22013
+ continue;
22014
+ }
22015
+ if (!record2.generatedFromAgent && !existing.generatedFromAgent) {
22016
+ deduped.push(record2);
22017
+ continue;
22018
+ }
22019
+ if (stableResource(resource) !== stableResource(existing.resource)) {
22020
+ throw new Error(
22021
+ `Conflicting generated resource "${key}" from agent authoring. Inline environment definitions must be identical when they share a name.`
22022
+ );
22023
+ }
22024
+ }
22025
+ return deduped.map((record2) => record2.resource);
22026
+ }
22027
+ function stableResource(resource) {
22028
+ return JSON.stringify({
22029
+ kind: resource.kind,
22030
+ metadata: metadataComparable(resource.metadata),
22031
+ spec: sortJson(resource.spec)
22032
+ });
22033
+ }
22034
+ function metadataComparable(metadata) {
22035
+ return sortJson(metadata);
22036
+ }
22037
+ function sortJson(value) {
22038
+ if (Array.isArray(value)) {
22039
+ return value.map(sortJson);
22040
+ }
22041
+ if (isRecord2(value)) {
22042
+ return Object.fromEntries(
22043
+ Object.entries(value).sort(([left], [right]) => left.localeCompare(right)).map(([key, nested]) => [key, sortJson(nested)])
22044
+ );
22045
+ }
22046
+ return value;
21971
22047
  }
21972
22048
  function appliedResourceKind(request, response, index) {
21973
22049
  const plannedResources = response.plan.filter(
@@ -22002,21 +22078,19 @@ function applyFiles(root) {
22002
22078
  const files = [];
22003
22079
  for (const kind of PROJECT_APPLY_RESOURCE_KINDS) {
22004
22080
  const kindFiles = [];
22005
- for (const directory of applyDirectories(kind)) {
22006
- const path2 = join4(root, directory);
22007
- let entries;
22008
- try {
22009
- entries = readdirSync3(path2, { withFileTypes: true });
22010
- } catch {
22011
- continue;
22012
- }
22013
- kindFiles.push(...resourceApplyFiles(path2, entries));
22081
+ const path2 = join4(root, primaryApplyDirectory(kind));
22082
+ let entries;
22083
+ try {
22084
+ entries = readdirSync3(path2, { withFileTypes: true });
22085
+ } catch {
22086
+ continue;
22014
22087
  }
22088
+ kindFiles.push(...resourceApplyFiles(path2, entries));
22015
22089
  const importedFiles = kind === RESOURCE_KIND_SESSION ? importedAgentAuthoringPaths(kindFiles) : /* @__PURE__ */ new Set();
22016
22090
  const appliedFiles = kind === RESOURCE_KIND_SESSION ? kindFiles.filter(
22017
- (path2) => !importedFiles.has(resolve2(path2)) && !isSharedAgentAuthoringFile(root, path2)
22091
+ (path3) => !importedFiles.has(resolve2(path3)) && !isSharedAgentAuthoringFile(root, path3)
22018
22092
  ) : kindFiles;
22019
- files.push(...appliedFiles.map((path2) => ({ kind, path: path2 })));
22093
+ files.push(...appliedFiles.map((path3) => ({ kind, path: path3 })));
22020
22094
  }
22021
22095
  return files;
22022
22096
  }
@@ -22025,6 +22099,22 @@ function isSharedAgentAuthoringFile(root, path2) {
22025
22099
  const resolvedPath = resolve2(path2);
22026
22100
  return resolvedPath.startsWith(`${agentsSharedRoot}/`);
22027
22101
  }
22102
+ function assertNoLegacySessionFiles(root) {
22103
+ const path2 = join4(root, "sessions");
22104
+ let entries;
22105
+ try {
22106
+ entries = readdirSync3(path2, { withFileTypes: true });
22107
+ } catch {
22108
+ return;
22109
+ }
22110
+ const files = resourceApplyFiles(path2, entries);
22111
+ if (files.length === 0) {
22112
+ return;
22113
+ }
22114
+ throw new Error(
22115
+ `Legacy .auto/sessions files are no longer supported. Move ${files.length === 1 ? "this file" : "these files"} to .auto/agents and use the root-level Agent facade format: ${files.join(", ")}`
22116
+ );
22117
+ }
22028
22118
  function mcpOAuthSessionToolConnectionsFromSessionTools(input) {
22029
22119
  return Object.entries(input.tools).flatMap(([alias, tool]) => {
22030
22120
  if (tool.kind !== "mcp_remote" || tool.disabled || tool.auth.kind !== "mcp_oauth") {
@@ -22055,21 +22145,36 @@ function readApplyDocumentFile(path2) {
22055
22145
  if (documents.length === 1) {
22056
22146
  const system = ProjectApplySystemConfigSchema.safeParse(documents[0]);
22057
22147
  if (system.success) {
22058
- return system.data.spec;
22148
+ const resources = system.data.spec.resources;
22149
+ return {
22150
+ ...system.data.spec,
22151
+ resourceRecords: resources.map((resource) => ({
22152
+ resource,
22153
+ generatedFromAgent: false
22154
+ }))
22155
+ };
22059
22156
  }
22060
22157
  }
22158
+ const resourceRecords = documents.flatMap(
22159
+ (document) => readApplyDocument(document, path2)
22160
+ );
22061
22161
  return {
22062
22162
  delete: [],
22063
22163
  dryRun: false,
22064
22164
  prune: false,
22065
- resources: documents.map((document) => readApplyDocument(document, path2)),
22165
+ resources: resourceRecords.map((record2) => record2.resource),
22166
+ resourceRecords,
22066
22167
  assets: {}
22067
22168
  };
22068
22169
  }
22069
22170
  function readApplyDocument(document, path2) {
22070
22171
  const candidate = applyCandidate(document);
22071
22172
  if (candidate.kind === RESOURCE_KIND_SESSION) {
22072
- return compileAgentDocumentValue(document, path2).resource;
22173
+ const result = compileAgentDocumentValue(document, path2);
22174
+ return result.resources.map((resource) => ({
22175
+ resource,
22176
+ generatedFromAgent: resource !== result.resource
22177
+ }));
22073
22178
  }
22074
22179
  const parsed = APPLY_SCHEMAS[candidate.kind].safeParse(candidate.value);
22075
22180
  if (!parsed.success) {
@@ -22077,11 +22182,16 @@ function readApplyDocument(document, path2) {
22077
22182
  `Invalid ${candidate.kind} resource: ${parsed.error.message}`
22078
22183
  );
22079
22184
  }
22080
- return {
22081
- kind: candidate.kind,
22082
- metadata: parsed.data.metadata,
22083
- spec: parsed.data.spec
22084
- };
22185
+ return [
22186
+ {
22187
+ resource: {
22188
+ kind: candidate.kind,
22189
+ metadata: parsed.data.metadata,
22190
+ spec: parsed.data.spec
22191
+ },
22192
+ generatedFromAgent: false
22193
+ }
22194
+ ];
22085
22195
  }
22086
22196
  function readApplyAssets(resources, projectRoot) {
22087
22197
  const assets = {};
@@ -22197,23 +22307,19 @@ function isInside(path2, parent) {
22197
22307
  return path2.startsWith(`${parent}/`);
22198
22308
  }
22199
22309
  function applyCandidate(document) {
22200
- if (!isRecord3(document) || !("kind" in document)) {
22310
+ if (!isRecord2(document) || !("kind" in document)) {
22201
22311
  return { kind: RESOURCE_KIND_SESSION, value: document };
22202
22312
  }
22203
- if (document.kind === LEGACY_RESOURCE_KIND_SESSION) {
22204
- return {
22205
- kind: RESOURCE_KIND_SESSION,
22206
- value: {
22207
- metadata: document.metadata,
22208
- spec: document.spec
22209
- }
22210
- };
22313
+ if (document.kind === "session") {
22314
+ throw new Error(
22315
+ 'Legacy resource kind "session" is no longer supported. Use .auto/agents with the root-level Agent facade format.'
22316
+ );
22211
22317
  }
22212
22318
  if (!PROJECT_APPLY_RESOURCE_KINDS.includes(
22213
22319
  document.kind
22214
22320
  )) {
22215
22321
  throw new Error(
22216
- `Unsupported apply resource kind "${String(document.kind)}"; supported kinds are ${PROJECT_APPLY_RESOURCE_KINDS.map((kind2) => `"${kind2}"`).join(", ")} (legacy alias "session" is also accepted)`
22322
+ `Unsupported apply resource kind "${String(document.kind)}"; supported kinds are ${PROJECT_APPLY_RESOURCE_KINDS.map((kind2) => `"${kind2}"`).join(", ")}`
22217
22323
  );
22218
22324
  }
22219
22325
  const kind = document.kind;
@@ -22225,13 +22331,10 @@ function applyCandidate(document) {
22225
22331
  }
22226
22332
  };
22227
22333
  }
22228
- function applyDirectories(kind) {
22229
- return [...LEGACY_APPLY_DIRECTORIES[kind] ?? [], APPLY_DIRECTORIES[kind]];
22230
- }
22231
22334
  function primaryApplyDirectory(kind) {
22232
22335
  return APPLY_DIRECTORIES[kind];
22233
22336
  }
22234
- function isRecord3(value) {
22337
+ function isRecord2(value) {
22235
22338
  return typeof value === "object" && value !== null && !Array.isArray(value);
22236
22339
  }
22237
22340
  function resourceApplyFiles(directory, entries) {
@@ -22250,7 +22353,7 @@ function resourceApplyFiles(directory, entries) {
22250
22353
  }
22251
22354
  return files.sort((left, right) => left.localeCompare(right));
22252
22355
  }
22253
- var APPLY_DIRECTORIES, LEGACY_APPLY_DIRECTORIES, APPLY_SCHEMAS, ALLOWED_AVATAR_EXTENSIONS;
22356
+ var APPLY_DIRECTORIES, APPLY_SCHEMAS, ALLOWED_AVATAR_EXTENSIONS;
22254
22357
  var init_files = __esm({
22255
22358
  "src/commands/apply/files.ts"() {
22256
22359
  "use strict";
@@ -22261,9 +22364,6 @@ var init_files = __esm({
22261
22364
  identity: "identities",
22262
22365
  agent: "agents"
22263
22366
  };
22264
- LEGACY_APPLY_DIRECTORIES = {
22265
- [RESOURCE_KIND_SESSION]: ["sessions"]
22266
- };
22267
22367
  APPLY_SCHEMAS = {
22268
22368
  environment: EnvironmentApplyRequestSchema,
22269
22369
  identity: IdentityApplyRequestSchema,
@@ -22563,11 +22663,8 @@ function parseProjectResourceReference(resource) {
22563
22663
  if (!PROJECT_APPLY_RESOURCE_KINDS.includes(
22564
22664
  kind
22565
22665
  )) {
22566
- if (kind === LEGACY_RESOURCE_KIND_SESSION) {
22567
- return { kind: RESOURCE_KIND_SESSION, name };
22568
- }
22569
22666
  throw new Error(
22570
- `Unsupported resource kind "${kind}"; supported kinds are ${PROJECT_APPLY_RESOURCE_KINDS.map((value) => `"${value}"`).join(", ")} (legacy alias "session" is also accepted)`
22667
+ `Unsupported resource kind "${kind}"; supported kinds are ${PROJECT_APPLY_RESOURCE_KINDS.map((value) => `"${value}"`).join(", ")}`
22571
22668
  );
22572
22669
  }
22573
22670
  return {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@autohq/cli",
3
- "version": "0.1.137",
3
+ "version": "0.1.139",
4
4
  "license": "SEE LICENSE IN README.md",
5
5
  "publishConfig": {
6
6
  "access": "public"