@ycodium-ai/agent-grok 0.2.3265 → 0.2.3277

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 +165 -135
  2. package/package.json +4 -4
package/dist/index.js CHANGED
@@ -160,7 +160,7 @@ var GROK_CARD = {
160
160
  // src/grokInstance.ts
161
161
  import * as NodeCrypto3 from "node:crypto";
162
162
  import {
163
- raceAbort as raceAbort2
163
+ raceAbort as raceAbort3
164
164
  } from "@ycodium-ai/plugin-api/executor";
165
165
  import { nodeStreamsFromHandle as nodeStreamsFromHandle2 } from "@ycodium-ai/plugin-api/process-stdin";
166
166
 
@@ -27914,6 +27914,11 @@ function tokenizeLaunchArgs(value) {
27914
27914
  return tokens;
27915
27915
  }
27916
27916
 
27917
+ // src/grokSignIn.ts
27918
+ import {
27919
+ raceAbort
27920
+ } from "@ycodium-ai/plugin-api/executor";
27921
+
27917
27922
  // src/deviceCodeOutput.ts
27918
27923
  var OUTPUT_QUIET_MS = 3e3;
27919
27924
  var SILENT_CAP_MS = 3e4;
@@ -27974,6 +27979,12 @@ function readDeviceCodeOutput(stdout, onText) {
27974
27979
  return { text: text3, code };
27975
27980
  }
27976
27981
 
27982
+ // src/grokHome.ts
27983
+ import * as NodeCrypto2 from "node:crypto";
27984
+ import * as NodeOS2 from "node:os";
27985
+ import * as NodePath4 from "node:path";
27986
+ import { mergeLaunchEnv } from "@ycodium-ai/plugin-api/executor";
27987
+
27977
27988
  // src/grokAccount.ts
27978
27989
  import * as NodeFS2 from "node:fs";
27979
27990
  import * as NodePath3 from "node:path";
@@ -28059,9 +28070,142 @@ var readGrokAccount = (homePath) => {
28059
28070
  };
28060
28071
  };
28061
28072
 
