@slock-ai/daemon 0.57.5-play.20260611173452 → 0.57.6
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/{chunk-NHANGBTA.js → chunk-XQ3HLMCZ.js} +75 -136
- package/dist/cli/index.js +73 -0
- package/dist/core.js +5 -5
- package/dist/dist-CYKZS5JA.js +20188 -0
- package/dist/index.js +3 -5
- package/package.json +4 -4
|
@@ -1879,7 +1879,7 @@ function buildPrompt(config, opts) {
|
|
|
1879
1879
|
const checkCmd = "`slock message check`";
|
|
1880
1880
|
const inboxCheckCmd = "`slock inbox check`";
|
|
1881
1881
|
const messageDeliveryText = opts.includeStdinNotificationSection ? "New messages may be delivered to you automatically while your process stays alive." : "The daemon will automatically restart you when new messages arrive.";
|
|
1882
|
-
const noConcreteMessageStartupStep = opts.includeStdinNotificationSection ? `3. If there is no concrete incoming message to handle
|
|
1882
|
+
const noConcreteMessageStartupStep = opts.includeStdinNotificationSection ? `3. If there is no concrete incoming message to handle but this turn includes a Slock inbox notice: the notice means messages exist that you have not seen \u2014 their bodies are withheld to avoid flooding you, not absent (unobserved is not the same as nonexistent). Whether and when to read them is your judgment, now or later; ${checkCmd} reads them and the notice metadata (who, where, how many) helps you triage. Never derive "no work" from a content-free notice alone \u2014 if you choose not to read, that is a deferral to report honestly, not a conclusion that nothing is pending. If there is neither a concrete message nor an inbox notice, stop and wait. ${messageDeliveryText}` : `3. If there is no concrete incoming message to handle, stop and wait. ${messageDeliveryText}`;
|
|
1883
1883
|
const criticalRules = [
|
|
1884
1884
|
"- Always communicate through `slock` CLI commands. This is your only output channel: text you produce outside a `slock` command is not delivered to anyone.",
|
|
1885
1885
|
...opts.extraCriticalRules,
|
|
@@ -2025,7 +2025,7 @@ While you are working, the daemon may write a batched, content-free inbox update
|
|
|
2025
2025
|
|
|
2026
2026
|
How to handle these:
|
|
2027
2027
|
- Treat the notification as a non-urgent signal that new Slock messages are waiting; it does not include the message content and does not require an immediate interruption.
|
|
2028
|
-
-
|
|
2028
|
+
- A content-free notice means messages exist that you have not seen \u2014 not that there is no content or no action. Whether and when to read them is your judgment, now or later; ${checkCmd} is one cheap command and the notice metadata helps you triage. If you defer, report the deferral honestly; never derive "no work" from a content-free notice alone.
|
|
2029
2029
|
- Keep working until a natural breakpoint. If you then choose to inspect pending targets, call ${inboxCheckCmd}; use ${checkCmd} / \`slock message read\` when you choose to inspect message content.
|
|
2030
2030
|
- If a message you explicitly read is higher priority, pivot to it. If not, continue your current work.`;
|
|
2031
2031
|
} else {
|
|
@@ -2040,7 +2040,7 @@ ${notifyExample}
|
|
|
2040
2040
|
|
|
2041
2041
|
How to handle these:
|
|
2042
2042
|
- The notice is target-scoped and content-free. Its header may show total unread/pending count, while detail rows list the targets changed by this update; it never includes message bodies.
|
|
2043
|
-
-
|
|
2043
|
+
- A content-free notice means messages exist that you have not seen \u2014 not that there is no content or no action. Whether and when to read them is your judgment, now or later; ${checkCmd} is one cheap command and the notice metadata helps you triage. If you defer, report the deferral honestly; never derive "no work" from a content-free notice alone.
|
|
2044
2044
|
- Do not interrupt the current step just because a notice arrived. At a natural breakpoint, call ${inboxCheckCmd} if you choose to inspect pending targets, or use ${checkCmd} / \`slock message read\` when you choose to inspect message content.
|
|
2045
2045
|
- If a message you explicitly read is higher priority, you may pivot to it. If not, continue your current work.`;
|
|
2046
2046
|
}
|
|
@@ -2096,19 +2096,6 @@ function listLegacySlockStatePaths(slockHome = resolveSlockHome(), homeDir = os.
|
|
|
2096
2096
|
return candidates.filter((candidate) => existsSync(candidate.path));
|
|
2097
2097
|
}
|
|
2098
2098
|
|
|
2099
|
-
// src/authEnv.ts
|
|
2100
|
-
var DAEMON_API_KEY_ENV = "SLOCK_MACHINE_API_KEY";
|
|
2101
|
-
var SLOCK_AGENT_TOKEN_ENV = "SLOCK_AGENT_TOKEN";
|
|
2102
|
-
function scrubDaemonAuthEnv(env) {
|
|
2103
|
-
delete env[DAEMON_API_KEY_ENV];
|
|
2104
|
-
return env;
|
|
2105
|
-
}
|
|
2106
|
-
function scrubDaemonChildEnv(env) {
|
|
2107
|
-
delete env[DAEMON_API_KEY_ENV];
|
|
2108
|
-
delete env[SLOCK_AGENT_TOKEN_ENV];
|
|
2109
|
-
return env;
|
|
2110
|
-
}
|
|
2111
|
-
|
|
2112
2099
|
// src/agentCredentialProxy.ts
|
|
2113
2100
|
import { randomBytes } from "crypto";
|
|
2114
2101
|
import http from "http";
|
|
@@ -3297,6 +3284,7 @@ function routeFamilyForPath(pathname) {
|
|
|
3297
3284
|
if (pathname === "/internal/agent-api/tasks/claim") return "tasks/claim";
|
|
3298
3285
|
if (pathname === "/internal/agent-api/tasks/update-status") return "tasks/update";
|
|
3299
3286
|
if (pathname === "/internal/agent-api/tasks" || pathname.startsWith("/internal/agent-api/tasks/")) return "tasks";
|
|
3287
|
+
if (/^\/internal\/agent-api\/attachments\/[^/]+\/comments/.test(pathname)) return "agent-api/attachments/comments";
|
|
3300
3288
|
if (pathname.startsWith("/internal/agent-api/attachments/")) return "agent-api/attachments";
|
|
3301
3289
|
if (/^\/internal\/agent-api\/messages\/[^/]+\/resolve$/.test(pathname)) return "agent-api/messages/resolve";
|
|
3302
3290
|
if (/^\/internal\/agent-api\/messages\/[^/]+\/reactions$/.test(pathname)) return "agent-api/messages/reactions";
|
|
@@ -3595,9 +3583,7 @@ var LOOPBACK_NO_PROXY = "127.0.0.1,localhost";
|
|
|
3595
3583
|
var CLI_TRANSPORT_TRACE_DIR_ENV = "SLOCK_CLI_TRANSPORT_TRACE_DIR";
|
|
3596
3584
|
var safePathPart = (value) => value.replace(/[^a-zA-Z0-9_.-]/g, "_");
|
|
3597
3585
|
var RAW_CREDENTIAL_ENV_DENYLIST = [
|
|
3598
|
-
"
|
|
3599
|
-
"SLOCK_AGENT_CREDENTIAL_KEY",
|
|
3600
|
-
"SLOCK_AGENT_CREDENTIAL_KEY_FILE"
|
|
3586
|
+
"SLOCK_AGENT_CREDENTIAL_KEY"
|
|
3601
3587
|
];
|
|
3602
3588
|
var cachedOpencliBinPath;
|
|
3603
3589
|
function resolveOpencliBinPath() {
|
|
@@ -3812,7 +3798,7 @@ exec ${shellSingleQuote(process.execPath)} ${shellSingleQuote(opencliBinPath)} "
|
|
|
3812
3798
|
...agentCredentialProxy ? {} : { SLOCK_AGENT_TOKEN_FILE: tokenFile },
|
|
3813
3799
|
PATH: `${slockDir}${path2.delimiter}${process.env.PATH ?? ""}`
|
|
3814
3800
|
};
|
|
3815
|
-
|
|
3801
|
+
delete spawnEnv.SLOCK_AGENT_TOKEN;
|
|
3816
3802
|
for (const key of RAW_CREDENTIAL_ENV_DENYLIST) {
|
|
3817
3803
|
delete spawnEnv[key];
|
|
3818
3804
|
}
|
|
@@ -4241,7 +4227,7 @@ function resolveCommandOnWindows(command, env, execFileSyncFn, existsSyncFn) {
|
|
|
4241
4227
|
}
|
|
4242
4228
|
function resolveCommandOnPath(command, deps = {}) {
|
|
4243
4229
|
const platform = deps.platform ?? process.platform;
|
|
4244
|
-
const env =
|
|
4230
|
+
const env = withWindowsUserEnvironment(deps.env ?? process.env, deps);
|
|
4245
4231
|
const execFileSyncFn = deps.execFileSyncFn ?? execFileSync;
|
|
4246
4232
|
const existsSyncFn = deps.existsSyncFn ?? existsSync2;
|
|
4247
4233
|
if (platform === "win32") {
|
|
@@ -4267,7 +4253,7 @@ function firstExistingPath(candidates, deps = {}) {
|
|
|
4267
4253
|
return null;
|
|
4268
4254
|
}
|
|
4269
4255
|
function readCommandVersion(command, args = [], deps = {}) {
|
|
4270
|
-
const env =
|
|
4256
|
+
const env = withWindowsUserEnvironment(deps.env ?? process.env, deps);
|
|
4271
4257
|
const execFileSyncFn = deps.execFileSyncFn ?? execFileSync;
|
|
4272
4258
|
try {
|
|
4273
4259
|
const output = normalizeExecOutput(execFileSyncFn(command, [...args, "--version"], {
|
|
@@ -5656,11 +5642,11 @@ function detectCursorModels(runCommand = runCursorModelsCommand) {
|
|
|
5656
5642
|
return parseCursorModelsOutput(String(result.stdout || ""));
|
|
5657
5643
|
}
|
|
5658
5644
|
function buildCursorModelProbeEnv(deps = {}) {
|
|
5659
|
-
return
|
|
5645
|
+
return withWindowsUserEnvironment({
|
|
5660
5646
|
...deps.env ?? process.env,
|
|
5661
5647
|
FORCE_COLOR: "0",
|
|
5662
5648
|
NO_COLOR: "1"
|
|
5663
|
-
}, deps)
|
|
5649
|
+
}, deps);
|
|
5664
5650
|
}
|
|
5665
5651
|
function runCursorModelsCommand() {
|
|
5666
5652
|
return spawnSync("cursor-agent", ["models"], {
|
|
@@ -5716,7 +5702,7 @@ function resolveGeminiSpawn(commandArgs, deps = {}) {
|
|
|
5716
5702
|
}
|
|
5717
5703
|
const execFileSyncFn = deps.execFileSyncFn ?? execFileSync3;
|
|
5718
5704
|
const existsSyncFn = deps.existsSyncFn ?? existsSync5;
|
|
5719
|
-
const env =
|
|
5705
|
+
const env = deps.env ?? process.env;
|
|
5720
5706
|
const winPath = path7.win32;
|
|
5721
5707
|
let geminiEntry = null;
|
|
5722
5708
|
try {
|
|
@@ -5853,15 +5839,12 @@ var GeminiDriver = class {
|
|
|
5853
5839
|
// src/drivers/kimi.ts
|
|
5854
5840
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
5855
5841
|
import { spawn as spawn7 } from "child_process";
|
|
5856
|
-
import {
|
|
5842
|
+
import { existsSync as existsSync6, readFileSync as readFileSync3, writeFileSync as writeFileSync3 } from "fs";
|
|
5857
5843
|
import os4 from "os";
|
|
5858
5844
|
import path8 from "path";
|
|
5859
5845
|
var KIMI_WIRE_PROTOCOL_VERSION = "1.3";
|
|
5860
5846
|
var KIMI_SYSTEM_PROMPT_FILE = ".slock-kimi-system.md";
|
|
5861
5847
|
var KIMI_AGENT_FILE = ".slock-kimi-agent.yaml";
|
|
5862
|
-
var KIMI_GENERATED_CONFIG_FILE = ".slock-kimi-config.toml";
|
|
5863
|
-
var SLOCK_KIMI_CONFIG_CONTENT_ENV = "SLOCK_KIMI_CONFIG_CONTENT";
|
|
5864
|
-
var SLOCK_KIMI_CONFIG_FILE_ENV = "SLOCK_KIMI_CONFIG_FILE";
|
|
5865
5848
|
function parseToolArguments(raw) {
|
|
5866
5849
|
if (typeof raw !== "string") return raw;
|
|
5867
5850
|
try {
|
|
@@ -5870,73 +5853,6 @@ function parseToolArguments(raw) {
|
|
|
5870
5853
|
return raw;
|
|
5871
5854
|
}
|
|
5872
5855
|
}
|
|
5873
|
-
function readKimiConfigSource(home = os4.homedir(), env = process.env) {
|
|
5874
|
-
const inlineConfig = env[SLOCK_KIMI_CONFIG_CONTENT_ENV];
|
|
5875
|
-
if (inlineConfig && inlineConfig.trim()) {
|
|
5876
|
-
return {
|
|
5877
|
-
raw: inlineConfig,
|
|
5878
|
-
explicitPath: null,
|
|
5879
|
-
sourcePath: SLOCK_KIMI_CONFIG_CONTENT_ENV
|
|
5880
|
-
};
|
|
5881
|
-
}
|
|
5882
|
-
const explicitPath = env[SLOCK_KIMI_CONFIG_FILE_ENV];
|
|
5883
|
-
const configPath = explicitPath && explicitPath.trim() ? explicitPath : path8.join(home, ".kimi", "config.toml");
|
|
5884
|
-
try {
|
|
5885
|
-
return {
|
|
5886
|
-
raw: readFileSync3(configPath, "utf8"),
|
|
5887
|
-
explicitPath: explicitPath && explicitPath.trim() ? explicitPath : null,
|
|
5888
|
-
sourcePath: configPath
|
|
5889
|
-
};
|
|
5890
|
-
} catch {
|
|
5891
|
-
return {
|
|
5892
|
-
raw: null,
|
|
5893
|
-
explicitPath: explicitPath && explicitPath.trim() ? explicitPath : null,
|
|
5894
|
-
sourcePath: configPath
|
|
5895
|
-
};
|
|
5896
|
-
}
|
|
5897
|
-
}
|
|
5898
|
-
function buildKimiSpawnEnv(env = process.env) {
|
|
5899
|
-
const spawnEnv = { ...env, FORCE_COLOR: "0", NO_COLOR: "1" };
|
|
5900
|
-
delete spawnEnv[SLOCK_KIMI_CONFIG_CONTENT_ENV];
|
|
5901
|
-
delete spawnEnv[SLOCK_KIMI_CONFIG_FILE_ENV];
|
|
5902
|
-
return scrubDaemonChildEnv(spawnEnv);
|
|
5903
|
-
}
|
|
5904
|
-
function buildKimiEffectiveEnv(ctx, overrideEnv) {
|
|
5905
|
-
return {
|
|
5906
|
-
...process.env,
|
|
5907
|
-
...ctx.config.envVars || {},
|
|
5908
|
-
...overrideEnv || {}
|
|
5909
|
-
};
|
|
5910
|
-
}
|
|
5911
|
-
function buildKimiLaunchOptions(ctx, opts = {}) {
|
|
5912
|
-
const env = buildKimiEffectiveEnv(ctx, opts.env);
|
|
5913
|
-
const source = readKimiConfigSource(opts.home ?? os4.homedir(), env);
|
|
5914
|
-
const args = [];
|
|
5915
|
-
let configFilePath = null;
|
|
5916
|
-
let configContent = null;
|
|
5917
|
-
if (source.explicitPath) {
|
|
5918
|
-
configFilePath = source.explicitPath;
|
|
5919
|
-
} else if (source.raw !== null && source.sourcePath === SLOCK_KIMI_CONFIG_CONTENT_ENV) {
|
|
5920
|
-
configFilePath = path8.join(ctx.workingDirectory, KIMI_GENERATED_CONFIG_FILE);
|
|
5921
|
-
configContent = source.raw;
|
|
5922
|
-
if (opts.writeGeneratedConfig !== false) {
|
|
5923
|
-
writeFileSync3(configFilePath, source.raw, { encoding: "utf8", mode: 384 });
|
|
5924
|
-
chmodSync(configFilePath, 384);
|
|
5925
|
-
}
|
|
5926
|
-
}
|
|
5927
|
-
if (configFilePath) {
|
|
5928
|
-
args.push("--config-file", configFilePath);
|
|
5929
|
-
}
|
|
5930
|
-
if (ctx.config.model && ctx.config.model !== "default") {
|
|
5931
|
-
args.push("--model", ctx.config.model);
|
|
5932
|
-
}
|
|
5933
|
-
return {
|
|
5934
|
-
args,
|
|
5935
|
-
env: buildKimiSpawnEnv(env),
|
|
5936
|
-
configFilePath,
|
|
5937
|
-
configContent
|
|
5938
|
-
};
|
|
5939
|
-
}
|
|
5940
5856
|
function resolveKimiSpawn(commandArgs, deps = {}) {
|
|
5941
5857
|
return {
|
|
5942
5858
|
command: resolveCommandOnPath("kimi", deps) ?? "kimi",
|
|
@@ -5960,25 +5876,7 @@ var KimiDriver = class {
|
|
|
5960
5876
|
};
|
|
5961
5877
|
model = {
|
|
5962
5878
|
detectedModelsVerifiedAs: "launchable",
|
|
5963
|
-
toLaunchSpec: (modelId
|
|
5964
|
-
if (!ctx) return { args: ["--model", modelId] };
|
|
5965
|
-
const launchCtx = {
|
|
5966
|
-
...ctx,
|
|
5967
|
-
config: {
|
|
5968
|
-
...ctx.config,
|
|
5969
|
-
model: modelId
|
|
5970
|
-
}
|
|
5971
|
-
};
|
|
5972
|
-
const launch = buildKimiLaunchOptions(launchCtx, {
|
|
5973
|
-
home: opts?.home,
|
|
5974
|
-
writeGeneratedConfig: false
|
|
5975
|
-
});
|
|
5976
|
-
return {
|
|
5977
|
-
args: launch.args,
|
|
5978
|
-
env: launch.env,
|
|
5979
|
-
configFiles: launch.configFilePath ? [launch.configFilePath] : void 0
|
|
5980
|
-
};
|
|
5981
|
-
}
|
|
5879
|
+
toLaunchSpec: (modelId) => ({ args: ["--model", modelId] })
|
|
5982
5880
|
};
|
|
5983
5881
|
supportsStdinNotification = true;
|
|
5984
5882
|
busyDeliveryMode = "direct";
|
|
@@ -6002,23 +5900,21 @@ var KimiDriver = class {
|
|
|
6002
5900
|
` system_prompt_path: ./${KIMI_SYSTEM_PROMPT_FILE}`,
|
|
6003
5901
|
""
|
|
6004
5902
|
].join("\n"), "utf8");
|
|
6005
|
-
const launch = buildKimiLaunchOptions(ctx);
|
|
6006
5903
|
const args = [
|
|
6007
5904
|
"--wire",
|
|
6008
5905
|
"--yolo",
|
|
6009
5906
|
"--agent-file",
|
|
6010
5907
|
agentFilePath,
|
|
6011
5908
|
"--session",
|
|
6012
|
-
this.sessionId
|
|
6013
|
-
...launch.args
|
|
5909
|
+
this.sessionId
|
|
6014
5910
|
];
|
|
6015
5911
|
const launchRuntimeFields = runtimeConfigToLaunchFields(ctx.config);
|
|
6016
5912
|
if (launchRuntimeFields.model && launchRuntimeFields.model !== "default") {
|
|
6017
5913
|
args.push("--model", launchRuntimeFields.model);
|
|
6018
5914
|
}
|
|
6019
5915
|
const spawnEnv = (await prepareCliTransport(ctx, { NO_COLOR: "1" })).spawnEnv;
|
|
6020
|
-
const
|
|
6021
|
-
const proc = spawn7(
|
|
5916
|
+
const launch = resolveKimiSpawn(args);
|
|
5917
|
+
const proc = spawn7(launch.command, launch.args, {
|
|
6022
5918
|
cwd: ctx.workingDirectory,
|
|
6023
5919
|
stdio: ["pipe", "pipe", "pipe"],
|
|
6024
5920
|
env: spawnEnv,
|
|
@@ -6026,7 +5922,7 @@ var KimiDriver = class {
|
|
|
6026
5922
|
// and has an 8191-character command-line limit. Kimi's official
|
|
6027
5923
|
// installer/uv entrypoint is an executable, so launch it directly and
|
|
6028
5924
|
// keep prompts on stdin / files instead of routing through cmd.exe.
|
|
6029
|
-
shell:
|
|
5925
|
+
shell: launch.shell
|
|
6030
5926
|
});
|
|
6031
5927
|
proc.stdin?.write(JSON.stringify({
|
|
6032
5928
|
jsonrpc: "2.0",
|
|
@@ -6139,9 +6035,14 @@ var KimiDriver = class {
|
|
|
6139
6035
|
return detectKimiModels();
|
|
6140
6036
|
}
|
|
6141
6037
|
};
|
|
6142
|
-
function detectKimiModels(home = os4.homedir()
|
|
6143
|
-
const
|
|
6144
|
-
|
|
6038
|
+
function detectKimiModels(home = os4.homedir()) {
|
|
6039
|
+
const configPath = path8.join(home, ".kimi", "config.toml");
|
|
6040
|
+
let raw;
|
|
6041
|
+
try {
|
|
6042
|
+
raw = readFileSync3(configPath, "utf8");
|
|
6043
|
+
} catch {
|
|
6044
|
+
return null;
|
|
6045
|
+
}
|
|
6145
6046
|
const models = [];
|
|
6146
6047
|
const sectionRe = /^\s*\[models(?:\.([^\]]+)|"\.[^"]+"|\."[^"]+")\s*\]\s*$/gm;
|
|
6147
6048
|
const lineRe = /^\s*\[models\.(.+?)\s*\]\s*$/gm;
|
|
@@ -6379,7 +6280,7 @@ function runOpenCodeModelsCommand(home, deps = {}) {
|
|
|
6379
6280
|
const platform = deps.platform ?? process.platform;
|
|
6380
6281
|
const spawnSyncFn = deps.spawnSyncFn ?? spawnSync2;
|
|
6381
6282
|
const result = spawnSyncFn("opencode", ["models"], {
|
|
6382
|
-
env:
|
|
6283
|
+
env: { ...process.env, HOME: home, FORCE_COLOR: "0", NO_COLOR: "1" },
|
|
6383
6284
|
encoding: "utf8",
|
|
6384
6285
|
timeout: 5e3,
|
|
6385
6286
|
shell: platform === "win32"
|
|
@@ -14184,7 +14085,7 @@ var DAEMON_CORE_TRACE_ATTR_CONTRACTS = {
|
|
|
14184
14085
|
spanAttrs: ["running_agents_count", "idle_agents_count"]
|
|
14185
14086
|
}
|
|
14186
14087
|
};
|
|
14187
|
-
var DAEMON_CLI_USAGE =
|
|
14088
|
+
var DAEMON_CLI_USAGE = "Usage: slock-daemon --server-url <url> --api-key <key>";
|
|
14188
14089
|
var RunnerCredentialMintError2 = class extends Error {
|
|
14189
14090
|
code;
|
|
14190
14091
|
retryable;
|
|
@@ -14220,9 +14121,9 @@ function runnerCredentialErrorDetail2(error) {
|
|
|
14220
14121
|
async function waitForRunnerCredentialRetry2() {
|
|
14221
14122
|
await new Promise((resolve) => setTimeout(resolve, RUNNER_CREDENTIAL_MINT_RETRY_DELAY_MS2));
|
|
14222
14123
|
}
|
|
14223
|
-
function parseDaemonCliArgs(args
|
|
14124
|
+
function parseDaemonCliArgs(args) {
|
|
14224
14125
|
let serverUrl = "";
|
|
14225
|
-
let apiKey =
|
|
14126
|
+
let apiKey = "";
|
|
14226
14127
|
for (let i = 0; i < args.length; i++) {
|
|
14227
14128
|
if (args[i] === "--server-url" && args[i + 1]) serverUrl = args[++i];
|
|
14228
14129
|
if (args[i] === "--api-key" && args[i + 1]) apiKey = args[++i];
|
|
@@ -14250,6 +14151,17 @@ function resolveSlockCliPath(moduleUrl = import.meta.url) {
|
|
|
14250
14151
|
return workspaceDistPath;
|
|
14251
14152
|
}
|
|
14252
14153
|
}
|
|
14154
|
+
function resolveSlockCliPathOrEmpty(moduleUrl = import.meta.url) {
|
|
14155
|
+
try {
|
|
14156
|
+
return resolveSlockCliPath(moduleUrl);
|
|
14157
|
+
} catch {
|
|
14158
|
+
return "";
|
|
14159
|
+
}
|
|
14160
|
+
}
|
|
14161
|
+
async function runBundledSlockCli(argv) {
|
|
14162
|
+
process.argv = [process.execPath, "slock", ...argv];
|
|
14163
|
+
await import("./dist-CYKZS5JA.js");
|
|
14164
|
+
}
|
|
14253
14165
|
function detectRuntimes(tracer = noopTracer) {
|
|
14254
14166
|
const ids = [];
|
|
14255
14167
|
const versions = {};
|
|
@@ -14399,7 +14311,7 @@ var DaemonCore = class {
|
|
|
14399
14311
|
this.options = options;
|
|
14400
14312
|
this.daemonVersion = options.daemonVersion ?? readDaemonVersion();
|
|
14401
14313
|
this.computerVersion = (process.env.SLOCK_COMPUTER_VERSION || "").trim() || null;
|
|
14402
|
-
this.slockCliPath = options.slockCliPath ??
|
|
14314
|
+
this.slockCliPath = options.slockCliPath ?? resolveSlockCliPathOrEmpty();
|
|
14403
14315
|
this.slockHome = resolveSlockHome();
|
|
14404
14316
|
process.env[SLOCK_HOME_ENV] = this.slockHome;
|
|
14405
14317
|
this.injectedTracer = Boolean(options.tracer);
|
|
@@ -14897,18 +14809,29 @@ var DaemonCore = class {
|
|
|
14897
14809
|
case "computer:restart":
|
|
14898
14810
|
case "computer:upgrade": {
|
|
14899
14811
|
const action = msg.type === "computer:restart" ? "restart" : "upgrade";
|
|
14812
|
+
const requestId = msg.requestId;
|
|
14900
14813
|
this.recordDaemonTrace("daemon.computer_control.received", {
|
|
14901
14814
|
action,
|
|
14902
|
-
handled: Boolean(this.options.onComputerControl)
|
|
14815
|
+
handled: Boolean(this.options.onComputerControl),
|
|
14816
|
+
...requestId ? { request_id: requestId } : {}
|
|
14903
14817
|
});
|
|
14904
14818
|
if (this.options.onComputerControl) {
|
|
14905
|
-
|
|
14906
|
-
|
|
14907
|
-
|
|
14819
|
+
const ctx = {
|
|
14820
|
+
requestId,
|
|
14821
|
+
emitUpgradeProgress: (ev) => {
|
|
14822
|
+
if (!requestId) return;
|
|
14823
|
+
this.connection.send({ type: "computer:upgrade:progress", requestId, ...ev });
|
|
14824
|
+
},
|
|
14825
|
+
emitUpgradeDone: (ev) => {
|
|
14826
|
+
if (!requestId) return;
|
|
14827
|
+
this.connection.send({ type: "computer:upgrade:done", requestId, ...ev });
|
|
14828
|
+
}
|
|
14829
|
+
};
|
|
14830
|
+
void Promise.resolve().then(() => this.options.onComputerControl(action, ctx)).catch((err) => {
|
|
14908
14831
|
logger.error(
|
|
14909
14832
|
`[Daemon] computer:${action} control handler failed: ${err instanceof Error ? err.message : String(err)}`
|
|
14910
14833
|
);
|
|
14911
|
-
}
|
|
14834
|
+
});
|
|
14912
14835
|
} else {
|
|
14913
14836
|
logger.info(`[Daemon] Ignoring computer:${action} \u2014 not launched by a Computer service.`);
|
|
14914
14837
|
}
|
|
@@ -14949,6 +14872,22 @@ var DaemonCore = class {
|
|
|
14949
14872
|
idle_agents_count: idleAgentSessions.length,
|
|
14950
14873
|
runtime_profile_reports_count: runtimeProfileReports.length
|
|
14951
14874
|
});
|
|
14875
|
+
if (this.options.onComputerUpgradeReconcile) {
|
|
14876
|
+
void Promise.resolve().then(
|
|
14877
|
+
() => this.options.onComputerUpgradeReconcile((done) => {
|
|
14878
|
+
this.connection.send({ type: "computer:upgrade:done", ...done });
|
|
14879
|
+
this.recordDaemonTrace("daemon.computer_upgrade.reconciled", {
|
|
14880
|
+
request_id: done.requestId,
|
|
14881
|
+
ok: done.ok,
|
|
14882
|
+
...done.newVersion ? { new_version: done.newVersion } : {}
|
|
14883
|
+
});
|
|
14884
|
+
})
|
|
14885
|
+
).catch((err) => {
|
|
14886
|
+
logger.error(
|
|
14887
|
+
`[Daemon] computer upgrade reconcile failed: ${err instanceof Error ? err.message : String(err)}`
|
|
14888
|
+
);
|
|
14889
|
+
});
|
|
14890
|
+
}
|
|
14952
14891
|
for (const agentId of runningAgentIds) {
|
|
14953
14892
|
const sessionId = this.agentManager.getAgentSessionId(agentId);
|
|
14954
14893
|
const launchId = this.agentManager.getAgentLaunchId(agentId);
|
|
@@ -15003,8 +14942,6 @@ var DaemonCore = class {
|
|
|
15003
14942
|
};
|
|
15004
14943
|
|
|
15005
14944
|
export {
|
|
15006
|
-
DAEMON_API_KEY_ENV,
|
|
15007
|
-
scrubDaemonAuthEnv,
|
|
15008
14945
|
subscribeDaemonLogs,
|
|
15009
14946
|
resolveWorkspaceDirectoryPath,
|
|
15010
14947
|
scanWorkspaceDirectories,
|
|
@@ -15013,6 +14950,8 @@ export {
|
|
|
15013
14950
|
parseDaemonCliArgs,
|
|
15014
14951
|
readDaemonVersion,
|
|
15015
14952
|
resolveSlockCliPath,
|
|
14953
|
+
resolveSlockCliPathOrEmpty,
|
|
14954
|
+
runBundledSlockCli,
|
|
15016
14955
|
detectRuntimes,
|
|
15017
14956
|
DaemonCore
|
|
15018
14957
|
};
|
package/dist/cli/index.js
CHANGED
|
@@ -166,6 +166,8 @@ function routeFamilyForPath(pathname) {
|
|
|
166
166
|
if (normalized === "/internal/agent-api/tasks" || normalized.startsWith("/internal/agent-api/tasks/")) {
|
|
167
167
|
return "tasks";
|
|
168
168
|
}
|
|
169
|
+
if (/^\/internal\/agent-api\/attachments\/[^/]+\/comments/.test(normalized)) return "agent-api/attachments/comments";
|
|
170
|
+
if (/^\/api\/attachments\/[^/]+\/comments/.test(normalized)) return "agent-api/attachments/comments";
|
|
169
171
|
if (normalized.startsWith("/internal/agent-api/attachments/")) return "agent-api/attachments";
|
|
170
172
|
if (normalized.startsWith("/api/attachments/")) return "attachments/download";
|
|
171
173
|
if (/^\/internal\/agent-api\/messages\/[^/]+\/reactions$/.test(normalized)) return "agent-api/messages/reactions";
|
|
@@ -18751,6 +18753,76 @@ function registerAttachmentViewCommand(parent, runtimeOptions) {
|
|
|
18751
18753
|
registerCliCommand(parent, attachmentViewCommand, runtimeOptions);
|
|
18752
18754
|
}
|
|
18753
18755
|
|
|
18756
|
+
// src/commands/attachment/comments.ts
|
|
18757
|
+
function anchorSummary(anchor) {
|
|
18758
|
+
if (anchor.type === "md-section") {
|
|
18759
|
+
const title = anchor.data.headingTitle ?? anchor.data.headingId;
|
|
18760
|
+
return typeof title === "string" && title ? `\xA7 ${title}` : "\xA7 section";
|
|
18761
|
+
}
|
|
18762
|
+
if (anchor.type === "lines" || anchor.type === "csv-rows") {
|
|
18763
|
+
const start = Number(anchor.data.start);
|
|
18764
|
+
const end = Number(anchor.data.end ?? start);
|
|
18765
|
+
if (!Number.isFinite(start)) return anchor.type;
|
|
18766
|
+
const prefix = anchor.type === "lines" ? "L" : "rows ";
|
|
18767
|
+
return start === (Number.isFinite(end) ? end : start) ? `${prefix}${start}` : `${prefix}${start}\u2013${end}`;
|
|
18768
|
+
}
|
|
18769
|
+
if (anchor.type === "html-region") {
|
|
18770
|
+
const quote = anchor.data.quote;
|
|
18771
|
+
if (typeof quote === "string" && quote.trim().length > 0) {
|
|
18772
|
+
const trimmed = quote.trim();
|
|
18773
|
+
return trimmed.length > 60 ? `${trimmed.slice(0, 60)}\u2026` : trimmed;
|
|
18774
|
+
}
|
|
18775
|
+
return "HTML region";
|
|
18776
|
+
}
|
|
18777
|
+
return anchor.type;
|
|
18778
|
+
}
|
|
18779
|
+
var attachmentCommentsCommand = defineCommand(
|
|
18780
|
+
{
|
|
18781
|
+
name: "comments",
|
|
18782
|
+
description: "List comments scoped to an attachment",
|
|
18783
|
+
options: [
|
|
18784
|
+
{ flags: "--id <attachmentId>", description: "Attachment UUID" },
|
|
18785
|
+
{ flags: "--limit <n>", description: "Max comments to return (default 200)" }
|
|
18786
|
+
]
|
|
18787
|
+
},
|
|
18788
|
+
async (ctx, opts) => {
|
|
18789
|
+
const id = opts.id?.trim();
|
|
18790
|
+
if (!id) {
|
|
18791
|
+
throw new CliError({ code: "INVALID_ARG", message: "--id is required" });
|
|
18792
|
+
}
|
|
18793
|
+
const agentContext = ctx.loadAgentContext();
|
|
18794
|
+
const client = ctx.createApiClient(agentContext);
|
|
18795
|
+
const limitParam = opts.limit && Number.isFinite(Number(opts.limit)) ? `?limit=${Number(opts.limit)}` : "";
|
|
18796
|
+
const res = await client.request(
|
|
18797
|
+
"GET",
|
|
18798
|
+
`/api/attachments/${encodeURIComponent(id)}/comments${limitParam}`
|
|
18799
|
+
);
|
|
18800
|
+
if (!res.ok || !res.data) {
|
|
18801
|
+
const code = res.status >= 500 ? "SERVER_5XX" : "COMMENTS_FAILED";
|
|
18802
|
+
throw new CliError({ code, message: res.error ?? `HTTP ${res.status}` });
|
|
18803
|
+
}
|
|
18804
|
+
const { comments, threadChannelId } = res.data;
|
|
18805
|
+
if (comments.length === 0) {
|
|
18806
|
+
writeText(ctx.io, `No comments on attachment ${id.slice(0, 8)}.
|
|
18807
|
+
`);
|
|
18808
|
+
return;
|
|
18809
|
+
}
|
|
18810
|
+
const lines = [`## Comments on attachment ${id.slice(0, 8)} (${comments.length})`];
|
|
18811
|
+
for (const c of comments) {
|
|
18812
|
+
const check2 = c.reactions.some((r) => r.emoji === "\u2705") ? " \u2705" : "";
|
|
18813
|
+
const anchor = c.anchor ? ` [anchor: ${anchorSummary(c.anchor)}]` : "";
|
|
18814
|
+
lines.push(`[msg=${c.id.slice(0, 8)} time=${c.createdAt} type=${c.senderType}]${check2}${anchor} @${c.senderName}: ${c.content}`);
|
|
18815
|
+
}
|
|
18816
|
+
if (threadChannelId) {
|
|
18817
|
+
lines.push(`(full conversation lives in thread channel ${threadChannelId})`);
|
|
18818
|
+
}
|
|
18819
|
+
writeText(ctx.io, lines.join("\n") + "\n");
|
|
18820
|
+
}
|
|
18821
|
+
);
|
|
18822
|
+
function registerAttachmentCommentsCommand(parent, runtimeOptions) {
|
|
18823
|
+
registerCliCommand(parent, attachmentCommentsCommand, runtimeOptions);
|
|
18824
|
+
}
|
|
18825
|
+
|
|
18754
18826
|
// src/commands/task/_format.ts
|
|
18755
18827
|
function formatTaskList(channel, data, statusFilter) {
|
|
18756
18828
|
if (!data.tasks || data.tasks.length === 0) {
|
|
@@ -20390,6 +20462,7 @@ registerReactCommand(messageCmd);
|
|
|
20390
20462
|
var attachmentCmd = program.command("attachment").description("Attachment operations");
|
|
20391
20463
|
registerAttachmentUploadCommand(attachmentCmd);
|
|
20392
20464
|
registerAttachmentViewCommand(attachmentCmd);
|
|
20465
|
+
registerAttachmentCommentsCommand(attachmentCmd);
|
|
20393
20466
|
var taskCmd = program.command("task").description("Task board operations");
|
|
20394
20467
|
registerTaskListCommand(taskCmd);
|
|
20395
20468
|
registerTaskCreateCommand(taskCmd);
|
package/dist/core.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import {
|
|
2
|
-
DAEMON_API_KEY_ENV,
|
|
3
2
|
DAEMON_CLI_USAGE,
|
|
4
3
|
DaemonCore,
|
|
5
4
|
deleteWorkspaceDirectory,
|
|
@@ -7,13 +6,13 @@ import {
|
|
|
7
6
|
parseDaemonCliArgs,
|
|
8
7
|
readDaemonVersion,
|
|
9
8
|
resolveSlockCliPath,
|
|
9
|
+
resolveSlockCliPathOrEmpty,
|
|
10
10
|
resolveWorkspaceDirectoryPath,
|
|
11
|
+
runBundledSlockCli,
|
|
11
12
|
scanWorkspaceDirectories,
|
|
12
|
-
scrubDaemonAuthEnv,
|
|
13
13
|
subscribeDaemonLogs
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-XQ3HLMCZ.js";
|
|
15
15
|
export {
|
|
16
|
-
DAEMON_API_KEY_ENV,
|
|
17
16
|
DAEMON_CLI_USAGE,
|
|
18
17
|
DaemonCore,
|
|
19
18
|
deleteWorkspaceDirectory,
|
|
@@ -21,8 +20,9 @@ export {
|
|
|
21
20
|
parseDaemonCliArgs,
|
|
22
21
|
readDaemonVersion,
|
|
23
22
|
resolveSlockCliPath,
|
|
23
|
+
resolveSlockCliPathOrEmpty,
|
|
24
24
|
resolveWorkspaceDirectoryPath,
|
|
25
|
+
runBundledSlockCli,
|
|
25
26
|
scanWorkspaceDirectories,
|
|
26
|
-
scrubDaemonAuthEnv,
|
|
27
27
|
subscribeDaemonLogs
|
|
28
28
|
};
|