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
23 changes: 20 additions & 3 deletions packages/cli/src/utils/commands2md.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,28 @@ function escapeHtml(value: string): string {
.replaceAll('>', '>')
}

function renderDefaultValue(value: unknown): string | undefined {
if (value === undefined || typeof value === 'function') return undefined
if (typeof value === 'symbol') return undefined
if (typeof value !== 'object' || value === null) return String(value)

const serialized = JSON.stringify(value, (_key, item: unknown) => {
if (item && typeof item === 'object' && !Array.isArray(item)) {
return Object.fromEntries(
Object.entries(item).sort(([left], [right]) =>
left.localeCompare(right)
)
)
}
return item
})
return serialized === '{}' ? undefined : serialized
}

function renderOption(option: Option): string {
const defaultValue = renderDefaultValue(option.defaultValue)
const fallback =
option.defaultValue === undefined
? ''
: ` Default: \`${String(option.defaultValue)}\`.`
defaultValue === undefined ? '' : ` Default: \`${defaultValue}\`.`
return `- \`${escapeHtml(option.flags)}\`: ${escapeHtml(option.description || 'No description.')}${fallback}`
}

Expand Down
46 changes: 46 additions & 0 deletions packages/cli/tests/utils/commands2md.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { Command, Option } from 'commander'
import { readFileSync, rmSync } from 'node:fs'
import { tmpdir } from 'node:os'
import path from 'node:path'
import { afterEach, describe, expect, test } from 'vitest'
import { commands2md } from '../../src/utils/commands2md'

const outputDir = path.join(
tmpdir(),
`agentbox-cli-reference-${process.pid}-${Date.now()}`
)

afterEach(() => rmSync(outputDir, { recursive: true, force: true }))

describe('commands2md defaults', () => {
test('omits empty objects and serializes structured defaults', () => {
const configure = new Command('configure')
const sandbox = new Command('sandbox')
.addOption(
new Option('-e, --env <KEY=VALUE>', 'environment variables').default({})
)
.addOption(
new Option('--labels <JSON>', 'labels').default({ zebra: 2, alpha: 1 })
)
.addOption(new Option('--ports <PORT>', 'ports').default([8080, 8081]))
.addOption(new Option('--format <FORMAT>', 'format').default('pretty'))
const template = new Command('template')

commands2md([configure, sandbox, template], outputDir)

const markdown = readFileSync(path.join(outputDir, 'sandbox.md'), 'utf8')
expect(markdown).not.toContain('[object Object]')
expect(markdown).toContain(
'- `--labels &lt;JSON&gt;`: labels Default: `{"alpha":1,"zebra":2}`.'
)
expect(markdown).toContain(
'- `--ports &lt;PORT&gt;`: ports Default: `[8080,8081]`.'
)
expect(markdown).toContain(
'- `--format &lt;FORMAT&gt;`: format Default: `pretty`.'
)
expect(markdown).toContain(
'- `-e, --env &lt;KEY=VALUE&gt;`: environment variables\n'
)
})
})
2 changes: 1 addition & 1 deletion reference/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
"openapi/markdown/uploadFile.md": "acf5f7029d2b4de2ce96b50bb24f5e4495c188dfed878851ffe2f91e5b7b24d3",
"openapi/operations.json": "1593bd80b73d87117a5ebf8211d0ba014e0170c84fca5fe9f1a82ec457a6b575",
"sdk/cli/auth.md": "0b2c75262b0c0670c7bc0f0f3cbed65fbe4a16d6fe4437789a5685b8bf2174a1",
"sdk/cli/sandbox.md": "0f59649197a6f42282a8b789c4384e8e41d2e525de414a22dffe073f0fca4d64",
"sdk/cli/sandbox.md": "16b64c5a4e932eca2452e400e0faf154eba1d3c7373513aa7cd9744e02908313",
"sdk/cli/template.md": "f270b22b9ee10a9b954a14f24e04c5449b4d5823bb28002ffde3ed682594cfc5",
"sdk/javascript/code-interpreter/README.md": "a787206eb86f81fc306b373ce20bc6c91464b0ab3c3ec7650eccbb6be5f676c5",
"sdk/javascript/code-interpreter/classes/Sandbox.md": "0c380df735431ad98397ec32920159e4c6ba103e600603551ded77b2f472839a",
Expand Down
6 changes: 3 additions & 3 deletions reference/sdk/cli/sandbox.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ agentbox sandbox connect [options] <sandboxID>

- `-u, --user &lt;user&gt;`: user to start the terminal session as
- `-c, --cwd &lt;dir&gt;`: working directory for the terminal session
- `-e, --env &lt;KEY=VALUE&gt;`: set environment variable for the terminal session (repeatable) Default: `[object Object]`.
- `-e, --env &lt;KEY=VALUE&gt;`: set environment variable for the terminal session (repeatable)

## agentbox sandbox create

Expand All @@ -44,7 +44,7 @@ agentbox sandbox create [options] [template]
- `--timeout &lt;seconds&gt;`: sandbox timeout in seconds
- `-u, --user &lt;user&gt;`: user to start the terminal session as
- `-c, --cwd &lt;dir&gt;`: working directory for the terminal session
- `-e, --env &lt;KEY=VALUE&gt;`: set environment variable for the terminal session (repeatable) Default: `[object Object]`.
- `-e, --env &lt;KEY=VALUE&gt;`: set environment variable for the terminal session (repeatable)

## agentbox sandbox exec

Expand All @@ -61,7 +61,7 @@ agentbox sandbox exec [options] <sandboxID> <command...>
- `-b, --background`: run in background and return immediately
- `-c, --cwd &lt;dir&gt;`: working directory
- `-u, --user &lt;user&gt;`: run as specified user
- `-e, --env &lt;KEY=VALUE&gt;`: set environment variable (repeatable) Default: `[object Object]`.
- `-e, --env &lt;KEY=VALUE&gt;`: set environment variable (repeatable)

## agentbox sandbox info

Expand Down
5 changes: 5 additions & 0 deletions scripts/test-reference-contract.py
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,11 @@ def main() -> None:
for forbidden in FORBIDDEN_REFERENCE_PROPERTIES:
assert forbidden not in rendered_markdown

cli_markdown = "\n".join(
path.read_text() for path in (REFERENCE / "sdk/cli").glob("*.md")
)
assert "[object Object]" not in cli_markdown

javascript_files = {
str(path.relative_to(REFERENCE))
for path in (REFERENCE / "sdk/javascript").rglob("*.md")
Expand Down
Loading