28073
+ // src/grokHome.ts
28074
+ function expandHomePath(value) {
28075
+ if (value === "~") return NodeOS2.homedir();
28076
+ if (value.startsWith("~/") || value.startsWith("~\\")) {
28077
+ return NodePath4.join(NodeOS2.homedir(), value.slice(2));
28078
+ }
28079
+ return value;
28080
+ }
28081
+ function resolveGrokHomePath(value) {
28082
+ const trimmed3 = value.trim();
28083
+ if (trimmed3.length === 0) return NodePath4.join(NodeOS2.homedir(), ".grok");
28084
+ return NodePath4.resolve(expandHomePath(trimmed3));
28085
+ }
28086
+ function probeGrokAccount(accountPath) {
28087
+ const resolved = resolveGrokHomePath(accountPath);
28088
+ const account = readGrokAccount(resolved);
28089
+ return {
28090
+ accountPath: resolved,
28091
+ state: account.state,
28092
+ ...account.email === void 0 ? {} : { email: account.email },
28093
+ ...account.name === void 0 ? {} : { name: account.name },
28094
+ ...account.expiresAt === void 0 ? {} : { expiresAt: account.expiresAt }
28095
+ };
28096
+ }
28097
+ function grokContinuationKey(recipe) {
28098
+ return `grok:home:${resolveGrokHomePath(recipe.homePath)}`;
28099
+ }
28100
+ function resolveAccountHomePath(recipe, configuredHome) {
28101
+ const fromEnvironment = recipe.environment["GROK_HOME"]?.trim();
28102
+ if (fromEnvironment !== void 0 && fromEnvironment.length > 0) {
28103
+ return NodePath4.resolve(expandHomePath(fromEnvironment));
28104
+ }
28105
+ return resolveGrokHomePath(configuredHome);
28106
+ }
28107
+ function absentPath() {
28108
+ return NodePath4.join(
28109
+ NodeOS2.tmpdir(),
28110
+ `ycodium-grok-no-auth-${NodeCrypto2.randomUUID()}`,
28111
+ "auth.json"
28112
+ );
28113
+ }
28114
+ function ownEndpointAuthGuard(recipe) {
28115
+ const connectivity = GROK_CARD.modelConnectivity;
28116
+ const baseUrlKey = connectivity.baseUrlEnvKey;
28117
+ if (baseUrlKey === void 0 || (recipe.environment[baseUrlKey]?.trim() ?? "") === "") return {};
28118
+ const guard = {};
28119
+ for (const entry of connectivity.extraEnv ?? []) {
28120
+ if (entry.value === "$absentPath") guard[entry.name] = absentPath();
28121
+ }
28122
+ return guard;
28123
+ }
28124
+ function buildSignInEnv(recipe) {
28125
+ const configuredHome = recipe.homePath;
28126
+ const homeInjection = configuredHome.trim().length > 0 ? { [GROK_CARD.homeEnvVar]: resolveGrokHomePath(configuredHome) } : {};
28127
+ return mergeLaunchEnv({
28128
+ accountHome: homeInjection,
28129
+ instanceTable: recipe.environment,
28130
+ handOverrides: { GROK_OAUTH2_REFERRER: "ycodium" }
28131
+ });
28132
+ }
28133
+ function buildSpawnEnv(recipe, resolvedHomePath, homeConfigured) {
28134
+ const homeInjection = homeConfigured ? { [GROK_CARD.homeEnvVar]: resolvedHomePath } : {};
28135
+ return mergeLaunchEnv({
28136
+ accountHome: { ...homeInjection, ...ownEndpointAuthGuard(recipe) },
28137
+ instanceTable: recipe.environment,
28138
+ handOverrides: { GROK_OAUTH2_REFERRER: "ycodium" }
28139
+ });
28140
+ }
28141
+
28142
+ // src/grokSignIn.ts
28143
+ function makeGrokSignIn(input2) {
28144
+ const { host, recipe } = input2;
28145
+ const operations = /* @__PURE__ */ new Map();
28146
+ const signIn = {
28147
+ start: async (signal) => {
28148
+ if (recipe.binaryPath.length === 0) throw new Error("Grok program path is not configured");
28149
+ const env = buildSignInEnv(recipe);
28150
+ const handle = await host.process.spawn({
28151
+ program: recipe.binaryPath,
28152
+ args: [...GROK_CARD.deviceCodeSignInArgs],
28153
+ owner: { bindingId: host.bindingId },
28154
+ ...Object.keys(env).length > 0 ? { env } : {},
28155
+ ...signal === void 0 ? {} : { signal }
28156
+ });
28157
+ const output2 = readDeviceCodeOutput(
28158
+ handle.stdout,
28159
+ (text3) => host.log.info("sign-in output", { text: text3 })
28160
+ );
28161
+ const operationId = `grok-sign-in-${Date.now().toString(36)}-${operations.size}`;
28162
+ let closing;
28163
+ const operation = {
28164
+ handle,
28165
+ close: () => closing ??= Promise.resolve().then(async () => {
28166
+ await handle.kill("SIGTERM").catch(() => void 0);
28167
+ await Promise.allSettled([handle.exited, output2.text]);
28168
+ }).finally(() => {
28169
+ if (operations.get(operationId) === operation) operations.delete(operationId);
28170
+ })
28171
+ };
28172
+ operations.set(operationId, operation);
28173
+ try {
28174
+ const code = await raceAbort(output2.code, signal);
28175
+ if (signal?.aborted || input2.isDisposed()) throw new Error("Grok sign-in cancelled");
28176
+ return { operationId, ...code };
28177
+ } catch (error62) {
28178
+ await operation.close();
28179
+ throw error62;
28180
+ }
28181
+ },
28182
+ cancel: async (operationId) => {
28183
+ await operations.get(operationId)?.close();
28184
+ },
28185
+ verify: async (signal) => {
28186
+ const active = [...operations.values()];
28187
+ try {
28188
+ for (const operation of active) {
28189
+ const code = await raceAbort(operation.handle.exited, signal);
28190
+ if (code !== 0) throw new Error(`Grok sign-in exited with code ${String(code)}`);
28191
+ }
28192
+ return await input2.probe(signal);
28193
+ } finally {
28194
+ await Promise.all(active.map((operation) => operation.close()));
28195
+ }
28196
+ }
28197
+ };
28198
+ return {
28199
+ signIn,
28200
+ close: async () => {
28201
+ await Promise.all([...operations.values()].map((operation) => operation.close()));
28202
+ }
28203
+ };
28204
+ }
28205
+
28062
28206
  // src/grokQuota.ts
