@foundation0/api 1.0.1 → 1.1.0

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/README.md CHANGED
@@ -1,6 +1,6 @@
1
- # F0 MCP Server
1
+ # example-org MCP Server
2
2
 
3
- Install and register the F0 MCP server with the MCP-enabled agent/tooling you use.
3
+ Install and register the example-org MCP server with the MCP-enabled agent/tooling you use.
4
4
 
5
5
  ## 1) Install
6
6
 
@@ -23,7 +23,7 @@ The runnable entrypoint is `f0-mcp` (available from `bin` when installed globall
23
23
  The server supports:
24
24
 
25
25
  - `GITEA_HOST` (recommended, required by git-backed tools)
26
- - `F0_GITEA_HOST` (fallback host variable)
26
+ - `FALLBACK_GITEA_HOST` (fallback host variable)
27
27
  - `GITEA_TOKEN` (for authenticated actions)
28
28
  - `MCP_TOOLS_PREFIX` (or `--tools-prefix`) to namespace tools in clients
29
29
 
@@ -37,7 +37,7 @@ Useful defaults:
37
37
  ### A) `.codex/config.toml`
38
38
 
39
39
  ```toml
40
- [mcp_servers.f0]
40
+ [mcp_servers.example]
41
41
  command = "bun"
42
42
  args = ["x", "@foundation0/api", "f0-mcp"]
43
43
  enabled = true
@@ -45,7 +45,7 @@ startup_timeout_ms = 20_000
45
45
  env = {
46
46
  GITEA_HOST = "https://gitea.example.com",
47
47
  GITEA_TOKEN = "your-token",
48
- MCP_TOOLS_PREFIX = "f0"
48
+ MCP_TOOLS_PREFIX = "example"
49
49
  }
50
50
  ```
51
51
 
@@ -61,9 +61,9 @@ args = []
61
61
  ```json
62
62
  {
63
63
  "mcpServers": {
64
- "f0": {
64
+ "example": {
65
65
  "command": "bun",
66
- "args": ["x", "@foundation0/api", "f0-mcp", "--tools-prefix", "f0"],
66
+ "args": ["x", "@foundation0/api", "f0-mcp", "--tools-prefix", "example"],
67
67
  "env": {
68
68
  "GITEA_HOST": "https://gitea.example.com",
69
69
  "GITEA_TOKEN": "your-token"
@@ -82,7 +82,7 @@ Use the same command/args/env block in your MCP server configuration area:
82
82
  ```json
83
83
  {
84
84
  "command": "bun",
85
- "args": ["x", "@foundation0/api", "f0-mcp", "--tools-prefix", "f0"],
85
+ "args": ["x", "@foundation0/api", "f0-mcp", "--tools-prefix", "example"],
86
86
  "env": {
87
87
  "GITEA_HOST": "https://gitea.example.com",
88
88
  "GITEA_TOKEN": "your-token"
@@ -105,7 +105,7 @@ Add environment variables for host/token and optional `MCP_TOOLS_PREFIX`.
105
105
  f0-mcp --help
106
106
 
107
107
  # examples
108
- f0-mcp --tools-prefix=f0 --server-name=my-f0
108
+ f0-mcp --tools-prefix=example --server-name=my-example
109
109
  f0-mcp --tools-prefix api --server-version 1.2.3
110
110
  ```
111
111
 
package/agents.ts CHANGED
@@ -23,12 +23,25 @@ export interface AgentLoadResult {
23
23
  loaded: unknown
24
24
  }
25
25
 
26
+ export interface AgentRunResult {
27
+ agentName: string
28
+ exitCode: number
29
+ }
30
+
31
+ export interface AgentCreateResult {
32
+ agentName: string
33
+ agentRoot: string
34
+ createdPaths: string[]
35
+ }
36
+
26
37
  interface ActiveConfigInput {
27
38
  path: string
28
39
  required: boolean
29
40
  }
30
41
 
31
- const CLI_NAME = 'f0'
42
+ const CLI_NAME = 'example'
43
+ const AGENT_INITIAL_VERSION = 'v0.0.1'
44
+ const DEFAULT_SKILL_NAME = 'coding-standards'
32
45
  const VERSION_RE = 'v?\\d+(?:\\.\\d+){2,}'
33
46
  const VERSION_RE_CORE = `(?:${VERSION_RE})`
34
47
  const VERSION_WITH_EXT_RE = new RegExp(`^(.+)\\.(${VERSION_RE})\\.([A-Za-z][A-Za-z0-9_-]*)$`)
@@ -36,13 +49,16 @@ const VERSION_ONLY_RE = new RegExp(`^(.+)\\.(${VERSION_RE})$`)
36
49
  const PRIORITIZED_EXTS = ['.md', '.json', '.yaml', '.yml', '.ts', '.js', '.txt']
37
50
 
38
51
  export function usage(): string {
39
- return `Usage:\n ${CLI_NAME} agents <agent-name> <file-path> --set-active\n ${CLI_NAME} agents --list\n ${CLI_NAME} agents <agent-name> load\n\n` +
40
- `Examples:\n ${CLI_NAME} agents coder /system/boot.v0.0.1 --set-active\n ${CLI_NAME} agents coder /system/boot --set-active --latest\n ${CLI_NAME} agents coder /skills/coding-standards.v0.0.1 --set-active\n ${CLI_NAME} agents --list\n` +
52
+ return `Usage:\n ${CLI_NAME} agents create <agent-name>\n ${CLI_NAME} agents <agent-name> <file-path> --set-active\n ${CLI_NAME} agents --list\n ${CLI_NAME} agents <agent-name> load\n ${CLI_NAME} agents <agent-name> run [codex-args...]\n\n` +
53
+ `Examples:\n ${CLI_NAME} agents create reviewer\n ${CLI_NAME} agents coder /system/boot.v0.0.1 --set-active\n ${CLI_NAME} agents coder /system/boot --set-active --latest\n ${CLI_NAME} agents coder /skills/coding-standards.v0.0.1 --set-active\n ${CLI_NAME} agents --list\n` +
41
54
  ` ${CLI_NAME} agents coder load\n` +
55
+ ` ${CLI_NAME} agents coder run --model gpt-5\n` +
42
56
  `\n` +
43
57
  `file-path is relative to the agent root (leading slash required).\n` +
44
58
  `Use --latest to resolve /file-name to the latest version.\n` +
45
- `The active file created is [file].active.<ext>.\n`
59
+ `The active file created is [file].active.<ext>.\n` +
60
+ `Use "run" to start codex with developer_instructions from system/prompt.ts.\n` +
61
+ `Set EXAMPLE_CODEX_BIN to pin a specific codex binary.\n`
46
62
  }
47
63
 
48
64
  export function resolveAgentsRoot(processRoot: string = process.cwd()): string {
@@ -76,6 +92,200 @@ export function listAgents(processRoot: string = process.cwd()): string[] {
76
92
  .sort((a, b) => a.localeCompare(b))
77
93
  }
78
94
 
95
+ function normalizeAgentName(agentName: string): string {
96
+ if (!agentName || typeof agentName !== 'string') {
97
+ throw new Error('agent-name is required.')
98
+ }
99
+
100
+ const normalized = agentName.trim()
101
+ if (!normalized) {
102
+ throw new Error('agent-name is required.')
103
+ }
104
+
105
+ if (normalized.startsWith('-')) {
106
+ throw new Error(`Invalid agent-name: ${agentName}`)
107
+ }
108
+
109
+ if (normalized === '.' || normalized === '..' || normalized.includes('/') || normalized.includes('\\')) {
110
+ throw new Error(`Invalid agent-name: ${agentName}`)
111
+ }
112
+
113
+ if (!/^[A-Za-z0-9][A-Za-z0-9._-]*$/.test(normalized)) {
114
+ throw new Error(`Invalid agent-name: ${agentName}`)
115
+ }
116
+
117
+ return normalized
118
+ }
119
+
120
+ function titleCaseAgentName(agentName: string): string {
121
+ return agentName
122
+ .split(/[-_]+/)
123
+ .filter(Boolean)
124
+ .map((part) => `${part.slice(0, 1).toUpperCase()}${part.slice(1)}`)
125
+ .join(' ')
126
+ }
127
+
128
+ function buildBootDocument(agentName: string): string {
129
+ const title = titleCaseAgentName(agentName) || agentName
130
+ return `# ${title} Agent Boot (${AGENT_INITIAL_VERSION})
131
+
132
+ You are the \`${agentName}\` agent.
133
+
134
+ ## Role
135
+ - Follow the active workflow and execute scoped tasks.
136
+ - Keep outputs concise, concrete, and implementation-focused.
137
+ - Avoid changing unrelated files or behavior.
138
+
139
+ ## Startup Sequence
140
+ 1. Read active boot/workflow docs and enabled skills.
141
+ 2. Confirm scope and constraints before changes.
142
+ 3. Apply the smallest safe change set.
143
+ 4. Report changed files and outcomes.
144
+ `
145
+ }
146
+
147
+ function buildWorkflowDocument(agentName: string): string {
148
+ return `# ${titleCaseAgentName(agentName) || agentName} Workflow (${AGENT_INITIAL_VERSION})
149
+
150
+ 1. Parse request and constraints.
151
+ 2. Identify exact files and minimal edits.
152
+ 3. Implement and verify changes.
153
+ 4. If blocked, stop and report the blocker.
154
+ 5. Return result summary with next actions if needed.
155
+ `
156
+ }
157
+
158
+ function buildToolsConfig(): string {
159
+ return `${JSON.stringify({
160
+ tools: [
161
+ {
162
+ name: 'shell_command',
163
+ enabled: true,
164
+ description: 'Execute shell commands for file and workspace operations.',
165
+ },
166
+ {
167
+ name: 'apply_patch',
168
+ enabled: true,
169
+ description: 'Apply focused file edits safely.',
170
+ },
171
+ {
172
+ name: 'read_file',
173
+ enabled: true,
174
+ description: 'Read files when needed for context.',
175
+ },
176
+ ],
177
+ permissions: {
178
+ network: false,
179
+ write: true,
180
+ delete: true,
181
+ },
182
+ }, null, 2)}
183
+ `
184
+ }
185
+
186
+ function buildModelConfig(): string {
187
+ return `${JSON.stringify({
188
+ provider: 'openai',
189
+ model: 'gpt-5',
190
+ temperature: 0.2,
191
+ max_tokens: 4096,
192
+ top_p: 0.95,
193
+ }, null, 2)}
194
+ `
195
+ }
196
+
197
+ function buildDefaultSkillDocument(): string {
198
+ return `# Coding Standards (${AGENT_INITIAL_VERSION})
199
+
200
+ - Keep changes minimal and focused on the request.
201
+ - Preserve existing behavior unless explicitly changing it.
202
+ - Prefer readable, deterministic implementations.
203
+ `
204
+ }
205
+
206
+ const SYSTEM_PROMPT_TS_TEMPLATE = `import * as fs from 'fs'
207
+ import * as path from 'path'
208
+
209
+ const base = path.join(__dirname)
210
+ const readActive = (p: string) => fs.readFileSync(path.join(base, p), 'utf8')
211
+
212
+ export const boot = readActive('boot.active.md')
213
+ export const workflow = readActive('workflow.active.md')
214
+ export const tools = JSON.parse(readActive('tools.active.json'))
215
+ export const model = JSON.parse(readActive('model.active.json'))
216
+
217
+ export const prompt = [boot, workflow].join('\\n\\n')
218
+
219
+ export const agentConfig = {
220
+ boot,
221
+ workflow,
222
+ tools,
223
+ model,
224
+ prompt,
225
+ }
226
+ `
227
+
228
+ const SKILLS_TS_TEMPLATE = `import * as fs from 'fs'
229
+ import * as path from 'path'
230
+
231
+ export interface SkillFile {
232
+ id: string
233
+ version: string
234
+ activeFile: string
235
+ resolvedFile: string
236
+ content: string
237
+ }
238
+
239
+ const skillsDir = path.join(__dirname)
240
+ const enabledListPath = path.join(skillsDir, 'enabled-skills.md')
241
+
242
+ const resolveVersionAndId = (activeFile: string) => {
243
+ const baseName = path.basename(activeFile, '.active.md')
244
+ const resolved = \`\${baseName}.${AGENT_INITIAL_VERSION}.md\`
245
+ return {
246
+ id: baseName,
247
+ version: '${AGENT_INITIAL_VERSION}',
248
+ resolvedFile: resolved,
249
+ }
250
+ }
251
+
252
+ const enabledLines = fs
253
+ .readFileSync(enabledListPath, 'utf8')
254
+ .split(/\\r?\\n/)
255
+ .map((line) => line.trim())
256
+ .filter(Boolean)
257
+
258
+ export const skills: SkillFile[] = enabledLines.map((activeFile) => {
259
+ const resolved = resolveVersionAndId(activeFile)
260
+ return {
261
+ ...resolved,
262
+ activeFile,
263
+ content: fs.readFileSync(path.join(skillsDir, resolved.resolvedFile), 'utf8'),
264
+ }
265
+ })
266
+ `
267
+
268
+ const LOAD_TS_TEMPLATE = `import { readFileSync } from 'fs'
269
+ import * as path from 'path'
270
+
271
+ import { agentConfig } from './system/prompt'
272
+ import { skills } from './skills/skills'
273
+
274
+ const activeDoc = path.join(__dirname, 'system')
275
+
276
+ const loadActive = (name: string) =>
277
+ readFileSync(path.join(activeDoc, name), 'utf8').trim()
278
+
279
+ export const load = () => ({
280
+ ...agentConfig,
281
+ bootDoc: loadActive('boot.active.md'),
282
+ workflowDoc: loadActive('workflow.active.md'),
283
+ skills,
284
+ })
285
+
286
+ export type AgentBundle = ReturnType<typeof load>
287
+ `
288
+
79
289
  export function parseTargetSpec(spec: string): VersionedFileSpec {
80
290
  if (!spec || typeof spec !== 'string') {
81
291
  throw new Error('file-path is required.')
@@ -285,6 +495,68 @@ function createWindowsSymlink(activeFile: string, sourceFile: string): boolean {
285
495
  return result.status === 0
286
496
  }
287
497
 
498
+ export function createAgent(agentName: string, processRoot: string = process.cwd()): AgentCreateResult {
499
+ const normalizedAgentName = normalizeAgentName(agentName)
500
+ const agentsRoot = resolveAgentsRootFrom(processRoot)
501
+ const agentRoot = path.join(agentsRoot, normalizedAgentName)
502
+
503
+ if (fs.existsSync(agentRoot)) {
504
+ throw new Error(`Agent folder already exists: ${agentRoot}`)
505
+ }
506
+
507
+ const systemDir = path.join(agentRoot, 'system')
508
+ const skillsDir = path.join(agentRoot, 'skills')
509
+
510
+ fs.mkdirSync(systemDir, { recursive: true })
511
+ fs.mkdirSync(skillsDir, { recursive: true })
512
+
513
+ const createdPaths: string[] = []
514
+ const writeFile = (relativePath: string, content: string) => {
515
+ const absolutePath = path.join(agentRoot, relativePath)
516
+ fs.mkdirSync(path.dirname(absolutePath), { recursive: true })
517
+ fs.writeFileSync(absolutePath, content, 'utf8')
518
+ createdPaths.push(absolutePath)
519
+ }
520
+
521
+ const bootFileName = `boot.${AGENT_INITIAL_VERSION}.md`
522
+ const workflowFileName = `workflow.${AGENT_INITIAL_VERSION}.md`
523
+ const toolsFileName = `tools.${AGENT_INITIAL_VERSION}.json`
524
+ const modelFileName = `model.${AGENT_INITIAL_VERSION}.json`
525
+ const skillFileName = `${DEFAULT_SKILL_NAME}.${AGENT_INITIAL_VERSION}.md`
526
+ const activeSkillFileName = `${DEFAULT_SKILL_NAME}.active.md`
527
+
528
+ writeFile(path.join('system', bootFileName), buildBootDocument(normalizedAgentName))
529
+ writeFile(path.join('system', workflowFileName), buildWorkflowDocument(normalizedAgentName))
530
+ writeFile(path.join('system', toolsFileName), buildToolsConfig())
531
+ writeFile(path.join('system', modelFileName), buildModelConfig())
532
+ writeFile(path.join('system', 'prompt.ts'), SYSTEM_PROMPT_TS_TEMPLATE)
533
+
534
+ writeFile(path.join('skills', skillFileName), buildDefaultSkillDocument())
535
+ writeFile(path.join('skills', 'enabled-skills.md'), `${activeSkillFileName}\n`)
536
+ writeFile(path.join('skills', 'skills.ts'), SKILLS_TS_TEMPLATE)
537
+
538
+ writeFile('load.ts', LOAD_TS_TEMPLATE)
539
+
540
+ const createActiveLink = (versionedFile: string, activeFile: string) => {
541
+ const source = path.join(agentRoot, versionedFile)
542
+ const target = path.join(agentRoot, activeFile)
543
+ setActiveLink(source, target)
544
+ createdPaths.push(target)
545
+ }
546
+
547
+ createActiveLink(path.join('system', bootFileName), path.join('system', 'boot.active.md'))
548
+ createActiveLink(path.join('system', workflowFileName), path.join('system', 'workflow.active.md'))
549
+ createActiveLink(path.join('system', toolsFileName), path.join('system', 'tools.active.json'))
550
+ createActiveLink(path.join('system', modelFileName), path.join('system', 'model.active.json'))
551
+ createActiveLink(path.join('skills', skillFileName), path.join('skills', activeSkillFileName))
552
+
553
+ return {
554
+ agentName: normalizedAgentName,
555
+ agentRoot,
556
+ createdPaths: createdPaths.sort((a, b) => a.localeCompare(b)),
557
+ }
558
+ }
559
+
288
560
  export function setActive(
289
561
  agentName: string,
290
562
  target: string,
@@ -362,6 +634,135 @@ export async function loadAgent(agentName: string, processRoot: string = process
362
634
  }
363
635
  }
364
636
 
637
+ type SpawnCodexResult = {
638
+ status: number | null
639
+ signal: NodeJS.Signals | null
640
+ error?: Error
641
+ }
642
+
643
+ type SpawnCodexFn = (args: string[]) => SpawnCodexResult
644
+
645
+ function getCodexCommand(): string {
646
+ const override = process.env.EXAMPLE_CODEX_BIN?.trim()
647
+ if (override) {
648
+ return override
649
+ }
650
+ if (process.platform === 'win32') {
651
+ // Prefer npm/pnpm cmd shim over stale codex.exe binaries.
652
+ return 'codex.cmd'
653
+ }
654
+ return 'codex'
655
+ }
656
+
657
+ const defaultSpawnCodex: SpawnCodexFn = (args) => {
658
+ const spawnOptions = {
659
+ stdio: 'inherit' as const,
660
+ env: process.env,
661
+ }
662
+
663
+ const primaryCommand = getCodexCommand()
664
+ const primary = spawnSync(primaryCommand, args, spawnOptions)
665
+ if (primary.error) {
666
+ const err = primary.error as NodeJS.ErrnoException
667
+ if (
668
+ process.platform === 'win32'
669
+ && !process.env.EXAMPLE_CODEX_BIN
670
+ && primaryCommand === 'codex.cmd'
671
+ && err.code === 'ENOENT'
672
+ ) {
673
+ return spawnSync('codex', args, spawnOptions)
674
+ }
675
+ }
676
+
677
+ return primary
678
+ }
679
+
680
+ function toExitCode(signal: NodeJS.Signals | null): number {
681
+ if (!signal) {
682
+ return 1
683
+ }
684
+ if (signal === 'SIGINT') {
685
+ return 130
686
+ }
687
+ if (signal === 'SIGTERM') {
688
+ return 143
689
+ }
690
+ return 1
691
+ }
692
+
693
+ function isRecord(value: unknown): value is Record<string, unknown> {
694
+ return typeof value === 'object' && value !== null
695
+ }
696
+
697
+ async function resolvePromptValue(value: unknown): Promise<unknown> {
698
+ if (typeof value === 'function') {
699
+ return await value()
700
+ }
701
+ return value
702
+ }
703
+
704
+ function extractPromptString(value: unknown): string | null {
705
+ if (typeof value === 'string') {
706
+ return value
707
+ }
708
+ if (isRecord(value) && typeof value.prompt === 'string') {
709
+ return value.prompt
710
+ }
711
+ return null
712
+ }
713
+
714
+ export async function loadAgentPrompt(agentName: string, processRoot: string = process.cwd()): Promise<string> {
715
+ const agentsRoot = resolveAgentsRoot(processRoot)
716
+ const agentDir = path.join(agentsRoot, agentName)
717
+
718
+ if (!existsDir(agentDir)) {
719
+ throw new Error(`Agent folder not found: ${agentDir}`)
720
+ }
721
+
722
+ const promptFile = path.join(agentDir, 'system', 'prompt.ts')
723
+ if (!existsFile(promptFile)) {
724
+ throw new Error(`Prompt file not found for agent '${agentName}': ${promptFile}`)
725
+ }
726
+
727
+ const promptModuleUrl = pathToFileURL(promptFile).href
728
+ const promptModule = await import(promptModuleUrl)
729
+ const candidates = [
730
+ await resolvePromptValue(promptModule.prompt),
731
+ await resolvePromptValue(promptModule.agentConfig),
732
+ await resolvePromptValue(promptModule.default),
733
+ ]
734
+
735
+ for (const candidate of candidates) {
736
+ const promptText = extractPromptString(candidate)
737
+ if (promptText !== null) {
738
+ return promptText
739
+ }
740
+ }
741
+
742
+ throw new Error(`Prompt module for agent '${agentName}' must export a prompt string.`)
743
+ }
744
+
745
+ export async function runAgent(
746
+ agentName: string,
747
+ codexArgs: string[] = [],
748
+ processRoot: string = process.cwd(),
749
+ options: { spawnCodex?: SpawnCodexFn } = {}
750
+ ): Promise<AgentRunResult> {
751
+ const prompt = await loadAgentPrompt(agentName, processRoot)
752
+ const spawnCodex = options.spawnCodex ?? defaultSpawnCodex
753
+ const args = ['--config', `developer_instructions=${prompt}`, ...codexArgs]
754
+ const result = spawnCodex(args)
755
+
756
+ if (result.error) {
757
+ throw new Error(`Failed to start codex: ${result.error.message}`)
758
+ }
759
+
760
+ return {
761
+ agentName,
762
+ exitCode: typeof result.status === 'number' ? result.status : toExitCode(result.signal),
763
+ }
764
+ }
765
+
365
766
  function validateActiveConfigInputs(agentDir: string): void {
366
767
  const issues: string[] = []
367
768
 
@@ -432,6 +833,7 @@ export async function main(argv: string[], processRoot: string = process.cwd()):
432
833
 
433
834
  const [scope, maybeAgentOrFlag, maybeTarget, ...rest] = argv
434
835
  const listMode = scope === 'agents' && maybeAgentOrFlag === '--list'
836
+ const createMode = scope === 'agents' && maybeAgentOrFlag === 'create'
435
837
 
436
838
  if (scope !== 'agents') {
437
839
  throw new Error('Expected command `agents` as first positional argument.')
@@ -445,6 +847,21 @@ export async function main(argv: string[], processRoot: string = process.cwd()):
445
847
  return listAgents(processRoot).join('\n')
446
848
  }
447
849
 
850
+ if (createMode) {
851
+ if (!maybeTarget) {
852
+ throw new Error('Missing required argument: <agent-name>.')
853
+ }
854
+
855
+ const unknownFlags = rest.filter(Boolean)
856
+ if (unknownFlags.length > 0) {
857
+ throw new Error(`Unknown flags for create mode: ${unknownFlags.join(', ')}`)
858
+ }
859
+
860
+ const result = createAgent(maybeTarget, processRoot)
861
+ const displayPath = path.relative(processRoot, result.agentRoot) || result.agentRoot
862
+ return `[${CLI_NAME}] created agent: ${result.agentName} (${displayPath})`
863
+ }
864
+
448
865
  const agentName = maybeAgentOrFlag
449
866
  const target = maybeTarget
450
867
  const setActive = rest.includes('--set-active')
@@ -458,6 +875,14 @@ export async function main(argv: string[], processRoot: string = process.cwd()):
458
875
  return JSON.stringify(result.loaded, null, 2)
459
876
  }
460
877
 
878
+ if (target === 'run') {
879
+ const result = await runAgent(agentName, rest, processRoot)
880
+ if (result.exitCode !== 0) {
881
+ process.exitCode = result.exitCode
882
+ }
883
+ return ''
884
+ }
885
+
461
886
  if (!agentName || !target) {
462
887
  throw new Error('Missing required arguments: <agent-name> and <file-path>.')
463
888
  }
package/git.ts CHANGED
@@ -1,25 +1,8 @@
1
- export type GitServiceApiExecutionResult<T = unknown> = {
2
- mapping: Record<string, unknown>
3
- request: {
4
- url: string
5
- method: string
6
- headers: Record<string, string>
7
- query: string[]
8
- body?: unknown
9
- }
10
- response: {
11
- headers: Record<string, string>
12
- }
13
- status: number
14
- ok: boolean
15
- body: T
16
- }
17
-
18
- export type GitServiceApiMethod = (...args: unknown[]) => Promise<GitServiceApiExecutionResult>
19
-
20
- export type GitServiceApi = {
21
- [key: string]: GitServiceApi | GitServiceApiMethod
22
- }
1
+ export type {
2
+ GitServiceApi,
3
+ GitServiceApiExecutionResult,
4
+ GitServiceApiMethod,
5
+ } from '@foundation0/git'
23
6
 
24
7
  export {
25
8
  buildGitApiMockResponse,
@@ -28,4 +11,4 @@ export {
28
11
  extractDependencyIssueNumbers,
29
12
  resolveProjectRepoIdentity,
30
13
  syncIssueDependencies,
31
- } from './dist/git.js'
14
+ } from '@foundation0/git'
package/mcp/cli.mjs CHANGED
@@ -32,6 +32,6 @@ try {
32
32
  process.exit(1)
33
33
  }
34
34
 
35
- console.error('Failed to launch F0 MCP server', error)
35
+ console.error('Failed to launch example-org MCP server', error)
36
36
  process.exit(1)
37
37
  }
package/mcp/cli.ts CHANGED
@@ -1,43 +1,43 @@
1
- import { runF0McpServer } from './server'
2
-
3
- const getArgValue = (name: string, fallback?: string): string | undefined => {
4
- const exactArg = process.argv.find((arg) => arg.startsWith(`${name}=`))
5
- if (exactArg) {
6
- const [, value] = exactArg.split('=', 2)
7
- return value
8
- }
9
-
10
- const index = process.argv.indexOf(name)
11
- if (index >= 0 && index + 1 < process.argv.length) {
12
- const next = process.argv[index + 1]
13
- if (!next.startsWith('--')) {
14
- return next
15
- }
16
- }
17
-
18
- return fallback
19
- }
20
-
21
- const hasFlag = (name: string): boolean => process.argv.includes(name)
22
-
1
+ import { runExampleMcpServer } from './server'
2
+
3
+ const getArgValue = (name: string, fallback?: string): string | undefined => {
4
+ const exactArg = process.argv.find((arg) => arg.startsWith(`${name}=`))
5
+ if (exactArg) {
6
+ const [, value] = exactArg.split('=', 2)
7
+ return value
8
+ }
9
+
10
+ const index = process.argv.indexOf(name)
11
+ if (index >= 0 && index + 1 < process.argv.length) {
12
+ const next = process.argv[index + 1]
13
+ if (!next.startsWith('--')) {
14
+ return next
15
+ }
16
+ }
17
+
18
+ return fallback
19
+ }
20
+
21
+ const hasFlag = (name: string): boolean => process.argv.includes(name)
22
+
23
23
  const serverName = getArgValue('--server-name', 'f0-mcp')
24
- const serverVersion = getArgValue('--server-version', '1.0.0')
25
- const toolsPrefix = getArgValue('--tools-prefix') ?? process.env.MCP_TOOLS_PREFIX
26
-
24
+ const serverVersion = getArgValue('--server-version', '1.0.0')
25
+ const toolsPrefix = getArgValue('--tools-prefix') ?? process.env.MCP_TOOLS_PREFIX
26
+
27
27
  if (hasFlag('--help') || hasFlag('-h')) {
28
28
  console.log('Usage: f0-mcp [--tools-prefix=api]')
29
- console.log('Optional flags:')
30
- console.log(' --server-name <name>')
31
- console.log(' --server-version <version>')
32
- console.log(' --tools-prefix <prefix>')
33
- process.exit(0)
34
- }
35
-
36
- void runF0McpServer({
37
- serverName: serverName ?? undefined,
38
- serverVersion: serverVersion ?? undefined,
39
- toolsPrefix,
40
- }).catch((error) => {
41
- console.error('Failed to start F0 MCP server', error)
42
- process.exit(1)
43
- })
29
+ console.log('Optional flags:')
30
+ console.log(' --server-name <name>')
31
+ console.log(' --server-version <version>')
32
+ console.log(' --tools-prefix <prefix>')
33
+ process.exit(0)
34
+ }
35
+
36
+ void runExampleMcpServer({
37
+ serverName: serverName ?? undefined,
38
+ serverVersion: serverVersion ?? undefined,
39
+ toolsPrefix,
40
+ }).catch((error) => {
41
+ console.error('Failed to start example-org MCP server', error)
42
+ process.exit(1)
43
+ })
package/mcp/client.ts CHANGED
@@ -40,30 +40,30 @@ const tryParseResult = (text: string): { parsed?: unknown; text: string } => {
40
40
  }
41
41
  }
42
42
 
43
- export interface F0McpClientOptions {
43
+ export interface ExampleMcpClientOptions {
44
44
  name?: string
45
45
  version?: string
46
46
  requestTimeoutMs?: number
47
47
  }
48
48
 
49
- export interface F0McpCallArgs {
49
+ export interface ExampleMcpCallArgs {
50
50
  args?: unknown[]
51
51
  options?: Record<string, unknown>
52
52
  [key: string]: unknown
53
53
  }
54
54
 
55
- export type F0McpCallResponse = {
55
+ export type ExampleMcpCallResponse = {
56
56
  isError: boolean
57
57
  text: string
58
58
  data: unknown
59
59
  }
60
60
 
61
- export class F0McpClient {
61
+ export class ExampleMcpClient {
62
62
  private readonly client: Client
63
63
  private readonly requestTimeoutMs: number
64
64
  private transport: StdioClientTransport | null = null
65
65
 
66
- public constructor(options: F0McpClientOptions = {}) {
66
+ public constructor(options: ExampleMcpClientOptions = {}) {
67
67
  this.requestTimeoutMs = options.requestTimeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS
68
68
  this.client = new Client(
69
69
  {
@@ -110,7 +110,7 @@ export class F0McpClient {
110
110
  return response.tools.map((tool) => tool.name)
111
111
  }
112
112
 
113
- public async call(toolName: string, args: F0McpCallArgs = {}): Promise<F0McpCallResponse> {
113
+ public async call(toolName: string, args: ExampleMcpCallArgs = {}): Promise<ExampleMcpCallResponse> {
114
114
  const response = await this.client.request(
115
115
  {
116
116
  method: 'tools/call',
@@ -138,12 +138,12 @@ export class F0McpClient {
138
138
  path: string,
139
139
  methodArgs: unknown[] = [],
140
140
  methodOptions: Record<string, unknown> = {},
141
- ): Promise<F0McpCallResponse> {
141
+ ): Promise<ExampleMcpCallResponse> {
142
142
  const args = { args: methodArgs.map((value) => String(value)), options: methodOptions }
143
143
  return this.call(path, args)
144
144
  }
145
145
  }
146
146
 
147
- export const createF0McpClient = (options: F0McpClientOptions = {}): F0McpClient => {
148
- return new F0McpClient(options)
147
+ export const createExampleMcpClient = (options: ExampleMcpClientOptions = {}): ExampleMcpClient => {
148
+ return new ExampleMcpClient(options)
149
149
  }
package/mcp/index.ts CHANGED
@@ -1,15 +1,15 @@
1
1
  export {
2
- createF0McpServer,
3
- runF0McpServer,
2
+ createExampleMcpServer,
3
+ runExampleMcpServer,
4
4
  normalizeToolCallNameForServer,
5
- type F0McpServerOptions,
6
- type F0McpServerInstance,
5
+ type ExampleMcpServerOptions,
6
+ type ExampleMcpServerInstance,
7
7
  } from './server'
8
8
 
9
9
  export {
10
- F0McpClient,
11
- createF0McpClient,
12
- type F0McpCallArgs,
13
- type F0McpCallResponse,
14
- type F0McpClientOptions,
10
+ ExampleMcpClient,
11
+ createExampleMcpClient,
12
+ type ExampleMcpCallArgs,
13
+ type ExampleMcpCallResponse,
14
+ type ExampleMcpClientOptions,
15
15
  } from './client'
package/mcp/server.ts CHANGED
@@ -308,20 +308,20 @@ const invokeTool = async (tool: ToolDefinition, payload: unknown): Promise<unkno
308
308
  return Promise.resolve(tool.method(...invocationArgs))
309
309
  }
310
310
 
311
- export interface F0McpServerOptions {
311
+ export interface ExampleMcpServerOptions {
312
312
  serverName?: string
313
313
  serverVersion?: string
314
314
  toolsPrefix?: string
315
315
  }
316
316
 
317
- export type F0McpServerInstance = {
317
+ export type ExampleMcpServerInstance = {
318
318
  api: ApiEndpoint
319
319
  tools: ToolDefinition[]
320
320
  server: Server
321
321
  run: () => Promise<Server>
322
322
  }
323
323
 
324
- export const createF0McpServer = (options: F0McpServerOptions = {}): F0McpServerInstance => {
324
+ export const createExampleMcpServer = (options: ExampleMcpServerOptions = {}): ExampleMcpServerInstance => {
325
325
  const api: ApiEndpoint = {
326
326
  agents: agentsApi,
327
327
  projects: projectsApi,
@@ -336,7 +336,7 @@ export const createF0McpServer = (options: F0McpServerOptions = {}): F0McpServer
336
336
 
337
337
  const server = new Server(
338
338
  {
339
- name: options.serverName ?? 'f0-api',
339
+ name: options.serverName ?? 'example-api',
340
340
  version: options.serverVersion ?? '1.0.0',
341
341
  },
342
342
  {
@@ -452,8 +452,8 @@ export const createF0McpServer = (options: F0McpServerOptions = {}): F0McpServer
452
452
  return { api, tools, server, run }
453
453
  }
454
454
 
455
- export const runF0McpServer = async (options: F0McpServerOptions = {}): Promise<Server> => {
456
- const instance = createF0McpServer(options)
455
+ export const runExampleMcpServer = async (options: ExampleMcpServerOptions = {}): Promise<Server> => {
456
+ const instance = createExampleMcpServer(options)
457
457
  return instance.run()
458
458
  }
459
459
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@foundation0/api",
3
- "version": "1.0.1",
3
+ "version": "1.1.0",
4
4
  "description": "Foundation 0 API",
5
5
  "type": "module",
6
6
  "bin": {
@@ -11,15 +11,13 @@
11
11
  "main": "agents.ts",
12
12
  "keywords": [
13
13
  "foundation0",
14
- "f0",
15
14
  "api"
16
15
  ],
17
- "author": "",
16
+ "author": "Foundation 0",
18
17
  "license": "ISC",
19
18
  "files": [
20
19
  "agents.ts",
21
20
  "git.ts",
22
- "dist/git.js",
23
21
  "taskgraph-parser.ts",
24
22
  "projects.ts",
25
23
  "mcp"
@@ -29,13 +27,13 @@
29
27
  "registry": "https://registry.npmjs.org/"
30
28
  },
31
29
  "dependencies": {
30
+ "@foundation0/git": "^1.0.0",
32
31
  "@modelcontextprotocol/sdk": "^1.13.0"
33
32
  },
34
33
  "scripts": {
35
- "build:git": "bun build ../git/packages/git/src/index.ts --target bun --format esm --minify --outfile ./dist/git.js",
36
34
  "mcp": "bun run mcp/cli.ts",
37
35
  "test": "echo \"Error: no test specified\" && exit 1",
38
- "deploy": "pnpm prepublishOnly && pnpm publish --access public",
36
+ "deploy": "pnpm publish --access public",
39
37
  "version:patch": "pnpm version patch",
40
38
  "version:minor": "pnpm version minor",
41
39
  "version:major": "pnpm version major"
package/projects.ts CHANGED
@@ -160,7 +160,7 @@ export type ProjectWriteGitTaskResult = {
160
160
  issue: ProjectGitTaskRecord
161
161
  }
162
162
 
163
- const CLI_NAME = 'f0'
163
+ const CLI_NAME = 'example'
164
164
  const VERSION_RE = 'v?\\d+(?:\\.\\d+){2,}'
165
165
  const VERSION_RE_CORE = `(?:${VERSION_RE})`
166
166
  const ACTIVE_EXT_PRIORITY = ['.md', '.json', '.yaml', '.yml', '.ts', '.js', '.txt']
@@ -171,9 +171,9 @@ const VERSIONED_DOC_RE = new RegExp(`^(.+)\\.(${VERSION_RE_CORE})\\.([^.]+)$`)
171
171
  const TASK_HASH_LENGTH = 8
172
172
  const ISSUE_LIST_PAGE_SIZE = 100
173
173
  const resolveGiteaHost = (): string => {
174
- const host = process.env.GITEA_HOST ?? process.env.F0_GITEA_HOST
174
+ const host = process.env.GITEA_HOST ?? process.env.EXAMPLE_GITEA_HOST
175
175
  if (!host) {
176
- throw new Error('No Gitea host configured. Set GITEA_HOST or F0_GITEA_HOST.')
176
+ throw new Error('No Gitea host configured. Set GITEA_HOST or EXAMPLE_GITEA_HOST.')
177
177
  }
178
178
  return host
179
179
  }
@@ -1856,13 +1856,13 @@ export async function syncTasks(
1856
1856
  }
1857
1857
  const log = syncOptions.verbose
1858
1858
  ? (message: string) => {
1859
- process.stderr.write(`[f0 projects ${projectName}] ${message}\n`)
1859
+ process.stderr.write(`[example projects ${projectName}] ${message}\n`)
1860
1860
  }
1861
1861
  : null
1862
1862
 
1863
- const previousTimeoutEnv = process.env.F0_GIT_REQUEST_TIMEOUT_MS
1863
+ const previousTimeoutEnv = process.env.EXAMPLE_GIT_REQUEST_TIMEOUT_MS
1864
1864
  if (syncOptions.requestTimeoutMs) {
1865
- process.env.F0_GIT_REQUEST_TIMEOUT_MS = String(syncOptions.requestTimeoutMs)
1865
+ process.env.EXAMPLE_GIT_REQUEST_TIMEOUT_MS = String(syncOptions.requestTimeoutMs)
1866
1866
  }
1867
1867
 
1868
1868
  log?.(`Resolved project root: ${projectRoot}`)
@@ -2020,9 +2020,9 @@ export async function syncTasks(
2020
2020
 
2021
2021
  if (syncOptions.skipDependencies) {
2022
2022
  if (previousTimeoutEnv === undefined) {
2023
- delete process.env.F0_GIT_REQUEST_TIMEOUT_MS
2023
+ delete process.env.EXAMPLE_GIT_REQUEST_TIMEOUT_MS
2024
2024
  } else {
2025
- process.env.F0_GIT_REQUEST_TIMEOUT_MS = previousTimeoutEnv
2025
+ process.env.EXAMPLE_GIT_REQUEST_TIMEOUT_MS = previousTimeoutEnv
2026
2026
  }
2027
2027
 
2028
2028
  return {
@@ -2081,9 +2081,9 @@ export async function syncTasks(
2081
2081
  }
2082
2082
 
2083
2083
  if (previousTimeoutEnv === undefined) {
2084
- delete process.env.F0_GIT_REQUEST_TIMEOUT_MS
2084
+ delete process.env.EXAMPLE_GIT_REQUEST_TIMEOUT_MS
2085
2085
  } else {
2086
- process.env.F0_GIT_REQUEST_TIMEOUT_MS = previousTimeoutEnv
2086
+ process.env.EXAMPLE_GIT_REQUEST_TIMEOUT_MS = previousTimeoutEnv
2087
2087
  }
2088
2088
 
2089
2089
  return {
@@ -2127,7 +2127,7 @@ export async function clearIssues(
2127
2127
 
2128
2128
  const log = clearOptions.verbose
2129
2129
  ? (message: string) => {
2130
- process.stderr.write(`[f0 projects ${projectName}] ${message}\n`)
2130
+ process.stderr.write(`[example projects ${projectName}] ${message}\n`)
2131
2131
  }
2132
2132
  : null
2133
2133
 
package/dist/git.js DELETED
@@ -1,4 +0,0 @@
1
- // @bun
2
- var q="2022-11-28";function x(e){let a=e.method??"GET",t=e.path,r=e.query??[],s=e.headers??[],l=e.apiBase??"https://api.github.com",o=e.apiVersion??"2022-11-28",u=[a,...t,...r,...s];return{endpoint:t.length>0?`${l}/${t.join("/")}`:l,method:a,path:[...t],query:[...r],headers:[...s],requestParts:u,apiVersion:o}}class L{apiBase;apiVersion;defaultMethod;constructor(e={}){this.apiBase=e.apiBase??"https://api.github.com",this.apiVersion=e.apiVersion??q,this.defaultMethod=e.defaultMethod??"GET"}buildInvocation(e){return{path:e.path,method:e.method??this.defaultMethod,query:e.query,headers:e.headers,apiBase:this.apiBase,apiVersion:this.apiVersion}}request(e){return x(this.buildInvocation(e))}requestAsync(e){return Promise.resolve(this.request(e))}get metadata(){return{apiBase:this.apiBase,apiVersion:this.apiVersion,defaultMethod:this.defaultMethod}}}function ne(e={}){return new L(e)}import{existsSync as le,readFileSync as ue}from"fs";import{dirname as oe,join as M}from"path";var ie="https://gitea.machian.com",me="GITEA",pe="/swagger.v1.json",ke=(e)=>{let a=e.trim();if(!a||a.startsWith("#"))return null;let t=a.indexOf("=");if(t<0)return null;let r=a.slice(0,t).trim(),s=a.slice(t+1).trim();if(!r)return null;if(s.length>=2&&s.startsWith('"')&&s.endsWith('"'))return[r,s.slice(1,-1)];if(s.length>=2&&s.startsWith("'")&&s.endsWith("'"))return[r,s.slice(1,-1)];return[r,s]},ce=(e)=>{if(!le(e))return{};let a={},t=ue(e,"utf8");for(let r of t.split(/\r?\n/)){let s=ke(r);if(!s)continue;let[l,o]=s;a[l]=o}return a},fe=()=>{let e=[M(process.cwd(),".env"),M(oe(process.cwd()),".env")];for(let a of e){let t=ce(a);if(Object.keys(t).length>0)return t}return{}},Ve=(e)=>{let a=(e??"").toUpperCase();if(a==="GITEA")return"GITEA";if(a==="GITHUB")return"GITHUB";return me},F=(e={})=>{let a=fe(),t=Ve(e.platform??process.env.PLATFORM??process.env.GIT_PLATFORM??a.PLATFORM??a.GIT_PLATFORM),r=e.giteaHost??process.env.GITEA_HOST??a.GITEA_HOST??ie,s=e.giteaToken??process.env.GITEA_TOKEN??a.GITEA_TOKEN,l=e.giteaApiVersion??process.env.GITEA_API_VERSION??a.GITEA_API_VERSION,o=e.giteaSwaggerPath??process.env.GITEA_SWAGGER_PATH??a.GITEA_SWAGGER_PATH??pe;return{platform:t,giteaHost:r,giteaToken:s,giteaApiVersion:l,giteaSwaggerPath:o}};var n=(e,a,t,r)=>({featurePath:e,method:a,swaggerPath:t,notes:r}),ge=[n(["issue","close"],"PATCH","/repos/{owner}/{repo}/issues/{number}"),n(["issue","comment"],"POST","/repos/{owner}/{repo}/issues/{number}/comments"),n(["issue","create"],"POST","/repos/{owner}/{repo}/issues"),n(["issue","delete"],"DELETE","/repos/{owner}/{repo}/issues/{number}"),n(["issue","edit"],"PATCH","/repos/{owner}/{repo}/issues/{number}"),n(["issue","list"],"GET","/repos/{owner}/{repo}/issues"),n(["issue","lock"],"PUT","/repos/{owner}/{repo}/issues/{number}/lock"),n(["issue","pin"],"POST","/repos/{owner}/{repo}/issues/{number}/pin"),n(["issue","reopen"],"PATCH","/repos/{owner}/{repo}/issues/{number}"),n(["issue","view"],"GET","/repos/{owner}/{repo}/issues/{number}"),n(["pr","comment"],"POST","/repos/{owner}/{repo}/issues/{number}/comments"),n(["pr","create"],"POST","/repos/{owner}/{repo}/pulls"),n(["pr","diff"],"GET","/repos/{owner}/{repo}/pulls/{number}.{diffType}"),n(["pr","edit"],"PATCH","/repos/{owner}/{repo}/pulls/{number}"),n(["pr","list"],"GET","/repos/{owner}/{repo}/pulls"),n(["pr","close"],"PATCH","/repos/{owner}/{repo}/pulls/{number}"),n(["pr","lock"],"PUT","/repos/{owner}/{repo}/issues/{number}/lock"),n(["pr","merge"],"POST","/repos/{owner}/{repo}/pulls/{number}/merge"),n(["pr","reopen"],"PATCH","/repos/{owner}/{repo}/pulls/{number}"),n(["pr","view"],"GET","/repos/{owner}/{repo}/pulls/{number}"),n(["repo","archive"],"GET","/repos/{owner}/{repo}/archive/{archive}"),n(["repo","create"],"POST","/user/repos"),n(["repo","delete"],"DELETE","/repos/{owner}/{repo}"),n(["repo","deploy-key"],"GET","/repos/{owner}/{repo}/keys"),n(["repo","edit"],"PATCH","/repos/{owner}/{repo}"),n(["repo","fork"],"POST","/repos/{owner}/{repo}/forks"),n(["repo","list"],"GET","/user/repos"),n(["repo","sync"],"POST","/repos/{owner}/{repo}/mirror-sync"),n(["repo","view"],"GET","/repos/{owner}/{repo}"),n(["release","create"],"POST","/repos/{owner}/{repo}/releases"),n(["release","delete"],"DELETE","/repos/{owner}/{repo}/releases/{id}"),n(["release","delete-asset"],"DELETE","/repos/{owner}/{repo}/releases/{id}/assets/{attachment_id}"),n(["release","download"],"GET","/repos/{owner}/{repo}/releases/{id}/assets/{attachment_id}"),n(["release","edit"],"PATCH","/repos/{owner}/{repo}/releases/{id}"),n(["release","list"],"GET","/repos/{owner}/{repo}/releases"),n(["release","upload"],"POST","/repos/{owner}/{repo}/releases/{id}/assets"),n(["release","verify"],"GET","/repos/{owner}/{repo}/releases/{id}"),n(["release","verify-asset"],"GET","/repos/{owner}/{repo}/releases/{id}/assets/{attachment_id}"),n(["release","view"],"GET","/repos/{owner}/{repo}/releases/{id}"),n(["contents","create"],"POST","/repos/{owner}/{repo}/contents/{filepath}"),n(["contents","delete"],"DELETE","/repos/{owner}/{repo}/contents/{filepath}"),n(["contents","list"],"GET","/repos/{owner}/{repo}/contents/{filepath}"),n(["contents","update"],"PUT","/repos/{owner}/{repo}/contents/{filepath}"),n(["contents","view"],"GET","/repos/{owner}/{repo}/contents/{filepath}"),n(["search","code"],"GET","/repos/search"),n(["search","commits"],"GET","/repos/search"),n(["search","issues"],"GET","/repos/issues/search"),n(["search","prs"],"GET","/repos/issues/search"),n(["search","repos"],"GET","/repos/search"),n(["workflow","disable"],"PUT","/repos/{owner}/{repo}/actions/workflows/{workflow_id}/disable"),n(["workflow","enable"],"PUT","/repos/{owner}/{repo}/actions/workflows/{workflow_id}/enable"),n(["workflow","list"],"GET","/repos/{owner}/{repo}/actions/workflows"),n(["workflow","run"],"POST","/repos/{owner}/{repo}/actions/workflows/{workflow_id}/dispatches"),n(["workflow","view"],"GET","/repos/{owner}/{repo}/actions/workflows/{workflow_id}"),n(["secret","delete"],"DELETE","/repos/{owner}/{repo}/actions/secrets/{secretname}"),n(["secret","list"],"GET","/repos/{owner}/{repo}/actions/secrets"),n(["secret","set"],"PUT","/repos/{owner}/{repo}/actions/secrets/{secretname}"),n(["variable","delete"],"DELETE","/repos/{owner}/{repo}/actions/variables/{variablename}"),n(["variable","get"],"GET","/repos/{owner}/{repo}/actions/variables/{variablename}"),n(["variable","list"],"GET","/repos/{owner}/{repo}/actions/variables"),n(["variable","set"],"POST","/repos/{owner}/{repo}/actions/variables/{variablename}"),n(["gpg-key","add"],"POST","/user/gpg_keys"),n(["gpg-key","delete"],"DELETE","/user/gpg_keys/{id}"),n(["gpg-key","list"],"GET","/user/gpg_keys"),n(["ssh-key","add"],"POST","/user/keys"),n(["ssh-key","delete"],"DELETE","/user/keys/{id}"),n(["ssh-key","list"],"GET","/user/keys"),n(["label","clone"],"POST","/repos/{owner}/{repo}/labels"),n(["label","create"],"POST","/repos/{owner}/{repo}/labels"),n(["label","delete"],"DELETE","/repos/{owner}/{repo}/labels/{id}"),n(["label","edit"],"PATCH","/repos/{owner}/{repo}/labels/{id}"),n(["label","list"],"GET","/repos/{owner}/{repo}/labels")],he=new Map([["issue",n(["issue"],"GET","/repos/{owner}/{repo}/issues","fallback to issue list")],["pr",n(["pr"],"GET","/repos/{owner}/{repo}/pulls","fallback to pull request list")],["repo",n(["repo"],"GET","/repos/{owner}/{repo}","fallback to repository read")],["release",n(["release"],"GET","/repos/{owner}/{repo}/releases","fallback to release list")],["run",n(["run"],"GET","/repos/{owner}/{repo}/actions/tasks","fallback to workflow task list")],["workflow",n(["workflow"],"GET","/repos/{owner}/{repo}/actions/workflows","fallback to workflow list")],["search",n(["search"],"GET","/repos/search","fallback to global repo search")],["secret",n(["secret"],"GET","/repos/{owner}/{repo}/actions/secrets","fallback to repository secret list")],["variable",n(["variable"],"GET","/repos/{owner}/{repo}/actions/variables","fallback to repository variable list")],["label",n(["label"],"GET","/repos/{owner}/{repo}/labels","fallback to repository label list")],["org",n(["org"],"GET","/orgs","fallback to list organizations")]]),U=(e)=>ge.find((a)=>a.featurePath.length===e.length&&a.featurePath.every((t,r)=>t===e[r])),W=(e)=>he.get(e[0]);var de=new Set(["GET","POST","PUT","PATCH","DELETE"]),we=new Set(["view","get","list","status","exists","search","stats","verify","check"]),be=new Set(["delete","remove","unarchive","unstar","unwatch","unpin","unlink","unsubscribe","unfollow","deprovision","expire"]),ye=new Set(["edit","update","close","open","pin","reopen","rename","set","transfer","enable","disable","lock","unlock","set-default","follow","watch","subscribe","archive","merge","approve"]),Ge=new Set(["create","add","run","dispatch","comment","fork","sync","set-upstream","upload","install","request","approve","create-team","apply","start","stop","rerun","reset"]),Q=(e)=>{if(!e||typeof e!=="string")return;let a=e.trim().toUpperCase();return de.has(a)?a:void 0},ve=(e)=>{if(e.length===0)return"GET";let a=e[e.length-1].toLowerCase();if(we.has(a))return"GET";if(be.has(a))return"DELETE";if(ye.has(a))return"PATCH";if(Ge.has(a))return"POST";if(e.length===1)return"GET";return"POST"};class O{apiBase;apiVersion;token;swaggerUrl;swaggerSpec;constructor(e){this.apiBase=this.buildApiBase(e.giteaHost),this.apiVersion=e.apiVersion,this.token=e.giteaToken,this.swaggerUrl=this.buildSwaggerUrl(e.giteaHost,e.giteaSwaggerPath),this.swaggerSpec=e.swaggerSpec}get platform(){return"GITEA"}async mapFeature(e){let a=e.args??[],t=e.flagValues??{},r=U(e.feature.path)??W(e.feature.path);if(!r)return this.mapFallback(e.feature.path,a,this.mapFlags(t,e.feature.path),e.method);return this.mapRule(r,a,t,e.method)}async mapFeatureResponse(e){let a=await this.mapFeature(e);return x({path:a.mappedPath,method:a.method,query:a.query,headers:a.headers,apiBase:a.apiBase,apiVersion:a.apiVersion})}async validateFeature(e){let a=await this.mapFeature(e),t=await this.fetchSwaggerSpec(),r=`/${a.mappedPath.join("/")}`,s=t.paths?.[r];if(!s)return{...a,mapped:!1,reason:`Swagger endpoint not found: ${r}`};let l=Object.prototype.hasOwnProperty.call(s,a.method.toLowerCase()),o=l?void 0:`Swagger method mismatch for ${r}: ${a.method}`;return{...a,mapped:l,reason:o}}async fetchSwaggerSpec(){if(this.swaggerSpec)return this.swaggerSpec;let e=await fetch(this.swaggerUrl,{headers:this.token?{Authorization:`token ${this.token}`}:void 0});if(!e.ok)throw Error(`Could not fetch swagger spec from ${this.swaggerUrl}: ${e.status}`);return await e.json()}mapRule(e,a=[],t={},r){let s=this.mapSwaggerPath(e.swaggerPath,a,this.shouldUseContentsRoot(e,a)),l=this.mapFeatureQuery(e,t),o=this.mapHeaders(),u=Q(r)??e.method;return{platform:this.platform,featurePath:e.featurePath,mappedPath:s,method:u,query:l,headers:o,apiBase:this.apiBase,swaggerPath:e.swaggerPath,mapped:!0,apiVersion:this.apiVersion,reason:e.notes}}mapFallback(e,a,t,r){let{owner:s,repo:l,tail:o}=this.extractOwnerRepoArgs(a),u=this.sanitizePath(["repos",s,l,...e,...o]),i=this.mapHeaders(),m=Q(r)??ve(e);return{platform:this.platform,featurePath:e,mappedPath:u,method:m,query:t,headers:i,apiBase:this.apiBase,swaggerPath:`/${u.join("/")}`,mapped:!1,apiVersion:this.apiVersion,reason:`No direct mapping for feature: ${e.join(" ")}`}}mapFeatureQuery(e,a){let t=[...e.staticQuery??[]];return t.push(...this.mapFlags(a,e.featurePath)),t}mapFlags(e,a){let t=[];if(a[0]==="search"){if(a[1]==="prs")t.push("type=pr");if(a[1]==="issues")t.push("type=issue")}for(let[r,s]of Object.entries(e)){if(s===void 0)continue;let l=this.normalizeFlagKey(r);if(typeof s==="boolean"){t.push(`${l}=${s}`);continue}t.push(`${l}=${s}`)}return t}mapHeaders(){let e=["Accept: application/json"];if(this.token)e.push(`Authorization: token ${this.token}`);return e}shouldUseContentsRoot(e,a){if(e.swaggerPath!=="/repos/{owner}/{repo}/contents/{filepath}")return!1;if(e.featurePath[0]!=="contents"||e.featurePath[1]!=="list")return!1;let[,,t]=a;if(t===void 0||t==="")return!0;return String(t).trim()===""}mapSwaggerPath(e,a=[],t=!1){let r=this.normalizeSwaggerPathArgs(e,a),s=this.sanitizePath(e.split("/")),l=0,o=s.flatMap((u)=>{if(!u.startsWith("{")||!u.endsWith("}"))return[u];let i=r[l];l+=1;let m=/^\\{v\\d+\\}$/.test(i);if(t&&u==="{filepath}"&&(!i||i.trim()===""||m))return[];return[i?i:u]});return this.sanitizePath(o)}normalizeSwaggerPathArgs(e,a){let t=[...a],s=e.split("/").filter((l)=>l.startsWith("{")&&l.endsWith("}")).length;if(s<=1)return t;if(!t[0])return t;if(t[0].includes("/")&&s>=2){let l=t[0].split("/");if(l.length>=2&&l[0]&&l[1])t[0]=l[0],t.splice(1,0,l[1])}if(s>=2&&t.length>=2)return t;while(t.length<s)t.push(`{v${t.length}}`);return t}extractOwnerRepoArgs(e){if(!e.length)return{owner:"{owner}",repo:"{repo}",tail:[]};if(e.length>=2)return{owner:e[0],repo:e[1],tail:e.slice(2)};let t=e[0].split("/");if(t.length===2&&t[0]&&t[1])return{owner:t[0],repo:t[1],tail:[]};return{owner:"{owner}",repo:"{repo}",tail:e}}buildApiBase(e){let a=e.replace(/\/$/,"");if(a.endsWith("/api/v1"))return a;return`${a}/api/v1`}buildSwaggerUrl(e,a="/swagger.v1.json"){let t=this.buildApiBase(e).replace(/\/api\/v1$/,""),r=a.startsWith("/")?a:`/${a}`;return`${t}${r}`}sanitizePath(e){return e.filter((a)=>a.length>0)}normalizeFlagKey(e){return e.replace(/^--/,"").trim()}}var $=(e={})=>{let a=F(e.config);if(a.platform==="GITEA")return new O({giteaHost:a.giteaHost,giteaToken:a.giteaToken,giteaSwaggerPath:a.giteaSwaggerPath,apiVersion:a.giteaApiVersion,...e.swaggerSpec?{swaggerSpec:e.swaggerSpec}:{}});throw Error(`Unsupported platform: ${a.platform}`)},Ae=async(e,a={})=>{let t=$(a),r=await t.mapFeature(e),s=await t.mapFeatureResponse(e);return{mapping:r,response:s}};var z={features:[{path:["agent-task","create"],args:["<task description>"],flags:[{name:"--base",takesValue:!0},{name:"--custom-agent",takesValue:!0},{name:"--follow",takesValue:!1},{name:"--from-file",takesValue:!0}]},{path:["agent-task","list"],args:[],flags:[{name:"--limit",takesValue:!0},{name:"--web",takesValue:!1}]},{path:["agent-task","view"],args:["<session-id> | <pr-number> | <pr-url> | <pr-branch>"],flags:[{name:"--follow",takesValue:!1},{name:"--log",takesValue:!1},{name:"--web",takesValue:!1}]},{path:["alias","delete"],args:[],flags:[{name:"--all",takesValue:!1}]},{path:["alias","import"],args:["<filename> | -"],flags:[{name:"--clobber",takesValue:!1}]},{path:["alias","list"],args:[],flags:[]},{path:["alias","set"],args:["<alias>","<expansion>"],flags:[{name:"--clobber",takesValue:!1},{name:"--shell",takesValue:!1},{name:"--cache",takesValue:!0},{name:"--field",takesValue:!0},{name:"--header",takesValue:!0},{name:"--hostname",takesValue:!0},{name:"--include",takesValue:!1},{name:"--input",takesValue:!0},{name:"--jq",takesValue:!0},{name:"--method",takesValue:!0},{name:"--paginate",takesValue:!1},{name:"--preview",takesValue:!0},{name:"--raw-field",takesValue:!0},{name:"--silent",takesValue:!1},{name:"--slurp",takesValue:!1},{name:"--template",takesValue:!0},{name:"--verbose",takesValue:!1}]},{path:["attestation","download"],args:["<file-path> | oci://<image-uri>"],flags:[{name:"--digest-alg",takesValue:!0},{name:"--hostname",takesValue:!0},{name:"--limit",takesValue:!0},{name:"--owner",takesValue:!0},{name:"--predicate-type",takesValue:!0},{name:"--repo",takesValue:!0}]},{path:["attestation","trusted-root"],args:[],flags:[{name:"--hostname",takesValue:!0},{name:"--tuf-root",takesValue:!0},{name:"--tuf-url",takesValue:!0},{name:"--verify-only",takesValue:!1}]},{path:["attestation","verify"],args:["<file-path> | oci://<image-uri>"],flags:[{name:"--bundle",takesValue:!0},{name:"--bundle-from-oci",takesValue:!1},{name:"--cert-identity",takesValue:!0},{name:"--cert-identity-regex",takesValue:!0},{name:"--cert-oidc-issuer",takesValue:!0},{name:"--custom-trusted-root",takesValue:!0},{name:"--deny-self-hosted-runners",takesValue:!1},{name:"--digest-alg",takesValue:!0},{name:"--format",takesValue:!0},{name:"--hostname",takesValue:!0},{name:"--jq",takesValue:!0},{name:"--limit",takesValue:!0},{name:"--no-public-good",takesValue:!1},{name:"--owner",takesValue:!0},{name:"--predicate-type",takesValue:!0},{name:"--repo",takesValue:!0},{name:"--signer-digest",takesValue:!0},{name:"--signer-repo",takesValue:!0},{name:"--signer-workflow",takesValue:!0},{name:"--source-digest",takesValue:!0},{name:"--source-ref",takesValue:!0},{name:"--template",takesValue:!0}]},{path:["auth","login"],args:[],flags:[{name:"--clipboard",takesValue:!1},{name:"--git-protocol",takesValue:!0},{name:"--hostname",takesValue:!0},{name:"--insecure-storage",takesValue:!1},{name:"--scopes",takesValue:!0},{name:"--skip-ssh-key",takesValue:!1},{name:"--web",takesValue:!1},{name:"--with-token",takesValue:!1}]},{path:["auth","logout"],args:[],flags:[{name:"--hostname",takesValue:!0},{name:"--user",takesValue:!0}]},{path:["auth","refresh"],args:[],flags:[{name:"--clipboard",takesValue:!1},{name:"--hostname",takesValue:!0},{name:"--insecure-storage",takesValue:!1},{name:"--remove-scopes",takesValue:!0},{name:"--reset-scopes",takesValue:!1},{name:"--scopes",takesValue:!0}]},{path:["auth","setup-git"],args:[],flags:[{name:"--force",takesValue:!1},{name:"--hostname",takesValue:!0}]},{path:["auth","status"],args:[],flags:[{name:"--active",takesValue:!1},{name:"--hostname",takesValue:!0},{name:"--jq",takesValue:!0},{name:"--json",takesValue:!0},{name:"--show-token",takesValue:!1},{name:"--template",takesValue:!0}]},{path:["auth","switch"],args:[],flags:[{name:"--hostname",takesValue:!0},{name:"--user",takesValue:!0}]},{path:["auth","token"],args:[],flags:[{name:"--hostname",takesValue:!0},{name:"--user",takesValue:!0},{name:"--branch",takesValue:!0},{name:"--commit",takesValue:!1},{name:"--no-browser",takesValue:!1},{name:"--projects",takesValue:!1},{name:"--releases",takesValue:!1},{name:"--settings",takesValue:!1},{name:"--wiki",takesValue:!1}]},{path:["cache","delete"],args:["<cache-id> | <cache-key> | --all"],flags:[{name:"--all",takesValue:!1},{name:"--ref",takesValue:!0},{name:"--succeed-on-no-caches",takesValue:!1}]},{path:["cache","list"],args:[],flags:[{name:"--jq",takesValue:!0},{name:"--json",takesValue:!0},{name:"--key",takesValue:!0},{name:"--limit",takesValue:!0},{name:"--order",takesValue:!0},{name:"--ref",takesValue:!0},{name:"--sort",takesValue:!0},{name:"--template",takesValue:!0}]},{path:["codespace","code"],args:[],flags:[{name:"--codespace",takesValue:!0},{name:"--insiders",takesValue:!1},{name:"--repo",takesValue:!0},{name:"--repo-owner",takesValue:!0},{name:"--web",takesValue:!1}]},{path:["codespace","cp"],args:["-e","-r","]","<sources>...","<dest>"],flags:[{name:"--codespace",takesValue:!0},{name:"--expand",takesValue:!1},{name:"--profile",takesValue:!0},{name:"--recursive",takesValue:!1},{name:"--repo",takesValue:!0},{name:"--repo-owner",takesValue:!0}]},{path:["codespace","create"],args:[],flags:[{name:"--branch",takesValue:!0},{name:"--default-permissions",takesValue:!1},{name:"--devcontainer-path",takesValue:!0},{name:"--display-name",takesValue:!0},{name:"--idle-timeout",takesValue:!0},{name:"--location",takesValue:!0},{name:"--machine",takesValue:!0},{name:"--repo",takesValue:!0},{name:"--retention-period",takesValue:!0},{name:"--status",takesValue:!1},{name:"--web",takesValue:!1}]},{path:["codespace","delete"],args:[],flags:[{name:"--all",takesValue:!1},{name:"--codespace",takesValue:!0},{name:"--days",takesValue:!1},{name:"--force",takesValue:!1},{name:"--org",takesValue:!0},{name:"--repo",takesValue:!0},{name:"--repo-owner",takesValue:!0},{name:"--user",takesValue:!0}]},{path:["codespace","edit"],args:[],flags:[{name:"--codespace",takesValue:!0},{name:"--display-name",takesValue:!0},{name:"--machine",takesValue:!0},{name:"--repo",takesValue:!0},{name:"--repo-owner",takesValue:!0}]},{path:["codespace","jupyter"],args:[],flags:[{name:"--codespace",takesValue:!0},{name:"--repo",takesValue:!0},{name:"--repo-owner",takesValue:!0}]},{path:["codespace","list"],args:[],flags:[{name:"--jq",takesValue:!0},{name:"--json",takesValue:!0},{name:"--limit",takesValue:!0},{name:"--org",takesValue:!0},{name:"--repo",takesValue:!0},{name:"--template",takesValue:!0},{name:"--user",takesValue:!0},{name:"--web",takesValue:!1}]},{path:["codespace","logs"],args:[],flags:[{name:"--codespace",takesValue:!0},{name:"--follow",takesValue:!1},{name:"--repo",takesValue:!0},{name:"--repo-owner",takesValue:!0}]},{path:["codespace","ports"],args:[],flags:[{name:"--codespace",takesValue:!0},{name:"--jq",takesValue:!0},{name:"--json",takesValue:!0},{name:"--repo",takesValue:!0},{name:"--repo-owner",takesValue:!0},{name:"--template",takesValue:!0}]},{path:["codespace","rebuild"],args:[],flags:[{name:"--codespace",takesValue:!0},{name:"--full",takesValue:!1},{name:"--repo",takesValue:!0},{name:"--repo-owner",takesValue:!0}]},{path:["codespace","ssh"],args:["<flags>...","<command>"],flags:[{name:"--codespace",takesValue:!0},{name:"--config",takesValue:!1},{name:"--debug",takesValue:!1},{name:"--debug-file",takesValue:!0},{name:"--profile",takesValue:!0},{name:"--repo",takesValue:!0},{name:"--repo-owner",takesValue:!0},{name:"--server-port",takesValue:!0}]},{path:["codespace","stop"],args:[],flags:[{name:"--codespace",takesValue:!0},{name:"--org",takesValue:!0},{name:"--repo",takesValue:!0},{name:"--repo-owner",takesValue:!0},{name:"--user",takesValue:!0}]},{path:["codespace","view"],args:[],flags:[{name:"--codespace",takesValue:!0},{name:"--jq",takesValue:!0},{name:"--json",takesValue:!0},{name:"--repo",takesValue:!0},{name:"--repo-owner",takesValue:!0},{name:"--template",takesValue:!0},{name:"--shell",takesValue:!0}]},{path:["config","clear-cache"],args:[],flags:[]},{path:["config","get"],args:["<key>"],flags:[{name:"--host",takesValue:!0}]},{path:["config","list"],args:[],flags:[{name:"--host",takesValue:!0}]},{path:["config","set"],args:["<key>","<value>"],flags:[{name:"--host",takesValue:!0}]},{path:["extension","browse"],args:[],flags:[{name:"--debug",takesValue:!1},{name:"--single-column",takesValue:!1}]},{path:["extension","create"],args:["<name>"],flags:[{name:"--precompiled",takesValue:!0}]},{path:["extension","exec"],args:["<name>","args"],flags:[]},{path:["extension","install"],args:["<repository>"],flags:[{name:"--force",takesValue:!1},{name:"--pin",takesValue:!0}]},{path:["extension","list"],args:[],flags:[]},{path:["extension","remove"],args:["<name>"],flags:[]},{path:["extension","search"],args:["<query>"],flags:[{name:"--jq",takesValue:!0},{name:"--json",takesValue:!0},{name:"--license",takesValue:!0},{name:"--limit",takesValue:!0},{name:"--order",takesValue:!0},{name:"--owner",takesValue:!0},{name:"--sort",takesValue:!0},{name:"--template",takesValue:!0},{name:"--web",takesValue:!1}]},{path:["extension","upgrade"],args:[],flags:[{name:"--all",takesValue:!1},{name:"--dry-run",takesValue:!1},{name:"--force",takesValue:!1}]},{path:["gist","clone"],args:["<gist>","<directory>"],flags:[]},{path:["gist","create"],args:["<filename>... | <pattern>... | -"],flags:[{name:"--desc",takesValue:!0},{name:"--filename",takesValue:!0},{name:"--public",takesValue:!1},{name:"--web",takesValue:!1}]},{path:["gist","delete"],args:["<id> | <url>"],flags:[{name:"--yes",takesValue:!1}]},{path:["gist","edit"],args:["<id> | <url>","<filename>"],flags:[{name:"--add",takesValue:!0},{name:"--desc",takesValue:!0},{name:"--filename",takesValue:!0},{name:"--remove",takesValue:!0}]},{path:["gist","list"],args:[],flags:[{name:"--filter",takesValue:!0},{name:"--include-content",takesValue:!1},{name:"--limit",takesValue:!0},{name:"--public",takesValue:!1},{name:"--secret",takesValue:!1}]},{path:["gist","rename"],args:["<id> | <url>","<old-filename>","<new-filename>"],flags:[]},{path:["gist","view"],args:["<id> | <url>"],flags:[{name:"--filename",takesValue:!0},{name:"--files",takesValue:!1},{name:"--raw",takesValue:!1},{name:"--web",takesValue:!1}]},{path:["gpg-key","add"],args:["<key-file>"],flags:[{name:"--title",takesValue:!0}]},{path:["gpg-key","delete"],args:["<key-id>"],flags:[{name:"--yes",takesValue:!1}]},{path:["gpg-key","list"],args:[],flags:[]},{path:["issue","close"],args:["<number> | <url>"],flags:[{name:"--comment",takesValue:!0},{name:"--reason",takesValue:!0}]},{path:["issue","comment"],args:["<number> | <url>"],flags:[{name:"--body",takesValue:!0},{name:"--body-file",takesValue:!0},{name:"--create-if-none",takesValue:!1},{name:"--delete-last",takesValue:!1},{name:"--edit-last",takesValue:!1},{name:"--editor",takesValue:!1},{name:"--web",takesValue:!1},{name:"--yes",takesValue:!1}]},{path:["issue","create"],args:[],flags:[{name:"--assignee",takesValue:!0},{name:"--body",takesValue:!0},{name:"--body-file",takesValue:!0},{name:"--editor",takesValue:!1},{name:"--label",takesValue:!0},{name:"--milestone",takesValue:!0},{name:"--project",takesValue:!0},{name:"--recover",takesValue:!0},{name:"--template",takesValue:!0},{name:"--title",takesValue:!0},{name:"--web",takesValue:!1}]},{path:["issue","delete"],args:["<number> | <url>"],flags:[{name:"--yes",takesValue:!1}]},{path:["issue","develop"],args:["<number> | <url>"],flags:[{name:"--base",takesValue:!0},{name:"--branch-repo",takesValue:!0},{name:"--checkout",takesValue:!1},{name:"--list",takesValue:!1},{name:"--name",takesValue:!0}]},{path:["issue","edit"],args:["<numbers> | <urls>"],flags:[{name:"--add-assignee",takesValue:!0},{name:"--add-label",takesValue:!0},{name:"--add-project",takesValue:!0},{name:"--body",takesValue:!0},{name:"--body-file",takesValue:!0},{name:"--milestone",takesValue:!0},{name:"--remove-assignee",takesValue:!0},{name:"--remove-label",takesValue:!0},{name:"--remove-milestone",takesValue:!1},{name:"--remove-project",takesValue:!0},{name:"--title",takesValue:!0}]},{path:["issue","list"],args:[],flags:[{name:"--app",takesValue:!0},{name:"--assignee",takesValue:!0},{name:"--author",takesValue:!0},{name:"--jq",takesValue:!0},{name:"--json",takesValue:!0},{name:"--label",takesValue:!0},{name:"--limit",takesValue:!0},{name:"--mention",takesValue:!0},{name:"--milestone",takesValue:!0},{name:"--search",takesValue:!0},{name:"--state",takesValue:!0},{name:"--template",takesValue:!0},{name:"--web",takesValue:!1}]},{path:["issue","lock"],args:["<number> | <url>"],flags:[{name:"--reason",takesValue:!0}]},{path:["issue","pin"],args:["<number> | <url>"],flags:[]},{path:["issue","reopen"],args:["<number> | <url>"],flags:[{name:"--comment",takesValue:!0}]},{path:["issue","status"],args:[],flags:[{name:"--jq",takesValue:!0},{name:"--json",takesValue:!0},{name:"--template",takesValue:!0}]},{path:["issue","transfer"],args:["<number> | <url>","<destination-repo>"],flags:[]},{path:["issue","unlock"],args:["<number> | <url>"],flags:[]},{path:["issue","unpin"],args:["<number> | <url>"],flags:[]},{path:["issue","view"],args:["<number> | <url>"],flags:[{name:"--comments",takesValue:!1},{name:"--jq",takesValue:!0},{name:"--json",takesValue:!0},{name:"--template",takesValue:!0},{name:"--web",takesValue:!1}]},{path:["label","clone"],args:["<source-repository>"],flags:[{name:"--force",takesValue:!1}]},{path:["label","create"],args:["<name>"],flags:[{name:"--color",takesValue:!0},{name:"--description",takesValue:!0},{name:"--force",takesValue:!1}]},{path:["label","delete"],args:["<name>"],flags:[{name:"--yes",takesValue:!1}]},{path:["label","edit"],args:["<name>"],flags:[{name:"--color",takesValue:!0},{name:"--description",takesValue:!0},{name:"--name",takesValue:!0}]},{path:["label","list"],args:[],flags:[{name:"--jq",takesValue:!0},{name:"--json",takesValue:!0},{name:"--limit",takesValue:!0},{name:"--order",takesValue:!0},{name:"--search",takesValue:!0},{name:"--sort",takesValue:!0},{name:"--template",takesValue:!0},{name:"--web",takesValue:!1}]},{path:["org","list"],args:[],flags:[{name:"--limit",takesValue:!0},{name:"--help",takesValue:!1},{name:"--repo",takesValue:!1}]},{path:["pr","checkout"],args:["<number> | <url> | <branch>"],flags:[{name:"--branch",takesValue:!0},{name:"--detach",takesValue:!1},{name:"--force",takesValue:!1},{name:"--recurse-submodules",takesValue:!1}]},{path:["pr","checks"],args:["<number> | <url> | <branch>"],flags:[{name:"--fail-fast",takesValue:!1},{name:"--interval",takesValue:!0},{name:"--jq",takesValue:!0},{name:"--json",takesValue:!0},{name:"--required",takesValue:!1},{name:"--template",takesValue:!0},{name:"--watch",takesValue:!1},{name:"--web",takesValue:!1}]},{path:["pr","close"],args:["<number> | <url> | <branch>"],flags:[{name:"--comment",takesValue:!0},{name:"--delete-branch",takesValue:!1}]},{path:["pr","comment"],args:["<number> | <url> | <branch>"],flags:[{name:"--body",takesValue:!0},{name:"--body-file",takesValue:!0},{name:"--create-if-none",takesValue:!1},{name:"--delete-last",takesValue:!1},{name:"--edit-last",takesValue:!1},{name:"--editor",takesValue:!1},{name:"--web",takesValue:!1},{name:"--yes",takesValue:!1}]},{path:["pr","create"],args:[],flags:[{name:"--assignee",takesValue:!0},{name:"--base",takesValue:!0},{name:"--body",takesValue:!0},{name:"--body-file",takesValue:!0},{name:"--draft",takesValue:!1},{name:"--dry-run",takesValue:!1},{name:"--editor",takesValue:!1},{name:"--fill",takesValue:!1},{name:"--fill-first",takesValue:!1},{name:"--fill-verbose",takesValue:!1},{name:"--head",takesValue:!0},{name:"--label",takesValue:!0},{name:"--milestone",takesValue:!0},{name:"--no-maintainer-edit",takesValue:!1},{name:"--project",takesValue:!0},{name:"--recover",takesValue:!0},{name:"--reviewer",takesValue:!0},{name:"--template",takesValue:!0},{name:"--title",takesValue:!0},{name:"--web",takesValue:!1}]},{path:["pr","diff"],args:["<number> | <url> | <branch>"],flags:[{name:"--color",takesValue:!0},{name:"--name-only",takesValue:!1},{name:"--patch",takesValue:!1},{name:"--web",takesValue:!1}]},{path:["pr","edit"],args:["<number> | <url> | <branch>"],flags:[{name:"--add-assignee",takesValue:!0},{name:"--add-label",takesValue:!0},{name:"--add-project",takesValue:!0},{name:"--add-reviewer",takesValue:!0},{name:"--base",takesValue:!0},{name:"--body",takesValue:!0},{name:"--body-file",takesValue:!0},{name:"--milestone",takesValue:!0},{name:"--remove-assignee",takesValue:!0},{name:"--remove-label",takesValue:!0},{name:"--remove-milestone",takesValue:!1},{name:"--remove-project",takesValue:!0},{name:"--remove-reviewer",takesValue:!0},{name:"--title",takesValue:!0}]},{path:["pr","list"],args:[],flags:[{name:"--app",takesValue:!0},{name:"--assignee",takesValue:!0},{name:"--author",takesValue:!0},{name:"--base",takesValue:!0},{name:"--draft",takesValue:!1},{name:"--head",takesValue:!0},{name:"--jq",takesValue:!0},{name:"--json",takesValue:!0},{name:"--label",takesValue:!0},{name:"--limit",takesValue:!0},{name:"--search",takesValue:!0},{name:"--state",takesValue:!0},{name:"--template",takesValue:!0},{name:"--web",takesValue:!1}]},{path:["pr","lock"],args:["<number> | <url>"],flags:[{name:"--reason",takesValue:!0}]},{path:["pr","merge"],args:["<number> | <url> | <branch>"],flags:[{name:"--admin",takesValue:!1},{name:"--author-email",takesValue:!0},{name:"--auto",takesValue:!1},{name:"--body",takesValue:!0},{name:"--body-file",takesValue:!0},{name:"--delete-branch",takesValue:!1},{name:"--disable-auto",takesValue:!1},{name:"--match-head-commit",takesValue:!1},{name:"--merge",takesValue:!1},{name:"--rebase",takesValue:!1},{name:"--squash",takesValue:!1},{name:"--subject",takesValue:!0}]},{path:["pr","ready"],args:["<number> | <url> | <branch>"],flags:[{name:"--undo",takesValue:!1}]},{path:["pr","reopen"],args:["<number> | <url> | <branch>"],flags:[{name:"--comment",takesValue:!0}]},{path:["pr","revert"],args:["<number> | <url> | <branch>"],flags:[{name:"--body",takesValue:!0},{name:"--body-file",takesValue:!0},{name:"--draft",takesValue:!1},{name:"--title",takesValue:!0}]},{path:["pr","review"],args:["<number> | <url> | <branch>"],flags:[{name:"--approve",takesValue:!1},{name:"--body",takesValue:!0},{name:"--body-file",takesValue:!0},{name:"--comment",takesValue:!1},{name:"--request-changes",takesValue:!1}]},{path:["pr","status"],args:[],flags:[{name:"--conflict-status",takesValue:!1},{name:"--jq",takesValue:!0},{name:"--json",takesValue:!0},{name:"--template",takesValue:!0}]},{path:["pr","unlock"],args:["<number> | <url>"],flags:[]},{path:["pr","update-branch"],args:["<number> | <url> | <branch>"],flags:[{name:"--rebase",takesValue:!1}]},{path:["pr","view"],args:["<number> | <url> | <branch>"],flags:[{name:"--comments",takesValue:!1},{name:"--jq",takesValue:!0},{name:"--json",takesValue:!0},{name:"--template",takesValue:!0},{name:"--web",takesValue:!1}]},{path:["preview","prompter"],args:["prompt type"],flags:[]},{path:["project","close"],args:["<number>"],flags:[{name:"--format",takesValue:!0},{name:"--jq",takesValue:!0},{name:"--owner",takesValue:!0},{name:"--template",takesValue:!0},{name:"--undo",takesValue:!1}]},{path:["project","copy"],args:["<number>"],flags:[{name:"--drafts",takesValue:!1},{name:"--format",takesValue:!0},{name:"--jq",takesValue:!0},{name:"--source-owner",takesValue:!0},{name:"--target-owner",takesValue:!0},{name:"--template",takesValue:!0},{name:"--title",takesValue:!0}]},{path:["project","create"],args:[],flags:[{name:"--format",takesValue:!0},{name:"--jq",takesValue:!0},{name:"--owner",takesValue:!0},{name:"--template",takesValue:!0},{name:"--title",takesValue:!0}]},{path:["project","delete"],args:["<number>"],flags:[{name:"--format",takesValue:!0},{name:"--jq",takesValue:!0},{name:"--owner",takesValue:!0},{name:"--template",takesValue:!0}]},{path:["project","edit"],args:["<number>"],flags:[{name:"--description",takesValue:!0},{name:"--format",takesValue:!0},{name:"--jq",takesValue:!0},{name:"--owner",takesValue:!0},{name:"--readme",takesValue:!0},{name:"--template",takesValue:!0},{name:"--title",takesValue:!0},{name:"--visibility",takesValue:!0}]},{path:["project","field-create"],args:["<number>"],flags:[{name:"--data-type",takesValue:!0},{name:"--format",takesValue:!0},{name:"--jq",takesValue:!0},{name:"--name",takesValue:!0},{name:"--owner",takesValue:!0},{name:"--single-select-options",takesValue:!0},{name:"--template",takesValue:!0}]},{path:["project","field-delete"],args:[],flags:[{name:"--format",takesValue:!0},{name:"--id",takesValue:!0},{name:"--jq",takesValue:!0},{name:"--template",takesValue:!0}]},{path:["project","field-list"],args:["<number>"],flags:[{name:"--format",takesValue:!0},{name:"--jq",takesValue:!0},{name:"--limit",takesValue:!0},{name:"--owner",takesValue:!0},{name:"--template",takesValue:!0}]},{path:["project","item-add"],args:["<number>"],flags:[{name:"--format",takesValue:!0},{name:"--jq",takesValue:!0},{name:"--owner",takesValue:!0},{name:"--template",takesValue:!0},{name:"--url",takesValue:!0}]},{path:["project","item-archive"],args:["<number>"],flags:[{name:"--format",takesValue:!0},{name:"--id",takesValue:!0},{name:"--jq",takesValue:!0},{name:"--owner",takesValue:!0},{name:"--template",takesValue:!0},{name:"--undo",takesValue:!1}]},{path:["project","item-create"],args:["<number>"],flags:[{name:"--body",takesValue:!0},{name:"--format",takesValue:!0},{name:"--jq",takesValue:!0},{name:"--owner",takesValue:!0},{name:"--template",takesValue:!0},{name:"--title",takesValue:!0}]},{path:["project","item-delete"],args:["<number>"],flags:[{name:"--format",takesValue:!0},{name:"--id",takesValue:!0},{name:"--jq",takesValue:!0},{name:"--owner",takesValue:!0},{name:"--template",takesValue:!0}]},{path:["project","item-edit"],args:[],flags:[{name:"--body",takesValue:!0},{name:"--clear",takesValue:!1},{name:"--date",takesValue:!0},{name:"--field-id",takesValue:!0},{name:"--format",takesValue:!0},{name:"--id",takesValue:!0},{name:"--iteration-id",takesValue:!0},{name:"--jq",takesValue:!0},{name:"--number",takesValue:!0},{name:"--project-id",takesValue:!0},{name:"--single-select-option-id",takesValue:!0},{name:"--template",takesValue:!0},{name:"--text",takesValue:!0},{name:"--title",takesValue:!0}]},{path:["project","item-list"],args:["<number>"],flags:[{name:"--format",takesValue:!0},{name:"--jq",takesValue:!0},{name:"--limit",takesValue:!0},{name:"--owner",takesValue:!0},{name:"--template",takesValue:!0}]},{path:["project","link"],args:["<number>"],flags:[{name:"--owner",takesValue:!0},{name:"--repo",takesValue:!0},{name:"--team",takesValue:!0}]},{path:["project","list"],args:[],flags:[{name:"--closed",takesValue:!1},{name:"--format",takesValue:!0},{name:"--jq",takesValue:!0},{name:"--limit",takesValue:!0},{name:"--owner",takesValue:!0},{name:"--template",takesValue:!0},{name:"--web",takesValue:!1}]},{path:["project","mark-template"],args:["<number>"],flags:[{name:"--format",takesValue:!0},{name:"--jq",takesValue:!0},{name:"--owner",takesValue:!0},{name:"--template",takesValue:!0},{name:"--undo",takesValue:!1}]},{path:["project","unlink"],args:["<number>"],flags:[{name:"--owner",takesValue:!0},{name:"--repo",takesValue:!0},{name:"--team",takesValue:!0}]},{path:["project","view"],args:["<number>"],flags:[{name:"--format",takesValue:!0},{name:"--jq",takesValue:!0},{name:"--owner",takesValue:!0},{name:"--template",takesValue:!0},{name:"--web",takesValue:!1}]},{path:["release","create"],args:["<tag>","<filename>... | <pattern>..."],flags:[{name:"--discussion-category",takesValue:!0},{name:"--draft",takesValue:!1},{name:"--fail-on-no-commits",takesValue:!1},{name:"--generate-notes",takesValue:!1},{name:"--latest",takesValue:!1},{name:"--notes",takesValue:!0},{name:"--notes-file",takesValue:!0},{name:"--notes-from-tag",takesValue:!1},{name:"--notes-start-tag",takesValue:!0},{name:"--prerelease",takesValue:!1},{name:"--target",takesValue:!0},{name:"--title",takesValue:!0},{name:"--verify-tag",takesValue:!1}]},{path:["release","delete"],args:["<tag>"],flags:[{name:"--cleanup-tag",takesValue:!1},{name:"--yes",takesValue:!1}]},{path:["release","delete-asset"],args:["<tag>","<asset-name>"],flags:[{name:"--yes",takesValue:!1}]},{path:["release","download"],args:["<tag>"],flags:[{name:"--archive",takesValue:!0},{name:"--clobber",takesValue:!1},{name:"--dir",takesValue:!0},{name:"--output",takesValue:!0},{name:"--pattern",takesValue:!0},{name:"--skip-existing",takesValue:!1}]},{path:["release","edit"],args:["<tag>"],flags:[{name:"--discussion-category",takesValue:!0},{name:"--draft",takesValue:!1},{name:"--latest",takesValue:!1},{name:"--notes",takesValue:!0},{name:"--notes-file",takesValue:!0},{name:"--prerelease",takesValue:!1},{name:"--tag",takesValue:!0},{name:"--target",takesValue:!0},{name:"--title",takesValue:!0},{name:"--verify-tag",takesValue:!1}]},{path:["release","list"],args:[],flags:[{name:"--exclude-drafts",takesValue:!1},{name:"--exclude-pre-releases",takesValue:!1},{name:"--jq",takesValue:!0},{name:"--json",takesValue:!0},{name:"--limit",takesValue:!0},{name:"--order",takesValue:!0},{name:"--template",takesValue:!0}]},{path:["release","upload"],args:["<tag>","<files>..."],flags:[{name:"--clobber",takesValue:!1}]},{path:["release","verify"],args:["<tag>"],flags:[{name:"--format",takesValue:!0},{name:"--jq",takesValue:!0},{name:"--template",takesValue:!0}]},{path:["release","verify-asset"],args:["<tag>","<file-path>"],flags:[{name:"--format",takesValue:!0},{name:"--jq",takesValue:!0},{name:"--template",takesValue:!0}]},{path:["release","view"],args:["<tag>"],flags:[{name:"--jq",takesValue:!0},{name:"--json",takesValue:!0},{name:"--template",takesValue:!0},{name:"--web",takesValue:!1}]},{path:["repo","archive"],args:["<repository>"],flags:[{name:"--yes",takesValue:!1}]},{path:["repo","autolink"],args:["<command>"],flags:[]},{path:["repo","clone"],args:["<repository>","<directory>"],flags:[{name:"--upstream-remote-name",takesValue:!0}]},{path:["repo","create"],args:["<name>"],flags:[{name:"--add-readme",takesValue:!1},{name:"--clone",takesValue:!1},{name:"--description",takesValue:!0},{name:"--disable-issues",takesValue:!1},{name:"--disable-wiki",takesValue:!1},{name:"--gitignore",takesValue:!0},{name:"--homepage",takesValue:!1},{name:"--include-all-branches",takesValue:!1},{name:"--internal",takesValue:!1},{name:"--license",takesValue:!0},{name:"--private",takesValue:!1},{name:"--public",takesValue:!1},{name:"--push",takesValue:!1},{name:"--remote",takesValue:!0},{name:"--source",takesValue:!0},{name:"--team",takesValue:!0},{name:"--template",takesValue:!0}]},{path:["repo","delete"],args:["<repository>"],flags:[{name:"--yes",takesValue:!1}]},{path:["repo","deploy-key"],args:["<command>"],flags:[]},{path:["repo","edit"],args:["<repository>"],flags:[{name:"--accept-visibility-change-consequences",takesValue:!1},{name:"--add-topic",takesValue:!0},{name:"--allow-forking",takesValue:!1},{name:"--allow-update-branch",takesValue:!1},{name:"--default-branch",takesValue:!0},{name:"--delete-branch-on-merge",takesValue:!1},{name:"--description",takesValue:!0},{name:"--enable-advanced-security",takesValue:!1},{name:"--enable-auto-merge",takesValue:!1},{name:"--enable-discussions",takesValue:!1},{name:"--enable-issues",takesValue:!1},{name:"--enable-merge-commit",takesValue:!1},{name:"--enable-projects",takesValue:!1},{name:"--enable-rebase-merge",takesValue:!1},{name:"--enable-secret-scanning",takesValue:!1},{name:"--enable-secret-scanning-push-protection",takesValue:!1},{name:"--enable-squash-merge",takesValue:!1},{name:"--enable-wiki",takesValue:!1},{name:"--homepage",takesValue:!1},{name:"--remove-topic",takesValue:!0},{name:"--template",takesValue:!1},{name:"--visibility",takesValue:!0}]},{path:["repo","fork"],args:["<repository>"],flags:[{name:"--clone",takesValue:!1},{name:"--default-branch-only",takesValue:!1},{name:"--fork-name",takesValue:!0},{name:"--org",takesValue:!0},{name:"--remote",takesValue:!1},{name:"--remote-name",takesValue:!0}]},{path:["repo","gitignore"],args:["<command>"],flags:[]},{path:["repo","license"],args:["<command>"],flags:[]},{path:["repo","list"],args:["<owner>"],flags:[{name:"--archived",takesValue:!1},{name:"--fork",takesValue:!1},{name:"--jq",takesValue:!0},{name:"--json",takesValue:!0},{name:"--language",takesValue:!0},{name:"--limit",takesValue:!0},{name:"--no-archived",takesValue:!1},{name:"--source",takesValue:!1},{name:"--template",takesValue:!0},{name:"--topic",takesValue:!0},{name:"--visibility",takesValue:!0}]},{path:["repo","rename"],args:["<new-name>"],flags:[{name:"--yes",takesValue:!1}]},{path:["repo","set-default"],args:["<repository>"],flags:[{name:"--unset",takesValue:!1},{name:"--view",takesValue:!1}]},{path:["repo","sync"],args:["<destination-repository>"],flags:[{name:"--branch",takesValue:!0},{name:"--force",takesValue:!1},{name:"--source",takesValue:!0}]},{path:["repo","unarchive"],args:["<repository>"],flags:[{name:"--yes",takesValue:!1}]},{path:["repo","view"],args:["<repository>"],flags:[{name:"--branch",takesValue:!0},{name:"--jq",takesValue:!0},{name:"--json",takesValue:!0},{name:"--template",takesValue:!0},{name:"--web",takesValue:!1}]},{path:["ruleset","check"],args:["<branch>"],flags:[{name:"--default",takesValue:!1},{name:"--web",takesValue:!1}]},{path:["ruleset","list"],args:[],flags:[{name:"--limit",takesValue:!0},{name:"--org",takesValue:!0},{name:"--parents",takesValue:!1},{name:"--web",takesValue:!1}]},{path:["ruleset","view"],args:["<ruleset-id>"],flags:[{name:"--org",takesValue:!0},{name:"--parents",takesValue:!1},{name:"--web",takesValue:!1}]},{path:["run","cancel"],args:["<run-id>"],flags:[{name:"--force",takesValue:!1}]},{path:["run","delete"],args:["<run-id>"],flags:[]},{path:["run","download"],args:["<run-id>"],flags:[{name:"--dir",takesValue:!0},{name:"--name",takesValue:!0},{name:"--pattern",takesValue:!0}]},{path:["run","list"],args:[],flags:[{name:"--all",takesValue:!1},{name:"--branch",takesValue:!0},{name:"--commit",takesValue:!1},{name:"--created",takesValue:!0},{name:"--event",takesValue:!0},{name:"--jq",takesValue:!0},{name:"--json",takesValue:!0},{name:"--limit",takesValue:!0},{name:"--status",takesValue:!0},{name:"--template",takesValue:!0},{name:"--user",takesValue:!0},{name:"--workflow",takesValue:!0}]},{path:["run","rerun"],args:["<run-id>"],flags:[{name:"--debug",takesValue:!1},{name:"--failed",takesValue:!1},{name:"--job",takesValue:!0}]},{path:["run","view"],args:["<run-id>"],flags:[{name:"--attempt",takesValue:!0},{name:"--exit-status",takesValue:!1},{name:"--job",takesValue:!0},{name:"--jq",takesValue:!0},{name:"--json",takesValue:!0},{name:"--log",takesValue:!1},{name:"--log-failed",takesValue:!1},{name:"--template",takesValue:!0},{name:"--verbose",takesValue:!1},{name:"--web",takesValue:!1}]},{path:["run","watch"],args:["<run-id>"],flags:[{name:"--compact",takesValue:!1},{name:"--exit-status",takesValue:!1},{name:"--interval",takesValue:!0}]},{path:["search","code"],args:["<query>"],flags:[{name:"--extension",takesValue:!0},{name:"--filename",takesValue:!0},{name:"--jq",takesValue:!0},{name:"--json",takesValue:!0},{name:"--language",takesValue:!0},{name:"--limit",takesValue:!0},{name:"--match",takesValue:!0},{name:"--owner",takesValue:!0},{name:"--repo",takesValue:!0},{name:"--size",takesValue:!0},{name:"--template",takesValue:!0},{name:"--web",takesValue:!1}]},{path:["search","commits"],args:["<query>"],flags:[{name:"--author",takesValue:!0},{name:"--author-date",takesValue:!0},{name:"--author-email",takesValue:!0},{name:"--author-name",takesValue:!0},{name:"--committer",takesValue:!0},{name:"--committer-date",takesValue:!0},{name:"--committer-email",takesValue:!0},{name:"--committer-name",takesValue:!0},{name:"--hash",takesValue:!0},{name:"--jq",takesValue:!0},{name:"--json",takesValue:!0},{name:"--limit",takesValue:!0},{name:"--merge",takesValue:!1},{name:"--order",takesValue:!0},{name:"--owner",takesValue:!0},{name:"--parent",takesValue:!0},{name:"--repo",takesValue:!0},{name:"--sort",takesValue:!0},{name:"--template",takesValue:!0},{name:"--tree",takesValue:!0},{name:"--visibility",takesValue:!0},{name:"--web",takesValue:!1}]},{path:["search","issues"],args:["<query>"],flags:[{name:"--app",takesValue:!0},{name:"--archived",takesValue:!1},{name:"--assignee",takesValue:!0},{name:"--author",takesValue:!0},{name:"--closed",takesValue:!0},{name:"--commenter",takesValue:!0},{name:"--comments",takesValue:!0},{name:"--created",takesValue:!0},{name:"--include-prs",takesValue:!1},{name:"--interactions",takesValue:!0},{name:"--involves",takesValue:!0},{name:"--jq",takesValue:!0},{name:"--json",takesValue:!0},{name:"--label",takesValue:!0},{name:"--language",takesValue:!0},{name:"--limit",takesValue:!0},{name:"--locked",takesValue:!1},{name:"--match",takesValue:!0},{name:"--mentions",takesValue:!0},{name:"--milestone",takesValue:!0},{name:"--no-assignee",takesValue:!1},{name:"--no-label",takesValue:!1},{name:"--no-milestone",takesValue:!1},{name:"--no-project",takesValue:!1},{name:"--order",takesValue:!0},{name:"--owner",takesValue:!0},{name:"--project",takesValue:!0},{name:"--reactions",takesValue:!0},{name:"--repo",takesValue:!0},{name:"--sort",takesValue:!0},{name:"--state",takesValue:!0},{name:"--team-mentions",takesValue:!0},{name:"--template",takesValue:!0},{name:"--updated",takesValue:!0},{name:"--visibility",takesValue:!0},{name:"--web",takesValue:!1}]},{path:["search","prs"],args:["<query>"],flags:[{name:"--app",takesValue:!0},{name:"--archived",takesValue:!1},{name:"--assignee",takesValue:!0},{name:"--author",takesValue:!0},{name:"--base",takesValue:!0},{name:"--checks",takesValue:!0},{name:"--closed",takesValue:!0},{name:"--commenter",takesValue:!0},{name:"--comments",takesValue:!0},{name:"--created",takesValue:!0},{name:"--draft",takesValue:!1},{name:"--head",takesValue:!0},{name:"--interactions",takesValue:!0},{name:"--involves",takesValue:!0},{name:"--jq",takesValue:!0},{name:"--json",takesValue:!0},{name:"--label",takesValue:!0},{name:"--language",takesValue:!0},{name:"--limit",takesValue:!0},{name:"--locked",takesValue:!1},{name:"--match",takesValue:!0},{name:"--mentions",takesValue:!0},{name:"--merged",takesValue:!1},{name:"--merged-at",takesValue:!0},{name:"--milestone",takesValue:!0},{name:"--no-assignee",takesValue:!1},{name:"--no-label",takesValue:!1},{name:"--no-milestone",takesValue:!1},{name:"--no-project",takesValue:!1},{name:"--order",takesValue:!0},{name:"--owner",takesValue:!0},{name:"--project",takesValue:!0},{name:"--reactions",takesValue:!0},{name:"--repo",takesValue:!0},{name:"--review",takesValue:!0},{name:"--review-requested",takesValue:!0},{name:"--reviewed-by",takesValue:!0},{name:"--sort",takesValue:!0},{name:"--state",takesValue:!0},{name:"--team-mentions",takesValue:!0},{name:"--template",takesValue:!0},{name:"--updated",takesValue:!0},{name:"--visibility",takesValue:!0},{name:"--web",takesValue:!1}]},{path:["search","repos"],args:["<query>"],flags:[{name:"--archived",takesValue:!1},{name:"--created",takesValue:!0},{name:"--followers",takesValue:!0},{name:"--forks",takesValue:!0},{name:"--good-first-issues",takesValue:!0},{name:"--help-wanted-issues",takesValue:!0},{name:"--include-forks",takesValue:!0},{name:"--jq",takesValue:!0},{name:"--json",takesValue:!0},{name:"--language",takesValue:!0},{name:"--license",takesValue:!0},{name:"--limit",takesValue:!0},{name:"--match",takesValue:!0},{name:"--number-topics",takesValue:!0},{name:"--order",takesValue:!0},{name:"--owner",takesValue:!0},{name:"--size",takesValue:!0},{name:"--sort",takesValue:!0},{name:"--stars",takesValue:!0},{name:"--template",takesValue:!0},{name:"--topic",takesValue:!0},{name:"--updated",takesValue:!0},{name:"--visibility",takesValue:!0},{name:"--web",takesValue:!1}]},{path:["secret","delete"],args:["<secret-name>"],flags:[{name:"--app",takesValue:!0},{name:"--env",takesValue:!0},{name:"--org",takesValue:!0},{name:"--user",takesValue:!1}]},{path:["secret","list"],args:[],flags:[{name:"--app",takesValue:!0},{name:"--env",takesValue:!0},{name:"--jq",takesValue:!0},{name:"--json",takesValue:!0},{name:"--org",takesValue:!0},{name:"--template",takesValue:!0},{name:"--user",takesValue:!1}]},{path:["secret","set"],args:["<secret-name>"],flags:[{name:"--app",takesValue:!0},{name:"--body",takesValue:!0},{name:"--env",takesValue:!0},{name:"--env-file",takesValue:!0},{name:"--no-repos-selected",takesValue:!1},{name:"--no-store",takesValue:!1},{name:"--org",takesValue:!0},{name:"--repos",takesValue:!0},{name:"--user",takesValue:!1},{name:"--visibility",takesValue:!0}]},{path:["ssh-key","add"],args:["<key-file>"],flags:[{name:"--title",takesValue:!0},{name:"--type",takesValue:!0}]},{path:["ssh-key","delete"],args:["<id>"],flags:[{name:"--yes",takesValue:!1}]},{path:["ssh-key","list"],args:[],flags:[{name:"--exclude",takesValue:!0},{name:"--org",takesValue:!0}]},{path:["variable","delete"],args:["<variable-name>"],flags:[{name:"--env",takesValue:!0},{name:"--org",takesValue:!0}]},{path:["variable","get"],args:["<variable-name>"],flags:[{name:"--env",takesValue:!0},{name:"--jq",takesValue:!0},{name:"--json",takesValue:!0},{name:"--org",takesValue:!0},{name:"--template",takesValue:!0}]},{path:["variable","list"],args:[],flags:[{name:"--env",takesValue:!0},{name:"--jq",takesValue:!0},{name:"--json",takesValue:!0},{name:"--org",takesValue:!0},{name:"--template",takesValue:!0}]},{path:["variable","set"],args:["<variable-name>"],flags:[{name:"--body",takesValue:!0},{name:"--env",takesValue:!0},{name:"--env-file",takesValue:!0},{name:"--org",takesValue:!0},{name:"--repos",takesValue:!0},{name:"--visibility",takesValue:!0}]},{path:["workflow","disable"],args:["<workflow-id> | <workflow-name>"],flags:[]},{path:["workflow","enable"],args:["<workflow-id> | <workflow-name>"],flags:[]},{path:["workflow","list"],args:[],flags:[{name:"--all",takesValue:!1},{name:"--jq",takesValue:!0},{name:"--json",takesValue:!0},{name:"--limit",takesValue:!0},{name:"--template",takesValue:!0}]},{path:["workflow","run"],args:["<workflow-id> | <workflow-name>"],flags:[{name:"--field",takesValue:!0},{name:"--json",takesValue:!1},{name:"--raw-field",takesValue:!0},{name:"--ref",takesValue:!0}]},{path:["workflow","view"],args:["<workflow-id> | <workflow-name> | <filename>"],flags:[{name:"--ref",takesValue:!0},{name:"--web",takesValue:!1},{name:"--yaml",takesValue:!1}]},{path:["contents","create"],args:["<file-path>"],flags:[]},{path:["contents","view"],args:["<file-path>"],flags:[]},{path:["contents","list"],args:["<dir-path>"],flags:[]},{path:["contents","update"],args:["<file-path>"],flags:[]},{path:["contents","delete"],args:["<file-path>"],flags:[]}]};import{spawn as Ee}from"child_process";import Te from"crypto";var Pe=60000,je=(e)=>typeof e==="object"&&e!==null&&!Array.isArray(e),C=(e)=>{if(typeof e==="number"&&Number.isFinite(e)&&e>0)return Math.floor(e);if(typeof e!=="string")return null;let a=e.trim();if(!a)return null;let t=Number(a);if(!Number.isFinite(t)||t<=0)return null;return Math.floor(t)},Se=()=>{return C(process.env.F0_GIT_REQUEST_TIMEOUT_MS)??C(process.env.F0_HTTP_REQUEST_TIMEOUT_MS)??C(process.env.F0_HTTP_TIMEOUT_MS)??Pe},Re=(e)=>Object.fromEntries(e.map((a)=>{let t=a.indexOf(":");if(t<0)return null;let r=a.slice(0,t).trim(),s=a.slice(t+1).trim();return[r,s]}).filter((a)=>Boolean(a))),Ie=(e)=>{if(e.length===0||!je(e[e.length-1]))return{args:e.map((t)=>String(t)),options:{}};let a=e[e.length-1];return{args:e.slice(0,-1).map((t)=>String(t)),options:a}},J=(e)=>e.replace(/^--/,"").trim().toLowerCase(),xe=(e,a)=>{let t={},r={},s=new Map;for(let o of e.flags){let u=J(o.name);s.set(u,o.name)}let l=new Set(["body","json","data","payload","headers","query","method"]);for(let[o,u]of Object.entries(a)){let i=J(o);if(u===void 0)continue;if(l.has(i))continue;if(s.has(i)){let m=s.get(i);if(m)t[m]=typeof u==="boolean"?u:String(u);continue}r[o]=u}return{flags:t,unhandled:r}},Fe=(e,a,t)=>{if(!["POST","PUT","PATCH","DELETE"].includes(e.toUpperCase()))return;if(a.body!==void 0)return a.body;if(a.json!==void 0)return a.json;if(a.data!==void 0)return a.data;if(a.payload!==void 0)return a.payload;if(Object.keys(t).length>0)return t;return},_e=(e,a,t,r={})=>{let s=`${e}/${a.join("/")}`,l=new URL(s);for(let o of t){let[u,i=""]=o.split("=",2);if(!u)continue;l.searchParams.set(u,i)}for(let[o,u]of Object.entries(r))l.searchParams.set(o,String(u));return l.toString()},Oe=()=>typeof AbortSignal<"u"&&typeof AbortSignal.timeout==="function",$e=()=>Boolean(process.env.VITEST)||!1,Ce=(e)=>{let a=(e??"").trim().toLowerCase();if(a==="fetch"||a==="curl")return a;let t=Boolean(process.versions?.bun);if(!$e()&&t&&process.platform==="win32")return"curl";return"fetch"},K=async(e)=>{if(!e)return Buffer.from([]);let a=[];for await(let t of e)if(typeof t==="string")a.push(Buffer.from(t));else a.push(Buffer.from(t));return Buffer.concat(a)},De=async(e,a,t)=>{let r=process.platform==="win32"?"curl.exe":"curl",l=`
3
- __F0_CURL_STATUS_${Te.randomBytes(8).toString("hex")}__`,o=`${l}%{http_code}${l}`,u=["--silent","--show-error","--location","--request",a.method,"--write-out",o],i=t>0?Math.max(1,Math.ceil(t/1000)):null;if(i!==null)u.push("--max-time",String(i));for(let[d,f]of Object.entries(a.headers))u.push("--header",`${d}: ${f}`);if(a.body!==void 0)u.push("--data-binary","@-");u.push(e);let m=Ee(r,u,{stdio:["pipe","pipe","pipe"],windowsHide:!0});if(a.body!==void 0)m.stdin.write(a.body);m.stdin.end();let[V,G]=await Promise.all([K(m.stdout),K(m.stderr)]),h=await new Promise((d)=>{m.on("close",(f)=>d(f??0)),m.on("error",()=>d(1))}),g=V.toString("utf8"),k=G.toString("utf8").trim();if(h!==0){let d=k||`curl failed with exit code ${h}`;if(h===28&&t>0)throw Error(`Request timed out after ${t}ms: ${a.method} ${e}`);throw Error(d)}let c=g.lastIndexOf(l),w=c>-1?g.lastIndexOf(l,c-1):-1;if(w<0||c<0)throw Error("Failed to parse curl response status code.");let b=g.slice(w+l.length,c).trim(),p=Number(b),E=g.slice(0,w);if(!Number.isFinite(p)||p<=0)throw Error(`Invalid curl status code: ${b}`);return{status:p,ok:p>=200&&p<300,bodyText:E,responseHeaders:{}}},He=(e,a,t,r,s,l)=>{return async(...o)=>{let{args:u,options:i}=Ie(o),{flags:m,unhandled:V}=xe(e,i),{query:G,method:h,...g}=i,k=await a.mapFeature({feature:e,args:u,flagValues:m,method:h}),c=k.mappedPath.map((f)=>{if(f==="{owner}"&&t.defaultOwner)return t.defaultOwner;if(f==="{repo}"&&t.defaultRepo)return t.defaultRepo;return f}),w=Fe(k.method,g,V),b={...Re(k.headers),...i.headers??{}};if(w!==void 0&&!b["Content-Type"])b["Content-Type"]="application/json";let p=_e(k.apiBase,c,k.query,G??{}),E={method:k.method,headers:b,body:w!==void 0?JSON.stringify(w):void 0},d=Date.now();l?.(`http:request ${k.method} ${p}`);try{let f={},y=0,v=!1,j="";if(s==="curl"){let T=await De(p,{method:k.method,headers:b,...E.body!==void 0?{body:String(E.body)}:{}},r);y=T.status,v=T.ok;let P=T.bodyText;j=P;try{j=JSON.parse(P)}catch{j=P}}else{let T=r>0&&Oe()?AbortSignal.timeout(r):null,P=!T&&r>0?new AbortController:null,B=P?setTimeout(()=>P.abort(),r):null;try{let S=await fetch(p,{...E,...T?{signal:T}:{},...P?{signal:P.signal}:{}});y=S.status,v=S.ok;let H=await S.text();j=H;try{j=JSON.parse(H)}catch{j=H}try{S.headers.forEach((se,re)=>{f[re.toLowerCase()]=se})}catch{}}catch(S){if(T&&T.aborted||P?.signal.aborted)throw Error(`Request timed out after ${r}ms: ${k.method} ${p}`);throw S}finally{if(B)clearTimeout(B)}}return l?.(`http:response ${k.method} ${p} -> ${y} (${Date.now()-d}ms)`),{mapping:{...k,mappedPath:c},request:{url:p,method:k.method,headers:b,query:[...k.query],body:w},response:{headers:f},status:y,ok:v,body:j}}catch(f){let y=f instanceof Error?f.message:String(f);throw l?.(`http:error ${k.method} ${p} (${y})`),f}}},X=(e,a,t,r,s,l,o,u)=>{let i=e;for(let m=0;m<a.length;m+=1){let V=a[m];if(m===a.length-1){i[V]=He(t,r,s,l,o,u);continue}if(!i[V])i[V]={};let h=i[V];if(typeof h!=="object"||h===null)i[V]={};i=i[V]}},Y=(e={})=>{let a=F(e.config),t=$({config:a,...e.swaggerSpec?{swaggerSpec:e.swaggerSpec}:{}}),r=C(e.requestTimeoutMs)??Se(),s=Ce(e.httpTransport??process.env.F0_GIT_HTTP_TRANSPORT),l=e.log,o={defaultOwner:e.defaultOwner??process.env.GITEA_TEST_OWNER??"F0",defaultRepo:e.defaultRepo??process.env.GITEA_TEST_REPO??"_test"},u={};for(let i of z.features){if(i.path.length===0)continue;if(X(u,i.path,i,t,o,r,s,l),i.path[0]!=="repo")X(u,["repo",...i.path],i,t,o,r,s,l)}return u},qe=Y();import{spawn as Le}from"child_process";import Ne from"crypto";var Be="https://gitea.machian.com",Me=60000,N=(e)=>{if(typeof e==="number"&&Number.isFinite(e)&&e>0)return Math.floor(e);if(typeof e!=="string")return null;let a=e.trim();if(!a)return null;let t=Number(a);if(!Number.isFinite(t)||t<=0)return null;return Math.floor(t)},ae=()=>{return N(process.env.F0_GIT_REQUEST_TIMEOUT_MS)??N(process.env.F0_HTTP_REQUEST_TIMEOUT_MS)??N(process.env.F0_HTTP_TIMEOUT_MS)??Me},Ue=()=>typeof AbortSignal<"u"&&typeof AbortSignal.timeout==="function",We=()=>Boolean(process.env.VITEST)||!1,Qe=(e)=>{let a=(e??"").trim().toLowerCase();if(a==="fetch"||a==="curl")return a;let t=Boolean(process.versions?.bun);if(!We()&&t&&process.platform==="win32")return"curl";return"fetch"},ze=async(e,a)=>{let t=ae();if(!Number.isFinite(t)||t<=0)return fetch(e,a);let r=t>0&&Ue()?AbortSignal.timeout(t):null,s=!r?new AbortController:null,l=s?setTimeout(()=>s.abort(),t):null;try{return await fetch(e,{...a,...r?{signal:r}:{},...s?{signal:s.signal}:{}})}catch(o){if(r&&r.aborted||s?.signal.aborted)throw Error(`Request timed out after ${t}ms: ${a.method??"GET"} ${e}`);throw o}finally{if(l)clearTimeout(l)}},Z=async(e)=>{if(!e)return Buffer.from([]);let a=[];for await(let t of e)if(typeof t==="string")a.push(Buffer.from(t));else a.push(Buffer.from(t));return Buffer.concat(a)},Je=async(e,a,t)=>{let r=process.platform==="win32"?"curl.exe":"curl",l=`
4
- __F0_CURL_STATUS_${Ne.randomBytes(8).toString("hex")}__`,o=`${l}%{http_code}${l}`,u=["--silent","--show-error","--location","--request",a.method,"--write-out",o],i=t>0?Math.max(1,Math.ceil(t/1000)):null;if(i!==null)u.push("--max-time",String(i));for(let[d,f]of Object.entries(a.headers))u.push("--header",`${d}: ${f}`);if(a.body!==void 0)u.push("--data-binary","@-");u.push(e);let m=Le(r,u,{stdio:["pipe","pipe","pipe"],windowsHide:!0});if(a.body!==void 0)m.stdin.write(a.body);m.stdin.end();let[V,G]=await Promise.all([Z(m.stdout),Z(m.stderr)]),h=await new Promise((d)=>{m.on("close",(f)=>d(f??0)),m.on("error",()=>d(1))}),g=V.toString("utf8"),k=G.toString("utf8").trim();if(h!==0){let d=k||`curl failed with exit code ${h}`;if(h===28&&t>0)throw Error(`Request timed out after ${t}ms: ${a.method} ${e}`);throw Error(d)}let c=g.lastIndexOf(l),w=c>-1?g.lastIndexOf(l,c-1):-1;if(w<0||c<0)throw Error("Failed to parse curl response status code.");let b=g.slice(w+l.length,c).trim(),p=Number(b),E=g.slice(0,w);if(!Number.isFinite(p)||p<=0)throw Error(`Invalid curl status code: ${b}`);return{status:p,ok:p>=200&&p<300,bodyText:E}},R=(e)=>{let a=Number(e);if(!Number.isFinite(a)||a<=0||Math.floor(a)!==a)return null;return a},ee=(e)=>{let a=[];if(!e)return a;let t=R(e.number);if(t!==null)a.push(t);let r=R(e.index);if(r!==null)a.push(r);let s=e.issue;if(s&&typeof s==="object"&&!Array.isArray(s)){let l=s,o=R(l.number);if(o!==null)a.push(o);let u=R(l.index);if(u!==null)a.push(u)}return a};function I(e){let a=[];if(Array.isArray(e)){for(let t of e){if(!t||typeof t!=="object"||Array.isArray(t))continue;let r=t,s=R(r.number);if(s!==null)a.push(s);let l=R(r.index);if(l!==null)a.push(l);a.push(...ee(r))}return[...new Set(a)]}if(e&&typeof e==="object"&&!Array.isArray(e)){let t=e;if(Array.isArray(t.dependencies))return I(t.dependencies);if(Array.isArray(t.blocks))return I(t.blocks);if(Array.isArray(t.issues))return I(t.issues);return ee(t)}return[]}var te=(e)=>{let a=e.trim().replace(/\/$/,"");return a.endsWith("/api/v1")?a:`${a}/api/v1`},Ke=(e,a,t,r)=>{return`${te(e)}/repos/${encodeURIComponent(a)}/${encodeURIComponent(t)}/issues/${r}/dependencies`};async function _(e,a,t,r,s=Be,l,o){let u=Ke(s,a,t,r),i={Accept:"application/json",...l?{Authorization:`token ${l}`}:{},...o?{"Content-Type":"application/json"}:{}},m=ae(),V=Qe(process.env.F0_GIT_HTTP_TRANSPORT),G=!1,h=0,g="",k="";if(V==="curl"){let c=await Je(u,{method:e,headers:i,...o?{body:JSON.stringify(o)}:{}},m);G=c.ok,h=c.status,k=c.bodyText}else{let c=await ze(u,{method:e,headers:i,body:o?JSON.stringify(o):void 0});G=c.ok,h=c.status,k=await c.text()}g=k;try{g=JSON.parse(k)}catch{}return{ok:G,status:h,body:g,mapping:{featurePath:["issue","dependencies"],mappedPath:["issue","dependencies"],method:e,query:[],headers:[],apiBase:te(s),swaggerPath:"/repos/{owner}/{repo}/issues/{index}/dependencies",mapped:!0},request:{url:u,method:e,headers:{Accept:"application/json",...o?{"Content-Type":"application/json"}:{}},query:[],body:o},response:{headers:{}}}}async function Xe(e,a,t,r,s,l,o,u){let i=await _("GET",e,a,t,s,l);if(!i.ok)throw Error(`Failed to load issue dependencies for #${t}: status=${i.status} url=${i.request.url}`);let m=I(i.body),V=[...new Set(r.filter((p)=>p>0))],G=new Set(m),h=new Set(V),g=V.filter((p)=>!G.has(p)),k=m.filter((p)=>!h.has(p)),c=V.filter((p)=>G.has(p)).length;if(u)if(g.length>0||k.length>0)u(`Issue #${t}: dependency sync [add=${g.join(",")||"none"}, remove=${k.join(",")||"none"}]`);else u(`Issue #${t}: dependency sync already correct`);let w=0,b=0;if(!o){for(let y of k){let v=await _("DELETE",e,a,t,s,l,{index:y,owner:e,repo:a});if(!v.ok)throw Error(`Failed to remove dependency ${y} from issue #${t}: status=${v.status} url=${v.request.url}`);b+=1}for(let y of g){let v=await _("POST",e,a,t,s,l,{index:y,owner:e,repo:a});if(!v.ok)throw Error(`Failed to add dependency ${y} to issue #${t}: status=${v.status} url=${v.request.url}`);w+=1}let p=await _("GET",e,a,t,s,l);if(!p.ok)throw Error(`Failed to verify dependencies for issue #${t}: status=${p.status} url=${p.request.url}`);let E=I(p.body),d=new Set(E),f=V.filter((y)=>!d.has(y));if(f.length>0)throw Error(`Dependency sync mismatch for issue #${t}. Missing dependencies: ${f.join(", ")}`)}return{added:w,removed:b,unchanged:c}}import D from"fs";import A from"path";function Ye(e){try{if(e.startsWith("http://")||e.startsWith("https://")||e.startsWith("ssh://")){let t=new URL(e).pathname.split("/").filter(Boolean);if(t.length>=2){let r=t[t.length-2],l=t[t.length-1].replace(/\.git$/,"");return{owner:r,repo:l}}}if(e.startsWith("git@")){let a=e.split(":",2);if(a.length===2){let t=a[1].split("/").filter(Boolean);if(t.length>=2){let r=t[t.length-2],s=t[t.length-1].replace(/\.git$/,"");return{owner:r,repo:s}}}}}catch{return null}return null}function Ze(e){let a="";try{a=D.readFileSync(e,"utf8")}catch{return null}for(let t of a.split(/\r?\n/)){let r=t.trim();if(!r.startsWith("url"))continue;let s=r.match(/^url\s*=\s*(.+?)\s*$/);if(!s)continue;let l=Ye(s[1].trim());if(l)return l}return null}function ea(e){let a="";try{a=D.readFileSync(e,"utf8")}catch{return null}let r=a.trim().match(/^gitdir:\s*(.+)$/i);if(!r)return null;let s=r[1].trim();if(!s)return null;if(A.isAbsolute(s))return s;let l=A.dirname(e);while(!0){let o=A.resolve(l,s);try{if(D.statSync(o).isDirectory())return o}catch{}let u=A.dirname(l);if(u===l)break;l=u}return A.resolve(A.dirname(e),s)}function aa(e){let a;try{a=D.statSync(e)}catch{return null}if(a.isDirectory())return A.join(e,"config");if(a.isFile()){let t=ea(e);if(!t)return null;return A.join(t,"config")}return null}function ta(e){let a=[A.join(e,"code",".git"),A.join(e,".git")];for(let t of a){let r=aa(t);if(!r)continue;let s=Ze(r);if(s)return s}return null}export{Xe as syncIssueDependencies,ta as resolveProjectRepoIdentity,Ae as mapGitServiceFeature,qe as gitServiceApi,F as getGitPlatformConfig,I as extractDependencyIssueNumbers,ne as createRemoteGitApiClient,Y as createGitServiceApi,$ as createGitPlatformAdapter,_ as callIssueDependenciesApi,x as buildGitApiMockResponse,L as RemoteGitApiClient,O as GiteaPlatformAdapter,q as GIT_API_VERSION};