@aiwg/cli 2026.10.1 → 2026.10.3
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/agentic/code/providers/capability-matrix.yaml +270 -0
- package/agentic/code/providers/model-capabilities.v1.json +3091 -24
- package/bin/aiwg.mjs +86 -21
- package/dist/src/a2a/codecs.js +9 -0
- package/dist/src/artifacts/corpus-tools/vision-extract.js +105 -15
- package/dist/src/artifacts/repair.js +9 -4
- package/dist/src/channel/manager.mjs +59 -10
- package/dist/src/cli/child-process-result.js +40 -0
- package/dist/src/cli/env.js +38 -16
- package/dist/src/cli/flag-parsing.js +236 -0
- package/dist/src/cli/handlers/decision.js +210 -4
- package/dist/src/cli/handlers/diagnose.js +9 -2
- package/dist/src/cli/handlers/feedback.js +14 -5
- package/dist/src/cli/handlers/init.js +245 -30
- package/dist/src/cli/handlers/mc.js +23 -0
- package/dist/src/cli/handlers/models.js +69 -6
- package/dist/src/cli/handlers/ralph.js +3 -0
- package/dist/src/cli/handlers/refresh.js +16 -0
- package/dist/src/cli/handlers/regenerate.js +14 -0
- package/dist/src/cli/handlers/runtime-info.js +24 -9
- package/dist/src/cli/handlers/script-runner.js +16 -6
- package/dist/src/cli/handlers/session.js +396 -62
- package/dist/src/cli/handlers/sessions.js +146 -40
- package/dist/src/cli/handlers/setup-manifest.js +439 -39
- package/dist/src/cli/handlers/setup.js +139 -39
- package/dist/src/cli/handlers/subcommands.js +3 -1
- package/dist/src/cli/handlers/team.js +18 -8
- package/dist/src/cli/handlers/use.js +13 -0
- package/dist/src/cli/handlers/utilities.js +106 -23
- package/dist/src/cli/prompt-utils.js +72 -0
- package/dist/src/cli/provider-resolution.js +11 -0
- package/dist/src/config/aiwg-config.js +268 -4
- package/dist/src/config/cli.js +146 -19
- package/dist/src/config/dispatch-thresholds-runtime.mjs +38 -0
- package/dist/src/config/project-artifacts-health.mjs +14 -3
- package/dist/src/config/user-config.js +36 -10
- package/dist/src/decision/adapters/jev.js +75 -27
- package/dist/src/decision/driver.js +3 -1
- package/dist/src/decision/entry.js +38 -6
- package/dist/src/decision/heldout/collector.js +10 -1
- package/dist/src/decision/index.js +1 -0
- package/dist/src/decision/interop.js +60 -8
- package/dist/src/decision/ledger.js +839 -0
- package/dist/src/decision/validate.js +6 -3
- package/dist/src/effects/dispatch-verifier.js +252 -0
- package/dist/src/effects/index.js +1 -0
- package/dist/src/features/installer.js +2 -2
- package/dist/src/flow/graph-metadata.js +5 -0
- package/dist/src/gates/providers/loader.js +3 -1
- package/dist/src/installation/manager-command.mjs +1 -1
- package/dist/src/installation/manager.mjs +17 -2
- package/dist/src/lint/runner.js +2 -2
- package/dist/src/mcp/adapters/codex-runtime.js +360 -56
- package/dist/src/mcp/cli.mjs +587 -77
- package/dist/src/mcp/config-file.mjs +279 -0
- package/dist/src/mcp/config-layers.mjs +348 -0
- package/dist/src/mcp/credentials.mjs +484 -0
- package/dist/src/mcp/grok-build-config.mjs +16 -26
- package/dist/src/mcp/helpers.mjs +106 -2
- package/dist/src/mcp/omp-config.mjs +50 -29
- package/dist/src/mcp/profiles.js +97 -23
- package/dist/src/mcp/profiles.mjs +99 -27
- package/dist/src/mcp/registry.js +264 -57
- package/dist/src/mcp/registry.mjs +198 -45
- package/dist/src/mcp/server.mjs +403 -20
- package/dist/src/mcp/toml-string.mjs +9 -0
- package/dist/src/mcp/toml-strip-mcp.mjs +135 -0
- package/dist/src/mcp/tool-filters.mjs +357 -0
- package/dist/src/mcp/tools/agentic-sandbox.mjs +3 -1
- package/dist/src/mcp/tools/decision.mjs +21 -3
- package/dist/src/mcp/tools/orchestration.mjs +38 -0
- package/dist/src/mcp/tools/subsystems.mjs +39 -8
- package/dist/src/mcp/tools/worker-invoke.mjs +1539 -0
- package/dist/src/mcp/tools/worker-shell-control.mjs +258 -0
- package/dist/src/mcp/tools/worker-stdin-runtime.mjs +79 -0
- package/dist/src/memory/project-registry.js +2 -2
- package/dist/src/mission-protocol/codecs.js +639 -1
- package/dist/src/mission-protocol/types.js +110 -0
- package/dist/src/mission-protocol/worker-status.js +2 -0
- package/dist/src/models/config-loader.js +70 -13
- package/dist/src/models/grok-build-models.js +93 -41
- package/dist/src/models/model-capabilities.v1.json +3091 -24
- package/dist/src/models/model-discovery.js +862 -63
- package/dist/src/models/provider-policy.js +625 -11
- package/dist/src/models/qualification-digest.mjs +17 -0
- package/dist/src/models/resolver.js +259 -0
- package/dist/src/models/worker-direct-readiness.js +529 -0
- package/dist/src/models/worker-dispatch-offer.js +169 -0
- package/dist/src/models/worker-health-readiness.js +131 -0
- package/dist/src/models/worker-installation.mjs +879 -0
- package/dist/src/models/wrapper-route.js +18 -0
- package/dist/src/ops/registry.js +9 -14
- package/dist/src/plugins/standalone-packager.js +4 -3
- package/dist/src/process/bounded-child-process.mjs +387 -0
- package/dist/src/process/cli-command.mjs +75 -0
- package/dist/src/providers/capability-matrix.js +8 -0
- package/dist/src/providers/capability-matrix.yaml +270 -0
- package/dist/src/providers/grok-build-headless.js +43 -21
- package/dist/src/providers/provider-definitions.js +9 -1
- package/dist/src/providers/provider-definitions.mjs +9 -2
- package/dist/src/serve/executor-registry.js +16 -24
- package/dist/src/serve/fleet-mission-conductor.js +9 -0
- package/dist/src/serve/mission-conductor.js +9 -0
- package/dist/src/serve/shared-host-scheduler.js +2 -0
- package/dist/src/serve/worker-invocation.js +538 -0
- package/dist/src/serve/worker-stdin-frame.mjs +107 -0
- package/dist/src/sessions/adapter-registry.js +45 -0
- package/dist/src/sessions/adapters/generic.js +37 -3
- package/dist/src/sessions/adapters/grokbot-locator.js +111 -0
- package/dist/src/sessions/adapters/grokbot.js +423 -24
- package/dist/src/sessions/adapters/muse-workspace-scan.js +108 -0
- package/dist/src/sessions/adapters/muse.js +68 -29
- package/dist/src/sessions/adapters/pi.js +1 -0
- package/dist/src/sessions/batch-contracts.js +13 -1
- package/dist/src/sessions/batch-import.js +23 -42
- package/dist/src/sessions/candidates.js +47 -11
- package/dist/src/sessions/contracts.js +35 -0
- package/dist/src/sessions/coverage-preflight.js +134 -0
- package/dist/src/sessions/discovery.js +3 -0
- package/dist/src/sessions/grok-build-cli.js +67 -5
- package/dist/src/sessions/importer.js +24 -8
- package/dist/src/sessions/index.js +2 -0
- package/dist/src/sessions/repository.js +54 -13
- package/dist/src/sessions/workspace-discovery.js +99 -37
- package/dist/src/skills/adapters/clawhub.js +10 -8
- package/dist/src/skills/adapters/openclaw.js +10 -7
- package/dist/src/smiths/context-pipeline/parallelism-section.js +192 -3
- package/dist/src/smiths/context-pipeline/workspace-context.js +116 -9
- package/dist/src/smiths/hook-bridge/codex-translator.js +6 -5
- package/dist/src/smiths/mcpsmith/example.js +1 -1
- package/dist/src/smiths/toolsmith/runtime-discovery.mjs +10 -14
- package/dist/src/storage/backends/logseq.js +68 -7
- package/dist/src/storage/fortemi-qualification-receipt.js +2 -2
- package/dist/src/testing/generators/test-code-generator.js +57 -30
- package/dist/src/uhp/client.js +11 -1
- package/dist/src/uhp/mission.js +5 -0
- package/dist/src/update/checker.mjs +5 -5
- package/dist/src/update/notifier.mjs +54 -2
- package/dist/src/writing/fidelity.js +18 -1
- package/package.json +18 -1
- package/schemas/mission-v1.schema.json +2429 -0
- package/schemas/models/model-catalog.v1.schema.json +301 -0
- package/schemas/models/model-config-compatibility.v1.schema.json +281 -0
- package/schemas/models/model-policy.v1.schema.json +14 -0
- package/schemas/models/provider-model-capabilities.v1.schema.json +1066 -0
- package/tools/_resolve-impl.mjs +39 -0
- package/tools/agents/deploy-agents.mjs +15 -2
- package/tools/agents/providers/base.mjs +49 -32
- package/tools/agents/providers/grokbot.mjs +11 -12
- package/tools/agents/providers/hermes.mjs +6 -3
- package/tools/agents/providers/omp.mjs +5 -2
- package/tools/agents/providers/openclaw-translator.mjs +19 -5
- package/tools/providers/deepseek-harness-transport.mjs +358 -0
- package/tools/providers/omp-transport.mjs +192 -0
- package/tools/ralph-external/lib/claude-adapter.mjs +389 -0
- package/tools/ralph-external/lib/codex-adapter.mjs +432 -0
- package/tools/ralph-external/lib/deepseek-harness-adapter.mjs +397 -0
- package/tools/ralph-external/lib/factory-adapter.mjs +503 -0
- package/tools/ralph-external/lib/muse-adapter.mjs +364 -0
- package/tools/ralph-external/lib/omp-adapter.mjs +315 -0
- package/tools/ralph-external/lib/opencode-adapter.mjs +575 -0
- package/tools/ralph-external/lib/openhuman-adapter.mjs +75 -0
- package/tools/ralph-external/lib/pi-adapter.mjs +333 -0
- package/tools/ralph-external/lib/provider-adapter.mjs +690 -0
- package/tools/ralph-external/lib/worker-health.mjs +439 -0
- package/vscode-extension/schemas/aiwg.config.v1.json +1953 -0
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { ClaudeSessionAdapter } from './adapters/claude.js';
|
|
2
|
+
import { CodexSessionAdapter } from './adapters/codex.js';
|
|
3
|
+
import { CopilotSessionAdapter } from './adapters/copilot.js';
|
|
4
|
+
import { CursorSessionAdapter } from './adapters/cursor.js';
|
|
5
|
+
import { FactorySessionAdapter } from './adapters/factory.js';
|
|
6
|
+
import { HermesSessionAdapter } from './adapters/hermes.js';
|
|
7
|
+
import { OpenCodeSessionAdapter } from './adapters/opencode.js';
|
|
8
|
+
import { OpenClawSessionAdapter } from './adapters/openclaw.js';
|
|
9
|
+
import { OpenHumanSessionAdapter } from './adapters/openhuman.js';
|
|
10
|
+
import { GrokbotSessionAdapter } from './adapters/grokbot.js';
|
|
11
|
+
import { GrokBuildSessionAdapter } from './adapters/grok-build.js';
|
|
12
|
+
import { MuseSessionAdapter } from './adapters/muse.js';
|
|
13
|
+
import { PiSessionAdapter } from './adapters/pi.js';
|
|
14
|
+
import { OmpSessionAdapter } from './adapters/omp.js';
|
|
15
|
+
import { DeepSeekHarnessSessionAdapter } from './adapters/deepseek-harness.js';
|
|
16
|
+
import { WarpSessionAdapter } from './adapters/warp.js';
|
|
17
|
+
import { DevinDesktopSessionAdapter } from './adapters/windsurf.js';
|
|
18
|
+
import { GenericSessionInterchangeAdapter } from './adapters/generic.js';
|
|
19
|
+
import { SessionSourceAdapterRegistry } from './discovery.js';
|
|
20
|
+
export function createSessionAdapterRegistry() {
|
|
21
|
+
const registry = new SessionSourceAdapterRegistry();
|
|
22
|
+
for (const adapter of [
|
|
23
|
+
new ClaudeSessionAdapter(),
|
|
24
|
+
new CodexSessionAdapter(),
|
|
25
|
+
new CopilotSessionAdapter(),
|
|
26
|
+
new CursorSessionAdapter(),
|
|
27
|
+
new FactorySessionAdapter(),
|
|
28
|
+
new HermesSessionAdapter(),
|
|
29
|
+
new OpenCodeSessionAdapter(),
|
|
30
|
+
new OpenClawSessionAdapter(),
|
|
31
|
+
new OpenHumanSessionAdapter(),
|
|
32
|
+
new GrokbotSessionAdapter(),
|
|
33
|
+
new GrokBuildSessionAdapter(),
|
|
34
|
+
new MuseSessionAdapter(),
|
|
35
|
+
new PiSessionAdapter(),
|
|
36
|
+
new OmpSessionAdapter(),
|
|
37
|
+
new DeepSeekHarnessSessionAdapter(),
|
|
38
|
+
new WarpSessionAdapter(),
|
|
39
|
+
new DevinDesktopSessionAdapter(),
|
|
40
|
+
new GenericSessionInterchangeAdapter(),
|
|
41
|
+
])
|
|
42
|
+
registry.register(adapter);
|
|
43
|
+
return registry;
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=adapter-registry.js.map
|
|
@@ -88,6 +88,7 @@ export class GenericSessionInterchangeAdapter {
|
|
|
88
88
|
sourceSchemaVersion: header.schemaVersion,
|
|
89
89
|
consistency: header.consistency,
|
|
90
90
|
operationalState: 'available',
|
|
91
|
+
declaredWorkspaceId: header.workspace.id,
|
|
91
92
|
};
|
|
92
93
|
}
|
|
93
94
|
async *stream(source, cursor) {
|
|
@@ -179,7 +180,10 @@ export class GenericSessionInterchangeAdapter {
|
|
|
179
180
|
const header = parseHeader(value);
|
|
180
181
|
assertSupportedSchemaMajor(header.schemaVersion);
|
|
181
182
|
if (header.sourceId !== source.sourceId) {
|
|
182
|
-
|
|
183
|
+
// SCHEMA_DRIFT: the selected identity no longer describes this file's
|
|
184
|
+
// declared source, so importing it would attach events to the wrong source.
|
|
185
|
+
throw new SessionContractError('SCHEMA_DRIFT', `selected source identity does not match interchange header: --source-id ${quoteValue(source.sourceId)} `
|
|
186
|
+
+ `but header sourceId is ${quoteValue(header.sourceId)}; pass --source-id ${quoteValue(header.sourceId)}`);
|
|
183
187
|
}
|
|
184
188
|
return header;
|
|
185
189
|
}
|
|
@@ -200,7 +204,10 @@ function parseHeader(value) {
|
|
|
200
204
|
if (hasAmbiguousTimestamp(result.error)) {
|
|
201
205
|
throw new SessionContractError('AMBIGUOUS_TIMESTAMP', 'generic interchange header has an ambiguous timestamp');
|
|
202
206
|
}
|
|
203
|
-
|
|
207
|
+
if (!isDeclaredInterchange(value)) {
|
|
208
|
+
throw new SessionContractError('MALFORMED_SOURCE', 'input is not a declared AIWG generic session interchange');
|
|
209
|
+
}
|
|
210
|
+
throw new SessionContractError('MALFORMED_SOURCE', `generic interchange header ${describeIssue(result.error, true)}`);
|
|
204
211
|
}
|
|
205
212
|
function parseEvent(value) {
|
|
206
213
|
const result = GenericInterchangeEventSchema.safeParse(value);
|
|
@@ -209,7 +216,34 @@ function parseEvent(value) {
|
|
|
209
216
|
if (hasAmbiguousTimestamp(result.error)) {
|
|
210
217
|
throw new SessionContractError('AMBIGUOUS_TIMESTAMP', 'generic interchange event has an ambiguous timestamp');
|
|
211
218
|
}
|
|
212
|
-
|
|
219
|
+
// Event values can carry transcript content, so name the field and the
|
|
220
|
+
// expected shape without echoing the received value.
|
|
221
|
+
throw new SessionContractError('MALFORMED_SOURCE', `generic interchange event is malformed: ${describeIssue(result.error, false)}`);
|
|
222
|
+
}
|
|
223
|
+
function isDeclaredInterchange(value) {
|
|
224
|
+
return typeof value === 'object' && value !== null
|
|
225
|
+
&& value.type === GENERIC_INTERCHANGE_KIND;
|
|
226
|
+
}
|
|
227
|
+
function quoteValue(value) {
|
|
228
|
+
const text = typeof value === 'string' ? value : JSON.stringify(value) ?? String(value);
|
|
229
|
+
return JSON.stringify(text.length > 64 ? `${text.slice(0, 64)}…` : text);
|
|
230
|
+
}
|
|
231
|
+
function describeIssue(error, echoReceived) {
|
|
232
|
+
const issue = error.issues[0];
|
|
233
|
+
const field = issue.path.length > 0 ? `field "${issue.path.join('.')}"` : 'record';
|
|
234
|
+
if (issue.code === z.ZodIssueCode.invalid_enum_value) {
|
|
235
|
+
const received = echoReceived ? ` (got ${quoteValue(issue.received)})` : '';
|
|
236
|
+
return `${field} must be one of ${issue.options.join('|')}${received}`;
|
|
237
|
+
}
|
|
238
|
+
if (issue.code === z.ZodIssueCode.invalid_type) {
|
|
239
|
+
return issue.received === 'undefined'
|
|
240
|
+
? `${field} is required (${issue.expected})`
|
|
241
|
+
: `${field} must be ${issue.expected} (got ${issue.received})`;
|
|
242
|
+
}
|
|
243
|
+
if (issue.code === z.ZodIssueCode.invalid_literal) {
|
|
244
|
+
return `${field} must be ${quoteValue(issue.expected)}`;
|
|
245
|
+
}
|
|
246
|
+
return `${field} is invalid: ${issue.message}`;
|
|
213
247
|
}
|
|
214
248
|
function hasAmbiguousTimestamp(error) {
|
|
215
249
|
return error.issues.some((issue) => issue.code === z.ZodIssueCode.custom
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Grok Bot desktop native-store locator primitives (#2970).
|
|
3
|
+
*
|
|
4
|
+
* The Grok Bot desktop app ("sand") persists one JSON document per logical
|
|
5
|
+
* key under `$XDG_CONFIG_HOME/Grok Bot/sand-client-persistence/` (default
|
|
6
|
+
* `~/.config/Grok Bot/...`, Linux only — macOS/Windows equivalents are
|
|
7
|
+
* unverified and must never be guessed). Each file is named `<key>.blob`,
|
|
8
|
+
* where `<key>` is the RFC 4648 section 6 base32 encoding of the key string,
|
|
9
|
+
* lowercase, unpadded.
|
|
10
|
+
*
|
|
11
|
+
* This module decodes filenames ONLY — it never opens file content. The
|
|
12
|
+
* adapter layer uses {@link classifyGrokbotBlobName} to build a strict
|
|
13
|
+
* allowlist: only filenames that decode to a transcript-replica or
|
|
14
|
+
* last-roster key are ever candidates for opening. Every other `.blob` file
|
|
15
|
+
* (composer drafts, send journal, experiments, UI layout, secrets, cookies,
|
|
16
|
+
* local/session storage, etc.) is left untouched.
|
|
17
|
+
*
|
|
18
|
+
* @see docs/providers/grokbot-sessions.md
|
|
19
|
+
* @issue #2970
|
|
20
|
+
*/
|
|
21
|
+
const BASE32_ALPHABET = 'abcdefghijklmnopqrstuvwxyz234567';
|
|
22
|
+
const BASE32_INDEX = new Map(BASE32_ALPHABET.split('').map((char, index) => [char, index]));
|
|
23
|
+
const BASE32_SHAPE = /^[a-z2-7]+$/;
|
|
24
|
+
const TRANSCRIPT_REPLICA_KEY_PATTERN = /^sand\.client\.slice\.account\.grok%7Cuser_[^.]+\.transcript\.replicas\.([0-9a-fA-F-]{36})$/;
|
|
25
|
+
const ROSTER_KEY_PATTERN = /^sand\.client\.slice\.account\.grok%7Cuser_[^.]+\.roster\.last-roster$/;
|
|
26
|
+
/** Unpadded lowercase RFC 4648 base32 encode, most significant bit first. */
|
|
27
|
+
export function encodeGrokbotKey(key) {
|
|
28
|
+
const bytes = Buffer.from(key, 'utf8');
|
|
29
|
+
let bits = 0;
|
|
30
|
+
let value = 0;
|
|
31
|
+
let out = '';
|
|
32
|
+
for (const byte of bytes) {
|
|
33
|
+
value = ((value << 8) | byte) & 0xffff;
|
|
34
|
+
bits += 8;
|
|
35
|
+
while (bits >= 5) {
|
|
36
|
+
out += BASE32_ALPHABET[(value >>> (bits - 5)) & 31];
|
|
37
|
+
bits -= 5;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
if (bits > 0)
|
|
41
|
+
out += BASE32_ALPHABET[(value << (5 - bits)) & 31];
|
|
42
|
+
return out;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Decode an unpadded lowercase RFC 4648 base32 string back to its original
|
|
46
|
+
* UTF-8 key. Returns null for anything that is not canonical base32 (wrong
|
|
47
|
+
* alphabet, or non-zero padding bits) rather than guessing.
|
|
48
|
+
*/
|
|
49
|
+
export function decodeGrokbotKey(encoded) {
|
|
50
|
+
if (encoded.length === 0 || !BASE32_SHAPE.test(encoded))
|
|
51
|
+
return null;
|
|
52
|
+
const bytes = [];
|
|
53
|
+
let buffer = 0;
|
|
54
|
+
let bitsLeft = 0;
|
|
55
|
+
for (const char of encoded) {
|
|
56
|
+
const index = BASE32_INDEX.get(char);
|
|
57
|
+
if (index === undefined)
|
|
58
|
+
return null;
|
|
59
|
+
buffer = (buffer << 5) | index;
|
|
60
|
+
bitsLeft += 5;
|
|
61
|
+
if (bitsLeft >= 8) {
|
|
62
|
+
bitsLeft -= 8;
|
|
63
|
+
bytes.push((buffer >> bitsLeft) & 0xff);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
if (bitsLeft >= 5)
|
|
67
|
+
return null;
|
|
68
|
+
if (bitsLeft > 0 && (buffer & ((1 << bitsLeft) - 1)) !== 0)
|
|
69
|
+
return null;
|
|
70
|
+
try {
|
|
71
|
+
return Buffer.from(bytes).toString('utf8');
|
|
72
|
+
}
|
|
73
|
+
catch {
|
|
74
|
+
return null;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Classify a `<base32>.blob` filename WITHOUT opening it. Returns null for
|
|
79
|
+
* anything that is not a `.blob` file, does not decode to canonical base32,
|
|
80
|
+
* or decodes to a key outside the allowlist (composer drafts, send journal,
|
|
81
|
+
* experiments, ui-layout, secrets, cookies, storage, etc.).
|
|
82
|
+
*/
|
|
83
|
+
export function classifyGrokbotBlobName(filename) {
|
|
84
|
+
if (!filename.endsWith('.blob'))
|
|
85
|
+
return null;
|
|
86
|
+
const encoded = filename.slice(0, -'.blob'.length);
|
|
87
|
+
const key = decodeGrokbotKey(encoded);
|
|
88
|
+
if (key === null)
|
|
89
|
+
return null;
|
|
90
|
+
const transcript = TRANSCRIPT_REPLICA_KEY_PATTERN.exec(key);
|
|
91
|
+
if (transcript)
|
|
92
|
+
return { kind: 'transcript-replica', conversationId: transcript[1] };
|
|
93
|
+
if (ROSTER_KEY_PATTERN.test(key))
|
|
94
|
+
return { kind: 'roster' };
|
|
95
|
+
return null;
|
|
96
|
+
}
|
|
97
|
+
/** Build the `<key>.blob` filename for a transcript replica (test fixtures only). */
|
|
98
|
+
export function grokbotTranscriptReplicaFilename(account, conversationId) {
|
|
99
|
+
return `${encodeGrokbotKey(`sand.client.slice.account.grok%7Cuser_${account}.transcript.replicas.${conversationId}`)}.blob`;
|
|
100
|
+
}
|
|
101
|
+
/** Build the `<key>.blob` filename for the account roster (test fixtures only). */
|
|
102
|
+
export function grokbotRosterFilename(account) {
|
|
103
|
+
return `${encodeGrokbotKey(`sand.client.slice.account.grok%7Cuser_${account}.roster.last-roster`)}.blob`;
|
|
104
|
+
}
|
|
105
|
+
/** Extract the conversation id from an authorized transcript-replica locator path, or null. */
|
|
106
|
+
export function grokbotConversationIdFromLocator(locator) {
|
|
107
|
+
const base = locator.replaceAll('\\', '/').split('/').pop() ?? '';
|
|
108
|
+
const classification = classifyGrokbotBlobName(base);
|
|
109
|
+
return classification?.kind === 'transcript-replica' ? classification.conversationId : null;
|
|
110
|
+
}
|
|
111
|
+
//# sourceMappingURL=grokbot-locator.js.map
|