@cargo-ai/cli 1.0.139 → 1.0.141
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/content/file.d.ts.map +1 -1
- package/build/commands/content/file.js +5 -28
- package/build/commands/workspaceManagement/file.d.ts.map +1 -1
- package/build/commands/workspaceManagement/file.js +4 -1
- package/build/commands/workspaceManagement/index.d.ts.map +1 -1
- package/build/commands/workspaceManagement/index.js +1 -3
- package/build/index.js +12 -0
- package/build/legacySessionHooks.d.ts +9 -0
- package/build/legacySessionHooks.d.ts.map +1 -0
- package/build/legacySessionHooks.js +101 -0
- package/build/utils/contentType.d.ts +2 -0
- package/build/utils/contentType.d.ts.map +1 -0
- package/build/utils/contentType.js +31 -0
- package/package.json +5 -5
- 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
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"file.d.ts","sourceRoot":"","sources":["../../../src/commands/content/file.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEzC,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"file.d.ts","sourceRoot":"","sources":["../../../src/commands/content/file.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEzC,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AAIxC,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,GAAG,GAAG,IAAI,CA0Q7E"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { readFile, writeFile } from "node:fs/promises";
|
|
2
|
-
import { basename
|
|
2
|
+
import { basename } from "node:path";
|
|
3
|
+
import { guessContentType } from "../../utils/contentType.js";
|
|
3
4
|
import { handleApiCall, outputJson } from "../runHandler.js";
|
|
4
5
|
export function registerFileCommands(parent, getApi) {
|
|
5
6
|
const file = parent.command("file").description("Storage file operations");
|
|
@@ -52,7 +53,9 @@ export function registerFileCommands(parent, getApi) {
|
|
|
52
53
|
.action(async (opts) => {
|
|
53
54
|
const buffer = await readFile(opts.file);
|
|
54
55
|
const name = basename(opts.file);
|
|
55
|
-
const fileObj = new File([buffer], name
|
|
56
|
+
const fileObj = new File([buffer], name, {
|
|
57
|
+
type: guessContentType(opts.file),
|
|
58
|
+
});
|
|
56
59
|
const api = getApi();
|
|
57
60
|
await handleApiCall(() => new Promise((resolve, reject) => {
|
|
58
61
|
api.content.file.upload({
|
|
@@ -207,29 +210,3 @@ const parseVisibility = (value) => {
|
|
|
207
210
|
}
|
|
208
211
|
throw new Error(`--visibility must be private or public, got ${value}`);
|
|
209
212
|
};
|
|
210
|
-
const CONTENT_TYPES_BY_EXTENSION = {
|
|
211
|
-
".csv": "text/csv",
|
|
212
|
-
".gif": "image/gif",
|
|
213
|
-
".html": "text/html",
|
|
214
|
-
".jpeg": "image/jpeg",
|
|
215
|
-
".jpg": "image/jpeg",
|
|
216
|
-
".json": "application/json",
|
|
217
|
-
".md": "text/markdown",
|
|
218
|
-
".mp3": "audio/mpeg",
|
|
219
|
-
".mp4": "video/mp4",
|
|
220
|
-
".pdf": "application/pdf",
|
|
221
|
-
".png": "image/png",
|
|
222
|
-
".pptx": "application/vnd.openxmlformats-officedocument.presentationml.presentation",
|
|
223
|
-
".svg": "image/svg+xml",
|
|
224
|
-
".txt": "text/plain",
|
|
225
|
-
".wav": "audio/wav",
|
|
226
|
-
".webm": "video/webm",
|
|
227
|
-
".webp": "image/webp",
|
|
228
|
-
".docx": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
|
229
|
-
".xlsx": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
|
230
|
-
".zip": "application/zip",
|
|
231
|
-
};
|
|
232
|
-
const guessContentType = (filePath) => {
|
|
233
|
-
const contentType = CONTENT_TYPES_BY_EXTENSION[extname(filePath).toLowerCase()];
|
|
234
|
-
return contentType !== undefined ? contentType : "application/octet-stream";
|
|
235
|
-
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"file.d.ts","sourceRoot":"","sources":["../../../src/commands/workspaceManagement/file.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEzC,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"file.d.ts","sourceRoot":"","sources":["../../../src/commands/workspaceManagement/file.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEzC,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AAIxC,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,GAAG,GAAG,IAAI,CAiD7E"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { readFile } from "node:fs/promises";
|
|
2
2
|
import { basename } from "node:path";
|
|
3
|
+
import { guessContentType } from "../../utils/contentType.js";
|
|
3
4
|
import { handleApiCall, outputJson } from "../runHandler.js";
|
|
4
5
|
export function registerFileCommands(parent, getApi) {
|
|
5
6
|
const file = parent.command("file").description("Workspace file operations");
|
|
@@ -10,7 +11,9 @@ export function registerFileCommands(parent, getApi) {
|
|
|
10
11
|
.action(async (opts) => {
|
|
11
12
|
const buffer = await readFile(opts.file);
|
|
12
13
|
const name = basename(opts.file);
|
|
13
|
-
const fileObj = new File([buffer], name
|
|
14
|
+
const fileObj = new File([buffer], name, {
|
|
15
|
+
type: guessContentType(opts.file),
|
|
16
|
+
});
|
|
14
17
|
const api = getApi();
|
|
15
18
|
await handleApiCall(() => new Promise((resolve, reject) => {
|
|
16
19
|
api.workspaceManagement.file.upload({
|
|
@@ -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
|
@@ -32,6 +32,7 @@ import { registerUserManagementCommands } from "./commands/userManagement/index.
|
|
|
32
32
|
import { registerVersionCommand } from "./commands/version.js";
|
|
33
33
|
import { registerWorkspaceManagementCommands } from "./commands/workspaceManagement/index.js";
|
|
34
34
|
import { getConfig } from "./config.js";
|
|
35
|
+
import { removeLegacySessionHooks } from "./legacySessionHooks.js";
|
|
35
36
|
import { buildPaletteLayout } from "./paletteLayout.js";
|
|
36
37
|
import { collectSetupIssues, isSignedIn } from "./setupIssues.js";
|
|
37
38
|
import { cachedLatestSkillsPin, cachedLatestVersion, maybeRefreshUpdateCache, } from "./updateNotifier.js";
|
|
@@ -237,6 +238,17 @@ declareSources({
|
|
|
237
238
|
},
|
|
238
239
|
],
|
|
239
240
|
});
|
|
241
|
+
// Before parsing, so it also runs from the legacy hook itself, which still
|
|
242
|
+
// calls the `workspaceManagement session upsert` command removed with it.
|
|
243
|
+
try {
|
|
244
|
+
const removal = removeLegacySessionHooks();
|
|
245
|
+
if (removal.outcome === "removed") {
|
|
246
|
+
process.stderr.write(`Removed the retired Cargo session hooks: ${removal.paths.join(", ")}.\n`);
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
catch {
|
|
250
|
+
// A cleanup that fails is retried by the next command; it never blocks this one.
|
|
251
|
+
}
|
|
240
252
|
const argv = pinAskBooleanFlags(rewriteChatFlag(process.argv));
|
|
241
253
|
const binPath = process.argv[1] === undefined ? "cargo-ai" : process.argv[1];
|
|
242
254
|
// First, so it is the first row of the palette: for someone signed in, this is
|
|
@@ -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
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contentType.d.ts","sourceRoot":"","sources":["../../src/utils/contentType.ts"],"names":[],"mappings":"AA+BA,eAAO,MAAM,gBAAgB,aAAc,MAAM,KAAG,MAKnD,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { extname } from "node:path";
|
|
2
|
+
// Uploads carry this as their type: without it the API stores the file as
|
|
3
|
+
// application/octet-stream under a `.bin` key, and an image shows up as a
|
|
4
|
+
// document.
|
|
5
|
+
const CONTENT_TYPES_BY_EXTENSION = {
|
|
6
|
+
".csv": "text/csv",
|
|
7
|
+
".gif": "image/gif",
|
|
8
|
+
".html": "text/html",
|
|
9
|
+
".jpeg": "image/jpeg",
|
|
10
|
+
".jpg": "image/jpeg",
|
|
11
|
+
".json": "application/json",
|
|
12
|
+
".md": "text/markdown",
|
|
13
|
+
".mov": "video/quicktime",
|
|
14
|
+
".mp3": "audio/mpeg",
|
|
15
|
+
".mp4": "video/mp4",
|
|
16
|
+
".pdf": "application/pdf",
|
|
17
|
+
".png": "image/png",
|
|
18
|
+
".pptx": "application/vnd.openxmlformats-officedocument.presentationml.presentation",
|
|
19
|
+
".svg": "image/svg+xml",
|
|
20
|
+
".txt": "text/plain",
|
|
21
|
+
".wav": "audio/wav",
|
|
22
|
+
".webm": "video/webm",
|
|
23
|
+
".webp": "image/webp",
|
|
24
|
+
".docx": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
|
25
|
+
".xlsx": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
|
26
|
+
".zip": "application/zip",
|
|
27
|
+
};
|
|
28
|
+
export const guessContentType = (filePath) => {
|
|
29
|
+
const contentType = CONTENT_TYPES_BY_EXTENSION[extname(filePath).toLowerCase()];
|
|
30
|
+
return contentType !== undefined ? contentType : "application/octet-stream";
|
|
31
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cargo-ai/cli",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.141",
|
|
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,10 +74,10 @@
|
|
|
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.
|
|
79
|
+
"@cargo-ai/cdk": "^1.0.135",
|
|
80
|
+
"@cargo-ai/types": "^1.0.105",
|
|
81
81
|
"@cargo-ai/utils": "^1.0.35",
|
|
82
82
|
"@cargo-ai/worker-sdk": "^1.0.21",
|
|
83
83
|
"@modelcontextprotocol/sdk": "^1.32.0",
|
|
@@ -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
|
-
}
|