@marcusrbrown/infra 0.13.1 → 0.13.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +11965 -0
- package/package.json +7 -3
- package/src/__snapshots__/cli.test.ts.snap +0 -219
- package/src/__test__/mcp-ctx-fixture.test.ts +0 -108
- package/src/__test__/mcp-ctx-fixture.ts +0 -104
- package/src/cli.test.ts +0 -66
- package/src/cli.ts +0 -43
- package/src/commands/cliproxy/config.test.ts +0 -475
- package/src/commands/cliproxy/config.ts +0 -238
- package/src/commands/cliproxy/deploy.test.ts +0 -181
- package/src/commands/cliproxy/deploy.ts +0 -157
- package/src/commands/cliproxy/host.test.ts +0 -73
- package/src/commands/cliproxy/host.ts +0 -31
- package/src/commands/cliproxy/index.ts +0 -21
- package/src/commands/cliproxy/keys.test.ts +0 -326
- package/src/commands/cliproxy/keys.ts +0 -201
- package/src/commands/cliproxy/login.test.ts +0 -415
- package/src/commands/cliproxy/login.ts +0 -131
- package/src/commands/cliproxy/models.test.ts +0 -592
- package/src/commands/cliproxy/models.ts +0 -237
- package/src/commands/cliproxy/open.test.ts +0 -132
- package/src/commands/cliproxy/open.ts +0 -78
- package/src/commands/cliproxy/setup/gh.test.ts +0 -218
- package/src/commands/cliproxy/setup/gh.ts +0 -250
- package/src/commands/cliproxy/setup/preview.test.ts +0 -159
- package/src/commands/cliproxy/setup/preview.ts +0 -41
- package/src/commands/cliproxy/setup/prompts.test.ts +0 -58
- package/src/commands/cliproxy/setup/prompts.ts +0 -99
- package/src/commands/cliproxy/setup/providers.test.ts +0 -245
- package/src/commands/cliproxy/setup/providers.ts +0 -136
- package/src/commands/cliproxy/setup/smoke-test.test.ts +0 -821
- package/src/commands/cliproxy/setup/smoke-test.ts +0 -223
- package/src/commands/cliproxy/setup/templates.test.ts +0 -357
- package/src/commands/cliproxy/setup/templates.ts +0 -145
- package/src/commands/cliproxy/setup/validation.test.ts +0 -567
- package/src/commands/cliproxy/setup/validation.ts +0 -209
- package/src/commands/cliproxy/setup/workflow-analyzer.test.ts +0 -363
- package/src/commands/cliproxy/setup/workflow-analyzer.ts +0 -136
- package/src/commands/cliproxy/setup.test.ts +0 -2366
- package/src/commands/cliproxy/setup.ts +0 -809
- package/src/commands/cliproxy/shared.test.ts +0 -118
- package/src/commands/cliproxy/shared.ts +0 -84
- package/src/commands/cliproxy/status.test.ts +0 -1157
- package/src/commands/cliproxy/status.ts +0 -597
- package/src/commands/dashboard/deploy.test.ts +0 -215
- package/src/commands/dashboard/deploy.ts +0 -135
- package/src/commands/dashboard/host.test.ts +0 -79
- package/src/commands/dashboard/host.ts +0 -33
- package/src/commands/dashboard/index.ts +0 -13
- package/src/commands/dashboard/logs.test.ts +0 -317
- package/src/commands/dashboard/logs.ts +0 -180
- package/src/commands/dashboard/status.test.ts +0 -708
- package/src/commands/dashboard/status.ts +0 -293
- package/src/commands/gateway/backup.test.ts +0 -426
- package/src/commands/gateway/backup.ts +0 -205
- package/src/commands/gateway/deploy.test.ts +0 -491
- package/src/commands/gateway/deploy.ts +0 -173
- package/src/commands/gateway/host.test.ts +0 -89
- package/src/commands/gateway/host.ts +0 -33
- package/src/commands/gateway/index.ts +0 -17
- package/src/commands/gateway/logs.test.ts +0 -263
- package/src/commands/gateway/logs.ts +0 -160
- package/src/commands/gateway/restore.test.ts +0 -650
- package/src/commands/gateway/restore.ts +0 -308
- package/src/commands/gateway/status.test.ts +0 -755
- package/src/commands/gateway/status.ts +0 -255
- package/src/commands/keeweb/deploy.test.ts +0 -177
- package/src/commands/keeweb/deploy.ts +0 -191
- package/src/commands/keeweb/index.ts +0 -11
- package/src/commands/keeweb/open.test.ts +0 -54
- package/src/commands/keeweb/open.ts +0 -30
- package/src/commands/keeweb/status.test.ts +0 -509
- package/src/commands/keeweb/status.ts +0 -359
- package/src/commands/mcp.test.ts +0 -260
- package/src/commands/mcp.ts +0 -58
- package/src/commands/status.test.ts +0 -222
- package/src/commands/status.ts +0 -161
- package/src/commands/umami/deploy.test.ts +0 -202
- package/src/commands/umami/deploy.ts +0 -132
- package/src/commands/umami/host.test.ts +0 -79
- package/src/commands/umami/host.ts +0 -33
- package/src/commands/umami/index.ts +0 -13
- package/src/commands/umami/logs.test.ts +0 -191
- package/src/commands/umami/logs.ts +0 -163
- package/src/commands/umami/status.test.ts +0 -633
- package/src/commands/umami/status.ts +0 -285
- package/src/commands/vpn/client.test.ts +0 -949
- package/src/commands/vpn/client.ts +0 -467
- package/src/commands/vpn/deploy.test.ts +0 -208
- package/src/commands/vpn/deploy.ts +0 -143
- package/src/commands/vpn/host.test.ts +0 -89
- package/src/commands/vpn/host.ts +0 -36
- package/src/commands/vpn/index.ts +0 -15
- package/src/commands/vpn/logs.test.ts +0 -234
- package/src/commands/vpn/logs.ts +0 -136
- package/src/commands/vpn/peers.test.ts +0 -478
- package/src/commands/vpn/shared.test.ts +0 -454
- package/src/commands/vpn/shared.ts +0 -170
- package/src/commands/vpn/status.test.ts +0 -142
- package/src/commands/vpn/status.ts +0 -78
- package/src/conventions.test.ts +0 -1180
- package/src/lib/action-ctx.ts +0 -25
- package/src/lib/known-hosts.test.ts +0 -192
- package/src/lib/known-hosts.ts +0 -76
- package/src/lib/redact.ts +0 -21
- package/src/lib/ssh-identity.test.ts +0 -134
- package/src/lib/ssh-identity.ts +0 -76
- /package/{src/resources/known_hosts → dist/known_hosts-tk724cp0.} +0 -0
|
@@ -1,136 +0,0 @@
|
|
|
1
|
-
import type {CommandResult} from './gh'
|
|
2
|
-
|
|
3
|
-
import {runGh} from './gh'
|
|
4
|
-
|
|
5
|
-
// ─── Types ────────────────────────────────────────────────────────────────────
|
|
6
|
-
|
|
7
|
-
export type FroBotWorkflowCheck =
|
|
8
|
-
| {kind: 'missing'}
|
|
9
|
-
| {kind: 'unreachable'; reason: string}
|
|
10
|
-
| {kind: 'no-agent-step'}
|
|
11
|
-
| {
|
|
12
|
-
kind: 'analyzed'
|
|
13
|
-
stepsWithGaps: readonly {stepOrdinal: number; missingInputs: readonly string[]}[]
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
// ─── Constants ────────────────────────────────────────────────────────────────
|
|
17
|
-
|
|
18
|
-
// github-token and prompt are intentionally excluded from this check:
|
|
19
|
-
// github-token is harness-agnostic (PAT wiring, not secret-routing) and prompt is
|
|
20
|
-
// workflow-defined (the user's prompt body, not a harness default).
|
|
21
|
-
//
|
|
22
|
-
// NOTE: `enable-omo: true` is NOT a required input.
|
|
23
|
-
// For proxy-routed providers configured via OPENCODE_CONFIG.provider.<name>.options.baseURL,
|
|
24
|
-
// the fro-bot/agent action honors auth.json directly (regardless of oMo state).
|
|
25
|
-
// Source: fro-bot/agent@v0.44.3+ action.yaml lines 99-104; verified by librarian 2026-05-25.
|
|
26
|
-
const REQUIRED_OPENCODE_INPUTS = ['auth-json', 'opencode-config', 'model'] as const
|
|
27
|
-
type RequiredOpencodeInput = (typeof REQUIRED_OPENCODE_INPUTS)[number]
|
|
28
|
-
|
|
29
|
-
// ─── Helpers ──────────────────────────────────────────────────────────────────
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* Slice the workflow content into one entry per `fro-bot/agent` step. Handles
|
|
33
|
-
* both the `- name:\n uses: ...` and `- uses: ...` step shapes. Returns an
|
|
34
|
-
* empty array if no fro-bot/agent step is present.
|
|
35
|
-
*
|
|
36
|
-
* Step-scoped slicing prevents false-passes where a same-named input key in a
|
|
37
|
-
* sibling step (strategy.matrix, custom actions, reusable workflow with:
|
|
38
|
-
* blocks) could mask a genuine gap in fro-bot/agent's wiring.
|
|
39
|
-
*/
|
|
40
|
-
export function findFroBotAgentStepBodies(content: string): {stepOrdinal: number; body: string}[] {
|
|
41
|
-
const bodies: {stepOrdinal: number; body: string}[] = []
|
|
42
|
-
const pattern = /^(\s*(?:-\s+)?)uses:\s*fro-bot\/agent@/gm
|
|
43
|
-
|
|
44
|
-
for (const match of content.matchAll(pattern)) {
|
|
45
|
-
if (match.index === undefined || match[1] === undefined) continue
|
|
46
|
-
|
|
47
|
-
const stepBodyIndent = match[1].length
|
|
48
|
-
const dashIndent = Math.max(0, stepBodyIndent - 2)
|
|
49
|
-
const lines = content.slice(match.index).split('\n')
|
|
50
|
-
const stepLines: string[] = [lines[0] ?? '']
|
|
51
|
-
|
|
52
|
-
for (let index = 1; index < lines.length; index += 1) {
|
|
53
|
-
const line = lines[index] ?? ''
|
|
54
|
-
if (!line.trim()) {
|
|
55
|
-
stepLines.push(line)
|
|
56
|
-
continue
|
|
57
|
-
}
|
|
58
|
-
const firstNonSpace = line.search(/\S/)
|
|
59
|
-
if (firstNonSpace === dashIndent && line.trimStart().startsWith('-')) break
|
|
60
|
-
if (firstNonSpace < dashIndent) break
|
|
61
|
-
stepLines.push(line)
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
bodies.push({stepOrdinal: bodies.length + 1, body: stepLines.join('\n')})
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
return bodies
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
// ─── Exports ──────────────────────────────────────────────────────────────────
|
|
71
|
-
|
|
72
|
-
export function analyzeFroBotWorkflow(workflowContent: string): FroBotWorkflowCheck {
|
|
73
|
-
const steps = findFroBotAgentStepBodies(workflowContent)
|
|
74
|
-
|
|
75
|
-
if (steps.length === 0) {
|
|
76
|
-
return {kind: 'no-agent-step'}
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
const stepsWithGaps = steps
|
|
80
|
-
.map(step => ({
|
|
81
|
-
stepOrdinal: step.stepOrdinal,
|
|
82
|
-
missingInputs: REQUIRED_OPENCODE_INPUTS.filter(input => {
|
|
83
|
-
const inputPattern = new RegExp(String.raw`^\s+${input}:`, 'm')
|
|
84
|
-
return !inputPattern.test(step.body)
|
|
85
|
-
}),
|
|
86
|
-
}))
|
|
87
|
-
.filter(step => step.missingInputs.length > 0)
|
|
88
|
-
|
|
89
|
-
return {kind: 'analyzed', stepsWithGaps}
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
/**
|
|
93
|
-
* Extracted pure helper: turn a `gh api /repos/.../contents/<file>` result into
|
|
94
|
-
* a FroBotWorkflowCheck. Separated from checkFroBotWorkflow so tests can exercise
|
|
95
|
-
* the 404-vs-transport-error logic without mocking Bun.spawn.
|
|
96
|
-
*/
|
|
97
|
-
export function interpretGhContentResult(result: CommandResult): FroBotWorkflowCheck {
|
|
98
|
-
if (result.exitCode === 0) {
|
|
99
|
-
return analyzeFroBotWorkflow(result.stdout)
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
// gh prints `gh: Not Found (HTTP 404)` on 404; anything else is auth/network/5xx.
|
|
103
|
-
if (/HTTP 404/.test(result.stderr)) {
|
|
104
|
-
return {kind: 'missing'}
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
return {
|
|
108
|
-
kind: 'unreachable',
|
|
109
|
-
reason: result.stderr.trim() || `gh api exited with code ${result.exitCode}`,
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
export async function checkFroBotWorkflow(repo: string): Promise<FroBotWorkflowCheck> {
|
|
114
|
-
const result = await runGh([
|
|
115
|
-
'api',
|
|
116
|
-
'--header',
|
|
117
|
-
'Accept: application/vnd.github.raw',
|
|
118
|
-
`/repos/${repo}/contents/.github/workflows/fro-bot.yaml`,
|
|
119
|
-
])
|
|
120
|
-
|
|
121
|
-
return interpretGhContentResult(result)
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
// Snippet uses 10-space indent to match the canonical `with:` block depth
|
|
125
|
-
// in marcusrbrown/infra/.github/workflows/fro-bot.yaml, so users can paste
|
|
126
|
-
// directly under their step's `with:` key without re-indenting.
|
|
127
|
-
export function formatWorkflowSnippet(missingInputs: readonly string[]): string {
|
|
128
|
-
/* eslint-disable no-template-curly-in-string -- GitHub Actions expression syntax, not JS template literals */
|
|
129
|
-
const inputMap = {
|
|
130
|
-
'auth-json': 'auth-json: ${{ secrets.OPENCODE_AUTH_JSON }}',
|
|
131
|
-
'opencode-config': 'opencode-config: ${{ secrets.OPENCODE_CONFIG }}',
|
|
132
|
-
model: 'model: ${{ vars.FRO_BOT_MODEL }}',
|
|
133
|
-
} satisfies Record<RequiredOpencodeInput, string>
|
|
134
|
-
/* eslint-enable no-template-curly-in-string */
|
|
135
|
-
return missingInputs.map(input => ` ${(inputMap as Record<string, string>)[input]}`).join('\n')
|
|
136
|
-
}
|