gsd-pi 2.77.0-dev.1d17f366c → 2.77.0-dev.58d3d4d6c
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/resources/extensions/gsd/auto/session.js +6 -0
- package/dist/resources/extensions/gsd/auto-post-unit.js +79 -0
- package/dist/resources/extensions/gsd/auto-prompts.js +48 -7
- package/dist/resources/extensions/gsd/auto-start.js +62 -3
- package/dist/resources/extensions/gsd/auto.js +34 -0
- package/dist/resources/extensions/gsd/context-store.js +23 -7
- package/dist/resources/extensions/gsd/forensics.js +106 -0
- package/dist/resources/extensions/gsd/preferences-validation.js +23 -0
- package/dist/resources/extensions/gsd/prompt-cache-optimizer.js +4 -0
- package/dist/resources/extensions/gsd/slice-cadence.js +238 -0
- package/dist/resources/extensions/gsd/tools/validate-milestone.js +7 -2
- package/dist/resources/extensions/gsd/worktree-manager.js +51 -0
- package/dist/resources/extensions/gsd/worktree-resolver.js +86 -7
- package/dist/resources/extensions/gsd/worktree-telemetry.js +198 -0
- package/dist/tsconfig.extensions.tsbuildinfo +1 -1
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +9 -9
- package/dist/web/standalone/.next/build-manifest.json +2 -2
- package/dist/web/standalone/.next/prerender-manifest.json +3 -3
- package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.html +1 -1
- package/dist/web/standalone/.next/server/app/index.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app-paths-manifest.json +9 -9
- package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
- package/dist/web/standalone/.next/server/middleware-manifest.json +5 -5
- package/dist/web/standalone/.next/server/pages/404.html +1 -1
- package/dist/web/standalone/.next/server/pages/500.html +1 -1
- package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
- package/package.json +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.js +36 -5
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js +30 -12
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/tool-execution.test.ts +49 -3
- package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +48 -9
- package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
- package/src/resources/extensions/gsd/auto/session.ts +7 -0
- package/src/resources/extensions/gsd/auto-post-unit.ts +81 -0
- package/src/resources/extensions/gsd/auto-prompts.ts +59 -7
- package/src/resources/extensions/gsd/auto-start.ts +64 -2
- package/src/resources/extensions/gsd/auto.ts +37 -0
- package/src/resources/extensions/gsd/context-store.ts +25 -8
- package/src/resources/extensions/gsd/forensics.ts +118 -1
- package/src/resources/extensions/gsd/git-service.ts +16 -0
- package/src/resources/extensions/gsd/journal.ts +11 -1
- package/src/resources/extensions/gsd/preferences-validation.ts +21 -0
- package/src/resources/extensions/gsd/prompt-cache-optimizer.ts +4 -0
- package/src/resources/extensions/gsd/slice-cadence.ts +299 -0
- package/src/resources/extensions/gsd/tests/artifacts-table-preserved-on-cache-invalidate.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/auto-loop.test.ts +5 -8
- package/src/resources/extensions/gsd/tests/auto-remediate-slice-status.test.ts +4 -1
- package/src/resources/extensions/gsd/tests/auto-retry-mcp-churn-fixes.test.ts +12 -9
- package/src/resources/extensions/gsd/tests/auto-start-clean-runtime-db-gated.test.ts +3 -2
- package/src/resources/extensions/gsd/tests/auto-start-cold-db-bootstrap.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/auto-start-model-capture.test.ts +4 -3
- package/src/resources/extensions/gsd/tests/auto-start-worktree-db-path.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/auto-thinking-restore.test.ts +3 -2
- package/src/resources/extensions/gsd/tests/auto-warning-noise-regression.test.ts +3 -2
- package/src/resources/extensions/gsd/tests/bootstrap-derive-state-db-open.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/canonical-milestone-root.test.ts +108 -0
- package/src/resources/extensions/gsd/tests/complete-slice-verification-gate.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/context-store.test.ts +79 -0
- package/src/resources/extensions/gsd/tests/copy-planning-artifacts-samepath.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/discuss-slice-structured-questions.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/discuss-tool-scope-leak.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/double-merge-guard.test.ts +4 -3
- package/src/resources/extensions/gsd/tests/empty-content-abort-loop.test.ts +4 -3
- package/src/resources/extensions/gsd/tests/finalize-timeout-guard.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/forensics-hook-key-parse.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/forensics-worktree-telemetry.test.ts +145 -0
- package/src/resources/extensions/gsd/tests/idle-watchdog-stall-override.test.ts +6 -1
- package/src/resources/extensions/gsd/tests/import-done-milestones.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/integration/all-milestones-complete-merge.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/interactive-routing-bypass.test.ts +9 -3
- package/src/resources/extensions/gsd/tests/knowledge.test.ts +93 -1
- package/src/resources/extensions/gsd/tests/merge-conflict-stops-loop.test.ts +10 -3
- package/src/resources/extensions/gsd/tests/native-git-bridge-exec-fallback.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/orphaned-worktree-audit.test.ts +59 -2
- package/src/resources/extensions/gsd/tests/parallel-research-dispatch.test.ts +4 -1
- package/src/resources/extensions/gsd/tests/preferences-worktree-sync.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/prompt-cache-optimizer.test.ts +12 -0
- package/src/resources/extensions/gsd/tests/prompt-step-ordering.test.ts +15 -4
- package/src/resources/extensions/gsd/tests/queue-draft-detection.test.ts +3 -2
- package/src/resources/extensions/gsd/tests/queued-discuss-fast-path.test.ts +4 -5
- package/src/resources/extensions/gsd/tests/restore-tools-after-discuss.test.ts +6 -3
- package/src/resources/extensions/gsd/tests/sidecar-queue.test.ts +3 -2
- package/src/resources/extensions/gsd/tests/slice-cadence.test.ts +242 -0
- package/src/resources/extensions/gsd/tests/slice-context-injection.test.ts +3 -2
- package/src/resources/extensions/gsd/tests/smart-entry-draft.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/stop-auto-race-null-unit.test.ts +3 -3
- package/src/resources/extensions/gsd/tests/subagent-model-dispatch.test.ts +7 -6
- package/src/resources/extensions/gsd/tests/sync-worktree-skip-current.test.ts +4 -3
- package/src/resources/extensions/gsd/tests/test-helpers.test.ts +147 -0
- package/src/resources/extensions/gsd/tests/test-helpers.ts +140 -0
- package/src/resources/extensions/gsd/tests/token-profile.test.ts +8 -1
- package/src/resources/extensions/gsd/tests/verify-artifact-tightened.test.ts +6 -5
- package/src/resources/extensions/gsd/tests/worktree-health-monorepo.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/worktree-nested-git-safety.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/worktree-submodule-safety.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/worktree-telemetry.test.ts +210 -0
- package/src/resources/extensions/gsd/tests/zombie-gsd-state.test.ts +3 -3
- package/src/resources/extensions/gsd/tools/validate-milestone.ts +8 -2
- package/src/resources/extensions/gsd/worktree-manager.ts +53 -0
- package/src/resources/extensions/gsd/worktree-resolver.ts +96 -9
- package/src/resources/extensions/gsd/worktree-telemetry.ts +322 -0
- /package/dist/web/standalone/.next/static/{vidAVJkURvTJ0_V2-64ro → Cev5xrAYA3ZGTRLyjR2fX}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{vidAVJkURvTJ0_V2-64ro → Cev5xrAYA3ZGTRLyjR2fX}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Worktree telemetry — #4764
|
|
3
|
+
*
|
|
4
|
+
* Thin emit helpers + aggregator on top of the existing journal. Separate
|
|
5
|
+
* module so callers import a tiny surface and don't have to assemble
|
|
6
|
+
* JournalEntry records by hand. Kernighan: the underlying emit path
|
|
7
|
+
* (emitJournalEvent) is already battle-tested; this module is just
|
|
8
|
+
* structured call sites + a summarizer.
|
|
9
|
+
*
|
|
10
|
+
* Emitted event types (see journal.ts):
|
|
11
|
+
* - worktree-created worktree entered/created for a milestone
|
|
12
|
+
* - worktree-merged worktree merge back to main completed
|
|
13
|
+
* - worktree-orphaned audit detected an orphaned branch/worktree
|
|
14
|
+
* - auto-exit auto-mode exited (pause/stop/blocked/error)
|
|
15
|
+
* - worktree-sync syncStateToProjectRoot snapshot
|
|
16
|
+
* - canonical-root-redirect resolveCanonicalMilestoneRoot redirected
|
|
17
|
+
*
|
|
18
|
+
* These events are purely observational. They never block, never throw,
|
|
19
|
+
* and never carry code content — only IDs, counts, durations, and reasons.
|
|
20
|
+
*/
|
|
21
|
+
import { randomUUID } from "node:crypto";
|
|
22
|
+
import { emitJournalEvent, queryJournal } from "./journal.js";
|
|
23
|
+
function now() {
|
|
24
|
+
return new Date().toISOString();
|
|
25
|
+
}
|
|
26
|
+
function baseEntry(eventType, data) {
|
|
27
|
+
return {
|
|
28
|
+
ts: now(),
|
|
29
|
+
flowId: (typeof data.flowId === "string" ? data.flowId : undefined) ?? randomUUID(),
|
|
30
|
+
seq: typeof data.seq === "number" ? data.seq : 0,
|
|
31
|
+
eventType,
|
|
32
|
+
data,
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
// ─── Emitters ────────────────────────────────────────────────────────────
|
|
36
|
+
export function emitWorktreeCreated(projectRoot, milestoneId, meta = {}) {
|
|
37
|
+
emitJournalEvent(projectRoot, baseEntry("worktree-created", {
|
|
38
|
+
milestoneId,
|
|
39
|
+
startedAt: now(),
|
|
40
|
+
flowId: meta.flowId,
|
|
41
|
+
reason: meta.reason ?? "enter-milestone",
|
|
42
|
+
}));
|
|
43
|
+
}
|
|
44
|
+
export function emitWorktreeMerged(projectRoot, milestoneId, meta = {}) {
|
|
45
|
+
emitJournalEvent(projectRoot, baseEntry("worktree-merged", {
|
|
46
|
+
milestoneId,
|
|
47
|
+
endedAt: now(),
|
|
48
|
+
flowId: meta.flowId,
|
|
49
|
+
reason: meta.reason ?? "other",
|
|
50
|
+
startedAt: meta.startedAt,
|
|
51
|
+
durationMs: meta.durationMs,
|
|
52
|
+
sliceCount: meta.sliceCount,
|
|
53
|
+
taskCount: meta.taskCount,
|
|
54
|
+
conflict: meta.conflict ?? false,
|
|
55
|
+
conflictedFiles: meta.conflictedFiles ?? 0,
|
|
56
|
+
}));
|
|
57
|
+
}
|
|
58
|
+
export function emitWorktreeOrphaned(projectRoot, milestoneId, meta) {
|
|
59
|
+
emitJournalEvent(projectRoot, baseEntry("worktree-orphaned", {
|
|
60
|
+
milestoneId,
|
|
61
|
+
flowId: meta.flowId,
|
|
62
|
+
reason: meta.reason,
|
|
63
|
+
commitsAhead: meta.commitsAhead,
|
|
64
|
+
worktreeDirExists: meta.worktreeDirExists ?? false,
|
|
65
|
+
detectedAt: now(),
|
|
66
|
+
}));
|
|
67
|
+
}
|
|
68
|
+
export function emitAutoExit(projectRoot, meta) {
|
|
69
|
+
emitJournalEvent(projectRoot, baseEntry("auto-exit", {
|
|
70
|
+
reason: meta.reason,
|
|
71
|
+
flowId: meta.flowId,
|
|
72
|
+
milestoneId: meta.milestoneId,
|
|
73
|
+
milestoneMerged: meta.milestoneMerged,
|
|
74
|
+
exitedAt: now(),
|
|
75
|
+
}));
|
|
76
|
+
}
|
|
77
|
+
export function emitWorktreeSync(projectRoot, milestoneId, meta) {
|
|
78
|
+
emitJournalEvent(projectRoot, baseEntry("worktree-sync", {
|
|
79
|
+
milestoneId,
|
|
80
|
+
flowId: meta.flowId,
|
|
81
|
+
filesCopied: meta.filesCopied,
|
|
82
|
+
bytesCopied: meta.bytesCopied,
|
|
83
|
+
commitsAhead: meta.commitsAhead,
|
|
84
|
+
worktreeAgeMs: meta.worktreeAgeMs,
|
|
85
|
+
}));
|
|
86
|
+
}
|
|
87
|
+
export function emitCanonicalRootRedirect(projectRoot, milestoneId, redirectedTo, meta = {}) {
|
|
88
|
+
emitJournalEvent(projectRoot, baseEntry("canonical-root-redirect", {
|
|
89
|
+
milestoneId,
|
|
90
|
+
redirectedTo,
|
|
91
|
+
flowId: meta.flowId,
|
|
92
|
+
}));
|
|
93
|
+
}
|
|
94
|
+
// #4765 — slice-cadence collapse events
|
|
95
|
+
export function emitSliceMerged(projectRoot, milestoneId, sliceId, meta = {}) {
|
|
96
|
+
emitJournalEvent(projectRoot, baseEntry("slice-merged", {
|
|
97
|
+
milestoneId,
|
|
98
|
+
sliceId,
|
|
99
|
+
mergedAt: now(),
|
|
100
|
+
durationMs: meta.durationMs,
|
|
101
|
+
conflict: meta.conflict ?? false,
|
|
102
|
+
commitSha: meta.commitSha,
|
|
103
|
+
flowId: meta.flowId,
|
|
104
|
+
}));
|
|
105
|
+
}
|
|
106
|
+
export function emitMilestoneResquash(projectRoot, milestoneId, meta = { sliceCount: 0 }) {
|
|
107
|
+
emitJournalEvent(projectRoot, baseEntry("milestone-resquash", {
|
|
108
|
+
milestoneId,
|
|
109
|
+
sliceCount: meta.sliceCount,
|
|
110
|
+
startSha: meta.startSha,
|
|
111
|
+
endSha: meta.endSha,
|
|
112
|
+
resquashedAt: now(),
|
|
113
|
+
flowId: meta.flowId,
|
|
114
|
+
}));
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Summarize worktree telemetry across the journal. Optional time window
|
|
118
|
+
* via filters.after / filters.before (ISO-8601).
|
|
119
|
+
*/
|
|
120
|
+
export function summarizeWorktreeTelemetry(projectRoot, filters) {
|
|
121
|
+
const entries = queryJournal(projectRoot, filters);
|
|
122
|
+
const summary = {
|
|
123
|
+
worktreesCreated: 0,
|
|
124
|
+
worktreesMerged: 0,
|
|
125
|
+
orphansDetected: 0,
|
|
126
|
+
orphansByReason: {},
|
|
127
|
+
mergeDurationsMs: [],
|
|
128
|
+
mergeConflicts: 0,
|
|
129
|
+
exitsByReason: {},
|
|
130
|
+
exitsWithUnmergedWork: 0,
|
|
131
|
+
canonicalRedirects: 0,
|
|
132
|
+
slicesMerged: 0,
|
|
133
|
+
sliceMergeConflicts: 0,
|
|
134
|
+
milestoneResquashes: 0,
|
|
135
|
+
};
|
|
136
|
+
for (const e of entries) {
|
|
137
|
+
const d = e.data ?? {};
|
|
138
|
+
switch (e.eventType) {
|
|
139
|
+
case "worktree-created":
|
|
140
|
+
summary.worktreesCreated++;
|
|
141
|
+
break;
|
|
142
|
+
case "worktree-merged":
|
|
143
|
+
summary.worktreesMerged++;
|
|
144
|
+
if (typeof d.durationMs === "number")
|
|
145
|
+
summary.mergeDurationsMs.push(d.durationMs);
|
|
146
|
+
if (d.conflict === true)
|
|
147
|
+
summary.mergeConflicts++;
|
|
148
|
+
break;
|
|
149
|
+
case "worktree-orphaned": {
|
|
150
|
+
summary.orphansDetected++;
|
|
151
|
+
const reason = typeof d.reason === "string" ? d.reason : "unknown";
|
|
152
|
+
summary.orphansByReason[reason] = (summary.orphansByReason[reason] ?? 0) + 1;
|
|
153
|
+
break;
|
|
154
|
+
}
|
|
155
|
+
case "auto-exit": {
|
|
156
|
+
const reason = typeof d.reason === "string" ? d.reason : "unknown";
|
|
157
|
+
summary.exitsByReason[reason] = (summary.exitsByReason[reason] ?? 0) + 1;
|
|
158
|
+
if (d.milestoneMerged === false)
|
|
159
|
+
summary.exitsWithUnmergedWork++;
|
|
160
|
+
break;
|
|
161
|
+
}
|
|
162
|
+
case "canonical-root-redirect":
|
|
163
|
+
summary.canonicalRedirects++;
|
|
164
|
+
break;
|
|
165
|
+
case "slice-merged":
|
|
166
|
+
summary.slicesMerged++;
|
|
167
|
+
if (d.conflict === true)
|
|
168
|
+
summary.sliceMergeConflicts++;
|
|
169
|
+
break;
|
|
170
|
+
case "milestone-resquash":
|
|
171
|
+
summary.milestoneResquashes++;
|
|
172
|
+
break;
|
|
173
|
+
default:
|
|
174
|
+
break;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
summary.mergeDurationsMs.sort((a, b) => a - b);
|
|
178
|
+
return summary;
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Return the p{quantile} of a sorted array using the nearest-rank method.
|
|
182
|
+
* Quantile in [0,1].
|
|
183
|
+
*
|
|
184
|
+
* Prior implementation used Math.floor(q*n), which overstates exact-rank
|
|
185
|
+
* quantiles by one sample (e.g. p95 of 20 values returned the max instead
|
|
186
|
+
* of the 19th value). The nearest-rank index is ceil(q*n) - 1, clamped to
|
|
187
|
+
* [0, n-1].
|
|
188
|
+
*/
|
|
189
|
+
export function percentile(sortedValues, q) {
|
|
190
|
+
if (sortedValues.length === 0)
|
|
191
|
+
return null;
|
|
192
|
+
if (q <= 0)
|
|
193
|
+
return sortedValues[0];
|
|
194
|
+
if (q >= 1)
|
|
195
|
+
return sortedValues[sortedValues.length - 1];
|
|
196
|
+
const idx = Math.min(sortedValues.length - 1, Math.max(0, Math.ceil(q * sortedValues.length) - 1));
|
|
197
|
+
return sortedValues[idx];
|
|
198
|
+
}
|