@botiverse/raft-daemon 0.68.0 → 0.69.0-play.20260704183824
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.
|
@@ -3288,6 +3288,7 @@ var AGENT_ACTIVITY_DETAIL_KINDS = [
|
|
|
3288
3288
|
"compaction_stale",
|
|
3289
3289
|
"reviewing_changes",
|
|
3290
3290
|
"review_finished",
|
|
3291
|
+
"review_stale",
|
|
3291
3292
|
"runtime_reconnecting",
|
|
3292
3293
|
"runtime_error",
|
|
3293
3294
|
"runtime_crashed",
|
|
@@ -4708,6 +4709,19 @@ function listLegacySlockStatePaths(slockHome = resolveSlockHome(), homeDir = os.
|
|
|
4708
4709
|
return candidates.filter((candidate) => existsSync(candidate.path));
|
|
4709
4710
|
}
|
|
4710
4711
|
|
|
4712
|
+
// src/authEnv.ts
|
|
4713
|
+
var DAEMON_API_KEY_ENV = "SLOCK_MACHINE_API_KEY";
|
|
4714
|
+
var SLOCK_AGENT_TOKEN_ENV = "SLOCK_AGENT_TOKEN";
|
|
4715
|
+
function scrubDaemonAuthEnv(env) {
|
|
4716
|
+
delete env[DAEMON_API_KEY_ENV];
|
|
4717
|
+
return env;
|
|
4718
|
+
}
|
|
4719
|
+
function scrubDaemonChildEnv(env) {
|
|
4720
|
+
delete env[DAEMON_API_KEY_ENV];
|
|
4721
|
+
delete env[SLOCK_AGENT_TOKEN_ENV];
|
|
4722
|
+
return env;
|
|
4723
|
+
}
|
|
4724
|
+
|
|
4711
4725
|
// src/agentCredentialProxy.ts
|
|
4712
4726
|
import { randomBytes } from "crypto";
|
|
4713
4727
|
import http from "http";
|
|
@@ -6282,7 +6296,9 @@ var LOOPBACK_NO_PROXY = "127.0.0.1,localhost";
|
|
|
6282
6296
|
var CLI_TRANSPORT_TRACE_DIR_ENV = "SLOCK_CLI_TRANSPORT_TRACE_DIR";
|
|
6283
6297
|
var safePathPart = (value) => value.replace(/[^a-zA-Z0-9_.-]/g, "_");
|
|
6284
6298
|
var RAW_CREDENTIAL_ENV_DENYLIST = [
|
|
6285
|
-
"
|
|
6299
|
+
"SLOCK_AGENT_TOKEN",
|
|
6300
|
+
"SLOCK_AGENT_CREDENTIAL_KEY",
|
|
6301
|
+
"SLOCK_AGENT_CREDENTIAL_KEY_FILE"
|
|
6286
6302
|
];
|
|
6287
6303
|
var WORKSPACE_CLI_TRANSPORT_FILENAMES = [
|
|
6288
6304
|
"agent-token",
|
|
@@ -6637,7 +6653,7 @@ set "SLOCK_AGENT_ACTIVE_CAPABILITIES=${DEFAULT_ACTIVE_CAPABILITIES}"\r
|
|
|
6637
6653
|
SLOCK_SERVER_URL: ctx.config.serverUrl,
|
|
6638
6654
|
PATH: `${slockDir}${path2.delimiter}${process.env.PATH ?? ""}`
|
|
6639
6655
|
};
|
|
6640
|
-
|
|
6656
|
+
scrubDaemonChildEnv(spawnEnv);
|
|
6641
6657
|
for (const key of RAW_CREDENTIAL_ENV_DENYLIST) {
|
|
6642
6658
|
delete spawnEnv[key];
|
|
6643
6659
|
}
|
|
@@ -7205,7 +7221,7 @@ function requiresWindowsShell(command, platform = process.platform) {
|
|
|
7205
7221
|
}
|
|
7206
7222
|
function resolveCommandOnPath(command, deps = {}) {
|
|
7207
7223
|
const platform = deps.platform ?? process.platform;
|
|
7208
|
-
const env = withWindowsUserEnvironment(deps.env ?? process.env, deps);
|
|
7224
|
+
const env = scrubDaemonChildEnv({ ...withWindowsUserEnvironment(deps.env ?? process.env, deps) });
|
|
7209
7225
|
const execFileSyncFn = deps.execFileSyncFn ?? execFileSync;
|
|
7210
7226
|
const existsSyncFn = deps.existsSyncFn ?? existsSync3;
|
|
7211
7227
|
if (platform === "win32") {
|
|
@@ -7231,7 +7247,7 @@ function firstExistingPath(candidates, deps = {}) {
|
|
|
7231
7247
|
return null;
|
|
7232
7248
|
}
|
|
7233
7249
|
function readCommandVersion(command, args = [], deps = {}) {
|
|
7234
|
-
const env = withWindowsUserEnvironment(deps.env ?? process.env, deps);
|
|
7250
|
+
const env = scrubDaemonChildEnv({ ...withWindowsUserEnvironment(deps.env ?? process.env, deps) });
|
|
7235
7251
|
const execFileSyncFn = deps.execFileSyncFn ?? execFileSync;
|
|
7236
7252
|
try {
|
|
7237
7253
|
const output = normalizeExecOutput(execFileSyncFn(command, [...args, "--version"], {
|
|
@@ -9315,11 +9331,11 @@ function detectCursorModels(runCommand = runCursorModelsCommand) {
|
|
|
9315
9331
|
return parseCursorModelsOutput(String(result.stdout || ""));
|
|
9316
9332
|
}
|
|
9317
9333
|
function buildCursorModelProbeEnv(deps = {}) {
|
|
9318
|
-
return withWindowsUserEnvironment({
|
|
9334
|
+
return scrubDaemonChildEnv(withWindowsUserEnvironment({
|
|
9319
9335
|
...deps.env ?? process.env,
|
|
9320
9336
|
FORCE_COLOR: "0",
|
|
9321
9337
|
NO_COLOR: "1"
|
|
9322
|
-
}, deps);
|
|
9338
|
+
}, deps));
|
|
9323
9339
|
}
|
|
9324
9340
|
function runCursorModelsCommand() {
|
|
9325
9341
|
return spawnSync("cursor-agent", ["models"], {
|
|
@@ -9375,7 +9391,7 @@ function resolveGeminiSpawn(commandArgs, deps = {}) {
|
|
|
9375
9391
|
}
|
|
9376
9392
|
const execFileSyncFn = deps.execFileSyncFn ?? execFileSync3;
|
|
9377
9393
|
const existsSyncFn = deps.existsSyncFn ?? existsSync5;
|
|
9378
|
-
const env = deps.env ?? process.env;
|
|
9394
|
+
const env = scrubDaemonChildEnv({ ...deps.env ?? process.env });
|
|
9379
9395
|
const winPath = path8.win32;
|
|
9380
9396
|
let geminiEntry = null;
|
|
9381
9397
|
try {
|
|
@@ -9512,12 +9528,15 @@ var GeminiDriver = class {
|
|
|
9512
9528
|
// src/drivers/kimi.ts
|
|
9513
9529
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
9514
9530
|
import { spawn as spawn7 } from "child_process";
|
|
9515
|
-
import { existsSync as existsSync6, readFileSync as readFileSync3, writeFileSync as writeFileSync3 } from "fs";
|
|
9531
|
+
import { chmodSync, existsSync as existsSync6, readFileSync as readFileSync3, writeFileSync as writeFileSync3 } from "fs";
|
|
9516
9532
|
import os4 from "os";
|
|
9517
9533
|
import path9 from "path";
|
|
9518
9534
|
var KIMI_WIRE_PROTOCOL_VERSION = "1.3";
|
|
9519
9535
|
var KIMI_SYSTEM_PROMPT_FILE = ".slock-kimi-system.md";
|
|
9520
9536
|
var KIMI_AGENT_FILE = ".slock-kimi-agent.yaml";
|
|
9537
|
+
var KIMI_GENERATED_CONFIG_FILE = ".slock-kimi-config.toml";
|
|
9538
|
+
var SLOCK_KIMI_CONFIG_CONTENT_ENV = "SLOCK_KIMI_CONFIG_CONTENT";
|
|
9539
|
+
var SLOCK_KIMI_CONFIG_FILE_ENV = "SLOCK_KIMI_CONFIG_FILE";
|
|
9521
9540
|
function parseToolArguments(raw) {
|
|
9522
9541
|
if (typeof raw !== "string") return raw;
|
|
9523
9542
|
try {
|
|
@@ -9526,6 +9545,73 @@ function parseToolArguments(raw) {
|
|
|
9526
9545
|
return raw;
|
|
9527
9546
|
}
|
|
9528
9547
|
}
|
|
9548
|
+
function readKimiConfigSource(home = os4.homedir(), env = process.env) {
|
|
9549
|
+
const inlineConfig = env[SLOCK_KIMI_CONFIG_CONTENT_ENV];
|
|
9550
|
+
if (inlineConfig && inlineConfig.trim()) {
|
|
9551
|
+
return {
|
|
9552
|
+
raw: inlineConfig,
|
|
9553
|
+
explicitPath: null,
|
|
9554
|
+
sourcePath: SLOCK_KIMI_CONFIG_CONTENT_ENV
|
|
9555
|
+
};
|
|
9556
|
+
}
|
|
9557
|
+
const explicitPath = env[SLOCK_KIMI_CONFIG_FILE_ENV];
|
|
9558
|
+
const configPath = explicitPath && explicitPath.trim() ? explicitPath : path9.join(home, ".kimi", "config.toml");
|
|
9559
|
+
try {
|
|
9560
|
+
return {
|
|
9561
|
+
raw: readFileSync3(configPath, "utf8"),
|
|
9562
|
+
explicitPath: explicitPath && explicitPath.trim() ? explicitPath : null,
|
|
9563
|
+
sourcePath: configPath
|
|
9564
|
+
};
|
|
9565
|
+
} catch {
|
|
9566
|
+
return {
|
|
9567
|
+
raw: null,
|
|
9568
|
+
explicitPath: explicitPath && explicitPath.trim() ? explicitPath : null,
|
|
9569
|
+
sourcePath: configPath
|
|
9570
|
+
};
|
|
9571
|
+
}
|
|
9572
|
+
}
|
|
9573
|
+
function buildKimiSpawnEnv(env = process.env) {
|
|
9574
|
+
const spawnEnv = { ...env, FORCE_COLOR: "0", NO_COLOR: "1" };
|
|
9575
|
+
delete spawnEnv[SLOCK_KIMI_CONFIG_CONTENT_ENV];
|
|
9576
|
+
delete spawnEnv[SLOCK_KIMI_CONFIG_FILE_ENV];
|
|
9577
|
+
return scrubDaemonChildEnv(spawnEnv);
|
|
9578
|
+
}
|
|
9579
|
+
function buildKimiEffectiveEnv(ctx, overrideEnv) {
|
|
9580
|
+
return {
|
|
9581
|
+
...process.env,
|
|
9582
|
+
...ctx.config.envVars || {},
|
|
9583
|
+
...overrideEnv || {}
|
|
9584
|
+
};
|
|
9585
|
+
}
|
|
9586
|
+
function buildKimiLaunchOptions(ctx, opts = {}) {
|
|
9587
|
+
const env = buildKimiEffectiveEnv(ctx, opts.env);
|
|
9588
|
+
const source = readKimiConfigSource(opts.home ?? os4.homedir(), env);
|
|
9589
|
+
const args = [];
|
|
9590
|
+
let configFilePath = null;
|
|
9591
|
+
let configContent = null;
|
|
9592
|
+
if (source.explicitPath) {
|
|
9593
|
+
configFilePath = source.explicitPath;
|
|
9594
|
+
} else if (source.raw !== null && source.sourcePath === SLOCK_KIMI_CONFIG_CONTENT_ENV) {
|
|
9595
|
+
configFilePath = path9.join(ctx.workingDirectory, KIMI_GENERATED_CONFIG_FILE);
|
|
9596
|
+
configContent = source.raw;
|
|
9597
|
+
if (opts.writeGeneratedConfig !== false) {
|
|
9598
|
+
writeFileSync3(configFilePath, source.raw, { encoding: "utf8", mode: 384 });
|
|
9599
|
+
chmodSync(configFilePath, 384);
|
|
9600
|
+
}
|
|
9601
|
+
}
|
|
9602
|
+
if (configFilePath) {
|
|
9603
|
+
args.push("--config-file", configFilePath);
|
|
9604
|
+
}
|
|
9605
|
+
if (ctx.config.model && ctx.config.model !== "default") {
|
|
9606
|
+
args.push("--model", ctx.config.model);
|
|
9607
|
+
}
|
|
9608
|
+
return {
|
|
9609
|
+
args,
|
|
9610
|
+
env: buildKimiSpawnEnv(env),
|
|
9611
|
+
configFilePath,
|
|
9612
|
+
configContent
|
|
9613
|
+
};
|
|
9614
|
+
}
|
|
9529
9615
|
function resolveKimiSpawn(commandArgs, deps = {}) {
|
|
9530
9616
|
return {
|
|
9531
9617
|
command: resolveCommandOnPath("kimi", deps) ?? "kimi",
|
|
@@ -9549,7 +9635,25 @@ var KimiDriver = class {
|
|
|
9549
9635
|
};
|
|
9550
9636
|
model = {
|
|
9551
9637
|
detectedModelsVerifiedAs: "launchable",
|
|
9552
|
-
toLaunchSpec: (modelId) =>
|
|
9638
|
+
toLaunchSpec: (modelId, ctx, opts) => {
|
|
9639
|
+
if (!ctx) return { args: ["--model", modelId] };
|
|
9640
|
+
const launchCtx = {
|
|
9641
|
+
...ctx,
|
|
9642
|
+
config: {
|
|
9643
|
+
...ctx.config,
|
|
9644
|
+
model: modelId
|
|
9645
|
+
}
|
|
9646
|
+
};
|
|
9647
|
+
const launch = buildKimiLaunchOptions(launchCtx, {
|
|
9648
|
+
home: opts?.home,
|
|
9649
|
+
writeGeneratedConfig: false
|
|
9650
|
+
});
|
|
9651
|
+
return {
|
|
9652
|
+
args: launch.args,
|
|
9653
|
+
env: launch.env,
|
|
9654
|
+
configFiles: launch.configFilePath ? [launch.configFilePath] : void 0
|
|
9655
|
+
};
|
|
9656
|
+
}
|
|
9553
9657
|
};
|
|
9554
9658
|
supportsStdinNotification = true;
|
|
9555
9659
|
busyDeliveryMode = "direct";
|
|
@@ -9573,21 +9677,23 @@ var KimiDriver = class {
|
|
|
9573
9677
|
` system_prompt_path: ./${KIMI_SYSTEM_PROMPT_FILE}`,
|
|
9574
9678
|
""
|
|
9575
9679
|
].join("\n"), "utf8");
|
|
9680
|
+
const launch = buildKimiLaunchOptions(ctx);
|
|
9576
9681
|
const args = [
|
|
9577
9682
|
"--wire",
|
|
9578
9683
|
"--yolo",
|
|
9579
9684
|
"--agent-file",
|
|
9580
9685
|
agentFilePath,
|
|
9581
9686
|
"--session",
|
|
9582
|
-
this.sessionId
|
|
9687
|
+
this.sessionId,
|
|
9688
|
+
...launch.args
|
|
9583
9689
|
];
|
|
9584
9690
|
const launchRuntimeFields = runtimeConfigToLaunchFields(hydrateRuntimeConfig(ctx.config));
|
|
9585
9691
|
if (launchRuntimeFields.model && launchRuntimeFields.model !== "default") {
|
|
9586
9692
|
args.push("--model", launchRuntimeFields.model);
|
|
9587
9693
|
}
|
|
9588
9694
|
const spawnEnv = (await prepareCliTransport(ctx, { NO_COLOR: "1" })).spawnEnv;
|
|
9589
|
-
const
|
|
9590
|
-
const proc = spawn7(
|
|
9695
|
+
const spawnTarget = resolveKimiSpawn(args);
|
|
9696
|
+
const proc = spawn7(spawnTarget.command, spawnTarget.args, {
|
|
9591
9697
|
cwd: ctx.workingDirectory,
|
|
9592
9698
|
stdio: ["pipe", "pipe", "pipe"],
|
|
9593
9699
|
env: spawnEnv,
|
|
@@ -9595,7 +9701,7 @@ var KimiDriver = class {
|
|
|
9595
9701
|
// and has an 8191-character command-line limit. Kimi's official
|
|
9596
9702
|
// installer/uv entrypoint is an executable, so launch it directly and
|
|
9597
9703
|
// keep prompts on stdin / files instead of routing through cmd.exe.
|
|
9598
|
-
shell:
|
|
9704
|
+
shell: spawnTarget.shell
|
|
9599
9705
|
});
|
|
9600
9706
|
proc.stdin?.write(JSON.stringify({
|
|
9601
9707
|
jsonrpc: "2.0",
|
|
@@ -9708,14 +9814,9 @@ var KimiDriver = class {
|
|
|
9708
9814
|
return detectKimiModels();
|
|
9709
9815
|
}
|
|
9710
9816
|
};
|
|
9711
|
-
function detectKimiModels(home = os4.homedir()) {
|
|
9712
|
-
const
|
|
9713
|
-
|
|
9714
|
-
try {
|
|
9715
|
-
raw = readFileSync3(configPath, "utf8");
|
|
9716
|
-
} catch {
|
|
9717
|
-
return null;
|
|
9718
|
-
}
|
|
9817
|
+
function detectKimiModels(home = os4.homedir(), opts = {}) {
|
|
9818
|
+
const raw = readKimiConfigSource(home, opts.env).raw;
|
|
9819
|
+
if (raw === null) return null;
|
|
9719
9820
|
const models = [];
|
|
9720
9821
|
const sectionRe = /^\s*\[models(?:\.([^\]]+)|"\.[^"]+"|\."[^"]+")\s*\]\s*$/gm;
|
|
9721
9822
|
const lineRe = /^\s*\[models\.(.+?)\s*\]\s*$/gm;
|
|
@@ -10381,7 +10482,7 @@ function runOpenCodeModelsCommand(home, deps = {}) {
|
|
|
10381
10482
|
const platform = deps.platform ?? process.platform;
|
|
10382
10483
|
const spawnSyncFn = deps.spawnSyncFn ?? spawnSync2;
|
|
10383
10484
|
const result = spawnSyncFn("opencode", ["models"], {
|
|
10384
|
-
env: { ...process.env, HOME: home, FORCE_COLOR: "0", NO_COLOR: "1" },
|
|
10485
|
+
env: scrubDaemonChildEnv({ ...process.env, HOME: home, FORCE_COLOR: "0", NO_COLOR: "1" }),
|
|
10385
10486
|
encoding: "utf8",
|
|
10386
10487
|
timeout: 5e3,
|
|
10387
10488
|
shell: platform === "win32"
|
|
@@ -13560,11 +13661,12 @@ var RUNTIME_ERROR_DELIVERY_BACKOFF_MAX_MS = 5 * 6e4;
|
|
|
13560
13661
|
var RUNTIME_ERROR_FINGERPRINT_FENCE_THRESHOLD = 3;
|
|
13561
13662
|
var SPAWN_FAIL_BACKOFF_BASE_MS = 1e3;
|
|
13562
13663
|
var SPAWN_FAIL_BACKOFF_MAX_MS = 3e4;
|
|
13563
|
-
var SPAWN_FAIL_BACKOFF_THRESHOLD =
|
|
13664
|
+
var SPAWN_FAIL_BACKOFF_THRESHOLD = 0;
|
|
13564
13665
|
var RUNNER_CREDENTIAL_MINT_BACKOFF_BASE_MS = 6e4;
|
|
13565
13666
|
var RUNNER_CREDENTIAL_MINT_BACKOFF_MAX_MS = 10 * 6e4;
|
|
13566
13667
|
var RUNNER_CREDENTIAL_MINT_BACKOFF_THRESHOLD = 0;
|
|
13567
13668
|
var COMPACTION_STALE_MS = 5 * 6e4;
|
|
13669
|
+
var REVIEW_STALE_MS = 10 * 6e4;
|
|
13568
13670
|
var RUNTIME_PROGRESS_STALE_MS = 15 * 6e4;
|
|
13569
13671
|
var DEFAULT_RUNTIME_START_TIMEOUT_MS = 2 * 6e4;
|
|
13570
13672
|
var DEFAULT_STALLED_RECOVERY_SIGTERM_TIMEOUT_MS = 1e4;
|
|
@@ -14653,10 +14755,10 @@ var AgentProcessManager = class _AgentProcessManager {
|
|
|
14653
14755
|
}
|
|
14654
14756
|
// ----- SPAWN-FAIL BACKOFF (per-agent) ----------------------------------
|
|
14655
14757
|
// Anchored at auto_restart_from_idle (apm:3596) + runtime_profile_auto_restart (apm:4137).
|
|
14656
|
-
//
|
|
14657
|
-
//
|
|
14658
|
-
// inner credential-mint loop exhausted
|
|
14659
|
-
//
|
|
14758
|
+
// One outer spawn failure enters cooldown immediately so repeated wakes cannot burn one
|
|
14759
|
+
// full spawn attempt per delivery. Runner credential mint failures keep a longer cooldown
|
|
14760
|
+
// because one outer failure already means the inner credential-mint loop exhausted
|
|
14761
|
+
// RUNNER_CREDENTIAL_MINT_MAX_ATTEMPTS.
|
|
14660
14762
|
// Successful spawn resets state. State lives outside AgentProcess because spawn fails BEFORE
|
|
14661
14763
|
// ap exists and the rate-window must persist across stop/respawn (else stop/start churn
|
|
14662
14764
|
// bypasses the cap — CC1 lifecycle pattern). Never advances any consume cursor or model-seen
|
|
@@ -14809,14 +14911,22 @@ var AgentProcessManager = class _AgentProcessManager {
|
|
|
14809
14911
|
this.sendStdinNotification(agentId);
|
|
14810
14912
|
}, delayMs);
|
|
14811
14913
|
}
|
|
14812
|
-
|
|
14914
|
+
scheduleIdleInboxDeliveryRetry(agentId, ap, notificationCount, source, traceName) {
|
|
14915
|
+
if (notificationCount <= 0 || !ap.driver.supportsStdinNotification || !ap.sessionId) return false;
|
|
14916
|
+
ap.notifications.add(notificationCount);
|
|
14917
|
+
ap.notifications.clearTimer();
|
|
14918
|
+
return ap.notifications.schedule(() => {
|
|
14919
|
+
this.flushIdleInboxDeliveryRetry(agentId, source, traceName);
|
|
14920
|
+
}, this.stdinNotificationRetryMs);
|
|
14921
|
+
}
|
|
14922
|
+
flushIdleInboxDeliveryRetry(agentId, source, traceName) {
|
|
14813
14923
|
const ap = this.agents.get(agentId);
|
|
14814
14924
|
if (!ap) return false;
|
|
14815
14925
|
const count = ap.notifications.takePendingAndClearTimer();
|
|
14816
14926
|
if (count === 0) return false;
|
|
14817
14927
|
if (!ap.driver.supportsStdinNotification || !ap.sessionId || ap.inbox.length === 0) {
|
|
14818
14928
|
ap.notifications.add(count);
|
|
14819
|
-
this.recordDaemonTrace(
|
|
14929
|
+
this.recordDaemonTrace(traceName, {
|
|
14820
14930
|
agentId,
|
|
14821
14931
|
runtime: ap.config.runtime,
|
|
14822
14932
|
model: ap.config.model,
|
|
@@ -14837,7 +14947,7 @@ var AgentProcessManager = class _AgentProcessManager {
|
|
|
14837
14947
|
ap.notifications.pruneContributedToPending(ap.inbox, ap.sessionId);
|
|
14838
14948
|
const messages = ap.notifications.filterUncontributedMessages(ap.inbox, ap.sessionId);
|
|
14839
14949
|
if (messages.length === 0) {
|
|
14840
|
-
this.recordDaemonTrace(
|
|
14950
|
+
this.recordDaemonTrace(traceName, {
|
|
14841
14951
|
agentId,
|
|
14842
14952
|
runtime: ap.config.runtime,
|
|
14843
14953
|
model: ap.config.model,
|
|
@@ -14851,16 +14961,16 @@ var AgentProcessManager = class _AgentProcessManager {
|
|
|
14851
14961
|
return false;
|
|
14852
14962
|
}
|
|
14853
14963
|
this.commitApmIdleState(agentId, ap, false);
|
|
14854
|
-
this.startRuntimeTrace(agentId, ap, "
|
|
14964
|
+
this.startRuntimeTrace(agentId, ap, source.replaceAll("_", "-"), messages);
|
|
14855
14965
|
this.broadcastMessageReceivedActivity(agentId);
|
|
14856
14966
|
const accepted = this.deliverInboxUpdateViaStdin(
|
|
14857
14967
|
agentId,
|
|
14858
14968
|
ap,
|
|
14859
14969
|
messages,
|
|
14860
14970
|
"idle",
|
|
14861
|
-
|
|
14971
|
+
source
|
|
14862
14972
|
);
|
|
14863
|
-
this.recordDaemonTrace(
|
|
14973
|
+
this.recordDaemonTrace(traceName, {
|
|
14864
14974
|
agentId,
|
|
14865
14975
|
runtime: ap.config.runtime,
|
|
14866
14976
|
model: ap.config.model,
|
|
@@ -14873,6 +14983,13 @@ var AgentProcessManager = class _AgentProcessManager {
|
|
|
14873
14983
|
});
|
|
14874
14984
|
return accepted;
|
|
14875
14985
|
}
|
|
14986
|
+
flushAsyncRejectedIdleDelivery(agentId) {
|
|
14987
|
+
return this.flushIdleInboxDeliveryRetry(
|
|
14988
|
+
agentId,
|
|
14989
|
+
"async_rejected_idle_delivery_retry",
|
|
14990
|
+
"daemon.agent.stdin_delivery.async_rejected.retry"
|
|
14991
|
+
);
|
|
14992
|
+
}
|
|
14876
14993
|
isApmIdle(ap) {
|
|
14877
14994
|
return ap.gatedSteering.isIdle;
|
|
14878
14995
|
}
|
|
@@ -14936,6 +15053,7 @@ var AgentProcessManager = class _AgentProcessManager {
|
|
|
14936
15053
|
if (options.includeCompactionWatchdog ?? true) {
|
|
14937
15054
|
this.clearCompactionWatchdog(ap);
|
|
14938
15055
|
}
|
|
15056
|
+
this.clearReviewWatchdog(ap);
|
|
14939
15057
|
this.clearStalledRecoverySigtermWatchdog(ap);
|
|
14940
15058
|
}
|
|
14941
15059
|
clearRuntimeErrorDeliveryBackoffWithTrace(agentId, ap, resetSource) {
|
|
@@ -15311,7 +15429,8 @@ var AgentProcessManager = class _AgentProcessManager {
|
|
|
15311
15429
|
detailKind: activity.statusEntry.detailKind ?? "daemon_activity",
|
|
15312
15430
|
entries: activity.entries,
|
|
15313
15431
|
launchId: ap?.launchId || void 0,
|
|
15314
|
-
clientSeq: ap ? this.nextActivityClientSeq(agentId) : void 0
|
|
15432
|
+
clientSeq: ap ? this.nextActivityClientSeq(agentId) : void 0,
|
|
15433
|
+
isHeartbeat: false
|
|
15315
15434
|
});
|
|
15316
15435
|
}
|
|
15317
15436
|
recordRuntimeDiagnosticActivity(agentId, ap, event) {
|
|
@@ -15324,7 +15443,8 @@ var AgentProcessManager = class _AgentProcessManager {
|
|
|
15324
15443
|
detailKind: ap.lastActivityDetailKind || "none",
|
|
15325
15444
|
entries: [runtimeDiagnosticTrajectoryEntry(event)],
|
|
15326
15445
|
launchId: ap.launchId || void 0,
|
|
15327
|
-
clientSeq: this.nextActivityClientSeq(agentId)
|
|
15446
|
+
clientSeq: this.nextActivityClientSeq(agentId),
|
|
15447
|
+
isHeartbeat: false
|
|
15328
15448
|
});
|
|
15329
15449
|
this.recordDaemonTrace("daemon.runtime.diagnostic", {
|
|
15330
15450
|
agentId,
|
|
@@ -15375,7 +15495,8 @@ var AgentProcessManager = class _AgentProcessManager {
|
|
|
15375
15495
|
detailKind: ap.lastActivityDetailKind || "none",
|
|
15376
15496
|
entries: [runtimeRecoveryTrajectoryEntry(event)],
|
|
15377
15497
|
launchId: ap.launchId || void 0,
|
|
15378
|
-
clientSeq: this.nextActivityClientSeq(agentId)
|
|
15498
|
+
clientSeq: this.nextActivityClientSeq(agentId),
|
|
15499
|
+
isHeartbeat: false
|
|
15379
15500
|
});
|
|
15380
15501
|
this.recordDaemonTrace("daemon.runtime.recovery.visible", {
|
|
15381
15502
|
agentId,
|
|
@@ -16112,6 +16233,7 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
16112
16233
|
readinessTransition: null,
|
|
16113
16234
|
activation: { kind: "idle" },
|
|
16114
16235
|
compaction: { kind: "none" },
|
|
16236
|
+
review: { kind: "none" },
|
|
16115
16237
|
runtimeProgress: new RuntimeProgressState(Date.now()),
|
|
16116
16238
|
runtimeTraceSpan: null,
|
|
16117
16239
|
runtimeTraceCounters: createRuntimeTraceCounters(),
|
|
@@ -18232,7 +18354,8 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
18232
18354
|
entries,
|
|
18233
18355
|
launchId,
|
|
18234
18356
|
clientSeq,
|
|
18235
|
-
producerFactId
|
|
18357
|
+
producerFactId,
|
|
18358
|
+
isHeartbeat: false
|
|
18236
18359
|
});
|
|
18237
18360
|
this.recordActivityProducedTrace(agentId, activityKind, detail, detailKind, entries, ap, launchId, clientSeq, producerFactId);
|
|
18238
18361
|
if (ap) {
|
|
@@ -18260,7 +18383,10 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
18260
18383
|
detailKind: ap.lastActivityDetailKind,
|
|
18261
18384
|
launchId: heartbeatLaunchId,
|
|
18262
18385
|
clientSeq: heartbeatClientSeq,
|
|
18263
|
-
producerFactId: heartbeatProducerFactId
|
|
18386
|
+
producerFactId: heartbeatProducerFactId,
|
|
18387
|
+
// The one knowing site: this timer re-broadcasts stale
|
|
18388
|
+
// lastActivity, so it declares its replay provenance.
|
|
18389
|
+
isHeartbeat: true
|
|
18264
18390
|
});
|
|
18265
18391
|
this.recordActivityProducedTrace(agentId, ap.lastActivityKind, ap.lastActivityDetail, ap.lastActivityDetailKind, [], ap, heartbeatLaunchId, heartbeatClientSeq, heartbeatProducerFactId);
|
|
18266
18392
|
}, ACTIVITY_HEARTBEAT_MS);
|
|
@@ -18341,7 +18467,8 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
18341
18467
|
launchId,
|
|
18342
18468
|
probeId,
|
|
18343
18469
|
clientSeq,
|
|
18344
|
-
producerFactId
|
|
18470
|
+
producerFactId,
|
|
18471
|
+
isHeartbeat: false
|
|
18345
18472
|
});
|
|
18346
18473
|
this.recordActivityProducedTrace(agentId, activityKind, detail, detailKind, [], ap, launchId, clientSeq, producerFactId);
|
|
18347
18474
|
}
|
|
@@ -18489,6 +18616,29 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
18489
18616
|
ap.compaction = { ...ap.compaction, watchdog: null };
|
|
18490
18617
|
this.broadcastActivity(agentId, "working", "Context compaction still running; no finish event observed", [], void 0, "compaction_stale");
|
|
18491
18618
|
}
|
|
18619
|
+
startReviewWatchdog(agentId, ap) {
|
|
18620
|
+
this.clearReviewWatchdog(ap);
|
|
18621
|
+
const startedAt = Date.now();
|
|
18622
|
+
const watchdog = setTimeout(() => {
|
|
18623
|
+
this.markReviewStale(agentId, startedAt);
|
|
18624
|
+
}, REVIEW_STALE_MS);
|
|
18625
|
+
ap.review = { kind: "active", startedAt, watchdog };
|
|
18626
|
+
}
|
|
18627
|
+
clearReviewWatchdog(ap) {
|
|
18628
|
+
if (ap.review.kind === "active" && ap.review.watchdog) {
|
|
18629
|
+
clearTimeout(ap.review.watchdog);
|
|
18630
|
+
}
|
|
18631
|
+
ap.review = { kind: "none" };
|
|
18632
|
+
}
|
|
18633
|
+
markReviewStale(agentId, startedAt) {
|
|
18634
|
+
const ap = this.agents.get(agentId);
|
|
18635
|
+
if (!ap || ap.review.kind !== "active" || ap.review.startedAt !== startedAt) return;
|
|
18636
|
+
ap.review = { ...ap.review, watchdog: null };
|
|
18637
|
+
this.broadcastActivity(agentId, "working", "Review mode still active; no finish event observed", [], void 0, "review_stale");
|
|
18638
|
+
const reduction = reduceApmGatedReview(ap.gatedSteering, { kind: "review_finished" });
|
|
18639
|
+
this.commitGatedSteeringDecisionState(agentId, ap, reduction.nextState, { event: "review_finished", inferred: true });
|
|
18640
|
+
this.flushReviewBoundaryMessages(agentId, ap);
|
|
18641
|
+
}
|
|
18492
18642
|
completeCompactionIfActive(agentId, detail = "Context compaction finished", options = {}) {
|
|
18493
18643
|
const ap = this.agents.get(agentId);
|
|
18494
18644
|
if (!ap || ap.compaction.kind !== "active") return;
|
|
@@ -19428,11 +19578,15 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
19428
19578
|
if (ap) {
|
|
19429
19579
|
const reduction = reduceApmGatedReview(ap.gatedSteering, { kind: "review_started" });
|
|
19430
19580
|
this.commitGatedSteeringDecisionState(agentId, ap, reduction.nextState, { event: "review_started" });
|
|
19581
|
+
this.startReviewWatchdog(agentId, ap);
|
|
19431
19582
|
}
|
|
19432
19583
|
break;
|
|
19433
19584
|
case "review_finished":
|
|
19434
19585
|
this.flushPendingTrajectory(agentId);
|
|
19435
|
-
if (ap)
|
|
19586
|
+
if (ap) {
|
|
19587
|
+
this.clearReviewWatchdog(ap);
|
|
19588
|
+
this.recordRuntimeTraceEvent(agentId, ap, "runtime.review_mode.finished");
|
|
19589
|
+
}
|
|
19436
19590
|
this.broadcastActivity(agentId, "working", "Review finished", [], void 0, "review_finished");
|
|
19437
19591
|
if (ap) {
|
|
19438
19592
|
const reduction = reduceApmGatedReview(ap.gatedSteering, { kind: "review_finished" });
|
|
@@ -19953,6 +20107,15 @@ ${RESPONSE_TARGET_HINT}`;
|
|
|
19953
20107
|
`${mode} inbox update`
|
|
19954
20108
|
);
|
|
19955
20109
|
if (!sendResult.ok) {
|
|
20110
|
+
const retryNotificationCount = mode === "idle" && ap.driver.supportsStdinNotification && ap.sessionId ? messages.length : 0;
|
|
20111
|
+
const retrySource = source.endsWith("_retry") ? source : `${source}_retry`;
|
|
20112
|
+
const retryScheduled = mode === "idle" ? this.scheduleIdleInboxDeliveryRetry(
|
|
20113
|
+
agentId,
|
|
20114
|
+
ap,
|
|
20115
|
+
retryNotificationCount,
|
|
20116
|
+
retrySource,
|
|
20117
|
+
"daemon.agent.stdin_delivery.idle_retry"
|
|
20118
|
+
) : false;
|
|
19956
20119
|
if (mode === "idle") {
|
|
19957
20120
|
this.commitApmIdleState(agentId, ap, true);
|
|
19958
20121
|
}
|
|
@@ -19977,7 +20140,9 @@ ${RESPONSE_TARGET_HINT}`;
|
|
|
19977
20140
|
outcome: runtimeSendFailureOutcome(sendResult),
|
|
19978
20141
|
failure_reason: sendResult.reason,
|
|
19979
20142
|
failure_error: sendResult.error,
|
|
19980
|
-
requeued_messages_count:
|
|
20143
|
+
requeued_messages_count: retryNotificationCount,
|
|
20144
|
+
retry_scheduled: retryScheduled,
|
|
20145
|
+
notification_timer_present: ap.notifications.hasTimer,
|
|
19981
20146
|
cursors_advanced: "none"
|
|
19982
20147
|
}, "error");
|
|
19983
20148
|
return false;
|
|
@@ -20162,6 +20327,14 @@ var systemClock = {
|
|
|
20162
20327
|
clearTimeout: (timer) => clearTimeout(timer)
|
|
20163
20328
|
};
|
|
20164
20329
|
var INBOUND_WATCHDOG_MS = 7e4;
|
|
20330
|
+
function normalizeHandshakeReason(value) {
|
|
20331
|
+
const raw = Array.isArray(value) ? value[0] : value;
|
|
20332
|
+
if (typeof raw !== "string") return null;
|
|
20333
|
+
const trimmed = raw.trim();
|
|
20334
|
+
if (!trimmed) return null;
|
|
20335
|
+
if (!/^[a-z0-9_:-]{1,80}$/i.test(trimmed)) return "invalid_header";
|
|
20336
|
+
return trimmed;
|
|
20337
|
+
}
|
|
20165
20338
|
function durationMsBucket(ms) {
|
|
20166
20339
|
if (ms == null || !Number.isFinite(ms) || ms < 0) return "unknown";
|
|
20167
20340
|
if (ms === 0) return "0";
|
|
@@ -20254,6 +20427,7 @@ var DaemonConnection = class {
|
|
|
20254
20427
|
});
|
|
20255
20428
|
const ws = this.options.wsFactory ? this.options.wsFactory(wsUrl, wsOptions) : new WebSocket(wsUrl, wsOptions);
|
|
20256
20429
|
this.ws = ws;
|
|
20430
|
+
let handshakeRejected = false;
|
|
20257
20431
|
ws.on("open", () => {
|
|
20258
20432
|
if (this.ws !== ws) return;
|
|
20259
20433
|
if (!this.shouldConnect) return;
|
|
@@ -20314,8 +20488,27 @@ var DaemonConnection = class {
|
|
|
20314
20488
|
this.options.onDisconnect();
|
|
20315
20489
|
this.scheduleReconnect();
|
|
20316
20490
|
});
|
|
20491
|
+
ws.on("unexpected-response", (_request, response) => {
|
|
20492
|
+
if (this.ws !== ws) return;
|
|
20493
|
+
handshakeRejected = true;
|
|
20494
|
+
const reason = normalizeHandshakeReason(response.headers["slock-reason"]);
|
|
20495
|
+
const statusCode = response.statusCode ?? 0;
|
|
20496
|
+
const reasonText = reason ? `, slock_reason=${reason}` : "";
|
|
20497
|
+
logger.error(`[Daemon] WebSocket handshake rejected (status=${statusCode}${reasonText})`);
|
|
20498
|
+
this.trace("daemon.connection.handshake_rejected", {
|
|
20499
|
+
status_code: statusCode,
|
|
20500
|
+
slock_reason_present: Boolean(reason),
|
|
20501
|
+
slock_reason: reason
|
|
20502
|
+
}, "error");
|
|
20503
|
+
response.resume();
|
|
20504
|
+
try {
|
|
20505
|
+
ws.terminate();
|
|
20506
|
+
} catch {
|
|
20507
|
+
}
|
|
20508
|
+
});
|
|
20317
20509
|
ws.on("error", (err) => {
|
|
20318
20510
|
if (this.ws !== ws) return;
|
|
20511
|
+
if (handshakeRejected) return;
|
|
20319
20512
|
logger.error(`[Daemon] WebSocket error: ${err.message}`);
|
|
20320
20513
|
this.trace("daemon.connection.error", {
|
|
20321
20514
|
error_class: err.name || "Error"
|
|
@@ -21333,7 +21526,7 @@ var DAEMON_CORE_TRACE_ATTR_CONTRACTS = {
|
|
|
21333
21526
|
spanAttrs: ["agentId", "event_kind", "runtime"]
|
|
21334
21527
|
}
|
|
21335
21528
|
};
|
|
21336
|
-
var DAEMON_CLI_USAGE =
|
|
21529
|
+
var DAEMON_CLI_USAGE = `Usage: slock-daemon --server-url <url> (--api-key <key> or ${DAEMON_API_KEY_ENV}=<key>)`;
|
|
21337
21530
|
var RunnerCredentialMintError2 = class extends Error {
|
|
21338
21531
|
code;
|
|
21339
21532
|
retryable;
|
|
@@ -21369,9 +21562,9 @@ function runnerCredentialErrorDetail2(error) {
|
|
|
21369
21562
|
async function waitForRunnerCredentialRetry2() {
|
|
21370
21563
|
await new Promise((resolve) => setTimeout(resolve, RUNNER_CREDENTIAL_MINT_RETRY_DELAY_MS2));
|
|
21371
21564
|
}
|
|
21372
|
-
function parseDaemonCliArgs(args) {
|
|
21565
|
+
function parseDaemonCliArgs(args, env = {}) {
|
|
21373
21566
|
let serverUrl = "";
|
|
21374
|
-
let apiKey = "";
|
|
21567
|
+
let apiKey = env[DAEMON_API_KEY_ENV] ?? "";
|
|
21375
21568
|
for (let i = 0; i < args.length; i++) {
|
|
21376
21569
|
if (args[i] === "--server-url" && args[i + 1]) serverUrl = args[++i];
|
|
21377
21570
|
if (args[i] === "--api-key" && args[i + 1]) apiKey = args[++i];
|
|
@@ -21408,7 +21601,7 @@ function resolveSlockCliPathOrEmpty(moduleUrl = import.meta.url) {
|
|
|
21408
21601
|
}
|
|
21409
21602
|
async function runBundledSlockCli(argv) {
|
|
21410
21603
|
process.argv = [process.execPath, "slock", ...argv];
|
|
21411
|
-
await import("./dist-
|
|
21604
|
+
await import("./dist-IHHGSWH2.js");
|
|
21412
21605
|
}
|
|
21413
21606
|
function detectRuntimes(tracer = noopTracer) {
|
|
21414
21607
|
const ids = [];
|
|
@@ -22350,6 +22543,8 @@ var DaemonCore = class {
|
|
|
22350
22543
|
|
|
22351
22544
|
export {
|
|
22352
22545
|
subscribeDaemonLogs,
|
|
22546
|
+
DAEMON_API_KEY_ENV,
|
|
22547
|
+
scrubDaemonAuthEnv,
|
|
22353
22548
|
resolveWorkspaceDirectoryPath,
|
|
22354
22549
|
scanWorkspaceDirectories,
|
|
22355
22550
|
deleteWorkspaceDirectory,
|
package/dist/cli/index.js
CHANGED
|
@@ -44746,6 +44746,9 @@ init_esm_shims();
|
|
|
44746
44746
|
// ../shared/src/agentScopes.ts
|
|
44747
44747
|
init_esm_shims();
|
|
44748
44748
|
|
|
44749
|
+
// ../shared/src/docs/crossPageInvariants.ts
|
|
44750
|
+
init_esm_shims();
|
|
44751
|
+
|
|
44749
44752
|
// ../shared/src/testing/failpoints.ts
|
|
44750
44753
|
init_esm_shims();
|
|
44751
44754
|
var NoopFailpointRegistry = class {
|
|
@@ -44853,6 +44856,7 @@ var AGENT_ACTIVITY_DETAIL_KINDS = [
|
|
|
44853
44856
|
"compaction_stale",
|
|
44854
44857
|
"reviewing_changes",
|
|
44855
44858
|
"review_finished",
|
|
44859
|
+
"review_stale",
|
|
44856
44860
|
"runtime_reconnecting",
|
|
44857
44861
|
"runtime_error",
|
|
44858
44862
|
"runtime_crashed",
|
|
@@ -51041,6 +51045,9 @@ function formatClaimResults(channel, data) {
|
|
|
51041
51045
|
const msgShort = r.messageId ? r.messageId.slice(0, 8) : "";
|
|
51042
51046
|
return `${label} (msg:${msgShort}): claimed`;
|
|
51043
51047
|
}
|
|
51048
|
+
if (r.reason === "already claimed by you") {
|
|
51049
|
+
return `${label}: already claimed by you.`;
|
|
51050
|
+
}
|
|
51044
51051
|
return `${label}: FAILED \u2014 ${r.reason || "already claimed"}. Do not work on this task unless an owner/admin explicitly redirects it to you.`;
|
|
51045
51052
|
});
|
|
51046
51053
|
const succeeded = data.results.filter((r) => r.success).length;
|
package/dist/core.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import {
|
|
2
|
+
DAEMON_API_KEY_ENV,
|
|
2
3
|
DAEMON_CLI_USAGE,
|
|
3
4
|
DAEMON_CORE_TRACE_ATTR_CONTRACTS,
|
|
4
5
|
DaemonCore,
|
|
@@ -11,9 +12,11 @@ import {
|
|
|
11
12
|
resolveWorkspaceDirectoryPath,
|
|
12
13
|
runBundledSlockCli,
|
|
13
14
|
scanWorkspaceDirectories,
|
|
15
|
+
scrubDaemonAuthEnv,
|
|
14
16
|
subscribeDaemonLogs
|
|
15
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-FRBMWZ3P.js";
|
|
16
18
|
export {
|
|
19
|
+
DAEMON_API_KEY_ENV,
|
|
17
20
|
DAEMON_CLI_USAGE,
|
|
18
21
|
DAEMON_CORE_TRACE_ATTR_CONTRACTS,
|
|
19
22
|
DaemonCore,
|
|
@@ -26,5 +29,6 @@ export {
|
|
|
26
29
|
resolveWorkspaceDirectoryPath,
|
|
27
30
|
runBundledSlockCli,
|
|
28
31
|
scanWorkspaceDirectories,
|
|
32
|
+
scrubDaemonAuthEnv,
|
|
29
33
|
subscribeDaemonLogs
|
|
30
34
|
};
|
|
@@ -44281,6 +44281,7 @@ init_esm_shims();
|
|
|
44281
44281
|
init_esm_shims();
|
|
44282
44282
|
init_esm_shims();
|
|
44283
44283
|
init_esm_shims();
|
|
44284
|
+
init_esm_shims();
|
|
44284
44285
|
var NoopFailpointRegistry = class {
|
|
44285
44286
|
get enabled() {
|
|
44286
44287
|
return false;
|
|
@@ -44382,6 +44383,7 @@ var AGENT_ACTIVITY_DETAIL_KINDS = [
|
|
|
44382
44383
|
"compaction_stale",
|
|
44383
44384
|
"reviewing_changes",
|
|
44384
44385
|
"review_finished",
|
|
44386
|
+
"review_stale",
|
|
44385
44387
|
"runtime_reconnecting",
|
|
44386
44388
|
"runtime_error",
|
|
44387
44389
|
"runtime_crashed",
|
|
@@ -50421,6 +50423,9 @@ function formatClaimResults(channel, data) {
|
|
|
50421
50423
|
const msgShort = r.messageId ? r.messageId.slice(0, 8) : "";
|
|
50422
50424
|
return `${label} (msg:${msgShort}): claimed`;
|
|
50423
50425
|
}
|
|
50426
|
+
if (r.reason === "already claimed by you") {
|
|
50427
|
+
return `${label}: already claimed by you.`;
|
|
50428
|
+
}
|
|
50424
50429
|
return `${label}: FAILED \u2014 ${r.reason || "already claimed"}. Do not work on this task unless an owner/admin explicitly redirects it to you.`;
|
|
50425
50430
|
});
|
|
50426
50431
|
const succeeded = data.results.filter((r) => r.success).length;
|
package/dist/index.js
CHANGED
|
@@ -2,11 +2,13 @@
|
|
|
2
2
|
import {
|
|
3
3
|
DAEMON_CLI_USAGE,
|
|
4
4
|
DaemonCore,
|
|
5
|
-
parseDaemonCliArgs
|
|
6
|
-
|
|
5
|
+
parseDaemonCliArgs,
|
|
6
|
+
scrubDaemonAuthEnv
|
|
7
|
+
} from "./chunk-FRBMWZ3P.js";
|
|
7
8
|
|
|
8
9
|
// src/index.ts
|
|
9
|
-
var parsedArgs = parseDaemonCliArgs(process.argv.slice(2));
|
|
10
|
+
var parsedArgs = parseDaemonCliArgs(process.argv.slice(2), process.env);
|
|
11
|
+
scrubDaemonAuthEnv(process.env);
|
|
10
12
|
if (!parsedArgs) {
|
|
11
13
|
console.error(DAEMON_CLI_USAGE);
|
|
12
14
|
process.exit(1);
|