@floh-solutions/pharos-cli 0.4.0 → 0.12.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.
Files changed (63) hide show
  1. package/dist/cli.d.ts.map +1 -1
  2. package/dist/cli.js +381 -7
  3. package/dist/cli.js.map +1 -1
  4. package/dist/commands/attach.d.ts +30 -0
  5. package/dist/commands/attach.d.ts.map +1 -0
  6. package/dist/commands/attach.js +55 -0
  7. package/dist/commands/attach.js.map +1 -0
  8. package/dist/commands/create.d.ts +35 -0
  9. package/dist/commands/create.d.ts.map +1 -0
  10. package/dist/commands/create.js +82 -0
  11. package/dist/commands/create.js.map +1 -0
  12. package/dist/commands/detach.d.ts +34 -0
  13. package/dist/commands/detach.d.ts.map +1 -0
  14. package/dist/commands/detach.js +117 -0
  15. package/dist/commands/detach.js.map +1 -0
  16. package/dist/commands/discover.d.ts +66 -0
  17. package/dist/commands/discover.d.ts.map +1 -0
  18. package/dist/commands/discover.js +128 -0
  19. package/dist/commands/discover.js.map +1 -0
  20. package/dist/commands/hooks.d.ts +24 -0
  21. package/dist/commands/hooks.d.ts.map +1 -0
  22. package/dist/commands/hooks.js +184 -0
  23. package/dist/commands/hooks.js.map +1 -0
  24. package/dist/commands/image.d.ts +44 -0
  25. package/dist/commands/image.d.ts.map +1 -0
  26. package/dist/commands/image.js +114 -0
  27. package/dist/commands/image.js.map +1 -0
  28. package/dist/commands/import.d.ts +51 -0
  29. package/dist/commands/import.d.ts.map +1 -0
  30. package/dist/commands/import.js +190 -0
  31. package/dist/commands/import.js.map +1 -0
  32. package/dist/commands/link.d.ts +40 -0
  33. package/dist/commands/link.d.ts.map +1 -0
  34. package/dist/commands/link.js +150 -0
  35. package/dist/commands/link.js.map +1 -0
  36. package/dist/commands/people.d.ts +39 -0
  37. package/dist/commands/people.d.ts.map +1 -0
  38. package/dist/commands/people.js +64 -0
  39. package/dist/commands/people.js.map +1 -0
  40. package/dist/commands/query.d.ts +43 -0
  41. package/dist/commands/query.d.ts.map +1 -0
  42. package/dist/commands/query.js +202 -0
  43. package/dist/commands/query.js.map +1 -0
  44. package/dist/commands/recycle.d.ts +10 -0
  45. package/dist/commands/recycle.d.ts.map +1 -0
  46. package/dist/commands/recycle.js +118 -0
  47. package/dist/commands/recycle.js.map +1 -0
  48. package/dist/commands/update.d.ts +52 -0
  49. package/dist/commands/update.d.ts.map +1 -0
  50. package/dist/commands/update.js +181 -0
  51. package/dist/commands/update.js.map +1 -0
  52. package/dist/commands/wiki.d.ts.map +1 -1
  53. package/dist/commands/wiki.js +133 -2
  54. package/dist/commands/wiki.js.map +1 -1
  55. package/dist/output.d.ts.map +1 -1
  56. package/dist/output.js +32 -2
  57. package/dist/output.js.map +1 -1
  58. package/dist/wiql-build.d.ts +92 -0
  59. package/dist/wiql-build.d.ts.map +1 -0
  60. package/dist/wiql-build.js +147 -0
  61. package/dist/wiql-build.js.map +1 -0
  62. package/package.json +3 -3
  63. package/skill/SKILL.md +315 -65