28063
28207
  import * as NodeFS3 from "node:fs";
28064
- import * as NodePath4 from "node:path";
28208
+ import * as NodePath5 from "node:path";
28065
28209
  import {
28066
28210
  parseRetryAfterMs
28067
28211
  } from "@ycodium-ai/plugin-api/usage";
@@ -28108,7 +28252,7 @@ var grokQuotaWindows = (body) => {
28108
28252
  };
28109
28253
  var createGrokUsage = (input2) => {
28110
28254
  const now = input2.now ?? Date.now;
28111
- const authPath = NodePath4.join(input2.homePath, AUTH_FILE_NAME2);
28255
+ const authPath = NodePath5.join(input2.homePath, AUTH_FILE_NAME2);
28112
28256
  const readQuota = async (request) => {
28113
28257
  const baseUrlKey = GROK_CARD.modelConnectivity.baseUrlEnvKey;
28114
28258
  if (baseUrlKey !== void 0 && (input2.environment[baseUrlKey]?.trim() ?? "") !== "") {
@@ -28824,8 +28968,8 @@ var grokPromptSettlement = {
28824
28968
  };
28825
28969
 
28826
28970
  // src/grokSkills.ts
28827
- import * as NodeOS2 from "node:os";
28828
- import * as NodePath5 from "node:path";
28971
+ import * as NodeOS3 from "node:os";
28972
+ import * as NodePath6 from "node:path";
28829
28973
  var INSPECT_TIMEOUT_MS = 15e3;
28830
28974
  var MAX_INSPECT_OUTPUT_BYTES = 4 * 1024 * 1024;
28831
28975
  var GROK_INSPECT_ARGS = ["inspect", "--json"];
@@ -28885,7 +29029,7 @@ var runGrokInspect = async (input2) => {
28885
29029
  };
28886
29030
  async function probeGrokSkills(input2) {
28887
29031
  try {
28888
- return await runGrokInspect({ ...input2, cwd: NodeOS2.homedir() });
29032
+ return await runGrokInspect({ ...input2, cwd: NodeOS3.homedir() });
28889
29033
  } catch {
28890
29034
  return [];
28891
29035
  }
@@ -28894,14 +29038,14 @@ async function inspectGrokWorkspace(input2) {
28894
29038
  const skills = await runGrokInspect(input2);
28895
29039
  const watched = /* @__PURE__ */ new Set([
28896
29040
  // 项目技能目录的位置没有实测,这两处只是触发重查的提示,不影响答案本身。
28897
- NodePath5.join(input2.cwd, ".grok", "skills"),
28898
- NodePath5.join(input2.cwd, ".agents", "skills")
29041
+ NodePath6.join(input2.cwd, ".grok", "skills"),
29042
+ NodePath6.join(input2.cwd, ".agents", "skills")
28899
29043
  ]);
28900
29044
  for (const skill of skills) {
28901
29045
  watched.add(skill.path);
28902
- const skillDirectory = NodePath5.dirname(skill.path);
29046
+ const skillDirectory = NodePath6.dirname(skill.path);
28903
29047
  watched.add(skillDirectory);
28904
- watched.add(NodePath5.dirname(skillDirectory));
29048
+ watched.add(NodePath6.dirname(skillDirectory));
28905
29049
  }
28906
29050
  return { skills, watchPaths: [...watched] };
28907
29051
  }
@@ -28955,7 +29099,7 @@ function grokOpenCommands(session) {
28955
29099
 
28956
29100
  // src/modelCacheRefresh.ts
28957
29101
  import * as NodeFS4 from "node:fs";
28958
- import * as NodePath6 from "node:path";
29102
+ import * as NodePath7 from "node:path";
28959
29103
  import {
28960
29104
  ExecutorSpawnAbortedError as ExecutorSpawnAbortedError2,
28961
29105
  ExecutorSpawnRefusedError as ExecutorSpawnRefusedError2,
@@ -28967,7 +29111,7 @@ import {
28967
29111
  describeExecutorSpawnFailure,
28968
29112
  ExecutorSpawnAbortedError,
28969
29113
  ExecutorSpawnRefusedError,
28970
- raceAbort
29114
+ raceAbort as raceAbort2
28971
29115
  } from "@ycodium-ai/plugin-api/executor";
28972
29116
  import { nodeStreamsFromHandle } from "@ycodium-ai/plugin-api/process-stdin";
28973
29117
  var PROBE_REQUEST_TIMEOUT_MS = 2e4;
@@ -29003,7 +29147,7 @@ async function probeGrokModels(input2) {
29003
29147
  let handshake;
29004
29148
  try {
29005
29149
  const { readable, writable } = nodeStreamsFromHandle(handle);
29006
- handshake = await raceAbort(
29150
+ handshake = await raceAbort2(
29007
29151
  openAcpProbeHandshake({
29008
29152
  readable,
29009
29153
  writable,
@@ -29039,7 +29183,7 @@ var GROK_MODEL_CACHE_FILE = "models_cache.json";
29039
29183
  var GROK_MODEL_CACHE_MAX_AGE_MS = 24 * 60 * 60 * 1e3;
29040
29184
  var GROK_MODELS_COMMAND_TIMEOUT_MS = 6e4;
29041
29185
  function grokModelCachePath(accountHome) {
29042
- return NodePath6.join(accountHome, GROK_MODEL_CACHE_FILE);
29186
+ return NodePath7.join(accountHome, GROK_MODEL_CACHE_FILE);
29043
29187
  }
29044
29188
  function readGrokModelCacheMtimeMs(accountHome) {
29045
29189
  try {
@@ -29194,79 +29338,6 @@ function createGrokModelCatalog(input2) {
29194
29338
  return { readCliVersion, refreshModelCatalog, refreshForSend };
29195
29339
  }
29196
29340
 
29197
- // src/grokHome.ts
29198
- import * as NodeCrypto2 from "node:crypto";
29199
- import * as NodeOS3 from "node:os";
29200
- import * as NodePath7 from "node:path";
29201
- import { mergeLaunchEnv } from "@ycodium-ai/plugin-api/executor";
29202
- function expandHomePath(value) {
29203
- if (value === "~") return NodeOS3.homedir();
29204
- if (value.startsWith("~/") || value.startsWith("~\\")) {
29205
- return NodePath7.join(NodeOS3.homedir(), value.slice(2));
29206
- }
29207
- return value;
29208
- }
29209
- function resolveGrokHomePath(value) {
29210
- const trimmed3 = value.trim();
29211
- if (trimmed3.length === 0) return NodePath7.join(NodeOS3.homedir(), ".grok");
29212
- return NodePath7.resolve(expandHomePath(trimmed3));
29213
- }
29214
- function probeGrokAccount(accountPath) {
29215
- const resolved = resolveGrokHomePath(accountPath);
29216
- const account = readGrokAccount(resolved);
29217
- return {
29218
- accountPath: resolved,
29219
- state: account.state,
29220
- ...account.email === void 0 ? {} : { email: account.email },
29221
- ...account.name === void 0 ? {} : { name: account.name },
29222
- ...account.expiresAt === void 0 ? {} : { expiresAt: account.expiresAt }
29223
- };
29224
- }
29225
- function grokContinuationKey(recipe) {
29226
- return `grok:home:${resolveGrokHomePath(recipe.homePath)}`;
29227
- }
29228
- function resolveAccountHomePath(recipe, configuredHome) {
29229
- const fromEnvironment = recipe.environment["GROK_HOME"]?.trim();
29230
- if (fromEnvironment !== void 0 && fromEnvironment.length > 0) {
29231
- return NodePath7.resolve(expandHomePath(fromEnvironment));
29232
- }
29233
- return resolveGrokHomePath(configuredHome);
29234
- }
29235
- function absentPath() {
29236
- return NodePath7.join(
29237
- NodeOS3.tmpdir(),
29238
- `ycodium-grok-no-auth-${NodeCrypto2.randomUUID()}`,
29239
- "auth.json"
29240
- );
29241
- }
29242
- function ownEndpointAuthGuard(recipe) {
29243
- const connectivity = GROK_CARD.modelConnectivity;
29244
- const baseUrlKey = connectivity.baseUrlEnvKey;
29245
- if (baseUrlKey === void 0 || (recipe.environment[baseUrlKey]?.trim() ?? "") === "") return {};
29246
- const guard = {};
29247
- for (const entry of connectivity.extraEnv ?? []) {
29248
- if (entry.value === "$absentPath") guard[entry.name] = absentPath();
29249
- }
29250
- return guard;
29251
- }
29252
- function buildSignInEnv(recipe) {
29253
- const configuredHome = recipe.homePath;
29254
- const homeInjection = configuredHome.trim().length > 0 ? { [GROK_CARD.homeEnvVar]: resolveGrokHomePath(configuredHome) } : {};
29255
- return mergeLaunchEnv({
29256
- accountHome: homeInjection,
29257
- instanceTable: recipe.environment,
29258
- handOverrides: { GROK_OAUTH2_REFERRER: "ycodium" }
29259
- });
29260
- }
29261
- function buildSpawnEnv(recipe, resolvedHomePath, homeConfigured) {
29262
- const homeInjection = homeConfigured ? { [GROK_CARD.homeEnvVar]: resolvedHomePath } : {};
29263
- return mergeLaunchEnv({
29264
- accountHome: { ...homeInjection, ...ownEndpointAuthGuard(recipe) },
29265
- instanceTable: recipe.environment,
29266
- handOverrides: { GROK_OAUTH2_REFERRER: "ycodium" }
29267
- });
29268
- }
29269
-
29270
29341
  // src/grokInstance.ts
29271
29342
  var RESUME_SCHEMA_VERSION = 1;
29272
29343
  var yieldTick = () => new Promise((resolve2) => {
@@ -29326,7 +29397,6 @@ var createGrokInstance = (config2, host) => {
29326
29397
  const recipe = parseGrokInstanceConfig(config2);
29327
29398
  const events = new EventBus();
29328
29399
  const threads = /* @__PURE__ */ new Map();
29329
- const signInOperations = /* @__PURE__ */ new Map();
29330
29400
  let disposed = false;
29331
29401
  const { requireThread, registerSession, stopSession, stopAll } = createAcpSessionRegistry(
29332
29402
  threads,
@@ -29334,11 +29404,7 @@ var createGrokInstance = (config2, host) => {
29334
29404
  host.log
29335
29405
  );
29336
29406
  const disposeOnce = createRetryableClose(async () => {
29337
- const operations = [...signInOperations.values()];
29338
- signInOperations.clear();
29339
- for (const operation of operations) {
29340
- await operation.handle.kill("SIGTERM").catch(() => void 0);
29341
- }
29407
+ await signIn.close();
29342
29408
  await stopAll();
29343
29409
  events.close();
29344
29410
  });
@@ -29387,9 +29453,9 @@ var createGrokInstance = (config2, host) => {
29387
29453
  };
29388
29454
  }
29389
29455
  const env = spawnEnv();
29390
- const version2 = await raceAbort2(modelCatalog.readCliVersion(signal), signal);
29456
+ const version2 = await raceAbort3(modelCatalog.readCliVersion(signal), signal);
29391
29457
  if (signal?.aborted) throw new Error("aborted");
29392
- await raceAbort2(
29458
+ await raceAbort3(
29393
29459
  modelCatalog.refreshModelCatalog({
29394
29460
  force: false,
29395
29461
  cliVersion: version2,
@@ -29398,7 +29464,7 @@ var createGrokInstance = (config2, host) => {
29398
29464
  signal
29399
29465
  );
29400
29466
  if (signal?.aborted) throw new Error("aborted");
29401
- const [outcome, skills] = await raceAbort2(
29467
+ const [outcome, skills] = await raceAbort3(
29402
29468
  Promise.all([
29403
29469
  probeGrokModels({
29404
29470
  recipe,
@@ -29437,6 +29503,7 @@ var createGrokInstance = (config2, host) => {
29437
29503
  ...GROK_NATIVE_MODE_REPORT
29438
29504
  };
29439
29505
  };
29506
+ const signIn = makeGrokSignIn({ host, recipe, probe, isDisposed: () => disposed });
29440
29507
  const instance = {
29441
29508
  probe,
29442
29509
  readCliVersion: () => modelCatalog.readCliVersion(),
@@ -29721,44 +29788,7 @@ var createGrokInstance = (config2, host) => {
29721
29788
  disposed = true;
29722
29789
  return disposeOnce();
29723
29790
  },
29724
- /**
29725
- * 设备码登录:`grok login --device-auth` 是 RFC 8628 流程,CLI 自己打印网址和
29726
- * 验证码、轮询到批准,不开浏览器,所以服务器没有图形界面也跑得起来。怎么从
29727
- * stdout 捞网址与验证码见 deviceCodeOutput.ts,流程本身不假造。
29728
- */
29729
- signIn: {
29730
- start: async () => {
29731
- if (recipe.binaryPath.length === 0) {
29732
- throw new Error("Grok program path is not configured");
29733
- }
29734
- const env = buildSignInEnv(recipe);
29735
- const handle = await host.process.spawn({
29736
- program: recipe.binaryPath,
29737
- args: [...GROK_CARD.deviceCodeSignInArgs],
29738
- owner: { bindingId: host.bindingId },
29739
- ...Object.keys(env).length > 0 ? { env } : {}
29740
- });
29741
- const output2 = readDeviceCodeOutput(
29742
- handle.stdout,
29743
- (text3) => host.log.info("sign-in output", { text: text3 })
29744
- );
29745
- const stdoutText = output2.text;
29746
- const operationId = `grok-sign-in-${Date.now().toString(36)}-${signInOperations.size}`;
29747
- signInOperations.set(operationId, { handle, stdoutText });
29748
- void stdoutText.finally(() => {
29749
- signInOperations.delete(operationId);
29750
- });
29751
- return { operationId, ...await output2.code };
29752
- },
29753
- cancel: async (operationId) => {
29754
- const operation = signInOperations.get(operationId);
29755
- if (operation === void 0) return;
29756
- signInOperations.delete(operationId);
29757
- await operation.handle.kill("SIGTERM").catch(() => void 0);
29758
- await operation.stdoutText.catch(() => void 0);
29759
- },
29760
- verify: () => probe()
29761
- }
29791
+ signIn: signIn.signIn
29762
29792
  };
29763
29793
  return instance;
29764
29794
  };
@@ -29776,7 +29806,7 @@ var executors = [
29776
29806
  ];
29777
29807
  var index_default = definePlugin({
29778
29808
  id: "agent-grok",
29779
- apiVersion: 31,
29809
+ apiVersion: 32,
29780
29810
  executors,
29781
29811
  activate(ctx) {
29782
29812
  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.3265",
3
+ "version": "0.2.3277",
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.3265",
25
- "ycodium-acp-executor": "0.2.3265",
26
- "ycodium-executor-testing": "0.0.0"
24
+ "@ycodium-ai/plugin-api": "0.2.0",
25
+ "ycodium-executor-testing": "0.0.0",
26
+ "ycodium-acp-executor": "0.2.0"
27
27
  },
28
28
  "ycodium": {
29
29
  "plugin": "./dist/index.js",