@agentconnect.md/daemon 1.0.0-rc.296 → 1.0.0-rc.298

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.
Files changed (28) hide show
  1. package/dist/{acp-host-03mQVw2Q.js → acp-host-DezWSmEG.js} +2 -2
  2. package/dist/{acp-host-03mQVw2Q.js.map → acp-host-DezWSmEG.js.map} +1 -1
  3. package/dist/{agent-list-DHFLd9ux.js → agent-list-Da9Osn4O.js} +2 -2
  4. package/dist/{agent-list-DHFLd9ux.js.map → agent-list-Da9Osn4O.js.map} +1 -1
  5. package/dist/{chat-IRJd4_lj.js → chat-D8QIIHor.js} +3 -3
  6. package/dist/{chat-IRJd4_lj.js.map → chat-D8QIIHor.js.map} +1 -1
  7. package/dist/{load-agents-8AzZXdVx.js → dist-Cq1Kimg_.js} +18 -399
  8. package/dist/dist-Cq1Kimg_.js.map +1 -0
  9. package/dist/gh-token-BfPlYQav.js +97 -0
  10. package/dist/gh-token-BfPlYQav.js.map +1 -0
  11. package/dist/{git-credential-DLRF9bOx.js → git-credential-DhWn1IBJ.js} +26 -8
  12. package/dist/git-credential-DhWn1IBJ.js.map +1 -0
  13. package/dist/{gitcred-server-Dhp-tyEI.js → gitcred-server-KXxLyYxc.js} +107 -55
  14. package/dist/gitcred-server-KXxLyYxc.js.map +1 -0
  15. package/dist/index.js +9 -5
  16. package/dist/index.js.map +1 -1
  17. package/dist/load-agents-gTqVkOwl.js +401 -0
  18. package/dist/load-agents-gTqVkOwl.js.map +1 -0
  19. package/dist/{login-vU_lQeMG.js → login-ycknK_Ag.js} +4 -3
  20. package/dist/{login-vU_lQeMG.js.map → login-ycknK_Ag.js.map} +1 -1
  21. package/dist/run-foreground-B5Uw1HWo.js +2 -0
  22. package/dist/{run-foreground-DasVEmdw.js → run-foreground-qa22G1Nt.js} +172 -20
  23. package/dist/{run-foreground-DasVEmdw.js.map → run-foreground-qa22G1Nt.js.map} +1 -1
  24. package/package.json +1 -1
  25. package/dist/git-credential-DLRF9bOx.js.map +0 -1
  26. package/dist/gitcred-server-Dhp-tyEI.js.map +0 -1
  27. package/dist/load-agents-8AzZXdVx.js.map +0 -1
  28. package/dist/run-foreground-K-ATxgOm.js +0 -2
@@ -3,11 +3,13 @@ import { n as require_ms, t as require_src$3 } from "./src-DDtlVutj.js";
3
3
  import { n as init_esm_shims, t as __dirname } from "./esm-shims-DxGcm4Hw.js";
4
4
  import { t as DAEMON_VERSION } from "./version-DGaRXjBK.js";
5
5
  import { C as _coercedNumber, T as NEVER, a as array, d as literal, f as looseObject, i as any, m as object, o as boolean, p as number$1, t as ZodNumber, v as string, x as url$4 } from "./schemas-CQkO9hC5.js";
6
- import { C as ZodIssueCode, S as RESERVED_MCP_SERVER_NAME, _ as buildEnvelope, a as agentChildEnv, b as MAX_FRAME_BYTES, c as persistRelays, d as normalizeGitUrl, f as RELAY_DAEMON_SUBPROTOCOL, g as SHARED_CONFIG_ACTION_ID, h as decodeRelayDaemonFrame, i as selectAgent, m as buildRelayDaemonFrame, n as findAgentFiles, o as loadConfig, p as RELAY_DAEMON_WS_PATH, r as loadAgents, s as persistDaemonId, v as decodeEnvelope, y as encode } from "./load-agents-8AzZXdVx.js";
6
+ import { a as RELAY_DAEMON_WS_PATH, c as SHARED_CONFIG_ACTION_ID, d as encode, f as MAX_FRAME_BYTES, g as ZodIssueCode, h as RESERVED_MCP_SERVER_NAME, i as RELAY_DAEMON_SUBPROTOCOL, l as buildEnvelope, n as gitRepoLabel, o as buildRelayDaemonFrame, r as normalizeGitUrl, s as decodeRelayDaemonFrame, u as decodeEnvelope } from "./dist-Cq1Kimg_.js";
7
+ import { a as agentChildEnv, c as persistRelays, i as selectAgent, n as findAgentFiles, o as loadConfig, r as loadAgents, s as persistDaemonId } from "./load-agents-gTqVkOwl.js";
7
8
  import { l as resolveRoot, o as mcpSocketPath, u as statePath } from "./paths-DEcUO8lC.js";
