@floh-solutions/pharos-cli 0.28.0 → 0.30.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 +33 -0
- package/dist/adopt-type.d.ts.map +1 -1
- package/dist/adopt-type.js +7 -2
- package/dist/adopt-type.js.map +1 -1
- package/dist/capabilities.d.ts +7 -0
- package/dist/capabilities.d.ts.map +1 -1
- package/dist/capabilities.js +25 -0
- package/dist/capabilities.js.map +1 -1
- package/dist/cli.d.ts +18 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +178 -86
- package/dist/cli.js.map +1 -1
- package/dist/commands/delegate.d.ts +143 -0
- package/dist/commands/delegate.d.ts.map +1 -0
- package/dist/commands/delegate.js +364 -0
- package/dist/commands/delegate.js.map +1 -0
- package/dist/commands/doctor.d.ts +8 -0
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +179 -4
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/issue.d.ts.map +1 -1
- package/dist/commands/issue.js +89 -7
- package/dist/commands/issue.js.map +1 -1
- package/dist/commands/setup.d.ts.map +1 -1
- package/dist/commands/setup.js +7 -3
- package/dist/commands/setup.js.map +1 -1
- package/dist/delegate/hosts.d.ts +83 -0
- package/dist/delegate/hosts.d.ts.map +1 -0
- package/dist/delegate/hosts.js +154 -0
- package/dist/delegate/hosts.js.map +1 -0
- package/dist/delegate/quote.d.ts +78 -0
- package/dist/delegate/quote.d.ts.map +1 -0
- package/dist/delegate/quote.js +134 -0
- package/dist/delegate/quote.js.map +1 -0
- package/dist/delegate/sessions.d.ts +113 -0
- package/dist/delegate/sessions.d.ts.map +1 -0
- package/dist/delegate/sessions.js +220 -0
- package/dist/delegate/sessions.js.map +1 -0
- package/dist/delegate/vsix.d.ts +122 -0
- package/dist/delegate/vsix.d.ts.map +1 -0
- package/dist/delegate/vsix.js +329 -0
- package/dist/delegate/vsix.js.map +1 -0
- package/package.json +5 -4
- package/skill/SKILL.md +67 -6
- package/vscode/README.md +30 -0
- package/vscode/pharos-bridge.json +10 -0
- package/vscode/pharos-bridge.vsix +0 -0
- package/dist/commands/pr.d.ts +0 -56
- package/dist/commands/pr.d.ts.map +0 -1
- package/dist/commands/pr.js +0 -202
- package/dist/commands/pr.js.map +0 -1
|
@@ -0,0 +1,329 @@
|
|
|
1
|
+
import { execFile } from "node:child_process";
|
|
2
|
+
import { createHash } from "node:crypto";
|
|
3
|
+
import { readdir, readFile, stat } from "node:fs/promises";
|
|
4
|
+
import { homedir } from "node:os";
|
|
5
|
+
import { dirname, join } from "node:path";
|
|
6
|
+
import { fileURLToPath } from "node:url";
|
|
7
|
+
import { promisify } from "node:util";
|
|
8
|
+
import { inflateRawSync } from "node:zlib";
|
|
9
|
+
import { bundleCli, findApp, HOSTS } from "./hosts.js";
|
|
10
|
+
const run = promisify(execFile);
|
|
11
|
+
/**
|
|
12
|
+
* The Pharos bridge for VS Code — what this CLI ships, and what a machine has.
|
|
13
|
+
*
|
|
14
|
+
* ## Why the CLI carries a `.vsix` at all
|
|
15
|
+
*
|
|
16
|
+
* Nothing outside VS Code can put a prompt into a session (measured against
|
|
17
|
+
* the Claude Code and Codex extensions: no URI handler takes text, and the
|
|
18
|
+
* `code` CLI runs no terminal command). The bridge — `packages/pharos-vscode`,
|
|
19
|
+
* publisher `floh-solutions`, name `pharos` — is the thing that can, and it
|
|
20
|
+
* ships INSIDE the npm package the way `skill/` does, so `pharos setup
|
|
21
|
+
* --install vscode-bridge` needs no network and no Marketplace listing. A
|
|
22
|
+
* listing is a later, separate decision and a fourth release route.
|
|
23
|
+
*
|
|
24
|
+
* ## Two files, one source of truth
|
|
25
|
+
*
|
|
26
|
+
* The bridge's build writes `vscode/pharos-bridge.vsix` and, beside it,
|
|
27
|
+
* `vscode/pharos-bridge.json` — `{ id, version, vsix, sha256, bytes }`,
|
|
28
|
+
* derived from the extension's own `package.json`. The JSON is what `doctor`
|
|
29
|
+
* reads to say which bridge this CLI ships, and the sha256 in it is what the
|
|
30
|
+
* installer checks the `.vsix` against before handing it to VS Code: the
|
|
31
|
+
* `convert.ts` rule, that bytes are verified against something already in the
|
|
32
|
+
* package rather than trusted because they are there. When the JSON is absent
|
|
33
|
+
* the `.vsix` is unzipped for its `extension/package.json` instead, so an
|
|
34
|
+
* older build still reports a version.
|
|
35
|
+
*/
|
|
36
|
+
export const BRIDGE_EXTENSION_ID = "floh-solutions.pharos";
|
|
37
|
+
/** `anthropic.claude-code` and `openai.chatgpt` — the ids the extension folders and manifest carry. */
|
|
38
|
+
export const CLAUDE_EXTENSION_ID = "anthropic.claude-code";
|
|
39
|
+
export const CODEX_EXTENSION_ID = "openai.chatgpt";
|
|
40
|
+
/**
|
|
41
|
+
* Where the bundled `.vsix` is.
|
|
42
|
+
*
|
|
43
|
+
* `PHAROS_BRIDGE_VSIX` overrides it — for a developer installing a local
|
|
44
|
+
* build, and for the tests, which must never install a real extension into
|
|
45
|
+
* somebody's editor to prove a refusal.
|
|
46
|
+
*/
|
|
47
|
+
export function bundledVsixPath(env = process.env) {
|
|
48
|
+
const override = env["PHAROS_BRIDGE_VSIX"];
|
|
49
|
+
if (override !== undefined && override !== "")
|
|
50
|
+
return override;
|
|
51
|
+
// Relative to the compiled file, so it resolves from dist/ in a global npm
|
|
52
|
+
// install as well as from src/ in this checkout — the `skill/` rule.
|
|
53
|
+
return fileURLToPath(new URL("../../vscode/pharos-bridge.vsix", import.meta.url));
|
|
54
|
+
}
|
|
55
|
+
/** The manifest the bridge's build writes beside the `.vsix`. */
|
|
56
|
+
export function bundledManifestPath(env = process.env) {
|
|
57
|
+
return join(dirname(bundledVsixPath(env)), "pharos-bridge.json");
|
|
58
|
+
}
|
|
59
|
+
/** The bridge this CLI ships, or null when the `.vsix` is not there. Never throws. */
|
|
60
|
+
export async function bundledBridge(env = process.env) {
|
|
61
|
+
const path = bundledVsixPath(env);
|
|
62
|
+
let bytes;
|
|
63
|
+
try {
|
|
64
|
+
const info = await stat(path);
|
|
65
|
+
if (!info.isFile())
|
|
66
|
+
return null;
|
|
67
|
+
bytes = await readFile(path);
|
|
68
|
+
}
|
|
69
|
+
catch {
|
|
70
|
+
return null;
|
|
71
|
+
}
|
|
72
|
+
try {
|
|
73
|
+
const raw = await readFile(bundledManifestPath(env), "utf8");
|
|
74
|
+
const parsed = JSON.parse(raw);
|
|
75
|
+
const id = typeof parsed["id"] === "string" ? parsed["id"] : null;
|
|
76
|
+
const dot = id?.indexOf(".") ?? -1;
|
|
77
|
+
return {
|
|
78
|
+
path,
|
|
79
|
+
bytes: bytes.length,
|
|
80
|
+
manifest: {
|
|
81
|
+
publisher: id !== null && dot > 0 ? id.slice(0, dot) : null,
|
|
82
|
+
name: id !== null && dot > 0 ? id.slice(dot + 1) : null,
|
|
83
|
+
version: typeof parsed["version"] === "string" ? parsed["version"] : null,
|
|
84
|
+
},
|
|
85
|
+
sha256: typeof parsed["sha256"] === "string" ? parsed["sha256"].toLowerCase() : null,
|
|
86
|
+
via: "manifest",
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
catch {
|
|
90
|
+
return { path, bytes: bytes.length, manifest: vsixManifest(bytes), sha256: null, via: "vsix" };
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* `extension/package.json` out of a `.vsix`, which is a zip.
|
|
95
|
+
*
|
|
96
|
+
* A zip reader in forty lines rather than a dependency: the package has none
|
|
97
|
+
* today, and one to read three fields out of a file we produce ourselves
|
|
98
|
+
* would be a poor trade. Handles the two methods `vsce` writes (stored and
|
|
99
|
+
* deflate) and nothing else; zip64 is not needed for a bridge this size.
|
|
100
|
+
*/
|
|
101
|
+
export function vsixManifest(bytes) {
|
|
102
|
+
const empty = { publisher: null, name: null, version: null };
|
|
103
|
+
const entry = zipEntry(bytes, "extension/package.json");
|
|
104
|
+
if (entry === null)
|
|
105
|
+
return empty;
|
|
106
|
+
try {
|
|
107
|
+
const parsed = JSON.parse(entry.toString("utf8"));
|
|
108
|
+
return {
|
|
109
|
+
publisher: typeof parsed["publisher"] === "string" ? parsed["publisher"] : null,
|
|
110
|
+
name: typeof parsed["name"] === "string" ? parsed["name"] : null,
|
|
111
|
+
version: typeof parsed["version"] === "string" ? parsed["version"] : null,
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
catch {
|
|
115
|
+
return empty;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
const EOCD = 0x06054b50;
|
|
119
|
+
const CENTRAL = 0x02014b50;
|
|
120
|
+
const LOCAL = 0x04034b50;
|
|
121
|
+
/** One file's contents out of a zip, by exact name, or null. */
|
|
122
|
+
export function zipEntry(bytes, name) {
|
|
123
|
+
// The end-of-central-directory record is at the very end, before an optional
|
|
124
|
+
// comment of at most 65535 bytes. Scan back for its signature.
|
|
125
|
+
let eocd = -1;
|
|
126
|
+
for (let at = bytes.length - 22; at >= Math.max(0, bytes.length - 22 - 65_535); at -= 1) {
|
|
127
|
+
if (bytes.readUInt32LE(at) === EOCD) {
|
|
128
|
+
eocd = at;
|
|
129
|
+
break;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
if (eocd === -1)
|
|
133
|
+
return null;
|
|
134
|
+
const entries = bytes.readUInt16LE(eocd + 10);
|
|
135
|
+
let at = bytes.readUInt32LE(eocd + 16);
|
|
136
|
+
for (let index = 0; index < entries; index += 1) {
|
|
137
|
+
if (at + 46 > bytes.length || bytes.readUInt32LE(at) !== CENTRAL)
|
|
138
|
+
return null;
|
|
139
|
+
const method = bytes.readUInt16LE(at + 10);
|
|
140
|
+
const compressedSize = bytes.readUInt32LE(at + 20);
|
|
141
|
+
const nameLength = bytes.readUInt16LE(at + 28);
|
|
142
|
+
const extraLength = bytes.readUInt16LE(at + 30);
|
|
143
|
+
const commentLength = bytes.readUInt16LE(at + 32);
|
|
144
|
+
const localOffset = bytes.readUInt32LE(at + 42);
|
|
145
|
+
const entryName = bytes.subarray(at + 46, at + 46 + nameLength).toString("utf8");
|
|
146
|
+
if (entryName === name) {
|
|
147
|
+
if (localOffset + 30 > bytes.length || bytes.readUInt32LE(localOffset) !== LOCAL)
|
|
148
|
+
return null;
|
|
149
|
+
const localNameLength = bytes.readUInt16LE(localOffset + 26);
|
|
150
|
+
const localExtraLength = bytes.readUInt16LE(localOffset + 28);
|
|
151
|
+
const start = localOffset + 30 + localNameLength + localExtraLength;
|
|
152
|
+
const data = bytes.subarray(start, start + compressedSize);
|
|
153
|
+
if (method === 0)
|
|
154
|
+
return Buffer.from(data);
|
|
155
|
+
if (method === 8) {
|
|
156
|
+
try {
|
|
157
|
+
return inflateRawSync(data);
|
|
158
|
+
}
|
|
159
|
+
catch {
|
|
160
|
+
return null;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
return null;
|
|
164
|
+
}
|
|
165
|
+
at += 46 + nameLength + extraLength + commentLength;
|
|
166
|
+
}
|
|
167
|
+
return null;
|
|
168
|
+
}
|
|
169
|
+
/** `~/.vscode[-insiders]/extensions` for a VS Code flavour; null for any other host. */
|
|
170
|
+
export function extensionsDirectory(host, env = process.env) {
|
|
171
|
+
const spec = HOSTS[host].vscode;
|
|
172
|
+
if (spec === undefined)
|
|
173
|
+
return null;
|
|
174
|
+
return join(env["HOME"] ?? homedir(), spec.extensionsDir);
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* What a flavour has installed. `null` when the directory does not exist —
|
|
178
|
+
* which is "this VS Code has never run", a different fact from "no extensions".
|
|
179
|
+
*
|
|
180
|
+
* `extensions.json` is read first because it is what VS Code itself reads:
|
|
181
|
+
* the reference machine held two `anthropic.claude-code-*` folders side by
|
|
182
|
+
* side (an update leaves the old one behind), and only the manifest says which
|
|
183
|
+
* is live. A missing or unreadable manifest falls back to the folder names,
|
|
184
|
+
* `<publisher>.<name>-<version>[-<platform>]`.
|
|
185
|
+
*/
|
|
186
|
+
export async function installedExtensions(host, env = process.env) {
|
|
187
|
+
const directory = extensionsDirectory(host, env);
|
|
188
|
+
if (directory === null)
|
|
189
|
+
return null;
|
|
190
|
+
let names;
|
|
191
|
+
try {
|
|
192
|
+
names = await readdir(directory);
|
|
193
|
+
}
|
|
194
|
+
catch {
|
|
195
|
+
return null;
|
|
196
|
+
}
|
|
197
|
+
try {
|
|
198
|
+
const raw = await readFile(join(directory, "extensions.json"), "utf8");
|
|
199
|
+
const parsed = JSON.parse(raw);
|
|
200
|
+
if (Array.isArray(parsed)) {
|
|
201
|
+
const listed = [];
|
|
202
|
+
for (const entry of parsed) {
|
|
203
|
+
const record = entry;
|
|
204
|
+
const id = record.identifier?.id;
|
|
205
|
+
if (typeof id !== "string" || typeof record.version !== "string")
|
|
206
|
+
continue;
|
|
207
|
+
const folder = typeof record.relativeLocation === "string" ? record.relativeLocation : `${id}-${record.version}`;
|
|
208
|
+
listed.push({ id: id.toLowerCase(), version: record.version, path: join(directory, folder) });
|
|
209
|
+
}
|
|
210
|
+
return listed;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
catch {
|
|
214
|
+
// No manifest, or not the shape expected. The folders still say.
|
|
215
|
+
}
|
|
216
|
+
const scanned = [];
|
|
217
|
+
for (const name of names) {
|
|
218
|
+
const parsed = parseExtensionFolder(name);
|
|
219
|
+
if (parsed !== null)
|
|
220
|
+
scanned.push({ ...parsed, path: join(directory, name) });
|
|
221
|
+
}
|
|
222
|
+
return scanned;
|
|
223
|
+
}
|
|
224
|
+
/** `anthropic.claude-code-2.1.228-darwin-arm64` → id and version. Null for anything else. */
|
|
225
|
+
export function parseExtensionFolder(name) {
|
|
226
|
+
const match = /^([a-z0-9][a-z0-9-]*\.[a-z0-9][a-z0-9-]*)-(\d+\.\d+\.\d+(?:[-.][0-9A-Za-z.-]+)?)$/i.exec(name);
|
|
227
|
+
if (match === null)
|
|
228
|
+
return null;
|
|
229
|
+
let version = match[2];
|
|
230
|
+
// A platform suffix is not part of the version: strip `-darwin-arm64` and its kin.
|
|
231
|
+
version = version.replace(/-(darwin|linux|win32|alpine|web|universal)[-0-9A-Za-z]*$/i, "");
|
|
232
|
+
return { id: match[1].toLowerCase(), version };
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* Install the bundled bridge into every VS Code flavour on this machine.
|
|
236
|
+
*
|
|
237
|
+
* Through the bundle's OWN `bin/code`, because the `code` command is usually
|
|
238
|
+
* not on PATH (see {@link bundleCli}). `--force` replaces an older bridge
|
|
239
|
+
* without a prompt; a headless install that stops to ask is a wizard that
|
|
240
|
+
* hangs.
|
|
241
|
+
*
|
|
242
|
+
* A missing `.vsix` is a refusal with the path, never a stack trace: the
|
|
243
|
+
* package can legitimately ship without one until the bridge's build has
|
|
244
|
+
* written it, and `doctor` names that state too. A `.vsix` that does not
|
|
245
|
+
* match its manifest's checksum is refused the same way — nothing is handed
|
|
246
|
+
* to VS Code that the package did not vouch for.
|
|
247
|
+
*/
|
|
248
|
+
export async function installBridge(options = {}) {
|
|
249
|
+
const env = options.env ?? process.env;
|
|
250
|
+
const bundled = await bundledBridge(env);
|
|
251
|
+
if (bundled === null) {
|
|
252
|
+
return {
|
|
253
|
+
ok: false,
|
|
254
|
+
command: null,
|
|
255
|
+
detail: `This pharos ships no bridge — ${bundledVsixPath(env)} is absent. It is produced by the `
|
|
256
|
+
+ "bridge's build (packages/pharos-vscode) and packed into the npm package; a checkout "
|
|
257
|
+
+ "gets it from `pnpm --filter ./packages/pharos-vscode build`, or point "
|
|
258
|
+
+ "PHAROS_BRIDGE_VSIX at one.",
|
|
259
|
+
flavours: [],
|
|
260
|
+
};
|
|
261
|
+
}
|
|
262
|
+
if (bundled.sha256 !== null) {
|
|
263
|
+
const digest = createHash("sha256").update(await readFile(bundled.path)).digest("hex");
|
|
264
|
+
if (digest !== bundled.sha256) {
|
|
265
|
+
return {
|
|
266
|
+
ok: false,
|
|
267
|
+
command: null,
|
|
268
|
+
detail: `${bundled.path} does not match the checksum in ${bundledManifestPath(env)} — got ${digest}, `
|
|
269
|
+
+ `expected ${bundled.sha256}. Nothing was installed: the two files were written by `
|
|
270
|
+
+ "different builds, or one was replaced by hand. Rebuild the bridge so both come from "
|
|
271
|
+
+ "one build.",
|
|
272
|
+
flavours: [],
|
|
273
|
+
};
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
const flavours = [];
|
|
277
|
+
let lastCommand = null;
|
|
278
|
+
for (const host of ["vscode", "vscode-insiders"]) {
|
|
279
|
+
const app = await findApp(host, env);
|
|
280
|
+
if (app === null)
|
|
281
|
+
continue;
|
|
282
|
+
const cli = bundleCli(app.path);
|
|
283
|
+
const args = ["--install-extension", bundled.path, "--force"];
|
|
284
|
+
const command = `${quoteForDisplay(cli)} ${args.map(quoteForDisplay).join(" ")}`;
|
|
285
|
+
lastCommand = command;
|
|
286
|
+
options.onCommand?.(command);
|
|
287
|
+
try {
|
|
288
|
+
await run(cli, args, { timeout: 5 * 60_000, maxBuffer: 4 * 1024 * 1024, env });
|
|
289
|
+
flavours.push({
|
|
290
|
+
host,
|
|
291
|
+
ok: true,
|
|
292
|
+
detail: `Installed ${bundled.manifest.version ?? "the bundled bridge"} into ${HOSTS[host].name}.`,
|
|
293
|
+
});
|
|
294
|
+
}
|
|
295
|
+
catch (error) {
|
|
296
|
+
flavours.push({
|
|
297
|
+
host,
|
|
298
|
+
ok: false,
|
|
299
|
+
detail: `That command failed: ${error instanceof Error ? error.message : String(error)}`,
|
|
300
|
+
});
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
if (flavours.length === 0) {
|
|
304
|
+
return {
|
|
305
|
+
ok: false,
|
|
306
|
+
command: null,
|
|
307
|
+
detail: "Neither Visual Studio Code nor Visual Studio Code - Insiders is installed — looked up by "
|
|
308
|
+
+ `bundle id (${HOSTS.vscode.bundleId}, ${HOSTS["vscode-insiders"].bundleId}) through `
|
|
309
|
+
+ "Spotlight and at the usual paths under /Applications and ~/Applications. "
|
|
310
|
+
+ "Install one and run this again.",
|
|
311
|
+
flavours,
|
|
312
|
+
};
|
|
313
|
+
}
|
|
314
|
+
const ok = flavours.every((flavour) => flavour.ok);
|
|
315
|
+
return {
|
|
316
|
+
ok,
|
|
317
|
+
command: lastCommand,
|
|
318
|
+
detail: flavours.map((flavour) => `${HOSTS[flavour.host].name}: ${flavour.detail}`).join(" ")
|
|
319
|
+
+ (ok
|
|
320
|
+
? " VS Code asks once whether the extension may handle a pharos URI — that is the "
|
|
321
|
+
+ "trust prompt, not a fault."
|
|
322
|
+
: ""),
|
|
323
|
+
flavours,
|
|
324
|
+
};
|
|
325
|
+
}
|
|
326
|
+
function quoteForDisplay(value) {
|
|
327
|
+
return /[\s'"$`\\]/.test(value) ? `'${value.replace(/'/g, `'\\''`)}'` : value;
|
|
328
|
+
}
|
|
329
|
+
//# sourceMappingURL=vsix.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vsix.js","sourceRoot":"","sources":["../../src/delegate/vsix.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAE3C,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,EAAe,MAAM,YAAY,CAAC;AAEpE,MAAM,GAAG,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;AAEhC;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,MAAM,CAAC,MAAM,mBAAmB,GAAG,uBAAuB,CAAC;AAE3D,uGAAuG;AACvG,MAAM,CAAC,MAAM,mBAAmB,GAAG,uBAAuB,CAAC;AAC3D,MAAM,CAAC,MAAM,kBAAkB,GAAG,gBAAgB,CAAC;AAEnD;;;;;;GAMG;AACH,MAAM,UAAU,eAAe,CAAC,MAAyB,OAAO,CAAC,GAAG;IAClE,MAAM,QAAQ,GAAG,GAAG,CAAC,oBAAoB,CAAC,CAAC;IAC3C,IAAI,QAAQ,KAAK,SAAS,IAAI,QAAQ,KAAK,EAAE;QAAE,OAAO,QAAQ,CAAC;IAC/D,2EAA2E;IAC3E,qEAAqE;IACrE,OAAO,aAAa,CAAC,IAAI,GAAG,CAAC,iCAAiC,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AACpF,CAAC;AAED,iEAAiE;AACjE,MAAM,UAAU,mBAAmB,CAAC,MAAyB,OAAO,CAAC,GAAG;IACtE,OAAO,IAAI,CAAC,OAAO,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC,EAAE,oBAAoB,CAAC,CAAC;AACnE,CAAC;AAmBD,sFAAsF;AACtF,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,MAAyB,OAAO,CAAC,GAAG;IACtE,MAAM,IAAI,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC;IAClC,IAAI,KAAa,CAAC;IAClB,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,CAAC;QAC9B,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE;YAAE,OAAO,IAAI,CAAC;QAChC,KAAK,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,CAAC;IAC/B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,mBAAmB,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,CAAC;QAC7D,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAA4B,CAAC;QAC1D,MAAM,EAAE,GAAG,OAAO,MAAM,CAAC,IAAI,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QAClE,MAAM,GAAG,GAAG,EAAE,EAAE,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;QACnC,OAAO;YACL,IAAI;YACJ,KAAK,EAAE,KAAK,CAAC,MAAM;YACnB,QAAQ,EAAE;gBACR,SAAS,EAAE,EAAE,KAAK,IAAI,IAAI,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI;gBAC3D,IAAI,EAAE,EAAE,KAAK,IAAI,IAAI,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI;gBACvD,OAAO,EAAE,OAAO,MAAM,CAAC,SAAS,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI;aAC1E;YACD,MAAM,EAAE,OAAO,MAAM,CAAC,QAAQ,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,IAAI;YACpF,GAAG,EAAE,UAAU;SAChB,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC,MAAM,EAAE,QAAQ,EAAE,YAAY,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC;IACjG,CAAC;AACH,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,YAAY,CAAC,KAAa;IACxC,MAAM,KAAK,GAAiB,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAC3E,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,EAAE,wBAAwB,CAAC,CAAC;IACxD,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC;IACjC,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAA4B,CAAC;QAC7E,OAAO;YACL,SAAS,EAAE,OAAO,MAAM,CAAC,WAAW,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,IAAI;YAC/E,IAAI,EAAE,OAAO,MAAM,CAAC,MAAM,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI;YAChE,OAAO,EAAE,OAAO,MAAM,CAAC,SAAS,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI;SAC1E,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,MAAM,IAAI,GAAG,UAAU,CAAC;AACxB,MAAM,OAAO,GAAG,UAAU,CAAC;AAC3B,MAAM,KAAK,GAAG,UAAU,CAAC;AAEzB,gEAAgE;AAChE,MAAM,UAAU,QAAQ,CAAC,KAAa,EAAE,IAAY;IAClD,6EAA6E;IAC7E,+DAA+D;IAC/D,IAAI,IAAI,GAAG,CAAC,CAAC,CAAC;IACd,KAAK,IAAI,EAAE,GAAG,KAAK,CAAC,MAAM,GAAG,EAAE,EAAE,EAAE,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,MAAM,GAAG,EAAE,GAAG,MAAM,CAAC,EAAE,EAAE,IAAI,CAAC,EAAE,CAAC;QACxF,IAAI,KAAK,CAAC,YAAY,CAAC,EAAE,CAAC,KAAK,IAAI,EAAE,CAAC;YACpC,IAAI,GAAG,EAAE,CAAC;YACV,MAAM;QACR,CAAC;IACH,CAAC;IACD,IAAI,IAAI,KAAK,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IAE7B,MAAM,OAAO,GAAG,KAAK,CAAC,YAAY,CAAC,IAAI,GAAG,EAAE,CAAC,CAAC;IAC9C,IAAI,EAAE,GAAG,KAAK,CAAC,YAAY,CAAC,IAAI,GAAG,EAAE,CAAC,CAAC;IAEvC,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,OAAO,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC;QAChD,IAAI,EAAE,GAAG,EAAE,GAAG,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,YAAY,CAAC,EAAE,CAAC,KAAK,OAAO;YAAE,OAAO,IAAI,CAAC;QAC9E,MAAM,MAAM,GAAG,KAAK,CAAC,YAAY,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC;QAC3C,MAAM,cAAc,GAAG,KAAK,CAAC,YAAY,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC;QACnD,MAAM,UAAU,GAAG,KAAK,CAAC,YAAY,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC;QAC/C,MAAM,WAAW,GAAG,KAAK,CAAC,YAAY,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC;QAChD,MAAM,aAAa,GAAG,KAAK,CAAC,YAAY,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC;QAClD,MAAM,WAAW,GAAG,KAAK,CAAC,YAAY,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC;QAChD,MAAM,SAAS,GAAG,KAAK,CAAC,QAAQ,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,UAAU,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QAEjF,IAAI,SAAS,KAAK,IAAI,EAAE,CAAC;YACvB,IAAI,WAAW,GAAG,EAAE,GAAG,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,YAAY,CAAC,WAAW,CAAC,KAAK,KAAK;gBAAE,OAAO,IAAI,CAAC;YAC9F,MAAM,eAAe,GAAG,KAAK,CAAC,YAAY,CAAC,WAAW,GAAG,EAAE,CAAC,CAAC;YAC7D,MAAM,gBAAgB,GAAG,KAAK,CAAC,YAAY,CAAC,WAAW,GAAG,EAAE,CAAC,CAAC;YAC9D,MAAM,KAAK,GAAG,WAAW,GAAG,EAAE,GAAG,eAAe,GAAG,gBAAgB,CAAC;YACpE,MAAM,IAAI,GAAG,KAAK,CAAC,QAAQ,CAAC,KAAK,EAAE,KAAK,GAAG,cAAc,CAAC,CAAC;YAC3D,IAAI,MAAM,KAAK,CAAC;gBAAE,OAAO,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC3C,IAAI,MAAM,KAAK,CAAC,EAAE,CAAC;gBACjB,IAAI,CAAC;oBACH,OAAO,cAAc,CAAC,IAAI,CAAC,CAAC;gBAC9B,CAAC;gBAAC,MAAM,CAAC;oBACP,OAAO,IAAI,CAAC;gBACd,CAAC;YACH,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC;QAED,EAAE,IAAI,EAAE,GAAG,UAAU,GAAG,WAAW,GAAG,aAAa,CAAC;IACtD,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAQD,wFAAwF;AACxF,MAAM,UAAU,mBAAmB,CAAC,IAAY,EAAE,MAAyB,OAAO,CAAC,GAAG;IACpF,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC;IAChC,IAAI,IAAI,KAAK,SAAS;QAAE,OAAO,IAAI,CAAC;IACpC,OAAO,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,OAAO,EAAE,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC;AAC5D,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,IAAY,EACZ,MAAyB,OAAO,CAAC,GAAG;IAEpC,MAAM,SAAS,GAAG,mBAAmB,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;IACjD,IAAI,SAAS,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IAEpC,IAAI,KAAe,CAAC;IACpB,IAAI,CAAC;QACH,KAAK,GAAG,MAAM,OAAO,CAAC,SAAS,CAAC,CAAC;IACnC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,SAAS,EAAE,iBAAiB,CAAC,EAAE,MAAM,CAAC,CAAC;QACvE,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAY,CAAC;QAC1C,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;YAC1B,MAAM,MAAM,GAAyB,EAAE,CAAC;YACxC,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;gBAC3B,MAAM,MAAM,GAAG,KAAyF,CAAC;gBACzG,MAAM,EAAE,GAAG,MAAM,CAAC,UAAU,EAAE,EAAE,CAAC;gBACjC,IAAI,OAAO,EAAE,KAAK,QAAQ,IAAI,OAAO,MAAM,CAAC,OAAO,KAAK,QAAQ;oBAAE,SAAS;gBAC3E,MAAM,MAAM,GAAG,OAAO,MAAM,CAAC,gBAAgB,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,CAAC,GAAG,EAAE,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;gBACjH,MAAM,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,WAAW,EAAE,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC;YAChG,CAAC;YACD,OAAO,MAAM,CAAC;QAChB,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,iEAAiE;IACnE,CAAC;IAED,MAAM,OAAO,GAAyB,EAAE,CAAC;IACzC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,MAAM,GAAG,oBAAoB,CAAC,IAAI,CAAC,CAAC;QAC1C,IAAI,MAAM,KAAK,IAAI;YAAE,OAAO,CAAC,IAAI,CAAC,EAAE,GAAG,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;IAChF,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,6FAA6F;AAC7F,MAAM,UAAU,oBAAoB,CAAC,IAAY;IAC/C,MAAM,KAAK,GAAG,oFAAoF,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC9G,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IAChC,IAAI,OAAO,GAAG,KAAK,CAAC,CAAC,CAAE,CAAC;IACxB,mFAAmF;IACnF,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,2DAA2D,EAAE,EAAE,CAAC,CAAC;IAC3F,OAAO,EAAE,EAAE,EAAE,KAAK,CAAC,CAAC,CAAE,CAAC,WAAW,EAAE,EAAE,OAAO,EAAE,CAAC;AAClD,CAAC;AAWD;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,UAGI,EAAE;IAEN,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC;IACvC,MAAM,OAAO,GAAG,MAAM,aAAa,CAAC,GAAG,CAAC,CAAC;IACzC,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;QACrB,OAAO;YACL,EAAE,EAAE,KAAK;YACT,OAAO,EAAE,IAAI;YACb,MAAM,EACJ,iCAAiC,eAAe,CAAC,GAAG,CAAC,oCAAoC;kBACvF,sFAAsF;kBACtF,wEAAwE;kBACxE,4BAA4B;YAChC,QAAQ,EAAE,EAAE;SACb,CAAC;IACJ,CAAC;IAED,IAAI,OAAO,CAAC,MAAM,KAAK,IAAI,EAAE,CAAC;QAC5B,MAAM,MAAM,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,MAAM,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACvF,IAAI,MAAM,KAAK,OAAO,CAAC,MAAM,EAAE,CAAC;YAC9B,OAAO;gBACL,EAAE,EAAE,KAAK;gBACT,OAAO,EAAE,IAAI;gBACb,MAAM,EACJ,GAAG,OAAO,CAAC,IAAI,mCAAmC,mBAAmB,CAAC,GAAG,CAAC,UAAU,MAAM,IAAI;sBAC5F,YAAY,OAAO,CAAC,MAAM,yDAAyD;sBACnF,sFAAsF;sBACtF,YAAY;gBAChB,QAAQ,EAAE,EAAE;aACb,CAAC;QACJ,CAAC;IACH,CAAC;IAED,MAAM,QAAQ,GAAqC,EAAE,CAAC;IACtD,IAAI,WAAW,GAAkB,IAAI,CAAC;IAEtC,KAAK,MAAM,IAAI,IAAI,CAAC,QAAQ,EAAE,iBAAiB,CAAU,EAAE,CAAC;QAC1D,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;QACrC,IAAI,GAAG,KAAK,IAAI;YAAE,SAAS;QAC3B,MAAM,GAAG,GAAG,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAChC,MAAM,IAAI,GAAG,CAAC,qBAAqB,EAAE,OAAO,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;QAC9D,MAAM,OAAO,GAAG,GAAG,eAAe,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QACjF,WAAW,GAAG,OAAO,CAAC;QACtB,OAAO,CAAC,SAAS,EAAE,CAAC,OAAO,CAAC,CAAC;QAC7B,IAAI,CAAC;YACH,MAAM,GAAG,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,OAAO,EAAE,CAAC,GAAG,MAAM,EAAE,SAAS,EAAE,CAAC,GAAG,IAAI,GAAG,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC;YAC/E,QAAQ,CAAC,IAAI,CAAC;gBACZ,IAAI;gBACJ,EAAE,EAAE,IAAI;gBACR,MAAM,EAAE,aAAa,OAAO,CAAC,QAAQ,CAAC,OAAO,IAAI,oBAAoB,SAAS,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,GAAG;aAClG,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,QAAQ,CAAC,IAAI,CAAC;gBACZ,IAAI;gBACJ,EAAE,EAAE,KAAK;gBACT,MAAM,EAAE,wBAAwB,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE;aACzF,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,OAAO;YACL,EAAE,EAAE,KAAK;YACT,OAAO,EAAE,IAAI;YACb,MAAM,EACJ,2FAA2F;kBACzF,cAAc,KAAK,CAAC,MAAM,CAAC,QAAQ,KAAK,KAAK,CAAC,iBAAiB,CAAC,CAAC,QAAQ,YAAY;kBACrF,2EAA2E;kBAC3E,iCAAiC;YACrC,QAAQ;SACT,CAAC;IACJ,CAAC;IAED,MAAM,EAAE,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IACnD,OAAO;QACL,EAAE;QACF,OAAO,EAAE,WAAW;QACpB,MAAM,EACJ,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,IAAI,KAAK,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;cACnF,CAAC,EAAE;gBACH,CAAC,CAAC,iFAAiF;sBAC/E,4BAA4B;gBAChC,CAAC,CAAC,EAAE,CAAC;QACT,QAAQ;KACT,CAAC;AACJ,CAAC;AAED,SAAS,eAAe,CAAC,KAAa;IACpC,OAAO,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC;AAChF,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@floh-solutions/pharos-cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.30.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",
|
|
@@ -18,15 +18,16 @@
|
|
|
18
18
|
},
|
|
19
19
|
"files": [
|
|
20
20
|
"dist",
|
|
21
|
-
"skill"
|
|
21
|
+
"skill",
|
|
22
|
+
"vscode"
|
|
22
23
|
],
|
|
23
24
|
"engines": {
|
|
24
25
|
"node": ">=22"
|
|
25
26
|
},
|
|
26
27
|
"dependencies": {
|
|
27
|
-
"@floh-solutions/gh-core": "0.4.0",
|
|
28
28
|
"@floh-solutions/ado-core": "0.11.0",
|
|
29
|
-
"@floh-solutions/plan-to-board": "0.
|
|
29
|
+
"@floh-solutions/plan-to-board": "0.2.0",
|
|
30
|
+
"@floh-solutions/gh-core": "0.4.0"
|
|
30
31
|
},
|
|
31
32
|
"devDependencies": {
|
|
32
33
|
"@types/node": "^22.10.2",
|
package/skill/SKILL.md
CHANGED
|
@@ -98,7 +98,10 @@ issue edit <owner/name#45> the issue's OWN fields, behind a lost-update
|
|
|
98
98
|
hooks list | check | create | repoint | delete service hooks for realtime.
|
|
99
99
|
`check` needs --hub <url>; `list` shows the URL
|
|
100
100
|
already in use
|
|
101
|
-
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
|
|
102
105
|
setup org, project, token → keychain + shell profile
|
|
103
106
|
--install ask|all|a,b offer the optional
|
|
104
107
|
capabilities (LibreOffice, poppler, converter,
|
|
@@ -116,6 +119,10 @@ bridge map|unmap|digest edit that mapping (--label is an ID, not a name
|
|
|
116
119
|
written back to the work item
|
|
117
120
|
doctor what is installed on THIS machine, what is
|
|
118
121
|
missing, and what each missing thing costs
|
|
122
|
+
delegate hand a prompt to a coding agent in Terminal or
|
|
123
|
+
VS Code — Pharos.app's verb, not usually yours.
|
|
124
|
+
You are on the RECEIVING end: see "When a
|
|
125
|
+
prompt begins Fetch Azure DevOps work item"
|
|
119
126
|
```
|
|
120
127
|
|
|
121
128
|
Text input: `--text` / `--file` / `--stdin`. Global: `--pretty` for a human,
|
|
@@ -595,6 +602,15 @@ states exist" and "which mean finished" are different questions — `Inactive` i
|
|
|
595
602
|
finished on a Test Plan and appears in nobody's hard-coded Done/Closed/Removed
|
|
596
603
|
list.
|
|
597
604
|
|
|
605
|
+
**Nothing in this CLI writes a state name it was not told.** `query` reads the
|
|
606
|
+
categories to decide what "open" means, `update` refuses a state the type does
|
|
607
|
+
not have, `issue close` moves an item into the project's own terminal state,
|
|
608
|
+
`issue adopt` and `issue backfill` resolve the work item TYPE by role, and
|
|
609
|
+
`plan` maps its file's `Epic`/`Issue`/`Task` and `To Do`/`Doing`/`Done` onto
|
|
610
|
+
whatever this project calls those roles. Where any of them cannot read the
|
|
611
|
+
project it falls back to the stock names **and says so** — `source: "fallback"`,
|
|
612
|
+
a `note`, or a warning on stderr. If you see one, the answer is a guess.
|
|
613
|
+
|
|
598
614
|
`pharos whoami` is the other one worth reaching for early: it names the identity
|
|
599
615
|
behind `ADO_PAT`, which is who `@Me` resolves to and who every write is
|
|
600
616
|
attributed to. A shared or service token quietly makes "assigned to me" mean
|
|
@@ -950,11 +966,19 @@ pharos issue backfill contoso/widgets --label bug --parent 39 --limit 25 --max-w
|
|
|
950
966
|
```
|
|
951
967
|
|
|
952
968
|
**Read the preview before adding `--yes`.** It names the repository, the `gh`
|
|
953
|
-
account it would be reached as, **
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
--yes` is four hundred, each with a
|
|
957
|
-
has nothing to do with.
|
|
969
|
+
account it would be reached as, **the Azure DevOps organisation and project the
|
|
970
|
+
work items would land on**, and **`workItemType` — what they would be created
|
|
971
|
+
as** — nothing in the design pairs a repo with a board, and a mis-aimed `adopt`
|
|
972
|
+
is one work item where a mis-aimed `backfill --yes` is four hundred, each with a
|
|
973
|
+
public comment naming a board its reporter has nothing to do with.
|
|
974
|
+
|
|
975
|
+
**The type is resolved per issue, from the project, exactly as `adopt` resolves
|
|
976
|
+
it.** It reads which type this project maps to the requirement role and which to
|
|
977
|
+
the bug role, so an issue labelled as a bug becomes a bug and the rest become
|
|
978
|
+
the requirement type — `Issue` and `Issue` on Basic, `Bug` and `User Story` on
|
|
979
|
+
Agile. Every adopted row carries `typeSource` saying which answer it got:
|
|
980
|
+
`category`, `repo-default`, `label`, `flag`, or `fallback` for "the project
|
|
981
|
+
could not be asked". Pass `--type` to pin one for the whole run.
|
|
958
982
|
|
|
959
983
|
**Each adoption is two writes**, so four hundred issues is eight hundred against
|
|
960
984
|
a default cap of 20. That cost is worked out *before* anything is written and a
|
|
@@ -1283,6 +1307,43 @@ no Azure DevOps account, which is every reporter.
|
|
|
1283
1307
|
anything you do is recorded against whoever owns `ADO_PAT`. Never suggest
|
|
1284
1308
|
sharing one.
|
|
1285
1309
|
|
|
1310
|
+
## When a prompt begins "Fetch Azure DevOps work item #N with the pharos skill"
|
|
1311
|
+
|
|
1312
|
+
That is a **delegation from Pharos**, the macOS board app. Somebody right-
|
|
1313
|
+
clicked a work item and chose *Ask Agent*; the app found or started this
|
|
1314
|
+
session in the folder linked to that project and typed the prompt in. Only the
|
|
1315
|
+
**id** was sent — no title, no URL, no description — on purpose: you fetch the
|
|
1316
|
+
item yourself, with the CLI already configured for the right organisation, so
|
|
1317
|
+
what you read is what is on the board now rather than a copy the app might
|
|
1318
|
+
have got wrong.
|
|
1319
|
+
|
|
1320
|
+
So the first move is the usual one, and it is the whole context in one call:
|
|
1321
|
+
|
|
1322
|
+
```bash
|
|
1323
|
+
pharos task <id> # description, discussion, attachments, relations, linked pages
|
|
1324
|
+
pharos download <id> --all --out ./attachments # then READ them — images too
|
|
1325
|
+
```
|
|
1326
|
+
|
|
1327
|
+
Read everything it returns, including the discussion and every attachment and
|
|
1328
|
+
image (the section on reading attachments above says how, and `pharos doctor`
|
|
1329
|
+
says what this machine can open). Then, **which of the two prompts you got
|
|
1330
|
+
decides what happens next**:
|
|
1331
|
+
|
|
1332
|
+
- It ends with *"so we can then discuss the task"* — the person wants to talk
|
|
1333
|
+
first. Summarise what the item asks for, what is specified and what is not,
|
|
1334
|
+
and what you would do; then **wait**.
|
|
1335
|
+
- It carries instructions after the fetch sentence — the person has already
|
|
1336
|
+
decided. Take the item on as instructed, without asking whether to start.
|
|
1337
|
+
|
|
1338
|
+
Either way the reply loop is the board's, not the chat's, because the person
|
|
1339
|
+
who delegated is watching the work item in Pharos rather than this pane:
|
|
1340
|
+
|
|
1341
|
+
```bash
|
|
1342
|
+
pharos update <id> --state Doing # the moment work starts (`pharos types` for the names)
|
|
1343
|
+
pharos comment add <id> --file notes.md # questions, findings, decisions — on the item
|
|
1344
|
+
pharos task <id> # re-read before acting on an answer
|
|
1345
|
+
```
|
|
1346
|
+
|
|
1286
1347
|
## When it is not set up
|
|
1287
1348
|
|
|
1288
1349
|
`"kind": "config"` on exit 2 means the environment is missing. Run `pharos
|
package/vscode/README.md
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# The Pharos bridge for VS Code, as shipped by the CLI
|
|
2
|
+
|
|
3
|
+
Two files land here, and neither is committed:
|
|
4
|
+
|
|
5
|
+
| file | what |
|
|
6
|
+
|---|---|
|
|
7
|
+
| `pharos-bridge.vsix` | the extension `floh-solutions.pharos`, built from `packages/pharos-vscode` |
|
|
8
|
+
| `pharos-bridge.json` | `{ id, version, vsix, sha256, bytes, engines }`, derived from that package's `package.json` by the same build |
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
pnpm --filter ./packages/pharos-vscode build # from the repo root; writes both files here
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
They ship inside the npm package because `files` in `package.json` names
|
|
15
|
+
`vscode/` — npm packs a gitignored path when `files` names it — and
|
|
16
|
+
`scripts/prepack.mjs` refuses to pack when either is missing, so the CLI can
|
|
17
|
+
never go out bridge-less by accident.
|
|
18
|
+
|
|
19
|
+
The CLI reads them in two places:
|
|
20
|
+
|
|
21
|
+
- `pharos doctor` compares the bridge installed in each VS Code flavour with
|
|
22
|
+
the `version` in the JSON (`vscode-bridge`, `vscode-insiders-bridge`).
|
|
23
|
+
- `pharos setup --install vscode-bridge` checks the `.vsix` against the
|
|
24
|
+
JSON's `sha256` and hands it to each installed flavour's own
|
|
25
|
+
`Contents/Resources/app/bin/code --install-extension`, because the `code`
|
|
26
|
+
command is usually not on PATH.
|
|
27
|
+
|
|
28
|
+
`PHAROS_BRIDGE_VSIX=/path/to/other.vsix` overrides the location — for
|
|
29
|
+
installing a local build, and for the tests, which must never install a real
|
|
30
|
+
extension into somebody's editor.
|
|
Binary file
|
package/dist/commands/pr.d.ts
DELETED
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
import { type ExitCode, type Io } from "../output.js";
|
|
2
|
-
import type { Session } from "../session.js";
|
|
3
|
-
/**
|
|
4
|
-
* `pharos pr` — where the trail goes after adoption.
|
|
5
|
-
*
|
|
6
|
-
* ## The gap this closes
|
|
7
|
-
*
|
|
8
|
-
* `pharos issue` joins a GitHub issue to a work item, and `issue trail` follows
|
|
9
|
-
* that join from either end. Both stop at the moment the work becomes code. A
|
|
10
|
-
* session asking *"is this actually done?"* got filing, adoption and a state
|
|
11
|
-
* field, and nothing at all about the branch that answers the question.
|
|
12
|
-
*
|
|
13
|
-
* ## What it composes
|
|
14
|
-
*
|
|
15
|
-
* One call, two platforms, four questions that are otherwise four commands and
|
|
16
|
-
* two credentials:
|
|
17
|
-
*
|
|
18
|
-
* | | otherwise |
|
|
19
|
-
* |---|---|
|
|
20
|
-
* | the pull request and its review verdict | `gh pr view` |
|
|
21
|
-
* | which checks are RED (not the first few) | `gh pr checks` |
|
|
22
|
-
* | which work items it belongs to | a WIQL query, or reading a marker by hand |
|
|
23
|
-
* | whether the two platforms AGREE | nothing — this is the part nobody has |
|
|
24
|
-
*
|
|
25
|
-
* ## The join is two paths, and the implicit one is the one that fires
|
|
26
|
-
*
|
|
27
|
-
* A pull request reaches a work item two ways, and both are read:
|
|
28
|
-
*
|
|
29
|
-
* 1. **Directly** — `AB#4821` in the body. This is what Azure Boards' own GitHub
|
|
30
|
-
* app reads, and Pharos writes it so that integration lights up free where it
|
|
31
|
-
* happens to be installed.
|
|
32
|
-
* 2. **Transitively** — `Fixes #45`, where issue #45 has been adopted. GitHub
|
|
33
|
-
* reports this as `closingIssuesReferences`, and it is the path that actually
|
|
34
|
-
* occurs: developers write `Fixes #45` constantly and `AB#4821` almost never.
|
|
35
|
-
*
|
|
36
|
-
* Path 2 costs one extra read per closed issue — the issue's comments, which is
|
|
37
|
-
* where the `pharos:v1` trailer lives. `linksFromComments` is `gh-core`'s, the
|
|
38
|
-
* same function `issue trail` and the macOS app use, because "what counts as a
|
|
39
|
-
* link" must have exactly one answer.
|
|
40
|
-
*
|
|
41
|
-
* ## The disagreements are the point
|
|
42
|
-
*
|
|
43
|
-
* Everything above is a read that something else could eventually do. The
|
|
44
|
-
* `disagreements` array is the part **neither platform will ever tell you**:
|
|
45
|
-
* an open pull request against a work item somebody already closed, a merged one
|
|
46
|
-
* against a work item still sitting in To Do. Azure DevOps cannot see the pull
|
|
47
|
-
* request and GitHub does not know the work item exists, so nothing anywhere is
|
|
48
|
-
* in a position to notice. Same shape as `pharos issue drift`, one step further
|
|
49
|
-
* down the pipeline.
|
|
50
|
-
*/
|
|
51
|
-
export interface PrCommandOptions {
|
|
52
|
-
/** Skip resolving `Fixes #N` through to work items. One read per closed issue. */
|
|
53
|
-
noWorkItems: boolean;
|
|
54
|
-
}
|
|
55
|
-
export declare function runPr(io: Io, session: Session, rest: readonly string[], options: PrCommandOptions): Promise<ExitCode>;
|
|
56
|
-
//# sourceMappingURL=pr.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"pr.d.ts","sourceRoot":"","sources":["../../src/commands/pr.ts"],"names":[],"mappings":"AAOA,OAAO,EAAyC,KAAK,QAAQ,EAAE,KAAK,EAAE,EAAE,MAAM,cAAc,CAAC;AAC7F,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAE7C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+CG;AAEH,MAAM,WAAW,gBAAgB;IAC/B,kFAAkF;IAClF,WAAW,EAAE,OAAO,CAAC;CACtB;AAED,wBAAsB,KAAK,CACzB,EAAE,EAAE,EAAE,EACN,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,QAAQ,CAAC,CA6EnB"}
|