@astralyn/pi 0.84.1 → 0.84.3
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/CHANGELOG.md +25 -1
- package/dist/cli/args.js +1 -1
- package/dist/cli/args.js.map +1 -1
- package/dist/cli/config-selector.d.ts.map +1 -1
- package/dist/cli/config-selector.js +2 -3
- package/dist/cli/config-selector.js.map +1 -1
- package/dist/cli/startup-ui.d.ts.map +1 -1
- package/dist/cli/startup-ui.js +3 -5
- package/dist/cli/startup-ui.js.map +1 -1
- package/dist/config.d.ts +5 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +8 -1
- package/dist/config.js.map +1 -1
- package/dist/core/agent-session.d.ts +1 -25
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +29 -408
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/compaction-controller.d.ts +89 -0
- package/dist/core/compaction-controller.d.ts.map +1 -0
- package/dist/core/compaction-controller.js +428 -0
- package/dist/core/compaction-controller.js.map +1 -0
- package/dist/core/extensions/index.d.ts +1 -1
- package/dist/core/extensions/index.d.ts.map +1 -1
- package/dist/core/extensions/index.js.map +1 -1
- package/dist/core/extensions/loader.js +3 -3
- package/dist/core/extensions/loader.js.map +1 -1
- package/dist/core/extensions/types.d.ts +1 -15
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/provider-attribution.js +2 -2
- package/dist/core/provider-attribution.js.map +1 -1
- package/dist/core/settings-manager.js +1 -1
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/telemetry.d.ts +1 -1
- package/dist/core/telemetry.d.ts.map +1 -1
- package/dist/core/telemetry.js +1 -1
- package/dist/core/telemetry.js.map +1 -1
- package/dist/extensions/deepwiki/index.d.ts.map +1 -1
- package/dist/extensions/deepwiki/index.js +23 -1
- package/dist/extensions/deepwiki/index.js.map +1 -1
- package/dist/extensions/deepwiki/render.d.ts +1 -1
- package/dist/extensions/deepwiki/render.d.ts.map +1 -1
- package/dist/extensions/deepwiki/render.js +4 -2
- package/dist/extensions/deepwiki/render.js.map +1 -1
- package/dist/extensions/index.d.ts.map +1 -1
- package/dist/extensions/index.js +0 -4
- package/dist/extensions/index.js.map +1 -1
- package/dist/extensions/question/index.d.ts.map +1 -1
- package/dist/extensions/question/index.js +0 -1
- package/dist/extensions/question/index.js.map +1 -1
- package/dist/extensions/subagent/index.d.ts.map +1 -1
- package/dist/extensions/subagent/index.js +20 -2
- package/dist/extensions/subagent/index.js.map +1 -1
- package/dist/extensions/todo/schema.d.ts +1 -1
- package/dist/extensions/todo/state.js +5 -5
- package/dist/extensions/todo/state.js.map +1 -1
- package/dist/modes/interactive/components/extension-selector.d.ts +0 -2
- package/dist/modes/interactive/components/extension-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/extension-selector.js +1 -1
- package/dist/modes/interactive/components/extension-selector.js.map +1 -1
- package/dist/modes/interactive/components/settings-selector.js +1 -1
- package/dist/modes/interactive/components/settings-selector.js.map +1 -1
- package/dist/modes/interactive/components/tool-chrome.d.ts +28 -0
- package/dist/modes/interactive/components/tool-chrome.d.ts.map +1 -0
- package/dist/modes/interactive/components/tool-chrome.js +81 -0
- package/dist/modes/interactive/components/tool-chrome.js.map +1 -0
- package/dist/modes/interactive/components/tool-execution.d.ts +0 -3
- package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/dist/modes/interactive/components/tool-execution.js +11 -108
- package/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +35 -52
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/docs/bundled/README.md +0 -2
- package/docs/bundled/extensions/subagent.md +1 -1
- package/docs/bundled/tool-presentation.md +2 -2
- package/docs/docs.json +0 -8
- package/docs/extensions.md +6 -23
- package/docs/settings.md +1 -1
- package/docs/usage.md +1 -2
- package/examples/extensions/README.md +2 -0
- package/examples/extensions/plan-mode/README.md +66 -0
- package/examples/extensions/plan-mode/index.ts +390 -0
- package/examples/extensions/plan-mode/utils.ts +168 -0
- package/examples/extensions/subagent/README.md +175 -0
- package/examples/extensions/subagent/agents/planner.md +37 -0
- package/examples/extensions/subagent/agents/reviewer.md +35 -0
- package/examples/extensions/subagent/agents/scout.md +50 -0
- package/examples/extensions/subagent/agents/worker.md +24 -0
- package/examples/extensions/subagent/agents.ts +126 -0
- package/examples/extensions/subagent/index.ts +1009 -0
- package/examples/extensions/subagent/prompts/implement-and-review.md +10 -0
- package/examples/extensions/subagent/prompts/implement.md +10 -0
- package/examples/extensions/subagent/prompts/scout-and-plan.md +9 -0
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
- package/dist/extensions/biu/index.d.ts +0 -19
- package/dist/extensions/biu/index.d.ts.map +0 -1
- package/dist/extensions/biu/index.js +0 -350
- package/dist/extensions/biu/index.js.map +0 -1
- package/dist/extensions/biu/prompts.d.ts +0 -26
- package/dist/extensions/biu/prompts.d.ts.map +0 -1
- package/dist/extensions/biu/prompts.js +0 -260
- package/dist/extensions/biu/prompts.js.map +0 -1
- package/dist/extensions/biu/workspace.d.ts +0 -122
- package/dist/extensions/biu/workspace.d.ts.map +0 -1
- package/dist/extensions/biu/workspace.js +0 -404
- package/dist/extensions/biu/workspace.js.map +0 -1
- package/dist/extensions/rewind/anchor.d.ts +0 -29
- package/dist/extensions/rewind/anchor.d.ts.map +0 -1
- package/dist/extensions/rewind/anchor.js +0 -35
- package/dist/extensions/rewind/anchor.js.map +0 -1
- package/dist/extensions/rewind/config.d.ts +0 -16
- package/dist/extensions/rewind/config.d.ts.map +0 -1
- package/dist/extensions/rewind/config.js +0 -69
- package/dist/extensions/rewind/config.js.map +0 -1
- package/dist/extensions/rewind/engine.d.ts +0 -93
- package/dist/extensions/rewind/engine.d.ts.map +0 -1
- package/dist/extensions/rewind/engine.js +0 -778
- package/dist/extensions/rewind/engine.js.map +0 -1
- package/dist/extensions/rewind/gc.d.ts +0 -35
- package/dist/extensions/rewind/gc.d.ts.map +0 -1
- package/dist/extensions/rewind/gc.js +0 -169
- package/dist/extensions/rewind/gc.js.map +0 -1
- package/dist/extensions/rewind/index.d.ts +0 -3
- package/dist/extensions/rewind/index.d.ts.map +0 -1
- package/dist/extensions/rewind/index.js +0 -287
- package/dist/extensions/rewind/index.js.map +0 -1
- package/dist/extensions/rewind/menu.d.ts +0 -13
- package/dist/extensions/rewind/menu.d.ts.map +0 -1
- package/dist/extensions/rewind/menu.js +0 -123
- package/dist/extensions/rewind/menu.js.map +0 -1
- package/dist/extensions/rewind/paths.d.ts +0 -4
- package/dist/extensions/rewind/paths.d.ts.map +0 -1
- package/dist/extensions/rewind/paths.js +0 -15
- package/dist/extensions/rewind/paths.js.map +0 -1
- package/dist/extensions/rewind/restore.d.ts +0 -54
- package/dist/extensions/rewind/restore.d.ts.map +0 -1
- package/dist/extensions/rewind/restore.js +0 -94
- package/dist/extensions/rewind/restore.js.map +0 -1
- package/dist/extensions/rewind/snapshot.d.ts +0 -45
- package/dist/extensions/rewind/snapshot.d.ts.map +0 -1
- package/dist/extensions/rewind/snapshot.js +0 -21
- package/dist/extensions/rewind/snapshot.js.map +0 -1
- package/dist/extensions/rewind/storage.d.ts +0 -12
- package/dist/extensions/rewind/storage.d.ts.map +0 -1
- package/dist/extensions/rewind/storage.js +0 -33
- package/dist/extensions/rewind/storage.js.map +0 -1
- package/dist/extensions/rewind/text.d.ts +0 -7
- package/dist/extensions/rewind/text.d.ts.map +0 -1
- package/dist/extensions/rewind/text.js +0 -19
- package/dist/extensions/rewind/text.js.map +0 -1
- package/dist/extensions/rewind/tool-path.d.ts +0 -3
- package/dist/extensions/rewind/tool-path.d.ts.map +0 -1
- package/dist/extensions/rewind/tool-path.js +0 -9
- package/dist/extensions/rewind/tool-path.js.map +0 -1
- package/dist/utils/coalescing-terminal.d.ts +0 -132
- package/dist/utils/coalescing-terminal.d.ts.map +0 -1
- package/dist/utils/coalescing-terminal.js +0 -292
- package/dist/utils/coalescing-terminal.js.map +0 -1
- package/docs/bundled/extensions/biu.md +0 -63
- package/docs/bundled/extensions/rewind.md +0 -86
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* restore.ts — map a /tree navigation target to the snapshot that should be
|
|
3
|
-
* restored and apply it via the engine.
|
|
4
|
-
*
|
|
5
|
-
* Snapshot semantics: a frame anchored at user entry U records the work tree
|
|
6
|
-
* at the moment U's run STARTED (see engine.ts beginTurn). The selection here
|
|
7
|
-
* must mirror AgentSession.navigateTree's leaf rules:
|
|
8
|
-
*
|
|
9
|
-
* - user / custom_message target: navigateTree removes the target's turn
|
|
10
|
-
* from the branch (leaf = parent, text returns to the editor) → restore
|
|
11
|
-
* to the state BEFORE that turn = the snapshot anchored at the target.
|
|
12
|
-
* - any other target: the target's turn STAYS in the conversation
|
|
13
|
-
* (leaf = target) → restore to the state AFTER that turn = the first
|
|
14
|
-
* chronological snapshot anchored at a descendant turn (it recorded the
|
|
15
|
-
* work tree when the next run began). No such snapshot → nothing was
|
|
16
|
-
* recorded after the target, so offer no restore at all — falling back to
|
|
17
|
-
* an ancestor frame would roll back the target turn's own edits and leave
|
|
18
|
-
* the work tree older than the conversation.
|
|
19
|
-
*/
|
|
20
|
-
import { applySnapshot, collectChangeDiffStats, collectChanges, } from "./engine.js";
|
|
21
|
-
/** Cycle guard for parent-chain walks (ids are acyclic in practice). */
|
|
22
|
-
const ANCESTOR_WALK_GUARD = 100_000;
|
|
23
|
-
/** True when `id`'s parent chain passes through `ancestorId` (strict descent). */
|
|
24
|
-
function isDescendantOf(view, id, ancestorId) {
|
|
25
|
-
let cur = view.getEntry(id)?.parentId ?? null;
|
|
26
|
-
let guard = 0;
|
|
27
|
-
while (cur !== null && guard++ < ANCESTOR_WALK_GUARD) {
|
|
28
|
-
if (cur === ancestorId)
|
|
29
|
-
return true;
|
|
30
|
-
cur = view.getEntry(cur)?.parentId ?? null;
|
|
31
|
-
}
|
|
32
|
-
return false;
|
|
33
|
-
}
|
|
34
|
-
/**
|
|
35
|
-
* First (chronological) snapshot anchored at a strict descendant of `entryId`
|
|
36
|
-
* — the run that started right after `entryId` existed, so its frame records
|
|
37
|
-
* the work tree state "just after" the entry.
|
|
38
|
-
*/
|
|
39
|
-
function snapshotAfterEntry(snapshots, view, entryId) {
|
|
40
|
-
for (const snap of snapshots) {
|
|
41
|
-
if (!snap.userEntryId)
|
|
42
|
-
continue;
|
|
43
|
-
if (isDescendantOf(view, snap.userEntryId, entryId))
|
|
44
|
-
return snap;
|
|
45
|
-
}
|
|
46
|
-
return undefined;
|
|
47
|
-
}
|
|
48
|
-
/**
|
|
49
|
-
* The snapshot that matches navigating to `targetId`, per the rules in the
|
|
50
|
-
* module header. Undefined when no recorded state corresponds to the target
|
|
51
|
-
* (then the work tree should be left alone).
|
|
52
|
-
*/
|
|
53
|
-
export function snapshotForEntry(snapshots, view, targetId) {
|
|
54
|
-
const target = view.getEntry(targetId);
|
|
55
|
-
if (!target)
|
|
56
|
-
return undefined;
|
|
57
|
-
if (target.isTurnAnchor) {
|
|
58
|
-
// Exact anchor match: the frame recording the state right before this
|
|
59
|
-
// turn ran. Chronologically last wins if duplicate anchors exist.
|
|
60
|
-
let exact;
|
|
61
|
-
for (const snap of snapshots) {
|
|
62
|
-
if (snap.userEntryId === targetId)
|
|
63
|
-
exact = snap;
|
|
64
|
-
}
|
|
65
|
-
if (exact)
|
|
66
|
-
return exact;
|
|
67
|
-
// No frame for this turn (it recorded no changes): the state before it
|
|
68
|
-
// equals the state after its parent.
|
|
69
|
-
return target.parentId === null ? undefined : snapshotAfterEntry(snapshots, view, target.parentId);
|
|
70
|
-
}
|
|
71
|
-
return snapshotAfterEntry(snapshots, view, targetId);
|
|
72
|
-
}
|
|
73
|
-
/**
|
|
74
|
-
* Absolute file paths restoring to this snapshot would change on disk (empty =
|
|
75
|
-
* none). Callers use the length for the count and the paths for the preview.
|
|
76
|
-
*/
|
|
77
|
-
export function snapshotChangedPaths(sessionId, snapshot) {
|
|
78
|
-
return collectChanges(sessionId, snapshot);
|
|
79
|
-
}
|
|
80
|
-
/**
|
|
81
|
-
* Coarse +N/−M line stats for the confirm dialog (paths must already be known
|
|
82
|
-
* changed — typically from snapshotChangedPaths).
|
|
83
|
-
*/
|
|
84
|
-
export function snapshotChangeDiffStats(sessionId, snapshot, changedPaths) {
|
|
85
|
-
return collectChangeDiffStats(sessionId, snapshot, changedPaths);
|
|
86
|
-
}
|
|
87
|
-
/**
|
|
88
|
-
* Restore the work tree to `snapshot` and return changed absolute paths.
|
|
89
|
-
* Pass `onlyPaths` from a prior snapshotChangedPaths call to skip re-compare.
|
|
90
|
-
*/
|
|
91
|
-
export async function restoreToSnapshot(sessionId, snapshot, opts) {
|
|
92
|
-
return applySnapshot(sessionId, snapshot, opts);
|
|
93
|
-
}
|
|
94
|
-
//# sourceMappingURL=restore.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"restore.js","sourceRoot":"","sources":["../../../src/extensions/rewind/restore.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,EAEN,aAAa,EAEb,sBAAsB,EACtB,cAAc,GACd,MAAM,aAAa,CAAC;AAgBrB,wEAAwE;AACxE,MAAM,mBAAmB,GAAG,OAAO,CAAC;AAEpC,kFAAkF;AAClF,SAAS,cAAc,CAAC,IAAmB,EAAE,EAAU,EAAE,UAAkB;IAC1E,IAAI,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,QAAQ,IAAI,IAAI,CAAC;IAC9C,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,OAAO,GAAG,KAAK,IAAI,IAAI,KAAK,EAAE,GAAG,mBAAmB,EAAE,CAAC;QACtD,IAAI,GAAG,KAAK,UAAU;YAAE,OAAO,IAAI,CAAC;QACpC,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,QAAQ,IAAI,IAAI,CAAC;IAC5C,CAAC;IACD,OAAO,KAAK,CAAC;AACd,CAAC;AAED;;;;GAIG;AACH,SAAS,kBAAkB,CAC1B,SAAgC,EAChC,IAAmB,EACnB,OAAe;IAEf,KAAK,MAAM,IAAI,IAAI,SAAS,EAAE,CAAC;QAC9B,IAAI,CAAC,IAAI,CAAC,WAAW;YAAE,SAAS;QAChC,IAAI,cAAc,CAAC,IAAI,EAAE,IAAI,CAAC,WAAW,EAAE,OAAO,CAAC;YAAE,OAAO,IAAI,CAAC;IAClE,CAAC;IACD,OAAO,SAAS,CAAC;AAClB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,gBAAgB,CAC/B,SAAgC,EAChC,IAAmB,EACnB,QAAgB;IAEhB,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IACvC,IAAI,CAAC,MAAM;QAAE,OAAO,SAAS,CAAC;IAE9B,IAAI,MAAM,CAAC,YAAY,EAAE,CAAC;QACzB,sEAAsE;QACtE,kEAAkE;QAClE,IAAI,KAAsC,CAAC;QAC3C,KAAK,MAAM,IAAI,IAAI,SAAS,EAAE,CAAC;YAC9B,IAAI,IAAI,CAAC,WAAW,KAAK,QAAQ;gBAAE,KAAK,GAAG,IAAI,CAAC;QACjD,CAAC;QACD,IAAI,KAAK;YAAE,OAAO,KAAK,CAAC;QACxB,uEAAuE;QACvE,qCAAqC;QACrC,OAAO,MAAM,CAAC,QAAQ,KAAK,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,kBAAkB,CAAC,SAAS,EAAE,IAAI,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC;IACpG,CAAC;IAED,OAAO,kBAAkB,CAAC,SAAS,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC;AACtD,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,oBAAoB,CAAC,SAAiB,EAAE,QAA6B;IACpF,OAAO,cAAc,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;AAC5C,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,uBAAuB,CACtC,SAAiB,EACjB,QAA6B,EAC7B,YAA+B;IAE/B,OAAO,sBAAsB,CAAC,SAAS,EAAE,QAAQ,EAAE,YAAY,CAAC,CAAC;AAClE,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACtC,SAAiB,EACjB,QAA6B,EAC7B,IAA2B;IAE3B,OAAO,aAAa,CAAC,SAAS,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC;AACjD,CAAC","sourcesContent":["/**\n * restore.ts — map a /tree navigation target to the snapshot that should be\n * restored and apply it via the engine.\n *\n * Snapshot semantics: a frame anchored at user entry U records the work tree\n * at the moment U's run STARTED (see engine.ts beginTurn). The selection here\n * must mirror AgentSession.navigateTree's leaf rules:\n *\n * - user / custom_message target: navigateTree removes the target's turn\n * from the branch (leaf = parent, text returns to the editor) → restore\n * to the state BEFORE that turn = the snapshot anchored at the target.\n * - any other target: the target's turn STAYS in the conversation\n * (leaf = target) → restore to the state AFTER that turn = the first\n * chronological snapshot anchored at a descendant turn (it recorded the\n * work tree when the next run began). No such snapshot → nothing was\n * recorded after the target, so offer no restore at all — falling back to\n * an ancestor frame would roll back the target turn's own edits and leave\n * the work tree older than the conversation.\n */\nimport {\n\ttype ApplySnapshotOptions,\n\tapplySnapshot,\n\ttype CoarseDiffStats,\n\tcollectChangeDiffStats,\n\tcollectChanges,\n} from \"./engine.ts\";\nimport type { FileHistorySnapshot } from \"./snapshot.ts\";\n\n/** Minimal per-entry view needed to walk the tree and classify targets. */\nexport interface EntryView {\n\tid: string;\n\tparentId: string | null;\n\t/** True for entries navigateTree treats as turn starts (user / custom_message → leaf = parent). */\n\tisTurnAnchor: boolean;\n}\n\n/** Minimal session view we need to walk the entry tree. */\nexport interface EntryTreeView {\n\tgetEntry(id: string): EntryView | undefined;\n}\n\n/** Cycle guard for parent-chain walks (ids are acyclic in practice). */\nconst ANCESTOR_WALK_GUARD = 100_000;\n\n/** True when `id`'s parent chain passes through `ancestorId` (strict descent). */\nfunction isDescendantOf(view: EntryTreeView, id: string, ancestorId: string): boolean {\n\tlet cur = view.getEntry(id)?.parentId ?? null;\n\tlet guard = 0;\n\twhile (cur !== null && guard++ < ANCESTOR_WALK_GUARD) {\n\t\tif (cur === ancestorId) return true;\n\t\tcur = view.getEntry(cur)?.parentId ?? null;\n\t}\n\treturn false;\n}\n\n/**\n * First (chronological) snapshot anchored at a strict descendant of `entryId`\n * — the run that started right after `entryId` existed, so its frame records\n * the work tree state \"just after\" the entry.\n */\nfunction snapshotAfterEntry(\n\tsnapshots: FileHistorySnapshot[],\n\tview: EntryTreeView,\n\tentryId: string,\n): FileHistorySnapshot | undefined {\n\tfor (const snap of snapshots) {\n\t\tif (!snap.userEntryId) continue;\n\t\tif (isDescendantOf(view, snap.userEntryId, entryId)) return snap;\n\t}\n\treturn undefined;\n}\n\n/**\n * The snapshot that matches navigating to `targetId`, per the rules in the\n * module header. Undefined when no recorded state corresponds to the target\n * (then the work tree should be left alone).\n */\nexport function snapshotForEntry(\n\tsnapshots: FileHistorySnapshot[],\n\tview: EntryTreeView,\n\ttargetId: string,\n): FileHistorySnapshot | undefined {\n\tconst target = view.getEntry(targetId);\n\tif (!target) return undefined;\n\n\tif (target.isTurnAnchor) {\n\t\t// Exact anchor match: the frame recording the state right before this\n\t\t// turn ran. Chronologically last wins if duplicate anchors exist.\n\t\tlet exact: FileHistorySnapshot | undefined;\n\t\tfor (const snap of snapshots) {\n\t\t\tif (snap.userEntryId === targetId) exact = snap;\n\t\t}\n\t\tif (exact) return exact;\n\t\t// No frame for this turn (it recorded no changes): the state before it\n\t\t// equals the state after its parent.\n\t\treturn target.parentId === null ? undefined : snapshotAfterEntry(snapshots, view, target.parentId);\n\t}\n\n\treturn snapshotAfterEntry(snapshots, view, targetId);\n}\n\n/**\n * Absolute file paths restoring to this snapshot would change on disk (empty =\n * none). Callers use the length for the count and the paths for the preview.\n */\nexport function snapshotChangedPaths(sessionId: string, snapshot: FileHistorySnapshot): Promise<string[]> {\n\treturn collectChanges(sessionId, snapshot);\n}\n\n/**\n * Coarse +N/−M line stats for the confirm dialog (paths must already be known\n * changed — typically from snapshotChangedPaths).\n */\nexport function snapshotChangeDiffStats(\n\tsessionId: string,\n\tsnapshot: FileHistorySnapshot,\n\tchangedPaths: readonly string[],\n): Promise<CoarseDiffStats> {\n\treturn collectChangeDiffStats(sessionId, snapshot, changedPaths);\n}\n\n/**\n * Restore the work tree to `snapshot` and return changed absolute paths.\n * Pass `onlyPaths` from a prior snapshotChangedPaths call to skip re-compare.\n */\nexport async function restoreToSnapshot(\n\tsessionId: string,\n\tsnapshot: FileHistorySnapshot,\n\topts?: ApplySnapshotOptions,\n): Promise<string[]> {\n\treturn applySnapshot(sessionId, snapshot, opts);\n}\n"]}
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* snapshot.ts — persisted data shapes for the rewind extension's file-history
|
|
3
|
-
* engine. Pure types + tiny helpers; no Pi imports, no side effects, so the
|
|
4
|
-
* engine and its selftests can import them under plain node.
|
|
5
|
-
*
|
|
6
|
-
* A FileHistorySnapshot is written to the session JSONL (via the integration
|
|
7
|
-
* layer's appendEntry, custom type "pi-rewind-snapshot"). It is never sent to
|
|
8
|
-
* the LLM and survives reload/compaction. Each snapshot anchors to one turn and
|
|
9
|
-
* records, for every tracked file, which backup blob holds that file's contents
|
|
10
|
-
* as of the start of the turn.
|
|
11
|
-
*/
|
|
12
|
-
/** Custom session-entry type used to persist snapshots to the session JSONL. */
|
|
13
|
-
export declare const SNAPSHOT_ENTRY_TYPE = "pi-rewind-snapshot";
|
|
14
|
-
/**
|
|
15
|
-
* One file's backup at a specific version.
|
|
16
|
-
* `backupName === null` means the file did not exist at this version — rewinding
|
|
17
|
-
* to a snapshot carrying a null backup deletes the file.
|
|
18
|
-
*/
|
|
19
|
-
export interface FileBackup {
|
|
20
|
-
/** Backup blob filename (`<sha256(relpath)[:16]>@v<n>`), or null if the file did not exist. */
|
|
21
|
-
backupName: string | null;
|
|
22
|
-
/** Monotonic version for this file within the session (1-based). */
|
|
23
|
-
version: number;
|
|
24
|
-
}
|
|
25
|
-
/**
|
|
26
|
-
* One turn's snapshot. `v` lets future readers migrate old entries.
|
|
27
|
-
* `trackedFileBackups` is keyed by the file's path *relative to cwd* when inside
|
|
28
|
-
* cwd (else the absolute path), matching the engine's path shortening.
|
|
29
|
-
*/
|
|
30
|
-
export interface FileHistorySnapshot {
|
|
31
|
-
v: 1;
|
|
32
|
-
/** Session entry id this snapshot anchors to (used to match /tree navigation). */
|
|
33
|
-
userEntryId: string;
|
|
34
|
-
/** Leaf/turn id when finalized (informational). */
|
|
35
|
-
turnId: string;
|
|
36
|
-
/** The user prompt that drove the turn (truncated; shown in the /tree sync prompt). */
|
|
37
|
-
prompt: string;
|
|
38
|
-
/** Map of tracking-path → the backup recorded for that file at the start of this turn. */
|
|
39
|
-
trackedFileBackups: Record<string, FileBackup>;
|
|
40
|
-
/** ISO timestamp the snapshot was finalized. */
|
|
41
|
-
timestamp: string;
|
|
42
|
-
}
|
|
43
|
-
/** Narrow an arbitrary session-entry payload to a FileHistorySnapshot. */
|
|
44
|
-
export declare function isSnapshot(data: unknown): data is FileHistorySnapshot;
|
|
45
|
-
//# sourceMappingURL=snapshot.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"snapshot.d.ts","sourceRoot":"","sources":["../../../src/extensions/rewind/snapshot.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,gFAAgF;AAChF,eAAO,MAAM,mBAAmB,uBAAuB,CAAC;AAExD;;;;GAIG;AACH,MAAM,WAAW,UAAU;IAC1B,+FAA+F;IAC/F,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,oEAAoE;IACpE,OAAO,EAAE,MAAM,CAAC;CAChB;AAED;;;;GAIG;AACH,MAAM,WAAW,mBAAmB;IACnC,CAAC,EAAE,CAAC,CAAC;IACL,kFAAkF;IAClF,WAAW,EAAE,MAAM,CAAC;IACpB,mDAAmD;IACnD,MAAM,EAAE,MAAM,CAAC;IACf,uFAAuF;IACvF,MAAM,EAAE,MAAM,CAAC;IACf,0FAA0F;IAC1F,kBAAkB,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IAC/C,gDAAgD;IAChD,SAAS,EAAE,MAAM,CAAC;CAClB;AAED,0EAA0E;AAC1E,wBAAgB,UAAU,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,IAAI,mBAAmB,CAMrE"}
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* snapshot.ts — persisted data shapes for the rewind extension's file-history
|
|
3
|
-
* engine. Pure types + tiny helpers; no Pi imports, no side effects, so the
|
|
4
|
-
* engine and its selftests can import them under plain node.
|
|
5
|
-
*
|
|
6
|
-
* A FileHistorySnapshot is written to the session JSONL (via the integration
|
|
7
|
-
* layer's appendEntry, custom type "pi-rewind-snapshot"). It is never sent to
|
|
8
|
-
* the LLM and survives reload/compaction. Each snapshot anchors to one turn and
|
|
9
|
-
* records, for every tracked file, which backup blob holds that file's contents
|
|
10
|
-
* as of the start of the turn.
|
|
11
|
-
*/
|
|
12
|
-
/** Custom session-entry type used to persist snapshots to the session JSONL. */
|
|
13
|
-
export const SNAPSHOT_ENTRY_TYPE = "pi-rewind-snapshot";
|
|
14
|
-
/** Narrow an arbitrary session-entry payload to a FileHistorySnapshot. */
|
|
15
|
-
export function isSnapshot(data) {
|
|
16
|
-
if (!data || typeof data !== "object")
|
|
17
|
-
return false;
|
|
18
|
-
const s = data;
|
|
19
|
-
return (typeof s.userEntryId === "string" && typeof s.trackedFileBackups === "object" && s.trackedFileBackups !== null);
|
|
20
|
-
}
|
|
21
|
-
//# sourceMappingURL=snapshot.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"snapshot.js","sourceRoot":"","sources":["../../../src/extensions/rewind/snapshot.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,gFAAgF;AAChF,MAAM,CAAC,MAAM,mBAAmB,GAAG,oBAAoB,CAAC;AAiCxD,0EAA0E;AAC1E,MAAM,UAAU,UAAU,CAAC,IAAa;IACvC,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IACpD,MAAM,CAAC,GAAG,IAAoC,CAAC;IAC/C,OAAO,CACN,OAAO,CAAC,CAAC,WAAW,KAAK,QAAQ,IAAI,OAAO,CAAC,CAAC,kBAAkB,KAAK,QAAQ,IAAI,CAAC,CAAC,kBAAkB,KAAK,IAAI,CAC9G,CAAC;AACH,CAAC","sourcesContent":["/**\n * snapshot.ts — persisted data shapes for the rewind extension's file-history\n * engine. Pure types + tiny helpers; no Pi imports, no side effects, so the\n * engine and its selftests can import them under plain node.\n *\n * A FileHistorySnapshot is written to the session JSONL (via the integration\n * layer's appendEntry, custom type \"pi-rewind-snapshot\"). It is never sent to\n * the LLM and survives reload/compaction. Each snapshot anchors to one turn and\n * records, for every tracked file, which backup blob holds that file's contents\n * as of the start of the turn.\n */\n\n/** Custom session-entry type used to persist snapshots to the session JSONL. */\nexport const SNAPSHOT_ENTRY_TYPE = \"pi-rewind-snapshot\";\n\n/**\n * One file's backup at a specific version.\n * `backupName === null` means the file did not exist at this version — rewinding\n * to a snapshot carrying a null backup deletes the file.\n */\nexport interface FileBackup {\n\t/** Backup blob filename (`<sha256(relpath)[:16]>@v<n>`), or null if the file did not exist. */\n\tbackupName: string | null;\n\t/** Monotonic version for this file within the session (1-based). */\n\tversion: number;\n}\n\n/**\n * One turn's snapshot. `v` lets future readers migrate old entries.\n * `trackedFileBackups` is keyed by the file's path *relative to cwd* when inside\n * cwd (else the absolute path), matching the engine's path shortening.\n */\nexport interface FileHistorySnapshot {\n\tv: 1;\n\t/** Session entry id this snapshot anchors to (used to match /tree navigation). */\n\tuserEntryId: string;\n\t/** Leaf/turn id when finalized (informational). */\n\tturnId: string;\n\t/** The user prompt that drove the turn (truncated; shown in the /tree sync prompt). */\n\tprompt: string;\n\t/** Map of tracking-path → the backup recorded for that file at the start of this turn. */\n\ttrackedFileBackups: Record<string, FileBackup>;\n\t/** ISO timestamp the snapshot was finalized. */\n\ttimestamp: string;\n}\n\n/** Narrow an arbitrary session-entry payload to a FileHistorySnapshot. */\nexport function isSnapshot(data: unknown): data is FileHistorySnapshot {\n\tif (!data || typeof data !== \"object\") return false;\n\tconst s = data as Partial<FileHistorySnapshot>;\n\treturn (\n\t\ttypeof s.userEntryId === \"string\" && typeof s.trackedFileBackups === \"object\" && s.trackedFileBackups !== null\n\t);\n}\n"]}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
/** Bind the on-disk roots. Called once by index.ts (or by selftests). */
|
|
2
|
-
export declare function configureStorage(opts: {
|
|
3
|
-
backupsRoot: string;
|
|
4
|
-
sessionsRoot: string;
|
|
5
|
-
}): void;
|
|
6
|
-
/** Root holding every session's backup directory. */
|
|
7
|
-
export declare function backupsRootDir(): string;
|
|
8
|
-
/** A single session's backup directory. */
|
|
9
|
-
export declare function backupsDir(sessionId: string): string;
|
|
10
|
-
/** Root holding Pi's session JSONL files (for orphan detection). */
|
|
11
|
-
export declare function sessionsRootDir(): string;
|
|
12
|
-
//# sourceMappingURL=storage.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../../../src/extensions/rewind/storage.ts"],"names":[],"mappings":"AAiBA,yEAAyE;AACzE,wBAAgB,gBAAgB,CAAC,IAAI,EAAE;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAG1F;AAED,qDAAqD;AACrD,wBAAgB,cAAc,IAAI,MAAM,CAEvC;AAED,2CAA2C;AAC3C,wBAAgB,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAEpD;AAED,oEAAoE;AACpE,wBAAgB,eAAe,IAAI,MAAM,CAExC"}
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* storage.ts — injected storage roots for the rewind engine.
|
|
3
|
-
*
|
|
4
|
-
* engine.ts and gc.ts must stay loadable under plain node (for offline
|
|
5
|
-
* selftests), so they cannot statically import paths.ts (which imports
|
|
6
|
-
* getAgentDir from @astralyn/pi — unresolvable outside Pi).
|
|
7
|
-
* Instead they read the roots from here, and the integration layer (index.ts)
|
|
8
|
-
* calls configureStorage() with the real paths at startup. Selftests call it with
|
|
9
|
-
* temp directories.
|
|
10
|
-
*
|
|
11
|
-
* No Pi imports in this module.
|
|
12
|
-
*/
|
|
13
|
-
import { join } from "node:path";
|
|
14
|
-
let backupsRoot = "";
|
|
15
|
-
let sessionsRoot = "";
|
|
16
|
-
/** Bind the on-disk roots. Called once by index.ts (or by selftests). */
|
|
17
|
-
export function configureStorage(opts) {
|
|
18
|
-
backupsRoot = opts.backupsRoot;
|
|
19
|
-
sessionsRoot = opts.sessionsRoot;
|
|
20
|
-
}
|
|
21
|
-
/** Root holding every session's backup directory. */
|
|
22
|
-
export function backupsRootDir() {
|
|
23
|
-
return backupsRoot;
|
|
24
|
-
}
|
|
25
|
-
/** A single session's backup directory. */
|
|
26
|
-
export function backupsDir(sessionId) {
|
|
27
|
-
return join(backupsRoot, sessionId);
|
|
28
|
-
}
|
|
29
|
-
/** Root holding Pi's session JSONL files (for orphan detection). */
|
|
30
|
-
export function sessionsRootDir() {
|
|
31
|
-
return sessionsRoot;
|
|
32
|
-
}
|
|
33
|
-
//# sourceMappingURL=storage.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"storage.js","sourceRoot":"","sources":["../../../src/extensions/rewind/storage.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,IAAI,WAAW,GAAG,EAAE,CAAC;AACrB,IAAI,YAAY,GAAG,EAAE,CAAC;AAEtB,yEAAyE;AACzE,MAAM,UAAU,gBAAgB,CAAC,IAAmD;IACnF,WAAW,GAAG,IAAI,CAAC,WAAW,CAAC;IAC/B,YAAY,GAAG,IAAI,CAAC,YAAY,CAAC;AAClC,CAAC;AAED,qDAAqD;AACrD,MAAM,UAAU,cAAc;IAC7B,OAAO,WAAW,CAAC;AACpB,CAAC;AAED,2CAA2C;AAC3C,MAAM,UAAU,UAAU,CAAC,SAAiB;IAC3C,OAAO,IAAI,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC;AACrC,CAAC;AAED,oEAAoE;AACpE,MAAM,UAAU,eAAe;IAC9B,OAAO,YAAY,CAAC;AACrB,CAAC","sourcesContent":["/**\n * storage.ts — injected storage roots for the rewind engine.\n *\n * engine.ts and gc.ts must stay loadable under plain node (for offline\n * selftests), so they cannot statically import paths.ts (which imports\n * getAgentDir from @astralyn/pi — unresolvable outside Pi).\n * Instead they read the roots from here, and the integration layer (index.ts)\n * calls configureStorage() with the real paths at startup. Selftests call it with\n * temp directories.\n *\n * No Pi imports in this module.\n */\nimport { join } from \"node:path\";\n\nlet backupsRoot = \"\";\nlet sessionsRoot = \"\";\n\n/** Bind the on-disk roots. Called once by index.ts (or by selftests). */\nexport function configureStorage(opts: { backupsRoot: string; sessionsRoot: string }): void {\n\tbackupsRoot = opts.backupsRoot;\n\tsessionsRoot = opts.sessionsRoot;\n}\n\n/** Root holding every session's backup directory. */\nexport function backupsRootDir(): string {\n\treturn backupsRoot;\n}\n\n/** A single session's backup directory. */\nexport function backupsDir(sessionId: string): string {\n\treturn join(backupsRoot, sessionId);\n}\n\n/** Root holding Pi's session JSONL files (for orphan detection). */\nexport function sessionsRootDir(): string {\n\treturn sessionsRoot;\n}\n"]}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
export interface TruncateTextOptions {
|
|
2
|
-
ellipsis?: string;
|
|
3
|
-
collapseWhitespace?: boolean;
|
|
4
|
-
}
|
|
5
|
-
export declare function truncateText(text: string, maxLength: number, options?: TruncateTextOptions): string;
|
|
6
|
-
export declare function formatSize(bytes: number): string;
|
|
7
|
-
//# sourceMappingURL=text.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"text.d.ts","sourceRoot":"","sources":["../../../src/extensions/rewind/text.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,mBAAmB;IACnC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,GAAE,mBAAwB,GAAG,MAAM,CAMvG;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAKhD"}
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
export function truncateText(text, maxLength, options = {}) {
|
|
2
|
-
const ellipsis = options.ellipsis ?? "...";
|
|
3
|
-
const source = options.collapseWhitespace ? text.replace(/\s+/g, " ").trim() : text;
|
|
4
|
-
if (source.length <= maxLength)
|
|
5
|
-
return source;
|
|
6
|
-
if (ellipsis.length >= maxLength)
|
|
7
|
-
return ellipsis.slice(0, maxLength);
|
|
8
|
-
return `${source.slice(0, maxLength - ellipsis.length)}${ellipsis}`;
|
|
9
|
-
}
|
|
10
|
-
export function formatSize(bytes) {
|
|
11
|
-
if (bytes < 1024)
|
|
12
|
-
return `${bytes}B`;
|
|
13
|
-
if (bytes < 1024 * 1024)
|
|
14
|
-
return `${(bytes / 1024).toFixed(1)}KB`;
|
|
15
|
-
if (bytes < 1024 * 1024 * 1024)
|
|
16
|
-
return `${(bytes / (1024 * 1024)).toFixed(1)}MB`;
|
|
17
|
-
return `${(bytes / (1024 * 1024 * 1024)).toFixed(2)}GB`;
|
|
18
|
-
}
|
|
19
|
-
//# sourceMappingURL=text.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"text.js","sourceRoot":"","sources":["../../../src/extensions/rewind/text.ts"],"names":[],"mappings":"AAKA,MAAM,UAAU,YAAY,CAAC,IAAY,EAAE,SAAiB,EAAE,UAA+B,EAAE;IAC9F,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,KAAK,CAAC;IAC3C,MAAM,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;IACpF,IAAI,MAAM,CAAC,MAAM,IAAI,SAAS;QAAE,OAAO,MAAM,CAAC;IAC9C,IAAI,QAAQ,CAAC,MAAM,IAAI,SAAS;QAAE,OAAO,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC;IACtE,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,GAAG,QAAQ,CAAC,MAAM,CAAC,GAAG,QAAQ,EAAE,CAAC;AACrE,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,KAAa;IACvC,IAAI,KAAK,GAAG,IAAI;QAAE,OAAO,GAAG,KAAK,GAAG,CAAC;IACrC,IAAI,KAAK,GAAG,IAAI,GAAG,IAAI;QAAE,OAAO,GAAG,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC;IACjE,IAAI,KAAK,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI;QAAE,OAAO,GAAG,CAAC,KAAK,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC;IACjF,OAAO,GAAG,CAAC,KAAK,GAAG,CAAC,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC;AACzD,CAAC","sourcesContent":["export interface TruncateTextOptions {\n\tellipsis?: string;\n\tcollapseWhitespace?: boolean;\n}\n\nexport function truncateText(text: string, maxLength: number, options: TruncateTextOptions = {}): string {\n\tconst ellipsis = options.ellipsis ?? \"...\";\n\tconst source = options.collapseWhitespace ? text.replace(/\\s+/g, \" \").trim() : text;\n\tif (source.length <= maxLength) return source;\n\tif (ellipsis.length >= maxLength) return ellipsis.slice(0, maxLength);\n\treturn `${source.slice(0, maxLength - ellipsis.length)}${ellipsis}`;\n}\n\nexport function formatSize(bytes: number): string {\n\tif (bytes < 1024) return `${bytes}B`;\n\tif (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)}KB`;\n\tif (bytes < 1024 * 1024 * 1024) return `${(bytes / (1024 * 1024)).toFixed(1)}MB`;\n\treturn `${(bytes / (1024 * 1024 * 1024)).toFixed(2)}GB`;\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"tool-path.d.ts","sourceRoot":"","sources":["../../../src/extensions/rewind/tool-path.ts"],"names":[],"mappings":"AAEA,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAGtE;AAED,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAEpE"}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import path from "node:path";
|
|
2
|
-
export function editWriteTargetPath(input) {
|
|
3
|
-
const rawPath = input?.path;
|
|
4
|
-
return typeof rawPath === "string" && rawPath.length > 0 ? rawPath : undefined;
|
|
5
|
-
}
|
|
6
|
-
export function resolveToolPath(rawPath, cwd) {
|
|
7
|
-
return path.isAbsolute(rawPath) ? rawPath : path.resolve(cwd, rawPath);
|
|
8
|
-
}
|
|
9
|
-
//# sourceMappingURL=tool-path.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"tool-path.js","sourceRoot":"","sources":["../../../src/extensions/rewind/tool-path.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,MAAM,UAAU,mBAAmB,CAAC,KAAc;IACjD,MAAM,OAAO,GAAI,KAAwC,EAAE,IAAI,CAAC;IAChE,OAAO,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC;AAChF,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,OAAe,EAAE,GAAW;IAC3D,OAAO,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;AACxE,CAAC","sourcesContent":["import path from \"node:path\";\n\nexport function editWriteTargetPath(input: unknown): string | undefined {\n\tconst rawPath = (input as { path?: unknown } | undefined)?.path;\n\treturn typeof rawPath === \"string\" && rawPath.length > 0 ? rawPath : undefined;\n}\n\nexport function resolveToolPath(rawPath: string, cwd: string): string {\n\treturn path.isAbsolute(rawPath) ? rawPath : path.resolve(cwd, rawPath);\n}\n"]}
|
|
@@ -1,132 +0,0 @@
|
|
|
1
|
-
import { ProcessTerminal } from "@earendil-works/pi-tui";
|
|
2
|
-
/**
|
|
3
|
-
* ProcessTerminal that (1) coalesces every write issued within one synchronous
|
|
4
|
-
* task into a single stdout write and (2) keeps content-driven full redraws
|
|
5
|
-
* from destroying the terminal's scrollback.
|
|
6
|
-
*
|
|
7
|
-
* Coalescing: pi-tui emits each render pass as several separate stdout
|
|
8
|
-
* writes: the frame wrapped in synchronized output (CSI ?2026h/l), then a
|
|
9
|
-
* relative cursor move that parks the hardware cursor at the focused
|
|
10
|
-
* component's caret for IME composition, then a cursor visibility toggle.
|
|
11
|
-
* Terminals that anchor the IME candidate window to the hardware cursor
|
|
12
|
-
* (Windows Terminal and other ConPTY hosts, WezTerm) can process the frame
|
|
13
|
-
* write before the reposition write arrives, briefly leaving the cursor at
|
|
14
|
-
* the end of the last repainted line. With an IME active this makes the
|
|
15
|
-
* candidate window jump between the caret and the right edge of the input
|
|
16
|
-
* line on every keystroke. Merging the writes makes each frame atomic, so the
|
|
17
|
-
* only cursor position a terminal can observe is the final one.
|
|
18
|
-
*
|
|
19
|
-
* Scrollback preservation: pi-tui's fullRender(clear) opens with
|
|
20
|
-
* `2J H 3J`, wiping the terminal's scrollback, and then replays the entire
|
|
21
|
-
* transcript. During streaming, content-driven triggers (a line changing
|
|
22
|
-
* above the viewport during markdown reflow) fire this routinely, which — in
|
|
23
|
-
* terminals that clamp the scroll offset when scrollback vanishes, notably
|
|
24
|
-
* Windows Terminal — yanks a scrolled-up reader to the top of the buffer on
|
|
25
|
-
* every reflow (upstream #6502, #5576, #6050; rejected upstream fix #4204).
|
|
26
|
-
*
|
|
27
|
-
* Preservation is therefore windowed, not permanent: the host marks agent
|
|
28
|
-
* runs via setAgentRunActive, which turns preservation on at run start and
|
|
29
|
-
* keeps it on until the user's next input after the run settles, since they
|
|
30
|
-
* may still be scrolled up reading. The input half of the window is observed
|
|
31
|
-
* directly on this terminal's own input path, so it needs no TUI listener
|
|
32
|
-
* and survives renderer switches (which reuse this terminal) untouched. An
|
|
33
|
-
* idle-session full redraw — Ctrl+O toggles, mode switches — passes through
|
|
34
|
-
* with upstream's wipe-and-replay, whose result is byte-perfect: scrollback
|
|
35
|
-
* becomes the clean new transcript. Mid-run user toggles can arm
|
|
36
|
-
* passNextFullRedraw for the same clean replay on their own frame.
|
|
37
|
-
*
|
|
38
|
-
* While preservation is active, a matching frame is rewritten to repaint
|
|
39
|
-
* without the wipe. With setViewportTopProvider wired, the rewrite knows
|
|
40
|
-
* which transcript line the visible screen starts at, so a frame that grew
|
|
41
|
-
* the transcript repaints the on-screen rows with the new content at those
|
|
42
|
-
* same positions and then scrolls the extra lines in at the bottom row.
|
|
43
|
-
* Each bottom-row newline pushes the top row — already repainted with the
|
|
44
|
-
* correct new content — into scrollback, exactly like ordinary streaming
|
|
45
|
-
* output, so scrollback ends up byte-equivalent to the upstream full replay
|
|
46
|
-
* without ever clearing it. Without the provider, or when the transcript
|
|
47
|
-
* shrank (lines cannot be pulled back out of scrollback), the rewrite falls
|
|
48
|
-
* back to overwriting the visible screen in place with the bottom
|
|
49
|
-
* viewport-height rows, at the cost of a stale seam above the screen. ED 2
|
|
50
|
-
* is avoided entirely in rewritten frames because conhost/Windows Terminal
|
|
51
|
-
* implement it by scrolling the screen contents into scrollback rather than
|
|
52
|
-
* erasing in place.
|
|
53
|
-
*
|
|
54
|
-
* Width- and height-change redraws keep the upstream wipe because re-wrapped
|
|
55
|
-
* content genuinely invalidates old scrollback, and frames containing kitty
|
|
56
|
-
* graphics pass through untouched. A frame that does not match the expected
|
|
57
|
-
* shape is passed through unchanged, so if upstream reshapes its render
|
|
58
|
-
* output the wrapper degrades back to stock behavior.
|
|
59
|
-
*/
|
|
60
|
-
export declare class CoalescingTerminal extends ProcessTerminal {
|
|
61
|
-
private pending;
|
|
62
|
-
private flushQueued;
|
|
63
|
-
private lastWriteColumns;
|
|
64
|
-
private lastWriteRows;
|
|
65
|
-
private viewportTopProvider;
|
|
66
|
-
private preserve;
|
|
67
|
-
private passArmed;
|
|
68
|
-
private agentRunActive;
|
|
69
|
-
private flushOnExit;
|
|
70
|
-
/**
|
|
71
|
-
* Enable or disable the scrollback-preserving rewrite. Preservation is
|
|
72
|
-
* only worth its imperfections (stale renderings above the screen, seams
|
|
73
|
-
* on shrink) while the transcript is mutating on its own and the reader
|
|
74
|
-
* may be scrolled up — i.e. during an agent run and until the user's next
|
|
75
|
-
* input after it settles. Outside that window every full redraw passes
|
|
76
|
-
* through with upstream's wipe-and-replay, whose result is byte-perfect:
|
|
77
|
-
* scrollback becomes the clean new transcript. Default: disabled.
|
|
78
|
-
* setAgentRunActive drives this for the normal agent-run window; this
|
|
79
|
-
* primitive remains for direct control in tests.
|
|
80
|
-
*/
|
|
81
|
-
setScrollbackPreservation(enabled: boolean): void;
|
|
82
|
-
/**
|
|
83
|
-
* Open or close the agent-run half of the preservation window. Opening
|
|
84
|
-
* (agent_start) turns preservation on. Closing (agent_settled) leaves
|
|
85
|
-
* preservation on: trailing reflow frames may land after the run while
|
|
86
|
-
* the reader is still scrolled up. The window then closes on the user's
|
|
87
|
-
* next input, observed in start()'s input wrapper — once the user acts
|
|
88
|
-
* they are back at the bottom, and upstream's clean wipe-and-replay wins
|
|
89
|
-
* again until the next run.
|
|
90
|
-
*/
|
|
91
|
-
setAgentRunActive(active: boolean): void;
|
|
92
|
-
/**
|
|
93
|
-
* Arm a one-shot exemption for an explicit user action (Ctrl+O tool
|
|
94
|
-
* expansion, thinking visibility) so its own full redraw keeps the
|
|
95
|
-
* upstream wipe-and-replay even while preservation is active mid-run.
|
|
96
|
-
* The user just pressed a key, so they are interacting at the bottom;
|
|
97
|
-
* a clean replay beats preservation's stale-seam trade-offs there. The
|
|
98
|
-
* flag is cleared by the next write so it cannot leak onto a later
|
|
99
|
-
* streaming redraw.
|
|
100
|
-
*/
|
|
101
|
-
passNextFullRedraw(): void;
|
|
102
|
-
/**
|
|
103
|
-
* Wire the renderer's notion of which transcript line the visible screen
|
|
104
|
-
* currently starts at (pi-tui's `previousViewportTop`). Full-redraw frames
|
|
105
|
-
* that grew the transcript then scroll the new above-screen lines into
|
|
106
|
-
* scrollback instead of dropping them. The provider is read while the
|
|
107
|
-
* frame is being written, i.e. before the renderer updates its own
|
|
108
|
-
* bookkeeping for that frame; returning undefined falls back to the
|
|
109
|
-
* bottom-anchored in-place repaint.
|
|
110
|
-
*/
|
|
111
|
-
setViewportTopProvider(provider: () => number | undefined): void;
|
|
112
|
-
constructor();
|
|
113
|
-
start(onInput: (data: string) => void, onResize: () => void): void;
|
|
114
|
-
write(data: string): void;
|
|
115
|
-
moveBy(lines: number): void;
|
|
116
|
-
hideCursor(): void;
|
|
117
|
-
showCursor(): void;
|
|
118
|
-
clearLine(): void;
|
|
119
|
-
clearFromCursor(): void;
|
|
120
|
-
clearScreen(): void;
|
|
121
|
-
stop(): void;
|
|
122
|
-
/**
|
|
123
|
-
* Rewrite a full-redraw frame (`?2026h 2J H 3J <lines> ?2026l`) so it
|
|
124
|
-
* repaints the screen without wiping scrollback. Anything that does not
|
|
125
|
-
* match this exact shape — including width-change redraws and frames
|
|
126
|
-
* touching kitty images — passes through unchanged.
|
|
127
|
-
*/
|
|
128
|
-
private preserveScrollback;
|
|
129
|
-
private readViewportTop;
|
|
130
|
-
private flush;
|
|
131
|
-
}
|
|
132
|
-
//# sourceMappingURL=coalescing-terminal.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"coalescing-terminal.d.ts","sourceRoot":"","sources":["../../src/utils/coalescing-terminal.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AASzD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyDG;AACH,qBAAa,kBAAmB,SAAQ,eAAe;IACtD,OAAO,CAAC,OAAO,CAAM;IACrB,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,gBAAgB,CAAqB;IAC7C,OAAO,CAAC,aAAa,CAAqB;IAC1C,OAAO,CAAC,mBAAmB,CAAyC;IACpE,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,cAAc,CAAS;IAC/B,OAAO,CAAC,WAAW,CAAsB;IAEzC;;;;;;;;;;OAUG;IACH,yBAAyB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAIjD;;;;;;;;OAQG;IACH,iBAAiB,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI;IAKxC;;;;;;;;OAQG;IACH,kBAAkB,IAAI,IAAI;IAI1B;;;;;;;;OAQG;IACH,sBAAsB,CAAC,QAAQ,EAAE,MAAM,MAAM,GAAG,SAAS,GAAG,IAAI;;IAWvD,KAAK,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,EAAE,QAAQ,EAAE,MAAM,IAAI,GAAG,IAAI;IAoBlE,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAUzB,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAQ3B,UAAU,IAAI,IAAI;IAIlB,UAAU,IAAI,IAAI;IAIlB,SAAS,IAAI,IAAI;IAIjB,eAAe,IAAI,IAAI;IAIvB,WAAW,IAAI,IAAI;IAInB,IAAI,IAAI,IAAI;IAQrB;;;;;OAKG;IACH,OAAO,CAAC,kBAAkB;IA2E1B,OAAO,CAAC,eAAe;IAUvB,OAAO,CAAC,KAAK;CASb"}
|