@cargo-ai/cli 1.0.72 → 1.0.73

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/build/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from "node:module";
3
- import { BRAND, canRunPalette, declareSources, fetchCreditsLeft, fetchWorkspaceName, formatWorkspaceSuffix, printSetupIssues, registerCommands as registerCdkCommands, runPalette, SessionExpiredError, } from "@cargo-ai/cdk/cli";
3
+ import { availableCodingAgents, BRAND, canRunPalette, cdkProjectRoot, declareSources, fetchCreditsLeft, fetchWorkspaceName, formatWorkspaceSuffix, isInteractive, printSetupIssues, registerCommands as registerCdkCommands, runPalette, SessionExpiredError, } from "@cargo-ai/cdk/cli";
4
4
  import { Command } from "commander";
5
5
  import { AGENT_SKILLS_HINT } from "./agentSkills.js";
6
6
  import { createApi } from "./api.js";
@@ -20,12 +20,15 @@ import { registerOrchestrationCommands } from "./commands/orchestration/index.js
20
20
  import { registerRevenueOrganizationCommands } from "./commands/revenueOrganization/index.js";
21
21
  import { ExitCodes, failWith } from "./commands/runHandler.js";
22
22
  import { registerSegmentationCommands } from "./commands/segmentation/index.js";
23
+ import { registerStartCommand, runStart } from "./commands/start/index.js";
24
+ import { loadStartState, shouldRunStart } from "./commands/start/state.js";
23
25
  import { registerStorageCommands } from "./commands/storage/index.js";
24
26
  import { registerSystemOfRecordIntegrationCommands } from "./commands/systemOfRecordIntegration/index.js";
25
27
  import { registerUserManagementCommands } from "./commands/userManagement/index.js";
26
28
  import { registerVersionCommand } from "./commands/version.js";
27
29
  import { registerWorkspaceManagementCommands } from "./commands/workspaceManagement/index.js";
28
30
  import { getConfig } from "./config.js";
31
+ import { buildPaletteLayout } from "./paletteLayout.js";
29
32
  import { collectSetupIssues, isSignedIn } from "./setupIssues.js";
30
33
  import { cachedLatestVersion, maybeRefreshUpdateCache, } from "./updateNotifier.js";
31
34
  const require = createRequire(import.meta.url);
