@adhdev/daemon-core 0.9.82-rc.293 → 0.9.82-rc.294
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 +195 -18
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +195 -18
- package/dist/index.mjs.map +1 -1
- package/dist/providers/spec/cli-adapter.d.ts +14 -0
- package/dist/providers/types/interactive-prompt.d.ts +19 -0
- package/package.json +2 -2
- package/src/config/chat-history.ts +255 -10
- package/src/mesh/coordinator-prompt.ts +1 -0
- package/src/providers/cli-provider-instance.ts +36 -14
- package/src/providers/spec/cli-adapter.ts +40 -0
- package/src/providers/types/interactive-prompt.ts +1 -1
package/dist/index.mjs
CHANGED
|
@@ -270,10 +270,10 @@ function readInjected(value) {
|
|
|
270
270
|
}
|
|
271
271
|
function getDaemonBuildInfo() {
|
|
272
272
|
if (cached) return cached;
|
|
273
|
-
const commit = readInjected(true ? "
|
|
274
|
-
const commitShort = readInjected(true ? "
|
|
275
|
-
const version = readInjected(true ? "0.9.82-rc.
|
|
276
|
-
const builtAt = readInjected(true ? "2026-06-
|
|
273
|
+
const commit = readInjected(true ? "6ee0e52b0b7347870577ebe598054d87127078fe" : void 0) ?? "unknown";
|
|
274
|
+
const commitShort = readInjected(true ? "6ee0e52b" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
|
|
275
|
+
const version = readInjected(true ? "0.9.82-rc.294" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
|
|
276
|
+
const builtAt = readInjected(true ? "2026-06-16T12:15:42.290Z" : void 0);
|
|
277
277
|
cached = builtAt ? { commit, commitShort, version, builtAt } : { commit, commitShort, version };
|
|
278
278
|
return cached;
|
|
279
279
|
}
|
|
@@ -2007,6 +2007,7 @@ function buildRulesSection(coordinatorCliType) {
|
|
|
2007
2007
|
- **Verify via git, not source.** Use \`mesh_git_status\` to confirm side effects. Treat agent summaries as self-reports, not verification.
|
|
2008
2008
|
- **Limit parallelism.** Start with 1\u20132 tasks; scale only on success. Never duplicate a session because \`mesh_read_chat\` shows no final message while tool/terminal activity is ongoing. This caps *concurrent* load \u2014 it does not mean serialize independent work: when a new, independent request arrives and there is headroom under \`maxParallelTasks\`, dispatch it right away rather than waiting for an in-flight task or a user nudge (read-only diagnosis especially, since it has no merge cost).
|
|
2009
2009
|
- **Check history first.** Call \`mesh_task_history\` at session start to avoid duplicate work and inform recovery. On failure, read task history before retrying.
|
|
2010
|
+
- **Sequence shared-base-moving merges.** Parallel dispatch is encouraged, but merging one worktree can advance another in-flight worktree's base \u2014 especially the oss submodule pointer \u2014 turning a clean fast-forward into a diverged rebase (patch-equivalence correctly blocks this). Before merging an in-flight worktree while siblings are also in flight, land in an intentional order, re-clone long-running worktrees from the advanced base, or expect to manually rebase + ff-only the laggards; merging an independent fix mid-flight can strand siblings into a rebase.
|
|
2010
2011
|
- **Converge branches.** After worktree tasks: refine/fast-forward, or classify as \`pushed_feature_branch_needs_merge\` / \`blocked_review\` / \`cleanup_candidate\` / \`not_mergeable\`. Clean up with \`mesh_remove_node\`.
|
|
2011
2012
|
- **Refinery is config-driven.** \`mesh_refine_node\` must run validation from \`.adhdev/refine.{json,yaml,yml}\` or \`repo-mesh.refine.*\`. Heuristics are scaffolding only.
|
|
2012
2013
|
- **Submodule reachability = publish-needed.** \`submodule_reachability_failed\` \u2192 classify as \`blocked_review\`, request user approval to push to submodule main, then rerun \`mesh_refine_node\`.
|
|
@@ -21571,22 +21572,160 @@ function isBoundedTailRequest(limit, offset, excludeRecentCount) {
|
|
|
21571
21572
|
if (!Number.isFinite(numericOffset) || !Number.isFinite(numericExclude)) return false;
|
|
21572
21573
|
return true;
|
|
21573
21574
|
}
|
|
21575
|
+
var REVERSE_TAIL_SMALL_FILE_BYTES = 64 * 1024;
|
|
21576
|
+
var REVERSE_TAIL_CHUNK_BYTES = 64 * 1024;
|
|
21577
|
+
var TAIL_LINES_RETAINED = BOUNDED_TAIL_MAX_LIMIT + 2 * BOUNDED_TAIL_SLACK;
|
|
21578
|
+
var INCREMENTAL_TAIL_CACHE_MAX_ENTRIES = 64;
|
|
21579
|
+
var incrementalTailCache = /* @__PURE__ */ new Map();
|
|
21580
|
+
function evictIncrementalTailCache() {
|
|
21581
|
+
while (incrementalTailCache.size > INCREMENTAL_TAIL_CACHE_MAX_ENTRIES) {
|
|
21582
|
+
const oldest = incrementalTailCache.keys().next().value;
|
|
21583
|
+
if (oldest === void 0) break;
|
|
21584
|
+
incrementalTailCache.delete(oldest);
|
|
21585
|
+
}
|
|
21586
|
+
}
|
|
21587
|
+
function splitBufferLines(buf) {
|
|
21588
|
+
const lines = [];
|
|
21589
|
+
let lineEnd = buf.length;
|
|
21590
|
+
let firstNewline = -1;
|
|
21591
|
+
for (let i = buf.length - 1; i >= 0; i--) {
|
|
21592
|
+
if (buf[i] !== 10) continue;
|
|
21593
|
+
if (i + 1 < lineEnd) {
|
|
21594
|
+
lines.push(buf.toString("utf-8", i + 1, lineEnd));
|
|
21595
|
+
}
|
|
21596
|
+
lineEnd = i;
|
|
21597
|
+
firstNewline = i;
|
|
21598
|
+
}
|
|
21599
|
+
lines.reverse();
|
|
21600
|
+
const head = firstNewline >= 0 ? buf.subarray(0, firstNewline) : buf;
|
|
21601
|
+
return { head, lines };
|
|
21602
|
+
}
|
|
21603
|
+
function readReverseTailLines(filePath, needed) {
|
|
21604
|
+
const fd = fs5.openSync(filePath, "r");
|
|
21605
|
+
try {
|
|
21606
|
+
const stat2 = fs5.fstatSync(fd);
|
|
21607
|
+
const size = stat2.size;
|
|
21608
|
+
let position = size;
|
|
21609
|
+
let carry = Buffer.alloc(0);
|
|
21610
|
+
const collected = [];
|
|
21611
|
+
while (position > 0 && collected.length < needed) {
|
|
21612
|
+
const chunkSize = Math.min(REVERSE_TAIL_CHUNK_BYTES, position);
|
|
21613
|
+
position -= chunkSize;
|
|
21614
|
+
const chunk = Buffer.alloc(chunkSize);
|
|
21615
|
+
fs5.readSync(fd, chunk, 0, chunkSize, position);
|
|
21616
|
+
const combined = carry.length ? Buffer.concat([chunk, carry]) : chunk;
|
|
21617
|
+
const { head, lines } = splitBufferLines(combined);
|
|
21618
|
+
carry = head;
|
|
21619
|
+
for (let i = lines.length - 1; i >= 0; i--) {
|
|
21620
|
+
collected.push(lines[i]);
|
|
21621
|
+
}
|
|
21622
|
+
}
|
|
21623
|
+
const reachedStart = position <= 0;
|
|
21624
|
+
if (reachedStart && carry.length) {
|
|
21625
|
+
collected.push(carry.toString("utf-8"));
|
|
21626
|
+
}
|
|
21627
|
+
collected.reverse();
|
|
21628
|
+
return { lines: collected, coversWholeFile: reachedStart, size, mtimeMs: stat2.mtimeMs };
|
|
21629
|
+
} finally {
|
|
21630
|
+
fs5.closeSync(fd);
|
|
21631
|
+
}
|
|
21632
|
+
}
|
|
21633
|
+
function readFileTailLines(filePath, needed) {
|
|
21634
|
+
let stat2;
|
|
21635
|
+
try {
|
|
21636
|
+
stat2 = fs5.statSync(filePath);
|
|
21637
|
+
} catch {
|
|
21638
|
+
return { lines: [], coversWholeFile: true };
|
|
21639
|
+
}
|
|
21640
|
+
const size = stat2.size;
|
|
21641
|
+
const mtimeMs = stat2.mtimeMs;
|
|
21642
|
+
if (size === 0) {
|
|
21643
|
+
incrementalTailCache.delete(filePath);
|
|
21644
|
+
return { lines: [], coversWholeFile: true };
|
|
21645
|
+
}
|
|
21646
|
+
const cached2 = incrementalTailCache.get(filePath);
|
|
21647
|
+
if (cached2) {
|
|
21648
|
+
if (cached2.size === size && cached2.mtimeMs === mtimeMs) {
|
|
21649
|
+
incrementalTailCache.delete(filePath);
|
|
21650
|
+
incrementalTailCache.set(filePath, cached2);
|
|
21651
|
+
if (cached2.coversWholeFile || cached2.lines.length >= needed) {
|
|
21652
|
+
return { lines: cached2.lines, coversWholeFile: cached2.coversWholeFile };
|
|
21653
|
+
}
|
|
21654
|
+
} else if (size > cached2.size) {
|
|
21655
|
+
const incremental = tryIncrementalTailGrowth(filePath, cached2, size, mtimeMs, needed);
|
|
21656
|
+
if (incremental) return { lines: incremental.lines, coversWholeFile: incremental.coversWholeFile };
|
|
21657
|
+
}
|
|
21658
|
+
incrementalTailCache.delete(filePath);
|
|
21659
|
+
}
|
|
21660
|
+
if (size <= REVERSE_TAIL_SMALL_FILE_BYTES) {
|
|
21661
|
+
let content;
|
|
21662
|
+
try {
|
|
21663
|
+
content = fs5.readFileSync(filePath, "utf-8");
|
|
21664
|
+
} catch {
|
|
21665
|
+
return { lines: [], coversWholeFile: true };
|
|
21666
|
+
}
|
|
21667
|
+
const lines = content.split("\n");
|
|
21668
|
+
if (lines.length && lines[lines.length - 1] === "") lines.pop();
|
|
21669
|
+
storeIncrementalTailCache(filePath, size, mtimeMs, lines, true);
|
|
21670
|
+
return { lines, coversWholeFile: true };
|
|
21671
|
+
}
|
|
21672
|
+
let result;
|
|
21673
|
+
try {
|
|
21674
|
+
result = readReverseTailLines(filePath, needed);
|
|
21675
|
+
} catch {
|
|
21676
|
+
return { lines: [], coversWholeFile: true };
|
|
21677
|
+
}
|
|
21678
|
+
storeIncrementalTailCache(filePath, result.size, result.mtimeMs, result.lines, result.coversWholeFile);
|
|
21679
|
+
return { lines: result.lines, coversWholeFile: result.coversWholeFile };
|
|
21680
|
+
}
|
|
21681
|
+
function tryIncrementalTailGrowth(filePath, cached2, size, mtimeMs, needed) {
|
|
21682
|
+
const fd = fs5.openSync(filePath, "r");
|
|
21683
|
+
try {
|
|
21684
|
+
if (cached2.size > 0) {
|
|
21685
|
+
const boundary = Buffer.alloc(1);
|
|
21686
|
+
fs5.readSync(fd, boundary, 0, 1, cached2.size - 1);
|
|
21687
|
+
if (boundary[0] !== 10) return null;
|
|
21688
|
+
}
|
|
21689
|
+
const appendedLength = size - cached2.size;
|
|
21690
|
+
const appended = Buffer.alloc(appendedLength);
|
|
21691
|
+
fs5.readSync(fd, appended, 0, appendedLength, cached2.size);
|
|
21692
|
+
const newLines = appended.toString("utf-8").split("\n");
|
|
21693
|
+
if (newLines.length && newLines[newLines.length - 1] === "") newLines.pop();
|
|
21694
|
+
const merged = cached2.lines.concat(newLines);
|
|
21695
|
+
const trimmed = merged.length > TAIL_LINES_RETAINED ? merged.slice(merged.length - TAIL_LINES_RETAINED) : merged;
|
|
21696
|
+
const coversWholeFile = cached2.coversWholeFile && trimmed.length === merged.length;
|
|
21697
|
+
storeIncrementalTailCache(filePath, size, mtimeMs, trimmed, coversWholeFile);
|
|
21698
|
+
if (coversWholeFile || trimmed.length >= needed) {
|
|
21699
|
+
return { lines: trimmed, coversWholeFile };
|
|
21700
|
+
}
|
|
21701
|
+
return { lines: trimmed, coversWholeFile };
|
|
21702
|
+
} catch {
|
|
21703
|
+
return null;
|
|
21704
|
+
} finally {
|
|
21705
|
+
fs5.closeSync(fd);
|
|
21706
|
+
}
|
|
21707
|
+
}
|
|
21708
|
+
function storeIncrementalTailCache(filePath, size, mtimeMs, lines, coversWholeFile) {
|
|
21709
|
+
const retained = lines.length > TAIL_LINES_RETAINED ? lines.slice(lines.length - TAIL_LINES_RETAINED) : lines;
|
|
21710
|
+
const covers = coversWholeFile && retained.length === lines.length;
|
|
21711
|
+
incrementalTailCache.delete(filePath);
|
|
21712
|
+
incrementalTailCache.set(filePath, { size, mtimeMs, lines: retained, coversWholeFile: covers });
|
|
21713
|
+
evictIncrementalTailCache();
|
|
21714
|
+
}
|
|
21574
21715
|
function readBoundedTailRecords(agentType, dir, files, needed) {
|
|
21575
21716
|
const collected = [];
|
|
21576
21717
|
const seen = /* @__PURE__ */ new Set();
|
|
21577
21718
|
let readAllFiles = true;
|
|
21578
21719
|
for (let f = 0; f < files.length; f++) {
|
|
21579
21720
|
const filePath = path12.join(dir, files[f]);
|
|
21580
|
-
|
|
21581
|
-
|
|
21582
|
-
|
|
21583
|
-
} catch {
|
|
21584
|
-
continue;
|
|
21585
|
-
}
|
|
21586
|
-
const lines = content.trim().split("\n").filter(Boolean);
|
|
21721
|
+
const remaining = Math.max(0, needed - collected.length);
|
|
21722
|
+
const perFileNeeded = Math.min(needed, remaining + BOUNDED_TAIL_SLACK);
|
|
21723
|
+
const { lines, coversWholeFile } = readFileTailLines(filePath, perFileNeeded);
|
|
21587
21724
|
for (let i = lines.length - 1; i >= 0; i--) {
|
|
21725
|
+
const line = lines[i];
|
|
21726
|
+
if (!line) continue;
|
|
21588
21727
|
try {
|
|
21589
|
-
const parsed = JSON.parse(
|
|
21728
|
+
const parsed = JSON.parse(line);
|
|
21590
21729
|
const sanitizedMessage = sanitizeHistoryMessage(agentType, parsed);
|
|
21591
21730
|
if (!sanitizedMessage) continue;
|
|
21592
21731
|
const hash = buildHistoryMessageHash(agentType, sanitizedMessage);
|
|
@@ -21596,6 +21735,10 @@ function readBoundedTailRecords(agentType, dir, files, needed) {
|
|
|
21596
21735
|
} catch {
|
|
21597
21736
|
}
|
|
21598
21737
|
}
|
|
21738
|
+
if (!coversWholeFile) {
|
|
21739
|
+
readAllFiles = false;
|
|
21740
|
+
break;
|
|
21741
|
+
}
|
|
21599
21742
|
if (collected.length >= needed && f < files.length - 1) {
|
|
21600
21743
|
readAllFiles = false;
|
|
21601
21744
|
break;
|
|
@@ -31552,12 +31695,14 @@ var SpecCliAdapter = class _SpecCliAdapter {
|
|
|
31552
31695
|
}
|
|
31553
31696
|
this.maybeClearResolvedClaudeTuiPrompt();
|
|
31554
31697
|
this.maybeCaptureClaudeTuiPrompt();
|
|
31698
|
+
this.maybeUpgradeClaudeTuiMultiSelect();
|
|
31555
31699
|
this.statusCallback?.();
|
|
31556
31700
|
return;
|
|
31557
31701
|
case "pty_data":
|
|
31558
31702
|
this.detectInteractivePromptFromPtyChunk(ev.chunk);
|
|
31559
31703
|
this.maybeClearResolvedClaudeTuiPrompt();
|
|
31560
31704
|
this.maybeCaptureClaudeTuiPrompt();
|
|
31705
|
+
this.maybeUpgradeClaudeTuiMultiSelect();
|
|
31561
31706
|
try {
|
|
31562
31707
|
this.ptyDataCallback?.(ev.chunk);
|
|
31563
31708
|
} catch {
|
|
@@ -31706,6 +31851,35 @@ var SpecCliAdapter = class _SpecCliAdapter {
|
|
|
31706
31851
|
this.claudeTuiPromptCaptureInFlight = false;
|
|
31707
31852
|
});
|
|
31708
31853
|
}
|
|
31854
|
+
/**
|
|
31855
|
+
* The TUI prompt is captured on the FIRST frame that renders the
|
|
31856
|
+
* "Enter to select" footer. At that instant the option rows' checkbox
|
|
31857
|
+
* column may not have drawn yet, so `detectClaudeTuiMultiSelect` returns
|
|
31858
|
+
* false and the prompt is frozen as single-select — the dashboard then
|
|
31859
|
+
* renders radio buttons even though the picker is multi-select.
|
|
31860
|
+
*
|
|
31861
|
+
* While the same TUI prompt is still on screen, re-check the live snapshot:
|
|
31862
|
+
* if checkbox glyphs have since appeared, promote any single-select
|
|
31863
|
+
* question to multi-select and re-emit status. Promotion is one-way
|
|
31864
|
+
* (false→true only) — once a question is known multi-select we never demote
|
|
31865
|
+
* it, since the glyph column can scroll out of view on later frames.
|
|
31866
|
+
*/
|
|
31867
|
+
maybeUpgradeClaudeTuiMultiSelect() {
|
|
31868
|
+
if (this.cliType !== "claude-cli" || this.interactivePromptTransport !== "tui" || !this.activeInteractivePrompt) return;
|
|
31869
|
+
const questions = this.activeInteractivePrompt.questions;
|
|
31870
|
+
if (questions.length !== 1) return;
|
|
31871
|
+
if (questions[0].multiSelect) return;
|
|
31872
|
+
let screenText = "";
|
|
31873
|
+
try {
|
|
31874
|
+
screenText = this.driver.snapshot();
|
|
31875
|
+
} catch {
|
|
31876
|
+
return;
|
|
31877
|
+
}
|
|
31878
|
+
if (!screenText.includes("Enter to select")) return;
|
|
31879
|
+
if (!detectClaudeTuiMultiSelect(screenText)) return;
|
|
31880
|
+
questions[0].multiSelect = true;
|
|
31881
|
+
this.statusCallback?.();
|
|
31882
|
+
}
|
|
31709
31883
|
readClaudeTuiHeaders(screenText) {
|
|
31710
31884
|
const navLine = screenText.split(/\r?\n/).find((line) => line.includes("\u2714 Submit") && /[☐☒]/.test(line));
|
|
31711
31885
|
if (!navLine) return [];
|
|
@@ -31855,6 +32029,7 @@ function normalizeProviderSessionId(provider, providerSessionId) {
|
|
|
31855
32029
|
}
|
|
31856
32030
|
|
|
31857
32031
|
// src/providers/cli-provider-instance.ts
|
|
32032
|
+
var STATUS_HYDRATION_TAIL_LIMIT = 200;
|
|
31858
32033
|
function isIdleStatus(value) {
|
|
31859
32034
|
const status = typeof value === "string" ? value.trim().toLowerCase() : "";
|
|
31860
32035
|
return !status || status === "idle" || status === "ready";
|
|
@@ -33517,12 +33692,14 @@ ${effect.notification.body || ""}`.trim();
|
|
|
33517
33692
|
const newestMessageAt = parsedMessages.reduce((newest, message) => Math.max(newest, getMessageTime(message)), 0);
|
|
33518
33693
|
return newestMessageAt === 0;
|
|
33519
33694
|
}
|
|
33520
|
-
syncCanonicalSavedHistoryIfNeeded() {
|
|
33695
|
+
syncCanonicalSavedHistoryIfNeeded(options = {}) {
|
|
33521
33696
|
if (!this.providerSessionId) return false;
|
|
33522
33697
|
const canonicalHistory = this.provider.nativeHistory;
|
|
33523
33698
|
if (!canonicalHistory) return false;
|
|
33699
|
+
const limit = options.full ? Number.MAX_SAFE_INTEGER : STATUS_HYDRATION_TAIL_LIMIT;
|
|
33700
|
+
const windowTag = options.full ? "full" : `tail:${STATUS_HYDRATION_TAIL_LIMIT}`;
|
|
33524
33701
|
if (isNativeSourceCanonicalHistory(canonicalHistory)) {
|
|
33525
|
-
const cacheKey = [this.type, this.providerSessionId, this.workingDir].join("\0");
|
|
33702
|
+
const cacheKey = [this.type, this.providerSessionId, this.workingDir, windowTag].join("\0");
|
|
33526
33703
|
const now = Date.now();
|
|
33527
33704
|
if (cacheKey === this.lastNativeSourceCanonicalCacheKey && now - this.lastNativeSourceCanonicalCheckAt < 2e3) {
|
|
33528
33705
|
return true;
|
|
@@ -33534,7 +33711,7 @@ ${effect.notification.body || ""}`.trim();
|
|
|
33534
33711
|
historySessionId: this.providerSessionId,
|
|
33535
33712
|
workspace: this.workingDir,
|
|
33536
33713
|
offset: 0,
|
|
33537
|
-
limit
|
|
33714
|
+
limit,
|
|
33538
33715
|
historyBehavior: this.provider.historyBehavior,
|
|
33539
33716
|
scripts: this.provider.scripts
|
|
33540
33717
|
});
|
|
@@ -33550,7 +33727,7 @@ ${effect.notification.body || ""}`.trim();
|
|
|
33550
33727
|
return true;
|
|
33551
33728
|
}
|
|
33552
33729
|
try {
|
|
33553
|
-
const cacheKey = [this.type, this.providerSessionId, this.workingDir, canonicalHistory.mode || "materialized-mirror"].join("\0");
|
|
33730
|
+
const cacheKey = [this.type, this.providerSessionId, this.workingDir, canonicalHistory.mode || "materialized-mirror", windowTag].join("\0");
|
|
33554
33731
|
const now = Date.now();
|
|
33555
33732
|
if (cacheKey === this.lastNativeSourceCanonicalCacheKey && now - this.lastNativeSourceCanonicalCheckAt < 2e3) {
|
|
33556
33733
|
return true;
|
|
@@ -33560,7 +33737,7 @@ ${effect.notification.body || ""}`.trim();
|
|
|
33560
33737
|
if (!materializeProviderNativeHistory(this.type, canonicalHistory, this.providerSessionId, this.workingDir, this.provider.scripts)) {
|
|
33561
33738
|
return false;
|
|
33562
33739
|
}
|
|
33563
|
-
const restoredHistory = readChatHistory(this.type, 0,
|
|
33740
|
+
const restoredHistory = readChatHistory(this.type, 0, limit, this.providerSessionId, 0, this.provider.historyBehavior);
|
|
33564
33741
|
this.lastPersistedHistoryMessages = restoredHistory.messages.map((message) => ({
|
|
33565
33742
|
role: message.role,
|
|
33566
33743
|
content: message.content,
|
|
@@ -33575,7 +33752,7 @@ ${effect.notification.body || ""}`.trim();
|
|
|
33575
33752
|
}
|
|
33576
33753
|
restorePersistedHistoryFromCurrentSession() {
|
|
33577
33754
|
if (!this.providerSessionId) return;
|
|
33578
|
-
this.syncCanonicalSavedHistoryIfNeeded();
|
|
33755
|
+
this.syncCanonicalSavedHistoryIfNeeded({ full: true });
|
|
33579
33756
|
const restoredHistory = isNativeSourceCanonicalHistory(this.provider.nativeHistory) ? readProviderChatHistory(this.type, {
|
|
33580
33757
|
canonicalHistory: this.provider.nativeHistory,
|
|
33581
33758
|
historySessionId: this.providerSessionId,
|