pi-ui-extend 1.0.39 → 1.0.41

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.
Files changed (113) hide show
  1. package/README.md +1 -1
  2. package/dist/app/commands/command-registry.js +2 -2
  3. package/dist/app/commands/command-session-actions.d.ts +0 -1
  4. package/dist/app/commands/command-session-actions.js +22 -13
  5. package/dist/app/icons.d.ts +14 -0
  6. package/dist/app/icons.js +33 -0
  7. package/dist/app/rendering/conversation-tool-renderer.js +2 -2
  8. package/dist/app/rendering/dcp-stats.d.ts +6 -1
  9. package/dist/app/rendering/dcp-stats.js +214 -46
  10. package/dist/app/rendering/editor-panels.js +8 -5
  11. package/dist/app/session/lazy-session-manager.js +12 -1
  12. package/dist/app/session/tabs-controller.d.ts +2 -5
  13. package/dist/app/session/tabs-controller.js +12 -21
  14. package/dist/app/subagents/subagents-model.d.ts +14 -1
  15. package/dist/app/subagents/subagents-model.js +34 -15
  16. package/dist/app/types.d.ts +2 -0
  17. package/dist/bundled-extensions/session-title/config.js +1 -1
  18. package/dist/markdown-format.js +27 -9
  19. package/dist/schemas/pi-tools-suite-schema.d.ts +29 -16
  20. package/dist/schemas/pi-tools-suite-schema.js +46 -31
  21. package/external/pi-tools-suite/README.md +392 -52
  22. package/external/pi-tools-suite/docs/browser-qa-subagent.md +31 -21
  23. package/external/pi-tools-suite/docs/context-gateway-p00-adr.md +216 -0
  24. package/external/pi-tools-suite/docs/context-gateway-p01n-gate-review.md +122 -0
  25. package/external/pi-tools-suite/docs/context-gateway-p01n-measurement.md +133 -0
  26. package/external/pi-tools-suite/docs/context-gateway-p01r-ra-evidence.md +111 -0
  27. package/external/pi-tools-suite/docs/context-gateway-p01r-rb-evidence.md +100 -0
  28. package/external/pi-tools-suite/docs/context-gateway-p01r-rc-evidence.md +69 -0
  29. package/external/pi-tools-suite/docs/context-gateway-p01r-rd-evidence.md +100 -0
  30. package/external/pi-tools-suite/docs/context-gateway-p01r-re-evidence.md +74 -0
  31. package/external/pi-tools-suite/docs/context-gateway-p01r-rf-evidence.md +153 -0
  32. package/external/pi-tools-suite/docs/context-gateway-p01r-rg-evidence.md +235 -0
  33. package/external/pi-tools-suite/docs/evals.md +684 -0
  34. package/external/pi-tools-suite/docs/subagent-model-pools.md +109 -0
  35. package/external/pi-tools-suite/package.json +10 -3
  36. package/external/pi-tools-suite/src/async-subagents/{private-skills → agents}/browser-qa/scripts/browser-qa-runner.mjs +82 -1
  37. package/external/pi-tools-suite/src/async-subagents/{private-skills/browser-qa/SKILL.md → agents/browser-qa.md} +261 -12
  38. package/external/pi-tools-suite/src/async-subagents/agents/implement.md +20 -0
  39. package/external/pi-tools-suite/src/async-subagents/agents/oracle.md +16 -0
  40. package/external/pi-tools-suite/src/async-subagents/agents/research.md +18 -0
  41. package/external/pi-tools-suite/src/async-subagents/agents/verify.md +18 -0
  42. package/external/pi-tools-suite/src/async-subagents/async-subagents.sample.jsonc +27 -243
  43. package/external/pi-tools-suite/src/async-subagents/commands.ts +6 -2
  44. package/external/pi-tools-suite/src/async-subagents/core/agent-catalog.ts +41 -0
  45. package/external/pi-tools-suite/src/async-subagents/core/agent-strategy.ts +13 -93
  46. package/external/pi-tools-suite/src/async-subagents/core/agents-dir.ts +494 -0
  47. package/external/pi-tools-suite/src/async-subagents/core/browser-qa.ts +9 -0
  48. package/external/pi-tools-suite/src/async-subagents/core/config.ts +200 -143
  49. package/external/pi-tools-suite/src/async-subagents/core/model-fallback.ts +1 -1
  50. package/external/pi-tools-suite/src/async-subagents/core/model-selection.ts +54 -0
  51. package/external/pi-tools-suite/src/async-subagents/core/prompt.ts +7 -6
  52. package/external/pi-tools-suite/src/async-subagents/core/routing.ts +52 -45
  53. package/external/pi-tools-suite/src/async-subagents/core/spawn.ts +12 -4
  54. package/external/pi-tools-suite/src/async-subagents/index.ts +11 -1
  55. package/external/pi-tools-suite/src/async-subagents/lib.ts +6 -2
  56. package/external/pi-tools-suite/src/async-subagents/tools/spawn.ts +46 -18
  57. package/external/pi-tools-suite/src/async-subagents/tools/subagents.ts +3 -2
  58. package/external/pi-tools-suite/src/async-subagents/types.ts +2 -0
  59. package/external/pi-tools-suite/src/coding-discipline/index.ts +41 -142
  60. package/external/pi-tools-suite/src/config.ts +1 -22
  61. package/external/pi-tools-suite/src/context-gateway/accounting.ts +151 -0
  62. package/external/pi-tools-suite/src/context-gateway/config.ts +111 -0
  63. package/external/pi-tools-suite/src/context-gateway/index.ts +160 -0
  64. package/external/pi-tools-suite/src/context-gateway/metadata-normalization.ts +88 -0
  65. package/external/pi-tools-suite/src/context-gateway/storeless-capabilities.ts +89 -0
  66. package/external/pi-tools-suite/src/context-gateway/telemetry.ts +429 -0
  67. package/external/pi-tools-suite/src/context-gateway/test-output-parser.ts +326 -0
  68. package/external/pi-tools-suite/src/context-gateway/types.ts +152 -0
  69. package/external/pi-tools-suite/src/dcp/auto-compress-budget.ts +106 -0
  70. package/external/pi-tools-suite/src/dcp/auto-compress.ts +810 -106
  71. package/external/pi-tools-suite/src/dcp/commands.ts +64 -139
  72. package/external/pi-tools-suite/src/dcp/compress-tool.ts +369 -35
  73. package/external/pi-tools-suite/src/dcp/compression-blocks.ts +510 -64
  74. package/external/pi-tools-suite/src/dcp/compression-preview.ts +113 -0
  75. package/external/pi-tools-suite/src/dcp/compression-progress.ts +70 -0
  76. package/external/pi-tools-suite/src/dcp/config.ts +36 -61
  77. package/external/pi-tools-suite/src/dcp/conversation-index.ts +421 -0
  78. package/external/pi-tools-suite/src/dcp/debug-log.ts +7 -5
  79. package/external/pi-tools-suite/src/dcp/index.ts +617 -203
  80. package/external/pi-tools-suite/src/dcp/journal.ts +566 -0
  81. package/external/pi-tools-suite/src/dcp/progress-controller.ts +244 -0
  82. package/external/pi-tools-suite/src/dcp/prompts.ts +10 -7
  83. package/external/pi-tools-suite/src/dcp/provider-tool-results.ts +189 -0
  84. package/external/pi-tools-suite/src/dcp/pruner-candidates.ts +298 -78
  85. package/external/pi-tools-suite/src/dcp/pruner-compression-blocks.ts +173 -281
  86. package/external/pi-tools-suite/src/dcp/pruner-emergency.ts +2 -4
  87. package/external/pi-tools-suite/src/dcp/pruner-message-ids.ts +17 -5
  88. package/external/pi-tools-suite/src/dcp/pruner-metadata.ts +11 -1
  89. package/external/pi-tools-suite/src/dcp/pruner-nudge.ts +30 -82
  90. package/external/pi-tools-suite/src/dcp/pruner-tools.ts +22 -133
  91. package/external/pi-tools-suite/src/dcp/pruner.ts +18 -33
  92. package/external/pi-tools-suite/src/dcp/recovery.ts +129 -0
  93. package/external/pi-tools-suite/src/dcp/shadow-plan.ts +127 -0
  94. package/external/pi-tools-suite/src/dcp/state-transaction.ts +102 -0
  95. package/external/pi-tools-suite/src/dcp/state.ts +158 -580
  96. package/external/pi-tools-suite/src/dcp/ui.ts +1 -0
  97. package/external/pi-tools-suite/src/default-pi-tools-suite-config.ts +55 -220
  98. package/external/pi-tools-suite/src/index.ts +9 -0
  99. package/external/pi-tools-suite/src/model-tools/index.ts +76 -42
  100. package/external/pi-tools-suite/src/repo-discovery/index.ts +84 -18
  101. package/external/pi-tools-suite/src/repo-discovery/native-compact.ts +458 -0
  102. package/external/pi-tools-suite/src/session-recovery/index.ts +189 -43
  103. package/external/pi-tools-suite/src/tool-descriptions.ts +43 -38
  104. package/external/pi-tools-suite/src/truncation-metadata-normalizer/index.ts +17 -0
  105. package/package.json +6 -6
  106. package/schemas/pi-tools-suite.json +159 -78
  107. package/external/pi-tools-suite/src/async-subagents/private-skills/browser-qa/references/auth-scaffold-spec.md +0 -78
  108. package/external/pi-tools-suite/src/async-subagents/private-skills/browser-qa/references/qa-design.md +0 -223
  109. package/external/pi-tools-suite/src/dcp/state-persistence.ts +0 -195
  110. /package/external/pi-tools-suite/src/async-subagents/{private-skills/browser-qa/references → agents/browser-qa/examples}/qa-auth.example.jsonc +0 -0
  111. /package/external/pi-tools-suite/src/async-subagents/{private-skills/browser-qa/references → agents/browser-qa/examples}/qa-flow.example.jsonc +0 -0
  112. /package/external/pi-tools-suite/src/async-subagents/{private-skills → agents}/browser-qa/vendor/fflate.LICENSE +0 -0
  113. /package/external/pi-tools-suite/src/async-subagents/{private-skills → agents}/browser-qa/vendor/fflate.mjs +0 -0
