@gavin-hu/my-pi-agent 0.18.0 → 0.20.0
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 +66 -52
- package/README.zh-CN.md +56 -46
- package/docs/extensions/README.md +34 -0
- package/docs/extensions/board.md +507 -0
- package/{extensions/bytefly/README.md → docs/extensions/bytefly.md} +774 -574
- package/{extensions/check/README.md → docs/extensions/check.md} +83 -68
- package/{extensions/context/README.md → docs/extensions/context.md} +40 -23
- package/docs/extensions/file-browse.md +561 -0
- package/{extensions/file-open/README.md → docs/extensions/file-open.md} +31 -23
- package/{extensions/file-read/README.md → docs/extensions/file-read.md} +47 -55
- package/{extensions/goal/README.md → docs/extensions/goal.md} +115 -131
- package/{extensions/job/README.md → docs/extensions/job.md} +62 -52
- package/{extensions/memory/README.md → docs/extensions/memory.md} +71 -60
- package/{extensions/plan/README.md → docs/extensions/plan.md} +440 -322
- package/{extensions/question/README.md → docs/extensions/question.md} +54 -31
- package/{extensions/rewind/README.md → docs/extensions/rewind.md} +115 -122
- package/docs/extensions/session-bus.md +298 -0
- package/{extensions/subagent/README.md → docs/extensions/subagent.md} +165 -118
- package/docs/extensions/team.md +254 -0
- package/{extensions/todo/README.md → docs/extensions/todo.md} +85 -88
- package/{extensions/watch/README.md → docs/extensions/watch.md} +54 -36
- package/{extensions/web-access/README.md → docs/extensions/web-access.md} +93 -50
- package/{extensions/wechat/README.md → docs/extensions/wechat.md} +260 -163
- package/{extensions/worktree/README.md → docs/extensions/worktree.md} +137 -79
- package/extensions/board/commands.ts +105 -0
- package/extensions/board/config.ts +36 -0
- package/extensions/board/format.ts +170 -0
- package/extensions/board/index.ts +40 -0
- package/extensions/board/input.ts +54 -0
- package/extensions/board/join.ts +42 -0
- package/extensions/board/page.ts +388 -0
- package/extensions/board/result.ts +108 -0
- package/extensions/board/rows.ts +48 -0
- package/extensions/board/schema.ts +90 -0
- package/extensions/board/seat.ts +28 -0
- package/extensions/board/snapshot.ts +42 -0
- package/extensions/board/tools.ts +444 -0
- package/extensions/board/transport/router.ts +91 -0
- package/extensions/board/transport/server.ts +138 -0
- package/extensions/board/types.ts +121 -0
- package/extensions/board/view/client.ts +51 -0
- package/extensions/board/view/dialog.ts +43 -0
- package/extensions/board/view/keys.ts +125 -0
- package/extensions/board/view/live.ts +231 -0
- package/extensions/board/view/names.ts +91 -0
- package/extensions/board/view/page.ts +118 -0
- package/extensions/board/view/render.ts +519 -0
- package/extensions/board/view/styles.ts +228 -0
- package/extensions/board/view/team.ts +327 -0
- package/extensions/bytefly/footer/budget.ts +6 -5
- package/extensions/bytefly/footer/collect/entries.ts +12 -4
- package/extensions/bytefly/footer/collect/snapshot.ts +8 -17
- package/extensions/bytefly/footer/config.ts +19 -8
- package/extensions/bytefly/footer/price/price.ts +30 -8
- package/extensions/bytefly/footer/register.ts +5 -5
- package/extensions/bytefly/footer/render/format.ts +18 -0
- package/extensions/bytefly/footer/render/lines.ts +23 -7
- package/extensions/bytefly/footer/render/segments.ts +117 -31
- package/extensions/bytefly/footer/types.ts +29 -5
- package/extensions/bytefly/footer/unpriced.ts +42 -17
- package/extensions/bytefly/panel/commands.ts +67 -7
- package/extensions/bytefly/panel/filter.ts +68 -0
- package/extensions/bytefly/panel/format.ts +16 -15
- package/extensions/bytefly/panel/join.ts +56 -13
- package/extensions/bytefly/panel/prices.ts +43 -0
- package/extensions/bytefly/panel/settings-runtime.ts +0 -6
- package/extensions/bytefly/panel/settings.ts +75 -43
- package/extensions/bytefly/panel/tui/entries.ts +26 -8
- package/extensions/bytefly/panel/tui/frame.ts +130 -93
- package/extensions/bytefly/panel/tui/keys.ts +352 -0
- package/extensions/bytefly/panel/tui/list-view.ts +25 -46
- package/extensions/bytefly/panel/tui/panes.ts +76 -0
- package/extensions/bytefly/panel/tui/section-view.ts +126 -0
- package/extensions/bytefly/panel/tui/settings-section.ts +54 -125
- package/extensions/bytefly/panel/tui/settings-view.ts +30 -131
- package/extensions/bytefly/panel/tui/side-pane.ts +224 -0
- package/extensions/bytefly/panel/tui.ts +306 -259
- package/extensions/bytefly/picker/discovery.ts +0 -2
- package/extensions/bytefly/picker/types.ts +0 -2
- package/extensions/bytefly/update/check.ts +39 -0
- package/extensions/bytefly/update/format.ts +15 -0
- package/extensions/bytefly/update/register.ts +73 -34
- package/extensions/bytefly/update/state.ts +6 -3
- package/extensions/check/commands.ts +2 -1
- package/extensions/context/tui.ts +1 -1
- package/extensions/file-browse/{config.ts → config/config.ts} +1 -1
- package/extensions/file-browse/files/classify.ts +136 -0
- package/extensions/file-browse/files/files.ts +12 -0
- package/extensions/file-browse/files/index.ts +90 -0
- package/extensions/file-browse/files/list.ts +261 -0
- package/extensions/file-browse/{paths.ts → files/paths.ts} +1 -1
- package/extensions/file-browse/files/tree.ts +101 -0
- package/extensions/file-browse/{git.ts → git/git.ts} +10 -3
- package/extensions/file-browse/index.ts +4 -4
- package/extensions/file-browse/{live.ts → live/live.ts} +20 -69
- package/extensions/file-browse/{router.ts → transport/router.ts} +21 -17
- package/extensions/file-browse/transport/server.ts +110 -0
- package/extensions/file-browse/{chrome.ts → view/chrome.ts} +4 -4
- package/extensions/file-browse/{client.ts → view/client.ts} +1 -1
- package/extensions/file-browse/{diff-html.ts → view/diff-html.ts} +3 -3
- package/extensions/file-browse/view/emit.ts +51 -0
- package/extensions/file-browse/{html.ts → view/html.ts} +19 -18
- package/extensions/file-browse/{icons.ts → view/icons.ts} +1 -1
- package/extensions/file-browse/{markdown.ts → view/markdown.ts} +18 -20
- package/extensions/file-browse/{raw-html.ts → view/raw-html.ts} +19 -14
- package/extensions/file-browse/{styles.ts → view/styles.ts} +29 -5
- package/extensions/file-browse/{tree.ts → view/tree.ts} +1 -1
- package/extensions/file-browse/{urls.ts → view/urls.ts} +1 -1
- package/extensions/file-read/schema.ts +2 -1
- package/extensions/job/runtime.ts +4 -4
- package/extensions/memory/store.ts +12 -5
- package/extensions/plan/blocks.ts +23 -2
- package/extensions/plan/commands.ts +21 -16
- package/extensions/plan/feedback.ts +185 -52
- package/extensions/plan/format.ts +10 -3
- package/extensions/plan/index.ts +23 -5
- package/extensions/plan/plan-files.ts +88 -0
- package/extensions/plan/plan-index.ts +43 -9
- package/extensions/plan/plan-text.ts +33 -23
- package/extensions/plan/plans.ts +27 -34
- package/extensions/plan/policy.ts +30 -17
- package/extensions/plan/review.ts +3 -27
- package/extensions/plan/runtime.ts +52 -11
- package/extensions/plan/sections.ts +112 -0
- package/extensions/plan/steps.ts +3 -22
- package/extensions/plan/todos.ts +51 -3
- package/extensions/plan/tools/exit.ts +20 -95
- package/extensions/plan/tools/todo-seed.ts +4 -2
- package/extensions/plan/tools/write.ts +12 -1
- package/extensions/plan/tui.ts +5 -34
- package/extensions/plan/types.ts +15 -8
- package/extensions/plan/web-blocks.ts +89 -0
- package/extensions/plan/web-chrome.ts +3 -5
- package/extensions/plan/web-client.ts +179 -330
- package/extensions/plan/web-collab.ts +3 -3
- package/extensions/plan/web-comments.ts +18 -8
- package/extensions/plan/web-composer.ts +80 -0
- package/extensions/plan/web-draft.ts +40 -0
- package/extensions/plan/web-keys.ts +134 -0
- package/extensions/plan/web-outline.ts +192 -0
- package/extensions/plan/web-page.ts +4 -8
- package/extensions/plan/web-plan.ts +150 -0
- package/extensions/plan/web-router.ts +3 -58
- package/extensions/plan/web-settle.ts +194 -0
- package/extensions/plan/web-share-session.ts +24 -30
- package/extensions/plan/web-streams.ts +14 -14
- package/extensions/plan/web-tokens.ts +2 -2
- package/extensions/plan/web.ts +66 -120
- package/extensions/rewind/{commands.ts → commands/commands.ts} +5 -5
- package/extensions/rewind/{review.ts → commands/review.ts} +15 -14
- package/extensions/rewind/{rewind.ts → commands/rewind.ts} +6 -6
- package/extensions/rewind/{config.ts → config/config.ts} +1 -1
- package/extensions/rewind/index.ts +3 -3
- package/extensions/rewind/{policy.ts → state/policy.ts} +4 -4
- package/extensions/rewind/{runtime.ts → state/runtime.ts} +11 -11
- package/extensions/rewind/{snapshot-run.ts → state/snapshot-run.ts} +1 -1
- package/extensions/rewind/{timeline.ts → state/timeline.ts} +2 -2
- package/extensions/rewind/{format.ts → text/format.ts} +3 -3
- package/extensions/rewind/{git.ts → transport/git.ts} +2 -2
- package/extensions/rewind/{restore.ts → transport/restore.ts} +2 -2
- package/extensions/rewind/{snapshot.ts → transport/snapshot.ts} +1 -1
- package/extensions/rewind/{store.ts → transport/store.ts} +1 -1
- package/extensions/rewind/{checklist.ts → view/checklist.ts} +6 -6
- package/extensions/rewind/{hunk-picker.ts → view/hunk-picker.ts} +8 -8
- package/extensions/rewind/{path-picker.ts → view/path-picker.ts} +7 -7
- package/extensions/rewind/{review-tui.ts → view/review-tui.ts} +11 -11
- package/extensions/rewind/{rewind-tui.ts → view/rewind-tui.ts} +17 -11
- package/extensions/rewind/{status.ts → view/status.ts} +4 -4
- package/extensions/session-bus/commands.ts +17 -69
- package/extensions/session-bus/format.ts +22 -45
- package/extensions/session-bus/index.ts +13 -7
- package/extensions/session-bus/join-request.ts +40 -0
- package/extensions/session-bus/mail-watch.ts +134 -0
- package/extensions/session-bus/notice.ts +32 -4
- package/{lib/claims → extensions/session-bus}/overlap.ts +11 -18
- package/extensions/session-bus/protocol.ts +19 -49
- package/extensions/session-bus/resolve.ts +67 -0
- package/extensions/session-bus/result.ts +16 -51
- package/extensions/session-bus/rows.ts +11 -5
- package/extensions/session-bus/runtime.ts +220 -267
- package/extensions/session-bus/store.ts +55 -7
- package/extensions/session-bus/tools.ts +31 -66
- package/extensions/session-bus/tui.ts +5 -5
- package/extensions/session-bus/types.ts +23 -14
- package/extensions/subagent/agents.ts +9 -8
- package/extensions/subagent/commands.ts +2 -1
- package/extensions/subagent/invocation.ts +4 -2
- package/extensions/team/commands.ts +145 -0
- package/extensions/team/dispatch.ts +133 -0
- package/extensions/team/format.ts +119 -0
- package/extensions/team/index.ts +34 -0
- package/extensions/team/schema.ts +29 -0
- package/extensions/team/tools.ts +267 -0
- package/extensions/team/types.ts +65 -0
- package/extensions/todo/index.ts +4 -1
- package/extensions/todo/nudge.ts +8 -2
- package/extensions/web-access/fetch/page.ts +4 -1
- package/extensions/web-access/fetch/structured.ts +447 -0
- package/extensions/web-access/fetch/tool.ts +2 -1
- package/extensions/web-access/search/tool.ts +2 -1
- package/extensions/wechat/bridge.ts +106 -251
- package/extensions/wechat/{commands.ts → commands/commands.ts} +26 -18
- package/extensions/wechat/{doctor.ts → commands/doctor.ts} +5 -5
- package/extensions/wechat/{history.ts → commands/history.ts} +1 -1
- package/extensions/wechat/{login.ts → commands/login.ts} +3 -3
- package/extensions/wechat/{slash.ts → commands/slash.ts} +38 -2
- package/extensions/wechat/dialog/channels.ts +136 -0
- package/extensions/wechat/{interaction.ts → dialog/interaction.ts} +37 -37
- package/extensions/wechat/{prompt.ts → dialog/prompt.ts} +2 -2
- package/extensions/wechat/{remote-ui.ts → dialog/remote-ui.ts} +1 -1
- package/extensions/wechat/index.ts +10 -10
- package/extensions/wechat/intake.ts +245 -0
- package/extensions/wechat/{admission.ts → peer/admission.ts} +2 -2
- package/extensions/wechat/{peer-session.ts → peer/peer-session.ts} +2 -2
- package/extensions/wechat/{peer-worker.ts → peer/peer-worker.ts} +100 -22
- package/extensions/wechat/{presence.ts → peer/presence.ts} +8 -7
- package/extensions/wechat/{reply-pipeline.ts → peer/reply-pipeline.ts} +1 -1
- package/extensions/wechat/{credentials.ts → state/credentials.ts} +2 -2
- package/extensions/wechat/{state.ts → state/state.ts} +14 -2
- package/extensions/wechat/{format.ts → text/format.ts} +3 -3
- package/extensions/wechat/{notices.ts → text/notices.ts} +8 -0
- package/extensions/wechat/tools.ts +29 -12
- package/extensions/wechat/{client.ts → transport/client.ts} +26 -2
- package/extensions/wechat/{deliver.ts → transport/deliver.ts} +72 -28
- package/extensions/wechat/{inbound.ts → transport/inbound.ts} +5 -5
- package/extensions/wechat/{media.ts → transport/media.ts} +11 -5
- package/extensions/wechat/transport/outbound.ts +142 -0
- package/extensions/wechat/{poll.ts → transport/poll.ts} +3 -3
- package/extensions/wechat/types.ts +10 -1
- package/extensions/wechat/{login-screen.ts → view/login-screen.ts} +4 -4
- package/extensions/wechat/{status-screen.ts → view/status-screen.ts} +31 -26
- package/extensions/worktree/commands.ts +24 -17
- package/extensions/worktree/exit.ts +12 -6
- package/extensions/worktree/git.ts +22 -14
- package/extensions/worktree/guard.ts +18 -290
- package/extensions/worktree/handoff.ts +10 -2
- package/extensions/worktree/index.ts +2 -1
- package/extensions/worktree/lifecycle.ts +2 -0
- package/extensions/worktree/registry.ts +20 -11
- package/extensions/worktree/root-tools.ts +13 -3
- package/extensions/worktree/runtime.ts +8 -2
- package/extensions/worktree/screen.ts +15 -8
- package/extensions/worktree/shell.ts +303 -0
- package/extensions/worktree/state.ts +1 -1
- package/extensions/worktree/status.ts +42 -9
- package/extensions/worktree/tools.ts +19 -13
- package/lib/README.md +11 -8
- package/lib/board/card.ts +479 -0
- package/lib/board/links.ts +141 -0
- package/lib/board/page-pointer.ts +310 -0
- package/lib/board/round-text.ts +81 -0
- package/lib/board/round.ts +94 -0
- package/lib/board/rules.ts +437 -0
- package/lib/board/session.ts +105 -0
- package/lib/board/store.ts +497 -0
- package/lib/board/view.ts +234 -0
- package/lib/errors.ts +12 -4
- package/lib/format.ts +35 -0
- package/lib/http/guard.ts +112 -0
- package/lib/http/index.ts +16 -5
- package/lib/http/serve.ts +237 -0
- package/lib/http/server.ts +12 -10
- package/lib/http/sink.ts +135 -0
- package/lib/http/token.ts +38 -0
- package/lib/plan-entry.ts +11 -0
- package/lib/policy.ts +25 -2
- package/lib/requirements.ts +6 -7
- package/lib/session-label.ts +64 -0
- package/lib/session-roster.ts +201 -0
- package/lib/session-tool.ts +184 -0
- package/lib/spawn.ts +37 -3
- package/lib/stray-fields.ts +45 -0
- package/lib/tool-names.ts +38 -2
- package/lib/tui/glyphs.ts +3 -2
- package/lib/web/README.md +57 -4
- package/lib/web/client-runtime.ts +123 -0
- package/lib/web/components.ts +5 -0
- package/lib/web/index.ts +4 -2
- package/lib/web/markup.ts +88 -1
- package/lib/web/names.ts +42 -0
- package/lib/web/runtime.ts +7 -1
- package/lib/web/tokens.ts +25 -2
- package/package.json +26 -14
- package/skills/next/SKILL.md +4 -3
- package/skills/project-docs/SKILL.md +133 -0
- package/skills/project-docs/references/audit.md +131 -0
- package/skills/project-docs/references/changelog.md +105 -0
- package/skills/project-docs/references/discovery.md +127 -0
- package/skills/project-docs/references/readme.md +80 -0
- package/skills/project-docs/references/release.md +84 -0
- package/skills/project-docs/references/roadmap.md +93 -0
- package/skills/project-docs/scripts/state.ts +316 -0
- package/skills/refactor/SKILL.md +100 -125
- package/skills/refactor/references/handoff.md +35 -0
- package/skills/refactor/references/signals.md +54 -0
- package/skills/refactor/scripts/inventory.ts +587 -0
- package/extensions/bytefly/panel/tui/extensions-view.ts +0 -40
- package/extensions/bytefly/panel/tui/skills-view.ts +0 -50
- package/extensions/file-browse/README.md +0 -506
- package/extensions/file-browse/files.ts +0 -564
- package/extensions/file-browse/server.ts +0 -141
- package/extensions/job/process.ts +0 -35
- package/extensions/plan/split.ts +0 -87
- package/extensions/session-bus/README.md +0 -247
- package/extensions/session-bus/team.ts +0 -102
- package/extensions/wechat/outbound.ts +0 -100
- package/lib/plans/sections.ts +0 -172
- package/lib/plans/setting.ts +0 -52
- package/lib/plans/split.ts +0 -215
- package/lib/plans/store.ts +0 -19
- package/lib/plans/team.ts +0 -151
- package/skills/changelog/SKILL.md +0 -148
- package/skills/parallel-dev/SKILL.md +0 -150
- /package/extensions/file-browse/{rev.ts → live/rev.ts} +0 -0
- /package/extensions/file-browse/{diff.ts → text/diff.ts} +0 -0
- /package/extensions/file-browse/{fuzzy.ts → text/fuzzy.ts} +0 -0
- /package/extensions/file-browse/{live-client.ts → view/live-client.ts} +0 -0
- /package/extensions/file-browse/{palette.ts → view/palette.ts} +0 -0
- /package/extensions/rewind/{patch.ts → text/patch.ts} +0 -0
- /package/extensions/rewind/{paths.ts → text/paths.ts} +0 -0
- /package/extensions/rewind/{queue.ts → transport/queue.ts} +0 -0
- /package/extensions/rewind/{temp-index.ts → transport/temp-index.ts} +0 -0
- /package/extensions/wechat/{lock.ts → state/lock.ts} +0 -0
- /package/extensions/wechat/{channel.ts → text/channel.ts} +0 -0
package/extensions/plan/web.ts
CHANGED
|
@@ -6,39 +6,38 @@
|
|
|
6
6
|
* for one plan, opens the default browser at a tokenized URL, and resolves
|
|
7
7
|
* `done` when the user saves feedback, cancels, closes the tab (detected by the
|
|
8
8
|
* event stream dropping), or aborts the turn. The route logic lives in the pure
|
|
9
|
-
* `web-router.ts`; this module
|
|
10
|
-
* and it takes injected seams so tests can run one on `127.0.0.1:0`.
|
|
9
|
+
* `web-router.ts`; this module owns the routes and the timers, `lib/http` owns
|
|
10
|
+
* the socket, and it takes injected seams so tests can run one on `127.0.0.1:0`.
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
|
-
import { createServer, type IncomingMessage, type ServerResponse } from "node:http";
|
|
14
13
|
import { networkInterfaces } from "node:os";
|
|
15
14
|
import { basename } from "node:path";
|
|
16
15
|
import { openInBrowser } from "../../lib/browser.ts";
|
|
17
16
|
import {
|
|
18
|
-
bindLoopback,
|
|
19
|
-
createCloser,
|
|
20
17
|
jsonHeaders,
|
|
21
|
-
|
|
18
|
+
type LoopbackRequest,
|
|
19
|
+
type LoopbackReply,
|
|
20
|
+
type LoopbackServer,
|
|
22
21
|
parseRequestUrl,
|
|
23
|
-
|
|
22
|
+
serveLoopback,
|
|
24
23
|
type ServeResponse,
|
|
25
24
|
} from "../../lib/http/index.ts";
|
|
26
25
|
import { fenceLanguage, highlightLines } from "../../lib/highlight.ts";
|
|
27
26
|
import { type ArmTimer, defaultInterval, defaultTimer, type RepeatTimer } from "../../lib/timer.ts";
|
|
28
|
-
import { codeBody, fenceInfo
|
|
27
|
+
import { codeBody, fenceInfo } from "./blocks.ts";
|
|
29
28
|
import {
|
|
30
29
|
claimAuthor,
|
|
31
30
|
MAX_ANNOTATIONS,
|
|
32
31
|
MAX_COMMENT_LENGTH,
|
|
33
32
|
MAX_QUOTE_LENGTH,
|
|
34
33
|
normalizeAuthor,
|
|
35
|
-
|
|
34
|
+
readFeedback,
|
|
36
35
|
stripFeedback,
|
|
37
36
|
type PlanAnnotation,
|
|
38
37
|
} from "./feedback.ts";
|
|
39
38
|
import { planTitle, type PlanStore, type StoredPlan } from "./plans.ts";
|
|
40
39
|
import { changedSections, planDigest, type SectionDigest } from "./plan-text.ts";
|
|
41
|
-
import {
|
|
40
|
+
import { extractPlanSteps } from "./steps.ts";
|
|
42
41
|
import type { ReviewCaller } from "./types.ts";
|
|
43
42
|
import { handleReviewRequest, type ReviewContext, type SaveResult } from "./web-router.ts";
|
|
44
43
|
import type { ReviewPageData } from "./web-page.ts";
|
|
@@ -71,8 +70,6 @@ export interface PlanReviewOptions {
|
|
|
71
70
|
signal?: AbortSignal;
|
|
72
71
|
/** Whether the browser may approve the plan (only the `exit_plan_mode` flow). */
|
|
73
72
|
canApprove?: boolean;
|
|
74
|
-
/** A line the page shows the owner, such as why approval belongs in the terminal. */
|
|
75
|
-
note?: string;
|
|
76
73
|
/** The section digests the previous review showed, so this page can mark changed sections. */
|
|
77
74
|
baseline?: SectionDigest[];
|
|
78
75
|
/**
|
|
@@ -143,40 +140,6 @@ const DROP_GRACE_MS = 1500;
|
|
|
143
140
|
*/
|
|
144
141
|
const PLAN_POLL_MS = 1000;
|
|
145
142
|
|
|
146
|
-
/** A request body, or the fact that it was too large to read. */
|
|
147
|
-
type BodyResult = { ok: true; body: string } | { ok: false };
|
|
148
|
-
|
|
149
|
-
/**
|
|
150
|
-
* Read a request body, stopping at {@link MAX_BODY_BYTES}. An oversize body is
|
|
151
|
-
* reported rather than destroyed here, so the handler can still answer 413 over
|
|
152
|
-
* the open socket instead of the client seeing a dropped connection.
|
|
153
|
-
*/
|
|
154
|
-
function readBody(request: IncomingMessage, limit: number): Promise<BodyResult> {
|
|
155
|
-
return new Promise((resolve) => {
|
|
156
|
-
const chunks: Buffer[] = [];
|
|
157
|
-
let size = 0;
|
|
158
|
-
let done = false;
|
|
159
|
-
const settle = (result: BodyResult): void => {
|
|
160
|
-
if (done) return;
|
|
161
|
-
done = true;
|
|
162
|
-
resolve(result);
|
|
163
|
-
};
|
|
164
|
-
request.on("data", (chunk: Buffer) => {
|
|
165
|
-
if (done) return;
|
|
166
|
-
size += chunk.length;
|
|
167
|
-
if (size > limit) {
|
|
168
|
-
chunks.length = 0;
|
|
169
|
-
request.pause();
|
|
170
|
-
settle({ ok: false });
|
|
171
|
-
return;
|
|
172
|
-
}
|
|
173
|
-
chunks.push(chunk);
|
|
174
|
-
});
|
|
175
|
-
request.on("end", () => settle({ ok: true, body: Buffer.concat(chunks).toString("utf-8") }));
|
|
176
|
-
request.on("error", () => settle({ ok: false }));
|
|
177
|
-
});
|
|
178
|
-
}
|
|
179
|
-
|
|
180
143
|
export function createPlanWebReview(store: PlanStore, deps: PlanWebReviewDeps = {}): PlanWebReview {
|
|
181
144
|
const sessions = new Set<PlanReviewSession>();
|
|
182
145
|
// What each running review can do about sharing; the session itself stays the
|
|
@@ -193,7 +156,9 @@ export function createPlanWebReview(store: PlanStore, deps: PlanWebReviewDeps =
|
|
|
193
156
|
): Promise<PlanReviewSession | undefined> => {
|
|
194
157
|
const { signal } = options;
|
|
195
158
|
const canApprove = options.canApprove === true;
|
|
196
|
-
|
|
159
|
+
// One cap for both listeners: a reviewer's page posts the same bodies as the
|
|
160
|
+
// owner's, so the shared one cannot be the stricter or the looser of the two.
|
|
161
|
+
const bodyLimit = deps.maxBodyBytes ?? MAX_BODY_BYTES;
|
|
197
162
|
// One token per holder: the owner's is minted here and never shared, and a
|
|
198
163
|
// reviewer token is minted by `share()`. The table owns the collision rule and
|
|
199
164
|
// the name each link has bound.
|
|
@@ -279,13 +244,16 @@ export function createPlanWebReview(store: PlanStore, deps: PlanWebReviewDeps =
|
|
|
279
244
|
const page = async (caller: ReviewCaller): Promise<ReviewPageData> => {
|
|
280
245
|
const { role } = caller;
|
|
281
246
|
const stored = await refreshPageText();
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
const
|
|
288
|
-
|
|
247
|
+
// The body, its blocks, and the comments out of one read of the file: an
|
|
248
|
+
// anchor names a block from this same parse, so the island cannot mark a
|
|
249
|
+
// comment onto a line the page never rendered.
|
|
250
|
+
const read = readFeedback(stored.content);
|
|
251
|
+
const current = read.body;
|
|
252
|
+
const blocks = read.blocks;
|
|
253
|
+
// Per-section change marks, each carrying its own section: the same shape the
|
|
254
|
+
// terminal review renders, so a heading and its mark cannot be paired wrongly.
|
|
255
|
+
const marks = changedSections(options.baseline, current);
|
|
256
|
+
const outline = marks.flatMap(({ section, changed }) =>
|
|
289
257
|
section.title === ""
|
|
290
258
|
? []
|
|
291
259
|
: [
|
|
@@ -294,7 +262,7 @@ export function createPlanWebReview(store: PlanStore, deps: PlanWebReviewDeps =
|
|
|
294
262
|
line: section.line,
|
|
295
263
|
level: section.level,
|
|
296
264
|
text: section.title,
|
|
297
|
-
...(changed
|
|
265
|
+
...(changed ? { changed: true } : {}),
|
|
298
266
|
},
|
|
299
267
|
],
|
|
300
268
|
);
|
|
@@ -312,9 +280,9 @@ export function createPlanWebReview(store: PlanStore, deps: PlanWebReviewDeps =
|
|
|
312
280
|
return {
|
|
313
281
|
// The document's own H1 reads better than the file-name slug, and the
|
|
314
282
|
// slug is still the fallback for a plan that starts with something else.
|
|
315
|
-
title:
|
|
283
|
+
title: marks.find((mark) => mark.section.level === 1)?.section.title || planTitle(basename(plan.path)),
|
|
316
284
|
blocks,
|
|
317
|
-
annotations:
|
|
285
|
+
annotations: read.annotations,
|
|
318
286
|
outline,
|
|
319
287
|
steps: {
|
|
320
288
|
done: stepList.filter((step) => step.status === "completed").length,
|
|
@@ -328,7 +296,6 @@ export function createPlanWebReview(store: PlanStore, deps: PlanWebReviewDeps =
|
|
|
328
296
|
rev: planDigest(current),
|
|
329
297
|
...(caller.name === undefined ? {} : { author: caller.name }),
|
|
330
298
|
canApprove: role === "owner" && canApprove,
|
|
331
|
-
...(role === "owner" && options.note !== undefined ? { note: options.note } : {}),
|
|
332
299
|
share: role === "owner" ? shareSession.state() : undefined,
|
|
333
300
|
};
|
|
334
301
|
};
|
|
@@ -376,6 +343,7 @@ export function createPlanWebReview(store: PlanStore, deps: PlanWebReviewDeps =
|
|
|
376
343
|
// frame hooks, so sharing stays one concern instead of five fields here.
|
|
377
344
|
const shareSession = createShareSession({
|
|
378
345
|
handleRequest,
|
|
346
|
+
maxBodyBytes: bodyLimit,
|
|
379
347
|
ownerPort: () => currentPort,
|
|
380
348
|
networkInterfaces: deps.networkInterfaces ?? networkInterfaces,
|
|
381
349
|
mintReviewer: () => tokens.mint("reviewer"),
|
|
@@ -410,78 +378,56 @@ export function createPlanWebReview(store: PlanStore, deps: PlanWebReviewDeps =
|
|
|
410
378
|
// Live event streams, used only to notice a closed owner tab: a reviewer's
|
|
411
379
|
// tab is not the review's lifetime. The explicit Cancel button and the abort
|
|
412
380
|
// signal are the deterministic paths.
|
|
413
|
-
const server = createServer(handleRequest);
|
|
414
381
|
/** One request, on either listener: the loopback page or a shared one. */
|
|
415
|
-
function handleRequest(request:
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
}
|
|
425
|
-
const body = read.body;
|
|
426
|
-
let result: ServeResponse;
|
|
427
|
-
try {
|
|
428
|
-
result = await handleReviewRequest(context, method, request.url ?? "/", request.headers, body);
|
|
429
|
-
} catch {
|
|
430
|
-
result = {
|
|
431
|
-
status: 500,
|
|
432
|
-
headers: jsonHeaders(),
|
|
433
|
-
body: JSON.stringify({ error: "Internal error" }),
|
|
434
|
-
};
|
|
435
|
-
}
|
|
436
|
-
if (result.stream) {
|
|
437
|
-
openEventStream(response, result);
|
|
438
|
-
// A page that walks away mid-frame must not take the session down.
|
|
439
|
-
response.on("error", () => {});
|
|
440
|
-
const token = parseRequestUrl(request.url ?? "/")?.search.get("token") ?? "";
|
|
441
|
-
const streamCaller = context.caller(token);
|
|
442
|
-
if (streamCaller !== undefined) streams.add(response, { role: streamCaller.role, token });
|
|
443
|
-
request.on("close", () => streams.remove(response));
|
|
444
|
-
return;
|
|
445
|
-
}
|
|
446
|
-
// A save or cancel only resolves the session after its response is on the
|
|
447
|
-
// wire; otherwise `close()` would force-close the socket mid-reply. The
|
|
448
|
-
// `close` path covers a client that walks away before the flush callback
|
|
449
|
-
// runs, so a settle cannot be lost with the socket.
|
|
450
|
-
const settlePending = (): void => {
|
|
451
|
-
const terminal = pendingResult;
|
|
452
|
-
if (!terminal) return;
|
|
453
|
-
pendingResult = undefined;
|
|
454
|
-
finish(terminal);
|
|
382
|
+
async function handleRequest(request: LoopbackRequest): Promise<LoopbackReply> {
|
|
383
|
+
let result: ServeResponse;
|
|
384
|
+
try {
|
|
385
|
+
result = await handleReviewRequest(context, request.method, request.url, request.headers, request.body);
|
|
386
|
+
} catch {
|
|
387
|
+
result = {
|
|
388
|
+
status: 500,
|
|
389
|
+
headers: jsonHeaders(),
|
|
390
|
+
body: JSON.stringify({ error: "Internal error" }),
|
|
455
391
|
};
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
392
|
+
}
|
|
393
|
+
// A save or cancel only resolves the session after its response is on the
|
|
394
|
+
// wire; otherwise `close()` would force-close the socket mid-reply. The same
|
|
395
|
+
// hook covers a client that walks away before the flush, so a settle cannot be
|
|
396
|
+
// lost with the socket.
|
|
397
|
+
const settlePending = (): void => {
|
|
398
|
+
const terminal = pendingResult;
|
|
399
|
+
if (!terminal) return;
|
|
400
|
+
pendingResult = undefined;
|
|
401
|
+
finish(terminal);
|
|
402
|
+
};
|
|
403
|
+
if (!result.stream) return { result, afterResponse: settlePending };
|
|
404
|
+
const token = parseRequestUrl(request.url)?.search.get("token") ?? "";
|
|
405
|
+
const streamCaller = context.caller(token);
|
|
406
|
+
return {
|
|
407
|
+
result,
|
|
408
|
+
openSink: (sink) => {
|
|
409
|
+
if (streamCaller !== undefined) streams.add(sink, { role: streamCaller.role, token });
|
|
410
|
+
return () => streams.remove(sink);
|
|
411
|
+
},
|
|
412
|
+
};
|
|
459
413
|
}
|
|
460
414
|
|
|
461
|
-
// The accept-level `error` listener lives in `bindHost`, so a transient
|
|
462
|
-
// failure cannot take the host down; the review still ends through its own
|
|
463
|
-
// paths: cancel, abort, drop, or shutdown.
|
|
464
415
|
const preferred = deps.port ?? ports.get(plan.path) ?? 0;
|
|
465
|
-
let
|
|
416
|
+
let server: LoopbackServer;
|
|
466
417
|
try {
|
|
467
|
-
|
|
418
|
+
server = await serveLoopback({
|
|
419
|
+
ports: preferred === 0 ? [0] : [preferred, 0],
|
|
420
|
+
maxBodyBytes: bodyLimit,
|
|
421
|
+
handler: handleRequest,
|
|
422
|
+
});
|
|
468
423
|
} catch {
|
|
469
|
-
// The remembered port may have been taken between turns;
|
|
470
|
-
|
|
471
|
-
try {
|
|
472
|
-
port = await bindLoopback(server, 0);
|
|
473
|
-
} catch {
|
|
474
|
-
port = undefined;
|
|
475
|
-
}
|
|
476
|
-
}
|
|
477
|
-
}
|
|
478
|
-
if (port === undefined) {
|
|
479
|
-
server.close();
|
|
424
|
+
// The remembered port may have been taken between turns; the fallback above
|
|
425
|
+
// covers that, so reaching here means neither port answered.
|
|
480
426
|
return undefined;
|
|
481
427
|
}
|
|
428
|
+
const port = server.port;
|
|
482
429
|
ports.set(plan.path, port);
|
|
483
430
|
currentPort = port;
|
|
484
|
-
const closeServer = createCloser(server);
|
|
485
431
|
|
|
486
432
|
const url = `http://127.0.0.1:${port}/?token=${token}`;
|
|
487
433
|
let closed = false;
|
|
@@ -498,7 +444,7 @@ export function createPlanWebReview(store: PlanStore, deps: PlanWebReviewDeps =
|
|
|
498
444
|
stopTicker();
|
|
499
445
|
streams.clear();
|
|
500
446
|
await shareSession.close();
|
|
501
|
-
await
|
|
447
|
+
await server.close();
|
|
502
448
|
};
|
|
503
449
|
|
|
504
450
|
const session: PlanReviewSession = { url, port, done, close };
|
|
@@ -8,13 +8,13 @@
|
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
import type { ExtensionAPI, ExtensionCommandContext } from "@earendil-works/pi-coding-agent";
|
|
11
|
-
import { withRailsSuppressed } from "
|
|
12
|
-
import { formatRewindListText, formatRewindRow } from "
|
|
11
|
+
import { withRailsSuppressed } from "../../../lib/rails.ts";
|
|
12
|
+
import { formatRewindListText, formatRewindRow } from "../text/format.ts";
|
|
13
13
|
import { openReview } from "./review.ts";
|
|
14
14
|
import { rewindTo } from "./rewind.ts";
|
|
15
|
-
import type { RewindRuntime } from "
|
|
16
|
-
import { RewindListComponent } from "
|
|
17
|
-
import { buildRewindPoints, type RewindPoint } from "
|
|
15
|
+
import type { RewindRuntime } from "../state/runtime.ts";
|
|
16
|
+
import { RewindListComponent } from "../view/rewind-tui.ts";
|
|
17
|
+
import { buildRewindPoints, type RewindPoint } from "../state/timeline.ts";
|
|
18
18
|
|
|
19
19
|
/** Pick a point from the timeline, or undefined when the user cancels. */
|
|
20
20
|
async function choosePoint(ctx: ExtensionCommandContext, points: RewindPoint[]): Promise<RewindPoint | undefined> {
|
|
@@ -10,10 +10,11 @@
|
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
12
|
import type { ExtensionAPI, ExtensionCommandContext } from "@earendil-works/pi-coding-agent";
|
|
13
|
-
import { messageOf } from "
|
|
14
|
-
import { sanitizeLine } from "
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
13
|
+
import { messageOf } from "../../../lib/errors.ts";
|
|
14
|
+
import { sanitizeLine } from "../../../lib/format.ts";
|
|
15
|
+
import { planModeRefusal } from "../../../lib/plan-entry.ts";
|
|
16
|
+
import { isPlanModeEnabled } from "../../../lib/plan-state.ts";
|
|
17
|
+
import { withRailsSuppressed } from "../../../lib/rails.ts";
|
|
17
18
|
import {
|
|
18
19
|
boundDiff,
|
|
19
20
|
formatHunkRevertBody,
|
|
@@ -23,20 +24,20 @@ import {
|
|
|
23
24
|
formatRevertSelectedBody,
|
|
24
25
|
formatReviewListText,
|
|
25
26
|
formatReviewRevertText,
|
|
26
|
-
} from "
|
|
27
|
-
import { HunkPickerComponent } from "
|
|
28
|
-
import { buildHunkPatch, parseFilePatch } from "
|
|
29
|
-
import { entryPaths, toReviewEntries, type ReviewEntry } from "
|
|
27
|
+
} from "../text/format.ts";
|
|
28
|
+
import { HunkPickerComponent } from "../view/hunk-picker.ts";
|
|
29
|
+
import { buildHunkPatch, parseFilePatch } from "../text/patch.ts";
|
|
30
|
+
import { entryPaths, toReviewEntries, type ReviewEntry } from "../text/paths.ts";
|
|
30
31
|
import {
|
|
31
32
|
ReviewDiffComponent,
|
|
32
33
|
ReviewListComponent,
|
|
33
34
|
type ReviewDiffAction,
|
|
34
35
|
type ReviewListResult,
|
|
35
|
-
} from "
|
|
36
|
-
import type { RestorePlan } from "
|
|
37
|
-
import type { RewindRuntime } from "
|
|
38
|
-
import { buildRewindPoints, type RewindPoint } from "
|
|
39
|
-
import type { Snapshot, RestoreSummary } from "
|
|
36
|
+
} from "../view/review-tui.ts";
|
|
37
|
+
import type { RestorePlan } from "../transport/restore.ts";
|
|
38
|
+
import type { RewindRuntime } from "../state/runtime.ts";
|
|
39
|
+
import { buildRewindPoints, type RewindPoint } from "../state/timeline.ts";
|
|
40
|
+
import type { Snapshot, RestoreSummary } from "../types.ts";
|
|
40
41
|
|
|
41
42
|
/** One reviewable view of the working tree. */
|
|
42
43
|
interface ReviewView {
|
|
@@ -75,7 +76,7 @@ async function loadReview(runtime: RewindRuntime, ctx: ExtensionCommandContext):
|
|
|
75
76
|
return {
|
|
76
77
|
ok: false,
|
|
77
78
|
kind: "warning",
|
|
78
|
-
message: "
|
|
79
|
+
message: planModeRefusal("reviewing and reverting its changes"),
|
|
79
80
|
};
|
|
80
81
|
}
|
|
81
82
|
|
|
@@ -9,13 +9,13 @@
|
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
11
|
import type { ExtensionCommandContext } from "@earendil-works/pi-coding-agent";
|
|
12
|
-
import { withRailsSuppressed } from "
|
|
12
|
+
import { withRailsSuppressed } from "../../../lib/rails.ts";
|
|
13
13
|
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
14
|
-
import { formatChangeSummary, formatRestoreText, previewDiffText } from "
|
|
15
|
-
import { PathPickerComponent } from "
|
|
16
|
-
import type { ChangedPath } from "
|
|
17
|
-
import type { RewindRuntime } from "
|
|
18
|
-
import { rewindScopes, type RewindPoint, type RewindScope } from "
|
|
14
|
+
import { formatChangeSummary, formatRestoreText, previewDiffText } from "../text/format.ts";
|
|
15
|
+
import { PathPickerComponent } from "../view/path-picker.ts";
|
|
16
|
+
import type { ChangedPath } from "../text/paths.ts";
|
|
17
|
+
import type { RewindRuntime } from "../state/runtime.ts";
|
|
18
|
+
import { rewindScopes, type RewindPoint, type RewindScope } from "../state/timeline.ts";
|
|
19
19
|
|
|
20
20
|
/** Human labels for the scope picker, in menu order. */
|
|
21
21
|
const SCOPE_LABELS: Record<RewindScope, string> = {
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* malformed documents are ignored, and every value is clamped to a safe range.
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
import { clampInteger, cleanString, loadConfigSection, stringList } from "
|
|
9
|
+
import { clampInteger, cleanString, loadConfigSection, stringList } from "../../../lib/config.ts";
|
|
10
10
|
|
|
11
11
|
export interface RewindConfig {
|
|
12
12
|
/** Take one automatic snapshot per user prompt. Default: true. */
|
|
@@ -16,9 +16,9 @@
|
|
|
16
16
|
|
|
17
17
|
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
18
18
|
import { isExtensionEnabled } from "../../lib/env.ts";
|
|
19
|
-
import { registerCommands } from "./commands.ts";
|
|
20
|
-
import { createRuntime } from "./runtime.ts";
|
|
21
|
-
import { createSnapshotRun } from "./snapshot-run.ts";
|
|
19
|
+
import { registerCommands } from "./commands/commands.ts";
|
|
20
|
+
import { createRuntime } from "./state/runtime.ts";
|
|
21
|
+
import { createSnapshotRun } from "./state/snapshot-run.ts";
|
|
22
22
|
|
|
23
23
|
export function registerRewind(pi: ExtensionAPI): void {
|
|
24
24
|
const runtime = createRuntime(pi);
|
|
@@ -9,12 +9,12 @@
|
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
11
|
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
12
|
-
import { createReadOnlyPolicy } from "
|
|
13
|
-
import { ASK_USER_QUESTION_TOOL, GOAL_TOOL, TODO_TOOL } from "
|
|
14
|
-
import type { RewindConfig } from "
|
|
12
|
+
import { createReadOnlyPolicy, WORKSPACE_READERS } from "../../../lib/policy.ts";
|
|
13
|
+
import { ASK_USER_QUESTION_TOOL, GOAL_TOOL, TODO_TOOL } from "../../../lib/tool-names.ts";
|
|
14
|
+
import type { RewindConfig } from "../config/config.ts";
|
|
15
15
|
|
|
16
16
|
/** Tools that only read files or track session state, so they never snapshot. */
|
|
17
|
-
const READER_TOOLS = [
|
|
17
|
+
const READER_TOOLS = [...WORKSPACE_READERS, TODO_TOOL, GOAL_TOOL];
|
|
18
18
|
|
|
19
19
|
/** The interactive tool: it prompts the user and never touches the working tree. */
|
|
20
20
|
const SESSION_TOOLS = [ASK_USER_QUESTION_TOOL];
|
|
@@ -9,8 +9,8 @@
|
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
11
|
import type { ExtensionAPI, ExtensionContext } from "@earendil-works/pi-coding-agent";
|
|
12
|
-
import { resolveEffectiveCwd } from "
|
|
13
|
-
import { loadConfig, type RewindConfig } from "
|
|
12
|
+
import { resolveEffectiveCwd } from "../../../lib/env.ts";
|
|
13
|
+
import { loadConfig, type RewindConfig } from "../config/config.ts";
|
|
14
14
|
import {
|
|
15
15
|
applyPatchReverse,
|
|
16
16
|
createRewindRunner,
|
|
@@ -19,16 +19,16 @@ import {
|
|
|
19
19
|
repoRoot,
|
|
20
20
|
revParse,
|
|
21
21
|
type RunGit,
|
|
22
|
-
} from "
|
|
23
|
-
import { createOperationQueue } from "
|
|
24
|
-
import { applyRestore, planRestore, type PlanResult, type RestoreInput } from "
|
|
25
|
-
import type { PathStat } from "
|
|
26
|
-
import { createSnapshot } from "
|
|
27
|
-
import { createStatusChip } from "
|
|
28
|
-
import { belongsToRoot, listSnapshots, pruneSnapshots } from "
|
|
29
|
-
import { createTempIndexStore } from "
|
|
22
|
+
} from "../transport/git.ts";
|
|
23
|
+
import { createOperationQueue } from "../transport/queue.ts";
|
|
24
|
+
import { applyRestore, planRestore, type PlanResult, type RestoreInput } from "../transport/restore.ts";
|
|
25
|
+
import type { PathStat } from "../text/paths.ts";
|
|
26
|
+
import { createSnapshot } from "../transport/snapshot.ts";
|
|
27
|
+
import { createStatusChip } from "../view/status.ts";
|
|
28
|
+
import { belongsToRoot, listSnapshots, pruneSnapshots } from "../transport/store.ts";
|
|
29
|
+
import { createTempIndexStore } from "../transport/temp-index.ts";
|
|
30
30
|
import { lastUserEntryId } from "./timeline.ts";
|
|
31
|
-
import type { Snapshot, SnapshotReason, RestoreSummary } from "
|
|
31
|
+
import type { Snapshot, SnapshotReason, RestoreSummary } from "../types.ts";
|
|
32
32
|
|
|
33
33
|
export interface SnapshotOptions {
|
|
34
34
|
reason: SnapshotReason;
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
12
|
import type { ExtensionAPI, ExtensionContext } from "@earendil-works/pi-coding-agent";
|
|
13
|
-
import { summarizePrompt } from "
|
|
13
|
+
import { summarizePrompt } from "../text/format.ts";
|
|
14
14
|
import { createSnapshotPolicy, type SnapshotPolicy } from "./policy.ts";
|
|
15
15
|
import type { RewindRuntime } from "./runtime.ts";
|
|
16
16
|
|
|
@@ -9,8 +9,8 @@
|
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
11
|
import type { SessionEntry, SessionMessageEntry } from "@earendil-works/pi-coding-agent";
|
|
12
|
-
import { summarizePrompt } from "
|
|
13
|
-
import type { Snapshot } from "
|
|
12
|
+
import { summarizePrompt } from "../text/format.ts";
|
|
13
|
+
import type { Snapshot } from "../types.ts";
|
|
14
14
|
|
|
15
15
|
/** What a rewind can restore for one point. */
|
|
16
16
|
export type RewindScope = "both" | "conversation" | "code";
|
|
@@ -7,10 +7,10 @@
|
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
import { sliceByColumn, truncateToWidth, visibleWidth } from "@earendil-works/pi-tui";
|
|
10
|
-
import { sanitizeLine, stripControlChars } from "
|
|
11
|
-
import { GLYPHS, SEPARATORS } from "
|
|
10
|
+
import { sanitizeLine, stripControlChars } from "../../../lib/format.ts";
|
|
11
|
+
import { GLYPHS, SEPARATORS } from "../../../lib/tui/glyphs.ts";
|
|
12
12
|
import { SELECTION_MARKS, type ReviewEntry } from "./paths.ts";
|
|
13
|
-
import type { RestoreSummary } from "
|
|
13
|
+
import type { RestoreSummary } from "../types.ts";
|
|
14
14
|
|
|
15
15
|
/** Longest prompt summary shown before truncation. */
|
|
16
16
|
const LABEL_WIDTH = 48;
|
|
@@ -23,8 +23,8 @@ import {
|
|
|
23
23
|
revParseMany,
|
|
24
24
|
runGitOrThrow as run,
|
|
25
25
|
type RunGit,
|
|
26
|
-
} from "
|
|
27
|
-
import { parseNameStatus, parseNumStat, type ChangedPath, type PathStat } from "
|
|
26
|
+
} from "../../../lib/git/index.ts";
|
|
27
|
+
import { parseNameStatus, parseNumStat, type ChangedPath, type PathStat } from "../text/paths.ts";
|
|
28
28
|
|
|
29
29
|
// Re-export exactly the shared helpers this extension consumes, so rewind code
|
|
30
30
|
// has one git import surface instead of reaching into `lib/git` directly.
|
|
@@ -26,8 +26,8 @@ import {
|
|
|
26
26
|
treeFromWorkingTree,
|
|
27
27
|
type RunGit,
|
|
28
28
|
} from "./git.ts";
|
|
29
|
-
import { entryPaths, summarize, type ChangedPath } from "
|
|
30
|
-
import type { Snapshot, RestoreSummary } from "
|
|
29
|
+
import { entryPaths, summarize, type ChangedPath } from "../text/paths.ts";
|
|
30
|
+
import type { Snapshot, RestoreSummary } from "../types.ts";
|
|
31
31
|
|
|
32
32
|
export interface RestoreDeps {
|
|
33
33
|
runGit: RunGit;
|
|
@@ -18,7 +18,7 @@ import {
|
|
|
18
18
|
type RunGit,
|
|
19
19
|
} from "./git.ts";
|
|
20
20
|
import { encodeMessage, refFor, META_VERSION, type SnapshotMeta } from "./store.ts";
|
|
21
|
-
import type { Snapshot, SnapshotReason } from "
|
|
21
|
+
import type { Snapshot, SnapshotReason } from "../types.ts";
|
|
22
22
|
|
|
23
23
|
export interface SnapshotDeps {
|
|
24
24
|
runGit: RunGit;
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
import { commitMessages, deleteRef, listRefs, type RunGit } from "./git.ts";
|
|
10
|
-
import type { Snapshot, SnapshotReason } from "
|
|
10
|
+
import type { Snapshot, SnapshotReason } from "../types.ts";
|
|
11
11
|
|
|
12
12
|
/** Prefix of the metadata line in a snapshot commit body. */
|
|
13
13
|
export const META_MARKER = "pi-rewind: ";
|
|
@@ -14,12 +14,12 @@
|
|
|
14
14
|
|
|
15
15
|
import type { Theme } from "@earendil-works/pi-coding-agent";
|
|
16
16
|
import { Key, matchesKey, type Component, type TuiMouseEvent, type TuiMouseEventResult } from "@earendil-works/pi-tui";
|
|
17
|
-
import { detailBlockRows, dockListFrame, type ViewportRowsSource } from "
|
|
18
|
-
import { clip } from "
|
|
19
|
-
import { fitRows, formatRange, isCloseKey, ListCursor, navigateList, scrollList } from "
|
|
20
|
-
import { emptyState } from "
|
|
21
|
-
import { titleRule } from "
|
|
22
|
-
import { paint } from "
|
|
17
|
+
import { detailBlockRows, dockListFrame, type ViewportRowsSource } from "../../../lib/tui/chrome.ts";
|
|
18
|
+
import { clip } from "../../../lib/tui/columns.ts";
|
|
19
|
+
import { fitRows, formatRange, isCloseKey, ListCursor, navigateList, scrollList } from "../../../lib/tui/cursor.ts";
|
|
20
|
+
import { emptyState } from "../../../lib/tui/rows.ts";
|
|
21
|
+
import { titleRule } from "../../../lib/tui/rules.ts";
|
|
22
|
+
import { paint } from "../../../lib/tui/tokens.ts";
|
|
23
23
|
|
|
24
24
|
/** Rows the checklist shows when the terminal height is unknown. */
|
|
25
25
|
const SCREEN_DEFAULT_ITEMS = 12;
|
|
@@ -11,15 +11,15 @@
|
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
13
|
import type { Theme } from "@earendil-works/pi-coding-agent";
|
|
14
|
-
import { sanitizeLine } from "
|
|
15
|
-
import { screenHint, type ViewportRowsSource } from "
|
|
16
|
-
import { clip } from "
|
|
17
|
-
import { SEPARATORS } from "
|
|
18
|
-
import { checkbox, listRow } from "
|
|
19
|
-
import { paint } from "
|
|
14
|
+
import { sanitizeLine } from "../../../lib/format.ts";
|
|
15
|
+
import { screenHint, type ViewportRowsSource } from "../../../lib/tui/chrome.ts";
|
|
16
|
+
import { clip } from "../../../lib/tui/columns.ts";
|
|
17
|
+
import { SEPARATORS } from "../../../lib/tui/glyphs.ts";
|
|
18
|
+
import { checkbox, listRow } from "../../../lib/tui/rows.ts";
|
|
19
|
+
import { paint } from "../../../lib/tui/tokens.ts";
|
|
20
20
|
import { ChecklistScreen } from "./checklist.ts";
|
|
21
|
-
import { formatReviewEntryCounts } from "
|
|
22
|
-
import type { Hunk } from "
|
|
21
|
+
import { formatReviewEntryCounts } from "../text/format.ts";
|
|
22
|
+
import type { Hunk } from "../text/patch.ts";
|
|
23
23
|
|
|
24
24
|
export interface HunkPickerOptions {
|
|
25
25
|
/** The file the hunks belong to. */
|
|
@@ -13,14 +13,14 @@
|
|
|
13
13
|
*/
|
|
14
14
|
|
|
15
15
|
import type { Theme } from "@earendil-works/pi-coding-agent";
|
|
16
|
-
import { sanitizeLine } from "
|
|
17
|
-
import { screenHint, type ViewportRowsSource } from "
|
|
18
|
-
import { clip } from "
|
|
19
|
-
import { SEPARATORS } from "
|
|
20
|
-
import { checkbox, listRow } from "
|
|
21
|
-
import { paint } from "
|
|
16
|
+
import { sanitizeLine } from "../../../lib/format.ts";
|
|
17
|
+
import { screenHint, type ViewportRowsSource } from "../../../lib/tui/chrome.ts";
|
|
18
|
+
import { clip } from "../../../lib/tui/columns.ts";
|
|
19
|
+
import { SEPARATORS } from "../../../lib/tui/glyphs.ts";
|
|
20
|
+
import { checkbox, listRow } from "../../../lib/tui/rows.ts";
|
|
21
|
+
import { paint } from "../../../lib/tui/tokens.ts";
|
|
22
22
|
import { ChecklistScreen } from "./checklist.ts";
|
|
23
|
-
import { baseName, expandGroup, groupPaths, SELECTION_MARKS, type ChangedPath, type PathGroup } from "
|
|
23
|
+
import { baseName, expandGroup, groupPaths, SELECTION_MARKS, type ChangedPath, type PathGroup } from "../text/paths.ts";
|
|
24
24
|
|
|
25
25
|
export interface PathPickerOptions {
|
|
26
26
|
/** The changed paths the snapshot differs on. */
|