@agentconnect.md/daemon 1.61.0-rc.194 → 1.61.0-rc.195

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.
@@ -1 +1 @@
1
- {"version":3,"file":"git-url-nFiL6sQ7.js","names":["z.string","z.object","z.enum","z.number","z\n .object"],"sources":["../../protocol/dist/consts.js","../../protocol/dist/code-host.js","../../protocol/dist/git-url.js"],"sourcesContent":["/**\n * Cross-package wire + lifecycle constants shared by the daemon and the CLI.\n *\n * These are pure data (no zod, no runtime deps) so both `@agentconnect.md/cli`\n * and `@agentconnect.md/daemon` can import them without pulling in each other:\n * the daemon dials the CP with the subprotocol/path, and the CLI's login probe\n * dials the same way; both the daemon (planned-exit code) and the CLI (run\n * respawn shell + generated service units) must agree on the restart exit code.\n */\n/**\n * Cap on agent→agent hop depth (agent-collaboration §2.4/§4.5), shared by every\n * component that can admit an agent-to-agent edge.\n *\n * It lives here because send-message-routing-rework.md §4.1 requires ONE budget across\n * transports: \"the same `MAX_AGENT_CALL_HOPS`, whether it is a same-daemon internal\n * call, a relayed internal call, a direct-daemon platform mention, or a relayed platform\n * mention\". Three independent copies (daemon, relay agent-msg router, relay ingress)\n * could drift, and a relay that allowed one more hop than the daemon would let a relayed\n * chain outlive the budget an internal chain gets — a loop-safety hole that no single\n * package's tests would catch.\n *\n * The value is a runaway-loop backstop, not a conversation-length policy: a healthy\n * exchange terminates because the agents are done, and every extra hop only costs one\n * more turn. It was raised from 8 to 20 because 8 cut ordinary human-started relay games\n * short (a thread rooted in one human message affords exactly this many agent→agent\n * edges), while 20 is still far below anything a real collaboration needs and keeps a\n * genuine A↔B ping-pong bounded within seconds.\n */\nexport const MAX_AGENT_CALL_HOPS = 20;\n/**\n * Whether an agent-to-agent delivery has reached the exclusive hop boundary.\n *\n * A delivery at the boundary is not admitted: when the cap is 20, hop 19 is the\n * last agent turn that may run and its reply closes the autonomous exchange.\n * Keeping the comparison beside the shared constant prevents daemon and relay\n * admission paths from drifting on the boundary semantics.\n */\nexport function hasReachedAgentCallHopLimit(deliveryHopCount) {\n return deliveryHopCount >= MAX_AGENT_CALL_HOPS;\n}\n/** The daemon↔CP WebSocket subprotocol negotiated on `ClientTransport.dial`. */\nexport const CP_SUBPROTOCOL = 'agentconnect.v1';\n/** The CP mount path the daemon↔CP WebSocket connects to. */\nexport const CP_WS_PATH = '/daemon/ws';\n/** CP accepts metadata-only transcript activity invalidations from current daemons. */\nexport const SESSION_LIVE_TAIL_FEATURE = 'session-live-tail-v1';\n/** Daemon resolves workspace list/read/git-status requests against the isolated\n * worktree named by `sessionId` instead of silently falling back to primary. */\nexport const WORKSPACE_SESSION_READ_FEATURE = 'workspace-session-read-v1';\n/** Daemon resolves every workspace read/git frame against the secondary root named by `repo` —\n * the checkout under `<agentRoot>/repos/<owner>/<repo>`, or that root's per-session worktree. The\n * CP must check this before forwarding a `repo`-scoped request: an older daemon ignores the field\n * and would answer for the PRIMARY workspace, which is the wrong repository's files. */\nexport const WORKSPACE_REPO_SCOPE_FEATURE = 'workspace-repo-scope-v1';\n/** Daemon serves the console's git review reads — `workspace/gitdiff`,\n * `workspace/gitlog`, and per-file `additions`/`deletions` on `workspace/gitstatus`.\n * The CP must check this before sending either new frame: an older daemon ignores\n * an unknown frame silently, so the REQ would burn its whole retransmit budget and\n * then surface as an offline daemon. */\nexport const WORKSPACE_GIT_REVIEW_FEATURE = 'workspace-git-review-v1';\n/** Daemon serves the console's git WRITES — `workspace/gitstage`, `workspace/gitunstage`,\n * `workspace/gitcommit` and `workspace/gitpush`. Checked before sending, for the same reason\n * as the review feature: an older daemon ignores an unknown frame silently, so the REQ would\n * burn its retransmit budget and then read as an offline daemon. The console renders the write\n * controls as ABSENT (not inert) on a daemon without it. */\nexport const WORKSPACE_GIT_WRITE_FEATURE = 'workspace-git-write-v1';\n/** Daemon serves `workspace/gitmessage` — the AI commit-message draft, run on the AGENT's own\n * runtime. Separate from the write feature on purpose: it is not a write, and the console hides one\n * button (the wand) on a daemon without it while keeping stage/commit/push. Checked before sending,\n * like every other new frame: an older daemon ignores it silently and the REQ would burn its\n * retransmit budget before reading as an offline daemon. */\nexport const WORKSPACE_GIT_MESSAGE_FEATURE = 'workspace-git-message-v1';\n/** Daemon serves `task/list` — the console Tasks panel's read of one ACP session's background-task\n * lease. Checked before sending, like every other new frame: an older daemon ignores it silently, so\n * the REQ would burn its whole retransmit budget and then read as an offline daemon. The console\n * hides the Tasks tab on a daemon without it rather than showing a tab that can never answer. */\nexport const TASK_LIST_FEATURE = 'task-list-v1';\n/** Daemon serves `automerge/set` + `automerge/state` — the PR panel's merge-when-ready watcher, run at\n * the edge because GitHub's own auto-merge refuses every pull request that is not BLOCKED. Checked\n * before sending, like every other new frame: an older daemon ignores it silently, so the REQ would\n * burn its retransmit budget and then read as an offline daemon. The console disables the box on a\n * daemon without it rather than offering a control that can never arm. */\nexport const AUTO_MERGE_FEATURE = 'auto-merge-v1';\n/** Daemon honours `automerge/set.sessionId` — an isolated session's arm is watched in that session's own pod; an older daemon strips the field and arms in the agent pod, so the CP sends it only to one advertising this. */\nexport const AUTO_MERGE_SESSION_FEATURE = 'auto-merge-session-v1';\n/** Daemon serves `sandbox/keepalive` — an open console page holding a cluster agent's pod against the\n * idle sweep while its worktree is dirty or a merge-when-ready watcher is armed in it. Checked before\n * sending, like every other new frame: an older daemon ignores it silently, so the REQ would burn its\n * retransmit budget and then read as an offline daemon. A console that gets no answer simply stops\n * renewing — the sweep's own rules then apply, which is the pre-feature behaviour. */\nexport const SANDBOX_KEEP_ALIVE_FEATURE = 'sandbox-keep-alive-v1';\n/** Daemon serves `runtime/commands` — the slash commands an agent's ACP runtime advertised it can be\n * asked to run. Checked before sending: an older daemon ignores an unknown frame silently, so the REQ\n * would burn its retransmit budget and then read as an offline daemon. */\nexport const RUNTIME_COMMANDS_FEATURE = 'runtime-commands-v1';\n/** Daemon serves `agent/wake` — the console's \"start this agent's sandbox\" for a Files/Memory read.\n * Advertised only by a daemon that runs agents in cluster sandboxes: on any other daemon there is\n * nothing to wake, and the CP answers `unsupported` without sending a frame it would ignore. */\nexport const AGENT_WAKE_FEATURE = 'agent-wake-v1';\n/** Daemon honours `agent/wake.sessionId` — resume that session's own pod, never the agent's; an older daemon strips the field and wakes the agent pod, so the CP sends it only to one advertising this. */\nexport const SESSION_WAKE_FEATURE = 'session-wake-v1';\n/** Daemon serves `daemon/runtimes/probe` (the self-hosted console's \"refresh runtimes\"); a managed pool refreshes on its timer alone. */\nexport const RUNTIME_PROBE_FEATURE = 'runtime-probe-v1';\n/** Relay reports body-free GitHub feedback and daemon durably continues the linked session. */\nexport const PULL_REQUEST_FEEDBACK_FEATURE = 'pull-request-feedback-v1';\n/** CP keeps each relay's `rc/bot-credential-check` and aggregates the mark, and records `rc/bot-revoked` evidence; a relay sends neither to an older CP and revokes on an ambiguous answer there instead. */\nexport const BOT_CREDENTIAL_CHECK_FEATURE = 'bot-credential-check-v2';\n/** How long the CP must let ONE `workspace/gitmessage` REQ run before giving up, and it must send it\n * single-shot (`{ ackTimeoutMs: WORKSPACE_GIT_MESSAGE_BUDGET_MS, maxTries: 1 }`). The default 5s ack\n * timeout would retransmit an in-flight model pass four times: identical frame ids, so the daemon\n * joins them into one pass, but the CP would still fail the request while the answer was coming.\n * The daemon's own budget is strictly smaller, so the REP always wins this race. */\nexport const WORKSPACE_GIT_MESSAGE_BUDGET_MS = 75_000;\n/**\n * CP accepts the `event/session-purged` retention-GC receipt (#485) and marks the\n * session's stored metadata content-purged. Advertised by the CP in\n * `register/ok.serverFeatures`; a daemon that does not see it KEEPS its durable\n * receipts instead of emitting a frame an older CP would reject as\n * `UNKNOWN_FRAME` — the report is re-tried once the CP is upgraded.\n */\nexport const SESSION_PURGE_FEATURE = 'session-purge-v1';\n/**\n * CP accepts the correlated `event/session-sync` metadata snapshot. Daemons\n * keep one latest-wins snapshot per session until the CP acknowledges the\n * persistence commit; older CPs continue receiving best-effort `event/session`\n * events while the durable snapshot remains queued for a later upgrade.\n */\nexport const SESSION_METADATA_ACK_FEATURE = 'session-metadata-ack-v1';\n/** CP accepts `integration/revoked`, a daemon socket's explicit credential-lifecycle report; an older CP rejects the frame, so the daemon keeps its reports instead. */\nexport const INTEGRATION_REVOKED_FEATURE = 'integration-revoked-v1';\n/**\n * Daemon understands the `session/visibility` gate pushes + register-time\n * snapshot replay (session-visibility.md §5.1). Advertised by the daemon in\n * `RegisterReq.capabilities.features`; the CP gates all visibility pushes on\n * it so older daemons never see the frames.\n */\nexport const SESSION_VISIBILITY_FEATURE = 'session-visibility-v1';\n/** Daemon/runtime support private, session-scoped remote MCP headers and stable invocation ids. */\nexport const WEBCHAT_REMOTE_MCP_FEATURE = 'webchat_remote_mcp_v1';\n/**\n * Daemon understands multi-agent webchat conversations: `mentions`/`post` on\n * webchat turns, the transcript-only `context` op, agent-attributed\n * ack/output/done, and `rd/webchat-post` reply fan-out\n * (webchat-multi-agents.md). The CP refuses to CREATE a conversation with more\n * than one agent unless every selected agent's daemon advertises this.\n */\nexport const WEBCHAT_MULTI_AGENT_FEATURE = 'webchat_multi_agent_v1';\n/**\n * Cross-surface session continuation (webchat-cross-integration-continuation.md):\n * the daemon accepts `RdMsgWebchat.targetSessionId` and dispatches the browser\n * turn onto the target session's own local coordinates; a relay advertises the\n * same feature in `rc/register.features` when it preserves the field end to end.\n * The CP refuses to mint a session-targeted webchat token unless the owning\n * daemon AND every live relay advertise it (fail-closed rollout).\n */\nexport const WEBCHAT_SESSION_CONTINUATION_FEATURE = 'webchat_session_continuation_v1';\n/**\n * Hook-origin continuation (webchat-cross-integration-continuation.md §9): the\n * daemon accepts a `targetSessionId` naming a hook-origin session (GitHub,\n * GitLab, a generic webhook, a schedule) and runs the browser turn on it with\n * the console as the ONLY surface — no platform connection, no mirror. The CP\n * refuses to mint a session-targeted token for such a session unless the owning\n * daemon advertises this on top of {@link WEBCHAT_SESSION_CONTINUATION_FEATURE}.\n */\nexport const WEBCHAT_HOOK_CONTINUATION_FEATURE = 'webchat_hook_continuation_v1';\n/** Daemon and Control Plane support Organization Knowledge, Dream suggestions,\n * and immutable managed-skill bundle retrieval. */\nexport const ORGANIZATION_KNOWLEDGE_FEATURE = 'organization-knowledge-v1';\n/** Daemon currently admits staged Dream suggestion content reads and owner\n * review decisions. Omitted while the staged-content security hold is active. */\nexport const ORGANIZATION_SUGGESTION_REVIEW_FEATURE = 'organization-suggestion-review-v1';\n/** Daemon understands externally-bound Slack session audiences, including the\n * `external` visibility value and the stricter shared-memory exclusion bit. */\nexport const SLACK_SESSION_AUDIENCE_FEATURE = 'slack-session-audience-v1';\n/**\n * Daemon persists `AgentSpec.configRevision` and enforces the monotonic\n * comparison before applying a CP-owned snapshot\n * (organization-secrets-and-variables.md §7). Organization environment entries\n * rely on full-map replacement semantics, so a bound agent may only be placed on\n * a daemon that advertises this: without the fence, an older full snapshot that\n * completes late could reinstate a rotated or deleted value.\n */\nexport const AGENT_CONFIG_REVISION_FEATURE = 'agent-config-revision-v1';\n/** Auth-only recovery capability that permits CP to queue an offline daemon upgrade. */\nexport const DAEMON_BOOTSTRAP_UPGRADE_FEATURE = 'daemon-bootstrap-upgrade-v1';\n/** Frozen version of the auth-only bootstrap handshake. */\nexport const DAEMON_BOOTSTRAP_PROTOCOL_VERSION = 1;\n/**\n * Per-value ceiling for an environment variable or secret, shared by the agent\n * and organization surfaces so one entry can never be sized past what any\n * resolved `AgentSpec` could carry.\n *\n * 64 KiB is a quarter of `MAX_FRAME_BYTES`: generous for the real payloads\n * (a PEM block, a kubeconfig, a service-account JSON) while leaving room for the\n * rest of the spec. It is a per-VALUE guard only — the authoritative check is the\n * transaction-time admission budget over the whole resolved environment, which\n * the Control Plane applies per affected agent before persisting.\n */\nexport const MAX_ENVIRONMENT_VALUE_LENGTH = 64 * 1024;\n/**\n * Exit code a daemon uses for a PLANNED lifecycle exit (drain-then-exit on a\n * `daemon/restart` or `daemon/upgrade`, cli-daemon-split.md §6). It must be\n * non-zero: launchd's `KeepAlive.SuccessfulExit=false` only relaunches on a\n * non-zero exit, so exit 0 would leave the daemon down on macOS. Both\n * supervisors relaunch on it (systemd `Restart=always` covers any code). 75 is\n * EX_TEMPFAIL from sysexits(3) — \"temporary failure, retry\" — which reads\n * correctly for \"the daemon asked to be brought back up\".\n *\n * The CLI's `run` respawn shell (§6.1) also keys off this exact code to decide\n * whether to relaunch vs propagate the child's exit.\n */\nexport const RESERVED_RESTART_CODE = 75;\n/**\n * `AGENTCONNECT_SUPERVISOR` value a pool member runs under: Kubernetes, where the\n * kubelet takes the place of launchd/systemd AND of the CLI's version store.\n *\n * It supervises restart — `restartPolicy: Always` brings the container back after\n * {@link RESERVED_RESTART_CODE}, in place and in the same pod, which is the same\n * shape as a systemd process restart — but not upgrade: the running version is the\n * image, so only whoever owns the Deployment can change it.\n */\nexport const K8S_SUPERVISOR = 'k8s';\n/**\n * Audience the projected ServiceAccount token an in-cluster daemon authenticates with is\n * restricted to. The shim handshake run one hop up: a sandbox proves itself to the daemon\n * with a token scoped to `SHIM_TOKEN_AUDIENCE`, and here the daemon proves itself to the\n * control plane the same way. The audiences differ, so neither token is accepted at the\n * other end.\n *\n * This and {@link CLOUD_DAEMON_SA_NAME} are the two names the deployment that stamps them and\n * the control plane that checks them must agree on exactly. They live here rather than\n * being configured on each side because a constant kept in two places eventually holds two\n * values: a rename passes every build and every test, since each side stays self-consistent,\n * and fails only at runtime when a real daemon's token is rejected. One definition makes that\n * a compile error instead.\n */\nexport const CP_TOKEN_AUDIENCE = 'ac-control-plane';\n/**\n * ServiceAccount a pool member runs as, and the control plane's second check on a reviewed\n * token, so a later change cannot authenticate some other pod in the same namespace. A pool\n * member serves EVERY org, so it lives in the install's control namespace rather than in an\n * org namespace and no namespace⇒org mapping can name its org — the org is a per-connection\n * selector it declares in `auth`, which is safe precisely because this ServiceAccount is an\n * install-level principal. Shared for the same reason as {@link CP_TOKEN_AUDIENCE}.\n */\nexport const CLOUD_DAEMON_SA_NAME = 'ac-cloud-daemon';\n/**\n * DEFAULT ServiceAccount name for the usage-report collector — the principal allowed to\n * post `gateway`-source session usage to the control plane's batch ingress. A default, not\n * a contract: the collector is not this codebase's pod, so the deployment that runs it\n * names it and tells the control plane through `USAGE_COLLECTOR_SERVICE_ACCOUNT`; this\n * value is what an unconfigured control plane expects. The name stays separate from\n * {@link CLOUD_DAEMON_SA_NAME} on purpose whatever it is set to: both tokens carry\n * {@link CP_TOKEN_AUDIENCE}, so the ServiceAccount is what keeps a daemon's token from\n * writing usage and a collector's token from claiming a daemon identity.\n */\nexport const USAGE_COLLECTOR_SA_NAME = 'ac-usage-collector';\n/**\n * ServiceAccount the org-usage READER runs as — the principal allowed to read an org's\n * usage aggregate without a human's session visibility, so a settlement job can total a\n * closed period. A third name beside {@link USAGE_COLLECTOR_SA_NAME} because the two\n * capabilities are not the same risk: the collector's token can create spend records,\n * this one can only disclose them, and no workload should hold both by accident. They\n * are separate pods, so they are separate ServiceAccounts; if they ever merge, that is a\n * deliberate deployment decision and not something a shared constant did quietly.\n */\nexport const USAGE_READER_SA_NAME = 'ac-usage-reader';\n/** Where the deployment projects that token into the daemon pod, and where the daemon reads it\n * from. Not part of the verification, but the same two-sided agreement: the mounter and the\n * reader are both in this repo, so one definition beats a comment asking them to match. */\nexport const CP_IDENTITY_TOKEN_PATH = '/var/run/ac-cp-identity/token';\n/** Env var carrying the control plane's own WebSocket URL into an in-cluster daemon. The pod\n * has no config file to read it from, and a URL is not a secret. Same two-sided agreement as\n * the token path: the deployment sets it, the daemon reads it. */\nexport const CP_URL_ENV = 'AC_CP_URL';\n/** Env var switching an in-cluster daemon's usage reporting off, for a deployment that meters\n * upstream of the daemon and needs that plane to be the single writer. Same reason it is an\n * env and not a config key alone: an in-cluster daemon has no config file to carry one. Read\n * as a boolean — `false`/`0` disable, anything else leaves reporting on. */\nexport const USAGE_REPORTING_ENV = 'AC_USAGE_REPORTING';\n/** Env var carrying the operator's workspace clone-origin allowlist into an in-cluster daemon,\n * comma-separated. The policy is the OPERATOR's — a tenant can never widen it — and in a cluster\n * the deployment is who that is, with no config file to say it in. Absent leaves the daemon's own\n * default; a malformed entry is fatal rather than dropped, because a silently missing origin is a\n * clone refused later with no trace of why. */\nexport const WORKSPACE_GIT_ORIGINS_ENV = 'AC_WORKSPACE_GIT_ALLOWED_ORIGINS';\n/** A pool member's rollout generation (its pod-template hash), reported on register (frames/register.ts). */\nexport const POD_TEMPLATE_HASH_ENV = 'AC_POD_TEMPLATE_HASH';\n/** CP answers the `agent/exists` batch existence query the pool's orphan reconciler\n * asks before collecting a leaked sandbox object; a daemon that does not see it\n * skips the sweep rather than emit a frame an older CP rejects as `UNKNOWN_FRAME`. */\nexport const AGENT_EXISTS_FEATURE = 'agent-exists-v1';\n/** CP also answers `agent/exists` with WHERE each surviving agent is placed, so the pool's\n * reconciler can tell an agent that is gone from one that merely moved off this member set.\n * A daemon that does not see it omits `placedOnSetId` and sweeps on existence alone — the\n * pre-placement behavior, which collects strictly less and never more. */\nexport const AGENT_PLACEMENT_FEATURE = 'agent-placement-v1';\n// ── GitLab.com code-host features (gitlab-com-integration.md §17.3) ─────────\n// Each string is advertised only when its COMPLETE slice is live; the CP must\n// never place a GitLab-shaped workspace, grant, or hook on a peer without it.\n/** Daemon/relay serves the complete GitLab.com slice: hook normalization, credential\n * routing, poster, and (relay) signed ingress. Gate for placement, snapshot projection,\n * and rule broadcast — a GitLab-shaped value sent without it is frame-fatal downstream. */\nexport const GITLAB_COM_V1_FEATURE = 'gitlab-com-v1';\n/** The default value of the GitLab host axis (§24.1). An absent host on a replicated\n * agent spec, a compiled hook rule, trusted hook metadata, or a credential grant means\n * this — the default of one axis, never a separate mode. */\nexport const GITLAB_DEFAULT_BASE_URL = 'https://gitlab.com';\n/** Daemon/relay serves the self-managed-instance slice: the host carried per agent rather\n * than assumed (§24.4). Gates placement, snapshot projection, hook assignment, and hook\n * dispatch ONLY when the configured host is not `GITLAB_DEFAULT_BASE_URL`; on GitLab.com\n * nothing is gated. Fail-closed by omission — a peer without it never sees self-managed\n * work, so it cannot fall back to GitLab.com for it. */\nexport const GITLAB_INSTANCE_V1_FEATURE = 'gitlab-instance-v1';\n/** True when a carried host names an instance other than GitLab.com — the only case anything\n * gates (§24.4). Absent is the default value of the axis, so it is never self-managed. Lives\n * here, not in one consumer: the control plane, the relay, and the daemon all read it. */\nexport function isSelfManagedGitlabHost(host) {\n return host !== undefined && host !== GITLAB_DEFAULT_BASE_URL;\n}\n// ── Gitea code-host features (gitea-integration.md §11) ────────────────────\n/** Daemon/relay serves the complete Gitea slice: hook normalization, credential routing,\n * poster, and (relay) signed ingress. Gate for placement, spec projection, hook assignment,\n * and the relay's dispatch target, with the same fail-closed-by-omission semantics as the\n * GitLab bits. One string covers gitea.com and a self-hosted instance: a self-hosted\n * address is the same code path, so there is no separate instance feature. */\nexport const GITEA_V1_FEATURE = 'gitea-v1';\n/** The default value of the Gitea instance axis (§3). An absent host on a replicated agent\n * spec, a compiled hook rule, trusted hook metadata, or a credential grant means this — the\n * default of one axis, never a separate mode. */\nexport const GITEA_DEFAULT_BASE_URL = 'https://gitea.com';\n/** CP serves provider-qualified gitcred v2 request/grant fields. A daemon must not name a\n * provider before seeing this, and must reject a grant whose provider or numeric repository\n * id differs from its request (an older CP strips new fields and answers GitHub-shaped). */\nexport const GITCRED_PROVIDER_V2_FEATURE = 'gitcred-provider-v2';\n/** CP accepts an explicitly github-qualified credential request and echoes `provider: 'github'` back. */\nexport const GITCRED_GITHUB_V2_FEATURE = 'gitcred-github-v2';\n/** Provider-routed formal-review surface (`submitCodeReview` and the provider-neutral\n * review authorization/result frames). */\nexport const CODEHOST_REVIEW_V1_FEATURE = 'codehost-review-v1';\n/** Daemon decodes the host-neutral `mode: 'git'` workspace arm (git-workspace-model.md §8).\n * The CP dual-encodes: the `git` arm to daemons advertising this, the legacy\n * `github`/`gitlab` arms to everyone else — the new arm is frame-fatal without it. */\nexport const WORKSPACE_GIT_V1_FEATURE = 'workspace-git-v1';\n/** Informational status-note projection, each side attesting to its own half: the daemon renders\n * and updates the note (desired/result frame pair), the CP drives the ledger end to end including\n * the gitlab arm of `hook/start` that records the started head and opens `running`. */\nexport const CODEHOST_NOTE_PROJECTION_V1_FEATURE = 'codehost-note-projection-v1';\n/** CP resolves and revalidates approval-DM recipients (`agent/approval-route`,\n * slack-approval-dm.md §4.2). A daemon must not send that REQ before seeing this:\n * a new request type is frame-fatal to an older CP. */\nexport const APPROVAL_DM_ROUTE_V1_FEATURE = 'approval-dm-route-v1';\n/** CP mints the §14.2 broker effect lease — `purpose: 'gitlab_effect'` on a gitcred v2 request,\n * authorized by the agent's GitLab workspace binding or an enabled gitlab hook and clamped by the\n * grant's echoed access. A daemon must not name that purpose before seeing this: a new enum value\n * in a daemon→CP frame is frame-fatal to an older CP (§17.3), not a stripped field. */\nexport const GITLAB_EFFECT_V1_FEATURE = 'gitlab-effect-v1';\n/** Session executors (session-executors.md §6): the CP serves `executor/candidates` and relays `executor/prepare` and `executor/release`, a daemon answers the relayed ones; neither end sends an executor frame to a peer without it. */\nexport const SESSION_EXECUTORS_V1_FEATURE = 'session-executors-v1';\n/** How long the CP lets ONE relayed `executor/prepare` (or `executor/release`) run, single-shot: above the pool's 90 s pod-readiness budget, which an executor's own preparation budget must stay under. */\nexport const EXECUTOR_PREPARE_RELAY_BUDGET_MS = 120_000;\n/** CP serves the `memory/store` family (memory-evolution.md §3.2.1); a daemon refuses a `control-plane` home without it. */\nexport const AGENT_MEMORY_STORE_V1_FEATURE = 'agent-memory-store-v1';\n//# sourceMappingURL=consts.js.map","// ⚠️ NO RELATIVE IMPORTS — a bundler compiles this from source; web's protocol-imports.leaf.test.ts enforces it.\nimport { z } from 'zod';\n/**\n * Code-host provider identity (gitlab-com-integration.md §8.1).\n *\n * Code hosts are NOT chat platforms: they have no connection, no ingress plugin\n * identity, and no manifest entry. What they share is a provider-qualified\n * NUMERIC repository identity — paths and clone URLs are mutable display hints,\n * so authorization, hook matching, and run effects must key on\n * `(provider, externalId)` and never on a display path.\n */\nexport const CODE_HOST_PROVIDERS = ['github', 'gitlab', 'gitea'];\nexport function isCodeHostProvider(value) {\n return typeof value === 'string' && CODE_HOST_PROVIDERS.includes(value);\n}\n/** The generic inbound endpoint — the one hook kind that is not a code host. */\nexport const GENERIC_HOOK_KIND = 'webhook';\n/**\n * Inbound-trigger source vocabulary: the generic endpoint plus one entry per code\n * host. Deriving it from `CODE_HOST_PROVIDERS` is what makes a new host a\n * compile-time event — every `Record<HookKind, …>` mapping over this union stops\n * type-checking until it is given an entry, so no host can silently inherit the\n * generic webhook rendering the way GitLab once did.\n */\nexport const HOOK_KINDS = [GENERIC_HOOK_KIND, ...CODE_HOST_PROVIDERS];\n/** A hook kind that identifies a code host, as opposed to the generic endpoint. */\nexport function isCodeHostHookKind(kind) {\n return kind !== GENERIC_HOOK_KIND;\n}\n/**\n * Wire form for provider fields — an OPEN string, mirroring the KNOWN_PLATFORMS\n * precedent (frames/route.ts): zod rejects unknown enum values wholesale, and an\n * unknown provider inside a known frame must degrade per-value, never make the\n * whole frame undecodable on an older peer. Consumers gate on\n * `isCodeHostProvider` and fail closed per value.\n */\nexport const CodeHostProviderString = z.string().min(1);\n/** Decimal wire form for provider numeric ids (same shape as HookBigIntString; local to avoid an import cycle). */\nexport const CodeHostExternalId = z.string().regex(/^(?:0|[1-9]\\d*)$/);\n/**\n * Provider-qualified repository reference. `externalId` is the rename-stable\n * authority (GitHub numeric repo id / GitLab numeric project id); `path` is the\n * current display path (\"owner/repo\", \"group/subgroup/project\") and is never a\n * match key.\n */\nexport const CodeHostRepoRef = z.object({\n provider: CodeHostProviderString,\n externalId: CodeHostExternalId,\n path: z.string().min(1).optional()\n});\n/** Trusted ordinary reply coordinates; these carry no hook-run or formal-review authority. */\nexport const CodeHostReplyTarget = z.object({\n hookId: z.string().min(1),\n provider: CodeHostProviderString,\n // Pin a configurable provider's instance across delayed replies.\n host: z.string().url().optional(),\n subjectKind: z.enum(['issue', 'merge_request']).optional(),\n // GitHub uses owner/repo; GitLab and Gitea use the numeric scope of the effect lease.\n repo: z.string().min(1),\n // Gitea's REST path, distinct from the numeric lease scope.\n repoPath: z.string().min(1).optional(),\n number: z.number().int().positive(),\n reviewCommentId: z.string().min(1).optional(),\n // Acknowledge the triggering comment; publish the answer on the stable thread root below.\n triggerComment: z\n .object({ kind: z.enum(['issue_comment', 'review_comment', 'note']), id: z.string().min(1) })\n .optional(),\n reviewThreadRootCommentId: z.string().min(1).optional()\n});\n//# sourceMappingURL=code-host.js.map","/**\n * Git repo address helpers, shared by the CP (normalize on write) and the\n * daemon (defensive normalize before clone).\n *\n * STORAGE INVARIANT: `workspace.gitRepo` is persisted as a FULL cloneable git\n * address (e.g. `https://github.com/acme/infra`), never the `acme/infra`\n * shorthand a user may type. UIs shorten it back to `org/repo` for display\n * with `gitRepoLabel`.\n */\nimport { WORKSPACE_GIT_ORIGINS_ENV } from './consts.js';\n/** Scheme-full address: https://, ssh://, git://, file://, … */\nconst SCHEME_RE = /^[a-z][a-z0-9+.-]*:\\/\\//i;\n/** Any URI scheme, including non-hierarchical forms such as `ext::…`. */\nconst ANY_SCHEME_RE = /^[a-z][a-z0-9+.-]*:/i;\n/** scp-like ssh address: git@github.com:acme/infra(.git) */\nconst SCP_RE = /^[\\w.-]+@[\\w.-]+:(.+)$/;\nconst SCP_PARTS_RE = /^([\\w.-]+)@([\\w.-]+):(.+)$/;\nconst CONTROL_RE = /[\\u0000-\\u001f\\u007f]/;\n/** Wildcard allowlist entry: a policy containing it admits every valid clone origin. */\nexport const WORKSPACE_GIT_ANY_ORIGIN = '*';\n/** Ease-of-use daemon default: any valid https/ssh origin. An operator tightens by\n * stating exact origins — which REPLACE this — or disables remote Git with []. */\nexport const DEFAULT_WORKSPACE_GIT_ALLOWED_ORIGINS = [WORKSPACE_GIT_ANY_ORIGIN];\n/**\n * Hard cap on an untrusted repo reference. Real clone addresses are far under\n * this; the bound exists so no amount of caller-supplied text can turn\n * normalization into a long synchronous scan on the CP's single event loop.\n */\nexport const MAX_GIT_REPO_LENGTH = 512;\nexport class GitCloneUrlError extends Error {\n constructor(message) {\n super(message);\n this.name = 'GitCloneUrlError';\n }\n}\n/**\n * Strip trailing `/` without a backtracking regex.\n *\n * `s.replace(/\\/+$/, '')` looks anchored but is not: the engine retries the\n * greedy `+` from every offset, so a long run of slashes that does NOT end the\n * string costs O(n²). These helpers run inside request validation on the\n * control plane's single-threaded event loop, where that is a stall for every\n * tenant, not just the caller.\n */\nfunction trimTrailingSlashes(s) {\n let end = s.length;\n while (end > 0 && s.charCodeAt(end - 1) === 0x2f /* '/' */)\n end--;\n return end === s.length ? s : s.slice(0, end);\n}\n/**\n * Normalize a user-supplied repo reference into a full cloneable git address.\n * Idempotent — full addresses pass through unchanged.\n *\n * - `https://…` / `ssh://…` / `git://…` / `git@host:…` → as-is\n * - `github.com/acme/infra` (host-prefixed shorthand) → `https://github.com/acme/infra`\n * - `acme/infra` (bare org/repo) → `https://github.com/acme/infra`\n * - anything else (e.g. a local path) → as-is\n */\nexport function normalizeGitUrl(input) {\n const s = trimTrailingSlashes(input.trim());\n if (!s || SCHEME_RE.test(s) || SCP_RE.test(s))\n return s;\n const segments = s.split('/');\n // host-prefixed shorthand: first segment looks like a hostname (has a dot)\n if (segments.length >= 3 && segments[0].includes('.'))\n return `https://${s}`;\n // bare org/repo → GitHub by default\n if (segments.length === 2 && segments.every((p) => p.length > 0))\n return `https://github.com/${s}`;\n return s;\n}\nfunction invalidCloneUrl(message) {\n throw new GitCloneUrlError(message);\n}\nfunction hasLocalPathPrefix(value) {\n return (value.startsWith('/') ||\n value.startsWith('\\\\') ||\n value.startsWith('./') ||\n value.startsWith('../') ||\n value.startsWith('~/') ||\n /^[a-z]:[\\\\/]/i.test(value));\n}\n/**\n * Normalize and validate an untrusted git clone target.\n *\n * This shared codec remains host-agnostic so the CP can store repositories for\n * different daemon deployments. Only credential-free HTTPS and SSH transports\n * are accepted; the daemon applies its operator-owned exact-origin policy at\n * the execution boundary.\n */\nexport function normalizeGitCloneUrl(input) {\n // Bound FIRST: every check below scans the value, and this is the one entry\n // point untrusted repo text reaches. A real address is nowhere near the cap.\n if (input.length > MAX_GIT_REPO_LENGTH)\n invalidCloneUrl('git clone url is too long');\n if (CONTROL_RE.test(input))\n invalidCloneUrl('git clone url must not contain control characters');\n const s = trimTrailingSlashes(input.trim());\n if (!s)\n invalidCloneUrl('git clone url must not be empty');\n if (s.startsWith('-'))\n invalidCloneUrl('git clone url must not start with \"-\"');\n if (/\\s/.test(s))\n invalidCloneUrl('git clone url must not contain whitespace');\n // Git and WHATWG URLs disagree about whether a backslash terminates the\n // authority. Reject it outright so validation, redaction, and Git cannot\n // select different credentials or hosts.\n if (s.includes('\\\\'))\n invalidCloneUrl('git clone url must not contain backslashes');\n if (hasLocalPathPrefix(s))\n invalidCloneUrl('local git paths are not supported');\n const scp = SCP_PARTS_RE.exec(s);\n if (scp) {\n const path = scp[3];\n if (!path || path.startsWith('-') || path.includes('?') || path.includes('#')) {\n invalidCloneUrl('invalid scp-style git clone url');\n }\n return s;\n }\n // Reject ext::, file:, Windows drive-like values, and every other\n // non-hierarchical/unsupported scheme before shorthand normalization.\n if (ANY_SCHEME_RE.test(s) && !SCHEME_RE.test(s)) {\n invalidCloneUrl('git clone url must use https or ssh');\n }\n const normalized = normalizeGitUrl(s);\n if (!SCHEME_RE.test(normalized))\n invalidCloneUrl('git clone url must identify a remote repository');\n let url;\n try {\n url = new URL(normalized);\n }\n catch {\n invalidCloneUrl('git clone url must be a valid absolute URL');\n }\n if (url.protocol !== 'https:' && url.protocol !== 'ssh:') {\n invalidCloneUrl('git clone url must use https or ssh');\n }\n if (url.protocol === 'https:' && (url.username || url.password)) {\n invalidCloneUrl('https git clone url must not contain credentials');\n }\n if (url.protocol === 'ssh:' && url.password) {\n invalidCloneUrl('ssh git clone url must not contain a password');\n }\n if (normalized.includes('?') || normalized.includes('#')) {\n invalidCloneUrl('git clone url must not contain a query or fragment');\n }\n if (!url.hostname || !url.pathname || url.pathname === '/') {\n invalidCloneUrl('git clone url must identify a remote repository');\n }\n return normalized;\n}\nconst GITHUB_SKILL_COMPONENT_RE = /^[A-Za-z0-9_.-]+$/;\nconst GITHUB_SKILL_DOT_SEGMENT_RE = /\\/(?:\\.|%2e)(?:\\.|%2e)?(?:\\/|$)/i;\n/** Normalize the deliberately narrow source vocabulary supported by the\n * daemon's bounded GitHub archive acquisition path. Unlike generic workspaces,\n * skill sources cannot name arbitrary Git servers until an equally bounded\n * transport exists for them. */\nexport function normalizeGitHubSkillSource(input) {\n const normalized = normalizeGitCloneUrl(input);\n // WHATWG URL parsing collapses literal and percent-encoded dot segments.\n // Reject them before parsing so admission cannot silently reinterpret an\n // unsafe tree subdirectory as a different ref/path.\n if (GITHUB_SKILL_DOT_SEGMENT_RE.test(normalized)) {\n invalidCloneUrl('GitHub skill source must not contain dot path segments');\n }\n const scp = SCP_PARTS_RE.exec(normalized);\n if (scp) {\n if (scp[1] !== 'git' || scp[2].toLowerCase().replace(/\\.+$/, '') !== 'github.com') {\n invalidCloneUrl('skill source must use GitHub');\n }\n assertGitHubSkillRepositoryPath(scp[3], false, false);\n return normalized;\n }\n const url = new URL(normalized);\n const protocol = url.protocol;\n if (url.hostname.toLowerCase().replace(/\\.+$/, '') !== 'github.com' || url.port) {\n invalidCloneUrl('skill source must use canonical GitHub');\n }\n if (protocol === 'https:') {\n if (url.username || url.password)\n invalidCloneUrl('GitHub skill source must not contain credentials');\n }\n else if (protocol === 'ssh:') {\n if (url.username !== 'git' || url.password) {\n invalidCloneUrl('GitHub SSH skill source must use the git role');\n }\n }\n else {\n invalidCloneUrl('GitHub skill source must use https or ssh');\n }\n assertGitHubSkillRepositoryPath(url.pathname, protocol === 'https:', true);\n return normalized;\n}\nfunction assertGitHubSkillRepositoryPath(path, allowTree, urlPath) {\n // URL pathnames have exactly one structural leading slash; scp paths have\n // none. Do not trim an arbitrary run here: doing so would admit nonstandard\n // server-side absolute paths that the bounded daemon transport cannot safely\n // canonicalize to GitHub HTTPS.\n if (urlPath ? !path.startsWith('/') || path.startsWith('//') : path.startsWith('/') || path.startsWith('~')) {\n invalidCloneUrl('GitHub skill source must use a repository-relative path');\n }\n const encodedParts = (urlPath ? path.slice(1) : path).split('/');\n if (encodedParts.some((part) => !part)) {\n invalidCloneUrl('GitHub skill source path must not contain empty components');\n }\n let parts;\n try {\n parts = encodedParts.map((part) => decodeURIComponent(part));\n }\n catch {\n invalidCloneUrl('GitHub skill source contains malformed URL encoding');\n }\n if (parts.some((part) => !part || part.includes('/') || part.includes('\\\\') || CONTROL_RE.test(part))) {\n invalidCloneUrl('GitHub skill source contains an unsafe encoded path component');\n }\n if (parts.length < 2 || !parts[0] || !parts[1]) {\n invalidCloneUrl('GitHub skill source must identify owner/repository');\n }\n const owner = parts[0];\n const repo = parts[1].replace(/\\.git$/i, '');\n if (!GITHUB_SKILL_COMPONENT_RE.test(owner) || !GITHUB_SKILL_COMPONENT_RE.test(repo)) {\n invalidCloneUrl('GitHub skill source contains an invalid owner or repository');\n }\n if (parts.length === 2)\n return;\n if (!allowTree || parts.length < 4 || parts[2] !== 'tree' || parts.slice(3).some((part) => !part)) {\n invalidCloneUrl('GitHub skill source path must be owner/repository or owner/repository/tree/ref[/subdir]');\n }\n const ref = parts[3];\n if (ref.length > 256 || ref === '.' || ref === '..') {\n invalidCloneUrl('GitHub skill source contains an unsafe tree ref');\n }\n const subDir = parts.slice(4);\n if (subDir.join('/').length > 1_024 || subDir.some((part) => part === '.' || part === '..')) {\n invalidCloneUrl('GitHub skill source contains an unsafe tree subdirectory');\n }\n}\nfunction canonicalGitOrigin(protocol, hostname, port) {\n // A final DNS root dot does not select a different host. WHATWG already\n // does this for special schemes; reparse through HTTPS because SSH is a\n // non-special scheme and otherwise preserves case / percent-encoded IDNs.\n let host;\n try {\n host = new URL(`https://${hostname}`).hostname.toLowerCase().replace(/\\.+$/, '');\n }\n catch {\n invalidCloneUrl('git origin must identify a valid host');\n }\n if (!host)\n invalidCloneUrl('git origin must identify a host');\n const defaultPort = protocol === 'https:' ? '443' : '22';\n return `${protocol}//${host}${port && port !== defaultPort ? `:${port}` : ''}`;\n}\n/**\n * Normalize an operator-owned allowlist entry to an exact scheme/host/port\n * origin, or the bare `*` wildcard. Partial wildcards, paths, credentials,\n * queries, and fragments are not policy syntax: repository paths remain\n * tenant-selected within an allowed origin.\n */\nexport function normalizeWorkspaceGitOrigin(input) {\n if (CONTROL_RE.test(input))\n invalidCloneUrl('git origin must not contain control characters');\n const raw = input.trim();\n if (raw === WORKSPACE_GIT_ANY_ORIGIN)\n return WORKSPACE_GIT_ANY_ORIGIN;\n if (!raw || /\\s/.test(raw) || raw.includes('\\\\') || raw.includes('*')) {\n invalidCloneUrl('git origin must be an exact https or ssh origin');\n }\n let url;\n try {\n url = new URL(raw);\n }\n catch {\n invalidCloneUrl('git origin must be a valid absolute URL');\n }\n if (url.protocol !== 'https:' && url.protocol !== 'ssh:') {\n invalidCloneUrl('git origin must use https or ssh');\n }\n const authorityStart = raw.indexOf('://') + 3;\n const pathStart = raw.indexOf('/', authorityStart);\n const authority = raw.slice(authorityStart, pathStart < 0 ? raw.length : pathStart);\n const path = pathStart < 0 ? '' : raw.slice(pathStart);\n if (authority.includes('@') ||\n raw.includes('?') ||\n raw.includes('#') ||\n url.username ||\n url.password ||\n (path !== '' && path !== '/')) {\n invalidCloneUrl('git origin must not contain credentials, a path, query, or fragment');\n }\n return canonicalGitOrigin(url.protocol, url.hostname, url.port);\n}\n/** Return the canonical exact origin selected by a validated clone URL. */\nexport function workspaceGitOriginOf(input) {\n const normalized = normalizeGitCloneUrl(input);\n const scp = SCP_PARTS_RE.exec(normalized);\n if (scp)\n return canonicalGitOrigin('ssh:', scp[2], '');\n const url = new URL(normalized);\n return canonicalGitOrigin(url.protocol, url.hostname, url.port);\n}\n/**\n * Normalize a clone URL and require its exact scheme/host/port origin to be in\n * the deployment policy; a policy carrying `*` admits every valid origin. The\n * caller owns the list; tenant input can never add to it.\n */\nexport function normalizeAllowedWorkspaceGitUrl(input, allowedOrigins) {\n const normalized = normalizeGitCloneUrl(input);\n const allowed = new Set(allowedOrigins.map(normalizeWorkspaceGitOrigin));\n if (allowed.has(WORKSPACE_GIT_ANY_ORIGIN))\n return normalized;\n const origin = workspaceGitOriginOf(normalized);\n if (!allowed.has(origin)) {\n // The refusal names the origin and the operator knob: the reader is usually a tenant whose\n // fix is asking the daemon's operator, so the message must say what to ask for.\n invalidCloneUrl(`git clone origin ${origin} is not allowed by this daemon — its operator can allow it via security.workspaceGitAllowedOrigins in the daemon config (${WORKSPACE_GIT_ORIGINS_ENV} for a cluster member)`);\n }\n return normalized;\n}\nfunction withoutQueryOrFragment(value) {\n const query = value.indexOf('?');\n const fragment = value.indexOf('#');\n const cut = query < 0 ? fragment : fragment < 0 ? query : Math.min(query, fragment);\n return cut < 0 ? value : value.slice(0, cut);\n}\nfunction redactHierarchicalUrlFallback(value) {\n const match = /^([a-z][a-z0-9+.-]*:\\/\\/)([^/]*)(.*)$/i.exec(value);\n if (!match)\n return value;\n const [, prefix, authority, path] = match;\n const at = authority.lastIndexOf('@');\n if (at < 0)\n return value;\n const host = authority.slice(at + 1);\n if (prefix.toLowerCase() !== 'ssh://')\n return `${prefix}${host}${path}`;\n const username = authority.slice(0, at).split(':', 1)[0];\n return `${prefix}${username ? `${username}@` : ''}${host}${path}`;\n}\nfunction redactMalformedHierarchicalUrl(value) {\n const withoutTail = withoutQueryOrFragment(value);\n const redacted = redactHierarchicalUrlFallback(withoutTail);\n if (redacted !== withoutTail)\n return redacted;\n const authority = /^([a-z][a-z0-9+.-]*:\\/\\/)([^/]*)/i.exec(withoutTail);\n // An unparseable colon-bearing authority may be user:password or a malformed\n // host/port. Returning only the scheme is conservative, non-secret, and\n // deliberately non-cloneable.\n return authority?.[2]?.includes(':') ? authority[1] : redacted;\n}\n/**\n * Best-effort redaction for stored or historical git addresses.\n *\n * This function is deliberately total: response serialization and logging must\n * not fail merely because a legacy value is malformed. Existing shorthand\n * normalization is retained, HTTPS/other URL userinfo is removed, SSH keeps\n * its non-secret username while dropping a password, and query/fragment data\n * is discarded.\n */\nexport function redactGitUrlSecrets(input) {\n const normalized = normalizeGitUrl(input);\n if (SCP_RE.test(normalized) || !SCHEME_RE.test(normalized))\n return withoutQueryOrFragment(normalized);\n // Git and WHATWG disagree on backslashes, so never let WHATWG reserialize an\n // ambiguous password as apparent path text.\n if (normalized.includes('\\\\'))\n return redactMalformedHierarchicalUrl(normalized);\n try {\n const url = new URL(normalized);\n if (url.protocol === 'ssh:') {\n url.password = '';\n }\n else {\n url.username = '';\n url.password = '';\n }\n url.search = '';\n url.hash = '';\n return normalizeGitUrl(url.toString());\n }\n catch {\n // Malformed hierarchical URLs still receive a conservative string-level\n // redaction so the total fallback cannot echo obvious credentials.\n return redactMalformedHierarchicalUrl(normalized);\n }\n}\n/** Canonical GitHub clone URL for an App-backed workspace. The GitHub\n * installation grant is tied to owner/repo, so a caller-supplied host or extra\n * path must never select different content while retaining that authority. */\nexport function normalizeGithubRepoUrl(input) {\n const redacted = redactGitUrlSecrets(input);\n const hasGitSuffix = redacted.endsWith('.git');\n const label = gitRepoLabel(redacted);\n const parts = label.split('/');\n if (parts.length !== 2 || parts.some((part) => !part)) {\n invalidCloneUrl('github repository must be exactly owner/repo');\n }\n return normalizeGitCloneUrl(`${label}${hasGitSuffix ? '.git' : ''}`);\n}\n/**\n * Shorten a stored git address to the `org/repo` display form.\n * `https://github.com/acme/infra.git` / `git@github.com:acme/infra` → `acme/infra`.\n * Unrecognized inputs come back unchanged (minus a trailing `.git`).\n */\nexport function gitRepoLabel(gitRepo) {\n const s = trimTrailingSlashes(gitRepo.trim()).replace(/\\.git$/, '');\n const scp = SCP_RE.exec(s);\n if (scp)\n return scp[1].replace(/^\\/+/, '');\n const url = /^[a-z][a-z0-9+.-]*:\\/\\/[^/]+\\/(.+)$/i.exec(s);\n if (url)\n return url[1];\n const segments = s.split('/');\n if (segments.length >= 3 && segments[0].includes('.'))\n return segments.slice(1).join('/');\n return s;\n}\n//# sourceMappingURL=git-url.js.map"],"mappings":"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"}
1
+ {"version":3,"file":"git-url-nFiL6sQ7.js","names":["z.string","z.object","z.enum","z.number","z\n .object"],"sources":["../../protocol/dist/consts.js","../../protocol/dist/code-host.js","../../protocol/dist/git-url.js"],"sourcesContent":["/**\n * Cross-package wire + lifecycle constants shared by the daemon and the CLI.\n *\n * These are pure data (no zod, no runtime deps) so both `@agentconnect.md/cli`\n * and `@agentconnect.md/daemon` can import them without pulling in each other:\n * the daemon dials the CP with the subprotocol/path, and the CLI's login probe\n * dials the same way; both the daemon (planned-exit code) and the CLI (run\n * respawn shell + generated service units) must agree on the restart exit code.\n */\n/**\n * Cap on agent→agent hop depth (agent-collaboration §2.4/§4.5), shared by every\n * component that can admit an agent-to-agent edge.\n *\n * It lives here because send-message-routing-rework.md §4.1 requires ONE budget across\n * transports: \"the same `MAX_AGENT_CALL_HOPS`, whether it is a same-daemon internal\n * call, a relayed internal call, a direct-daemon platform mention, or a relayed platform\n * mention\". Three independent copies (daemon, relay agent-msg router, relay ingress)\n * could drift, and a relay that allowed one more hop than the daemon would let a relayed\n * chain outlive the budget an internal chain gets — a loop-safety hole that no single\n * package's tests would catch.\n *\n * The value is a runaway-loop backstop, not a conversation-length policy: a healthy\n * exchange terminates because the agents are done, and every extra hop only costs one\n * more turn. It was raised from 8 to 20 because 8 cut ordinary human-started relay games\n * short (a thread rooted in one human message affords exactly this many agent→agent\n * edges), while 20 is still far below anything a real collaboration needs and keeps a\n * genuine A↔B ping-pong bounded within seconds.\n */\nexport const MAX_AGENT_CALL_HOPS = 20;\n/**\n * Whether an agent-to-agent delivery has reached the exclusive hop boundary.\n *\n * A delivery at the boundary is not admitted: when the cap is 20, hop 19 is the\n * last agent turn that may run and its reply closes the autonomous exchange.\n * Keeping the comparison beside the shared constant prevents daemon and relay\n * admission paths from drifting on the boundary semantics.\n */\nexport function hasReachedAgentCallHopLimit(deliveryHopCount) {\n return deliveryHopCount >= MAX_AGENT_CALL_HOPS;\n}\n/** The daemon↔CP WebSocket subprotocol negotiated on `ClientTransport.dial`. */\nexport const CP_SUBPROTOCOL = 'agentconnect.v1';\n/** The CP mount path the daemon↔CP WebSocket connects to. */\nexport const CP_WS_PATH = '/daemon/ws';\n/** The relay route Google Chat posts interaction events to (google-chat-integration.md §2); the Setup Server publishes the same path as the app's HTTPS endpoint. */\nexport const GOOGLE_CHAT_EVENTS_PATH = '/googlechat/events';\n/** CP accepts metadata-only transcript activity invalidations from current daemons. */\nexport const SESSION_LIVE_TAIL_FEATURE = 'session-live-tail-v1';\n/** Daemon resolves workspace list/read/git-status requests against the isolated\n * worktree named by `sessionId` instead of silently falling back to primary. */\nexport const WORKSPACE_SESSION_READ_FEATURE = 'workspace-session-read-v1';\n/** Daemon resolves every workspace read/git frame against the secondary root named by `repo` —\n * the checkout under `<agentRoot>/repos/<owner>/<repo>`, or that root's per-session worktree. The\n * CP must check this before forwarding a `repo`-scoped request: an older daemon ignores the field\n * and would answer for the PRIMARY workspace, which is the wrong repository's files. */\nexport const WORKSPACE_REPO_SCOPE_FEATURE = 'workspace-repo-scope-v1';\n/** Daemon serves the console's git review reads — `workspace/gitdiff`,\n * `workspace/gitlog`, and per-file `additions`/`deletions` on `workspace/gitstatus`.\n * The CP must check this before sending either new frame: an older daemon ignores\n * an unknown frame silently, so the REQ would burn its whole retransmit budget and\n * then surface as an offline daemon. */\nexport const WORKSPACE_GIT_REVIEW_FEATURE = 'workspace-git-review-v1';\n/** Daemon serves the console's git WRITES — `workspace/gitstage`, `workspace/gitunstage`,\n * `workspace/gitcommit` and `workspace/gitpush`. Checked before sending, for the same reason\n * as the review feature: an older daemon ignores an unknown frame silently, so the REQ would\n * burn its retransmit budget and then read as an offline daemon. The console renders the write\n * controls as ABSENT (not inert) on a daemon without it. */\nexport const WORKSPACE_GIT_WRITE_FEATURE = 'workspace-git-write-v1';\n/** Daemon serves `workspace/gitmessage` — the AI commit-message draft, run on the AGENT's own\n * runtime. Separate from the write feature on purpose: it is not a write, and the console hides one\n * button (the wand) on a daemon without it while keeping stage/commit/push. Checked before sending,\n * like every other new frame: an older daemon ignores it silently and the REQ would burn its\n * retransmit budget before reading as an offline daemon. */\nexport const WORKSPACE_GIT_MESSAGE_FEATURE = 'workspace-git-message-v1';\n/** Daemon serves `task/list` — the console Tasks panel's read of one ACP session's background-task\n * lease. Checked before sending, like every other new frame: an older daemon ignores it silently, so\n * the REQ would burn its whole retransmit budget and then read as an offline daemon. The console\n * hides the Tasks tab on a daemon without it rather than showing a tab that can never answer. */\nexport const TASK_LIST_FEATURE = 'task-list-v1';\n/** Daemon serves `automerge/set` + `automerge/state` — the PR panel's merge-when-ready watcher, run at\n * the edge because GitHub's own auto-merge refuses every pull request that is not BLOCKED. Checked\n * before sending, like every other new frame: an older daemon ignores it silently, so the REQ would\n * burn its retransmit budget and then read as an offline daemon. The console disables the box on a\n * daemon without it rather than offering a control that can never arm. */\nexport const AUTO_MERGE_FEATURE = 'auto-merge-v1';\n/** Daemon honours `automerge/set.sessionId` — an isolated session's arm is watched in that session's own pod; an older daemon strips the field and arms in the agent pod, so the CP sends it only to one advertising this. */\nexport const AUTO_MERGE_SESSION_FEATURE = 'auto-merge-session-v1';\n/** Daemon serves `sandbox/keepalive` — an open console page holding a cluster agent's pod against the\n * idle sweep while its worktree is dirty or a merge-when-ready watcher is armed in it. Checked before\n * sending, like every other new frame: an older daemon ignores it silently, so the REQ would burn its\n * retransmit budget and then read as an offline daemon. A console that gets no answer simply stops\n * renewing — the sweep's own rules then apply, which is the pre-feature behaviour. */\nexport const SANDBOX_KEEP_ALIVE_FEATURE = 'sandbox-keep-alive-v1';\n/** Daemon serves `runtime/commands` — the slash commands an agent's ACP runtime advertised it can be\n * asked to run. Checked before sending: an older daemon ignores an unknown frame silently, so the REQ\n * would burn its retransmit budget and then read as an offline daemon. */\nexport const RUNTIME_COMMANDS_FEATURE = 'runtime-commands-v1';\n/** Daemon serves `agent/wake` — the console's \"start this agent's sandbox\" for a Files/Memory read.\n * Advertised only by a daemon that runs agents in cluster sandboxes: on any other daemon there is\n * nothing to wake, and the CP answers `unsupported` without sending a frame it would ignore. */\nexport const AGENT_WAKE_FEATURE = 'agent-wake-v1';\n/** Daemon honours `agent/wake.sessionId` — resume that session's own pod, never the agent's; an older daemon strips the field and wakes the agent pod, so the CP sends it only to one advertising this. */\nexport const SESSION_WAKE_FEATURE = 'session-wake-v1';\n/** Daemon serves `daemon/runtimes/probe` (the self-hosted console's \"refresh runtimes\"); a managed pool refreshes on its timer alone. */\nexport const RUNTIME_PROBE_FEATURE = 'runtime-probe-v1';\n/** Relay reports body-free GitHub feedback and daemon durably continues the linked session. */\nexport const PULL_REQUEST_FEEDBACK_FEATURE = 'pull-request-feedback-v1';\n/** CP keeps each relay's `rc/bot-credential-check` and aggregates the mark, and records `rc/bot-revoked` evidence; a relay sends neither to an older CP and revokes on an ambiguous answer there instead. */\nexport const BOT_CREDENTIAL_CHECK_FEATURE = 'bot-credential-check-v2';\n/** How long the CP must let ONE `workspace/gitmessage` REQ run before giving up, and it must send it\n * single-shot (`{ ackTimeoutMs: WORKSPACE_GIT_MESSAGE_BUDGET_MS, maxTries: 1 }`). The default 5s ack\n * timeout would retransmit an in-flight model pass four times: identical frame ids, so the daemon\n * joins them into one pass, but the CP would still fail the request while the answer was coming.\n * The daemon's own budget is strictly smaller, so the REP always wins this race. */\nexport const WORKSPACE_GIT_MESSAGE_BUDGET_MS = 75_000;\n/**\n * CP accepts the `event/session-purged` retention-GC receipt (#485) and marks the\n * session's stored metadata content-purged. Advertised by the CP in\n * `register/ok.serverFeatures`; a daemon that does not see it KEEPS its durable\n * receipts instead of emitting a frame an older CP would reject as\n * `UNKNOWN_FRAME` — the report is re-tried once the CP is upgraded.\n */\nexport const SESSION_PURGE_FEATURE = 'session-purge-v1';\n/**\n * CP accepts the correlated `event/session-sync` metadata snapshot. Daemons\n * keep one latest-wins snapshot per session until the CP acknowledges the\n * persistence commit; older CPs continue receiving best-effort `event/session`\n * events while the durable snapshot remains queued for a later upgrade.\n */\nexport const SESSION_METADATA_ACK_FEATURE = 'session-metadata-ack-v1';\n/** CP accepts `integration/revoked`, a daemon socket's explicit credential-lifecycle report; an older CP rejects the frame, so the daemon keeps its reports instead. */\nexport const INTEGRATION_REVOKED_FEATURE = 'integration-revoked-v1';\n/**\n * Daemon understands the `session/visibility` gate pushes + register-time\n * snapshot replay (session-visibility.md §5.1). Advertised by the daemon in\n * `RegisterReq.capabilities.features`; the CP gates all visibility pushes on\n * it so older daemons never see the frames.\n */\nexport const SESSION_VISIBILITY_FEATURE = 'session-visibility-v1';\n/** Daemon/runtime support private, session-scoped remote MCP headers and stable invocation ids. */\nexport const WEBCHAT_REMOTE_MCP_FEATURE = 'webchat_remote_mcp_v1';\n/**\n * Daemon understands multi-agent webchat conversations: `mentions`/`post` on\n * webchat turns, the transcript-only `context` op, agent-attributed\n * ack/output/done, and `rd/webchat-post` reply fan-out\n * (webchat-multi-agents.md). The CP refuses to CREATE a conversation with more\n * than one agent unless every selected agent's daemon advertises this.\n */\nexport const WEBCHAT_MULTI_AGENT_FEATURE = 'webchat_multi_agent_v1';\n/**\n * Cross-surface session continuation (webchat-cross-integration-continuation.md):\n * the daemon accepts `RdMsgWebchat.targetSessionId` and dispatches the browser\n * turn onto the target session's own local coordinates; a relay advertises the\n * same feature in `rc/register.features` when it preserves the field end to end.\n * The CP refuses to mint a session-targeted webchat token unless the owning\n * daemon AND every live relay advertise it (fail-closed rollout).\n */\nexport const WEBCHAT_SESSION_CONTINUATION_FEATURE = 'webchat_session_continuation_v1';\n/**\n * Hook-origin continuation (webchat-cross-integration-continuation.md §9): the\n * daemon accepts a `targetSessionId` naming a hook-origin session (GitHub,\n * GitLab, a generic webhook, a schedule) and runs the browser turn on it with\n * the console as the ONLY surface — no platform connection, no mirror. The CP\n * refuses to mint a session-targeted token for such a session unless the owning\n * daemon advertises this on top of {@link WEBCHAT_SESSION_CONTINUATION_FEATURE}.\n */\nexport const WEBCHAT_HOOK_CONTINUATION_FEATURE = 'webchat_hook_continuation_v1';\n/** Daemon and Control Plane support Organization Knowledge, Dream suggestions,\n * and immutable managed-skill bundle retrieval. */\nexport const ORGANIZATION_KNOWLEDGE_FEATURE = 'organization-knowledge-v1';\n/** Daemon currently admits staged Dream suggestion content reads and owner\n * review decisions. Omitted while the staged-content security hold is active. */\nexport const ORGANIZATION_SUGGESTION_REVIEW_FEATURE = 'organization-suggestion-review-v1';\n/** Daemon understands externally-bound Slack session audiences, including the\n * `external` visibility value and the stricter shared-memory exclusion bit. */\nexport const SLACK_SESSION_AUDIENCE_FEATURE = 'slack-session-audience-v1';\n/**\n * Daemon persists `AgentSpec.configRevision` and enforces the monotonic\n * comparison before applying a CP-owned snapshot\n * (organization-secrets-and-variables.md §7). Organization environment entries\n * rely on full-map replacement semantics, so a bound agent may only be placed on\n * a daemon that advertises this: without the fence, an older full snapshot that\n * completes late could reinstate a rotated or deleted value.\n */\nexport const AGENT_CONFIG_REVISION_FEATURE = 'agent-config-revision-v1';\n/** Auth-only recovery capability that permits CP to queue an offline daemon upgrade. */\nexport const DAEMON_BOOTSTRAP_UPGRADE_FEATURE = 'daemon-bootstrap-upgrade-v1';\n/** Frozen version of the auth-only bootstrap handshake. */\nexport const DAEMON_BOOTSTRAP_PROTOCOL_VERSION = 1;\n/**\n * Per-value ceiling for an environment variable or secret, shared by the agent\n * and organization surfaces so one entry can never be sized past what any\n * resolved `AgentSpec` could carry.\n *\n * 64 KiB is a quarter of `MAX_FRAME_BYTES`: generous for the real payloads\n * (a PEM block, a kubeconfig, a service-account JSON) while leaving room for the\n * rest of the spec. It is a per-VALUE guard only — the authoritative check is the\n * transaction-time admission budget over the whole resolved environment, which\n * the Control Plane applies per affected agent before persisting.\n */\nexport const MAX_ENVIRONMENT_VALUE_LENGTH = 64 * 1024;\n/**\n * Exit code a daemon uses for a PLANNED lifecycle exit (drain-then-exit on a\n * `daemon/restart` or `daemon/upgrade`, cli-daemon-split.md §6). It must be\n * non-zero: launchd's `KeepAlive.SuccessfulExit=false` only relaunches on a\n * non-zero exit, so exit 0 would leave the daemon down on macOS. Both\n * supervisors relaunch on it (systemd `Restart=always` covers any code). 75 is\n * EX_TEMPFAIL from sysexits(3) — \"temporary failure, retry\" — which reads\n * correctly for \"the daemon asked to be brought back up\".\n *\n * The CLI's `run` respawn shell (§6.1) also keys off this exact code to decide\n * whether to relaunch vs propagate the child's exit.\n */\nexport const RESERVED_RESTART_CODE = 75;\n/**\n * `AGENTCONNECT_SUPERVISOR` value a pool member runs under: Kubernetes, where the\n * kubelet takes the place of launchd/systemd AND of the CLI's version store.\n *\n * It supervises restart — `restartPolicy: Always` brings the container back after\n * {@link RESERVED_RESTART_CODE}, in place and in the same pod, which is the same\n * shape as a systemd process restart — but not upgrade: the running version is the\n * image, so only whoever owns the Deployment can change it.\n */\nexport const K8S_SUPERVISOR = 'k8s';\n/**\n * Audience the projected ServiceAccount token an in-cluster daemon authenticates with is\n * restricted to. The shim handshake run one hop up: a sandbox proves itself to the daemon\n * with a token scoped to `SHIM_TOKEN_AUDIENCE`, and here the daemon proves itself to the\n * control plane the same way. The audiences differ, so neither token is accepted at the\n * other end.\n *\n * This and {@link CLOUD_DAEMON_SA_NAME} are the two names the deployment that stamps them and\n * the control plane that checks them must agree on exactly. They live here rather than\n * being configured on each side because a constant kept in two places eventually holds two\n * values: a rename passes every build and every test, since each side stays self-consistent,\n * and fails only at runtime when a real daemon's token is rejected. One definition makes that\n * a compile error instead.\n */\nexport const CP_TOKEN_AUDIENCE = 'ac-control-plane';\n/**\n * ServiceAccount a pool member runs as, and the control plane's second check on a reviewed\n * token, so a later change cannot authenticate some other pod in the same namespace. A pool\n * member serves EVERY org, so it lives in the install's control namespace rather than in an\n * org namespace and no namespace⇒org mapping can name its org — the org is a per-connection\n * selector it declares in `auth`, which is safe precisely because this ServiceAccount is an\n * install-level principal. Shared for the same reason as {@link CP_TOKEN_AUDIENCE}.\n */\nexport const CLOUD_DAEMON_SA_NAME = 'ac-cloud-daemon';\n/**\n * DEFAULT ServiceAccount name for the usage-report collector — the principal allowed to\n * post `gateway`-source session usage to the control plane's batch ingress. A default, not\n * a contract: the collector is not this codebase's pod, so the deployment that runs it\n * names it and tells the control plane through `USAGE_COLLECTOR_SERVICE_ACCOUNT`; this\n * value is what an unconfigured control plane expects. The name stays separate from\n * {@link CLOUD_DAEMON_SA_NAME} on purpose whatever it is set to: both tokens carry\n * {@link CP_TOKEN_AUDIENCE}, so the ServiceAccount is what keeps a daemon's token from\n * writing usage and a collector's token from claiming a daemon identity.\n */\nexport const USAGE_COLLECTOR_SA_NAME = 'ac-usage-collector';\n/**\n * ServiceAccount the org-usage READER runs as — the principal allowed to read an org's\n * usage aggregate without a human's session visibility, so a settlement job can total a\n * closed period. A third name beside {@link USAGE_COLLECTOR_SA_NAME} because the two\n * capabilities are not the same risk: the collector's token can create spend records,\n * this one can only disclose them, and no workload should hold both by accident. They\n * are separate pods, so they are separate ServiceAccounts; if they ever merge, that is a\n * deliberate deployment decision and not something a shared constant did quietly.\n */\nexport const USAGE_READER_SA_NAME = 'ac-usage-reader';\n/** Where the deployment projects that token into the daemon pod, and where the daemon reads it\n * from. Not part of the verification, but the same two-sided agreement: the mounter and the\n * reader are both in this repo, so one definition beats a comment asking them to match. */\nexport const CP_IDENTITY_TOKEN_PATH = '/var/run/ac-cp-identity/token';\n/** Env var carrying the control plane's own WebSocket URL into an in-cluster daemon. The pod\n * has no config file to read it from, and a URL is not a secret. Same two-sided agreement as\n * the token path: the deployment sets it, the daemon reads it. */\nexport const CP_URL_ENV = 'AC_CP_URL';\n/** Env var switching an in-cluster daemon's usage reporting off, for a deployment that meters\n * upstream of the daemon and needs that plane to be the single writer. Same reason it is an\n * env and not a config key alone: an in-cluster daemon has no config file to carry one. Read\n * as a boolean — `false`/`0` disable, anything else leaves reporting on. */\nexport const USAGE_REPORTING_ENV = 'AC_USAGE_REPORTING';\n/** Env var carrying the operator's workspace clone-origin allowlist into an in-cluster daemon,\n * comma-separated. The policy is the OPERATOR's — a tenant can never widen it — and in a cluster\n * the deployment is who that is, with no config file to say it in. Absent leaves the daemon's own\n * default; a malformed entry is fatal rather than dropped, because a silently missing origin is a\n * clone refused later with no trace of why. */\nexport const WORKSPACE_GIT_ORIGINS_ENV = 'AC_WORKSPACE_GIT_ALLOWED_ORIGINS';\n/** A pool member's rollout generation (its pod-template hash), reported on register (frames/register.ts). */\nexport const POD_TEMPLATE_HASH_ENV = 'AC_POD_TEMPLATE_HASH';\n/** CP answers the `agent/exists` batch existence query the pool's orphan reconciler\n * asks before collecting a leaked sandbox object; a daemon that does not see it\n * skips the sweep rather than emit a frame an older CP rejects as `UNKNOWN_FRAME`. */\nexport const AGENT_EXISTS_FEATURE = 'agent-exists-v1';\n/** CP also answers `agent/exists` with WHERE each surviving agent is placed, so the pool's\n * reconciler can tell an agent that is gone from one that merely moved off this member set.\n * A daemon that does not see it omits `placedOnSetId` and sweeps on existence alone — the\n * pre-placement behavior, which collects strictly less and never more. */\nexport const AGENT_PLACEMENT_FEATURE = 'agent-placement-v1';\n// ── GitLab.com code-host features (gitlab-com-integration.md §17.3) ─────────\n// Each string is advertised only when its COMPLETE slice is live; the CP must\n// never place a GitLab-shaped workspace, grant, or hook on a peer without it.\n/** Daemon/relay serves the complete GitLab.com slice: hook normalization, credential\n * routing, poster, and (relay) signed ingress. Gate for placement, snapshot projection,\n * and rule broadcast — a GitLab-shaped value sent without it is frame-fatal downstream. */\nexport const GITLAB_COM_V1_FEATURE = 'gitlab-com-v1';\n/** The default value of the GitLab host axis (§24.1). An absent host on a replicated\n * agent spec, a compiled hook rule, trusted hook metadata, or a credential grant means\n * this — the default of one axis, never a separate mode. */\nexport const GITLAB_DEFAULT_BASE_URL = 'https://gitlab.com';\n/** Daemon/relay serves the self-managed-instance slice: the host carried per agent rather\n * than assumed (§24.4). Gates placement, snapshot projection, hook assignment, and hook\n * dispatch ONLY when the configured host is not `GITLAB_DEFAULT_BASE_URL`; on GitLab.com\n * nothing is gated. Fail-closed by omission — a peer without it never sees self-managed\n * work, so it cannot fall back to GitLab.com for it. */\nexport const GITLAB_INSTANCE_V1_FEATURE = 'gitlab-instance-v1';\n/** True when a carried host names an instance other than GitLab.com — the only case anything\n * gates (§24.4). Absent is the default value of the axis, so it is never self-managed. Lives\n * here, not in one consumer: the control plane, the relay, and the daemon all read it. */\nexport function isSelfManagedGitlabHost(host) {\n return host !== undefined && host !== GITLAB_DEFAULT_BASE_URL;\n}\n// ── Gitea code-host features (gitea-integration.md §11) ────────────────────\n/** Daemon/relay serves the complete Gitea slice: hook normalization, credential routing,\n * poster, and (relay) signed ingress. Gate for placement, spec projection, hook assignment,\n * and the relay's dispatch target, with the same fail-closed-by-omission semantics as the\n * GitLab bits. One string covers gitea.com and a self-hosted instance: a self-hosted\n * address is the same code path, so there is no separate instance feature. */\nexport const GITEA_V1_FEATURE = 'gitea-v1';\n/** The default value of the Gitea instance axis (§3). An absent host on a replicated agent\n * spec, a compiled hook rule, trusted hook metadata, or a credential grant means this — the\n * default of one axis, never a separate mode. */\nexport const GITEA_DEFAULT_BASE_URL = 'https://gitea.com';\n/** CP serves provider-qualified gitcred v2 request/grant fields. A daemon must not name a\n * provider before seeing this, and must reject a grant whose provider or numeric repository\n * id differs from its request (an older CP strips new fields and answers GitHub-shaped). */\nexport const GITCRED_PROVIDER_V2_FEATURE = 'gitcred-provider-v2';\n/** CP accepts an explicitly github-qualified credential request and echoes `provider: 'github'` back. */\nexport const GITCRED_GITHUB_V2_FEATURE = 'gitcred-github-v2';\n/** Provider-routed formal-review surface (`submitCodeReview` and the provider-neutral\n * review authorization/result frames). */\nexport const CODEHOST_REVIEW_V1_FEATURE = 'codehost-review-v1';\n/** Daemon decodes the host-neutral `mode: 'git'` workspace arm (git-workspace-model.md §8).\n * The CP dual-encodes: the `git` arm to daemons advertising this, the legacy\n * `github`/`gitlab` arms to everyone else — the new arm is frame-fatal without it. */\nexport const WORKSPACE_GIT_V1_FEATURE = 'workspace-git-v1';\n/** Informational status-note projection, each side attesting to its own half: the daemon renders\n * and updates the note (desired/result frame pair), the CP drives the ledger end to end including\n * the gitlab arm of `hook/start` that records the started head and opens `running`. */\nexport const CODEHOST_NOTE_PROJECTION_V1_FEATURE = 'codehost-note-projection-v1';\n/** CP resolves and revalidates approval-DM recipients (`agent/approval-route`,\n * slack-approval-dm.md §4.2). A daemon must not send that REQ before seeing this:\n * a new request type is frame-fatal to an older CP. */\nexport const APPROVAL_DM_ROUTE_V1_FEATURE = 'approval-dm-route-v1';\n/** CP mints the §14.2 broker effect lease — `purpose: 'gitlab_effect'` on a gitcred v2 request,\n * authorized by the agent's GitLab workspace binding or an enabled gitlab hook and clamped by the\n * grant's echoed access. A daemon must not name that purpose before seeing this: a new enum value\n * in a daemon→CP frame is frame-fatal to an older CP (§17.3), not a stripped field. */\nexport const GITLAB_EFFECT_V1_FEATURE = 'gitlab-effect-v1';\n/** Session executors (session-executors.md §6): the CP serves `executor/candidates` and relays `executor/prepare` and `executor/release`, a daemon answers the relayed ones; neither end sends an executor frame to a peer without it. */\nexport const SESSION_EXECUTORS_V1_FEATURE = 'session-executors-v1';\n/** How long the CP lets ONE relayed `executor/prepare` (or `executor/release`) run, single-shot: above the pool's 90 s pod-readiness budget, which an executor's own preparation budget must stay under. */\nexport const EXECUTOR_PREPARE_RELAY_BUDGET_MS = 120_000;\n/** CP serves the `memory/store` family (memory-evolution.md §3.2.1); a daemon refuses a `control-plane` home without it. */\nexport const AGENT_MEMORY_STORE_V1_FEATURE = 'agent-memory-store-v1';\n//# sourceMappingURL=consts.js.map","// ⚠️ NO RELATIVE IMPORTS — a bundler compiles this from source; web's protocol-imports.leaf.test.ts enforces it.\nimport { z } from 'zod';\n/**\n * Code-host provider identity (gitlab-com-integration.md §8.1).\n *\n * Code hosts are NOT chat platforms: they have no connection, no ingress plugin\n * identity, and no manifest entry. What they share is a provider-qualified\n * NUMERIC repository identity — paths and clone URLs are mutable display hints,\n * so authorization, hook matching, and run effects must key on\n * `(provider, externalId)` and never on a display path.\n */\nexport const CODE_HOST_PROVIDERS = ['github', 'gitlab', 'gitea'];\nexport function isCodeHostProvider(value) {\n return typeof value === 'string' && CODE_HOST_PROVIDERS.includes(value);\n}\n/** The generic inbound endpoint — the one hook kind that is not a code host. */\nexport const GENERIC_HOOK_KIND = 'webhook';\n/**\n * Inbound-trigger source vocabulary: the generic endpoint plus one entry per code\n * host. Deriving it from `CODE_HOST_PROVIDERS` is what makes a new host a\n * compile-time event — every `Record<HookKind, …>` mapping over this union stops\n * type-checking until it is given an entry, so no host can silently inherit the\n * generic webhook rendering the way GitLab once did.\n */\nexport const HOOK_KINDS = [GENERIC_HOOK_KIND, ...CODE_HOST_PROVIDERS];\n/** A hook kind that identifies a code host, as opposed to the generic endpoint. */\nexport function isCodeHostHookKind(kind) {\n return kind !== GENERIC_HOOK_KIND;\n}\n/**\n * Wire form for provider fields — an OPEN string, mirroring the KNOWN_PLATFORMS\n * precedent (frames/route.ts): zod rejects unknown enum values wholesale, and an\n * unknown provider inside a known frame must degrade per-value, never make the\n * whole frame undecodable on an older peer. Consumers gate on\n * `isCodeHostProvider` and fail closed per value.\n */\nexport const CodeHostProviderString = z.string().min(1);\n/** Decimal wire form for provider numeric ids (same shape as HookBigIntString; local to avoid an import cycle). */\nexport const CodeHostExternalId = z.string().regex(/^(?:0|[1-9]\\d*)$/);\n/**\n * Provider-qualified repository reference. `externalId` is the rename-stable\n * authority (GitHub numeric repo id / GitLab numeric project id); `path` is the\n * current display path (\"owner/repo\", \"group/subgroup/project\") and is never a\n * match key.\n */\nexport const CodeHostRepoRef = z.object({\n provider: CodeHostProviderString,\n externalId: CodeHostExternalId,\n path: z.string().min(1).optional()\n});\n/** Trusted ordinary reply coordinates; these carry no hook-run or formal-review authority. */\nexport const CodeHostReplyTarget = z.object({\n hookId: z.string().min(1),\n provider: CodeHostProviderString,\n // Pin a configurable provider's instance across delayed replies.\n host: z.string().url().optional(),\n subjectKind: z.enum(['issue', 'merge_request']).optional(),\n // GitHub uses owner/repo; GitLab and Gitea use the numeric scope of the effect lease.\n repo: z.string().min(1),\n // Gitea's REST path, distinct from the numeric lease scope.\n repoPath: z.string().min(1).optional(),\n number: z.number().int().positive(),\n reviewCommentId: z.string().min(1).optional(),\n // Acknowledge the triggering comment; publish the answer on the stable thread root below.\n triggerComment: z\n .object({ kind: z.enum(['issue_comment', 'review_comment', 'note']), id: z.string().min(1) })\n .optional(),\n reviewThreadRootCommentId: z.string().min(1).optional()\n});\n//# sourceMappingURL=code-host.js.map","/**\n * Git repo address helpers, shared by the CP (normalize on write) and the\n * daemon (defensive normalize before clone).\n *\n * STORAGE INVARIANT: `workspace.gitRepo` is persisted as a FULL cloneable git\n * address (e.g. `https://github.com/acme/infra`), never the `acme/infra`\n * shorthand a user may type. UIs shorten it back to `org/repo` for display\n * with `gitRepoLabel`.\n */\nimport { WORKSPACE_GIT_ORIGINS_ENV } from './consts.js';\n/** Scheme-full address: https://, ssh://, git://, file://, … */\nconst SCHEME_RE = /^[a-z][a-z0-9+.-]*:\\/\\//i;\n/** Any URI scheme, including non-hierarchical forms such as `ext::…`. */\nconst ANY_SCHEME_RE = /^[a-z][a-z0-9+.-]*:/i;\n/** scp-like ssh address: git@github.com:acme/infra(.git) */\nconst SCP_RE = /^[\\w.-]+@[\\w.-]+:(.+)$/;\nconst SCP_PARTS_RE = /^([\\w.-]+)@([\\w.-]+):(.+)$/;\nconst CONTROL_RE = /[\\u0000-\\u001f\\u007f]/;\n/** Wildcard allowlist entry: a policy containing it admits every valid clone origin. */\nexport const WORKSPACE_GIT_ANY_ORIGIN = '*';\n/** Ease-of-use daemon default: any valid https/ssh origin. An operator tightens by\n * stating exact origins — which REPLACE this — or disables remote Git with []. */\nexport const DEFAULT_WORKSPACE_GIT_ALLOWED_ORIGINS = [WORKSPACE_GIT_ANY_ORIGIN];\n/**\n * Hard cap on an untrusted repo reference. Real clone addresses are far under\n * this; the bound exists so no amount of caller-supplied text can turn\n * normalization into a long synchronous scan on the CP's single event loop.\n */\nexport const MAX_GIT_REPO_LENGTH = 512;\nexport class GitCloneUrlError extends Error {\n constructor(message) {\n super(message);\n this.name = 'GitCloneUrlError';\n }\n}\n/**\n * Strip trailing `/` without a backtracking regex.\n *\n * `s.replace(/\\/+$/, '')` looks anchored but is not: the engine retries the\n * greedy `+` from every offset, so a long run of slashes that does NOT end the\n * string costs O(n²). These helpers run inside request validation on the\n * control plane's single-threaded event loop, where that is a stall for every\n * tenant, not just the caller.\n */\nfunction trimTrailingSlashes(s) {\n let end = s.length;\n while (end > 0 && s.charCodeAt(end - 1) === 0x2f /* '/' */)\n end--;\n return end === s.length ? s : s.slice(0, end);\n}\n/**\n * Normalize a user-supplied repo reference into a full cloneable git address.\n * Idempotent — full addresses pass through unchanged.\n *\n * - `https://…` / `ssh://…` / `git://…` / `git@host:…` → as-is\n * - `github.com/acme/infra` (host-prefixed shorthand) → `https://github.com/acme/infra`\n * - `acme/infra` (bare org/repo) → `https://github.com/acme/infra`\n * - anything else (e.g. a local path) → as-is\n */\nexport function normalizeGitUrl(input) {\n const s = trimTrailingSlashes(input.trim());\n if (!s || SCHEME_RE.test(s) || SCP_RE.test(s))\n return s;\n const segments = s.split('/');\n // host-prefixed shorthand: first segment looks like a hostname (has a dot)\n if (segments.length >= 3 && segments[0].includes('.'))\n return `https://${s}`;\n // bare org/repo → GitHub by default\n if (segments.length === 2 && segments.every((p) => p.length > 0))\n return `https://github.com/${s}`;\n return s;\n}\nfunction invalidCloneUrl(message) {\n throw new GitCloneUrlError(message);\n}\nfunction hasLocalPathPrefix(value) {\n return (value.startsWith('/') ||\n value.startsWith('\\\\') ||\n value.startsWith('./') ||\n value.startsWith('../') ||\n value.startsWith('~/') ||\n /^[a-z]:[\\\\/]/i.test(value));\n}\n/**\n * Normalize and validate an untrusted git clone target.\n *\n * This shared codec remains host-agnostic so the CP can store repositories for\n * different daemon deployments. Only credential-free HTTPS and SSH transports\n * are accepted; the daemon applies its operator-owned exact-origin policy at\n * the execution boundary.\n */\nexport function normalizeGitCloneUrl(input) {\n // Bound FIRST: every check below scans the value, and this is the one entry\n // point untrusted repo text reaches. A real address is nowhere near the cap.\n if (input.length > MAX_GIT_REPO_LENGTH)\n invalidCloneUrl('git clone url is too long');\n if (CONTROL_RE.test(input))\n invalidCloneUrl('git clone url must not contain control characters');\n const s = trimTrailingSlashes(input.trim());\n if (!s)\n invalidCloneUrl('git clone url must not be empty');\n if (s.startsWith('-'))\n invalidCloneUrl('git clone url must not start with \"-\"');\n if (/\\s/.test(s))\n invalidCloneUrl('git clone url must not contain whitespace');\n // Git and WHATWG URLs disagree about whether a backslash terminates the\n // authority. Reject it outright so validation, redaction, and Git cannot\n // select different credentials or hosts.\n if (s.includes('\\\\'))\n invalidCloneUrl('git clone url must not contain backslashes');\n if (hasLocalPathPrefix(s))\n invalidCloneUrl('local git paths are not supported');\n const scp = SCP_PARTS_RE.exec(s);\n if (scp) {\n const path = scp[3];\n if (!path || path.startsWith('-') || path.includes('?') || path.includes('#')) {\n invalidCloneUrl('invalid scp-style git clone url');\n }\n return s;\n }\n // Reject ext::, file:, Windows drive-like values, and every other\n // non-hierarchical/unsupported scheme before shorthand normalization.\n if (ANY_SCHEME_RE.test(s) && !SCHEME_RE.test(s)) {\n invalidCloneUrl('git clone url must use https or ssh');\n }\n const normalized = normalizeGitUrl(s);\n if (!SCHEME_RE.test(normalized))\n invalidCloneUrl('git clone url must identify a remote repository');\n let url;\n try {\n url = new URL(normalized);\n }\n catch {\n invalidCloneUrl('git clone url must be a valid absolute URL');\n }\n if (url.protocol !== 'https:' && url.protocol !== 'ssh:') {\n invalidCloneUrl('git clone url must use https or ssh');\n }\n if (url.protocol === 'https:' && (url.username || url.password)) {\n invalidCloneUrl('https git clone url must not contain credentials');\n }\n if (url.protocol === 'ssh:' && url.password) {\n invalidCloneUrl('ssh git clone url must not contain a password');\n }\n if (normalized.includes('?') || normalized.includes('#')) {\n invalidCloneUrl('git clone url must not contain a query or fragment');\n }\n if (!url.hostname || !url.pathname || url.pathname === '/') {\n invalidCloneUrl('git clone url must identify a remote repository');\n }\n return normalized;\n}\nconst GITHUB_SKILL_COMPONENT_RE = /^[A-Za-z0-9_.-]+$/;\nconst GITHUB_SKILL_DOT_SEGMENT_RE = /\\/(?:\\.|%2e)(?:\\.|%2e)?(?:\\/|$)/i;\n/** Normalize the deliberately narrow source vocabulary supported by the\n * daemon's bounded GitHub archive acquisition path. Unlike generic workspaces,\n * skill sources cannot name arbitrary Git servers until an equally bounded\n * transport exists for them. */\nexport function normalizeGitHubSkillSource(input) {\n const normalized = normalizeGitCloneUrl(input);\n // WHATWG URL parsing collapses literal and percent-encoded dot segments.\n // Reject them before parsing so admission cannot silently reinterpret an\n // unsafe tree subdirectory as a different ref/path.\n if (GITHUB_SKILL_DOT_SEGMENT_RE.test(normalized)) {\n invalidCloneUrl('GitHub skill source must not contain dot path segments');\n }\n const scp = SCP_PARTS_RE.exec(normalized);\n if (scp) {\n if (scp[1] !== 'git' || scp[2].toLowerCase().replace(/\\.+$/, '') !== 'github.com') {\n invalidCloneUrl('skill source must use GitHub');\n }\n assertGitHubSkillRepositoryPath(scp[3], false, false);\n return normalized;\n }\n const url = new URL(normalized);\n const protocol = url.protocol;\n if (url.hostname.toLowerCase().replace(/\\.+$/, '') !== 'github.com' || url.port) {\n invalidCloneUrl('skill source must use canonical GitHub');\n }\n if (protocol === 'https:') {\n if (url.username || url.password)\n invalidCloneUrl('GitHub skill source must not contain credentials');\n }\n else if (protocol === 'ssh:') {\n if (url.username !== 'git' || url.password) {\n invalidCloneUrl('GitHub SSH skill source must use the git role');\n }\n }\n else {\n invalidCloneUrl('GitHub skill source must use https or ssh');\n }\n assertGitHubSkillRepositoryPath(url.pathname, protocol === 'https:', true);\n return normalized;\n}\nfunction assertGitHubSkillRepositoryPath(path, allowTree, urlPath) {\n // URL pathnames have exactly one structural leading slash; scp paths have\n // none. Do not trim an arbitrary run here: doing so would admit nonstandard\n // server-side absolute paths that the bounded daemon transport cannot safely\n // canonicalize to GitHub HTTPS.\n if (urlPath ? !path.startsWith('/') || path.startsWith('//') : path.startsWith('/') || path.startsWith('~')) {\n invalidCloneUrl('GitHub skill source must use a repository-relative path');\n }\n const encodedParts = (urlPath ? path.slice(1) : path).split('/');\n if (encodedParts.some((part) => !part)) {\n invalidCloneUrl('GitHub skill source path must not contain empty components');\n }\n let parts;\n try {\n parts = encodedParts.map((part) => decodeURIComponent(part));\n }\n catch {\n invalidCloneUrl('GitHub skill source contains malformed URL encoding');\n }\n if (parts.some((part) => !part || part.includes('/') || part.includes('\\\\') || CONTROL_RE.test(part))) {\n invalidCloneUrl('GitHub skill source contains an unsafe encoded path component');\n }\n if (parts.length < 2 || !parts[0] || !parts[1]) {\n invalidCloneUrl('GitHub skill source must identify owner/repository');\n }\n const owner = parts[0];\n const repo = parts[1].replace(/\\.git$/i, '');\n if (!GITHUB_SKILL_COMPONENT_RE.test(owner) || !GITHUB_SKILL_COMPONENT_RE.test(repo)) {\n invalidCloneUrl('GitHub skill source contains an invalid owner or repository');\n }\n if (parts.length === 2)\n return;\n if (!allowTree || parts.length < 4 || parts[2] !== 'tree' || parts.slice(3).some((part) => !part)) {\n invalidCloneUrl('GitHub skill source path must be owner/repository or owner/repository/tree/ref[/subdir]');\n }\n const ref = parts[3];\n if (ref.length > 256 || ref === '.' || ref === '..') {\n invalidCloneUrl('GitHub skill source contains an unsafe tree ref');\n }\n const subDir = parts.slice(4);\n if (subDir.join('/').length > 1_024 || subDir.some((part) => part === '.' || part === '..')) {\n invalidCloneUrl('GitHub skill source contains an unsafe tree subdirectory');\n }\n}\nfunction canonicalGitOrigin(protocol, hostname, port) {\n // A final DNS root dot does not select a different host. WHATWG already\n // does this for special schemes; reparse through HTTPS because SSH is a\n // non-special scheme and otherwise preserves case / percent-encoded IDNs.\n let host;\n try {\n host = new URL(`https://${hostname}`).hostname.toLowerCase().replace(/\\.+$/, '');\n }\n catch {\n invalidCloneUrl('git origin must identify a valid host');\n }\n if (!host)\n invalidCloneUrl('git origin must identify a host');\n const defaultPort = protocol === 'https:' ? '443' : '22';\n return `${protocol}//${host}${port && port !== defaultPort ? `:${port}` : ''}`;\n}\n/**\n * Normalize an operator-owned allowlist entry to an exact scheme/host/port\n * origin, or the bare `*` wildcard. Partial wildcards, paths, credentials,\n * queries, and fragments are not policy syntax: repository paths remain\n * tenant-selected within an allowed origin.\n */\nexport function normalizeWorkspaceGitOrigin(input) {\n if (CONTROL_RE.test(input))\n invalidCloneUrl('git origin must not contain control characters');\n const raw = input.trim();\n if (raw === WORKSPACE_GIT_ANY_ORIGIN)\n return WORKSPACE_GIT_ANY_ORIGIN;\n if (!raw || /\\s/.test(raw) || raw.includes('\\\\') || raw.includes('*')) {\n invalidCloneUrl('git origin must be an exact https or ssh origin');\n }\n let url;\n try {\n url = new URL(raw);\n }\n catch {\n invalidCloneUrl('git origin must be a valid absolute URL');\n }\n if (url.protocol !== 'https:' && url.protocol !== 'ssh:') {\n invalidCloneUrl('git origin must use https or ssh');\n }\n const authorityStart = raw.indexOf('://') + 3;\n const pathStart = raw.indexOf('/', authorityStart);\n const authority = raw.slice(authorityStart, pathStart < 0 ? raw.length : pathStart);\n const path = pathStart < 0 ? '' : raw.slice(pathStart);\n if (authority.includes('@') ||\n raw.includes('?') ||\n raw.includes('#') ||\n url.username ||\n url.password ||\n (path !== '' && path !== '/')) {\n invalidCloneUrl('git origin must not contain credentials, a path, query, or fragment');\n }\n return canonicalGitOrigin(url.protocol, url.hostname, url.port);\n}\n/** Return the canonical exact origin selected by a validated clone URL. */\nexport function workspaceGitOriginOf(input) {\n const normalized = normalizeGitCloneUrl(input);\n const scp = SCP_PARTS_RE.exec(normalized);\n if (scp)\n return canonicalGitOrigin('ssh:', scp[2], '');\n const url = new URL(normalized);\n return canonicalGitOrigin(url.protocol, url.hostname, url.port);\n}\n/**\n * Normalize a clone URL and require its exact scheme/host/port origin to be in\n * the deployment policy; a policy carrying `*` admits every valid origin. The\n * caller owns the list; tenant input can never add to it.\n */\nexport function normalizeAllowedWorkspaceGitUrl(input, allowedOrigins) {\n const normalized = normalizeGitCloneUrl(input);\n const allowed = new Set(allowedOrigins.map(normalizeWorkspaceGitOrigin));\n if (allowed.has(WORKSPACE_GIT_ANY_ORIGIN))\n return normalized;\n const origin = workspaceGitOriginOf(normalized);\n if (!allowed.has(origin)) {\n // The refusal names the origin and the operator knob: the reader is usually a tenant whose\n // fix is asking the daemon's operator, so the message must say what to ask for.\n invalidCloneUrl(`git clone origin ${origin} is not allowed by this daemon — its operator can allow it via security.workspaceGitAllowedOrigins in the daemon config (${WORKSPACE_GIT_ORIGINS_ENV} for a cluster member)`);\n }\n return normalized;\n}\nfunction withoutQueryOrFragment(value) {\n const query = value.indexOf('?');\n const fragment = value.indexOf('#');\n const cut = query < 0 ? fragment : fragment < 0 ? query : Math.min(query, fragment);\n return cut < 0 ? value : value.slice(0, cut);\n}\nfunction redactHierarchicalUrlFallback(value) {\n const match = /^([a-z][a-z0-9+.-]*:\\/\\/)([^/]*)(.*)$/i.exec(value);\n if (!match)\n return value;\n const [, prefix, authority, path] = match;\n const at = authority.lastIndexOf('@');\n if (at < 0)\n return value;\n const host = authority.slice(at + 1);\n if (prefix.toLowerCase() !== 'ssh://')\n return `${prefix}${host}${path}`;\n const username = authority.slice(0, at).split(':', 1)[0];\n return `${prefix}${username ? `${username}@` : ''}${host}${path}`;\n}\nfunction redactMalformedHierarchicalUrl(value) {\n const withoutTail = withoutQueryOrFragment(value);\n const redacted = redactHierarchicalUrlFallback(withoutTail);\n if (redacted !== withoutTail)\n return redacted;\n const authority = /^([a-z][a-z0-9+.-]*:\\/\\/)([^/]*)/i.exec(withoutTail);\n // An unparseable colon-bearing authority may be user:password or a malformed\n // host/port. Returning only the scheme is conservative, non-secret, and\n // deliberately non-cloneable.\n return authority?.[2]?.includes(':') ? authority[1] : redacted;\n}\n/**\n * Best-effort redaction for stored or historical git addresses.\n *\n * This function is deliberately total: response serialization and logging must\n * not fail merely because a legacy value is malformed. Existing shorthand\n * normalization is retained, HTTPS/other URL userinfo is removed, SSH keeps\n * its non-secret username while dropping a password, and query/fragment data\n * is discarded.\n */\nexport function redactGitUrlSecrets(input) {\n const normalized = normalizeGitUrl(input);\n if (SCP_RE.test(normalized) || !SCHEME_RE.test(normalized))\n return withoutQueryOrFragment(normalized);\n // Git and WHATWG disagree on backslashes, so never let WHATWG reserialize an\n // ambiguous password as apparent path text.\n if (normalized.includes('\\\\'))\n return redactMalformedHierarchicalUrl(normalized);\n try {\n const url = new URL(normalized);\n if (url.protocol === 'ssh:') {\n url.password = '';\n }\n else {\n url.username = '';\n url.password = '';\n }\n url.search = '';\n url.hash = '';\n return normalizeGitUrl(url.toString());\n }\n catch {\n // Malformed hierarchical URLs still receive a conservative string-level\n // redaction so the total fallback cannot echo obvious credentials.\n return redactMalformedHierarchicalUrl(normalized);\n }\n}\n/** Canonical GitHub clone URL for an App-backed workspace. The GitHub\n * installation grant is tied to owner/repo, so a caller-supplied host or extra\n * path must never select different content while retaining that authority. */\nexport function normalizeGithubRepoUrl(input) {\n const redacted = redactGitUrlSecrets(input);\n const hasGitSuffix = redacted.endsWith('.git');\n const label = gitRepoLabel(redacted);\n const parts = label.split('/');\n if (parts.length !== 2 || parts.some((part) => !part)) {\n invalidCloneUrl('github repository must be exactly owner/repo');\n }\n return normalizeGitCloneUrl(`${label}${hasGitSuffix ? '.git' : ''}`);\n}\n/**\n * Shorten a stored git address to the `org/repo` display form.\n * `https://github.com/acme/infra.git` / `git@github.com:acme/infra` → `acme/infra`.\n * Unrecognized inputs come back unchanged (minus a trailing `.git`).\n */\nexport function gitRepoLabel(gitRepo) {\n const s = trimTrailingSlashes(gitRepo.trim()).replace(/\\.git$/, '');\n const scp = SCP_RE.exec(s);\n if (scp)\n return scp[1].replace(/^\\/+/, '');\n const url = /^[a-z][a-z0-9+.-]*:\\/\\/[^/]+\\/(.+)$/i.exec(s);\n if (url)\n return url[1];\n const segments = s.split('/');\n if (segments.length >= 3 && segments[0].includes('.'))\n return segments.slice(1).join('/');\n return s;\n}\n//# sourceMappingURL=git-url.js.map"],"mappings":"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"}
package/dist/release.json CHANGED
@@ -1 +1 @@
1
- {"runtimeSandboxImage":"ghcr.io/agentconnect-md/runtime-sandbox-full:v1.61.0-rc.194"}
1
+ {"runtimeSandboxImage":"ghcr.io/agentconnect-md/runtime-sandbox-full:v1.61.0-rc.195"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agentconnect.md/daemon",
3
- "version": "1.61.0-rc.194",
3
+ "version": "1.61.0-rc.195",
4
4
  "description": "AgentConnect daemon — edge message + agent execution unit",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {