@driftless-sh/cli 0.1.50 → 0.1.51
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/index.js +143 -150
- package/dist/index.js.map +3 -3
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -214842,7 +214842,7 @@ async function installSkillCommand() {
|
|
|
214842
214842
|
// src/commands/init.ts
|
|
214843
214843
|
function getVersion() {
|
|
214844
214844
|
try {
|
|
214845
|
-
return "0.1.
|
|
214845
|
+
return "0.1.51";
|
|
214846
214846
|
} catch {
|
|
214847
214847
|
return "0.0.0";
|
|
214848
214848
|
}
|
|
@@ -215502,6 +215502,101 @@ ${result.violations.length} violation(s) found (${rulesEvaluated} rule(s) evalua
|
|
|
215502
215502
|
|
|
215503
215503
|
// src/commands/context.ts
|
|
215504
215504
|
init_api_client();
|
|
215505
|
+
|
|
215506
|
+
// src/repo-resolver.ts
|
|
215507
|
+
init_api_client();
|
|
215508
|
+
function notLinkedMessage(remote, workspaceSlug) {
|
|
215509
|
+
return `Repo '${remote.org}/${remote.repo}' is not registered in workspace '${workspaceSlug}'. Run \`driftless init\` to register it.`;
|
|
215510
|
+
}
|
|
215511
|
+
function formatDiagnostics(d) {
|
|
215512
|
+
const lines = [];
|
|
215513
|
+
if (d.remote) lines.push(` repo: ${d.remote.org}/${d.remote.repo}`);
|
|
215514
|
+
lines.push(` tried slugs: ${d.triedSlugs.length ? d.triedSlugs.join(", ") : "(none)"}`);
|
|
215515
|
+
lines.push(` config slug: ${d.configSlug ?? "(not cached \u2014 run `driftless login` or `driftless init`)"}`);
|
|
215516
|
+
if (!d.meAttempted) {
|
|
215517
|
+
lines.push(" /me: not attempted");
|
|
215518
|
+
} else if (d.meReturned) {
|
|
215519
|
+
lines.push(` /me: returned slug=${d.meSlug ?? "(none)"} workspace_id=${d.meWorkspaceId ?? "(none)"}`);
|
|
215520
|
+
} else {
|
|
215521
|
+
lines.push(` /me: FAILED \u2014 ${d.meError ?? "unknown error"}`);
|
|
215522
|
+
}
|
|
215523
|
+
if (d.failedEndpoint) lines.push(` last endpoint: ${d.failedEndpoint} (rejected)`);
|
|
215524
|
+
return lines.join("\n");
|
|
215525
|
+
}
|
|
215526
|
+
async function fetchRepos(slug) {
|
|
215527
|
+
try {
|
|
215528
|
+
const raw = await api.get(`/workspaces/${slug}/repos`);
|
|
215529
|
+
if (Array.isArray(raw)) return { repos: raw };
|
|
215530
|
+
return { error: "unexpected response shape" };
|
|
215531
|
+
} catch (e) {
|
|
215532
|
+
return { error: e instanceof Error ? e.message : String(e) };
|
|
215533
|
+
}
|
|
215534
|
+
}
|
|
215535
|
+
async function resolveRepo() {
|
|
215536
|
+
const remote = getGitRemote();
|
|
215537
|
+
if (!remote) return { ok: false, reason: "no_remote" };
|
|
215538
|
+
const configSlug = getCachedWorkspace().slug;
|
|
215539
|
+
let meSlug;
|
|
215540
|
+
let meWorkspaceId;
|
|
215541
|
+
let meReturned = false;
|
|
215542
|
+
let meError;
|
|
215543
|
+
try {
|
|
215544
|
+
const me = await api.get("/me", { timeoutMs: 8e3, retries: 1 });
|
|
215545
|
+
meReturned = true;
|
|
215546
|
+
meSlug = me?.slug;
|
|
215547
|
+
meWorkspaceId = me?.workspace_id;
|
|
215548
|
+
if (meSlug) saveWorkspaceToConfig(meSlug, meWorkspaceId);
|
|
215549
|
+
} catch (e) {
|
|
215550
|
+
meError = e instanceof Error ? e.message : String(e);
|
|
215551
|
+
}
|
|
215552
|
+
const candidates = [...new Set([configSlug, meSlug, remote.org].filter(Boolean))];
|
|
215553
|
+
let lastLinkedSlug;
|
|
215554
|
+
let failedEndpoint;
|
|
215555
|
+
for (const slug of candidates) {
|
|
215556
|
+
const result = await fetchRepos(slug);
|
|
215557
|
+
if ("error" in result) {
|
|
215558
|
+
failedEndpoint = `/workspaces/${slug}/repos`;
|
|
215559
|
+
continue;
|
|
215560
|
+
}
|
|
215561
|
+
const repo = result.repos.find((r) => r.github_org === remote.org && r.github_repo === remote.repo);
|
|
215562
|
+
if (repo) {
|
|
215563
|
+
saveWorkspaceToConfig(slug, meWorkspaceId);
|
|
215564
|
+
const source = slug === configSlug ? "config" : slug === meSlug ? "me" : "git-org";
|
|
215565
|
+
return {
|
|
215566
|
+
ok: true,
|
|
215567
|
+
workspaceSlug: slug,
|
|
215568
|
+
repoId: repo.id,
|
|
215569
|
+
remote,
|
|
215570
|
+
hasScanBaseline: !!repo.scan_summary,
|
|
215571
|
+
source
|
|
215572
|
+
};
|
|
215573
|
+
}
|
|
215574
|
+
lastLinkedSlug = slug;
|
|
215575
|
+
}
|
|
215576
|
+
const diagnostics = {
|
|
215577
|
+
remote,
|
|
215578
|
+
triedSlugs: candidates,
|
|
215579
|
+
configSlug,
|
|
215580
|
+
meAttempted: true,
|
|
215581
|
+
meReturned,
|
|
215582
|
+
meSlug,
|
|
215583
|
+
meWorkspaceId,
|
|
215584
|
+
meError,
|
|
215585
|
+
failedEndpoint
|
|
215586
|
+
};
|
|
215587
|
+
if (lastLinkedSlug) {
|
|
215588
|
+
return { ok: false, reason: "not_linked", workspaceSlug: lastLinkedSlug, remote, diagnostics };
|
|
215589
|
+
}
|
|
215590
|
+
return {
|
|
215591
|
+
ok: false,
|
|
215592
|
+
reason: "no_workspace",
|
|
215593
|
+
remote,
|
|
215594
|
+
detail: formatDiagnostics(diagnostics),
|
|
215595
|
+
diagnostics
|
|
215596
|
+
};
|
|
215597
|
+
}
|
|
215598
|
+
|
|
215599
|
+
// src/commands/context.ts
|
|
215505
215600
|
var import_node_fs5 = require("node:fs");
|
|
215506
215601
|
var import_node_path5 = require("node:path");
|
|
215507
215602
|
init_analytics();
|
|
@@ -216158,68 +216253,61 @@ ${label} (${items.length}):`);
|
|
|
216158
216253
|
if (missingFiles.length > 0 && !isJSON) {
|
|
216159
216254
|
console.error(`File(s) not found locally: ${missingFiles.join(", ")}. Matching by pattern only.`);
|
|
216160
216255
|
}
|
|
216161
|
-
|
|
216162
|
-
|
|
216163
|
-
|
|
216164
|
-
|
|
216165
|
-
|
|
216166
|
-
);
|
|
216167
|
-
console.log(`Would match ${results.length} topic${results.length === 1 ? "" : "s"}:`);
|
|
216168
|
-
for (const r of results) {
|
|
216169
|
-
console.log(` ${r.context.topic} via ${r.match_reason}`);
|
|
216170
|
-
}
|
|
216171
|
-
if (missingFiles.length > 0) {
|
|
216172
|
-
console.log(`
|
|
216173
|
-
Warnings:`);
|
|
216174
|
-
for (const f of missingFiles) {
|
|
216175
|
-
console.log(` ${f} does not exist locally \u2014 matched by pattern only`);
|
|
216176
|
-
}
|
|
216177
|
-
}
|
|
216178
|
-
if (!isJSON) {
|
|
216179
|
-
console.log("\n(Dry run \u2014 no context delivered)");
|
|
216180
|
-
}
|
|
216181
|
-
if (isJSON) {
|
|
216182
|
-
emitJSON2({ dry_run: true, matched: results.map((r) => ({ topic: r.context.topic, reason: r.match_reason })), missing_files: missingFiles });
|
|
216183
|
-
}
|
|
216184
|
-
} catch (e) {
|
|
216185
|
-
console.error(`Dry run failed: ${formatError(e)}`);
|
|
216186
|
-
process.exit(1);
|
|
216256
|
+
const resolution = await resolveRepo();
|
|
216257
|
+
if (!resolution.ok) {
|
|
216258
|
+
if (resolution.reason === "not_linked") {
|
|
216259
|
+
console.error(notLinkedMessage(resolution.remote, resolution.workspaceSlug));
|
|
216260
|
+
} else {
|
|
216261
|
+
console.error("Error: could not resolve workspace/repo. Run `driftless doctor`.");
|
|
216187
216262
|
}
|
|
216188
|
-
process.exit(
|
|
216263
|
+
process.exit(1);
|
|
216189
216264
|
}
|
|
216265
|
+
const wsSlug = resolution.workspaceSlug;
|
|
216266
|
+
const repoId = resolution.repoId;
|
|
216267
|
+
let payload;
|
|
216190
216268
|
try {
|
|
216191
|
-
|
|
216192
|
-
`/workspaces/${
|
|
216269
|
+
payload = await api.post(
|
|
216270
|
+
`/workspaces/${wsSlug}/repos/${repoId}/context/load`,
|
|
216193
216271
|
{ files }
|
|
216194
216272
|
);
|
|
216195
|
-
if (results.length === 0 && !isJSON) {
|
|
216196
|
-
console.log(`No context topics match these files.`);
|
|
216197
|
-
}
|
|
216198
|
-
if (isJSON) {
|
|
216199
|
-
emitJSON2(results);
|
|
216200
|
-
} else {
|
|
216201
|
-
if (results.length > 0) {
|
|
216202
|
-
console.log(`Matched ${results.length} context topic${results.length === 1 ? "" : "s"} for ${files.length} file${files.length === 1 ? "" : "s"}:
|
|
216203
|
-
`);
|
|
216204
|
-
for (const r of results) {
|
|
216205
|
-
try {
|
|
216206
|
-
const fullCtx = await api.get(`/workspaces/${workspaceSlug}/watchers/${r.context.topic}`);
|
|
216207
|
-
renderContextHuman(fullCtx);
|
|
216208
|
-
console.log("");
|
|
216209
|
-
} catch {
|
|
216210
|
-
console.log(`\u258C ${r.context.topic} (${r.match_reason})`);
|
|
216211
|
-
console.log(` ${r.context.summary}`);
|
|
216212
|
-
console.log("");
|
|
216213
|
-
}
|
|
216214
|
-
}
|
|
216215
|
-
} else {
|
|
216216
|
-
console.log(`No context topics match these files. No context covers the changed paths.`);
|
|
216217
|
-
}
|
|
216218
|
-
}
|
|
216219
216273
|
} catch (e) {
|
|
216220
216274
|
console.error(`Load failed: ${formatError(e)}`);
|
|
216221
216275
|
process.exit(1);
|
|
216222
216276
|
}
|
|
216277
|
+
if (flags["dry-run"] && !isJSON) {
|
|
216278
|
+
console.log("(Dry run \u2014 context loaded for inspection, nothing written)\n");
|
|
216279
|
+
}
|
|
216280
|
+
if (isJSON) {
|
|
216281
|
+
emitJSON2(payload);
|
|
216282
|
+
process.exit(0);
|
|
216283
|
+
}
|
|
216284
|
+
const allTopics = /* @__PURE__ */ new Set();
|
|
216285
|
+
for (const f of payload.files) {
|
|
216286
|
+
const c = f.coverage;
|
|
216287
|
+
console.log(`\u258C ${f.file}`);
|
|
216288
|
+
console.log(` coverage ${c.status}${c.high_risk ? " \u26A0 high-risk" : ""}`);
|
|
216289
|
+
console.log(` action ${c.recommended_action}`);
|
|
216290
|
+
const dt = c.direct_topics ?? [];
|
|
216291
|
+
const it = c.indirect_topics ?? [];
|
|
216292
|
+
if (dt.length) console.log(` direct ${dt.join(", ")}`);
|
|
216293
|
+
if (it.length) console.log(` indirect ${it.join(", ")}`);
|
|
216294
|
+
if (!dt.length && !it.length) console.log(` topics (none \u2014 no context covers this file)`);
|
|
216295
|
+
if (c.has_stale) console.log(` \u26A0 a matching topic is stale`);
|
|
216296
|
+
if (c.has_orphaned) console.log(` \u26A0 a matching topic is orphaned`);
|
|
216297
|
+
for (const t of [...dt, ...it]) allTopics.add(t);
|
|
216298
|
+
console.log("");
|
|
216299
|
+
}
|
|
216300
|
+
for (const slug of [...allTopics].sort()) {
|
|
216301
|
+
try {
|
|
216302
|
+
const fullCtx = await api.get(`/workspaces/${wsSlug}/watchers/${slug}`);
|
|
216303
|
+
renderContextHuman(fullCtx);
|
|
216304
|
+
console.log("");
|
|
216305
|
+
} catch {
|
|
216306
|
+
}
|
|
216307
|
+
}
|
|
216308
|
+
if (allTopics.size === 0) {
|
|
216309
|
+
console.log("No context covers the requested paths. Consider `driftless context add`.");
|
|
216310
|
+
}
|
|
216223
216311
|
return;
|
|
216224
216312
|
}
|
|
216225
216313
|
if (subCommand === "export") {
|
|
@@ -216380,101 +216468,6 @@ Run 'driftless help context' for full reference.`);
|
|
|
216380
216468
|
|
|
216381
216469
|
// src/commands/sync.ts
|
|
216382
216470
|
init_api_client();
|
|
216383
|
-
|
|
216384
|
-
// src/repo-resolver.ts
|
|
216385
|
-
init_api_client();
|
|
216386
|
-
function notLinkedMessage(remote, workspaceSlug) {
|
|
216387
|
-
return `Repo '${remote.org}/${remote.repo}' is not registered in workspace '${workspaceSlug}'. Run \`driftless init\` to register it.`;
|
|
216388
|
-
}
|
|
216389
|
-
function formatDiagnostics(d) {
|
|
216390
|
-
const lines = [];
|
|
216391
|
-
if (d.remote) lines.push(` repo: ${d.remote.org}/${d.remote.repo}`);
|
|
216392
|
-
lines.push(` tried slugs: ${d.triedSlugs.length ? d.triedSlugs.join(", ") : "(none)"}`);
|
|
216393
|
-
lines.push(` config slug: ${d.configSlug ?? "(not cached \u2014 run `driftless login` or `driftless init`)"}`);
|
|
216394
|
-
if (!d.meAttempted) {
|
|
216395
|
-
lines.push(" /me: not attempted");
|
|
216396
|
-
} else if (d.meReturned) {
|
|
216397
|
-
lines.push(` /me: returned slug=${d.meSlug ?? "(none)"} workspace_id=${d.meWorkspaceId ?? "(none)"}`);
|
|
216398
|
-
} else {
|
|
216399
|
-
lines.push(` /me: FAILED \u2014 ${d.meError ?? "unknown error"}`);
|
|
216400
|
-
}
|
|
216401
|
-
if (d.failedEndpoint) lines.push(` last endpoint: ${d.failedEndpoint} (rejected)`);
|
|
216402
|
-
return lines.join("\n");
|
|
216403
|
-
}
|
|
216404
|
-
async function fetchRepos(slug) {
|
|
216405
|
-
try {
|
|
216406
|
-
const raw = await api.get(`/workspaces/${slug}/repos`);
|
|
216407
|
-
if (Array.isArray(raw)) return { repos: raw };
|
|
216408
|
-
return { error: "unexpected response shape" };
|
|
216409
|
-
} catch (e) {
|
|
216410
|
-
return { error: e instanceof Error ? e.message : String(e) };
|
|
216411
|
-
}
|
|
216412
|
-
}
|
|
216413
|
-
async function resolveRepo() {
|
|
216414
|
-
const remote = getGitRemote();
|
|
216415
|
-
if (!remote) return { ok: false, reason: "no_remote" };
|
|
216416
|
-
const configSlug = getCachedWorkspace().slug;
|
|
216417
|
-
let meSlug;
|
|
216418
|
-
let meWorkspaceId;
|
|
216419
|
-
let meReturned = false;
|
|
216420
|
-
let meError;
|
|
216421
|
-
try {
|
|
216422
|
-
const me = await api.get("/me", { timeoutMs: 8e3, retries: 1 });
|
|
216423
|
-
meReturned = true;
|
|
216424
|
-
meSlug = me?.slug;
|
|
216425
|
-
meWorkspaceId = me?.workspace_id;
|
|
216426
|
-
if (meSlug) saveWorkspaceToConfig(meSlug, meWorkspaceId);
|
|
216427
|
-
} catch (e) {
|
|
216428
|
-
meError = e instanceof Error ? e.message : String(e);
|
|
216429
|
-
}
|
|
216430
|
-
const candidates = [...new Set([configSlug, meSlug, remote.org].filter(Boolean))];
|
|
216431
|
-
let lastLinkedSlug;
|
|
216432
|
-
let failedEndpoint;
|
|
216433
|
-
for (const slug of candidates) {
|
|
216434
|
-
const result = await fetchRepos(slug);
|
|
216435
|
-
if ("error" in result) {
|
|
216436
|
-
failedEndpoint = `/workspaces/${slug}/repos`;
|
|
216437
|
-
continue;
|
|
216438
|
-
}
|
|
216439
|
-
const repo = result.repos.find((r) => r.github_org === remote.org && r.github_repo === remote.repo);
|
|
216440
|
-
if (repo) {
|
|
216441
|
-
saveWorkspaceToConfig(slug, meWorkspaceId);
|
|
216442
|
-
const source = slug === configSlug ? "config" : slug === meSlug ? "me" : "git-org";
|
|
216443
|
-
return {
|
|
216444
|
-
ok: true,
|
|
216445
|
-
workspaceSlug: slug,
|
|
216446
|
-
repoId: repo.id,
|
|
216447
|
-
remote,
|
|
216448
|
-
hasScanBaseline: !!repo.scan_summary,
|
|
216449
|
-
source
|
|
216450
|
-
};
|
|
216451
|
-
}
|
|
216452
|
-
lastLinkedSlug = slug;
|
|
216453
|
-
}
|
|
216454
|
-
const diagnostics = {
|
|
216455
|
-
remote,
|
|
216456
|
-
triedSlugs: candidates,
|
|
216457
|
-
configSlug,
|
|
216458
|
-
meAttempted: true,
|
|
216459
|
-
meReturned,
|
|
216460
|
-
meSlug,
|
|
216461
|
-
meWorkspaceId,
|
|
216462
|
-
meError,
|
|
216463
|
-
failedEndpoint
|
|
216464
|
-
};
|
|
216465
|
-
if (lastLinkedSlug) {
|
|
216466
|
-
return { ok: false, reason: "not_linked", workspaceSlug: lastLinkedSlug, remote, diagnostics };
|
|
216467
|
-
}
|
|
216468
|
-
return {
|
|
216469
|
-
ok: false,
|
|
216470
|
-
reason: "no_workspace",
|
|
216471
|
-
remote,
|
|
216472
|
-
detail: formatDiagnostics(diagnostics),
|
|
216473
|
-
diagnostics
|
|
216474
|
-
};
|
|
216475
|
-
}
|
|
216476
|
-
|
|
216477
|
-
// src/commands/sync.ts
|
|
216478
216471
|
function parseArgs2(args) {
|
|
216479
216472
|
const flags = {};
|
|
216480
216473
|
for (let i = 0; i < args.length; i++) {
|
|
@@ -216997,7 +216990,7 @@ async function graphCommand(args) {
|
|
|
216997
216990
|
}
|
|
216998
216991
|
|
|
216999
216992
|
// src/index.ts
|
|
217000
|
-
var VERSION = "0.1.
|
|
216993
|
+
var VERSION = "0.1.51";
|
|
217001
216994
|
var HELP_TEXT = `Driftless CLI v${VERSION} \u2014 Living repo context for humans and coding agents
|
|
217002
216995
|
|
|
217003
216996
|
Install: npm install -g @driftless-sh/cli
|