8
- import { S as resolveRuntimes, _ as writeMemoryFile, a as initGitInjection, b as cachedRuntimeNames, c as simpleGit, d as memoryProviderFor, f as MemoryConflictError, g as resolveInMemoryDir, h as listMemory, i as prepareWorkspace, l as createMemoryProvider, m as MemoryTooLargeError, n as installedRuntimes, o as probeGitVersion, p as MemoryPathError, r as prefetchWorkspace, s as sessionGitEnv, t as AcpHost, u as memoryKindOf, v as MEMORY_TOOL_NAMES, x as cachedRuntimeVersions, y as toolsForIntegrations } from "./acp-host-03mQVw2Q.js";
9
- import { i as GitCredentialCache, n as gitcredSocketPath, r as writeGitcredShim, t as GitCredServer } from "./gitcred-server-Dhp-tyEI.js";
9
+ import { S as resolveRuntimes, _ as writeMemoryFile, a as initGitInjection, b as cachedRuntimeNames, c as simpleGit, d as memoryProviderFor, f as MemoryConflictError, g as resolveInMemoryDir, h as listMemory, i as prepareWorkspace, l as createMemoryProvider, m as MemoryTooLargeError, n as installedRuntimes, o as probeGitVersion, p as MemoryPathError, r as prefetchWorkspace, s as sessionGitEnv, t as AcpHost, u as memoryKindOf, v as MEMORY_TOOL_NAMES, x as cachedRuntimeVersions, y as toolsForIntegrations } from "./acp-host-DezWSmEG.js";
10
+ import { i as GitCredentialCache, n as gitcredSocketPath, r as writeGitcredShim, t as GitCredServer } from "./gitcred-server-KXxLyYxc.js";
10
11
  import { B as ToolListChangedNotificationSchema, D as ListPromptsResultSchema, E as ListChangedOptionsBaseSchema, F as PromptListChangedNotificationSchema, G as isZ4Schema, H as isJSONRPCRequest, I as ReadResourceResultSchema, J as encodeFrame, K as safeParse, L as ResourceListChangedNotificationSchema, M as ListToolsResultSchema, O as ListResourceTemplatesResultSchema, P as McpError, R as SUPPORTED_PROTOCOL_VERSIONS, S as InitializeResultSchema, T as LATEST_PROTOCOL_VERSION, U as isJSONRPCResultResponse, V as isInitializedNotification, W as getObjectShape, _ as ElicitResultSchema, a as AjvJsonSchemaValidator, b as GetPromptResultSchema, c as mergeCapabilities, d as CompleteResultSchema, f as CreateMessageRequestSchema, g as ElicitRequestSchema, h as CreateTaskResultSchema, i as assertToolsCallTaskCapability, k as ListResourcesResultSchema, m as CreateMessageResultWithToolsSchema, n as serializeMessage, o as require_fast_deep_equal, p as CreateMessageResultSchema, q as decodeFrames, r as assertClientRequestTaskCapability, s as Protocol, t as ReadBuffer, u as CallToolResultSchema, v as EmptyResultSchema, w as JSONRPCMessageSchema, y as ErrorCode } from "./stdio-DnS8WcXi.js";
12
+ import { createRequire } from "node:module";
11
13
  import { URL as URL$1 } from "url";
12
14
  import * as tls from "tls";
13
15
  import * as net$5 from "net";
@@ -7583,6 +7585,119 @@ var McpControlServer = class {
7583
7585
  }
7584
7586
  };
7585
7587
  //#endregion
