@floh-solutions/pharos-cli 0.27.0 → 0.29.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/skill/SKILL.md CHANGED
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: pharos
3
- description: "Use for AZURE DEVOPS work — when the user says Azure DevOps, ADO or dev.azure.com, or names an ADO work item by number (\"pick up 4821\"). Covers reading or updating a work item, bug, story or epic; the board, backlog, sprint or iteration; what is assigned to you; reading or writing a wiki page and its comments; searching the board and wiki for a phrase; linking a plan to an epic; attaching a file to a work item or taking one off; inline images in a field or page; @mentioning somebody so they are notified; importing Markdown, Word or PDF as pages; and whether a call is retryable. ALSO the GITHUB ISSUE ↔ work item EDGE: adopting an issue as a work item linked at both ends, bulk-adopting a repo, one reply reaching both, where they drifted, closing both ends together, a PULL REQUEST and its work item, and changing a comment that ALREADY EXISTS: editing, deleting, reacting, hiding, pinning. NOT a GitHub CLI: listing or viewing an issue, or POSTING a comment, is `gh`'s job. NOT for other trackers — Argus, Jira, Linear."
3
+ description: "Use for AZURE DEVOPS work — when the user says Azure DevOps, ADO or dev.azure.com, or names an ADO work item by number (\"pick up 4821\"). Covers reading or updating a work item, bug, story or epic; the board, backlog, sprint or iteration; what is assigned to you; reading or writing a wiki page and its comments; searching the board and wiki for a phrase; linking a plan to an epic; attaching a file to a work item or taking one off; inline images in a field or page; @mentioning somebody so they are notified; importing Markdown, Word or PDF as pages; and whether a call is retryable. ALSO the GITHUB ISSUE ↔ work item EDGE: adopting an issue as a work item linked at both ends, bulk-adopting a repo, one reply reaching both, where they drifted, closing both ends together, and changing a comment that ALREADY EXISTS: editing, deleting, reacting, hiding, pinning. NOT a GitHub CLI: listing or viewing an issue, or POSTING a comment, is `gh`'s job. NOT for other trackers — Argus, Jira, Linear."
4
4
  license: Proprietary
5
5
  ---
6
6
 
@@ -84,13 +84,6 @@ issue say <owner/name#45> ONE message, TWO audiences: the whole of it to
84
84
  comment's URL to the board. --summary
85
85
  issue trail <id|owner/name#45> the whole trail from EITHER end, with the
86
86
  evidence for each half. Read-only
87
- pr <owner/name#123> a PULL REQUEST and the work it belongs to:
88
- state, draft, review verdict, WHICH CHECKS ARE
89
- RED, the issues it closes, and the work items it
90
- reaches — via AB#123 in the body OR via an
91
- adopted issue named by "Fixes #45". Also where
92
- the pull request and the board DISAGREE
93
- --no-work-items skip the transitive lookup
94
87
  issue drift where the two platforms DISAGREE — the report no
95
88
  other tool can produce. --repo --limit --wiql
96
89
  issue backfill <owner/name> bulk adopt every issue the board does not link
@@ -105,7 +98,10 @@ issue edit <owner/name#45> the issue's OWN fields, behind a lost-update
105
98
  hooks list | check | create | repoint | delete service hooks for realtime.
106
99
  `check` needs --hub <url>; `list` shows the URL
107
100
  already in use
108
- plan <file> an implementation plan → a work item tree
101
+ plan <file> an implementation plan → a work item tree.
102
+ The plan file writes Epic/Issue/Task and
103
+ To Do/Doing/Done; the run maps them to whatever
104
+ THIS project calls those roles
109
105
  setup org, project, token → keychain + shell profile
110
106
  --install ask|all|a,b offer the optional
