deepline 0.3.113 → 0.3.114
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/dist/bundling-sources/sdk/src/client.ts +3 -1
- package/dist/bundling-sources/sdk/src/compat.ts +167 -11
- package/dist/bundling-sources/sdk/src/release.ts +1 -1
- package/dist/bundling-sources/sdk/src/skills-version.ts +27 -1
- package/dist/bundling-sources/shared_libs/monitors/inbound-queue.ts +6 -2
- package/dist/bundling-sources/shared_libs/observability/queue-health.ts +291 -6
- package/dist/bundling-sources/shared_libs/observability/scheduled-jobs.json +24 -24
- package/dist/bundling-sources/shared_libs/observability/scheduled-work-manual.ts +2 -0
- package/dist/bundling-sources/shared_libs/observability/scheduled-work.ts +29 -1
- package/dist/bundling-sources/shared_libs/play-runtime/admission-transport-policy.ts +91 -0
- package/dist/bundling-sources/shared_libs/play-runtime/context.ts +2 -0
- package/dist/bundling-sources/shared_libs/play-runtime/direct-admission-deadline.ts +34 -0
- package/dist/bundling-sources/shared_libs/play-runtime/fixture-behavior.ts +1 -0
- package/dist/bundling-sources/shared_libs/play-runtime/internal-bootstrap-token.ts +325 -0
- package/dist/bundling-sources/shared_libs/play-runtime/play-admission-outcome.ts +134 -0
- package/dist/bundling-sources/shared_libs/play-runtime/play-runs/admission/contracts.ts +13 -0
- package/dist/bundling-sources/shared_libs/play-runtime/play-runs/admission/index.ts +4 -1
- package/dist/bundling-sources/shared_libs/play-runtime/play-runs/admission/postgres-adapter.ts +13 -0
- package/dist/bundling-sources/shared_libs/play-runtime/play-webhook-admission-probe.ts +32 -0
- package/dist/bundling-sources/shared_libs/play-runtime/play-webhook-identity.ts +28 -0
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backend.ts +7 -0
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-cron-fire-task.ts +100 -0
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-runtime-worker.ts +313 -0
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-shared.ts +111 -3
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd.ts +16 -0
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/postgres-pool.ts +67 -8
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/postgres.ts +1394 -22
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/run-ledger-outbox-recovery.ts +74 -13
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/submit-admission.ts +79 -15
- package/dist/bundling-sources/shared_libs/play-runtime/webhook-receipt-retry.ts +21 -21
- package/dist/bundling-sources/shared_libs/plays/bundling/index.ts +4 -1
- package/dist/bundling-sources/shared_libs/product-notifications/catalog.ts +64 -0
- package/dist/bundling-sources/shared_libs/product-notifications/default-policy.ts +1 -1
- package/dist/bundling-sources/shared_libs/product-notifications/events.ts +20 -1
- package/dist/bundling-sources/shared_libs/security/receipt-admission-token.ts +224 -0
- package/dist/cli/index.js +574 -114
- package/dist/cli/index.mjs +592 -133
- package/dist/index.d.mts +54 -1
- package/dist/index.d.ts +54 -1
- package/dist/index.js +8 -3
- package/dist/index.mjs +8 -3
- package/dist/install-integrity.json +7 -0
- package/dist/plays/bundle-play-file.mjs +1 -1
- package/dist/release.d.mts +1 -1
- package/dist/release.d.ts +1 -1
- package/dist/release.js +1 -1
- package/dist/release.mjs +1 -1
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -1298,7 +1298,7 @@ var SDK_RELEASE = {
|
|
|
1298
1298
|
// getters keep their established compatibility behavior.
|
|
1299
1299
|
// 0.3.1 deprecated the legacy `deepline enrich` command in favor of Plays.
|
|
1300
1300
|
// 0.3.90 is the first deliberately versioned SDK release for API v3.
|
|
1301
|
-
version: "0.3.
|
|
1301
|
+
version: "0.3.114",
|
|
1302
1302
|
updateSummary: "Play grep now returns concise results with the matched fields and terms. Automatic CLI updates are enabled by default; use `deepline settings autoupdate off` to opt out, `deepline settings autoupdate on` to re-enable updates, or `deepline settings autoupdate pin <version>` to hold an exact release.",
|
|
1303
1303
|
packageCapabilities: {
|
|
1304
1304
|
updatePreferences: 1
|
|
@@ -1514,8 +1514,22 @@ function readPluginSkillsVersion() {
|
|
|
1514
1514
|
return "";
|
|
1515
1515
|
}
|
|
1516
1516
|
}
|
|
1517
|
+
var KNOWN_SKILL_AGENTS = [
|
|
1518
|
+
"antigravity",
|
|
1519
|
+
"claude-code",
|
|
1520
|
+
"cline",
|
|
1521
|
+
"codex",
|
|
1522
|
+
"cursor",
|
|
1523
|
+
"gemini-cli",
|
|
1524
|
+
"windsurf"
|
|
1525
|
+
];
|
|
1526
|
+
function skillsAgentPathSegment(agent) {
|
|
1527
|
+
if (agent === "*") return "all";
|
|
1528
|
+
const slug = agent.replace(/[^a-z0-9]+/gi, "-").replace(/^-+|-+$/g, "");
|
|
1529
|
+
return slug || "agent";
|
|
1530
|
+
}
|
|
1517
1531
|
function sdkSkillsVersionPath(baseUrl, agents = []) {
|
|
1518
|
-
const suffix = agents.length > 0 ? `-${agents.join("-")}` : "";
|
|
1532
|
+
const suffix = agents.length > 0 ? `-${agents.map(skillsAgentPathSegment).join("-")}` : "";
|
|
1519
1533
|
return (0, import_node_path2.join)(sdkCliStateDirPath(baseUrl), `skills${suffix}-version`);
|
|
1520
1534
|
}
|
|
1521
1535
|
function legacySdkSkillsVersionPath(baseUrl) {
|
|
@@ -4847,7 +4861,7 @@ function resolveToolExecuteTimeoutMs(toolId, input2) {
|
|
|
4847
4861
|
if (usesExtendedBetterContactLauncherBudget(normalized)) {
|
|
4848
4862
|
return BETTERCONTACT_LAUNCHER_CLIENT_TIMEOUT_MS;
|
|
4849
4863
|
}
|
|
4850
|
-
return normalized === "deeplineagent" || normalized === "deeplineagent_deeplineagent" || normalized === "ai_inference" || normalized === "deeplineagent_ai_inference" || normalized === "aiinference" ? DEEPLINEAGENT_EXECUTE_TIMEOUT_MS : void 0;
|
|
4864
|
+
return normalized === "deeplineagent" || normalized === "deeplineagent_deeplineagent" || normalized === "ai_inference" || normalized === "deeplineagent_ai_inference" || normalized === "ai_evaluate" || normalized === "deeplineagent_ai_evaluate" || normalized === "aiinference" ? DEEPLINEAGENT_EXECUTE_TIMEOUT_MS : void 0;
|
|
4851
4865
|
}
|
|
4852
4866
|
var RUNS_FAILED_LOG_LIMIT = 20;
|
|
4853
4867
|
var RUN_LOGS_PAGE_LIMIT = 1e3;
|
|
@@ -8196,7 +8210,9 @@ var import_node_fs3 = require("fs");
|
|
|
8196
8210
|
var import_node_os3 = require("os");
|
|
8197
8211
|
var import_node_path3 = require("path");
|
|
8198
8212
|
var CHECK_TIMEOUT_MS = 2e3;
|
|
8199
|
-
var
|
|
8213
|
+
var SDK_COMPATIBILITY_TRUST_MS = 10 * 60 * 1e3;
|
|
8214
|
+
var SDK_COMPATIBILITY_CACHE_TTL_MS = 24 * 60 * 60 * 1e3;
|
|
8215
|
+
var SDK_COMPATIBILITY_FAST_DEADLINE_MS = 400;
|
|
8200
8216
|
function shouldSkipCompatibilityCheck() {
|
|
8201
8217
|
const value = process.env.DEEPLINE_SKIP_SDK_COMPAT_CHECK?.trim().toLowerCase();
|
|
8202
8218
|
return value === "1" || value === "true" || value === "yes";
|
|
@@ -8225,7 +8241,29 @@ function legacyCompatibilityCacheKey(baseUrl, command) {
|
|
|
8225
8241
|
command: command?.trim() || null
|
|
8226
8242
|
});
|
|
8227
8243
|
}
|
|
8244
|
+
function isCleanCompatibilityPolicy(response) {
|
|
8245
|
+
if (!response) return false;
|
|
8246
|
+
return response.ok === true && response.update_required !== true && response.status !== "unsupported" && !response.auto_update?.should_auto_update && !response.cli_family;
|
|
8247
|
+
}
|
|
8248
|
+
function readFreshCleanCompatibility(baseUrl, command, skillsVersion) {
|
|
8249
|
+
const cached = readCachedCompatibility(baseUrl, command, skillsVersion);
|
|
8250
|
+
return isCleanCompatibilityPolicy(cached) ? cached : null;
|
|
8251
|
+
}
|
|
8252
|
+
function readTrustedCleanCompatibility(baseUrl, command, skillsVersion, now = Date.now()) {
|
|
8253
|
+
const entry = readCachedCompatibilityEntry(baseUrl, command, skillsVersion);
|
|
8254
|
+
if (!entry || !isSavedWithin(entry.savedAt, SDK_COMPATIBILITY_TRUST_MS, now))
|
|
8255
|
+
return null;
|
|
8256
|
+
return isCleanCompatibilityPolicy(entry.response) ? entry.response : null;
|
|
8257
|
+
}
|
|
8258
|
+
function isSavedWithin(savedAt, windowMs, now) {
|
|
8259
|
+
if (typeof savedAt !== "number") return false;
|
|
8260
|
+
const age = now - savedAt;
|
|
8261
|
+
return Number.isFinite(age) && age >= 0 && age <= windowMs;
|
|
8262
|
+
}
|
|
8228
8263
|
function readCachedCompatibility(baseUrl, command, skillsVersion) {
|
|
8264
|
+
return readCachedCompatibilityEntry(baseUrl, command, skillsVersion)?.response ?? null;
|
|
8265
|
+
}
|
|
8266
|
+
function readCachedCompatibilityEntry(baseUrl, command, skillsVersion) {
|
|
8229
8267
|
try {
|
|
8230
8268
|
const path = sdkCompatibilityCachePath(baseUrl);
|
|
8231
8269
|
const legacyPath = legacySdkCompatibilityCachePath();
|
|
@@ -8238,14 +8276,31 @@ function readCachedCompatibility(baseUrl, command, skillsVersion) {
|
|
|
8238
8276
|
(0, import_node_fs3.readFileSync)(cachePath, "utf8")
|
|
8239
8277
|
);
|
|
8240
8278
|
const entry = parsed.entries?.[compatibilityCacheKey(baseUrl, command, skillsVersion)] ?? (useLegacyCache ? parsed.entries?.[legacyCompatibilityCacheKey(baseUrl, command)] : void 0);
|
|
8241
|
-
if (!entry ||
|
|
8279
|
+
if (!entry || !isSavedWithin(entry.savedAt, SDK_COMPATIBILITY_CACHE_TTL_MS, Date.now())) {
|
|
8242
8280
|
return null;
|
|
8243
8281
|
}
|
|
8244
|
-
return entry
|
|
8282
|
+
return entry;
|
|
8245
8283
|
} catch {
|
|
8246
8284
|
return null;
|
|
8247
8285
|
}
|
|
8248
8286
|
}
|
|
8287
|
+
function invalidateCachedCompatibility(baseUrl, command, skillsVersion) {
|
|
8288
|
+
try {
|
|
8289
|
+
const path = sdkCompatibilityCachePath(baseUrl);
|
|
8290
|
+
const legacyPath = legacySdkCompatibilityCachePath();
|
|
8291
|
+
const cachePath = !(0, import_node_fs3.existsSync)(path) && (0, import_node_fs3.existsSync)(legacyPath) ? legacyPath : path;
|
|
8292
|
+
if (!(0, import_node_fs3.existsSync)(cachePath)) return;
|
|
8293
|
+
const existing = JSON.parse(
|
|
8294
|
+
(0, import_node_fs3.readFileSync)(cachePath, "utf8")
|
|
8295
|
+
);
|
|
8296
|
+
const entries = existing.entries ?? {};
|
|
8297
|
+
delete entries[compatibilityCacheKey(baseUrl, command, skillsVersion)];
|
|
8298
|
+
delete entries[legacyCompatibilityCacheKey(baseUrl, command)];
|
|
8299
|
+
(0, import_node_fs3.writeFileSync)(cachePath, `${JSON.stringify({ entries }, null, 2)}
|
|
8300
|
+
`);
|
|
8301
|
+
} catch {
|
|
8302
|
+
}
|
|
8303
|
+
}
|
|
8249
8304
|
function writeCachedCompatibility(baseUrl, command, skillsVersion, response) {
|
|
8250
8305
|
try {
|
|
8251
8306
|
const path = sdkCompatibilityCachePath(baseUrl);
|
|
@@ -8266,7 +8321,10 @@ async function checkSdkCompatibility(baseUrl, options = {}) {
|
|
|
8266
8321
|
return { response: null, error: null };
|
|
8267
8322
|
}
|
|
8268
8323
|
const controller = new AbortController();
|
|
8269
|
-
const timeout = setTimeout(
|
|
8324
|
+
const timeout = setTimeout(
|
|
8325
|
+
() => controller.abort(),
|
|
8326
|
+
options.timeoutMs ?? CHECK_TIMEOUT_MS
|
|
8327
|
+
);
|
|
8270
8328
|
try {
|
|
8271
8329
|
const url = new URL("/api/v2/sdk/compat", baseUrl);
|
|
8272
8330
|
url.searchParams.set("version", SDK_VERSION);
|
|
@@ -8288,14 +8346,17 @@ async function checkSdkCompatibility(baseUrl, options = {}) {
|
|
|
8288
8346
|
signal: controller.signal
|
|
8289
8347
|
});
|
|
8290
8348
|
const data = await response.json().catch(() => null);
|
|
8291
|
-
if (data) {
|
|
8292
|
-
|
|
8293
|
-
|
|
8294
|
-
options.command,
|
|
8295
|
-
options.skillsVersion,
|
|
8296
|
-
data
|
|
8349
|
+
if (!data || typeof data.ok !== "boolean" || typeof data.status !== "string") {
|
|
8350
|
+
throw new Error(
|
|
8351
|
+
`SDK compatibility endpoint returned a non-policy response (HTTP ${response.status}).`
|
|
8297
8352
|
);
|
|
8298
8353
|
}
|
|
8354
|
+
writeCachedCompatibility(
|
|
8355
|
+
baseUrl,
|
|
8356
|
+
options.command,
|
|
8357
|
+
options.skillsVersion,
|
|
8358
|
+
data
|
|
8359
|
+
);
|
|
8299
8360
|
return { response: data, error: null };
|
|
8300
8361
|
} catch (error) {
|
|
8301
8362
|
const cached = readCachedCompatibility(
|
|
@@ -8304,6 +8365,13 @@ async function checkSdkCompatibility(baseUrl, options = {}) {
|
|
|
8304
8365
|
options.skillsVersion
|
|
8305
8366
|
);
|
|
8306
8367
|
if (cached) {
|
|
8368
|
+
if (options.timeoutMs !== void 0 && options.timeoutMs < CHECK_TIMEOUT_MS) {
|
|
8369
|
+
invalidateCachedCompatibility(
|
|
8370
|
+
baseUrl,
|
|
8371
|
+
options.command,
|
|
8372
|
+
options.skillsVersion
|
|
8373
|
+
);
|
|
8374
|
+
}
|
|
8307
8375
|
return { response: cached, error: null };
|
|
8308
8376
|
}
|
|
8309
8377
|
return {
|
|
@@ -35109,7 +35177,19 @@ function renderMonitorGet(payload) {
|
|
|
35109
35177
|
const field = asRecord2(value);
|
|
35110
35178
|
const path = asString(field?.path);
|
|
35111
35179
|
const description = asString(field?.description);
|
|
35112
|
-
|
|
35180
|
+
const semantics = asString(field?.semantics);
|
|
35181
|
+
const applicability = asString(field?.applicability);
|
|
35182
|
+
const grammar = asRecord2(field?.grammar);
|
|
35183
|
+
const grammarSyntax = asString(grammar?.syntax);
|
|
35184
|
+
return path ? [
|
|
35185
|
+
{
|
|
35186
|
+
path,
|
|
35187
|
+
description,
|
|
35188
|
+
semantics,
|
|
35189
|
+
applicability,
|
|
35190
|
+
grammarSyntax
|
|
35191
|
+
}
|
|
35192
|
+
] : [];
|
|
35113
35193
|
}) : [];
|
|
35114
35194
|
if (specFields.length > 0) {
|
|
35115
35195
|
lines.push("", "Monitor spec:");
|
|
@@ -35117,6 +35197,15 @@ function renderMonitorGet(payload) {
|
|
|
35117
35197
|
lines.push(
|
|
35118
35198
|
` ${field.path}${field.description ? ` \u2014 ${field.description}` : ""}`
|
|
35119
35199
|
);
|
|
35200
|
+
if (field.semantics && field.semantics !== field.description) {
|
|
35201
|
+
lines.push(` Behavior: ${field.semantics}`);
|
|
35202
|
+
}
|
|
35203
|
+
if (field.applicability) {
|
|
35204
|
+
lines.push(` Applies to: ${field.applicability}`);
|
|
35205
|
+
}
|
|
35206
|
+
if (field.grammarSyntax) {
|
|
35207
|
+
lines.push(` Format: ${field.grammarSyntax}`);
|
|
35208
|
+
}
|
|
35120
35209
|
}
|
|
35121
35210
|
}
|
|
35122
35211
|
lines.push("", `Current SQL listener consumers (${boundPlays.length}):`);
|
|
@@ -35881,8 +35970,10 @@ Notes:
|
|
|
35881
35970
|
Read-only. Returns the exact editable definition, selected Deepline pricing,
|
|
35882
35971
|
billing state, output streams, dependent published plays, and monitor_spec.
|
|
35883
35972
|
When monitor_spec.available is true, its fields describe the deployed type's
|
|
35884
|
-
editable fields
|
|
35885
|
-
|
|
35973
|
+
editable fields, constraints, and provider-specific behavior. For TAMRadar,
|
|
35974
|
+
this includes the effective updates_since precision and engagement timing
|
|
35975
|
+
rules. Otherwise use the stored definition and check before proposing an
|
|
35976
|
+
update so scope and downstream effects are visible.
|
|
35886
35977
|
|
|
35887
35978
|
Examples:
|
|
35888
35979
|
deepline monitors get my-monitor --json
|
|
@@ -38608,7 +38699,6 @@ async function maybeReportSdkCliFailure(input2) {
|
|
|
38608
38699
|
|
|
38609
38700
|
// src/cli/skills-sync.ts
|
|
38610
38701
|
var CHECK_TIMEOUT_MS2 = 3e3;
|
|
38611
|
-
var SKILLS_SYNC_CLAIM_MAX_AGE_MS = 60 * 60 * 1e3;
|
|
38612
38702
|
function shouldSkipSkillsSync() {
|
|
38613
38703
|
if (detectAgentRuntime() === "claude_cowork") {
|
|
38614
38704
|
return true;
|
|
@@ -38619,65 +38709,286 @@ function shouldSkipSkillsSync() {
|
|
|
38619
38709
|
function unavailableSkillsNoticePath(baseUrl) {
|
|
38620
38710
|
return (0, import_node_path20.join)(sdkCliStateDirPath(baseUrl), "skills-sync-unavailable-version");
|
|
38621
38711
|
}
|
|
38622
|
-
|
|
38712
|
+
var SKILLS_SYNC_IN_PROGRESS_TTL_MS = 10 * 60 * 1e3;
|
|
38713
|
+
var SKILLS_SYNC_IN_PROGRESS_PID_CAP_MS = 6 * 60 * 60 * 1e3;
|
|
38714
|
+
var agentLeaseSegment = skillsAgentPathSegment;
|
|
38715
|
+
function sortedLeaseAgents(agents) {
|
|
38716
|
+
const expanded = agents.includes("*") ? [...agents, ...KNOWN_SKILL_AGENTS] : agents;
|
|
38717
|
+
return [...new Set(expanded)].sort((a, b) => a.localeCompare(b));
|
|
38718
|
+
}
|
|
38719
|
+
function inProgressSkillsSyncPath(baseUrl, agent) {
|
|
38623
38720
|
return (0, import_node_path20.join)(
|
|
38624
38721
|
sdkCliStateDirPath(baseUrl),
|
|
38625
|
-
`skills-sync-
|
|
38722
|
+
`skills-sync-in-progress-${agentLeaseSegment(agent)}`
|
|
38626
38723
|
);
|
|
38627
38724
|
}
|
|
38628
|
-
function
|
|
38629
|
-
|
|
38630
|
-
|
|
38631
|
-
|
|
38725
|
+
function readInProgressSkillsSyncLeaseFromDir(dir) {
|
|
38726
|
+
const claim = readMarkedSkillsSyncVersion((0, import_node_path20.join)(dir, "claim"));
|
|
38727
|
+
const [version = "", startedAt = ""] = claim.split(" ");
|
|
38728
|
+
const pidRaw = readMarkedSkillsSyncVersion((0, import_node_path20.join)(dir, "pid"));
|
|
38729
|
+
return {
|
|
38730
|
+
claimToken: version && startedAt ? `${version} ${startedAt}` : "",
|
|
38731
|
+
version,
|
|
38732
|
+
startedAt: Number(startedAt),
|
|
38733
|
+
pid: /^\d+$/.test(pidRaw) ? Number(pidRaw) : null,
|
|
38734
|
+
owner: readMarkedSkillsSyncVersion((0, import_node_path20.join)(dir, "owner"))
|
|
38735
|
+
};
|
|
38736
|
+
}
|
|
38737
|
+
function readInProgressSkillsSyncLease(baseUrl, agent) {
|
|
38738
|
+
return readInProgressSkillsSyncLeaseFromDir(
|
|
38739
|
+
inProgressSkillsSyncPath(baseUrl, agent)
|
|
38632
38740
|
);
|
|
38633
38741
|
}
|
|
38634
|
-
function
|
|
38742
|
+
function readInProgressSkillsSyncLeases(baseUrl, agents) {
|
|
38743
|
+
return new Map(
|
|
38744
|
+
sortedLeaseAgents(agents).map((agent) => [
|
|
38745
|
+
agent,
|
|
38746
|
+
readInProgressSkillsSyncLease(baseUrl, agent)
|
|
38747
|
+
])
|
|
38748
|
+
);
|
|
38749
|
+
}
|
|
38750
|
+
var UNRESOLVED_SKILLS_CLAIM_VERSION = "unresolved";
|
|
38751
|
+
function claimedSkillsVersion(leases) {
|
|
38752
|
+
for (const lease of leases.values()) {
|
|
38753
|
+
if (lease.version && lease.version !== UNRESOLVED_SKILLS_CLAIM_VERSION) {
|
|
38754
|
+
return lease.version;
|
|
38755
|
+
}
|
|
38756
|
+
}
|
|
38757
|
+
return "";
|
|
38758
|
+
}
|
|
38759
|
+
function isProcessAlive(pid) {
|
|
38635
38760
|
try {
|
|
38636
|
-
(
|
|
38637
|
-
|
|
38638
|
-
} catch {
|
|
38761
|
+
process.kill(pid, 0);
|
|
38762
|
+
return true;
|
|
38763
|
+
} catch (error) {
|
|
38764
|
+
return error.code === "EPERM";
|
|
38639
38765
|
}
|
|
38640
38766
|
}
|
|
38641
|
-
function
|
|
38642
|
-
|
|
38767
|
+
function isFreshInProgressSkillsSync(lease, now = Date.now()) {
|
|
38768
|
+
if (!Number.isFinite(lease.startedAt)) return false;
|
|
38769
|
+
const age = now - lease.startedAt;
|
|
38770
|
+
if (age < 0) return false;
|
|
38771
|
+
if (lease.pid !== null && isProcessAlive(lease.pid)) {
|
|
38772
|
+
return age < SKILLS_SYNC_IN_PROGRESS_PID_CAP_MS;
|
|
38773
|
+
}
|
|
38774
|
+
return age < SKILLS_SYNC_IN_PROGRESS_TTL_MS;
|
|
38775
|
+
}
|
|
38776
|
+
function quarantine(path, tag) {
|
|
38777
|
+
const holding = `${path}.${tag}-${process.pid}-${Date.now()}`;
|
|
38643
38778
|
try {
|
|
38644
|
-
(0, import_node_fs18.
|
|
38779
|
+
(0, import_node_fs18.renameSync)(path, holding);
|
|
38780
|
+
return holding;
|
|
38645
38781
|
} catch {
|
|
38646
|
-
return
|
|
38782
|
+
return null;
|
|
38647
38783
|
}
|
|
38648
|
-
|
|
38649
|
-
|
|
38650
|
-
|
|
38784
|
+
}
|
|
38785
|
+
function claimOneInProgressSkillsSync(baseUrl, remoteVersion, agent, owner) {
|
|
38786
|
+
const dir = inProgressSkillsSyncPath(baseUrl, agent);
|
|
38787
|
+
const errorCode = (error) => error.code;
|
|
38788
|
+
const create = () => {
|
|
38789
|
+
const claimToken = `${remoteVersion} ${Date.now()}`;
|
|
38790
|
+
const staging = `${dir}.staging-${process.pid}-${Date.now()}`;
|
|
38791
|
+
(0, import_node_fs18.mkdirSync)(staging);
|
|
38792
|
+
(0, import_node_fs18.writeFileSync)((0, import_node_path20.join)(staging, "claim"), `${claimToken}
|
|
38793
|
+
`, "utf-8");
|
|
38794
|
+
(0, import_node_fs18.writeFileSync)((0, import_node_path20.join)(staging, "owner"), `${owner}
|
|
38795
|
+
`, "utf-8");
|
|
38651
38796
|
try {
|
|
38652
|
-
(0, import_node_fs18.
|
|
38653
|
-
|
|
38654
|
-
(0, import_node_fs18.
|
|
38655
|
-
|
|
38656
|
-
|
|
38657
|
-
|
|
38658
|
-
|
|
38797
|
+
(0, import_node_fs18.renameSync)(staging, dir);
|
|
38798
|
+
} catch (error) {
|
|
38799
|
+
(0, import_node_fs18.rmSync)(staging, { recursive: true, force: true });
|
|
38800
|
+
const code = errorCode(error);
|
|
38801
|
+
const err = new Error("lease directory already exists");
|
|
38802
|
+
err.code = code === "EEXIST" || code === "ENOTEMPTY" ? "EEXIST" : String(code ?? "");
|
|
38803
|
+
throw err;
|
|
38804
|
+
}
|
|
38805
|
+
return { state: "claimed", claimToken };
|
|
38806
|
+
};
|
|
38807
|
+
try {
|
|
38808
|
+
(0, import_node_fs18.mkdirSync)((0, import_node_path20.dirname)(dir), { recursive: true });
|
|
38809
|
+
return create();
|
|
38810
|
+
} catch (error) {
|
|
38811
|
+
if (errorCode(error) !== "EEXIST") return { state: "unavailable" };
|
|
38812
|
+
}
|
|
38813
|
+
if (isFreshInProgressSkillsSync(readInProgressSkillsSyncLease(baseUrl, agent))) {
|
|
38814
|
+
return { state: "held" };
|
|
38815
|
+
}
|
|
38816
|
+
const tombstone = quarantine(dir, "stale");
|
|
38817
|
+
if (!tombstone) {
|
|
38818
|
+
return { state: "held" };
|
|
38819
|
+
}
|
|
38820
|
+
(0, import_node_fs18.rmSync)(tombstone, { recursive: true, force: true });
|
|
38821
|
+
try {
|
|
38822
|
+
return create();
|
|
38823
|
+
} catch (error) {
|
|
38824
|
+
return errorCode(error) === "EEXIST" ? { state: "held" } : { state: "unavailable" };
|
|
38825
|
+
}
|
|
38826
|
+
}
|
|
38827
|
+
function claimInProgressSkillsSync(baseUrl, remoteVersion, agents) {
|
|
38828
|
+
const claimTokens = /* @__PURE__ */ new Map();
|
|
38829
|
+
const owner = (0, import_node_crypto10.randomUUID)();
|
|
38830
|
+
for (const agent of sortedLeaseAgents(agents)) {
|
|
38831
|
+
const claim = claimOneInProgressSkillsSync(
|
|
38832
|
+
baseUrl,
|
|
38833
|
+
remoteVersion,
|
|
38834
|
+
agent,
|
|
38835
|
+
owner
|
|
38836
|
+
);
|
|
38837
|
+
if (claim.state !== "claimed") {
|
|
38838
|
+
releaseInProgressSkillsSync(baseUrl, claimTokens);
|
|
38839
|
+
return { state: claim.state };
|
|
38840
|
+
}
|
|
38841
|
+
claimTokens.set(agent, claim.claimToken);
|
|
38842
|
+
}
|
|
38843
|
+
return { state: "claimed", claimTokens, owner };
|
|
38844
|
+
}
|
|
38845
|
+
function claimAndSpawnDetachedSkillsSync(baseUrl, agents, remoteVersion, spawnDetached) {
|
|
38846
|
+
const claim = claimInProgressSkillsSync(baseUrl, remoteVersion, agents);
|
|
38847
|
+
if (claim.state !== "claimed") return claim.state;
|
|
38848
|
+
const { claimTokens, owner } = claim;
|
|
38849
|
+
spawnDetached([SKILLS_AUTO_SYNC_COMMAND, "--claim", owner], () => {
|
|
38850
|
+
releaseInProgressSkillsSync(baseUrl, claimTokens);
|
|
38851
|
+
if (remoteVersion !== UNRESOLVED_SKILLS_CLAIM_VERSION) {
|
|
38852
|
+
markFailedSkillsSync(baseUrl, remoteVersion, agents);
|
|
38659
38853
|
}
|
|
38660
|
-
|
|
38854
|
+
deferSkillsNotice(
|
|
38855
|
+
baseUrl,
|
|
38856
|
+
agents
|
|
38857
|
+
)(
|
|
38858
|
+
"Deepline skills refresh failed to start; run `deepline skills` to retry."
|
|
38859
|
+
);
|
|
38860
|
+
});
|
|
38861
|
+
return "claimed";
|
|
38862
|
+
}
|
|
38863
|
+
function recordOwnPidOnInProgressSkillsSync(baseUrl, leases) {
|
|
38864
|
+
for (const [agent, lease] of leases) {
|
|
38865
|
+
if (!lease.claimToken) continue;
|
|
38661
38866
|
try {
|
|
38662
|
-
|
|
38663
|
-
|
|
38867
|
+
(0, import_node_fs18.writeFileSync)(
|
|
38868
|
+
(0, import_node_path20.join)(inProgressSkillsSyncPath(baseUrl, agent), "pid"),
|
|
38869
|
+
`${process.pid}
|
|
38870
|
+
`,
|
|
38871
|
+
"utf-8"
|
|
38872
|
+
);
|
|
38873
|
+
} catch {
|
|
38874
|
+
}
|
|
38875
|
+
}
|
|
38876
|
+
}
|
|
38877
|
+
function releaseInProgressSkillsSync(baseUrl, claimTokens) {
|
|
38878
|
+
for (const [agent, claimToken] of claimTokens) {
|
|
38879
|
+
const dir = inProgressSkillsSyncPath(baseUrl, agent);
|
|
38880
|
+
if (!claimToken) {
|
|
38881
|
+
try {
|
|
38882
|
+
(0, import_node_fs18.rmSync)(dir, { recursive: true, force: true });
|
|
38883
|
+
} catch {
|
|
38664
38884
|
}
|
|
38665
|
-
|
|
38666
|
-
|
|
38667
|
-
|
|
38885
|
+
continue;
|
|
38886
|
+
}
|
|
38887
|
+
const tombstone = quarantine(dir, "release");
|
|
38888
|
+
if (!tombstone) continue;
|
|
38889
|
+
try {
|
|
38890
|
+
if (readInProgressSkillsSyncLeaseFromDir(tombstone).claimToken !== claimToken) {
|
|
38891
|
+
(0, import_node_fs18.renameSync)(tombstone, dir);
|
|
38668
38892
|
continue;
|
|
38669
38893
|
}
|
|
38670
|
-
if (owners.length !== 1) return { status: "held" };
|
|
38671
|
-
(0, import_node_fs18.renameSync)(path, `${path}-stale-${owners[0]}`);
|
|
38672
38894
|
} catch {
|
|
38673
|
-
|
|
38895
|
+
}
|
|
38896
|
+
(0, import_node_fs18.rmSync)(tombstone, { recursive: true, force: true });
|
|
38897
|
+
}
|
|
38898
|
+
}
|
|
38899
|
+
function claimTokensOf(leases) {
|
|
38900
|
+
return new Map(
|
|
38901
|
+
[...leases].map(([agent, lease]) => [agent, lease.claimToken])
|
|
38902
|
+
);
|
|
38903
|
+
}
|
|
38904
|
+
async function acquireSkillsInstallLease(baseUrl, agents, version, options = {
|
|
38905
|
+
waitMs: 9e4
|
|
38906
|
+
}) {
|
|
38907
|
+
const pollMs = options.pollMs ?? 250;
|
|
38908
|
+
const deadline = Date.now() + options.waitMs;
|
|
38909
|
+
let waited = false;
|
|
38910
|
+
for (; ; ) {
|
|
38911
|
+
const claim = claimInProgressSkillsSync(baseUrl, version, agents);
|
|
38912
|
+
if (claim.state === "unavailable") {
|
|
38913
|
+
return { release: () => {
|
|
38914
|
+
} };
|
|
38915
|
+
}
|
|
38916
|
+
if (claim.state === "claimed") {
|
|
38917
|
+
recordOwnPidOnInProgressSkillsSync(
|
|
38918
|
+
baseUrl,
|
|
38919
|
+
readInProgressSkillsSyncLeases(baseUrl, agents)
|
|
38920
|
+
);
|
|
38921
|
+
return {
|
|
38922
|
+
release: () => releaseInProgressSkillsSync(baseUrl, claim.claimTokens)
|
|
38923
|
+
};
|
|
38924
|
+
}
|
|
38925
|
+
if (Date.now() >= deadline) return null;
|
|
38926
|
+
if (!waited) {
|
|
38927
|
+
waited = true;
|
|
38928
|
+
options.onWait?.();
|
|
38929
|
+
}
|
|
38930
|
+
await new Promise((resolve21) => setTimeout(resolve21, pollMs));
|
|
38931
|
+
}
|
|
38932
|
+
}
|
|
38933
|
+
function skillsInstallLeasePath(baseUrl, agents) {
|
|
38934
|
+
return sortedLeaseAgents(agents).map((agent) => inProgressSkillsSyncPath(baseUrl, agent)).join(", ");
|
|
38935
|
+
}
|
|
38936
|
+
function deferredSkillsNoticePath(baseUrl, agents) {
|
|
38937
|
+
return (0, import_node_path20.join)(
|
|
38938
|
+
sdkCliStateDirPath(baseUrl),
|
|
38939
|
+
`skills-sync-notice-${sortedLeaseAgents(agents).map(agentLeaseSegment).join("-")}`
|
|
38940
|
+
);
|
|
38941
|
+
}
|
|
38942
|
+
function deferSkillsNotice(baseUrl, agents) {
|
|
38943
|
+
const path = deferredSkillsNoticePath(baseUrl, agents);
|
|
38944
|
+
return (text) => {
|
|
38945
|
+
try {
|
|
38946
|
+
(0, import_node_fs18.mkdirSync)((0, import_node_path20.dirname)(path), { recursive: true });
|
|
38947
|
+
(0, import_node_fs18.appendFileSync)(path, `${text.trimEnd()}
|
|
38948
|
+
`, "utf-8");
|
|
38949
|
+
} catch {
|
|
38950
|
+
}
|
|
38951
|
+
};
|
|
38952
|
+
}
|
|
38953
|
+
function flushDeferredSkillsNotices(baseUrl, agents) {
|
|
38954
|
+
const path = deferredSkillsNoticePath(baseUrl, agents);
|
|
38955
|
+
if (!(0, import_node_fs18.existsSync)(path)) return;
|
|
38956
|
+
const tombstone = quarantine(path, "consuming");
|
|
38957
|
+
if (!tombstone) return;
|
|
38958
|
+
let text = "";
|
|
38959
|
+
try {
|
|
38960
|
+
text = (0, import_node_fs18.readFileSync)(tombstone, "utf-8");
|
|
38961
|
+
} catch {
|
|
38962
|
+
return;
|
|
38963
|
+
} finally {
|
|
38964
|
+
try {
|
|
38965
|
+
(0, import_node_fs18.unlinkSync)(tombstone);
|
|
38966
|
+
} catch {
|
|
38674
38967
|
}
|
|
38675
38968
|
}
|
|
38676
|
-
|
|
38969
|
+
if (text.trim()) writeSdkSkillsStatusLine(text.trimEnd());
|
|
38677
38970
|
}
|
|
38678
|
-
function
|
|
38679
|
-
|
|
38680
|
-
|
|
38971
|
+
function flushDeferredSkillsSyncNotices(baseUrl) {
|
|
38972
|
+
if (shouldSkipSkillsSync() || hasActivePluginSkills()) return;
|
|
38973
|
+
const agents = resolveAutoSyncSkillAgents();
|
|
38974
|
+
if (agents.length === 0) return;
|
|
38975
|
+
flushDeferredSkillsNotices(baseUrl, agents);
|
|
38976
|
+
}
|
|
38977
|
+
var SKILLS_AUTO_SYNC_COMMAND = "skills-auto-sync";
|
|
38978
|
+
function spawnDetachedSkillsSyncChild(argv, onSpawnError) {
|
|
38979
|
+
const child = (0, import_node_child_process2.spawn)(process.execPath, [process.argv[1] ?? "", ...argv], {
|
|
38980
|
+
detached: true,
|
|
38981
|
+
stdio: "ignore",
|
|
38982
|
+
env: process.env
|
|
38983
|
+
});
|
|
38984
|
+
child.on("error", () => onSpawnError?.());
|
|
38985
|
+
child.unref();
|
|
38986
|
+
}
|
|
38987
|
+
function failedSkillsSyncPath(baseUrl, agents) {
|
|
38988
|
+
return (0, import_node_path20.join)(
|
|
38989
|
+
sdkCliStateDirPath(baseUrl),
|
|
38990
|
+
`skills-sync-failed-${agents.map(agentLeaseSegment).join("-")}-version`
|
|
38991
|
+
);
|
|
38681
38992
|
}
|
|
38682
38993
|
function hasMarkedSkillsSyncVersion(path, version) {
|
|
38683
38994
|
return Boolean(version) && readMarkedSkillsSyncVersion(path) === version;
|
|
@@ -38699,12 +39010,12 @@ function writeMarkedSkillsSyncVersion(path, version) {
|
|
|
38699
39010
|
return false;
|
|
38700
39011
|
}
|
|
38701
39012
|
}
|
|
38702
|
-
function writeUnavailableSkillsNotice(baseUrl, remoteVersion, skillNames) {
|
|
39013
|
+
function writeUnavailableSkillsNotice(baseUrl, remoteVersion, skillNames, notice = writeSdkSkillsStatusLine) {
|
|
38703
39014
|
const path = unavailableSkillsNoticePath(baseUrl);
|
|
38704
39015
|
if (hasMarkedSkillsSyncVersion(path, remoteVersion)) return;
|
|
38705
39016
|
writeMarkedSkillsSyncVersion(path, remoteVersion);
|
|
38706
39017
|
const manualCommand = `npx ${buildSkillsInstallArgs(baseUrl, skillNames).join(" ")}`;
|
|
38707
|
-
|
|
39018
|
+
notice(
|
|
38708
39019
|
`Deepline agent skills are out of date, but neither \`bunx\` nor \`npx\` is available. Install Node.js/npm or Bun, then run:
|
|
38709
39020
|
${manualCommand}`
|
|
38710
39021
|
);
|
|
@@ -38889,7 +39200,7 @@ function runOneSkillsInstall(install) {
|
|
|
38889
39200
|
});
|
|
38890
39201
|
});
|
|
38891
39202
|
}
|
|
38892
|
-
async function runSkillsInstall(installs, agents) {
|
|
39203
|
+
async function runSkillsInstall(installs, agents, notice = writeSdkSkillsStatusLine) {
|
|
38893
39204
|
const failures = [];
|
|
38894
39205
|
for (const install of installs) {
|
|
38895
39206
|
const result = await runOneSkillsInstall(install);
|
|
@@ -38899,15 +39210,14 @@ async function runSkillsInstall(installs, agents) {
|
|
|
38899
39210
|
const details = failures.map((failure) => failure.detail).filter(Boolean).join("\n");
|
|
38900
39211
|
const attemptedCommands = failures.map((failure) => ` ${failure.manualCommand}`).join("\n");
|
|
38901
39212
|
const retryAgent = agents.at(0);
|
|
38902
|
-
|
|
39213
|
+
notice(
|
|
38903
39214
|
`Deepline agent-skills refresh failed for ${agents.join(", ")}. The Deepline command will continue; this only affects optional local agent instructions, not authentication, data, or billing.
|
|
38904
39215
|
` + (attemptedCommands ? `Attempted installer command${failures.length === 1 ? "" : "s"}:
|
|
38905
39216
|
${attemptedCommands}
|
|
38906
39217
|
` : "") + (details ? `Installer output:
|
|
38907
39218
|
${details}
|
|
38908
39219
|
` : "") + (retryAgent ? `To retry with full installer output: deepline skills --agent ${retryAgent} --json
|
|
38909
|
-
` : "") + `To temporarily suppress automatic skills sync: ${temporarySkillsSyncSkipCommand()}
|
|
38910
|
-
`
|
|
39220
|
+
` : "") + `To temporarily suppress automatic skills sync: ${temporarySkillsSyncSkipCommand()}`
|
|
38911
39221
|
);
|
|
38912
39222
|
return {
|
|
38913
39223
|
installed: false,
|
|
@@ -38982,72 +39292,132 @@ async function syncSdkSkillsIfNeeded(baseUrl, options = {}) {
|
|
|
38982
39292
|
if (usingPluginSkills) {
|
|
38983
39293
|
return;
|
|
38984
39294
|
}
|
|
38985
|
-
const localVersion = readSdkSkillsLocalVersion(baseUrl);
|
|
38986
|
-
const update = options.update === void 0 ? await fetchSkillsUpdate(baseUrl, localVersion) : options.update ? {
|
|
38987
|
-
needsUpdate: options.update.needs_update,
|
|
38988
|
-
remoteVersion: options.update.remote.version
|
|
38989
|
-
} : null;
|
|
38990
|
-
if (!update?.needsUpdate || !update.remoteVersion) {
|
|
38991
|
-
return;
|
|
38992
|
-
}
|
|
38993
39295
|
const agents = resolveAutoSyncSkillAgents();
|
|
38994
|
-
if (
|
|
39296
|
+
if (options.mode === "detached" && agents.length > 0) {
|
|
39297
|
+
flushDeferredSkillsNotices(baseUrl, agents);
|
|
39298
|
+
}
|
|
39299
|
+
const ownsInProgressMarker = options.mode !== "detached" && agents.length > 0 && Boolean(options.claim);
|
|
39300
|
+
const leases = ownsInProgressMarker ? readInProgressSkillsSyncLeases(baseUrl, agents) : null;
|
|
39301
|
+
if (leases && [...leases.values()].some((lease) => lease.owner !== options.claim)) {
|
|
38995
39302
|
return;
|
|
38996
39303
|
}
|
|
39304
|
+
if (leases) recordOwnPidOnInProgressSkillsSync(baseUrl, leases);
|
|
39305
|
+
const claimedVersion = leases ? claimedSkillsVersion(leases) : "";
|
|
39306
|
+
if (options.mode === "detached" && agents.length > 0 && options.update === void 0 && !claimedVersion) {
|
|
39307
|
+
const outcome = claimAndSpawnDetachedSkillsSync(
|
|
39308
|
+
baseUrl,
|
|
39309
|
+
agents,
|
|
39310
|
+
UNRESOLVED_SKILLS_CLAIM_VERSION,
|
|
39311
|
+
options.spawnDetached ?? spawnDetachedSkillsSyncChild
|
|
39312
|
+
);
|
|
39313
|
+
if (outcome !== "unavailable") return;
|
|
39314
|
+
}
|
|
39315
|
+
try {
|
|
39316
|
+
const localVersion = readSdkSkillsLocalVersion(baseUrl);
|
|
39317
|
+
const update = options.update === void 0 ? claimedVersion ? { needsUpdate: true, remoteVersion: claimedVersion } : await fetchSkillsUpdate(baseUrl, localVersion) : options.update ? {
|
|
39318
|
+
needsUpdate: options.update.needs_update,
|
|
39319
|
+
remoteVersion: options.update.remote.version
|
|
39320
|
+
} : null;
|
|
39321
|
+
if (!update?.needsUpdate || !update.remoteVersion) {
|
|
39322
|
+
return;
|
|
39323
|
+
}
|
|
39324
|
+
if (agents.length > 0 && hasFailedSkillsSync(baseUrl, update.remoteVersion, agents)) {
|
|
39325
|
+
return;
|
|
39326
|
+
}
|
|
39327
|
+
if (options.mode === "detached" && agents.length === 0) {
|
|
39328
|
+
writeUnavailableSkillsNotice(
|
|
39329
|
+
baseUrl,
|
|
39330
|
+
update.remoteVersion,
|
|
39331
|
+
buildSdkSkillNames(DEFAULT_SDK_SKILL_NAMES)
|
|
39332
|
+
);
|
|
39333
|
+
return;
|
|
39334
|
+
}
|
|
39335
|
+
if (options.mode === "detached" && agents.length > 0) {
|
|
39336
|
+
const outcome = claimAndSpawnDetachedSkillsSync(
|
|
39337
|
+
baseUrl,
|
|
39338
|
+
agents,
|
|
39339
|
+
update.remoteVersion,
|
|
39340
|
+
options.spawnDetached ?? spawnDetachedSkillsSyncChild
|
|
39341
|
+
);
|
|
39342
|
+
if (outcome === "held") return;
|
|
39343
|
+
if (outcome === "claimed") {
|
|
39344
|
+
writeSdkSkillsStatusLine(
|
|
39345
|
+
"Deepline skills changed; refreshing agent skills in the background."
|
|
39346
|
+
);
|
|
39347
|
+
return;
|
|
39348
|
+
}
|
|
39349
|
+
}
|
|
39350
|
+
await runInlineSkillsSync(
|
|
39351
|
+
baseUrl,
|
|
39352
|
+
update.remoteVersion,
|
|
39353
|
+
agents,
|
|
39354
|
+
options.notices ?? "print"
|
|
39355
|
+
);
|
|
39356
|
+
} finally {
|
|
39357
|
+
if (leases) {
|
|
39358
|
+
releaseInProgressSkillsSync(baseUrl, claimTokensOf(leases));
|
|
39359
|
+
}
|
|
39360
|
+
}
|
|
39361
|
+
}
|
|
39362
|
+
async function runInlineSkillsSync(baseUrl, remoteVersion, agents, notices) {
|
|
39363
|
+
const update = { remoteVersion };
|
|
39364
|
+
const notice = notices === "defer" ? deferSkillsNotice(baseUrl, agents) : writeSdkSkillsStatusLine;
|
|
38997
39365
|
const remoteSkillNames = await fetchV1SkillNames(baseUrl);
|
|
38998
39366
|
const skillNames = buildSdkSkillNames(
|
|
38999
39367
|
remoteSkillNames.length > 0 ? remoteSkillNames : DEFAULT_SDK_SKILL_NAMES
|
|
39000
39368
|
);
|
|
39001
39369
|
if (skillNames.length === 0) return;
|
|
39002
39370
|
if (agents.length === 0) {
|
|
39003
|
-
writeUnavailableSkillsNotice(
|
|
39371
|
+
writeUnavailableSkillsNotice(
|
|
39372
|
+
baseUrl,
|
|
39373
|
+
update.remoteVersion,
|
|
39374
|
+
skillNames,
|
|
39375
|
+
notice
|
|
39376
|
+
);
|
|
39004
39377
|
return;
|
|
39005
39378
|
}
|
|
39006
39379
|
const installs = resolveSkillsInstallCommands(baseUrl, skillNames, agents);
|
|
39007
39380
|
if (installs.length === 0) {
|
|
39008
|
-
writeUnavailableSkillsNotice(
|
|
39381
|
+
writeUnavailableSkillsNotice(
|
|
39382
|
+
baseUrl,
|
|
39383
|
+
update.remoteVersion,
|
|
39384
|
+
skillNames,
|
|
39385
|
+
notice
|
|
39386
|
+
);
|
|
39009
39387
|
return;
|
|
39010
39388
|
}
|
|
39011
|
-
|
|
39012
|
-
if (claim.status === "held") return;
|
|
39013
|
-
try {
|
|
39014
|
-
if (hasFailedSkillsSync(baseUrl, update.remoteVersion, agents) || readSdkSkillsLocalVersion(baseUrl) === update.remoteVersion) {
|
|
39015
|
-
return;
|
|
39016
|
-
}
|
|
39389
|
+
if (notices === "print") {
|
|
39017
39390
|
writeSdkSkillsStatusLine(
|
|
39018
39391
|
"Deepline skills changed; syncing agent skills..."
|
|
39019
39392
|
);
|
|
39020
|
-
const installResult = await runSkillsInstall(installs, agents);
|
|
39021
|
-
if (!installResult.installed) {
|
|
39022
|
-
const markerWritten = markFailedSkillsSync(
|
|
39023
|
-
baseUrl,
|
|
39024
|
-
update.remoteVersion,
|
|
39025
|
-
agents
|
|
39026
|
-
);
|
|
39027
|
-
void maybeReportAutomaticSkillsSyncFailure({
|
|
39028
|
-
baseUrl,
|
|
39029
|
-
remoteSkillsVersion: update.remoteVersion,
|
|
39030
|
-
agents,
|
|
39031
|
-
skillsPackage: SKILLS_NPX_PACKAGE,
|
|
39032
|
-
targetSkillCount: skillNames.length,
|
|
39033
|
-
markerWritten,
|
|
39034
|
-
attempts: installResult.attempts
|
|
39035
|
-
});
|
|
39036
|
-
return;
|
|
39037
|
-
}
|
|
39038
|
-
runLegacySkillsCleanup(agents);
|
|
39039
|
-
writeSdkSkillsLocalVersion(baseUrl, update.remoteVersion, agents);
|
|
39040
|
-
clearUnavailableSkillsNotice(baseUrl);
|
|
39041
|
-
clearFailedSkillsSync(baseUrl, agents);
|
|
39042
|
-
writeSdkSkillsStatusLine("Deepline agent skills are up to date.");
|
|
39043
|
-
} finally {
|
|
39044
|
-
if (claim.status === "claimed") {
|
|
39045
|
-
clearSkillsSyncClaim(baseUrl, agents, claim.token);
|
|
39046
|
-
}
|
|
39047
39393
|
}
|
|
39394
|
+
const installResult = await runSkillsInstall(installs, agents, notice);
|
|
39395
|
+
if (!installResult.installed) {
|
|
39396
|
+
const markerWritten = markFailedSkillsSync(
|
|
39397
|
+
baseUrl,
|
|
39398
|
+
update.remoteVersion,
|
|
39399
|
+
agents
|
|
39400
|
+
);
|
|
39401
|
+
void maybeReportAutomaticSkillsSyncFailure({
|
|
39402
|
+
baseUrl,
|
|
39403
|
+
remoteSkillsVersion: update.remoteVersion,
|
|
39404
|
+
agents,
|
|
39405
|
+
skillsPackage: SKILLS_NPX_PACKAGE,
|
|
39406
|
+
targetSkillCount: skillNames.length,
|
|
39407
|
+
markerWritten,
|
|
39408
|
+
attempts: installResult.attempts
|
|
39409
|
+
});
|
|
39410
|
+
return;
|
|
39411
|
+
}
|
|
39412
|
+
runLegacySkillsCleanup(agents);
|
|
39413
|
+
writeSdkSkillsLocalVersion(baseUrl, update.remoteVersion, agents);
|
|
39414
|
+
clearUnavailableSkillsNotice(baseUrl);
|
|
39415
|
+
clearFailedSkillsSync(baseUrl, agents);
|
|
39416
|
+
notice("Deepline agent skills are up to date.");
|
|
39048
39417
|
}
|
|
39049
39418
|
|
|
39050
39419
|
// src/cli/commands/skills.ts
|
|
39420
|
+
var SKILLS_INSTALL_LEASE_WAIT_MS = 9e4;
|
|
39051
39421
|
var SKILLS_PROCESS_TIMEOUT_MS = 45e3;
|
|
39052
39422
|
var RUNTIME_TO_SKILLS_AGENT = {
|
|
39053
39423
|
antigravity: "antigravity",
|
|
@@ -39304,6 +39674,45 @@ async function runSkillsCommand(options, dependencies = {}) {
|
|
|
39304
39674
|
)
|
|
39305
39675
|
]);
|
|
39306
39676
|
}
|
|
39677
|
+
const lease = scope === "global" ? await acquireSkillsInstallLease(baseUrl, agents, plan.version, {
|
|
39678
|
+
waitMs: dependencies.installLeaseWaitMs ?? SKILLS_INSTALL_LEASE_WAIT_MS,
|
|
39679
|
+
onWait: () => process.stderr.write(
|
|
39680
|
+
"Waiting for a background Deepline skills refresh to finish...\n"
|
|
39681
|
+
)
|
|
39682
|
+
}) : { release: () => {
|
|
39683
|
+
} };
|
|
39684
|
+
if (!lease) {
|
|
39685
|
+
printCommandEnvelope(
|
|
39686
|
+
{
|
|
39687
|
+
ok: false,
|
|
39688
|
+
status: "failed",
|
|
39689
|
+
code: "SKILLS_SYNC_IN_PROGRESS",
|
|
39690
|
+
exitCode: 7,
|
|
39691
|
+
scope,
|
|
39692
|
+
agents,
|
|
39693
|
+
message: "A background Deepline skills refresh is still running for these agents.",
|
|
39694
|
+
next: `Retry in a moment: deepline skills --scope ${scope} --json. If no refresh is running, remove ${skillsInstallLeasePath(baseUrl, agents)}`
|
|
39695
|
+
},
|
|
39696
|
+
{ json: options.json }
|
|
39697
|
+
);
|
|
39698
|
+
return 7;
|
|
39699
|
+
}
|
|
39700
|
+
try {
|
|
39701
|
+
return await runSkillsInstallWithLease({
|
|
39702
|
+
options,
|
|
39703
|
+
dependencies,
|
|
39704
|
+
baseUrl,
|
|
39705
|
+
scope,
|
|
39706
|
+
root,
|
|
39707
|
+
agents,
|
|
39708
|
+
plan
|
|
39709
|
+
});
|
|
39710
|
+
} finally {
|
|
39711
|
+
lease.release();
|
|
39712
|
+
}
|
|
39713
|
+
}
|
|
39714
|
+
async function runSkillsInstallWithLease(input2) {
|
|
39715
|
+
const { options, dependencies, baseUrl, scope, root, agents, plan } = input2;
|
|
39307
39716
|
process.stderr.write(
|
|
39308
39717
|
`Replacing Deepline skills for ${agents.join(", ")} (${scope})...
|
|
39309
39718
|
`
|
|
@@ -39416,6 +39825,31 @@ Examples:
|
|
|
39416
39825
|
).action(async (options) => {
|
|
39417
39826
|
process.exitCode = await runSkillsCommand(options);
|
|
39418
39827
|
});
|
|
39828
|
+
program.command(SKILLS_AUTO_SYNC_COMMAND, { hidden: true }).description("Refresh Deepline agent skills in the background.").option(
|
|
39829
|
+
"--claim <token>",
|
|
39830
|
+
"Owner token of the leases this child was started for."
|
|
39831
|
+
).action(async (options) => {
|
|
39832
|
+
const claim = options.claim?.trim();
|
|
39833
|
+
if (!claim) {
|
|
39834
|
+
printCommandEnvelope(
|
|
39835
|
+
{
|
|
39836
|
+
ok: false,
|
|
39837
|
+
status: "failed",
|
|
39838
|
+
code: "SKILLS_AUTO_SYNC_CLAIM_REQUIRED",
|
|
39839
|
+
exitCode: 2,
|
|
39840
|
+
message: "skills-auto-sync is started by ordinary deepline commands and requires the lease token they pass; run `deepline skills` to install skills yourself."
|
|
39841
|
+
},
|
|
39842
|
+
{ json: true }
|
|
39843
|
+
);
|
|
39844
|
+
process.exitCode = 2;
|
|
39845
|
+
return;
|
|
39846
|
+
}
|
|
39847
|
+
await syncSdkSkillsIfNeeded(autoDetectBaseUrl().replace(/\/$/, ""), {
|
|
39848
|
+
mode: "inline",
|
|
39849
|
+
notices: "defer",
|
|
39850
|
+
claim
|
|
39851
|
+
});
|
|
39852
|
+
});
|
|
39419
39853
|
}
|
|
39420
39854
|
|
|
39421
39855
|
// src/cli/commands/setup.ts
|
|
@@ -43439,14 +43873,15 @@ Examples:
|
|
|
43439
43873
|
deepline tools describe hunter_email_verifier --json
|
|
43440
43874
|
deepline tools describe deeplineagent --model openai/gpt-5.5 --json
|
|
43441
43875
|
deepline tools describe ai_inference --estimate-payload @payload.json --json
|
|
43876
|
+
deepline tools describe ai_evaluate --estimate-payload @payload.json --json
|
|
43442
43877
|
deepline tools execute hunter_email_verifier --input '{"email":"a@b.com"}'
|
|
43443
43878
|
`
|
|
43444
43879
|
).option("--json", "Emit JSON output. Also automatic when stdout is piped").option(
|
|
43445
43880
|
"--model <model>",
|
|
43446
|
-
"For
|
|
43881
|
+
"For language tools, include AI Gateway metadata; for ai_evaluate, set the quote payload model"
|
|
43447
43882
|
).option(
|
|
43448
43883
|
"--estimate-payload <payload>",
|
|
43449
|
-
"Quote an ai_inference or deeplineagent JSON payload (inline or @file)"
|
|
43884
|
+
"Quote an ai_evaluate, ai_inference, or deeplineagent JSON payload (inline or @file)"
|
|
43450
43885
|
).option("--pricing-only", "Only print pricing and billing semantics").option("--schema-only", "Only print input schema fields").option(
|
|
43451
43886
|
"--examples-only",
|
|
43452
43887
|
"Only print runnable examples and sample payloads"
|
|
@@ -43548,9 +43983,9 @@ async function getTool(toolId, options = {}) {
|
|
|
43548
43983
|
}
|
|
43549
43984
|
let inferenceQuote = null;
|
|
43550
43985
|
if (options.estimatePayload) {
|
|
43551
|
-
if (toolId !== "deeplineagent" && toolId !== "ai_inference") {
|
|
43986
|
+
if (toolId !== "deeplineagent" && toolId !== "ai_inference" && toolId !== "ai_evaluate") {
|
|
43552
43987
|
console.error(
|
|
43553
|
-
"--estimate-payload is only supported for deeplineagent and ai_inference."
|
|
43988
|
+
"--estimate-payload is only supported for ai_evaluate, deeplineagent, and ai_inference."
|
|
43554
43989
|
);
|
|
43555
43990
|
return 2;
|
|
43556
43991
|
}
|
|
@@ -43564,7 +43999,7 @@ async function getTool(toolId, options = {}) {
|
|
|
43564
43999
|
inferenceQuote = await client2.quoteInferenceTool(toolId, estimatePayload);
|
|
43565
44000
|
}
|
|
43566
44001
|
const modelDescription = options.model && (toolId === "deeplineagent" || toolId === "ai_inference") ? await client2.describeModel(options.model) : null;
|
|
43567
|
-
if (options.model && !modelDescription) {
|
|
44002
|
+
if (options.model && !modelDescription && toolId !== "ai_evaluate") {
|
|
43568
44003
|
console.error(
|
|
43569
44004
|
"--model is only supported for deeplineagent and ai_inference."
|
|
43570
44005
|
);
|
|
@@ -46142,7 +46577,7 @@ Exit codes:
|
|
|
46142
46577
|
`
|
|
46143
46578
|
);
|
|
46144
46579
|
program.hook("preAction", async (_thisCommand, actionCommand) => {
|
|
46145
|
-
if (actionCommand.name() === "version" || actionCommand.name() === "update" || actionCommand.name() === "setup" || actionCommand.name() === "skills" || actionCommand.name() === "doctor" || isAutoUpdateSettingsInvocation() || isDeprecatedCommandInvocation()) {
|
|
46580
|
+
if (actionCommand.name() === "version" || actionCommand.name() === "update" || actionCommand.name() === "setup" || actionCommand.name() === "skills" || actionCommand.name() === SKILLS_AUTO_SYNC_COMMAND || actionCommand.name() === "doctor" || isAutoUpdateSettingsInvocation() || isDeprecatedCommandInvocation()) {
|
|
46146
46581
|
return;
|
|
46147
46582
|
}
|
|
46148
46583
|
const compatibilityCommand = compatibilityCommandPath(actionCommand) || actionCommand.name();
|
|
@@ -46150,18 +46585,42 @@ Exit codes:
|
|
|
46150
46585
|
progress?.phase("checking sdk compatibility");
|
|
46151
46586
|
}
|
|
46152
46587
|
const baseUrl = autoDetectBaseUrl().replace(/\/$/, "");
|
|
46588
|
+
flushDeferredSkillsSyncNotices(baseUrl);
|
|
46153
46589
|
const shouldDeferSkillsSync = shouldDeferSkillsSyncForCommand();
|
|
46154
46590
|
const skillsVersion = shouldDeferSkillsSync ? void 0 : readSdkSkillsLocalVersion(baseUrl);
|
|
46155
|
-
const
|
|
46591
|
+
const trusted = readTrustedCleanCompatibility(
|
|
46592
|
+
baseUrl,
|
|
46593
|
+
compatibilityCommand,
|
|
46594
|
+
skillsVersion
|
|
46595
|
+
);
|
|
46596
|
+
const fastDeadline = trusted === null && readFreshCleanCompatibility(
|
|
46597
|
+
baseUrl,
|
|
46598
|
+
compatibilityCommand,
|
|
46599
|
+
skillsVersion
|
|
46600
|
+
) !== null;
|
|
46601
|
+
if (trusted) {
|
|
46602
|
+
recordCliTrace({
|
|
46603
|
+
phase: "cli.sdk_compatibility",
|
|
46604
|
+
ms: 0,
|
|
46605
|
+
ok: true,
|
|
46606
|
+
baseUrl,
|
|
46607
|
+
command: compatibilityCommand,
|
|
46608
|
+
skillsVersion: skillsVersion ?? null,
|
|
46609
|
+
source: "trusted_cache"
|
|
46610
|
+
});
|
|
46611
|
+
}
|
|
46612
|
+
const compatibility = trusted ? { response: trusted, error: null } : await traceCliSpan(
|
|
46156
46613
|
"cli.sdk_compatibility",
|
|
46157
46614
|
{
|
|
46158
46615
|
baseUrl,
|
|
46159
46616
|
command: compatibilityCommand,
|
|
46160
|
-
skillsVersion: skillsVersion ?? null
|
|
46617
|
+
skillsVersion: skillsVersion ?? null,
|
|
46618
|
+
fastDeadline
|
|
46161
46619
|
},
|
|
46162
46620
|
() => checkSdkCompatibility(baseUrl, {
|
|
46163
46621
|
command: compatibilityCommand,
|
|
46164
|
-
skillsVersion
|
|
46622
|
+
skillsVersion,
|
|
46623
|
+
...fastDeadline ? { timeoutMs: SDK_COMPATIBILITY_FAST_DEADLINE_MS } : {}
|
|
46165
46624
|
})
|
|
46166
46625
|
);
|
|
46167
46626
|
if (compatibility.error) {
|
|
@@ -46184,7 +46643,8 @@ Exit codes:
|
|
|
46184
46643
|
"cli.sdk_skills_sync",
|
|
46185
46644
|
{ baseUrl },
|
|
46186
46645
|
() => syncSdkSkillsIfNeeded(baseUrl, {
|
|
46187
|
-
update: skillsUpdate
|
|
46646
|
+
update: skillsUpdate,
|
|
46647
|
+
mode: "detached"
|
|
46188
46648
|
})
|
|
46189
46649
|
);
|
|
46190
46650
|
}
|