@floh-solutions/pharos-cli 0.23.0 → 0.25.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 +409 -5
- package/dist/capabilities.d.ts.map +1 -1
- package/dist/capabilities.js +23 -0
- package/dist/capabilities.js.map +1 -1
- package/dist/cli.d.ts +4 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +362 -36
- package/dist/cli.js.map +1 -1
- package/dist/commands/comment-github.d.ts +138 -0
- package/dist/commands/comment-github.d.ts.map +1 -0
- package/dist/commands/comment-github.js +427 -0
- package/dist/commands/comment-github.js.map +1 -0
- package/dist/commands/comment.d.ts.map +1 -1
- package/dist/commands/comment.js +114 -19
- package/dist/commands/comment.js.map +1 -1
- package/dist/commands/doctor.d.ts +71 -2
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +414 -8
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/issue.d.ts +75 -0
- package/dist/commands/issue.d.ts.map +1 -0
- package/dist/commands/issue.js +2466 -0
- package/dist/commands/issue.js.map +1 -0
- package/dist/commands/setup.d.ts +6 -0
- package/dist/commands/setup.d.ts.map +1 -1
- package/dist/commands/setup.js +114 -0
- package/dist/commands/setup.js.map +1 -1
- package/dist/half-link.d.ts +157 -0
- package/dist/half-link.d.ts.map +1 -0
- package/dist/half-link.js +257 -0
- package/dist/half-link.js.map +1 -0
- package/dist/issue-scan.d.ts +383 -0
- package/dist/issue-scan.d.ts.map +1 -0
- package/dist/issue-scan.js +455 -0
- package/dist/issue-scan.js.map +1 -0
- package/dist/output.d.ts +18 -1
- package/dist/output.d.ts.map +1 -1
- package/dist/output.js +293 -0
- package/dist/output.js.map +1 -1
- package/dist/session.d.ts +101 -2
- package/dist/session.d.ts.map +1 -1
- package/dist/session.js +132 -11
- package/dist/session.js.map +1 -1
- package/dist/target.d.ts +40 -4
- package/dist/target.d.ts.map +1 -1
- package/dist/target.js +14 -3
- package/dist/target.js.map +1 -1
- package/package.json +3 -2
- package/skill/SKILL.md +422 -11
package/README.md
CHANGED
|
@@ -71,6 +71,10 @@ A bad token exits **2**, not 1 — retrying it is pure noise. A conflict carries
|
|
|
71
71
|
both revisions, and says out loud that posting a comment bumps `System.Rev`, so
|
|
72
72
|
a rev mismatch is *not* proof that somebody edited the same field.
|
|
73
73
|
|
|
74
|
+
A failure that came from GitHub says so — `"platform": "github"` — because
|
|
75
|
+
`pharos issue` touches two platforms in one call and which one refused is the
|
|
76
|
+
first thing to know. Its absence means Azure DevOps or this tool, as before.
|
|
77
|
+
|
|
74
78
|
## Guards
|
|
75
79
|
|
|
76
80
|
Every verb here is one an agent can call in a loop against a board real people
|
|
@@ -98,6 +102,10 @@ something a caller can skip.
|
|
|
98
102
|
runaway loop becomes a clean refusal rather than 500 work items. `--max-writes 0`
|
|
99
103
|
is read-only: reads work, every write is refused before it is sent.
|
|
100
104
|
|
|
105
|
+
It counts **both platforms**. `pharos issue` writes to Azure DevOps and to
|
|
106
|
+
GitHub in one invocation, and a cap that covered one of them because the other
|
|
107
|
+
left by a different transport would be a cap in name only.
|
|
108
|
+
|
|
101
109
|
It is **not security** — anything that can run this holds the token and can make
|
|
102
110
|
the same REST calls directly. It shapes intent and catches accidents. A
|
|
103
111
|
capability that must be impossible has to be withheld at the token.
|
|
@@ -108,13 +116,18 @@ capability that must be impossible has to be withheld at the token.
|
|
|
108
116
|
task <id> the whole context, in one call
|
|
109
117
|
wiki list | tree | read | write | delete
|
|
110
118
|
comment list | add | edit | delete | react | unreact | reactors
|
|
119
|
+
comment hide | unhide | pin | unpin GitHub only
|
|
120
|
+
issue adopt | link | say | trail | drift | backfill | close
|
|
121
|
+
a GitHub issue and a work item, joined —
|
|
122
|
+
and kept honest
|
|
111
123
|
plan <file> an implementation plan becomes a work item tree
|
|
112
124
|
```
|
|
113
125
|
|
|
114
|
-
`comment` takes
|
|
115
|
-
page is an **absolute path** (`/Plans/Foo`)
|
|
116
|
-
|
|
117
|
-
them apart is also the only
|
|
126
|
+
`comment` takes any of three targets: a work item is its number (`210`), a wiki
|
|
127
|
+
page is an **absolute path** (`/Plans/Foo`), a GitHub issue is
|
|
128
|
+
`owner/name#45`. The leading slash is required by the wiki API itself — it
|
|
129
|
+
answers 404 without one — so the spelling that tells them apart is also the only
|
|
130
|
+
spelling that works, and the three grammars cannot collide.
|
|
118
131
|
|
|
119
132
|
Long text does not belong on a command line:
|
|
120
133
|
|
|
@@ -123,6 +136,327 @@ pharos comment add 210 --file review.md
|
|
|
123
136
|
pharos wiki write /Plans/Sprint-4 --stdin < plan.md
|
|
124
137
|
```
|
|
125
138
|
|
|
139
|
+
### `comment` on a GitHub issue — the surface `gh` half has and half has not
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
pharos comment list contoso/widgets#45 # ids, state, and what you MAY do
|
|
143
|
+
pharos comment edit contoso/widgets#45 900 --file fixed.md
|
|
144
|
+
pharos comment delete contoso/widgets#45 900 --yes
|
|
145
|
+
pharos comment react contoso/widgets#45 900 thumbs-up
|
|
146
|
+
pharos comment hide contoso/widgets#45 900 off-topic
|
|
147
|
+
pharos comment pin contoso/widgets#45 900
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
This is the one place `pharos` reaches past the join, and it is two arguments
|
|
151
|
+
rather than one. **Editing or deleting a comment can destroy the link record**,
|
|
152
|
+
which nothing outside this repo knows to protect. And **hide and pin have no
|
|
153
|
+
`gh` verb at all** — they are GraphQL mutations with no REST route, so they pass
|
|
154
|
+
the same "nothing else can do this" test the `issue` verbs pass. Posting a *new*
|
|
155
|
+
comment is still `gh issue comment` or `pharos issue say`, and `comment add` on
|
|
156
|
+
a GitHub issue is refused with both of those named.
|
|
157
|
+
|
|
158
|
+
**`list` is the load-bearing verb**, and it is not one the macOS app needed: the
|
|
159
|
+
app has a window, an agent has this. Before it there was no way to learn a
|
|
160
|
+
GitHub comment id from this CLI at all, so nothing else here was addressable. It
|
|
161
|
+
prints both ids per comment — the REST number that edit, delete and reactions
|
|
162
|
+
address, and the node id that hide and pin take, because neither is derivable
|
|
163
|
+
from the other — plus a `may` object read from GitHub's own `viewerCan…` fields.
|
|
164
|
+
For a window those grey out a menu item; for an agent they turn a write that
|
|
165
|
+
would 403 into a fact known beforehand.
|
|
166
|
+
|
|
167
|
+
**An edit cannot double or strip the `pharos:v1` trailer.** Send prose with no
|
|
168
|
+
trailer and the existing one is restored, with `markerPreserved: true` saying
|
|
169
|
+
so; send two, or one naming a different work item, or one on a comment that
|
|
170
|
+
never had one, and the edit is refused with the reason and the repair. The rule
|
|
171
|
+
lives in `gh-core`, not here, because it is a rule about the link record rather
|
|
172
|
+
than about this command — and the macOS app edits through the same package.
|
|
173
|
+
|
|
174
|
+
**Deleting the comment that carries the trailer is allowed and never silent.**
|
|
175
|
+
The `--yes` refusal names the work item about to lose its GitHub end and hands
|
|
176
|
+
over the `pharos issue link` that puts it back; `--dry-run` prints the same
|
|
177
|
+
preview and exits 0. Both read the comment first, because a preview that could
|
|
178
|
+
not say which of the two deletes this is would be a preview of the wrong thing.
|
|
179
|
+
|
|
180
|
+
Reactions are **not one vocabulary across the two platforms**. Azure DevOps
|
|
181
|
+
takes `like dislike heart hooray smile confused`; GitHub takes `thumbs-up
|
|
182
|
+
thumbs-down laugh hooray confused heart rocket eyes`. Passing one platform's
|
|
183
|
+
name to the other is refused rather than translated. The CLI spelling is words
|
|
184
|
+
because GitHub's own names for the first two are `+1` and `-1`, and `-1` as a
|
|
185
|
+
positional is read as a flag by every argument parser including this one.
|
|
186
|
+
|
|
187
|
+
### `issue` — the GitHub edge, and only the edge
|
|
188
|
+
|
|
189
|
+
```bash
|
|
190
|
+
pharos issue adopt contoso/widgets#45 --parent 39
|
|
191
|
+
pharos issue link contoso/widgets#45 4821
|
|
192
|
+
pharos issue say contoso/widgets#45 --file reply.md
|
|
193
|
+
pharos issue trail 4821 # …or trail contoso/widgets#45
|
|
194
|
+
pharos issue drift # where the two platforms disagree
|
|
195
|
+
pharos issue backfill contoso/widgets --limit 25 --yes
|
|
196
|
+
pharos issue close 4821 --text "Shipped in 1.4.0."
|
|
197
|
+
pharos issue edit contoso/widgets#45 --title "Crash on resize" --yes
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
Azure DevOps already has a GitHub integration and **the link it makes carries
|
|
201
|
+
nothing**: title, body, comments, labels and state stay on their own island, and
|
|
202
|
+
the transition only ever fires from a commit or a PR merge, never from closing
|
|
203
|
+
an issue. That is the gap, and it is the whole pitch — not "there is no
|
|
204
|
+
integration".
|
|
205
|
+
|
|
206
|
+
**Eight verbs, because `gh` already exists.** Listing, viewing and commenting on
|
|
207
|
+
an issue is `gh`'s job and it is better at it — closing one *end* is `gh issue
|
|
208
|
+
close`, and closing the *pair* is `pharos issue close`; a second GitHub CLI
|
|
209
|
+
would be the drifting duplicate this repo has been bitten by three times.
|
|
210
|
+
Pharos owns what `gh` cannot see: the join.
|
|
211
|
+
|
|
212
|
+
**`edit` is the one verb that overlaps `gh` head on, and it earns that by
|
|
213
|
+
refusing.** `gh issue edit` writes the same fields and writes them well; what it
|
|
214
|
+
cannot do is notice that somebody changed the thing you are overwriting. It is
|
|
215
|
+
last-write-wins — if a colleague renamed the issue while you were composing,
|
|
216
|
+
their rename is gone and neither of you is told. Fine for a human at a terminal,
|
|
217
|
+
wrong for an agent that reads, thinks for a minute, and writes into a world that
|
|
218
|
+
moved. Want an unguarded edit? `gh issue edit` is right there.
|
|
219
|
+
|
|
220
|
+
The guard is a **value compare**, because GitHub offers nothing better:
|
|
221
|
+
`PATCH /repos/{o}/{r}/issues/{n}` answers **400** to `If-Match` (measured), and
|
|
222
|
+
`updated_at` and the ETag both move when somebody merely *comments*, so a
|
|
223
|
+
timestamp guard would refuse a good edit for a change that touched nothing. So
|
|
224
|
+
`edit` re-reads immediately before sending and refuses only if the text it is
|
|
225
|
+
about to overwrite moved. Pass `--if-title` / `--if-body` / `--if-body-file` to
|
|
226
|
+
guard against what **you** saw rather than against this command's own read; the
|
|
227
|
+
output says which, as `fields.guard.window`. It narrows the race to one round
|
|
228
|
+
trip and does not close it, and it says so.
|
|
229
|
+
|
|
230
|
+
Two things GitHub does quietly, which `edit` reports:
|
|
231
|
+
`POST …/labels` **creates** a repository label that does not exist (so an unknown
|
|
232
|
+
one is refused with near misses — `--create-label` is how you mean it), and
|
|
233
|
+
`POST …/assignees` **ignores** a login it will not assign while still answering
|
|
234
|
+
201 (so read `assignees.ignored`). Labels and assignees go through their own
|
|
235
|
+
add/remove endpoints, never the whole-issue PATCH, which carries them as whole
|
|
236
|
+
arrays and would overwrite every label on every write.
|
|
237
|
+
|
|
238
|
+
`adopt` creates the work item **and** writes both ends of the link:
|
|
239
|
+
|
|
240
|
+
| | where | |
|
|
241
|
+
|---|---|---|
|
|
242
|
+
| 1 | a `Hyperlink` relation on the work item | measured, not chosen — `_apis/githubconnections` answers **401** on Pharos's PAT scopes while a control call answers 200, so the connection id a native `vstfs:///GitHub/Issue/…` link needs cannot be read at all |
|
|
243
|
+
| 2 | one comment on the issue: `AB#4821` **and** `<!-- pharos:v1 repo=… issue=… ado=… -->` | `AB#` is free official linking wherever the Azure Boards app happens to be installed and harmless text where it is not. The trailer is what every machine reads, including the loop guard |
|
|
244
|
+
|
|
245
|
+
**The marker goes in a comment, never the issue body.** Editing a reporter's
|
|
246
|
+
body collides with them, is rude on a public repo, and needs write access we may
|
|
247
|
+
not have on a community issue. A comment is append-only and needs none of that.
|
|
248
|
+
|
|
249
|
+
The relation and the parent ride in the **same patch** as the fields, so a work
|
|
250
|
+
item is never briefly pointing at nothing. Azure DevOps is written first because
|
|
251
|
+
the work item id does not exist until it lands — so the one failure this can
|
|
252
|
+
leave is always the same shape, and it is reported rather than swallowed:
|
|
253
|
+
|
|
254
|
+
```json
|
|
255
|
+
{ "error": { "createdWorkItem": 4821, "halfLinked": true, "wrote": ["hyperlink"],
|
|
256
|
+
"recover": "pharos issue link contoso/widgets#45 4821" } }
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
`link` writes only the half that is missing, which makes it both the way to join
|
|
260
|
+
an existing pair and the repair for exactly that state.
|
|
261
|
+
|
|
262
|
+
**Adopting an issue twice never makes a second work item, and there are three
|
|
263
|
+
different answers behind that one sentence.** Which one you get says what state
|
|
264
|
+
the pair was in:
|
|
265
|
+
|
|
266
|
+
| the issue carries a marker | exit **0**, `created: false` — the work item it names, and nothing written. The state you asked for already holds |
|
|
267
|
+
| a work item links the issue and the issue says nothing | exit **3**, `halfLinked: true`, carrying `recover` — the same `pharos issue link …` command the failure above handed over. Finishing that link is the repair; a second work item is not |
|
|
268
|
+
| two work items claim one issue | exit **3**, both named, and no `recover` — picking one would be inventing an answer to the question this feature exists to answer |
|
|
269
|
+
|
|
270
|
+
The middle row is the one that used to be a duplicate. The marker is the index
|
|
271
|
+
and in that state it was never posted, so before creating anything `adopt` also
|
|
272
|
+
asks **this machine** — an adoption is written to `~/.config/pharos/half-links.json`
|
|
273
|
+
between the create and the comment, and removed when the comment lands — and
|
|
274
|
+
then **the board**, narrowing on `[System.HyperLinkCount]` and matching the
|
|
275
|
+
relation URLs client-side, which is the only way round Azure DevOps having no
|
|
276
|
+
query over them. The board is the stronger of the two — it sees a half-link
|
|
277
|
+
left on another machine — and the local record covers what it cannot: a board
|
|
278
|
+
query that is refused, a half-link older than that scan's cap, and a refusal
|
|
279
|
+
that costs no round trip. Every run reports `boardCheck`, because "the board
|
|
280
|
+
says nobody has adopted this" and "the board could not be asked" are different
|
|
281
|
+
facts and only one of them means the check happened.
|
|
282
|
+
|
|
283
|
+
`trail` is read-only and answers from **either** end — the output shape does not
|
|
284
|
+
depend on which you passed. Read `evidence`: `["hyperlink","marker"]` is a
|
|
285
|
+
complete link, and either one alone is a link that only half exists.
|
|
286
|
+
|
|
287
|
+
#### `say` — one message, two audiences
|
|
288
|
+
|
|
289
|
+
```bash
|
|
290
|
+
pharos issue say contoso/widgets#45 --file reply.md
|
|
291
|
+
pharos issue say contoso/widgets#45 --stdin --summary "Fixed in 1.4.2; asked for a crash log"
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
| | GitHub | Azure DevOps |
|
|
295
|
+
|---|---|---|
|
|
296
|
+
| who reads it | the reporter, who does **not** have an Azure DevOps account and never will | the team |
|
|
297
|
+
| what they get | the full explanation, in their register | a summary, and the URL of the comment carrying the rest |
|
|
298
|
+
|
|
299
|
+
**The asymmetry is the verb.** The same words in both places is `gh issue
|
|
300
|
+
comment` followed by `pharos comment add`, and neither of those knows the other
|
|
301
|
+
happened. Without `--summary` the board gets the first paragraph cut to 200
|
|
302
|
+
characters — a guess, and allowed to be one *only* because the comment's URL
|
|
303
|
+
travels with it. The board is never the record of what was said; GitHub is.
|
|
304
|
+
|
|
305
|
+
**The loop guard keys on content, never on `sender.login`.** GitHub events carry
|
|
306
|
+
an actor and Azure DevOps events do not, which makes the actor look like the easy
|
|
307
|
+
answer and is the trap: every client writes with its own `gh` credential, so
|
|
308
|
+
`sender.login == me` is *also* true of the human typing into the web UI, and
|
|
309
|
+
suppressing on it silently swallows their real comments. So the guard is the
|
|
310
|
+
`pharos:v1` trailer, in two halves:
|
|
311
|
+
|
|
312
|
+
- **Every comment `say` posts carries it**, because the read sweep is only safe
|
|
313
|
+
if `isPharosAuthored` is total. One unmarked Pharos comment anywhere is one the
|
|
314
|
+
sweep reads as a human's, and the loop that starts from it does not stop.
|
|
315
|
+
- **A message that already carries one is refused.** That is Pharos's own output
|
|
316
|
+
being handed back — a mirrored body, a copy-paste, a script re-posting what it
|
|
317
|
+
read — and it is the loop starting one step before any sweep could see it. The
|
|
318
|
+
macOS app's queue refuses exactly the same thing.
|
|
319
|
+
|
|
320
|
+
GitHub is written **first** here, the opposite of `adopt`, because the board's
|
|
321
|
+
comment carries the GitHub comment's URL and that does not exist until the POST
|
|
322
|
+
returns. The work item is read before anything is published, since the GitHub
|
|
323
|
+
half lands on a repository that may not be ours. If the board half then fails:
|
|
324
|
+
|
|
325
|
+
```json
|
|
326
|
+
{ "error": { "halfSaid": true, "wrote": ["github-comment"],
|
|
327
|
+
"github": { "commentUrl": "https://github.com/…#issuecomment-950" },
|
|
328
|
+
"recover": "pharos comment add 4821 --stdin", "adoComment": "…" } }
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
**Do not re-run it.** A comment is an append, so a second `say` posts a second
|
|
332
|
+
public comment; the error carries the exact text and the command that writes the
|
|
333
|
+
half that is missing.
|
|
334
|
+
|
|
335
|
+
`say` starts from the issue end only. A work item may hyperlink several issues,
|
|
336
|
+
so that end names no single reporter — `pharos issue trail <id>` is how you find
|
|
337
|
+
out which issue you meant.
|
|
338
|
+
|
|
339
|
+
Pull requests are out of scope for v1 and are refused by name rather than
|
|
340
|
+
half-supported: on GitHub's API every PR is also an issue, so `adopt` on a PR
|
|
341
|
+
number would otherwise mirror something the rest of this does not model.
|
|
342
|
+
|
|
343
|
+
#### `drift` — the report no other tool can produce
|
|
344
|
+
|
|
345
|
+
```bash
|
|
346
|
+
pharos issue drift
|
|
347
|
+
pharos issue drift --repo contoso/widgets --limit 50
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
`gh` can list issues; Azure DevOps can list work items; **neither holds both
|
|
351
|
+
sides**, so neither can say *these two disagree*. A link nobody checks decays
|
|
352
|
+
quietly — an issue gets closed on GitHub and the board still shows the work in
|
|
353
|
+
progress, or a work item is marked done and the reporter, who has no Azure
|
|
354
|
+
DevOps account and never will, is still waiting.
|
|
355
|
+
|
|
356
|
+
Four kinds, because they want four different actions:
|
|
357
|
+
|
|
358
|
+
| kind | what it means |
|
|
359
|
+
|---|---|
|
|
360
|
+
| `state` | both ends exist and disagree about whether the work is finished |
|
|
361
|
+
| `missing-issue` | the work item names an issue GitHub does not have |
|
|
362
|
+
| `one-sided` | the board has the link and the issue does not — what a failed `adopt` leaves. Carries the `pharos issue link …` that repairs it |
|
|
363
|
+
| `unreadable` | the GitHub end could not be read, so nothing about this pair is known |
|
|
364
|
+
|
|
365
|
+
**It scans links, not issues.** An unadopted issue is not drift — on a repo with
|
|
366
|
+
four hundred of them, counting "not linked" as a problem buries three real
|
|
367
|
+
findings under three hundred and eighty-eight rows of noise. What is *missing*
|
|
368
|
+
from the bridge is `backfill`'s question; what is *wrong* inside it is this one.
|
|
369
|
+
|
|
370
|
+
**"Finished" is read from the project, never guessed.** A process template
|
|
371
|
+
renames every state, and `Resolved` is terminal on a Bug and open on a User
|
|
372
|
+
Story — so each work item is judged against its own type's categories and the
|
|
373
|
+
report says which source it used. When the catalogue cannot be read the stock
|
|
374
|
+
names are used *and said out loud*, because a row is uninterpretable without
|
|
375
|
+
knowing what was counted as finished.
|
|
376
|
+
|
|
377
|
+
An unreadable repository is **information, not a fault, and never fails the
|
|
378
|
+
command**: a work item can hyperlink a repo somebody else adopted on a machine
|
|
379
|
+
configured differently.
|
|
380
|
+
|
|
381
|
+
#### `backfill` — the adoption path, for the repo everybody actually has
|
|
382
|
+
|
|
383
|
+
```bash
|
|
384
|
+
pharos issue backfill contoso/widgets # previews, then REFUSES
|
|
385
|
+
pharos issue backfill contoso/widgets --dry-run # the same preview, exit 0
|
|
386
|
+
pharos issue backfill contoso/widgets --limit 25 --max-writes 50 --yes
|
|
387
|
+
pharos issue backfill contoso/widgets --label bug --parent 39 --yes
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
Without a bulk route the bridge only works on a greenfield repository, which is
|
|
391
|
+
not where anybody is. A team with four hundred open issues cannot adopt them one
|
|
392
|
+
command at a time.
|
|
393
|
+
|
|
394
|
+
**Deciding what is already adopted costs two requests, not four hundred.** The
|
|
395
|
+
board is the enumerable side: a work item carries its `Hyperlink` relations on
|
|
396
|
+
its own row, so one WIQL and one `workitemsbatch` return every link at once.
|
|
397
|
+
GitHub cannot answer the equivalent question at all — the marker lives in a
|
|
398
|
+
comment, so asking costs a request per issue. That subtraction is correct
|
|
399
|
+
because `adopt` writes the Azure DevOps end **first**, so the half-state it can
|
|
400
|
+
leave is a hyperlink with no comment and never the reverse. The mirror image is
|
|
401
|
+
still possible if somebody deletes a relation by hand, so the marker is re-read
|
|
402
|
+
per issue **at adoption time** — on the handful being written — and an issue
|
|
403
|
+
that turns out to be claimed already is skipped rather than adopted twice.
|
|
404
|
+
|
|
405
|
+
**It is resumable and needs no state file to be.** The link *is* the progress
|
|
406
|
+
record: a second run reads the board again, finds the ones the first run adopted
|
|
407
|
+
already linked, and carries on. Candidates are ordered by issue number ascending
|
|
408
|
+
so that is true in the obvious way as well as the technical one.
|
|
409
|
+
|
|
410
|
+
**The write budget is the throttle, on purpose.** Each adoption is two writes, so
|
|
411
|
+
four hundred issues is eight hundred against a default cap of twenty. That cost
|
|
412
|
+
is worked out *before* anything is written and a run that cannot finish is
|
|
413
|
+
refused, naming both ways forward — rather than stopping at write nineteen,
|
|
414
|
+
which is the outcome a caller can reason about least.
|
|
415
|
+
|
|
416
|
+
A bare invocation previews and **refuses** (exit 3); `--dry-run` is the same
|
|
417
|
+
preview at exit 0. The preview names the repository, the `gh` account it would
|
|
418
|
+
be reached as, **and the Azure DevOps organisation and project the work items
|
|
419
|
+
would land on**. Nothing in the design pairs a repo with a board, and a
|
|
420
|
+
mis-aimed `adopt` is one work item where a mis-aimed `backfill --yes` is four
|
|
421
|
+
hundred — each with a public comment naming a board its reporter has nothing to
|
|
422
|
+
do with.
|
|
423
|
+
|
|
424
|
+
`--state` defaults to `open`: a closed issue is history, and adopting it creates
|
|
425
|
+
a work item that is finished before anybody looks at it.
|
|
426
|
+
|
|
427
|
+
#### `close` — the ending of the trail
|
|
428
|
+
|
|
429
|
+
```bash
|
|
430
|
+
pharos issue close 4821 # …or close contoso/widgets#45
|
|
431
|
+
pharos issue close 4821 --to Removed --reason not-planned
|
|
432
|
+
pharos issue close 4821 --file release-note.md
|
|
433
|
+
```
|
|
434
|
+
|
|
435
|
+
Closes **both** ends, comments on each **pointing at the other**, then **re-reads
|
|
436
|
+
both** and reports what actually moved. Two 200s are not proof: a workflow rule
|
|
437
|
+
can refuse a transition on a field the API happily accepted, so `verified` is
|
|
438
|
+
what was there afterwards rather than what was sent.
|
|
439
|
+
|
|
440
|
+
**It does not compose `Closes #45` / `Fixes AB#123` into a PR body.** Those fire
|
|
441
|
+
on a PR *merge* and pull requests are out of scope for v1 — so there would be
|
|
442
|
+
nothing to compose into and nothing to verify.
|
|
443
|
+
|
|
444
|
+
**There is no hardcodable `Closed`.** The state written comes from the project's
|
|
445
|
+
own categories: exactly one terminal state for that work item type is used,
|
|
446
|
+
several is a **refusal** naming them and `--to`, because `Done` and `Removed` are
|
|
447
|
+
both finished and mean opposite things. If the catalogue cannot be read at all it
|
|
448
|
+
refuses rather than guessing — `drift` degrades to the stock names because a
|
|
449
|
+
misclassified row is a question somebody can dismiss, and the same guess here
|
|
450
|
+
would be a write.
|
|
451
|
+
|
|
452
|
+
`--to`, not `--state`: `--state` already means `open|closed|all` on `backfill`,
|
|
453
|
+
and one flag with two meanings across two verbs of one command is a bug that only
|
|
454
|
+
shows up when somebody runs it.
|
|
455
|
+
|
|
456
|
+
Closing an already-closed pair writes nothing and exits 0. A work item linking
|
|
457
|
+
several issues is refused unless `--all` says so — "close 4821" should not read
|
|
458
|
+
as "close four strangers' issues".
|
|
459
|
+
|
|
126
460
|
## Configuration
|
|
127
461
|
|
|
128
462
|
| | |
|
|
@@ -143,6 +477,76 @@ items, `vso.wiki_write` for the wiki.
|
|
|
143
477
|
**Every person uses their own token.** Board attribution is per-person, and a
|
|
144
478
|
shared token makes everyone's work read as one account.
|
|
145
479
|
|
|
480
|
+
### GitHub, which follows a different rule for a measured reason
|
|
481
|
+
|
|
482
|
+
The rule above is about `ADO_PAT` and it has not moved. GitHub is a separate
|
|
483
|
+
thing, and it needs two facts that an environment variable cannot carry.
|
|
484
|
+
|
|
485
|
+
**The credential comes from `gh`, so there is no fourth secret to manage.**
|
|
486
|
+
`gh auth token --user <account>` resolves it and the API calls are ordinary
|
|
487
|
+
HTTPS from there; revoking GitHub access never touches the Azure DevOps token.
|
|
488
|
+
Pass `--user` or nothing else: a bare `gh auth token` returns whatever `GH_TOKEN`
|
|
489
|
+
happens to be exported and ignores the keyring entirely, so an exported token in
|
|
490
|
+
somebody's shell would silently become the identity of a sweep.
|
|
491
|
+
|
|
492
|
+
**The account is bound per repository, in `~/.config/pharos/repos.json`.**
|
|
493
|
+
|
|
494
|
+
```bash
|
|
495
|
+
pharos setup --repo contoso/widgets --gh-account alisina-tibata
|
|
496
|
+
```
|
|
497
|
+
|
|
498
|
+
Both flags or neither — a repository is a `(repo, account)` **pair**, and there
|
|
499
|
+
is deliberately no fallback to whichever account `gh` has active. Azure DevOps
|
|
500
|
+
binds a project to one GitHub identity; `gh` holds many at once with one active
|
|
501
|
+
machine-wide, and on the machine this was measured on the active account was not
|
|
502
|
+
the one owning the repository behind the project being worked. The failure is
|
|
503
|
+
not a clean error either: two accounts can each see a repository of the same
|
|
504
|
+
name, so the wrong one answers **200** for a different repository. That is what
|
|
505
|
+
`pharos doctor --verify` compares owners for.
|
|
506
|
+
|
|
507
|
+
`$PHAROS_REPOS_FILE` and `$XDG_CONFIG_HOME` both move the file. `gh` is optional
|
|
508
|
+
— without it every `pharos issue` verb is refused by name with the reason, and
|
|
509
|
+
the Azure DevOps verbs are untouched.
|
|
510
|
+
|
|
511
|
+
**And it runs in the other direction too: a verb whose target is a GitHub issue
|
|
512
|
+
needs no `ADO_PAT`.** `pharos comment list contoso/widgets#45` reads over `gh`'s
|
|
513
|
+
credential and touches Azure DevOps at no point, so it works on a machine that
|
|
514
|
+
has never had a PAT. The Azure DevOps configuration is resolved when something
|
|
515
|
+
actually needs Azure DevOps, and not before — which means the `kind: "config"`
|
|
516
|
+
error naming `ADO_PAT` now arrives only from a verb that would have used it.
|
|
517
|
+
`pharos issue` is the exception and honestly so: it writes to both platforms in
|
|
518
|
+
one invocation, so it needs both credentials.
|
|
519
|
+
|
|
520
|
+
**`half-links.json` sits beside it, and it is the only thing this CLI remembers
|
|
521
|
+
between runs.** An adoption is written there between the work item create and
|
|
522
|
+
the GitHub comment and removed when the comment lands, so what survives is
|
|
523
|
+
exactly the set of adoptions that half-happened — the state neither platform can
|
|
524
|
+
be asked about, and the one a retry follows. It is never consulted for what a
|
|
525
|
+
link *is*: the marker and the hyperlink are read fresh every time, and an entry
|
|
526
|
+
is checked against Azure DevOps before it is believed. Delete it and you lose
|
|
527
|
+
nothing but one guard; `$PHAROS_HALF_LINKS_FILE` moves it.
|
|
528
|
+
|
|
529
|
+
## Checking a machine
|
|
530
|
+
|
|
531
|
+
```bash
|
|
532
|
+
pharos doctor # three tiers, with a stable id per check
|
|
533
|
+
pharos doctor --verify # prove the credentials with real calls
|
|
534
|
+
pharos setup --install gh # or ask|all|libreoffice,poppler,…
|
|
535
|
+
```
|
|
536
|
+
|
|
537
|
+
`doctor` is read-only and works before anything is configured, which is what
|
|
538
|
+
makes it the right first move when something behaves oddly. It prints the PATH
|
|
539
|
+
it searched, because a GUI-launched app inherits a minimal one and would
|
|
540
|
+
otherwise be told a fully provisioned machine is bare.
|
|
541
|
+
|
|
542
|
+
It is offline apart from one probe, and that probe is named rather than glossed:
|
|
543
|
+
**`gh auth status` validates every token against github.com**, with no flag to
|
|
544
|
+
stop it, so it runs only when `gh` is installed. Measured on gh 2.87.3, it also
|
|
545
|
+
reports an unreachable host as `The token in keyring is invalid` — a
|
|
546
|
+
connectivity fault worded as a credential fault. `gh-auth` therefore never tells
|
|
547
|
+
you that you are signed out; it reports both causes, because from here they are
|
|
548
|
+
genuinely indistinguishable.
|
|
549
|
+
|
|
146
550
|
## Requirements
|
|
147
551
|
|
|
148
|
-
Node 22 or later.
|
|
552
|
+
Node 22 or later. `gh` for the GitHub bridge, and nothing else is required.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"capabilities.d.ts","sourceRoot":"","sources":["../src/capabilities.ts"],"names":[],"mappings":"AAQA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAEH,MAAM,WAAW,UAAU;IACzB,mEAAmE;IACnE,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,+CAA+C;IAC/C,OAAO,EAAE,MAAM,CAAC;IAChB,yEAAyE;IACzE,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,OAAO,CAAC;IACZ,qEAAqE;IACrE,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;CAChB;
|
|
1
|
+
{"version":3,"file":"capabilities.d.ts","sourceRoot":"","sources":["../src/capabilities.ts"],"names":[],"mappings":"AAQA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAEH,MAAM,WAAW,UAAU;IACzB,mEAAmE;IACnE,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,+CAA+C;IAC/C,OAAO,EAAE,MAAM,CAAC;IAChB,yEAAyE;IACzE,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,OAAO,CAAC;IACZ,qEAAqE;IACrE,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;CAChB;AA0CD,eAAO,MAAM,WAAW,EAAE,UAAU,EAsCnC,CAAC;AAEF,qEAAqE;AACrE,wBAAsB,mBAAmB,CACvC,GAAG,EAAE,SAAS,MAAM,EAAE,EACtB,OAAO,GAAE;IACP,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,gEAAgE;IAChE,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACtC,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CACnD,GACL,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAgB9B"}
|
package/dist/capabilities.js
CHANGED
|
@@ -26,6 +26,21 @@ const PACKAGES = {
|
|
|
26
26
|
apt: ["install", "-y", "poppler-utils"],
|
|
27
27
|
winget: ["install", "--id", "oschwartz10612.Poppler", "-e"],
|
|
28
28
|
},
|
|
29
|
+
// **`gh` is a credential source, not a transport** (plan §2, and @#779's
|
|
30
|
+
// clarification of it). Pharos resolves a token with `gh auth token --user
|
|
31
|
+
// <account>` and then makes ordinary HTTPS calls; installing gh is what makes
|
|
32
|
+
// that possible, and it is why there is no fourth Keychain entry to manage.
|
|
33
|
+
//
|
|
34
|
+
// No apt entry, deliberately. GitHub's own Linux instructions add their
|
|
35
|
+
// package repository (https://cli.github.com/packages) rather than pointing at
|
|
36
|
+
// a distro package, and what `apt install gh` gets you varies by release. A
|
|
37
|
+
// command that does not exist here is worse than no command, because somebody
|
|
38
|
+
// will paste it — so Linux gets the honest refusal and the doctor check names
|
|
39
|
+
// where to look.
|
|
40
|
+
gh: {
|
|
41
|
+
brew: ["install", "gh"],
|
|
42
|
+
winget: ["install", "--id", "GitHub.cli", "-e"],
|
|
43
|
+
},
|
|
29
44
|
};
|
|
30
45
|
export const INSTALLABLE = [
|
|
31
46
|
{
|
|
@@ -41,6 +56,14 @@ export const INSTALLABLE = [
|
|
|
41
56
|
unlocks: "`wiki import` for .docx, .pdf, .rtf, .html and .odt.",
|
|
42
57
|
size: "7.5 MB download",
|
|
43
58
|
},
|
|
59
|
+
{
|
|
60
|
+
id: "gh",
|
|
61
|
+
name: "GitHub CLI",
|
|
62
|
+
unlocks: "The GitHub bridge: `pharos issue` adopts, links and mirrors an issue against a work item. "
|
|
63
|
+
+ "gh holds the credential, so nothing new is stored and revoking GitHub access never "
|
|
64
|
+
+ "touches the Azure DevOps token.",
|
|
65
|
+
size: "~35 MB",
|
|
66
|
+
},
|
|
44
67
|
{
|
|
45
68
|
id: "libreoffice",
|
|
46
69
|
name: "LibreOffice",
|
package/dist/capabilities.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"capabilities.js","sourceRoot":"","sources":["../src/capabilities.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"capabilities.js","sourceRoot":"","sources":["../src/capabilities.ts"],"names":[],"mappings":"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"}
|
package/dist/cli.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { AdoClient } from "@floh-solutions/ado-core";
|
|
2
|
+
import type { GitHubClient } from "@floh-solutions/gh-core";
|
|
2
3
|
import { type ExitCode } from "./output.js";
|
|
3
4
|
/**
|
|
4
5
|
* Every command this file dispatches — **one list, used by both the sentence and
|
|
@@ -11,7 +12,7 @@ import { type ExitCode } from "./output.js";
|
|
|
11
12
|
* expensive kind of wrong. Anything added to the switch belongs here, and the
|
|
12
13
|
* test below fails if it does not.
|
|
13
14
|
*/
|
|
14
|
-
export declare const COMMANDS: readonly ["setup", "whoami", "query", "task", "types", "history", "iterations", "areas", "links", "fields", "create", "update", "link", "unlink", "delete", "restore", "deleted", "attach", "detach", "download", "image", "people", "wiki", "comment", "hooks", "plan", "doctor"];
|
|
15
|
+
export declare const COMMANDS: readonly ["setup", "whoami", "query", "task", "types", "history", "iterations", "areas", "links", "fields", "create", "update", "link", "unlink", "delete", "restore", "deleted", "attach", "detach", "download", "image", "people", "wiki", "comment", "hooks", "plan", "doctor", "issue"];
|
|
15
16
|
export interface RunOptions {
|
|
16
17
|
argv: string[];
|
|
17
18
|
cwd: string;
|
|
@@ -22,6 +23,8 @@ export interface RunOptions {
|
|
|
22
23
|
readStdin?: (() => Promise<string>) | undefined;
|
|
23
24
|
/** Injected by tests, so the whole router can run against a mock transport. */
|
|
24
25
|
client?: AdoClient | undefined;
|
|
26
|
+
/** The same, for the GitHub half of `pharos issue`. */
|
|
27
|
+
github?: GitHubClient | undefined;
|
|
25
28
|
}
|
|
26
29
|
export declare function run(options: RunOptions): Promise<ExitCode>;
|
|
27
30
|
//# sourceMappingURL=cli.d.ts.map
|
package/dist/cli.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AA8B5D,OAAO,EAKL,KAAK,QAAQ,EAEd,MAAM,aAAa,CAAC;AAyBrB;;;;;;;;;;GAUG;AACH,eAAO,MAAM,QAAQ,6RAMX,CAAC;AA8gBX,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC,UAAU,CAAC;IACvB,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/B,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/B,gDAAgD;IAChD,SAAS,CAAC,EAAE,CAAC,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,SAAS,CAAC;IAChD,+EAA+E;IAC/E,MAAM,CAAC,EAAE,SAAS,GAAG,SAAS,CAAC;IAC/B,uDAAuD;IACvD,MAAM,CAAC,EAAE,YAAY,GAAG,SAAS,CAAC;CACnC;AAED,wBAAsB,GAAG,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,QAAQ,CAAC,CAOhE"}
|