@runtypelabs/cli 0.1.10 → 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 +27 -0
- package/dist/index.js +195 -179
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -10,6 +10,12 @@ Command-line interface for the Runtype AI platform.
|
|
|
10
10
|
npm install -g @runtypelabs/cli
|
|
11
11
|
```
|
|
12
12
|
|
|
13
|
+
Or run without installing:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npx @runtypelabs/cli <command>
|
|
17
|
+
```
|
|
18
|
+
|
|
13
19
|
## Quick Start
|
|
14
20
|
|
|
15
21
|
### 1. Create Account & Authenticate
|
|
@@ -54,6 +60,27 @@ runtype records create --name "My Record" --type "document"
|
|
|
54
60
|
runtype records list --type document
|
|
55
61
|
```
|
|
56
62
|
|
|
63
|
+
### 4. Run Multi-Session Agent Tasks
|
|
64
|
+
|
|
65
|
+
Use `runtype marathon` (or `runtype agents task`) to run long-running, multi-session agent tasks with real-time streaming output.
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
# Run a task — agent output streams to your terminal in real time
|
|
69
|
+
runtype marathon "Code Builder" -m "Refactor the auth module to use JWT tokens"
|
|
70
|
+
|
|
71
|
+
# Set a budget and session limit, save progress with a custom name
|
|
72
|
+
runtype marathon agent_abc123 -m "Write integration tests for the API" \
|
|
73
|
+
--max-sessions 10 --max-cost 2.50 --name "api-tests"
|
|
74
|
+
|
|
75
|
+
# Resume an interrupted task (picks up where it left off)
|
|
76
|
+
runtype marathon "Code Builder" -m "Refactor the auth module to use JWT tokens" \
|
|
77
|
+
--resume --name "auth-refactor" --debug
|
|
78
|
+
|
|
79
|
+
# Sync progress to a Runtype record (visible in the dashboard)
|
|
80
|
+
runtype marathon "Code Builder" -m "Build the payments integration" \
|
|
81
|
+
--max-sessions 20 --track --name "payments"
|
|
82
|
+
```
|
|
83
|
+
|
|
57
84
|
## Chat Commands
|
|
58
85
|
|
|
59
86
|
During a chat session, you can use these special commands:
|
package/dist/index.js
CHANGED
|
@@ -2783,7 +2783,7 @@ var import_chalk16 = __toESM(require("chalk"));
|
|
|
2783
2783
|
var import_ora11 = __toESM(require("ora"));
|
|
2784
2784
|
var import_sdk6 = require("@runtypelabs/sdk");
|
|
2785
2785
|
|
|
2786
|
-
// src/commands/agents-
|
|
2786
|
+
// src/commands/agents-task.ts
|
|
2787
2787
|
init_cjs_shims();
|
|
2788
2788
|
var import_commander11 = require("commander");
|
|
2789
2789
|
var import_chalk15 = __toESM(require("chalk"));
|
|
@@ -2810,206 +2810,221 @@ function loadState(filePath) {
|
|
|
2810
2810
|
function saveState(filePath, state) {
|
|
2811
2811
|
const dir = path4.dirname(filePath);
|
|
2812
2812
|
fs3.mkdirSync(dir, { recursive: true });
|
|
2813
|
-
state.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
2814
2813
|
fs3.writeFileSync(filePath, JSON.stringify(state, null, 2));
|
|
2815
2814
|
}
|
|
2816
|
-
|
|
2817
|
-
|
|
2818
|
-
|
|
2819
|
-
|
|
2820
|
-
|
|
2821
|
-
|
|
2822
|
-
|
|
2823
|
-
|
|
2824
|
-
|
|
2825
|
-
|
|
2826
|
-
|
|
2827
|
-
|
|
2828
|
-
|
|
2829
|
-
|
|
2830
|
-
|
|
2831
|
-
|
|
2832
|
-
|
|
2833
|
-
|
|
2834
|
-
|
|
2835
|
-
|
|
2836
|
-
|
|
2837
|
-
console.log(import_chalk15.default.gray(` Create one with: runtype agents create -n "${agent}"`));
|
|
2838
|
-
process.exit(1);
|
|
2839
|
-
}
|
|
2840
|
-
} catch (error) {
|
|
2841
|
-
spinner.fail("Failed to look up agent");
|
|
2842
|
-
const message = error instanceof Error ? error.message : "Unknown error";
|
|
2843
|
-
console.error(import_chalk15.default.red(message));
|
|
2815
|
+
async function taskAction(agent, options) {
|
|
2816
|
+
const apiKey = await ensureAuth();
|
|
2817
|
+
if (!apiKey) return;
|
|
2818
|
+
const client = new import_sdk5.RuntypeClient({
|
|
2819
|
+
apiKey,
|
|
2820
|
+
baseUrl: getApiUrl()
|
|
2821
|
+
});
|
|
2822
|
+
let agentId = agent;
|
|
2823
|
+
if (!agent.startsWith("agent_")) {
|
|
2824
|
+
const spinner = (0, import_ora10.default)("Looking up agent by name...").start();
|
|
2825
|
+
try {
|
|
2826
|
+
const list = await client.agents.list();
|
|
2827
|
+
const found = list.data.find(
|
|
2828
|
+
(a) => a.name.toLowerCase() === agent.toLowerCase()
|
|
2829
|
+
);
|
|
2830
|
+
if (found) {
|
|
2831
|
+
agentId = found.id;
|
|
2832
|
+
spinner.succeed(`Found agent: ${import_chalk15.default.green(agentId)}`);
|
|
2833
|
+
} else {
|
|
2834
|
+
spinner.fail(`No agent found with name "${agent}"`);
|
|
2835
|
+
console.log(import_chalk15.default.gray(` Create one with: runtype agents create -n "${agent}"`));
|
|
2844
2836
|
process.exit(1);
|
|
2845
2837
|
}
|
|
2838
|
+
} catch (error) {
|
|
2839
|
+
spinner.fail("Failed to look up agent");
|
|
2840
|
+
const errMsg = error instanceof Error ? error.message : "Unknown error";
|
|
2841
|
+
console.error(import_chalk15.default.red(errMsg));
|
|
2842
|
+
process.exit(1);
|
|
2846
2843
|
}
|
|
2847
|
-
|
|
2848
|
-
|
|
2849
|
-
|
|
2850
|
-
|
|
2851
|
-
|
|
2852
|
-
|
|
2853
|
-
|
|
2854
|
-
|
|
2855
|
-
|
|
2856
|
-
|
|
2857
|
-
|
|
2858
|
-
|
|
2859
|
-
|
|
2860
|
-
|
|
2861
|
-
|
|
2862
|
-
|
|
2863
|
-
|
|
2864
|
-
|
|
2865
|
-
}
|
|
2866
|
-
localState = existing;
|
|
2867
|
-
localState.status = "running";
|
|
2868
|
-
priorSessionCount = localState.sessionCount;
|
|
2869
|
-
priorCost = localState.totalCost;
|
|
2870
|
-
console.log(
|
|
2871
|
-
import_chalk15.default.cyan(
|
|
2872
|
-
`Resuming from session ${priorSessionCount} ($${priorCost.toFixed(4)} spent)`
|
|
2873
|
-
)
|
|
2874
|
-
);
|
|
2875
|
-
} else {
|
|
2876
|
-
localState = {
|
|
2877
|
-
agentId,
|
|
2878
|
-
taskName,
|
|
2879
|
-
message: options.message,
|
|
2880
|
-
status: "running",
|
|
2881
|
-
sessionCount: 0,
|
|
2882
|
-
totalCost: 0,
|
|
2883
|
-
context: {},
|
|
2884
|
-
lastOutput: "",
|
|
2885
|
-
sessions: [],
|
|
2886
|
-
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
2887
|
-
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
2888
|
-
};
|
|
2844
|
+
}
|
|
2845
|
+
const taskName = options.name || agentId;
|
|
2846
|
+
const filePath = stateFilePath(taskName, options.stateDir);
|
|
2847
|
+
const maxSessions = parseInt(options.maxSessions, 10);
|
|
2848
|
+
const maxCost = options.maxCost ? parseFloat(options.maxCost) : void 0;
|
|
2849
|
+
let priorSessionCount = 0;
|
|
2850
|
+
let priorCost = 0;
|
|
2851
|
+
if (options.resume) {
|
|
2852
|
+
const existing = loadState(filePath);
|
|
2853
|
+
if (!existing) {
|
|
2854
|
+
console.error(import_chalk15.default.red(`No state file found at ${filePath}`));
|
|
2855
|
+
console.log(import_chalk15.default.gray(" Run without --resume to start a new task."));
|
|
2856
|
+
process.exit(1);
|
|
2857
|
+
}
|
|
2858
|
+
if (existing.status === "complete") {
|
|
2859
|
+
console.log(import_chalk15.default.yellow("This task already completed."));
|
|
2860
|
+
if (options.json) printJson(existing);
|
|
2861
|
+
return;
|
|
2889
2862
|
}
|
|
2890
|
-
|
|
2891
|
-
|
|
2892
|
-
|
|
2893
|
-
|
|
2894
|
-
|
|
2895
|
-
|
|
2896
|
-
|
|
2863
|
+
priorSessionCount = existing.sessionCount;
|
|
2864
|
+
priorCost = existing.totalCost;
|
|
2865
|
+
console.log(
|
|
2866
|
+
import_chalk15.default.cyan(
|
|
2867
|
+
`Resuming from session ${priorSessionCount} ($${priorCost.toFixed(4)} spent)`
|
|
2868
|
+
)
|
|
2869
|
+
);
|
|
2870
|
+
}
|
|
2871
|
+
let lastKnownState = null;
|
|
2872
|
+
let interrupted = false;
|
|
2873
|
+
const onSigint = () => {
|
|
2874
|
+
if (interrupted) process.exit(1);
|
|
2875
|
+
interrupted = true;
|
|
2876
|
+
console.log(import_chalk15.default.yellow("\n\nInterrupted \u2014 saving state..."));
|
|
2877
|
+
if (lastKnownState) {
|
|
2878
|
+
lastKnownState.status = "paused";
|
|
2879
|
+
saveState(filePath, lastKnownState);
|
|
2897
2880
|
console.log(import_chalk15.default.green(`State saved to ${filePath}`));
|
|
2898
|
-
|
|
2899
|
-
import_chalk15.default.gray(
|
|
2900
|
-
` Resume with: runtype agents run-task ${agent} -m "${options.message}" --resume${options.name ? ` --name ${options.name}` : ""}`
|
|
2901
|
-
)
|
|
2902
|
-
);
|
|
2903
|
-
process.exit(0);
|
|
2904
|
-
};
|
|
2905
|
-
process.on("SIGINT", onSigint);
|
|
2906
|
-
const remainingSessions = maxSessions - priorSessionCount;
|
|
2907
|
-
console.log(import_chalk15.default.cyan(`
|
|
2908
|
-
Running task "${taskName}" on ${agentId}`));
|
|
2881
|
+
}
|
|
2909
2882
|
console.log(
|
|
2910
2883
|
import_chalk15.default.gray(
|
|
2911
|
-
`
|
|
2884
|
+
` Resume with: runtype marathon ${agent} -m "${options.message}" --resume${options.name ? ` --name ${options.name}` : ""}`
|
|
2912
2885
|
)
|
|
2913
2886
|
);
|
|
2914
|
-
|
|
2887
|
+
process.exit(0);
|
|
2888
|
+
};
|
|
2889
|
+
process.on("SIGINT", onSigint);
|
|
2890
|
+
const remainingSessions = maxSessions - priorSessionCount;
|
|
2891
|
+
const remainingCost = maxCost ? maxCost - priorCost : void 0;
|
|
2892
|
+
console.log(import_chalk15.default.cyan(`
|
|
2893
|
+
Running task "${taskName}" on ${agentId}`));
|
|
2894
|
+
console.log(
|
|
2895
|
+
import_chalk15.default.gray(
|
|
2896
|
+
` Sessions: ${priorSessionCount > 0 ? `${priorSessionCount} done, ` : ""}${remainingSessions} remaining${maxCost ? ` | Budget: $${maxCost.toFixed(2)}` : ""}`
|
|
2897
|
+
)
|
|
2898
|
+
);
|
|
2899
|
+
console.log(import_chalk15.default.gray(` State: ${filePath}
|
|
2915
2900
|
`));
|
|
2916
|
-
|
|
2917
|
-
|
|
2918
|
-
|
|
2919
|
-
|
|
2920
|
-
|
|
2921
|
-
|
|
2922
|
-
|
|
2923
|
-
|
|
2924
|
-
|
|
2925
|
-
|
|
2926
|
-
|
|
2927
|
-
|
|
2928
|
-
|
|
2929
|
-
|
|
2930
|
-
|
|
2931
|
-
|
|
2932
|
-
|
|
2933
|
-
|
|
2934
|
-
|
|
2935
|
-
|
|
2936
|
-
|
|
2937
|
-
|
|
2938
|
-
|
|
2939
|
-
|
|
2940
|
-
|
|
2941
|
-
|
|
2942
|
-
|
|
2943
|
-
|
|
2944
|
-
|
|
2945
|
-
|
|
2946
|
-
|
|
2947
|
-
|
|
2948
|
-
|
|
2949
|
-
|
|
2950
|
-
|
|
2951
|
-
|
|
2952
|
-
|
|
2953
|
-
|
|
2954
|
-
|
|
2955
|
-
|
|
2956
|
-
|
|
2957
|
-
|
|
2958
|
-
|
|
2959
|
-
|
|
2960
|
-
|
|
2961
|
-
|
|
2962
|
-
|
|
2901
|
+
try {
|
|
2902
|
+
let currentSession = priorSessionCount;
|
|
2903
|
+
const streamCallbacks = {
|
|
2904
|
+
onAgentStart: () => {
|
|
2905
|
+
currentSession++;
|
|
2906
|
+
console.log(import_chalk15.default.cyan(`
|
|
2907
|
+
\u2500\u2500 Session ${currentSession} \u2500\u2500
|
|
2908
|
+
`));
|
|
2909
|
+
},
|
|
2910
|
+
onTurnDelta: (event) => {
|
|
2911
|
+
if (event.contentType === "text") {
|
|
2912
|
+
process.stdout.write(event.delta);
|
|
2913
|
+
} else if (event.contentType === "thinking" && options.debug) {
|
|
2914
|
+
process.stdout.write(import_chalk15.default.dim(event.delta));
|
|
2915
|
+
}
|
|
2916
|
+
},
|
|
2917
|
+
onToolStart: (event) => {
|
|
2918
|
+
if (options.debug) {
|
|
2919
|
+
console.log(import_chalk15.default.gray(`
|
|
2920
|
+
[tool] ${event.toolName}...`));
|
|
2921
|
+
}
|
|
2922
|
+
},
|
|
2923
|
+
onToolComplete: (event) => {
|
|
2924
|
+
if (options.debug) {
|
|
2925
|
+
const status = event.success ? import_chalk15.default.green("ok") : import_chalk15.default.red("failed");
|
|
2926
|
+
console.log(import_chalk15.default.gray(` [tool] ${event.toolName} \u2192 ${status}`));
|
|
2927
|
+
}
|
|
2928
|
+
},
|
|
2929
|
+
onError: (event) => {
|
|
2930
|
+
console.error(import_chalk15.default.red(`
|
|
2931
|
+
Error: ${event.error}`));
|
|
2932
|
+
}
|
|
2933
|
+
};
|
|
2934
|
+
const result = await client.agents.runTask(agentId, {
|
|
2935
|
+
message: options.message,
|
|
2936
|
+
maxSessions: remainingSessions,
|
|
2937
|
+
maxCost: remainingCost,
|
|
2938
|
+
debugMode: options.debug,
|
|
2939
|
+
stream: true,
|
|
2940
|
+
streamCallbacks,
|
|
2941
|
+
trackProgress: options.track ? taskName : void 0,
|
|
2942
|
+
onSession: (state) => {
|
|
2943
|
+
const adjustedState = {
|
|
2944
|
+
...state,
|
|
2945
|
+
sessionCount: priorSessionCount + state.sessionCount,
|
|
2946
|
+
totalCost: priorCost + state.totalCost
|
|
2947
|
+
};
|
|
2948
|
+
lastKnownState = adjustedState;
|
|
2949
|
+
saveState(filePath, adjustedState);
|
|
2950
|
+
const latest = state.sessions[state.sessions.length - 1];
|
|
2951
|
+
if (latest) {
|
|
2952
|
+
const total = adjustedState.sessionCount;
|
|
2953
|
+
const costStr = import_chalk15.default.yellow(`$${adjustedState.totalCost.toFixed(4)}`);
|
|
2954
|
+
const reasonColor = latest.stopReason === "complete" ? import_chalk15.default.green : import_chalk15.default.gray;
|
|
2963
2955
|
console.log(
|
|
2964
|
-
`
|
|
2956
|
+
`
|
|
2957
|
+
${import_chalk15.default.dim(`[${total}/${maxSessions}]`)} ${reasonColor(latest.stopReason)} | total: ${costStr}`
|
|
2965
2958
|
);
|
|
2966
|
-
if (session.lastOutput) {
|
|
2967
|
-
const preview = session.lastOutput.slice(0, 120).replace(/\n/g, " ");
|
|
2968
|
-
console.log(
|
|
2969
|
-
` ${import_chalk15.default.dim(preview)}${session.lastOutput.length > 120 ? "..." : ""}`
|
|
2970
|
-
);
|
|
2971
|
-
}
|
|
2972
2959
|
}
|
|
2973
|
-
|
|
2974
|
-
localState.status = result.status;
|
|
2975
|
-
localState.totalCost = priorCost + result.totalCost;
|
|
2976
|
-
Object.assign(localState.context, result.context);
|
|
2977
|
-
saveState(filePath, localState);
|
|
2978
|
-
process.removeListener("SIGINT", onSigint);
|
|
2979
|
-
console.log();
|
|
2980
|
-
const statusColor = result.status === "complete" ? import_chalk15.default.green : result.status === "budget_exceeded" ? import_chalk15.default.red : import_chalk15.default.yellow;
|
|
2981
|
-
console.log(`Status: ${statusColor(localState.status)}`);
|
|
2982
|
-
console.log(`Sessions: ${localState.sessionCount}`);
|
|
2983
|
-
console.log(`Total cost: ${import_chalk15.default.yellow(`$${localState.totalCost.toFixed(4)}`)}`);
|
|
2984
|
-
console.log(`State: ${import_chalk15.default.gray(filePath)}`);
|
|
2985
|
-
if (localState.status === "paused" || localState.status === "max_sessions") {
|
|
2986
|
-
console.log(
|
|
2987
|
-
import_chalk15.default.gray(
|
|
2988
|
-
`
|
|
2989
|
-
Resume: runtype agents run-task ${agent} -m "${options.message}" --resume${options.name ? ` --name ${options.name}` : ""}`
|
|
2990
|
-
)
|
|
2991
|
-
);
|
|
2992
|
-
}
|
|
2993
|
-
if (options.json) {
|
|
2994
|
-
console.log();
|
|
2995
|
-
printJson(localState);
|
|
2960
|
+
if (interrupted) return false;
|
|
2996
2961
|
}
|
|
2997
|
-
}
|
|
2998
|
-
|
|
2999
|
-
|
|
3000
|
-
|
|
3001
|
-
|
|
3002
|
-
|
|
3003
|
-
|
|
3004
|
-
|
|
3005
|
-
|
|
2962
|
+
});
|
|
2963
|
+
const finalState = {
|
|
2964
|
+
agentId,
|
|
2965
|
+
agentName: result.sessions[0]?.stopReason ? agentId : agentId,
|
|
2966
|
+
taskName,
|
|
2967
|
+
status: result.status,
|
|
2968
|
+
sessionCount: priorSessionCount + result.sessionCount,
|
|
2969
|
+
totalCost: priorCost + result.totalCost,
|
|
2970
|
+
lastOutput: result.lastOutput,
|
|
2971
|
+
lastStopReason: result.sessions[result.sessions.length - 1]?.stopReason || "complete",
|
|
2972
|
+
sessions: result.sessions,
|
|
2973
|
+
startedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
2974
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
2975
|
+
};
|
|
2976
|
+
saveState(filePath, finalState);
|
|
2977
|
+
process.removeListener("SIGINT", onSigint);
|
|
2978
|
+
console.log();
|
|
2979
|
+
const statusColor = result.status === "complete" ? import_chalk15.default.green : result.status === "budget_exceeded" ? import_chalk15.default.red : import_chalk15.default.yellow;
|
|
2980
|
+
console.log(`Status: ${statusColor(result.status)}`);
|
|
2981
|
+
console.log(`Sessions: ${finalState.sessionCount}`);
|
|
2982
|
+
console.log(`Total cost: ${import_chalk15.default.yellow(`$${finalState.totalCost.toFixed(4)}`)}`);
|
|
2983
|
+
console.log(`State: ${import_chalk15.default.gray(filePath)}`);
|
|
2984
|
+
if (result.recordId) {
|
|
2985
|
+
console.log(`Record: ${import_chalk15.default.gray(result.recordId)}`);
|
|
2986
|
+
}
|
|
2987
|
+
if (result.status === "paused" || result.status === "max_sessions") {
|
|
2988
|
+
console.log(
|
|
2989
|
+
import_chalk15.default.gray(
|
|
2990
|
+
`
|
|
2991
|
+
Resume: runtype marathon ${agent} -m "${options.message}" --resume${options.name ? ` --name ${options.name}` : ""}`
|
|
2992
|
+
)
|
|
2993
|
+
);
|
|
2994
|
+
}
|
|
2995
|
+
if (options.json) {
|
|
2996
|
+
console.log();
|
|
2997
|
+
printJson(finalState);
|
|
3006
2998
|
}
|
|
2999
|
+
} catch (error) {
|
|
3000
|
+
const stateAtError = lastKnownState;
|
|
3001
|
+
if (stateAtError) {
|
|
3002
|
+
stateAtError.status = "paused";
|
|
3003
|
+
saveState(filePath, stateAtError);
|
|
3004
|
+
}
|
|
3005
|
+
process.removeListener("SIGINT", onSigint);
|
|
3006
|
+
const errMsg = error instanceof Error ? error.message : "Unknown error";
|
|
3007
|
+
console.error(import_chalk15.default.red(`
|
|
3008
|
+
Task failed: ${errMsg}`));
|
|
3009
|
+
console.log(import_chalk15.default.gray(`State saved to ${filePath} \u2014 resume with --resume`));
|
|
3010
|
+
process.exit(1);
|
|
3007
3011
|
}
|
|
3012
|
+
}
|
|
3013
|
+
function applyTaskOptions(cmd) {
|
|
3014
|
+
return cmd.argument("<agent>", "Agent ID or name").requiredOption("-m, --message <text>", "Task message for the agent").option("--max-sessions <n>", "Maximum sessions", "50").option("--max-cost <n>", "Budget in USD").option("--name <name>", "Task name (used for state file, defaults to agent name)").option("--state-dir <path>", "Directory for state files (default: .runtype/tasks/)").option("--resume", "Resume from existing local state").option("--track", "Sync progress to a Runtype record (visible in dashboard)").option("--debug", "Show debug output from each session").option("--json", "Output final result as JSON").action(taskAction);
|
|
3015
|
+
}
|
|
3016
|
+
var taskCommand = applyTaskOptions(
|
|
3017
|
+
new import_commander11.Command("task").description("Run a multi-session agent task")
|
|
3008
3018
|
);
|
|
3019
|
+
function createMarathonCommand() {
|
|
3020
|
+
return applyTaskOptions(
|
|
3021
|
+
new import_commander11.Command("marathon").description("Run a multi-session agent task (alias for agents task)")
|
|
3022
|
+
);
|
|
3023
|
+
}
|
|
3009
3024
|
|
|
3010
3025
|
// src/commands/agents.ts
|
|
3011
3026
|
var agentsCommand = new import_commander12.Command("agents").description("Manage agents");
|
|
3012
|
-
agentsCommand.addCommand(
|
|
3027
|
+
agentsCommand.addCommand(taskCommand);
|
|
3013
3028
|
agentsCommand.command("list").description("List all agents").option("--json", "Output as JSON").option("--limit <n>", "Limit results", "20").action(async (options) => {
|
|
3014
3029
|
const apiKey = await ensureAuth();
|
|
3015
3030
|
if (!apiKey) return;
|
|
@@ -4077,6 +4092,7 @@ program.addCommand(apiKeysCommand);
|
|
|
4077
4092
|
program.addCommand(analyticsCommand);
|
|
4078
4093
|
program.addCommand(billingCommand);
|
|
4079
4094
|
program.addCommand(flowVersionsCommand);
|
|
4095
|
+
program.addCommand(createMarathonCommand());
|
|
4080
4096
|
program.exitOverride();
|
|
4081
4097
|
try {
|
|
4082
4098
|
if (!process.argv.slice(2).length) {
|