7588
+ //#region src/cp/gh-shim.ts
7589
+ /**
7590
+ * run/bin/gh — the gh wrapper shim (agent-multi-repo-authorization.md decision
7591
+ * 4, issue #457).
7592
+ *
7593
+ * `gh` has no credential-helper hook: it reads a STATIC `GH_TOKEN` fixed at
7594
+ * process spawn, which is why P2.5's injected token went stale after ≤1h and
7595
+ * could only ever name the workspace repo. The daemon prepends `run/bin` to
7596
+ * the agent runtime's PATH so every `gh …` the agent runs lands here first;
7597
+ * the wrapper resolves the TARGET repo (GH_REPO → -R/--repo → cwd origin),
7598
+ * pulls that repo's fresh token through gitcred.sock (`agentconnect gh-token`,
7599
+ * same socket + cache as the git credential helper) and exec's the real gh
7600
+ * with GH_TOKEN set. Per-invocation fresh + per-repo correct.
7601
+ *
7602
+ * Precedence: a USER-supplied GH_TOKEN must win (the `daemon.ts` env-injection
7603
+ * contract) — the daemon exports the spawn token under both GH_TOKEN and the
7604
+ * AC_GH_TOKEN_INJECTED sentinel, so `GH_TOKEN != sentinel` means the user set
7605
+ * their own and the wrapper defers entirely. When the daemon can't serve a
7606
+ * token (repo unauthorized, CP down) the wrapper prints the daemon's
7607
+ * actionable reason on stderr and falls back to the spawn-time env token.
7608
+ *
7609
+ * The script is SECRET-FREE (paths + agent id only) and regenerated every
7610
+ * daemon boot, like `git-credential-helper.sh`. Tokens transit a shell
7611
+ * variable and the exec'd process env — never argv, never disk.
7612
+ */
7613
+ function ghShimDir(root) {
7614
+ return join(root, "run", "bin");
7615
+ }
7616
+ /** (Re)write `run/bin/gh` and return the bin dir to prepend to agent PATHs. */
7617
+ function writeGhShim(root, cliEntry) {
7618
+ const dir = ghShimDir(root);
7619
+ mkdirSync(dir, {
7620
+ recursive: true,
7621
+ mode: 448
7622
+ });
7623
+ try {
7624
+ chmodSync(dir, 448);
7625
+ } catch {}
7626
+ const q = (v) => `'${v.replaceAll("'", "'\\''")}'`;
7627
+ const argv = [q(process.execPath)];
7628
+ if (cliEntry.endsWith(".ts")) {
7629
+ const req = createRequire(import.meta.url);
7630
+ argv.push(q(req.resolve("tsx/cli")));
7631
+ }
7632
+ argv.push(q(cliEntry));
7633
+ const cli = argv.join(" ");
7634
+ const body = `#!/bin/sh
7635
+ # agentconnect gh wrapper — regenerated on daemon start; NO secrets.
7636
+ # Per-repo, per-invocation GH_TOKEN via the daemon socket (issue #457).
7637
+
7638
+ SELF_DIR=${q(dir)}
7639
+
7640
+ # The real gh: first one on PATH outside our own bin dir.
7641
+ REAL_GH=""
7642
+ _OLDIFS=$IFS; IFS=:
7643
+ for _d in $PATH; do
7644
+ [ "$_d" = "$SELF_DIR" ] && continue
7645
+ if [ -x "$_d/gh" ]; then REAL_GH="$_d/gh"; break; fi
7646
+ done
7647
+ IFS=$_OLDIFS
7648
+ if [ -z "$REAL_GH" ]; then
7649
+ echo "agentconnect: gh is not installed on this machine" >&2
7650
+ exit 127
7651
+ fi
7652
+
7653
+ # A user-configured GH_TOKEN wins: the daemon-injected one always equals the
7654
+ # AC_GH_TOKEN_INJECTED sentinel, so any difference means "the user set it".
7655
+ if [ -n "$GH_TOKEN" ] && [ "$GH_TOKEN" != "$AC_GH_TOKEN_INJECTED" ]; then
7656
+ exec "$REAL_GH" "$@"
7657
+ fi
7658
+ if [ -z "$AC_AGENT_ID" ]; then
7659
+ exec "$REAL_GH" "$@"
7660
+ fi
7661
+
7662
+ # Target repo: -R/--repo argv (all spellings, last wins — matches gh's pflag),
7663
+ # then GH_REPO env (gh gives the flag precedence over the env), then the cwd
7664
+ # origin remote. Scans a COPY of the args (for-loop doesn't consume "$@").
7665
+ _REPO=""
7666
+ _prev=""
7667
+ for _a in "$@"; do
7668
+ case "$_prev" in
7669
+ -R|--repo) _REPO="$_a" ;;
7670
+ esac
7671
+ case "$_a" in
7672
+ --repo=*) _REPO="\${_a#--repo=}" ;;
7673
+ -R=*) _REPO="\${_a#-R=}" ;;
7674
+ -R?*) _REPO="\${_a#-R}" ;;
7675
+ esac
7676
+ _prev="$_a"
7677
+ done
7678
+ if [ -z "$_REPO" ]; then _REPO="$GH_REPO"; fi
7679
+ if [ -z "$_REPO" ]; then
7680
+ _REPO=$(git remote get-url origin 2>/dev/null || true)
7681
+ fi
7682
+
7683
+ # Fresh token from the daemon (stdout = token only; stderr passes through so
7684
+ # the agent can read WHY a repo was refused). Exit 2 = "not ours" (non-github
7685
+ # host) — run the real gh untouched.
7686
+ _TOKEN=$(AGENTCONNECT_ROOT=${q(root)} ${cli} gh-token "$AC_AGENT_ID" "$_REPO")
7687
+ _RC=$?
7688
+ if [ "$_RC" -eq 2 ]; then
7689
+ exec "$REAL_GH" "$@"
7690
+ fi
7691
+ if [ -n "$_TOKEN" ]; then
7692
+ GH_TOKEN="$_TOKEN" exec "$REAL_GH" "$@"
7693
+ fi
7694
+ # Daemon couldn't serve one — fall back to the spawn-time env token (if any).
7695
+ exec "$REAL_GH" "$@"
7696
+ `;
7697
+ writeFileSync(join(dir, "gh"), body, { mode: 493 });
7698
+ return dir;
7699
+ }
7700
+ //#endregion
7586
7701
  //#region src/mcp/inject.ts
