@ycodium-ai/agent-grok 0.2.3710 → 0.2.3766
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/index.js +253 -228
- package/locales/en.json +9 -0
- package/locales/zh-CN.json +9 -0
- package/package.json +6 -4
package/dist/index.js
CHANGED
|
@@ -6,6 +6,11 @@ var __export = (target, all) => {
|
|
|
6
6
|
|
|
7
7
|
// src/index.ts
|
|
8
8
|
import { definePlugin } from "@ycodium-ai/plugin-api";
|
|
9
|
+
import {
|
|
10
|
+
EXECUTOR_EFFECTIVE_PAYLOAD_SCHEMA,
|
|
11
|
+
executorHomeEffectiveValue,
|
|
12
|
+
readExecutorEffectiveRequest
|
|
13
|
+
} from "@ycodium-ai/plugin-api/executor";
|
|
9
14
|
|
|
10
15
|
// src/card.ts
|
|
11
16
|
var GROK_DRIVER_KIND = "grok";
|
|
@@ -23,6 +28,8 @@ var GROK_CARD = {
|
|
|
23
28
|
// `grokInstance.startSession` 里按用户选择拼。
|
|
24
29
|
launchArgs: "agent stdio",
|
|
25
30
|
homeEnvVar: "GROK_HOME",
|
|
31
|
+
// 设置表单里留空的格子此刻会用什么,见 index.ts 的同名命令。
|
|
32
|
+
effectiveCommand: "effectiveConfig",
|
|
26
33
|
// 只有一个账户目录,它同时装着会话历史:换目录,已开的 thread 就接不上这个实例了。
|
|
27
34
|
accountDirectory: {
|
|
28
35
|
configKeys: ["homePath"],
|
|
@@ -161,6 +168,166 @@ var GROK_CARD = {
|
|
|
161
168
|
}
|
|
162
169
|
};
|
|
163
170
|
|
|
171
|
+
// src/grokHome.ts
|
|
172
|
+
import * as NodeCrypto from "node:crypto";
|
|
173
|
+
import * as NodeOS from "node:os";
|
|
174
|
+
import * as NodePath2 from "node:path";
|
|
175
|
+
import { mergeLaunchEnv } from "@ycodium-ai/plugin-api/executor";
|
|
176
|
+
|
|
177
|
+
// src/grokAccount.ts
|
|
178
|
+
import * as NodeFS from "node:fs";
|
|
179
|
+
import * as NodePath from "node:path";
|
|
180
|
+
var AUTH_FILE_NAME = "auth.json";
|
|
181
|
+
var isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
182
|
+
var readString = (record4, key) => {
|
|
183
|
+
const value = record4[key];
|
|
184
|
+
if (typeof value !== "string") return void 0;
|
|
185
|
+
const trimmed3 = value.trim();
|
|
186
|
+
return trimmed3.length > 0 ? trimmed3 : void 0;
|
|
187
|
+
};
|
|
188
|
+
var parseJsonRecord = (raw) => {
|
|
189
|
+
let parsed;
|
|
190
|
+
try {
|
|
191
|
+
parsed = JSON.parse(raw);
|
|
192
|
+
} catch {
|
|
193
|
+
return void 0;
|
|
194
|
+
}
|
|
195
|
+
return isRecord(parsed) ? parsed : void 0;
|
|
196
|
+
};
|
|
197
|
+
var directoryExists = (homePath) => {
|
|
198
|
+
try {
|
|
199
|
+
return NodeFS.statSync(homePath).isDirectory();
|
|
200
|
+
} catch {
|
|
201
|
+
return false;
|
|
202
|
+
}
|
|
203
|
+
};
|
|
204
|
+
var readCredentialFile = (path) => {
|
|
205
|
+
try {
|
|
206
|
+
return NodeFS.readFileSync(path, "utf8");
|
|
207
|
+
} catch {
|
|
208
|
+
return void 0;
|
|
209
|
+
}
|
|
210
|
+
};
|
|
211
|
+
var signedOutProbe = (exists) => ({
|
|
212
|
+
state: "signed-out",
|
|
213
|
+
directoryExists: exists,
|
|
214
|
+
email: void 0,
|
|
215
|
+
name: void 0,
|
|
216
|
+
expiresAt: void 0
|
|
217
|
+
});
|
|
218
|
+
var unreadableProbe = (exists) => ({
|
|
219
|
+
state: "unreadable",
|
|
220
|
+
directoryExists: exists,
|
|
221
|
+
email: void 0,
|
|
222
|
+
name: void 0,
|
|
223
|
+
expiresAt: void 0
|
|
224
|
+
});
|
|
225
|
+
var joinName = (record4) => {
|
|
226
|
+
const first = readString(record4, "first_name");
|
|
227
|
+
const last = readString(record4, "last_name");
|
|
228
|
+
const joined = [first, last].filter((part) => part !== void 0).join(" ");
|
|
229
|
+
return joined.length > 0 ? joined : void 0;
|
|
230
|
+
};
|
|
231
|
+
var findIdentityEntry = (parsed) => {
|
|
232
|
+
for (const value of Object.values(parsed)) {
|
|
233
|
+
if (!isRecord(value)) continue;
|
|
234
|
+
if (readString(value, "email") !== void 0 || readString(value, "user_id") !== void 0) {
|
|
235
|
+
return value;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
return void 0;
|
|
239
|
+
};
|
|
240
|
+
var isExpired = (expiresAt, nowMs) => {
|
|
241
|
+
if (expiresAt === void 0) return false;
|
|
242
|
+
const parsed = Date.parse(expiresAt);
|
|
243
|
+
return Number.isNaN(parsed) ? false : parsed <= nowMs;
|
|
244
|
+
};
|
|
245
|
+
var readGrokAccount = (homePath) => {
|
|
246
|
+
const exists = directoryExists(homePath);
|
|
247
|
+
const raw = readCredentialFile(NodePath.join(homePath, AUTH_FILE_NAME));
|
|
248
|
+
if (raw === void 0) return signedOutProbe(exists);
|
|
249
|
+
const parsed = parseJsonRecord(raw);
|
|
250
|
+
const identity = parsed === void 0 ? void 0 : findIdentityEntry(parsed);
|
|
251
|
+
if (identity === void 0) return unreadableProbe(exists);
|
|
252
|
+
const expiresAt = readString(identity, "expires_at");
|
|
253
|
+
return {
|
|
254
|
+
state: isExpired(expiresAt, Date.now()) ? "expired" : "signed-in",
|
|
255
|
+
directoryExists: exists,
|
|
256
|
+
email: readString(identity, "email"),
|
|
257
|
+
name: joinName(identity),
|
|
258
|
+
expiresAt
|
|
259
|
+
};
|
|
260
|
+
};
|
|
261
|
+
|
|
262
|
+
// src/grokHome.ts
|
|
263
|
+
function expandHomePath(value) {
|
|
264
|
+
if (value === "~") return NodeOS.homedir();
|
|
265
|
+
if (value.startsWith("~/") || value.startsWith("~\\")) {
|
|
266
|
+
return NodePath2.join(NodeOS.homedir(), value.slice(2));
|
|
267
|
+
}
|
|
268
|
+
return value;
|
|
269
|
+
}
|
|
270
|
+
function resolveGrokHomePath(value) {
|
|
271
|
+
const trimmed3 = value.trim();
|
|
272
|
+
if (trimmed3.length === 0) return NodePath2.join(NodeOS.homedir(), ".grok");
|
|
273
|
+
return NodePath2.resolve(expandHomePath(trimmed3));
|
|
274
|
+
}
|
|
275
|
+
function probeGrokAccount(accountPath) {
|
|
276
|
+
const resolved = resolveGrokHomePath(accountPath);
|
|
277
|
+
const account = readGrokAccount(resolved);
|
|
278
|
+
return {
|
|
279
|
+
accountPath: resolved,
|
|
280
|
+
state: account.state,
|
|
281
|
+
...account.email === void 0 ? {} : { email: account.email },
|
|
282
|
+
...account.name === void 0 ? {} : { name: account.name },
|
|
283
|
+
...account.expiresAt === void 0 ? {} : { expiresAt: account.expiresAt }
|
|
284
|
+
};
|
|
285
|
+
}
|
|
286
|
+
function grokContinuationKey(recipe) {
|
|
287
|
+
return `grok:home:${resolveGrokHomePath(recipe.homePath)}`;
|
|
288
|
+
}
|
|
289
|
+
function resolveAccountHomePath(recipe, configuredHome) {
|
|
290
|
+
const fromEnvironment = recipe.environment["GROK_HOME"]?.trim();
|
|
291
|
+
if (fromEnvironment !== void 0 && fromEnvironment.length > 0) {
|
|
292
|
+
return NodePath2.resolve(expandHomePath(fromEnvironment));
|
|
293
|
+
}
|
|
294
|
+
return resolveGrokHomePath(configuredHome);
|
|
295
|
+
}
|
|
296
|
+
function absentPath() {
|
|
297
|
+
return NodePath2.join(
|
|
298
|
+
NodeOS.tmpdir(),
|
|
299
|
+
`ycodium-grok-no-auth-${NodeCrypto.randomUUID()}`,
|
|
300
|
+
"auth.json"
|
|
301
|
+
);
|
|
302
|
+
}
|
|
303
|
+
function ownEndpointAuthGuard(recipe) {
|
|
304
|
+
const connectivity = GROK_CARD.modelConnectivity;
|
|
305
|
+
const baseUrlKey = connectivity.baseUrlEnvKey;
|
|
306
|
+
if (baseUrlKey === void 0 || (recipe.environment[baseUrlKey]?.trim() ?? "") === "") return {};
|
|
307
|
+
const guard = {};
|
|
308
|
+
for (const entry of connectivity.extraEnv ?? []) {
|
|
309
|
+
if (entry.value === "$absentPath") guard[entry.name] = absentPath();
|
|
310
|
+
}
|
|
311
|
+
return guard;
|
|
312
|
+
}
|
|
313
|
+
function buildSignInEnv(recipe) {
|
|
314
|
+
const configuredHome = recipe.homePath;
|
|
315
|
+
const homeInjection = configuredHome.trim().length > 0 ? { [GROK_CARD.homeEnvVar]: resolveGrokHomePath(configuredHome) } : {};
|
|
316
|
+
return mergeLaunchEnv({
|
|
317
|
+
accountHome: homeInjection,
|
|
318
|
+
instanceTable: recipe.environment,
|
|
319
|
+
handOverrides: { GROK_OAUTH2_REFERRER: "ycodium" }
|
|
320
|
+
});
|
|
321
|
+
}
|
|
322
|
+
function buildSpawnEnv(recipe, resolvedHomePath, homeConfigured) {
|
|
323
|
+
const homeInjection = homeConfigured ? { [GROK_CARD.homeEnvVar]: resolvedHomePath } : {};
|
|
324
|
+
return mergeLaunchEnv({
|
|
325
|
+
accountHome: { ...homeInjection, ...ownEndpointAuthGuard(recipe) },
|
|
326
|
+
instanceTable: recipe.environment,
|
|
327
|
+
handOverrides: { GROK_OAUTH2_REFERRER: "ycodium" }
|
|
328
|
+
});
|
|
329
|
+
}
|
|
330
|
+
|
|
164
331
|
// src/grokInstance.ts
|
|
165
332
|
import * as NodeCrypto3 from "node:crypto";
|
|
166
333
|
import {
|
|
@@ -169,7 +336,7 @@ import {
|
|
|
169
336
|
import { nodeStreamsFromHandle as nodeStreamsFromHandle2 } from "@ycodium-ai/plugin-api/process-stdin";
|
|
170
337
|
|
|
171
338
|
// ../../packages/ycodium-acp-executor/src/executor.ts
|
|
172
|
-
import * as
|
|
339
|
+
import * as NodeCrypto2 from "node:crypto";
|
|
173
340
|
|
|
174
341
|
// ../../packages/ycodium-acp-executor/src/approvals.ts
|
|
175
342
|
function createApprovalGate(input2) {
|
|
@@ -397,7 +564,7 @@ var UnboundedEventStream = class {
|
|
|
397
564
|
};
|
|
398
565
|
|
|
399
566
|
// ../../packages/ycodium-acp-executor/src/config-options.ts
|
|
400
|
-
function
|
|
567
|
+
function isRecord2(value) {
|
|
401
568
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
402
569
|
}
|
|
403
570
|
function asString(value) {
|
|
@@ -416,7 +583,7 @@ function flattenChoices(rawOptions, currentValue) {
|
|
|
416
583
|
const out = [];
|
|
417
584
|
const seen = /* @__PURE__ */ new Set();
|
|
418
585
|
const push = (entry) => {
|
|
419
|
-
if (!
|
|
586
|
+
if (!isRecord2(entry)) return;
|
|
420
587
|
const value = asString(entry["value"]);
|
|
421
588
|
if (value === void 0 || seen.has(value)) return;
|
|
422
589
|
seen.add(value);
|
|
@@ -431,7 +598,7 @@ function flattenChoices(rawOptions, currentValue) {
|
|
|
431
598
|
});
|
|
432
599
|
};
|
|
433
600
|
for (const entry of rawOptions) {
|
|
434
|
-
if (
|
|
601
|
+
if (isRecord2(entry) && Array.isArray(entry["options"])) {
|
|
435
602
|
for (const nested of entry["options"]) push(nested);
|
|
436
603
|
continue;
|
|
437
604
|
}
|
|
@@ -440,7 +607,7 @@ function flattenChoices(rawOptions, currentValue) {
|
|
|
440
607
|
return out;
|
|
441
608
|
}
|
|
442
609
|
function isConfigOption(entry, configId) {
|
|
443
|
-
return
|
|
610
|
+
return isRecord2(entry) && asString(entry["id"])?.trim() === configId.trim();
|
|
444
611
|
}
|
|
445
612
|
function findConfigOptionEntry(configOptions, configId) {
|
|
446
613
|
return Array.isArray(configOptions) && configId.trim() !== "" ? configOptions.find(
|
|
@@ -455,7 +622,7 @@ function withConfigOptionValue(configOptions, configId, value) {
|
|
|
455
622
|
}
|
|
456
623
|
function pickEffortOption(configOptions) {
|
|
457
624
|
if (!Array.isArray(configOptions)) return void 0;
|
|
458
|
-
const candidates = configOptions.filter(
|
|
625
|
+
const candidates = configOptions.filter(isRecord2).filter((option) => normalizedField(option, "type") === "select").filter(looksLikeEffortOption);
|
|
459
626
|
return candidates.find((option) => normalizedField(option, "category") === "model_option") ?? candidates.find((option) => normalizedField(option, "id") === "effort") ?? candidates.find((option) => normalizedField(option, "category") === "thought_level") ?? candidates[0];
|
|
460
627
|
}
|
|
461
628
|
function findAcpEffortConfig(configOptions) {
|
|
@@ -475,7 +642,7 @@ function findAcpEffortConfig(configOptions) {
|
|
|
475
642
|
}
|
|
476
643
|
|
|
477
644
|
// ../../packages/ycodium-acp-executor/src/util.ts
|
|
478
|
-
function
|
|
645
|
+
function isRecord3(value) {
|
|
479
646
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
480
647
|
}
|
|
481
648
|
function asTrimmedString(value) {
|
|
@@ -530,11 +697,11 @@ function extractCommandFromTitle(title) {
|
|
|
530
697
|
return backtickMatch?.[1]?.trim() || void 0;
|
|
531
698
|
}
|
|
532
699
|
function extractToolCommand(data, title) {
|
|
533
|
-
const item =
|
|
534
|
-
const itemInput = item &&
|
|
535
|
-
const itemResult = item &&
|
|
536
|
-
const rawInput =
|
|
537
|
-
const dataInput =
|
|
700
|
+
const item = isRecord3(data?.["item"]) ? data["item"] : void 0;
|
|
701
|
+
const itemInput = item && isRecord3(item["input"]) ? item["input"] : void 0;
|
|
702
|
+
const itemResult = item && isRecord3(item["result"]) ? item["result"] : void 0;
|
|
703
|
+
const rawInput = isRecord3(data?.["rawInput"]) ? data["rawInput"] : void 0;
|
|
704
|
+
const dataInput = isRecord3(data?.["input"]) ? data["input"] : void 0;
|
|
538
705
|
const candidates = [
|
|
539
706
|
normalizeCommandValue(item?.["command"]),
|
|
540
707
|
normalizeCommandValue(itemInput?.["command"]),
|
|
@@ -579,7 +746,7 @@ function collectPaths(value, paths, seen, depth) {
|
|
|
579
746
|
}
|
|
580
747
|
return;
|
|
581
748
|
}
|
|
582
|
-
if (!
|
|
749
|
+
if (!isRecord3(value)) {
|
|
583
750
|
return;
|
|
584
751
|
}
|
|
585
752
|
for (const key of ["path", "filePath", "relativePath", "filename", "newPath", "oldPath"]) {
|
|
@@ -657,7 +824,7 @@ function deriveToolActivityPresentation(input2) {
|
|
|
657
824
|
const title = asTrimmedString(input2.title);
|
|
658
825
|
const detail = stripTrailingExitCode(asTrimmedString(input2.detail));
|
|
659
826
|
const fallbackSummary = asTrimmedString(input2.fallbackSummary) ?? "Tool";
|
|
660
|
-
const data =
|
|
827
|
+
const data = isRecord3(input2.data) ? input2.data : void 0;
|
|
661
828
|
const command = extractToolCommand(data, title);
|
|
662
829
|
const primaryPath = extractPrimaryPath(data);
|
|
663
830
|
const action = classifyToolAction({
|
|
@@ -689,7 +856,7 @@ function deriveToolActivityPresentation(input2) {
|
|
|
689
856
|
};
|
|
690
857
|
}
|
|
691
858
|
if (action === "search") {
|
|
692
|
-
const rawInput =
|
|
859
|
+
const rawInput = isRecord3(data?.["rawInput"]) ? data["rawInput"] : void 0;
|
|
693
860
|
const query = asTrimmedString(rawInput?.["query"]) ?? asTrimmedString(rawInput?.["pattern"]) ?? asTrimmedString(rawInput?.["searchTerm"]);
|
|
694
861
|
return {
|
|
695
862
|
summary: "Searched files",
|
|
@@ -749,7 +916,7 @@ function extractCommandFromTitle2(title) {
|
|
|
749
916
|
return match?.[1]?.trim() || void 0;
|
|
750
917
|
}
|
|
751
918
|
function extractToolCallCommand(rawInput, title) {
|
|
752
|
-
if (
|
|
919
|
+
if (isRecord3(rawInput)) {
|
|
753
920
|
const directCommand = normalizeCommandValue2(rawInput["command"]);
|
|
754
921
|
if (directCommand) {
|
|
755
922
|
return directCommand;
|
|
@@ -777,7 +944,7 @@ function boundTailText(text4, limit = TOOL_CALL_CONTENT_MAX_CHARS) {
|
|
|
777
944
|
var boundToolCallOutputText = (text4) => boundTailText(text4);
|
|
778
945
|
var RAW_OUTPUT_TEXT_FIELDS = ["content", "stdout", "stderr", "output"];
|
|
779
946
|
function boundToolCallRawOutput(rawOutput) {
|
|
780
|
-
if (!
|
|
947
|
+
if (!isRecord3(rawOutput)) {
|
|
781
948
|
return rawOutput;
|
|
782
949
|
}
|
|
783
950
|
let changed = false;
|
|
@@ -969,11 +1136,11 @@ function collectSessionConfigOptionValues(configOption) {
|
|
|
969
1136
|
);
|
|
970
1137
|
}
|
|
971
1138
|
function collectSessionModelIds(models) {
|
|
972
|
-
if (!
|
|
1139
|
+
if (!isRecord3(models) || !Array.isArray(models["availableModels"])) {
|
|
973
1140
|
return [];
|
|
974
1141
|
}
|
|
975
1142
|
return models["availableModels"].flatMap(
|
|
976
|
-
(model) =>
|
|
1143
|
+
(model) => isRecord3(model) && typeof model["modelId"] === "string" ? [model["modelId"]] : []
|
|
977
1144
|
);
|
|
978
1145
|
}
|
|
979
1146
|
function catalogModelLastSegment(value) {
|
|
@@ -1045,7 +1212,7 @@ function parseAvailableCommandsUpdate(params) {
|
|
|
1045
1212
|
}
|
|
1046
1213
|
const commands = [];
|
|
1047
1214
|
for (const command of availableCommands) {
|
|
1048
|
-
if (!
|
|
1215
|
+
if (!isRecord3(command)) {
|
|
1049
1216
|
continue;
|
|
1050
1217
|
}
|
|
1051
1218
|
const name = typeof command["name"] === "string" ? command["name"].trim() : "";
|
|
@@ -1053,7 +1220,7 @@ function parseAvailableCommandsUpdate(params) {
|
|
|
1053
1220
|
continue;
|
|
1054
1221
|
}
|
|
1055
1222
|
const description = typeof command["description"] === "string" ? command["description"].trim() || void 0 : void 0;
|
|
1056
|
-
const input2 =
|
|
1223
|
+
const input2 = isRecord3(command["input"]) ? command["input"] : void 0;
|
|
1057
1224
|
const inputHint = typeof input2?.["hint"] === "string" ? input2["hint"].trim() || void 0 : void 0;
|
|
1058
1225
|
commands.push({
|
|
1059
1226
|
name,
|
|
@@ -1107,7 +1274,7 @@ function boundToolCallRawPayload(params, update, toolCall) {
|
|
|
1107
1274
|
}
|
|
1108
1275
|
function textFromContentBlocks(blocks) {
|
|
1109
1276
|
const parts = blocks.flatMap(
|
|
1110
|
-
(block) =>
|
|
1277
|
+
(block) => isRecord3(block) && block["type"] === "text" && typeof block["text"] === "string" ? [block["text"]] : []
|
|
1111
1278
|
);
|
|
1112
1279
|
const joined = parts.join("");
|
|
1113
1280
|
return joined.trim().length > 0 ? joined : void 0;
|
|
@@ -1132,7 +1299,7 @@ function parseSessionUpdateEvent(params) {
|
|
|
1132
1299
|
const entries = Array.isArray(upd["entries"]) ? upd["entries"] : [];
|
|
1133
1300
|
const plan = entries.map((entry, index) => ({
|
|
1134
1301
|
step: readAcpText(entry, "content") ?? `Step ${index + 1}`,
|
|
1135
|
-
status: normalizePlanStepStatus(
|
|
1302
|
+
status: normalizePlanStepStatus(isRecord3(entry) ? entry["status"] : void 0)
|
|
1136
1303
|
}));
|
|
1137
1304
|
if (plan.length > 0) {
|
|
1138
1305
|
events.push({
|
|
@@ -1172,7 +1339,7 @@ function parseSessionUpdateEvent(params) {
|
|
|
1172
1339
|
}
|
|
1173
1340
|
case "agent_message_chunk":
|
|
1174
1341
|
case "agent_thought_chunk": {
|
|
1175
|
-
const content =
|
|
1342
|
+
const content = isRecord3(upd["content"]) ? upd["content"] : void 0;
|
|
1176
1343
|
const contentType = content?.["type"];
|
|
1177
1344
|
const streamKind = kind === "agent_thought_chunk" ? "reasoning_text" : "assistant_text";
|
|
1178
1345
|
if (contentType === "text") {
|
|
@@ -1212,7 +1379,7 @@ function parseSessionUpdateEvent(params) {
|
|
|
1212
1379
|
}
|
|
1213
1380
|
case "compaction_summary_chunk": {
|
|
1214
1381
|
const compactionId = readAcpText(upd, "compactionId");
|
|
1215
|
-
const content =
|
|
1382
|
+
const content = isRecord3(upd["content"]) ? upd["content"] : void 0;
|
|
1216
1383
|
const text4 = content?.["type"] === "text" ? content["text"] : void 0;
|
|
1217
1384
|
if (compactionId === void 0 || typeof text4 !== "string" || text4.length === 0) break;
|
|
1218
1385
|
events.push({ _tag: "CompactionSummaryChunk", compactionId, text: text4 });
|
|
@@ -22906,17 +23073,17 @@ function isResponseMessage(value) {
|
|
|
22906
23073
|
function isNotificationMessage(value) {
|
|
22907
23074
|
return isJsonRpcEnvelope(value) && !("id" in value) && typeof value["method"] === "string";
|
|
22908
23075
|
}
|
|
22909
|
-
function
|
|
23076
|
+
function isRecord4(value) {
|
|
22910
23077
|
return typeof value === "object" && value !== null;
|
|
22911
23078
|
}
|
|
22912
23079
|
function isJsonRpcEnvelope(value) {
|
|
22913
|
-
return
|
|
23080
|
+
return isRecord4(value) && value["jsonrpc"] === "2.0";
|
|
22914
23081
|
}
|
|
22915
23082
|
function isJsonRpcId(value) {
|
|
22916
23083
|
return value === null || typeof value === "string" || typeof value === "number" && Number.isFinite(value);
|
|
22917
23084
|
}
|
|
22918
23085
|
function isResponseShapedMessage(value) {
|
|
22919
|
-
return
|
|
23086
|
+
return isRecord4(value) && !("method" in value) && ("id" in value || "result" in value || "error" in value);
|
|
22920
23087
|
}
|
|
22921
23088
|
function isResponseBatch(batch) {
|
|
22922
23089
|
let hasValidCall = false;
|
|
@@ -22926,7 +23093,7 @@ function isResponseBatch(batch) {
|
|
|
22926
23093
|
for (const entry of batch) {
|
|
22927
23094
|
hasValidCall ||= isRequestMessage(entry) || isNotificationMessage(entry);
|
|
22928
23095
|
hasValidResponse ||= isResponseMessage(entry);
|
|
22929
|
-
if (!
|
|
23096
|
+
if (!isRecord4(entry)) {
|
|
22930
23097
|
continue;
|
|
22931
23098
|
}
|
|
22932
23099
|
hasCallShape ||= "method" in entry;
|
|
@@ -22941,13 +23108,13 @@ function isResponseBatch(batch) {
|
|
|
22941
23108
|
return hasResponseShape && !hasCallShape;
|
|
22942
23109
|
}
|
|
22943
23110
|
function cancelRequestId(params) {
|
|
22944
|
-
if (!
|
|
23111
|
+
if (!isRecord4(params) || !isJsonRpcId(params["requestId"])) {
|
|
22945
23112
|
return void 0;
|
|
22946
23113
|
}
|
|
22947
23114
|
return params["requestId"];
|
|
22948
23115
|
}
|
|
22949
23116
|
function isErrorResponse(value) {
|
|
22950
|
-
return
|
|
23117
|
+
return isRecord4(value) && typeof value["code"] === "number" && Number.isInteger(value["code"]) && typeof value["message"] === "string";
|
|
22951
23118
|
}
|
|
22952
23119
|
var Handled = {
|
|
22953
23120
|
/**
|
|
@@ -23492,7 +23659,7 @@ var Connection = class {
|
|
|
23492
23659
|
if (this.abortController.signal.aborted) {
|
|
23493
23660
|
return Promise.resolve();
|
|
23494
23661
|
}
|
|
23495
|
-
if (!
|
|
23662
|
+
if (!isRecord4(message)) {
|
|
23496
23663
|
console.error("Invalid message", { message });
|
|
23497
23664
|
return Promise.resolve();
|
|
23498
23665
|
}
|
|
@@ -23895,7 +24062,7 @@ function ndJsonStream(output2, input2) {
|
|
|
23895
24062
|
await writeJson(protocolErrorResponse(RequestError.parseError()));
|
|
23896
24063
|
return;
|
|
23897
24064
|
}
|
|
23898
|
-
if (
|
|
24065
|
+
if (isRecord4(message) || Array.isArray(message)) {
|
|
23899
24066
|
controller.enqueue(message);
|
|
23900
24067
|
} else {
|
|
23901
24068
|
await writeJson(protocolErrorResponse(RequestError.invalidRequest(message)));
|
|
@@ -24882,14 +25049,14 @@ var legacyClientNotificationMethods = /* @__PURE__ */ new Set([
|
|
|
24882
25049
|
import * as NodeStream from "node:stream";
|
|
24883
25050
|
|
|
24884
25051
|
// ../../packages/ycodium-acp-executor/src/jsonrpc.ts
|
|
24885
|
-
function
|
|
25052
|
+
function isRecord5(value) {
|
|
24886
25053
|
return typeof value === "object" && value !== null;
|
|
24887
25054
|
}
|
|
24888
25055
|
function isJsonRpcId2(value) {
|
|
24889
25056
|
return typeof value === "string" || typeof value === "number" && Number.isFinite(value);
|
|
24890
25057
|
}
|
|
24891
25058
|
function isJsonRpcEnvelope2(value) {
|
|
24892
|
-
return
|
|
25059
|
+
return isRecord5(value) && value["jsonrpc"] === "2.0";
|
|
24893
25060
|
}
|
|
24894
25061
|
function isRequestMessage2(value) {
|
|
24895
25062
|
return isJsonRpcEnvelope2(value) && "id" in value && typeof value["method"] === "string" && isJsonRpcId2(value["id"]);
|
|
@@ -24909,7 +25076,7 @@ function isNotificationMessage2(value) {
|
|
|
24909
25076
|
return isJsonRpcEnvelope2(value) && !("id" in value) && typeof value["method"] === "string";
|
|
24910
25077
|
}
|
|
24911
25078
|
function readJsonRpcError(value) {
|
|
24912
|
-
if (!
|
|
25079
|
+
if (!isRecord5(value) || typeof value["code"] !== "number" || typeof value["message"] !== "string") {
|
|
24913
25080
|
return void 0;
|
|
24914
25081
|
}
|
|
24915
25082
|
return {
|
|
@@ -24982,11 +25149,11 @@ var KNOWN_SESSION_UPDATES = /* @__PURE__ */ new Set([
|
|
|
24982
25149
|
"compaction_summary_chunk"
|
|
24983
25150
|
]);
|
|
24984
25151
|
function isSessionUpdateEnvelope(payload) {
|
|
24985
|
-
if (!
|
|
25152
|
+
if (!isRecord5(payload) || typeof payload["sessionId"] !== "string") {
|
|
24986
25153
|
return false;
|
|
24987
25154
|
}
|
|
24988
25155
|
const update = payload["update"];
|
|
24989
|
-
return
|
|
25156
|
+
return isRecord5(update) && typeof update["sessionUpdate"] === "string";
|
|
24990
25157
|
}
|
|
24991
25158
|
function hasKnownVariantShape(update) {
|
|
24992
25159
|
const kind = update["sessionUpdate"];
|
|
@@ -24994,7 +25161,7 @@ function hasKnownVariantShape(update) {
|
|
|
24994
25161
|
return false;
|
|
24995
25162
|
}
|
|
24996
25163
|
if (kind === "user_message_chunk" || kind === "agent_message_chunk" || kind === "agent_thought_chunk") {
|
|
24997
|
-
return
|
|
25164
|
+
return isRecord5(update["content"]);
|
|
24998
25165
|
}
|
|
24999
25166
|
return true;
|
|
25000
25167
|
}
|
|
@@ -25400,7 +25567,7 @@ function forgetConfigOptionValue(state, configId) {
|
|
|
25400
25567
|
const forgetsModel = configId === void 0 || configId === state.modelConfigId;
|
|
25401
25568
|
const { currentModelReported: _forgottenReport, ...withoutReport } = state;
|
|
25402
25569
|
const configOptions = configId !== void 0 && Array.isArray(state.configOptions) ? state.configOptions.map((option) => {
|
|
25403
|
-
if (!
|
|
25570
|
+
if (!isRecord3(option) || option["id"] !== configId) return option;
|
|
25404
25571
|
const { currentValue: _forgotten, ...rest } = option;
|
|
25405
25572
|
return rest;
|
|
25406
25573
|
}) : state.configOptions;
|
|
@@ -25411,7 +25578,7 @@ function forgetConfigOptionValue(state, configId) {
|
|
|
25411
25578
|
};
|
|
25412
25579
|
}
|
|
25413
25580
|
function modelSelectionStateFromSetup(setup) {
|
|
25414
|
-
const sessionModels =
|
|
25581
|
+
const sessionModels = isRecord3(setup.models) ? setup.models : void 0;
|
|
25415
25582
|
const modelConfigId = extractModelConfigId(setup);
|
|
25416
25583
|
const strategy = modelConfigId !== void 0 ? "config-option" : "session/set_model";
|
|
25417
25584
|
const modelConfigOption = modelConfigId === void 0 ? void 0 : findSessionConfigOption(setup.configOptions, modelConfigId);
|
|
@@ -26779,7 +26946,7 @@ function createExecutorRequests({
|
|
|
26779
26946
|
pendingUserInputs.delete(requestId);
|
|
26780
26947
|
pending.resolve({
|
|
26781
26948
|
kind: "answered",
|
|
26782
|
-
answers:
|
|
26949
|
+
answers: isRecord3(answers) ? answers : {}
|
|
26783
26950
|
});
|
|
26784
26951
|
};
|
|
26785
26952
|
return {
|
|
@@ -26793,7 +26960,7 @@ function createExecutorRequests({
|
|
|
26793
26960
|
}
|
|
26794
26961
|
|
|
26795
26962
|
// ../../packages/ycodium-acp-executor/src/artifacts.ts
|
|
26796
|
-
import * as
|
|
26963
|
+
import * as NodePath3 from "node:path";
|
|
26797
26964
|
import * as NodeURL from "node:url";
|
|
26798
26965
|
function resourceLinkArtifacts(content) {
|
|
26799
26966
|
if (content["type"] !== "resource_link" || typeof content["uri"] !== "string") return [];
|
|
@@ -26804,7 +26971,7 @@ function resourceLinkArtifacts(content) {
|
|
|
26804
26971
|
} catch {
|
|
26805
26972
|
return [];
|
|
26806
26973
|
}
|
|
26807
|
-
if (!
|
|
26974
|
+
if (!NodePath3.isAbsolute(path)) return [];
|
|
26808
26975
|
const name = typeof content["name"] === "string" ? content["name"].trim() : "";
|
|
26809
26976
|
const mimeType = typeof content["mimeType"] === "string" ? content["mimeType"].trim() : "";
|
|
26810
26977
|
return [
|
|
@@ -27078,18 +27245,18 @@ function modelRefreshFailedError(requestedModelId, error62) {
|
|
|
27078
27245
|
}
|
|
27079
27246
|
|
|
27080
27247
|
// ../../packages/ycodium-acp-executor/src/runtime-mode.ts
|
|
27081
|
-
function
|
|
27248
|
+
function isRecord6(value) {
|
|
27082
27249
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
27083
27250
|
}
|
|
27084
27251
|
function asString2(value) {
|
|
27085
27252
|
return typeof value === "string" ? value : void 0;
|
|
27086
27253
|
}
|
|
27087
27254
|
function acpModeConfigId(setup) {
|
|
27088
|
-
if (!
|
|
27255
|
+
if (!isRecord6(setup)) return void 0;
|
|
27089
27256
|
const configOptions = setup["configOptions"];
|
|
27090
27257
|
if (!Array.isArray(configOptions)) return void 0;
|
|
27091
27258
|
for (const option of configOptions) {
|
|
27092
|
-
if (!
|
|
27259
|
+
if (!isRecord6(option)) continue;
|
|
27093
27260
|
if (asString2(option["category"])?.trim().toLowerCase() !== "mode") continue;
|
|
27094
27261
|
const id = asString2(option["id"])?.trim();
|
|
27095
27262
|
if (id) return id;
|
|
@@ -27536,14 +27703,14 @@ function createExecutorSettlement({
|
|
|
27536
27703
|
|
|
27537
27704
|
// ../../packages/ycodium-acp-executor/src/executor/subagent-sessions.ts
|
|
27538
27705
|
function parseState(raw) {
|
|
27539
|
-
if (!
|
|
27706
|
+
if (!isRecord3(raw)) return { status: void 0, error: void 0 };
|
|
27540
27707
|
const state = raw["state"];
|
|
27541
27708
|
if (state === "running") return { status: "running", error: void 0 };
|
|
27542
27709
|
if (state === "requires_action") return { status: "waiting", error: void 0 };
|
|
27543
27710
|
if (state !== "idle") return { status: void 0, error: void 0 };
|
|
27544
27711
|
const stopReason = raw["stopReason"];
|
|
27545
|
-
const error62 =
|
|
27546
|
-
if (stopReason === "error" ||
|
|
27712
|
+
const error62 = isRecord3(raw["error"]) ? asTrimmedString(raw["error"]["message"]) : void 0;
|
|
27713
|
+
if (stopReason === "error" || isRecord3(raw["error"])) return { status: "failed", error: error62 };
|
|
27547
27714
|
if (stopReason === "cancelled") return { status: "cancelled", error: void 0 };
|
|
27548
27715
|
return { status: "idle", error: void 0 };
|
|
27549
27716
|
}
|
|
@@ -27559,7 +27726,7 @@ function childLinkage(childId, record4) {
|
|
|
27559
27726
|
function createSubagentSessionTracker(registry2) {
|
|
27560
27727
|
const observe = (notification, ctx) => {
|
|
27561
27728
|
const update = notification.update;
|
|
27562
|
-
if (!
|
|
27729
|
+
if (!isRecord3(update) || update["sessionUpdate"] !== "subagent_update") return [];
|
|
27563
27730
|
const childId = asTrimmedString(update["sessionId"]);
|
|
27564
27731
|
if (childId === void 0 || ctx.ownSessionIds.has(childId)) return [];
|
|
27565
27732
|
const outerId = notification.sessionId;
|
|
@@ -27984,9 +28151,9 @@ function readOpenToolCalls(toolCalls, turnId) {
|
|
|
27984
28151
|
}
|
|
27985
28152
|
|
|
27986
28153
|
// ../../packages/ycodium-acp-executor/src/protocol-log.ts
|
|
27987
|
-
import * as
|
|
27988
|
-
import * as
|
|
27989
|
-
import * as
|
|
28154
|
+
import * as NodeFS2 from "node:fs";
|
|
28155
|
+
import * as NodeOS2 from "node:os";
|
|
28156
|
+
import * as NodePath4 from "node:path";
|
|
27990
28157
|
var DEFAULT_MAX_BYTES = 8 * 1024 * 1024;
|
|
27991
28158
|
var UNSAFE_FILE_CHARS = /[^A-Za-z0-9._-]+/gu;
|
|
27992
28159
|
function safeFileName(value) {
|
|
@@ -27994,12 +28161,12 @@ function safeFileName(value) {
|
|
|
27994
28161
|
}
|
|
27995
28162
|
function createAcpProtocolLogFile(input2) {
|
|
27996
28163
|
const maxBytes = input2.maxBytes ?? DEFAULT_MAX_BYTES;
|
|
27997
|
-
|
|
27998
|
-
const filePath =
|
|
28164
|
+
NodeFS2.mkdirSync(input2.directory, { recursive: true });
|
|
28165
|
+
const filePath = NodePath4.join(
|
|
27999
28166
|
input2.directory,
|
|
28000
28167
|
`${safeFileName(input2.provider)}-${safeFileName(input2.threadId)}-${Date.now().toString(36)}.ndjson`
|
|
28001
28168
|
);
|
|
28002
|
-
const stream = (input2.openStream ?? ((path) =>
|
|
28169
|
+
const stream = (input2.openStream ?? ((path) => NodeFS2.createWriteStream(path, { flags: "a" })))(
|
|
28003
28170
|
filePath
|
|
28004
28171
|
);
|
|
28005
28172
|
let bytes = 0;
|
|
@@ -28051,7 +28218,7 @@ function createAcpProtocolLogFromEnv(input2) {
|
|
|
28051
28218
|
const flag = process.env.YCODIUM_ACP_PROTOCOL_LOG;
|
|
28052
28219
|
if (flag !== "1" && flag?.toLowerCase() !== "true") return void 0;
|
|
28053
28220
|
const configured = process.env.YCODIUM_ACP_PROTOCOL_LOG_DIR?.trim();
|
|
28054
|
-
const directory = configured && configured.length > 0 ? configured :
|
|
28221
|
+
const directory = configured && configured.length > 0 ? configured : NodePath4.join(NodeOS2.tmpdir(), "ycodium-acp-protocol");
|
|
28055
28222
|
try {
|
|
28056
28223
|
const sink = createAcpProtocolLogFile({
|
|
28057
28224
|
directory,
|
|
@@ -28075,7 +28242,7 @@ function defaultNowIso() {
|
|
|
28075
28242
|
return (/* @__PURE__ */ new Date()).toISOString();
|
|
28076
28243
|
}
|
|
28077
28244
|
function defaultRandomId() {
|
|
28078
|
-
return
|
|
28245
|
+
return NodeCrypto2.randomUUID();
|
|
28079
28246
|
}
|
|
28080
28247
|
function createAcpExecutor(options) {
|
|
28081
28248
|
const hooks = { ...defaultVendorHooks, ...options.hooks };
|
|
@@ -28671,28 +28838,28 @@ var MAX_VERSION_OUTPUT_BYTES = 64 * 1024;
|
|
|
28671
28838
|
|
|
28672
28839
|
// src/config.ts
|
|
28673
28840
|
var GROK_DEFAULT_LAUNCH_ARGS = "agent stdio";
|
|
28674
|
-
function
|
|
28841
|
+
function isRecord7(value) {
|
|
28675
28842
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
28676
28843
|
}
|
|
28677
|
-
function
|
|
28844
|
+
function readString2(value) {
|
|
28678
28845
|
return typeof value === "string" ? value : "";
|
|
28679
28846
|
}
|
|
28680
28847
|
function readTrimmed(value) {
|
|
28681
|
-
return
|
|
28848
|
+
return readString2(value).trim();
|
|
28682
28849
|
}
|
|
28683
28850
|
function readEnvironment(value) {
|
|
28684
28851
|
if (!Array.isArray(value)) return {};
|
|
28685
28852
|
const env = {};
|
|
28686
28853
|
for (const entry of value) {
|
|
28687
|
-
if (!
|
|
28854
|
+
if (!isRecord7(entry)) continue;
|
|
28688
28855
|
const name = readTrimmed(entry["name"]);
|
|
28689
28856
|
if (name.length === 0) continue;
|
|
28690
|
-
env[name] =
|
|
28857
|
+
env[name] = readString2(entry["value"]);
|
|
28691
28858
|
}
|
|
28692
28859
|
return env;
|
|
28693
28860
|
}
|
|
28694
28861
|
function parseGrokInstanceConfig(config2) {
|
|
28695
|
-
if (!
|
|
28862
|
+
if (!isRecord7(config2)) {
|
|
28696
28863
|
return {
|
|
28697
28864
|
binaryPath: "",
|
|
28698
28865
|
launchArgs: GROK_DEFAULT_LAUNCH_ARGS,
|
|
@@ -28702,11 +28869,11 @@ function parseGrokInstanceConfig(config2) {
|
|
|
28702
28869
|
envelopeDriver: void 0
|
|
28703
28870
|
};
|
|
28704
28871
|
}
|
|
28705
|
-
const nested =
|
|
28872
|
+
const nested = isRecord7(config2["config"]) ? config2["config"] : void 0;
|
|
28706
28873
|
const settings = nested ?? config2;
|
|
28707
28874
|
return {
|
|
28708
28875
|
binaryPath: readTrimmed(settings["binaryPath"]),
|
|
28709
|
-
launchArgs:
|
|
28876
|
+
launchArgs: readString2(settings["launchArgs"]) || GROK_DEFAULT_LAUNCH_ARGS,
|
|
28710
28877
|
homePath: readTrimmed(settings["homePath"]) || readTrimmed(config2["homePath"]),
|
|
28711
28878
|
homeEnvVar: readTrimmed(settings["homeEnvVar"]) || readTrimmed(config2["homeEnvVar"]),
|
|
28712
28879
|
environment: readEnvironment(config2["environment"]),
|
|
@@ -28830,166 +28997,6 @@ function readDeviceCodeOutput(stdout, onText) {
|
|
|
28830
28997
|
return { text: text4, code };
|
|
28831
28998
|
}
|
|
28832
28999
|
|
|
28833
|
-
// src/grokHome.ts
|
|
28834
|
-
import * as NodeCrypto2 from "node:crypto";
|
|
28835
|
-
import * as NodeOS2 from "node:os";
|
|
28836
|
-
import * as NodePath4 from "node:path";
|
|
28837
|
-
import { mergeLaunchEnv } from "@ycodium-ai/plugin-api/executor";
|
|
28838
|
-
|
|
28839
|
-
// src/grokAccount.ts
|
|
28840
|
-
import * as NodeFS2 from "node:fs";
|
|
28841
|
-
import * as NodePath3 from "node:path";
|
|
28842
|
-
var AUTH_FILE_NAME = "auth.json";
|
|
28843
|
-
var isRecord7 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
28844
|
-
var readString2 = (record4, key) => {
|
|
28845
|
-
const value = record4[key];
|
|
28846
|
-
if (typeof value !== "string") return void 0;
|
|
28847
|
-
const trimmed3 = value.trim();
|
|
28848
|
-
return trimmed3.length > 0 ? trimmed3 : void 0;
|
|
28849
|
-
};
|
|
28850
|
-
var parseJsonRecord = (raw) => {
|
|
28851
|
-
let parsed;
|
|
28852
|
-
try {
|
|
28853
|
-
parsed = JSON.parse(raw);
|
|
28854
|
-
} catch {
|
|
28855
|
-
return void 0;
|
|
28856
|
-
}
|
|
28857
|
-
return isRecord7(parsed) ? parsed : void 0;
|
|
28858
|
-
};
|
|
28859
|
-
var directoryExists = (homePath) => {
|
|
28860
|
-
try {
|
|
28861
|
-
return NodeFS2.statSync(homePath).isDirectory();
|
|
28862
|
-
} catch {
|
|
28863
|
-
return false;
|
|
28864
|
-
}
|
|
28865
|
-
};
|
|
28866
|
-
var readCredentialFile = (path) => {
|
|
28867
|
-
try {
|
|
28868
|
-
return NodeFS2.readFileSync(path, "utf8");
|
|
28869
|
-
} catch {
|
|
28870
|
-
return void 0;
|
|
28871
|
-
}
|
|
28872
|
-
};
|
|
28873
|
-
var signedOutProbe = (exists) => ({
|
|
28874
|
-
state: "signed-out",
|
|
28875
|
-
directoryExists: exists,
|
|
28876
|
-
email: void 0,
|
|
28877
|
-
name: void 0,
|
|
28878
|
-
expiresAt: void 0
|
|
28879
|
-
});
|
|
28880
|
-
var unreadableProbe = (exists) => ({
|
|
28881
|
-
state: "unreadable",
|
|
28882
|
-
directoryExists: exists,
|
|
28883
|
-
email: void 0,
|
|
28884
|
-
name: void 0,
|
|
28885
|
-
expiresAt: void 0
|
|
28886
|
-
});
|
|
28887
|
-
var joinName = (record4) => {
|
|
28888
|
-
const first = readString2(record4, "first_name");
|
|
28889
|
-
const last = readString2(record4, "last_name");
|
|
28890
|
-
const joined = [first, last].filter((part) => part !== void 0).join(" ");
|
|
28891
|
-
return joined.length > 0 ? joined : void 0;
|
|
28892
|
-
};
|
|
28893
|
-
var findIdentityEntry = (parsed) => {
|
|
28894
|
-
for (const value of Object.values(parsed)) {
|
|
28895
|
-
if (!isRecord7(value)) continue;
|
|
28896
|
-
if (readString2(value, "email") !== void 0 || readString2(value, "user_id") !== void 0) {
|
|
28897
|
-
return value;
|
|
28898
|
-
}
|
|
28899
|
-
}
|
|
28900
|
-
return void 0;
|
|
28901
|
-
};
|
|
28902
|
-
var isExpired = (expiresAt, nowMs) => {
|
|
28903
|
-
if (expiresAt === void 0) return false;
|
|
28904
|
-
const parsed = Date.parse(expiresAt);
|
|
28905
|
-
return Number.isNaN(parsed) ? false : parsed <= nowMs;
|
|
28906
|
-
};
|
|
28907
|
-
var readGrokAccount = (homePath) => {
|
|
28908
|
-
const exists = directoryExists(homePath);
|
|
28909
|
-
const raw = readCredentialFile(NodePath3.join(homePath, AUTH_FILE_NAME));
|
|
28910
|
-
if (raw === void 0) return signedOutProbe(exists);
|
|
28911
|
-
const parsed = parseJsonRecord(raw);
|
|
28912
|
-
const identity = parsed === void 0 ? void 0 : findIdentityEntry(parsed);
|
|
28913
|
-
if (identity === void 0) return unreadableProbe(exists);
|
|
28914
|
-
const expiresAt = readString2(identity, "expires_at");
|
|
28915
|
-
return {
|
|
28916
|
-
state: isExpired(expiresAt, Date.now()) ? "expired" : "signed-in",
|
|
28917
|
-
directoryExists: exists,
|
|
28918
|
-
email: readString2(identity, "email"),
|
|
28919
|
-
name: joinName(identity),
|
|
28920
|
-
expiresAt
|
|
28921
|
-
};
|
|
28922
|
-
};
|
|
28923
|
-
|
|
28924
|
-
// src/grokHome.ts
|
|
28925
|
-
function expandHomePath(value) {
|
|
28926
|
-
if (value === "~") return NodeOS2.homedir();
|
|
28927
|
-
if (value.startsWith("~/") || value.startsWith("~\\")) {
|
|
28928
|
-
return NodePath4.join(NodeOS2.homedir(), value.slice(2));
|
|
28929
|
-
}
|
|
28930
|
-
return value;
|
|
28931
|
-
}
|
|
28932
|
-
function resolveGrokHomePath(value) {
|
|
28933
|
-
const trimmed3 = value.trim();
|
|
28934
|
-
if (trimmed3.length === 0) return NodePath4.join(NodeOS2.homedir(), ".grok");
|
|
28935
|
-
return NodePath4.resolve(expandHomePath(trimmed3));
|
|
28936
|
-
}
|
|
28937
|
-
function probeGrokAccount(accountPath) {
|
|
28938
|
-
const resolved = resolveGrokHomePath(accountPath);
|
|
28939
|
-
const account = readGrokAccount(resolved);
|
|
28940
|
-
return {
|
|
28941
|
-
accountPath: resolved,
|
|
28942
|
-
state: account.state,
|
|
28943
|
-
...account.email === void 0 ? {} : { email: account.email },
|
|
28944
|
-
...account.name === void 0 ? {} : { name: account.name },
|
|
28945
|
-
...account.expiresAt === void 0 ? {} : { expiresAt: account.expiresAt }
|
|
28946
|
-
};
|
|
28947
|
-
}
|
|
28948
|
-
function grokContinuationKey(recipe) {
|
|
28949
|
-
return `grok:home:${resolveGrokHomePath(recipe.homePath)}`;
|
|
28950
|
-
}
|
|
28951
|
-
function resolveAccountHomePath(recipe, configuredHome) {
|
|
28952
|
-
const fromEnvironment = recipe.environment["GROK_HOME"]?.trim();
|
|
28953
|
-
if (fromEnvironment !== void 0 && fromEnvironment.length > 0) {
|
|
28954
|
-
return NodePath4.resolve(expandHomePath(fromEnvironment));
|
|
28955
|
-
}
|
|
28956
|
-
return resolveGrokHomePath(configuredHome);
|
|
28957
|
-
}
|
|
28958
|
-
function absentPath() {
|
|
28959
|
-
return NodePath4.join(
|
|
28960
|
-
NodeOS2.tmpdir(),
|
|
28961
|
-
`ycodium-grok-no-auth-${NodeCrypto2.randomUUID()}`,
|
|
28962
|
-
"auth.json"
|
|
28963
|
-
);
|
|
28964
|
-
}
|
|
28965
|
-
function ownEndpointAuthGuard(recipe) {
|
|
28966
|
-
const connectivity = GROK_CARD.modelConnectivity;
|
|
28967
|
-
const baseUrlKey = connectivity.baseUrlEnvKey;
|
|
28968
|
-
if (baseUrlKey === void 0 || (recipe.environment[baseUrlKey]?.trim() ?? "") === "") return {};
|
|
28969
|
-
const guard = {};
|
|
28970
|
-
for (const entry of connectivity.extraEnv ?? []) {
|
|
28971
|
-
if (entry.value === "$absentPath") guard[entry.name] = absentPath();
|
|
28972
|
-
}
|
|
28973
|
-
return guard;
|
|
28974
|
-
}
|
|
28975
|
-
function buildSignInEnv(recipe) {
|
|
28976
|
-
const configuredHome = recipe.homePath;
|
|
28977
|
-
const homeInjection = configuredHome.trim().length > 0 ? { [GROK_CARD.homeEnvVar]: resolveGrokHomePath(configuredHome) } : {};
|
|
28978
|
-
return mergeLaunchEnv({
|
|
28979
|
-
accountHome: homeInjection,
|
|
28980
|
-
instanceTable: recipe.environment,
|
|
28981
|
-
handOverrides: { GROK_OAUTH2_REFERRER: "ycodium" }
|
|
28982
|
-
});
|
|
28983
|
-
}
|
|
28984
|
-
function buildSpawnEnv(recipe, resolvedHomePath, homeConfigured) {
|
|
28985
|
-
const homeInjection = homeConfigured ? { [GROK_CARD.homeEnvVar]: resolvedHomePath } : {};
|
|
28986
|
-
return mergeLaunchEnv({
|
|
28987
|
-
accountHome: { ...homeInjection, ...ownEndpointAuthGuard(recipe) },
|
|
28988
|
-
instanceTable: recipe.environment,
|
|
28989
|
-
handOverrides: { GROK_OAUTH2_REFERRER: "ycodium" }
|
|
28990
|
-
});
|
|
28991
|
-
}
|
|
28992
|
-
|
|
28993
29000
|
// src/grokSignIn.ts
|
|
28994
29001
|
function makeGrokSignIn(input2) {
|
|
28995
29002
|
const { host, recipe } = input2;
|
|
@@ -30961,6 +30968,7 @@ var createGrokInstance = (config2, host) => {
|
|
|
30961
30968
|
var executors = [
|
|
30962
30969
|
{
|
|
30963
30970
|
card: GROK_CARD,
|
|
30971
|
+
lifecycle: [{ kind: "detect", reversible: true }],
|
|
30964
30972
|
createInstance: async (config2, host) => {
|
|
30965
30973
|
host.log.info("createInstance");
|
|
30966
30974
|
return createGrokInstance(config2, host);
|
|
@@ -30970,9 +30978,26 @@ var executors = [
|
|
|
30970
30978
|
];
|
|
30971
30979
|
var index_default = definePlugin({
|
|
30972
30980
|
id: "agent-grok",
|
|
30973
|
-
apiVersion:
|
|
30981
|
+
apiVersion: 56,
|
|
30974
30982
|
executors,
|
|
30975
30983
|
activate(ctx) {
|
|
30984
|
+
ctx.command({
|
|
30985
|
+
name: "effectiveConfig",
|
|
30986
|
+
description: "Settings form: the account directory an empty path resolves to on this machine.",
|
|
30987
|
+
scope: "read",
|
|
30988
|
+
payloadSchema: EXECUTOR_EFFECTIVE_PAYLOAD_SCHEMA,
|
|
30989
|
+
handle: async (payload) => {
|
|
30990
|
+
const request = readExecutorEffectiveRequest(payload);
|
|
30991
|
+
return {
|
|
30992
|
+
homePath: executorHomeEffectiveValue(
|
|
30993
|
+
"GROK_HOME",
|
|
30994
|
+
request,
|
|
30995
|
+
process.env,
|
|
30996
|
+
(value) => resolveGrokHomePath(value ?? "")
|
|
30997
|
+
)
|
|
30998
|
+
};
|
|
30999
|
+
}
|
|
31000
|
+
});
|
|
30976
31001
|
ctx.log.info("grok executor ready");
|
|
30977
31002
|
}
|
|
30978
31003
|
});
|
package/locales/en.json
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
{
|
|
2
|
+
"presentation": {
|
|
3
|
+
"name": "Grok",
|
|
4
|
+
"description": "Use Grok in Ycodium and pick up earlier sessions where they left off."
|
|
5
|
+
},
|
|
2
6
|
"form": {
|
|
3
7
|
"binaryPath": {
|
|
4
8
|
"title": "Program path",
|
|
@@ -9,6 +13,11 @@
|
|
|
9
13
|
"title": "Account directory",
|
|
10
14
|
"description": "Sessions and the `grok login` credentials live here, so providers sharing this directory can pick up each other's threads and providers with different directories cannot. Leave empty to use the CLI's default (~/.grok).",
|
|
11
15
|
"placeholder": "e.g. ~/.grok-work"
|
|
16
|
+
},
|
|
17
|
+
"effective": {
|
|
18
|
+
"provider": "{{name}} in this provider",
|
|
19
|
+
"machine": "{{name}} on this machine",
|
|
20
|
+
"default": "default"
|
|
12
21
|
}
|
|
13
22
|
},
|
|
14
23
|
"usage": {
|
package/locales/zh-CN.json
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
{
|
|
2
|
+
"presentation": {
|
|
3
|
+
"name": "Grok",
|
|
4
|
+
"description": "在 Ycodium 里使用 Grok,之前的会话可以接着做。"
|
|
5
|
+
},
|
|
2
6
|
"form": {
|
|
3
7
|
"binaryPath": {
|
|
4
8
|
"title": "程序路径",
|
|
@@ -9,6 +13,11 @@
|
|
|
9
13
|
"title": "账号目录",
|
|
10
14
|
"description": "会话和 `grok login` 的凭据都保存在这里,因此共用同一目录的 provider 可以接手彼此的会话,目录不同的则不能。留空则使用该命令行工具的默认目录(~/.grok)。",
|
|
11
15
|
"placeholder": "例如 ~/.grok-work"
|
|
16
|
+
},
|
|
17
|
+
"effective": {
|
|
18
|
+
"provider": "本 provider 的 {{name}}",
|
|
19
|
+
"machine": "本机的 {{name}}",
|
|
20
|
+
"default": "默认"
|
|
12
21
|
}
|
|
13
22
|
},
|
|
14
23
|
"usage": {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ycodium-ai/agent-grok",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.3766",
|
|
4
4
|
"description": "Grok executor: grok CLI over Agent Client Protocol stdio.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ycodium",
|
|
@@ -21,14 +21,16 @@
|
|
|
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.
|
|
25
|
-
"ycodium-acp-executor": "0.2.
|
|
24
|
+
"@ycodium-ai/plugin-api": "0.2.3766",
|
|
25
|
+
"ycodium-acp-executor": "0.2.3766",
|
|
26
26
|
"ycodium-executor-testing": "0.0.0"
|
|
27
27
|
},
|
|
28
28
|
"ycodium": {
|
|
29
29
|
"plugin": "./dist/index.js",
|
|
30
30
|
"displayName": "Grok",
|
|
31
|
-
"
|
|
31
|
+
"displayNameKey": "presentation.name",
|
|
32
|
+
"description": "Use Grok in Ycodium and pick up earlier sessions where they left off.",
|
|
33
|
+
"descriptionKey": "presentation.description",
|
|
32
34
|
"icon": "./assets/icon.svg",
|
|
33
35
|
"permissions": [
|
|
34
36
|
{
|