deepline 0.1.102 → 0.1.104
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 +14 -12
- package/dist/cli/index.js +711 -132
- package/dist/cli/index.mjs +721 -135
- package/dist/index.d.mts +6 -6
- package/dist/index.d.ts +6 -6
- package/dist/index.js +7 -5
- package/dist/index.mjs +7 -5
- package/dist/repo/sdk/src/client.ts +3 -3
- package/dist/repo/sdk/src/index.ts +1 -1
- package/dist/repo/sdk/src/play.ts +2 -2
- package/dist/repo/sdk/src/release.ts +4 -2
- package/dist/repo/sdk/src/types.ts +2 -2
- package/dist/repo/shared_libs/play-runtime/csv-rename.ts +26 -0
- package/dist/repo/shared_libs/play-runtime/providers.ts +2 -2
- package/dist/repo/shared_libs/play-runtime/scheduler-backend.ts +2 -0
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -25,8 +25,8 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
25
25
|
|
|
26
26
|
// src/cli/index.ts
|
|
27
27
|
var import_promises7 = require("fs/promises");
|
|
28
|
-
var
|
|
29
|
-
var
|
|
28
|
+
var import_node_path20 = require("path");
|
|
29
|
+
var import_node_os12 = require("os");
|
|
30
30
|
var import_commander3 = require("commander");
|
|
31
31
|
|
|
32
32
|
// src/config.ts
|
|
@@ -237,10 +237,12 @@ var SDK_RELEASE = {
|
|
|
237
237
|
// failed runs, persisted/succeeded/failed row counts, strict local CSV
|
|
238
238
|
// preflight (existence, data rows, quotes, duplicate headers), HTML error
|
|
239
239
|
// scrubbing, and word-boundary watch truncation.
|
|
240
|
-
|
|
240
|
+
// 0.1.103 ships the refined SDK CLI command surface.
|
|
241
|
+
// 0.1.104 ships postgres_fast suspension/billing parity and runtime worker hardening.
|
|
242
|
+
version: "0.1.104",
|
|
241
243
|
apiContract: "2026-06-dataset-column-cell-stale-hard-cutover",
|
|
242
244
|
supportPolicy: {
|
|
243
|
-
latest: "0.1.
|
|
245
|
+
latest: "0.1.104",
|
|
244
246
|
minimumSupported: "0.1.53",
|
|
245
247
|
deprecatedBelow: "0.1.53"
|
|
246
248
|
}
|
|
@@ -649,7 +651,7 @@ function decodeSseFrame(frame) {
|
|
|
649
651
|
return parsed;
|
|
650
652
|
}
|
|
651
653
|
function sleep(ms) {
|
|
652
|
-
return new Promise((
|
|
654
|
+
return new Promise((resolve16) => setTimeout(resolve16, ms));
|
|
653
655
|
}
|
|
654
656
|
|
|
655
657
|
// src/stream-reconnect.ts
|
|
@@ -1360,14 +1362,14 @@ async function* observeRunEvents(options) {
|
|
|
1360
1362
|
try {
|
|
1361
1363
|
for (; ; ) {
|
|
1362
1364
|
if (queue.length === 0) {
|
|
1363
|
-
const waitForItem = new Promise((
|
|
1364
|
-
wake =
|
|
1365
|
+
const waitForItem = new Promise((resolve16) => {
|
|
1366
|
+
wake = resolve16;
|
|
1365
1367
|
});
|
|
1366
1368
|
if (!sawFirstSnapshot) {
|
|
1367
1369
|
const timedOut = await Promise.race([
|
|
1368
1370
|
waitForItem.then(() => false),
|
|
1369
1371
|
new Promise(
|
|
1370
|
-
(
|
|
1372
|
+
(resolve16) => setTimeout(() => resolve16(true), OBSERVE_BOOTSTRAP_TIMEOUT_MS)
|
|
1371
1373
|
)
|
|
1372
1374
|
]);
|
|
1373
1375
|
if (timedOut && queue.length === 0) {
|
|
@@ -1464,7 +1466,7 @@ var EXECUTE_RESPONSE_CONTRACT_HEADER = "x-deepline-execute-response-contract";
|
|
|
1464
1466
|
var V2_EXECUTE_RESPONSE_CONTRACT = "v2-tool-response";
|
|
1465
1467
|
var COMPILE_MANIFEST_RETRY_DELAYS_MS = [250, 1e3];
|
|
1466
1468
|
function sleep2(ms) {
|
|
1467
|
-
return new Promise((
|
|
1469
|
+
return new Promise((resolve16) => setTimeout(resolve16, ms));
|
|
1468
1470
|
}
|
|
1469
1471
|
function isTransientCompileManifestError(error) {
|
|
1470
1472
|
if (error instanceof DeeplineError && typeof error.statusCode === "number") {
|
|
@@ -1906,7 +1908,7 @@ var DeeplineClient = class {
|
|
|
1906
1908
|
* or {@link runPlay}.
|
|
1907
1909
|
*
|
|
1908
1910
|
* Supported invocation surfaces intentionally share this same run contract:
|
|
1909
|
-
* `deepline
|
|
1911
|
+
* `deepline plays run`, repo scripts such as `bun run deepline -- plays run`,
|
|
1910
1912
|
* SDK context calls like `Deepline.connect().play(name).run()`, and direct
|
|
1911
1913
|
* `POST /api/v2/plays/run` calls all return a workflow/run id. The completed
|
|
1912
1914
|
* output is always retrievable from `getPlayStatus(runId).result` (or from
|
|
@@ -2075,7 +2077,7 @@ var DeeplineClient = class {
|
|
|
2075
2077
|
*
|
|
2076
2078
|
* Unlike {@link registerPlayArtifact}, this does not store the artifact,
|
|
2077
2079
|
* publish a revision, or start a run. It is the authoritative cloud validation
|
|
2078
|
-
* path used by `deepline
|
|
2080
|
+
* path used by `deepline plays check`.
|
|
2079
2081
|
*/
|
|
2080
2082
|
async checkPlayArtifact(input2) {
|
|
2081
2083
|
return this.http.post("/api/v2/plays/check", input2);
|
|
@@ -2268,7 +2270,7 @@ var DeeplineClient = class {
|
|
|
2268
2270
|
* Get the current status of a play execution.
|
|
2269
2271
|
*
|
|
2270
2272
|
* Internal/advanced primitive. Public callers should usually prefer
|
|
2271
|
-
* {@link runPlay}, {@link PlayJob.get}, or `deepline
|
|
2273
|
+
* {@link runPlay}, {@link PlayJob.get}, or `deepline plays run --watch`.
|
|
2272
2274
|
*
|
|
2273
2275
|
* @param workflowId - Play-run id from {@link startPlayRun}
|
|
2274
2276
|
* @returns Current status with progress logs and partial results
|
|
@@ -3111,9 +3113,9 @@ async function writeOutputFile(filename, content) {
|
|
|
3111
3113
|
return fullPath;
|
|
3112
3114
|
}
|
|
3113
3115
|
function browserOpenStateFile() {
|
|
3114
|
-
const
|
|
3116
|
+
const homeDir2 = process.env.HOME || (0, import_node_os3.homedir)();
|
|
3115
3117
|
return (0, import_node_path3.join)(
|
|
3116
|
-
|
|
3118
|
+
homeDir2,
|
|
3117
3119
|
".local",
|
|
3118
3120
|
"deepline",
|
|
3119
3121
|
"runtime",
|
|
@@ -3587,8 +3589,8 @@ function printCommandEnvelope(envelope, options = {}) {
|
|
|
3587
3589
|
|
|
3588
3590
|
// src/cli/commands/auth.ts
|
|
3589
3591
|
var EXIT_OK = 0;
|
|
3590
|
-
var EXIT_AUTH =
|
|
3591
|
-
var EXIT_SERVER =
|
|
3592
|
+
var EXIT_AUTH = 3;
|
|
3593
|
+
var EXIT_SERVER = 5;
|
|
3592
3594
|
function envFilePath(baseUrl) {
|
|
3593
3595
|
return hostEnvFilePath(baseUrl);
|
|
3594
3596
|
}
|
|
@@ -3680,7 +3682,7 @@ function buildCandidateUrls2(url) {
|
|
|
3680
3682
|
}
|
|
3681
3683
|
}
|
|
3682
3684
|
function sleep4(ms) {
|
|
3683
|
-
return new Promise((
|
|
3685
|
+
return new Promise((resolve16) => setTimeout(resolve16, ms));
|
|
3684
3686
|
}
|
|
3685
3687
|
function printDeeplineLogo() {
|
|
3686
3688
|
if (process.stdout.isTTY && (process.stdout.columns ?? 80) >= 70) {
|
|
@@ -3943,7 +3945,7 @@ async function handleStatus(args) {
|
|
|
3943
3945
|
...hostStatusPayload ?? { host: baseUrl },
|
|
3944
3946
|
status: "not connected",
|
|
3945
3947
|
connected: false,
|
|
3946
|
-
next: "deepline auth register",
|
|
3948
|
+
next: "deepline auth register --no-wait && deepline auth wait",
|
|
3947
3949
|
render: {
|
|
3948
3950
|
sections: [
|
|
3949
3951
|
{
|
|
@@ -3951,7 +3953,10 @@ async function handleStatus(args) {
|
|
|
3951
3953
|
lines: [...hostLines, "Status: not connected"]
|
|
3952
3954
|
}
|
|
3953
3955
|
],
|
|
3954
|
-
actions: [
|
|
3956
|
+
actions: [
|
|
3957
|
+
{ label: "Register", command: "deepline auth register --no-wait" },
|
|
3958
|
+
{ label: "Wait", command: "deepline auth wait" }
|
|
3959
|
+
]
|
|
3955
3960
|
}
|
|
3956
3961
|
},
|
|
3957
3962
|
{ json: jsonOutput }
|
|
@@ -3973,7 +3978,7 @@ async function handleStatus(args) {
|
|
|
3973
3978
|
...hostStatusPayload ?? { host: baseUrl },
|
|
3974
3979
|
status: "unauthorized",
|
|
3975
3980
|
connected: false,
|
|
3976
|
-
next: "deepline auth register",
|
|
3981
|
+
next: "deepline auth register --no-wait && deepline auth wait",
|
|
3977
3982
|
render: {
|
|
3978
3983
|
sections: [
|
|
3979
3984
|
{
|
|
@@ -3981,7 +3986,10 @@ async function handleStatus(args) {
|
|
|
3981
3986
|
lines: [...hostLines, "Status: unauthorized"]
|
|
3982
3987
|
}
|
|
3983
3988
|
],
|
|
3984
|
-
actions: [
|
|
3989
|
+
actions: [
|
|
3990
|
+
{ label: "Register", command: "deepline auth register --no-wait" },
|
|
3991
|
+
{ label: "Wait", command: "deepline auth wait" }
|
|
3992
|
+
]
|
|
3985
3993
|
}
|
|
3986
3994
|
},
|
|
3987
3995
|
{ json: jsonOutput }
|
|
@@ -5627,7 +5635,7 @@ async function handleDbQuery(args) {
|
|
|
5627
5635
|
return 0;
|
|
5628
5636
|
}
|
|
5629
5637
|
function registerDbCommands(program) {
|
|
5630
|
-
const db = program.command("db").
|
|
5638
|
+
const db = program.command("db").description("Query the tenant customer database.").addHelpText(
|
|
5631
5639
|
"after",
|
|
5632
5640
|
`
|
|
5633
5641
|
Notes:
|
|
@@ -5648,7 +5656,7 @@ Examples:
|
|
|
5648
5656
|
deepline db query --sql "select domain, name from companies limit 20" --format markdown
|
|
5649
5657
|
`
|
|
5650
5658
|
);
|
|
5651
|
-
db.command("query").
|
|
5659
|
+
db.command("query").description("Run SQL against the tenant customer database.").addHelpText(
|
|
5652
5660
|
"after",
|
|
5653
5661
|
`
|
|
5654
5662
|
Notes:
|
|
@@ -5664,7 +5672,7 @@ Examples:
|
|
|
5664
5672
|
deepline db query --sql "select * from companies limit 20"
|
|
5665
5673
|
deepline db query --sql "select domain, name from companies limit 20" --json
|
|
5666
5674
|
deepline db query --sql "create table if not exists storage.agent_notes (id text primary key, note text not null)"
|
|
5667
|
-
deepline db
|
|
5675
|
+
deepline db query --sql "select count(*) from contacts" --json
|
|
5668
5676
|
deepline db query --sql "select * from contacts limit 20" --format csv --out contacts.csv
|
|
5669
5677
|
deepline db query --sql "select domain, name from companies limit 20" --format markdown
|
|
5670
5678
|
`
|
|
@@ -6915,7 +6923,7 @@ var PLAY_RUNTIME_PROVIDERS = {
|
|
|
6915
6923
|
runner: PLAY_RUNTIME_BACKENDS.daytona,
|
|
6916
6924
|
dedup: PLAY_DEDUP_BACKENDS.durableObject,
|
|
6917
6925
|
artifactKind: PLAY_ARTIFACT_KINDS.cjsNode20,
|
|
6918
|
-
label: "
|
|
6926
|
+
label: "BETA: Postgres Scheduler + warm sandbox runner + DO dedup"
|
|
6919
6927
|
},
|
|
6920
6928
|
postgres_fast_sandbox: {
|
|
6921
6929
|
id: PLAY_RUNTIME_PROVIDER_IDS.postgresFastSandbox,
|
|
@@ -6923,7 +6931,7 @@ var PLAY_RUNTIME_PROVIDERS = {
|
|
|
6923
6931
|
runner: PLAY_RUNTIME_BACKENDS.daytona,
|
|
6924
6932
|
dedup: PLAY_DEDUP_BACKENDS.durableObject,
|
|
6925
6933
|
artifactKind: PLAY_ARTIFACT_KINDS.cjsNode20,
|
|
6926
|
-
label: "
|
|
6934
|
+
label: "BETA: Postgres Scheduler + warm sandbox runner + DO dedup"
|
|
6927
6935
|
},
|
|
6928
6936
|
postgres_fast_workers: {
|
|
6929
6937
|
id: PLAY_RUNTIME_PROVIDER_IDS.postgresFastWorkers,
|
|
@@ -9221,7 +9229,7 @@ function traceCliSync(phase, fields, run) {
|
|
|
9221
9229
|
}
|
|
9222
9230
|
}
|
|
9223
9231
|
function sleep5(ms) {
|
|
9224
|
-
return new Promise((
|
|
9232
|
+
return new Promise((resolve16) => setTimeout(resolve16, ms));
|
|
9225
9233
|
}
|
|
9226
9234
|
function parseReferencedPlayTarget2(target) {
|
|
9227
9235
|
const trimmed = target.trim();
|
|
@@ -12153,7 +12161,7 @@ function writeStartedPlayRun(input2) {
|
|
|
12153
12161
|
);
|
|
12154
12162
|
}
|
|
12155
12163
|
function parsePlayRunOptions(args) {
|
|
12156
|
-
const usage = "Usage: deepline plays run <play-name> [--input '{...}'] [--no-wait] [--tail-timeout-ms 30000] [--force] [--full] [--<input> value]\n deepline plays run <play-file.ts> [--input '{...}'] [--no-wait] [--tail-timeout-ms 30000] [--force] [--full] [--<input> value]\n deepline plays run --file <play-file.ts> [--input '{...}'] [--profile <id>] [--no-wait] [--tail-timeout-ms 30000] [--force] [--full] [--<input> value]\n deepline plays run --name <name> [--input '{...}'] [--profile <id>] [--live|--latest|--revision-id <id>] [--no-wait] [--tail-timeout-ms 30000] [--force] [--no-open] [--json] [--full] [--<input> value]\n Unknown --<input> value flags, such as --limit 5, are passed into play input.\nRun `deepline plays run --help` for idempotency, tool call id, and ctx.dataset guidance.";
|
|
12164
|
+
const usage = "Usage: deepline plays run <play-name> [--input '{...}'] [--no-wait] [--tail-timeout-ms 30000] [--force] [--full] [--<input> value]\n deepline plays run <play-file.ts> [--input '{...}'] [--no-wait] [--tail-timeout-ms 30000] [--force] [--full] [--<input> value]\n deepline plays run --file <play-file.ts> [--input '{...}'] [--profile <id>] [--no-wait] [--tail-timeout-ms 30000] [--force] [--full] [--<input> value]\n deepline plays run --name <name> [--input '{...}'] [--profile <id>] [--live|--latest|--revision-id <id>] [--no-wait] [--tail-timeout-ms 30000] [--force] [--no-open] [--json] [--full] [--<input> value]\n --profile defaults to workers_edge; postgres_fast is BETA (opt-in per run, never the default).\n Unknown --<input> value flags, such as --limit 5, are passed into play input.\nRun `deepline plays run --help` for idempotency, tool call id, and ctx.dataset guidance.";
|
|
12157
12165
|
let filePath = null;
|
|
12158
12166
|
let playName = null;
|
|
12159
12167
|
let input2 = null;
|
|
@@ -12289,7 +12297,7 @@ function parsePlayRunOptions(args) {
|
|
|
12289
12297
|
function parsePlayCheckOptions(args) {
|
|
12290
12298
|
const target = args[0];
|
|
12291
12299
|
if (!target) {
|
|
12292
|
-
throw new Error("Usage: deepline
|
|
12300
|
+
throw new Error("Usage: deepline plays check <play-file.ts> [--json]");
|
|
12293
12301
|
}
|
|
12294
12302
|
const jsonOutput = argsWantJson(args);
|
|
12295
12303
|
return { target, jsonOutput };
|
|
@@ -13219,7 +13227,9 @@ async function handleRunExport(args) {
|
|
|
13219
13227
|
async function handlePlayGet(args) {
|
|
13220
13228
|
const target = args[0];
|
|
13221
13229
|
if (!target) {
|
|
13222
|
-
console.error(
|
|
13230
|
+
console.error(
|
|
13231
|
+
"Usage: deepline plays get <play-file.ts|play-name> [--json]"
|
|
13232
|
+
);
|
|
13223
13233
|
return 1;
|
|
13224
13234
|
}
|
|
13225
13235
|
if (looksLikeRunId(target)) {
|
|
@@ -13317,7 +13327,7 @@ async function handlePlayVersions(args) {
|
|
|
13317
13327
|
const nameIndex = args.indexOf("--name");
|
|
13318
13328
|
const playName = nameIndex >= 0 ? args[nameIndex + 1] : void 0;
|
|
13319
13329
|
if (!playName) {
|
|
13320
|
-
console.error("Usage: deepline
|
|
13330
|
+
console.error("Usage: deepline plays versions --name <name> [--json]");
|
|
13321
13331
|
return 1;
|
|
13322
13332
|
}
|
|
13323
13333
|
const client2 = new DeeplineClient();
|
|
@@ -13697,7 +13707,7 @@ async function handlePlayPublish(args) {
|
|
|
13697
13707
|
const playName = args[0];
|
|
13698
13708
|
if (!playName) {
|
|
13699
13709
|
console.error(
|
|
13700
|
-
"Usage: deepline
|
|
13710
|
+
"Usage: deepline plays publish <play-file.ts|play-name> [--latest|--revision-id <id>] [--json]"
|
|
13701
13711
|
);
|
|
13702
13712
|
return 1;
|
|
13703
13713
|
}
|
|
@@ -13841,7 +13851,7 @@ async function handlePlayDelete(args) {
|
|
|
13841
13851
|
return result.deleted ? 0 : 1;
|
|
13842
13852
|
}
|
|
13843
13853
|
function registerPlayCommands(program) {
|
|
13844
|
-
const play = program.command("plays").
|
|
13854
|
+
const play = program.command("plays").description("Search, validate, run, and manage cloud plays.").addHelpText(
|
|
13845
13855
|
"after",
|
|
13846
13856
|
`
|
|
13847
13857
|
Concepts:
|
|
@@ -16348,7 +16358,7 @@ async function runGeneratedEnrichPlay(runArgs, options = {}) {
|
|
|
16348
16358
|
});
|
|
16349
16359
|
} catch (error) {
|
|
16350
16360
|
if (attempt === 0 && isPlayStartStreamEndedError(error)) {
|
|
16351
|
-
await new Promise((
|
|
16361
|
+
await new Promise((resolve16) => setTimeout(resolve16, 250));
|
|
16352
16362
|
continue;
|
|
16353
16363
|
}
|
|
16354
16364
|
throw error;
|
|
@@ -17148,19 +17158,16 @@ Notes:
|
|
|
17148
17158
|
Use --command and --payload to attach a reproducible command shape.
|
|
17149
17159
|
|
|
17150
17160
|
Examples:
|
|
17151
|
-
deepline feedback "plays run failed after upload" --command "deepline plays run my.play.ts --watch"
|
|
17152
|
-
deepline feedback "unexpected billing output" --payload '{"command":"billing usage"}' --json
|
|
17161
|
+
deepline feedback send "plays run failed after upload" --command "deepline plays run my.play.ts --watch"
|
|
17162
|
+
deepline feedback send "unexpected billing output" --payload '{"command":"billing usage"}' --json
|
|
17153
17163
|
`
|
|
17154
17164
|
);
|
|
17155
|
-
feedback.
|
|
17156
|
-
program.command("provide-feedback").description("Legacy alias for `deepline feedback`.").addHelpText(
|
|
17165
|
+
feedback.command("send").description("Send CLI feedback to Deepline.").addHelpText(
|
|
17157
17166
|
"after",
|
|
17158
17167
|
`
|
|
17159
|
-
Notes:
|
|
17160
|
-
Compatibility alias. Prefer deepline feedback in new scripts and docs.
|
|
17161
|
-
|
|
17162
17168
|
Examples:
|
|
17163
|
-
deepline feedback "tools search returned stale results" --json
|
|
17169
|
+
deepline feedback send "tools search returned stale results" --json
|
|
17170
|
+
deepline feedback send "plays run failed after upload" --command "deepline plays run my.play.ts --watch"
|
|
17164
17171
|
`
|
|
17165
17172
|
).argument("<text>", "Feedback text").option("--command <command>", "Command that reproduced the issue").option("--payload <payload>", "JSON or plain-text payload for the repro").option("--json", "Emit JSON output").action(handleFeedback);
|
|
17166
17173
|
}
|
|
@@ -17281,8 +17288,44 @@ async function handleOrgSwitch(selection, options) {
|
|
|
17281
17288
|
{ json: options.json }
|
|
17282
17289
|
);
|
|
17283
17290
|
}
|
|
17291
|
+
async function handleOrgCreate(name, options) {
|
|
17292
|
+
const config = resolveConfig();
|
|
17293
|
+
const http = new HttpClient(config);
|
|
17294
|
+
const created = await http.post("/api/v2/auth/cli/org-create", {
|
|
17295
|
+
api_key: config.apiKey,
|
|
17296
|
+
name
|
|
17297
|
+
});
|
|
17298
|
+
saveHostEnvValues(config.baseUrl, {
|
|
17299
|
+
DEEPLINE_API_KEY: created.api_key,
|
|
17300
|
+
DEEPLINE_ACTIVE_ORG_ID: created.org_id,
|
|
17301
|
+
DEEPLINE_ACTIVE_ORG_NAME: created.org_name
|
|
17302
|
+
});
|
|
17303
|
+
const { api_key: _apiKey, ...publicCreated } = created;
|
|
17304
|
+
printCommandEnvelope(
|
|
17305
|
+
{
|
|
17306
|
+
ok: true,
|
|
17307
|
+
...publicCreated,
|
|
17308
|
+
api_key_saved: true,
|
|
17309
|
+
switched: true,
|
|
17310
|
+
host_env_path: hostEnvFilePath(config.baseUrl),
|
|
17311
|
+
render: {
|
|
17312
|
+
sections: [
|
|
17313
|
+
{
|
|
17314
|
+
title: "org create",
|
|
17315
|
+
lines: [
|
|
17316
|
+
`Created organization: ${created.org_name}.`,
|
|
17317
|
+
`Switched to ${created.org_name}.`,
|
|
17318
|
+
`Saved host auth in ${hostEnvFilePath(config.baseUrl)}`
|
|
17319
|
+
]
|
|
17320
|
+
}
|
|
17321
|
+
]
|
|
17322
|
+
}
|
|
17323
|
+
},
|
|
17324
|
+
{ json: options.json }
|
|
17325
|
+
);
|
|
17326
|
+
}
|
|
17284
17327
|
function registerOrgCommands(program) {
|
|
17285
|
-
const org = program.command("org").description("List and switch organizations.").addHelpText(
|
|
17328
|
+
const org = program.command("org").description("List, create, and switch organizations.").addHelpText(
|
|
17286
17329
|
"after",
|
|
17287
17330
|
`
|
|
17288
17331
|
Notes:
|
|
@@ -17291,6 +17334,7 @@ Notes:
|
|
|
17291
17334
|
|
|
17292
17335
|
Examples:
|
|
17293
17336
|
deepline org list --json
|
|
17337
|
+
deepline org create Acme --json
|
|
17294
17338
|
deepline org switch 2
|
|
17295
17339
|
deepline org switch --org-id org_123 --json
|
|
17296
17340
|
`
|
|
@@ -17306,6 +17350,19 @@ Examples:
|
|
|
17306
17350
|
deepline org list --json
|
|
17307
17351
|
`
|
|
17308
17352
|
).option("--json", "Emit JSON output. Also automatic when stdout is piped").action(handleOrgList);
|
|
17353
|
+
org.command("create <name>").description("Create a new organization and switch this CLI to it.").addHelpText(
|
|
17354
|
+
"after",
|
|
17355
|
+
`
|
|
17356
|
+
Notes:
|
|
17357
|
+
Mutates workspace state. The new organization is created for the current
|
|
17358
|
+
authenticated user, then the returned API key is saved for this host so later
|
|
17359
|
+
CLI commands target the new organization.
|
|
17360
|
+
|
|
17361
|
+
Examples:
|
|
17362
|
+
deepline org create Acme
|
|
17363
|
+
deepline org create "Acme Sales" --json
|
|
17364
|
+
`
|
|
17365
|
+
).option("--json", "Emit JSON output. Also automatic when stdout is piped").action(handleOrgCreate);
|
|
17309
17366
|
org.command("switch [selection]").description(
|
|
17310
17367
|
"Switch to another organization and save the new API key in the host auth file."
|
|
17311
17368
|
).addHelpText(
|
|
@@ -17350,7 +17407,7 @@ async function readHiddenLine(prompt) {
|
|
|
17350
17407
|
if (typeof import_node_process.stdin.setRawMode === "function") import_node_process.stdin.setRawMode(true);
|
|
17351
17408
|
let value = "";
|
|
17352
17409
|
import_node_process.stdin.resume();
|
|
17353
|
-
return await new Promise((
|
|
17410
|
+
return await new Promise((resolve16, reject) => {
|
|
17354
17411
|
let settled = false;
|
|
17355
17412
|
const cleanup = () => {
|
|
17356
17413
|
import_node_process.stdin.off("data", onData);
|
|
@@ -17365,7 +17422,7 @@ async function readHiddenLine(prompt) {
|
|
|
17365
17422
|
settled = true;
|
|
17366
17423
|
import_node_process.stdout.write("\n");
|
|
17367
17424
|
cleanup();
|
|
17368
|
-
|
|
17425
|
+
resolve16(line);
|
|
17369
17426
|
};
|
|
17370
17427
|
const fail = (error) => {
|
|
17371
17428
|
if (settled) return;
|
|
@@ -17535,16 +17592,553 @@ Examples:
|
|
|
17535
17592
|
);
|
|
17536
17593
|
}
|
|
17537
17594
|
|
|
17595
|
+
// src/cli/commands/sessions.ts
|
|
17596
|
+
var import_node_fs11 = require("fs");
|
|
17597
|
+
var import_node_os8 = require("os");
|
|
17598
|
+
var import_node_path14 = require("path");
|
|
17599
|
+
var import_node_zlib = require("zlib");
|
|
17600
|
+
var import_node_crypto4 = require("crypto");
|
|
17601
|
+
var UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
17602
|
+
var MAX_SESSION_UPLOAD_BYTES = 35e5;
|
|
17603
|
+
var MAX_DIRECT_SESSION_DECODED_BYTES = 50 * 1024 * 1024;
|
|
17604
|
+
var CHUNK_SIZE_BYTES = 25e5;
|
|
17605
|
+
var MAX_EVENT_STRING_CHARS = 8e3;
|
|
17606
|
+
var MAX_EVENT_LIST_ITEMS = 40;
|
|
17607
|
+
var MAX_EVENT_OBJECT_KEYS = 80;
|
|
17608
|
+
var TRUNCATION_MARKER = "...[truncated]";
|
|
17609
|
+
var NOISE_EVENT_TYPES = /* @__PURE__ */ new Set(["progress", "file-history-snapshot"]);
|
|
17610
|
+
function homeDir() {
|
|
17611
|
+
return process.env.HOME?.trim() || (0, import_node_os8.homedir)();
|
|
17612
|
+
}
|
|
17613
|
+
function detectShellContext() {
|
|
17614
|
+
const shellPath = process.env.SHELL?.trim() || process.env.ComSpec?.trim() || process.env.COMSPEC?.trim() || "";
|
|
17615
|
+
return {
|
|
17616
|
+
shell: shellPath ? (0, import_node_path14.basename)(shellPath).replace(/\.exe$/i, "") : "unknown",
|
|
17617
|
+
shell_path: shellPath || null,
|
|
17618
|
+
os: (0, import_node_os8.platform)(),
|
|
17619
|
+
cwd: process.cwd()
|
|
17620
|
+
};
|
|
17621
|
+
}
|
|
17622
|
+
function claudeProjectsRoot() {
|
|
17623
|
+
return (0, import_node_path14.join)(homeDir(), ".claude", "projects");
|
|
17624
|
+
}
|
|
17625
|
+
function listClaudeSessionFiles() {
|
|
17626
|
+
const root = claudeProjectsRoot();
|
|
17627
|
+
if (!(0, import_node_fs11.existsSync)(root)) return [];
|
|
17628
|
+
const projectDirs = readDirectoryNames(root);
|
|
17629
|
+
const files = [];
|
|
17630
|
+
for (const projectDir of projectDirs) {
|
|
17631
|
+
const fullProjectDir = (0, import_node_path14.join)(root, projectDir);
|
|
17632
|
+
for (const fileName of readDirectoryNames(fullProjectDir)) {
|
|
17633
|
+
if (fileName.endsWith(".jsonl")) {
|
|
17634
|
+
files.push((0, import_node_path14.join)(fullProjectDir, fileName));
|
|
17635
|
+
}
|
|
17636
|
+
}
|
|
17637
|
+
}
|
|
17638
|
+
return files;
|
|
17639
|
+
}
|
|
17640
|
+
function readDirectoryNames(dir) {
|
|
17641
|
+
try {
|
|
17642
|
+
return (0, import_node_fs11.readdirSync)(dir);
|
|
17643
|
+
} catch {
|
|
17644
|
+
return [];
|
|
17645
|
+
}
|
|
17646
|
+
}
|
|
17647
|
+
function newestClaudeSessionFile() {
|
|
17648
|
+
let newest = null;
|
|
17649
|
+
for (const filePath of listClaudeSessionFiles()) {
|
|
17650
|
+
try {
|
|
17651
|
+
const stat4 = (0, import_node_fs11.statSync)(filePath);
|
|
17652
|
+
if (!newest || stat4.mtimeMs > newest.mtimeMs) {
|
|
17653
|
+
newest = { filePath, mtimeMs: stat4.mtimeMs };
|
|
17654
|
+
}
|
|
17655
|
+
} catch {
|
|
17656
|
+
continue;
|
|
17657
|
+
}
|
|
17658
|
+
}
|
|
17659
|
+
return newest?.filePath ?? null;
|
|
17660
|
+
}
|
|
17661
|
+
function sessionIdFromFilePath(filePath) {
|
|
17662
|
+
return (0, import_node_path14.basename)(filePath, ".jsonl");
|
|
17663
|
+
}
|
|
17664
|
+
function findSessionFile(sessionId) {
|
|
17665
|
+
if (!UUID_RE.test(sessionId)) {
|
|
17666
|
+
throw new Error(
|
|
17667
|
+
"Invalid session ID format. Expected a UUID such as 5a3bfb97-a2d9-49d9-82c6-52ccc03dadca."
|
|
17668
|
+
);
|
|
17669
|
+
}
|
|
17670
|
+
for (const filePath of listClaudeSessionFiles()) {
|
|
17671
|
+
if (sessionIdFromFilePath(filePath) === sessionId) {
|
|
17672
|
+
return filePath;
|
|
17673
|
+
}
|
|
17674
|
+
}
|
|
17675
|
+
return null;
|
|
17676
|
+
}
|
|
17677
|
+
function resolveSessionTargets(input2) {
|
|
17678
|
+
const targets = [];
|
|
17679
|
+
if (input2.currentSession) {
|
|
17680
|
+
const currentFile = newestClaudeSessionFile();
|
|
17681
|
+
if (!currentFile) {
|
|
17682
|
+
throw new Error("No session files found in ~/.claude/projects/*/.");
|
|
17683
|
+
}
|
|
17684
|
+
const sessionId = sessionIdFromFilePath(currentFile);
|
|
17685
|
+
targets.push({
|
|
17686
|
+
sessionId,
|
|
17687
|
+
label: `session-${sessionId}`,
|
|
17688
|
+
filePath: currentFile
|
|
17689
|
+
});
|
|
17690
|
+
}
|
|
17691
|
+
for (const [index, sessionId] of (input2.sessionIds ?? []).entries()) {
|
|
17692
|
+
const filePath = findSessionFile(sessionId);
|
|
17693
|
+
if (!filePath) {
|
|
17694
|
+
throw new Error(
|
|
17695
|
+
`Session file not found: ~/.claude/projects/*/${sessionId}.jsonl`
|
|
17696
|
+
);
|
|
17697
|
+
}
|
|
17698
|
+
targets.push({
|
|
17699
|
+
sessionId,
|
|
17700
|
+
label: input2.labels?.[index] ?? `session-${sessionId}`,
|
|
17701
|
+
filePath
|
|
17702
|
+
});
|
|
17703
|
+
}
|
|
17704
|
+
if (targets.length === 0) {
|
|
17705
|
+
throw new Error("One of --session-id or --current-session is required.");
|
|
17706
|
+
}
|
|
17707
|
+
return targets;
|
|
17708
|
+
}
|
|
17709
|
+
function parseJsonLine(line) {
|
|
17710
|
+
try {
|
|
17711
|
+
return JSON.parse(line);
|
|
17712
|
+
} catch {
|
|
17713
|
+
return null;
|
|
17714
|
+
}
|
|
17715
|
+
}
|
|
17716
|
+
function normalizedJsonLines(raw) {
|
|
17717
|
+
return raw.toString("utf8").split(/\r?\n/).map((line) => line.trim()).filter(Boolean);
|
|
17718
|
+
}
|
|
17719
|
+
function stripNoiseEvents(raw) {
|
|
17720
|
+
const lines = [];
|
|
17721
|
+
for (const line of normalizedJsonLines(raw)) {
|
|
17722
|
+
const parsed = parseJsonLine(line);
|
|
17723
|
+
if (parsed && typeof parsed === "object" && NOISE_EVENT_TYPES.has(String(parsed.type ?? ""))) {
|
|
17724
|
+
continue;
|
|
17725
|
+
}
|
|
17726
|
+
lines.push(line);
|
|
17727
|
+
}
|
|
17728
|
+
return Buffer.from(lines.length > 0 ? `${lines.join("\n")}
|
|
17729
|
+
` : "", "utf8");
|
|
17730
|
+
}
|
|
17731
|
+
function messageContentKey(value) {
|
|
17732
|
+
const message = value.message;
|
|
17733
|
+
if (!message || typeof message !== "object") return null;
|
|
17734
|
+
const content = message.content;
|
|
17735
|
+
if (typeof content === "string") return content;
|
|
17736
|
+
if (!Array.isArray(content)) return null;
|
|
17737
|
+
return content.map((block) => {
|
|
17738
|
+
if (!block || typeof block !== "object") return String(block);
|
|
17739
|
+
const record = block;
|
|
17740
|
+
const type = String(record.type ?? "");
|
|
17741
|
+
if (type === "tool_use") {
|
|
17742
|
+
return `tool_use:${String(record.name ?? "")}:${String(record.id ?? "")}`;
|
|
17743
|
+
}
|
|
17744
|
+
if (type === "tool_result") {
|
|
17745
|
+
return `tool_result:${String(record.tool_use_id ?? "")}`;
|
|
17746
|
+
}
|
|
17747
|
+
return String(record.text ?? type);
|
|
17748
|
+
}).join("\n");
|
|
17749
|
+
}
|
|
17750
|
+
function dedupConsecutiveEvents(raw) {
|
|
17751
|
+
const rawLines = normalizedJsonLines(raw);
|
|
17752
|
+
const parsedEvents = rawLines.map(parseJsonLine);
|
|
17753
|
+
const output2 = [];
|
|
17754
|
+
let index = 0;
|
|
17755
|
+
while (index < parsedEvents.length) {
|
|
17756
|
+
const event = parsedEvents[index];
|
|
17757
|
+
if (!event || typeof event !== "object") {
|
|
17758
|
+
output2.push(rawLines[index] ?? "");
|
|
17759
|
+
index += 1;
|
|
17760
|
+
continue;
|
|
17761
|
+
}
|
|
17762
|
+
const record = event;
|
|
17763
|
+
const eventType = String(record.type ?? "");
|
|
17764
|
+
const eventKey = messageContentKey(record);
|
|
17765
|
+
if (!["user", "assistant"].includes(eventType) || !eventKey) {
|
|
17766
|
+
output2.push(rawLines[index] ?? "");
|
|
17767
|
+
index += 1;
|
|
17768
|
+
continue;
|
|
17769
|
+
}
|
|
17770
|
+
let runCount = 1;
|
|
17771
|
+
let cursor = index + 1;
|
|
17772
|
+
while (cursor < parsedEvents.length) {
|
|
17773
|
+
const next = parsedEvents[cursor];
|
|
17774
|
+
if (!next || typeof next !== "object") break;
|
|
17775
|
+
const nextRecord = next;
|
|
17776
|
+
if (String(nextRecord.type ?? "") !== eventType || messageContentKey(nextRecord) !== eventKey) {
|
|
17777
|
+
break;
|
|
17778
|
+
}
|
|
17779
|
+
runCount += 1;
|
|
17780
|
+
cursor += 1;
|
|
17781
|
+
}
|
|
17782
|
+
if (runCount > 1) {
|
|
17783
|
+
record._repeat_count = runCount;
|
|
17784
|
+
record._repeat_summary = `${runCount} consecutive identical ${eventType} messages collapsed`;
|
|
17785
|
+
output2.push(JSON.stringify(record));
|
|
17786
|
+
index = cursor;
|
|
17787
|
+
continue;
|
|
17788
|
+
}
|
|
17789
|
+
output2.push(rawLines[index] ?? "");
|
|
17790
|
+
index += 1;
|
|
17791
|
+
}
|
|
17792
|
+
return Buffer.from(output2.length > 0 ? `${output2.join("\n")}
|
|
17793
|
+
` : "", "utf8");
|
|
17794
|
+
}
|
|
17795
|
+
function compactEventValue(value) {
|
|
17796
|
+
if (typeof value === "string") {
|
|
17797
|
+
if (value.length <= MAX_EVENT_STRING_CHARS) return value;
|
|
17798
|
+
return `${value.slice(0, MAX_EVENT_STRING_CHARS - TRUNCATION_MARKER.length)}${TRUNCATION_MARKER}`;
|
|
17799
|
+
}
|
|
17800
|
+
if (Array.isArray(value)) {
|
|
17801
|
+
const compacted = value.slice(0, MAX_EVENT_LIST_ITEMS).map(compactEventValue);
|
|
17802
|
+
if (value.length > MAX_EVENT_LIST_ITEMS) {
|
|
17803
|
+
compacted.push(
|
|
17804
|
+
`${TRUNCATION_MARKER} ${value.length - MAX_EVENT_LIST_ITEMS} more item(s)`
|
|
17805
|
+
);
|
|
17806
|
+
}
|
|
17807
|
+
return compacted;
|
|
17808
|
+
}
|
|
17809
|
+
if (value && typeof value === "object") {
|
|
17810
|
+
const entries = Object.entries(value);
|
|
17811
|
+
const compacted = {};
|
|
17812
|
+
for (const [key, item] of entries.slice(0, MAX_EVENT_OBJECT_KEYS)) {
|
|
17813
|
+
compacted[key] = compactEventValue(item);
|
|
17814
|
+
}
|
|
17815
|
+
if (entries.length > MAX_EVENT_OBJECT_KEYS) {
|
|
17816
|
+
compacted._truncated_keys = entries.length - MAX_EVENT_OBJECT_KEYS;
|
|
17817
|
+
}
|
|
17818
|
+
return compacted;
|
|
17819
|
+
}
|
|
17820
|
+
return value;
|
|
17821
|
+
}
|
|
17822
|
+
function selectiveCompactToolResults(raw) {
|
|
17823
|
+
const lines = [];
|
|
17824
|
+
for (const line of normalizedJsonLines(raw)) {
|
|
17825
|
+
const parsed = parseJsonLine(line);
|
|
17826
|
+
if (!parsed || typeof parsed !== "object") {
|
|
17827
|
+
lines.push(line);
|
|
17828
|
+
continue;
|
|
17829
|
+
}
|
|
17830
|
+
const record = parsed;
|
|
17831
|
+
if (record.type === "user") {
|
|
17832
|
+
const message = record.message;
|
|
17833
|
+
const content = message && typeof message === "object" ? message.content : null;
|
|
17834
|
+
if (Array.isArray(content)) {
|
|
17835
|
+
message.content = content.map(
|
|
17836
|
+
(block) => block && typeof block === "object" && block.type === "tool_result" ? compactEventValue(block) : block
|
|
17837
|
+
);
|
|
17838
|
+
}
|
|
17839
|
+
}
|
|
17840
|
+
lines.push(JSON.stringify(record));
|
|
17841
|
+
}
|
|
17842
|
+
return Buffer.from(lines.length > 0 ? `${lines.join("\n")}
|
|
17843
|
+
` : "", "utf8");
|
|
17844
|
+
}
|
|
17845
|
+
function prepareSessionBuffer(raw) {
|
|
17846
|
+
return selectiveCompactToolResults(
|
|
17847
|
+
dedupConsecutiveEvents(stripNoiseEvents(raw))
|
|
17848
|
+
);
|
|
17849
|
+
}
|
|
17850
|
+
function buildSessionUploadContent(raw) {
|
|
17851
|
+
const prepared = prepareSessionBuffer(raw);
|
|
17852
|
+
const encoded = (0, import_node_zlib.gzipSync)(prepared).toString("base64");
|
|
17853
|
+
if (encoded.length <= MAX_SESSION_UPLOAD_BYTES && prepared.length <= MAX_DIRECT_SESSION_DECODED_BYTES) {
|
|
17854
|
+
return { encodedContent: encoded, needsChunking: false };
|
|
17855
|
+
}
|
|
17856
|
+
return { encodedContent: encoded, needsChunking: true };
|
|
17857
|
+
}
|
|
17858
|
+
async function uploadPayload(path, payload) {
|
|
17859
|
+
const { http } = getAuthedHttpClient();
|
|
17860
|
+
return await http.post(path, payload);
|
|
17861
|
+
}
|
|
17862
|
+
async function uploadChunkedSessions(sessions, options) {
|
|
17863
|
+
const uploadId = (0, import_node_crypto4.randomUUID)();
|
|
17864
|
+
for (const session of sessions) {
|
|
17865
|
+
const bytes = Buffer.from(session.encodedContent, "base64");
|
|
17866
|
+
const chunks = [];
|
|
17867
|
+
for (let offset = 0; offset < bytes.length; offset += CHUNK_SIZE_BYTES) {
|
|
17868
|
+
chunks.push(bytes.subarray(offset, offset + CHUNK_SIZE_BYTES));
|
|
17869
|
+
}
|
|
17870
|
+
process.stderr.write(
|
|
17871
|
+
`Uploading ${session.label} in ${chunks.length} chunk(s)...
|
|
17872
|
+
`
|
|
17873
|
+
);
|
|
17874
|
+
for (const [index, chunk] of chunks.entries()) {
|
|
17875
|
+
await uploadPayload("/api/v2/cli/send-session/chunk", {
|
|
17876
|
+
upload_id: uploadId,
|
|
17877
|
+
session_id: session.sessionId,
|
|
17878
|
+
index,
|
|
17879
|
+
total_chunks: chunks.length,
|
|
17880
|
+
data: chunk.toString("base64")
|
|
17881
|
+
});
|
|
17882
|
+
}
|
|
17883
|
+
}
|
|
17884
|
+
const response = await uploadPayload("/api/v2/cli/send-session/finalize", {
|
|
17885
|
+
upload_id: uploadId,
|
|
17886
|
+
session_ids: sessions.map((session) => session.sessionId),
|
|
17887
|
+
labels: sessions.map((session) => session.label),
|
|
17888
|
+
environments: sessions.map(() => detectShellContext())
|
|
17889
|
+
});
|
|
17890
|
+
printCommandEnvelope(
|
|
17891
|
+
{
|
|
17892
|
+
...response,
|
|
17893
|
+
ok: true,
|
|
17894
|
+
uploaded: sessions.length,
|
|
17895
|
+
render: {
|
|
17896
|
+
sections: [
|
|
17897
|
+
{
|
|
17898
|
+
title: "sessions send",
|
|
17899
|
+
lines: ["Session uploaded to #internal-reports (chunked)."]
|
|
17900
|
+
}
|
|
17901
|
+
]
|
|
17902
|
+
}
|
|
17903
|
+
},
|
|
17904
|
+
{ json: options.json }
|
|
17905
|
+
);
|
|
17906
|
+
}
|
|
17907
|
+
async function handleSessionsSend(options) {
|
|
17908
|
+
if (options.file) {
|
|
17909
|
+
const filePath = (0, import_node_path14.resolve)(options.file);
|
|
17910
|
+
if (!(0, import_node_fs11.existsSync)(filePath)) {
|
|
17911
|
+
throw new Error(`File not found: ${options.file}`);
|
|
17912
|
+
}
|
|
17913
|
+
const response2 = await uploadPayload("/api/v2/cli/send-session", {
|
|
17914
|
+
file: (0, import_node_fs11.readFileSync)(filePath).toString("base64"),
|
|
17915
|
+
filename: (0, import_node_path14.basename)(filePath)
|
|
17916
|
+
});
|
|
17917
|
+
printCommandEnvelope(
|
|
17918
|
+
{
|
|
17919
|
+
...response2,
|
|
17920
|
+
ok: true,
|
|
17921
|
+
filename: (0, import_node_path14.basename)(filePath),
|
|
17922
|
+
render: {
|
|
17923
|
+
sections: [
|
|
17924
|
+
{
|
|
17925
|
+
title: "sessions send",
|
|
17926
|
+
lines: [
|
|
17927
|
+
`File '${(0, import_node_path14.basename)(filePath)}' uploaded to #internal-reports.`
|
|
17928
|
+
]
|
|
17929
|
+
}
|
|
17930
|
+
]
|
|
17931
|
+
}
|
|
17932
|
+
},
|
|
17933
|
+
{ json: options.json }
|
|
17934
|
+
);
|
|
17935
|
+
return;
|
|
17936
|
+
}
|
|
17937
|
+
const targets = resolveSessionTargets({
|
|
17938
|
+
sessionIds: options.sessionId,
|
|
17939
|
+
labels: options.label,
|
|
17940
|
+
currentSession: options.currentSession
|
|
17941
|
+
});
|
|
17942
|
+
const built = targets.map((target) => {
|
|
17943
|
+
const upload = buildSessionUploadContent((0, import_node_fs11.readFileSync)(target.filePath));
|
|
17944
|
+
return { ...target, ...upload };
|
|
17945
|
+
});
|
|
17946
|
+
if (built.some((session) => session.needsChunking)) {
|
|
17947
|
+
await uploadChunkedSessions(built, options);
|
|
17948
|
+
return;
|
|
17949
|
+
}
|
|
17950
|
+
const response = built.length === 1 && !options.label?.length ? await uploadPayload("/api/v2/cli/send-session", {
|
|
17951
|
+
session_id: built[0]?.sessionId,
|
|
17952
|
+
content: built[0]?.encodedContent,
|
|
17953
|
+
environment: detectShellContext()
|
|
17954
|
+
}) : await uploadPayload("/api/v2/cli/send-session", {
|
|
17955
|
+
sessions: built.map((session) => ({
|
|
17956
|
+
session_id: session.sessionId,
|
|
17957
|
+
content: session.encodedContent,
|
|
17958
|
+
label: session.label,
|
|
17959
|
+
environment: detectShellContext()
|
|
17960
|
+
})),
|
|
17961
|
+
environment: detectShellContext()
|
|
17962
|
+
});
|
|
17963
|
+
printCommandEnvelope(
|
|
17964
|
+
{
|
|
17965
|
+
...response,
|
|
17966
|
+
ok: true,
|
|
17967
|
+
uploaded: built.length,
|
|
17968
|
+
render: {
|
|
17969
|
+
sections: [
|
|
17970
|
+
{
|
|
17971
|
+
title: "sessions send",
|
|
17972
|
+
lines: ["Session uploaded to #internal-reports."]
|
|
17973
|
+
}
|
|
17974
|
+
]
|
|
17975
|
+
}
|
|
17976
|
+
},
|
|
17977
|
+
{ json: options.json }
|
|
17978
|
+
);
|
|
17979
|
+
}
|
|
17980
|
+
function fallbackViewerAssets() {
|
|
17981
|
+
return {
|
|
17982
|
+
css: [
|
|
17983
|
+
"body{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;margin:0;padding:16px;background:#fafafa;color:#111}",
|
|
17984
|
+
".section{background:#fff;border:1px solid #ddd;border-radius:8px;padding:12px;margin-bottom:12px}",
|
|
17985
|
+
".section h2{margin:0 0 8px 0;font-size:14px}",
|
|
17986
|
+
"pre{margin:0;white-space:pre-wrap;word-break:break-word;background:#f6f8fa;border:1px solid #e3e5e8;border-radius:6px;padding:10px}"
|
|
17987
|
+
].join(""),
|
|
17988
|
+
js: [
|
|
17989
|
+
"(() => {",
|
|
17990
|
+
'const root=document.getElementById("main-content");',
|
|
17991
|
+
'const raw=document.getElementById("raw-sessions");',
|
|
17992
|
+
"if(!root||!raw)return;",
|
|
17993
|
+
'let sessions=[];try{sessions=JSON.parse(raw.textContent||"[]")}catch{}',
|
|
17994
|
+
'root.innerHTML="";',
|
|
17995
|
+
"for(const session of sessions){",
|
|
17996
|
+
'const section=document.createElement("section");section.className="section";',
|
|
17997
|
+
'const title=document.createElement("h2");title.textContent=String(session.label||"session");',
|
|
17998
|
+
'const pre=document.createElement("pre");',
|
|
17999
|
+
'pre.textContent=(Array.isArray(session.events)?session.events:[]).map((event)=>JSON.stringify(event)).join("\\n");',
|
|
18000
|
+
"section.append(title,pre);root.appendChild(section);",
|
|
18001
|
+
"}",
|
|
18002
|
+
"})();"
|
|
18003
|
+
].join("")
|
|
18004
|
+
};
|
|
18005
|
+
}
|
|
18006
|
+
function parsePreparedEvents(buffer) {
|
|
18007
|
+
return normalizedJsonLines(buffer).map((line) => {
|
|
18008
|
+
const parsed = parseJsonLine(line);
|
|
18009
|
+
return parsed ?? line;
|
|
18010
|
+
});
|
|
18011
|
+
}
|
|
18012
|
+
async function handleSessionsRender(options) {
|
|
18013
|
+
const targets = resolveSessionTargets({
|
|
18014
|
+
sessionIds: options.sessionId,
|
|
18015
|
+
labels: options.label,
|
|
18016
|
+
currentSession: options.currentSession
|
|
18017
|
+
});
|
|
18018
|
+
let outputPath = options.output ? (0, import_node_path14.resolve)(options.output) : "";
|
|
18019
|
+
if (!outputPath) {
|
|
18020
|
+
const outputDir = (0, import_node_path14.join)(process.cwd(), "deepline", "data");
|
|
18021
|
+
(0, import_node_fs11.mkdirSync)(outputDir, { recursive: true });
|
|
18022
|
+
outputPath = (0, import_node_path14.join)(
|
|
18023
|
+
outputDir,
|
|
18024
|
+
targets.length > 1 ? "session-viewer.html" : `session-${targets[0]?.sessionId}.html`
|
|
18025
|
+
);
|
|
18026
|
+
} else {
|
|
18027
|
+
(0, import_node_fs11.mkdirSync)((0, import_node_path14.dirname)(outputPath), { recursive: true });
|
|
18028
|
+
}
|
|
18029
|
+
const sessions = targets.map((target) => ({
|
|
18030
|
+
label: target.label,
|
|
18031
|
+
events: parsePreparedEvents(
|
|
18032
|
+
prepareSessionBuffer((0, import_node_fs11.readFileSync)(target.filePath))
|
|
18033
|
+
)
|
|
18034
|
+
}));
|
|
18035
|
+
const { css, js } = fallbackViewerAssets();
|
|
18036
|
+
const refreshMeta = options.autoRefresh ? `<meta http-equiv="refresh" content="${Number.parseInt(options.autoRefresh, 10)}">` : "";
|
|
18037
|
+
const rawJson = JSON.stringify(sessions).replace(/<\//g, "<\\/");
|
|
18038
|
+
const html = `<!DOCTYPE html>
|
|
18039
|
+
<html lang="en">
|
|
18040
|
+
<head>
|
|
18041
|
+
<meta charset="UTF-8">
|
|
18042
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
18043
|
+
${refreshMeta}
|
|
18044
|
+
<title>Session Viewer</title>
|
|
18045
|
+
<style>${css}</style>
|
|
18046
|
+
</head>
|
|
18047
|
+
<body>
|
|
18048
|
+
<div class="layout">
|
|
18049
|
+
<div class="main" id="main-content"></div>
|
|
18050
|
+
</div>
|
|
18051
|
+
<script type="application/json" id="raw-sessions">${rawJson}</script>
|
|
18052
|
+
<script>${js}</script>
|
|
18053
|
+
</body>
|
|
18054
|
+
</html>`;
|
|
18055
|
+
(0, import_node_fs11.writeFileSync)(outputPath, html, "utf8");
|
|
18056
|
+
printCommandEnvelope(
|
|
18057
|
+
{
|
|
18058
|
+
ok: true,
|
|
18059
|
+
file: outputPath,
|
|
18060
|
+
session_count: targets.length,
|
|
18061
|
+
render: {
|
|
18062
|
+
sections: [
|
|
18063
|
+
{
|
|
18064
|
+
title: "sessions render",
|
|
18065
|
+
lines: [`Rendered session viewer: ${outputPath}`]
|
|
18066
|
+
}
|
|
18067
|
+
]
|
|
18068
|
+
}
|
|
18069
|
+
},
|
|
18070
|
+
{ json: options.json }
|
|
18071
|
+
);
|
|
18072
|
+
}
|
|
18073
|
+
function collectOption(value, previous) {
|
|
18074
|
+
previous.push(value);
|
|
18075
|
+
return previous;
|
|
18076
|
+
}
|
|
18077
|
+
function registerSessionsCommands(program) {
|
|
18078
|
+
const sessions = program.command("sessions").description("Upload and render local agent session transcripts.").addHelpText(
|
|
18079
|
+
"after",
|
|
18080
|
+
`
|
|
18081
|
+
Notes:
|
|
18082
|
+
Session commands operate on local Claude session JSONL files under
|
|
18083
|
+
~/.claude/projects. send uploads a compacted transcript or file to Deepline.
|
|
18084
|
+
render writes a local HTML viewer.
|
|
18085
|
+
|
|
18086
|
+
Examples:
|
|
18087
|
+
deepline sessions send --current-session --json
|
|
18088
|
+
deepline sessions send --session-id 5a3bfb97-a2d9-49d9-82c6-52ccc03dadca
|
|
18089
|
+
deepline sessions render --current-session --output session.html
|
|
18090
|
+
`
|
|
18091
|
+
);
|
|
18092
|
+
sessions.command("send").description("Upload session transcript(s) or a local file to Deepline.").addHelpText(
|
|
18093
|
+
"after",
|
|
18094
|
+
`
|
|
18095
|
+
Examples:
|
|
18096
|
+
deepline sessions send --current-session --json
|
|
18097
|
+
deepline sessions send --session-id 5a3bfb97-a2d9-49d9-82c6-52ccc03dadca --label "pilot run"
|
|
18098
|
+
deepline sessions send --file ./debug.log --json
|
|
18099
|
+
`
|
|
18100
|
+
).option(
|
|
18101
|
+
"--session-id <uuid>",
|
|
18102
|
+
"Claude session UUID. Repeat for multiple sessions.",
|
|
18103
|
+
collectOption,
|
|
18104
|
+
[]
|
|
18105
|
+
).option(
|
|
18106
|
+
"--label <label>",
|
|
18107
|
+
"Label for the preceding session id",
|
|
18108
|
+
collectOption,
|
|
18109
|
+
[]
|
|
18110
|
+
).option("--current-session", "Use the newest local Claude session JSONL").option("--file <path>", "Upload a raw local file instead of a session").option("--json", "Emit JSON output. Also automatic when stdout is piped").action(handleSessionsSend);
|
|
18111
|
+
sessions.command("render").description("Render local session transcript(s) to an HTML viewer.").addHelpText(
|
|
18112
|
+
"after",
|
|
18113
|
+
`
|
|
18114
|
+
Examples:
|
|
18115
|
+
deepline sessions render --current-session
|
|
18116
|
+
deepline sessions render --session-id 5a3bfb97-a2d9-49d9-82c6-52ccc03dadca --output session.html
|
|
18117
|
+
deepline sessions render --current-session --auto-refresh 5 --json
|
|
18118
|
+
`
|
|
18119
|
+
).option(
|
|
18120
|
+
"--session-id <uuid>",
|
|
18121
|
+
"Claude session UUID. Repeat for multiple sessions.",
|
|
18122
|
+
collectOption,
|
|
18123
|
+
[]
|
|
18124
|
+
).option(
|
|
18125
|
+
"--label <label>",
|
|
18126
|
+
"Label for the preceding session id",
|
|
18127
|
+
collectOption,
|
|
18128
|
+
[]
|
|
18129
|
+
).option("--current-session", "Use the newest local Claude session JSONL").option("--auto-refresh <seconds>", "Add a browser auto-refresh interval").option("-o, --output <path>", "Output HTML path").option("--json", "Emit JSON output. Also automatic when stdout is piped").action(handleSessionsRender);
|
|
18130
|
+
}
|
|
18131
|
+
|
|
17538
18132
|
// src/cli/commands/tools.ts
|
|
17539
18133
|
var import_commander2 = require("commander");
|
|
18134
|
+
var import_node_fs13 = require("fs");
|
|
18135
|
+
var import_node_os10 = require("os");
|
|
18136
|
+
var import_node_path16 = require("path");
|
|
18137
|
+
|
|
18138
|
+
// src/tool-output.ts
|
|
17540
18139
|
var import_node_fs12 = require("fs");
|
|
17541
18140
|
var import_node_os9 = require("os");
|
|
17542
18141
|
var import_node_path15 = require("path");
|
|
17543
|
-
|
|
17544
|
-
// src/tool-output.ts
|
|
17545
|
-
var import_node_fs11 = require("fs");
|
|
17546
|
-
var import_node_os8 = require("os");
|
|
17547
|
-
var import_node_path14 = require("path");
|
|
17548
18142
|
function isPlainObject(value) {
|
|
17549
18143
|
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
17550
18144
|
}
|
|
@@ -17640,19 +18234,19 @@ function tryConvertToList(payload, options) {
|
|
|
17640
18234
|
return null;
|
|
17641
18235
|
}
|
|
17642
18236
|
function ensureOutputDir() {
|
|
17643
|
-
const outputDir = (0,
|
|
17644
|
-
(0,
|
|
18237
|
+
const outputDir = (0, import_node_path15.join)((0, import_node_os9.homedir)(), ".local", "share", "deepline", "data");
|
|
18238
|
+
(0, import_node_fs12.mkdirSync)(outputDir, { recursive: true });
|
|
17645
18239
|
return outputDir;
|
|
17646
18240
|
}
|
|
17647
18241
|
function writeJsonOutputFile(payload, stem) {
|
|
17648
18242
|
const outputDir = ensureOutputDir();
|
|
17649
|
-
const outputPath = (0,
|
|
17650
|
-
(0,
|
|
18243
|
+
const outputPath = (0, import_node_path15.join)(outputDir, `${stem}_${Date.now()}.json`);
|
|
18244
|
+
(0, import_node_fs12.writeFileSync)(outputPath, JSON.stringify(payload, null, 2), "utf-8");
|
|
17651
18245
|
return outputPath;
|
|
17652
18246
|
}
|
|
17653
18247
|
function writeCsvOutputFile(rows, stem) {
|
|
17654
18248
|
const outputDir = ensureOutputDir();
|
|
17655
|
-
const outputPath = (0,
|
|
18249
|
+
const outputPath = (0, import_node_path15.join)(outputDir, `${stem}_${Date.now()}.csv`);
|
|
17656
18250
|
const seen = /* @__PURE__ */ new Set();
|
|
17657
18251
|
const columns = [];
|
|
17658
18252
|
for (const row of rows) {
|
|
@@ -17675,7 +18269,7 @@ function writeCsvOutputFile(rows, stem) {
|
|
|
17675
18269
|
for (const row of rows) {
|
|
17676
18270
|
lines.push(columns.map((column) => escapeCell(row[column])).join(","));
|
|
17677
18271
|
}
|
|
17678
|
-
(0,
|
|
18272
|
+
(0, import_node_fs12.writeFileSync)(outputPath, `${lines.join("\n")}
|
|
17679
18273
|
`, "utf-8");
|
|
17680
18274
|
const previewRows = rows.slice(0, 5);
|
|
17681
18275
|
const previewColumns = columns.slice(0, 5);
|
|
@@ -17961,7 +18555,7 @@ Common commands:
|
|
|
17961
18555
|
|
|
17962
18556
|
Output:
|
|
17963
18557
|
Use describe for tool contracts.
|
|
17964
|
-
Use execute to run a tool.
|
|
18558
|
+
Use execute to run a tool.
|
|
17965
18559
|
`
|
|
17966
18560
|
);
|
|
17967
18561
|
tools.command("list").description("List available tools.").addHelpText(
|
|
@@ -18054,7 +18648,7 @@ Examples:
|
|
|
18054
18648
|
Notes:
|
|
18055
18649
|
Shows the compact agent contract by default: what the tool does, cost,
|
|
18056
18650
|
required inputs, play getters, and a runnable ctx.tools.execute snippet.
|
|
18057
|
-
|
|
18651
|
+
get is accepted as a compatibility alias for describe.
|
|
18058
18652
|
|
|
18059
18653
|
Examples:
|
|
18060
18654
|
deepline tools describe hunter_email_verifier
|
|
@@ -18088,29 +18682,13 @@ Examples:
|
|
|
18088
18682
|
gettersOnly: Boolean(options.gettersOnly)
|
|
18089
18683
|
});
|
|
18090
18684
|
});
|
|
18091
|
-
addToolMetadataCommand(tools.command("describe <toolId>"));
|
|
18092
|
-
tools.command("
|
|
18093
|
-
"after",
|
|
18094
|
-
`
|
|
18095
|
-
Examples:
|
|
18096
|
-
deepline tools describe hunter_email_verifier --json
|
|
18097
|
-
`
|
|
18098
|
-
).option("--json", "Emit JSON output. Also automatic when stdout is piped").action(async (toolId, options) => {
|
|
18099
|
-
const message = `tools get has been removed from the V2 SDK CLI. Use: deepline tools describe ${toolId} --json`;
|
|
18100
|
-
if (options.json || shouldEmitJson()) {
|
|
18101
|
-
printJsonError({ message, code: "TOOLS_GET_REMOVED" });
|
|
18102
|
-
} else {
|
|
18103
|
-
console.error(message);
|
|
18104
|
-
}
|
|
18105
|
-
process.exitCode = 2;
|
|
18106
|
-
});
|
|
18107
|
-
tools.command("execute <toolId>").alias("run").description("Execute a tool by id.").addHelpText(
|
|
18685
|
+
addToolMetadataCommand(tools.command("describe <toolId>").alias("get"));
|
|
18686
|
+
tools.command("execute <toolId>").description("Execute a tool by id.").addHelpText(
|
|
18108
18687
|
"after",
|
|
18109
18688
|
`
|
|
18110
18689
|
Notes:
|
|
18111
18690
|
Use tools for one atomic provider/API operation. Use plays for composed workflows,
|
|
18112
18691
|
waterfalls, row maps, checkpoints, and retries.
|
|
18113
|
-
execute is the canonical execution verb. run is a compatibility alias.
|
|
18114
18692
|
Calling a provider-backed tool can spend Deepline credits. Use --json for the
|
|
18115
18693
|
stable result payload plus output preview and debugging helpers.
|
|
18116
18694
|
|
|
@@ -18158,7 +18736,7 @@ Examples:
|
|
|
18158
18736
|
}
|
|
18159
18737
|
async function getTool(toolId, options = {}) {
|
|
18160
18738
|
if (!toolId) {
|
|
18161
|
-
console.error("Usage: deepline tools
|
|
18739
|
+
console.error("Usage: deepline tools describe <toolId> [--json]");
|
|
18162
18740
|
return 1;
|
|
18163
18741
|
}
|
|
18164
18742
|
const client2 = new DeeplineClient();
|
|
@@ -18709,11 +19287,11 @@ function normalizeOutputFormat(raw) {
|
|
|
18709
19287
|
}
|
|
18710
19288
|
function resolveAtFilePath(rawPath) {
|
|
18711
19289
|
const trimmed = rawPath.trim();
|
|
18712
|
-
const resolved = (0,
|
|
18713
|
-
if ((0,
|
|
19290
|
+
const resolved = (0, import_node_path16.resolve)(trimmed);
|
|
19291
|
+
if ((0, import_node_fs13.existsSync)(resolved)) return resolved;
|
|
18714
19292
|
if (process.platform !== "win32" && trimmed.includes("\\")) {
|
|
18715
|
-
const normalized = (0,
|
|
18716
|
-
if ((0,
|
|
19293
|
+
const normalized = (0, import_node_path16.resolve)(trimmed.replace(/\\/g, "/"));
|
|
19294
|
+
if ((0, import_node_fs13.existsSync)(normalized)) return normalized;
|
|
18717
19295
|
}
|
|
18718
19296
|
return resolved;
|
|
18719
19297
|
}
|
|
@@ -18724,7 +19302,7 @@ function readJsonArgument(raw, flagName) {
|
|
|
18724
19302
|
throw new Error(`Invalid ${flagName} value: empty @file path.`);
|
|
18725
19303
|
}
|
|
18726
19304
|
try {
|
|
18727
|
-
return (0,
|
|
19305
|
+
return (0, import_node_fs13.readFileSync)(resolveAtFilePath(filePath), "utf8").replace(
|
|
18728
19306
|
/^\uFEFF/,
|
|
18729
19307
|
""
|
|
18730
19308
|
);
|
|
@@ -18815,9 +19393,9 @@ function powerShellQuote(value) {
|
|
|
18815
19393
|
function seedToolListScript(input2) {
|
|
18816
19394
|
const stem = safeFileStem(input2.toolId);
|
|
18817
19395
|
const fileName = `${stem}-workflow-seed-${Date.now()}.play.ts`;
|
|
18818
|
-
const scriptDir = (0,
|
|
18819
|
-
(0,
|
|
18820
|
-
const scriptPath = (0,
|
|
19396
|
+
const scriptDir = (0, import_node_fs13.mkdtempSync)((0, import_node_path16.join)((0, import_node_os10.tmpdir)(), "deepline-workflow-seed-"));
|
|
19397
|
+
(0, import_node_fs13.chmodSync)(scriptDir, 448);
|
|
19398
|
+
const scriptPath = (0, import_node_path16.join)(scriptDir, fileName);
|
|
18821
19399
|
const projectDir = `deepline/projects/${stem}-workflow`;
|
|
18822
19400
|
const playName = `${stem}-workflow`;
|
|
18823
19401
|
const sampleRows = input2.rows.length > 0 ? `${JSON.stringify(input2.rows.slice(0, 2)).replace(/\]$/, "")}, ...]` : "[]";
|
|
@@ -18853,7 +19431,7 @@ export default definePlay(${JSON.stringify(playName)}, async (ctx) => {
|
|
|
18853
19431
|
};
|
|
18854
19432
|
});
|
|
18855
19433
|
`;
|
|
18856
|
-
(0,
|
|
19434
|
+
(0, import_node_fs13.writeFileSync)(scriptPath, script, { encoding: "utf-8", mode: 384 });
|
|
18857
19435
|
return {
|
|
18858
19436
|
path: scriptPath,
|
|
18859
19437
|
sourceCode: script,
|
|
@@ -19108,10 +19686,10 @@ async function executeTool(args) {
|
|
|
19108
19686
|
|
|
19109
19687
|
// src/cli/commands/workflow.ts
|
|
19110
19688
|
var import_promises6 = require("fs/promises");
|
|
19111
|
-
var
|
|
19689
|
+
var import_node_path17 = require("path");
|
|
19112
19690
|
|
|
19113
19691
|
// src/cli/workflow-to-play.ts
|
|
19114
|
-
var
|
|
19692
|
+
var import_node_crypto5 = require("crypto");
|
|
19115
19693
|
var HITL_WAIT_FOR_SIGNAL_TOOL = "deepline_workflow_wait_for_signal";
|
|
19116
19694
|
var HITL_SLACK_TOOL = "slack_message_with_hitl";
|
|
19117
19695
|
var SUB_WORKFLOW_TOOL_PREFIX = "deepline_workflow_";
|
|
@@ -19217,7 +19795,7 @@ function sanitizePlayNameSegment(value) {
|
|
|
19217
19795
|
}
|
|
19218
19796
|
function deriveWorkflowPlayName(workflowName) {
|
|
19219
19797
|
const base = sanitizePlayNameSegment(workflowName) || "workflow";
|
|
19220
|
-
const suffix = (0,
|
|
19798
|
+
const suffix = (0, import_node_crypto5.createHash)("sha256").update(workflowName).digest("hex").slice(0, 8);
|
|
19221
19799
|
const reserved = suffix.length + 1;
|
|
19222
19800
|
const allowedBase = Math.max(1, MAX_PLAY_NAME_LENGTH - reserved);
|
|
19223
19801
|
let name = `${base.slice(0, allowedBase)}_${suffix}`;
|
|
@@ -19315,7 +19893,7 @@ function readStatus(payload) {
|
|
|
19315
19893
|
}
|
|
19316
19894
|
async function readJsonOption(payload, file) {
|
|
19317
19895
|
if (file) {
|
|
19318
|
-
const raw = await (0, import_promises6.readFile)((0,
|
|
19896
|
+
const raw = await (0, import_promises6.readFile)((0, import_node_path17.resolve)(file), "utf8");
|
|
19319
19897
|
return JSON.parse(raw);
|
|
19320
19898
|
}
|
|
19321
19899
|
if (payload) {
|
|
@@ -19349,8 +19927,8 @@ async function transformOne(api, workflowId, outDir, publish) {
|
|
|
19349
19927
|
revision.config,
|
|
19350
19928
|
{ workflowName: workflow.name, version: revision.version }
|
|
19351
19929
|
);
|
|
19352
|
-
const file = (0,
|
|
19353
|
-
await (0, import_promises6.mkdir)((0,
|
|
19930
|
+
const file = (0, import_node_path17.join)((0, import_node_path17.resolve)(outDir), `${compiled.playName}.play.ts`);
|
|
19931
|
+
await (0, import_promises6.mkdir)((0, import_node_path17.dirname)(file), { recursive: true });
|
|
19354
19932
|
await (0, import_promises6.writeFile)(file, compiled.sourceCode, "utf8");
|
|
19355
19933
|
let published = false;
|
|
19356
19934
|
if (publish) {
|
|
@@ -19597,8 +20175,8 @@ Notes:
|
|
|
19597
20175
|
|
|
19598
20176
|
// src/cli/commands/update.ts
|
|
19599
20177
|
var import_node_child_process = require("child_process");
|
|
19600
|
-
var
|
|
19601
|
-
var
|
|
20178
|
+
var import_node_fs14 = require("fs");
|
|
20179
|
+
var import_node_path18 = require("path");
|
|
19602
20180
|
function posixShellQuote(value) {
|
|
19603
20181
|
return `'${value.replace(/'/g, `'\\''`)}'`;
|
|
19604
20182
|
}
|
|
@@ -19617,19 +20195,19 @@ function buildSourceUpdateCommand(sourceRoot) {
|
|
|
19617
20195
|
return `${cdCommand} && git fetch origin main --tags && git merge --ff-only origin/main`;
|
|
19618
20196
|
}
|
|
19619
20197
|
function findRepoBackedSdkRoot(startPath) {
|
|
19620
|
-
let current = (0,
|
|
20198
|
+
let current = (0, import_node_path18.resolve)(startPath);
|
|
19621
20199
|
while (true) {
|
|
19622
|
-
if ((0,
|
|
20200
|
+
if ((0, import_node_fs14.existsSync)((0, import_node_path18.join)(current, "sdk", "package.json")) && (0, import_node_fs14.existsSync)((0, import_node_path18.join)(current, "sdk", "bin", "deepline-dev.ts"))) {
|
|
19623
20201
|
return current;
|
|
19624
20202
|
}
|
|
19625
|
-
const parent = (0,
|
|
20203
|
+
const parent = (0, import_node_path18.dirname)(current);
|
|
19626
20204
|
if (parent === current) return null;
|
|
19627
20205
|
current = parent;
|
|
19628
20206
|
}
|
|
19629
20207
|
}
|
|
19630
20208
|
function resolveUpdatePlan() {
|
|
19631
|
-
const entrypoint = process.argv[1] ? (0,
|
|
19632
|
-
const sourceRoot = entrypoint ? findRepoBackedSdkRoot((0,
|
|
20209
|
+
const entrypoint = process.argv[1] ? (0, import_node_path18.resolve)(process.argv[1]) : "";
|
|
20210
|
+
const sourceRoot = entrypoint ? findRepoBackedSdkRoot((0, import_node_path18.dirname)(entrypoint)) : null;
|
|
19633
20211
|
if (sourceRoot) {
|
|
19634
20212
|
return {
|
|
19635
20213
|
kind: "source",
|
|
@@ -19704,7 +20282,7 @@ async function handleUpdate(options) {
|
|
|
19704
20282
|
return runCommand(plan.command, plan.args);
|
|
19705
20283
|
}
|
|
19706
20284
|
function registerUpdateCommand(program) {
|
|
19707
|
-
program.command("update").
|
|
20285
|
+
program.command("update").description("Update the Deepline SDK/CLI.").addHelpText(
|
|
19708
20286
|
"after",
|
|
19709
20287
|
`
|
|
19710
20288
|
Notes:
|
|
@@ -19732,7 +20310,7 @@ var command_compatibility_default = {
|
|
|
19732
20310
|
session: {
|
|
19733
20311
|
family: "python",
|
|
19734
20312
|
label: "a legacy Python CLI session/playground command",
|
|
19735
|
-
sdk_alternative: "Use
|
|
20313
|
+
sdk_alternative: "Use `deepline sessions send ...` or `deepline sessions render ...` for transcript workflows."
|
|
19736
20314
|
},
|
|
19737
20315
|
workflows: {
|
|
19738
20316
|
family: "python",
|
|
@@ -19752,15 +20330,14 @@ var command_compatibility_default = {
|
|
|
19752
20330
|
label: "an SDK CLI play command",
|
|
19753
20331
|
python_alternative: "Use `deepline workflows ...` only for legacy workflows."
|
|
19754
20332
|
},
|
|
19755
|
-
play: {
|
|
19756
|
-
family: "sdk",
|
|
19757
|
-
label: "an SDK CLI play command",
|
|
19758
|
-
python_alternative: "Use `deepline workflows ...` only for legacy workflows."
|
|
19759
|
-
},
|
|
19760
20333
|
runs: {
|
|
19761
20334
|
family: "sdk",
|
|
19762
20335
|
label: "an SDK CLI run inspection command"
|
|
19763
20336
|
},
|
|
20337
|
+
sessions: {
|
|
20338
|
+
family: "sdk",
|
|
20339
|
+
label: "an SDK CLI session transcript command"
|
|
20340
|
+
},
|
|
19764
20341
|
health: {
|
|
19765
20342
|
family: "sdk",
|
|
19766
20343
|
label: "an SDK CLI health command"
|
|
@@ -19892,9 +20469,9 @@ function unknownCommandNameFromMessage(message) {
|
|
|
19892
20469
|
|
|
19893
20470
|
// src/cli/skills-sync.ts
|
|
19894
20471
|
var import_node_child_process2 = require("child_process");
|
|
19895
|
-
var
|
|
19896
|
-
var
|
|
19897
|
-
var
|
|
20472
|
+
var import_node_fs15 = require("fs");
|
|
20473
|
+
var import_node_os11 = require("os");
|
|
20474
|
+
var import_node_path19 = require("path");
|
|
19898
20475
|
var CHECK_TIMEOUT_MS2 = 3e3;
|
|
19899
20476
|
var SDK_SKILL_NAME = "deepline-plays";
|
|
19900
20477
|
var attemptedSync = false;
|
|
@@ -19908,20 +20485,20 @@ function activePluginSkillsDir() {
|
|
|
19908
20485
|
return "";
|
|
19909
20486
|
}
|
|
19910
20487
|
const dir = process.env.DEEPLINE_PLUGIN_SKILLS_DIR?.trim() ?? "";
|
|
19911
|
-
return dir && (0,
|
|
20488
|
+
return dir && (0, import_node_fs15.existsSync)(dir) ? dir : "";
|
|
19912
20489
|
}
|
|
19913
20490
|
function readPluginSkillsVersion() {
|
|
19914
20491
|
const dir = activePluginSkillsDir();
|
|
19915
20492
|
if (!dir) return "";
|
|
19916
20493
|
try {
|
|
19917
|
-
return (0,
|
|
20494
|
+
return (0, import_node_fs15.readFileSync)((0, import_node_path19.join)(dir, ".version"), "utf-8").trim();
|
|
19918
20495
|
} catch {
|
|
19919
20496
|
return "";
|
|
19920
20497
|
}
|
|
19921
20498
|
}
|
|
19922
20499
|
function sdkSkillsVersionPath(baseUrl) {
|
|
19923
|
-
const home = process.env.HOME?.trim() || (0,
|
|
19924
|
-
return (0,
|
|
20500
|
+
const home = process.env.HOME?.trim() || (0, import_node_os11.homedir)();
|
|
20501
|
+
return (0, import_node_path19.join)(
|
|
19925
20502
|
home,
|
|
19926
20503
|
".local",
|
|
19927
20504
|
"deepline",
|
|
@@ -19934,25 +20511,25 @@ function readLocalSkillsVersion(baseUrl) {
|
|
|
19934
20511
|
const pluginVersion = readPluginSkillsVersion();
|
|
19935
20512
|
if (pluginVersion) return pluginVersion;
|
|
19936
20513
|
const path = sdkSkillsVersionPath(baseUrl);
|
|
19937
|
-
if (!(0,
|
|
20514
|
+
if (!(0, import_node_fs15.existsSync)(path)) return "";
|
|
19938
20515
|
try {
|
|
19939
|
-
return (0,
|
|
20516
|
+
return (0, import_node_fs15.readFileSync)(path, "utf-8").trim();
|
|
19940
20517
|
} catch {
|
|
19941
20518
|
return "";
|
|
19942
20519
|
}
|
|
19943
20520
|
}
|
|
19944
20521
|
function writeLocalSkillsVersion(baseUrl, version) {
|
|
19945
20522
|
const path = sdkSkillsVersionPath(baseUrl);
|
|
19946
|
-
(0,
|
|
19947
|
-
(0,
|
|
20523
|
+
(0, import_node_fs15.mkdirSync)((0, import_node_path19.dirname)(path), { recursive: true });
|
|
20524
|
+
(0, import_node_fs15.writeFileSync)(path, `${version}
|
|
19948
20525
|
`, "utf-8");
|
|
19949
20526
|
}
|
|
19950
20527
|
function installedSdkSkillHasStalePositionalExecuteExamples() {
|
|
19951
|
-
const home = process.env.HOME?.trim() || (0,
|
|
20528
|
+
const home = process.env.HOME?.trim() || (0, import_node_os11.homedir)();
|
|
19952
20529
|
const pluginSkillsDir = activePluginSkillsDir();
|
|
19953
|
-
const roots = pluginSkillsDir ? [(0,
|
|
19954
|
-
(0,
|
|
19955
|
-
(0,
|
|
20530
|
+
const roots = pluginSkillsDir ? [(0, import_node_path19.join)(pluginSkillsDir, SDK_SKILL_NAME)] : [
|
|
20531
|
+
(0, import_node_path19.join)(home, ".claude", "skills", SDK_SKILL_NAME),
|
|
20532
|
+
(0, import_node_path19.join)(home, ".agents", "skills", SDK_SKILL_NAME)
|
|
19956
20533
|
];
|
|
19957
20534
|
const staleMarkers = [
|
|
19958
20535
|
"ctx.tools.execute(key",
|
|
@@ -19962,22 +20539,22 @@ function installedSdkSkillHasStalePositionalExecuteExamples() {
|
|
|
19962
20539
|
'rowCtx.tools.execute("'
|
|
19963
20540
|
];
|
|
19964
20541
|
const scan = (dir) => {
|
|
19965
|
-
for (const entry of (0,
|
|
19966
|
-
const path = (0,
|
|
19967
|
-
const stat4 = (0,
|
|
20542
|
+
for (const entry of (0, import_node_fs15.readdirSync)(dir)) {
|
|
20543
|
+
const path = (0, import_node_path19.join)(dir, entry);
|
|
20544
|
+
const stat4 = (0, import_node_fs15.statSync)(path);
|
|
19968
20545
|
if (stat4.isDirectory()) {
|
|
19969
20546
|
if (scan(path)) return true;
|
|
19970
20547
|
continue;
|
|
19971
20548
|
}
|
|
19972
20549
|
if (!entry.endsWith(".md")) continue;
|
|
19973
|
-
const text = (0,
|
|
20550
|
+
const text = (0, import_node_fs15.readFileSync)(path, "utf-8");
|
|
19974
20551
|
if (staleMarkers.some((marker) => text.includes(marker))) return true;
|
|
19975
20552
|
}
|
|
19976
20553
|
return false;
|
|
19977
20554
|
};
|
|
19978
20555
|
for (const root of roots) {
|
|
19979
20556
|
try {
|
|
19980
|
-
if ((0,
|
|
20557
|
+
if ((0, import_node_fs15.existsSync)(root) && scan(root)) return true;
|
|
19981
20558
|
} catch {
|
|
19982
20559
|
continue;
|
|
19983
20560
|
}
|
|
@@ -20049,7 +20626,7 @@ function resolveSkillsInstallCommands(baseUrl) {
|
|
|
20049
20626
|
return [npxInstall];
|
|
20050
20627
|
}
|
|
20051
20628
|
function runOneSkillsInstall(install) {
|
|
20052
|
-
return new Promise((
|
|
20629
|
+
return new Promise((resolve16) => {
|
|
20053
20630
|
const child = (0, import_node_child_process2.spawn)(install.command, install.args, {
|
|
20054
20631
|
stdio: ["ignore", "ignore", "pipe"],
|
|
20055
20632
|
env: process.env
|
|
@@ -20059,7 +20636,7 @@ function runOneSkillsInstall(install) {
|
|
|
20059
20636
|
stderr += chunk.toString("utf-8");
|
|
20060
20637
|
});
|
|
20061
20638
|
child.on("error", (error) => {
|
|
20062
|
-
|
|
20639
|
+
resolve16({
|
|
20063
20640
|
ok: false,
|
|
20064
20641
|
detail: `failed to start ${install.command}: ${error.message}`,
|
|
20065
20642
|
manualCommand: install.manualCommand
|
|
@@ -20067,11 +20644,11 @@ function runOneSkillsInstall(install) {
|
|
|
20067
20644
|
});
|
|
20068
20645
|
child.on("close", (code) => {
|
|
20069
20646
|
if (code === 0) {
|
|
20070
|
-
|
|
20647
|
+
resolve16({ ok: true, detail: "", manualCommand: install.manualCommand });
|
|
20071
20648
|
return;
|
|
20072
20649
|
}
|
|
20073
20650
|
const detail = stderr.trim();
|
|
20074
|
-
|
|
20651
|
+
resolve16({
|
|
20075
20652
|
ok: false,
|
|
20076
20653
|
detail: detail ? `${install.command}: ${detail}` : `${install.command} exited ${code}`,
|
|
20077
20654
|
manualCommand: install.manualCommand
|
|
@@ -20159,8 +20736,8 @@ function shouldDeferSkillsSyncForCommand() {
|
|
|
20159
20736
|
return (command === "play" || command === "plays") && subcommand === "run" && args.includes("--json");
|
|
20160
20737
|
}
|
|
20161
20738
|
async function runPlayRunnerHealthCheck() {
|
|
20162
|
-
const dir = await (0, import_promises7.mkdtemp)((0,
|
|
20163
|
-
const file = (0,
|
|
20739
|
+
const dir = await (0, import_promises7.mkdtemp)((0, import_node_path20.join)((0, import_node_os12.tmpdir)(), "deepline-health-play-"));
|
|
20740
|
+
const file = (0, import_node_path20.join)(dir, "health-check.play.ts");
|
|
20164
20741
|
try {
|
|
20165
20742
|
await (0, import_promises7.writeFile)(
|
|
20166
20743
|
file,
|
|
@@ -20348,6 +20925,7 @@ Common commands:
|
|
|
20348
20925
|
deepline preflight
|
|
20349
20926
|
deepline health
|
|
20350
20927
|
deepline auth status --json
|
|
20928
|
+
deepline sessions send --current-session --json
|
|
20351
20929
|
deepline plays search email --json
|
|
20352
20930
|
deepline plays describe person-linkedin-to-email --json
|
|
20353
20931
|
deepline plays run my.play.ts --input '{"domain":"stripe.com"}'
|
|
@@ -20400,6 +20978,7 @@ Exit codes:
|
|
|
20400
20978
|
registerAuthCommands(program);
|
|
20401
20979
|
registerToolsCommands(program);
|
|
20402
20980
|
registerPlayCommands(program);
|
|
20981
|
+
registerSessionsCommands(program);
|
|
20403
20982
|
registerWorkflowCommands(program);
|
|
20404
20983
|
registerSecretsCommands(program);
|
|
20405
20984
|
registerBillingCommands(program);
|