@jmanuelcorral/openteam 0.12.0 → 0.13.1
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/README.es.md +2 -2
- package/README.md +2 -2
- package/dist/cli/consoleServe.d.ts +1 -1
- package/dist/cli.js +87 -21
- package/dist/commands/dispatch.d.ts +7 -0
- package/dist/commands/dispatch.d.ts.map +1 -1
- package/dist/commands/doctor.d.ts +13 -0
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/purge.d.ts.map +1 -1
- package/dist/commands/setup.d.ts +19 -1
- package/dist/commands/setup.d.ts.map +1 -1
- package/dist/config/resolve.d.ts +19 -18
- package/dist/config/resolve.d.ts.map +1 -1
- package/dist/config/schema.d.ts +19 -9
- package/dist/config/schema.d.ts.map +1 -1
- package/dist/console/assets.d.ts +1 -1
- package/dist/console/assets.d.ts.map +1 -1
- package/dist/console/render.d.ts +4 -9
- package/dist/console/render.d.ts.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +211 -154
- package/dist/storage/graph/soakRecorder.d.ts +19 -0
- package/dist/storage/graph/soakRecorder.d.ts.map +1 -1
- package/dist/web/graphRoute.d.ts +19 -20
- package/dist/web/graphRoute.d.ts.map +1 -1
- package/dist/web/server.d.ts +3 -3
- package/dist/web/start.d.ts +3 -4
- package/dist/web/start.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -293,7 +293,7 @@ var GraphEngineSchema = z2.enum(["builtin", "langgraph"]);
|
|
|
293
293
|
var DEFAULT_GRAPH_JOURNAL_ROOT = ".opencode/openteam-local/graph/runs";
|
|
294
294
|
var DEFAULT_GRAPH_WORKTREES_DIR = ".opencode/openteam-local/graph/worktrees";
|
|
295
295
|
var GraphConfigSchema = z2.object({
|
|
296
|
-
mode: GraphModeSchema.default("
|
|
296
|
+
mode: GraphModeSchema.default("shadow"),
|
|
297
297
|
engine: GraphEngineSchema.optional(),
|
|
298
298
|
killSwitch: z2.boolean().default(false),
|
|
299
299
|
journalRoot: z2.string().min(1).default(DEFAULT_GRAPH_JOURNAL_ROOT),
|
|
@@ -316,8 +316,8 @@ var ConsoleConfigSchema = z2.object({
|
|
|
316
316
|
pty: z2.boolean().optional()
|
|
317
317
|
}).strict().default({ enabled: true }),
|
|
318
318
|
graphView: z2.object({
|
|
319
|
-
enabled: z2.boolean().default(
|
|
320
|
-
}).strict().
|
|
319
|
+
enabled: z2.boolean().default(true)
|
|
320
|
+
}).strict().default({ enabled: true })
|
|
321
321
|
}).strict().default({
|
|
322
322
|
host: "127.0.0.1",
|
|
323
323
|
port: 4599,
|
|
@@ -326,7 +326,8 @@ var ConsoleConfigSchema = z2.object({
|
|
|
326
326
|
recentRoutes: 50,
|
|
327
327
|
openBrowser: false,
|
|
328
328
|
remoteStorage: false,
|
|
329
|
-
terminal: { enabled: true }
|
|
329
|
+
terminal: { enabled: true },
|
|
330
|
+
graphView: { enabled: true }
|
|
330
331
|
});
|
|
331
332
|
var DEFAULT_STORAGE_SQLITE_INDEX_PATH = ".opencode/openteam-local/index.sqlite";
|
|
332
333
|
var StorageConfigSchema = z2.object({
|
|
@@ -505,7 +506,13 @@ var OpenTeamConfigObjectSchema = z2.object({
|
|
|
505
506
|
console: ConsoleConfigSchema,
|
|
506
507
|
storage: StorageConfigSchema,
|
|
507
508
|
memory: MemoryConfigSchema.optional(),
|
|
508
|
-
graph: GraphConfigSchema.
|
|
509
|
+
graph: GraphConfigSchema.default({
|
|
510
|
+
mode: "shadow",
|
|
511
|
+
killSwitch: false,
|
|
512
|
+
journalRoot: DEFAULT_GRAPH_JOURNAL_ROOT,
|
|
513
|
+
operatorApproval: false,
|
|
514
|
+
worktrees: { enabled: false }
|
|
515
|
+
}),
|
|
509
516
|
orchestrator: OrchestratorConfigSchema.optional()
|
|
510
517
|
}).strict();
|
|
511
518
|
var OpenTeamConfigSchema = OpenTeamConfigObjectSchema;
|
|
@@ -2855,7 +2862,7 @@ function loadOpenTeamConfig(raw) {
|
|
|
2855
2862
|
|
|
2856
2863
|
// src/config/resolve.ts
|
|
2857
2864
|
function resolveGraphConfig(config, source) {
|
|
2858
|
-
const configuredMode = config.graph?.mode ?? "
|
|
2865
|
+
const configuredMode = config.graph?.mode ?? "shadow";
|
|
2859
2866
|
const killSwitch = config.graph?.killSwitch ?? false;
|
|
2860
2867
|
const effectiveMode = killSwitch ? "off" : configuredMode;
|
|
2861
2868
|
return {
|
|
@@ -8134,6 +8141,20 @@ function rosterHealthSection(audit, loadError, rosterRoleCount) {
|
|
|
8134
8141
|
}
|
|
8135
8142
|
return lines;
|
|
8136
8143
|
}
|
|
8144
|
+
function gitignoreSection(gitignore) {
|
|
8145
|
+
if (gitignore.missingRules.length === 0) {
|
|
8146
|
+
return [
|
|
8147
|
+
" gitignore:",
|
|
8148
|
+
` ✓ ${gitignore.path} ignores openteam's generated runtime state.`
|
|
8149
|
+
];
|
|
8150
|
+
}
|
|
8151
|
+
const quoted = gitignore.missingRules.map((rule) => `\`${rule}\``).join(", ");
|
|
8152
|
+
const lines = [" gitignore:"];
|
|
8153
|
+
lines.push(gitignore.exists ? ` ✗ ${gitignore.path} is missing openteam ignore rule(s): ${gitignore.missingRules.join(", ")}` : ` ✗ ${gitignore.path} does not exist, so no openteam ignore rule(s) are in place: ${gitignore.missingRules.join(", ")}`);
|
|
8154
|
+
lines.push(" problem: openteam writes machine-local runtime output (telemetry, graph state, soak recordings) that must not be committed.");
|
|
8155
|
+
lines.push(` remedy: add ${quoted} to ${gitignore.path} (or re-run \`openteam setup\`), then re-run \`openteam doctor\`.`);
|
|
8156
|
+
return lines;
|
|
8157
|
+
}
|
|
8137
8158
|
function agentModelsSection(diagnostics, searchedPaths) {
|
|
8138
8159
|
const lines = [" agent models:"];
|
|
8139
8160
|
if (diagnostics.length === 0) {
|
|
@@ -8181,6 +8202,9 @@ function renderDoctor(input) {
|
|
|
8181
8202
|
lines.push(...diagnosticsSection(input.diagnostics));
|
|
8182
8203
|
}
|
|
8183
8204
|
lines.push(...rosterHealthSection(input.rosterAudit, input.rosterLoadError, input.rosterRoleCount));
|
|
8205
|
+
if (input.gitignore !== undefined) {
|
|
8206
|
+
lines.push(...gitignoreSection(input.gitignore));
|
|
8207
|
+
}
|
|
8184
8208
|
if (input.otelBackend !== undefined) {
|
|
8185
8209
|
const otel = input.otelBackend;
|
|
8186
8210
|
lines.push(" opentelemetry:");
|
|
@@ -8446,6 +8470,143 @@ function renderMigration(report) {
|
|
|
8446
8470
|
// src/commands/purge.ts
|
|
8447
8471
|
import * as path3 from "node:path";
|
|
8448
8472
|
|
|
8473
|
+
// src/storage/graph/soakRecorder.ts
|
|
8474
|
+
var SOAK_EVIDENCE_DIR = ".opencode/soak";
|
|
8475
|
+
var SOAK_RECORDER_BASE_DIR = ".opencode";
|
|
8476
|
+
var SOAK_RECORDER_ID_FILENAME = "soak-recorder-id";
|
|
8477
|
+
var SOAK_RECORDER_ID_PATH = `${SOAK_RECORDER_BASE_DIR}/${SOAK_RECORDER_ID_FILENAME}`;
|
|
8478
|
+
async function ensureRecorderId(ports, basePath) {
|
|
8479
|
+
const idPath = `${basePath}/${SOAK_RECORDER_ID_FILENAME}`;
|
|
8480
|
+
if (await ports.fs.exists(idPath)) {
|
|
8481
|
+
const id = (await ports.fs.readFile(idPath)).trim();
|
|
8482
|
+
if (/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/.test(id)) {
|
|
8483
|
+
return id;
|
|
8484
|
+
}
|
|
8485
|
+
}
|
|
8486
|
+
const newId = ports.id.randomUUID();
|
|
8487
|
+
await ports.fs.writeFile(idPath, newId);
|
|
8488
|
+
return newId;
|
|
8489
|
+
}
|
|
8490
|
+
async function readAllChains(ports, evidenceDir) {
|
|
8491
|
+
if (!await ports.fs.exists(evidenceDir)) {
|
|
8492
|
+
return { chains: [], rejectedLines: 0, rejections: [] };
|
|
8493
|
+
}
|
|
8494
|
+
const files = await ports.fs.readDir(evidenceDir);
|
|
8495
|
+
const chains = [];
|
|
8496
|
+
const rejections = [];
|
|
8497
|
+
for (const file of files) {
|
|
8498
|
+
if (!file.endsWith(".jsonl")) {
|
|
8499
|
+
continue;
|
|
8500
|
+
}
|
|
8501
|
+
const content = await ports.fs.readFile(`${evidenceDir}/${file}`);
|
|
8502
|
+
const lines = content.split(`
|
|
8503
|
+
`);
|
|
8504
|
+
const observations = [];
|
|
8505
|
+
for (const [index, line] of lines.entries()) {
|
|
8506
|
+
if (line.trim().length === 0) {
|
|
8507
|
+
continue;
|
|
8508
|
+
}
|
|
8509
|
+
const lineNumber = index + 1;
|
|
8510
|
+
let rawParsed;
|
|
8511
|
+
try {
|
|
8512
|
+
rawParsed = JSON.parse(line);
|
|
8513
|
+
} catch {
|
|
8514
|
+
rejections.push({ file, lineNumber, detail: "invalid JSON" });
|
|
8515
|
+
continue;
|
|
8516
|
+
}
|
|
8517
|
+
const parsed = SoakObservationSchema.safeParse(rawParsed);
|
|
8518
|
+
if (parsed.success) {
|
|
8519
|
+
observations.push(parsed.data);
|
|
8520
|
+
} else {
|
|
8521
|
+
rejections.push({
|
|
8522
|
+
file,
|
|
8523
|
+
lineNumber,
|
|
8524
|
+
detail: formatSoakObservationIssues(parsed.error.issues)
|
|
8525
|
+
});
|
|
8526
|
+
}
|
|
8527
|
+
}
|
|
8528
|
+
if (observations.length > 0) {
|
|
8529
|
+
chains.push(observations);
|
|
8530
|
+
}
|
|
8531
|
+
}
|
|
8532
|
+
return { chains, rejectedLines: rejections.length, rejections };
|
|
8533
|
+
}
|
|
8534
|
+
function formatSoakObservationIssues(issues) {
|
|
8535
|
+
return issues.map((i) => `${i.path.join(".")}: ${i.code}`).join("; ");
|
|
8536
|
+
}
|
|
8537
|
+
function canonicalObservationPreimage2(obs) {
|
|
8538
|
+
return JSON.stringify({
|
|
8539
|
+
version: obs.version,
|
|
8540
|
+
seq: obs.seq,
|
|
8541
|
+
timestamp: obs.timestamp,
|
|
8542
|
+
platform: obs.platform,
|
|
8543
|
+
opencodeVersion: obs.opencodeVersion,
|
|
8544
|
+
provenance: obs.provenance,
|
|
8545
|
+
traceDigest: obs.traceDigest,
|
|
8546
|
+
criticalDivergences: obs.criticalDivergences,
|
|
8547
|
+
privacy: obs.privacy,
|
|
8548
|
+
duplicateEffects: obs.duplicateEffects,
|
|
8549
|
+
modelVerification: obs.modelVerification
|
|
8550
|
+
});
|
|
8551
|
+
}
|
|
8552
|
+
async function appendObservation(ports, evidenceDir, recorderId, input) {
|
|
8553
|
+
if (input.opencodeVersion === "unknown") {
|
|
8554
|
+
throw new Error("opencode-version-unreadable");
|
|
8555
|
+
}
|
|
8556
|
+
await ports.fs.mkdir(evidenceDir);
|
|
8557
|
+
const chainPath = `${evidenceDir}/${recorderId}.jsonl`;
|
|
8558
|
+
let seq = 0;
|
|
8559
|
+
let prevChainDigest = "0".repeat(64);
|
|
8560
|
+
if (await ports.fs.exists(chainPath)) {
|
|
8561
|
+
const content = await ports.fs.readFile(chainPath);
|
|
8562
|
+
const lines = content.split(`
|
|
8563
|
+
`).filter((l) => l.trim().length > 0);
|
|
8564
|
+
if (lines.length > 0) {
|
|
8565
|
+
const lastLine = lines[lines.length - 1];
|
|
8566
|
+
let rawParsed;
|
|
8567
|
+
try {
|
|
8568
|
+
rawParsed = JSON.parse(lastLine);
|
|
8569
|
+
} catch {
|
|
8570
|
+
throw new Error("corrupt chain tail: invalid JSON");
|
|
8571
|
+
}
|
|
8572
|
+
const parsed = SoakObservationSchema.safeParse(rawParsed);
|
|
8573
|
+
if (!parsed.success) {
|
|
8574
|
+
const detail = parsed.error.issues.map((i) => `${i.path.join(".")}: ${i.code}`).join("; ");
|
|
8575
|
+
throw new Error(`corrupt chain tail: ${detail}`);
|
|
8576
|
+
}
|
|
8577
|
+
seq = parsed.data.seq + 1;
|
|
8578
|
+
prevChainDigest = parsed.data.chainDigest;
|
|
8579
|
+
}
|
|
8580
|
+
}
|
|
8581
|
+
const timestamp = ports.clock.now();
|
|
8582
|
+
const base = {
|
|
8583
|
+
version: 1,
|
|
8584
|
+
seq,
|
|
8585
|
+
timestamp,
|
|
8586
|
+
platform: input.platform,
|
|
8587
|
+
opencodeVersion: input.opencodeVersion,
|
|
8588
|
+
provenance: input.provenance,
|
|
8589
|
+
traceDigest: input.traceDigest,
|
|
8590
|
+
criticalDivergences: input.criticalDivergences,
|
|
8591
|
+
privacy: input.privacy,
|
|
8592
|
+
duplicateEffects: input.duplicateEffects,
|
|
8593
|
+
modelVerification: input.modelVerification
|
|
8594
|
+
};
|
|
8595
|
+
const preimage = canonicalObservationPreimage2(base);
|
|
8596
|
+
const chainDigest = sha256Hex(prevChainDigest + preimage);
|
|
8597
|
+
const observation = { ...base, chainDigest };
|
|
8598
|
+
assertReferenceOnly(observation);
|
|
8599
|
+
const line = JSON.stringify(observation);
|
|
8600
|
+
if (await ports.fs.exists(chainPath)) {
|
|
8601
|
+
const existing = await ports.fs.readFile(chainPath);
|
|
8602
|
+
await ports.fs.writeFile(chainPath, `${existing}
|
|
8603
|
+
${line}`);
|
|
8604
|
+
} else {
|
|
8605
|
+
await ports.fs.writeFile(chainPath, line);
|
|
8606
|
+
}
|
|
8607
|
+
return observation;
|
|
8608
|
+
}
|
|
8609
|
+
|
|
8449
8610
|
// src/commands/setup.ts
|
|
8450
8611
|
var OPENTEAM_PLUGIN_SPEC = "@jmanuelcorral/openteam";
|
|
8451
8612
|
var OPENCODE_GITIGNORE_PATH = ".opencode/.gitignore";
|
|
@@ -8457,6 +8618,11 @@ var GENERATED_OPENTEAM_STATE_PATHS = [
|
|
|
8457
8618
|
DEFAULT_STORAGE_SQLITE_INDEX_PATH,
|
|
8458
8619
|
DEFAULT_MEMORY_INDEX_PATH
|
|
8459
8620
|
];
|
|
8621
|
+
var GENERATED_OPENTEAM_STATE_GROUPS = [
|
|
8622
|
+
{ kind: "dir", paths: GENERATED_OPENTEAM_STATE_PATHS },
|
|
8623
|
+
{ kind: "dir", paths: [SOAK_EVIDENCE_DIR] },
|
|
8624
|
+
{ kind: "file", paths: [SOAK_RECORDER_ID_PATH] }
|
|
8625
|
+
];
|
|
8460
8626
|
var OPENCODE_DIR = ".opencode";
|
|
8461
8627
|
var AGENT_DIR = `${OPENCODE_DIR}/agent`;
|
|
8462
8628
|
function splitSetupPath(path3) {
|
|
@@ -8477,18 +8643,27 @@ function commonGeneratedStateRoot(paths) {
|
|
|
8477
8643
|
}
|
|
8478
8644
|
return common.join("/");
|
|
8479
8645
|
}
|
|
8480
|
-
function generatedStateIgnoreRule() {
|
|
8481
|
-
const root = commonGeneratedStateRoot(
|
|
8646
|
+
function generatedStateIgnoreRule(group) {
|
|
8647
|
+
const root = commonGeneratedStateRoot(group.paths);
|
|
8482
8648
|
const opencodePrefix = `${OPENCODE_DIR}/`;
|
|
8483
8649
|
if (!root.startsWith(opencodePrefix)) {
|
|
8484
8650
|
throw new Error(`generated openteam state path is outside ${OPENCODE_DIR}`);
|
|
8485
8651
|
}
|
|
8486
|
-
|
|
8652
|
+
const rule = root.slice(opencodePrefix.length);
|
|
8653
|
+
return group.kind === "dir" ? `${rule}/` : rule;
|
|
8487
8654
|
}
|
|
8488
|
-
var OPENCODE_GITIGNORE_GENERATED_STATE_RULES =
|
|
8489
|
-
generatedStateIgnoreRule()
|
|
8490
|
-
];
|
|
8655
|
+
var OPENCODE_GITIGNORE_GENERATED_STATE_RULES = GENERATED_OPENTEAM_STATE_GROUPS.map(generatedStateIgnoreRule);
|
|
8491
8656
|
var LEGACY_OPENCODE_GITIGNORE_STATE_RULES = ["openteam/"];
|
|
8657
|
+
function normalizeGitignoreRule(line) {
|
|
8658
|
+
return line.trim().replace(/^\/+/, "");
|
|
8659
|
+
}
|
|
8660
|
+
function activeGitignoreRules(gitignore) {
|
|
8661
|
+
return gitignore.split(/\r?\n/).map(normalizeGitignoreRule).filter((line) => line.length > 0 && !line.startsWith("#"));
|
|
8662
|
+
}
|
|
8663
|
+
function missingGeneratedStateRules(gitignore) {
|
|
8664
|
+
const present = new Set(activeGitignoreRules(gitignore));
|
|
8665
|
+
return OPENCODE_GITIGNORE_GENERATED_STATE_RULES.filter((rule) => !present.has(rule));
|
|
8666
|
+
}
|
|
8492
8667
|
|
|
8493
8668
|
// src/commands/purge.ts
|
|
8494
8669
|
var PURGE_CATEGORY_IDS = [
|
|
@@ -8536,7 +8711,7 @@ function resolveStaticPurgeItems(config, paths) {
|
|
|
8536
8711
|
...paths.opencodeConfigPaths.map((p) => ({ kind: "opencode-config", path: p })),
|
|
8537
8712
|
{ kind: "gitignore", path: paths.gitignorePath }
|
|
8538
8713
|
],
|
|
8539
|
-
roster: [],
|
|
8714
|
+
roster: [{ kind: "file", path: OPENTEAM_ROSTER_PATH }],
|
|
8540
8715
|
decisions: [
|
|
8541
8716
|
{ kind: "file", path: paths.decisionsPath },
|
|
8542
8717
|
{ kind: "file", path: paths.telemetryPath }
|
|
@@ -8828,8 +9003,12 @@ function categoryPrompt(id, items) {
|
|
|
8828
9003
|
return "Remove openteam configuration and wiring?";
|
|
8829
9004
|
case "roster": {
|
|
8830
9005
|
const names = items.filter((item) => item.kind === "agent").map((item) => item.name);
|
|
8831
|
-
const
|
|
8832
|
-
|
|
9006
|
+
const hasRegistry = items.some((item) => item.kind === "file" && item.path === OPENTEAM_ROSTER_PATH);
|
|
9007
|
+
const plural = names.length === 1 ? "" : "s";
|
|
9008
|
+
const agentNames = names.length > 0 ? `: ${names.join(", ")}` : "";
|
|
9009
|
+
const agentClause = `${names.length} user agent${plural}${agentNames}`;
|
|
9010
|
+
const parts = hasRegistry ? [`roster registry (${OPENTEAM_ROSTER_PATH})`, agentClause] : [agentClause];
|
|
9011
|
+
return `Remove the agent roster? (${parts.join("; ")})`;
|
|
8833
9012
|
}
|
|
8834
9013
|
case "decisions":
|
|
8835
9014
|
return "Remove decisions and telemetry?";
|
|
@@ -8891,7 +9070,9 @@ async function collectCategories(input) {
|
|
|
8891
9070
|
const { runtime, config, paths } = input;
|
|
8892
9071
|
const staticItems = resolveStaticPurgeItems(config, paths);
|
|
8893
9072
|
const agents = await runtime.port.listAgents();
|
|
8894
|
-
const
|
|
9073
|
+
const discoveredAgents = agents.filter((agent) => path3.resolve(agent.path) !== path3.resolve(paths.orchestratorAgentPath)).map((agent) => ({ kind: "agent", path: agent.path, name: agent.name }));
|
|
9074
|
+
const rosterRegistry = await presentItemsFor(runtime.port, staticItems.roster);
|
|
9075
|
+
const rosterItems = [...rosterRegistry, ...discoveredAgents];
|
|
8895
9076
|
const worktrees = await runtime.port.listWorktrees();
|
|
8896
9077
|
const worktreeItems = worktrees.map((worktree) => ({
|
|
8897
9078
|
kind: "worktree",
|
|
@@ -10044,6 +10225,15 @@ async function runCli(argv, deps) {
|
|
|
10044
10225
|
...defaultModel !== undefined ? { defaultModel } : {}
|
|
10045
10226
|
});
|
|
10046
10227
|
const legacyLayout = deps.detectLegacyLayout !== undefined ? await deps.detectLegacyLayout() : undefined;
|
|
10228
|
+
let gitignoreCoverage;
|
|
10229
|
+
if (deps.readGitignore !== undefined) {
|
|
10230
|
+
const raw = await deps.readGitignore();
|
|
10231
|
+
gitignoreCoverage = {
|
|
10232
|
+
path: OPENCODE_GITIGNORE_PATH,
|
|
10233
|
+
exists: raw !== undefined,
|
|
10234
|
+
missingRules: missingGeneratedStateRules(raw ?? "")
|
|
10235
|
+
};
|
|
10236
|
+
}
|
|
10047
10237
|
const otelBackend = describeOtelBackendForDoctor({
|
|
10048
10238
|
backend: "opentelemetry",
|
|
10049
10239
|
connectionEnv: "APPLICATIONINSIGHTS_CONNECTION_STRING"
|
|
@@ -10076,7 +10266,8 @@ async function runCli(argv, deps) {
|
|
|
10076
10266
|
...opencodeConfigError !== undefined ? { opencodeConfigError } : {},
|
|
10077
10267
|
...cacheEntries !== undefined ? { cacheEntries, cliVersion: deps.version } : {},
|
|
10078
10268
|
...legacyLayout !== undefined && legacyLayout.length > 0 ? { legacyLayout } : {},
|
|
10079
|
-
...otelBackend !== undefined ? { otelBackend } : {}
|
|
10269
|
+
...otelBackend !== undefined ? { otelBackend } : {},
|
|
10270
|
+
...gitignoreCoverage !== undefined ? { gitignore: gitignoreCoverage } : {}
|
|
10080
10271
|
})
|
|
10081
10272
|
};
|
|
10082
10273
|
}
|
|
@@ -10752,139 +10943,6 @@ function compareShadowRun(legacy, shadow) {
|
|
|
10752
10943
|
};
|
|
10753
10944
|
}
|
|
10754
10945
|
|
|
10755
|
-
// src/storage/graph/soakRecorder.ts
|
|
10756
|
-
async function ensureRecorderId(ports, basePath) {
|
|
10757
|
-
const idPath = `${basePath}/soak-recorder-id`;
|
|
10758
|
-
if (await ports.fs.exists(idPath)) {
|
|
10759
|
-
const id = (await ports.fs.readFile(idPath)).trim();
|
|
10760
|
-
if (/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/.test(id)) {
|
|
10761
|
-
return id;
|
|
10762
|
-
}
|
|
10763
|
-
}
|
|
10764
|
-
const newId = ports.id.randomUUID();
|
|
10765
|
-
await ports.fs.writeFile(idPath, newId);
|
|
10766
|
-
return newId;
|
|
10767
|
-
}
|
|
10768
|
-
async function readAllChains(ports, evidenceDir) {
|
|
10769
|
-
if (!await ports.fs.exists(evidenceDir)) {
|
|
10770
|
-
return { chains: [], rejectedLines: 0, rejections: [] };
|
|
10771
|
-
}
|
|
10772
|
-
const files = await ports.fs.readDir(evidenceDir);
|
|
10773
|
-
const chains = [];
|
|
10774
|
-
const rejections = [];
|
|
10775
|
-
for (const file of files) {
|
|
10776
|
-
if (!file.endsWith(".jsonl")) {
|
|
10777
|
-
continue;
|
|
10778
|
-
}
|
|
10779
|
-
const content = await ports.fs.readFile(`${evidenceDir}/${file}`);
|
|
10780
|
-
const lines = content.split(`
|
|
10781
|
-
`);
|
|
10782
|
-
const observations = [];
|
|
10783
|
-
for (const [index, line] of lines.entries()) {
|
|
10784
|
-
if (line.trim().length === 0) {
|
|
10785
|
-
continue;
|
|
10786
|
-
}
|
|
10787
|
-
const lineNumber = index + 1;
|
|
10788
|
-
let rawParsed;
|
|
10789
|
-
try {
|
|
10790
|
-
rawParsed = JSON.parse(line);
|
|
10791
|
-
} catch {
|
|
10792
|
-
rejections.push({ file, lineNumber, detail: "invalid JSON" });
|
|
10793
|
-
continue;
|
|
10794
|
-
}
|
|
10795
|
-
const parsed = SoakObservationSchema.safeParse(rawParsed);
|
|
10796
|
-
if (parsed.success) {
|
|
10797
|
-
observations.push(parsed.data);
|
|
10798
|
-
} else {
|
|
10799
|
-
rejections.push({
|
|
10800
|
-
file,
|
|
10801
|
-
lineNumber,
|
|
10802
|
-
detail: formatSoakObservationIssues(parsed.error.issues)
|
|
10803
|
-
});
|
|
10804
|
-
}
|
|
10805
|
-
}
|
|
10806
|
-
if (observations.length > 0) {
|
|
10807
|
-
chains.push(observations);
|
|
10808
|
-
}
|
|
10809
|
-
}
|
|
10810
|
-
return { chains, rejectedLines: rejections.length, rejections };
|
|
10811
|
-
}
|
|
10812
|
-
function formatSoakObservationIssues(issues) {
|
|
10813
|
-
return issues.map((i) => `${i.path.join(".")}: ${i.code}`).join("; ");
|
|
10814
|
-
}
|
|
10815
|
-
function canonicalObservationPreimage2(obs) {
|
|
10816
|
-
return JSON.stringify({
|
|
10817
|
-
version: obs.version,
|
|
10818
|
-
seq: obs.seq,
|
|
10819
|
-
timestamp: obs.timestamp,
|
|
10820
|
-
platform: obs.platform,
|
|
10821
|
-
opencodeVersion: obs.opencodeVersion,
|
|
10822
|
-
provenance: obs.provenance,
|
|
10823
|
-
traceDigest: obs.traceDigest,
|
|
10824
|
-
criticalDivergences: obs.criticalDivergences,
|
|
10825
|
-
privacy: obs.privacy,
|
|
10826
|
-
duplicateEffects: obs.duplicateEffects,
|
|
10827
|
-
modelVerification: obs.modelVerification
|
|
10828
|
-
});
|
|
10829
|
-
}
|
|
10830
|
-
async function appendObservation(ports, evidenceDir, recorderId, input) {
|
|
10831
|
-
if (input.opencodeVersion === "unknown") {
|
|
10832
|
-
throw new Error("opencode-version-unreadable");
|
|
10833
|
-
}
|
|
10834
|
-
await ports.fs.mkdir(evidenceDir);
|
|
10835
|
-
const chainPath = `${evidenceDir}/${recorderId}.jsonl`;
|
|
10836
|
-
let seq = 0;
|
|
10837
|
-
let prevChainDigest = "0".repeat(64);
|
|
10838
|
-
if (await ports.fs.exists(chainPath)) {
|
|
10839
|
-
const content = await ports.fs.readFile(chainPath);
|
|
10840
|
-
const lines = content.split(`
|
|
10841
|
-
`).filter((l) => l.trim().length > 0);
|
|
10842
|
-
if (lines.length > 0) {
|
|
10843
|
-
const lastLine = lines[lines.length - 1];
|
|
10844
|
-
let rawParsed;
|
|
10845
|
-
try {
|
|
10846
|
-
rawParsed = JSON.parse(lastLine);
|
|
10847
|
-
} catch {
|
|
10848
|
-
throw new Error("corrupt chain tail: invalid JSON");
|
|
10849
|
-
}
|
|
10850
|
-
const parsed = SoakObservationSchema.safeParse(rawParsed);
|
|
10851
|
-
if (!parsed.success) {
|
|
10852
|
-
const detail = parsed.error.issues.map((i) => `${i.path.join(".")}: ${i.code}`).join("; ");
|
|
10853
|
-
throw new Error(`corrupt chain tail: ${detail}`);
|
|
10854
|
-
}
|
|
10855
|
-
seq = parsed.data.seq + 1;
|
|
10856
|
-
prevChainDigest = parsed.data.chainDigest;
|
|
10857
|
-
}
|
|
10858
|
-
}
|
|
10859
|
-
const timestamp = ports.clock.now();
|
|
10860
|
-
const base = {
|
|
10861
|
-
version: 1,
|
|
10862
|
-
seq,
|
|
10863
|
-
timestamp,
|
|
10864
|
-
platform: input.platform,
|
|
10865
|
-
opencodeVersion: input.opencodeVersion,
|
|
10866
|
-
provenance: input.provenance,
|
|
10867
|
-
traceDigest: input.traceDigest,
|
|
10868
|
-
criticalDivergences: input.criticalDivergences,
|
|
10869
|
-
privacy: input.privacy,
|
|
10870
|
-
duplicateEffects: input.duplicateEffects,
|
|
10871
|
-
modelVerification: input.modelVerification
|
|
10872
|
-
};
|
|
10873
|
-
const preimage = canonicalObservationPreimage2(base);
|
|
10874
|
-
const chainDigest = sha256Hex(prevChainDigest + preimage);
|
|
10875
|
-
const observation = { ...base, chainDigest };
|
|
10876
|
-
assertReferenceOnly(observation);
|
|
10877
|
-
const line = JSON.stringify(observation);
|
|
10878
|
-
if (await ports.fs.exists(chainPath)) {
|
|
10879
|
-
const existing = await ports.fs.readFile(chainPath);
|
|
10880
|
-
await ports.fs.writeFile(chainPath, `${existing}
|
|
10881
|
-
${line}`);
|
|
10882
|
-
} else {
|
|
10883
|
-
await ports.fs.writeFile(chainPath, line);
|
|
10884
|
-
}
|
|
10885
|
-
return observation;
|
|
10886
|
-
}
|
|
10887
|
-
|
|
10888
10946
|
// src/plugin/soakObserver.ts
|
|
10889
10947
|
function resolvePlatform(platform) {
|
|
10890
10948
|
if (platform === "win32")
|
|
@@ -13029,7 +13087,7 @@ var createOtlpSpanExporter = (connection, config) => {
|
|
|
13029
13087
|
// package.json
|
|
13030
13088
|
var package_default = {
|
|
13031
13089
|
name: "@jmanuelcorral/openteam",
|
|
13032
|
-
version: "0.
|
|
13090
|
+
version: "0.13.1",
|
|
13033
13091
|
packageManager: "bun@1.3.14",
|
|
13034
13092
|
description: "Cost-aware, local-first routing plugin for opencode with cheapest-capable frontier fallback and multi-agent orchestration.",
|
|
13035
13093
|
license: "MIT",
|
|
@@ -13205,7 +13263,6 @@ function warnSoakEvidenceRejections(result, warn) {
|
|
|
13205
13263
|
var SHADOW_CERT_PATH = "artifacts/graph-shadow-certificate.json";
|
|
13206
13264
|
var RELEASE_CERT_PATH = "artifacts/graph-release-certificate.json";
|
|
13207
13265
|
var SOAK_CERT_PATH = "artifacts/graph-soak-certificate.json";
|
|
13208
|
-
var SOAK_EVIDENCE_DIR = ".opencode/soak";
|
|
13209
13266
|
async function readAndParseCertificate(storage, path4, parse2, digestExtractor) {
|
|
13210
13267
|
try {
|
|
13211
13268
|
const content = await storage.read(path4);
|
|
@@ -13728,14 +13785,14 @@ var server = async (ctx, rawOptions) => {
|
|
|
13728
13785
|
let shadowDeps;
|
|
13729
13786
|
if (graphConfig.effectiveMode !== "off") {
|
|
13730
13787
|
const recorderPorts = recorderPortsFromStorage(storage);
|
|
13731
|
-
const recorderId = await ensureRecorderId(recorderPorts,
|
|
13788
|
+
const recorderId = await ensureRecorderId(recorderPorts, SOAK_RECORDER_BASE_DIR);
|
|
13732
13789
|
shadowDeps = {
|
|
13733
13790
|
gate: {
|
|
13734
13791
|
mode: graphConfig.configuredMode,
|
|
13735
13792
|
killSwitch: graphConfig.killSwitch
|
|
13736
13793
|
},
|
|
13737
13794
|
ports: recorderPorts,
|
|
13738
|
-
evidenceDir:
|
|
13795
|
+
evidenceDir: SOAK_EVIDENCE_DIR,
|
|
13739
13796
|
recorderId,
|
|
13740
13797
|
resolveOpencodeVersion: getOpencodeVersion,
|
|
13741
13798
|
criticalCodes: DEFAULT_SOAK_POLICY.criticalDivergenceCodes
|
|
@@ -31,6 +31,25 @@ export type RecorderPorts = {
|
|
|
31
31
|
export type SoakChainReadPorts = {
|
|
32
32
|
readonly fs: Pick<FsPort, "readFile" | "exists" | "readDir">;
|
|
33
33
|
};
|
|
34
|
+
/**
|
|
35
|
+
* Directory (relative to cwd) the shadow soak pipeline writes its JSONL evidence
|
|
36
|
+
* chains to. Exported so `openteam setup`'s ignore-rule derivation and the plugin
|
|
37
|
+
* writer in `src/index.ts` share one literal and can never drift apart (the drift
|
|
38
|
+
* that left these recordings unignored in consuming projects).
|
|
39
|
+
*/
|
|
40
|
+
export declare const SOAK_EVIDENCE_DIR = ".opencode/soak";
|
|
41
|
+
/**
|
|
42
|
+
* Base directory that holds the machine-local recorder id file. Passed to
|
|
43
|
+
* {@link ensureRecorderId} as `basePath`.
|
|
44
|
+
*/
|
|
45
|
+
export declare const SOAK_RECORDER_BASE_DIR = ".opencode";
|
|
46
|
+
/** Filename of the machine-local recorder id, stored under {@link SOAK_RECORDER_BASE_DIR}. */
|
|
47
|
+
export declare const SOAK_RECORDER_ID_FILENAME = "soak-recorder-id";
|
|
48
|
+
/**
|
|
49
|
+
* Full path (relative to cwd) of the machine-local recorder id file. Exported so
|
|
50
|
+
* the ignore-rule derivation covers it alongside {@link SOAK_EVIDENCE_DIR}.
|
|
51
|
+
*/
|
|
52
|
+
export declare const SOAK_RECORDER_ID_PATH = ".opencode/soak-recorder-id";
|
|
34
53
|
export type SoakObservationLineRejection = {
|
|
35
54
|
readonly file: string;
|
|
36
55
|
readonly lineNumber: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"soakRecorder.d.ts","sourceRoot":"","sources":["../../../src/storage/graph/soakRecorder.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,KAAK,uBAAuB,EAC5B,KAAK,yBAAyB,EAC9B,KAAK,eAAe,EAEpB,KAAK,YAAY,EACjB,KAAK,eAAe,EACrB,MAAM,wBAAwB,CAAC;AAEhC;;;;;;GAMG;AAMH,8DAA8D;AAC9D,MAAM,MAAM,MAAM,GAAG;IACnB,QAAQ,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IACrD,QAAQ,CAAC,SAAS,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACrE,QAAQ,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IACpD,QAAQ,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,SAAS,MAAM,EAAE,CAAC,CAAC;IAC/D,QAAQ,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACjD,CAAC;AAEF,uCAAuC;AACvC,MAAM,MAAM,SAAS,GAAG;IACtB,QAAQ,CAAC,GAAG,EAAE,MAAM,MAAM,CAAC;CAC5B,CAAC;AAEF,kCAAkC;AAClC,MAAM,MAAM,MAAM,GAAG;IACnB,QAAQ,CAAC,UAAU,EAAE,MAAM,MAAM,CAAC;CACnC,CAAC;AAEF,2CAA2C;AAC3C,MAAM,MAAM,aAAa,GAAG;IAC1B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC;IAC1B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC,MAAM,EAAE,UAAU,GAAG,QAAQ,GAAG,SAAS,CAAC,CAAC;CAC9D,CAAC;
|
|
1
|
+
{"version":3,"file":"soakRecorder.d.ts","sourceRoot":"","sources":["../../../src/storage/graph/soakRecorder.ts"],"names":[],"mappings":"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"}
|
package/dist/web/graphRoute.d.ts
CHANGED
|
@@ -1,36 +1,35 @@
|
|
|
1
1
|
import type { IncomingMessage, ServerResponse } from "node:http";
|
|
2
2
|
import type { GraphViewProjectionV1 } from "../telemetry/graphView";
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
4
|
+
* Additive HTTP endpoint serving the graph view's reference-only projection
|
|
5
|
+
* (GE-082): `GET /api/graph` (JSON) and the SSE `event: graph` frame pushed on
|
|
6
|
+
* every runtime change through the existing `/events` channel.
|
|
7
7
|
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
8
|
+
* Security — **token parity with `/api/state`**: when the Console is exposed
|
|
9
|
+
* remotely (with `storageApi`), `remoteToken` requires the same ephemeral token
|
|
10
|
+
* as the other read routes; without it → 401. On pure loopback
|
|
11
|
+
* (`remoteToken` undefined), it stays open like `/api/state`.
|
|
12
12
|
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
13
|
+
* Read-only and additive: if no `graphApi` is wired, the route answers a typed
|
|
14
|
+
* disabled envelope so the shell can explain how to re-enable the tree.
|
|
15
15
|
*/
|
|
16
16
|
export type GraphRouteDeps = {
|
|
17
|
-
/**
|
|
17
|
+
/** Current graph-view projection, or `null` when there is no active run. */
|
|
18
18
|
readView: () => Promise<GraphViewProjectionV1 | null>;
|
|
19
19
|
/**
|
|
20
|
-
*
|
|
21
|
-
* loopback
|
|
20
|
+
* Remote-exposure token, in parity with `/api/state`. `undefined` on pure
|
|
21
|
+
* loopback (open route).
|
|
22
22
|
*/
|
|
23
23
|
remoteToken?: string;
|
|
24
24
|
};
|
|
25
25
|
/**
|
|
26
26
|
* Payload served by `GET /api/graph` when no graph provider is wired.
|
|
27
27
|
*
|
|
28
|
-
* Lighting up the agent tree requires
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
* screen render the remediation hint instead of a dead panel.
|
|
28
|
+
* Lighting up the agent tree requires `graph.mode` to be non-`"off"` and
|
|
29
|
+
* `console.graphView.enabled` to be `true`. Those are now defaults, but this
|
|
30
|
+
* envelope remains important when an operator explicitly disables either side:
|
|
31
|
+
* the UI can distinguish "the graph is off" from "this console has no such
|
|
32
|
+
* endpoint" and render the remediation hint instead of a dead panel.
|
|
34
33
|
*/
|
|
35
34
|
export type GraphDisabledEnvelope = {
|
|
36
35
|
readonly disabled: true;
|
|
@@ -40,9 +39,9 @@ export type GraphDisabledEnvelope = {
|
|
|
40
39
|
/** Remediation text naming both flags the operator has to set. */
|
|
41
40
|
export declare const GRAPH_DISABLED_REMEDIATION: 'Agent tree is off. In .opencode/openteam.json set graph.mode to a value other than "off" and console.graphView.enabled to true, then restart the console.';
|
|
42
41
|
export declare const GRAPH_DISABLED_ENVELOPE: GraphDisabledEnvelope;
|
|
43
|
-
/**
|
|
42
|
+
/** SSE event type for the graph channel, multiplexed over `/events`. */
|
|
44
43
|
export declare const GRAPH_SSE_EVENT: "graph";
|
|
45
|
-
/**
|
|
44
|
+
/** Graph-channel SSE frame for an already serialized JSON payload. */
|
|
46
45
|
export declare function graphSseMessage(json: string): string;
|
|
47
46
|
/**
|
|
48
47
|
* Enruta `GET /api/graph`. Devuelve `true` si atendió (y respondió) la petición,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"graphRoute.d.ts","sourceRoot":"","sources":["../../src/web/graphRoute.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAGjE,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAEpE;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,cAAc,GAAG;IAC3B,
|
|
1
|
+
{"version":3,"file":"graphRoute.d.ts","sourceRoot":"","sources":["../../src/web/graphRoute.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAGjE,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAEpE;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,cAAc,GAAG;IAC3B,4EAA4E;IAC5E,QAAQ,EAAE,MAAM,OAAO,CAAC,qBAAqB,GAAG,IAAI,CAAC,CAAC;IACtD;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF;;;;;;;;GAQG;AACH,MAAM,MAAM,qBAAqB,GAAG;IAClC,QAAQ,CAAC,QAAQ,EAAE,IAAI,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,gBAAgB,CAAC;IAClC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAC9B,CAAC;AAEF,kEAAkE;AAClE,eAAO,MAAM,0BAA0B,EACrC,2JAAoK,CAAC;AAEvK,eAAO,MAAM,uBAAuB,EAAE,qBAIrC,CAAC;AAIF,wEAAwE;AACxE,eAAO,MAAM,eAAe,EAAG,OAAgB,CAAC;AAEhD,sEAAsE;AACtE,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEpD;AAoBD;;;;;GAKG;AACH,wBAAsB,gBAAgB,CACpC,OAAO,EAAE,eAAe,EACxB,QAAQ,EAAE,cAAc,EACxB,GAAG,EAAE,GAAG,EACR,IAAI,EAAE,cAAc,GACnB,OAAO,CAAC,OAAO,CAAC,CAsBlB"}
|
package/dist/web/server.d.ts
CHANGED
|
@@ -67,9 +67,9 @@ export type ConsoleServerDeps = {
|
|
|
67
67
|
* (`console.graphView.enabled`) but the graph engine is off (`graph.mode` ==
|
|
68
68
|
* "off"), so no `graphApi` provider is wired. The shell still mounts the
|
|
69
69
|
* agent-tree tab and renders the `graph.mode` remediation hint instead of a
|
|
70
|
-
* bare-missing tab (PRD W7 acceptance #9).
|
|
71
|
-
*
|
|
72
|
-
* is
|
|
70
|
+
* bare-missing tab (PRD W7 acceptance #9). `GET /api/graph` still answers a
|
|
71
|
+
* disabled envelope; the SSE `graph` frame stays absent because it follows
|
|
72
|
+
* `graphApi`. Absent/`false` means the tree is not marked disabled.
|
|
73
73
|
*/
|
|
74
74
|
graphDisabled?: boolean;
|
|
75
75
|
};
|
package/dist/web/start.d.ts
CHANGED
|
@@ -52,10 +52,9 @@ export type ConsoleRuntimeDeps = {
|
|
|
52
52
|
/** Endpoint remoto de storage (`/storage/*`). Opcional y opt-in. */
|
|
53
53
|
storageApi?: StorageRouteDeps;
|
|
54
54
|
/**
|
|
55
|
-
*
|
|
56
|
-
*
|
|
57
|
-
*
|
|
58
|
-
* idéntica a hoy.
|
|
55
|
+
* Reference-only graph-view provider (GE-083). Wired as `graphApi` (enabling
|
|
56
|
+
* `/api/graph`, the `graph` SSE channel, and DAG rendering) when
|
|
57
|
+
* `config.graphView.enabled` is `true`; explicit `false` keeps it disabled.
|
|
59
58
|
*/
|
|
60
59
|
graphView?: {
|
|
61
60
|
readView: () => Promise<GraphViewProjectionV1 | null>;
|
package/dist/web/start.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"start.d.ts","sourceRoot":"","sources":["../../src/web/start.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,IAAI,OAAO,EAAE,MAAM,SAAS,CAAC;AAE3C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAIpE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAGvD,MAAM,MAAM,kBAAkB,GAAG;IAC/B,MAAM,EAAE,aAAa,CAAC;IACtB;;;OAGG;IACH,gBAAgB,CAAC,EAAE,MAAM,aAAa,CAAC;IACvC;;OAEG;IACH,SAAS,CAAC,EAAE,OAAO,eAAe,EAAE,eAAe,CAAC;IACpD;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,yDAAyD;IACzD,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,+DAA+D;IAC/D,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,qEAAqE;IACrE,OAAO,EAAE,eAAe,CAAC;IACzB,cAAc,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC;IACtD,GAAG,EAAE,MAAM,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC,CAAC;IACtD,OAAO,CAAC,EAAE;QAAE,EAAE,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC9C,sEAAsE;IACtE,OAAO,CAAC,EAAE;QACR,KAAK,EAAE,MAAM,CAAC;QACd,eAAe,EAAE,OAAO,CAAC;QACzB,gBAAgB,CAAC,EAAE,OAAO,CAAC;QAC3B,UAAU,CAAC,EAAE,OAAO,CAAC;QACrB,YAAY,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,aAAa,CAAC;QAClD,eAAe,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,SAAS,CAAC;KACnD,CAAC;IACF,oEAAoE;IACpE,UAAU,CAAC,EAAE,gBAAgB,CAAC;IAC9B
|
|
1
|
+
{"version":3,"file":"start.d.ts","sourceRoot":"","sources":["../../src/web/start.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,IAAI,OAAO,EAAE,MAAM,SAAS,CAAC;AAE3C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAIpE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAGvD,MAAM,MAAM,kBAAkB,GAAG;IAC/B,MAAM,EAAE,aAAa,CAAC;IACtB;;;OAGG;IACH,gBAAgB,CAAC,EAAE,MAAM,aAAa,CAAC;IACvC;;OAEG;IACH,SAAS,CAAC,EAAE,OAAO,eAAe,EAAE,eAAe,CAAC;IACpD;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,yDAAyD;IACzD,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,+DAA+D;IAC/D,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,qEAAqE;IACrE,OAAO,EAAE,eAAe,CAAC;IACzB,cAAc,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC;IACtD,GAAG,EAAE,MAAM,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC,CAAC;IACtD,OAAO,CAAC,EAAE;QAAE,EAAE,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC9C,sEAAsE;IACtE,OAAO,CAAC,EAAE;QACR,KAAK,EAAE,MAAM,CAAC;QACd,eAAe,EAAE,OAAO,CAAC;QACzB,gBAAgB,CAAC,EAAE,OAAO,CAAC;QAC3B,UAAU,CAAC,EAAE,OAAO,CAAC;QACrB,YAAY,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,aAAa,CAAC;QAClD,eAAe,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,SAAS,CAAC;KACnD,CAAC;IACF,oEAAoE;IACpE,UAAU,CAAC,EAAE,gBAAgB,CAAC;IAC9B;;;;OAIG;IACH,SAAS,CAAC,EAAE;QACV,QAAQ,EAAE,MAAM,OAAO,CAAC,qBAAqB,GAAG,IAAI,CAAC,CAAC;KACvD,CAAC;IACF,8BAA8B;IAC9B,KAAK,CAAC,EAAE,cAAc,UAAU,EAAE,mBAAmB,CAAC;IACtD,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,IAAI,KAAK,UAAU,CAAC,OAAO,OAAO,CAAC,CAAC;IAC3E,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACjC,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,IAAI,CAAC;CACnB,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,YAAY,CAC1B,IAAI,EAAE,kBAAkB,GACvB,OAAO,CAAC,cAAc,CAAC,CAEzB"}
|