@driftless-sh/cli 0.1.19 → 0.1.21
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 +137 -46
- package/dist/index.js.map +3 -3
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -126140,7 +126140,7 @@ ${lanes.join("\n")}
|
|
|
126140
126140
|
}
|
|
126141
126141
|
}
|
|
126142
126142
|
function createImportCallExpressionAMD(arg, containsLexicalThis) {
|
|
126143
|
-
const
|
|
126143
|
+
const resolve8 = factory2.createUniqueName("resolve");
|
|
126144
126144
|
const reject = factory2.createUniqueName("reject");
|
|
126145
126145
|
const parameters = [
|
|
126146
126146
|
factory2.createParameterDeclaration(
|
|
@@ -126149,7 +126149,7 @@ ${lanes.join("\n")}
|
|
|
126149
126149
|
/*dotDotDotToken*/
|
|
126150
126150
|
void 0,
|
|
126151
126151
|
/*name*/
|
|
126152
|
-
|
|
126152
|
+
resolve8
|
|
126153
126153
|
),
|
|
126154
126154
|
factory2.createParameterDeclaration(
|
|
126155
126155
|
/*modifiers*/
|
|
@@ -126166,7 +126166,7 @@ ${lanes.join("\n")}
|
|
|
126166
126166
|
factory2.createIdentifier("require"),
|
|
126167
126167
|
/*typeArguments*/
|
|
126168
126168
|
void 0,
|
|
126169
|
-
[factory2.createArrayLiteralExpression([arg || factory2.createOmittedExpression()]),
|
|
126169
|
+
[factory2.createArrayLiteralExpression([arg || factory2.createOmittedExpression()]), resolve8, reject]
|
|
126170
126170
|
)
|
|
126171
126171
|
)
|
|
126172
126172
|
]);
|
|
@@ -212884,8 +212884,8 @@ Additional information: BADCLIENT: Bad error code, ${badCode} not found in range
|
|
|
212884
212884
|
installPackage(options) {
|
|
212885
212885
|
this.packageInstallId++;
|
|
212886
212886
|
const request2 = { kind: "installPackage", ...options, id: this.packageInstallId };
|
|
212887
|
-
const promise = new Promise((
|
|
212888
|
-
(this.packageInstalledPromise ?? (this.packageInstalledPromise = /* @__PURE__ */ new Map())).set(this.packageInstallId, { resolve:
|
|
212887
|
+
const promise = new Promise((resolve8, reject) => {
|
|
212888
|
+
(this.packageInstalledPromise ?? (this.packageInstalledPromise = /* @__PURE__ */ new Map())).set(this.packageInstallId, { resolve: resolve8, reject });
|
|
212889
212889
|
});
|
|
212890
212890
|
this.installer.send(request2);
|
|
212891
212891
|
return promise;
|
|
@@ -214179,6 +214179,8 @@ var require_dist = __commonJS({
|
|
|
214179
214179
|
return enricher_1.enrichComponents;
|
|
214180
214180
|
} });
|
|
214181
214181
|
async function scanRepo2(rootPath) {
|
|
214182
|
+
const startMs = Date.now();
|
|
214183
|
+
const startMem = process.memoryUsage().heapUsed;
|
|
214182
214184
|
const identity = (0, identity_1.identifyRepo)(rootPath);
|
|
214183
214185
|
let components = (0, nestjs_extractor_1.extractNestJS)(rootPath);
|
|
214184
214186
|
components = await (0, enricher_1.enrichComponents)(components);
|
|
@@ -214191,7 +214193,18 @@ var require_dist = __commonJS({
|
|
|
214191
214193
|
total_modules: components.filter((c) => c.type === "module").length,
|
|
214192
214194
|
total_dtos: components.filter((c) => c.type === "dto").length
|
|
214193
214195
|
};
|
|
214194
|
-
|
|
214196
|
+
const durationMs = Date.now() - startMs;
|
|
214197
|
+
const memoryMb = Math.round((process.memoryUsage().heapUsed - startMem) / 1024 / 1024);
|
|
214198
|
+
return {
|
|
214199
|
+
identity,
|
|
214200
|
+
components,
|
|
214201
|
+
stats,
|
|
214202
|
+
telemetry: {
|
|
214203
|
+
duration_ms: durationMs,
|
|
214204
|
+
memory_mb: memoryMb,
|
|
214205
|
+
files_parsed: uniqueFiles.size
|
|
214206
|
+
}
|
|
214207
|
+
};
|
|
214195
214208
|
}
|
|
214196
214209
|
}
|
|
214197
214210
|
});
|
|
@@ -214230,8 +214243,30 @@ function getBaseUrl() {
|
|
|
214230
214243
|
}
|
|
214231
214244
|
return DEFAULT_URL;
|
|
214232
214245
|
}
|
|
214246
|
+
function parseError(e) {
|
|
214247
|
+
const msg = e.message;
|
|
214248
|
+
const jsonMatch = msg.match(/\{[^}]*"message"[^}]*\}/);
|
|
214249
|
+
if (jsonMatch) {
|
|
214250
|
+
try {
|
|
214251
|
+
const parsed = JSON.parse(jsonMatch[0]);
|
|
214252
|
+
if (parsed.message) return parsed.message;
|
|
214253
|
+
} catch {
|
|
214254
|
+
}
|
|
214255
|
+
}
|
|
214256
|
+
const statusMatch = msg.match(/HTTP (\d+):/);
|
|
214257
|
+
if (statusMatch) {
|
|
214258
|
+
const code = parseInt(statusMatch[1], 10);
|
|
214259
|
+
if (code === 500) return "Internal server error \u2014 the API encountered an unexpected issue";
|
|
214260
|
+
if (code === 401) return "Authentication failed \u2014 check your API key";
|
|
214261
|
+
if (code === 403) return "Access denied \u2014 your API key lacks permission";
|
|
214262
|
+
if (code === 404) return "Not found \u2014 the resource does not exist";
|
|
214263
|
+
if (code === 429) return "Rate limited \u2014 too many requests, try again later";
|
|
214264
|
+
return `Server error (HTTP ${code})`;
|
|
214265
|
+
}
|
|
214266
|
+
return msg;
|
|
214267
|
+
}
|
|
214233
214268
|
function request(method, path, body) {
|
|
214234
|
-
return new Promise((
|
|
214269
|
+
return new Promise((resolve8, reject) => {
|
|
214235
214270
|
const baseUrl = getBaseUrl();
|
|
214236
214271
|
const fullUrl = `${baseUrl}${path}`;
|
|
214237
214272
|
const url = new URL(fullUrl);
|
|
@@ -214257,14 +214292,14 @@ function request(method, path, body) {
|
|
|
214257
214292
|
return;
|
|
214258
214293
|
}
|
|
214259
214294
|
try {
|
|
214260
|
-
|
|
214295
|
+
resolve8(JSON.parse(data));
|
|
214261
214296
|
} catch {
|
|
214262
|
-
|
|
214297
|
+
resolve8(data);
|
|
214263
214298
|
}
|
|
214264
214299
|
});
|
|
214265
214300
|
}
|
|
214266
214301
|
);
|
|
214267
|
-
req.on("error", reject);
|
|
214302
|
+
req.on("error", (e) => reject(new Error(`Connection failed: ${e.message}`)));
|
|
214268
214303
|
if (body) req.write(JSON.stringify(body));
|
|
214269
214304
|
req.end();
|
|
214270
214305
|
});
|
|
@@ -214282,6 +214317,9 @@ function getApiUrl() {
|
|
|
214282
214317
|
function getApiKey() {
|
|
214283
214318
|
return loadApiKey();
|
|
214284
214319
|
}
|
|
214320
|
+
function formatError(e) {
|
|
214321
|
+
return parseError(e);
|
|
214322
|
+
}
|
|
214285
214323
|
|
|
214286
214324
|
// src/git.ts
|
|
214287
214325
|
var import_node_child_process = require("node:child_process");
|
|
@@ -214516,6 +214554,15 @@ function generateSmartRules(repoId, patterns) {
|
|
|
214516
214554
|
scope: { paths: ["apps/", "libs/"] },
|
|
214517
214555
|
pattern: { type: "FORBIDDEN_IMPORT", params: { imports: ["@modelcontextprotocol", "mcp"] } },
|
|
214518
214556
|
repo_id: repoId
|
|
214557
|
+
},
|
|
214558
|
+
{
|
|
214559
|
+
name: "Controllers must be thin",
|
|
214560
|
+
description: "Controllers should only handle routing and validation. Move business logic, token manipulation, and debug code to services.",
|
|
214561
|
+
type: "STRUCTURAL",
|
|
214562
|
+
severity: "high",
|
|
214563
|
+
scope: { file_patterns: ["*.controller.ts"] },
|
|
214564
|
+
pattern: { type: "CONTROLLER_THICK", params: {} },
|
|
214565
|
+
repo_id: repoId
|
|
214519
214566
|
}
|
|
214520
214567
|
);
|
|
214521
214568
|
return rules;
|
|
@@ -214677,12 +214724,24 @@ async function initCommand(args) {
|
|
|
214677
214724
|
(sum, component) => sum + (component.relations?.length || 0),
|
|
214678
214725
|
0
|
|
214679
214726
|
);
|
|
214680
|
-
|
|
214681
|
-
|
|
214727
|
+
const actualEndpoints = components.filter((c) => c.type === "endpoint").length;
|
|
214728
|
+
const actualServices = components.filter((c) => c.type === "service").length;
|
|
214729
|
+
const actualModules = components.filter((c) => c.type === "module").length;
|
|
214730
|
+
const actualGuards = components.filter((c) => c.type === "guard").length;
|
|
214731
|
+
const actualControllers = components.filter((c) => c.type === "controller").length;
|
|
214732
|
+
const actualDtos = components.filter((c) => c.type === "dto").length;
|
|
214733
|
+
console.log(` Framework: ${summary.framework} | Endpoints: ${actualEndpoints} | Services: ${actualServices}`);
|
|
214734
|
+
console.log(` Modules: ${actualModules} | Guards: ${actualGuards}`);
|
|
214682
214735
|
console.log(` Relations: ${relationCount}`);
|
|
214736
|
+
if (actualControllers > 0) console.log(` Controllers: ${actualControllers}`);
|
|
214737
|
+
if (actualDtos > 0) console.log(` DTOs: ${actualDtos}`);
|
|
214683
214738
|
if (summary.auth_patterns.length > 0) {
|
|
214684
214739
|
console.log(` Auth: ${summary.auth_patterns.join(", ")}`);
|
|
214685
214740
|
}
|
|
214741
|
+
if (scanResult.telemetry) {
|
|
214742
|
+
const t = scanResult.telemetry;
|
|
214743
|
+
console.log(` Scan: ${t.duration_ms}ms, ${t.memory_mb}MB heap, ${t.files_parsed} files`);
|
|
214744
|
+
}
|
|
214686
214745
|
let repo;
|
|
214687
214746
|
try {
|
|
214688
214747
|
const repos = await api.get(`/workspaces/${workspaceSlug}/repos`);
|
|
@@ -214787,7 +214846,7 @@ Creating ${smartRules.length} architectural rules...`);
|
|
|
214787
214846
|
}
|
|
214788
214847
|
console.log(` Docs anchored: ${docsAnchored}`);
|
|
214789
214848
|
console.log("\n---");
|
|
214790
|
-
console.log(`Architecture: ${
|
|
214849
|
+
console.log(`Architecture: ${actualModules} modules, ${actualEndpoints} endpoints, ${actualServices} services`);
|
|
214791
214850
|
console.log(`Relations: ${relationCount} cross-component dependencies mapped`);
|
|
214792
214851
|
console.log(`Rules: ${rulesCreated} architectural rules created from code analysis`);
|
|
214793
214852
|
console.log(`Watchers: ${watchersCreated} context watchers auto-generated`);
|
|
@@ -214832,6 +214891,7 @@ async function scanCommand(args) {
|
|
|
214832
214891
|
const onlyDiff = args.includes("--diff");
|
|
214833
214892
|
let diff = "";
|
|
214834
214893
|
let source = "";
|
|
214894
|
+
let changedFiles = [];
|
|
214835
214895
|
if (onlyDiff) {
|
|
214836
214896
|
diff = getUncommittedDiff();
|
|
214837
214897
|
source = "uncommitted changes";
|
|
@@ -214839,6 +214899,7 @@ async function scanCommand(args) {
|
|
|
214839
214899
|
console.log("No uncommitted changes. Clean.");
|
|
214840
214900
|
process.exit(0);
|
|
214841
214901
|
}
|
|
214902
|
+
changedFiles = diff.split("\n").filter((line) => line.startsWith("+++ b/") || line.startsWith("--- a/")).map((line) => line.replace(/^\+\+\+ b\//, "").replace(/^--- a\//, "")).filter((f, i, arr) => arr.indexOf(f) === i);
|
|
214842
214903
|
} else {
|
|
214843
214904
|
const staged = getStagedDiff();
|
|
214844
214905
|
const unstaged = getUncommittedDiff();
|
|
@@ -214852,6 +214913,9 @@ async function scanCommand(args) {
|
|
|
214852
214913
|
const commitHash = getLastCommitHash();
|
|
214853
214914
|
const author = getAuthorName();
|
|
214854
214915
|
console.log(`Scanning ${source}...`);
|
|
214916
|
+
if (changedFiles.length > 0) {
|
|
214917
|
+
console.log(` Files: ${changedFiles.join(", ")}`);
|
|
214918
|
+
}
|
|
214855
214919
|
const result = await api.post("/scan", {
|
|
214856
214920
|
workspace_id: workspace.workspace_id,
|
|
214857
214921
|
repo_id: repo.id,
|
|
@@ -214859,16 +214923,17 @@ async function scanCommand(args) {
|
|
|
214859
214923
|
commit_hash: commitHash,
|
|
214860
214924
|
author
|
|
214861
214925
|
});
|
|
214926
|
+
const rulesEvaluated = result.rules_evaluated || 0;
|
|
214862
214927
|
if (result.status === "clean") {
|
|
214863
|
-
console.log(
|
|
214928
|
+
console.log(`Clean \u2014 ${rulesEvaluated} rule(s) evaluated, no violations.`);
|
|
214864
214929
|
process.exit(0);
|
|
214865
214930
|
}
|
|
214866
214931
|
if (!result.violations || result.violations.length === 0) {
|
|
214867
|
-
console.log(
|
|
214932
|
+
console.log(`Clean \u2014 ${rulesEvaluated} rule(s) evaluated, no violations.`);
|
|
214868
214933
|
process.exit(0);
|
|
214869
214934
|
}
|
|
214870
214935
|
console.log(`
|
|
214871
|
-
${result.violations.length} violation(s) found:
|
|
214936
|
+
${result.violations.length} violation(s) found (${rulesEvaluated} rule(s) evaluated):
|
|
214872
214937
|
`);
|
|
214873
214938
|
for (const v of result.violations) {
|
|
214874
214939
|
const severityColor = v.severity === "critical" || v.severity === "high" ? "\x1B[31m" : "\x1B[33m";
|
|
@@ -214883,6 +214948,8 @@ ${result.violations.length} violation(s) found:
|
|
|
214883
214948
|
}
|
|
214884
214949
|
|
|
214885
214950
|
// src/commands/context.ts
|
|
214951
|
+
var import_node_fs4 = require("node:fs");
|
|
214952
|
+
var import_node_path4 = require("node:path");
|
|
214886
214953
|
function parseArgs(args) {
|
|
214887
214954
|
const flags = {};
|
|
214888
214955
|
const positional = [];
|
|
@@ -215065,13 +215132,16 @@ async function contextCommand(args) {
|
|
|
215065
215132
|
const qs = query.length > 0 ? `?${query.join("&")}` : "";
|
|
215066
215133
|
try {
|
|
215067
215134
|
const summaries = await api.get(`/workspaces/${workspaceSlug}/watchers${qs}`);
|
|
215135
|
+
if (summaries.length === 0) {
|
|
215136
|
+
console.error("No context topics yet. Run `driftless init` to auto-generate watchers from your codebase.");
|
|
215137
|
+
}
|
|
215068
215138
|
if (isHuman) {
|
|
215069
215139
|
renderSummaryHuman(summaries);
|
|
215070
215140
|
} else {
|
|
215071
215141
|
emitJSON(summaries);
|
|
215072
215142
|
}
|
|
215073
215143
|
} catch (e) {
|
|
215074
|
-
console.error(`List failed: ${e
|
|
215144
|
+
console.error(`List failed: ${formatError(e)}`);
|
|
215075
215145
|
process.exit(1);
|
|
215076
215146
|
}
|
|
215077
215147
|
return;
|
|
@@ -215104,13 +215174,16 @@ async function contextCommand(args) {
|
|
|
215104
215174
|
`/workspaces/${workspaceSlug}/watchers/match-files`,
|
|
215105
215175
|
{ files }
|
|
215106
215176
|
);
|
|
215177
|
+
if (results.length === 0) {
|
|
215178
|
+
console.error(`No context topics match these files. No watcher covers the changed paths.`);
|
|
215179
|
+
}
|
|
215107
215180
|
if (isHuman) {
|
|
215108
215181
|
renderMatchFilesHuman(results, files);
|
|
215109
215182
|
} else {
|
|
215110
215183
|
emitJSON(results);
|
|
215111
215184
|
}
|
|
215112
215185
|
} catch (e) {
|
|
215113
|
-
console.error(`Match failed: ${e
|
|
215186
|
+
console.error(`Match failed: ${formatError(e)}`);
|
|
215114
215187
|
process.exit(1);
|
|
215115
215188
|
}
|
|
215116
215189
|
return;
|
|
@@ -215126,7 +215199,11 @@ async function contextCommand(args) {
|
|
|
215126
215199
|
if (isHuman) {
|
|
215127
215200
|
renderContextHuman(ctx);
|
|
215128
215201
|
} else {
|
|
215129
|
-
|
|
215202
|
+
const sanitized = JSON.parse(JSON.stringify(ctx, (_key, value) => {
|
|
215203
|
+
if (typeof value === "string" && value.length > 500) return value.slice(0, 500) + "\u2026";
|
|
215204
|
+
return value;
|
|
215205
|
+
}));
|
|
215206
|
+
emitJSON(sanitized);
|
|
215130
215207
|
}
|
|
215131
215208
|
} catch (e) {
|
|
215132
215209
|
console.error(`Topic '${slug}' not found.`);
|
|
@@ -215144,13 +215221,16 @@ async function contextCommand(args) {
|
|
|
215144
215221
|
const results = await api.get(
|
|
215145
215222
|
`/workspaces/${workspaceSlug}/watchers/search?q=${encodeURIComponent(query)}`
|
|
215146
215223
|
);
|
|
215224
|
+
if (results.length === 0) {
|
|
215225
|
+
console.error(`No context topics matching "${query}".`);
|
|
215226
|
+
}
|
|
215147
215227
|
if (isHuman) {
|
|
215148
215228
|
renderSummaryHuman(results);
|
|
215149
215229
|
} else {
|
|
215150
215230
|
emitJSON(results);
|
|
215151
215231
|
}
|
|
215152
215232
|
} catch (e) {
|
|
215153
|
-
console.error(`Search failed: ${e
|
|
215233
|
+
console.error(`Search failed: ${formatError(e)}`);
|
|
215154
215234
|
process.exit(1);
|
|
215155
215235
|
}
|
|
215156
215236
|
return;
|
|
@@ -215324,10 +215404,14 @@ async function contextCommand(args) {
|
|
|
215324
215404
|
if (filesFlag) console.log(` files: ${filesFlag}`);
|
|
215325
215405
|
if (patternFlag) console.log(` pattern: ${patternFlag}`);
|
|
215326
215406
|
} else {
|
|
215327
|
-
|
|
215407
|
+
const sanitized = JSON.parse(JSON.stringify(result, (_key, value) => {
|
|
215408
|
+
if (typeof value === "string" && value.length > 500) return value.slice(0, 500) + "\u2026";
|
|
215409
|
+
return value;
|
|
215410
|
+
}));
|
|
215411
|
+
emitJSON(sanitized);
|
|
215328
215412
|
}
|
|
215329
215413
|
} catch (e) {
|
|
215330
|
-
console.error(`Anchor failed: ${e
|
|
215414
|
+
console.error(`Anchor failed: ${formatError(e)}`);
|
|
215331
215415
|
process.exit(1);
|
|
215332
215416
|
}
|
|
215333
215417
|
return;
|
|
@@ -215343,18 +215427,25 @@ async function contextCommand(args) {
|
|
|
215343
215427
|
console.error("No files provided.");
|
|
215344
215428
|
process.exit(1);
|
|
215345
215429
|
}
|
|
215430
|
+
const missingFiles = files.filter((f) => !(0, import_node_fs4.existsSync)((0, import_node_path4.resolve)(process.cwd(), f)));
|
|
215431
|
+
if (missingFiles.length > 0 && isHuman) {
|
|
215432
|
+
console.error(`File(s) not found locally: ${missingFiles.join(", ")}. Matching by pattern only.`);
|
|
215433
|
+
}
|
|
215346
215434
|
try {
|
|
215347
215435
|
const results = await api.post(
|
|
215348
215436
|
`/workspaces/${workspaceSlug}/watchers/match-files`,
|
|
215349
215437
|
{ files }
|
|
215350
215438
|
);
|
|
215439
|
+
if (results.length === 0) {
|
|
215440
|
+
console.error(`No context topics match these files. No watcher covers the changed paths.`);
|
|
215441
|
+
}
|
|
215351
215442
|
if (isHuman) {
|
|
215352
215443
|
renderMatchFilesHuman(results, files);
|
|
215353
215444
|
} else {
|
|
215354
215445
|
emitJSON(results);
|
|
215355
215446
|
}
|
|
215356
215447
|
} catch (e) {
|
|
215357
|
-
console.error(`Push failed: ${e
|
|
215448
|
+
console.error(`Push failed: ${formatError(e)}`);
|
|
215358
215449
|
process.exit(1);
|
|
215359
215450
|
}
|
|
215360
215451
|
return;
|
|
@@ -215365,8 +215456,8 @@ Run 'driftless help context' for full reference.`);
|
|
|
215365
215456
|
}
|
|
215366
215457
|
|
|
215367
215458
|
// src/commands/install-skill.ts
|
|
215368
|
-
var
|
|
215369
|
-
var
|
|
215459
|
+
var import_node_fs5 = require("node:fs");
|
|
215460
|
+
var import_node_path5 = require("node:path");
|
|
215370
215461
|
var template = `# Driftless \u2014 Live Repo Context
|
|
215371
215462
|
|
|
215372
215463
|
Driftless Cloud holds the team's living codebase context (topics, anchors, rules, gotchas).
|
|
@@ -215492,29 +215583,29 @@ Context delivery + structural verification only.
|
|
|
215492
215583
|
`;
|
|
215493
215584
|
function installSkillCommand() {
|
|
215494
215585
|
const cwd = process.cwd();
|
|
215495
|
-
const agentsPath = (0,
|
|
215496
|
-
if ((0,
|
|
215497
|
-
const existing = (0,
|
|
215586
|
+
const agentsPath = (0, import_node_path5.resolve)(cwd, "AGENTS.md");
|
|
215587
|
+
if ((0, import_node_fs5.existsSync)(agentsPath)) {
|
|
215588
|
+
const existing = (0, import_node_fs5.readFileSync)(agentsPath, "utf8");
|
|
215498
215589
|
if (existing.includes("# Driftless")) {
|
|
215499
215590
|
console.log("Driftless section already present in AGENTS.md.");
|
|
215500
215591
|
return;
|
|
215501
215592
|
}
|
|
215502
|
-
(0,
|
|
215593
|
+
(0, import_node_fs5.writeFileSync)(agentsPath, existing + "\n---\n\n" + template);
|
|
215503
215594
|
console.log(`Appended Driftless section to ${agentsPath}`);
|
|
215504
215595
|
} else {
|
|
215505
|
-
(0,
|
|
215596
|
+
(0, import_node_fs5.writeFileSync)(agentsPath, template);
|
|
215506
215597
|
console.log(`Driftless skill installed at ${agentsPath}`);
|
|
215507
215598
|
}
|
|
215508
215599
|
}
|
|
215509
215600
|
|
|
215510
215601
|
// src/commands/login.ts
|
|
215511
|
-
var
|
|
215512
|
-
var
|
|
215602
|
+
var import_node_fs6 = require("node:fs");
|
|
215603
|
+
var import_node_path6 = require("node:path");
|
|
215513
215604
|
var import_node_readline = require("node:readline");
|
|
215514
215605
|
var import_node_child_process2 = require("node:child_process");
|
|
215515
215606
|
var import_node_os2 = require("node:os");
|
|
215516
|
-
var CONFIG_DIR = (0,
|
|
215517
|
-
var CONFIG_PATH2 = (0,
|
|
215607
|
+
var CONFIG_DIR = (0, import_node_path6.resolve)((0, import_node_os2.homedir)(), ".driftless");
|
|
215608
|
+
var CONFIG_PATH2 = (0, import_node_path6.resolve)(CONFIG_DIR, "config.json");
|
|
215518
215609
|
function openBrowser(url) {
|
|
215519
215610
|
const cmd = process.platform === "darwin" ? "open" : process.platform === "win32" ? "start" : "xdg-open";
|
|
215520
215611
|
(0, import_node_child_process2.exec)(`${cmd} ${url}`);
|
|
@@ -215543,10 +215634,10 @@ async function loginCommand(args) {
|
|
|
215543
215634
|
input: process.stdin,
|
|
215544
215635
|
output: process.stdout
|
|
215545
215636
|
});
|
|
215546
|
-
const apiKey = await new Promise((
|
|
215637
|
+
const apiKey = await new Promise((resolve8) => {
|
|
215547
215638
|
rl.question("Paste your API key: ", (answer) => {
|
|
215548
215639
|
rl.close();
|
|
215549
|
-
|
|
215640
|
+
resolve8(answer.trim());
|
|
215550
215641
|
});
|
|
215551
215642
|
});
|
|
215552
215643
|
if (!apiKey.startsWith("drift_")) {
|
|
@@ -215559,10 +215650,10 @@ async function loginCommand(args) {
|
|
|
215559
215650
|
function saveConfig(apiKey, apiUrl) {
|
|
215560
215651
|
const url = apiUrl || "https://api.driftless.icu/api/v1";
|
|
215561
215652
|
try {
|
|
215562
|
-
if (!(0,
|
|
215563
|
-
(0,
|
|
215653
|
+
if (!(0, import_node_fs6.existsSync)(CONFIG_DIR)) {
|
|
215654
|
+
(0, import_node_fs6.mkdirSync)(CONFIG_DIR, { recursive: true });
|
|
215564
215655
|
}
|
|
215565
|
-
(0,
|
|
215656
|
+
(0, import_node_fs6.writeFileSync)(
|
|
215566
215657
|
CONFIG_PATH2,
|
|
215567
215658
|
JSON.stringify({ api_key: apiKey, api_url: url }, null, 2) + "\n"
|
|
215568
215659
|
);
|
|
@@ -215578,8 +215669,8 @@ function saveConfig(apiKey, apiUrl) {
|
|
|
215578
215669
|
}
|
|
215579
215670
|
|
|
215580
215671
|
// src/commands/doctor.ts
|
|
215581
|
-
var
|
|
215582
|
-
var
|
|
215672
|
+
var import_node_fs7 = require("node:fs");
|
|
215673
|
+
var import_node_path7 = require("node:path");
|
|
215583
215674
|
async function doctorCommand() {
|
|
215584
215675
|
const checks = [];
|
|
215585
215676
|
const apiKey = getApiKey();
|
|
@@ -215590,7 +215681,7 @@ async function doctorCommand() {
|
|
|
215590
215681
|
}
|
|
215591
215682
|
const apiUrl = getApiUrl();
|
|
215592
215683
|
try {
|
|
215593
|
-
await api.get("/
|
|
215684
|
+
await api.get("/health");
|
|
215594
215685
|
checks.push({ name: "API reachable", status: "ok", detail: apiUrl });
|
|
215595
215686
|
} catch {
|
|
215596
215687
|
checks.push({ name: "API reachable", status: "fail", detail: `Cannot reach ${apiUrl}` });
|
|
@@ -215665,9 +215756,9 @@ async function doctorCommand() {
|
|
|
215665
215756
|
} else {
|
|
215666
215757
|
checks.push({ name: "Baseline", status: "warn", detail: "Skipped (no git remote)" });
|
|
215667
215758
|
}
|
|
215668
|
-
const agentsPath = (0,
|
|
215669
|
-
if ((0,
|
|
215670
|
-
const content = (0,
|
|
215759
|
+
const agentsPath = (0, import_node_path7.resolve)(process.cwd(), "AGENTS.md");
|
|
215760
|
+
if ((0, import_node_fs7.existsSync)(agentsPath)) {
|
|
215761
|
+
const content = (0, import_node_fs7.readFileSync)(agentsPath, "utf-8");
|
|
215671
215762
|
if (content.includes("driftless")) {
|
|
215672
215763
|
checks.push({ name: "AGENTS.md", status: "ok", detail: "Driftless skill installed" });
|
|
215673
215764
|
} else {
|
|
@@ -215722,7 +215813,7 @@ function pad2(s, n) {
|
|
|
215722
215813
|
}
|
|
215723
215814
|
|
|
215724
215815
|
// src/index.ts
|
|
215725
|
-
var VERSION = "0.1.
|
|
215816
|
+
var VERSION = "0.1.21";
|
|
215726
215817
|
var HELP_TEXT = `Driftless CLI v${VERSION} \u2014 Context integrity for AI engineering teams
|
|
215727
215818
|
|
|
215728
215819
|
Install: npm install -g @driftless-sh/cli
|