@@ -74,7 +77,15 @@ Run "cargo-ai <command> <subcommand> --help" for details on a subcommand.`);
74
77
  // Commands that are themselves the fix, or that already say all of this
75
78
  // better: the header would either duplicate their output or nag someone who is
76
79
  // mid-repair.
77
- const SETUP_HEADER_SKIP = ["login", "logout", "doctor", "version", "mcp"];
80
+ const SETUP_HEADER_SKIP = [
81
+ "login",
82
+ "logout",
83
+ "start",
84
+ "onboard",
85
+ "doctor",
86
+ "version",
87
+ "mcp",
88
+ ];
78
89
  /**
79
90
  * Say what is wrong before the command runs rather than after it fails, and
80
91
  * name the fix. Every check behind this is a file read (see `setupIssues.ts`)
@@ -163,6 +174,11 @@ declareSources({
163
174
  { argv: ["segmentation", "segment", "list"], value: "uuid", label: "name" },
164
175
  ],
165
176
  });
177
+ const binPath = process.argv[1] === undefined ? "cargo-ai" : process.argv[1];
178
+ // First, so it is the first row of the palette: for someone signed in, this is
179
+ // the shortest path to a briefed coding agent, and it was previously reachable
180
+ // only by knowing the name of a command that sounds like a one-time thing.
181
+ registerStartCommand(program, getApi, { binPath, openPalette });
166
182
  registerAuthCommands(program, getApi);
167
183
  registerVersionCommand(program, version);
168
184
  registerDoctorCommand(program, version);
@@ -190,17 +206,45 @@ registerCdkCommands(program
190
206
  // wall: twenty command groups is a list to navigate, not one to read. Anything
191
207
  // non-interactive (a pipe, CI, an agent) keeps the help it has always had.
192
208
  const bare = process.argv.slice(2).length === 0 && canRunPalette();
193
- const start = bare ? openPalette() : program.parseAsync();
194
- async function openPalette() {
209
+ // ...except for someone who has never signed in, for whom that palette is
210
+ // twenty groups that all exit 3. They get the entrance instead, once.
211
+ const entrance = bare === true &&
212
+ shouldRunStart({
213
+ signedIn: isSignedIn(),
214
+ interactive: isInteractive(),
215
+ ranBefore: loadStartState() !== undefined,
216
+ });
217
+ const start = bare === false
218
+ ? program.parseAsync()
219
+ : entrance === true
220
+ ? runStart(getApi, { binPath, openPalette }, {})
221
+ : openPalette();
222
+ async function openPalette(startPath) {
195
223
  const [title, latestVersion] = await Promise.all([
196
224
  paletteTitle(),
197
225
  maybeRefreshUpdateCache(),
198
226
  ]);
227
+ // Probed once: this shells out to `which` per candidate agent, and nobody
228
+ // installs a coding agent from inside the palette.
229
+ const agents = availableCodingAgents();
230
+ const collectIssues = () => collectSetupIssues({ currentVersion: version, latestVersion });
231
+ // Re-read after each command: signing in or out from inside the palette
232
+ // changes both what the setup line says and which rows are worth pinning.
233
+ // The cwd is re-tested too — a command can create a project in it.
234
+ const rebuildLayout = () => buildPaletteLayout({
235
+ signedIn: isSignedIn(),
236
+ agents,
237
+ cdkProjectRoot: cdkProjectRoot(process.cwd()),
238
+ });
199
239
  await runPalette({
200
240
  program,
201
- binPath: process.argv[1] === undefined ? "cargo-ai" : process.argv[1],
241
+ binPath,
242
+ startPath,
202
243
  title,
203
- issues: collectSetupIssues({ currentVersion: version, latestVersion }),
244
+ issues: collectIssues(),
245
+ refreshIssues: collectIssues,
246
+ layout: rebuildLayout(),
247
+ refreshLayout: rebuildLayout,
204
248
  });
205
249
  }
206
250
  /**
@@ -0,0 +1,16 @@
1
+ import type { CodingAgent, PaletteLayout, PinnedRow } from "@cargo-ai/cdk/cli";
2
+ export type PaletteLayoutInput = {
3
+ signedIn: boolean;
4
+ agents: readonly CodingAgent[];
5
+ /** The CDK repo root the palette is standing in, or undefined when none. */
6
+ cdkProjectRoot: string | undefined;
7
+ };
8
+ export declare function buildPaletteLayout(input: PaletteLayoutInput): PaletteLayout;
9
+ /**
10
+ * The rows above the rule. Signed out there is exactly one thing worth
11
+ * offering, and it is not a list of twenty command groups that all exit 3.
12
+ *
13
+ * Exported for tests; `buildPaletteLayout` is the only production caller.
14
+ */
15
+ export declare function pinnedRows(input: PaletteLayoutInput): PinnedRow[];
16
+ //# sourceMappingURL=paletteLayout.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paletteLayout.d.ts","sourceRoot":"","sources":["../src/paletteLayout.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAsE/E,MAAM,MAAM,kBAAkB,GAAG;IAC/B,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,EAAE,SAAS,WAAW,EAAE,CAAC;IAC/B,4EAA4E;IAC5E,cAAc,EAAE,MAAM,GAAG,SAAS,CAAC;CACpC,CAAC;AAEF,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,kBAAkB,GAAG,aAAa,CAM3E;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,kBAAkB,GAAG,SAAS,EAAE,CA+CjE"}
@@ -0,0 +1,131 @@
1
+ // How the root menu is arranged: what is pinned above it, what it does not
2
+ // draw, and the order of what is left.
3
+ //
4
+ // The palette derives its rows from commander's command tree, which knows
5
+ // registration order and nothing else. That put `version` and `doctor` — twice
6
+ // a year, both of them — above the whole product, and left the thing a person
7
+ // most often wants, a coding agent briefed on their workspace, two screens
8
+ // down behind `start`. This is the missing opinion, kept in one place and as
9
+ // data, so it can be read and tested rather than inferred from a menu.
10
+ /** Pinned row values. The leading space keeps them out of the command namespace. */
11
+ const SIGN_IN = " sign-in";
12
+ const DEMO = " demo";
13
+ const CODE = " code";
14
+ const ADD_COOKBOOK = " add-cookbook";
15
+ /**
16
+ * `start` runs most of these; the pinned row is the shortcut to one of them.
17
+ * The exception is "Add a cookbook", which runs `cdk add` directly: it is not
18
+ * a `start` destination, because it needs neither the sign-in step nor a
19
+ * choice of where to carry on — you are already in the project.
20
+ */
21
+ const ENTRANCE = "start";
22
+ /**
23
+ * Root commands the menu does not draw. Each is still runnable, still in
24
+ * `--help`, and still reachable by name — they are simply not what somebody
25
+ * opening a menu is looking for.
26
+ *
27
+ * `start` is hidden because its destinations are pinned above: a row that
28
+ * opens a menu of rows already on screen is a detour. `version` is
29
+ * `--version`, and `doctor` reports it anyway.
30
+ */
31
+ const HIDDEN = [ENTRANCE, "version"];
32
+ /**
33
+ * The sections, in reading order: everything the workspace is made of, then
34
+ * the workspace as code on its own, then the machine you are sitting at —
35
+ * which ends beside `/exit`, since leaving and checking your setup are the
36
+ * same kind of errand. What people reach for most is not here at all; those
37
+ * are the pinned rows, above the first section.
38
+ *
39
+ * Anything a release adds and nobody lists here still appears, in tree order,
40
+ * in a final section — a new command is never invisible by omission. So a new
41
+ * command group belongs in whichever of these three it is part of, and needs
42
+ * no entry to be reachable.
43
+ */
44
+ const SECTIONS = [
45
+ // Everything the workspace is: what you run, the data and connectors it runs
46
+ // on, the knowledge it reads, and the surfaces it exposes. One group, most
47
+ // used first — the divisions that used to be here were the CLI's own
48
+ // architecture showing through, which is not a distinction anybody browsing
49
+ // a menu is making.
50
+ [
51
+ "orchestration",
52
+ "storage",
53
+ "connection",
54
+ "segmentation",
55
+ "ai",
56
+ "context",
57
+ "content",
58
+ "hosting",
59
+ "mcp",
60
+ "mailboxManagement",
61
+ "workspaceManagement",
62
+ "billing",
63
+ "observability",
64
+ "revenue-organization",
65
+ "expression",
66
+ "user-management",
67
+ "system-of-record",
68
+ ],
69
+ // The workspace as code sits on its own: it is the same resources again,
70
+ // declared in a repo rather than run from here.
71
+ ["cdk"],
72
+ ["doctor", "whoami", "login", "logout"],
73
+ ];
74
+ export function buildPaletteLayout(input) {
75
+ return {
76
+ pinned: pinnedRows(input),
77
+ hide: HIDDEN,
78
+ sections: SECTIONS,
79
+ };
80
+ }
81
+ /**
82
+ * The rows above the rule. Signed out there is exactly one thing worth
83
+ * offering, and it is not a list of twenty command groups that all exit 3.
84
+ *
85
+ * Exported for tests; `buildPaletteLayout` is the only production caller.
86
+ */
87
+ export function pinnedRows(input) {
88
+ if (input.signedIn === false) {
89
+ return [
90
+ {
91
+ value: SIGN_IN,
92
+ label: "Sign in",
93
+ hint: "then pick where to carry on",
94
+ argv: [ENTRANCE],
95
+ },
96
+ ];
97
+ }
98
+ // Inside a CDK project, "Add a cookbook" is more useful than "Set up as
99
+ // code" — the project already exists. Outside, scaffold one.
100
+ const cdkRow = input.cdkProjectRoot !== undefined
101
+ ? {
102
+ value: ADD_COOKBOOK,
103
+ label: "Add a cookbook",
104
+ hint: "install a worked pipeline into this project",
105
+ // `--dir` because `cdk add` refuses a directory with no
106
+ // package.json, and the palette is as often open in `infra/` — where
107
+ // the scaffold's README sends people — as at the root.
108
+ argv: ["cdk", "add", "--dir", input.cdkProjectRoot],
109
+ }
110
+ : {
111
+ value: CODE,
112
+ label: "Set up as code",
113
+ hint: "scaffold a CDK project",
114
+ argv: [ENTRANCE, "--continue", "code"],
115
+ };
116
+ return [
117
+ ...input.agents.map((agent) => ({
118
+ value: ` agent:${agent.bin}`,
119
+ label: `Open ${agent.label}`,
120
+ hint: "briefed on this workspace",
121
+ argv: [ENTRANCE, "--continue", agent.bin],
122
+ })),
123
+ {
124
+ value: DEMO,
125
+ label: "Guided demo",
126
+ hint: "companies, then the people, for your ICP",
127
+ argv: [ENTRANCE, "--continue", "demo"],
128
+ },
129
+ cdkRow,
130
+ ];
131
+ }
@@ -1,8 +1,7 @@
1
- import type { SetupIssue } from "@cargo-ai/cdk/cli";
2
- export type SkillsPin = {
3
- version: string;
4
- path: string;
5
- };
1
+ import type { SetupIssue, SkillsPin } from "@cargo-ai/cdk/cli";
2
+ import { isSignedIn, readSkillsPin } from "@cargo-ai/cdk/cli";
3
+ export type { SkillsPin };
4
+ export { isSignedIn, readSkillsPin };
6
5
  export type SetupIssueInput = {
7
6
  currentVersion: string;
8
7
  /**
@@ -23,15 +22,4 @@ export type SetupIssueDeps = {
23
22
  readSkillsPin: () => SkillsPin | undefined;
24
23
  };
25
24
  export declare function collectSetupIssues(input: SetupIssueInput, deps?: SetupIssueDeps): SetupIssue[];
26
- /**
27
- * The CLI version the installed skills bundle was written against, from
28
- * whichever agent's skills directory holds one.
29
- */
30
- export declare function readSkillsPin(): SkillsPin | undefined;
31
- /**
32
- * Deliberately not `getConfig()`: that resolves the whole auth config and exits
33
- * the process on a workspace conflict, which a header printed before every
34
- * command must never do. Presence of a credential is all this line needs.
35
- */
36
- export declare function isSignedIn(): boolean;
37
25
  //# sourceMappingURL=setupIssues.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"setupIssues.d.ts","sourceRoot":"","sources":["../src/setupIssues.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAWpD,MAAM,MAAM,SAAS,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAE1D,MAAM,MAAM,eAAe,GAAG;IAC5B,cAAc,EAAE,MAAM,CAAC;IACvB;;;;;OAKG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF;;;;GAIG;AACH,MAAM,MAAM,cAAc,GAAG;IAC3B,UAAU,EAAE,MAAM,OAAO,CAAC;IAC1B,aAAa,EAAE,MAAM,SAAS,GAAG,SAAS,CAAC;CAC5C,CAAC;AAIF,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,eAAe,EACtB,IAAI,GAAE,cAA4B,GACjC,UAAU,EAAE,CAyCd;AAED;;;GAGG;AACH,wBAAgB,aAAa,IAAI,SAAS,GAAG,SAAS,CAcrD;AAED;;;;GAIG;AACH,wBAAgB,UAAU,IAAI,OAAO,CAYpC"}
1
+ {"version":3,"file":"setupIssues.d.ts","sourceRoot":"","sources":["../src/setupIssues.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC/D,OAAO,EACL,UAAU,EACV,aAAa,EAEd,MAAM,mBAAmB,CAAC;AAM3B,YAAY,EAAE,SAAS,EAAE,CAAC;AAC1B,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,CAAC;AAErC,MAAM,MAAM,eAAe,GAAG;IAC5B,cAAc,EAAE,MAAM,CAAC;IACvB;;;;;OAKG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF;;;;GAIG;AACH,MAAM,MAAM,cAAc,GAAG;IAC3B,UAAU,EAAE,MAAM,OAAO,CAAC;IAC1B,aAAa,EAAE,MAAM,SAAS,GAAG,SAAS,CAAC;CAC5C,CAAC;AAIF,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,eAAe,EACtB,IAAI,GAAE,cAA4B,GACjC,UAAU,EAAE,CAyCd"}
@@ -4,14 +4,10 @@
4
4
  // This runs before every command, so every check here is a small file read or
5
5
  // cheaper — no network. `cargo-ai doctor` is the same list with the online
6
6
  // checks added.
7
- import * as fs from "node:fs";
8
- import * as os from "node:os";
9
- import * as path from "node:path";
10
- import { loadCredentials } from "./credentials.js";
7
+ import { isSignedIn, readSkillsPin, SKILLS_INSTALL_COMMAND, } from "@cargo-ai/cdk/cli";
11
8
  import { isOutdated, UPDATE_COMMAND } from "./version.js";
12
- const SEMVER_PATTERN = /^\d+\.\d+\.\d+$/;
13
- const SKILLS_UPDATE_COMMAND = "npx skills add getcargohq/cargo-skills";
14
9
  const LOGIN_COMMAND = "cargo-ai login --oauth";
10
+ export { isSignedIn, readSkillsPin };
15
11
  const machineDeps = { isSignedIn, readSkillsPin };
16
12
  export function collectSetupIssues(input, deps = machineDeps) {
17
13
  const issues = [];
@@ -41,53 +37,8 @@ export function collectSetupIssues(input, deps = machineDeps) {
41
37
  label: `skills expect CLI ${pin.version}`,
42
38
  fix: isOutdated(input.currentVersion, pin.version) === true
43
39
  ? UPDATE_COMMAND
44
- : SKILLS_UPDATE_COMMAND,
40
+ : SKILLS_INSTALL_COMMAND,
45
41
  });
46
42
  }
47
43
  return issues;
48
44
  }
49
- /**
50
- * The CLI version the installed skills bundle was written against, from
51
- * whichever agent's skills directory holds one.
52
- */
53
- export function readSkillsPin() {
54
- for (const candidate of skillsPinCandidates()) {
55
- try {
56
- const raw = fs.readFileSync(candidate, "utf8").trim();
57
- if (SEMVER_PATTERN.test(raw)) {
58
- return { version: raw, path: candidate };
59
- }
60
- }
61
- catch {
62
- // Missing or unreadable — try the next candidate.
63
- }
64
- }
65
- return undefined;
66
- }
67
- /**
68
- * Deliberately not `getConfig()`: that resolves the whole auth config and exits
69
- * the process on a workspace conflict, which a header printed before every
70
- * command must never do. Presence of a credential is all this line needs.
71
- */
72
- export function isSignedIn() {
73
- const token = process.env["CARGO_API_TOKEN"];
74
- if (token !== undefined && token.trim() !== "") {
75
- return true;
76
- }
77
- try {
78
- return loadCredentials() !== undefined;
79
- }
80
- catch {
81
- return false;
82
- }
83
- }
84
- function skillsPinCandidates() {
85
- const home = os.homedir();
86
- const envDir = process.env["CARGO_SKILLS_DIR"];
87
- const candidates = [];
88
- if (envDir !== undefined && envDir.length > 0) {
89
- candidates.push(path.join(envDir, "cargo", "cli-version"));
90
- }
91
- candidates.push(path.join(home, ".claude", "skills", "cargo", "cli-version"), path.join(home, ".claude", "plugins", "marketplaces", "cargo", "cargo", "cli-version"), path.join(home, ".openclaw", "skills", "cargo", "cli-version"));
92
- return candidates;
93
- }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cargo-ai/cli",
3
- "version": "1.0.72",
3
+ "version": "1.0.73",
4
4
  "private": false,
5
5
  "license": "UNLICENSED",
6
6
  "homepage": "https://getcargo.ai",
@@ -64,9 +64,9 @@
64
64
  "format:check": "prettier --check ."
65
65
  },
66
66
  "dependencies": {
67
- "@cargo-ai/api": "^1.0.69",
67
+ "@cargo-ai/api": "^1.0.70",
68
68
  "@cargo-ai/app-sdk": "^1.0.9",
69
- "@cargo-ai/cdk": "^1.0.57",
69
+ "@cargo-ai/cdk": "^1.0.59",
70
70
  "@cargo-ai/types": "^1.0.66",
71
71
  "@cargo-ai/worker-sdk": "^1.0.17",
72
72
  "@modelcontextprotocol/sdk": "1.29.0",