@cargo-ai/cli 1.0.140 → 1.0.142
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/commands/docs.d.ts +5 -0
- package/build/commands/docs.d.ts.map +1 -0
- package/build/commands/docs.js +27 -0
- package/build/commands/signedOutNotice.d.ts +1 -1
- package/build/commands/signedOutNotice.d.ts.map +1 -1
- package/build/commands/signedOutNotice.js +1 -1
- package/build/commands/skills.d.ts +3 -0
- package/build/commands/skills.d.ts.map +1 -0
- package/build/commands/skills.js +32 -0
- package/build/commands/workspaceManagement/index.d.ts.map +1 -1
- package/build/commands/workspaceManagement/index.js +1 -3
- package/build/index.js +22 -1
- package/build/legacySessionHooks.d.ts +9 -0
- package/build/legacySessionHooks.d.ts.map +1 -0
- package/build/legacySessionHooks.js +101 -0
- package/build/paletteLayout.d.ts +5 -0
- package/build/paletteLayout.d.ts.map +1 -1
- package/build/paletteLayout.js +72 -13
- package/package.json +6 -6
- package/build/commands/workspaceManagement/session.d.ts +0 -4
- package/build/commands/workspaceManagement/session.d.ts.map +0 -1
- package/build/commands/workspaceManagement/session.js +0 -32
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { Command } from "commander";
|
|
2
|
+
/** The same address the website links as its documentation. */
|
|
3
|
+
export declare const DOCS_URL = "https://docs.getcargo.ai";
|
|
4
|
+
export declare function registerDocsCommand(program: Command): void;
|
|
5
|
+
//# sourceMappingURL=docs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"docs.d.ts","sourceRoot":"","sources":["../../src/commands/docs.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKzC,+DAA+D;AAC/D,eAAO,MAAM,QAAQ,6BAA6B,CAAC;AAMnD,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAe1D"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { openBrowser } from "../utils/openBrowser.js";
|
|
2
|
+
import { colors, info, outputJson } from "./runHandler.js";
|
|
3
|
+
/** The same address the website links as its documentation. */
|
|
4
|
+
export const DOCS_URL = "https://docs.getcargo.ai";
|
|
5
|
+
export function registerDocsCommand(program) {
|
|
6
|
+
program
|
|
7
|
+
.command("docs")
|
|
8
|
+
.description("Open the Cargo documentation in your browser")
|
|
9
|
+
.option("--no-open", "Print the URL without launching a browser")
|
|
10
|
+
.addHelpText("after", `
|
|
11
|
+
Examples:
|
|
12
|
+
$ cargo-ai docs
|
|
13
|
+
$ cargo-ai docs --no-open`)
|
|
14
|
+
.action((opts) => {
|
|
15
|
+
runDocs(opts);
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
function runDocs(opts) {
|
|
19
|
+
const opened = opts.open === true;
|
|
20
|
+
info("");
|
|
21
|
+
info(`The Cargo docs: ${colors.cyan(DOCS_URL)}`);
|
|
22
|
+
info("");
|
|
23
|
+
if (opened === true) {
|
|
24
|
+
openBrowser(DOCS_URL);
|
|
25
|
+
}
|
|
26
|
+
outputJson({ ok: true, url: DOCS_URL, opened });
|
|
27
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export declare const SIGN_UP_COMMAND = "cargo-ai login --email you@company.com";
|
|
2
|
-
export declare const SIGNED_OUT_NOTICE = "Not signed in: reading the official integrations and their actions only. Sign up with `cargo-ai login --email you@company.com` (100 free credits
|
|
2
|
+
export declare const SIGNED_OUT_NOTICE = "Not signed in: reading the official integrations and their actions only. Sign up with `cargo-ai login --email you@company.com` (100 free credits for your first month; no card with a work email) to run one.";
|
|
3
3
|
export declare function noteSignedOut(): void;
|
|
4
4
|
//# sourceMappingURL=signedOutNotice.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"signedOutNotice.d.ts","sourceRoot":"","sources":["../../src/commands/signedOutNotice.ts"],"names":[],"mappings":"AAOA,eAAO,MAAM,eAAe,2CAA2C,CAAC;AAExE,eAAO,MAAM,iBAAiB,
|
|
1
|
+
{"version":3,"file":"signedOutNotice.d.ts","sourceRoot":"","sources":["../../src/commands/signedOutNotice.ts"],"names":[],"mappings":"AAOA,eAAO,MAAM,eAAe,2CAA2C,CAAC;AAExE,eAAO,MAAM,iBAAiB,kNAAgM,CAAC;AAE/N,wBAAgB,aAAa,IAAI,IAAI,CAIpC"}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
import { isSignedIn } from "@cargo-ai/cdk/cli";
|
|
4
4
|
import { info } from "./runHandler.js";
|
|
5
5
|
export const SIGN_UP_COMMAND = "cargo-ai login --email you@company.com";
|
|
6
|
-
export const SIGNED_OUT_NOTICE = `Not signed in: reading the official integrations and their actions only. Sign up with \`${SIGN_UP_COMMAND}\` (100 free credits
|
|
6
|
+
export const SIGNED_OUT_NOTICE = `Not signed in: reading the official integrations and their actions only. Sign up with \`${SIGN_UP_COMMAND}\` (100 free credits for your first month; no card with a work email) to run one.`;
|
|
7
7
|
export function noteSignedOut() {
|
|
8
8
|
if (isSignedIn() === false) {
|
|
9
9
|
info(SIGNED_OUT_NOTICE);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skills.d.ts","sourceRoot":"","sources":["../../src/commands/skills.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIzC,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAsB7D"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { installSkillsGlobally, SKILLS_INSTALL_COMMAND, skillsInstalledFor, } from "@cargo-ai/cdk/cli";
|
|
2
|
+
import { failWith, info, outputJson } from "./runHandler.js";
|
|
3
|
+
export function registerSkillsCommands(program) {
|
|
4
|
+
const skills = program
|
|
5
|
+
.command("skills")
|
|
6
|
+
.description("The Cargo skills, so your coding agent knows this CLI");
|
|
7
|
+
skills
|
|
8
|
+
.command("install")
|
|
9
|
+
.description("Install the Cargo skills for every coding agent here")
|
|
10
|
+
.addHelpText("after", `
|
|
11
|
+
Installs the getcargohq/cargo-skills bundle for every coding agent on this
|
|
12
|
+
machine (Claude Code, Codex, Cursor, …). Does nothing when this machine, or the
|
|
13
|
+
project you are in, already has them. Running it is the consent: unlike the
|
|
14
|
+
offer after sign-in, it does not ask first.
|
|
15
|
+
|
|
16
|
+
Equivalent to:
|
|
17
|
+
$ ${SKILLS_INSTALL_COMMAND}`)
|
|
18
|
+
.action(() => {
|
|
19
|
+
runInstall();
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
function runInstall() {
|
|
23
|
+
if (skillsInstalledFor(process.cwd()) === true) {
|
|
24
|
+
info("The Cargo skills are already installed.");
|
|
25
|
+
outputJson({ ok: true, installed: true });
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
if (installSkillsGlobally() === false) {
|
|
29
|
+
failWith(`Could not install the Cargo skills. Install them with: ${SKILLS_INSTALL_COMMAND}`);
|
|
30
|
+
}
|
|
31
|
+
outputJson({ ok: true, installed: true });
|
|
32
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/workspaceManagement/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEzC,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/workspaceManagement/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEzC,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AAUxC,wBAAgB,mCAAmC,CACjD,MAAM,EAAE,OAAO,EACf,MAAM,EAAE,MAAM,GAAG,GAChB,IAAI,CAeN"}
|
|
@@ -3,14 +3,13 @@ import { registerFileCommands } from "./file.js";
|
|
|
3
3
|
import { registerFolderCommands } from "./folder.js";
|
|
4
4
|
import { registerReportCommands } from "./report.js";
|
|
5
5
|
import { registerRoleCommands } from "./role.js";
|
|
6
|
-
import { registerSessionCommands } from "./session.js";
|
|
7
6
|
import { registerTokenCommands } from "./token.js";
|
|
8
7
|
import { registerUserCommands } from "./user.js";
|
|
9
8
|
import { registerWorkspacesCommands } from "./workspaces.js";
|
|
10
9
|
export function registerWorkspaceManagementCommands(parent, getApi) {
|
|
11
10
|
const workspaceManagement = parent
|
|
12
11
|
.command("workspaceManagement")
|
|
13
|
-
.description("Workspaces, users, tokens, environment variables, roles, folders, reports
|
|
12
|
+
.description("Workspaces, users, tokens, environment variables, roles, folders, reports");
|
|
14
13
|
registerWorkspacesCommands(workspaceManagement, getApi);
|
|
15
14
|
registerUserCommands(workspaceManagement, getApi);
|
|
16
15
|
registerTokenCommands(workspaceManagement, getApi);
|
|
@@ -19,5 +18,4 @@ export function registerWorkspaceManagementCommands(parent, getApi) {
|
|
|
19
18
|
registerFolderCommands(workspaceManagement, getApi);
|
|
20
19
|
registerFileCommands(workspaceManagement, getApi);
|
|
21
20
|
registerReportCommands(workspaceManagement, getApi);
|
|
22
|
-
registerSessionCommands(workspaceManagement, getApi);
|
|
23
21
|
}
|
package/build/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { createRequire } from "node:module";
|
|
3
|
-
import { availableCodingAgents, BRAND, canRunPalette, creditsLeftOf, declareSources, fetchStateConnected, fetchSubscription, fetchWorkspaceName, findProjectDir, formatWorkspaceSuffix, isInteractive, isUnpaidPlan, printSetupIssues, registerCommands as registerCdkCommands, runPalette, SessionExpiredError, } from "@cargo-ai/cdk/cli";
|
|
3
|
+
import { availableCodingAgents, BRAND, canRunPalette, creditsLeftOf, declareSources, fetchStateConnected, fetchSubscription, fetchWorkspaceName, findProjectDir, formatWorkspaceSuffix, isInteractive, isUnpaidPlan, printSetupIssues, registerCommands as registerCdkCommands, runPalette, SessionExpiredError, skillsInstalledFor, } 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";
|
|
@@ -14,6 +14,7 @@ import { registerBookDemoCommand } from "./commands/bookDemo.js";
|
|
|
14
14
|
import { registerConnectionCommands } from "./commands/connection/index.js";
|
|
15
15
|
import { registerContentCommands } from "./commands/content/index.js";
|
|
16
16
|
import { registerContextCommands } from "./commands/context/index.js";
|
|
17
|
+
import { registerDocsCommand } from "./commands/docs.js";
|
|
17
18
|
import { registerDoctorCommand } from "./commands/doctor.js";
|
|
18
19
|
import { registerExpressionCommands } from "./commands/expression/index.js";
|
|
19
20
|
import { registerHostingCommands } from "./commands/hosting/index.js";
|
|
@@ -24,6 +25,7 @@ import { registerOrchestrationCommands } from "./commands/orchestration/index.js
|
|
|
24
25
|
import { registerRevenueOrganizationCommands } from "./commands/revenueOrganization/index.js";
|
|
25
26
|
import { ExitCodes, failWith } from "./commands/runHandler.js";
|
|
26
27
|
import { registerSegmentationCommands } from "./commands/segmentation/index.js";
|
|
28
|
+
import { registerSkillsCommands } from "./commands/skills.js";
|
|
27
29
|
import { registerStartCommand, runStart } from "./commands/start/index.js";
|
|
28
30
|
import { loadStartState, shouldRunStart } from "./commands/start/state.js";
|
|
29
31
|
import { registerStorageCommands } from "./commands/storage/index.js";
|
|
@@ -32,6 +34,7 @@ import { registerUserManagementCommands } from "./commands/userManagement/index.
|
|
|
32
34
|
import { registerVersionCommand } from "./commands/version.js";
|
|
33
35
|
import { registerWorkspaceManagementCommands } from "./commands/workspaceManagement/index.js";
|
|
34
36
|
import { getConfig } from "./config.js";
|
|
37
|
+
import { removeLegacySessionHooks } from "./legacySessionHooks.js";
|
|
35
38
|
import { buildPaletteLayout } from "./paletteLayout.js";
|
|
36
39
|
import { collectSetupIssues, isSignedIn } from "./setupIssues.js";
|
|
37
40
|
import { cachedLatestSkillsPin, cachedLatestVersion, maybeRefreshUpdateCache, } from "./updateNotifier.js";
|
|
@@ -106,6 +109,9 @@ const SETUP_HEADER_SKIP = [
|
|
|
106
109
|
"mcp",
|
|
107
110
|
"ask",
|
|
108
111
|
"book-demo",
|
|
112
|
+
"docs",
|
|
113
|
+
// The header's skills line would ask for the install this command runs.
|
|
114
|
+
"skills",
|
|
109
115
|
];
|
|
110
116
|
/**
|
|
111
117
|
* Say what is wrong before the command runs rather than after it fails, and
|
|
@@ -237,6 +243,17 @@ declareSources({
|
|
|
237
243
|
},
|
|
238
244
|
],
|
|
239
245
|
});
|
|
246
|
+
// Before parsing, so it also runs from the legacy hook itself, which still
|
|
247
|
+
// calls the `workspaceManagement session upsert` command removed with it.
|
|
248
|
+
try {
|
|
249
|
+
const removal = removeLegacySessionHooks();
|
|
250
|
+
if (removal.outcome === "removed") {
|
|
251
|
+
process.stderr.write(`Removed the retired Cargo session hooks: ${removal.paths.join(", ")}.\n`);
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
catch {
|
|
255
|
+
// A cleanup that fails is retried by the next command; it never blocks this one.
|
|
256
|
+
}
|
|
240
257
|
const argv = pinAskBooleanFlags(rewriteChatFlag(process.argv));
|
|
241
258
|
const binPath = process.argv[1] === undefined ? "cargo-ai" : process.argv[1];
|
|
242
259
|
// First, so it is the first row of the palette: for someone signed in, this is
|
|
@@ -248,6 +265,8 @@ registerAuthCommands(program, getApi);
|
|
|
248
265
|
registerVersionCommand(program, version);
|
|
249
266
|
registerDoctorCommand(program, version);
|
|
250
267
|
registerBookDemoCommand(program);
|
|
268
|
+
registerDocsCommand(program);
|
|
269
|
+
registerSkillsCommands(program);
|
|
251
270
|
registerObservabilityCommands(program, getApi);
|
|
252
271
|
registerOrchestrationCommands(program, getApi, getPublicApi);
|
|
253
272
|
registerWorkspaceManagementCommands(program, getApi);
|
|
@@ -321,6 +340,8 @@ async function openPalette(startPath) {
|
|
|
321
340
|
agents,
|
|
322
341
|
projectDir: root,
|
|
323
342
|
cwd,
|
|
343
|
+
// Re-read with the rest: picking "Install skills" is what changes it.
|
|
344
|
+
skillsInstalled: skillsInstalledFor(cwd),
|
|
324
345
|
unpaidPlan: lookups.unpaidPlan,
|
|
325
346
|
// Only trusted for the project it was asked about: a command can `cd`
|
|
326
347
|
// the process or create a project, and an answer about another state
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export type RemoveLegacySessionHooksResult = {
|
|
2
|
+
outcome: "removed";
|
|
3
|
+
paths: string[];
|
|
4
|
+
} | {
|
|
5
|
+
outcome: "notRemoved";
|
|
6
|
+
reason: "noLegacyHooks" | "settingsUnreadable";
|
|
7
|
+
};
|
|
8
|
+
export declare const removeLegacySessionHooks: (homeDir?: string) => RemoveLegacySessionHooksResult;
|
|
9
|
+
//# sourceMappingURL=legacySessionHooks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"legacySessionHooks.d.ts","sourceRoot":"","sources":["../src/legacySessionHooks.ts"],"names":[],"mappings":"AAyBA,MAAM,MAAM,8BAA8B,GACtC;IAAE,OAAO,EAAE,SAAS,CAAC;IAAC,KAAK,EAAE,MAAM,EAAE,CAAA;CAAE,GACvC;IAAE,OAAO,EAAE,YAAY,CAAC;IAAC,MAAM,EAAE,eAAe,GAAG,oBAAoB,CAAA;CAAE,CAAC;AAE9E,eAAO,MAAM,wBAAwB,aAC1B,MAAM,KACd,8BAwBF,CAAC"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { existsSync, readFileSync, renameSync, unlinkSync, writeFileSync, } from "node:fs";
|
|
2
|
+
import { homedir } from "node:os";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
// What the retired standalone installer (api.getcargo.io/install.sh) put in
|
|
5
|
+
// ~/.claude/hooks: session hooks that uploaded each session's latest prompt and
|
|
6
|
+
// an AI-written summary. That standalone session-start.sh installs the pinned
|
|
7
|
+
// CLI at every session start, so this release reaches those machines through
|
|
8
|
+
// it, and removes the hooks the first time any `cargo-ai` command runs.
|
|
9
|
+
const LEGACY_HOOK_FILES = [
|
|
10
|
+
"session-start.sh",
|
|
11
|
+
"session-checkpoint.sh",
|
|
12
|
+
"session-end.sh",
|
|
13
|
+
];
|
|
14
|
+
// Every version of those scripts opens with this, and only ours do: a file of
|
|
15
|
+
// the same name that another tool wrote is left alone.
|
|
16
|
+
const CARGO_HOOK_HEADER = "# Cargo session";
|
|
17
|
+
export const removeLegacySessionHooks = (homeDir = homedir()) => {
|
|
18
|
+
const hooksDir = join(homeDir, ".claude", "hooks");
|
|
19
|
+
const paths = LEGACY_HOOK_FILES.map((file) => join(hooksDir, file)).filter((path) => isCargoHook(path));
|
|
20
|
+
if (paths.length === 0) {
|
|
21
|
+
return { outcome: "notRemoved", reason: "noLegacyHooks" };
|
|
22
|
+
}
|
|
23
|
+
// Deregister first, and delete only once that worked: a hook still listed in
|
|
24
|
+
// settings.json but missing on disk errors at every session.
|
|
25
|
+
const settingsPath = join(homeDir, ".claude", "settings.json");
|
|
26
|
+
const isDeregistered = deregisterHooks(settingsPath, paths);
|
|
27
|
+
if (isDeregistered === false) {
|
|
28
|
+
return { outcome: "notRemoved", reason: "settingsUnreadable" };
|
|
29
|
+
}
|
|
30
|
+
paths.forEach((path) => {
|
|
31
|
+
unlinkSync(path);
|
|
32
|
+
});
|
|
33
|
+
return { outcome: "removed", paths };
|
|
34
|
+
};
|
|
35
|
+
function isCargoHook(path) {
|
|
36
|
+
if (existsSync(path) === false) {
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
return readFileSync(path, "utf8").includes(CARGO_HOOK_HEADER);
|
|
40
|
+
}
|
|
41
|
+
function deregisterHooks(settingsPath, paths) {
|
|
42
|
+
if (existsSync(settingsPath) === false) {
|
|
43
|
+
return true;
|
|
44
|
+
}
|
|
45
|
+
let settings;
|
|
46
|
+
try {
|
|
47
|
+
settings = JSON.parse(readFileSync(settingsPath, "utf8"));
|
|
48
|
+
}
|
|
49
|
+
catch {
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
if (isRecord(settings) === false) {
|
|
53
|
+
return false;
|
|
54
|
+
}
|
|
55
|
+
const hooks = settings["hooks"];
|
|
56
|
+
if (isRecord(hooks) === false) {
|
|
57
|
+
return true;
|
|
58
|
+
}
|
|
59
|
+
let isChanged = false;
|
|
60
|
+
const keptHooks = {};
|
|
61
|
+
Object.entries(hooks).forEach(([event, entries]) => {
|
|
62
|
+
if (Array.isArray(entries) === false) {
|
|
63
|
+
keptHooks[event] = entries;
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
const keptEntries = entries.flatMap((entry) => {
|
|
67
|
+
if (isRecord(entry) === false ||
|
|
68
|
+
Array.isArray(entry["hooks"]) === false) {
|
|
69
|
+
return [entry];
|
|
70
|
+
}
|
|
71
|
+
const commands = entry["hooks"];
|
|
72
|
+
const keptCommands = commands.filter((command) => isRecord(command) === false ||
|
|
73
|
+
paths.includes(String(command["command"])) === false);
|
|
74
|
+
if (keptCommands.length === commands.length) {
|
|
75
|
+
return [entry];
|
|
76
|
+
}
|
|
77
|
+
isChanged = true;
|
|
78
|
+
if (keptCommands.length === 0) {
|
|
79
|
+
return [];
|
|
80
|
+
}
|
|
81
|
+
return [{ ...entry, hooks: keptCommands }];
|
|
82
|
+
});
|
|
83
|
+
if (keptEntries.length > 0) {
|
|
84
|
+
keptHooks[event] = keptEntries;
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
if (isChanged === false) {
|
|
88
|
+
return true;
|
|
89
|
+
}
|
|
90
|
+
// Through a temporary file, so an interrupted write never leaves Claude Code
|
|
91
|
+
// with half a settings.json.
|
|
92
|
+
const temporaryPath = `${settingsPath}.cargo-${String(process.pid)}`;
|
|
93
|
+
writeFileSync(temporaryPath, `${JSON.stringify({ ...settings, hooks: keptHooks }, null, 2)}\n`);
|
|
94
|
+
renameSync(temporaryPath, settingsPath);
|
|
95
|
+
return true;
|
|
96
|
+
}
|
|
97
|
+
function isRecord(value) {
|
|
98
|
+
return (typeof value === "object" &&
|
|
99
|
+
value !== null &&
|
|
100
|
+
Array.isArray(value) === false);
|
|
101
|
+
}
|
package/build/paletteLayout.d.ts
CHANGED
|
@@ -22,6 +22,11 @@ export type PaletteLayoutInput = {
|
|
|
22
22
|
* row that fails when picked.
|
|
23
23
|
*/
|
|
24
24
|
stateConnected?: boolean;
|
|
25
|
+
/**
|
|
26
|
+
* Whether a coding agent opened here would find the Cargo skills. True hides
|
|
27
|
+
* "Agent skills": a row that would only say "already installed".
|
|
28
|
+
*/
|
|
29
|
+
skillsInstalled?: boolean;
|
|
25
30
|
};
|
|
26
31
|
export declare function buildPaletteLayout(input: PaletteLayoutInput): PaletteLayout;
|
|
27
32
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"paletteLayout.d.ts","sourceRoot":"","sources":["../src/paletteLayout.ts"],"names":[],"mappings":"AAYA,OAAO,EAEL,KAAK,WAAW,EAChB,KAAK,aAAa,EAClB,KAAK,SAAS,EACf,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"paletteLayout.d.ts","sourceRoot":"","sources":["../src/paletteLayout.ts"],"names":[],"mappings":"AAYA,OAAO,EAEL,KAAK,WAAW,EAChB,KAAK,aAAa,EAClB,KAAK,SAAS,EACf,MAAM,mBAAmB,CAAC;AAwH3B,MAAM,MAAM,kBAAkB,GAAG;IAC/B,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,EAAE,SAAS,WAAW,EAAE,CAAC;IAC/B,mFAAmF;IACnF,UAAU,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B;;;;OAIG;IACH,GAAG,EAAE,MAAM,CAAC;IACZ;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;;;OAKG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB;;;OAGG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B,CAAC;AAEF,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,kBAAkB,GAAG,aAAa,CAQ3E;AA2BD;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,kBAAkB,GAAG,SAAS,EAAE,CAmFjE"}
|
package/build/paletteLayout.js
CHANGED
|
@@ -37,16 +37,20 @@ const ENTRANCE = "start";
|
|
|
37
37
|
* opens a menu of rows already on screen is a detour. `ask` is the same kind
|
|
38
38
|
* of entrance — pinned as "Ask Cargo" — so drawing it again in the tree is a
|
|
39
39
|
* second door to the same room. `version` is `--version`, and `doctor`
|
|
40
|
-
* reports it anyway. `book-demo`
|
|
41
|
-
*
|
|
40
|
+
* reports it anyway. `login`, `logout`, `skills` and `book-demo` come and go
|
|
41
|
+
* with the session; see `hiddenRows`.
|
|
42
42
|
*/
|
|
43
43
|
const HIDDEN = [ENTRANCE, "ask", "version"];
|
|
44
44
|
/**
|
|
45
|
-
* The sections, in reading order:
|
|
46
|
-
* the
|
|
47
|
-
*
|
|
48
|
-
*
|
|
49
|
-
*
|
|
45
|
+
* The sections, in reading order: the errands you run on your own setup —
|
|
46
|
+
* your account, the docs, the agent skills — then the workspace as code, then
|
|
47
|
+
* the command groups. What people reach for most is not here at all; those
|
|
48
|
+
* are the pinned rows, above the first section.
|
|
49
|
+
*
|
|
50
|
+
* The command groups come last because they are the reference shelf: each is
|
|
51
|
+
* a menu of its own, and nobody opening the palette starts by reading them
|
|
52
|
+
* all. The short rows above them would otherwise sit two screens down, beside
|
|
53
|
+
* `/exit`.
|
|
50
54
|
*
|
|
51
55
|
* Anything a release adds and nobody lists here still appears, in tree order,
|
|
52
56
|
* in a final section — a new command is never invisible by omission. So a new
|
|
@@ -54,6 +58,12 @@ const HIDDEN = [ENTRANCE, "ask", "version"];
|
|
|
54
58
|
* no entry to be reachable.
|
|
55
59
|
*/
|
|
56
60
|
const SECTIONS = [
|
|
61
|
+
// Signed out, `login` and `logout` are both hidden behind the pinned Sign in,
|
|
62
|
+
// so `login` is only ever seen signed in, as "Switch account".
|
|
63
|
+
["whoami", "login", "logout", "docs", "skills", "doctor", "book-demo"],
|
|
64
|
+
// The workspace as code sits on its own: it is the same resources again,
|
|
65
|
+
// declared in a repo rather than run from here.
|
|
66
|
+
["project"],
|
|
57
67
|
// Everything the workspace is: what you run, the data and connectors it runs
|
|
58
68
|
// on, the knowledge it reads, and the surfaces it exposes. One group, most
|
|
59
69
|
// used first — the divisions that used to be here were the CLI's own
|
|
@@ -78,20 +88,69 @@ const SECTIONS = [
|
|
|
78
88
|
"user-management",
|
|
79
89
|
"system-of-record",
|
|
80
90
|
],
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
91
|
+
];
|
|
92
|
+
/**
|
|
93
|
+
* What each root row reads as. Command names are written for a shell
|
|
94
|
+
* (`mailboxManagement`, `system-of-record`); a menu row is read by a person.
|
|
95
|
+
* The slash name still filters (`/ai` finds "AI"), and a command missing here
|
|
96
|
+
* keeps its `/name`.
|
|
97
|
+
*/
|
|
98
|
+
const LABELS = [
|
|
99
|
+
{ name: "whoami", label: "Who am I" },
|
|
100
|
+
{ name: "login", label: "Switch account" },
|
|
101
|
+
{ name: "logout", label: "Log out" },
|
|
102
|
+
{ name: "docs", label: "Docs" },
|
|
103
|
+
{ name: "skills", label: "Agent skills" },
|
|
104
|
+
{ name: "doctor", label: "Check setup" },
|
|
105
|
+
{ name: "book-demo", label: "Book a demo" },
|
|
106
|
+
{ name: "project", label: "Project" },
|
|
107
|
+
{ name: "orchestration", label: "Orchestration" },
|
|
108
|
+
{ name: "storage", label: "Storage" },
|
|
109
|
+
{ name: "connection", label: "Connections" },
|
|
110
|
+
{ name: "segmentation", label: "Segmentation" },
|
|
111
|
+
{ name: "ai", label: "AI" },
|
|
112
|
+
{ name: "context", label: "Context" },
|
|
113
|
+
{ name: "content", label: "Content" },
|
|
114
|
+
{ name: "hosting", label: "Hosting" },
|
|
115
|
+
{ name: "mcp", label: "MCP" },
|
|
116
|
+
{ name: "mailboxManagement", label: "Mailboxes" },
|
|
117
|
+
{ name: "workspaceManagement", label: "Workspace" },
|
|
118
|
+
{ name: "billing", label: "Billing" },
|
|
119
|
+
{ name: "observability", label: "Observability" },
|
|
120
|
+
{ name: "revenue-organization", label: "Revenue organization" },
|
|
121
|
+
{ name: "expression", label: "Expressions" },
|
|
122
|
+
{ name: "user-management", label: "User" },
|
|
123
|
+
{ name: "system-of-record", label: "Systems of record" },
|
|
85
124
|
];
|
|
86
125
|
export function buildPaletteLayout(input) {
|
|
87
|
-
const pinBookDemo = input.signedIn === true && input.unpaidPlan === true;
|
|
88
126
|
return {
|
|
89
127
|
pinned: pinnedRows(input),
|
|
90
|
-
hide:
|
|
128
|
+
hide: hiddenRows(input),
|
|
91
129
|
sections: SECTIONS,
|
|
130
|
+
labels: LABELS,
|
|
92
131
|
placeholder: "type to filter, or ask a question",
|
|
93
132
|
};
|
|
94
133
|
}
|
|
134
|
+
/**
|
|
135
|
+
* `HIDDEN`, plus the rows this session makes pointless. Signed out, there is
|
|
136
|
+
* nothing to log out of, and the pinned "Sign in" is the way in — it carries
|
|
137
|
+
* on into the rest of the setup, which a bare `login` does not. "Agent skills"
|
|
138
|
+
* goes once they are installed (installing is all the group does), and "Book a
|
|
139
|
+
* demo" is hidden here only when it is pinned.
|
|
140
|
+
*/
|
|
141
|
+
function hiddenRows(input) {
|
|
142
|
+
const hidden = [...HIDDEN];
|
|
143
|
+
if (input.signedIn === false) {
|
|
144
|
+
hidden.push("login", "logout");
|
|
145
|
+
}
|
|
146
|
+
if (input.skillsInstalled === true) {
|
|
147
|
+
hidden.push("skills");
|
|
148
|
+
}
|
|
149
|
+
if (input.signedIn === true && input.unpaidPlan === true) {
|
|
150
|
+
hidden.push("book-demo");
|
|
151
|
+
}
|
|
152
|
+
return hidden;
|
|
153
|
+
}
|
|
95
154
|
/**
|
|
96
155
|
* The rows above the rule. Signed out there is exactly one thing worth
|
|
97
156
|
* offering, and it is not a list of twenty command groups that all exit 3.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cargo-ai/cli",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.142",
|
|
4
4
|
"mcpName": "io.github.getcargohq/cargo",
|
|
5
5
|
"private": false,
|
|
6
6
|
"license": "UNLICENSED",
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
"node": ">=22"
|
|
49
49
|
},
|
|
50
50
|
"volta": {
|
|
51
|
-
"node": "
|
|
51
|
+
"node": "24.22.2"
|
|
52
52
|
},
|
|
53
53
|
"type": "module",
|
|
54
54
|
"bin": {
|
|
@@ -74,11 +74,11 @@
|
|
|
74
74
|
"dependencies": {
|
|
75
75
|
"@ai-sdk/harness": "1.0.144",
|
|
76
76
|
"@ai-sdk/harness-claude-code": "1.0.148",
|
|
77
|
-
"@cargo-ai/api": "^1.0.
|
|
77
|
+
"@cargo-ai/api": "^1.0.106",
|
|
78
78
|
"@cargo-ai/app-sdk": "^1.0.11",
|
|
79
|
-
"@cargo-ai/cdk": "^1.0.
|
|
80
|
-
"@cargo-ai/types": "^1.0.
|
|
81
|
-
"@cargo-ai/utils": "^1.0.
|
|
79
|
+
"@cargo-ai/cdk": "^1.0.136",
|
|
80
|
+
"@cargo-ai/types": "^1.0.106",
|
|
81
|
+
"@cargo-ai/utils": "^1.0.36",
|
|
82
82
|
"@cargo-ai/worker-sdk": "^1.0.21",
|
|
83
83
|
"@modelcontextprotocol/sdk": "^1.32.0",
|
|
84
84
|
"ai": "^7.0.133",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../../src/commands/workspaceManagement/session.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEzC,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AAIxC,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,OAAO,EACf,MAAM,EAAE,MAAM,GAAG,GAChB,IAAI,CAkDN"}
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import { parseBooleanOption } from "../../utils/booleanOption.js";
|
|
2
|
-
import { handleApiCall, outputJson } from "../runHandler.js";
|
|
3
|
-
export function registerSessionCommands(parent, getApi) {
|
|
4
|
-
const session = parent
|
|
5
|
-
.command("session")
|
|
6
|
-
.description("Claude Code session tracking");
|
|
7
|
-
session
|
|
8
|
-
.command("upsert")
|
|
9
|
-
.description("Create or update a Claude Code session")
|
|
10
|
-
.requiredOption("--session-id <sessionId>", "Claude Code session id")
|
|
11
|
-
.requiredOption("--title <title>", "Short title for the session")
|
|
12
|
-
.requiredOption("--summary <summary>", "Summary of what happened in the session")
|
|
13
|
-
.option("--finished [true|false]", "Mark the session as finished now (sets finishedAt = now)", parseBooleanOption)
|
|
14
|
-
.option("--finished-at <timestamp>", "Explicit ISO timestamp for when the session finished")
|
|
15
|
-
.action(async (opts) => {
|
|
16
|
-
let finishedAt;
|
|
17
|
-
if (opts.finishedAt !== undefined) {
|
|
18
|
-
finishedAt = opts.finishedAt;
|
|
19
|
-
}
|
|
20
|
-
else if (opts.finished === true) {
|
|
21
|
-
finishedAt = new Date().toISOString();
|
|
22
|
-
}
|
|
23
|
-
const api = getApi();
|
|
24
|
-
const result = await handleApiCall(() => api.workspaceManagement.session.upsert({
|
|
25
|
-
sessionId: opts.sessionId,
|
|
26
|
-
title: opts.title,
|
|
27
|
-
summary: opts.summary,
|
|
28
|
-
finishedAt,
|
|
29
|
-
}));
|
|
30
|
-
outputJson(result);
|
|
31
|
-
});
|
|
32
|
-
}
|