@pmelab/gtd 6.9.1 → 6.10.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 CHANGED
@@ -144,14 +144,16 @@ importantly: gitignore everything your scripts write.
144
144
 
145
145
  Editor integration: `gtd lsp` starts an LSP server over stdio for `.gtd/`
146
146
  steering files — symbols and check/uncheck actions over a `review`-mode file's
147
- chunks, symbols over a `qa`-mode file's open questions, diagnostics for both
148
- (live as you edit), and a `gtd.openSteeringFile` command that jumps to the
149
- current state's steering file. Config-driven via each state's `file:`/`mode:`
150
- (see [CLI reference](docs/cli.md#gtd-lsp)) — falls back to basename dispatch
151
- (`TODO.md`/`REVIEW.md`) with no config in sight. Those two formats are gtd's
152
- built-in steering-file MODES — validators, not formatters: a mode's `format:`
153
- and `validate:` are shell commands a workflow (or a project's `.gtdrc`) declares
154
- for itself, so you bring your own formatter and your own checkers (see
147
+ chunks, go-to-definition from a `review`-mode hunk line into the file it points
148
+ at (at its `#line`), symbols over a `qa`-mode file's open questions, diagnostics
149
+ for both (live as you edit), and a `gtd.openSteeringFile` command that jumps to
150
+ the current state's steering file. Config-driven via each state's
151
+ `file:`/`mode:` (see [CLI reference](docs/cli.md#gtd-lsp)) — falls back to
152
+ basename dispatch (`TODO.md`/`REVIEW.md`) with no config in sight. Those two
153
+ formats are gtd's built-in steering-file MODES — validators, not formatters: a
154
+ mode's `format:` and `validate:` are shell commands a workflow (or a project's
155
+ `.gtdrc`) declares for itself, so you bring your own formatter and your own
156
+ checkers (see
155
157
  [Configuration](docs/configuration.md#modes--pluggable-steering-file-modes)).
156
158
  Both halves are enforced by `gtd validate` and the `gtd step` gate.
157
159
 
@@ -203725,11 +203725,22 @@ const parseReviewDoc = (content) => {
203725
203725
  /**
203726
203726
  * LSP server for `.gtd/` steering files — document symbols for a `qa`-mode
203727
203727
  * file's open questions and a `review`-mode file's review chunks/hunks, code
203728
- * actions to check/uncheck a hunk or a whole chunk, and diagnostics publishing
203729
- * the same parsers' `errors` the `gtd validate` CLI command reports (see
203730
- * `src/OpenQuestions.ts` / `src/ReviewDoc.ts`'s module docs — those parsers
203731
- * are each format's single source of truth, shared by this server and the
203732
- * command).
203728
+ * actions to check/uncheck a hunk or a whole chunk, go-to-definition from a
203729
+ * `review`-mode hunk line into the file it points at, and diagnostics
203730
+ * publishing the same parsers' `errors` the `gtd validate` CLI command reports
203731
+ * (see `src/OpenQuestions.ts` / `src/ReviewDoc.ts`'s module docs — those
203732
+ * parsers are each format's single source of truth, shared by this server and
203733
+ * the command).
203734
+ *
203735
+ * GO-TO-DEFINITION (`textDocument/definition`, `review`-mode only): the cursor
203736
+ * on a hunk pointer line (`- [ ] ./src/foo.ts#42`) jumps to `./src/foo.ts` at
203737
+ * line 42 (`hunkDefinitionLocation`). The `./`-relative path resolves against
203738
+ * the git toplevel of the file's own directory (`tryGitTopLevel`), falling
203739
+ * back to the workspace root — never the document's own `.gtd/` directory — so
203740
+ * a repo-root-relative diff path lands correctly even with no workspace folder
203741
+ * open; no target is returned when neither anchor resolves. The `#line` is
203742
+ * 1-based (a bare `./path` lands at the top of the file); the target file is
203743
+ * not stat-ed, so a stale pointer still jumps and the editor reports the miss.
203733
203744
  *
203734
203745
  * CONFIG-DRIVEN (see `docs/design/state-file-association.md` §3): the server
203735
203746
  * locates the active gtd config the SAME way the CLI does (`ConfigService`'s
@@ -203941,6 +203952,40 @@ const reviewCodeActions = (uri, content, range) => {
203941
203952
  });
203942
203953
  return actions;
203943
203954
  };
203955
+ /**
203956
+ * Go-to-definition target for a `.gtd/REVIEW.md` hunk line: the file the hunk
203957
+ * pointer at `line` (0-based, `params.position.line`) points into. `root` is
203958
+ * the repo the `./`-relative hunk paths were authored against (the git
203959
+ * toplevel of REVIEW.md's directory — see `resolveDefinitionRoot`). Returns
203960
+ * `undefined` when `line` isn't a parsed hunk pointer (a heading, prose, or a
203961
+ * malformed line has no `sourceLine`), so the provider yields no target there.
203962
+ *
203963
+ * The `#line` in a pointer is 1-based (git/human line numbers); LSP positions
203964
+ * are 0-based, so it maps to `line - 1`. A bare `./path` with no `#line` lands
203965
+ * at the top of the file (line 0). The range is collapsed (a cursor, not a
203966
+ * selection) and the target file is NOT stat-ed — a stale/deleted/`../`-escaping
203967
+ * path still returns a Location and the editor reports the miss itself. Pure —
203968
+ * no git, no protocol, unit-testable directly.
203969
+ */
203970
+ const hunkDefinitionLocation = (content, line, root) => {
203971
+ const { changesets } = parseReviewDoc(content);
203972
+ const hunk = changesets.flatMap((chunk) => chunk.files).find((file) => file.sourceLine === line);
203973
+ if (!hunk) return void 0;
203974
+ const targetLine = hunk.line !== void 0 ? hunk.line - 1 : 0;
203975
+ return {
203976
+ uri: pathToFileURL(resolve(root, hunk.path)).toString(),
203977
+ range: {
203978
+ start: {
203979
+ line: targetLine,
203980
+ character: 0
203981
+ },
203982
+ end: {
203983
+ line: targetLine,
203984
+ character: 0
203985
+ }
203986
+ }
203987
+ };
203988
+ };
203944
203989
  /** The basename dispatch this server has always had — the fallback for any path the active workflow's `file:` map doesn't cover (or when no config resolves at all). */
203945
203990
  const basenameFallbackMode = (name) => {
203946
203991
  if (name === "TODO.md") return "qa";
@@ -204057,6 +204102,21 @@ const loadModeMap = async (root, onWarn) => {
204057
204102
  }
204058
204103
  };
204059
204104
  /**
204105
+ * The git working-tree root of `dir` (`git rev-parse --show-toplevel`), or
204106
+ * `undefined` when `dir` is outside any repository. This is the anchor a
204107
+ * hunk's `./`-relative path resolves against — the repo the review diff's
204108
+ * paths were authored against (`GitService.topLevel()`, the same op the CLI
204109
+ * uses). Any failure resolves to `undefined` so the caller can fall back to
204110
+ * the workspace root.
204111
+ */
204112
+ const tryGitTopLevel = async (dir) => {
204113
+ try {
204114
+ return await runPromise(GitService.pipe(flatMap$4((git) => git.topLevel()), provide$1(gitLayerForRoot(dir))));
204115
+ } catch {
204116
+ return;
204117
+ }
204118
+ };
204119
+ /**
204060
204120
  * Resolve the CURRENT state/actor and its `file:` (rendered), exactly like
204061
204121
  * the CLI (`resolveRest`/`computeProcessRun`/`buildTemplateContext` — the
204062
204122
  * same `src/Edge.ts` helpers `gtd status`/`gtd next` call), scoped to `root`.
@@ -204098,6 +204158,7 @@ const startLspServer = () => gen(function* () {
204098
204158
  textDocumentSync: import_main.TextDocumentSyncKind.Incremental,
204099
204159
  documentSymbolProvider: true,
204100
204160
  codeActionProvider: true,
204161
+ definitionProvider: true,
204101
204162
  executeCommandProvider: { commands: [OPEN_STEERING_FILE_COMMAND] }
204102
204163
  } };
204103
204164
  });
@@ -204118,6 +204179,15 @@ const startLspServer = () => gen(function* () {
204118
204179
  if (modeForDocument(document.uri, map) !== "review") return [];
204119
204180
  return reviewCodeActions(document.uri, document.getText(), params.range);
204120
204181
  });
204182
+ connection.onDefinition(async (params) => {
204183
+ const document = documents.get(params.textDocument.uri);
204184
+ if (!document) return [];
204185
+ const map = await loadModeMap(rootFor(document.uri), warn);
204186
+ if (modeForDocument(document.uri, map) !== "review") return [];
204187
+ const root = await tryGitTopLevel(dirname(fileURLToPath(document.uri))) ?? workspaceRoot;
204188
+ if (root === void 0) return [];
204189
+ return hunkDefinitionLocation(document.getText(), params.position.line, root) ?? [];
204190
+ });
204121
204191
  connection.onExecuteCommand(async (params) => {
204122
204192
  if (params.command !== OPEN_STEERING_FILE_COMMAND) return null;
204123
204193
  const root = workspaceRoot ?? process.cwd();
package/docs/cli.md CHANGED
@@ -391,9 +391,12 @@ are rejected).
391
391
 
392
392
  Starts an LSP server over stdio for `.gtd/` steering files — document symbols
393
393
  for a `qa`-mode file's open questions and a `review`-mode file's review
394
- chunks/hunks, code actions to check/uncheck a hunk or a whole chunk, and
395
- diagnostics publishing the same parser findings `gtd validate` reports (see
396
- `src/OpenQuestions.ts` / `src/ReviewDoc.ts` and
394
+ chunks/hunks, code actions to check/uncheck a hunk or a whole chunk,
395
+ go-to-definition (`textDocument/definition`) from a `review`-mode hunk pointer
396
+ line into the file it points at (at its 1-based `#line`, or the top of the file
397
+ for a bare `./path`; the `./`-relative path resolves against the repo's git
398
+ toplevel), and diagnostics publishing the same parser findings `gtd validate`
399
+ reports (see `src/OpenQuestions.ts` / `src/ReviewDoc.ts` and
397
400
  [STATES.md §12](../STATES.md#12-steering-file-validation-gtd-validate)).
398
401
 
399
402
  **Config-driven** (see
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pmelab/gtd",
3
- "version": "6.9.1",
3
+ "version": "6.10.0",
4
4
  "private": false,
5
5
  "description": "Git-aware CLI that emits the next prompt for an autonomous coding agent based on the current repository state",
6
6
  "bin": {