7587
7702
  /**
7588
7703
  * Build the `mcpServers` entry that makes the agent harness spawn our stdio
@@ -214910,6 +215025,9 @@ var Daemon = class Daemon {
214910
215025
  });
214911
215026
  gitCreds;
214912
215027
  gitCredServer;
215028
+ /** run/bin with the gh wrapper (multi-repo #457) — prepended to github-app
215029
+ * agents' PATH at host spawn; unset ⇒ shim write failed, spawn without it. */
215030
+ ghBinDir;
214913
215031
  agents = /* @__PURE__ */ new Map();
214914
215032
  fileAgents = /* @__PURE__ */ new Map();
214915
215033
  hosts = /* @__PURE__ */ new Map();
@@ -214998,9 +215116,21 @@ var Daemon = class Daemon {
214998
215116
  await this.gitCreds.get(agentId, reason);
214999
215117
  }
215000
215118
  });
215119
+ try {
215120
+ this.ghBinDir = writeGhShim(root, process.argv[1] ?? "");
215121
+ } catch (err) {
215122
+ this.log.warn(`gitcred: gh wrapper shim write failed — spawning agents without it (${formatErr(err)})`);
215123
+ }
215001
215124
  this.gitCredServer = new GitCredServer(this.gitCreds, gitcredSocketPath(root), {
215002
- info: (m) => this.log.info(m),
215003
- warn: (m) => this.log.warn(m)
215125
+ log: {
215126
+ info: (m) => this.log.info(m),
215127
+ warn: (m) => this.log.warn(m)
215128
+ },
215129
+ workspaceRepoOf: (agentId) => {
215130
+ const ws = this.agents.get(agentId)?.workspace;
215131
+ if (ws?.mode !== "git-repo" || !ws.gitRepo) return void 0;
215132
+ return gitRepoLabel(ws.gitRepo) ?? void 0;
215133
+ }
215004
215134
  });
215005
215135
  this.gitCredServer.start();
215006
215136
  probeGitVersion((m) => this.log.warn(m));
