@slock-ai/daemon 0.52.1 → 0.52.2-play.20260522165849

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/cli/index.js CHANGED
@@ -14161,6 +14161,7 @@ var SERVER_CAPABILITY_MATRIX = {
14161
14161
  var RUNTIMES = [
14162
14162
  { id: "claude", displayName: "Claude Code", binary: "claude", supported: true },
14163
14163
  { id: "codex", displayName: "Codex CLI", binary: "codex", supported: true },
14164
+ { id: "pi", displayName: "Pi", binary: "pi", supported: true },
14164
14165
  { id: "kimi", displayName: "Kimi CLI", binary: "kimi", supported: true },
14165
14166
  { id: "copilot", displayName: "Copilot CLI", binary: "copilot", supported: true },
14166
14167
  { id: "cursor", displayName: "Cursor CLI", binary: "cursor-agent", supported: true },
@@ -14432,6 +14433,7 @@ var ApiClient = class {
14432
14433
  };
14433
14434
 
14434
14435
  // src/commands/action/prepare.ts
14436
+ var ACTION_HEREDOC_DELIMITER = "SLOCKACTION";
14435
14437
  var PrepareActionInputError = class extends Error {
14436
14438
  constructor(code, message) {
14437
14439
  super(message);
@@ -14451,9 +14453,9 @@ function missingActionMessage() {
14451
14453
  return [
14452
14454
  "No action JSON received on stdin.",
14453
14455
  "Pipe a JSON ActionCardAction object (channel:create / agent:create / channel:add_member) into slock action prepare:",
14454
- ` slock action prepare --target "#channel" <<'EOF'`,
14456
+ ` slock action prepare --target "#channel" <<'${ACTION_HEREDOC_DELIMITER}'`,
14455
14457
  ' {"type":"channel:create","name":"demo","visibility":"public"}',
14456
- " EOF"
14458
+ ` ${ACTION_HEREDOC_DELIMITER}`
14457
14459
  ].join("\n");
14458
14460
  }
14459
14461
  async function resolveActionInput(input = process.stdin) {
@@ -14573,7 +14575,7 @@ function formatServerInfo(data) {
14573
14575
  text += " (none)\n";
14574
14576
  }
14575
14577
  text += "\n### Humans\n";
14576
- text += `To start a new DM: slock message send --target "dm:@name" <<'EOF' followed by the message body and EOF. To reply in an existing DM: reuse the target from received messages.
14578
+ text += `To start a new DM: slock message send --target "dm:@name" <<'SLOCKMSG' followed by the message body and SLOCKMSG. To reply in an existing DM: reuse the target from received messages.
14577
14579
  `;
14578
14580
  if (humans.length > 0) {
14579
14581
  for (const u of humans) {
@@ -15063,6 +15065,7 @@ function clearSavedDraft(agentId, target) {
15063
15065
  }
15064
15066
 
15065
15067
  // src/commands/message/send.ts
15068
+ var MESSAGE_HEREDOC_DELIMITER = "SLOCKMSG";
15066
15069
  var SendContentError = class extends Error {
15067
15070
  constructor(code, message) {
15068
15071
  super(message);
@@ -15082,9 +15085,9 @@ function missingContentMessage() {
15082
15085
  return [
15083
15086
  "No message content received on stdin.",
15084
15087
  "Use a heredoc or pipe content into slock message send:",
15085
- ` slock message send --target "#channel" <<'EOF'`,
15088
+ ` slock message send --target "#channel" <<'${MESSAGE_HEREDOC_DELIMITER}'`,
15086
15089
  " message body",
15087
- " EOF"
15090
+ ` ${MESSAGE_HEREDOC_DELIMITER}`
15088
15091
  ].join("\n");
15089
15092
  }
15090
15093
  async function resolveSendContent(input = process.stdin) {
@@ -15111,9 +15114,9 @@ function rejectArgContent(positionalContent, opts) {
15111
15114
  [
15112
15115
  "Message content must be provided on stdin, not as positional arguments.",
15113
15116
  "Use:",
15114
- ` slock message send --target "#channel" <<'EOF'`,
15117
+ ` slock message send --target "#channel" <<'${MESSAGE_HEREDOC_DELIMITER}'`,
15115
15118
  " message body",
15116
- " EOF"
15119
+ ` ${MESSAGE_HEREDOC_DELIMITER}`
15117
15120
  ].join("\n")
15118
15121
  );
15119
15122
  }
@@ -15149,9 +15152,9 @@ function rejectSendDraftStdin(content, target) {
15149
15152
  [
15150
15153
  "--send-draft sends the current saved draft and does not accept stdin.",
15151
15154
  "To update the draft, send the revised content normally without --send-draft:",
15152
- ` slock message send --target "${target}" <<'EOF'`,
15155
+ ` slock message send --target "${target}" <<'${MESSAGE_HEREDOC_DELIMITER}'`,
15153
15156
  " revised message",
15154
- " EOF"
15157
+ ` ${MESSAGE_HEREDOC_DELIMITER}`
15155
15158
  ].join("\n")
15156
15159
  );
15157
15160
  }
@@ -15159,9 +15162,9 @@ function formatHeldSendOutput(target, data) {
15159
15162
  return formatFreshnessHoldOutput(target, data, {
15160
15163
  heldAction: "Your message has been saved as a draft.",
15161
15164
  draftInstructions: `To update the draft, send revised content normally:
15162
- slock message send --target "${target}" <<'EOF'
15165
+ slock message send --target "${target}" <<'${MESSAGE_HEREDOC_DELIMITER}'
15163
15166
  revised message
15164
- EOF
15167
+ ${MESSAGE_HEREDOC_DELIMITER}
15165
15168
  To send the current draft unchanged:
15166
15169
  slock message send --send-draft --target "${target}"
15167
15170
  `,
@@ -15216,9 +15219,9 @@ function registerSendCommand(parent) {
15216
15219
  [
15217
15220
  "No saved draft exists for this target.",
15218
15221
  "To create or update a draft, send message content normally:",
15219
- ` slock message send --target "${opts.target}" <<'EOF'`,
15222
+ ` slock message send --target "${opts.target}" <<'${MESSAGE_HEREDOC_DELIMITER}'`,
15220
15223
  " message body",
15221
- " EOF"
15224
+ ` ${MESSAGE_HEREDOC_DELIMITER}`
15222
15225
  ].join("\n")
15223
15226
  );
15224
15227
  return;
@@ -16170,6 +16173,153 @@ function registerProfileUpdateCommand(parent) {
16170
16173
  });
16171
16174
  }
16172
16175
 
16176
+ // src/commands/integration/_format.ts
16177
+ function formatMaybe(value) {
16178
+ return value?.trim() || "-";
16179
+ }
16180
+ function buildAgentAppUrl(returnUrl, requestId) {
16181
+ if (!returnUrl?.trim()) return null;
16182
+ try {
16183
+ const url2 = new URL(returnUrl);
16184
+ url2.searchParams.set("code", requestId);
16185
+ return url2.toString();
16186
+ } catch {
16187
+ return null;
16188
+ }
16189
+ }
16190
+ function formatIntegrationList(data) {
16191
+ const activeByServiceId = new Map(data.activeLogins.map((login) => [login.serviceId, login]));
16192
+ const lines = [];
16193
+ lines.push("Registered services:");
16194
+ if (data.services.length === 0) {
16195
+ lines.push("- none");
16196
+ } else {
16197
+ for (const service of data.services) {
16198
+ const active = activeByServiceId.get(service.id);
16199
+ lines.push(`- ${service.name}`);
16200
+ lines.push(` service: ${service.clientId}`);
16201
+ lines.push(` id: ${service.id}`);
16202
+ lines.push(` status: ${active ? "active login" : "not logged in"}`);
16203
+ lines.push(` return URL: ${formatMaybe(service.returnUrl)}`);
16204
+ if (service.homepageUrl) lines.push(` homepage: ${service.homepageUrl}`);
16205
+ if (service.description) lines.push(` description: ${service.description}`);
16206
+ if (!active) lines.push(` next: slock integration login --service ${JSON.stringify(service.clientId)}`);
16207
+ }
16208
+ }
16209
+ lines.push("");
16210
+ lines.push("Active agent logins:");
16211
+ if (data.activeLogins.length === 0) {
16212
+ lines.push("- none");
16213
+ } else {
16214
+ for (const login of data.activeLogins) {
16215
+ lines.push(`- ${login.name}`);
16216
+ lines.push(` service: ${login.clientId}`);
16217
+ lines.push(` grant id: ${login.id}`);
16218
+ lines.push(` scopes: ${login.scopes.length > 0 ? login.scopes.join(", ") : "-"}`);
16219
+ lines.push(` return URL: ${formatMaybe(login.returnUrl)}`);
16220
+ lines.push(` created: ${login.createdAt}`);
16221
+ }
16222
+ }
16223
+ return lines.join("\n");
16224
+ }
16225
+ function formatIntegrationLogin(data) {
16226
+ const verb = data.status === "already_logged_in" ? "Already logged in" : "Agent login ready";
16227
+ const lines = [
16228
+ `${verb}: ${data.service.name}`,
16229
+ `service: ${data.service.clientId}`,
16230
+ `id: ${data.service.id}`,
16231
+ `scopes: ${data.scopes.length > 0 ? data.scopes.join(", ") : "-"}`,
16232
+ `return URL: ${formatMaybe(data.service.returnUrl)}`,
16233
+ "complete: this agent login is configured in Slock; no human OAuth is required",
16234
+ "identity: run `slock profile show` if the service or human asks for your Slock Agent identity card"
16235
+ ];
16236
+ const agentAppUrl = buildAgentAppUrl(data.service.returnUrl, data.requestId);
16237
+ if (agentAppUrl) {
16238
+ lines.push(`app URL: ${agentAppUrl}`);
16239
+ lines.push("next: open the app URL if you need the third-party app surface, or run `slock integration list` to confirm active login");
16240
+ } else {
16241
+ lines.push("next: use the registered service, or run `slock integration list` to confirm active login");
16242
+ }
16243
+ return lines.join("\n");
16244
+ }
16245
+
16246
+ // src/commands/integration/list.ts
16247
+ function registerIntegrationListCommand(parent) {
16248
+ parent.command("list").description("List registered third-party services and this agent's active logins").option("--json", "Emit machine-readable JSON").action(async (opts) => {
16249
+ let ctx;
16250
+ try {
16251
+ ctx = loadAgentContext();
16252
+ } catch (err) {
16253
+ if (err instanceof AgentBootstrapError) fail(err.code, err.message);
16254
+ throw err;
16255
+ }
16256
+ const client = new ApiClient(ctx);
16257
+ const res = await client.request(
16258
+ "GET",
16259
+ `/internal/agent/${encodeURIComponent(ctx.agentId)}/integrations`
16260
+ );
16261
+ if (!res.ok || !res.data) {
16262
+ const code = res.status >= 500 ? "SERVER_5XX" : "INTEGRATION_LIST_FAILED";
16263
+ fail(code, res.error ?? `HTTP ${res.status}`);
16264
+ }
16265
+ if (opts.json) {
16266
+ emit({ ok: true, data: res.data });
16267
+ return;
16268
+ }
16269
+ process.stdout.write(`${formatIntegrationList(res.data)}
16270
+ `);
16271
+ });
16272
+ }
16273
+
16274
+ // src/commands/integration/login.ts
16275
+ function normalizeScopes(raw) {
16276
+ if (!raw || raw.length === 0) return void 0;
16277
+ const scopes = Array.from(new Set(
16278
+ raw.flatMap((value) => value.split(",")).map((value) => value.trim()).filter(Boolean)
16279
+ )).sort();
16280
+ if (scopes.length === 0) {
16281
+ fail("INVALID_ARG", "--scope must include at least one non-empty scope");
16282
+ }
16283
+ return scopes;
16284
+ }
16285
+ function registerIntegrationLoginCommand(parent) {
16286
+ parent.command("login").description("Provision or reuse this agent's login for a registered service").requiredOption("--service <id>", "Registered service id, client id, or exact service name").option("--scope <scope>", "Requested scope; can be repeated or comma-separated", (value, previous = []) => {
16287
+ previous.push(value);
16288
+ return previous;
16289
+ }).option("--json", "Emit machine-readable JSON").action(async (opts) => {
16290
+ let ctx;
16291
+ try {
16292
+ ctx = loadAgentContext();
16293
+ } catch (err) {
16294
+ if (err instanceof AgentBootstrapError) fail(err.code, err.message);
16295
+ throw err;
16296
+ }
16297
+ const service = opts.service.trim();
16298
+ if (!service) {
16299
+ fail("INVALID_ARG", "--service must not be empty");
16300
+ }
16301
+ const client = new ApiClient(ctx);
16302
+ const res = await client.request(
16303
+ "POST",
16304
+ `/internal/agent/${encodeURIComponent(ctx.agentId)}/integrations/login`,
16305
+ {
16306
+ service,
16307
+ scopes: normalizeScopes(opts.scope)
16308
+ }
16309
+ );
16310
+ if (!res.ok || !res.data) {
16311
+ const code = res.status >= 500 ? "SERVER_5XX" : "INTEGRATION_LOGIN_FAILED";
16312
+ fail(code, res.error ?? `HTTP ${res.status}`);
16313
+ }
16314
+ if (opts.json) {
16315
+ emit({ ok: true, data: res.data });
16316
+ return;
16317
+ }
16318
+ process.stdout.write(`${formatIntegrationLogin(res.data)}
16319
+ `);
16320
+ });
16321
+ }
16322
+
16173
16323
  // src/commands/reminder/_format.ts
16174
16324
  var MODIFY_HINT = "(to modify: snooze/update/cancel; slock reminder --help)";
16175
16325
  function formatReminder(r) {
@@ -16562,6 +16712,9 @@ registerTaskUpdateCommand(taskCmd);
16562
16712
  var profileCmd = program.command("profile").description("Profile operations");
16563
16713
  registerProfileShowCommand(profileCmd);
16564
16714
  registerProfileUpdateCommand(profileCmd);
16715
+ var integrationCmd = program.command("integration").description("Third-party service integration operations");
16716
+ registerIntegrationListCommand(integrationCmd);
16717
+ registerIntegrationLoginCommand(integrationCmd);
16565
16718
  var reminderCmd = program.command("reminder").description("Reminder operations");
16566
16719
  registerReminderScheduleCommand(reminderCmd);
16567
16720
  registerReminderListCommand(reminderCmd);
package/dist/core.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import {
2
+ DAEMON_API_KEY_ENV,
2
3
  DAEMON_CLI_USAGE,
3
4
  DaemonCore,
4
5
  deleteWorkspaceDirectory,
@@ -8,12 +9,14 @@ import {
8
9
  resolveChatBridgePath,
9
10
  resolveSlockCliPath,
10
11
  resolveWorkspaceDirectoryPath,
11
- scanWorkspaceDirectories
12
- } from "./chunk-WGO5H7XX.js";
12
+ scanWorkspaceDirectories,
13
+ scrubDaemonAuthEnv
14
+ } from "./chunk-AGSYS44K.js";
13
15
  import {
14
16
  subscribeDaemonLogs
15
17
  } from "./chunk-KNMCE6WB.js";
16
18
  export {
19
+ DAEMON_API_KEY_ENV,
17
20
  DAEMON_CLI_USAGE,
18
21
  DaemonCore,
19
22
  deleteWorkspaceDirectory,
@@ -24,5 +27,6 @@ export {
24
27
  resolveSlockCliPath,
25
28
  resolveWorkspaceDirectoryPath,
26
29
  scanWorkspaceDirectories,
30
+ scrubDaemonAuthEnv,
27
31
  subscribeDaemonLogs
28
32
  };
@@ -0,0 +1,96 @@
1
+ // src/drivers/piSdkRunner.ts
2
+ import { readFile } from "fs/promises";
3
+ import path from "path";
4
+ import {
5
+ AuthStorage,
6
+ createAgentSessionFromServices,
7
+ createAgentSessionServices,
8
+ SessionManager
9
+ } from "@earendil-works/pi-coding-agent";
10
+ function writeJson(value) {
11
+ process.stdout.write(`${JSON.stringify(value)}
12
+ `);
13
+ }
14
+ function parseArgs(argv) {
15
+ const index = argv.indexOf("--config");
16
+ const configPath = index >= 0 ? argv[index + 1] : void 0;
17
+ if (!configPath) throw new Error("Missing --config <path>");
18
+ return { configPath };
19
+ }
20
+ function resolveConfiguredModel(modelId, modelRegistry) {
21
+ if (!modelId) return void 0;
22
+ const [provider, ...rest] = modelId.split("/");
23
+ const providerScopedId = rest.join("/");
24
+ if (provider && providerScopedId) {
25
+ const exact = modelRegistry.find(provider, providerScopedId);
26
+ if (exact) return exact;
27
+ }
28
+ return modelRegistry.getAll().find(
29
+ (model) => model.id === modelId || `${model.provider}/${model.id}` === modelId || (providerScopedId ? model.id === providerScopedId : false)
30
+ );
31
+ }
32
+ async function createSessionManager(config) {
33
+ if (!config.sessionId) return SessionManager.create(config.cwd, config.sessionDir);
34
+ const localSessions = await SessionManager.list(config.cwd, config.sessionDir);
35
+ const match = localSessions.find((session) => session.id.startsWith(config.sessionId));
36
+ if (match) return SessionManager.open(match.path, config.sessionDir);
37
+ return SessionManager.create(config.cwd, config.sessionDir);
38
+ }
39
+ async function run() {
40
+ const { configPath } = parseArgs(process.argv.slice(2));
41
+ const config = JSON.parse(await readFile(configPath, "utf8"));
42
+ const authStorage = AuthStorage.create(path.join(config.agentDir, "auth.json"));
43
+ const services = await createAgentSessionServices({
44
+ cwd: config.cwd,
45
+ agentDir: config.agentDir,
46
+ authStorage,
47
+ resourceLoaderOptions: {
48
+ appendSystemPrompt: [config.standingPrompt],
49
+ noContextFiles: true,
50
+ noExtensions: true,
51
+ noPromptTemplates: true,
52
+ noSkills: true,
53
+ noThemes: true
54
+ }
55
+ });
56
+ for (const diagnostic of services.diagnostics) {
57
+ const line = `[Pi SDK] ${diagnostic.type}: ${diagnostic.message}`;
58
+ if (diagnostic.type === "error") throw new Error(line);
59
+ process.stderr.write(`${line}
60
+ `);
61
+ }
62
+ const sessionManager = await createSessionManager(config);
63
+ const model = resolveConfiguredModel(config.model, services.modelRegistry);
64
+ if (config.model && !model) {
65
+ throw new Error(`Configured Pi model '${config.model}' was not found in Pi model registry.`);
66
+ }
67
+ const { session } = await createAgentSessionFromServices({
68
+ services,
69
+ sessionManager,
70
+ model
71
+ });
72
+ const header = session.sessionManager.getHeader();
73
+ if (header) writeJson(header);
74
+ const unsubscribe = session.subscribe((event) => writeJson(event));
75
+ try {
76
+ await session.prompt(config.prompt);
77
+ } finally {
78
+ unsubscribe();
79
+ session.dispose();
80
+ await services.settingsManager.flush();
81
+ }
82
+ }
83
+ run().catch((error) => {
84
+ const message = error instanceof Error ? error.message : String(error);
85
+ writeJson({
86
+ type: "message_end",
87
+ message: {
88
+ role: "assistant",
89
+ content: [],
90
+ stopReason: "error",
91
+ errorMessage: message
92
+ }
93
+ });
94
+ writeJson({ type: "turn_end" });
95
+ process.exitCode = 1;
96
+ });
package/dist/index.js CHANGED
@@ -2,12 +2,14 @@
2
2
  import {
3
3
  DAEMON_CLI_USAGE,
4
4
  DaemonCore,
5
- parseDaemonCliArgs
6
- } from "./chunk-WGO5H7XX.js";
5
+ parseDaemonCliArgs,
6
+ scrubDaemonAuthEnv
7
+ } from "./chunk-AGSYS44K.js";
7
8
  import "./chunk-KNMCE6WB.js";
8
9
 
9
10
  // src/index.ts
10
- var parsedArgs = parseDaemonCliArgs(process.argv.slice(2));
11
+ var parsedArgs = parseDaemonCliArgs(process.argv.slice(2), process.env);
12
+ scrubDaemonAuthEnv(process.env);
11
13
  if (!parsedArgs) {
12
14
  console.error(DAEMON_CLI_USAGE);
13
15
  process.exit(1);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@slock-ai/daemon",
3
- "version": "0.52.1",
3
+ "version": "0.52.2-play.20260522165849",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "slock-daemon": "dist/index.js"
@@ -36,6 +36,8 @@
36
36
  "release:alpha": "npm version prerelease --preid=alpha --no-git-tag-version && cd ../.. && pnpm install --lockfile-only && git add packages/daemon/package.json pnpm-lock.yaml && git commit -m \"chore: bump @slock-ai/daemon to v$(node -p \"require('./packages/daemon/package.json').version\")\" && git tag daemon-v$(node -p \"require('./packages/daemon/package.json').version\") && git push && git push --tags"
37
37
  },
38
38
  "dependencies": {
39
+ "@earendil-works/pi-coding-agent": "0.74.0",
40
+ "@jackwener/opencli": "^1.8.0",
39
41
  "@modelcontextprotocol/sdk": "^1.29.0",
40
42
  "commander": "^12.1.0",
41
43
  "https-proxy-agent": "^7.0.6",