Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 52 additions & 0 deletions dag/extdeps/github/pulls.dag
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,13 @@ data extdeps_external_authority_anchor: ExternalAuthority = ExternalAuthority {
}
}

data github_cli_pull_merge_authority: ExternalAuthority = ExternalAuthority {
uri: Uri {
scheme: Https
locator: "cli.github.com/manual/gh_pr_merge"
}
}

type PullRequestState = Open | Closed

type ReviewState = Pending | Commented | Approved | ChangesRequested | Dismissed
Expand Down Expand Up @@ -122,6 +129,51 @@ type IssueComment {
created_at: Timestamp
}

data github_cli_exact_head_merge_note: String = "GitHub CLI documents --match-head-commit as the commit SHA the pull-request head must match to allow merge and --squash as the repository's squash strategy. The operation exposes termination as data because a nonzero result is a domain refusal the landing workflow must render and receipt, not an interpreter crash. It deliberately carries no --admin and no --auto: landing workflow v1 performs the one operator-clicked merge already admitted by the dashboard summary; merge-queue enqueue remains a later realization."

service github.CliPulls {
operation ListOpenJson {
input { repo: NonEmptyStr }
output {
success: Bool from "exit_success"
stdout: String from "stdout"
stderr: String from "stderr"
}
readonly
transport shell {
argv: [
"gh", "pr", "list",
"--repo", "{repo}",
"--state", "open",
"--limit", "1000",
"--json", "number,title,url,headRefName,headRefOid,isDraft,state",
]
}
}

operation SquashMergeExactHead {
input {
repo: NonEmptyStr
pull_number: Int
expected_head: CommitSha
}
output {
success: Bool from "exit_success"
exit_code: Int from "exit_code"
stdout: String from "stdout"
stderr: String from "stderr"
}
transport shell {
argv: [
"gh", "pr", "merge", "{pull_number}",
"--repo", "{repo}",
"--squash",
"--match-head-commit", "{expected_head}",
]
}
}
}

service github.Pulls {
config {
endpoint: default_api_base
Expand Down
50 changes: 50 additions & 0 deletions dag/extdeps/session_dashboard.dag
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
module extdeps.session_dashboard

import std.types { Bool, NonEmptyStr, String }
import v2.std.optional { Present, Absent }
import extdeps.external_authority { ExternalAuthority }
import extdeps.uri { Uri, Https }

data extdeps_external_authority_anchor: ExternalAuthority = ExternalAuthority {
uri: Uri { scheme: Https, locator: "github.com/gunb-ai/session-dashboard" }
}

type DashboardBaseUrl = NonEmptyStr where brand("DashboardBaseUrl")
type DashboardRelativePath = NonEmptyStr where brand("DashboardRelativePath")

data session_dashboard_tls_note: String = "The session dashboard endpoint named by DASHBOARD_URL is an operator-local HTTPS service with a locally issued certificate (the live session value fails public-root verification). GetFromDashboard admits only a validated HTTPS DashboardBaseUrl plus a root-relative DashboardRelativePath, composes them inside the transport, and still requires curl --fail: HTTP errors are refusals. The tailnet/server placement supplies reachability authorization; this operation must not be reused as a general Internet HTTP client. This landing-dashboard scaffold is owned by the gunbc served-dashboard lane. Dissolve when the dashboard publishes its CA path or the services share an in-process read interface."

fn dashboard_base_url(raw: String) -> DashboardBaseUrl? {
if starts_with(s: raw, prefix: "https://")
&& !string_contains(s: raw, pattern: "?")
&& !string_contains(s: raw, pattern: "#") {
Present { value: raw as DashboardBaseUrl }
} else {
none
}
}

fn dashboard_relative_path(raw: String) -> DashboardRelativePath? {
if starts_with(s: raw, prefix: "/")
&& !starts_with(s: raw, prefix: "//")
&& !string_contains(s: raw, pattern: "://") {
Present { value: raw as DashboardRelativePath }
} else {
none
}
}

service session_dashboard.Api {
operation GetFromDashboard {
input { base: DashboardBaseUrl, path: DashboardRelativePath }
output {
body: String from "stdout"
success: Bool from "exit_success"
stderr: String from "stderr"
}
readonly
transport shell {
argv: ["curl", "--fail-with-body", "-sS", "--insecure", "{base}{path}"]
}
}
}
Loading
Loading