@ycodium-ai/agent-grok 0.2.3210 → 0.2.3214

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 (2) hide show
  1. package/dist/index.js +135 -28
  2. package/package.json +4 -4
package/dist/index.js CHANGED
@@ -26990,6 +26990,92 @@ function readOpenToolCalls(toolCalls, turnId) {
26990
26990
  return running;
26991
26991
  }
26992
26992
 
26993
+ // ../../packages/ycodium-acp-executor/src/protocol-log.ts
26994
+ import * as NodeFS from "node:fs";
26995
+ import * as NodeOS from "node:os";
26996
+ import * as NodePath2 from "node:path";
26997
+ var DEFAULT_MAX_BYTES = 8 * 1024 * 1024;
26998
+ var UNSAFE_FILE_CHARS = /[^A-Za-z0-9._-]+/gu;
26999
+ function safeFileName(value) {
27000
+ return value.replaceAll(UNSAFE_FILE_CHARS, "_");
27001
+ }
27002
+ function createAcpProtocolLogFile(input2) {
27003
+ const maxBytes = input2.maxBytes ?? DEFAULT_MAX_BYTES;
27004
+ NodeFS.mkdirSync(input2.directory, { recursive: true });
27005
+ const filePath = NodePath2.join(
27006
+ input2.directory,
27007
+ `${safeFileName(input2.provider)}-${safeFileName(input2.threadId)}-${Date.now().toString(36)}.ndjson`
27008
+ );
27009
+ const stream = (input2.openStream ?? ((path) => NodeFS.createWriteStream(path, { flags: "a" })))(
27010
+ filePath
27011
+ );
27012
+ let bytes = 0;
27013
+ let stopped = false;
27014
+ const closed = Promise.withResolvers();
27015
+ let closing = false;
27016
+ stream.once("close", () => closed.resolve());
27017
+ stream.on("error", () => {
27018
+ stopped = true;
27019
+ stream.destroy();
27020
+ });
27021
+ const writeTruncated = () => {
27022
+ stopped = true;
27023
+ const marker = `${JSON.stringify({ at: (/* @__PURE__ */ new Date()).toISOString(), stage: "truncated" })}
27024
+ `;
27025
+ if (bytes + Buffer.byteLength(marker) <= maxBytes) stream.write(marker);
27026
+ stream.end();
27027
+ };
27028
+ const writeLine = (value) => {
27029
+ if (stopped) return;
27030
+ const line = `${JSON.stringify(value)}
27031
+ `;
27032
+ const lineBytes = Buffer.byteLength(line);
27033
+ if (bytes + lineBytes > maxBytes) {
27034
+ writeTruncated();
27035
+ return;
27036
+ }
27037
+ bytes += lineBytes;
27038
+ stream.write(line);
27039
+ };
27040
+ return {
27041
+ path: filePath,
27042
+ write: (event) => writeLine({
27043
+ at: (/* @__PURE__ */ new Date()).toISOString(),
27044
+ direction: event.direction,
27045
+ stage: event.stage,
27046
+ payload: event.payload
27047
+ }),
27048
+ close: async () => {
27049
+ if (closing) return closed.promise;
27050
+ closing = true;
27051
+ stopped = true;
27052
+ stream.end();
27053
+ await closed.promise;
27054
+ }
27055
+ };
27056
+ }
27057
+ function createAcpProtocolLogFromEnv(input2) {
27058
+ const flag = process.env.YCODIUM_ACP_PROTOCOL_LOG;
27059
+ if (flag !== "1" && flag?.toLowerCase() !== "true") return void 0;
27060
+ const configured = process.env.YCODIUM_ACP_PROTOCOL_LOG_DIR?.trim();
27061
+ const directory = configured && configured.length > 0 ? configured : NodePath2.join(NodeOS.tmpdir(), "ycodium-acp-protocol");
27062
+ try {
27063
+ const sink = createAcpProtocolLogFile({
27064
+ directory,
27065
+ provider: input2.provider,
27066
+ threadId: input2.threadId
27067
+ });
27068
+ input2.log?.info("acp protocol frames are being recorded", { path: sink.path });
27069
+ return sink;
27070
+ } catch (error62) {
27071
+ input2.log?.warn?.("acp protocol frame log could not be opened", {
27072
+ directory,
27073
+ error: error62 instanceof Error ? error62.message : String(error62)
27074
+ });
27075
+ return void 0;
27076
+ }
27077
+ }
27078
+
26993
27079
  // ../../packages/ycodium-acp-executor/src/executor.ts
