Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
*
!codegen.Dockerfile
2 changes: 2 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ codegen-image:
generate-in-container:
cd packages/js-sdk && pnpm generate
cd packages/python-sdk && make generate
python scripts/generate-reference.py
python scripts/test-reference-contract.py

# Maintainer-only update from a local mono checkout.
sync-specs:
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ The CLI stores local configuration in `~/.agentbox/config.json`; environment var
- [Templates and builds](https://docs.agentbox.ru/en/sdk/templates/)
- [Code Interpreter](https://docs.agentbox.ru/en/sdk/code-interpreter/)
- [CLI](https://docs.agentbox.ru/en/cli/)
- [API reference](https://docs.agentbox.ru/en/sdk/api-reference/)
- [API reference](https://docs.agentbox.ru/en/api-reference/)
- [Examples](https://docs.agentbox.ru/en/examples/)

## Development
Expand Down
4 changes: 4 additions & 0 deletions codegen.Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,8 @@ RUN npm install -g \
@bufbuild/protoc-gen-es@2.6.2 \
@redocly/cli@2.46.1

RUN pip install griffe2md==1.5.0

RUN npm install -g tsx@4.20.6

CMD ["make", "generate"]
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@
"oxlint": "^1.78.0",
"prettier": "^3.6.2",
"tsdown": "catalog:",
"tsx": "4.20.6",
"typedoc": "0.28.20",
"typedoc-plugin-markdown": "4.13.0",
"typescript": "catalog:",
"vitest": "catalog:"
},
Expand Down
5 changes: 2 additions & 3 deletions packages/cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,16 +45,15 @@
"test": "vitest run",
"test:watch": "vitest watch",
"test:coverage": "vitest run --coverage",
"reference": "tsx src/reference.ts",
"check-deps": "knip"
},
"devDependencies": {
"@types/inquirer": "^9.0.10",
"@types/json2md": "^1.5.4",
"@types/node": "catalog:",
"@types/statuses": "^2.0.6",
"@typescript/native": "catalog:",
"@vitest/coverage-v8": "catalog:",
"json2md": "^2.0.3",
"knip": "^5.43.6",
"tsdown": "catalog:",
"typescript": "catalog:",
Expand All @@ -71,12 +70,12 @@
"agentbox": "dist/index.js"
},
"dependencies": {
"@abox-dev/sdk": "workspace:^",
"@inquirer/prompts": "^7.9.0",
"boxen": "^7.1.1",
"chalk": "^5.3.0",
"cli-highlight": "^2.1.11",
"commander": "^11.1.0",
"@abox-dev/sdk": "workspace:^",
"inquirer": "^12.10.0",
"simple-update-notifier": "^2.0.0",
"simple-wcswidth": "^1.1.2",
Expand Down
11 changes: 0 additions & 11 deletions packages/cli/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
#!/usr/bin/env -S node --enable-source-maps

import simpleUpdateNotifier from 'simple-update-notifier'
import * as commander from 'commander'
import * as packageJSON from '../package.json'
import { program } from './commands'
import { commands2md } from './utils/commands2md'

export const pkg = packageJSON

Expand All @@ -23,15 +21,6 @@ const prog = program.version(
'display AgentBox CLI version'
)

if (process.env.NODE_ENV === 'development') {
prog
.addOption(new commander.Option('-cmd2md').hideHelp())
.on('option:-cmd2md', () => {
commands2md(program.commands as any)
process.exit(0)
})
}

async function main() {
await prog.parseAsync()
await updateCheck
Expand Down
11 changes: 11 additions & 0 deletions packages/cli/src/reference.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import path from 'node:path'

import { program } from './commands'
import { commands2md } from './utils/commands2md'

const destination = process.argv[2]
if (!destination) {
throw new Error('Usage: pnpm reference OUTPUT_DIR')
}

commands2md(program.commands, path.resolve(destination))
138 changes: 63 additions & 75 deletions packages/cli/src/utils/commands2md.ts
Original file line number Diff line number Diff line change
@@ -1,85 +1,73 @@
import { Command } from 'commander'
import fs from 'fs'
import json2md from 'json2md'
import path from 'path'
import { Command, Option } from 'commander'
import fs from 'node:fs'
import path from 'node:path'

/**
* Converts command objects to Markdown documentation.
* This function takes an array of command objects and generates a structured
* Markdown document describing each command, its usage, options, and subcommands.
* @returns A string containing the entire markdown documentation for all commands.
*/
export function commands2md(commands: Command[]): void {
const outputDir = 'sdk_ref'
if (!fs.existsSync(outputDir)) {
fs.mkdirSync(outputDir, { recursive: true })
}
function escapeHtml(value: string): string {
return value
.replaceAll('&', '&')
.replaceAll('<', '&lt;')
.replaceAll('>', '&gt;')
}

function commandToMd(
command: any,
parentName: string = ''
): [string, string] {
const commandName = command.name() as string
const fullName = parentName ? `${parentName} ${commandName}` : commandName
function renderOption(option: Option): string {
const fallback =
option.defaultValue === undefined
? ''
: ` Default: \`${String(option.defaultValue)}\`.`
return `- \`${escapeHtml(option.flags)}\`: ${escapeHtml(option.description || 'No description.')}${fallback}`
}

const mdStructure = [
{ h2: `agentbox ${fullName}` },
{ p: command.description() },
{ h3: 'Usage' },
{
code: {
language: 'bash',
content: `agentbox ${fullName} ${command.usage()}`,
},
},
...(command.options.length > 0
? [
{ h3: 'Options' },
{
ul: command.options.map(
(y: any) =>
`\`${y.flags}: ${y.description} ${
y.defaultValue !== undefined
? `[default: ${y.defaultValue}]`
: ''
}\``
),
},
]
: []),
]
function renderCommand(command: Command, parents: string[] = []): string {
const fullName = [...parents, command.name()].join(' ')
const usage = command.usage() || '[options]'
const lines = [
`## agentbox ${fullName}`,
'',
escapeHtml(command.description() || 'No description.'),
'',
'### Usage',
'',
'```bash',
`agentbox ${fullName} ${usage}`.trimEnd(),
'```',
'',
]

let mdContent = json2md(mdStructure)
if (command.options.length) {
lines.push('### Options', '', ...command.options.map(renderOption), '')
}

// Process subcommands
command.commands.forEach((subcommand: any) => {
const [, subMdContent] = commandToMd(subcommand, fullName)
mdContent += subMdContent + '\n\n'
})
for (const subcommand of [...command.commands].sort((a, b) =>
a.name().localeCompare(b.name())
)) {
lines.push(renderCommand(subcommand, [...parents, command.name()]))
}
return lines.join('\n')
}

// Clean the mdContent from terminal colors and escape HTML characters
mdContent = mdContent
.replace(/</g, '<')
.replace(/>/g, '>')
.replace(/\[1m/g, '')
.replace(/\[22m/g, '')
.replace(/\[34m/g, '')
.replace(/\[39m/g, '')
.replace(/\[38;2;255;183;102m/g, '')
export function commands2md(
commands: readonly Command[],
outputDir: string
): void {
fs.rmSync(outputDir, { recursive: true, force: true })
fs.mkdirSync(outputDir, { recursive: true })

return [fullName, mdContent]
}
const groups = new Map<string, Command[]>([
['auth', commands.filter((command) => command.name() === 'configure')],
['sandbox', commands.filter((command) => command.name() === 'sandbox')],
['template', commands.filter((command) => command.name() === 'template')],
])

commands.forEach((command: any) => {
try {
const [commandName, mdContent] = commandToMd(command)
const fileName = `${commandName}.md`
const filePath = path.join(outputDir, fileName)
fs.writeFileSync(filePath, mdContent)
console.log(`Generated documentation for ${commandName} at ${filePath}`)
} catch (error) {
console.error(`Error processing command: ${command.name()}`)
console.error(error)
for (const [group, groupCommands] of groups) {
if (!groupCommands.length) {
throw new Error(`CLI reference group ${group} has no commands`)
}
})
const title = group[0].toUpperCase() + group.slice(1)
const markdown = [
`# ${title} commands`,
'',
...groupCommands.map((command) => renderCommand(command)),
].join('\n')
fs.writeFileSync(path.join(outputDir, `${group}.md`), `${markdown}\n`)
}
}
2 changes: 1 addition & 1 deletion packages/code-interpreter-js/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,4 @@ try {
}
```

See the [Code Interpreter guide](https://docs.agentbox.ru/en/sdk/code-interpreter/) and [API reference](https://docs.agentbox.ru/en/sdk/api-reference/javascript/code-interpreter/).
See the [Code Interpreter guide](https://docs.agentbox.ru/en/sdk/code-interpreter/) and [API reference](https://docs.agentbox.ru/en/sdk-reference/javascript/code-interpreter/).
2 changes: 1 addition & 1 deletion packages/code-interpreter-python/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,4 @@ with Sandbox.create() as sandbox:
print(execution.text)
```

`AsyncSandbox` provides the equivalent async API. See the [Code Interpreter guide](https://docs.agentbox.ru/en/sdk/code-interpreter/) and [API reference](https://docs.agentbox.ru/en/sdk/api-reference/python/code-interpreter/).
`AsyncSandbox` provides the equivalent async API. See the [Code Interpreter guide](https://docs.agentbox.ru/en/sdk/code-interpreter/) and [API reference](https://docs.agentbox.ru/en/sdk-reference/python/code-interpreter/).
2 changes: 1 addition & 1 deletion packages/code-interpreter-python/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ dependencies = [

[project.urls]
Homepage = "https://docs.agentbox.ru/en/sdk/code-interpreter/"
Documentation = "https://docs.agentbox.ru/en/sdk/api-reference/python/code-interpreter/"
Documentation = "https://docs.agentbox.ru/en/sdk-reference/python/code-interpreter/"
Repository = "https://github.com/abox-dev/sdk/tree/main/packages/code-interpreter-python"
"Bug Tracker" = "https://github.com/abox-dev/sdk/issues"

Expand Down
2 changes: 1 addition & 1 deletion packages/js-sdk/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,4 @@ const client = new AgentBox({ apiKey: 'ab_...' })
const sandbox = await client.Sandbox.create()
```

Documentation: [core SDK](https://docs.agentbox.ru/en/sdk/), [sandboxes](https://docs.agentbox.ru/en/sdk/sandboxes/), [commands](https://docs.agentbox.ru/en/sdk/commands/), [files](https://docs.agentbox.ru/en/sdk/files/), [templates](https://docs.agentbox.ru/en/sdk/templates/), and [API reference](https://docs.agentbox.ru/en/sdk/api-reference/javascript/).
Documentation: [core SDK](https://docs.agentbox.ru/en/sdk/), [sandboxes](https://docs.agentbox.ru/en/sdk/sandboxes/), [commands](https://docs.agentbox.ru/en/sdk/commands/), [files](https://docs.agentbox.ru/en/sdk/files/), [templates](https://docs.agentbox.ru/en/sdk/templates/), and [API reference](https://docs.agentbox.ru/en/sdk-reference/javascript/).
2 changes: 1 addition & 1 deletion packages/python-sdk/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,4 @@ client = AgentBox(api_key="ab_...")
sandbox = await client.AsyncSandbox.create()
```

Documentation: [core SDK](https://docs.agentbox.ru/en/sdk/), [sandboxes](https://docs.agentbox.ru/en/sdk/sandboxes/), [commands](https://docs.agentbox.ru/en/sdk/commands/), [files](https://docs.agentbox.ru/en/sdk/files/), [templates](https://docs.agentbox.ru/en/sdk/templates/), and [API reference](https://docs.agentbox.ru/en/sdk/api-reference/python/).
Documentation: [core SDK](https://docs.agentbox.ru/en/sdk/), [sandboxes](https://docs.agentbox.ru/en/sdk/sandboxes/), [commands](https://docs.agentbox.ru/en/sdk/commands/), [files](https://docs.agentbox.ru/en/sdk/files/), [templates](https://docs.agentbox.ru/en/sdk/templates/), and [API reference](https://docs.agentbox.ru/en/sdk-reference/python/).
2 changes: 1 addition & 1 deletion packages/python-sdk/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ dependencies = [

[project.urls]
Homepage = "https://docs.agentbox.ru/en/sdk/"
Documentation = "https://docs.agentbox.ru/en/sdk/api-reference/python/"
Documentation = "https://docs.agentbox.ru/en/sdk-reference/python/"
Repository = "https://github.com/abox-dev/sdk/tree/main/packages/python-sdk"
"Bug Tracker" = "https://github.com/abox-dev/sdk/issues"

Expand Down
Loading
Loading