111
107
  capabilities (LibreOffice, poppler, converter,
@@ -201,64 +197,6 @@ It parses, returns 200, and matches **everything** — `IN GROUP` covers work it
201
197
  TYPE categories only, and an unknown group resolves to the empty set with no
202
198
  error. Measured, 2026-08-05.
203
199
 
204
- ## After adoption, the work becomes code: `pharos pr`
205
-
206
- `issue trail` follows filing -> adoption -> close. It stops at the moment the
207
- work becomes a branch. `pharos pr` is the part that does not.
208
-
209
- ```bash
210
- pharos pr contoso/widgets#123 # the pull request AND the board
211
- pharos pr contoso/widgets#123 --pretty
212
- pharos pr contoso/widgets#123 --no-work-items # skip the transitive lookup
213
- ```
214
-
215
- One call replaces `gh pr view` + `gh pr checks` + a WIQL query + a relations
216
- read, across two credentials — and answers one question none of them can.
217
-
218
- **Two paths reach a work item, and the implicit one is the one that fires:**
219
-
220
- | | |
221
- |---|---|
222
- | `AB#4821` in the body | explicit. What Azure Boards' own app reads |
223
- | `Fixes #45`, where #45 is adopted | **the one that actually happens** |
224
-
225
- The second costs one read per closed issue (its comments, where the `pharos:v1`
226
- trailer lives) and is why `--no-work-items` exists for when you do not need it.
227
-
228
- ### `disagreements` is the part nothing else can produce
229
-
230
- ```jsonc
231
- {
232
- "pullRequest": { "number": 123, "state": "MERGED", "merged": true,
233
- "review": "APPROVED", "checks": "FAILURE",
234
- "failingChecks": [ { "name": "e2e-tests", "conclusion": "FAILURE" } ] },
235
- "closesIssues": [45],
236
- "workItems": [ { "id": 4821, "type": "Issue", "state": "To Do", "title": "…" } ],
237
- "disagreements": [
238
- "#4821 is \"To Do\" but this pull request is already MERGED — the work shipped and the board never moved."
239
- ],
240
- "problems": []
241
- }
242
- ```
243
-
244
- Azure DevOps cannot see the pull request and GitHub does not know the work item
245
- exists, so **neither system will ever report this**. An empty `disagreements`
246
- means they agree; it is silent when there is nothing to say.
247
-
248
- Three things about the shape:
249
-
250
- - **`checks` is the rollup and it is authoritative. `failingChecks` names the
251
- red ones** — found by filtering every context, not by showing the first few.
252
- Measured: real pull requests report a `FAILURE` rollup while their first
253
- several contexts all read `SUCCESS`, because the red one is further down.
254
- - **`NONE` is not `SUCCESS`.** A pull request with no checks configured reports
255
- `NONE`, and a still-running one is `PENDING`, not a failure.
256
- - **`state` has three values** — `OPEN`, `CLOSED`, `MERGED`. Merged is its own
257
- state, not a kind of closed, and `merged: true` is the field to test.
258
-
259
- Posting a comment on a pull request is still `gh`'s job, exactly as it is for an
260
- issue. This verb reads; it does not write.
261
-
262
200
  ## Finding where it is WRITTEN: `pharos search`
263
201
 
264
202
  `query` answers *which work items*. `search` answers *where has this been
@@ -660,6 +598,15 @@ states exist" and "which mean finished" are different questions — `Inactive` i
660
598
  finished on a Test Plan and appears in nobody's hard-coded Done/Closed/Removed
661
599
  list.
662
600
 
601
+ **Nothing in this CLI writes a state name it was not told.** `query` reads the
602
+ categories to decide what "open" means, `update` refuses a state the type does
603
+ not have, `issue close` moves an item into the project's own terminal state,
604
+ `issue adopt` and `issue backfill` resolve the work item TYPE by role, and
605
+ `plan` maps its file's `Epic`/`Issue`/`Task` and `To Do`/`Doing`/`Done` onto
606
+ whatever this project calls those roles. Where any of them cannot read the
607
+ project it falls back to the stock names **and says so** — `source: "fallback"`,
608
+ a `note`, or a warning on stderr. If you see one, the answer is a guess.
609
+
663
610
  `pharos whoami` is the other one worth reaching for early: it names the identity
664
611
  behind `ADO_PAT`, which is who `@Me` resolves to and who every write is
665
612
  attributed to. A shared or service token quietly makes "assigned to me" mean
@@ -1015,11 +962,19 @@ pharos issue backfill contoso/widgets --label bug --parent 39 --limit 25 --max-w
1015
962
  ```
1016
963
 
1017
964
  **Read the preview before adding `--yes`.** It names the repository, the `gh`
1018
- account it would be reached as, **and the Azure DevOps organisation and project
1019
- the work items would land on** nothing in the design pairs a repo with a
1020
- board, and a mis-aimed `adopt` is one work item where a mis-aimed `backfill
1021
- --yes` is four hundred, each with a public comment naming a board its reporter
1022
- has nothing to do with.
965
+ account it would be reached as, **the Azure DevOps organisation and project the
966
+ work items would land on**, and **`workItemType` what they would be created
967
+ as** nothing in the design pairs a repo with a board, and a mis-aimed `adopt`
968
+ is one work item where a mis-aimed `backfill --yes` is four hundred, each with a
969
+ public comment naming a board its reporter has nothing to do with.
970
+
971
+ **The type is resolved per issue, from the project, exactly as `adopt` resolves
972
+ it.** It reads which type this project maps to the requirement role and which to
973
+ the bug role, so an issue labelled as a bug becomes a bug and the rest become
974
+ the requirement type — `Issue` and `Issue` on Basic, `Bug` and `User Story` on
975
+ Agile. Every adopted row carries `typeSource` saying which answer it got:
976
+ `category`, `repo-default`, `label`, `flag`, or `fallback` for "the project
977
+ could not be asked". Pass `--type` to pin one for the whole run.
1023
978
 
1024
979
  **Each adoption is two writes**, so four hundred issues is eight hundred against
1025
980
  a default cap of 20. That cost is worked out *before* anything is written and a