UNPKG

@struktoai/mirage-core

Version:

A Unified Virtual Filesystem For AI Agents

100 lines • 4.75 kB
// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. ========= // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // ========= Copyright 2026 @ Strukto.AI All Rights Reserved. ========= import { githubPages } from "./paginate.js"; import { decodeBase64 } from "../../utils/base64.js"; const WORKFLOW_LOOKUP = 100; // gh reads every page of a run's jobs, however many there are. const ALL_JOBS = Number.MAX_SAFE_INTEGER; const ENC = new TextEncoder(); function actions(ref, tail) { return `/repos/${ref.owner}/${ref.repo}/actions/${tail}`; } export async function resolveWorkflow(transport, ref, workflow) { if (/^\d+$/.test(workflow) || workflow.endsWith('.yml') || workflow.endsWith('.yaml')) { return workflow; } const rows = await listWorkflows(transport, ref, WORKFLOW_LOOKUP); const wanted = workflow.toLowerCase(); const match = rows.find((row) => (typeof row.name === 'string' ? row.name.toLowerCase() : '') === wanted); if (match === undefined) throw new Error(`could not find any workflows named ${workflow}`); const id = match.id; return typeof id === 'number' || typeof id === 'string' ? String(id) : ''; } export async function listRuns(transport, ref, params, limit, workflow) { const tail = workflow === undefined ? 'runs' : `workflows/${encodeURIComponent(await resolveWorkflow(transport, ref, workflow))}/runs`; return githubPages(transport, actions(ref, tail), { params, limit, key: 'workflow_runs' }); } export function getRun(transport, ref, runId) { return transport.get(actions(ref, `runs/${String(runId)}`)); } export function rerun(transport, ref, runId, suffix, body) { return transport.request('POST', actions(ref, `runs/${String(runId)}/${suffix}`), body); } export function rerunJob(transport, ref, jobId, debug) { return transport.request('POST', actions(ref, `jobs/${String(jobId)}/rerun`), { enable_debug_logging: debug, }); } export function listWorkflows(transport, ref, limit, include) { return githubPages(transport, actions(ref, 'workflows'), { limit, key: 'workflows', ...(include === undefined ? {} : { include }), }); } export async function getWorkflow(transport, ref, workflow) { const selector = await resolveWorkflow(transport, ref, workflow); return transport.get(actions(ref, `workflows/${encodeURIComponent(selector)}`)); } export async function dispatchWorkflow(transport, ref, workflow, body) { const selector = await resolveWorkflow(transport, ref, workflow); return transport.request('POST', actions(ref, `workflows/${encodeURIComponent(selector)}/dispatches`), body); } /** A run's jobs, every page of them, as `gh run view` reads them. */ export function listJobs(transport, ref, runId) { return githubPages(transport, actions(ref, `runs/${String(runId)}/jobs`), { limit: ALL_JOBS, key: 'jobs', }); } // A body a transport handed back as bytes, text, or nothing. function bytesOf(data) { if (data instanceof Uint8Array) return data; if (data instanceof ArrayBuffer) return new Uint8Array(data); return typeof data === 'string' ? ENC.encode(data) : new Uint8Array(0); } /** A completed run's log archive, the zip GitHub ships its logs as. */ export async function runLogArchive(transport, ref, runId) { return bytesOf(await transport.get(actions(ref, `runs/${String(runId)}/logs`))); } /** One job's whole log, where gh turns when the archive holds none for it. */ export async function jobLog(transport, ref, jobId) { return bytesOf(await transport.get(actions(ref, `jobs/${String(jobId)}/logs`))); } /** * A workflow file's bytes as the repository holds it, at `gitRef` or the * default branch: the one read `gh workflow view --yaml` makes. */ export async function workflowContent(transport, ref, path, gitRef) { const params = gitRef === undefined || gitRef === '' ? undefined : { ref: gitRef }; const data = (await transport.get(`/repos/${ref.owner}/${ref.repo}/contents/${path}`, params)); const content = data?.content; return typeof content === 'string' ? decodeBase64(content.replace(/\s/g, '')) : new Uint8Array(0); } //# sourceMappingURL=actions.js.map