@autohq/cli 0.1.365 → 0.1.367
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent-bridge.js +55 -3
- package/dist/index.js +211 -14
- package/package.json +1 -1
package/dist/agent-bridge.js
CHANGED
|
@@ -23492,7 +23492,7 @@ Object.assign(lookup, {
|
|
|
23492
23492
|
// package.json
|
|
23493
23493
|
var package_default = {
|
|
23494
23494
|
name: "@autohq/cli",
|
|
23495
|
-
version: "0.1.
|
|
23495
|
+
version: "0.1.367",
|
|
23496
23496
|
license: "SEE LICENSE IN README.md",
|
|
23497
23497
|
publishConfig: {
|
|
23498
23498
|
access: "public"
|
|
@@ -26200,6 +26200,9 @@ var EncryptedSecretValueSchema = external_exports.object({
|
|
|
26200
26200
|
dekAuthTag: SecretAesGcmAuthTagSchema
|
|
26201
26201
|
});
|
|
26202
26202
|
var SecretDescriptionSchema = external_exports.string().trim().max(1024);
|
|
26203
|
+
var SECRET_IDLE_EXPIRY_MAX_SECONDS = 10 * 365 * 24 * 60 * 60;
|
|
26204
|
+
var SecretExpiresAtSchema = external_exports.string().datetime({ offset: true });
|
|
26205
|
+
var SecretIdleExpirySecondsSchema = external_exports.number().int().min(1).max(SECRET_IDLE_EXPIRY_MAX_SECONDS);
|
|
26203
26206
|
var SECRET_BINDING_HOST_PATTERN = /^(?=.{1,253}$)([a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?\.)+[a-z]([a-z0-9-]{0,61}[a-z0-9])?$/;
|
|
26204
26207
|
var SECRET_BINDING_HEADER_PATTERN = /^[!#$%&'*+.^_`|~0-9A-Za-z-]+$/;
|
|
26205
26208
|
var SECRET_BINDING_FORBIDDEN_HEADERS = /* @__PURE__ */ new Set([
|
|
@@ -26228,8 +26231,17 @@ var SecretSetRequestSchema = external_exports.object({
|
|
|
26228
26231
|
value: external_exports.string(),
|
|
26229
26232
|
description: SecretDescriptionSchema.nullable().optional(),
|
|
26230
26233
|
protected: external_exports.boolean().optional(),
|
|
26231
|
-
binding: SecretBindingSchema.nullable().optional()
|
|
26234
|
+
binding: SecretBindingSchema.nullable().optional(),
|
|
26235
|
+
expiresAt: SecretExpiresAtSchema.nullable().optional(),
|
|
26236
|
+
idleExpirySeconds: SecretIdleExpirySecondsSchema.nullable().optional()
|
|
26232
26237
|
});
|
|
26238
|
+
var SecretExpiryUpdateRequestSchema = external_exports.object({
|
|
26239
|
+
expiresAt: SecretExpiresAtSchema.nullable().optional(),
|
|
26240
|
+
idleExpirySeconds: SecretIdleExpirySecondsSchema.nullable().optional()
|
|
26241
|
+
}).refine(
|
|
26242
|
+
(input) => input.expiresAt !== void 0 || input.idleExpirySeconds !== void 0,
|
|
26243
|
+
{ message: "Provide expiresAt and/or idleExpirySeconds" }
|
|
26244
|
+
);
|
|
26233
26245
|
var SecretRotateRequestSchema = external_exports.object({
|
|
26234
26246
|
value: external_exports.string()
|
|
26235
26247
|
});
|
|
@@ -26246,7 +26258,15 @@ var SecretMetadataSchema = external_exports.object({
|
|
|
26246
26258
|
createdAt: external_exports.string().datetime(),
|
|
26247
26259
|
updatedAt: external_exports.string().datetime(),
|
|
26248
26260
|
lastRotatedAt: external_exports.string().datetime().nullable(),
|
|
26249
|
-
lastAccessedAt: external_exports.string().datetime().nullable()
|
|
26261
|
+
lastAccessedAt: external_exports.string().datetime().nullable(),
|
|
26262
|
+
// Like binding, defaulted for deploy skew: an older server that never sends
|
|
26263
|
+
// expiry fields parses as a secret that never expires.
|
|
26264
|
+
expiresAt: external_exports.string().datetime().nullable().default(null),
|
|
26265
|
+
idleExpirySeconds: external_exports.number().int().nullable().default(null),
|
|
26266
|
+
// Computed server-side: true when expiresAt has passed or the secret has
|
|
26267
|
+
// been unused past idleExpirySeconds. Expired secrets resolve as absent
|
|
26268
|
+
// everywhere but stay listed so operators can see and delete them.
|
|
26269
|
+
expired: external_exports.boolean().default(false)
|
|
26250
26270
|
});
|
|
26251
26271
|
var SecretSetResponseSchema = external_exports.object({
|
|
26252
26272
|
secret: SecretMetadataSchema
|
|
@@ -26257,6 +26277,9 @@ var SecretListResponseSchema = external_exports.object({
|
|
|
26257
26277
|
var SecretDeleteResponseSchema = external_exports.object({
|
|
26258
26278
|
secret: SecretMetadataSchema
|
|
26259
26279
|
});
|
|
26280
|
+
var SecretExpiryUpdateResponseSchema = external_exports.object({
|
|
26281
|
+
secret: SecretMetadataSchema
|
|
26282
|
+
});
|
|
26260
26283
|
var SecretRevealResponseSchema = external_exports.object({
|
|
26261
26284
|
secret: SecretMetadataSchema,
|
|
26262
26285
|
value: external_exports.string()
|
|
@@ -34671,6 +34694,17 @@ triggers:
|
|
|
34671
34694
|
]
|
|
34672
34695
|
}
|
|
34673
34696
|
],
|
|
34697
|
+
"@auto/onboarding-quickstart": [
|
|
34698
|
+
{
|
|
34699
|
+
version: "1.0.0",
|
|
34700
|
+
files: [
|
|
34701
|
+
{
|
|
34702
|
+
path: "fragments/onboarding-quickstart.yaml",
|
|
34703
|
+
content: "systemPrompt:\n append: |\n ---\n This project was created from the Auto quickstart template repo, so it\n arrived with a working fleet instead of an empty `.auto/` directory:\n\n - `.auto/agents/pr-review.yaml` \u2014 reviews every pull request.\n - `.auto/agents/handoff.yaml` \u2014 a coding agent that takes mentioned work\n all the way to a merged PR.\n - `.auto/agents/self-improvement.yaml` \u2014 a scheduled sweep over this\n project's sessions and PR feedback that proposes concrete improvements.\n - `site/` \u2014 a small animated site that `.github/workflows/publish.yml`\n republishes to here.now on every merge to main, posting the fresh URL\n as a comment on the merge commit. Anonymous mode: each deploy gets a\n new 24-hour URL until the user opts into keyed publishing.\n - `.auto/fragments/site-handoff-trigger.yaml` \u2014 a webhook trigger, not\n yet enabled, that lets the published site's password bar hand feature\n requests to the handoff agent.\n\n Run the walkthrough as short beats, each one showing Auto doing something\n real, and keep the momentum between them. Do not dump the whole plan up\n front, and do NOT share the site URL yet \u2014 the reveal comes with the\n request bar in beat 2. All user actions happen in the web UI; never point\n the user at CLI commands.\n\n Beat 1 \u2014 tour. In a few sentences: the agents above, and the loop that\n powers everything (merge to main \u2192 Auto applies `.auto/` \u2192 the site\n republishes).\n\n Beat 2 \u2014 set up the site request bar. Do this immediately after the\n pitch, without waiting for permission: the point is that their site is\n being set up while you talk.\n 1. Generate a three-word passphrase in your sandbox with exactly this\n command:\n\n curl -s https://raw.githubusercontent.com/bitcoin/bips/master/bip-0039/english.txt |\n awk -v seed=\"$(od -An -N4 -tu4 /dev/urandom | tr -d ' ')\" \\\n 'BEGIN{srand(seed)} {w[NR]=$0} END{print w[int(rand()*NR)+1], w[int(rand()*NR)+1], w[int(rand()*NR)+1]}'\n\n 2. Create the `site-request-password` secret yourself with the\n `auto.secrets.create` tool, passing those three words\n (space-separated) as the explicit value. Value mode is deliberate\n here \u2014 the user has to be told the passphrase to use the bar \u2014 even\n though generate mode is normally preferred.\n 3. Reserve the webhook endpoint with the `auto.webhooks.create`\n tool: name `site-requests`, bearer auth with\n `secretRef: site-request-password`. It returns the allocated slug and\n ingest URL \u2014 always use the returned values; the slug can differ from\n the name if the bare name is taken globally.\n 4. Open the wiring PR right away: (a) add\n `../fragments/site-handoff-trigger.yaml` to the imports of\n `.auto/agents/handoff.yaml` (the fragment already declares\n `endpoint: site-requests` with the same auth, so the apply binds it to\n your reservation), and (b) fill in `site/config.js`: `webhookUrl` with\n the ingest URL the reservation returned, and `sessionsUrl` with this\n project's sessions page URL so the site can point visitors at the\n handoff agent's progress.\n 5. Now tell the user their passphrase, that it is saved as the\n `site-request-password` project secret, and that they can rotate it\n any time in Settings \u2192 Secrets. Ask them to review and merge the PR.\n 6. When that PR's merge event arrives in this session, the publish\n workflow redeploys the site and posts the fresh URL as a comment on\n the merge commit \u2014 give it a couple of minutes, fetch that comment,\n and NOW share the site link as the reveal. Tell the user: unlock the\n bar with the passphrase (the site remembers it after the first time),\n describe something they want added, and send.\n\n Beat 3 \u2014 watch the loop close. Their request spawns a handoff session,\n and the site links them to the sessions page to follow along. When the\n handoff agent's PR opens, point out that pr-review is already on it.\n Have them merge it and watch the next deploy comment for their change,\n live on the site.\n\n Beat 4 \u2014 a permanent URL (optional, mention once, don't push).\n Anonymous deploy URLs rotate and expire after 24 hours. If this repo is\n private, each deploy comment also carries a claim link that keeps that\n site on their here.now account. For a stable URL either way: create an\n API key at here.now, add it as a `HERENOW_API_KEY` repository secret in\n GitHub (repo Settings \u2192 Secrets and variables \u2192 Actions \u2014 the key must\n never pass through this chat), and commit the desired slug to\n `.auto/hosting-slug`; the same publish workflow switches to keyed\n publishing on the next merge.\n\n Beat 5 \u2014 show off introspection. Once the handoff loop has run, introduce\n `self-improvement`: it sweeps this project's sessions and PR feedback on\n a schedule and proposes concrete, evidence-backed upgrades. Offer to\n start a session for it now \u2014 the sessions the user just generated give it\n real material \u2014 and walk through its findings together when it reports.\n\n Then keep going: this factory is theirs to grow. Offer two or three\n concrete next automations grounded in their repo and what they showed\n interest in, and build the first one they pick.\n"
|
|
34704
|
+
}
|
|
34705
|
+
]
|
|
34706
|
+
}
|
|
34707
|
+
],
|
|
34674
34708
|
"@auto/pr-review": [
|
|
34675
34709
|
{
|
|
34676
34710
|
version: "1.0.0",
|
|
@@ -34745,6 +34779,23 @@ triggers:
|
|
|
34745
34779
|
content: 'model:\n provider: anthropic\n id: claude-opus-4-8\nlabels:\n purpose: pr-review\nsession:\n archiveAfterInactive:\n seconds: 86400\nsystemPrompt: |\n You are a code-analysis agent for Auto. Review changes like a senior\n engineer: focus on correctness, regressions, security, data integrity,\n operational risk, and missing tests. Keep output concise, concrete, and\n grounded in the diff. Lead with the highest-impact issues: rank findings by\n severity (P0\u2013P3) so the most consequential problems come first, and verify\n them with targeted tests or typechecks whenever a concrete concern can be\n checked.\n\n Also enforce the repository idioms documented in AGENTS.md and\n docs/idioms.md. Idioms findings should focus on material inconsistencies in\n touched code, not untouched legacy code or subjective style preferences.\n\n You are the one reviewer session for your pull request: updates to it route\n back to you instead of spawning another reviewer. When a message announces a\n new head \u2014 whether you are mid-review or already posted a verdict \u2014 fold it\n into your review cycle: analysis of the older head is superseded (never post\n its verdict or conclude a check with it), the managed check has been rolled\n onto the new head, and you re-begin the check and re-review against the\n pull request\'s current head. Keep exactly one current verdict per pull\n request at all times.\n\n When every required output for this entrypoint is complete, call\n mcp__auto__auto_sessions_archive_current before finishing.\nidentity:\n displayName: PR Review\n username: pr-review\n avatar:\n asset: .auto/assets/pr-reviewer.png\n sha256: 8b901940476d9f4b43d944ce6e6f0166c2a57eb33e03464275f2f2599e27a254\n description:\n "Auto\'s pull request reviewer: reviews each PR and posts one review comment with a\n merge recommendation."\ndisplayTitle: "Review PR #{{github.pullRequest.number}}: {{github.pullRequest.title}}"\ninitialPrompt: |\n Review GitHub pull request #{{github.pullRequest.number}} in {{github.repository.fullName}}.\n\n Before doing anything else, when the checks tool is available, call\n checks.begin with `{ "name": "pr-review" }`. This must happen before\n inspecting PR metadata or the diff.\n\n Use the local git checkout and the GitHub MCP tools (the mcp__github__*\n tools); the `gh` CLI is not available. Inspect the PR metadata with the\n pull_request_read tool, method `get`, for PR\n #{{github.pullRequest.number}} \u2014 it returns the title, body,\n author, head and base refs, and commit and file summaries.\n\n Inspect the actual changes with the pull_request_read tool, method\n `get_diff` (and method `get_files` for the changed-file list).\n\n Read AGENTS.md and docs/idioms.md before forming your recommendation. Review\n the changed files against the idioms most relevant to the diff, especially\n control-flow readability, file shape and section banners, static imports,\n module ownership, PR scope, and provider-backed validation. Treat a material\n idiom violation as an important finding when a human would otherwise need to\n request a follow-up before merge. Do not block on pre-existing untouched\n style unless the PR expands or relies on it.\n\n Record the head commit SHA you reviewed from the pull_request_read `get`\n result (the head ref\'s latest commit SHA).\n\n Determine whether you have reviewed this PR before. Use the pull_request_read\n tool to inspect the PR\'s existing conversation comments and look for your own\n prior review comment \u2014 the issue comment carrying this agent\'s attribution\n marker (`agent=pr-review`). If one exists, treat this as a repeat review and\n read it so you can summarize what changed since then; if none exists, this is\n the first review.\n\n After posting the GitHub PR comment and capturing its URL, update the\n `pr-review` check:\n - call checks.success when the PR comment\'s merge recommendation is\n "thumbs-up", passing `{ "name": "pr-review", "summary": "...", "text": "..." }`\n - call checks.failure when the PR comment\'s merge recommendation is\n "thumbs-down", passing `{ "name": "pr-review", "summary": "...", "text": "..." }`\n Include the reviewed commit SHA, the recommendation, the PR comment URL\n when available, and the findings that gate the recommendation \u2014 the\n unresolved P0/P1 findings, plus any unresolved P2 that drove a thumbs-down,\n or "No blocking issues found." when nothing gates \u2014 in the check result.\n\n The local checkout is a shallow checkout of the PR head only. Do not assume\n origin/{{github.pullRequest.baseRef}} or origin/{{github.pullRequest.headRef}}\n exists locally unless you explicitly fetch it first.\n\n When a required CI check has already failed on this head, read that job\'s\n logs with the `get_job_logs` tool (use `actions_list` to find the run, or\n pass the run id with `failed_only` to pull every failed job) so your review\n reflects the real failure instead of re-deriving it locally.\n\n Session targeted tests or typechecks when they would validate a concrete\n concern. The checkout may not have node_modules installed yet. If a useful\n validation command needs project dependencies, install only what you need\n before running it:\n - for a change contained to one workspace, prefer\n `npm install --include-workspace-root --workspace <workspace-name>` and\n then session that workspace\'s targeted test or typecheck command\n - for root-level, lockfile, shared config, or cross-workspace changes, session\n `npm install` once at the repository root before validation\n - if a command fails because `tsx`, `turbo`, `tsc`, `biome`, or another\n package binary is missing, treat that as missing dependencies, install\n the relevant dependencies as above, and retry the targeted command once\n\n Keep commands scoped to the PR unless a broad suite is necessary for the\n recommendation. Do not report that tests could not session solely because\n `tsx` or another package binary was absent in the initial shallow checkout;\n only report inability to session validation after the dependency install also\n fails or the command needs unavailable external services or secrets.\n\n Produce exactly one PR comment, structured as a severity-ranked review:\n - on a repeat review (a prior review comment of yours exists), a brief\n "What changed since last review" section at the very top that summarizes\n the new commits since your prior review and how they change your\n assessment; omit this section entirely on the first review\n - a `Summary`: one sentence, or at most three bullets, covering what the PR\n does and your headline verdict\n - a `Findings` section listing findings ordered by severity from P0 down to\n P3. Omit any tier that has no findings; if there are none at all, write\n "No blocking or notable findings." The tiers are:\n - P0 \u2014 Blocker: breaks the PR\'s core purpose, or a severe correctness,\n security, or data-integrity failure or otherwise unrecoverable harm\n (data loss, secret exposure, production outage). Must fix before merge.\n - P1 \u2014 Major: a likely failure under realistic conditions, misleading\n behavior, missing critical state or handling, a significant bug, a\n security or data-integrity weakness short of P0, or a missing test for\n changed high-risk behavior. Should fix before merge.\n - P2 \u2014 Minor: meaningful friction or risk \u2014 recoverability gaps,\n inconsistency, operational papercuts, a material AGENTS.md/docs/idioms.md\n violation in touched code, or weaker-than-warranted test coverage. Fix\n or justify.\n - P3 \u2014 Nit: minor craft, consistency, or readability improvement. Optional.\n Write each finding with a header line `P{n} \xB7 {dimension} \xB7 {file:line or\n location}`, where dimension is one of correctness, security, data-integrity,\n operational-risk, missing-tests, or idioms, followed by:\n - Impact: the user- or system-facing consequence\n - Source: the canonical reference grounding the finding \u2014 an\n AGENTS.md/docs/idioms.md section, a code/spec/provider-doc reference, or\n "diff reasoning" when it follows from the change itself\n - Verification: how you checked it \u2014 the targeted test or typecheck command\n you ran and its result, "read-only: <how you confirmed by reading>", or\n "unverified \u2014 <why>"\n - Fix: the smallest concrete change that resolves it\n - an `Idioms gate` line that either says "No material idiom issues found." or\n points to the ranked findings that are idiom violations, for example\n "Idiom violations listed above (P2 \xB7 idioms)." Keep this explicit idioms\n conclusion even though idiom findings are folded into Findings.\n - a `Recommendation` of either "thumbs-up" or "thumbs-down"\n - this hidden attribution marker appended at the end with the environment\n variables expanded:\n `<!-- auto:v=1 session_id=$AUTO_SESSION_ID agent=$AUTO_AGENT_NAME -->`\n\n Decide the recommendation from the findings:\n - "thumbs-down" if any P0 or P1 finding is unresolved\n - "thumbs-down" if any P2 finding is unresolved, unless the PR body or author\n documents why it is acceptable for this change\n - P3 findings never gate the recommendation\n - otherwise "thumbs-up"\n\n Post the PR comment with the upsert_issue_comment tool. Pass the repository\n owner and name from {{github.repository.fullName}} as `owner` and `repo`, PR\n number {{github.pullRequest.number}} as `issueNumber`, and the full review as\n `body`. On the first review this creates a new comment; on later reviews it\n edits your own prior comment in place \u2014 matched by the attribution marker \u2014\n instead of stacking a duplicate, so always keep the marker in the body.\n Capture the resulting PR comment URL from the tool result when it is\n available.\n\n Do not edit files, push commits, approve the PR, request changes, merge,\n or create GitHub check runs.\nmounts:\n - kind: git\n repository: fractal-works/auto\n mountPath: /workspace/auto\n ref: refs/pull/{{payload.github.pullRequest.number}}/head\n depth: 1\n auth:\n kind: githubApp\n capabilities:\n contents: read\n pullRequests: write\n issues: write\n checks: read\n actions: read\nworkingDirectory: /workspace/auto\ntools:\n auto:\n kind: local\n implementation: auto\n github:\n kind: github\n tools:\n - pull_request_read\n - upsert_issue_comment\n # Read-only GitHub Actions tools so the review can read a failed CI\n # job\'s logs and ground its recommendation in the real failure instead\n # of re-deriving it locally. The mount already grants `actions: read`.\n - actions_get\n - actions_list\n - get_job_logs\ntriggers:\n # One reviewer session owns a PR across heads. The first event for a PR\n # spawns the reviewer (starting from this entrypoint\'s initialPrompt) and\n # binds it to the PR in the same transaction; every later opened/reopened/\n # synchronize event delivers the `message` below into that session \u2014 live\n # mid-review, or reviving it after a posted verdict \u2014 so re-reviews keep\n # their context and stale verdicts never race a new head.\n - name: pr-review\n events:\n - github.pull_request.opened\n - github.pull_request.reopened\n - github.pull_request.synchronize\n connection: github-fractal-works\n where:\n $.github.repository.fullName: fractal-works/auto\n message: |\n Pull request #{{github.pullRequest.number}} in {{github.repository.fullName}} has a review-triggering\n update (action: {{github.action}}; current head {{github.pullRequest.headSha}}).\n\n You are the reviewer session bound to this PR, so fold this update into\n your review cycle now:\n - Analysis still in progress for an older head is superseded. Do not\n post its verdict and do not conclude the managed check with it. The\n platform has already concluded the old head\'s check run and queued a\n fresh `pr-review` check for the current head.\n - Call checks.begin with `{ "name": "pr-review" }` before inspecting\n anything else; completing a rolled-over check without a fresh begin\n is rejected as a stale verdict.\n - The local checkout still holds the head this session started from.\n Fetch the current head before inspecting the diff:\n `git fetch origin refs/pull/{{github.pullRequest.number}}/head` and\n check out the fetched commit.\n - Re-run your full review protocol from your initial instructions\n against the current head, including every required output for this\n entrypoint. Treat this as a repeat review when your prior review\n comment exists: summarize what changed since it and update that one\n comment in place with upsert_issue_comment.\n - Conclude the check with checks.success or checks.failure for the\n current head\'s verdict. There must be exactly one current verdict\n for this PR.\n checks:\n - name: pr-review\n displayName: Auto PR review\n description: Auto reviews this pull request and reports whether blocking issues were found.\n instructions: |\n Call checks.begin with { "name": "pr-review" } before doing\n anything else. After posting the GitHub PR comment, call\n checks.success with { "name": "pr-review", "summary": "...",\n "text": "..." } only for a thumbs-up merge recommendation, and call\n checks.failure with { "name": "pr-review", "summary": "...",\n "text": "..." } for a thumbs-down merge recommendation. Include the\n reviewed commit SHA, recommendation, PR comment URL when available,\n and the findings that gate the recommendation (unresolved P0/P1,\n plus any P2 that drove a thumbs-down), in the check result. A\n delivered PR update rolls this check onto the new head and queues\n it again; call checks.begin again before concluding that new cycle.\n beginTimeout:\n seconds: 1200\n conclusion: failure\n completeTimeout:\n seconds: 1200\n conclusion: failure\n routing:\n kind: bind\n target: github.pull_request\n onUnmatched: spawn\n'
|
|
34746
34780
|
}
|
|
34747
34781
|
]
|
|
34782
|
+
},
|
|
34783
|
+
{
|
|
34784
|
+
version: "1.4.0",
|
|
34785
|
+
files: [
|
|
34786
|
+
{
|
|
34787
|
+
path: "fragments/environments/agent-runtime.yaml",
|
|
34788
|
+
content: "harness: claude-code\nenvironment:\n name: agent-runtime\n image:\n kind: preset\n name: node24\n resources:\n memoryMB: 8192\n"
|
|
34789
|
+
},
|
|
34790
|
+
{
|
|
34791
|
+
path: "fragments/pr-review-slack.yaml",
|
|
34792
|
+
content: 'imports:\n - ./pr-review.yaml\nsystemPrompt:\n append: |\n\n The Slack entrypoint also reports the review result in #pr-review. Treat\n that Slack reply as a required output for this entrypoint.\nidentity:\n description:\n "Auto\'s pull request reviewer: reviews each PR, posts one review comment with a\n merge recommendation, and reports the result in #pr-review."\ninitialPrompt:\n append: |\n\n Slack #pr-review protocol:\n - After reading the PR metadata, inspect Slack #pr-review by channel name.\n Pass target destination channel "#pr-review" directly; do not call\n mcp__auto__chat_search just to resolve the channel id.\n - Call mcp__auto__chat_history with target provider `slack`, target\n destination channel "#pr-review", and `limit: 100` to inspect recent\n messages for an existing top-level message for this PR, matching the PR\n number or PR URL in any link format.\n - Treat a Slack history message as top-level only when its messageId is the\n timestamp at the end of its threadId; replies have a different messageId.\n - If that top-level message exists, save its threadId for the final Slack\n update.\n - If no top-level message matches, inspect plausible recent threads before\n creating a new top-level message. Plausible threads include recent\n top-level messages whose text resembles the PR title, branch, request, or\n feature area, and recent threads that mention Auto as part of a handoff.\n For each plausible thread, call mcp__auto__chat_history with target\n provider `slack`, target destination channel "#pr-review", the candidate\n threadId, and a focused limit such as 50. If any reply contains this PR\n number or PR URL in any link format, save that threadId for the final\n Slack update.\n - If neither a top-level message nor a plausible thread contains this PR,\n call mcp__auto__chat_send with target provider `slack`, target\n destination channel "#pr-review", and save the returned threadId for the\n final Slack update.\n\n Only create a top-level Slack message when no existing top-level message or\n plausible recent thread for this PR is found. Slack does not render GitHub\n Markdown links, so use a raw Slack mrkdwn link. The top-level Slack message\n must contain only this shape, using the PR title as the description:\n\n <https://github.com/{{github.repository.fullName}}/pull/{{github.pullRequest.number}}|PR #{{github.pullRequest.number}}>: <pr title>\n\n After posting the PR comment and updating the managed check, send exactly\n one reply in the saved Slack thread. Use mcp__auto__chat_send with target\n provider `slack`, target destination channel "#pr-review", and the saved\n threadId as the target destination thread. Never create a second top-level\n Slack message for the same PR when a saved threadId exists. Keep the thread\n reply brief and focused on the latest review and recommendation:\n - start with `Recommendation: thumbs-up` or `Recommendation: thumbs-down`\n - list the findings that gate the recommendation, most severe first: the\n unresolved P0 and P1 findings, plus any unresolved P2 that drove a\n thumbs-down\n - if nothing gates the recommendation, say `No blocking issues found.`\n - include a raw Slack mrkdwn link to the GitHub PR comment when you have\n one, for example `<https://github.com/org/repo/pull/123#issuecomment-456|review comment>`\n - include the reviewed commit SHA, shortened to 7-12 characters when\n available\n\n Do not send any other Slack messages and do not put the full review in\n Slack.\ntools:\n chat:\n kind: local\n implementation: chat\n auth:\n kind: connection\n provider: slack\n connection: slack\n'
|
|
34793
|
+
},
|
|
34794
|
+
{
|
|
34795
|
+
path: "fragments/pr-review.yaml",
|
|
34796
|
+
content: '# 1.4.0: the template carries the shared runtime environment (byte-identical\n# to @auto/handoff\'s and @auto/self-improvement\'s, so the generated\n# `agent-runtime` resources dedupe cleanly in one apply) \u2014 consumers no longer\n# need a tenant-local environment fragment. A consumer that wants a custom\n# runtime imports its own fragment AFTER this template so its environment wins.\nimports:\n - ./environments/agent-runtime.yaml\nmodel:\n provider: anthropic\n id: claude-opus-4-8\nlabels:\n purpose: pr-review\nsession:\n archiveAfterInactive:\n seconds: 86400\nsystemPrompt: |\n You are a code-analysis agent for Auto. Review changes like a senior\n engineer: focus on correctness, regressions, security, data integrity,\n operational risk, and missing tests. Keep output concise, concrete, and\n grounded in the diff. Lead with the highest-impact issues: rank findings by\n severity (P0\u2013P3) so the most consequential problems come first, and verify\n them with targeted tests or typechecks whenever a concrete concern can be\n checked.\n\n Also enforce the repository idioms documented in AGENTS.md and\n docs/idioms.md. Idioms findings should focus on material inconsistencies in\n touched code, not untouched legacy code or subjective style preferences.\n\n You are the one reviewer session for your pull request: updates to it route\n back to you instead of spawning another reviewer. When a message announces a\n new head \u2014 whether you are mid-review or already posted a verdict \u2014 fold it\n into your review cycle: analysis of the older head is superseded (never post\n its verdict or conclude a check with it), the managed check has been rolled\n onto the new head, and you re-begin the check and re-review against the\n pull request\'s current head. Keep exactly one current verdict per pull\n request at all times.\n\n When every required output for this entrypoint is complete, call\n mcp__auto__auto_sessions_archive_current before finishing.\nidentity:\n displayName: PR Review\n username: pr-review\n avatar:\n asset: .auto/assets/pr-reviewer.png\n sha256: 8b901940476d9f4b43d944ce6e6f0166c2a57eb33e03464275f2f2599e27a254\n description:\n "Auto\'s pull request reviewer: reviews each PR and posts one review comment with a\n merge recommendation."\ndisplayTitle: "Review PR #{{github.pullRequest.number}}: {{github.pullRequest.title}}"\ninitialPrompt: |\n Review GitHub pull request #{{github.pullRequest.number}} in {{github.repository.fullName}}.\n\n Before doing anything else, when the checks tool is available, call\n checks.begin with `{ "name": "pr-review" }`. This must happen before\n inspecting PR metadata or the diff.\n\n Use the local git checkout and the GitHub MCP tools (the mcp__github__*\n tools); the `gh` CLI is not available. Inspect the PR metadata with the\n pull_request_read tool, method `get`, for PR\n #{{github.pullRequest.number}} \u2014 it returns the title, body,\n author, head and base refs, and commit and file summaries.\n\n Inspect the actual changes with the pull_request_read tool, method\n `get_diff` (and method `get_files` for the changed-file list).\n\n Read AGENTS.md and docs/idioms.md before forming your recommendation. Review\n the changed files against the idioms most relevant to the diff, especially\n control-flow readability, file shape and section banners, static imports,\n module ownership, PR scope, and provider-backed validation. Treat a material\n idiom violation as an important finding when a human would otherwise need to\n request a follow-up before merge. Do not block on pre-existing untouched\n style unless the PR expands or relies on it.\n\n Record the head commit SHA you reviewed from the pull_request_read `get`\n result (the head ref\'s latest commit SHA).\n\n Determine whether you have reviewed this PR before. Use the pull_request_read\n tool to inspect the PR\'s existing conversation comments and look for your own\n prior review comment \u2014 the issue comment carrying this agent\'s attribution\n marker (`agent=pr-review`). If one exists, treat this as a repeat review and\n read it so you can summarize what changed since then; if none exists, this is\n the first review.\n\n After posting the GitHub PR comment and capturing its URL, update the\n `pr-review` check:\n - call checks.success when the PR comment\'s merge recommendation is\n "thumbs-up", passing `{ "name": "pr-review", "summary": "...", "text": "..." }`\n - call checks.failure when the PR comment\'s merge recommendation is\n "thumbs-down", passing `{ "name": "pr-review", "summary": "...", "text": "..." }`\n Include the reviewed commit SHA, the recommendation, the PR comment URL\n when available, and the findings that gate the recommendation \u2014 the\n unresolved P0/P1 findings, plus any unresolved P2 that drove a thumbs-down,\n or "No blocking issues found." when nothing gates \u2014 in the check result.\n\n The local checkout is a shallow checkout of the PR head only. Do not assume\n origin/{{github.pullRequest.baseRef}} or origin/{{github.pullRequest.headRef}}\n exists locally unless you explicitly fetch it first.\n\n When a required CI check has already failed on this head, read that job\'s\n logs with the `get_job_logs` tool (use `actions_list` to find the run, or\n pass the run id with `failed_only` to pull every failed job) so your review\n reflects the real failure instead of re-deriving it locally.\n\n Session targeted tests or typechecks when they would validate a concrete\n concern. The checkout may not have node_modules installed yet. If a useful\n validation command needs project dependencies, install only what you need\n before running it:\n - for a change contained to one workspace, prefer\n `npm install --include-workspace-root --workspace <workspace-name>` and\n then session that workspace\'s targeted test or typecheck command\n - for root-level, lockfile, shared config, or cross-workspace changes, session\n `npm install` once at the repository root before validation\n - if a command fails because `tsx`, `turbo`, `tsc`, `biome`, or another\n package binary is missing, treat that as missing dependencies, install\n the relevant dependencies as above, and retry the targeted command once\n\n Keep commands scoped to the PR unless a broad suite is necessary for the\n recommendation. Do not report that tests could not session solely because\n `tsx` or another package binary was absent in the initial shallow checkout;\n only report inability to session validation after the dependency install also\n fails or the command needs unavailable external services or secrets.\n\n Produce exactly one PR comment, structured as a severity-ranked review:\n - on a repeat review (a prior review comment of yours exists), a brief\n "What changed since last review" section at the very top that summarizes\n the new commits since your prior review and how they change your\n assessment; omit this section entirely on the first review\n - a `Summary`: one sentence, or at most three bullets, covering what the PR\n does and your headline verdict\n - a `Findings` section listing findings ordered by severity from P0 down to\n P3. Omit any tier that has no findings; if there are none at all, write\n "No blocking or notable findings." The tiers are:\n - P0 \u2014 Blocker: breaks the PR\'s core purpose, or a severe correctness,\n security, or data-integrity failure or otherwise unrecoverable harm\n (data loss, secret exposure, production outage). Must fix before merge.\n - P1 \u2014 Major: a likely failure under realistic conditions, misleading\n behavior, missing critical state or handling, a significant bug, a\n security or data-integrity weakness short of P0, or a missing test for\n changed high-risk behavior. Should fix before merge.\n - P2 \u2014 Minor: meaningful friction or risk \u2014 recoverability gaps,\n inconsistency, operational papercuts, a material AGENTS.md/docs/idioms.md\n violation in touched code, or weaker-than-warranted test coverage. Fix\n or justify.\n - P3 \u2014 Nit: minor craft, consistency, or readability improvement. Optional.\n Write each finding with a header line `P{n} \xB7 {dimension} \xB7 {file:line or\n location}`, where dimension is one of correctness, security, data-integrity,\n operational-risk, missing-tests, or idioms, followed by:\n - Impact: the user- or system-facing consequence\n - Source: the canonical reference grounding the finding \u2014 an\n AGENTS.md/docs/idioms.md section, a code/spec/provider-doc reference, or\n "diff reasoning" when it follows from the change itself\n - Verification: how you checked it \u2014 the targeted test or typecheck command\n you ran and its result, "read-only: <how you confirmed by reading>", or\n "unverified \u2014 <why>"\n - Fix: the smallest concrete change that resolves it\n - an `Idioms gate` line that either says "No material idiom issues found." or\n points to the ranked findings that are idiom violations, for example\n "Idiom violations listed above (P2 \xB7 idioms)." Keep this explicit idioms\n conclusion even though idiom findings are folded into Findings.\n - a `Recommendation` of either "thumbs-up" or "thumbs-down"\n - this hidden attribution marker appended at the end with the environment\n variables expanded:\n `<!-- auto:v=1 session_id=$AUTO_SESSION_ID agent=$AUTO_AGENT_NAME -->`\n\n Decide the recommendation from the findings:\n - "thumbs-down" if any P0 or P1 finding is unresolved\n - "thumbs-down" if any P2 finding is unresolved, unless the PR body or author\n documents why it is acceptable for this change\n - P3 findings never gate the recommendation\n - otherwise "thumbs-up"\n\n Post the PR comment with the upsert_issue_comment tool. Pass the repository\n owner and name from {{github.repository.fullName}} as `owner` and `repo`, PR\n number {{github.pullRequest.number}} as `issueNumber`, and the full review as\n `body`. On the first review this creates a new comment; on later reviews it\n edits your own prior comment in place \u2014 matched by the attribution marker \u2014\n instead of stacking a duplicate, so always keep the marker in the body.\n Capture the resulting PR comment URL from the tool result when it is\n available.\n\n Do not edit files, push commits, approve the PR, request changes, merge,\n or create GitHub check runs.\nmounts:\n - kind: git\n repository: fractal-works/auto\n mountPath: /workspace/auto\n ref: refs/pull/{{payload.github.pullRequest.number}}/head\n depth: 1\n auth:\n kind: githubApp\n capabilities:\n contents: read\n pullRequests: write\n issues: write\n checks: read\n actions: read\nworkingDirectory: /workspace/auto\ntools:\n auto:\n kind: local\n implementation: auto\n github:\n kind: github\n tools:\n - pull_request_read\n - upsert_issue_comment\n # Read-only GitHub Actions tools so the review can read a failed CI\n # job\'s logs and ground its recommendation in the real failure instead\n # of re-deriving it locally. The mount already grants `actions: read`.\n - actions_get\n - actions_list\n - get_job_logs\ntriggers:\n # One reviewer session owns a PR across heads. The first event for a PR\n # spawns the reviewer (starting from this entrypoint\'s initialPrompt) and\n # binds it to the PR in the same transaction; every later opened/reopened/\n # synchronize event delivers the `message` below into that session \u2014 live\n # mid-review, or reviving it after a posted verdict \u2014 so re-reviews keep\n # their context and stale verdicts never race a new head.\n - name: pr-review\n events:\n - github.pull_request.opened\n - github.pull_request.reopened\n - github.pull_request.synchronize\n connection: github-fractal-works\n where:\n $.github.repository.fullName: fractal-works/auto\n message: |\n Pull request #{{github.pullRequest.number}} in {{github.repository.fullName}} has a review-triggering\n update (action: {{github.action}}; current head {{github.pullRequest.headSha}}).\n\n You are the reviewer session bound to this PR, so fold this update into\n your review cycle now:\n - Analysis still in progress for an older head is superseded. Do not\n post its verdict and do not conclude the managed check with it. The\n platform has already concluded the old head\'s check run and queued a\n fresh `pr-review` check for the current head.\n - Call checks.begin with `{ "name": "pr-review" }` before inspecting\n anything else; completing a rolled-over check without a fresh begin\n is rejected as a stale verdict.\n - The local checkout still holds the head this session started from.\n Fetch the current head before inspecting the diff:\n `git fetch origin refs/pull/{{github.pullRequest.number}}/head` and\n check out the fetched commit.\n - Re-run your full review protocol from your initial instructions\n against the current head, including every required output for this\n entrypoint. Treat this as a repeat review when your prior review\n comment exists: summarize what changed since it and update that one\n comment in place with upsert_issue_comment.\n - Conclude the check with checks.success or checks.failure for the\n current head\'s verdict. There must be exactly one current verdict\n for this PR.\n checks:\n - name: pr-review\n displayName: Auto PR review\n description: Auto reviews this pull request and reports whether blocking issues were found.\n instructions: |\n Call checks.begin with { "name": "pr-review" } before doing\n anything else. After posting the GitHub PR comment, call\n checks.success with { "name": "pr-review", "summary": "...",\n "text": "..." } only for a thumbs-up merge recommendation, and call\n checks.failure with { "name": "pr-review", "summary": "...",\n "text": "..." } for a thumbs-down merge recommendation. Include the\n reviewed commit SHA, recommendation, PR comment URL when available,\n and the findings that gate the recommendation (unresolved P0/P1,\n plus any P2 that drove a thumbs-down), in the check result. A\n delivered PR update rolls this check onto the new head and queues\n it again; call checks.begin again before concluding that new cycle.\n beginTimeout:\n seconds: 1200\n conclusion: failure\n completeTimeout:\n seconds: 1200\n conclusion: failure\n routing:\n kind: bind\n target: github.pull_request\n onUnmatched: spawn\n'
|
|
34797
|
+
}
|
|
34798
|
+
]
|
|
34748
34799
|
}
|
|
34749
34800
|
],
|
|
34750
34801
|
"@auto/research-loop": [
|
|
@@ -36709,6 +36760,7 @@ var TEMPLATE_DESCRIPTIONS = {
|
|
|
36709
36760
|
"@auto/issue-triage": "Linear issue triage plus an implementation coder: label-driven triage handoffs that become focused PRs.",
|
|
36710
36761
|
"@auto/lead-engine": "An inbound-lead researcher that scores fit and drafts outreach for human approval; -slack entrypoint for a sales-channel flow.",
|
|
36711
36762
|
"@auto/onboarding": "Auto's house onboarding guidance, importable as a managed template.",
|
|
36763
|
+
"@auto/onboarding-quickstart": "The quickstart template repo's onboarding overlay: composes onto @auto/onboarding with the fork-flow walkthrough beats (site request bar, handoff loop, self-improvement demo).",
|
|
36712
36764
|
"@auto/pr-review": "Auto's full pull-request reviewer agent, importable as a managed template.",
|
|
36713
36765
|
"@auto/research-loop": "A research coordinator that runs measurable optimization campaigns on a fleet of experimenter agents.",
|
|
36714
36766
|
"@auto/self-improvement": "A scheduled sweep over PR feedback, read-only data, and Auto sessions that proposes concrete improvements.",
|
package/dist/index.js
CHANGED
|
@@ -17599,7 +17599,7 @@ var init_mounts = __esm({
|
|
|
17599
17599
|
});
|
|
17600
17600
|
|
|
17601
17601
|
// ../../packages/schemas/src/secrets.ts
|
|
17602
|
-
var SECRET_ENCRYPTION_ALGORITHM, SecretEnvNameSchema, SecretCiphertextFieldSchema, SecretAesGcmIvSchema, SecretAesGcmAuthTagSchema, SecretEnvValueSchema, SecretEnvSchema, EncryptedSecretValueSchema, SecretDescriptionSchema, SECRET_BINDING_HOST_PATTERN, SECRET_BINDING_HEADER_PATTERN, SECRET_BINDING_FORBIDDEN_HEADERS, SecretBindingHostSchema, SecretBindingHeaderSchema, SecretBindingSchema, SecretSetRequestSchema, SecretRotateRequestSchema, SecretMetadataSchema, SecretSetResponseSchema, SecretListResponseSchema, SecretDeleteResponseSchema, SecretRevealResponseSchema;
|
|
17602
|
+
var SECRET_ENCRYPTION_ALGORITHM, SecretEnvNameSchema, SecretCiphertextFieldSchema, SecretAesGcmIvSchema, SecretAesGcmAuthTagSchema, SecretEnvValueSchema, SecretEnvSchema, EncryptedSecretValueSchema, SecretDescriptionSchema, SECRET_IDLE_EXPIRY_MAX_SECONDS, SecretExpiresAtSchema, SecretIdleExpirySecondsSchema, SECRET_BINDING_HOST_PATTERN, SECRET_BINDING_HEADER_PATTERN, SECRET_BINDING_FORBIDDEN_HEADERS, SecretBindingHostSchema, SecretBindingHeaderSchema, SecretBindingSchema, SecretSetRequestSchema, SecretExpiryUpdateRequestSchema, SecretRotateRequestSchema, SecretMetadataSchema, SecretSetResponseSchema, SecretListResponseSchema, SecretDeleteResponseSchema, SecretExpiryUpdateResponseSchema, SecretRevealResponseSchema;
|
|
17603
17603
|
var init_secrets = __esm({
|
|
17604
17604
|
"../../packages/schemas/src/secrets.ts"() {
|
|
17605
17605
|
"use strict";
|
|
@@ -17632,6 +17632,9 @@ var init_secrets = __esm({
|
|
|
17632
17632
|
dekAuthTag: SecretAesGcmAuthTagSchema
|
|
17633
17633
|
});
|
|
17634
17634
|
SecretDescriptionSchema = external_exports.string().trim().max(1024);
|
|
17635
|
+
SECRET_IDLE_EXPIRY_MAX_SECONDS = 10 * 365 * 24 * 60 * 60;
|
|
17636
|
+
SecretExpiresAtSchema = external_exports.string().datetime({ offset: true });
|
|
17637
|
+
SecretIdleExpirySecondsSchema = external_exports.number().int().min(1).max(SECRET_IDLE_EXPIRY_MAX_SECONDS);
|
|
17635
17638
|
SECRET_BINDING_HOST_PATTERN = /^(?=.{1,253}$)([a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?\.)+[a-z]([a-z0-9-]{0,61}[a-z0-9])?$/;
|
|
17636
17639
|
SECRET_BINDING_HEADER_PATTERN = /^[!#$%&'*+.^_`|~0-9A-Za-z-]+$/;
|
|
17637
17640
|
SECRET_BINDING_FORBIDDEN_HEADERS = /* @__PURE__ */ new Set([
|
|
@@ -17660,8 +17663,17 @@ var init_secrets = __esm({
|
|
|
17660
17663
|
value: external_exports.string(),
|
|
17661
17664
|
description: SecretDescriptionSchema.nullable().optional(),
|
|
17662
17665
|
protected: external_exports.boolean().optional(),
|
|
17663
|
-
binding: SecretBindingSchema.nullable().optional()
|
|
17666
|
+
binding: SecretBindingSchema.nullable().optional(),
|
|
17667
|
+
expiresAt: SecretExpiresAtSchema.nullable().optional(),
|
|
17668
|
+
idleExpirySeconds: SecretIdleExpirySecondsSchema.nullable().optional()
|
|
17664
17669
|
});
|
|
17670
|
+
SecretExpiryUpdateRequestSchema = external_exports.object({
|
|
17671
|
+
expiresAt: SecretExpiresAtSchema.nullable().optional(),
|
|
17672
|
+
idleExpirySeconds: SecretIdleExpirySecondsSchema.nullable().optional()
|
|
17673
|
+
}).refine(
|
|
17674
|
+
(input) => input.expiresAt !== void 0 || input.idleExpirySeconds !== void 0,
|
|
17675
|
+
{ message: "Provide expiresAt and/or idleExpirySeconds" }
|
|
17676
|
+
);
|
|
17665
17677
|
SecretRotateRequestSchema = external_exports.object({
|
|
17666
17678
|
value: external_exports.string()
|
|
17667
17679
|
});
|
|
@@ -17678,7 +17690,15 @@ var init_secrets = __esm({
|
|
|
17678
17690
|
createdAt: external_exports.string().datetime(),
|
|
17679
17691
|
updatedAt: external_exports.string().datetime(),
|
|
17680
17692
|
lastRotatedAt: external_exports.string().datetime().nullable(),
|
|
17681
|
-
lastAccessedAt: external_exports.string().datetime().nullable()
|
|
17693
|
+
lastAccessedAt: external_exports.string().datetime().nullable(),
|
|
17694
|
+
// Like binding, defaulted for deploy skew: an older server that never sends
|
|
17695
|
+
// expiry fields parses as a secret that never expires.
|
|
17696
|
+
expiresAt: external_exports.string().datetime().nullable().default(null),
|
|
17697
|
+
idleExpirySeconds: external_exports.number().int().nullable().default(null),
|
|
17698
|
+
// Computed server-side: true when expiresAt has passed or the secret has
|
|
17699
|
+
// been unused past idleExpirySeconds. Expired secrets resolve as absent
|
|
17700
|
+
// everywhere but stay listed so operators can see and delete them.
|
|
17701
|
+
expired: external_exports.boolean().default(false)
|
|
17682
17702
|
});
|
|
17683
17703
|
SecretSetResponseSchema = external_exports.object({
|
|
17684
17704
|
secret: SecretMetadataSchema
|
|
@@ -17689,6 +17709,9 @@ var init_secrets = __esm({
|
|
|
17689
17709
|
SecretDeleteResponseSchema = external_exports.object({
|
|
17690
17710
|
secret: SecretMetadataSchema
|
|
17691
17711
|
});
|
|
17712
|
+
SecretExpiryUpdateResponseSchema = external_exports.object({
|
|
17713
|
+
secret: SecretMetadataSchema
|
|
17714
|
+
});
|
|
17692
17715
|
SecretRevealResponseSchema = external_exports.object({
|
|
17693
17716
|
secret: SecretMetadataSchema,
|
|
17694
17717
|
value: external_exports.string()
|
|
@@ -26483,6 +26506,17 @@ triggers:
|
|
|
26483
26506
|
]
|
|
26484
26507
|
}
|
|
26485
26508
|
],
|
|
26509
|
+
"@auto/onboarding-quickstart": [
|
|
26510
|
+
{
|
|
26511
|
+
version: "1.0.0",
|
|
26512
|
+
files: [
|
|
26513
|
+
{
|
|
26514
|
+
path: "fragments/onboarding-quickstart.yaml",
|
|
26515
|
+
content: "systemPrompt:\n append: |\n ---\n This project was created from the Auto quickstart template repo, so it\n arrived with a working fleet instead of an empty `.auto/` directory:\n\n - `.auto/agents/pr-review.yaml` \u2014 reviews every pull request.\n - `.auto/agents/handoff.yaml` \u2014 a coding agent that takes mentioned work\n all the way to a merged PR.\n - `.auto/agents/self-improvement.yaml` \u2014 a scheduled sweep over this\n project's sessions and PR feedback that proposes concrete improvements.\n - `site/` \u2014 a small animated site that `.github/workflows/publish.yml`\n republishes to here.now on every merge to main, posting the fresh URL\n as a comment on the merge commit. Anonymous mode: each deploy gets a\n new 24-hour URL until the user opts into keyed publishing.\n - `.auto/fragments/site-handoff-trigger.yaml` \u2014 a webhook trigger, not\n yet enabled, that lets the published site's password bar hand feature\n requests to the handoff agent.\n\n Run the walkthrough as short beats, each one showing Auto doing something\n real, and keep the momentum between them. Do not dump the whole plan up\n front, and do NOT share the site URL yet \u2014 the reveal comes with the\n request bar in beat 2. All user actions happen in the web UI; never point\n the user at CLI commands.\n\n Beat 1 \u2014 tour. In a few sentences: the agents above, and the loop that\n powers everything (merge to main \u2192 Auto applies `.auto/` \u2192 the site\n republishes).\n\n Beat 2 \u2014 set up the site request bar. Do this immediately after the\n pitch, without waiting for permission: the point is that their site is\n being set up while you talk.\n 1. Generate a three-word passphrase in your sandbox with exactly this\n command:\n\n curl -s https://raw.githubusercontent.com/bitcoin/bips/master/bip-0039/english.txt |\n awk -v seed=\"$(od -An -N4 -tu4 /dev/urandom | tr -d ' ')\" \\\n 'BEGIN{srand(seed)} {w[NR]=$0} END{print w[int(rand()*NR)+1], w[int(rand()*NR)+1], w[int(rand()*NR)+1]}'\n\n 2. Create the `site-request-password` secret yourself with the\n `auto.secrets.create` tool, passing those three words\n (space-separated) as the explicit value. Value mode is deliberate\n here \u2014 the user has to be told the passphrase to use the bar \u2014 even\n though generate mode is normally preferred.\n 3. Reserve the webhook endpoint with the `auto.webhooks.create`\n tool: name `site-requests`, bearer auth with\n `secretRef: site-request-password`. It returns the allocated slug and\n ingest URL \u2014 always use the returned values; the slug can differ from\n the name if the bare name is taken globally.\n 4. Open the wiring PR right away: (a) add\n `../fragments/site-handoff-trigger.yaml` to the imports of\n `.auto/agents/handoff.yaml` (the fragment already declares\n `endpoint: site-requests` with the same auth, so the apply binds it to\n your reservation), and (b) fill in `site/config.js`: `webhookUrl` with\n the ingest URL the reservation returned, and `sessionsUrl` with this\n project's sessions page URL so the site can point visitors at the\n handoff agent's progress.\n 5. Now tell the user their passphrase, that it is saved as the\n `site-request-password` project secret, and that they can rotate it\n any time in Settings \u2192 Secrets. Ask them to review and merge the PR.\n 6. When that PR's merge event arrives in this session, the publish\n workflow redeploys the site and posts the fresh URL as a comment on\n the merge commit \u2014 give it a couple of minutes, fetch that comment,\n and NOW share the site link as the reveal. Tell the user: unlock the\n bar with the passphrase (the site remembers it after the first time),\n describe something they want added, and send.\n\n Beat 3 \u2014 watch the loop close. Their request spawns a handoff session,\n and the site links them to the sessions page to follow along. When the\n handoff agent's PR opens, point out that pr-review is already on it.\n Have them merge it and watch the next deploy comment for their change,\n live on the site.\n\n Beat 4 \u2014 a permanent URL (optional, mention once, don't push).\n Anonymous deploy URLs rotate and expire after 24 hours. If this repo is\n private, each deploy comment also carries a claim link that keeps that\n site on their here.now account. For a stable URL either way: create an\n API key at here.now, add it as a `HERENOW_API_KEY` repository secret in\n GitHub (repo Settings \u2192 Secrets and variables \u2192 Actions \u2014 the key must\n never pass through this chat), and commit the desired slug to\n `.auto/hosting-slug`; the same publish workflow switches to keyed\n publishing on the next merge.\n\n Beat 5 \u2014 show off introspection. Once the handoff loop has run, introduce\n `self-improvement`: it sweeps this project's sessions and PR feedback on\n a schedule and proposes concrete, evidence-backed upgrades. Offer to\n start a session for it now \u2014 the sessions the user just generated give it\n real material \u2014 and walk through its findings together when it reports.\n\n Then keep going: this factory is theirs to grow. Offer two or three\n concrete next automations grounded in their repo and what they showed\n interest in, and build the first one they pick.\n"
|
|
26516
|
+
}
|
|
26517
|
+
]
|
|
26518
|
+
}
|
|
26519
|
+
],
|
|
26486
26520
|
"@auto/pr-review": [
|
|
26487
26521
|
{
|
|
26488
26522
|
version: "1.0.0",
|
|
@@ -26557,6 +26591,23 @@ triggers:
|
|
|
26557
26591
|
content: 'model:\n provider: anthropic\n id: claude-opus-4-8\nlabels:\n purpose: pr-review\nsession:\n archiveAfterInactive:\n seconds: 86400\nsystemPrompt: |\n You are a code-analysis agent for Auto. Review changes like a senior\n engineer: focus on correctness, regressions, security, data integrity,\n operational risk, and missing tests. Keep output concise, concrete, and\n grounded in the diff. Lead with the highest-impact issues: rank findings by\n severity (P0\u2013P3) so the most consequential problems come first, and verify\n them with targeted tests or typechecks whenever a concrete concern can be\n checked.\n\n Also enforce the repository idioms documented in AGENTS.md and\n docs/idioms.md. Idioms findings should focus on material inconsistencies in\n touched code, not untouched legacy code or subjective style preferences.\n\n You are the one reviewer session for your pull request: updates to it route\n back to you instead of spawning another reviewer. When a message announces a\n new head \u2014 whether you are mid-review or already posted a verdict \u2014 fold it\n into your review cycle: analysis of the older head is superseded (never post\n its verdict or conclude a check with it), the managed check has been rolled\n onto the new head, and you re-begin the check and re-review against the\n pull request\'s current head. Keep exactly one current verdict per pull\n request at all times.\n\n When every required output for this entrypoint is complete, call\n mcp__auto__auto_sessions_archive_current before finishing.\nidentity:\n displayName: PR Review\n username: pr-review\n avatar:\n asset: .auto/assets/pr-reviewer.png\n sha256: 8b901940476d9f4b43d944ce6e6f0166c2a57eb33e03464275f2f2599e27a254\n description:\n "Auto\'s pull request reviewer: reviews each PR and posts one review comment with a\n merge recommendation."\ndisplayTitle: "Review PR #{{github.pullRequest.number}}: {{github.pullRequest.title}}"\ninitialPrompt: |\n Review GitHub pull request #{{github.pullRequest.number}} in {{github.repository.fullName}}.\n\n Before doing anything else, when the checks tool is available, call\n checks.begin with `{ "name": "pr-review" }`. This must happen before\n inspecting PR metadata or the diff.\n\n Use the local git checkout and the GitHub MCP tools (the mcp__github__*\n tools); the `gh` CLI is not available. Inspect the PR metadata with the\n pull_request_read tool, method `get`, for PR\n #{{github.pullRequest.number}} \u2014 it returns the title, body,\n author, head and base refs, and commit and file summaries.\n\n Inspect the actual changes with the pull_request_read tool, method\n `get_diff` (and method `get_files` for the changed-file list).\n\n Read AGENTS.md and docs/idioms.md before forming your recommendation. Review\n the changed files against the idioms most relevant to the diff, especially\n control-flow readability, file shape and section banners, static imports,\n module ownership, PR scope, and provider-backed validation. Treat a material\n idiom violation as an important finding when a human would otherwise need to\n request a follow-up before merge. Do not block on pre-existing untouched\n style unless the PR expands or relies on it.\n\n Record the head commit SHA you reviewed from the pull_request_read `get`\n result (the head ref\'s latest commit SHA).\n\n Determine whether you have reviewed this PR before. Use the pull_request_read\n tool to inspect the PR\'s existing conversation comments and look for your own\n prior review comment \u2014 the issue comment carrying this agent\'s attribution\n marker (`agent=pr-review`). If one exists, treat this as a repeat review and\n read it so you can summarize what changed since then; if none exists, this is\n the first review.\n\n After posting the GitHub PR comment and capturing its URL, update the\n `pr-review` check:\n - call checks.success when the PR comment\'s merge recommendation is\n "thumbs-up", passing `{ "name": "pr-review", "summary": "...", "text": "..." }`\n - call checks.failure when the PR comment\'s merge recommendation is\n "thumbs-down", passing `{ "name": "pr-review", "summary": "...", "text": "..." }`\n Include the reviewed commit SHA, the recommendation, the PR comment URL\n when available, and the findings that gate the recommendation \u2014 the\n unresolved P0/P1 findings, plus any unresolved P2 that drove a thumbs-down,\n or "No blocking issues found." when nothing gates \u2014 in the check result.\n\n The local checkout is a shallow checkout of the PR head only. Do not assume\n origin/{{github.pullRequest.baseRef}} or origin/{{github.pullRequest.headRef}}\n exists locally unless you explicitly fetch it first.\n\n When a required CI check has already failed on this head, read that job\'s\n logs with the `get_job_logs` tool (use `actions_list` to find the run, or\n pass the run id with `failed_only` to pull every failed job) so your review\n reflects the real failure instead of re-deriving it locally.\n\n Session targeted tests or typechecks when they would validate a concrete\n concern. The checkout may not have node_modules installed yet. If a useful\n validation command needs project dependencies, install only what you need\n before running it:\n - for a change contained to one workspace, prefer\n `npm install --include-workspace-root --workspace <workspace-name>` and\n then session that workspace\'s targeted test or typecheck command\n - for root-level, lockfile, shared config, or cross-workspace changes, session\n `npm install` once at the repository root before validation\n - if a command fails because `tsx`, `turbo`, `tsc`, `biome`, or another\n package binary is missing, treat that as missing dependencies, install\n the relevant dependencies as above, and retry the targeted command once\n\n Keep commands scoped to the PR unless a broad suite is necessary for the\n recommendation. Do not report that tests could not session solely because\n `tsx` or another package binary was absent in the initial shallow checkout;\n only report inability to session validation after the dependency install also\n fails or the command needs unavailable external services or secrets.\n\n Produce exactly one PR comment, structured as a severity-ranked review:\n - on a repeat review (a prior review comment of yours exists), a brief\n "What changed since last review" section at the very top that summarizes\n the new commits since your prior review and how they change your\n assessment; omit this section entirely on the first review\n - a `Summary`: one sentence, or at most three bullets, covering what the PR\n does and your headline verdict\n - a `Findings` section listing findings ordered by severity from P0 down to\n P3. Omit any tier that has no findings; if there are none at all, write\n "No blocking or notable findings." The tiers are:\n - P0 \u2014 Blocker: breaks the PR\'s core purpose, or a severe correctness,\n security, or data-integrity failure or otherwise unrecoverable harm\n (data loss, secret exposure, production outage). Must fix before merge.\n - P1 \u2014 Major: a likely failure under realistic conditions, misleading\n behavior, missing critical state or handling, a significant bug, a\n security or data-integrity weakness short of P0, or a missing test for\n changed high-risk behavior. Should fix before merge.\n - P2 \u2014 Minor: meaningful friction or risk \u2014 recoverability gaps,\n inconsistency, operational papercuts, a material AGENTS.md/docs/idioms.md\n violation in touched code, or weaker-than-warranted test coverage. Fix\n or justify.\n - P3 \u2014 Nit: minor craft, consistency, or readability improvement. Optional.\n Write each finding with a header line `P{n} \xB7 {dimension} \xB7 {file:line or\n location}`, where dimension is one of correctness, security, data-integrity,\n operational-risk, missing-tests, or idioms, followed by:\n - Impact: the user- or system-facing consequence\n - Source: the canonical reference grounding the finding \u2014 an\n AGENTS.md/docs/idioms.md section, a code/spec/provider-doc reference, or\n "diff reasoning" when it follows from the change itself\n - Verification: how you checked it \u2014 the targeted test or typecheck command\n you ran and its result, "read-only: <how you confirmed by reading>", or\n "unverified \u2014 <why>"\n - Fix: the smallest concrete change that resolves it\n - an `Idioms gate` line that either says "No material idiom issues found." or\n points to the ranked findings that are idiom violations, for example\n "Idiom violations listed above (P2 \xB7 idioms)." Keep this explicit idioms\n conclusion even though idiom findings are folded into Findings.\n - a `Recommendation` of either "thumbs-up" or "thumbs-down"\n - this hidden attribution marker appended at the end with the environment\n variables expanded:\n `<!-- auto:v=1 session_id=$AUTO_SESSION_ID agent=$AUTO_AGENT_NAME -->`\n\n Decide the recommendation from the findings:\n - "thumbs-down" if any P0 or P1 finding is unresolved\n - "thumbs-down" if any P2 finding is unresolved, unless the PR body or author\n documents why it is acceptable for this change\n - P3 findings never gate the recommendation\n - otherwise "thumbs-up"\n\n Post the PR comment with the upsert_issue_comment tool. Pass the repository\n owner and name from {{github.repository.fullName}} as `owner` and `repo`, PR\n number {{github.pullRequest.number}} as `issueNumber`, and the full review as\n `body`. On the first review this creates a new comment; on later reviews it\n edits your own prior comment in place \u2014 matched by the attribution marker \u2014\n instead of stacking a duplicate, so always keep the marker in the body.\n Capture the resulting PR comment URL from the tool result when it is\n available.\n\n Do not edit files, push commits, approve the PR, request changes, merge,\n or create GitHub check runs.\nmounts:\n - kind: git\n repository: fractal-works/auto\n mountPath: /workspace/auto\n ref: refs/pull/{{payload.github.pullRequest.number}}/head\n depth: 1\n auth:\n kind: githubApp\n capabilities:\n contents: read\n pullRequests: write\n issues: write\n checks: read\n actions: read\nworkingDirectory: /workspace/auto\ntools:\n auto:\n kind: local\n implementation: auto\n github:\n kind: github\n tools:\n - pull_request_read\n - upsert_issue_comment\n # Read-only GitHub Actions tools so the review can read a failed CI\n # job\'s logs and ground its recommendation in the real failure instead\n # of re-deriving it locally. The mount already grants `actions: read`.\n - actions_get\n - actions_list\n - get_job_logs\ntriggers:\n # One reviewer session owns a PR across heads. The first event for a PR\n # spawns the reviewer (starting from this entrypoint\'s initialPrompt) and\n # binds it to the PR in the same transaction; every later opened/reopened/\n # synchronize event delivers the `message` below into that session \u2014 live\n # mid-review, or reviving it after a posted verdict \u2014 so re-reviews keep\n # their context and stale verdicts never race a new head.\n - name: pr-review\n events:\n - github.pull_request.opened\n - github.pull_request.reopened\n - github.pull_request.synchronize\n connection: github-fractal-works\n where:\n $.github.repository.fullName: fractal-works/auto\n message: |\n Pull request #{{github.pullRequest.number}} in {{github.repository.fullName}} has a review-triggering\n update (action: {{github.action}}; current head {{github.pullRequest.headSha}}).\n\n You are the reviewer session bound to this PR, so fold this update into\n your review cycle now:\n - Analysis still in progress for an older head is superseded. Do not\n post its verdict and do not conclude the managed check with it. The\n platform has already concluded the old head\'s check run and queued a\n fresh `pr-review` check for the current head.\n - Call checks.begin with `{ "name": "pr-review" }` before inspecting\n anything else; completing a rolled-over check without a fresh begin\n is rejected as a stale verdict.\n - The local checkout still holds the head this session started from.\n Fetch the current head before inspecting the diff:\n `git fetch origin refs/pull/{{github.pullRequest.number}}/head` and\n check out the fetched commit.\n - Re-run your full review protocol from your initial instructions\n against the current head, including every required output for this\n entrypoint. Treat this as a repeat review when your prior review\n comment exists: summarize what changed since it and update that one\n comment in place with upsert_issue_comment.\n - Conclude the check with checks.success or checks.failure for the\n current head\'s verdict. There must be exactly one current verdict\n for this PR.\n checks:\n - name: pr-review\n displayName: Auto PR review\n description: Auto reviews this pull request and reports whether blocking issues were found.\n instructions: |\n Call checks.begin with { "name": "pr-review" } before doing\n anything else. After posting the GitHub PR comment, call\n checks.success with { "name": "pr-review", "summary": "...",\n "text": "..." } only for a thumbs-up merge recommendation, and call\n checks.failure with { "name": "pr-review", "summary": "...",\n "text": "..." } for a thumbs-down merge recommendation. Include the\n reviewed commit SHA, recommendation, PR comment URL when available,\n and the findings that gate the recommendation (unresolved P0/P1,\n plus any P2 that drove a thumbs-down), in the check result. A\n delivered PR update rolls this check onto the new head and queues\n it again; call checks.begin again before concluding that new cycle.\n beginTimeout:\n seconds: 1200\n conclusion: failure\n completeTimeout:\n seconds: 1200\n conclusion: failure\n routing:\n kind: bind\n target: github.pull_request\n onUnmatched: spawn\n'
|
|
26558
26592
|
}
|
|
26559
26593
|
]
|
|
26594
|
+
},
|
|
26595
|
+
{
|
|
26596
|
+
version: "1.4.0",
|
|
26597
|
+
files: [
|
|
26598
|
+
{
|
|
26599
|
+
path: "fragments/environments/agent-runtime.yaml",
|
|
26600
|
+
content: "harness: claude-code\nenvironment:\n name: agent-runtime\n image:\n kind: preset\n name: node24\n resources:\n memoryMB: 8192\n"
|
|
26601
|
+
},
|
|
26602
|
+
{
|
|
26603
|
+
path: "fragments/pr-review-slack.yaml",
|
|
26604
|
+
content: 'imports:\n - ./pr-review.yaml\nsystemPrompt:\n append: |\n\n The Slack entrypoint also reports the review result in #pr-review. Treat\n that Slack reply as a required output for this entrypoint.\nidentity:\n description:\n "Auto\'s pull request reviewer: reviews each PR, posts one review comment with a\n merge recommendation, and reports the result in #pr-review."\ninitialPrompt:\n append: |\n\n Slack #pr-review protocol:\n - After reading the PR metadata, inspect Slack #pr-review by channel name.\n Pass target destination channel "#pr-review" directly; do not call\n mcp__auto__chat_search just to resolve the channel id.\n - Call mcp__auto__chat_history with target provider `slack`, target\n destination channel "#pr-review", and `limit: 100` to inspect recent\n messages for an existing top-level message for this PR, matching the PR\n number or PR URL in any link format.\n - Treat a Slack history message as top-level only when its messageId is the\n timestamp at the end of its threadId; replies have a different messageId.\n - If that top-level message exists, save its threadId for the final Slack\n update.\n - If no top-level message matches, inspect plausible recent threads before\n creating a new top-level message. Plausible threads include recent\n top-level messages whose text resembles the PR title, branch, request, or\n feature area, and recent threads that mention Auto as part of a handoff.\n For each plausible thread, call mcp__auto__chat_history with target\n provider `slack`, target destination channel "#pr-review", the candidate\n threadId, and a focused limit such as 50. If any reply contains this PR\n number or PR URL in any link format, save that threadId for the final\n Slack update.\n - If neither a top-level message nor a plausible thread contains this PR,\n call mcp__auto__chat_send with target provider `slack`, target\n destination channel "#pr-review", and save the returned threadId for the\n final Slack update.\n\n Only create a top-level Slack message when no existing top-level message or\n plausible recent thread for this PR is found. Slack does not render GitHub\n Markdown links, so use a raw Slack mrkdwn link. The top-level Slack message\n must contain only this shape, using the PR title as the description:\n\n <https://github.com/{{github.repository.fullName}}/pull/{{github.pullRequest.number}}|PR #{{github.pullRequest.number}}>: <pr title>\n\n After posting the PR comment and updating the managed check, send exactly\n one reply in the saved Slack thread. Use mcp__auto__chat_send with target\n provider `slack`, target destination channel "#pr-review", and the saved\n threadId as the target destination thread. Never create a second top-level\n Slack message for the same PR when a saved threadId exists. Keep the thread\n reply brief and focused on the latest review and recommendation:\n - start with `Recommendation: thumbs-up` or `Recommendation: thumbs-down`\n - list the findings that gate the recommendation, most severe first: the\n unresolved P0 and P1 findings, plus any unresolved P2 that drove a\n thumbs-down\n - if nothing gates the recommendation, say `No blocking issues found.`\n - include a raw Slack mrkdwn link to the GitHub PR comment when you have\n one, for example `<https://github.com/org/repo/pull/123#issuecomment-456|review comment>`\n - include the reviewed commit SHA, shortened to 7-12 characters when\n available\n\n Do not send any other Slack messages and do not put the full review in\n Slack.\ntools:\n chat:\n kind: local\n implementation: chat\n auth:\n kind: connection\n provider: slack\n connection: slack\n'
|
|
26605
|
+
},
|
|
26606
|
+
{
|
|
26607
|
+
path: "fragments/pr-review.yaml",
|
|
26608
|
+
content: '# 1.4.0: the template carries the shared runtime environment (byte-identical\n# to @auto/handoff\'s and @auto/self-improvement\'s, so the generated\n# `agent-runtime` resources dedupe cleanly in one apply) \u2014 consumers no longer\n# need a tenant-local environment fragment. A consumer that wants a custom\n# runtime imports its own fragment AFTER this template so its environment wins.\nimports:\n - ./environments/agent-runtime.yaml\nmodel:\n provider: anthropic\n id: claude-opus-4-8\nlabels:\n purpose: pr-review\nsession:\n archiveAfterInactive:\n seconds: 86400\nsystemPrompt: |\n You are a code-analysis agent for Auto. Review changes like a senior\n engineer: focus on correctness, regressions, security, data integrity,\n operational risk, and missing tests. Keep output concise, concrete, and\n grounded in the diff. Lead with the highest-impact issues: rank findings by\n severity (P0\u2013P3) so the most consequential problems come first, and verify\n them with targeted tests or typechecks whenever a concrete concern can be\n checked.\n\n Also enforce the repository idioms documented in AGENTS.md and\n docs/idioms.md. Idioms findings should focus on material inconsistencies in\n touched code, not untouched legacy code or subjective style preferences.\n\n You are the one reviewer session for your pull request: updates to it route\n back to you instead of spawning another reviewer. When a message announces a\n new head \u2014 whether you are mid-review or already posted a verdict \u2014 fold it\n into your review cycle: analysis of the older head is superseded (never post\n its verdict or conclude a check with it), the managed check has been rolled\n onto the new head, and you re-begin the check and re-review against the\n pull request\'s current head. Keep exactly one current verdict per pull\n request at all times.\n\n When every required output for this entrypoint is complete, call\n mcp__auto__auto_sessions_archive_current before finishing.\nidentity:\n displayName: PR Review\n username: pr-review\n avatar:\n asset: .auto/assets/pr-reviewer.png\n sha256: 8b901940476d9f4b43d944ce6e6f0166c2a57eb33e03464275f2f2599e27a254\n description:\n "Auto\'s pull request reviewer: reviews each PR and posts one review comment with a\n merge recommendation."\ndisplayTitle: "Review PR #{{github.pullRequest.number}}: {{github.pullRequest.title}}"\ninitialPrompt: |\n Review GitHub pull request #{{github.pullRequest.number}} in {{github.repository.fullName}}.\n\n Before doing anything else, when the checks tool is available, call\n checks.begin with `{ "name": "pr-review" }`. This must happen before\n inspecting PR metadata or the diff.\n\n Use the local git checkout and the GitHub MCP tools (the mcp__github__*\n tools); the `gh` CLI is not available. Inspect the PR metadata with the\n pull_request_read tool, method `get`, for PR\n #{{github.pullRequest.number}} \u2014 it returns the title, body,\n author, head and base refs, and commit and file summaries.\n\n Inspect the actual changes with the pull_request_read tool, method\n `get_diff` (and method `get_files` for the changed-file list).\n\n Read AGENTS.md and docs/idioms.md before forming your recommendation. Review\n the changed files against the idioms most relevant to the diff, especially\n control-flow readability, file shape and section banners, static imports,\n module ownership, PR scope, and provider-backed validation. Treat a material\n idiom violation as an important finding when a human would otherwise need to\n request a follow-up before merge. Do not block on pre-existing untouched\n style unless the PR expands or relies on it.\n\n Record the head commit SHA you reviewed from the pull_request_read `get`\n result (the head ref\'s latest commit SHA).\n\n Determine whether you have reviewed this PR before. Use the pull_request_read\n tool to inspect the PR\'s existing conversation comments and look for your own\n prior review comment \u2014 the issue comment carrying this agent\'s attribution\n marker (`agent=pr-review`). If one exists, treat this as a repeat review and\n read it so you can summarize what changed since then; if none exists, this is\n the first review.\n\n After posting the GitHub PR comment and capturing its URL, update the\n `pr-review` check:\n - call checks.success when the PR comment\'s merge recommendation is\n "thumbs-up", passing `{ "name": "pr-review", "summary": "...", "text": "..." }`\n - call checks.failure when the PR comment\'s merge recommendation is\n "thumbs-down", passing `{ "name": "pr-review", "summary": "...", "text": "..." }`\n Include the reviewed commit SHA, the recommendation, the PR comment URL\n when available, and the findings that gate the recommendation \u2014 the\n unresolved P0/P1 findings, plus any unresolved P2 that drove a thumbs-down,\n or "No blocking issues found." when nothing gates \u2014 in the check result.\n\n The local checkout is a shallow checkout of the PR head only. Do not assume\n origin/{{github.pullRequest.baseRef}} or origin/{{github.pullRequest.headRef}}\n exists locally unless you explicitly fetch it first.\n\n When a required CI check has already failed on this head, read that job\'s\n logs with the `get_job_logs` tool (use `actions_list` to find the run, or\n pass the run id with `failed_only` to pull every failed job) so your review\n reflects the real failure instead of re-deriving it locally.\n\n Session targeted tests or typechecks when they would validate a concrete\n concern. The checkout may not have node_modules installed yet. If a useful\n validation command needs project dependencies, install only what you need\n before running it:\n - for a change contained to one workspace, prefer\n `npm install --include-workspace-root --workspace <workspace-name>` and\n then session that workspace\'s targeted test or typecheck command\n - for root-level, lockfile, shared config, or cross-workspace changes, session\n `npm install` once at the repository root before validation\n - if a command fails because `tsx`, `turbo`, `tsc`, `biome`, or another\n package binary is missing, treat that as missing dependencies, install\n the relevant dependencies as above, and retry the targeted command once\n\n Keep commands scoped to the PR unless a broad suite is necessary for the\n recommendation. Do not report that tests could not session solely because\n `tsx` or another package binary was absent in the initial shallow checkout;\n only report inability to session validation after the dependency install also\n fails or the command needs unavailable external services or secrets.\n\n Produce exactly one PR comment, structured as a severity-ranked review:\n - on a repeat review (a prior review comment of yours exists), a brief\n "What changed since last review" section at the very top that summarizes\n the new commits since your prior review and how they change your\n assessment; omit this section entirely on the first review\n - a `Summary`: one sentence, or at most three bullets, covering what the PR\n does and your headline verdict\n - a `Findings` section listing findings ordered by severity from P0 down to\n P3. Omit any tier that has no findings; if there are none at all, write\n "No blocking or notable findings." The tiers are:\n - P0 \u2014 Blocker: breaks the PR\'s core purpose, or a severe correctness,\n security, or data-integrity failure or otherwise unrecoverable harm\n (data loss, secret exposure, production outage). Must fix before merge.\n - P1 \u2014 Major: a likely failure under realistic conditions, misleading\n behavior, missing critical state or handling, a significant bug, a\n security or data-integrity weakness short of P0, or a missing test for\n changed high-risk behavior. Should fix before merge.\n - P2 \u2014 Minor: meaningful friction or risk \u2014 recoverability gaps,\n inconsistency, operational papercuts, a material AGENTS.md/docs/idioms.md\n violation in touched code, or weaker-than-warranted test coverage. Fix\n or justify.\n - P3 \u2014 Nit: minor craft, consistency, or readability improvement. Optional.\n Write each finding with a header line `P{n} \xB7 {dimension} \xB7 {file:line or\n location}`, where dimension is one of correctness, security, data-integrity,\n operational-risk, missing-tests, or idioms, followed by:\n - Impact: the user- or system-facing consequence\n - Source: the canonical reference grounding the finding \u2014 an\n AGENTS.md/docs/idioms.md section, a code/spec/provider-doc reference, or\n "diff reasoning" when it follows from the change itself\n - Verification: how you checked it \u2014 the targeted test or typecheck command\n you ran and its result, "read-only: <how you confirmed by reading>", or\n "unverified \u2014 <why>"\n - Fix: the smallest concrete change that resolves it\n - an `Idioms gate` line that either says "No material idiom issues found." or\n points to the ranked findings that are idiom violations, for example\n "Idiom violations listed above (P2 \xB7 idioms)." Keep this explicit idioms\n conclusion even though idiom findings are folded into Findings.\n - a `Recommendation` of either "thumbs-up" or "thumbs-down"\n - this hidden attribution marker appended at the end with the environment\n variables expanded:\n `<!-- auto:v=1 session_id=$AUTO_SESSION_ID agent=$AUTO_AGENT_NAME -->`\n\n Decide the recommendation from the findings:\n - "thumbs-down" if any P0 or P1 finding is unresolved\n - "thumbs-down" if any P2 finding is unresolved, unless the PR body or author\n documents why it is acceptable for this change\n - P3 findings never gate the recommendation\n - otherwise "thumbs-up"\n\n Post the PR comment with the upsert_issue_comment tool. Pass the repository\n owner and name from {{github.repository.fullName}} as `owner` and `repo`, PR\n number {{github.pullRequest.number}} as `issueNumber`, and the full review as\n `body`. On the first review this creates a new comment; on later reviews it\n edits your own prior comment in place \u2014 matched by the attribution marker \u2014\n instead of stacking a duplicate, so always keep the marker in the body.\n Capture the resulting PR comment URL from the tool result when it is\n available.\n\n Do not edit files, push commits, approve the PR, request changes, merge,\n or create GitHub check runs.\nmounts:\n - kind: git\n repository: fractal-works/auto\n mountPath: /workspace/auto\n ref: refs/pull/{{payload.github.pullRequest.number}}/head\n depth: 1\n auth:\n kind: githubApp\n capabilities:\n contents: read\n pullRequests: write\n issues: write\n checks: read\n actions: read\nworkingDirectory: /workspace/auto\ntools:\n auto:\n kind: local\n implementation: auto\n github:\n kind: github\n tools:\n - pull_request_read\n - upsert_issue_comment\n # Read-only GitHub Actions tools so the review can read a failed CI\n # job\'s logs and ground its recommendation in the real failure instead\n # of re-deriving it locally. The mount already grants `actions: read`.\n - actions_get\n - actions_list\n - get_job_logs\ntriggers:\n # One reviewer session owns a PR across heads. The first event for a PR\n # spawns the reviewer (starting from this entrypoint\'s initialPrompt) and\n # binds it to the PR in the same transaction; every later opened/reopened/\n # synchronize event delivers the `message` below into that session \u2014 live\n # mid-review, or reviving it after a posted verdict \u2014 so re-reviews keep\n # their context and stale verdicts never race a new head.\n - name: pr-review\n events:\n - github.pull_request.opened\n - github.pull_request.reopened\n - github.pull_request.synchronize\n connection: github-fractal-works\n where:\n $.github.repository.fullName: fractal-works/auto\n message: |\n Pull request #{{github.pullRequest.number}} in {{github.repository.fullName}} has a review-triggering\n update (action: {{github.action}}; current head {{github.pullRequest.headSha}}).\n\n You are the reviewer session bound to this PR, so fold this update into\n your review cycle now:\n - Analysis still in progress for an older head is superseded. Do not\n post its verdict and do not conclude the managed check with it. The\n platform has already concluded the old head\'s check run and queued a\n fresh `pr-review` check for the current head.\n - Call checks.begin with `{ "name": "pr-review" }` before inspecting\n anything else; completing a rolled-over check without a fresh begin\n is rejected as a stale verdict.\n - The local checkout still holds the head this session started from.\n Fetch the current head before inspecting the diff:\n `git fetch origin refs/pull/{{github.pullRequest.number}}/head` and\n check out the fetched commit.\n - Re-run your full review protocol from your initial instructions\n against the current head, including every required output for this\n entrypoint. Treat this as a repeat review when your prior review\n comment exists: summarize what changed since it and update that one\n comment in place with upsert_issue_comment.\n - Conclude the check with checks.success or checks.failure for the\n current head\'s verdict. There must be exactly one current verdict\n for this PR.\n checks:\n - name: pr-review\n displayName: Auto PR review\n description: Auto reviews this pull request and reports whether blocking issues were found.\n instructions: |\n Call checks.begin with { "name": "pr-review" } before doing\n anything else. After posting the GitHub PR comment, call\n checks.success with { "name": "pr-review", "summary": "...",\n "text": "..." } only for a thumbs-up merge recommendation, and call\n checks.failure with { "name": "pr-review", "summary": "...",\n "text": "..." } for a thumbs-down merge recommendation. Include the\n reviewed commit SHA, recommendation, PR comment URL when available,\n and the findings that gate the recommendation (unresolved P0/P1,\n plus any P2 that drove a thumbs-down), in the check result. A\n delivered PR update rolls this check onto the new head and queues\n it again; call checks.begin again before concluding that new cycle.\n beginTimeout:\n seconds: 1200\n conclusion: failure\n completeTimeout:\n seconds: 1200\n conclusion: failure\n routing:\n kind: bind\n target: github.pull_request\n onUnmatched: spawn\n'
|
|
26609
|
+
}
|
|
26610
|
+
]
|
|
26560
26611
|
}
|
|
26561
26612
|
],
|
|
26562
26613
|
"@auto/research-loop": [
|
|
@@ -28552,6 +28603,7 @@ var init_hardcoded = __esm({
|
|
|
28552
28603
|
"@auto/issue-triage": "Linear issue triage plus an implementation coder: label-driven triage handoffs that become focused PRs.",
|
|
28553
28604
|
"@auto/lead-engine": "An inbound-lead researcher that scores fit and drafts outreach for human approval; -slack entrypoint for a sales-channel flow.",
|
|
28554
28605
|
"@auto/onboarding": "Auto's house onboarding guidance, importable as a managed template.",
|
|
28606
|
+
"@auto/onboarding-quickstart": "The quickstart template repo's onboarding overlay: composes onto @auto/onboarding with the fork-flow walkthrough beats (site request bar, handoff loop, self-improvement demo).",
|
|
28555
28607
|
"@auto/pr-review": "Auto's full pull-request reviewer agent, importable as a managed template.",
|
|
28556
28608
|
"@auto/research-loop": "A research coordinator that runs measurable optimization campaigns on a fleet of experimenter agents.",
|
|
28557
28609
|
"@auto/self-improvement": "A scheduled sweep over PR feedback, read-only data, and Auto sessions that proposes concrete improvements.",
|
|
@@ -30539,6 +30591,25 @@ function createApiClient(input) {
|
|
|
30539
30591
|
}
|
|
30540
30592
|
return SecretSetResponseSchema.parse(await response.json());
|
|
30541
30593
|
},
|
|
30594
|
+
async updateSecretExpiry(name, request, options = {}) {
|
|
30595
|
+
const organization = await activeOrganization();
|
|
30596
|
+
const path2 = `${secretPath(organization.organizationId, options.projectId, name)}/expiry`;
|
|
30597
|
+
const response = await authenticatedFetch(
|
|
30598
|
+
apiUrl(path2, options.apiBaseUrl),
|
|
30599
|
+
{
|
|
30600
|
+
method: "PATCH",
|
|
30601
|
+
headers: {
|
|
30602
|
+
"content-type": "application/json"
|
|
30603
|
+
},
|
|
30604
|
+
body: JSON.stringify(request)
|
|
30605
|
+
},
|
|
30606
|
+
options.apiBaseUrl
|
|
30607
|
+
);
|
|
30608
|
+
if (!response.ok) {
|
|
30609
|
+
throw new Error(await responseErrorMessage(response));
|
|
30610
|
+
}
|
|
30611
|
+
return SecretExpiryUpdateResponseSchema.parse(await response.json());
|
|
30612
|
+
},
|
|
30542
30613
|
async revealSecret(name, options = {}) {
|
|
30543
30614
|
const organization = await activeOrganization();
|
|
30544
30615
|
const path2 = `${secretPath(organization.organizationId, options.projectId, name)}/value`;
|
|
@@ -31605,7 +31676,7 @@ var init_package = __esm({
|
|
|
31605
31676
|
"package.json"() {
|
|
31606
31677
|
package_default = {
|
|
31607
31678
|
name: "@autohq/cli",
|
|
31608
|
-
version: "0.1.
|
|
31679
|
+
version: "0.1.367",
|
|
31609
31680
|
license: "SEE LICENSE IN README.md",
|
|
31610
31681
|
publishConfig: {
|
|
31611
31682
|
access: "public"
|
|
@@ -32776,7 +32847,11 @@ function fileBackedStringField() {
|
|
|
32776
32847
|
return {
|
|
32777
32848
|
target: "spec",
|
|
32778
32849
|
read: (value, context) => resolveFileBackedString2(value, context),
|
|
32779
|
-
merge: (base, override) => resolveAppendDirective(base, override)
|
|
32850
|
+
merge: (base, override) => resolveAppendDirective(base, override),
|
|
32851
|
+
compile: (value) => ({
|
|
32852
|
+
resources: [],
|
|
32853
|
+
value: rejectUnresolvedAppendDirective(value)
|
|
32854
|
+
})
|
|
32780
32855
|
};
|
|
32781
32856
|
}
|
|
32782
32857
|
function rejectDirectiveObject(value, input) {
|
|
@@ -32848,14 +32923,42 @@ function readAppendDirectiveMarker(value, input) {
|
|
|
32848
32923
|
function resolveAppendDirective(base, override) {
|
|
32849
32924
|
const directive = appendDirectiveFromMarker(override);
|
|
32850
32925
|
if (!directive) {
|
|
32926
|
+
const droppedPending = appendDirectiveFromMarker(base);
|
|
32927
|
+
if (droppedPending) {
|
|
32928
|
+
throw new Error(
|
|
32929
|
+
`Invalid agent authoring file ${droppedPending.path}: ${droppedPending.field} append directive was merged before any base value; import the base document before its append overlay`
|
|
32930
|
+
);
|
|
32931
|
+
}
|
|
32851
32932
|
return mergeValues3(base, override);
|
|
32852
32933
|
}
|
|
32853
|
-
if (typeof base
|
|
32854
|
-
|
|
32855
|
-
|
|
32856
|
-
|
|
32934
|
+
if (typeof base === "string") {
|
|
32935
|
+
return base + directive.text;
|
|
32936
|
+
}
|
|
32937
|
+
const pendingBase = appendDirectiveFromMarker(base);
|
|
32938
|
+
if (pendingBase) {
|
|
32939
|
+
return {
|
|
32940
|
+
[APPEND_DIRECTIVE_MARKER_KEY]: {
|
|
32941
|
+
text: pendingBase.text + directive.text,
|
|
32942
|
+
path: directive.path,
|
|
32943
|
+
field: directive.field
|
|
32944
|
+
}
|
|
32945
|
+
};
|
|
32946
|
+
}
|
|
32947
|
+
if (base === void 0) {
|
|
32948
|
+
return override;
|
|
32857
32949
|
}
|
|
32858
|
-
|
|
32950
|
+
throw new Error(
|
|
32951
|
+
`Invalid agent authoring file ${directive.path}: ${directive.field} append directive has no imported ${directive.field} to append to`
|
|
32952
|
+
);
|
|
32953
|
+
}
|
|
32954
|
+
function rejectUnresolvedAppendDirective(value) {
|
|
32955
|
+
const directive = appendDirectiveFromMarker(value);
|
|
32956
|
+
if (!directive) {
|
|
32957
|
+
return value;
|
|
32958
|
+
}
|
|
32959
|
+
throw new Error(
|
|
32960
|
+
`Invalid agent authoring file ${directive.path}: ${directive.field} append directive has no imported ${directive.field} to append to`
|
|
32961
|
+
);
|
|
32859
32962
|
}
|
|
32860
32963
|
function appendDirectiveFromMarker(value) {
|
|
32861
32964
|
if (!isRecord2(value)) {
|
|
@@ -50047,6 +50150,7 @@ function memberLine2(member, style) {
|
|
|
50047
50150
|
}
|
|
50048
50151
|
|
|
50049
50152
|
// src/commands/secrets/actions.ts
|
|
50153
|
+
init_src();
|
|
50050
50154
|
async function setSecret(input) {
|
|
50051
50155
|
const value = await secretValue({
|
|
50052
50156
|
options: input.commandOptions,
|
|
@@ -50059,6 +50163,7 @@ async function setSecret(input) {
|
|
|
50059
50163
|
value,
|
|
50060
50164
|
...input.commandOptions.description === void 0 ? {} : { description: input.commandOptions.description },
|
|
50061
50165
|
...resolveProtectedFlag(input.commandOptions),
|
|
50166
|
+
...resolveExpiryFields(input.commandOptions),
|
|
50062
50167
|
...resolveBindingFlags(input.commandOptions)
|
|
50063
50168
|
},
|
|
50064
50169
|
{
|
|
@@ -50084,6 +50189,17 @@ async function rotateSecret(input) {
|
|
|
50084
50189
|
);
|
|
50085
50190
|
writeRotateResponse(response, input);
|
|
50086
50191
|
}
|
|
50192
|
+
async function updateSecretExpiry(input) {
|
|
50193
|
+
const fields = resolveExpiryFields(input.commandOptions);
|
|
50194
|
+
if (fields.expiresAt === void 0 && fields.idleExpirySeconds === void 0) {
|
|
50195
|
+
throw new Error("Provide --expires-at and/or --idle-expiry.");
|
|
50196
|
+
}
|
|
50197
|
+
const response = await input.client.updateSecretExpiry(input.name, fields, {
|
|
50198
|
+
projectId: await secretProjectId(input),
|
|
50199
|
+
apiBaseUrl: input.commandOptions.apiBaseUrl
|
|
50200
|
+
});
|
|
50201
|
+
writeExpiryResponse(response, input);
|
|
50202
|
+
}
|
|
50087
50203
|
async function revealSecret(input) {
|
|
50088
50204
|
const response = await input.client.revealSecret(input.name, {
|
|
50089
50205
|
projectId: await secretProjectId(input),
|
|
@@ -50106,9 +50222,23 @@ async function listSecrets(input) {
|
|
|
50106
50222
|
}
|
|
50107
50223
|
for (const secret of response.secrets) {
|
|
50108
50224
|
const flags = secret.protected ? "protected" : "revealable";
|
|
50109
|
-
|
|
50110
|
-
|
|
50111
|
-
|
|
50225
|
+
const parts = [
|
|
50226
|
+
secret.name,
|
|
50227
|
+
scopeLabel(secret.projectId),
|
|
50228
|
+
flags,
|
|
50229
|
+
`updated ${secret.updatedAt}`
|
|
50230
|
+
];
|
|
50231
|
+
if (secret.expired) {
|
|
50232
|
+
parts.push("expired");
|
|
50233
|
+
} else {
|
|
50234
|
+
if (secret.expiresAt !== null) {
|
|
50235
|
+
parts.push(`expires ${secret.expiresAt}`);
|
|
50236
|
+
}
|
|
50237
|
+
if (secret.idleExpirySeconds !== null) {
|
|
50238
|
+
parts.push(`idle-expiry ${secret.idleExpirySeconds}s`);
|
|
50239
|
+
}
|
|
50240
|
+
}
|
|
50241
|
+
input.context.writeOutput(parts.join(" "));
|
|
50112
50242
|
}
|
|
50113
50243
|
}
|
|
50114
50244
|
function resolveProtectedFlag(options) {
|
|
@@ -50123,6 +50253,43 @@ function resolveProtectedFlag(options) {
|
|
|
50123
50253
|
}
|
|
50124
50254
|
return {};
|
|
50125
50255
|
}
|
|
50256
|
+
function parseExpiresAt(input) {
|
|
50257
|
+
if (input === "never") {
|
|
50258
|
+
return null;
|
|
50259
|
+
}
|
|
50260
|
+
const parsed = new Date(input);
|
|
50261
|
+
if (Number.isNaN(parsed.getTime())) {
|
|
50262
|
+
throw new Error(
|
|
50263
|
+
`Invalid --expires-at value "${input}". Use an ISO 8601 timestamp or "never".`
|
|
50264
|
+
);
|
|
50265
|
+
}
|
|
50266
|
+
return parsed.toISOString();
|
|
50267
|
+
}
|
|
50268
|
+
function parseIdleExpiry(input) {
|
|
50269
|
+
if (input === "never") {
|
|
50270
|
+
return null;
|
|
50271
|
+
}
|
|
50272
|
+
const match = /^(\d+)(s|m|h|d)?$/.exec(input);
|
|
50273
|
+
if (!match) {
|
|
50274
|
+
throw new Error(
|
|
50275
|
+
`Invalid --idle-expiry value "${input}". Use seconds or a duration like 30d, 12h, 90m, 3600s, or "never".`
|
|
50276
|
+
);
|
|
50277
|
+
}
|
|
50278
|
+
const unitSeconds = { s: 1, m: 60, h: 3600, d: 86400 }[match[2] ?? "s"] ?? 1;
|
|
50279
|
+
const seconds = Number(match[1]) * unitSeconds;
|
|
50280
|
+
if (seconds < 1 || seconds > SECRET_IDLE_EXPIRY_MAX_SECONDS) {
|
|
50281
|
+
throw new Error(
|
|
50282
|
+
`--idle-expiry must be between 1 second and ${SECRET_IDLE_EXPIRY_MAX_SECONDS} seconds (10 years).`
|
|
50283
|
+
);
|
|
50284
|
+
}
|
|
50285
|
+
return seconds;
|
|
50286
|
+
}
|
|
50287
|
+
function resolveExpiryFields(options) {
|
|
50288
|
+
return {
|
|
50289
|
+
...options.expiresAt === void 0 ? {} : { expiresAt: parseExpiresAt(options.expiresAt) },
|
|
50290
|
+
...options.idleExpiry === void 0 ? {} : { idleExpirySeconds: parseIdleExpiry(options.idleExpiry) }
|
|
50291
|
+
};
|
|
50292
|
+
}
|
|
50126
50293
|
function resolveBindingFlags(options) {
|
|
50127
50294
|
const hasBindingFlags = (options.bindHost?.length ?? 0) > 0 || options.bindHeader !== void 0 || options.bindFormat !== void 0;
|
|
50128
50295
|
if (options.unbind) {
|
|
@@ -50228,6 +50395,16 @@ function writeRotateResponse(response, input) {
|
|
|
50228
50395
|
`secret ${response.secret.name} rotated scope=${scopeLabel(response.secret.projectId)}`
|
|
50229
50396
|
);
|
|
50230
50397
|
}
|
|
50398
|
+
function writeExpiryResponse(response, input) {
|
|
50399
|
+
if (input.commandOptions.json) {
|
|
50400
|
+
input.context.writeOutput(JSON.stringify(response));
|
|
50401
|
+
return;
|
|
50402
|
+
}
|
|
50403
|
+
const idle = response.secret.idleExpirySeconds === null ? "never" : `${response.secret.idleExpirySeconds}s`;
|
|
50404
|
+
input.context.writeOutput(
|
|
50405
|
+
`secret ${response.secret.name} expiry updated scope=${scopeLabel(response.secret.projectId)} expires=${response.secret.expiresAt ?? "never"} idle=${idle}`
|
|
50406
|
+
);
|
|
50407
|
+
}
|
|
50231
50408
|
function writeRevealResponse(response, input) {
|
|
50232
50409
|
if (input.commandOptions.json) {
|
|
50233
50410
|
input.context.writeOutput(JSON.stringify(response));
|
|
@@ -50315,7 +50492,13 @@ function registerSecretCommands(program, context) {
|
|
|
50315
50492
|
).option("--unbind", "clear an existing destination binding").option("--protected", "mark write-only: refuse plaintext reveal (default)").option(
|
|
50316
50493
|
"--unprotected",
|
|
50317
50494
|
"allow scope-gated plaintext reveal of this secret"
|
|
50318
|
-
).option("--raw", "allow empty values and preserve stdin exactly").option(
|
|
50495
|
+
).option("--raw", "allow empty values and preserve stdin exactly").option(
|
|
50496
|
+
"--expires-at <timestamp>",
|
|
50497
|
+
'absolute expiry as an ISO 8601 timestamp, or "never" to clear'
|
|
50498
|
+
).option(
|
|
50499
|
+
"--idle-expiry <duration>",
|
|
50500
|
+
'expire after this long unused (seconds or 30d/12h/90m/3600s), or "never" to clear'
|
|
50501
|
+
).option("--json", "print the updated secret metadata as JSON").option("--api-url <url>", "Auto API base URL").option("--api-base-url <url>", "Auto API base URL").action(async (name, commandOptions) => {
|
|
50319
50502
|
await setSecret({
|
|
50320
50503
|
client: createContextApiClient(context),
|
|
50321
50504
|
commandOptions: withApiBaseUrl(context, commandOptions),
|
|
@@ -50334,6 +50517,20 @@ function registerSecretCommands(program, context) {
|
|
|
50334
50517
|
name
|
|
50335
50518
|
});
|
|
50336
50519
|
});
|
|
50520
|
+
secrets.command("expiry").description("Update a secret's expiry without changing its value.").argument("<name>", "secret name").option("--project <project>", "project id; defaults to organization scope").option(
|
|
50521
|
+
"--expires-at <timestamp>",
|
|
50522
|
+
'absolute expiry as an ISO 8601 timestamp, or "never" to clear'
|
|
50523
|
+
).option(
|
|
50524
|
+
"--idle-expiry <duration>",
|
|
50525
|
+
'expire after this long unused (seconds or 30d/12h/90m/3600s), or "never" to clear'
|
|
50526
|
+
).option("--json", "print the updated secret metadata as JSON").option("--api-url <url>", "Auto API base URL").option("--api-base-url <url>", "Auto API base URL").action(async (name, commandOptions) => {
|
|
50527
|
+
await updateSecretExpiry({
|
|
50528
|
+
client: createContextApiClient(context),
|
|
50529
|
+
commandOptions: withApiBaseUrl(context, commandOptions),
|
|
50530
|
+
context,
|
|
50531
|
+
name
|
|
50532
|
+
});
|
|
50533
|
+
});
|
|
50337
50534
|
secrets.command("reveal").description(
|
|
50338
50535
|
"Print the decrypted value of a non-protected secret (audited)."
|
|
50339
50536
|
).argument("<name>", "secret name").option("--project <project>", "project id; defaults to organization scope").option("--json", "print the secret value and metadata as JSON").option("--api-url <url>", "Auto API base URL").option("--api-base-url <url>", "Auto API base URL").action(async (name, commandOptions) => {
|