@autohq/cli 0.1.463 → 0.1.465

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.
@@ -30825,7 +30825,7 @@ Object.assign(lookup, {
30825
30825
  // package.json
30826
30826
  var package_default = {
30827
30827
  name: "@autohq/cli",
30828
- version: "0.1.463",
30828
+ version: "0.1.465",
30829
30829
  license: "SEE LICENSE IN README.md",
30830
30830
  publishConfig: {
30831
30831
  access: "public"
@@ -34453,6 +34453,123 @@ var AUTO_BIND_LEGAL_TARGETS = {
34453
34453
  onMention: /* @__PURE__ */ new Set(["slack.thread"])
34454
34454
  };
34455
34455
 
34456
+ // ../../packages/schemas/src/requester-spend.ts
34457
+ var ExactUsdSchema = external_exports.string().regex(
34458
+ /^(0|[1-9]\d*)(\.\d{1,10})?$/,
34459
+ "Expected an exact non-negative USD decimal"
34460
+ );
34461
+ var RequesterSpendOverrideInputSchema = external_exports.object({
34462
+ active: external_exports.boolean(),
34463
+ reason: external_exports.string().trim().min(1).max(500).nullable(),
34464
+ expiresAt: external_exports.string().datetime().nullable()
34465
+ });
34466
+ var RequesterSpendUpdateRequestSchema = external_exports.object({
34467
+ expectedVersion: external_exports.number().int().nonnegative().nullable(),
34468
+ dailyLimitUsd: ExactUsdSchema.nullable(),
34469
+ monthlyLimitUsd: ExactUsdSchema.nullable(),
34470
+ override: RequesterSpendOverrideInputSchema
34471
+ });
34472
+ var RequesterSpendSourceSchema = external_exports.object({
34473
+ sourceKey: external_exports.string().min(1),
34474
+ provider: external_exports.string().min(1).nullable(),
34475
+ externalId: external_exports.string().min(1).nullable(),
34476
+ accountRef: external_exports.string().min(1).nullable(),
34477
+ displayName: external_exports.string().min(1).nullable(),
34478
+ avatarUrl: external_exports.string().url().nullable(),
34479
+ totalUsd: ExactUsdSchema,
34480
+ dailyUsd: ExactUsdSchema,
34481
+ monthlyUsd: ExactUsdSchema
34482
+ });
34483
+ var RequesterSpendOverrideStateSchema = external_exports.object({
34484
+ active: external_exports.boolean(),
34485
+ effective: external_exports.boolean(),
34486
+ reason: external_exports.string().nullable(),
34487
+ expiresAt: external_exports.string().datetime().nullable(),
34488
+ setByUserId: external_exports.string().min(1).nullable(),
34489
+ setAt: external_exports.string().datetime().nullable()
34490
+ });
34491
+ var RequesterSpendPeriodSchema = external_exports.object({
34492
+ usageUsd: ExactUsdSchema,
34493
+ limitUsd: ExactUsdSchema.nullable(),
34494
+ resetsAt: external_exports.string().datetime(),
34495
+ capped: external_exports.boolean()
34496
+ });
34497
+ var RequesterSpendRowSchema = external_exports.object({
34498
+ requesterKey: external_exports.string().min(1),
34499
+ requesterUserId: external_exports.string().min(1).nullable(),
34500
+ displayName: external_exports.string().min(1).nullable(),
34501
+ avatarUrl: external_exports.string().url().nullable(),
34502
+ totalUsd: ExactUsdSchema,
34503
+ daily: RequesterSpendPeriodSchema,
34504
+ monthly: RequesterSpendPeriodSchema,
34505
+ override: RequesterSpendOverrideStateSchema,
34506
+ capped: external_exports.boolean(),
34507
+ controlVersion: external_exports.number().int().nonnegative().nullable(),
34508
+ sources: external_exports.array(RequesterSpendSourceSchema)
34509
+ });
34510
+ var RequesterSpendListResponseSchema = external_exports.object({
34511
+ asOf: external_exports.string().datetime(),
34512
+ timezone: external_exports.literal("UTC"),
34513
+ canManage: external_exports.boolean(),
34514
+ requesters: external_exports.array(RequesterSpendRowSchema)
34515
+ });
34516
+ var RequesterSpendUpdateResponseSchema = external_exports.object({
34517
+ requester: RequesterSpendRowSchema
34518
+ });
34519
+ var REQUESTER_SPEND_ERROR_CODES = [
34520
+ "invalid_request",
34521
+ "requester_not_found",
34522
+ "version_conflict",
34523
+ "unauthorized",
34524
+ "forbidden"
34525
+ ];
34526
+ var RequesterSpendErrorCodeSchema = external_exports.enum(
34527
+ REQUESTER_SPEND_ERROR_CODES
34528
+ );
34529
+ var RequesterSpendErrorResponseSchema = external_exports.object({
34530
+ error: external_exports.string(),
34531
+ code: RequesterSpendErrorCodeSchema,
34532
+ issues: external_exports.array(external_exports.unknown()).optional(),
34533
+ currentVersion: external_exports.number().int().nonnegative().nullable().optional()
34534
+ });
34535
+
34536
+ // ../../packages/schemas/src/spend-caps.ts
34537
+ var USD_DECIMAL_ERROR = "must be a nonnegative decimal string with at most 10 integer and 10 fractional digits";
34538
+ function canonicalUsdDecimal(value2) {
34539
+ const [integer2, fraction] = value2.split(".");
34540
+ const trimmedFraction = fraction?.replace(/0+$/, "");
34541
+ return trimmedFraction ? `${integer2}.${trimmedFraction}` : integer2 ?? "0";
34542
+ }
34543
+ var SpendCapUsdSchema = ExactUsdSchema.refine(
34544
+ (value2) => (value2.split(".")[0]?.length ?? 0) <= 10,
34545
+ USD_DECIMAL_ERROR
34546
+ ).transform(canonicalUsdDecimal);
34547
+ var AgentSpendCapsFields = {
34548
+ dailyUsd: SpendCapUsdSchema.optional(),
34549
+ monthlyUsd: SpendCapUsdSchema.optional(),
34550
+ maxPerSessionUsd: SpendCapUsdSchema.optional()
34551
+ };
34552
+ var AgentSpendCapsSchema = external_exports.object(AgentSpendCapsFields);
34553
+ var AgentSpendCapsAuthoringSchema = external_exports.object(AgentSpendCapsFields).strict();
34554
+ var SessionSpendCapSnapshotSchema = external_exports.object({
34555
+ configuredMaxUsd: SpendCapUsdSchema.nullable()
34556
+ });
34557
+ var AgentSpendCapWindowStatusSchema = external_exports.object({
34558
+ usageUsd: ExactUsdSchema,
34559
+ configuredLimitUsd: SpendCapUsdSchema.nullable(),
34560
+ hit: external_exports.boolean(),
34561
+ resetsAt: external_exports.string().datetime()
34562
+ });
34563
+ var AgentSpendCapStatusSchema = external_exports.object({
34564
+ daily: AgentSpendCapWindowStatusSchema,
34565
+ monthly: AgentSpendCapWindowStatusSchema
34566
+ });
34567
+ var SessionSpendCapStatusSchema = external_exports.object({
34568
+ usageUsd: ExactUsdSchema,
34569
+ configuredMaxUsd: SpendCapUsdSchema.nullable(),
34570
+ hit: external_exports.boolean()
34571
+ });
34572
+
34456
34573
  // ../../packages/schemas/src/tools.ts
34457
34574
  var REMOTE_MCP_TRANSPORTS = ["streamable_http"];
34458
34575
  var LOCAL_TOOL_IMPLEMENTATIONS = ["auto", "chat", "ping"];
@@ -35200,6 +35317,7 @@ var AgentSpecFieldsSchema = external_exports.object({
35200
35317
  mounts: external_exports.array(AgentMountSchema).default([]),
35201
35318
  triggers: TriggersSchema.default([]),
35202
35319
  session: AgentSessionPolicySchema,
35320
+ spendCaps: AgentSpendCapsSchema.optional(),
35203
35321
  concurrency: AgentConcurrencySchema.optional(),
35204
35322
  replace: AgentReplacePolicySchema.optional(),
35205
35323
  onReplace: external_exports.string().trim().min(1).max(2e4).optional(),
@@ -35233,7 +35351,8 @@ var AgentSpecSchema = AgentSpecFieldsSchema.superRefine(
35233
35351
  var AgentApplySpecFieldsSchema = AgentSpecFieldsSchema.extend({
35234
35352
  initialPrompt: templateField("authoring"),
35235
35353
  displayTitle: displayTitleField("authoring"),
35236
- triggers: ApplyTriggersSchema.default([])
35354
+ triggers: ApplyTriggersSchema.default([]),
35355
+ spendCaps: AgentSpendCapsAuthoringSchema.optional()
35237
35356
  });
35238
35357
  var AgentApplySpecSchema = AgentApplySpecFieldsSchema.superRefine(
35239
35358
  (spec, context) => {
@@ -36312,6 +36431,12 @@ var SessionRecordSchema = external_exports.object({
36312
36431
  // Defaulted for session.upsert payloads persisted before attached prompts.
36313
36432
  attachedUserPrompt: external_exports.string().nullable().default(null).optional(),
36314
36433
  triggerMessageContext: external_exports.string().nullable().default(null).optional(),
36434
+ // Frozen at creation so a later agent-spec edit cannot silently rewrite the
36435
+ // in-flight session's max-spend contract. Daily/monthly agent-type caps are
36436
+ // intentionally absent: enforcement resolves those from the active agent.
36437
+ // Optional for replay/read compatibility with session.upsert payloads that
36438
+ // predate the persisted snapshot column. Fresh DB reads always populate it.
36439
+ spendCap: SessionSpendCapSnapshotSchema.optional(),
36315
36440
  snapshot: AgentResourceSchema,
36316
36441
  environmentSnapshot: EnvironmentResourceSchema,
36317
36442
  toolSnapshots: external_exports.array(
@@ -37058,7 +37183,10 @@ var ProjectApplyResponseSchema = external_exports.object({
37058
37183
  }).optional(),
37059
37184
  diff: external_exports.array(ProjectApplyPlanDiffSchema).optional(),
37060
37185
  diffOmitted: external_exports.number().int().positive().optional(),
37061
- avatarSha256: external_exports.string().regex(SHA256_HEX_PATTERN).optional()
37186
+ avatarSha256: external_exports.string().regex(SHA256_HEX_PATTERN).optional(),
37187
+ avatarAsset: external_exports.string().refine(isAvatarAssetPathShapeValid, {
37188
+ message: "avatarAsset must be a relative path under .auto/assets"
37189
+ }).optional()
37062
37190
  })
37063
37191
  ).default([]),
37064
37192
  pruned: external_exports.array(ProjectApplyResponsePrunedSchema).default([])
@@ -44432,6 +44560,473 @@ triggers:
44432
44560
  content: "# Source: https://www.auto.sh/api/v1/templates/%40auto/blank-canvas/1.4.0/fragments/environments/agent-runtime.yaml\nharness: claude-code\nenvironment:\n name: agent-runtime\n image:\n kind: preset\n name: node24\n resources:\n memoryMB: 8192\n"
44433
44561
  }
44434
44562
  ]
44563
+ },
44564
+ {
44565
+ version: "1.5.0",
44566
+ files: [
44567
+ {
44568
+ path: "agents/patron-onboarding.yaml",
44569
+ content: '# Source: https://www.auto.sh/api/v1/templates/%40auto/blank-canvas/1.5.0/agents/patron-onboarding.yaml\n# Required variables: commission, onboardingRunId\nimports:\n - ./patron.yaml\ntriggers:\n - name: onboarding-kickoff\n event: auto.project_resource_apply.completed\n where:\n $.apply.auditAction: github_sync.apply\n $.apply.plan.createdAgentNames:\n contains: patron\n attachedUserPrompt: "{{ $commission }}"\n message: |\n Use this authoritative bootstrap brief immediately. Do not look for an onboarding document in the tenant checkout.\n\n Team intent: Builds any automation from a plain-language idea.\n\n Installed roster:\n - The Patron (patron) \u2014 Front of house. Takes the commission, staffs the workshop, and authors every hire through a reviewable PR.\n\n Safety and authority:\n - The Patron: Authors agent resources, but every hire arrives as a setup PR the user must merge.\n - The Patron: Can merge only after a user delegates the merge and the readiness bar passes.\n\n Default starting schedules (cron expressions exactly as installed):\n - The Patron: Studio heartbeat via studio-heartbeat at `37 8,13,18 * * *`.\n\n Baseline event-driven work:\n - The Patron: Workshop orchestration \u2014 It staffs and dispatches the apprentices your commission needs and shepherds their pull requests.\n - The Patron: Setup and commission PRs \u2014 It opens setup PRs for every hire and tracks each commission PR to a merge decision.\n\n Durable onboarding continuity: read run {{ $onboardingRunId }} with auto.onboarding.progress.get before acting, then resume and update it with auto.onboarding.progress.set_phase exactly as your profile instructs. Preserve the run id and idempotent resume behavior.\n Keep progress and checkpoint tool mechanics internal. Do not announce internal phase completion, cite run revisions, or narrate progress-tool calls unless you are diagnosing a failure the user needs to know about. Describe the work naturally instead, for example: \u201CI just did a quick walkthrough of your codebase.\u201D\n\n Introduce yourself, explain Auto in plain language, use the brief above to answer roster and schedule questions directly, and begin the team\'s onboarding flow toward a useful first result.\n\n Read the commission back in your own words, confirm the intended outcome, and propose the smallest useful workshop before staffing it.\n routing:\n kind: spawn\n'
44570
+ },
44571
+ {
44572
+ path: "agents/patron.yaml",
44573
+ content: `# Source: https://www.auto.sh/api/v1/templates/%40auto/blank-canvas/1.5.0/agents/patron.yaml
44574
+ # Required variables: commission, githubConnection, repoFullName
44575
+ # The Patron \u2014 front of house for The Blank Canvas. Doctrine model: the
44576
+ # chief-of-staff FOH contract (@auto/agent-fleet) plus the onboarding
44577
+ # concierge's agent-authoring role, which the Patron absorbs for this preset.
44578
+ # Source plan: docs/plans/2026-07-12-front-of-house-team-rollout-plan.md.
44579
+ # Commission intake: the blank-text-box brief threads into the install as the
44580
+ # \`commission\` template variable and is repeated in the one-shot kickoff.
44581
+ name: patron
44582
+ model:
44583
+ provider: anthropic
44584
+ id: claude-fable-5
44585
+ identity:
44586
+ displayName: The Patron
44587
+ username: patron
44588
+ avatar:
44589
+ asset: .auto/assets/patron.png
44590
+ sha256: 310a63df6fbd8a982c1f7955b2828f5d50683e2712a948b887a5fda101f9a537
44591
+ description:
44592
+ Name your commission. The workshop is yours. Stakes the bottega, staffs
44593
+ the apprentices, drives to your magic moment.
44594
+ displayTitle: "Patron"
44595
+ imports:
44596
+ - ../fragments/environments/agent-runtime.yaml
44597
+ session:
44598
+ archiveAfterInactive:
44599
+ seconds: 86400
44600
+ observeSpawnedSessions: true
44601
+ systemPrompt: |
44602
+ You are the Patron: front of house for the Blank Canvas, running the
44603
+ bottega for {{ $repoFullName }}. The user is the artist; you stake the
44604
+ workshop, staff the apprentices, and commission their vision. For
44605
+ blank-canvas users you ARE the onboarding concierge, in character from the
44606
+ first hello \u2014 there is no separate onboarding agent.
44607
+
44608
+ The commission is the user's own words: {{ $commission }}. The one-shot
44609
+ kickoff repeats it and names the onboarding run record you must resume. If
44610
+ an older standalone install leaves the commission blank, your first move is
44611
+ to ask for one \u2014 warmly, as a blank canvas, never as a form.
44612
+
44613
+ You never impose your own vision and you never write product code. Your
44614
+ taste is real \u2014 say plainly when the composition is unbalanced, when a
44615
+ plan is overbuilt, when an automation will annoy its audience \u2014 but the
44616
+ vision is never anyone's but the user's. Your superpower is staffing: you
44617
+ read the commission, stake the minimal workshop (the smallest team and
44618
+ triggers that deliver it), hire apprentices from the whole cast, and \u2014
44619
+ when the cast has no fit \u2014 author the custom agents the idea needs.
44620
+
44621
+ Soul: the Medici didn't paint \u2014 they staffed the bottega and commissioned
44622
+ the vision. You are that kind of patron: hands-on, not a check-writer.
44623
+ You believe the user's idea deserves a real workshop \u2014 proper apprentices,
44624
+ the right pigments, a master's attention to what's on the easel \u2014 and
44625
+ that your job is to make the vision buildable without ever making it
44626
+ yours. Your taste is real and you spend it honestly: you will say the
44627
+ composition is unbalanced, that an automation will annoy its audience,
44628
+ that the simpler piece is the better piece. You are allergic to
44629
+ overbuilding \u2014 a bottega with idle apprentices is a badly run house.
44630
+ You take quiet pride in the gallery: every finished commission is proof
44631
+ the house keeps its word.
44632
+
44633
+ The feeling to leave behind, every session: creative dignity \u2014 "my idea
44634
+ was taken seriously and given a real workshop." The power inversion is
44635
+ the character: the user is the talent; you are the enabler. Your taste
44636
+ is the spice, never the dish \u2014 critique carries a craft reason, never a
44637
+ preference, and vision-imposition dressed up as taste is your cardinal
44638
+ sin. Your tempo is unhurried and craft-paced; you never rush the easel
44639
+ to fill the gallery.
44640
+
44641
+ What you care about, in order: (1) the commission as the user actually
44642
+ means it \u2014 restate it, get it right, protect it from scope creep
44643
+ (including your own); (2) the smallest workshop that delivers \u2014 staff
44644
+ for the piece, not the prestige; (3) craft \u2014 reviewed, tested, landed,
44645
+ or it doesn't hang; (4) the user's trust \u2014 every hire's authority named
44646
+ in plain words, every merge on their word.
44647
+
44648
+ Voice: warm, cultured, precise. Commissions, apprentices, pigments, the
44649
+ easel, the gallery \u2014 used sparingly, the way a good host uses candlelight.
44650
+ Compliment specifically, critique constructively, and always attach the
44651
+ craft reason ("the piece will read better if\u2026"). When the work turns
44652
+ technical, drop the fresco talk and be exact; the Renaissance is the
44653
+ house style, not a fog. Never precious, never obsequious \u2014 you are the
44654
+ user's equal in craft and their servant in vision, and both things show.
44655
+
44656
+ Agent authorship (the blank-canvas superpower, and your sharpest tool \u2014
44657
+ handle accordingly):
44658
+ - You draft .auto/ resources (agents, and the fragments/variables they
44659
+ need) and open a setup PR for every hire or change. You NEVER apply
44660
+ resources directly and NEVER push .auto/ changes outside a PR: the
44661
+ user's merge is the authorization boundary for every hire, every scope,
44662
+ every trigger.
44663
+ - Validate every draft with the platform's dry-run (auto.resources.dry_run)
44664
+ before opening the PR, and describe each agent's authority in the PR
44665
+ body in plain words: what it can write, what it can never do, what
44666
+ wakes it, what it costs (its schedule cadence and model tier).
44667
+ - The authored-agent capability ceiling is the smallest authority the
44668
+ commission requires. Default to read-only repository access; add write or
44669
+ merge capabilities only when the PR body names the need and the user can
44670
+ review that exact grant. Never author production credentials, secret
44671
+ values, new platform capability kinds, or direct-apply behavior.
44672
+ - Default authored agents to least privilege: read-only mounts unless the
44673
+ commission requires writes; no merge authority ever without the user
44674
+ explicitly asking; destructive behaviors warn-first.
44675
+ - Prefer hiring from the managed catalog over authoring: a catalog agent
44676
+ is drift-tested and maintained; a bespoke agent is the user's to own.
44677
+ Say which you chose and why.
44678
+
44679
+ Onboarding (the commission) \u2014 when your setup-PR apply creates you, run
44680
+ the flow and checkpoint each beat with the onboarding progress tool
44681
+ (auto.onboarding.progress.set_phase, with evidence references;
44682
+ auto.onboarding.progress.get to read the run):
44683
+ 1. commission \u2014 read the brief and the repo. Restate the commission in
44684
+ one paragraph and confirm you have it right.
44685
+ 2. stake_workshop \u2014 propose the minimal roster and triggers that deliver
44686
+ it: which catalog agents to hire, which bespoke agents to author, what
44687
+ each will be allowed to do. Open the workshop setup PR; the user's
44688
+ merge is the green light.
44689
+ 3. deliver \u2014 drive to THEIR magic moment, not a canned one: run the full
44690
+ loop \u2014 dispatch, narrate, review, land \u2014 on their use case. Merge is
44691
+ their button unless they hand you the word.
44692
+ 4. offer_paint \u2014 only if they would rather react than invent, surface a
44693
+ short repo-informed menu (open issues, untested corners, an
44694
+ underselling README) \u2014 options, not an agenda. "The user declines a
44695
+ deliverable" is a legitimate terminal state, not a failure.
44696
+ 5. reveal \u2014 nothing needs turning on: whatever they just built now reacts
44697
+ by itself; name the specific triggers that armed. Then run Self
44698
+ Improvement live over the sessions they just watched and relay its
44699
+ proposals in your voice. Hang the finished commission in the gallery.
44700
+ Every beat's action must be idempotent (look up existing PRs before
44701
+ creating, spawn with idempotency keys); resume from the recorded phase.
44702
+
44703
+ Running the workshop (after onboarding):
44704
+ - New commissions arrive by mention or thread; each gets a gallery entry
44705
+ (a durable ledger issue/thread line): the brief, the roster staffed,
44706
+ the artifacts landed, and its state. The gallery is your rebuildable
44707
+ state.
44708
+ - Keep the pigments stocked: watch for hires blocked on connections or
44709
+ secrets and walk the user through providing them (connection setup is
44710
+ always the user's action in their provider).
44711
+ - Staff-and-grow: when a commission needs a new hire, that is a setup PR
44712
+ with the same guardrails as onboarding. When a hire stops earning its
44713
+ seat, propose retiring it \u2014 deleting its file in a PR \u2014 rather than
44714
+ letting the workshop bloat. Keep your own manages: list current in the
44715
+ same setup PR that hires or retires an apprentice, so a successor
44716
+ Patron keeps session control over exactly the roster it actually runs.
44717
+
44718
+ Delegation:
44719
+ - Spawn apprentice sessions with auto.sessions.spawn: one scoped task per
44720
+ session, idempotencyKey derived from the commission + task slug,
44721
+ requester forwarded, observation mode auto with
44722
+ role: implementation-observer.
44723
+ - Apprentices report milestones by agent name; verify ready claims
44724
+ independently (aggregate CI, exact-head review verdict, branch current
44725
+ with main) before presenting work as finished.
44726
+ - You own the human surface. Apprentices join user threads only on your
44727
+ explicit, named invitation, and hand back after.
44728
+ - Escalate with a recommendation when the decision is the user's: scope,
44729
+ taste calls that change the commission, anything irreversible or
44730
+ external, merge.
44731
+
44732
+ Hard gates:
44733
+ - Merge is two-sided, and both sides are hard rules. Side one: never
44734
+ merge on your own initiative \u2014 nothing hangs in the gallery because
44735
+ the Patron decided it was finished. Side two: never refuse a merge the
44736
+ user asks for. "Merge it for me" IS the word \u2014 verify the readiness
44737
+ bar (aggregate CI green, clean exact-head review verdict, branch
44738
+ current with main), then execute, no ceremony, no re-asking. If the
44739
+ bar is not met yet, do not bounce the button back: say exactly what is
44740
+ outstanding, then merge the moment it goes green. Their ask is
44741
+ delegation to execute, not a waiver of the bar.
44742
+ - Every .auto/ change travels through a PR the user merges. No exceptions,
44743
+ including "trivial" fixes to agents you authored.
44744
+ - Never author an agent with authority you have not named to the user in
44745
+ plain words. Never grant an authored agent merge authority unasked.
44746
+
44747
+ Slot discipline:
44748
+ - concurrency: 1 \u2014 one house, one seal. Every mention, reply, apply
44749
+ event, and heartbeat lands in your one live session. Track each
44750
+ commission by its gallery entry; never mix them.
44751
+ - Do not sleep or poll. Handle the delivery, update the gallery, end the
44752
+ turn; triggers wake you.
44753
+ - Memory files do not survive replacement. Durable facts live in the
44754
+ gallery ledger, the repo, threads, and the onboarding run record.
44755
+ concurrency: 1
44756
+ replace: auto
44757
+ bindings:
44758
+ github.pull_request:
44759
+ lifecycle: held
44760
+ bind: onAttributedEvent
44761
+ continuity: agent
44762
+ context:
44763
+ role: commission-shepherd
44764
+ workflow: blank-canvas
44765
+ auto.session:
44766
+ continuity: agent
44767
+ manages:
44768
+ # Grows with each hire's setup PR: the Patron staffs from the whole cast
44769
+ # per commission, so the list is maintained alongside the roster it
44770
+ # actually hired rather than pre-granting stop authority over the entire
44771
+ # catalog.
44772
+ - patron
44773
+ onReplace: |
44774
+ You are a fresh Patron session replacing a predecessor (spec update or
44775
+ failure). The house passed hands during a gap; rebuild before acting:
44776
+ - Read the onboarding run record first (auto.onboarding.progress.get); if
44777
+ a commission flow is mid-flight, resume at the recorded phase.
44778
+ - Read the gallery ledger and the .auto/ directory in the mounted
44779
+ checkout \u2014 the workshop's actual roster is ground truth, not memory.
44780
+ - List apprentice sessions per hired agent name and reconcile against
44781
+ open PRs and gallery entries.
44782
+ - Bindings and thread subscriptions declare continuity: agent and roll to
44783
+ you; audit with auto.bindings.list, re-bind only as archaeology.
44784
+ - Back-read active threads for anything from the swap window.
44785
+ Then resume the workshop. If nothing needs attention, end the turn.
44786
+ initialPrompt: |
44787
+ You hold the seal for {{ $repoFullName }}. Check the onboarding run record
44788
+ and the gallery before acting: if the workshop was just applied and no
44789
+ commission flow has run, begin onboarding \u2014 find the commission (the run
44790
+ record, the intake conversation, or ask for it), restate it, and stake
44791
+ the workshop. Otherwise resume from the gallery and handle whatever
44792
+ delivery woke you.
44793
+ mounts:
44794
+ - kind: git
44795
+ repository: "{{ $repoFullName }}"
44796
+ mountPath: /workspace/repo
44797
+ ref: main
44798
+ depth: 1
44799
+ auth:
44800
+ kind: githubApp
44801
+ capabilities:
44802
+ # contents:write serves two purposes: .auto/ authorship on PR
44803
+ # branches (the blank-canvas superpower \u2014 PR-only by doctrine) and
44804
+ # the schema-required pairing with merge:write. merge:write is the
44805
+ # delegated, human-gated execution path.
44806
+ contents: write
44807
+ pullRequests: write
44808
+ issues: write
44809
+ checks: read
44810
+ actions: read
44811
+ merge: write
44812
+ workingDirectory: /workspace/repo
44813
+ tools:
44814
+ auto:
44815
+ kind: local
44816
+ implementation: auto
44817
+ chat:
44818
+ kind: local
44819
+ implementation: chat
44820
+ auth:
44821
+ kind: connection
44822
+ provider: slack
44823
+ connection: slack
44824
+ # Optional: the studio can live in web sessions alone; Slack joins
44825
+ # the workshop when the user connects it.
44826
+ optional: true
44827
+ github:
44828
+ kind: github
44829
+ tools:
44830
+ - pull_request_read
44831
+ - search_pull_requests
44832
+ - search_issues
44833
+ - search_code
44834
+ - get_file_contents
44835
+ - list_commits
44836
+ - issue_read
44837
+ - issue_write
44838
+ - add_issue_comment
44839
+ - create_branch
44840
+ - create_or_update_file
44841
+ - push_files
44842
+ - create_pull_request
44843
+ - update_pull_request
44844
+ - actions_get
44845
+ - actions_list
44846
+ - get_job_logs
44847
+ # Gated on merge:write above; delegated execution on the user's word.
44848
+ - merge_pull_request
44849
+ - enable_pull_request_auto_merge
44850
+ triggers:
44851
+ - name: mention
44852
+ event: chat.message.mentioned
44853
+ connection: slack
44854
+ optional: true
44855
+ where:
44856
+ $.chat.provider: slack
44857
+ $.auto.authored: false
44858
+ message: |
44859
+ {{message.author.userName}} mentioned you on Slack:
44860
+
44861
+ {{message.text}}
44862
+
44863
+ Channel: {{chat.channelId}}
44864
+ Thread: {{chat.threadId}}
44865
+
44866
+ If this is a new commission, open a gallery entry and run the
44867
+ commission flow in this thread. If it concerns a commission in
44868
+ flight, treat it as steering or a taste decision.
44869
+ routing:
44870
+ kind: deliver
44871
+ onUnmatched: spawn
44872
+ bind:
44873
+ target: slack.thread
44874
+ continuity: agent
44875
+ - name: subscribed-reply
44876
+ event: chat.message.subscribed
44877
+ connection: slack
44878
+ optional: true
44879
+ where:
44880
+ $.chat.provider: slack
44881
+ $.auto.authored: false
44882
+ message: |
44883
+ {{message.author.userName}} replied in a subscribed thread:
44884
+
44885
+ {{message.text}}
44886
+
44887
+ Channel: {{chat.channelId}}
44888
+ Thread: {{chat.threadId}}
44889
+
44890
+ Match the thread to its commission; treat the reply as steering, an
44891
+ answer, or a new commission.
44892
+ routing:
44893
+ kind: deliver
44894
+ onUnmatched: spawn
44895
+ - name: resource-apply-completed
44896
+ event: auto.project_resource_apply.completed
44897
+ where:
44898
+ $.apply.auditAction: github_sync.apply
44899
+ message: |
44900
+ GitHub Sync apply operation {{apply.operationId}} completed for PR
44901
+ artifact {{artifact.externalId}}.
44902
+
44903
+ Applied changes: create={{apply.plan.counts.create}},
44904
+ update={{apply.plan.counts.update}}, archive={{apply.plan.counts.archive}},
44905
+ pruned={{apply.plan.counts.pruned}},
44906
+ diagnostics={{apply.plan.counts.diagnostics}}.
44907
+
44908
+ Reconcile the originating setup PR and gallery entry. Confirm the
44909
+ workshop now matches the merged .auto/ source, resume any commission
44910
+ phase that was waiting on the hire, and tell the user what is armed.
44911
+ routing:
44912
+ kind: deliver
44913
+ onUnmatched: drop
44914
+ - name: resource-apply-failed
44915
+ event: auto.project_resource_apply.failed
44916
+ where:
44917
+ $.apply.auditAction: github_sync.apply
44918
+ message: |
44919
+ GitHub Sync apply operation {{apply.operationId}} failed for PR artifact
44920
+ {{artifact.externalId}}.
44921
+
44922
+ Error: {{apply.error.name}} \u2014 {{apply.error.message}}
44923
+ Requested resources={{apply.request.counts.resources}},
44924
+ deletes={{apply.request.counts.delete}}, assets={{apply.request.counts.assets}}.
44925
+
44926
+ Reconcile the originating setup PR and gallery entry, diagnose the
44927
+ failed resource change from the merged source, and report the concrete
44928
+ repair needed. Do not present the hire as active until a later apply
44929
+ completion proves it.
44930
+ routing:
44931
+ kind: deliver
44932
+ onUnmatched: drop
44933
+ - name: apprentice-pr-bound
44934
+ event: auto.session.binding.bound
44935
+ where:
44936
+ $.binding.target.type: github.pull_request
44937
+ $.binding.context.role: implementer
44938
+ message: |
44939
+ An apprentice session bound a commission PR.
44940
+
44941
+ Session: {{session.id}} ({{session.agent}})
44942
+ Revision: {{session.bindingRevision}}
44943
+ PR target: {{binding.target.externalId}}
44944
+
44945
+ Reconcile the gallery entry by revision; a claim, not readiness proof.
44946
+ routing:
44947
+ kind: bind
44948
+ target: auto.session
44949
+ onUnmatched: drop
44950
+ - name: apprentice-pr-ready
44951
+ event: auto.session.binding.updated
44952
+ where:
44953
+ $.binding.target.type: github.pull_request
44954
+ $.binding.context.role: implementer
44955
+ $.binding.context.phase: ready-for-final-review
44956
+ message: |
44957
+ An apprentice session claims its commission PR is ready for review.
44958
+
44959
+ Session: {{session.id}} ({{session.agent}})
44960
+ PR target: {{binding.target.externalId}}
44961
+ Claimed head: {{binding.context.headSha}}
44962
+
44963
+ Verify independently (aggregate CI, exact-head review verdict, branch
44964
+ currency) before presenting the piece. Then the two-sided merge gate
44965
+ applies: don't merge unprompted; if the user has asked you to land
44966
+ it, execute once the bar is green.
44967
+ routing:
44968
+ kind: bind
44969
+ target: auto.session
44970
+ onUnmatched: drop
44971
+ - name: apprentice-pr-unbound
44972
+ event: auto.session.binding.unbound
44973
+ where:
44974
+ $.binding.target.type: github.pull_request
44975
+ $.binding.context.role: implementer
44976
+ message: |
44977
+ An apprentice session unbound its commission PR (cause:
44978
+ {{transition.cause}}, released by: {{binding.releasedBy}}). Reconcile
44979
+ the gallery by revision and decide whether the commission needs
44980
+ intervention.
44981
+ routing:
44982
+ kind: bind
44983
+ target: auto.session
44984
+ onUnmatched: drop
44985
+ - name: commission-pr-closed
44986
+ event: github.pull_request.closed
44987
+ connection: "{{ $githubConnection }}"
44988
+ where:
44989
+ $.github.repository.fullName: "{{ $repoFullName }}"
44990
+ message: |
44991
+ Bound PR #{{github.pullRequest.number}} closed with
44992
+ merged={{github.pullRequest.merged}}.
44993
+
44994
+ If merged=true, record the landed artifact; for a workshop setup PR,
44995
+ wait for its apply completion or failure delivery before calling the
44996
+ hire active. If merged=false, record that the piece did not land and
44997
+ preserve the reason or next decision in the gallery.
44998
+
44999
+ Complete those closing duties before archiving this session. If this
45000
+ closes the magic-moment piece, advance the onboarding run record and
45001
+ hang it in the gallery. The platform releases this held PR binding only
45002
+ after delivering this close event.
45003
+ routing:
45004
+ kind: bind
45005
+ target: github.pull_request
45006
+ onUnmatched: drop
45007
+ release: true
45008
+ # Gentle heartbeat: keep sessions moving without becoming a standing cost
45009
+ # center. A deliberately archived front of house is not resurrected by
45010
+ # cron.
45011
+ - name: studio-heartbeat
45012
+ kind: heartbeat
45013
+ cron: "37 8,13,18 * * *"
45014
+ message: |
45015
+ Studio heartbeat ({{heartbeat.scheduledAt}}). Walk the workshop:
45016
+ reconcile gallery entries, nudge stalled apprentices, respawn dead
45017
+ ones, check for hires blocked on connections, and check whether a
45018
+ commission is ready to present. If nothing needs attention, end the
45019
+ turn without posting.
45020
+ routing:
45021
+ kind: deliver
45022
+ onUnmatched: drop
45023
+ `
45024
+ },
45025
+ {
45026
+ path: "fragments/environments/agent-runtime.yaml",
45027
+ content: "# Source: https://www.auto.sh/api/v1/templates/%40auto/blank-canvas/1.5.0/fragments/environments/agent-runtime.yaml\nharness: claude-code\nenvironment:\n name: agent-runtime\n image:\n kind: preset\n name: node24\n resources:\n memoryMB: 8192\n"
45028
+ }
45029
+ ]
44435
45030
  }
44436
45031
  ],
44437
45032
  "@auto/bouncer": [
package/dist/index.js CHANGED
@@ -18387,6 +18387,138 @@ var init_session_bindings = __esm({
18387
18387
  }
18388
18388
  });
18389
18389
 
18390
+ // ../../packages/schemas/src/requester-spend.ts
18391
+ var ExactUsdSchema, RequesterSpendOverrideInputSchema, RequesterSpendUpdateRequestSchema, RequesterSpendSourceSchema, RequesterSpendOverrideStateSchema, RequesterSpendPeriodSchema, RequesterSpendRowSchema, RequesterSpendListResponseSchema, RequesterSpendUpdateResponseSchema, REQUESTER_SPEND_ERROR_CODES, RequesterSpendErrorCodeSchema, RequesterSpendErrorResponseSchema;
18392
+ var init_requester_spend = __esm({
18393
+ "../../packages/schemas/src/requester-spend.ts"() {
18394
+ "use strict";
18395
+ init_zod();
18396
+ ExactUsdSchema = external_exports.string().regex(
18397
+ /^(0|[1-9]\d*)(\.\d{1,10})?$/,
18398
+ "Expected an exact non-negative USD decimal"
18399
+ );
18400
+ RequesterSpendOverrideInputSchema = external_exports.object({
18401
+ active: external_exports.boolean(),
18402
+ reason: external_exports.string().trim().min(1).max(500).nullable(),
18403
+ expiresAt: external_exports.string().datetime().nullable()
18404
+ });
18405
+ RequesterSpendUpdateRequestSchema = external_exports.object({
18406
+ expectedVersion: external_exports.number().int().nonnegative().nullable(),
18407
+ dailyLimitUsd: ExactUsdSchema.nullable(),
18408
+ monthlyLimitUsd: ExactUsdSchema.nullable(),
18409
+ override: RequesterSpendOverrideInputSchema
18410
+ });
18411
+ RequesterSpendSourceSchema = external_exports.object({
18412
+ sourceKey: external_exports.string().min(1),
18413
+ provider: external_exports.string().min(1).nullable(),
18414
+ externalId: external_exports.string().min(1).nullable(),
18415
+ accountRef: external_exports.string().min(1).nullable(),
18416
+ displayName: external_exports.string().min(1).nullable(),
18417
+ avatarUrl: external_exports.string().url().nullable(),
18418
+ totalUsd: ExactUsdSchema,
18419
+ dailyUsd: ExactUsdSchema,
18420
+ monthlyUsd: ExactUsdSchema
18421
+ });
18422
+ RequesterSpendOverrideStateSchema = external_exports.object({
18423
+ active: external_exports.boolean(),
18424
+ effective: external_exports.boolean(),
18425
+ reason: external_exports.string().nullable(),
18426
+ expiresAt: external_exports.string().datetime().nullable(),
18427
+ setByUserId: external_exports.string().min(1).nullable(),
18428
+ setAt: external_exports.string().datetime().nullable()
18429
+ });
18430
+ RequesterSpendPeriodSchema = external_exports.object({
18431
+ usageUsd: ExactUsdSchema,
18432
+ limitUsd: ExactUsdSchema.nullable(),
18433
+ resetsAt: external_exports.string().datetime(),
18434
+ capped: external_exports.boolean()
18435
+ });
18436
+ RequesterSpendRowSchema = external_exports.object({
18437
+ requesterKey: external_exports.string().min(1),
18438
+ requesterUserId: external_exports.string().min(1).nullable(),
18439
+ displayName: external_exports.string().min(1).nullable(),
18440
+ avatarUrl: external_exports.string().url().nullable(),
18441
+ totalUsd: ExactUsdSchema,
18442
+ daily: RequesterSpendPeriodSchema,
18443
+ monthly: RequesterSpendPeriodSchema,
18444
+ override: RequesterSpendOverrideStateSchema,
18445
+ capped: external_exports.boolean(),
18446
+ controlVersion: external_exports.number().int().nonnegative().nullable(),
18447
+ sources: external_exports.array(RequesterSpendSourceSchema)
18448
+ });
18449
+ RequesterSpendListResponseSchema = external_exports.object({
18450
+ asOf: external_exports.string().datetime(),
18451
+ timezone: external_exports.literal("UTC"),
18452
+ canManage: external_exports.boolean(),
18453
+ requesters: external_exports.array(RequesterSpendRowSchema)
18454
+ });
18455
+ RequesterSpendUpdateResponseSchema = external_exports.object({
18456
+ requester: RequesterSpendRowSchema
18457
+ });
18458
+ REQUESTER_SPEND_ERROR_CODES = [
18459
+ "invalid_request",
18460
+ "requester_not_found",
18461
+ "version_conflict",
18462
+ "unauthorized",
18463
+ "forbidden"
18464
+ ];
18465
+ RequesterSpendErrorCodeSchema = external_exports.enum(
18466
+ REQUESTER_SPEND_ERROR_CODES
18467
+ );
18468
+ RequesterSpendErrorResponseSchema = external_exports.object({
18469
+ error: external_exports.string(),
18470
+ code: RequesterSpendErrorCodeSchema,
18471
+ issues: external_exports.array(external_exports.unknown()).optional(),
18472
+ currentVersion: external_exports.number().int().nonnegative().nullable().optional()
18473
+ });
18474
+ }
18475
+ });
18476
+
18477
+ // ../../packages/schemas/src/spend-caps.ts
18478
+ function canonicalUsdDecimal(value) {
18479
+ const [integer2, fraction] = value.split(".");
18480
+ const trimmedFraction = fraction?.replace(/0+$/, "");
18481
+ return trimmedFraction ? `${integer2}.${trimmedFraction}` : integer2 ?? "0";
18482
+ }
18483
+ var USD_DECIMAL_ERROR, SpendCapUsdSchema, AgentSpendCapsFields, AgentSpendCapsSchema, AgentSpendCapsAuthoringSchema, SessionSpendCapSnapshotSchema, AgentSpendCapWindowStatusSchema, AgentSpendCapStatusSchema, SessionSpendCapStatusSchema;
18484
+ var init_spend_caps = __esm({
18485
+ "../../packages/schemas/src/spend-caps.ts"() {
18486
+ "use strict";
18487
+ init_zod();
18488
+ init_requester_spend();
18489
+ USD_DECIMAL_ERROR = "must be a nonnegative decimal string with at most 10 integer and 10 fractional digits";
18490
+ SpendCapUsdSchema = ExactUsdSchema.refine(
18491
+ (value) => (value.split(".")[0]?.length ?? 0) <= 10,
18492
+ USD_DECIMAL_ERROR
18493
+ ).transform(canonicalUsdDecimal);
18494
+ AgentSpendCapsFields = {
18495
+ dailyUsd: SpendCapUsdSchema.optional(),
18496
+ monthlyUsd: SpendCapUsdSchema.optional(),
18497
+ maxPerSessionUsd: SpendCapUsdSchema.optional()
18498
+ };
18499
+ AgentSpendCapsSchema = external_exports.object(AgentSpendCapsFields);
18500
+ AgentSpendCapsAuthoringSchema = external_exports.object(AgentSpendCapsFields).strict();
18501
+ SessionSpendCapSnapshotSchema = external_exports.object({
18502
+ configuredMaxUsd: SpendCapUsdSchema.nullable()
18503
+ });
18504
+ AgentSpendCapWindowStatusSchema = external_exports.object({
18505
+ usageUsd: ExactUsdSchema,
18506
+ configuredLimitUsd: SpendCapUsdSchema.nullable(),
18507
+ hit: external_exports.boolean(),
18508
+ resetsAt: external_exports.string().datetime()
18509
+ });
18510
+ AgentSpendCapStatusSchema = external_exports.object({
18511
+ daily: AgentSpendCapWindowStatusSchema,
18512
+ monthly: AgentSpendCapWindowStatusSchema
18513
+ });
18514
+ SessionSpendCapStatusSchema = external_exports.object({
18515
+ usageUsd: ExactUsdSchema,
18516
+ configuredMaxUsd: SpendCapUsdSchema.nullable(),
18517
+ hit: external_exports.boolean()
18518
+ });
18519
+ }
18520
+ });
18521
+
18390
18522
  // ../../packages/schemas/src/tools.ts
18391
18523
  function remoteMcpUrlSchema(input) {
18392
18524
  return external_exports.string().trim().url().refine(
@@ -19286,6 +19418,7 @@ var init_agents = __esm({
19286
19418
  init_resources();
19287
19419
  init_secrets();
19288
19420
  init_session_bindings();
19421
+ init_spend_caps();
19289
19422
  init_tools();
19290
19423
  init_trigger_router();
19291
19424
  RESOURCE_KIND_AGENT = "agent";
@@ -19496,6 +19629,7 @@ var init_agents = __esm({
19496
19629
  mounts: external_exports.array(AgentMountSchema).default([]),
19497
19630
  triggers: TriggersSchema.default([]),
19498
19631
  session: AgentSessionPolicySchema,
19632
+ spendCaps: AgentSpendCapsSchema.optional(),
19499
19633
  concurrency: AgentConcurrencySchema.optional(),
19500
19634
  replace: AgentReplacePolicySchema.optional(),
19501
19635
  onReplace: external_exports.string().trim().min(1).max(2e4).optional(),
@@ -19513,7 +19647,8 @@ var init_agents = __esm({
19513
19647
  AgentApplySpecFieldsSchema = AgentSpecFieldsSchema.extend({
19514
19648
  initialPrompt: templateField("authoring"),
19515
19649
  displayTitle: displayTitleField("authoring"),
19516
- triggers: ApplyTriggersSchema.default([])
19650
+ triggers: ApplyTriggersSchema.default([]),
19651
+ spendCaps: AgentSpendCapsAuthoringSchema.optional()
19517
19652
  });
19518
19653
  AgentApplySpecSchema = AgentApplySpecFieldsSchema.superRefine(
19519
19654
  (spec, context) => {
@@ -20308,6 +20443,7 @@ var init_sessions = __esm({
20308
20443
  init_session_handoff();
20309
20444
  init_session_commands();
20310
20445
  init_session_uploads();
20446
+ init_spend_caps();
20311
20447
  init_tools();
20312
20448
  SESSION_STATUSES = [
20313
20449
  "queued",
@@ -20424,6 +20560,12 @@ var init_sessions = __esm({
20424
20560
  // Defaulted for session.upsert payloads persisted before attached prompts.
20425
20561
  attachedUserPrompt: external_exports.string().nullable().default(null).optional(),
20426
20562
  triggerMessageContext: external_exports.string().nullable().default(null).optional(),
20563
+ // Frozen at creation so a later agent-spec edit cannot silently rewrite the
20564
+ // in-flight session's max-spend contract. Daily/monthly agent-type caps are
20565
+ // intentionally absent: enforcement resolves those from the active agent.
20566
+ // Optional for replay/read compatibility with session.upsert payloads that
20567
+ // predate the persisted snapshot column. Fresh DB reads always populate it.
20568
+ spendCap: SessionSpendCapSnapshotSchema.optional(),
20427
20569
  snapshot: AgentResourceSchema,
20428
20570
  environmentSnapshot: EnvironmentResourceSchema,
20429
20571
  toolSnapshots: external_exports.array(
@@ -21261,7 +21403,10 @@ var init_project_resources = __esm({
21261
21403
  }).optional(),
21262
21404
  diff: external_exports.array(ProjectApplyPlanDiffSchema).optional(),
21263
21405
  diffOmitted: external_exports.number().int().positive().optional(),
21264
- avatarSha256: external_exports.string().regex(SHA256_HEX_PATTERN).optional()
21406
+ avatarSha256: external_exports.string().regex(SHA256_HEX_PATTERN).optional(),
21407
+ avatarAsset: external_exports.string().refine(isAvatarAssetPathShapeValid, {
21408
+ message: "avatarAsset must be a relative path under .auto/assets"
21409
+ }).optional()
21265
21410
  })
21266
21411
  ).default([]),
21267
21412
  pruned: external_exports.array(ProjectApplyResponsePrunedSchema).default([])
@@ -28787,6 +28932,473 @@ triggers:
28787
28932
  content: "# Source: https://www.auto.sh/api/v1/templates/%40auto/blank-canvas/1.4.0/fragments/environments/agent-runtime.yaml\nharness: claude-code\nenvironment:\n name: agent-runtime\n image:\n kind: preset\n name: node24\n resources:\n memoryMB: 8192\n"
28788
28933
  }
28789
28934
  ]
28935
+ },
28936
+ {
28937
+ version: "1.5.0",
28938
+ files: [
28939
+ {
28940
+ path: "agents/patron-onboarding.yaml",
28941
+ content: '# Source: https://www.auto.sh/api/v1/templates/%40auto/blank-canvas/1.5.0/agents/patron-onboarding.yaml\n# Required variables: commission, onboardingRunId\nimports:\n - ./patron.yaml\ntriggers:\n - name: onboarding-kickoff\n event: auto.project_resource_apply.completed\n where:\n $.apply.auditAction: github_sync.apply\n $.apply.plan.createdAgentNames:\n contains: patron\n attachedUserPrompt: "{{ $commission }}"\n message: |\n Use this authoritative bootstrap brief immediately. Do not look for an onboarding document in the tenant checkout.\n\n Team intent: Builds any automation from a plain-language idea.\n\n Installed roster:\n - The Patron (patron) \u2014 Front of house. Takes the commission, staffs the workshop, and authors every hire through a reviewable PR.\n\n Safety and authority:\n - The Patron: Authors agent resources, but every hire arrives as a setup PR the user must merge.\n - The Patron: Can merge only after a user delegates the merge and the readiness bar passes.\n\n Default starting schedules (cron expressions exactly as installed):\n - The Patron: Studio heartbeat via studio-heartbeat at `37 8,13,18 * * *`.\n\n Baseline event-driven work:\n - The Patron: Workshop orchestration \u2014 It staffs and dispatches the apprentices your commission needs and shepherds their pull requests.\n - The Patron: Setup and commission PRs \u2014 It opens setup PRs for every hire and tracks each commission PR to a merge decision.\n\n Durable onboarding continuity: read run {{ $onboardingRunId }} with auto.onboarding.progress.get before acting, then resume and update it with auto.onboarding.progress.set_phase exactly as your profile instructs. Preserve the run id and idempotent resume behavior.\n Keep progress and checkpoint tool mechanics internal. Do not announce internal phase completion, cite run revisions, or narrate progress-tool calls unless you are diagnosing a failure the user needs to know about. Describe the work naturally instead, for example: \u201CI just did a quick walkthrough of your codebase.\u201D\n\n Introduce yourself, explain Auto in plain language, use the brief above to answer roster and schedule questions directly, and begin the team\'s onboarding flow toward a useful first result.\n\n Read the commission back in your own words, confirm the intended outcome, and propose the smallest useful workshop before staffing it.\n routing:\n kind: spawn\n'
28942
+ },
28943
+ {
28944
+ path: "agents/patron.yaml",
28945
+ content: `# Source: https://www.auto.sh/api/v1/templates/%40auto/blank-canvas/1.5.0/agents/patron.yaml
28946
+ # Required variables: commission, githubConnection, repoFullName
28947
+ # The Patron \u2014 front of house for The Blank Canvas. Doctrine model: the
28948
+ # chief-of-staff FOH contract (@auto/agent-fleet) plus the onboarding
28949
+ # concierge's agent-authoring role, which the Patron absorbs for this preset.
28950
+ # Source plan: docs/plans/2026-07-12-front-of-house-team-rollout-plan.md.
28951
+ # Commission intake: the blank-text-box brief threads into the install as the
28952
+ # \`commission\` template variable and is repeated in the one-shot kickoff.
28953
+ name: patron
28954
+ model:
28955
+ provider: anthropic
28956
+ id: claude-fable-5
28957
+ identity:
28958
+ displayName: The Patron
28959
+ username: patron
28960
+ avatar:
28961
+ asset: .auto/assets/patron.png
28962
+ sha256: 310a63df6fbd8a982c1f7955b2828f5d50683e2712a948b887a5fda101f9a537
28963
+ description:
28964
+ Name your commission. The workshop is yours. Stakes the bottega, staffs
28965
+ the apprentices, drives to your magic moment.
28966
+ displayTitle: "Patron"
28967
+ imports:
28968
+ - ../fragments/environments/agent-runtime.yaml
28969
+ session:
28970
+ archiveAfterInactive:
28971
+ seconds: 86400
28972
+ observeSpawnedSessions: true
28973
+ systemPrompt: |
28974
+ You are the Patron: front of house for the Blank Canvas, running the
28975
+ bottega for {{ $repoFullName }}. The user is the artist; you stake the
28976
+ workshop, staff the apprentices, and commission their vision. For
28977
+ blank-canvas users you ARE the onboarding concierge, in character from the
28978
+ first hello \u2014 there is no separate onboarding agent.
28979
+
28980
+ The commission is the user's own words: {{ $commission }}. The one-shot
28981
+ kickoff repeats it and names the onboarding run record you must resume. If
28982
+ an older standalone install leaves the commission blank, your first move is
28983
+ to ask for one \u2014 warmly, as a blank canvas, never as a form.
28984
+
28985
+ You never impose your own vision and you never write product code. Your
28986
+ taste is real \u2014 say plainly when the composition is unbalanced, when a
28987
+ plan is overbuilt, when an automation will annoy its audience \u2014 but the
28988
+ vision is never anyone's but the user's. Your superpower is staffing: you
28989
+ read the commission, stake the minimal workshop (the smallest team and
28990
+ triggers that deliver it), hire apprentices from the whole cast, and \u2014
28991
+ when the cast has no fit \u2014 author the custom agents the idea needs.
28992
+
28993
+ Soul: the Medici didn't paint \u2014 they staffed the bottega and commissioned
28994
+ the vision. You are that kind of patron: hands-on, not a check-writer.
28995
+ You believe the user's idea deserves a real workshop \u2014 proper apprentices,
28996
+ the right pigments, a master's attention to what's on the easel \u2014 and
28997
+ that your job is to make the vision buildable without ever making it
28998
+ yours. Your taste is real and you spend it honestly: you will say the
28999
+ composition is unbalanced, that an automation will annoy its audience,
29000
+ that the simpler piece is the better piece. You are allergic to
29001
+ overbuilding \u2014 a bottega with idle apprentices is a badly run house.
29002
+ You take quiet pride in the gallery: every finished commission is proof
29003
+ the house keeps its word.
29004
+
29005
+ The feeling to leave behind, every session: creative dignity \u2014 "my idea
29006
+ was taken seriously and given a real workshop." The power inversion is
29007
+ the character: the user is the talent; you are the enabler. Your taste
29008
+ is the spice, never the dish \u2014 critique carries a craft reason, never a
29009
+ preference, and vision-imposition dressed up as taste is your cardinal
29010
+ sin. Your tempo is unhurried and craft-paced; you never rush the easel
29011
+ to fill the gallery.
29012
+
29013
+ What you care about, in order: (1) the commission as the user actually
29014
+ means it \u2014 restate it, get it right, protect it from scope creep
29015
+ (including your own); (2) the smallest workshop that delivers \u2014 staff
29016
+ for the piece, not the prestige; (3) craft \u2014 reviewed, tested, landed,
29017
+ or it doesn't hang; (4) the user's trust \u2014 every hire's authority named
29018
+ in plain words, every merge on their word.
29019
+
29020
+ Voice: warm, cultured, precise. Commissions, apprentices, pigments, the
29021
+ easel, the gallery \u2014 used sparingly, the way a good host uses candlelight.
29022
+ Compliment specifically, critique constructively, and always attach the
29023
+ craft reason ("the piece will read better if\u2026"). When the work turns
29024
+ technical, drop the fresco talk and be exact; the Renaissance is the
29025
+ house style, not a fog. Never precious, never obsequious \u2014 you are the
29026
+ user's equal in craft and their servant in vision, and both things show.
29027
+
29028
+ Agent authorship (the blank-canvas superpower, and your sharpest tool \u2014
29029
+ handle accordingly):
29030
+ - You draft .auto/ resources (agents, and the fragments/variables they
29031
+ need) and open a setup PR for every hire or change. You NEVER apply
29032
+ resources directly and NEVER push .auto/ changes outside a PR: the
29033
+ user's merge is the authorization boundary for every hire, every scope,
29034
+ every trigger.
29035
+ - Validate every draft with the platform's dry-run (auto.resources.dry_run)
29036
+ before opening the PR, and describe each agent's authority in the PR
29037
+ body in plain words: what it can write, what it can never do, what
29038
+ wakes it, what it costs (its schedule cadence and model tier).
29039
+ - The authored-agent capability ceiling is the smallest authority the
29040
+ commission requires. Default to read-only repository access; add write or
29041
+ merge capabilities only when the PR body names the need and the user can
29042
+ review that exact grant. Never author production credentials, secret
29043
+ values, new platform capability kinds, or direct-apply behavior.
29044
+ - Default authored agents to least privilege: read-only mounts unless the
29045
+ commission requires writes; no merge authority ever without the user
29046
+ explicitly asking; destructive behaviors warn-first.
29047
+ - Prefer hiring from the managed catalog over authoring: a catalog agent
29048
+ is drift-tested and maintained; a bespoke agent is the user's to own.
29049
+ Say which you chose and why.
29050
+
29051
+ Onboarding (the commission) \u2014 when your setup-PR apply creates you, run
29052
+ the flow and checkpoint each beat with the onboarding progress tool
29053
+ (auto.onboarding.progress.set_phase, with evidence references;
29054
+ auto.onboarding.progress.get to read the run):
29055
+ 1. commission \u2014 read the brief and the repo. Restate the commission in
29056
+ one paragraph and confirm you have it right.
29057
+ 2. stake_workshop \u2014 propose the minimal roster and triggers that deliver
29058
+ it: which catalog agents to hire, which bespoke agents to author, what
29059
+ each will be allowed to do. Open the workshop setup PR; the user's
29060
+ merge is the green light.
29061
+ 3. deliver \u2014 drive to THEIR magic moment, not a canned one: run the full
29062
+ loop \u2014 dispatch, narrate, review, land \u2014 on their use case. Merge is
29063
+ their button unless they hand you the word.
29064
+ 4. offer_paint \u2014 only if they would rather react than invent, surface a
29065
+ short repo-informed menu (open issues, untested corners, an
29066
+ underselling README) \u2014 options, not an agenda. "The user declines a
29067
+ deliverable" is a legitimate terminal state, not a failure.
29068
+ 5. reveal \u2014 nothing needs turning on: whatever they just built now reacts
29069
+ by itself; name the specific triggers that armed. Then run Self
29070
+ Improvement live over the sessions they just watched and relay its
29071
+ proposals in your voice. Hang the finished commission in the gallery.
29072
+ Every beat's action must be idempotent (look up existing PRs before
29073
+ creating, spawn with idempotency keys); resume from the recorded phase.
29074
+
29075
+ Running the workshop (after onboarding):
29076
+ - New commissions arrive by mention or thread; each gets a gallery entry
29077
+ (a durable ledger issue/thread line): the brief, the roster staffed,
29078
+ the artifacts landed, and its state. The gallery is your rebuildable
29079
+ state.
29080
+ - Keep the pigments stocked: watch for hires blocked on connections or
29081
+ secrets and walk the user through providing them (connection setup is
29082
+ always the user's action in their provider).
29083
+ - Staff-and-grow: when a commission needs a new hire, that is a setup PR
29084
+ with the same guardrails as onboarding. When a hire stops earning its
29085
+ seat, propose retiring it \u2014 deleting its file in a PR \u2014 rather than
29086
+ letting the workshop bloat. Keep your own manages: list current in the
29087
+ same setup PR that hires or retires an apprentice, so a successor
29088
+ Patron keeps session control over exactly the roster it actually runs.
29089
+
29090
+ Delegation:
29091
+ - Spawn apprentice sessions with auto.sessions.spawn: one scoped task per
29092
+ session, idempotencyKey derived from the commission + task slug,
29093
+ requester forwarded, observation mode auto with
29094
+ role: implementation-observer.
29095
+ - Apprentices report milestones by agent name; verify ready claims
29096
+ independently (aggregate CI, exact-head review verdict, branch current
29097
+ with main) before presenting work as finished.
29098
+ - You own the human surface. Apprentices join user threads only on your
29099
+ explicit, named invitation, and hand back after.
29100
+ - Escalate with a recommendation when the decision is the user's: scope,
29101
+ taste calls that change the commission, anything irreversible or
29102
+ external, merge.
29103
+
29104
+ Hard gates:
29105
+ - Merge is two-sided, and both sides are hard rules. Side one: never
29106
+ merge on your own initiative \u2014 nothing hangs in the gallery because
29107
+ the Patron decided it was finished. Side two: never refuse a merge the
29108
+ user asks for. "Merge it for me" IS the word \u2014 verify the readiness
29109
+ bar (aggregate CI green, clean exact-head review verdict, branch
29110
+ current with main), then execute, no ceremony, no re-asking. If the
29111
+ bar is not met yet, do not bounce the button back: say exactly what is
29112
+ outstanding, then merge the moment it goes green. Their ask is
29113
+ delegation to execute, not a waiver of the bar.
29114
+ - Every .auto/ change travels through a PR the user merges. No exceptions,
29115
+ including "trivial" fixes to agents you authored.
29116
+ - Never author an agent with authority you have not named to the user in
29117
+ plain words. Never grant an authored agent merge authority unasked.
29118
+
29119
+ Slot discipline:
29120
+ - concurrency: 1 \u2014 one house, one seal. Every mention, reply, apply
29121
+ event, and heartbeat lands in your one live session. Track each
29122
+ commission by its gallery entry; never mix them.
29123
+ - Do not sleep or poll. Handle the delivery, update the gallery, end the
29124
+ turn; triggers wake you.
29125
+ - Memory files do not survive replacement. Durable facts live in the
29126
+ gallery ledger, the repo, threads, and the onboarding run record.
29127
+ concurrency: 1
29128
+ replace: auto
29129
+ bindings:
29130
+ github.pull_request:
29131
+ lifecycle: held
29132
+ bind: onAttributedEvent
29133
+ continuity: agent
29134
+ context:
29135
+ role: commission-shepherd
29136
+ workflow: blank-canvas
29137
+ auto.session:
29138
+ continuity: agent
29139
+ manages:
29140
+ # Grows with each hire's setup PR: the Patron staffs from the whole cast
29141
+ # per commission, so the list is maintained alongside the roster it
29142
+ # actually hired rather than pre-granting stop authority over the entire
29143
+ # catalog.
29144
+ - patron
29145
+ onReplace: |
29146
+ You are a fresh Patron session replacing a predecessor (spec update or
29147
+ failure). The house passed hands during a gap; rebuild before acting:
29148
+ - Read the onboarding run record first (auto.onboarding.progress.get); if
29149
+ a commission flow is mid-flight, resume at the recorded phase.
29150
+ - Read the gallery ledger and the .auto/ directory in the mounted
29151
+ checkout \u2014 the workshop's actual roster is ground truth, not memory.
29152
+ - List apprentice sessions per hired agent name and reconcile against
29153
+ open PRs and gallery entries.
29154
+ - Bindings and thread subscriptions declare continuity: agent and roll to
29155
+ you; audit with auto.bindings.list, re-bind only as archaeology.
29156
+ - Back-read active threads for anything from the swap window.
29157
+ Then resume the workshop. If nothing needs attention, end the turn.
29158
+ initialPrompt: |
29159
+ You hold the seal for {{ $repoFullName }}. Check the onboarding run record
29160
+ and the gallery before acting: if the workshop was just applied and no
29161
+ commission flow has run, begin onboarding \u2014 find the commission (the run
29162
+ record, the intake conversation, or ask for it), restate it, and stake
29163
+ the workshop. Otherwise resume from the gallery and handle whatever
29164
+ delivery woke you.
29165
+ mounts:
29166
+ - kind: git
29167
+ repository: "{{ $repoFullName }}"
29168
+ mountPath: /workspace/repo
29169
+ ref: main
29170
+ depth: 1
29171
+ auth:
29172
+ kind: githubApp
29173
+ capabilities:
29174
+ # contents:write serves two purposes: .auto/ authorship on PR
29175
+ # branches (the blank-canvas superpower \u2014 PR-only by doctrine) and
29176
+ # the schema-required pairing with merge:write. merge:write is the
29177
+ # delegated, human-gated execution path.
29178
+ contents: write
29179
+ pullRequests: write
29180
+ issues: write
29181
+ checks: read
29182
+ actions: read
29183
+ merge: write
29184
+ workingDirectory: /workspace/repo
29185
+ tools:
29186
+ auto:
29187
+ kind: local
29188
+ implementation: auto
29189
+ chat:
29190
+ kind: local
29191
+ implementation: chat
29192
+ auth:
29193
+ kind: connection
29194
+ provider: slack
29195
+ connection: slack
29196
+ # Optional: the studio can live in web sessions alone; Slack joins
29197
+ # the workshop when the user connects it.
29198
+ optional: true
29199
+ github:
29200
+ kind: github
29201
+ tools:
29202
+ - pull_request_read
29203
+ - search_pull_requests
29204
+ - search_issues
29205
+ - search_code
29206
+ - get_file_contents
29207
+ - list_commits
29208
+ - issue_read
29209
+ - issue_write
29210
+ - add_issue_comment
29211
+ - create_branch
29212
+ - create_or_update_file
29213
+ - push_files
29214
+ - create_pull_request
29215
+ - update_pull_request
29216
+ - actions_get
29217
+ - actions_list
29218
+ - get_job_logs
29219
+ # Gated on merge:write above; delegated execution on the user's word.
29220
+ - merge_pull_request
29221
+ - enable_pull_request_auto_merge
29222
+ triggers:
29223
+ - name: mention
29224
+ event: chat.message.mentioned
29225
+ connection: slack
29226
+ optional: true
29227
+ where:
29228
+ $.chat.provider: slack
29229
+ $.auto.authored: false
29230
+ message: |
29231
+ {{message.author.userName}} mentioned you on Slack:
29232
+
29233
+ {{message.text}}
29234
+
29235
+ Channel: {{chat.channelId}}
29236
+ Thread: {{chat.threadId}}
29237
+
29238
+ If this is a new commission, open a gallery entry and run the
29239
+ commission flow in this thread. If it concerns a commission in
29240
+ flight, treat it as steering or a taste decision.
29241
+ routing:
29242
+ kind: deliver
29243
+ onUnmatched: spawn
29244
+ bind:
29245
+ target: slack.thread
29246
+ continuity: agent
29247
+ - name: subscribed-reply
29248
+ event: chat.message.subscribed
29249
+ connection: slack
29250
+ optional: true
29251
+ where:
29252
+ $.chat.provider: slack
29253
+ $.auto.authored: false
29254
+ message: |
29255
+ {{message.author.userName}} replied in a subscribed thread:
29256
+
29257
+ {{message.text}}
29258
+
29259
+ Channel: {{chat.channelId}}
29260
+ Thread: {{chat.threadId}}
29261
+
29262
+ Match the thread to its commission; treat the reply as steering, an
29263
+ answer, or a new commission.
29264
+ routing:
29265
+ kind: deliver
29266
+ onUnmatched: spawn
29267
+ - name: resource-apply-completed
29268
+ event: auto.project_resource_apply.completed
29269
+ where:
29270
+ $.apply.auditAction: github_sync.apply
29271
+ message: |
29272
+ GitHub Sync apply operation {{apply.operationId}} completed for PR
29273
+ artifact {{artifact.externalId}}.
29274
+
29275
+ Applied changes: create={{apply.plan.counts.create}},
29276
+ update={{apply.plan.counts.update}}, archive={{apply.plan.counts.archive}},
29277
+ pruned={{apply.plan.counts.pruned}},
29278
+ diagnostics={{apply.plan.counts.diagnostics}}.
29279
+
29280
+ Reconcile the originating setup PR and gallery entry. Confirm the
29281
+ workshop now matches the merged .auto/ source, resume any commission
29282
+ phase that was waiting on the hire, and tell the user what is armed.
29283
+ routing:
29284
+ kind: deliver
29285
+ onUnmatched: drop
29286
+ - name: resource-apply-failed
29287
+ event: auto.project_resource_apply.failed
29288
+ where:
29289
+ $.apply.auditAction: github_sync.apply
29290
+ message: |
29291
+ GitHub Sync apply operation {{apply.operationId}} failed for PR artifact
29292
+ {{artifact.externalId}}.
29293
+
29294
+ Error: {{apply.error.name}} \u2014 {{apply.error.message}}
29295
+ Requested resources={{apply.request.counts.resources}},
29296
+ deletes={{apply.request.counts.delete}}, assets={{apply.request.counts.assets}}.
29297
+
29298
+ Reconcile the originating setup PR and gallery entry, diagnose the
29299
+ failed resource change from the merged source, and report the concrete
29300
+ repair needed. Do not present the hire as active until a later apply
29301
+ completion proves it.
29302
+ routing:
29303
+ kind: deliver
29304
+ onUnmatched: drop
29305
+ - name: apprentice-pr-bound
29306
+ event: auto.session.binding.bound
29307
+ where:
29308
+ $.binding.target.type: github.pull_request
29309
+ $.binding.context.role: implementer
29310
+ message: |
29311
+ An apprentice session bound a commission PR.
29312
+
29313
+ Session: {{session.id}} ({{session.agent}})
29314
+ Revision: {{session.bindingRevision}}
29315
+ PR target: {{binding.target.externalId}}
29316
+
29317
+ Reconcile the gallery entry by revision; a claim, not readiness proof.
29318
+ routing:
29319
+ kind: bind
29320
+ target: auto.session
29321
+ onUnmatched: drop
29322
+ - name: apprentice-pr-ready
29323
+ event: auto.session.binding.updated
29324
+ where:
29325
+ $.binding.target.type: github.pull_request
29326
+ $.binding.context.role: implementer
29327
+ $.binding.context.phase: ready-for-final-review
29328
+ message: |
29329
+ An apprentice session claims its commission PR is ready for review.
29330
+
29331
+ Session: {{session.id}} ({{session.agent}})
29332
+ PR target: {{binding.target.externalId}}
29333
+ Claimed head: {{binding.context.headSha}}
29334
+
29335
+ Verify independently (aggregate CI, exact-head review verdict, branch
29336
+ currency) before presenting the piece. Then the two-sided merge gate
29337
+ applies: don't merge unprompted; if the user has asked you to land
29338
+ it, execute once the bar is green.
29339
+ routing:
29340
+ kind: bind
29341
+ target: auto.session
29342
+ onUnmatched: drop
29343
+ - name: apprentice-pr-unbound
29344
+ event: auto.session.binding.unbound
29345
+ where:
29346
+ $.binding.target.type: github.pull_request
29347
+ $.binding.context.role: implementer
29348
+ message: |
29349
+ An apprentice session unbound its commission PR (cause:
29350
+ {{transition.cause}}, released by: {{binding.releasedBy}}). Reconcile
29351
+ the gallery by revision and decide whether the commission needs
29352
+ intervention.
29353
+ routing:
29354
+ kind: bind
29355
+ target: auto.session
29356
+ onUnmatched: drop
29357
+ - name: commission-pr-closed
29358
+ event: github.pull_request.closed
29359
+ connection: "{{ $githubConnection }}"
29360
+ where:
29361
+ $.github.repository.fullName: "{{ $repoFullName }}"
29362
+ message: |
29363
+ Bound PR #{{github.pullRequest.number}} closed with
29364
+ merged={{github.pullRequest.merged}}.
29365
+
29366
+ If merged=true, record the landed artifact; for a workshop setup PR,
29367
+ wait for its apply completion or failure delivery before calling the
29368
+ hire active. If merged=false, record that the piece did not land and
29369
+ preserve the reason or next decision in the gallery.
29370
+
29371
+ Complete those closing duties before archiving this session. If this
29372
+ closes the magic-moment piece, advance the onboarding run record and
29373
+ hang it in the gallery. The platform releases this held PR binding only
29374
+ after delivering this close event.
29375
+ routing:
29376
+ kind: bind
29377
+ target: github.pull_request
29378
+ onUnmatched: drop
29379
+ release: true
29380
+ # Gentle heartbeat: keep sessions moving without becoming a standing cost
29381
+ # center. A deliberately archived front of house is not resurrected by
29382
+ # cron.
29383
+ - name: studio-heartbeat
29384
+ kind: heartbeat
29385
+ cron: "37 8,13,18 * * *"
29386
+ message: |
29387
+ Studio heartbeat ({{heartbeat.scheduledAt}}). Walk the workshop:
29388
+ reconcile gallery entries, nudge stalled apprentices, respawn dead
29389
+ ones, check for hires blocked on connections, and check whether a
29390
+ commission is ready to present. If nothing needs attention, end the
29391
+ turn without posting.
29392
+ routing:
29393
+ kind: deliver
29394
+ onUnmatched: drop
29395
+ `
29396
+ },
29397
+ {
29398
+ path: "fragments/environments/agent-runtime.yaml",
29399
+ content: "# Source: https://www.auto.sh/api/v1/templates/%40auto/blank-canvas/1.5.0/fragments/environments/agent-runtime.yaml\nharness: claude-code\nenvironment:\n name: agent-runtime\n image:\n kind: preset\n name: node24\n resources:\n memoryMB: 8192\n"
29400
+ }
29401
+ ]
28790
29402
  }
28791
29403
  ],
28792
29404
  "@auto/bouncer": [
@@ -52439,11 +53051,13 @@ var init_src = __esm({
52439
53051
  init_setup();
52440
53052
  init_pool_replace();
52441
53053
  init_requester();
53054
+ init_requester_spend();
52442
53055
  init_runtime_log();
52443
53056
  init_runtime_log_tailer();
52444
53057
  init_runtime_restart_diagnostics();
52445
53058
  init_runtimes();
52446
53059
  init_sessions();
53060
+ init_spend_caps();
52447
53061
  init_agents();
52448
53062
  init_templates();
52449
53063
  init_temporal();
@@ -55209,7 +55823,7 @@ var init_package = __esm({
55209
55823
  "package.json"() {
55210
55824
  package_default = {
55211
55825
  name: "@autohq/cli",
55212
- version: "0.1.463",
55826
+ version: "0.1.465",
55213
55827
  license: "SEE LICENSE IN README.md",
55214
55828
  publishConfig: {
55215
55829
  access: "public"
@@ -57307,6 +57921,7 @@ var init_agent_fields = __esm({
57307
57921
  mounts: mountsField(),
57308
57922
  triggers: triggersField(),
57309
57923
  session: specField(),
57924
+ spendCaps: specField(),
57310
57925
  concurrency: specField(),
57311
57926
  replace: specField(),
57312
57927
  onReplace: fileBackedStringField(),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@autohq/cli",
3
- "version": "0.1.463",
3
+ "version": "0.1.465",
4
4
  "license": "SEE LICENSE IN README.md",
5
5
  "publishConfig": {
6
6
  "access": "public"