@@ -0,0 +1,127 @@
1
+ import type { DcpConfig } from "./config.js"
2
+ import { applyPruning, detectCompressionCandidate, detectEmergencyCompressionCandidate, detectMessageCompressionCandidates, getActiveSummaryTokenEstimate, resolveContextThresholds } from "./pruner.js"
3
+ import { estimateMessageTokens } from "./pruner-metadata.js"
4
+ import type { CompressionCandidate, MessageCompressionCandidate } from "./pruner-types.js"
5
+ import { planDcpBudget, type DcpBudgetPlan } from "./progress-controller.js"
6
+ import type { DcpState } from "./state.js"
7
+
8
+ export interface DcpShadowPlanInput {
9
+ messages: any[]
10
+ state: DcpState
11
+ config: DcpConfig
12
+ contextWindow: number
13
+ providerUsageTokens?: number | null
14
+ reservedOutputTokens?: number
15
+ reservedToolTokens?: number
16
+ modelKeys?: string[]
17
+ }
18
+
19
+ export interface DcpShadowPlanResult {
20
+ projectedTokens: number
21
+ contextPercent: number
22
+ budget: DcpBudgetPlan
23
+ routineCandidate: CompressionCandidate | null
24
+ emergencyCandidate: CompressionCandidate | null
25
+ messageCandidates: MessageCompressionCandidate[]
26
+ projectedMessageCount: number
27
+ }
28
+
29
+ function cloneDcpState(state: DcpState): DcpState {
30
+ return {
31
+ ...state,
32
+ toolCalls: new Map([...state.toolCalls].map(([id, record]) => [id, {
33
+ ...record,
34
+ inputArgs: { ...(record.inputArgs ?? {}) },
35
+ }])),
36
+ prunedToolIds: new Set(state.prunedToolIds),
37
+ prunedToolReasons: new Map(state.prunedToolReasons),
38
+ providerSeenToolIds: new Set(state.providerSeenToolIds),
39
+ compressionBlocks: state.compressionBlocks.map((block) => ({
40
+ ...block,
41
+ coveredBlockIds: block.coveredBlockIds ? [...block.coveredBlockIds] : undefined,
42
+ protectedFragments: block.protectedFragments?.map((fragment) => ({ ...fragment })),
43
+ sourceCoverage: block.sourceCoverage ? { ...block.sourceCoverage } : undefined,
44
+ })),
45
+ messageIdSnapshot: new Map(state.messageIdSnapshot),
46
+ messageMetaSnapshot: new Map([...state.messageMetaSnapshot].map(([id, meta]) => [id, {
47
+ ...meta,
48
+ toolCallIds: meta.toolCallIds ? [...meta.toolCallIds] : undefined,
49
+ }])),
50
+ conversationIndexSnapshot: state.conversationIndexSnapshot.map((entry) => ({
51
+ ...entry,
52
+ toolCallIds: entry.toolCallIds ? [...entry.toolCallIds] : undefined,
53
+ })),
54
+ messageIdsByStableId: new Map(state.messageIdsByStableId),
55
+ accountedCompressionBlockIds: new Set(state.accountedCompressionBlockIds),
56
+ compressionTokenSavings: new Map(state.compressionTokenSavings),
57
+ accountedPrunedToolIds: new Set(state.accountedPrunedToolIds),
58
+ nudgeAnchors: state.nudgeAnchors.map((anchor) => ({ ...anchor })),
59
+ lastNudge: state.lastNudge ? { ...state.lastNudge } : undefined,
60
+ progressRecovery: state.progressRecovery ? { ...state.progressRecovery } : undefined,
61
+ }
62
+ }
63
+
64
+ /**
65
+ * E10 dry-run planner. All DCP transforms and candidate discovery run against a
66
+ * detached state clone; the supplied live state is never published, persisted,
67
+ * or passed to a model. This is intended for rollout diagnostics/shadow checks.
68
+ */
69
+ export function planDcpShadow(input: DcpShadowPlanInput): DcpShadowPlanResult {
70
+ const shadowState = cloneDcpState(input.state)
71
+ const projected = applyPruning(input.messages, shadowState, input.config)
72
+ const projectedTokens = projected.reduce((sum, message) => sum + estimateMessageTokens(message), 0)
73
+ const contextWindow = Math.max(1, Math.floor(input.contextWindow))
74
+ const emergency = input.config.strategies.emergencyCurrentTurnPruning
75
+ const thresholds = resolveContextThresholds(input.config, input.modelKeys ?? [], contextWindow)
76
+ const budget = planDcpBudget({
77
+ providerUsageTokens: input.providerUsageTokens,
78
+ repoProjectedTokens: projectedTokens,
79
+ contextWindow,
80
+ reservedOutputTokens: input.reservedOutputTokens ?? 0,
81
+ reservedToolTokens: input.reservedToolTokens ?? 0,
82
+ maxContextPercent: thresholds.maxContextPercent,
83
+ hardContextPercent: emergency.hardContextPercent,
84
+ targetContextPercent: Math.min(
85
+ emergency.targetContextPercent,
86
+ Math.max(0, thresholds.maxContextPercent * 0.9),
87
+ ),
88
+ summaryBufferEnabled: input.config.compress.summaryBuffer,
89
+ activeSummaryTokens: getActiveSummaryTokenEstimate(shadowState),
90
+ estimatorMarginTokens: Math.max(256, Math.ceil(contextWindow * 0.0025)),
91
+ })
92
+ const contextPercent = budget.projectedBeforeTokens / contextWindow
93
+ const recovery = budget.pressured ? { requiredSavingsTokens: budget.requiredSavingsTokens } : undefined
94
+ const routineCandidate = detectCompressionCandidate(
95
+ projected,
96
+ shadowState,
97
+ input.config,
98
+ contextPercent,
99
+ recovery,
100
+ )
101
+ const emergencyCandidate = routineCandidate === null && budget.pressured
102
+ ? detectEmergencyCompressionCandidate(
103
+ projected,
104
+ shadowState,
105
+ input.config,
106
+ contextPercent,
107
+ budget.softHeadroomTokens / contextWindow,
108
+ recovery,
109
+ )
110
+ : null
111
+ const messageCandidates = detectMessageCompressionCandidates(
112
+ projected,
113
+ shadowState,
114
+ input.config,
115
+ contextPercent,
116
+ )
117
+
118
+ return {
119
+ projectedTokens,
120
+ contextPercent,
121
+ budget,
122
+ routineCandidate,
123
+ emergencyCandidate,
124
+ messageCandidates,
125
+ projectedMessageCount: projected.length,
126
+ }
127
+ }
@@ -0,0 +1,102 @@
1
+ import type { DcpState } from "./state.js"
2
+ import { createHash } from "node:crypto"
3
+
4
+ /**
5
+ * Serialize all stateful DCP publications which share one live state object.
6
+ *
7
+ * Persistence has its own per-path queue, but that queue cannot protect the
8
+ * read/plan/publish interval: two callers can otherwise both clone `nextBlockId
9
+ * === 1`, persist independent snapshots, and both report success for b1. This
10
+ * queue deliberately spans preparation, durable publication, and the final
11
+ * in-memory commit.
12
+ */
13
+ const transactionTails = new WeakMap<DcpState, Promise<void>>()
14
+
15
+ export async function runDcpStateTransaction<T>(
16
+ state: DcpState,
17
+ operation: () => Promise<T> | T,
18
+ ): Promise<T> {
19
+ const previous = transactionTails.get(state) ?? Promise.resolve()
20
+ let release!: () => void
21
+ const current = new Promise<void>((resolve) => {
22
+ release = resolve
23
+ })
24
+ const tail = previous.catch(() => undefined).then(() => current)
25
+ transactionTails.set(state, tail)
26
+
27
+ await previous.catch(() => undefined)
28
+ try {
29
+ return await operation()
30
+ } finally {
31
+ release()
32
+ if (transactionTails.get(state) === tail) transactionTails.delete(state)
33
+ }
34
+ }
35
+
36
+ /** Runtime ownership changes invalidate any detached compression plan. */
37
+ export function invalidateDcpStateOwner(state: DcpState): number {
38
+ state.sessionEpoch = Math.max(1, Math.floor(state.sessionEpoch || 0) + 1)
39
+ return state.sessionEpoch
40
+ }
41
+
42
+ export function cloneDcpTransactionState(state: DcpState): DcpState {
43
+ return structuredClone(state)
44
+ }
45
+
46
+ function canonicalRuntimeValue(value: unknown, seen = new WeakSet<object>()): unknown {
47
+ if (value === null || typeof value === "string" || typeof value === "boolean") return value
48
+ if (typeof value === "number") return Number.isFinite(value) ? value : String(value)
49
+ if (typeof value === "bigint") return `${value}n`
50
+ if (typeof value === "undefined") return "[undefined]"
51
+ if (Array.isArray(value)) return value.map((item) => canonicalRuntimeValue(item, seen))
52
+ if (value instanceof Map) {
53
+ return [...value.entries()]
54
+ .map(([key, item]) => [canonicalRuntimeValue(key, seen), canonicalRuntimeValue(item, seen)] as const)
55
+ .sort(([a], [b]) => JSON.stringify(a).localeCompare(JSON.stringify(b)))
56
+ }
57
+ if (value instanceof Set) {
58
+ return [...value.values()]
59
+ .map((item) => canonicalRuntimeValue(item, seen))
60
+ .sort((a, b) => JSON.stringify(a).localeCompare(JSON.stringify(b)))
61
+ }
62
+ if (typeof value === "object") {
63
+ if (seen.has(value as object)) return "[cycle]"
64
+ seen.add(value as object)
65
+ const record = value as Record<string, unknown>
66
+ const result: Record<string, unknown> = {}
67
+ for (const key of Object.keys(record).sort()) result[key] = canonicalRuntimeValue(record[key], seen)
68
+ seen.delete(value as object)
69
+ return result
70
+ }
71
+ return String(value)
72
+ }
73
+
74
+ function transactionRevision(state: DcpState): string {
75
+ return createHash("sha256").update(JSON.stringify(canonicalRuntimeValue(state))).digest("hex")
76
+ }
77
+
78
+ /** Capture ownership before queuing, never after a long await. */
79
+ export function captureDcpTransactionGuard(
80
+ state: DcpState,
81
+ config: unknown,
82
+ signal?: AbortSignal,
83
+ context?: any,
84
+ ): () => void {
85
+ const epoch = state.sessionEpoch
86
+ const revision = transactionRevision(state)
87
+ const configRevision = JSON.stringify(config)
88
+ const contextRevision = () => JSON.stringify({
89
+ session: context?.sessionManager?.getSessionId?.(),
90
+ branch: context?.sessionManager?.getBranch?.(),
91
+ model: context?.model,
92
+ cwd: context?.cwd,
93
+ })
94
+ const owner = contextRevision()
95
+ return () => {
96
+ signal?.throwIfAborted()
97
+ if (state.sessionEpoch !== epoch || transactionRevision(state) !== revision ||
98
+ JSON.stringify(config) !== configRevision || contextRevision() !== owner) {
99
+ throw new Error("stale_plan: DCP session, branch, model, configuration or source revision changed before publication")
100
+ }
101
+ }
102
+ }