@sixb/cli-core 0.1.9 → 0.2.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 +21 -16
- package/dist/api-client.d.ts +1 -0
- package/dist/api-client.d.ts.map +1 -1
- package/dist/bin/sixb +26 -0
- package/dist/commands/data.d.ts +5 -0
- package/dist/commands/data.d.ts.map +1 -0
- package/dist/commands/files.d.ts.map +1 -1
- package/dist/commands/history.d.ts +7 -0
- package/dist/commands/history.d.ts.map +1 -0
- package/dist/commands/index.d.ts +1 -1
- package/dist/commands/index.d.ts.map +1 -1
- package/dist/commands/memory.d.ts +3 -0
- package/dist/commands/memory.d.ts.map +1 -0
- package/dist/commands/metadata.d.ts +11 -4
- package/dist/commands/metadata.d.ts.map +1 -1
- package/dist/commands/runs.d.ts +8 -1
- package/dist/commands/runs.d.ts.map +1 -1
- package/dist/commands/shared.d.ts +2 -0
- package/dist/commands/shared.d.ts.map +1 -1
- package/dist/commands/system.d.ts +21 -0
- package/dist/commands/system.d.ts.map +1 -0
- package/dist/commands/users.d.ts.map +1 -1
- package/dist/generated/sixb.mjs +2658 -0
- package/dist/index.d.ts +8 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +298 -58
- package/dist/index.js.map +21 -17
- package/dist/main.d.ts +3 -0
- package/dist/main.d.ts.map +1 -0
- package/dist/memory.d.ts +21 -0
- package/dist/memory.d.ts.map +1 -0
- package/dist/policies.d.ts +14 -0
- package/dist/policies.d.ts.map +1 -1
- package/dist/run.d.ts +1 -0
- package/dist/run.d.ts.map +1 -1
- package/dist/sandbox-cli.d.ts +8 -0
- package/dist/sandbox-cli.d.ts.map +1 -0
- package/package.json +15 -1
- package/src/api-client.ts +70 -2
- package/src/bin/sixb +26 -0
- package/src/commands/actions.ts +3 -3
- package/src/commands/data.ts +90 -0
- package/src/commands/files.ts +27 -3
- package/src/commands/history.ts +204 -0
- package/src/commands/index.ts +16 -0
- package/src/commands/memory.ts +358 -0
- package/src/commands/metadata.ts +76 -29
- package/src/commands/models.ts +3 -3
- package/src/commands/ontology.ts +2 -2
- package/src/commands/runs.ts +22 -16
- package/src/commands/shared.ts +6 -0
- package/src/commands/system.ts +67 -0
- package/src/commands/telemetry.ts +2 -2
- package/src/commands/users.ts +22 -2
- package/src/commands/workflows.ts +3 -3
- package/src/generated/sixb.mjs +2658 -0
- package/src/index.ts +12 -3
- package/src/main.ts +41 -0
- package/src/memory.ts +30 -0
- package/src/policies.ts +5 -0
- package/src/run.ts +3 -2
- package/src/sandbox-cli.ts +18 -0
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { readFile } from "node:fs/promises"
|
|
2
|
+
import { isHelp } from "../arguments"
|
|
3
|
+
import { CliError, EXIT_API, fail, INSTANCE_CLI_VERSION, writeJson, writeText } from "../output"
|
|
4
|
+
import { createInstanceApiClient, type SandboxInstanceCliMode } from "../run"
|
|
5
|
+
import { asRecord, isFileError } from "./shared"
|
|
6
|
+
|
|
7
|
+
/** The sandbox runtime `sixb status` reports and the agent worker's preflight expects. */
|
|
8
|
+
export const AGENT_RUNTIME_PROFILE = "sixb-agent-runtime/v1" as const
|
|
9
|
+
|
|
10
|
+
/** Stable JSON emitted by `sixb status` in a sandbox and consumed by worker preflight. */
|
|
11
|
+
export interface SandboxStatusReport {
|
|
12
|
+
readonly ok: true
|
|
13
|
+
readonly profile: typeof AGENT_RUNTIME_PROFILE
|
|
14
|
+
readonly cli: { readonly version: string }
|
|
15
|
+
readonly javascript: {
|
|
16
|
+
readonly name: "bun" | "node"
|
|
17
|
+
readonly version: string
|
|
18
|
+
}
|
|
19
|
+
readonly project: { readonly id: string }
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export async function status(args: readonly string[], mode: SandboxInstanceCliMode): Promise<void> {
|
|
23
|
+
if (isHelp(args[0])) return writeText("Usage: sixb status")
|
|
24
|
+
// Its output is JSON either way: --json, which people's `sixb status` takes, changes nothing.
|
|
25
|
+
if (args.some((arg) => arg !== "--json")) fail("status accepts no arguments but --json.")
|
|
26
|
+
const project = asRecord(await createInstanceApiClient(mode).get("/api/project"))
|
|
27
|
+
if (typeof project.id !== "string" || project.id.length === 0) {
|
|
28
|
+
throw new CliError(
|
|
29
|
+
{ code: "invalid_api_response", message: "The Sixb API returned an invalid project." },
|
|
30
|
+
EXIT_API
|
|
31
|
+
)
|
|
32
|
+
}
|
|
33
|
+
const report: SandboxStatusReport = {
|
|
34
|
+
ok: true,
|
|
35
|
+
profile: AGENT_RUNTIME_PROFILE,
|
|
36
|
+
cli: { version: INSTANCE_CLI_VERSION },
|
|
37
|
+
javascript: javascriptRuntime(),
|
|
38
|
+
project: { id: project.id },
|
|
39
|
+
}
|
|
40
|
+
writeJson(report)
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export async function context(args: readonly string[]): Promise<void> {
|
|
44
|
+
if (isHelp(args[0])) return writeText("Usage: sixb context")
|
|
45
|
+
if (args.length !== 0) fail("context accepts no arguments.")
|
|
46
|
+
const path = process.env.SIXB_RUN_CONTEXT
|
|
47
|
+
if (!path) fail("SIXB_RUN_CONTEXT is not set.")
|
|
48
|
+
let text: string
|
|
49
|
+
try {
|
|
50
|
+
text = await readFile(path, "utf8")
|
|
51
|
+
} catch (error) {
|
|
52
|
+
if (isFileError(error, "ENOENT")) fail(`Run context '${path}' does not exist.`)
|
|
53
|
+
throw error
|
|
54
|
+
}
|
|
55
|
+
try {
|
|
56
|
+
writeJson(JSON.parse(text))
|
|
57
|
+
} catch {
|
|
58
|
+
fail(`Run context '${path}' is not valid JSON.`, "invalid_json")
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function javascriptRuntime(): SandboxStatusReport["javascript"] {
|
|
63
|
+
if (typeof globalThis.Bun === "object") {
|
|
64
|
+
return { name: "bun", version: globalThis.Bun.version }
|
|
65
|
+
}
|
|
66
|
+
return { name: "node", version: process.versions.node }
|
|
67
|
+
}
|
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
import { fail, writeJson, writeText } from "../output"
|
|
12
12
|
import { CLI_LIMITS, DEFAULT_TELEMETRY_ORDER } from "../policies"
|
|
13
13
|
import { GROUP_HELP } from "./metadata"
|
|
14
|
-
import { normalizeWindowOptions, readJson, singleFileOption } from "./shared"
|
|
14
|
+
import { idSegment, normalizeWindowOptions, readJson, singleFileOption } from "./shared"
|
|
15
15
|
|
|
16
16
|
export async function telemetry(api: ApiClient, args: readonly string[]): Promise<void> {
|
|
17
17
|
const [sub, ...rest] = args
|
|
@@ -62,7 +62,7 @@ export async function telemetry(api: ApiClient, args: readonly string[]): Promis
|
|
|
62
62
|
}
|
|
63
63
|
|
|
64
64
|
function telemetryPath(args: readonly string[], terminal: "latest" | "history"): string {
|
|
65
|
-
return `/api/objects/${
|
|
65
|
+
return `/api/objects/${idSegment(args[0])}/${idSegment(args[1])}/telemetry/${idSegment(args[2])}/${terminal}`
|
|
66
66
|
}
|
|
67
67
|
|
|
68
68
|
function normalizeTelemetryQueryInput(input: unknown): Record<string, unknown> {
|
package/src/commands/users.ts
CHANGED
|
@@ -7,10 +7,11 @@ import {
|
|
|
7
7
|
parseCommandArgs,
|
|
8
8
|
requestsHelp,
|
|
9
9
|
} from "../arguments"
|
|
10
|
-
import { fail, writeJson, writeText } from "../output"
|
|
10
|
+
import { CliError, EXIT_API, fail, writeJson, writeText } from "../output"
|
|
11
11
|
import { CLI_LIMITS } from "../policies"
|
|
12
12
|
import { GROUP_HELP } from "./metadata"
|
|
13
13
|
import type { QueryOptions } from "./shared"
|
|
14
|
+
import { idSegment } from "./shared"
|
|
14
15
|
|
|
15
16
|
const USER_STATUSES = ["active", "suspended", "all"] as const
|
|
16
17
|
|
|
@@ -26,7 +27,22 @@ export async function users(api: ApiClient, args: readonly string[]): Promise<vo
|
|
|
26
27
|
|
|
27
28
|
if (sub === "get") {
|
|
28
29
|
const { positionals } = parseCommandArgs(rest, {}, "users get", 1)
|
|
29
|
-
|
|
30
|
+
const user = positionals[0]?.trim()
|
|
31
|
+
if (!user) fail("users get requires a user id or email.")
|
|
32
|
+
// Sign-in mints ids as `usr_<uuid>`, so an `@` marks an email.
|
|
33
|
+
if (!user.includes("@")) {
|
|
34
|
+
return writeJson(await api.get(`/api/users/${idSegment(user)}`))
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const page = await api.get("/api/users", { email: user })
|
|
38
|
+
const [member] = isRecord(page) && Array.isArray(page.users) ? page.users : []
|
|
39
|
+
if (member === undefined) {
|
|
40
|
+
throw new CliError(
|
|
41
|
+
{ code: "not_found", message: `No member has the email '${user}'.` },
|
|
42
|
+
EXIT_API
|
|
43
|
+
)
|
|
44
|
+
}
|
|
45
|
+
return writeJson(member)
|
|
30
46
|
}
|
|
31
47
|
|
|
32
48
|
if (sub === "list") {
|
|
@@ -65,3 +81,7 @@ function listQuery(options: {
|
|
|
65
81
|
: { offset: String(nonNegativeInteger("--offset", options["--offset"])) }),
|
|
66
82
|
}
|
|
67
83
|
}
|
|
84
|
+
|
|
85
|
+
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
86
|
+
return typeof value === "object" && value !== null && !Array.isArray(value)
|
|
87
|
+
}
|
|
@@ -3,7 +3,7 @@ import type { ApiClient } from "../api-client"
|
|
|
3
3
|
import { isHelp, parseCommandArgs, requestsHelp } from "../arguments"
|
|
4
4
|
import { fail, writeJson, writeRequestResult, writeText } from "../output"
|
|
5
5
|
import { GROUP_HELP } from "./metadata"
|
|
6
|
-
import { readJson } from "./shared"
|
|
6
|
+
import { idSegment, readJson } from "./shared"
|
|
7
7
|
|
|
8
8
|
export async function workflows(api: ApiClient, args: readonly string[]): Promise<void> {
|
|
9
9
|
const [sub, ...rest] = args
|
|
@@ -16,7 +16,7 @@ export async function workflows(api: ApiClient, args: readonly string[]): Promis
|
|
|
16
16
|
const {
|
|
17
17
|
positionals: [workflowId],
|
|
18
18
|
} = parseCommandArgs(rest, {}, "workflows get", 1)
|
|
19
|
-
return writeJson(await api.get(`/api/workflows/${
|
|
19
|
+
return writeJson(await api.get(`/api/workflows/${idSegment(workflowId)}`))
|
|
20
20
|
}
|
|
21
21
|
if (sub === "start") {
|
|
22
22
|
const {
|
|
@@ -30,7 +30,7 @@ export async function workflows(api: ApiClient, args: readonly string[]): Promis
|
|
|
30
30
|
// Every start names its run, so a repeated request returns the same run instead of another.
|
|
31
31
|
const runId = options["--run-id"] ?? `run_${randomUUID()}`
|
|
32
32
|
return writeRequestResult(
|
|
33
|
-
await api.post(`/api/workflows/${
|
|
33
|
+
await api.post(`/api/workflows/${idSegment(workflowId)}/runs`, {
|
|
34
34
|
input,
|
|
35
35
|
runId,
|
|
36
36
|
})
|