@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.
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +381 -7
- package/dist/cli.js.map +1 -1
- package/dist/commands/attach.d.ts +30 -0
- package/dist/commands/attach.d.ts.map +1 -0
- package/dist/commands/attach.js +55 -0
- package/dist/commands/attach.js.map +1 -0
- package/dist/commands/create.d.ts +35 -0
- package/dist/commands/create.d.ts.map +1 -0
- package/dist/commands/create.js +82 -0
- package/dist/commands/create.js.map +1 -0
- package/dist/commands/detach.d.ts +34 -0
- package/dist/commands/detach.d.ts.map +1 -0
- package/dist/commands/detach.js +117 -0
- package/dist/commands/detach.js.map +1 -0
- package/dist/commands/discover.d.ts +66 -0
- package/dist/commands/discover.d.ts.map +1 -0
- package/dist/commands/discover.js +128 -0
- package/dist/commands/discover.js.map +1 -0
- package/dist/commands/hooks.d.ts +24 -0
- package/dist/commands/hooks.d.ts.map +1 -0
- package/dist/commands/hooks.js +184 -0
- package/dist/commands/hooks.js.map +1 -0
- package/dist/commands/image.d.ts +44 -0
- package/dist/commands/image.d.ts.map +1 -0
- package/dist/commands/image.js +114 -0
- package/dist/commands/image.js.map +1 -0
- package/dist/commands/import.d.ts +51 -0
- package/dist/commands/import.d.ts.map +1 -0
- package/dist/commands/import.js +190 -0
- package/dist/commands/import.js.map +1 -0
- package/dist/commands/link.d.ts +40 -0
- package/dist/commands/link.d.ts.map +1 -0
- package/dist/commands/link.js +150 -0
- package/dist/commands/link.js.map +1 -0
- package/dist/commands/people.d.ts +39 -0
- package/dist/commands/people.d.ts.map +1 -0
- package/dist/commands/people.js +64 -0
- package/dist/commands/people.js.map +1 -0
- package/dist/commands/query.d.ts +43 -0
- package/dist/commands/query.d.ts.map +1 -0
- package/dist/commands/query.js +202 -0
- package/dist/commands/query.js.map +1 -0
- package/dist/commands/recycle.d.ts +10 -0
- package/dist/commands/recycle.d.ts.map +1 -0
- package/dist/commands/recycle.js +118 -0
- package/dist/commands/recycle.js.map +1 -0
- package/dist/commands/update.d.ts +52 -0
- package/dist/commands/update.d.ts.map +1 -0
- package/dist/commands/update.js +181 -0
- package/dist/commands/update.js.map +1 -0
- package/dist/commands/wiki.d.ts.map +1 -1
- package/dist/commands/wiki.js +133 -2
- package/dist/commands/wiki.js.map +1 -1
- package/dist/output.d.ts.map +1 -1
- package/dist/output.js +32 -2
- package/dist/output.js.map +1 -1
- package/dist/wiql-build.d.ts +92 -0
- package/dist/wiql-build.d.ts.map +1 -0
- package/dist/wiql-build.js +147 -0
- package/dist/wiql-build.js.map +1 -0
- package/package.json +3 -3
- package/skill/SKILL.md +315 -65
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { emit, emitText, usageError } from "../output.js";
|
|
2
|
+
import { approve } from "../session.js";
|
|
3
|
+
/**
|
|
4
|
+
* `pharos delete`, `restore` and `deleted` — the recycle bin.
|
|
5
|
+
*
|
|
6
|
+
* **Deleting is not destroying, and the words matter.** `DELETE
|
|
7
|
+
* /wit/workitems/{id}` moves an item to the project's recycle bin, from which
|
|
8
|
+
* anybody can restore it; only `?destroy=true` is permanent, and that needs a
|
|
9
|
+
* project-level permission most accounts do not have. The macOS app names its
|
|
10
|
+
* button "Move to Recycle Bin" rather than "Delete" for exactly this reason —
|
|
11
|
+
* a verb that reads as irreversible when it is not teaches people to fear the
|
|
12
|
+
* safe thing and, worse, to trust the unsafe one.
|
|
13
|
+
*
|
|
14
|
+
* `restore` and the recycle-bin listing are the half `az boards work-item
|
|
15
|
+
* delete` does not have at all, which is what makes this worth building rather
|
|
16
|
+
* than duplicating (#590).
|
|
17
|
+
*
|
|
18
|
+
* ## There is deliberately no way to destroy anything from here
|
|
19
|
+
*
|
|
20
|
+
* `WorkItemsApi.destroyDeleted` exists in `ado-core` and this CLI does not
|
|
21
|
+
* expose it. @user's call, and the reasoning is worth keeping because somebody
|
|
22
|
+
* will eventually propose adding it back:
|
|
23
|
+
*
|
|
24
|
+
* - **The primary consumer is an agent**, and agents learn to pass `--yes` —
|
|
25
|
+
* it is on every destructive verb here. A flag guarded only by convention is
|
|
26
|
+
* one prompt away from being satisfied.
|
|
27
|
+
* - **It is the only verb in the surface with no way back.** A wiki page has
|
|
28
|
+
* git history, a field has revisions, a deleted item has this bin.
|
|
29
|
+
* - It usually 403s anyway: destroying needs a project-level permission most
|
|
30
|
+
* accounts do not hold.
|
|
31
|
+
* - Nothing is gained. The bin is not a scarce resource.
|
|
32
|
+
*
|
|
33
|
+
* The web UI owns it, with an admin's own confirmation, in the place an admin
|
|
34
|
+
* already goes for permissions work.
|
|
35
|
+
*/
|
|
36
|
+
function workItemId(raw, usage) {
|
|
37
|
+
if (raw === undefined)
|
|
38
|
+
throw usageError(usage);
|
|
39
|
+
if (!/^\d+$/.test(raw))
|
|
40
|
+
throw usageError(`"${raw}" is not a work item id.`, { given: raw });
|
|
41
|
+
return Number(raw);
|
|
42
|
+
}
|
|
43
|
+
export async function runDelete(io, session, positionals) {
|
|
44
|
+
const id = workItemId(positionals[0], "Which work item? `pharos delete <id> --yes`.");
|
|
45
|
+
// Read first so the refusal can QUOTE what it is about to remove. "Delete 12
|
|
46
|
+
// work items?" is the dialog everybody clicks through; "#225 — Complete
|
|
47
|
+
// handover and closeout" is the one that stops the wrong hand.
|
|
48
|
+
const item = await session.client.workItems.get(id);
|
|
49
|
+
const title = item.fields?.["System.Title"];
|
|
50
|
+
const subject = typeof title === "string" && title !== "" ? `#${id} — ${title}` : `#${id}`;
|
|
51
|
+
const stop = approve(io, session, {
|
|
52
|
+
what: `move ${subject} to the Recycle Bin`,
|
|
53
|
+
would: { id, title: title ?? null, destination: "Recycle Bin", restorable: true },
|
|
54
|
+
});
|
|
55
|
+
if (stop !== undefined)
|
|
56
|
+
return stop;
|
|
57
|
+
if (session.previewOnly) {
|
|
58
|
+
return emit(io, { applied: false, dryRun: true, id, title: title ?? null });
|
|
59
|
+
}
|
|
60
|
+
await session.client.workItems.delete(id);
|
|
61
|
+
const result = {
|
|
62
|
+
applied: true,
|
|
63
|
+
id,
|
|
64
|
+
title: title ?? null,
|
|
65
|
+
restorable: true,
|
|
66
|
+
hint: `Undo with \`pharos restore ${id}\`.`,
|
|
67
|
+
};
|
|
68
|
+
return session.pretty ? emitText(io, `${subject} → Recycle Bin`) : emit(io, result);
|
|
69
|
+
}
|
|
70
|
+
export async function runRestore(io, session, positionals) {
|
|
71
|
+
const id = workItemId(positionals[0], "Which work item? `pharos restore <id>`.");
|
|
72
|
+
// No --yes: restoring puts something back, which is the recoverable direction
|
|
73
|
+
// and the one somebody reaches for when they have just made a mistake.
|
|
74
|
+
if (session.previewOnly) {
|
|
75
|
+
return emit(io, { applied: false, dryRun: true, id });
|
|
76
|
+
}
|
|
77
|
+
const restored = await session.client.workItems.restore(id);
|
|
78
|
+
const result = { applied: true, id, name: restored.name ?? null };
|
|
79
|
+
return session.pretty ? emitText(io, `#${id} restored`) : emit(io, result);
|
|
80
|
+
}
|
|
81
|
+
export async function runDeleted(io, session, options) {
|
|
82
|
+
const references = await session.client.workItems.listDeleted();
|
|
83
|
+
// The list endpoint returns SHALLOW references — `{id, url}` and nothing more
|
|
84
|
+
// — so without this second call the answer is a column of bare numbers. Same
|
|
85
|
+
// hydrate step `query` makes after WIQL, and for the same reason: a list of
|
|
86
|
+
// ids answers no question anybody actually asked.
|
|
87
|
+
const wanted = references.slice(0, options.top).map((reference) => reference.id);
|
|
88
|
+
const items = await session.client.workItems.getDeletedBatch(wanted);
|
|
89
|
+
const result = {
|
|
90
|
+
count: references.length,
|
|
91
|
+
shown: items.length,
|
|
92
|
+
items: items.map((item) => ({
|
|
93
|
+
id: item.id,
|
|
94
|
+
type: item.type ?? null,
|
|
95
|
+
name: item.name ?? null,
|
|
96
|
+
deletedBy: item.deletedBy ?? null,
|
|
97
|
+
// Not ISO-8601 — "8/4/2026 2:37:24 PM". Passed through as the label it is
|
|
98
|
+
// rather than parsed, because parsing it outside a US locale swaps the day
|
|
99
|
+
// and month for the first twelve days of any month.
|
|
100
|
+
deletedDate: item.deletedDate ?? null,
|
|
101
|
+
})),
|
|
102
|
+
...(references.length === 0 ? { note: "The Recycle Bin is empty." } : {}),
|
|
103
|
+
...(references.length > items.length
|
|
104
|
+
? { note: `${references.length} in the bin; naming the first ${items.length}. --top for more.` }
|
|
105
|
+
: {}),
|
|
106
|
+
};
|
|
107
|
+
if (!session.pretty)
|
|
108
|
+
return emit(io, result);
|
|
109
|
+
if (references.length === 0)
|
|
110
|
+
return emitText(io, "The Recycle Bin is empty.");
|
|
111
|
+
const lines = result.items.map((item) => ` #${String(item.id).padEnd(6)} ${(item.type ?? "").padEnd(10)} `
|
|
112
|
+
+ `${(item.name ?? "(unnamed)").slice(0, 50).padEnd(50)} ${item.deletedDate ?? ""}`);
|
|
113
|
+
if (references.length > items.length) {
|
|
114
|
+
lines.push("", `${references.length} in the bin; ${items.length} shown. --top for more.`);
|
|
115
|
+
}
|
|
116
|
+
return emitText(io, lines.join("\n"));
|
|
117
|
+
}
|
|
118
|
+
//# sourceMappingURL=recycle.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recycle.js","sourceRoot":"","sources":["../../src/commands/recycle.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { type WorkItem } from "@floh-solutions/ado-core";
|
|
2
|
+
import { type ExitCode, type Io } from "../output.js";
|
|
3
|
+
import type { Session } from "../session.js";
|
|
4
|
+
/**
|
|
5
|
+
* `pharos update <id>` — change a field, safely.
|
|
6
|
+
*
|
|
7
|
+
* **This verb is why the Azure DevOps MCP server can be removed.** The MCP was
|
|
8
|
+
* the only way to set a state or a priority from here, and it authenticates
|
|
9
|
+
* through the Azure CLI — which opens a browser, which makes any session that
|
|
10
|
+
* touches it non-autonomous. That was the whole cost.
|
|
11
|
+
*
|
|
12
|
+
* ## It is safer than the thing it replaces
|
|
13
|
+
*
|
|
14
|
+
* The MCP's patch op enum is `add | replace | remove`. There is no `test`, so
|
|
15
|
+
* **every MCP write is last-write-wins**: it cannot express "apply this only if
|
|
16
|
+
* the item is still at the revision I read". This reads the item, then applies
|
|
17
|
+
* the change under `test` on `/rev` (PLAN.md §9, and the reason `ado-core`
|
|
18
|
+
* exists at all). A teammate who wrote between the read and the write gets a
|
|
19
|
+
* `conflict` back rather than silently losing their edit.
|
|
20
|
+
*
|
|
21
|
+
* ## Why it is not behind `--yes`
|
|
22
|
+
*
|
|
23
|
+
* A field edit is an ordinary edit, like posting a comment — Azure DevOps keeps
|
|
24
|
+
* every revision, so nothing here is unrecoverable. Putting the most common verb
|
|
25
|
+
* on a board (moving a state when the work moves) behind a confirmation flag
|
|
26
|
+
* teaches people to pass `--yes` reflexively, which is how the flag stops
|
|
27
|
+
* meaning anything on the verbs where it matters. `--dry-run` is supported for
|
|
28
|
+
* when you want to look first.
|
|
29
|
+
*/
|
|
30
|
+
export interface UpdateCommandOptions {
|
|
31
|
+
state: string | undefined;
|
|
32
|
+
priority: string | undefined;
|
|
33
|
+
assignee: string | undefined;
|
|
34
|
+
title: string | undefined;
|
|
35
|
+
/** `Name=value`, repeatable. The escape hatch for every other field. */
|
|
36
|
+
fields: readonly string[];
|
|
37
|
+
/** Pin the revision explicitly instead of reading it in this command. */
|
|
38
|
+
expectRev: number | undefined;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Named fields, and the reference names they actually are.
|
|
42
|
+
*
|
|
43
|
+
* Exported because `pharos create` reads the same map. One definition means
|
|
44
|
+
* `--state` cannot come to mean different things on the two verbs that both
|
|
45
|
+
* take it — and a session that has learned one has learned the other.
|
|
46
|
+
*/
|
|
47
|
+
export declare const SHORTHAND: Record<string, string>;
|
|
48
|
+
export declare function runUpdate(io: Io, session: Session, positionals: readonly string[], options: UpdateCommandOptions): Promise<ExitCode>;
|
|
49
|
+
/** Exported for the attach command, which shares the id-parsing rule. */
|
|
50
|
+
export declare function workItemId(raw: string | undefined, usage: string): number;
|
|
51
|
+
export type { WorkItem };
|
|
52
|
+
//# sourceMappingURL=update.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"update.d.ts","sourceRoot":"","sources":["../../src/commands/update.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqC,KAAK,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AAE5F,OAAO,EAAuC,KAAK,QAAQ,EAAE,KAAK,EAAE,EAAE,MAAM,cAAc,CAAC;AAC3F,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAE7C;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7B,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7B,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,wEAAwE;IACxE,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;IAC1B,yEAAyE;IACzE,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;CAC/B;AAED;;;;;;GAMG;AACH,eAAO,MAAM,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAK5C,CAAC;AAEF,wBAAsB,SAAS,CAC7B,EAAE,EAAE,EAAE,EACN,OAAO,EAAE,OAAO,EAChB,WAAW,EAAE,SAAS,MAAM,EAAE,EAC9B,OAAO,EAAE,oBAAoB,GAC5B,OAAO,CAAC,QAAQ,CAAC,CAuEnB;AAuHD,yEAAyE;AACzE,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAIzE;AAED,YAAY,EAAE,QAAQ,EAAE,CAAC"}
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
import { setField } from "@floh-solutions/ado-core";
|
|
2
|
+
import { EXIT_OK, emit, emitText, usageError } from "../output.js";
|
|
3
|
+
/**
|
|
4
|
+
* Named fields, and the reference names they actually are.
|
|
5
|
+
*
|
|
6
|
+
* Exported because `pharos create` reads the same map. One definition means
|
|
7
|
+
* `--state` cannot come to mean different things on the two verbs that both
|
|
8
|
+
* take it — and a session that has learned one has learned the other.
|
|
9
|
+
*/
|
|
10
|
+
export const SHORTHAND = {
|
|
11
|
+
state: "System.State",
|
|
12
|
+
priority: "Microsoft.VSTS.Common.Priority",
|
|
13
|
+
assignee: "System.AssignedTo",
|
|
14
|
+
title: "System.Title",
|
|
15
|
+
};
|
|
16
|
+
export async function runUpdate(io, session, positionals, options) {
|
|
17
|
+
const raw = positionals[0];
|
|
18
|
+
if (raw === undefined)
|
|
19
|
+
throw usageError("Which work item? `pharos update <id> --state Doing`.");
|
|
20
|
+
if (!/^\d+$/.test(raw))
|
|
21
|
+
throw usageError(`"${raw}" is not a work item id.`, { given: raw });
|
|
22
|
+
const id = Number(raw);
|
|
23
|
+
const wanted = collect(options);
|
|
24
|
+
if (wanted.size === 0) {
|
|
25
|
+
throw usageError("Nothing to change. Pass --state, --priority, --assignee, --title, or --field Name=value.", { fields: Object.keys(SHORTHAND) });
|
|
26
|
+
}
|
|
27
|
+
// Read first, for two reasons: the revision the write is guarded on, and the
|
|
28
|
+
// before-values. A diff nobody can see is a write nobody can check.
|
|
29
|
+
const before = await session.client.workItems.get(id);
|
|
30
|
+
// AFTER the read, because a state is only valid for a TYPE. Measured live and
|
|
31
|
+
// it is why this moved: `--state "In Progress"` passed a flat check — the
|
|
32
|
+
// project really does have that state, on Test Suite — and then 400'd,
|
|
33
|
+
// because #225 is a Task and a Task has To Do, Doing, Done. Checking against
|
|
34
|
+
// the whole project is the same guess the caller was making, one layer down.
|
|
35
|
+
await assertStateExists(session, options.state, before);
|
|
36
|
+
const rev = options.expectRev ?? before.rev;
|
|
37
|
+
if (rev === undefined) {
|
|
38
|
+
throw usageError(`Work item #${id} did not report a revision, so the write cannot be guarded. Pass `
|
|
39
|
+
+ "--expect-rev to override.");
|
|
40
|
+
}
|
|
41
|
+
const changes = [...wanted].map(([field, value]) => ({
|
|
42
|
+
field,
|
|
43
|
+
from: readable(before.fields?.[field]),
|
|
44
|
+
to: value,
|
|
45
|
+
}));
|
|
46
|
+
// A change already applied is not a change. Worth saying rather than writing:
|
|
47
|
+
// a no-op PATCH still bumps System.Rev, which invalidates every other cached
|
|
48
|
+
// revision against this item for no reason at all.
|
|
49
|
+
const moving = changes.filter((change) => change.from !== change.to);
|
|
50
|
+
if (moving.length === 0) {
|
|
51
|
+
return emitOrText(io, session, {
|
|
52
|
+
applied: false,
|
|
53
|
+
id,
|
|
54
|
+
rev,
|
|
55
|
+
unchanged: true,
|
|
56
|
+
changes,
|
|
57
|
+
message: "Already set to that. Nothing was written.",
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
if (session.previewOnly) {
|
|
61
|
+
return emitOrText(io, session, { applied: false, dryRun: true, id, rev, changes: moving });
|
|
62
|
+
}
|
|
63
|
+
const ops = moving.map((change) => setField(change.field, change.to));
|
|
64
|
+
const after = await session.client.workItems.updateWithRev(id, rev, ops, {
|
|
65
|
+
suppressNotifications: true,
|
|
66
|
+
});
|
|
67
|
+
return emitOrText(io, session, {
|
|
68
|
+
applied: true,
|
|
69
|
+
id,
|
|
70
|
+
rev: after.rev,
|
|
71
|
+
previousRev: rev,
|
|
72
|
+
changes: moving,
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Refuse a state **this item's type** does not have, with the list attached.
|
|
77
|
+
*
|
|
78
|
+
* Two things matter and both were learned the hard way on a live board.
|
|
79
|
+
*
|
|
80
|
+
* **WHERE.** Without this the write goes out, Azure DevOps answers 400 with a
|
|
81
|
+
* sentence about supported values, and a session that cannot see the list
|
|
82
|
+
* guesses again — the single biggest retry cause in this CLI.
|
|
83
|
+
*
|
|
84
|
+
* **AGAINST WHAT.** The first version checked the state against the whole
|
|
85
|
+
* project and was wrong in the most convincing way available: `--state "In
|
|
86
|
+
* Progress"` sailed through, because that state genuinely exists — on Test
|
|
87
|
+
* Suite — and then 400'd, because the item was a Task. A project-wide check is
|
|
88
|
+
* the caller's own guess with an extra call in front of it. States belong to
|
|
89
|
+
* types.
|
|
90
|
+
*
|
|
91
|
+
* A failure to READ the catalogue is not a failure to update: if the types call
|
|
92
|
+
* 403s this says nothing and the write proceeds on its own merits. A validator
|
|
93
|
+
* that can block a legitimate write when it is the validator that is broken is
|
|
94
|
+
* worse than no validator.
|
|
95
|
+
*/
|
|
96
|
+
async function assertStateExists(session, state, item) {
|
|
97
|
+
if (state === undefined || state === "")
|
|
98
|
+
return;
|
|
99
|
+
const type = item.fields?.["System.WorkItemType"];
|
|
100
|
+
if (typeof type !== "string" || type === "")
|
|
101
|
+
return;
|
|
102
|
+
let states;
|
|
103
|
+
try {
|
|
104
|
+
const catalog = await session.client.workItemTypes.states();
|
|
105
|
+
const forType = catalog.byType.get(type);
|
|
106
|
+
if (forType === undefined)
|
|
107
|
+
return;
|
|
108
|
+
states = [...forType.open, ...forType.terminal];
|
|
109
|
+
}
|
|
110
|
+
catch {
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
if (states.length === 0)
|
|
114
|
+
return;
|
|
115
|
+
if (states.some((candidate) => candidate.toLowerCase() === state.toLowerCase()))
|
|
116
|
+
return;
|
|
117
|
+
throw usageError(`A ${type} has no state called "${state}". Run \`pharos types --type ${type}\` — states `
|
|
118
|
+
+ "belong to a work item type, so a state that exists elsewhere in the project is still "
|
|
119
|
+
+ "not one this item can take.", { given: state, type, states: [...states].sort() });
|
|
120
|
+
}
|
|
121
|
+
/** The requested changes, shorthand and `--field` merged, later wins. */
|
|
122
|
+
function collect(options) {
|
|
123
|
+
const wanted = new Map();
|
|
124
|
+
for (const [flag, field] of Object.entries(SHORTHAND)) {
|
|
125
|
+
const value = options[flag];
|
|
126
|
+
if (typeof value === "string" && value !== "")
|
|
127
|
+
wanted.set(field, value);
|
|
128
|
+
}
|
|
129
|
+
for (const pair of options.fields) {
|
|
130
|
+
// Split on the FIRST `=` only: a value can legitimately contain one, and a
|
|
131
|
+
// reference name never does.
|
|
132
|
+
const at = pair.indexOf("=");
|
|
133
|
+
if (at <= 0) {
|
|
134
|
+
throw usageError(`--field wants Name=value, not "${pair}".`, {
|
|
135
|
+
example: "--field Microsoft.VSTS.Scheduling.RemainingWork=3",
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
wanted.set(pair.slice(0, at).trim(), pair.slice(at + 1));
|
|
139
|
+
}
|
|
140
|
+
return wanted;
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* A field's current value as a string, for the before/after.
|
|
144
|
+
*
|
|
145
|
+
* Identities come back as objects and numbers as numbers; comparing those to a
|
|
146
|
+
* command-line string without flattening would report every write as a change,
|
|
147
|
+
* including the ones that are not.
|
|
148
|
+
*/
|
|
149
|
+
function readable(value) {
|
|
150
|
+
if (value === undefined || value === null)
|
|
151
|
+
return "";
|
|
152
|
+
if (typeof value === "object") {
|
|
153
|
+
const display = value.displayName;
|
|
154
|
+
if (typeof display === "string")
|
|
155
|
+
return display;
|
|
156
|
+
return JSON.stringify(value);
|
|
157
|
+
}
|
|
158
|
+
return String(value);
|
|
159
|
+
}
|
|
160
|
+
function emitOrText(io, session, result) {
|
|
161
|
+
if (!session.pretty)
|
|
162
|
+
return emit(io, result);
|
|
163
|
+
const lines = [`#${result.id} · rev ${result.rev ?? "?"}`];
|
|
164
|
+
for (const change of result.changes) {
|
|
165
|
+
lines.push(` ${change.field}: ${change.from === "" ? "(empty)" : change.from} → ${change.to}`);
|
|
166
|
+
}
|
|
167
|
+
if (result.applied === false) {
|
|
168
|
+
lines.push("", typeof result["message"] === "string" ? result["message"] : "Nothing written.");
|
|
169
|
+
}
|
|
170
|
+
emitText(io, lines.join("\n"));
|
|
171
|
+
return EXIT_OK;
|
|
172
|
+
}
|
|
173
|
+
/** Exported for the attach command, which shares the id-parsing rule. */
|
|
174
|
+
export function workItemId(raw, usage) {
|
|
175
|
+
if (raw === undefined)
|
|
176
|
+
throw usageError(usage);
|
|
177
|
+
if (!/^\d+$/.test(raw))
|
|
178
|
+
throw usageError(`"${raw}" is not a work item id.`, { given: raw });
|
|
179
|
+
return Number(raw);
|
|
180
|
+
}
|
|
181
|
+
//# sourceMappingURL=update.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"update.js","sourceRoot":"","sources":["../../src/commands/update.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wiki.d.ts","sourceRoot":"","sources":["../../src/commands/wiki.ts"],"names":[],"mappings":"AAEA,OAAO,EAAoB,KAAK,QAAQ,EAAE,KAAK,EAAE,EAAE,MAAM,cAAc,CAAC;AACxE,OAAO,EAAW,KAAK,OAAO,EAAE,MAAM,eAAe,CAAC;AAEtD;;;;;;;;;;;;;GAaG;AAEH,wBAAsB,OAAO,CAC3B,EAAE,EAAE,EAAE,EACN,OAAO,EAAE,OAAO,EAChB,WAAW,EAAE,SAAS,MAAM,EAAE,EAC9B,KAAK,EAAE;IAAE,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,GACtC,OAAO,CAAC,QAAQ,CAAC,
|
|
1
|
+
{"version":3,"file":"wiki.d.ts","sourceRoot":"","sources":["../../src/commands/wiki.ts"],"names":[],"mappings":"AAEA,OAAO,EAAoB,KAAK,QAAQ,EAAE,KAAK,EAAE,EAAE,MAAM,cAAc,CAAC;AACxE,OAAO,EAAW,KAAK,OAAO,EAAE,MAAM,eAAe,CAAC;AAEtD;;;;;;;;;;;;;GAaG;AAEH,wBAAsB,OAAO,CAC3B,EAAE,EAAE,EAAE,EACN,OAAO,EAAE,OAAO,EAChB,WAAW,EAAE,SAAS,MAAM,EAAE,EAC9B,KAAK,EAAE;IAAE,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,GACtC,OAAO,CAAC,QAAQ,CAAC,CA+BnB"}
|
package/dist/commands/wiki.js
CHANGED
|
@@ -29,10 +29,17 @@ export async function runWiki(io, session, positionals, input) {
|
|
|
29
29
|
return write(io, session, rest, input.content);
|
|
30
30
|
case "delete":
|
|
31
31
|
return remove(io, session, rest);
|
|
32
|
+
case "move":
|
|
33
|
+
return move(io, session, rest, { rename: false });
|
|
34
|
+
case "rename":
|
|
35
|
+
return move(io, session, rest, { rename: true });
|
|
36
|
+
case "duplicate":
|
|
37
|
+
return duplicate(io, session, rest);
|
|
32
38
|
case undefined:
|
|
33
|
-
throw usageError("`pharos wiki <list|tree|read|write|delete>`.");
|
|
39
|
+
throw usageError("`pharos wiki <list|tree|read|write|move|rename|duplicate|delete>`.");
|
|
34
40
|
default:
|
|
35
|
-
throw usageError(`Unknown wiki verb "${verb}". Try list, tree, read, write
|
|
41
|
+
throw usageError(`Unknown wiki verb "${verb}". Try list, tree, read, write, move, rename, duplicate `
|
|
42
|
+
+ "or delete.");
|
|
36
43
|
}
|
|
37
44
|
}
|
|
38
45
|
async function listWikis(io, session) {
|
|
@@ -136,6 +143,130 @@ async function remove(io, session, positionals) {
|
|
|
136
143
|
await session.wiki.deletePage(name, path, existing.version);
|
|
137
144
|
return emit(io, { applied: true, action: "deleted", wiki: name, path });
|
|
138
145
|
}
|
|
146
|
+
/**
|
|
147
|
+
* `wiki move <path> <newPath>` and `wiki rename <path> <name>`.
|
|
148
|
+
*
|
|
149
|
+
* **One function, because Azure DevOps has one endpoint.** A rename is a
|
|
150
|
+
* `newPath` whose leaf differs; a move is one whose parent differs. The two
|
|
151
|
+
* verbs exist because people reach for different words, and both land here so
|
|
152
|
+
* they cannot drift.
|
|
153
|
+
*
|
|
154
|
+
* Behind `--yes` — unlike `write`, which creates freely. A move CHANGES WHAT THE
|
|
155
|
+
* PAGE IS: the path is the identity, there is no page id, so every stored
|
|
156
|
+
* reference to the old path breaks, including artifact links from work items.
|
|
157
|
+
* Nothing anywhere reports that, which is exactly the shape of failure this CLI
|
|
158
|
+
* puts behind a guard.
|
|
159
|
+
*/
|
|
160
|
+
async function move(io, session, positionals, options) {
|
|
161
|
+
const path = requirePath(positionals[0]);
|
|
162
|
+
const given = positionals[1];
|
|
163
|
+
if (given === undefined || given.trim() === "") {
|
|
164
|
+
throw usageError(options.rename
|
|
165
|
+
? "`pharos wiki rename <path> <new name>` — the NAME, not a path."
|
|
166
|
+
: "`pharos wiki move <path> <new path>`.");
|
|
167
|
+
}
|
|
168
|
+
const name = await session.wikiIdentifier();
|
|
169
|
+
const newPath = options.rename ? joinPath(parentOf(path), given) : normalisePath(given);
|
|
170
|
+
if (newPath === path) {
|
|
171
|
+
return emit(io, { applied: false, action: "unchanged", wiki: name, path });
|
|
172
|
+
}
|
|
173
|
+
const source = await readIfPresent(session, name, path);
|
|
174
|
+
if (source === undefined) {
|
|
175
|
+
throw usageError(`There is no wiki page at ${path}.`, { wiki: name, path });
|
|
176
|
+
}
|
|
177
|
+
// Checked before the call so the refusal names the page rather than leaving
|
|
178
|
+
// Azure DevOps to answer with a conflict about a path the caller did not type.
|
|
179
|
+
if ((await readIfPresent(session, name, newPath)) !== undefined) {
|
|
180
|
+
throw usageError(`There is already a wiki page at ${newPath}.`, { wiki: name, newPath });
|
|
181
|
+
}
|
|
182
|
+
const stop = approve(io, session, {
|
|
183
|
+
what: `move the wiki page ${path} to ${newPath}`,
|
|
184
|
+
would: {
|
|
185
|
+
action: options.rename ? "rename" : "move",
|
|
186
|
+
wiki: name,
|
|
187
|
+
path,
|
|
188
|
+
newPath,
|
|
189
|
+
warning: "A wiki page has no id — its path IS its identity. Anything pointing at the old path "
|
|
190
|
+
+ "stops resolving, including artifact links from work items, and nothing reports it. "
|
|
191
|
+
+ "Sub-pages move with it.",
|
|
192
|
+
},
|
|
193
|
+
});
|
|
194
|
+
if (stop !== undefined)
|
|
195
|
+
return stop;
|
|
196
|
+
// `newOrder` ONLY when the parent changes. Measured: a reparent without it
|
|
197
|
+
// answers 400 "Nullable object must have a value", and a rename WITH it moves
|
|
198
|
+
// the page to the top of its siblings as a side effect nobody asked for.
|
|
199
|
+
const reparenting = parentOf(newPath) !== parentOf(path);
|
|
200
|
+
const moved = await session.wiki.movePage(name, path, newPath, reparenting ? { newOrder: 0 } : {});
|
|
201
|
+
return emit(io, {
|
|
202
|
+
applied: true,
|
|
203
|
+
action: options.rename ? "renamed" : "moved",
|
|
204
|
+
wiki: name,
|
|
205
|
+
path,
|
|
206
|
+
newPath: moved.newPath ?? newPath,
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* `wiki duplicate <path> [newPath]` — a verb Azure DevOps does not have.
|
|
211
|
+
*
|
|
212
|
+
* Read and write, so it needs no new endpoint. Without a target it lands at
|
|
213
|
+
* `<path> - Copy`, counting up to the first FREE name so duplicating twice gives
|
|
214
|
+
* `- Copy` and `- Copy 2` rather than a collision.
|
|
215
|
+
*
|
|
216
|
+
* NOT behind `--yes`: it creates something new and destroys nothing, which is
|
|
217
|
+
* the same trade `write` already makes for a page that does not exist.
|
|
218
|
+
*/
|
|
219
|
+
async function duplicate(io, session, positionals) {
|
|
220
|
+
const path = requirePath(positionals[0]);
|
|
221
|
+
const name = await session.wikiIdentifier();
|
|
222
|
+
const source = await readIfPresent(session, name, path);
|
|
223
|
+
if (source === undefined) {
|
|
224
|
+
throw usageError(`There is no wiki page at ${path}.`, { wiki: name, path });
|
|
225
|
+
}
|
|
226
|
+
let target = positionals[1] === undefined ? "" : normalisePath(positionals[1]);
|
|
227
|
+
if (target === "") {
|
|
228
|
+
target = `${path} - Copy`;
|
|
229
|
+
// From 2, because the unnumbered one IS the first copy — `- Copy 1` beside
|
|
230
|
+
// `- Copy` reads as two different things.
|
|
231
|
+
let n = 2;
|
|
232
|
+
while ((await readIfPresent(session, name, target)) !== undefined) {
|
|
233
|
+
target = `${path} - Copy ${n}`;
|
|
234
|
+
n += 1;
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
else if ((await readIfPresent(session, name, target)) !== undefined) {
|
|
238
|
+
throw usageError(`There is already a wiki page at ${target}.`, { wiki: name, target });
|
|
239
|
+
}
|
|
240
|
+
const content = await session.wiki.readPage(name, path);
|
|
241
|
+
await session.wiki.writePage(name, target, content.page.content ?? "", undefined);
|
|
242
|
+
return emit(io, {
|
|
243
|
+
applied: true,
|
|
244
|
+
action: "duplicated",
|
|
245
|
+
wiki: name,
|
|
246
|
+
path,
|
|
247
|
+
newPath: target,
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
/** Leading slash, no trailing one — the API is inconsistent about both. */
|
|
251
|
+
function normalisePath(path) {
|
|
252
|
+
let trimmed = path.trim();
|
|
253
|
+
while (trimmed.endsWith("/"))
|
|
254
|
+
trimmed = trimmed.slice(0, -1);
|
|
255
|
+
if (trimmed === "")
|
|
256
|
+
return "";
|
|
257
|
+
return trimmed.startsWith("/") ? trimmed : `/${trimmed}`;
|
|
258
|
+
}
|
|
259
|
+
function parentOf(path) {
|
|
260
|
+
const parts = normalisePath(path).split("/").filter(Boolean);
|
|
261
|
+
return parts.length > 1 ? `/${parts.slice(0, -1).join("/")}` : "";
|
|
262
|
+
}
|
|
263
|
+
function joinPath(parent, leaf) {
|
|
264
|
+
const head = normalisePath(parent);
|
|
265
|
+
const tail = leaf.trim().replace(/^\/+|\/+$/g, "");
|
|
266
|
+
if (tail === "")
|
|
267
|
+
return head;
|
|
268
|
+
return head === "" ? `/${tail}` : `${head}/${tail}`;
|
|
269
|
+
}
|
|
139
270
|
async function readIfPresent(session, wiki, path) {
|
|
140
271
|
try {
|
|
141
272
|
const page = await session.wiki.readPage(wiki, path);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wiki.js","sourceRoot":"","sources":["../../src/commands/wiki.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"wiki.js","sourceRoot":"","sources":["../../src/commands/wiki.ts"],"names":[],"mappings":"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"}
|
package/dist/output.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"output.d.ts","sourceRoot":"","sources":["../src/output.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"output.d.ts","sourceRoot":"","sources":["../src/output.ts"],"names":[],"mappings":"AAaA;;;;;;;;;;;;;;;GAeG;AAEH;;;;;;;GAOG;AACH,eAAO,MAAM,OAAO,IAAI,CAAC;AACzB,eAAO,MAAM,WAAW,IAAI,CAAC;AAC7B,eAAO,MAAM,UAAU,IAAI,CAAC;AAC5B,eAAO,MAAM,YAAY,IAAI,CAAC;AAE9B,MAAM,MAAM,QAAQ,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AAErC,MAAM,MAAM,SAAS,GACjB,OAAO,GACP,QAAQ,GACR,MAAM,GACN,SAAS,GACT,UAAU,GACV,UAAU,GACV,WAAW,GACX,SAAS,GACT,KAAK,GACL,UAAU,CAAC;AAEf,MAAM,WAAW,EAAE;IACjB,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/B,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CAChC;AAED;;;;;;GAMG;AACH,qBAAa,QAAS,SAAQ,KAAK;IACjC,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC5B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAEzC;;;;;;OAMG;IACH,QAAQ,CAAC,OAAO,QAAQ;gBAGtB,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,SAAS,EACf,QAAQ,EAAE,QAAQ,EAClB,MAAM,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM;CAQvC;AAED,2EAA2E;AAC3E,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GAAG,QAAQ,CAE1F;AAED;;;;;GAKG;AACH,wBAAgB,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GAAG,QAAQ,CAEvF;AAED,iFAAiF;AACjF,wBAAgB,IAAI,CAAC,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,OAAO,GAAG,QAAQ,CAGrD;AAED,sDAAsD;AACtD,wBAAgB,QAAQ,CAAC,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,GAAG,QAAQ,CAGvD;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,WAAW,CAAC,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,OAAO,GAAG,QAAQ,CAI5D"}
|
package/dist/output.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AdoAuthError, AdoConcurrencyError, AdoConfigError, AdoError, AdoNetworkError, AdoNotFoundError, AdoRateLimitError, } from "@floh-solutions/ado-core";
|
|
1
|
+
import { AdoAuthError, AdoConcurrencyError, AdoConfigError, AdoError, AdoNetworkError, AdoNotFoundError, AdoRateLimitError, adviceFor, deletionAdvice, namesAResourcePermission, } from "@floh-solutions/ado-core";
|
|
2
2
|
/**
|
|
3
3
|
* The output contract.
|
|
4
4
|
*
|
|
@@ -102,7 +102,15 @@ export function reportError(io, error) {
|
|
|
102
102
|
function describe(error) {
|
|
103
103
|
if (error instanceof CliError) {
|
|
104
104
|
return {
|
|
105
|
-
|
|
105
|
+
// `detail` FIRST, so the two contract fields cannot be overwritten by it.
|
|
106
|
+
//
|
|
107
|
+
// This was the other way round and it was a real bug, caught by a test:
|
|
108
|
+
// `pharos unlink` refused with a detail carrying `kind: "related"` (which
|
|
109
|
+
// relationship), and that silently replaced `kind: "refused"` (what sort
|
|
110
|
+
// of failure). The exit code was still 3, so the only thing that lied was
|
|
111
|
+
// the machine-readable field an agent branches on — the worst possible
|
|
112
|
+
// half of the contract to get wrong.
|
|
113
|
+
body: { ...error.detail, kind: error.kind, message: error.message },
|
|
106
114
|
code: error.exitCode,
|
|
107
115
|
};
|
|
108
116
|
}
|
|
@@ -179,7 +187,22 @@ function describe(error) {
|
|
|
179
187
|
code: EXIT_FAILED,
|
|
180
188
|
};
|
|
181
189
|
}
|
|
190
|
+
/**
|
|
191
|
+
* An Azure DevOps failure, with **what to do about it** where that is known.
|
|
192
|
+
*
|
|
193
|
+
* The structured fields say what went wrong in a shape a program can branch on.
|
|
194
|
+
* `advice` says what to do, which is the half that was missing: *"TF401289: The
|
|
195
|
+
* current user does not have permission to create tag definitions"* is accurate
|
|
196
|
+
* and leaves a session with nothing to try. See `ado-core`'s `advice.ts` for why
|
|
197
|
+
* the match is on the code and never on Microsoft's prose.
|
|
198
|
+
*
|
|
199
|
+
* Azure DevOps' own message is kept in front of it rather than replaced — the
|
|
200
|
+
* code is what somebody would search for.
|
|
201
|
+
*/
|
|
182
202
|
function adoBody(kind, error) {
|
|
203
|
+
const text = `${error.typeKey ?? ""} ${error.message}`;
|
|
204
|
+
const advice = adviceFor(text);
|
|
205
|
+
const deletion = error.method === "DELETE" ? deletionAdvice(text) : undefined;
|
|
183
206
|
return {
|
|
184
207
|
kind,
|
|
185
208
|
message: error.message,
|
|
@@ -189,6 +212,13 @@ function adoBody(kind, error) {
|
|
|
189
212
|
typeKey: error.typeKey,
|
|
190
213
|
// Quote this at Microsoft support. It is the only handle they accept.
|
|
191
214
|
activityId: error.activityId,
|
|
215
|
+
...(advice === undefined && deletion === undefined
|
|
216
|
+
? {}
|
|
217
|
+
: { advice: [advice, deletion].filter(Boolean).join(" ") }),
|
|
218
|
+
// A 403 naming a RESOURCE permission is a different problem from a rejected
|
|
219
|
+
// credential, and Azure DevOps answers both with 403. Saying which stops a
|
|
220
|
+
// session re-checking a token that is fine.
|
|
221
|
+
...(namesAResourcePermission(text) ? { credentialIsFine: true } : {}),
|
|
192
222
|
};
|
|
193
223
|
}
|
|
194
224
|
//# sourceMappingURL=output.js.map
|