26994
27080
  var DEFAULT_CANCEL_GRACE_MS = 5e3;
26995
27081
  function defaultNowIso() {
@@ -27098,9 +27184,16 @@ function createAcpExecutor(options) {
27098
27184
  });
27099
27185
  const { rememberSettledPromptKey, abortPendingSettlement, settleFromNotification } = createExecutorSettlement({ hooks, shared });
27100
27186
  const promptResults = createPromptResults({ options, shared });
27187
+ const protocolLogSink = options.protocolLog === void 0 ? createAcpProtocolLogFromEnv({
27188
+ provider: options.provider,
27189
+ threadId: options.threadId,
27190
+ ...options.log === void 0 ? {} : { log: options.log }
27191
+ }) : void 0;
27192
+ const protocolLog = options.protocolLog ?? protocolLogSink?.write;
27101
27193
  const connection = createAcpConnection({
27102
27194
  readable: options.readable,
27103
27195
  writable: options.writable,
27196
+ ...protocolLog === void 0 ? {} : { logger: protocolLog },
27104
27197
  onInboundFailure: (error62) => {
27105
27198
  options.log?.warn?.("acp connection closed: an inbound request could not be answered", {
27106
27199
  threadId: options.threadId,
@@ -27197,7 +27290,11 @@ function createAcpExecutor(options) {
27197
27290
  notifyPromptSettled,
27198
27291
  shared
27199
27292
  });
27200
- const { cancel, compact, dispose } = createExecutorLifecycle({
27293
+ const {
27294
+ cancel,
27295
+ compact,
27296
+ dispose: disposeLifecycle
27297
+ } = createExecutorLifecycle({
27201
27298
  promptResults,
27202
27299
  failIfDisposed,
27203
27300
  requireStarted,
@@ -27224,6 +27321,7 @@ function createAcpExecutor(options) {
27224
27321
  onInputDead,
27225
27322
  shared
27226
27323
  });
27324
+ let disposeOnce;
27227
27325
  return {
27228
27326
  get generation() {
27229
27327
  return shared.generation;
@@ -27246,7 +27344,16 @@ function createAcpExecutor(options) {
27246
27344
  setNativeMode,
27247
27345
  compact,
27248
27346
  openToolCalls: () => readOpenToolCalls(toolCalls, shared.activeTurnId),
27249
- dispose
27347
+ dispose: () => {
27348
+ disposeOnce ??= (async () => {
27349
+ try {
27350
+ await disposeLifecycle();
27351
+ } finally {
27352
+ await protocolLogSink?.close();
27353
+ }
27354
+ })();
27355
+ return disposeOnce;
27356
+ }
27250
27357
  };
27251
27358
  }
27252
27359
 
@@ -27657,8 +27764,8 @@ function readDeviceCodeOutput(stdout, onText) {
27657
27764
  }
27658
27765
 
27659
27766
  // src/grokAccount.ts
27660
- import * as NodeFS from "node:fs";
27661
- import * as NodePath2 from "node:path";
27767
+ import * as NodeFS2 from "node:fs";
27768
+ import * as NodePath3 from "node:path";
27662
27769
  var AUTH_FILE_NAME = "auth.json";
27663
27770
  var isRecord7 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
27664
27771
  var readString2 = (record3, key) => {
@@ -27678,14 +27785,14 @@ var parseJsonRecord = (raw) => {
27678
27785
  };
27679
27786
  var directoryExists = (homePath) => {
27680
27787
  try {
27681
- return NodeFS.statSync(homePath).isDirectory();
27788
+ return NodeFS2.statSync(homePath).isDirectory();
27682
27789
  } catch {
27683
27790
  return false;
27684
27791
  }
27685
27792
  };
27686
27793
  var readCredentialFile = (path) => {
27687
27794
  try {
27688
- return NodeFS.readFileSync(path, "utf8");
27795
+ return NodeFS2.readFileSync(path, "utf8");
27689
27796
  } catch {
27690
27797
  return void 0;
27691
27798
  }
@@ -27726,7 +27833,7 @@ var isExpired = (expiresAt, nowMs) => {
27726
27833
  };
27727
27834
  var readGrokAccount = (homePath) => {
27728
27835
  const exists = directoryExists(homePath);
27729
- const raw = readCredentialFile(NodePath2.join(homePath, AUTH_FILE_NAME));
27836
+ const raw = readCredentialFile(NodePath3.join(homePath, AUTH_FILE_NAME));
27730
27837
  if (raw === void 0) return signedOutProbe(exists);
27731
27838
  const parsed = parseJsonRecord(raw);
27732
27839
  const identity = parsed === void 0 ? void 0 : findIdentityEntry(parsed);
@@ -27742,8 +27849,8 @@ var readGrokAccount = (homePath) => {
27742
27849
  };
27743
27850
 
27744
27851
  // src/grokQuota.ts
27745
- import * as NodeFS2 from "node:fs";
27746
- import * as NodePath3 from "node:path";
27852
+ import * as NodeFS3 from "node:fs";
27853
+ import * as NodePath4 from "node:path";
27747
27854
  import {
27748
27855
  parseRetryAfterMs
27749
27856
  } from "@ycodium-ai/plugin-api/usage";
@@ -27790,7 +27897,7 @@ var grokQuotaWindows = (body) => {
27790
27897
  };
27791
27898
  var createGrokUsage = (input2) => {
27792
27899
  const now = input2.now ?? Date.now;
27793
- const authPath = NodePath3.join(input2.homePath, AUTH_FILE_NAME2);
27900
+ const authPath = NodePath4.join(input2.homePath, AUTH_FILE_NAME2);
27794
27901
  const readQuota = async (request) => {
27795
27902
  const baseUrlKey = GROK_CARD.modelConnectivity.baseUrlEnvKey;
27796
27903
  if (baseUrlKey !== void 0 && (input2.environment[baseUrlKey]?.trim() ?? "") !== "") {
@@ -27798,7 +27905,7 @@ var createGrokUsage = (input2) => {
27798
27905
  }
27799
27906
  let token = null;
27800
27907
  try {
27801
- token = extractGrokToken(parseJson(NodeFS2.readFileSync(authPath, "utf8")));
27908
+ token = extractGrokToken(parseJson(NodeFS3.readFileSync(authPath, "utf8")));
27802
27909
  } catch {
27803
27910
  token = null;
27804
27911
  }
@@ -28506,8 +28613,8 @@ var grokPromptSettlement = {
28506
28613
  };
28507
28614
 
28508
28615
  // src/grokSkills.ts
28509
- import * as NodeOS from "node:os";
28510
- import * as NodePath4 from "node:path";
28616
+ import * as NodeOS2 from "node:os";
28617
+ import * as NodePath5 from "node:path";
28511
28618
  var INSPECT_TIMEOUT_MS = 15e3;
28512
28619
  var MAX_INSPECT_OUTPUT_BYTES = 4 * 1024 * 1024;
28513
28620
  var GROK_INSPECT_ARGS = ["inspect", "--json"];
@@ -28566,7 +28673,7 @@ var runGrokInspect = async (input2) => {
28566
28673
  };
28567
28674
  async function probeGrokSkills(input2) {
28568
28675
  try {
28569
- return await runGrokInspect({ ...input2, cwd: NodeOS.homedir() });
28676
+ return await runGrokInspect({ ...input2, cwd: NodeOS2.homedir() });
28570
28677
  } catch {
28571
28678
  return [];
28572
28679
  }
@@ -28575,14 +28682,14 @@ async function inspectGrokWorkspace(input2) {
28575
28682
  const skills = await runGrokInspect(input2);
28576
28683
  const watched = /* @__PURE__ */ new Set([
28577
28684
  // 项目技能目录的位置没有实测,这两处只是触发重查的提示,不影响答案本身。
28578
- NodePath4.join(input2.cwd, ".grok", "skills"),
28579
- NodePath4.join(input2.cwd, ".agents", "skills")
28685
+ NodePath5.join(input2.cwd, ".grok", "skills"),
28686
+ NodePath5.join(input2.cwd, ".agents", "skills")
28580
28687
  ]);
28581
28688
  for (const skill of skills) {
28582
28689
  watched.add(skill.path);
28583
- const skillDirectory = NodePath4.dirname(skill.path);
28690
+ const skillDirectory = NodePath5.dirname(skill.path);
28584
28691
  watched.add(skillDirectory);
28585
- watched.add(NodePath4.dirname(skillDirectory));
28692
+ watched.add(NodePath5.dirname(skillDirectory));
28586
28693
  }
28587
28694
  return { skills, watchPaths: [...watched] };
28588
28695
  }
@@ -28699,20 +28806,20 @@ async function probeGrokVersion(input2) {
28699
28806
 
28700
28807
  // src/grokHome.ts
28701
28808
  import * as NodeCrypto2 from "node:crypto";
28702
- import * as NodeOS2 from "node:os";
28703
- import * as NodePath5 from "node:path";
28809
+ import * as NodeOS3 from "node:os";
28810
+ import * as NodePath6 from "node:path";
28704
28811
  import { mergeLaunchEnv } from "@ycodium-ai/plugin-api/executor";
28705
28812
  function expandHomePath(value) {
28706
- if (value === "~") return NodeOS2.homedir();
28813
+ if (value === "~") return NodeOS3.homedir();
28707
28814
  if (value.startsWith("~/") || value.startsWith("~\\")) {
28708
- return NodePath5.join(NodeOS2.homedir(), value.slice(2));
28815
+ return NodePath6.join(NodeOS3.homedir(), value.slice(2));
28709
28816
  }
28710
28817
  return value;
28711
28818
  }
28712
28819
  function resolveGrokHomePath(value) {
28713
28820
  const trimmed3 = value.trim();
28714
- if (trimmed3.length === 0) return NodePath5.join(NodeOS2.homedir(), ".grok");
28715
- return NodePath5.resolve(expandHomePath(trimmed3));
28821
+ if (trimmed3.length === 0) return NodePath6.join(NodeOS3.homedir(), ".grok");
28822
+ return NodePath6.resolve(expandHomePath(trimmed3));
28716
28823
  }
28717
28824
  function probeGrokAccount(accountPath) {
28718
28825
  const resolved = resolveGrokHomePath(accountPath);
@@ -28731,13 +28838,13 @@ function grokContinuationKey(recipe) {
28731
28838
  function resolveAccountHomePath(recipe, configuredHome) {
28732
28839
  const fromEnvironment = recipe.environment["GROK_HOME"]?.trim();
28733
28840
  if (fromEnvironment !== void 0 && fromEnvironment.length > 0) {
28734
- return NodePath5.resolve(expandHomePath(fromEnvironment));
28841
+ return NodePath6.resolve(expandHomePath(fromEnvironment));
28735
28842
  }
28736
28843
  return resolveGrokHomePath(configuredHome);
28737
28844
  }
28738
28845
  function absentPath() {
28739
- return NodePath5.join(
28740
- NodeOS2.tmpdir(),
28846
+ return NodePath6.join(
28847
+ NodeOS3.tmpdir(),
28741
28848
  `ycodium-grok-no-auth-${NodeCrypto2.randomUUID()}`,
28742
28849
  "auth.json"
28743
28850
  );
@@ -29248,7 +29355,7 @@ var executors = [
29248
29355
  ];
29249
29356
  var index_default = definePlugin({
29250
29357
  id: "agent-grok",
29251
- apiVersion: 20,
29358
+ apiVersion: 21,
29252
29359
  executors,
29253
29360
  activate(ctx) {
29254
29361
  ctx.log.info("grok executor ready");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ycodium-ai/agent-grok",
3
- "version": "0.2.3210",
3
+ "version": "0.2.3214",
4
4
  "description": "Grok executor: grok CLI over Agent Client Protocol stdio.",
5
5
  "keywords": [
6
6
  "ycodium",
@@ -21,9 +21,9 @@
21
21
  "@types/node": "24.12.4",
22
22
  "esbuild": "0.28.1",
23
23
  "vite-plus": "0.2.2",
24
- "@ycodium-ai/plugin-api": "0.2.3210",
25
- "ycodium-executor-testing": "0.0.0",
26
- "ycodium-acp-executor": "0.2.3210"
24
+ "@ycodium-ai/plugin-api": "0.2.3214",
25
+ "ycodium-acp-executor": "0.2.3214",
26
+ "ycodium-executor-testing": "0.0.0"
27
27
  },
28
28
  "ycodium": {
29
29
  "plugin": "./dist/index.js",