@gavin-hu/my-pi-agent 0.17.0 → 0.19.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 +61 -45
- package/README.zh-CN.md +54 -42
- package/docs/extensions/README.md +34 -0
- package/docs/extensions/board.md +344 -0
- package/{extensions/bytefly/README.md → docs/extensions/bytefly.md} +465 -416
- 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 +554 -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} +66 -53
- package/{extensions/memory/README.md → docs/extensions/memory.md} +74 -63
- package/docs/extensions/plan.md +976 -0
- package/{extensions/question/README.md → docs/extensions/question.md} +54 -28
- package/{extensions/rewind/README.md → docs/extensions/rewind.md} +115 -122
- package/docs/extensions/session-bus.md +285 -0
- package/{extensions/subagent/README.md → docs/extensions/subagent.md} +166 -119
- package/docs/extensions/team.md +226 -0
- package/{extensions/todo/README.md → docs/extensions/todo.md} +85 -88
- package/{extensions/watch/README.md → docs/extensions/watch.md} +60 -38
- package/{extensions/web-access/README.md → docs/extensions/web-access.md} +93 -50
- package/{extensions/wechat/README.md → docs/extensions/wechat.md} +275 -192
- package/{extensions/worktree/README.md → docs/extensions/worktree.md} +115 -72
- package/extensions/board/commands.ts +87 -0
- package/extensions/board/config.ts +36 -0
- package/extensions/board/format.ts +72 -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 +312 -0
- package/extensions/board/result.ts +99 -0
- package/extensions/board/rows.ts +48 -0
- package/extensions/board/schema.ts +75 -0
- package/extensions/board/seat.ts +29 -0
- package/extensions/board/snapshot.ts +41 -0
- package/extensions/board/tools.ts +279 -0
- package/extensions/board/transport/router.ts +172 -0
- package/extensions/board/transport/server.ts +149 -0
- package/extensions/board/types.ts +54 -0
- package/extensions/board/view/actions.ts +306 -0
- package/extensions/board/view/client.ts +41 -0
- package/extensions/board/view/keys.ts +121 -0
- package/extensions/board/view/live.ts +397 -0
- package/extensions/board/view/page.ts +158 -0
- package/extensions/board/view/render.ts +496 -0
- package/extensions/board/view/styles.ts +211 -0
- package/extensions/board/view/team.ts +305 -0
- package/extensions/board/writes.ts +99 -0
- package/extensions/bytefly/notify/types.ts +1 -1
- package/extensions/bytefly/panel/commands.ts +40 -7
- package/extensions/bytefly/panel/settings-runtime.ts +0 -6
- package/extensions/bytefly/panel/settings.ts +11 -21
- package/extensions/bytefly/panel/tui/settings-view.ts +1 -1
- 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/context/tui.ts +1 -1
- package/extensions/file-browse/{config.ts → config/config.ts} +13 -4
- package/extensions/file-browse/{files.ts → files/files.ts} +1 -14
- package/extensions/file-browse/{paths.ts → files/paths.ts} +1 -1
- 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} +54 -82
- package/extensions/file-browse/live/rev.ts +42 -0
- package/extensions/file-browse/{router.ts → transport/router.ts} +44 -17
- package/extensions/file-browse/transport/server.ts +110 -0
- package/extensions/file-browse/view/chrome.ts +83 -0
- package/extensions/file-browse/{client.ts → view/client.ts} +63 -1
- package/extensions/file-browse/view/diff-html.ts +94 -0
- package/extensions/file-browse/{html.ts → view/html.ts} +32 -158
- package/extensions/file-browse/{icons.ts → view/icons.ts} +1 -1
- package/extensions/file-browse/{live-client.ts → view/live-client.ts} +47 -1
- package/extensions/file-browse/{markdown.ts → view/markdown.ts} +7 -7
- package/extensions/file-browse/{raw-html.ts → view/raw-html.ts} +1 -1
- package/extensions/file-browse/{styles.ts → view/styles.ts} +31 -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/goal/plan-route.ts +8 -2
- package/extensions/job/index.ts +15 -7
- package/extensions/memory/store.ts +12 -5
- package/extensions/plan/blocks.ts +23 -2
- package/extensions/plan/commands.ts +77 -21
- package/extensions/plan/feedback.ts +409 -63
- package/extensions/plan/index.ts +7 -5
- package/extensions/plan/plan-index.ts +44 -10
- package/extensions/plan/plan-text.ts +51 -24
- package/extensions/plan/plans.ts +162 -57
- package/extensions/plan/policy.ts +20 -12
- package/extensions/plan/review-prompt.ts +93 -0
- package/extensions/plan/review.ts +51 -95
- package/extensions/plan/runtime.ts +22 -10
- package/extensions/plan/sections.ts +112 -0
- package/extensions/plan/steps.ts +63 -95
- package/extensions/plan/tools/enter.ts +8 -3
- package/extensions/plan/tools/exit.ts +13 -19
- package/extensions/plan/tools/write.ts +8 -3
- package/extensions/plan/tools.ts +1 -1
- package/extensions/plan/tui.ts +29 -15
- package/extensions/plan/types.ts +29 -3
- package/extensions/plan/web-chrome.ts +2 -1
- package/extensions/plan/web-client.ts +122 -178
- package/extensions/plan/web-collab.ts +207 -0
- package/extensions/plan/web-comments.ts +269 -0
- package/extensions/plan/web-page.ts +96 -17
- package/extensions/plan/web-router.ts +109 -47
- package/extensions/plan/web-share-session.ts +191 -0
- package/extensions/plan/web-share.ts +169 -0
- package/extensions/plan/web-streams.ts +124 -0
- package/extensions/plan/web-tokens.ts +63 -0
- package/extensions/plan/web.ts +245 -151
- package/extensions/question/dialogs.ts +91 -1
- package/extensions/question/tools.ts +2 -1
- package/extensions/rewind/{commands.ts → commands/commands.ts} +5 -5
- package/extensions/rewind/{review.ts → commands/review.ts} +13 -13
- 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 +113 -0
- package/extensions/session-bus/format.ts +101 -0
- package/extensions/session-bus/index.ts +75 -0
- package/extensions/session-bus/join-request.ts +40 -0
- package/extensions/session-bus/mail-watch.ts +134 -0
- package/extensions/session-bus/notice.ts +86 -0
- package/extensions/session-bus/overlap.ts +36 -0
- package/extensions/session-bus/protocol.ts +104 -0
- package/extensions/session-bus/resolve.ts +67 -0
- package/extensions/session-bus/result.ts +208 -0
- package/extensions/session-bus/rows.ts +171 -0
- package/extensions/session-bus/runtime.ts +466 -0
- package/extensions/session-bus/store.ts +365 -0
- package/extensions/session-bus/tools.ts +192 -0
- package/extensions/session-bus/tui.ts +394 -0
- package/extensions/session-bus/types.ts +98 -0
- package/extensions/subagent/agents.ts +9 -8
- package/extensions/subagent/invocation.ts +4 -2
- package/extensions/team/commands.ts +112 -0
- package/extensions/team/dispatch.ts +133 -0
- package/extensions/team/format.ts +105 -0
- package/extensions/team/index.ts +33 -0
- package/extensions/team/schema.ts +29 -0
- package/extensions/team/tools.ts +246 -0
- package/extensions/team/types.ts +48 -0
- package/extensions/watch/index.ts +15 -9
- 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 +76 -92
- 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} +66 -51
- package/extensions/wechat/{prompt.ts → dialog/prompt.ts} +40 -25
- package/extensions/wechat/{remote-ui.ts → dialog/remote-ui.ts} +1 -1
- package/extensions/wechat/index.ts +10 -10
- 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} +119 -56
- package/extensions/wechat/{presence.ts → peer/presence.ts} +11 -11
- package/extensions/wechat/{reply-pipeline.ts → peer/reply-pipeline.ts} +13 -5
- 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} +15 -7
- 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} +104 -40
- 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/git.ts +5 -0
- package/extensions/worktree/guard.ts +3 -5
- package/extensions/worktree/registry.ts +11 -5
- package/extensions/worktree/status.ts +1 -3
- package/lib/README.md +12 -6
- package/lib/board/card.ts +290 -0
- package/lib/board/links.ts +117 -0
- package/lib/board/page-pointer.ts +256 -0
- package/lib/board/round-text.ts +72 -0
- package/lib/board/round.ts +89 -0
- package/lib/board/rules.ts +304 -0
- package/lib/board/session.ts +105 -0
- package/lib/board/store.ts +310 -0
- package/lib/board/view.ts +150 -0
- package/lib/errors.ts +12 -4
- package/lib/format.ts +13 -0
- package/lib/http/guard.ts +112 -0
- package/lib/http/index.ts +16 -5
- package/lib/http/router.ts +40 -13
- package/lib/http/serve.ts +234 -0
- package/lib/http/server.ts +29 -13
- package/lib/http/sink.ts +110 -0
- package/lib/http/token.ts +38 -0
- package/lib/interaction.ts +10 -0
- package/lib/notice.ts +29 -2
- package/lib/plan-entry.ts +7 -2
- package/lib/policy.ts +12 -2
- package/lib/qr.ts +64 -0
- package/lib/repo-key.ts +74 -0
- package/lib/report.ts +52 -33
- package/lib/requirements.ts +7 -9
- package/lib/session-label.ts +64 -0
- package/lib/session-roster.ts +130 -0
- package/lib/session-tool.ts +184 -0
- package/lib/tool-names.ts +25 -2
- package/lib/tui/README.md +16 -2
- package/lib/tui/dock-screen.ts +85 -17
- package/lib/tui/glyphs.ts +2 -0
- package/lib/tui/line-pane.ts +15 -4
- package/lib/tui/tool.ts +23 -4
- package/lib/web/README.md +5 -2
- package/lib/web/components.ts +6 -1
- package/lib/web/runtime.ts +7 -1
- package/lib/web/tokens.ts +25 -2
- package/package.json +27 -14
- package/skills/init/SKILL.md +80 -45
- package/skills/init/references/agents-md-quality.md +26 -2
- package/skills/init/references/interview-questions.md +36 -14
- package/skills/next/SKILL.md +77 -51
- 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/file-browse/README.md +0 -467
- package/extensions/file-browse/server.ts +0 -134
- package/extensions/plan/README.md +0 -709
- package/extensions/plan/config.ts +0 -27
- package/extensions/wechat/outbound.ts +0 -100
- package/extensions/wechat/qrcode.ts +0 -46
- package/skills/changelog/SKILL.md +0 -148
- /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/{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
|
@@ -8,12 +8,29 @@
|
|
|
8
8
|
the effective working directory with the same symlink-aware guard the built-in
|
|
9
9
|
path tools use.
|
|
10
10
|
|
|
11
|
+
## Capabilities
|
|
12
|
+
|
|
13
|
+
Status records what a reader can rely on: **Shipped** is in a tagged release, **Unreleased** is complete in the current tree but not yet tagged, and **Partial** has one released part and one unreleased part. Rows are ordered by user value, highest first.
|
|
14
|
+
|
|
15
|
+
| Capability | How | What you get | Status |
|
|
16
|
+
|---|---|---|---|
|
|
17
|
+
| Document extraction | `read_doc` | Plain text from a document or workbook whose bytes the built-in `read` cannot decode. | Shipped |
|
|
18
|
+
| Paged reading | `read_doc` (`startIndex`, `maxChars`) | A long file arrives in slices, and a truncated result names the offset to ask for next. | Shipped |
|
|
19
|
+
| Workbook text | `read_doc` on `.xlsx` | One `[Sheet]` heading per worksheet followed by tab-separated rows, so the shape of the file survives. | Shipped |
|
|
20
|
+
| Confined reads | `read_doc` | A path outside the effective working directory is refused, symlinks resolved, before any parser runs. | Shipped |
|
|
21
|
+
| Progress and cancellation | `startToolProgress`, the abort signal | A slow extraction shows `Reading... <elapsed>` and can be cancelled instead of looking dead. | Shipped |
|
|
22
|
+
| Bounded extraction | `file-read.maxFileBytes`, `file-read.extractTimeoutMs` | An over-size file or a parser past its deadline fails the read instead of parking the turn. | Shipped |
|
|
23
|
+
| Per-format switches | `file-read.formats` | Any of the six formats can be turned off, and a disabled read names the key that did it. | Shipped |
|
|
24
|
+
| Unsupported-format hint | `read_doc` on another extension | The refusal names the supported formats and the legacy `.xls` conversion hint instead of a generic read error. | Shipped |
|
|
25
|
+
| Lazy parsers | `read_doc` | Only the format you read loads a library, so registration costs nothing at startup. | Shipped |
|
|
26
|
+
| Code-point slicing | `read_doc` (`startIndex`, `maxChars`) | CJK and emoji stay well-formed across a page boundary. | Shipped |
|
|
27
|
+
|
|
11
28
|
## Quickstart
|
|
12
29
|
|
|
13
30
|
```bash
|
|
14
|
-
pi --extension ./extensions/file-read # this extension
|
|
15
|
-
pi -e .
|
|
16
|
-
pi install ./
|
|
31
|
+
pi --extension ./extensions/file-read # load just this extension
|
|
32
|
+
pi -e . # load the whole @gavin-hu/my-pi-agent package
|
|
33
|
+
pi install ./ # install the package
|
|
17
34
|
```
|
|
18
35
|
|
|
19
36
|
The extraction libraries are ordinary dependencies, so a normal install brings
|
|
@@ -23,31 +40,15 @@ tool directly:
|
|
|
23
40
|
```jsonc
|
|
24
41
|
{ "path": "docs/spec.pdf" }
|
|
25
42
|
{ "path": "docs/spec.pdf", "startIndex": 40000, "maxChars": 40000 }
|
|
26
|
-
{ "path": "report.xlsx" }
|
|
27
43
|
```
|
|
28
44
|
|
|
29
|
-
## What it does
|
|
30
|
-
|
|
31
|
-
- Extracts plain text from `.pdf`, `.docx`, `.doc`, `.odt`, `.rtf`, and `.xlsx`
|
|
32
|
-
files for the model to read.
|
|
33
|
-
- Pages long files: when output is truncated, call again with the `startIndex`
|
|
34
|
-
named in the note.
|
|
35
|
-
- Slices by code point, so CJK and emoji stay well-formed.
|
|
36
|
-
- Reads only inside the effective working directory, resolving symlinks so a
|
|
37
|
-
link cannot escape it.
|
|
38
|
-
- Loads a format's parser only when that format is actually read, so registration
|
|
39
|
-
costs nothing at startup.
|
|
40
|
-
|
|
41
45
|
## Tool
|
|
42
46
|
|
|
43
|
-
`read_doc` — direct exposure, active by default, read-only, closed-world
|
|
44
|
-
(no network).
|
|
45
|
-
|
|
46
|
-
How the call and its result look in the transcript — the call line as a headline
|
|
47
|
-
and the body indented under it:
|
|
48
|
-
|
|
49
47
|
<img src="../../assets/tools/read_doc.png" alt="The read_doc tool's result: the call line and an indented body with the file path, format, size, and the extracted text preview" width="100%">
|
|
50
48
|
|
|
49
|
+
`read_doc` — direct exposure, active by default, read-only, closed-world (no
|
|
50
|
+
network). It takes one file and returns that file's text.
|
|
51
|
+
|
|
51
52
|
| Parameter | Type | Meaning |
|
|
52
53
|
|---|---|---|
|
|
53
54
|
| `path` | string, required, 1–4096 chars | Path to a `.pdf`, `.docx`, `.doc`, `.odt`, `.rtf`, or `.xlsx`, relative to the working directory (or absolute inside it). |
|
|
@@ -74,14 +75,8 @@ the text says what the file was.
|
|
|
74
75
|
|
|
75
76
|
Errors are thrown for: a missing or non-file path, a path outside the root, an
|
|
76
77
|
unsupported extension (with a targeted hint for legacy `.xls`), a disabled
|
|
77
|
-
format, an over-size file, and a parser that rejects the file.
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
## Behaviour by mode
|
|
81
|
-
|
|
82
|
-
The tool behaves identically in `tui`, RPC, JSON, and print modes; it has no
|
|
83
|
-
widgets or status output. `renderCall` / `renderResult` affect only the
|
|
84
|
-
interactive transcript (and HTML exports).
|
|
78
|
+
format, an over-size file, and a parser that rejects the file. No external
|
|
79
|
+
executable is installed.
|
|
85
80
|
|
|
86
81
|
The call line carries the path (`~`-shortened, OSC-8 linked when the terminal
|
|
87
82
|
supports it) and any paging options. The result line drops the path — it is
|
|
@@ -117,11 +112,18 @@ applied, so the theme's own ANSI codes stay intact. A host-rejected call (a
|
|
|
117
112
|
permission block, a validation failure) renders its own message through the same
|
|
118
113
|
sanitized error path.
|
|
119
114
|
|
|
115
|
+
## Behaviour by mode
|
|
116
|
+
|
|
117
|
+
The tool behaves identically in `tui`, RPC, JSON, and print modes; it has no
|
|
118
|
+
widgets or status output. `renderCall` / `renderResult` affect only the
|
|
119
|
+
interactive transcript (and HTML exports).
|
|
120
|
+
|
|
120
121
|
## Configuration
|
|
121
122
|
|
|
122
|
-
The `file-read` section of the shared `bytefly.json
|
|
123
|
-
|
|
124
|
-
|
|
123
|
+
The keys live in the `file-read` section of the shared `bytefly.json`; resolution
|
|
124
|
+
rules are in
|
|
125
|
+
[`../configuration.md`](../configuration.md#file-read--document-and-spreadsheet-extraction).
|
|
126
|
+
Each value is merged over the defaults and clamped:
|
|
125
127
|
|
|
126
128
|
| Key | Default | Clamp | Meaning |
|
|
127
129
|
|---|---|---|---|
|
|
@@ -163,16 +165,17 @@ reads only `file-read`, and `bun run config:migrate` renames an existing
|
|
|
163
165
|
|
|
164
166
|
## Extraction
|
|
165
167
|
|
|
166
|
-
Each extractor builds a plain-text document from the format's bytes
|
|
168
|
+
Each extractor builds a plain-text document from the format's bytes. Every
|
|
169
|
+
format is enabled by default; `file-read.formats` turns one off.
|
|
167
170
|
|
|
168
|
-
| Format | Library | Output normalization |
|
|
169
|
-
|
|
170
|
-
| PDF | `unpdf` (`extractText`, `mergePages: true`) | Every page in reading order, pages separated by a blank line. No OCR: a scanned or image-only PDF yields little or no text. |
|
|
171
|
-
| DOCX | `mammoth` (`extractRawText`) | The body story, paragraphs separated by blank lines. Headers, footers, footnotes, and comments are not included. |
|
|
172
|
-
| DOC | `word-extractor` (OLE body) | The classic Word body story. |
|
|
173
|
-
| ODT | `fflate` + `fast-xml-parser` | `content.xml` is unzipped and walked: paragraphs and headings are lines, table cells are tab-separated, and `text:s` / `text:tab` / `text:line-break` become their whitespace. |
|
|
174
|
-
| RTF | `rtf-parser` | Paragraphs are flattened to their span text; formatting is dropped. |
|
|
175
|
-
| XLSX | `exceljs` | One `[Sheet]` heading per non-empty worksheet, then tab-separated rows. Dates and numbers use the workbook's displayed text; formulas show their computed value. Cell formatting is dropped. |
|
|
171
|
+
| Format | Extensions | Library | Output normalization |
|
|
172
|
+
|---|---|---|---|
|
|
173
|
+
| PDF | `.pdf` | `unpdf` (`extractText`, `mergePages: true`) | Every page in reading order, pages separated by a blank line. No OCR: a scanned or image-only PDF yields little or no text. |
|
|
174
|
+
| DOCX | `.docx` | `mammoth` (`extractRawText`) | The body story, paragraphs separated by blank lines. Headers, footers, footnotes, and comments are not included. |
|
|
175
|
+
| DOC | `.doc` | `word-extractor` (OLE body) | The classic Word body story. |
|
|
176
|
+
| ODT | `.odt` | `fflate` + `fast-xml-parser` | `content.xml` is unzipped and walked: paragraphs and headings are lines, table cells are tab-separated, and `text:s` / `text:tab` / `text:line-break` become their whitespace. |
|
|
177
|
+
| RTF | `.rtf` | `rtf-parser` | Paragraphs are flattened to their span text; formatting is dropped. |
|
|
178
|
+
| XLSX | `.xlsx` | `exceljs` | One `[Sheet]` heading per non-empty worksheet, then tab-separated rows. Dates and numbers use the workbook's displayed text; formulas show their computed value. Cell formatting is dropped. |
|
|
176
179
|
|
|
177
180
|
The tool is pageable across the whole extracted text, so a word-processing
|
|
178
181
|
document or a workbook is read in the same `startIndex` / `maxChars` way as a PDF.
|
|
@@ -181,17 +184,6 @@ Each call is bounded by `extractTimeoutMs` (30 s by default). A parser that
|
|
|
181
184
|
outlasts the deadline is abandoned — the read fails with the limit named, and a
|
|
182
185
|
late result is discarded — so a pathological file cannot park the turn.
|
|
183
186
|
|
|
184
|
-
## Supported formats
|
|
185
|
-
|
|
186
|
-
| Format | Extensions | Extractor | Enabled by default |
|
|
187
|
-
|---|---|---|---|
|
|
188
|
-
| PDF | `.pdf` | `unpdf` | yes |
|
|
189
|
-
| DOCX | `.docx` | `mammoth` | yes |
|
|
190
|
-
| DOC | `.doc` | `word-extractor` | yes |
|
|
191
|
-
| ODT | `.odt` | `fflate` + `fast-xml-parser` | yes |
|
|
192
|
-
| RTF | `.rtf` | `rtf-parser` | yes |
|
|
193
|
-
| XLSX | `.xlsx` | `exceljs` | yes |
|
|
194
|
-
|
|
195
187
|
## Adding a format
|
|
196
188
|
|
|
197
189
|
The format table in `formats.ts` is the single source of truth; the handler,
|
|
@@ -208,7 +200,7 @@ config defaults, and error listing all derive from it.
|
|
|
208
200
|
3. Add a `ReadFormat` entry to `FORMATS` and widen the `id` union.
|
|
209
201
|
4. Add the new extractor to `extract/extract.test.ts` with a real minimal
|
|
210
202
|
fixture, and extend `tool.test.ts` for format selection and config.
|
|
211
|
-
5. Add a row to the
|
|
203
|
+
5. Add a row to the format table above.
|
|
212
204
|
|
|
213
205
|
`tool.ts`, `paging.ts`, and the config normalizer need no changes.
|
|
214
206
|
|
|
@@ -318,4 +310,4 @@ builds a genuine PDF, DOCX, and ODT; XLSX is written with `exceljs`; legacy `.do
|
|
|
318
310
|
reads the committed `files/legacy.doc`), so the libraries are exercised, not
|
|
319
311
|
stubbed. `tool.test.ts` injects fake extractors for behavioural cases and reads a
|
|
320
312
|
real PDF and a real `.doc` end to end; `test/helpers/fixtures/file-read.ts`
|
|
321
|
-
provides the scratch root and an escape symlink.
|
|
313
|
+
provides the scratch root and an escape symlink.
|
|
@@ -1,7 +1,27 @@
|
|
|
1
1
|
# goal — a persistent session objective for Pi
|
|
2
2
|
|
|
3
3
|
A single high-level objective for the session, kept visible and restated before
|
|
4
|
-
every turn. The goal is the *what*; the [`todo`](
|
|
4
|
+
every turn. The goal is the *what*; the [`todo`](./todo.md) list is the *how*.
|
|
5
|
+
|
|
6
|
+
## Capabilities
|
|
7
|
+
|
|
8
|
+
Status records what a reader can rely on: **Shipped** is in a tagged release, **Unreleased** is complete in the current tree but not yet tagged, and **Partial** has one released part and one unreleased part. Rows are ordered by user value, highest first.
|
|
9
|
+
|
|
10
|
+
| Capability | How | What you get | Status |
|
|
11
|
+
|---|---|---|---|
|
|
12
|
+
| Goal recording | `goal`, `/goal set`, `/goal raw`, `/goal clear` | The objective is replaced whole, cleared by an empty value, and recorded verbatim when you ask for it. | Shipped |
|
|
13
|
+
| Phase tracking | `goal`, `/goal done` | The goal is `planning`, `active`, or `achieved`, and only the workflow can open a draft. | Shipped |
|
|
14
|
+
| Plan-first question | `goal`, `/goal <prompt>`, `/goal raw` | One dialog decides whether a new goal enters plan mode before it is pursued. | Shipped |
|
|
15
|
+
| Plan-mode allowlist | `goal` in plan mode | The model can record or update the objective while plan mode keeps the rest of the session read-only. | Shipped |
|
|
16
|
+
| Plan-phase settlement | `planning` goal, `exit_plan_mode` | Leaving plan mode without approval makes the draft `active`; approving the plan writes its `## Goal` into it. | Shipped |
|
|
17
|
+
| Understanding loop | `/goal <prompt>`, `/goal set`, `/goal edit` | A typed goal is restated, questioned when it is unclear, and confirmed in the editor before it is recorded. | Shipped |
|
|
18
|
+
| Goal rail | the `Goal · active · …` widget, the `achieved` key | The objective stays one line above the editor while it is pursued. | Shipped |
|
|
19
|
+
| Per-turn restatement | the `[SESSION GOAL]` reminder | The model reads the pursued objective before each turn, without it entering the transcript. | Shipped |
|
|
20
|
+
| Open-list check | `goal`, `/goal done` | Completing the goal names the todo items the list still has open. | Shipped |
|
|
21
|
+
| Branch-following state | tool-result `details`, the `goal` session entry | The goal survives `/resume` and `/tree`, and abandoned branches never leak in. | Shipped |
|
|
22
|
+
| Command help | `/goal help`, `/goal -h`, `/goal --help` | The verb list and the usage of each form, without changing the goal. | Shipped |
|
|
23
|
+
|
|
24
|
+
## Quickstart
|
|
5
25
|
|
|
6
26
|
```bash
|
|
7
27
|
pi --extension ./extensions/goal # load just this extension
|
|
@@ -9,86 +29,29 @@ pi -e . # load the whole @gavin-hu/my-pi-agent packa
|
|
|
9
29
|
pi install ./ # install the package
|
|
10
30
|
```
|
|
11
31
|
|
|
12
|
-
|
|
32
|
+
```text
|
|
33
|
+
/goal # show the goal, or the usage when none is set
|
|
34
|
+
/goal Refactor the parser to support streaming input
|
|
35
|
+
```
|
|
13
36
|
|
|
14
|
-
|
|
37
|
+
The model records the same objective with `goal`; the model-facing tool never
|
|
38
|
+
runs the understanding loop.
|
|
15
39
|
|
|
16
|
-
|
|
40
|
+
## Tool
|
|
17
41
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
- Registers one model-callable tool, `goal`, that records the session
|
|
21
|
-
objective. Send the complete objective every call; an empty objective clears
|
|
22
|
-
it.
|
|
23
|
-
- Tracks the goal's **phase**, not a flag: `planning` while a plan is being
|
|
24
|
-
designed, `active` once the objective is final, `achieved` when it is done.
|
|
25
|
-
A model-issued call may only send `active` or `achieved`, so one call can never
|
|
26
|
-
claim a plan that does not exist.
|
|
27
|
-
- **Asks once whether to plan first** when a new goal is recorded: accepting
|
|
28
|
-
enters plan mode and stores the objective as `planning`, declining stores it
|
|
29
|
-
`active`. The `plan` extension owns the mode; the question and its consent
|
|
30
|
-
sentence come from `lib/plan-entry.ts`, the same ones `enter_plan_mode` shows,
|
|
31
|
-
so the user answers once. The question is skipped for an update to a goal that
|
|
32
|
-
is already pursued, without a dialog UI, or when `plan` is not loaded.
|
|
33
|
-
- **Settles a draft whose plan never arrived.** If plan mode is left without an
|
|
34
|
-
approved plan — the toggle, the shortcut, a resumed branch — the `planning`
|
|
35
|
-
goal becomes `active` with its own wording on the next observation, so the
|
|
36
|
-
phase can never get stuck. Approval is different: `plan` sets the goal from the
|
|
37
|
-
plan's own `## Goal` section (see the [`plan`](../plan/) docs).
|
|
38
|
-
- Achieves a goal over an open list knowingly: completing it while the branch's
|
|
39
|
-
todo list still has open items names the count in the result (`1 todo item is
|
|
40
|
-
still open…`), so the model closes the *how* instead of declaring the *what*
|
|
41
|
-
done over an unfinished list; `/goal done` appends the same sentence to its
|
|
42
|
-
notice. The count is read from the branch through `lib/todo-state.ts`; the
|
|
43
|
-
structured result is unchanged.
|
|
44
|
-
- Shows a persistent one-line rail above the editor whenever a goal exists,
|
|
45
|
-
label-first to match the [`todo`](../todo/) widget, pinned at the top of the
|
|
46
|
-
`Goal / Todos` stack when both are loaded:
|
|
47
|
-
|
|
48
|
-
```
|
|
49
|
-
Goal · active · Refactor the parser to support streaming input and ship it …
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
Once achieved the goal is hidden from the widget by default, matching a
|
|
53
|
-
completed todo list; the transcript keeps the record. Set `achieved: "show"`
|
|
54
|
-
in the `goal` section of `bytefly.json` to keep drawing the dimmed line
|
|
55
|
-
instead.
|
|
56
|
-
|
|
57
|
-
- Restates a **pursued** goal to the model before each turn (an invisible
|
|
58
|
-
`[SESSION GOAL]` message) — `planning` and `active` alike, so a plan is designed
|
|
59
|
-
against the objective — and stops once it is achieved.
|
|
60
|
-
- Stores tool-set goals in tool-result `details` and command-set goals as a
|
|
61
|
-
`goal` session entry, so either way the goal follows the active session branch
|
|
62
|
-
and survives `/resume` and `/tree` — a `planning` draft included, since it is
|
|
63
|
-
written the same way. Abandoned branches never leak into the current goal.
|
|
64
|
-
- Understands the goal before recording it: `/goal <prompt>` asks the session
|
|
65
|
-
model to restate the goal as it understands it and, when it cannot yet, to ask
|
|
66
|
-
up to three questions — which the command asks directly through host dialogs
|
|
67
|
-
(`select` / `input`). The answers are carried into the editor under the
|
|
68
|
-
restatement, below a `--- notes (not saved) ---` line, so accepting the
|
|
69
|
-
restatement as-is records the goal alone; folding an answer into the sentence
|
|
70
|
-
above the line keeps it. `/goal set
|
|
71
|
-
<prompt>` reuses the loop but records without starting a turn, `/goal edit`
|
|
72
|
-
changes the current goal in place, and `/goal raw <prompt>` records the typed
|
|
73
|
-
words verbatim. The loop is best-effort and needs a dialog UI plus a model; the
|
|
74
|
-
`goal` tool stays the silent setter.
|
|
42
|
+
<img src="../../assets/tools/goal.png" alt="The goal tool's result: the call line and an indented body with the Goal header and the objective body" width="100%">
|
|
75
43
|
|
|
76
|
-
|
|
44
|
+
`goal` — `exposure: "direct"` (the default), `executionMode: "sequential"`,
|
|
45
|
+
read-write, closed-world, idempotent. It is a whole-goal replacement: the model
|
|
46
|
+
sends the complete objective and the previous goal is discarded.
|
|
77
47
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
48
|
+
| Parameter | Type | Meaning |
|
|
49
|
+
|---|---|---|
|
|
50
|
+
| `objective` | string, required | The complete objective, one line. Pass `""` to clear. |
|
|
51
|
+
| `status` | `active` \| `achieved` | `achieved` completes the goal; `active` records a final objective; omit it to let the workflow ask whether to plan first. `planning` is the workflow's to set; a call cannot. |
|
|
81
52
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
| `name` | `goal` |
|
|
85
|
-
| `objective` | The complete objective, one line. Pass `""` to clear. |
|
|
86
|
-
| `status` | `achieved` completes the goal; `active` records a final objective; omit it to let the workflow ask whether to plan first. `planning` is the workflow's to set; a call cannot. |
|
|
87
|
-
| `exposure` | `direct` (default). |
|
|
88
|
-
| `executionMode` | `sequential` — calls share the in-memory goal. |
|
|
89
|
-
| `annotations` | `idempotentHint: true` (a snapshot write), not read-only. |
|
|
90
|
-
| `outputSchema` | `GoalResult` — `{ goal, action, error? }`, also returned as `structuredContent`. |
|
|
91
|
-
| `promptGuidelines` | Carry the when-to-use rule and the mark-achieved-with-a-blank-objective rule; the replacement/clear semantics live in the description. |
|
|
53
|
+
Result (`details` / `structuredContent`): `{ goal, action, error? }`, with
|
|
54
|
+
`goal: null` after a clear.
|
|
92
55
|
|
|
93
56
|
Validation (a violation returns an error result and leaves the goal unchanged):
|
|
94
57
|
a known `status`, an objective of at most 2000 characters, and a non-blank
|
|
@@ -109,19 +72,22 @@ whether the todos were written by the model, by `/todos`, or by an approved
|
|
|
109
72
|
plan. It is text only: `details`, `structuredContent`, and the transcript header
|
|
110
73
|
are unaffected.
|
|
111
74
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
75
|
+
The transcript result is the status header alone, directly under the call line
|
|
76
|
+
that names the objective:
|
|
77
|
+
|
|
78
|
+
```
|
|
79
|
+
goal → set: Refactor the parser to support streaming input
|
|
80
|
+
Goal · active
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
The renderer reuses the slot's component (`context.lastComponent`) rather than
|
|
84
|
+
rebuilding it each render.
|
|
119
85
|
|
|
120
|
-
|
|
86
|
+
## Commands
|
|
121
87
|
|
|
122
88
|
The command has no tool result, so it persists each change as a `goal` custom
|
|
123
89
|
entry; `reconstructGoal` replays both entry kinds in branch order through
|
|
124
|
-
`lib/goal-state.ts`, so its readers agree.
|
|
90
|
+
`lib/goal-state.ts`, so its readers agree. `/goal` completes each verb.
|
|
125
91
|
|
|
126
92
|
| Command | What it does |
|
|
127
93
|
|---|---|
|
|
@@ -134,50 +100,28 @@ entry; `reconstructGoal` replays both entry kinds in branch order through
|
|
|
134
100
|
| `/goal clear` | Clear the goal. |
|
|
135
101
|
| `/goal help` (or `-h` / `--help`) | Show the command usage. |
|
|
136
102
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
one at a time with `ctx.ui.select` (for a question with options) and
|
|
144
|
-
`ctx.ui.input` (for a free-form one); the command never calls
|
|
145
|
-
`ask_user_question`. A bare `/goal set` and `/goal edit` need a dialog UI —
|
|
146
|
-
without one they show the usage instead. `/goal raw` never needs one for the
|
|
147
|
-
words, but the plan question does need a dialog: both run variants ask it only
|
|
148
|
-
where a dialog UI exists, and record `active` otherwise. The record-only paths
|
|
149
|
-
never ask; a goal recorded while plan mode is already on is still a draft
|
|
150
|
-
(`planning`), because that is what it is.
|
|
103
|
+
The questions and the confirm step are host dialogs, forwarded by RPC, so the
|
|
104
|
+
loop needs one; in print and JSON mode the typed text is set and run unchanged.
|
|
105
|
+
A dismissed question or editor cancels the command, changing nothing. The
|
|
106
|
+
[`plan`](./plan.md) extension owns plan mode, so the plan question is skipped
|
|
107
|
+
when it is not loaded, and a bare `/goal set` shows the usage instead of an
|
|
108
|
+
editor when there is no dialog UI.
|
|
151
109
|
|
|
152
110
|
## Behaviour by mode
|
|
153
111
|
|
|
154
112
|
The tool works in every mode. The persistent widget requires interactive
|
|
155
113
|
(`tui`) mode; the reminder and the `/goal` command work everywhere. The
|
|
156
|
-
`/goal <prompt>`
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
asked only in TUI and RPC, and skipped when the `plan` extension is not loaded.
|
|
161
|
-
The widget is always a single line; the transcript result is the status header
|
|
162
|
-
alone, directly under the call line that names the objective:
|
|
163
|
-
|
|
164
|
-
```
|
|
165
|
-
goal → set: Refactor the parser to support streaming input
|
|
166
|
-
Goal · active
|
|
167
|
-
```
|
|
168
|
-
|
|
169
|
-
The renderer reuses the slot's component (`context.lastComponent`) rather than
|
|
170
|
-
rebuilding it each render. A `planning` goal shows the same rail with a warning
|
|
171
|
-
status word and is restated; achieved goals are hidden from the widget by
|
|
172
|
-
default (restore the dimmed line with `achieved: "show"`), and they are no
|
|
173
|
-
longer restated to the model. While a dock screen is open (`/todos`, `/jobs`,
|
|
174
|
-
`/rewind`, or the `question` questionnaire), the rail is hidden and
|
|
114
|
+
`/goal <prompt>` comprehension call uses a cancellable `tui` spinner in
|
|
115
|
+
interactive mode and runs directly in RPC. When a goal exists, the widget is
|
|
116
|
+
always a single line above the editor; while a dock screen is open (`/todos`,
|
|
117
|
+
`/jobs`, `/rewind`, or the `question` questionnaire), the rail is hidden and
|
|
175
118
|
returns on close.
|
|
176
119
|
|
|
177
120
|
## Configuration
|
|
178
121
|
|
|
179
122
|
The widget presentation is configurable from the `goal` section of the shared
|
|
180
|
-
`bytefly.json
|
|
123
|
+
`bytefly.json`; resolution rules are in
|
|
124
|
+
[`../configuration.md`](../configuration.md#goal--the-goal-widget).
|
|
181
125
|
|
|
182
126
|
| Key | Default | Meaning |
|
|
183
127
|
|---|---|---|
|
|
@@ -186,6 +130,53 @@ The widget presentation is configurable from the `goal` section of the shared
|
|
|
186
130
|
Malformed documents and invalid values are ignored, and goal behavior never
|
|
187
131
|
depends on config.
|
|
188
132
|
|
|
133
|
+
## Plan entry
|
|
134
|
+
|
|
135
|
+
A new goal's phase is decided once, with one dialog. Accepting enters plan mode
|
|
136
|
+
and stores the objective as `planning`, so a plan can be designed against it;
|
|
137
|
+
declining stores it `active`, the final objective. The question is skipped for
|
|
138
|
+
an update to a goal that is already pursued, without a dialog UI, and when
|
|
139
|
+
`plan` is not loaded. The question and its consent sentence come from
|
|
140
|
+
`lib/plan-entry.ts`, the same ones `enter_plan_mode` shows, so the user answers
|
|
141
|
+
once.
|
|
142
|
+
|
|
143
|
+
A draft whose plan never arrived is settled rather than stranded. If plan mode is
|
|
144
|
+
left without an approved plan — the toggle, the shortcut, a resumed branch — the
|
|
145
|
+
`planning` goal becomes `active` with its own wording on the next observation, so
|
|
146
|
+
the phase can never get stuck. Approval is different: `plan` sets the goal from
|
|
147
|
+
the plan's own `## Goal` section (see the [`plan`](./plan.md) docs), and only a
|
|
148
|
+
`planning` goal is eligible, so a final objective is the user's.
|
|
149
|
+
|
|
150
|
+
`goal` is allowlisted in `plan-mode` (alongside `todo`), so the model can record
|
|
151
|
+
or update the objective during read-only exploration without leaving plan mode.
|
|
152
|
+
Plan mode also reads the goal: it restates a pursued one in its injected context,
|
|
153
|
+
it promotes a `planning` goal when a plan is approved, and it offers to record the
|
|
154
|
+
plan's `## Goal` when the session has none (`lib/goal-state.ts` is the reader). An
|
|
155
|
+
`active` or `achieved` goal — a final objective — is never rewritten by an
|
|
156
|
+
approval.
|
|
157
|
+
|
|
158
|
+
## The understanding loop
|
|
159
|
+
|
|
160
|
+
`/goal <prompt>` asks the session model to restate the goal as it understands it
|
|
161
|
+
and, when it cannot yet, to ask up to three questions, which the command asks
|
|
162
|
+
directly through host dialogs (`select` / `input`). The answers are carried into
|
|
163
|
+
the editor under the restatement, below a `--- notes (not saved) ---` line, so
|
|
164
|
+
accepting the restatement as-is records the goal alone; folding an answer into
|
|
165
|
+
the sentence above the line keeps it. `/goal set <prompt>` reuses the loop but
|
|
166
|
+
records without starting a turn, and `/goal raw <prompt>` records the typed words
|
|
167
|
+
verbatim.
|
|
168
|
+
|
|
169
|
+
The loop is best-effort and needs a dialog UI plus a model. A plain-text clarifier
|
|
170
|
+
reply is treated as a restatement, so a model that ignores the JSON instruction
|
|
171
|
+
still works; a failed, timed-out, or unusable comprehension notices the user and
|
|
172
|
+
keeps the typed text. The questions are asked one at a time with `ctx.ui.select`
|
|
173
|
+
(for a question with options) and `ctx.ui.input` (for a free-form one); the
|
|
174
|
+
command never calls `ask_user_question`. `/goal raw` never needs a dialog for the
|
|
175
|
+
words, but the plan question does: both run variants ask it only where a dialog
|
|
176
|
+
UI exists, and record `active` otherwise. The record-only paths never ask, and a
|
|
177
|
+
goal recorded while plan mode is already on is still a draft (`planning`), because
|
|
178
|
+
that is what it is. The `goal` tool stays the silent setter.
|
|
179
|
+
|
|
189
180
|
## Non-goals
|
|
190
181
|
|
|
191
182
|
- No multiple or nested goals — one objective per session.
|
|
@@ -246,19 +237,12 @@ depends on config.
|
|
|
246
237
|
record and stops the reminder, which a single empty-clear cannot express.
|
|
247
238
|
- **The command runs the understanding loop.** `/goal <prompt>` is the
|
|
248
239
|
user-driven path: one comprehension call (`clarify-prompt.ts` + `clarify.ts`)
|
|
249
|
-
returns `{ understood, goal, questions }`.
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
the
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
`/goal set`
|
|
256
|
-
reuses the loop but skips the send; a bare `/goal set` or `/goal edit` opens
|
|
257
|
-
the editor prefilled with the current goal; and `/goal raw` skips the loop
|
|
258
|
-
entirely. The loop is best-effort (a failure keeps the typed text) and a
|
|
259
|
-
dismissed dialog cancels the command, so nothing is half-applied. No
|
|
260
|
-
conversation history is sent: the model must not invent scope the user did not
|
|
261
|
-
state. The `goal` tool remains the model's setter, with no comprehension loop.
|
|
240
|
+
returns `{ understood, goal, questions }`. No second model call rewrites the
|
|
241
|
+
goal, so the user is the one who folds an answer into the sentence, above the
|
|
242
|
+
sentinel line, when they want it kept; and no conversation history is sent, so
|
|
243
|
+
the model cannot invent scope the user did not state. The loop is best-effort
|
|
244
|
+
and a dismissed dialog cancels the command, so nothing is half-applied. The
|
|
245
|
+
`goal` tool remains the model's setter, with no comprehension loop.
|
|
262
246
|
- **State in `details` and a custom entry.** A `goal` tool call stores the goal
|
|
263
247
|
in its result's `details`; the `/goal` command appends a `goal` custom entry
|
|
264
248
|
(`pi.appendEntry`). `reconstructGoal` reads the branch through
|