pi-ui-extend 1.0.41 → 1.0.45
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.md +50 -13
- package/dist/app/app.d.ts +13 -0
- package/dist/app/app.js +158 -8
- package/dist/app/cli/install.js +2 -2
- package/dist/app/commands/command-controller.d.ts +4 -0
- package/dist/app/commands/command-controller.js +11 -0
- package/dist/app/commands/command-git-actions.d.ts +25 -0
- package/dist/app/commands/command-git-actions.js +381 -0
- package/dist/app/commands/command-host.d.ts +4 -0
- package/dist/app/commands/command-host.js +5 -2
- package/dist/app/commands/command-model-actions.d.ts +1 -0
- package/dist/app/commands/command-model-actions.js +57 -35
- package/dist/app/commands/command-navigation-actions.d.ts +1 -0
- package/dist/app/commands/command-navigation-actions.js +16 -3
- package/dist/app/commands/command-registry.d.ts +2 -0
- package/dist/app/commands/command-registry.js +15 -1
- package/dist/app/commands/command-session-actions.js +9 -3
- package/dist/app/commands/reload-context-inventory.d.ts +11 -0
- package/dist/app/commands/reload-context-inventory.js +70 -0
- package/dist/app/extensions/extension-actions-controller.d.ts +1 -0
- package/dist/app/extensions/extension-actions-controller.js +6 -0
- package/dist/app/extensions/subagent-catalog-state.d.ts +9 -0
- package/dist/app/extensions/subagent-catalog-state.js +23 -0
- package/dist/app/input/autocomplete-controller.js +61 -34
- package/dist/app/input/input-action-controller.d.ts +2 -0
- package/dist/app/input/input-action-controller.js +8 -1
- package/dist/app/input/input-controller.d.ts +2 -1
- package/dist/app/input/input-controller.js +7 -2
- package/dist/app/input/prompt-enhancer-controller.js +53 -35
- package/dist/app/input/voice-controller.d.ts +41 -45
- package/dist/app/input/voice-controller.js +351 -419
- package/dist/app/model/model-usage-controller.js +17 -7
- package/dist/app/model/model-usage-status.d.ts +4 -1
- package/dist/app/model/model-usage-status.js +270 -46
- package/dist/app/popup/menu-items-controller.d.ts +13 -3
- package/dist/app/popup/menu-items-controller.js +37 -21
- package/dist/app/popup/popup-action-controller.d.ts +12 -2
- package/dist/app/popup/popup-action-controller.js +77 -24
- package/dist/app/popup/popup-menu-controller.d.ts +36 -14
- package/dist/app/popup/popup-menu-controller.js +239 -69
- package/dist/app/rendering/dcp-stats.d.ts +9 -4
- package/dist/app/rendering/dcp-stats.js +40 -425
- package/dist/app/rendering/editor-panels.js +10 -4
- package/dist/app/rendering/popup-menu-renderer.d.ts +3 -5
- package/dist/app/rendering/popup-menu-renderer.js +42 -37
- package/dist/app/rendering/render-controller.js +23 -2
- package/dist/app/rendering/status-line-renderer.d.ts +5 -0
- package/dist/app/rendering/status-line-renderer.js +41 -5
- package/dist/app/rendering/tab-line-renderer.js +26 -20
- package/dist/app/runtime.d.ts +12 -1
- package/dist/app/runtime.js +120 -12
- package/dist/app/screen/mouse-controller.d.ts +2 -0
- package/dist/app/screen/mouse-controller.js +17 -7
- package/dist/app/screen/status-controller.d.ts +4 -0
- package/dist/app/screen/status-controller.js +5 -0
- package/dist/app/session/lazy-session-manager.js +34 -0
- package/dist/app/session/session-event-controller.d.ts +1 -0
- package/dist/app/session/session-event-controller.js +10 -1
- package/dist/app/session/session-history.d.ts +1 -0
- package/dist/app/session/session-history.js +12 -1
- package/dist/app/session/session-lifecycle-controller.d.ts +7 -1
- package/dist/app/session/session-lifecycle-controller.js +16 -1
- package/dist/app/session/tabs-controller.d.ts +26 -1
- package/dist/app/session/tabs-controller.js +454 -147
- package/dist/app/subagents/subagents-files.js +60 -1
- package/dist/app/subagents/subagents-model.d.ts +1 -0
- package/dist/app/subagents/subagents-model.js +18 -2
- package/dist/app/subagents/subagents-widget-controller.d.ts +1 -0
- package/dist/app/subagents/subagents-widget-controller.js +6 -0
- package/dist/app/types.d.ts +16 -1
- package/dist/app/workspace/workspace-actions-controller.js +10 -2
- package/dist/app/workspace/workspace-undo.d.ts +1 -0
- package/dist/app/workspace/workspace-undo.js +1 -0
- package/dist/bundled-extensions/question/index.js +9 -1
- package/dist/bundled-extensions/question/remote.d.ts +4 -0
- package/dist/bundled-extensions/question/remote.js +33 -0
- package/dist/bundled-extensions/telegram-connector/bot.d.ts +43 -0
- package/dist/bundled-extensions/telegram-connector/bot.js +166 -0
- package/dist/bundled-extensions/telegram-connector/config.d.ts +8 -0
- package/dist/bundled-extensions/telegram-connector/config.js +87 -0
- package/dist/bundled-extensions/telegram-connector/coordinator.d.ts +66 -0
- package/dist/bundled-extensions/telegram-connector/coordinator.js +413 -0
- package/dist/bundled-extensions/telegram-connector/index.d.ts +3 -0
- package/dist/bundled-extensions/telegram-connector/index.js +195 -0
- package/dist/bundled-extensions/terminal-bell/index.d.ts +0 -8
- package/dist/bundled-extensions/terminal-bell/index.js +0 -76
- package/dist/bundled-extensions/workspace-undo/index.d.ts +26 -0
- package/dist/bundled-extensions/workspace-undo/index.js +191 -0
- package/dist/config.d.ts +21 -2
- package/dist/config.js +159 -32
- package/dist/default-pix-config.js +25 -5
- package/dist/schemas/index.d.ts +1 -0
- package/dist/schemas/index.js +1 -0
- package/dist/schemas/pi-tools-suite-schema.d.ts +88 -62
- package/dist/schemas/pi-tools-suite-schema.js +54 -83
- package/dist/schemas/pix-schema.d.ts +19 -2
- package/dist/schemas/pix-schema.js +47 -5
- package/dist/schemas/tasks-schema.d.ts +18 -0
- package/dist/schemas/tasks-schema.js +41 -0
- package/docs/concurrency.md +9 -1
- package/docs/desktop-mvp.md +22 -6
- package/docs/desktop-task-manager.md +148 -84
- package/docs/release.md +30 -6
- package/external/pi-tools-suite/README.md +197 -84
- package/external/pi-tools-suite/docs/evals.md +1 -1
- package/external/pi-tools-suite/docs/session-recovery.md +47 -14
- package/external/pi-tools-suite/docs/subagent-model-pools.md +48 -30
- package/external/pi-tools-suite/docs/ui-qa-subagent.md +440 -0
- package/external/pi-tools-suite/package.json +6 -1
- package/external/pi-tools-suite/src/antigravity-auth/auth-store.ts +2 -1
- package/external/pi-tools-suite/src/antigravity-auth/constants.ts +9 -3
- package/external/pi-tools-suite/src/antigravity-auth/headers.ts +41 -3
- package/external/pi-tools-suite/src/antigravity-auth/models.ts +94 -21
- package/external/pi-tools-suite/src/antigravity-auth/oauth.ts +5 -17
- package/external/pi-tools-suite/src/antigravity-auth/payload.ts +72 -7
- package/external/pi-tools-suite/src/antigravity-auth/stream.ts +13 -1
- package/external/pi-tools-suite/src/async-subagents/agents/frontier-review.md +23 -0
- package/external/pi-tools-suite/src/async-subagents/agents/implement.md +1 -1
- package/external/pi-tools-suite/src/async-subagents/agents/presets.jsonc +16 -0
- package/external/pi-tools-suite/src/async-subagents/agents/research.md +5 -3
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/backends/browser.mjs +346 -0
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/backends/desktop.mjs +1038 -0
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/backends/tui.mjs +759 -0
- package/external/pi-tools-suite/src/async-subagents/agents/{browser-qa → ui-qa/browser}/scripts/browser-qa-runner.mjs +32 -23
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/drivers/chrome-devtools/chrome-devtools-provider.mjs +895 -0
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/drivers/linux/linux-atspi.py +494 -0
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/drivers/macos/macos-accessibility.swift +1085 -0
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/drivers/native-terminal/bridge-client.mjs +50 -0
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/drivers/native-terminal/native-terminal-host.mjs +501 -0
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/drivers/windows/windows-uia.ps1 +454 -0
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/guides/browser-auth.md +114 -0
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/guides/browser-chrome-devtools.md +91 -0
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/guides/browser-playwright.md +145 -0
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/guides/browser.md +82 -0
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/guides/desktop-linux.md +26 -0
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/guides/desktop-macos.md +29 -0
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/guides/desktop-windows.md +23 -0
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/guides/desktop.md +54 -0
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/guides/tui-native-terminal.md +59 -0
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/guides/tui-pty.md +37 -0
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/guides/tui.md +60 -0
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/scripts/ui-qa-runner.mjs +535 -0
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa.md +75 -0
- package/external/pi-tools-suite/src/async-subagents/commands.ts +15 -71
- package/external/pi-tools-suite/src/async-subagents/core/activity.ts +33 -0
- package/external/pi-tools-suite/src/async-subagents/core/agent-catalog.ts +5 -4
- package/external/pi-tools-suite/src/async-subagents/core/agent-strategy.ts +1 -1
- package/external/pi-tools-suite/src/async-subagents/core/agents-dir.ts +8 -5
- package/external/pi-tools-suite/src/async-subagents/core/browser-qa.ts +16 -2
- package/external/pi-tools-suite/src/async-subagents/core/config.ts +160 -327
- package/external/pi-tools-suite/src/async-subagents/core/model-selection.ts +2 -1
- package/external/pi-tools-suite/src/async-subagents/core/registry.ts +158 -33
- package/external/pi-tools-suite/src/async-subagents/core/routing.ts +21 -5
- package/external/pi-tools-suite/src/async-subagents/core/spawn.ts +40 -26
- package/external/pi-tools-suite/src/async-subagents/core/state.ts +40 -0
- package/external/pi-tools-suite/src/async-subagents/core/types.ts +7 -0
- package/external/pi-tools-suite/src/async-subagents/core/ultrawork-auto.ts +51 -45
- package/external/pi-tools-suite/src/async-subagents/index.ts +69 -5
- package/external/pi-tools-suite/src/async-subagents/lib.ts +16 -9
- package/external/pi-tools-suite/src/async-subagents/tools/spawn.ts +8 -5
- package/external/pi-tools-suite/src/async-subagents/tools/subagents.ts +5 -4
- package/external/pi-tools-suite/src/async-subagents/types.ts +1 -0
- package/external/pi-tools-suite/src/coding-discipline/index.ts +90 -59
- package/external/pi-tools-suite/src/config.ts +55 -1
- package/external/pi-tools-suite/src/context-gateway/accounting-log.ts +282 -0
- package/external/pi-tools-suite/src/context-gateway/config.ts +77 -3
- package/external/pi-tools-suite/src/context-gateway/efficiency.ts +414 -0
- package/external/pi-tools-suite/src/context-gateway/enforcement.ts +222 -0
- package/external/pi-tools-suite/src/context-gateway/index.ts +206 -19
- package/external/pi-tools-suite/src/context-gateway/storeless-capabilities.ts +7 -7
- package/external/pi-tools-suite/src/context-gateway/telemetry.ts +101 -28
- package/external/pi-tools-suite/src/context-gateway/types.ts +16 -3
- package/external/pi-tools-suite/src/context-inventory.ts +99 -0
- package/external/pi-tools-suite/src/dcp/auto-compress-budget.ts +39 -4
- package/external/pi-tools-suite/src/dcp/auto-compress.ts +128 -49
- package/external/pi-tools-suite/src/dcp/commands.ts +32 -156
- package/external/pi-tools-suite/src/dcp/compress-tool.ts +177 -46
- package/external/pi-tools-suite/src/dcp/compression-blocks.ts +6 -58
- package/external/pi-tools-suite/src/dcp/compression-preview.ts +9 -0
- package/external/pi-tools-suite/src/dcp/compression-progress.ts +22 -0
- package/external/pi-tools-suite/src/dcp/config.ts +114 -17
- package/external/pi-tools-suite/src/dcp/conversation-index.ts +36 -9
- package/external/pi-tools-suite/src/dcp/diagnostics.ts +41 -0
- package/external/pi-tools-suite/src/dcp/fresh-tool-results.ts +38 -0
- package/external/pi-tools-suite/src/dcp/index.ts +338 -66
- package/external/pi-tools-suite/src/dcp/journal.ts +126 -4
- package/external/pi-tools-suite/src/dcp/progress-controller.ts +2 -1
- package/external/pi-tools-suite/src/dcp/prompts.ts +83 -192
- package/external/pi-tools-suite/src/dcp/protected-continuity.ts +175 -0
- package/external/pi-tools-suite/src/dcp/pruner-candidates.ts +93 -3
- package/external/pi-tools-suite/src/dcp/pruner-message-ids.ts +6 -10
- package/external/pi-tools-suite/src/dcp/pruner-nudge.ts +36 -33
- package/external/pi-tools-suite/src/dcp/pruner-tools.ts +6 -3
- package/external/pi-tools-suite/src/dcp/pruner.ts +1 -0
- package/external/pi-tools-suite/src/dcp/routine-pressure.ts +86 -0
- package/external/pi-tools-suite/src/dcp/state.ts +9 -0
- package/external/pi-tools-suite/src/dcp/statistics.d.ts +8 -0
- package/external/pi-tools-suite/src/dcp/statistics.js +156 -0
- package/external/pi-tools-suite/src/default-pi-tools-suite-config.ts +78 -22
- package/external/pi-tools-suite/src/index.ts +7 -1
- package/external/pi-tools-suite/src/lib/project.ts +36 -1
- package/external/pi-tools-suite/src/model-tools/index.ts +10 -7
- package/external/pi-tools-suite/src/repo-discovery/index.ts +304 -4
- package/external/pi-tools-suite/src/resource-registry/index.ts +2551 -0
- package/external/pi-tools-suite/src/session-recovery/index.ts +17 -0
- package/external/pi-tools-suite/src/shell-command-policy.ts +219 -0
- package/external/pi-tools-suite/src/todo/index.ts +21 -0
- package/external/pi-tools-suite/src/todo/todo.ts +19 -1
- package/external/pi-tools-suite/src/tool-descriptions.ts +47 -19
- package/package.json +10 -9
- package/schemas/pi-tools-suite.json +466 -287
- package/schemas/pix.json +129 -11
- package/schemas/tasks.json +131 -0
- package/skills/simplify/SKILL.md +33 -5
- package/docs/desktop-markdown-media.md +0 -77
- package/external/pi-tools-suite/docs/browser-qa-subagent.md +0 -177
- package/external/pi-tools-suite/docs/dcp-emergency-current-turn.md +0 -102
- package/external/pi-tools-suite/src/async-subagents/agents/browser-qa.md +0 -598
- package/external/pi-tools-suite/src/async-subagents/async-subagents.sample.jsonc +0 -54
- package/external/pi-tools-suite/src/skill-installer/index.ts +0 -333
- package/skills/playwright-cli/SKILL.md +0 -420
- package/skills/playwright-cli/references/element-attributes.md +0 -23
- package/skills/playwright-cli/references/playwright-tests.md +0 -50
- package/skills/playwright-cli/references/request-mocking.md +0 -87
- package/skills/playwright-cli/references/running-code.md +0 -241
- package/skills/playwright-cli/references/session-management.md +0 -273
- package/skills/playwright-cli/references/spec-driven-testing.md +0 -311
- package/skills/playwright-cli/references/storage-state.md +0 -290
- package/skills/playwright-cli/references/test-generation.md +0 -142
- package/skills/playwright-cli/references/tracing.md +0 -154
- package/skills/playwright-cli/references/video-recording.md +0 -147
- package/skills/spec-lite/SKILL.md +0 -140
- /package/external/pi-tools-suite/src/async-subagents/agents/{browser-qa → ui-qa/browser}/examples/qa-auth.example.jsonc +0 -0
- /package/external/pi-tools-suite/src/async-subagents/agents/{browser-qa → ui-qa/browser}/examples/qa-flow.example.jsonc +0 -0
- /package/external/pi-tools-suite/src/async-subagents/agents/{browser-qa → ui-qa/browser}/vendor/fflate.LICENSE +0 -0
- /package/external/pi-tools-suite/src/async-subagents/agents/{browser-qa → ui-qa/browser}/vendor/fflate.mjs +0 -0
|
@@ -128,6 +128,16 @@ function validateExactBlock(value: unknown): asserts value is CompressionBlock {
|
|
|
128
128
|
throw new DcpJournalError(`DCP journal block b${value.id} has invalid ${key}`);
|
|
129
129
|
}
|
|
130
130
|
}
|
|
131
|
+
if (value.commitMetrics !== undefined) {
|
|
132
|
+
const m = value.commitMetrics;
|
|
133
|
+
if (!isRecord(m) || typeof m.operationId !== "string" || !m.operationId ||
|
|
134
|
+
!["manual", "auto", "consolidation"].includes(m.kind as string) ||
|
|
135
|
+
!finiteNonNegativeInteger(m.beforeTokens) || !finiteNonNegativeInteger(m.afterTokens) ||
|
|
136
|
+
!finiteNonNegativeInteger(m.netGainTokens) || m.netGainTokens <= 0 ||
|
|
137
|
+
m.beforeTokens - m.afterTokens !== m.netGainTokens) {
|
|
138
|
+
throw new DcpJournalError(`DCP journal block b${value.id} has invalid commit metrics`);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
131
141
|
for (const key of ["sourceMembers", "mutationMembers"] as const) {
|
|
132
142
|
const members = value[key];
|
|
133
143
|
if (!Array.isArray(members) || members.length === 0) {
|
|
@@ -438,13 +448,125 @@ function journalBranch(ctx: ExtensionContext): unknown[] {
|
|
|
438
448
|
}
|
|
439
449
|
}
|
|
440
450
|
|
|
451
|
+
function indexBranchParents(entries: readonly unknown[], requireFullChain: boolean): Map<string, string | null> | undefined {
|
|
452
|
+
const parents = new Map<string, string | null>();
|
|
453
|
+
let previousId: string | null = null;
|
|
454
|
+
for (const entry of entries) {
|
|
455
|
+
if (!isRecord(entry) || typeof entry.id !== "string" || !entry.id
|
|
456
|
+
|| parents.has(entry.id)) return undefined;
|
|
457
|
+
let parentId: string | null = null;
|
|
458
|
+
if (entry.parentId !== null) {
|
|
459
|
+
if (typeof entry.parentId !== "string" || !entry.parentId) return undefined;
|
|
460
|
+
parentId = entry.parentId;
|
|
461
|
+
}
|
|
462
|
+
if (requireFullChain && parentId !== previousId) return undefined;
|
|
463
|
+
parents.set(entry.id, parentId);
|
|
464
|
+
previousId = entry.id;
|
|
465
|
+
}
|
|
466
|
+
return parents;
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
/**
|
|
470
|
+
* getBranch() on Pix's lazy manager is a JSONL presentation tail: it may omit
|
|
471
|
+
* older ancestors AND interleave abandoned branches. Do not "simplify" this
|
|
472
|
+
* into a positional prefix/suffix comparison or an ID-membership test.
|
|
473
|
+
*
|
|
474
|
+
* Walk parentId from the captured current leaf. Only the full read may supply
|
|
475
|
+
* ancestors missing from the tail; overlapping IDs must have identical parents
|
|
476
|
+
* (SDK entry identities/parent links are immutable). Both the old leaf and the
|
|
477
|
+
* read tip must lie on that walk. A side-branch tip merely present in the tail
|
|
478
|
+
* is not evidence. Missing links/cycles/conflicts deny the retry.
|
|
479
|
+
*
|
|
480
|
+
* This proves permission to re-read, NOT a publishable merged snapshot. Never
|
|
481
|
+
* return the tail/union as history or hydrate synchronously to validate it.
|
|
482
|
+
* Contract + counterexample: specs/dcp-statistics.md#lazy-tail-retry-invariant.
|
|
483
|
+
*/
|
|
484
|
+
function readSnapshotFollowsCurrentBranch(
|
|
485
|
+
entries: readonly unknown[],
|
|
486
|
+
currentEntries: readonly unknown[],
|
|
487
|
+
previousLeafId: string,
|
|
488
|
+
currentLeafId: string,
|
|
489
|
+
): boolean {
|
|
490
|
+
const readParents = indexBranchParents(entries, true);
|
|
491
|
+
const currentParents = indexBranchParents(currentEntries, false);
|
|
492
|
+
if (!readParents?.has(previousLeafId) || !currentParents?.has(currentLeafId)) return false;
|
|
493
|
+
|
|
494
|
+
const readTipId = (entries.at(-1) as { id: string }).id;
|
|
495
|
+
const visited = new Set<string>();
|
|
496
|
+
let cursor: string | null = currentLeafId;
|
|
497
|
+
let reachedPrevious = false;
|
|
498
|
+
let reachedReadTip = false;
|
|
499
|
+
while (cursor !== null) {
|
|
500
|
+
if (visited.has(cursor)) return false;
|
|
501
|
+
visited.add(cursor);
|
|
502
|
+
const currentParent = currentParents.get(cursor);
|
|
503
|
+
const readParent = readParents.get(cursor);
|
|
504
|
+
if (currentParent !== undefined && readParent !== undefined && currentParent !== readParent) return false;
|
|
505
|
+
// An absent old ancestor may be supplied by the full read, but a missing
|
|
506
|
+
// new descendant cannot be guessed. Null is a root, not a missing value.
|
|
507
|
+
const parent = currentParent !== undefined ? currentParent : readParent;
|
|
508
|
+
if (parent === undefined) return false;
|
|
509
|
+
reachedPrevious ||= cursor === previousLeafId;
|
|
510
|
+
reachedReadTip ||= cursor === readTipId;
|
|
511
|
+
cursor = parent;
|
|
512
|
+
}
|
|
513
|
+
return reachedPrevious && reachedReadTip;
|
|
514
|
+
}
|
|
515
|
+
|
|
441
516
|
export async function readDcpJournalBranch(ctx: ExtensionContext): Promise<unknown[]> {
|
|
442
517
|
const manager = ctx.sessionManager as any;
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
518
|
+
const sessionId = manager.getSessionId?.();
|
|
519
|
+
const hasLeafIdentity = typeof manager.getLeafId === "function";
|
|
520
|
+
const readFullBranch = typeof manager.readFullBranchEntries === "function"
|
|
521
|
+
? () => manager.readFullBranchEntries()
|
|
522
|
+
: undefined;
|
|
523
|
+
|
|
524
|
+
// Lazy full-history reads yield to the event loop. A normal append on the
|
|
525
|
+
// same active branch (for example, tool results arriving while a reloaded
|
|
526
|
+
// runtime is replaying its journal) advances the leaf without changing the
|
|
527
|
+
// branch owner. Retry that transient race so startup does not permanently
|
|
528
|
+
// block DCP. A real branch move/fork, owner replacement, or a branch that
|
|
529
|
+
// keeps moving still fails closed.
|
|
530
|
+
const maxAttempts = readFullBranch ? 3 : 1;
|
|
531
|
+
for (let attempt = 0; attempt < maxAttempts; attempt += 1) {
|
|
532
|
+
const leafId = manager.getLeafId?.();
|
|
533
|
+
const entries = readFullBranch ? await readFullBranch() : manager.getBranch();
|
|
534
|
+
if (ctx.sessionManager !== manager || manager.getSessionId?.() !== sessionId) {
|
|
535
|
+
throw new DcpJournalError("DCP branch changed during history read; rebuild context");
|
|
536
|
+
}
|
|
537
|
+
if (!Array.isArray(entries)) throw new DcpJournalError("DCP full branch is unavailable");
|
|
538
|
+
// A presentation cursor is not a complete SDK branch, even if it contains
|
|
539
|
+
// recent users or journal deltas. Never silently initialize from that tail.
|
|
540
|
+
if (entries[0]?.parentId != null) throw new DcpJournalError("DCP received an incomplete branch (presentation tail)");
|
|
541
|
+
|
|
542
|
+
const currentLeafId = manager.getLeafId?.();
|
|
543
|
+
if (currentLeafId === leafId) {
|
|
544
|
+
if (hasLeafIdentity) {
|
|
545
|
+
const readLeafId = entries.at(-1)?.id;
|
|
546
|
+
if ((leafId == null && entries.length > 0) || (leafId != null && readLeafId !== leafId)) {
|
|
547
|
+
throw new DcpJournalError("DCP branch changed during history read; rebuild context");
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
return entries;
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
let sameBranchAdvance = false;
|
|
554
|
+
if (leafId && currentLeafId) {
|
|
555
|
+
try {
|
|
556
|
+
const currentEntries = manager.getBranch();
|
|
557
|
+
sameBranchAdvance = Array.isArray(currentEntries)
|
|
558
|
+
&& manager.getLeafId?.() === currentLeafId
|
|
559
|
+
&& readSnapshotFollowsCurrentBranch(entries, currentEntries, leafId, currentLeafId);
|
|
560
|
+
} catch {
|
|
561
|
+
sameBranchAdvance = false;
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
if (!sameBranchAdvance || attempt === maxAttempts - 1) {
|
|
565
|
+
throw new DcpJournalError("DCP branch changed during history read; rebuild context");
|
|
566
|
+
}
|
|
446
567
|
}
|
|
447
|
-
|
|
568
|
+
|
|
569
|
+
throw new DcpJournalError("DCP branch changed during history read; rebuild context");
|
|
448
570
|
}
|
|
449
571
|
|
|
450
572
|
function restoreLeafAfterAppendFailure(ctx: ExtensionContext, previousLeafId: string | null | undefined): void {
|
|
@@ -9,23 +9,21 @@
|
|
|
9
9
|
* Appended to the existing system prompt when DCP is enabled (automatic mode).
|
|
10
10
|
*/
|
|
11
11
|
export const SYSTEM_PROMPT = `
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
\`
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
Summaries must preserve only what is needed to continue: user intent and constraints, accepted decisions, files/symbols changed or inspected, actionable errors, verification status, and next steps. Do not infer, invent, or add facts that are not present in the selected messages. Drop incidental transcript detail, duplicate outputs, full logs, long code/JSON/diffs, and prose not needed later; include short literals only when required.
|
|
12
|
+
Keep live context high-signal. \`compress\` is the only DCP context tool; use it
|
|
13
|
+
only when a closed stale slice materially reduces context pressure. Low context
|
|
14
|
+
usage alone does not require compression. Good boundaries include completed
|
|
15
|
+
implementation, verification, investigation, config/docs, or understood logs.
|
|
16
|
+
Use \`messages\` for one large stale message and batch independent safe work.
|
|
17
|
+
|
|
18
|
+
Do not compress active work or raw code/errors/output needed next. If unfinished
|
|
19
|
+
work is compressed, preserve the active objective and next step. A summary must
|
|
20
|
+
preserve user intent/constraints, decisions, relevant files/symbols, actionable
|
|
21
|
+
errors, verification state, and next steps. Do not infer, invent, or add facts;
|
|
22
|
+
drop duplicate transcript detail, full logs, and long code/JSON/diffs.
|
|
23
|
+
|
|
24
|
+
\`mNNN\`/\`bN\` IDs and \`<dcp-system-reminder>\` tags are injected metadata;
|
|
25
|
+
never quote or output them. Critical/high-pressure reminders take priority;
|
|
26
|
+
routine reminders may be skipped when no safe useful slice exists.
|
|
29
27
|
`.trim()
|
|
30
28
|
|
|
31
29
|
/**
|
|
@@ -37,105 +35,52 @@ Summaries must preserve only what is needed to continue: user intent and constra
|
|
|
37
35
|
* ranges: Array<{
|
|
38
36
|
* startId: string // mNNN or bN
|
|
39
37
|
* endId: string // mNNN or bN
|
|
40
|
-
* summary
|
|
38
|
+
* summary?: string // optional parent-authored summary
|
|
41
39
|
* }>
|
|
42
40
|
* }
|
|
43
41
|
*/
|
|
44
|
-
export const COMPRESS_RANGE_DESCRIPTION = `
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
PROTECTED PROMPT CONTENT
|
|
87
|
-
If selected user text contains \`<protect>...</protect>\` content, preserve that protected content verbatim in your summary. The tool may append protected text automatically, but you should still account for it semantically.
|
|
88
|
-
|
|
89
|
-
COMPRESSED BLOCK PLACEHOLDERS
|
|
90
|
-
When rolling up compressed blocks, summarize their continuation-relevant meaning instead of copying the full old summaries. Every block carries a protected-fragment ledger, and those fragments are preserved separately. A block missing that ledger is invalid and must not be rolled up.
|
|
91
|
-
|
|
92
|
-
Only when the full previous summary is genuinely needed verbatim, use this exact placeholder format:
|
|
93
|
-
|
|
94
|
-
- \`(bN)\`
|
|
95
|
-
|
|
96
|
-
Compressed block sections in context are clearly marked with a header:
|
|
97
|
-
|
|
98
|
-
- \`[Compressed conversation section]\`
|
|
99
|
-
|
|
100
|
-
Compressed block IDs always use the \`bN\` form (never \`mNNN\`) and are represented as hidden DCP metadata.
|
|
101
|
-
|
|
102
|
-
Rules:
|
|
103
|
-
|
|
104
|
-
- Placeholders are optional, not required for every covered modern block. Each explicit placeholder expands the full old summary and may eliminate the intended savings. Include an intentionally preserved block at most once.
|
|
105
|
-
- Do not invent placeholders for blocks outside the selected range.
|
|
106
|
-
- Treat \`(bN)\` placeholders as RESERVED TOKENS. Do not emit \`(bN)\` text anywhere except intentional placeholders.
|
|
107
|
-
- If you need to mention a block in prose, use plain text like \`compressed bN\` (not as a placeholder).
|
|
108
|
-
- Preflight check before finalizing: each placeholder must refer to a known selected block whose full text you deliberately need to preserve. Otherwise write a concise factual summary in your own words.
|
|
109
|
-
|
|
110
|
-
These placeholders are semantic references. They will be replaced with the full stored compressed block content when the tool processes your output.
|
|
111
|
-
|
|
112
|
-
FLOW PRESERVATION WITH PLACEHOLDERS
|
|
113
|
-
When you use compressed block placeholders, write the surrounding summary text so it still reads correctly AFTER placeholder expansion.
|
|
114
|
-
|
|
115
|
-
- Treat each placeholder as a stand-in for a full conversation segment, not as a short label.
|
|
116
|
-
- Ensure transitions before and after each placeholder preserve chronology and causality.
|
|
117
|
-
- Do not write text that depends on the placeholder staying literal (for example, "as noted in \`(b2)\`").
|
|
118
|
-
- Your final meaning must be coherent once each placeholder is replaced with its full compressed block content.
|
|
119
|
-
|
|
120
|
-
BOUNDARY IDS
|
|
121
|
-
You specify boundaries by ID using the injected metadata IDs present in the conversation context:
|
|
122
|
-
|
|
123
|
-
- \`mNNN\` IDs identify raw messages (3 digits, zero-padded, e.g. \`m001\`, \`m042\`)
|
|
124
|
-
- \`bN\` IDs identify previously compressed blocks
|
|
125
|
-
|
|
126
|
-
Raw message IDs are provided in hidden DCP control metadata attached to stable user/tool-result carriers. IDs may be sparse; determine range order from where their carriers appear in context, not from the numeric suffix.
|
|
127
|
-
Some message-compression candidate hints include a low/medium/high priority; prefer high-priority stale message IDs for message-mode compression when a full range would be too broad.
|
|
128
|
-
Each carrier's metadata labels that carrier and any immediately preceding assistant message(s).
|
|
129
|
-
Treat these reference lines as boundary metadata only, not as tool result content.
|
|
130
|
-
|
|
131
|
-
Rules:
|
|
132
|
-
|
|
133
|
-
- Use only injected IDs in current context; \`startId\` must precede \`endId\`. Do not invent IDs.
|
|
134
|
-
- For \`ranges\`, never split a tool group: include the calling assistant and all its tool results, including parallel calls.
|
|
135
|
-
- If \`compress\` fails with \`Unknown message ID\`, treat those IDs as stale; retry at most once using only the error's listed current raw IDs or eligible \`bN\` blocks, or skip if no closed range is safe.
|
|
136
|
-
|
|
137
|
-
BATCHING
|
|
138
|
-
When multiple independent ranges or individual messages are ready, include all of them in one \`compress\` call. Range entries must not overlap. Message entries should each summarize exactly one raw message.`
|
|
42
|
+
export const COMPRESS_RANGE_DESCRIPTION = `Replace closed stale context with continuation-focused summaries.
|
|
43
|
+
|
|
44
|
+
WHEN: compress only when it materially improves live context or a DCP reminder
|
|
45
|
+
identifies useful stale work. Do not compress active/still-needed material. Passing
|
|
46
|
+
test/lint/build logs may become command + outcome + actionable failures; discard
|
|
47
|
+
raw logs/read/search output after their facts are captured.
|
|
48
|
+
|
|
49
|
+
SUMMARY: make it COMPLETE FOR CONTINUATION, not a transcript rewrite. Preserve
|
|
50
|
+
user intent/constraints, decisions, files/symbols changed or inspected, exact
|
|
51
|
+
errors that are still actionable, verification state, unresolved blockers, and
|
|
52
|
+
next steps. If work remains unfinished include \`Active objective\` and \`Next
|
|
53
|
+
step\`. Do not infer, invent, or add facts. Preserve uncertainty. Do not copy long
|
|
54
|
+
raw code, JSON, diffs, logs, or tool output; use short literals only when needed.
|
|
55
|
+
Normally omit \`summary\`: DCP generates it. An explicit \`summary\` overrides
|
|
56
|
+
generation when parent-authored continuation wording is genuinely required.
|
|
57
|
+
|
|
58
|
+
MODES:
|
|
59
|
+
- \`ranges\`: contiguous \`startId..endId\` spans.
|
|
60
|
+
- \`messages\`: one raw \`mNNN\` body when neighbours should remain raw. Use
|
|
61
|
+
\`messages\` for a single large stale message; it does not accept \`bN\`.
|
|
62
|
+
Batch independent non-overlapping selections in one call.
|
|
63
|
+
|
|
64
|
+
BOUNDARIES: use only injected IDs currently visible on stable user/tool-result
|
|
65
|
+
carriers. \`mNNN\` is raw, \`bN\` is an active compressed block; IDs may be sparse
|
|
66
|
+
and order is the conversation order, not the number. Carrier metadata labels the
|
|
67
|
+
carrier plus immediately preceding assistant message(s): \`a\`=assistant,
|
|
68
|
+
\`u\`=user, \`t\`=tool result, \`x\`=bash result, \`b\`=block alias. Do not invent IDs. For
|
|
69
|
+
\`ranges\`, never split a tool group: include the calling assistant and all its
|
|
70
|
+
tool results, including parallel calls. On \`Unknown message ID\`, retry at most
|
|
71
|
+
once using the current IDs reported by the tool.
|
|
72
|
+
|
|
73
|
+
PROTECTION/ROLLUP: preserve \`<protect>...</protect>\` text verbatim. When a
|
|
74
|
+
selected range contains compressed blocks, summarize their continuation-relevant
|
|
75
|
+
meaning; their protected-fragment ledgers survive separately. Placeholders are
|
|
76
|
+
optional: use \`(bN)\` only when the full selected prior summary is genuinely
|
|
77
|
+
required verbatim, at most once, and never invent a placeholder. Otherwise refer
|
|
78
|
+
to it in prose as \`compressed bN\`.
|
|
79
|
+
|
|
80
|
+
RESULT: the tool rejects non-positive full-projection gain. An unsuccessful call
|
|
81
|
+
does not satisfy a reminder. Inspect \`netGain\`, \`pressureRelieved\`, and
|
|
82
|
+
\`remainingRecoveryTokens\`; a positive partial commit can still leave pressure.
|
|
83
|
+
Do not discard required facts merely to hit a token target.`
|
|
139
84
|
|
|
140
85
|
/**
|
|
141
86
|
* Injected into messages when context usage exceeds maxContextPercent.
|
|
@@ -143,29 +88,11 @@ When multiple independent ranges or individual messages are ready, include all o
|
|
|
143
88
|
*/
|
|
144
89
|
export const CONTEXT_LIMIT_NUDGE_STRONG = `<dcp-system-reminder>
|
|
145
90
|
CRITICAL WARNING: MAX CONTEXT LIMIT REACHED
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
If you are in the middle of a critical atomic operation, finish that atomic step first, then compress immediately.
|
|
152
|
-
If any closed slice exists (finished implementation, verification, config/doc edit, answered exploration, dead end, or test/log inspection), compress it before replying or starting another task. Passing logs should become command + pass/fail + follow-up status only.
|
|
153
|
-
Recently completed todo/task/subtask items are preferred boundaries when they form a high-yield closed slice.
|
|
154
|
-
|
|
155
|
-
RANGE STRATEGY (MANDATORY)
|
|
156
|
-
Prioritize one large, closed, high-yield compression range first.
|
|
157
|
-
This overrides the normal preference for many small compressions.
|
|
158
|
-
Only split into multiple compressions if one large range would reduce summary quality or make boundary selection unsafe.
|
|
159
|
-
|
|
160
|
-
RANGE SELECTION
|
|
161
|
-
Start from older, resolved history and capture as much stale context as safely possible in one pass.
|
|
162
|
-
Avoid the newest active working slice unless it is clearly closed.
|
|
163
|
-
Use injected boundary IDs for compression (\`mNNN\` for messages, \`bN\` for compressed blocks), and ensure \`startId\` appears before \`endId\`.
|
|
164
|
-
For a single large stale message, use the \`messages\` array with its injected \`mNNN\` ID.
|
|
165
|
-
|
|
166
|
-
SUMMARY REQUIREMENTS
|
|
167
|
-
Your summary must cover all essential details from the selected range so work can continue without reopening raw messages, but it should not restate raw code, JSON, logs, or diffs unless a short literal is required.
|
|
168
|
-
If the compressed range includes user messages, preserve user intent exactly. Prefer direct quotes for short user messages to avoid semantic drift.
|
|
91
|
+
You MUST use the \`compress\` tool now, after any critical atomic step. Prefer one
|
|
92
|
+
large, older, closed high-yield range; split only for safety/summary quality. Keep
|
|
93
|
+
the newest active slice raw. Preserve user intent exactly and all state needed to
|
|
94
|
+
continue, but not full logs/code/diffs. Use current injected IDs; use \`messages\`
|
|
95
|
+
for one isolated large stale message.
|
|
169
96
|
</dcp-system-reminder>`
|
|
170
97
|
|
|
171
98
|
/**
|
|
@@ -174,20 +101,11 @@ If the compressed range includes user messages, preserve user intent exactly. Pr
|
|
|
174
101
|
*/
|
|
175
102
|
export const CONTEXT_LIMIT_NUDGE_SOFT = `<dcp-system-reminder>
|
|
176
103
|
ACTION REQUIRED: Context usage is high.
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
High-priority stale shell/read/repo/web outputs should be compressed once no exact raw text is needed. Passing logs should not remain raw after they are understood.
|
|
183
|
-
|
|
184
|
-
RANGE SELECTION
|
|
185
|
-
Prefer older, resolved history. Avoid the newest active working slice unless it is clearly done.
|
|
186
|
-
Use injected boundary IDs (\`mNNN\` for messages, \`bN\` for compressed blocks) and ensure \`startId\` appears before \`endId\`.
|
|
187
|
-
For a single large stale message, use message-mode compression via the \`messages\` array.
|
|
188
|
-
|
|
189
|
-
If multiple independent high-yield ranges are ready, batch them in a single \`compress\` call.
|
|
190
|
-
If nothing is cleanly closed and worth summarizing yet, continue with the next atomic step and re-check later.
|
|
104
|
+
Before more exploration, compress a high-yield older closed slice if one is safe
|
|
105
|
+
and useful. Keep active/tiny slices raw; understood logs/search/read output are
|
|
106
|
+
good candidates. Batch independent ranges; use message-mode compression for one
|
|
107
|
+
large stale message. If nothing is cleanly closed, continue with the next atomic
|
|
108
|
+
step and re-check later.
|
|
191
109
|
</dcp-system-reminder>`
|
|
192
110
|
|
|
193
111
|
/**
|
|
@@ -196,18 +114,10 @@ If nothing is cleanly closed and worth summarizing yet, continue with the next a
|
|
|
196
114
|
*/
|
|
197
115
|
export const TURN_NUDGE = `<dcp-system-reminder>
|
|
198
116
|
CONTEXT CHECK: Evaluate whether compression would materially improve the live context.
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
Do not compress just because a small slice closed while context is still low. Prefer compression before another large batch of searches, reads, CI log fetches, or tests when a high-yield stale slice exists.
|
|
205
|
-
High-priority stale shell/read/repo/web outputs and understood passing logs should be compressed once no exact raw text is needed.
|
|
206
|
-
|
|
207
|
-
Prefer small, closed-range compressions over one broad compression.
|
|
208
|
-
Use message-mode compression for isolated large stale messages.
|
|
209
|
-
The goal is to filter meaningful noise and distill key information so context accumulation stays under control.
|
|
210
|
-
Keep active context uncompressed.
|
|
117
|
+
Compress only a non-trivial closed stale slice that no longer needs verbatim text,
|
|
118
|
+
especially before another large tool batch. Do not compress just because a small
|
|
119
|
+
slice closed. Prefer closed ranges; use message-mode compression for an isolated
|
|
120
|
+
large stale message. Keep active context uncompressed.
|
|
211
121
|
</dcp-system-reminder>`
|
|
212
122
|
|
|
213
123
|
/**
|
|
@@ -215,15 +125,10 @@ Keep active context uncompressed.
|
|
|
215
125
|
*/
|
|
216
126
|
export const ITERATION_NUDGE = `<dcp-system-reminder>
|
|
217
127
|
CONTEXT CHECK: You've been iterating for a while after the last user message.
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
Avoid accumulating large tool outputs while a high-yield completed slice remains raw. If only small or still-needed ranges are closed, continue the next atomic step and re-check later.
|
|
224
|
-
|
|
225
|
-
Prefer multiple short, closed ranges over one large range when several independent slices are ready.
|
|
226
|
-
Use message-mode compression for isolated large stale messages.
|
|
128
|
+
Before another large tool batch, compress completed non-trivial work that no longer
|
|
129
|
+
needs raw detail. Prefer closed ranges; use message-mode compression for an
|
|
130
|
+
isolated large stale message. If only small or still-needed ranges are closed,
|
|
131
|
+
continue the next atomic step and re-check later.
|
|
227
132
|
</dcp-system-reminder>`
|
|
228
133
|
|
|
229
134
|
/**
|
|
@@ -233,25 +138,11 @@ Use message-mode compression for isolated large stale messages.
|
|
|
233
138
|
*/
|
|
234
139
|
export const MANUAL_MODE_SYSTEM_PROMPT = `
|
|
235
140
|
You are operating in DCP manual mode for context management.
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
- Only when a \`<dcp-system-reminder>\` nudge instructs you to (context-limit emergency)
|
|
244
|
-
- Never as background housekeeping or on your own initiative
|
|
245
|
-
|
|
246
|
-
WHEN YOU DO COMPRESS
|
|
247
|
-
Apply the same quality standards as always:
|
|
248
|
-
|
|
249
|
-
- Summaries must be complete for continuation, not transcript-sized; keep only file paths, decisions, findings, exact constraints, unresolved blockers, and verification state that may matter later
|
|
250
|
-
- Avoid raw JSON/code/diff/log blocks in summary strings; describe changes in prose or use very short quote-light code spans when literals are necessary
|
|
251
|
-
- Preserve user intent precisely; prefer direct quotes for short user messages
|
|
252
|
-
- Use only boundary IDs present in context (\`mNNN\` for messages, \`bN\` for compressed blocks)
|
|
253
|
-
- Batch independent ranges in a single \`compress\` call when possible
|
|
254
|
-
- Use message-mode compression for isolated large stale messages when directed by a context-limit nudge
|
|
255
|
-
|
|
256
|
-
Do not compress active, still-needed context. Only compress ranges that are genuinely closed and whose raw form is no longer required.
|
|
141
|
+
Do NOT proactively compress. Use \`compress\` only when the user explicitly asks
|
|
142
|
+
or a \`<dcp-system-reminder>\` requires context-limit recovery. Preserve user
|
|
143
|
+
intent precisely and enough decisions/files/errors/verification/next state to
|
|
144
|
+
continue; omit long raw code/JSON/diffs/logs. Use only visible \`mNNN\`/\`bN\`
|
|
145
|
+
IDs, batch independent safe ranges, and use message-mode for one large stale
|
|
146
|
+
message. Do not compress active, still-needed context. Injected DCP IDs/reminder
|
|
147
|
+
tags are metadata; never output them.
|
|
257
148
|
`.trim()
|