@@ -215731,17 +215861,26 @@ var Daemon = class Daemon {
215731
215861
  else {
215732
215862
  const runtime = this.runtimes[agent.runtime];
215733
215863
  if (!runtime) throw new Error(`runtime "${agent.runtime}" not available: not installed on this host, or absent from config.runtimes / the ACP registry`);
215864
+ const githubApp = agent.workspace.mode === "git-repo" && agent.workspace.gitCredential === "github-app";
215865
+ const env = {
215866
+ ...ghToken ? {
215867
+ GH_TOKEN: ghToken,
215868
+ AC_GH_TOKEN_INJECTED: ghToken
215869
+ } : {},
215870
+ ...agentChildEnv(agent),
215871
+ ...cpRuntimeEnv(agent),
215872
+ ...memoryProviderFor(agent, runtime).runtimeEnv(),
215873
+ ...githubApp ? sessionGitEnv(agent.id) : {}
215874
+ };
215875
+ if (githubApp && this.ghBinDir) {
215876
+ env.AC_AGENT_ID = agent.id;
215877
+ env.PATH = `${this.ghBinDir}:${env.PATH ?? process.env.PATH ?? ""}`;
215878
+ }
215734
215879
  host = new AcpHost(runtime, {
215735
215880
  onUpdate,
215736
215881
  onPermission: (sid, params) => this.onAcpPermission(agentId, sid, params),
215737
215882
  onElicit: (sid, params) => this.onAcpElicit(agentId, sid, params),
215738
- env: {
215739
- ...ghToken ? { GH_TOKEN: ghToken } : {},
215740
- ...agentChildEnv(agent),
215741
- ...cpRuntimeEnv(agent),
215742
- ...memoryProviderFor(agent, runtime).runtimeEnv(),
215743
- ...agent.workspace.mode === "git-repo" && agent.workspace.gitCredential === "github-app" ? sessionGitEnv(agent.id) : {}
215744
- },
215883
+ env,
215745
215884
  configPrefs: {
215746
215885
  model: agent.runtimeOverrides?.model,
215747
215886
  permissionMode: agent.permissionMode,
@@ -217379,7 +217518,10 @@ var Daemon = class Daemon {
217379
217518
  index: 0,
217380
217519
  replyText: ""
217381
217520
  } } : {},
217382
- ...githubReply ? { github: this.makeGithubReply(agentId, githubReply, sessionId) } : {}
217521
+ ...githubReply ? { github: {
217522
+ ...this.makeGithubReply(agentId, githubReply, sessionId),
217523
+ deferredFinalTranscript: false
217524
+ } } : {}
217383
217525
  };
217384
217526
  this.pending.set(sessionId, p);
217385
217527
  if (callMeta) this.activeTurnCallMeta.set(key, callMeta);
@@ -217460,7 +217602,16 @@ var Daemon = class Daemon {
217460
217602
  this.releaseElicits(sessionId);
217461
217603
  if (callMeta) this.activeTurnCallMeta.delete(key);
217462
217604
  this.clearCancelBackstop(sessionId);
217463
- if (p.github) await p.github.stream.finish(p.github.collector.finalText(finalPhase === "end")).catch((err) => this.log.warn(`github poster: final flush failed (${formatErr(err)})`));
217605
+ const githubFinal = p.github && finalPhase === "end" ? p.github.collector.finalText(true) : void 0;
217606
+ if (p.github?.deferredFinalTranscript && githubFinal?.trim()) this.store.appendTranscript({
217607
+ channel: p.channel,
217608
+ thread: p.statusThread,
217609
+ ts: monotonicTs(),
217610
+ sender: p.agentId,
217611
+ kind: "text",
217612
+ text: githubFinal
217613
+ });
217614
+ if (p.github) await p.github.stream.finish(githubFinal).catch((err) => this.log.warn(`github poster: final flush failed (${formatErr(err)})`));
217464
217615
  this.pending.delete(sessionId);
217465
217616
  this.store.setSessionState(key, "idle", this.clock.now());
217466
217617
  this.emitSessionMetadataSnapshot({
@@ -218116,15 +218267,16 @@ var Daemon = class Daemon {
218116
218267
  text: slackTitle
218117
218268
  });
218118
218269
  }
218270
+ const isHeadlessGithubFinal = p.github !== void 0 && p.platform === "hook" && update?.sessionUpdate === "agent_message_chunk" && update?._meta?.codex?.phase === "final_answer";
218271
+ if (p.github) {
218272
+ p.github.collector.onUpdate(update);
218273
+ if (isHeadlessGithubFinal) p.github.deferredFinalTranscript = true;
218274
+ }
218119
218275
  if (p.webchat) this.emitWebchatUpdate(p, update);
218120
- else {
218276
+ else if (!isHeadlessGithubFinal) {
218121
218277
  for (const action of p.conv.onUpdate(update)) this.enqueueApply(p, action);
218122
218278
  this.armIdle(p);
218123
218279
  }
218124
- if (p.github) {
218125
- const finalAnswer = p.github.collector.onUpdate(update);
218126
- if (finalAnswer) p.github.stream.replace(finalAnswer);
218127
- }
218128
218280
  for (const ev of p.rec.onUpdate(update)) this.recordEvent(p.agentId, p.channel, p.statusThread, ev);
218129
218281
  }
218130
218282
  /**
@@ -219117,4 +219269,4 @@ async function runForeground(opts, deps = {}) {
219117
219269
  //#endregion
219118
219270
  export { ClientTransport as i, CP_SUBPROTOCOL as n, CP_WS_PATH as r, runForeground as t };
219119
219271
 
219120
- //# sourceMappingURL=run-foreground-DasVEmdw.js.map
219272
+ //# sourceMappingURL=run-foreground-qa22G1Nt.js.map