@@ -1 +1 @@
1
- {"version":3,"file":"output.js","sourceRoot":"","sources":["../src/output.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"output.js","sourceRoot":"","sources":["../src/output.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,92 @@
1
+ import type { StateCatalog } from "@floh-solutions/ado-core";
2
+ /**
3
+ * Turning `pharos query`'s flags into one WIQL statement.
4
+ *
5
+ * **Pure, and separate from the command, because this is where the bugs are.**
6
+ * The flags AND together and every one of them puts a literal from the command
7
+ * line into a query language — so composition and quoting are the whole risk
8
+ * surface, and both can be proved without a network. The command file around
9
+ * this is only "call it, hydrate, print".
10
+ */
11
+ /** What the caller asked for. Everything is optional; everything ANDs. */
12
+ export interface QueryFilters {
13
+ /** `[System.AssignedTo] = @Me`. Mutually exclusive with {@link assignee}. */
14
+ mine?: boolean;
15
+ assignee?: string | undefined;
16
+ states?: readonly string[];
17
+ types?: readonly string[];
18
+ /** An iteration path, or a leaf name resolved under the project. */
19
+ sprint?: string | undefined;
20
+ /** An area path, same resolution as {@link sprint}. */
21
+ area?: string | undefined;
22
+ tags?: readonly string[];
23
+ /** Do not filter by openness at all. */
24
+ all?: boolean;
25
+ /** The project, for turning a leaf sprint name into a path. */
26
+ project?: string | undefined;
27
+ }
28
+ /**
29
+ * How "open" was decided, so the answer can say it.
30
+ *
31
+ * The output carries this verbatim. A list of work items is not interpretable
32
+ * without it: "12 open" means nothing until you know which states were counted
33
+ * as closed, and the whole reason this command exists is that a session had to
34
+ * work that out for itself and guess.
35
+ */
36
+ export interface Openness {
37
+ /** `categories` read the project; `fallback` guessed and should say so. */
38
+ source: "categories" | "fallback" | "explicit" | "none";
39
+ /** The states treated as finished. Empty when nothing was excluded. */
40
+ terminal: readonly string[];
41
+ /** Present only when it matters — see {@link StateCatalog.ambiguous}. */
42
+ perType?: boolean;
43
+ note?: string;
44
+ }
45
+ /** The names Azure DevOps' stock templates use, for when the catalogue is unreadable. */
46
+ export declare const FALLBACK_TERMINAL_STATES: readonly string[];
47
+ /**
48
+ * A WIQL string literal.
49
+ *
50
+ * Single quotes are doubled — WIQL's own escape, and the only one it has. This
51
+ * is not decoration: a sprint called `Bob's Sprint` composes an unterminated
52
+ * literal and Azure DevOps answers with a parse error naming a query the caller
53
+ * never wrote.
54
+ */
55
+ export declare function quote(value: string): string;
56
+ /**
57
+ * A leaf name becomes a path under the project; a path is left alone.
58
+ *
59
+ * `System.IterationPath` and `System.AreaPath` are tree fields whose values are
60
+ * always rooted at the project — `Contoso\Sprint 1`, never `Sprint 1`. Somebody
61
+ * typing `--sprint "Sprint 1"` means the obvious thing, and refusing it over a
62
+ * prefix they cannot see would be pedantry. A value that already contains a
63
+ * separator is taken as written, which is how a nested iteration is reached.
64
+ */
65
+ export declare function treePath(value: string, project: string | undefined): string;
66
+ /**
67
+ * The openness clause, or nothing.
68
+ *
69
+ * Two shapes, and the second is why {@link StateCatalog.ambiguous} exists. When
70
+ * every state name means the same thing on every type, one `NOT IN` covers the
71
+ * project. When a name is `InProgress` on one type and `Completed` on another,
72
+ * no single list is right — so each type gets its own clause and the types that
73
+ * carry no terminal state at all are admitted whole.
74
+ */
75
+ export declare function opennessClause(catalog: StateCatalog): string | undefined;
76
+ /**
77
+ * The statement.
78
+ *
79
+ * `[System.TeamProject] = @project` is always first and is not redundant with
80
+ * the project in the URL: WIQL will happily return items from other projects
81
+ * the token can see, and a `--mine` that reaches across an organisation is a
82
+ * different question from the one that was asked.
83
+ *
84
+ * Only `[System.Id]` is selected because WIQL returns references and never
85
+ * values however many columns are named — the fields come from the hydrate step
86
+ * afterwards, and selecting more here would only make the statement look like
87
+ * it did something it cannot.
88
+ */
89
+ export declare function buildWiql(filters: QueryFilters, openness: Openness, catalog?: StateCatalog): string;
90
+ /** What the openness of a query is, given what was asked and what could be read. */
91
+ export declare function opennessFor(filters: QueryFilters, catalog: StateCatalog | undefined, failure?: string): Openness;
92
+ //# sourceMappingURL=wiql-build.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wiql-build.d.ts","sourceRoot":"","sources":["../src/wiql-build.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAE7D;;;;;;;;GAQG;AAEH,0EAA0E;AAC1E,MAAM,WAAW,YAAY;IAC3B,6EAA6E;IAC7E,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3B,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC1B,oEAAoE;IACpE,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,uDAAuD;IACvD,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,IAAI,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACzB,wCAAwC;IACxC,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,+DAA+D;IAC/D,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC9B;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,QAAQ;IACvB,2EAA2E;IAC3E,MAAM,EAAE,YAAY,GAAG,UAAU,GAAG,UAAU,GAAG,MAAM,CAAC;IACxD,uEAAuE;IACvE,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;IAC5B,yEAAyE;IACzE,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,yFAAyF;AACzF,eAAO,MAAM,wBAAwB,EAAE,SAAS,MAAM,EAAkC,CAAC;AAEzF;;;;;;;GAOG;AACH,wBAAgB,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAE3C;AAOD;;;;;;;;GAQG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAG3E;AAED;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,YAAY,GAAG,MAAM,GAAG,SAAS,CAkBxE;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,SAAS,CAAC,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,MAAM,CA8CnG;AAED,oFAAoF;AACpF,wBAAgB,WAAW,CACzB,OAAO,EAAE,YAAY,EACrB,OAAO,EAAE,YAAY,GAAG,SAAS,EACjC,OAAO,CAAC,EAAE,MAAM,GACf,QAAQ,CAkCV"}
@@ -0,0 +1,147 @@
1
+ /** The names Azure DevOps' stock templates use, for when the catalogue is unreadable. */
2
+ export const FALLBACK_TERMINAL_STATES = ["Closed", "Done", "Removed"];
3
+ /**
4
+ * A WIQL string literal.
5
+ *
6
+ * Single quotes are doubled — WIQL's own escape, and the only one it has. This
7
+ * is not decoration: a sprint called `Bob's Sprint` composes an unterminated
8
+ * literal and Azure DevOps answers with a parse error naming a query the caller
9
+ * never wrote.
10
+ */
11
+ export function quote(value) {
12
+ return `'${value.replaceAll("'", "''")}'`;
13
+ }
14
+ function inClause(field, values) {
15
+ if (values.length === 1)
16
+ return `[${field}] = ${quote(values[0])}`;
17
+ return `[${field}] IN (${values.map(quote).join(", ")})`;
18
+ }
19
+ /**
20
+ * A leaf name becomes a path under the project; a path is left alone.
21
+ *
22
+ * `System.IterationPath` and `System.AreaPath` are tree fields whose values are
23
+ * always rooted at the project — `Contoso\Sprint 1`, never `Sprint 1`. Somebody
24
+ * typing `--sprint "Sprint 1"` means the obvious thing, and refusing it over a
25
+ * prefix they cannot see would be pedantry. A value that already contains a
26
+ * separator is taken as written, which is how a nested iteration is reached.
27
+ */
28
+ export function treePath(value, project) {
29
+ if (value.includes("\\") || project === undefined || project === "")
30
+ return value;
31
+ return `${project}\\${value}`;
32
+ }
33
+ /**
34
+ * The openness clause, or nothing.
35
+ *
36
+ * Two shapes, and the second is why {@link StateCatalog.ambiguous} exists. When
37
+ * every state name means the same thing on every type, one `NOT IN` covers the
38
+ * project. When a name is `InProgress` on one type and `Completed` on another,
39
+ * no single list is right — so each type gets its own clause and the types that
40
+ * carry no terminal state at all are admitted whole.
41
+ */
42
+ export function opennessClause(catalog) {
43
+ if (catalog.ambiguous.length === 0) {
44
+ if (catalog.terminal.length === 0)
45
+ return undefined;
46
+ return `[System.State] NOT IN (${catalog.terminal.map(quote).join(", ")})`;
47
+ }
48
+ const perType = [];
49
+ for (const [type, states] of catalog.byType) {
50
+ if (states.terminal.length === 0) {
51
+ perType.push(`[System.WorkItemType] = ${quote(type)}`);
52
+ continue;
53
+ }
54
+ perType.push(`([System.WorkItemType] = ${quote(type)}`
55
+ + ` AND [System.State] NOT IN (${states.terminal.map(quote).join(", ")}))`);
56
+ }
57
+ return perType.length === 0 ? undefined : `(${perType.join(" OR ")})`;
58
+ }
59
+ /**
60
+ * The statement.
61
+ *
62
+ * `[System.TeamProject] = @project` is always first and is not redundant with
63
+ * the project in the URL: WIQL will happily return items from other projects
64
+ * the token can see, and a `--mine` that reaches across an organisation is a
65
+ * different question from the one that was asked.
66
+ *
67
+ * Only `[System.Id]` is selected because WIQL returns references and never
68
+ * values however many columns are named — the fields come from the hydrate step
69
+ * afterwards, and selecting more here would only make the statement look like
70
+ * it did something it cannot.
71
+ */
72
+ export function buildWiql(filters, openness, catalog) {
73
+ const where = ["[System.TeamProject] = @project"];
74
+ if (filters.mine === true)
75
+ where.push("[System.AssignedTo] = @Me");
76
+ else if (filters.assignee !== undefined)
77
+ where.push(`[System.AssignedTo] = ${quote(filters.assignee)}`);
78
+ if (filters.types !== undefined && filters.types.length > 0) {
79
+ where.push(inClause("System.WorkItemType", filters.types));
80
+ }
81
+ if (filters.states !== undefined && filters.states.length > 0) {
82
+ where.push(inClause("System.State", filters.states));
83
+ }
84
+ else if (openness.source === "categories" && catalog !== undefined) {
85
+ const clause = opennessClause(catalog);
86
+ if (clause !== undefined)
87
+ where.push(clause);
88
+ }
89
+ else if (openness.source === "fallback") {
90
+ where.push(`[System.State] NOT IN (${openness.terminal.map(quote).join(", ")})`);
91
+ }
92
+ if (filters.sprint !== undefined) {
93
+ // `current` is the one value that is a macro rather than a path. It resolves
94
+ // against a TEAM, which is a path segment on the request rather than
95
+ // anything in the query — see `WiqlApi.query`.
96
+ where.push(filters.sprint.toLowerCase() === "current"
97
+ ? "[System.IterationPath] = @currentIteration"
98
+ : `[System.IterationPath] UNDER ${quote(treePath(filters.sprint, filters.project))}`);
99
+ }
100
+ if (filters.area !== undefined) {
101
+ where.push(`[System.AreaPath] UNDER ${quote(treePath(filters.area, filters.project))}`);
102
+ }
103
+ for (const tag of filters.tags ?? []) {
104
+ // Tags are a semicolon-joined string, so CONTAINS is the operator. It is a
105
+ // substring match: a `--tag api` also matches `api-v2`, which is worth
106
+ // knowing and not worth refusing.
107
+ where.push(`[System.Tags] CONTAINS ${quote(tag)}`);
108
+ }
109
+ return ("SELECT [System.Id] FROM WorkItems WHERE "
110
+ + where.join(" AND ")
111
+ + " ORDER BY [System.ChangedDate] DESC");
112
+ }
113
+ /** What the openness of a query is, given what was asked and what could be read. */
114
+ export function opennessFor(filters, catalog, failure) {
115
+ if (filters.states !== undefined && filters.states.length > 0) {
116
+ return {
117
+ source: "explicit",
118
+ terminal: [],
119
+ note: "You named the states, so nothing was treated as finished.",
120
+ };
121
+ }
122
+ if (filters.all === true) {
123
+ return { source: "none", terminal: [], note: "--all: every state, open or finished." };
124
+ }
125
+ if (catalog !== undefined) {
126
+ return {
127
+ source: "categories",
128
+ terminal: catalog.terminal,
129
+ ...(catalog.ambiguous.length > 0 ? { perType: true } : {}),
130
+ note: "Read from this project's own state categories, so it is right whatever the process "
131
+ + "template calls things."
132
+ + (catalog.ambiguous.length > 0
133
+ ? ` ${catalog.ambiguous.join(", ")} mean different things on different work item types,`
134
+ + " so the filter is per type."
135
+ : ""),
136
+ };
137
+ }
138
+ return {
139
+ source: "fallback",
140
+ terminal: FALLBACK_TERMINAL_STATES,
141
+ note: "COULD NOT read this project's state categories"
142
+ + (failure === undefined ? "" : ` (${failure})`)
143
+ + ", so these are Azure DevOps' stock names. If this project renames its states, this "
144
+ + "result may be missing work or showing finished work. Pass --state to be exact.",
145
+ };
146
+ }
147
+ //# sourceMappingURL=wiql-build.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wiql-build.js","sourceRoot":"","sources":["../src/wiql-build.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@floh-solutions/pharos-cli",
3
- "version": "0.4.0",
3
+ "version": "0.12.0",
4
4
  "description": "Azure DevOps from a headless shell, for an agent: the whole context of a task in one call, and the wiki/comment verbs Microsoft's MCP server does not ship.",
5
5
  "license": "UNLICENSED",
6
6
  "author": "FLOH Solutions",
@@ -24,8 +24,8 @@
24
24
  "node": ">=22"
25
25
  },
26
26
  "dependencies": {
27
- "@floh-solutions/ado-core": "0.1.0",
28
- "@floh-solutions/plan-to-board": "0.1.1"
27
+ "@floh-solutions/plan-to-board": "0.1.1",
28
+ "@floh-solutions/ado-core": "0.7.0"
29
29
  },
30
30
  "devDependencies": {
31
31
  "@types/node": "^22.10.2",