@driftless-sh/cli 0.1.22 → 0.1.23
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 +90 -36
- package/dist/index.js +702 -299
- package/dist/index.js.map +4 -4
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -6,9 +6,16 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
|
6
6
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
7
|
var __getProtoOf = Object.getPrototypeOf;
|
|
8
8
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
9
|
+
var __esm = (fn, res) => function __init() {
|
|
10
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
11
|
+
};
|
|
9
12
|
var __commonJS = (cb, mod) => function __require() {
|
|
10
13
|
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
11
14
|
};
|
|
15
|
+
var __export = (target, all) => {
|
|
16
|
+
for (var name in all)
|
|
17
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
18
|
+
};
|
|
12
19
|
var __copyProps = (to, from, except, desc) => {
|
|
13
20
|
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
21
|
for (let key of __getOwnPropNames(from))
|
|
@@ -26,6 +33,101 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
26
33
|
mod
|
|
27
34
|
));
|
|
28
35
|
|
|
36
|
+
// src/git.ts
|
|
37
|
+
var git_exports = {};
|
|
38
|
+
__export(git_exports, {
|
|
39
|
+
getAuthorName: () => getAuthorName,
|
|
40
|
+
getChangedFilesFromDiff: () => getChangedFilesFromDiff,
|
|
41
|
+
getChangedFilesList: () => getChangedFilesList,
|
|
42
|
+
getGitRemote: () => getGitRemote,
|
|
43
|
+
getLastCommitHash: () => getLastCommitHash,
|
|
44
|
+
getStagedDiff: () => getStagedDiff,
|
|
45
|
+
getUncommittedDiff: () => getUncommittedDiff,
|
|
46
|
+
isGitRepo: () => isGitRepo
|
|
47
|
+
});
|
|
48
|
+
function getGitRemote() {
|
|
49
|
+
try {
|
|
50
|
+
const url = (0, import_node_child_process.execSync)("git config --get remote.origin.url", {
|
|
51
|
+
encoding: "utf8",
|
|
52
|
+
cwd: process.cwd()
|
|
53
|
+
}).trim();
|
|
54
|
+
const match = url.match(/[:/]([^/]+)\/([^/]+?)(?:\.git)?$/);
|
|
55
|
+
if (match) {
|
|
56
|
+
return { org: match[1], repo: match[2] };
|
|
57
|
+
}
|
|
58
|
+
return null;
|
|
59
|
+
} catch {
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
function isGitRepo() {
|
|
64
|
+
return (0, import_node_fs2.existsSync)((0, import_node_path2.resolve)(process.cwd(), ".git"));
|
|
65
|
+
}
|
|
66
|
+
function getUncommittedDiff() {
|
|
67
|
+
try {
|
|
68
|
+
return (0, import_node_child_process.execSync)("git diff", { encoding: "utf8", cwd: process.cwd() }).trim();
|
|
69
|
+
} catch {
|
|
70
|
+
return "";
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
function getStagedDiff() {
|
|
74
|
+
try {
|
|
75
|
+
return (0, import_node_child_process.execSync)("git diff --staged", { encoding: "utf8", cwd: process.cwd() }).trim();
|
|
76
|
+
} catch {
|
|
77
|
+
return "";
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
function getLastCommitHash() {
|
|
81
|
+
try {
|
|
82
|
+
return (0, import_node_child_process.execSync)("git rev-parse HEAD", { encoding: "utf8", cwd: process.cwd() }).trim();
|
|
83
|
+
} catch {
|
|
84
|
+
return "unknown";
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
function getChangedFilesFromDiff(diff) {
|
|
88
|
+
const text = diff ?? getUncommittedDiff();
|
|
89
|
+
if (!text) return [];
|
|
90
|
+
const files = /* @__PURE__ */ new Set();
|
|
91
|
+
for (const line of text.split("\n")) {
|
|
92
|
+
if (line.startsWith("+++ b/")) {
|
|
93
|
+
files.add(line.slice(6));
|
|
94
|
+
} else if (line.startsWith("--- a/")) {
|
|
95
|
+
} else if (line.startsWith("diff --git ")) {
|
|
96
|
+
const match = line.match(/diff --git a\/(.+?) b\/(.+)$/);
|
|
97
|
+
if (match) files.add(match[2]);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return [...files];
|
|
101
|
+
}
|
|
102
|
+
function getChangedFilesList() {
|
|
103
|
+
try {
|
|
104
|
+
const unstaged = (0, import_node_child_process.execSync)("git diff --name-only HEAD", { encoding: "utf8", cwd: process.cwd() }).trim();
|
|
105
|
+
const staged = (0, import_node_child_process.execSync)("git diff --staged --name-only", { encoding: "utf8", cwd: process.cwd() }).trim();
|
|
106
|
+
const files = /* @__PURE__ */ new Set();
|
|
107
|
+
if (unstaged) unstaged.split("\n").forEach((f) => files.add(f));
|
|
108
|
+
if (staged) staged.split("\n").forEach((f) => files.add(f));
|
|
109
|
+
return [...files].filter(Boolean);
|
|
110
|
+
} catch {
|
|
111
|
+
return [];
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
function getAuthorName() {
|
|
115
|
+
try {
|
|
116
|
+
return (0, import_node_child_process.execSync)("git config user.name", { encoding: "utf8", cwd: process.cwd() }).trim();
|
|
117
|
+
} catch {
|
|
118
|
+
return "unknown";
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
var import_node_child_process, import_node_fs2, import_node_path2;
|
|
122
|
+
var init_git = __esm({
|
|
123
|
+
"src/git.ts"() {
|
|
124
|
+
"use strict";
|
|
125
|
+
import_node_child_process = require("node:child_process");
|
|
126
|
+
import_node_fs2 = require("node:fs");
|
|
127
|
+
import_node_path2 = require("node:path");
|
|
128
|
+
}
|
|
129
|
+
});
|
|
130
|
+
|
|
29
131
|
// ../../libs/scanner/dist/identity/identity.js
|
|
30
132
|
var require_identity = __commonJS({
|
|
31
133
|
"../../libs/scanner/dist/identity/identity.js"(exports2) {
|
|
@@ -2436,7 +2538,7 @@ var require_typescript = __commonJS({
|
|
|
2436
2538
|
var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor;
|
|
2437
2539
|
var __getOwnPropNames2 = Object.getOwnPropertyNames;
|
|
2438
2540
|
var __hasOwnProp2 = Object.prototype.hasOwnProperty;
|
|
2439
|
-
var
|
|
2541
|
+
var __export2 = (target, all) => {
|
|
2440
2542
|
for (var name in all)
|
|
2441
2543
|
__defProp2(target, name, { get: all[name], enumerable: true });
|
|
2442
2544
|
};
|
|
@@ -2450,7 +2552,7 @@ var require_typescript = __commonJS({
|
|
|
2450
2552
|
};
|
|
2451
2553
|
var __toCommonJS = (mod) => (__copyProps2, mod);
|
|
2452
2554
|
var typescript_exports = {};
|
|
2453
|
-
|
|
2555
|
+
__export2(typescript_exports, {
|
|
2454
2556
|
ANONYMOUS: () => ANONYMOUS,
|
|
2455
2557
|
AccessFlags: () => AccessFlags,
|
|
2456
2558
|
AssertionLevel: () => AssertionLevel,
|
|
@@ -7537,7 +7639,7 @@ ${lanes.join("\n")}
|
|
|
7537
7639
|
}
|
|
7538
7640
|
var timestamp = nativePerformanceTime ? () => nativePerformanceTime.now() : Date.now;
|
|
7539
7641
|
var ts_performance_exports = {};
|
|
7540
|
-
|
|
7642
|
+
__export2(ts_performance_exports, {
|
|
7541
7643
|
clearMarks: () => clearMarks,
|
|
7542
7644
|
clearMeasures: () => clearMeasures,
|
|
7543
7645
|
createTimer: () => createTimer,
|
|
@@ -55840,7 +55942,7 @@ ${lanes.join("\n")}
|
|
|
55840
55942
|
}
|
|
55841
55943
|
}
|
|
55842
55944
|
var ts_moduleSpecifiers_exports = {};
|
|
55843
|
-
|
|
55945
|
+
__export2(ts_moduleSpecifiers_exports, {
|
|
55844
55946
|
RelativePreference: () => RelativePreference,
|
|
55845
55947
|
countPathComponents: () => countPathComponents,
|
|
55846
55948
|
forEachFileNameOfModule: () => forEachFileNameOfModule,
|
|
@@ -126140,7 +126242,7 @@ ${lanes.join("\n")}
|
|
|
126140
126242
|
}
|
|
126141
126243
|
}
|
|
126142
126244
|
function createImportCallExpressionAMD(arg, containsLexicalThis) {
|
|
126143
|
-
const
|
|
126245
|
+
const resolve9 = factory2.createUniqueName("resolve");
|
|
126144
126246
|
const reject = factory2.createUniqueName("reject");
|
|
126145
126247
|
const parameters = [
|
|
126146
126248
|
factory2.createParameterDeclaration(
|
|
@@ -126149,7 +126251,7 @@ ${lanes.join("\n")}
|
|
|
126149
126251
|
/*dotDotDotToken*/
|
|
126150
126252
|
void 0,
|
|
126151
126253
|
/*name*/
|
|
126152
|
-
|
|
126254
|
+
resolve9
|
|
126153
126255
|
),
|
|
126154
126256
|
factory2.createParameterDeclaration(
|
|
126155
126257
|
/*modifiers*/
|
|
@@ -126166,7 +126268,7 @@ ${lanes.join("\n")}
|
|
|
126166
126268
|
factory2.createIdentifier("require"),
|
|
126167
126269
|
/*typeArguments*/
|
|
126168
126270
|
void 0,
|
|
126169
|
-
[factory2.createArrayLiteralExpression([arg || factory2.createOmittedExpression()]),
|
|
126271
|
+
[factory2.createArrayLiteralExpression([arg || factory2.createOmittedExpression()]), resolve9, reject]
|
|
126170
126272
|
)
|
|
126171
126273
|
)
|
|
126172
126274
|
]);
|
|
@@ -150640,7 +150742,7 @@ ${lanes.join("\n")}
|
|
|
150640
150742
|
}
|
|
150641
150743
|
}
|
|
150642
150744
|
var ts_JsTyping_exports = {};
|
|
150643
|
-
|
|
150745
|
+
__export2(ts_JsTyping_exports, {
|
|
150644
150746
|
NameValidationResult: () => NameValidationResult,
|
|
150645
150747
|
discoverTypings: () => discoverTypings,
|
|
150646
150748
|
isTypingUpToDate: () => isTypingUpToDate,
|
|
@@ -157686,7 +157788,7 @@ interface Symbol {
|
|
|
157686
157788
|
return options;
|
|
157687
157789
|
}
|
|
157688
157790
|
var ts_NavigateTo_exports = {};
|
|
157689
|
-
|
|
157791
|
+
__export2(ts_NavigateTo_exports, {
|
|
157690
157792
|
getNavigateToItems: () => getNavigateToItems
|
|
157691
157793
|
});
|
|
157692
157794
|
function getNavigateToItems(sourceFiles, checker, cancellationToken, searchValue, maxResultCount, excludeDtsFiles, excludeLibFiles) {
|
|
@@ -157791,7 +157893,7 @@ interface Symbol {
|
|
|
157791
157893
|
};
|
|
157792
157894
|
}
|
|
157793
157895
|
var ts_NavigationBar_exports = {};
|
|
157794
|
-
|
|
157896
|
+
__export2(ts_NavigationBar_exports, {
|
|
157795
157897
|
getNavigationBarItems: () => getNavigationBarItems,
|
|
157796
157898
|
getNavigationTree: () => getNavigationTree
|
|
157797
157899
|
});
|
|
@@ -158579,7 +158681,7 @@ interface Symbol {
|
|
|
158579
158681
|
return text.replace(/\\?(?:\r?\n|[\r\u2028\u2029])/g, "");
|
|
158580
158682
|
}
|
|
158581
158683
|
var ts_refactor_exports = {};
|
|
158582
|
-
|
|
158684
|
+
__export2(ts_refactor_exports, {
|
|
158583
158685
|
addExportsInOldFile: () => addExportsInOldFile,
|
|
158584
158686
|
addImportsForMovedSymbols: () => addImportsForMovedSymbols,
|
|
158585
158687
|
addNewFileToTsconfig: () => addNewFileToTsconfig,
|
|
@@ -162122,7 +162224,7 @@ ${newComment.split("\n").map((c) => ` * ${c}`).join("\n")}
|
|
|
162122
162224
|
}
|
|
162123
162225
|
}
|
|
162124
162226
|
var ts_refactor_extractSymbol_exports = {};
|
|
162125
|
-
|
|
162227
|
+
__export2(ts_refactor_extractSymbol_exports, {
|
|
162126
162228
|
Messages: () => Messages,
|
|
162127
162229
|
RangeFacts: () => RangeFacts,
|
|
162128
162230
|
getRangeToExtract: () => getRangeToExtract2,
|
|
@@ -166701,7 +166803,7 @@ ${newComment.split("\n").map((c) => ` * ${c}`).join("\n")}
|
|
|
166701
166803
|
return result;
|
|
166702
166804
|
}
|
|
166703
166805
|
var ts_BreakpointResolver_exports = {};
|
|
166704
|
-
|
|
166806
|
+
__export2(ts_BreakpointResolver_exports, {
|
|
166705
166807
|
spanInSourceFileAtLocation: () => spanInSourceFileAtLocation
|
|
166706
166808
|
});
|
|
166707
166809
|
function spanInSourceFileAtLocation(sourceFile, position) {
|
|
@@ -167207,7 +167309,7 @@ ${newComment.split("\n").map((c) => ` * ${c}`).join("\n")}
|
|
|
167207
167309
|
}
|
|
167208
167310
|
}
|
|
167209
167311
|
var ts_CallHierarchy_exports = {};
|
|
167210
|
-
|
|
167312
|
+
__export2(ts_CallHierarchy_exports, {
|
|
167211
167313
|
createCallHierarchyItem: () => createCallHierarchyItem,
|
|
167212
167314
|
getIncomingCalls: () => getIncomingCalls,
|
|
167213
167315
|
getOutgoingCalls: () => getOutgoingCalls,
|
|
@@ -167656,11 +167758,11 @@ ${newComment.split("\n").map((c) => ` * ${c}`).join("\n")}
|
|
|
167656
167758
|
return group(collectCallSites(program, declaration), getCallSiteGroupKey, (entries) => convertCallSiteGroupToOutgoingCall(program, entries));
|
|
167657
167759
|
}
|
|
167658
167760
|
var ts_classifier_exports = {};
|
|
167659
|
-
|
|
167761
|
+
__export2(ts_classifier_exports, {
|
|
167660
167762
|
v2020: () => ts_classifier_v2020_exports
|
|
167661
167763
|
});
|
|
167662
167764
|
var ts_classifier_v2020_exports = {};
|
|
167663
|
-
|
|
167765
|
+
__export2(ts_classifier_v2020_exports, {
|
|
167664
167766
|
TokenEncodingConsts: () => TokenEncodingConsts,
|
|
167665
167767
|
TokenModifier: () => TokenModifier,
|
|
167666
167768
|
TokenType: () => TokenType,
|
|
@@ -167668,7 +167770,7 @@ ${newComment.split("\n").map((c) => ` * ${c}`).join("\n")}
|
|
|
167668
167770
|
getSemanticClassifications: () => getSemanticClassifications2
|
|
167669
167771
|
});
|
|
167670
167772
|
var ts_codefix_exports = {};
|
|
167671
|
-
|
|
167773
|
+
__export2(ts_codefix_exports, {
|
|
167672
167774
|
PreserveOptionalFlags: () => PreserveOptionalFlags,
|
|
167673
167775
|
addNewNodeForMemberSymbol: () => addNewNodeForMemberSymbol,
|
|
167674
167776
|
codeFixAll: () => codeFixAll,
|
|
@@ -179589,7 +179691,7 @@ ${newComment.split("\n").map((c) => ` * ${c}`).join("\n")}
|
|
|
179589
179691
|
}
|
|
179590
179692
|
}
|
|
179591
179693
|
var ts_Completions_exports = {};
|
|
179592
|
-
|
|
179694
|
+
__export2(ts_Completions_exports, {
|
|
179593
179695
|
CompletionKind: () => CompletionKind,
|
|
179594
179696
|
CompletionSource: () => CompletionSource,
|
|
179595
179697
|
SortText: () => SortText,
|
|
@@ -183845,7 +183947,7 @@ ${newComment.split("\n").map((c) => ` * ${c}`).join("\n")}
|
|
|
183845
183947
|
return keyword === "abstract" || keyword === "async" || keyword === "await" || keyword === "declare" || keyword === "module" || keyword === "namespace" || keyword === "type" || keyword === "satisfies" || keyword === "as";
|
|
183846
183948
|
}
|
|
183847
183949
|
var ts_Completions_StringCompletions_exports = {};
|
|
183848
|
-
|
|
183950
|
+
__export2(ts_Completions_StringCompletions_exports, {
|
|
183849
183951
|
getStringLiteralCompletionDetails: () => getStringLiteralCompletionDetails,
|
|
183850
183952
|
getStringLiteralCompletions: () => getStringLiteralCompletions
|
|
183851
183953
|
});
|
|
@@ -184913,7 +185015,7 @@ ${newComment.split("\n").map((c) => ` * ${c}`).join("\n")}
|
|
|
184913
185015
|
return isCallExpression(node.parent) && firstOrUndefined(node.parent.arguments) === node && isIdentifier(node.parent.expression) && node.parent.expression.escapedText === "require";
|
|
184914
185016
|
}
|
|
184915
185017
|
var ts_FindAllReferences_exports = {};
|
|
184916
|
-
|
|
185018
|
+
__export2(ts_FindAllReferences_exports, {
|
|
184917
185019
|
Core: () => Core,
|
|
184918
185020
|
DefinitionKind: () => DefinitionKind,
|
|
184919
185021
|
EntryKind: () => EntryKind,
|
|
@@ -187497,7 +187599,7 @@ ${newComment.split("\n").map((c) => ` * ${c}`).join("\n")}
|
|
|
187497
187599
|
}
|
|
187498
187600
|
})(Core || (Core = {}));
|
|
187499
187601
|
var ts_GoToDefinition_exports = {};
|
|
187500
|
-
|
|
187602
|
+
__export2(ts_GoToDefinition_exports, {
|
|
187501
187603
|
createDefinitionInfo: () => createDefinitionInfo,
|
|
187502
187604
|
getDefinitionAndBoundSpan: () => getDefinitionAndBoundSpan,
|
|
187503
187605
|
getDefinitionAtPosition: () => getDefinitionAtPosition,
|
|
@@ -188069,7 +188171,7 @@ ${newComment.split("\n").map((c) => ` * ${c}`).join("\n")}
|
|
|
188069
188171
|
}
|
|
188070
188172
|
}
|
|
188071
188173
|
var ts_InlayHints_exports = {};
|
|
188072
|
-
|
|
188174
|
+
__export2(ts_InlayHints_exports, {
|
|
188073
188175
|
provideInlayHints: () => provideInlayHints
|
|
188074
188176
|
});
|
|
188075
188177
|
var leadingParameterNameCommentRegexFactory = (name) => {
|
|
@@ -188870,7 +188972,7 @@ ${newComment.split("\n").map((c) => ` * ${c}`).join("\n")}
|
|
|
188870
188972
|
}
|
|
188871
188973
|
}
|
|
188872
188974
|
var ts_JsDoc_exports = {};
|
|
188873
|
-
|
|
188975
|
+
__export2(ts_JsDoc_exports, {
|
|
188874
188976
|
getDocCommentTemplateAtPosition: () => getDocCommentTemplateAtPosition,
|
|
188875
188977
|
getJSDocParameterNameCompletionDetails: () => getJSDocParameterNameCompletionDetails,
|
|
188876
188978
|
getJSDocParameterNameCompletions: () => getJSDocParameterNameCompletions,
|
|
@@ -189307,7 +189409,7 @@ ${newComment.split("\n").map((c) => ` * ${c}`).join("\n")}
|
|
|
189307
189409
|
}
|
|
189308
189410
|
}
|
|
189309
189411
|
var ts_MapCode_exports = {};
|
|
189310
|
-
|
|
189412
|
+
__export2(ts_MapCode_exports, {
|
|
189311
189413
|
mapCode: () => mapCode
|
|
189312
189414
|
});
|
|
189313
189415
|
function mapCode(sourceFile, contents, focusLocations, host, formatContext, preferences) {
|
|
@@ -189511,7 +189613,7 @@ ${content}
|
|
|
189511
189613
|
node.forEachChild(resetNodePositions);
|
|
189512
189614
|
}
|
|
189513
189615
|
var ts_OrganizeImports_exports = {};
|
|
189514
|
-
|
|
189616
|
+
__export2(ts_OrganizeImports_exports, {
|
|
189515
189617
|
compareImportsOrRequireStatements: () => compareImportsOrRequireStatements,
|
|
189516
189618
|
compareModuleSpecifiers: () => compareModuleSpecifiers2,
|
|
189517
189619
|
getImportDeclarationInsertionIndex: () => getImportDeclarationInsertionIndex,
|
|
@@ -190171,7 +190273,7 @@ ${content}
|
|
|
190171
190273
|
return compareModuleSpecifiersWorker(m1, m2, comparer);
|
|
190172
190274
|
}
|
|
190173
190275
|
var ts_OutliningElementsCollector_exports = {};
|
|
190174
|
-
|
|
190276
|
+
__export2(ts_OutliningElementsCollector_exports, {
|
|
190175
190277
|
collectElements: () => collectElements
|
|
190176
190278
|
});
|
|
190177
190279
|
function collectElements(sourceFile, cancellationToken) {
|
|
@@ -190590,7 +190692,7 @@ ${content}
|
|
|
190590
190692
|
return findChildOfKind(body, 19, sourceFile);
|
|
190591
190693
|
}
|
|
190592
190694
|
var ts_Rename_exports = {};
|
|
190593
|
-
|
|
190695
|
+
__export2(ts_Rename_exports, {
|
|
190594
190696
|
getRenameInfo: () => getRenameInfo,
|
|
190595
190697
|
nodeIsEligibleForRename: () => nodeIsEligibleForRename
|
|
190596
190698
|
});
|
|
@@ -190746,7 +190848,7 @@ ${content}
|
|
|
190746
190848
|
}
|
|
190747
190849
|
}
|
|
190748
190850
|
var ts_SignatureHelp_exports = {};
|
|
190749
|
-
|
|
190851
|
+
__export2(ts_SignatureHelp_exports, {
|
|
190750
190852
|
getArgumentInfoForCompletions: () => getArgumentInfoForCompletions,
|
|
190751
190853
|
getSignatureHelpItems: () => getSignatureHelpItems
|
|
190752
190854
|
});
|
|
@@ -191292,7 +191394,7 @@ ${content}
|
|
|
191292
191394
|
return { name: typeParameter.symbol.name, documentation: typeParameter.symbol.getDocumentationComment(checker), displayParts, isOptional: false, isRest: false };
|
|
191293
191395
|
}
|
|
191294
191396
|
var ts_SmartSelectionRange_exports = {};
|
|
191295
|
-
|
|
191397
|
+
__export2(ts_SmartSelectionRange_exports, {
|
|
191296
191398
|
getSmartSelectionRange: () => getSmartSelectionRange
|
|
191297
191399
|
});
|
|
191298
191400
|
function getSmartSelectionRange(pos, sourceFile) {
|
|
@@ -191523,7 +191625,7 @@ ${content}
|
|
|
191523
191625
|
}
|
|
191524
191626
|
}
|
|
191525
191627
|
var ts_SymbolDisplay_exports = {};
|
|
191526
|
-
|
|
191628
|
+
__export2(ts_SymbolDisplay_exports, {
|
|
191527
191629
|
getSymbolDisplayPartsDocumentationAndSymbolKind: () => getSymbolDisplayPartsDocumentationAndSymbolKind,
|
|
191528
191630
|
getSymbolKind: () => getSymbolKind,
|
|
191529
191631
|
getSymbolModifiers: () => getSymbolModifiers
|
|
@@ -192491,7 +192593,7 @@ ${content}
|
|
|
192491
192593
|
});
|
|
192492
192594
|
}
|
|
192493
192595
|
var ts_textChanges_exports = {};
|
|
192494
|
-
|
|
192596
|
+
__export2(ts_textChanges_exports, {
|
|
192495
192597
|
ChangeTracker: () => ChangeTracker,
|
|
192496
192598
|
LeadingTriviaOption: () => LeadingTriviaOption,
|
|
192497
192599
|
TrailingTriviaOption: () => TrailingTriviaOption,
|
|
@@ -193908,7 +194010,7 @@ ${options.prefix}` : "\n" : options.prefix
|
|
|
193908
194010
|
});
|
|
193909
194011
|
}
|
|
193910
194012
|
var ts_formatting_exports = {};
|
|
193911
|
-
|
|
194013
|
+
__export2(ts_formatting_exports, {
|
|
193912
194014
|
FormattingContext: () => FormattingContext,
|
|
193913
194015
|
FormattingRequestKind: () => FormattingRequestKind,
|
|
193914
194016
|
RuleAction: () => RuleAction,
|
|
@@ -197808,7 +197910,7 @@ ${options.prefix}` : "\n" : options.prefix
|
|
|
197808
197910
|
}
|
|
197809
197911
|
})(SmartIndenter || (SmartIndenter = {}));
|
|
197810
197912
|
var ts_preparePasteEdits_exports = {};
|
|
197811
|
-
|
|
197913
|
+
__export2(ts_preparePasteEdits_exports, {
|
|
197812
197914
|
preparePasteEdits: () => preparePasteEdits
|
|
197813
197915
|
});
|
|
197814
197916
|
function preparePasteEdits(sourceFile, copiedFromRange, checker) {
|
|
@@ -197846,7 +197948,7 @@ ${options.prefix}` : "\n" : options.prefix
|
|
|
197846
197948
|
return shouldProvidePasteEdits;
|
|
197847
197949
|
}
|
|
197848
197950
|
var ts_PasteEdits_exports = {};
|
|
197849
|
-
|
|
197951
|
+
__export2(ts_PasteEdits_exports, {
|
|
197850
197952
|
pasteEditsProvider: () => pasteEditsProvider
|
|
197851
197953
|
});
|
|
197852
197954
|
var fixId55 = "providePostPasteEdits";
|
|
@@ -197953,7 +198055,7 @@ ${options.prefix}` : "\n" : options.prefix
|
|
|
197953
198055
|
};
|
|
197954
198056
|
}
|
|
197955
198057
|
var ts_exports2 = {};
|
|
197956
|
-
|
|
198058
|
+
__export2(ts_exports2, {
|
|
197957
198059
|
ANONYMOUS: () => ANONYMOUS,
|
|
197958
198060
|
AccessFlags: () => AccessFlags,
|
|
197959
198061
|
AssertionLevel: () => AssertionLevel,
|
|
@@ -200304,7 +200406,7 @@ ${options.prefix}` : "\n" : options.prefix
|
|
|
200304
200406
|
};
|
|
200305
200407
|
}
|
|
200306
200408
|
var ts_server_exports3 = {};
|
|
200307
|
-
|
|
200409
|
+
__export2(ts_server_exports3, {
|
|
200308
200410
|
ActionInvalidate: () => ActionInvalidate,
|
|
200309
200411
|
ActionPackageInstalled: () => ActionPackageInstalled,
|
|
200310
200412
|
ActionSet: () => ActionSet,
|
|
@@ -200402,7 +200504,7 @@ ${options.prefix}` : "\n" : options.prefix
|
|
|
200402
200504
|
updateProjectIfDirty: () => updateProjectIfDirty
|
|
200403
200505
|
});
|
|
200404
200506
|
var ts_server_typingsInstaller_exports = {};
|
|
200405
|
-
|
|
200507
|
+
__export2(ts_server_typingsInstaller_exports, {
|
|
200406
200508
|
TypingsInstaller: () => TypingsInstaller,
|
|
200407
200509
|
getNpmCommandForInstallation: () => getNpmCommandForInstallation,
|
|
200408
200510
|
installNpmPackages: () => installNpmPackages,
|
|
@@ -200969,7 +201071,7 @@ ${options.prefix}` : "\n" : options.prefix
|
|
|
200969
201071
|
return base === "tsconfig.json" || base === "jsconfig.json" ? base : void 0;
|
|
200970
201072
|
}
|
|
200971
201073
|
var ts_server_protocol_exports = {};
|
|
200972
|
-
|
|
201074
|
+
__export2(ts_server_protocol_exports, {
|
|
200973
201075
|
ClassificationType: () => ClassificationType,
|
|
200974
201076
|
CommandTypes: () => CommandTypes,
|
|
200975
201077
|
CompletionTriggerKind: () => CompletionTriggerKind,
|
|
@@ -212884,8 +212986,8 @@ Additional information: BADCLIENT: Bad error code, ${badCode} not found in range
|
|
|
212884
212986
|
installPackage(options) {
|
|
212885
212987
|
this.packageInstallId++;
|
|
212886
212988
|
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:
|
|
212989
|
+
const promise = new Promise((resolve9, reject) => {
|
|
212990
|
+
(this.packageInstalledPromise ?? (this.packageInstalledPromise = /* @__PURE__ */ new Map())).set(this.packageInstallId, { resolve: resolve9, reject });
|
|
212889
212991
|
});
|
|
212890
212992
|
this.installer.send(request2);
|
|
212891
212993
|
return promise;
|
|
@@ -213043,7 +213145,7 @@ Additional information: BADCLIENT: Bad error code, ${badCode} not found in range
|
|
|
213043
213145
|
_TypingsInstallerAdapter.requestDelayMillis = 100;
|
|
213044
213146
|
var TypingsInstallerAdapter = _TypingsInstallerAdapter;
|
|
213045
213147
|
var ts_server_exports4 = {};
|
|
213046
|
-
|
|
213148
|
+
__export2(ts_server_exports4, {
|
|
213047
213149
|
ActionInvalidate: () => ActionInvalidate,
|
|
213048
213150
|
ActionPackageInstalled: () => ActionPackageInstalled,
|
|
213049
213151
|
ActionSet: () => ActionSet,
|
|
@@ -214245,11 +214347,16 @@ function getBaseUrl() {
|
|
|
214245
214347
|
}
|
|
214246
214348
|
function parseError(e) {
|
|
214247
214349
|
const msg = e.message;
|
|
214248
|
-
const jsonMatch = msg.match(/\{[
|
|
214350
|
+
const jsonMatch = msg.match(/\{[\s\S]*\}/);
|
|
214249
214351
|
if (jsonMatch) {
|
|
214250
214352
|
try {
|
|
214251
214353
|
const parsed = JSON.parse(jsonMatch[0]);
|
|
214252
|
-
|
|
214354
|
+
const parts = [];
|
|
214355
|
+
if (parsed.message) parts.push(parsed.message);
|
|
214356
|
+
if (parsed.request_id) parts.push(`request_id: ${parsed.request_id}`);
|
|
214357
|
+
if (parsed.retryable !== void 0) parts.push(`retryable: ${parsed.retryable ? "yes" : "no"}`);
|
|
214358
|
+
if (parsed.endpoint) parts.push(`endpoint: ${parsed.endpoint}`);
|
|
214359
|
+
if (parts.length > 0) return parts.join(" | ");
|
|
214253
214360
|
} catch {
|
|
214254
214361
|
}
|
|
214255
214362
|
}
|
|
@@ -214266,7 +214373,7 @@ function parseError(e) {
|
|
|
214266
214373
|
return msg;
|
|
214267
214374
|
}
|
|
214268
214375
|
function request(method, path, body) {
|
|
214269
|
-
return new Promise((
|
|
214376
|
+
return new Promise((resolve9, reject) => {
|
|
214270
214377
|
const baseUrl = getBaseUrl();
|
|
214271
214378
|
const fullUrl = `${baseUrl}${path}`;
|
|
214272
214379
|
const url = new URL(fullUrl);
|
|
@@ -214292,9 +214399,9 @@ function request(method, path, body) {
|
|
|
214292
214399
|
return;
|
|
214293
214400
|
}
|
|
214294
214401
|
try {
|
|
214295
|
-
|
|
214402
|
+
resolve9(JSON.parse(data));
|
|
214296
214403
|
} catch {
|
|
214297
|
-
|
|
214404
|
+
resolve9(data);
|
|
214298
214405
|
}
|
|
214299
214406
|
});
|
|
214300
214407
|
}
|
|
@@ -214321,70 +214428,8 @@ function formatError(e) {
|
|
|
214321
214428
|
return parseError(e);
|
|
214322
214429
|
}
|
|
214323
214430
|
|
|
214324
|
-
// src/git.ts
|
|
214325
|
-
var import_node_child_process = require("node:child_process");
|
|
214326
|
-
var import_node_fs2 = require("node:fs");
|
|
214327
|
-
var import_node_path2 = require("node:path");
|
|
214328
|
-
function getGitRemote() {
|
|
214329
|
-
try {
|
|
214330
|
-
const url = (0, import_node_child_process.execSync)("git config --get remote.origin.url", {
|
|
214331
|
-
encoding: "utf8",
|
|
214332
|
-
cwd: process.cwd()
|
|
214333
|
-
}).trim();
|
|
214334
|
-
const match = url.match(/[:/]([^/]+)\/([^/]+?)(?:\.git)?$/);
|
|
214335
|
-
if (match) {
|
|
214336
|
-
return { org: match[1], repo: match[2] };
|
|
214337
|
-
}
|
|
214338
|
-
return null;
|
|
214339
|
-
} catch {
|
|
214340
|
-
return null;
|
|
214341
|
-
}
|
|
214342
|
-
}
|
|
214343
|
-
function isGitRepo() {
|
|
214344
|
-
return (0, import_node_fs2.existsSync)((0, import_node_path2.resolve)(process.cwd(), ".git"));
|
|
214345
|
-
}
|
|
214346
|
-
function getUncommittedDiff() {
|
|
214347
|
-
try {
|
|
214348
|
-
return (0, import_node_child_process.execSync)("git diff", { encoding: "utf8", cwd: process.cwd() }).trim();
|
|
214349
|
-
} catch {
|
|
214350
|
-
return "";
|
|
214351
|
-
}
|
|
214352
|
-
}
|
|
214353
|
-
function getStagedDiff() {
|
|
214354
|
-
try {
|
|
214355
|
-
return (0, import_node_child_process.execSync)("git diff --staged", { encoding: "utf8", cwd: process.cwd() }).trim();
|
|
214356
|
-
} catch {
|
|
214357
|
-
return "";
|
|
214358
|
-
}
|
|
214359
|
-
}
|
|
214360
|
-
function getLastCommitHash() {
|
|
214361
|
-
try {
|
|
214362
|
-
return (0, import_node_child_process.execSync)("git rev-parse HEAD", { encoding: "utf8", cwd: process.cwd() }).trim();
|
|
214363
|
-
} catch {
|
|
214364
|
-
return "unknown";
|
|
214365
|
-
}
|
|
214366
|
-
}
|
|
214367
|
-
function getChangedFilesList() {
|
|
214368
|
-
try {
|
|
214369
|
-
const unstaged = (0, import_node_child_process.execSync)("git diff --name-only HEAD", { encoding: "utf8", cwd: process.cwd() }).trim();
|
|
214370
|
-
const staged = (0, import_node_child_process.execSync)("git diff --staged --name-only", { encoding: "utf8", cwd: process.cwd() }).trim();
|
|
214371
|
-
const files = /* @__PURE__ */ new Set();
|
|
214372
|
-
if (unstaged) unstaged.split("\n").forEach((f) => files.add(f));
|
|
214373
|
-
if (staged) staged.split("\n").forEach((f) => files.add(f));
|
|
214374
|
-
return [...files].filter(Boolean);
|
|
214375
|
-
} catch {
|
|
214376
|
-
return [];
|
|
214377
|
-
}
|
|
214378
|
-
}
|
|
214379
|
-
function getAuthorName() {
|
|
214380
|
-
try {
|
|
214381
|
-
return (0, import_node_child_process.execSync)("git config user.name", { encoding: "utf8", cwd: process.cwd() }).trim();
|
|
214382
|
-
} catch {
|
|
214383
|
-
return "unknown";
|
|
214384
|
-
}
|
|
214385
|
-
}
|
|
214386
|
-
|
|
214387
214431
|
// src/commands/init.ts
|
|
214432
|
+
init_git();
|
|
214388
214433
|
var import_scanner = __toESM(require_dist());
|
|
214389
214434
|
var import_node_fs3 = require("node:fs");
|
|
214390
214435
|
var import_node_path3 = require("node:path");
|
|
@@ -214858,6 +214903,10 @@ View: https://driftless.icu/ecosystem`);
|
|
|
214858
214903
|
}
|
|
214859
214904
|
|
|
214860
214905
|
// src/commands/scan.ts
|
|
214906
|
+
init_git();
|
|
214907
|
+
function emitJSON(data) {
|
|
214908
|
+
console.log(JSON.stringify(data, null, 2));
|
|
214909
|
+
}
|
|
214861
214910
|
async function scanCommand(args) {
|
|
214862
214911
|
if (!isGitRepo()) {
|
|
214863
214912
|
console.error("Error: not a git repository.");
|
|
@@ -214868,6 +214917,7 @@ async function scanCommand(args) {
|
|
|
214868
214917
|
console.error("Error: no git remote found.");
|
|
214869
214918
|
process.exit(1);
|
|
214870
214919
|
}
|
|
214920
|
+
const isJSON = args.includes("--json");
|
|
214871
214921
|
let workspace;
|
|
214872
214922
|
try {
|
|
214873
214923
|
workspace = await api.get("/me");
|
|
@@ -214896,7 +214946,8 @@ async function scanCommand(args) {
|
|
|
214896
214946
|
diff = getUncommittedDiff();
|
|
214897
214947
|
source = "uncommitted changes";
|
|
214898
214948
|
if (!diff) {
|
|
214899
|
-
|
|
214949
|
+
if (isJSON) emitJSON({ status: "clean", files: [], rules_evaluated: 0 });
|
|
214950
|
+
else console.log("No uncommitted changes. Clean.");
|
|
214900
214951
|
process.exit(0);
|
|
214901
214952
|
}
|
|
214902
214953
|
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);
|
|
@@ -214906,15 +214957,18 @@ async function scanCommand(args) {
|
|
|
214906
214957
|
diff = [staged, unstaged].filter(Boolean).join("\n");
|
|
214907
214958
|
source = staged && unstaged ? "staged + unstaged" : staged ? "staged" : "unstaged";
|
|
214908
214959
|
if (!diff) {
|
|
214909
|
-
|
|
214960
|
+
if (isJSON) emitJSON({ status: "clean", files: [], rules_evaluated: 0 });
|
|
214961
|
+
else console.log("No changes to scan. Clean.");
|
|
214910
214962
|
process.exit(0);
|
|
214911
214963
|
}
|
|
214912
214964
|
}
|
|
214913
214965
|
const commitHash = getLastCommitHash();
|
|
214914
214966
|
const author = getAuthorName();
|
|
214915
|
-
|
|
214916
|
-
|
|
214917
|
-
|
|
214967
|
+
if (!isJSON) {
|
|
214968
|
+
console.log(`Scanning ${source}...`);
|
|
214969
|
+
if (changedFiles.length > 0) {
|
|
214970
|
+
console.log(` Files: ${changedFiles.join(", ")}`);
|
|
214971
|
+
}
|
|
214918
214972
|
}
|
|
214919
214973
|
const result = await api.post("/scan", {
|
|
214920
214974
|
workspace_id: workspace.workspace_id,
|
|
@@ -214925,29 +214979,42 @@ async function scanCommand(args) {
|
|
|
214925
214979
|
});
|
|
214926
214980
|
const rulesEvaluated = result.rules_evaluated || 0;
|
|
214927
214981
|
if (result.status === "clean") {
|
|
214928
|
-
|
|
214982
|
+
if (isJSON) {
|
|
214983
|
+
emitJSON({ status: "clean", files: changedFiles, rules_evaluated: rulesEvaluated, violations: [] });
|
|
214984
|
+
} else {
|
|
214985
|
+
console.log(`Clean \u2014 ${rulesEvaluated} rule(s) evaluated, no violations.`);
|
|
214986
|
+
}
|
|
214929
214987
|
process.exit(0);
|
|
214930
214988
|
}
|
|
214931
214989
|
if (!result.violations || result.violations.length === 0) {
|
|
214932
|
-
|
|
214990
|
+
if (isJSON) {
|
|
214991
|
+
emitJSON({ status: "clean", files: changedFiles, rules_evaluated: rulesEvaluated, violations: [] });
|
|
214992
|
+
} else {
|
|
214993
|
+
console.log(`Clean \u2014 ${rulesEvaluated} rule(s) evaluated, no violations.`);
|
|
214994
|
+
}
|
|
214933
214995
|
process.exit(0);
|
|
214934
214996
|
}
|
|
214935
|
-
|
|
214997
|
+
if (isJSON) {
|
|
214998
|
+
emitJSON({ status: "violated", files: changedFiles, rules_evaluated: rulesEvaluated, violations: result.violations });
|
|
214999
|
+
} else {
|
|
215000
|
+
console.log(`
|
|
214936
215001
|
${result.violations.length} violation(s) found (${rulesEvaluated} rule(s) evaluated):
|
|
214937
215002
|
`);
|
|
214938
|
-
|
|
214939
|
-
|
|
214940
|
-
|
|
214941
|
-
|
|
214942
|
-
|
|
214943
|
-
|
|
214944
|
-
|
|
215003
|
+
for (const v of result.violations) {
|
|
215004
|
+
const severityColor = v.severity === "critical" || v.severity === "high" ? "\x1B[31m" : "\x1B[33m";
|
|
215005
|
+
console.log(` ${severityColor}[${v.severity.toUpperCase()}]\x1B[0m ${v.rule_name}`);
|
|
215006
|
+
console.log(` ${v.explanation}`);
|
|
215007
|
+
console.log(` File: ${v.file_path}:${v.line_number}`);
|
|
215008
|
+
console.log(` Code: ${v.diff_snippet}`);
|
|
215009
|
+
console.log();
|
|
215010
|
+
}
|
|
215011
|
+
console.log("Fix these violations before pushing.");
|
|
214945
215012
|
}
|
|
214946
|
-
console.log("Fix these violations before pushing.");
|
|
214947
215013
|
process.exit(1);
|
|
214948
215014
|
}
|
|
214949
215015
|
|
|
214950
215016
|
// src/commands/context.ts
|
|
215017
|
+
init_git();
|
|
214951
215018
|
var import_node_fs4 = require("node:fs");
|
|
214952
215019
|
var import_node_path4 = require("node:path");
|
|
214953
215020
|
function parseArgs(args) {
|
|
@@ -214969,16 +215036,27 @@ function parseArgs(args) {
|
|
|
214969
215036
|
}
|
|
214970
215037
|
return { flags, positional };
|
|
214971
215038
|
}
|
|
214972
|
-
function
|
|
215039
|
+
function emitJSON2(data) {
|
|
214973
215040
|
console.log(JSON.stringify(data, null, 2));
|
|
214974
215041
|
}
|
|
214975
215042
|
function pad(s, n) {
|
|
214976
215043
|
if (s.length >= n) return s;
|
|
214977
215044
|
return s + " ".repeat(n - s.length);
|
|
214978
215045
|
}
|
|
215046
|
+
function formatBadges(badges) {
|
|
215047
|
+
const display = [];
|
|
215048
|
+
for (const b of badges) {
|
|
215049
|
+
if (b === "manual" || b === "fresh") continue;
|
|
215050
|
+
display.push(`[${b}]`);
|
|
215051
|
+
}
|
|
215052
|
+
return display.join(" ");
|
|
215053
|
+
}
|
|
214979
215054
|
function renderSummaryHuman(items) {
|
|
214980
215055
|
if (items.length === 0) {
|
|
214981
|
-
console.log("No context topics
|
|
215056
|
+
console.log("No context topics yet.");
|
|
215057
|
+
console.log("\nNext:");
|
|
215058
|
+
console.log(' driftless context add "auth-boundaries" --what "..." --how "..." --pattern "src/auth/**"');
|
|
215059
|
+
console.log(" driftless init # auto-generate topics from your codebase");
|
|
214982
215060
|
return;
|
|
214983
215061
|
}
|
|
214984
215062
|
const topicWidth = Math.max(...items.map((i) => i.topic.length), 12) + 2;
|
|
@@ -214991,14 +215069,6 @@ function renderSummaryHuman(items) {
|
|
|
214991
215069
|
console.log(`
|
|
214992
215070
|
${items.length} topic${items.length === 1 ? "" : "s"}.`);
|
|
214993
215071
|
}
|
|
214994
|
-
function formatBadges(badges) {
|
|
214995
|
-
const display = [];
|
|
214996
|
-
for (const b of badges) {
|
|
214997
|
-
if (b === "manual" || b === "fresh") continue;
|
|
214998
|
-
display.push(`[${b}]`);
|
|
214999
|
-
}
|
|
215000
|
-
return display.join(" ");
|
|
215001
|
-
}
|
|
215002
215072
|
function renderContextHuman(ctx) {
|
|
215003
215073
|
console.log(`\u258C ${ctx.topic}`);
|
|
215004
215074
|
console.log(` ${ctx.summary}`);
|
|
@@ -215028,9 +215098,7 @@ function renderContextHuman(ctx) {
|
|
|
215028
215098
|
console.log(`
|
|
215029
215099
|
docs (${ctx.anchors.docs.length})`);
|
|
215030
215100
|
for (const d of ctx.anchors.docs) {
|
|
215031
|
-
|
|
215032
|
-
console.log(` ${d.path || "(anchored)"}
|
|
215033
|
-
${preview}${d.content.split("\n").length > 3 ? "\n ..." : ""}`);
|
|
215101
|
+
console.log(` ${d.path || "(anchored)"}`);
|
|
215034
215102
|
}
|
|
215035
215103
|
}
|
|
215036
215104
|
if (ctx.components.length > 0) {
|
|
@@ -215084,7 +215152,7 @@ function renderMatchFilesHuman(results, files) {
|
|
|
215084
215152
|
console.log(`No matching context for ${files.length} changed file${files.length === 1 ? "" : "s"}.`);
|
|
215085
215153
|
return;
|
|
215086
215154
|
}
|
|
215087
|
-
console.log(
|
|
215155
|
+
console.log(`Matched ${results.length} topic${results.length === 1 ? "" : "s"} for ${files.length} file${files.length === 1 ? "" : "s"}:
|
|
215088
215156
|
`);
|
|
215089
215157
|
for (const r of results) {
|
|
215090
215158
|
const ctx = r.context;
|
|
@@ -215100,6 +215168,15 @@ function renderMatchFilesHuman(results, files) {
|
|
|
215100
215168
|
console.log("");
|
|
215101
215169
|
}
|
|
215102
215170
|
}
|
|
215171
|
+
function countLocalFilesMatching(pattern) {
|
|
215172
|
+
try {
|
|
215173
|
+
const { globSync } = require("node:fs");
|
|
215174
|
+
const matches = globSync(pattern, { cwd: process.cwd() });
|
|
215175
|
+
return matches.length;
|
|
215176
|
+
} catch {
|
|
215177
|
+
return 0;
|
|
215178
|
+
}
|
|
215179
|
+
}
|
|
215103
215180
|
async function resolveWorkspaceSlug() {
|
|
215104
215181
|
try {
|
|
215105
215182
|
const me = await api.get("/me");
|
|
@@ -215121,7 +215198,7 @@ async function contextCommand(args) {
|
|
|
215121
215198
|
const workspaceSlug = await resolveWorkspaceSlug();
|
|
215122
215199
|
const { flags, positional } = parseArgs(args);
|
|
215123
215200
|
const subCommand = positional[0];
|
|
215124
|
-
const
|
|
215201
|
+
const isJSON = !!flags["json"];
|
|
215125
215202
|
if (subCommand === "list") {
|
|
215126
215203
|
const query = [];
|
|
215127
215204
|
if (flags["stale"]) query.push("stale=true");
|
|
@@ -215132,13 +215209,16 @@ async function contextCommand(args) {
|
|
|
215132
215209
|
const qs = query.length > 0 ? `?${query.join("&")}` : "";
|
|
215133
215210
|
try {
|
|
215134
215211
|
const summaries = await api.get(`/workspaces/${workspaceSlug}/watchers${qs}`);
|
|
215135
|
-
if (summaries.length === 0) {
|
|
215136
|
-
console.
|
|
215137
|
-
|
|
215138
|
-
|
|
215139
|
-
|
|
215212
|
+
if (summaries.length === 0 && !isJSON) {
|
|
215213
|
+
console.log("No context topics yet.");
|
|
215214
|
+
console.log("\nNext:");
|
|
215215
|
+
console.log(' driftless context add "auth-boundaries" --what "..." --how "..." --pattern "src/auth/**"');
|
|
215216
|
+
console.log(" driftless init # auto-generate topics from your codebase");
|
|
215217
|
+
}
|
|
215218
|
+
if (isJSON) {
|
|
215219
|
+
emitJSON2(summaries);
|
|
215140
215220
|
} else {
|
|
215141
|
-
|
|
215221
|
+
renderSummaryHuman(summaries);
|
|
215142
215222
|
}
|
|
215143
215223
|
} catch (e) {
|
|
215144
215224
|
console.error(`List failed: ${formatError(e)}`);
|
|
@@ -215162,25 +215242,29 @@ async function contextCommand(args) {
|
|
|
215162
215242
|
files = getChangedFilesList();
|
|
215163
215243
|
}
|
|
215164
215244
|
if (files.length === 0) {
|
|
215165
|
-
if (
|
|
215245
|
+
if (!isJSON) {
|
|
215166
215246
|
console.log("No local changes detected.");
|
|
215167
215247
|
} else {
|
|
215168
|
-
|
|
215248
|
+
emitJSON2([]);
|
|
215169
215249
|
}
|
|
215170
215250
|
process.exit(0);
|
|
215171
215251
|
}
|
|
215252
|
+
const missingFiles = files.filter((f) => !(0, import_node_fs4.existsSync)((0, import_node_path4.resolve)(process.cwd(), f)));
|
|
215253
|
+
if (missingFiles.length > 0 && !isJSON) {
|
|
215254
|
+
console.error(`File(s) not found locally: ${missingFiles.join(", ")}. Matching by pattern only.`);
|
|
215255
|
+
}
|
|
215172
215256
|
try {
|
|
215173
215257
|
const results = await api.post(
|
|
215174
215258
|
`/workspaces/${workspaceSlug}/watchers/match-files`,
|
|
215175
215259
|
{ files }
|
|
215176
215260
|
);
|
|
215177
|
-
if (results.length === 0) {
|
|
215178
|
-
console.
|
|
215261
|
+
if (results.length === 0 && !isJSON) {
|
|
215262
|
+
console.log(`No context topics match these files.`);
|
|
215179
215263
|
}
|
|
215180
|
-
if (
|
|
215181
|
-
|
|
215264
|
+
if (isJSON) {
|
|
215265
|
+
emitJSON2(results);
|
|
215182
215266
|
} else {
|
|
215183
|
-
|
|
215267
|
+
renderMatchFilesHuman(results, files);
|
|
215184
215268
|
}
|
|
215185
215269
|
} catch (e) {
|
|
215186
215270
|
console.error(`Match failed: ${formatError(e)}`);
|
|
@@ -215189,21 +215273,21 @@ async function contextCommand(args) {
|
|
|
215189
215273
|
return;
|
|
215190
215274
|
}
|
|
215191
215275
|
if (!slug) {
|
|
215192
|
-
console.error("Usage: driftless context get <topic>
|
|
215193
|
-
console.error(' driftless context get --files "path1,path2"
|
|
215194
|
-
console.error(" driftless context get --diff
|
|
215276
|
+
console.error("Usage: driftless context get <topic>");
|
|
215277
|
+
console.error(' driftless context get --files "path1,path2"');
|
|
215278
|
+
console.error(" driftless context get --diff");
|
|
215195
215279
|
process.exit(1);
|
|
215196
215280
|
}
|
|
215197
215281
|
try {
|
|
215198
215282
|
const ctx = await api.get(`/workspaces/${workspaceSlug}/watchers/${slug}`);
|
|
215199
|
-
if (
|
|
215200
|
-
renderContextHuman(ctx);
|
|
215201
|
-
} else {
|
|
215283
|
+
if (isJSON) {
|
|
215202
215284
|
const sanitized = JSON.parse(JSON.stringify(ctx, (_key, value) => {
|
|
215203
215285
|
if (typeof value === "string" && value.length > 500) return value.slice(0, 500) + "\u2026";
|
|
215204
215286
|
return value;
|
|
215205
215287
|
}));
|
|
215206
|
-
|
|
215288
|
+
emitJSON2(sanitized);
|
|
215289
|
+
} else {
|
|
215290
|
+
renderContextHuman(ctx);
|
|
215207
215291
|
}
|
|
215208
215292
|
} catch (e) {
|
|
215209
215293
|
console.error(`Topic '${slug}' not found.`);
|
|
@@ -215214,20 +215298,20 @@ async function contextCommand(args) {
|
|
|
215214
215298
|
if (subCommand === "search") {
|
|
215215
215299
|
const query = positional.slice(1).join(" ");
|
|
215216
215300
|
if (!query) {
|
|
215217
|
-
console.error('Usage: driftless context search "<query>"
|
|
215301
|
+
console.error('Usage: driftless context search "<query>"');
|
|
215218
215302
|
process.exit(1);
|
|
215219
215303
|
}
|
|
215220
215304
|
try {
|
|
215221
215305
|
const results = await api.get(
|
|
215222
215306
|
`/workspaces/${workspaceSlug}/watchers/search?q=${encodeURIComponent(query)}`
|
|
215223
215307
|
);
|
|
215224
|
-
if (results.length === 0) {
|
|
215225
|
-
console.
|
|
215308
|
+
if (results.length === 0 && !isJSON) {
|
|
215309
|
+
console.log(`No context topics matching "${query}".`);
|
|
215226
215310
|
}
|
|
215227
|
-
if (
|
|
215228
|
-
|
|
215311
|
+
if (isJSON) {
|
|
215312
|
+
emitJSON2(results);
|
|
215229
215313
|
} else {
|
|
215230
|
-
|
|
215314
|
+
renderSummaryHuman(results);
|
|
215231
215315
|
}
|
|
215232
215316
|
} catch (e) {
|
|
215233
215317
|
console.error(`Search failed: ${formatError(e)}`);
|
|
@@ -215244,32 +215328,41 @@ async function contextCommand(args) {
|
|
|
215244
215328
|
let fileContent;
|
|
215245
215329
|
if (flags["file"]) {
|
|
215246
215330
|
try {
|
|
215247
|
-
|
|
215248
|
-
fileContent = fs.readFileSync(flags["file"], "utf-8");
|
|
215331
|
+
fileContent = (0, import_node_fs4.readFileSync)(flags["file"], "utf-8");
|
|
215249
215332
|
} catch {
|
|
215250
215333
|
console.error(`File not found: ${flags["file"]}`);
|
|
215251
215334
|
process.exit(1);
|
|
215252
215335
|
}
|
|
215253
215336
|
}
|
|
215337
|
+
const pattern = flags["pattern"];
|
|
215338
|
+
if (pattern && !isJSON) {
|
|
215339
|
+
const localCount = countLocalFilesMatching(pattern);
|
|
215340
|
+
if (localCount === 0) {
|
|
215341
|
+
console.error(`Warning: pattern "${pattern}" matches 0 files locally. Topic created anyway.`);
|
|
215342
|
+
}
|
|
215343
|
+
}
|
|
215254
215344
|
try {
|
|
215255
215345
|
const result = await api.post(`/workspaces/${workspaceSlug}/watchers`, {
|
|
215256
215346
|
name,
|
|
215257
215347
|
what: flags["what"],
|
|
215258
215348
|
how: flags["how"],
|
|
215259
215349
|
where_files: flags["where"] ? [flags["where"]] : void 0,
|
|
215260
|
-
pattern
|
|
215350
|
+
pattern,
|
|
215261
215351
|
decisions: flags["decisions"],
|
|
215262
215352
|
gotchas: flags["gotchas"],
|
|
215263
215353
|
ownership: flags["ownership"],
|
|
215264
215354
|
file_content: fileContent
|
|
215265
215355
|
});
|
|
215266
|
-
if (
|
|
215267
|
-
|
|
215356
|
+
if (isJSON) {
|
|
215357
|
+
emitJSON2(result);
|
|
215268
215358
|
} else {
|
|
215269
|
-
|
|
215359
|
+
console.log(`Topic '${name}' created.`);
|
|
215360
|
+
if (pattern) console.log(` pattern: ${pattern}`);
|
|
215361
|
+
if (flags["what"]) console.log(` what: ${flags["what"]}`);
|
|
215362
|
+
if (flags["how"]) console.log(` how: ${flags["how"]}`);
|
|
215270
215363
|
}
|
|
215271
215364
|
} catch (e) {
|
|
215272
|
-
console.error(`Failed to create topic: ${e
|
|
215365
|
+
console.error(`Failed to create topic: ${formatError(e)}`);
|
|
215273
215366
|
process.exit(1);
|
|
215274
215367
|
}
|
|
215275
215368
|
return;
|
|
@@ -215289,17 +215382,11 @@ async function contextCommand(args) {
|
|
|
215289
215382
|
if (flags["gotchas"]) updates.gotchas = flags["gotchas"];
|
|
215290
215383
|
if (flags["ownership"]) updates.ownership = flags["ownership"];
|
|
215291
215384
|
const gotchaFlag = flags["gotcha"] || flags["gotchas_append"];
|
|
215292
|
-
if (gotchaFlag)
|
|
215293
|
-
updates._append_gotchas = gotchaFlag;
|
|
215294
|
-
}
|
|
215385
|
+
if (gotchaFlag) updates._append_gotchas = gotchaFlag;
|
|
215295
215386
|
const invariantFlag = flags["invariant"];
|
|
215296
|
-
if (invariantFlag)
|
|
215297
|
-
updates._append_invariants = invariantFlag;
|
|
215298
|
-
}
|
|
215387
|
+
if (invariantFlag) updates._append_invariants = invariantFlag;
|
|
215299
215388
|
const checkFlag = flags["check"];
|
|
215300
|
-
if (checkFlag)
|
|
215301
|
-
updates._append_required_checks = checkFlag;
|
|
215302
|
-
}
|
|
215389
|
+
if (checkFlag) updates._append_required_checks = checkFlag;
|
|
215303
215390
|
const enforceFlag = flags["enforce"];
|
|
215304
215391
|
if (enforceFlag && typeof enforceFlag === "string") {
|
|
215305
215392
|
updates._enforce_rule = enforceFlag;
|
|
@@ -215319,12 +215406,28 @@ async function contextCommand(args) {
|
|
|
215319
215406
|
console.error('PR 3: --gotcha, --invariant, --check, --enforce "<rule-description>"');
|
|
215320
215407
|
process.exit(1);
|
|
215321
215408
|
}
|
|
215409
|
+
if (flags["dry-run"]) {
|
|
215410
|
+
console.log(`Would update topic '${slug}':`);
|
|
215411
|
+
for (const [key, value] of Object.entries(updates)) {
|
|
215412
|
+
if (key.startsWith("_")) continue;
|
|
215413
|
+
console.log(` ${key}: ${value}`);
|
|
215414
|
+
}
|
|
215415
|
+
if (!isJSON) {
|
|
215416
|
+
console.log("\n(Dry run \u2014 no changes written to Driftless Cloud)");
|
|
215417
|
+
}
|
|
215418
|
+
if (isJSON) {
|
|
215419
|
+
emitJSON2({ dry_run: true, topic: slug, updates });
|
|
215420
|
+
}
|
|
215421
|
+
process.exit(0);
|
|
215422
|
+
}
|
|
215322
215423
|
try {
|
|
215323
215424
|
const result = await api.patch(
|
|
215324
215425
|
`/workspaces/${workspaceSlug}/watchers/${slug}`,
|
|
215325
215426
|
updates
|
|
215326
215427
|
);
|
|
215327
|
-
if (
|
|
215428
|
+
if (isJSON) {
|
|
215429
|
+
emitJSON2(result);
|
|
215430
|
+
} else {
|
|
215328
215431
|
renderContextHuman(result);
|
|
215329
215432
|
if (result.enforcement) {
|
|
215330
215433
|
if (result.enforcement.created) {
|
|
@@ -215336,11 +215439,9 @@ async function contextCommand(args) {
|
|
|
215336
215439
|
\u26A0 enforce: ${result.enforcement.reason}`);
|
|
215337
215440
|
}
|
|
215338
215441
|
}
|
|
215339
|
-
} else {
|
|
215340
|
-
emitJSON(result);
|
|
215341
215442
|
}
|
|
215342
215443
|
} catch (e) {
|
|
215343
|
-
console.error(`Failed to update topic: ${e
|
|
215444
|
+
console.error(`Failed to update topic: ${formatError(e)}`);
|
|
215344
215445
|
process.exit(1);
|
|
215345
215446
|
}
|
|
215346
215447
|
return;
|
|
@@ -215351,12 +215452,25 @@ async function contextCommand(args) {
|
|
|
215351
215452
|
console.error("Usage: driftless context delete <topic>");
|
|
215352
215453
|
process.exit(1);
|
|
215353
215454
|
}
|
|
215455
|
+
if (flags["dry-run"]) {
|
|
215456
|
+
console.log(`Would delete topic '${slug}'.`);
|
|
215457
|
+
if (!isJSON) {
|
|
215458
|
+
console.log("(Dry run \u2014 no changes written to Driftless Cloud)");
|
|
215459
|
+
}
|
|
215460
|
+
if (isJSON) {
|
|
215461
|
+
emitJSON2({ dry_run: true, action: "delete", topic: slug });
|
|
215462
|
+
}
|
|
215463
|
+
process.exit(0);
|
|
215464
|
+
}
|
|
215354
215465
|
try {
|
|
215355
215466
|
await api.delete(`/workspaces/${workspaceSlug}/watchers/${slug}`);
|
|
215356
|
-
if (
|
|
215357
|
-
|
|
215467
|
+
if (isJSON) {
|
|
215468
|
+
emitJSON2({ status: "deleted", topic: slug });
|
|
215469
|
+
} else {
|
|
215470
|
+
console.log(`Topic '${slug}' deleted.`);
|
|
215471
|
+
}
|
|
215358
215472
|
} catch (e) {
|
|
215359
|
-
console.error(`Failed to delete topic: ${e
|
|
215473
|
+
console.error(`Failed to delete topic: ${formatError(e)}`);
|
|
215360
215474
|
process.exit(1);
|
|
215361
215475
|
}
|
|
215362
215476
|
return;
|
|
@@ -215379,8 +215493,7 @@ async function contextCommand(args) {
|
|
|
215379
215493
|
let fileContent;
|
|
215380
215494
|
if (docFlag) {
|
|
215381
215495
|
try {
|
|
215382
|
-
|
|
215383
|
-
fileContent = fs.readFileSync(docFlag, "utf-8");
|
|
215496
|
+
fileContent = (0, import_node_fs4.readFileSync)(docFlag, "utf-8");
|
|
215384
215497
|
} catch {
|
|
215385
215498
|
console.error(`File not found: ${docFlag}`);
|
|
215386
215499
|
process.exit(1);
|
|
@@ -215392,23 +215505,37 @@ async function contextCommand(args) {
|
|
|
215392
215505
|
if (filesFlag) updates.where_files = filesFlag.split(",").map((f) => f.trim()).filter(Boolean);
|
|
215393
215506
|
if (patternFlag) updates.pattern = patternFlag;
|
|
215394
215507
|
updates._event_detail = `ANCHOR_ADDED: doc=${!!fileContent}, note=${!!noteFlag}, files=${filesFlag || "none"}`;
|
|
215508
|
+
if (flags["dry-run"]) {
|
|
215509
|
+
console.log(`Would anchor topic '${slug}':`);
|
|
215510
|
+
if (docFlag) console.log(` doc: ${docFlag} (${fileContent ? fileContent.length : 0} chars)`);
|
|
215511
|
+
if (noteFlag) console.log(` note: ${noteFlag}`);
|
|
215512
|
+
if (filesFlag) console.log(` files: ${filesFlag}`);
|
|
215513
|
+
if (patternFlag) console.log(` pattern: ${patternFlag}`);
|
|
215514
|
+
if (!isJSON) {
|
|
215515
|
+
console.log("\n(Dry run \u2014 no changes written to Driftless Cloud)");
|
|
215516
|
+
}
|
|
215517
|
+
if (isJSON) {
|
|
215518
|
+
emitJSON2({ dry_run: true, action: "anchor", topic: slug, doc: docFlag, note: noteFlag, files: filesFlag, pattern: patternFlag });
|
|
215519
|
+
}
|
|
215520
|
+
process.exit(0);
|
|
215521
|
+
}
|
|
215395
215522
|
try {
|
|
215396
215523
|
const result = await api.patch(
|
|
215397
215524
|
`/workspaces/${workspaceSlug}/watchers/${slug}`,
|
|
215398
215525
|
updates
|
|
215399
215526
|
);
|
|
215400
|
-
if (
|
|
215401
|
-
console.log(`Topic '${slug}' anchored.`);
|
|
215402
|
-
if (fileContent) console.log(` doc: ${docFlag} (${fileContent.length} chars)`);
|
|
215403
|
-
if (noteFlag) console.log(` note: ${noteFlag}`);
|
|
215404
|
-
if (filesFlag) console.log(` files: ${filesFlag}`);
|
|
215405
|
-
if (patternFlag) console.log(` pattern: ${patternFlag}`);
|
|
215406
|
-
} else {
|
|
215527
|
+
if (isJSON) {
|
|
215407
215528
|
const sanitized = JSON.parse(JSON.stringify(result, (_key, value) => {
|
|
215408
215529
|
if (typeof value === "string" && value.length > 500) return value.slice(0, 500) + "\u2026";
|
|
215409
215530
|
return value;
|
|
215410
215531
|
}));
|
|
215411
|
-
|
|
215532
|
+
emitJSON2(sanitized);
|
|
215533
|
+
} else {
|
|
215534
|
+
console.log(`Topic '${slug}' anchored.`);
|
|
215535
|
+
if (docFlag) console.log(` doc: ${docFlag} (${fileContent ? fileContent.length : 0} chars)`);
|
|
215536
|
+
if (noteFlag) console.log(` note: ${noteFlag}`);
|
|
215537
|
+
if (filesFlag) console.log(` files: ${filesFlag}`);
|
|
215538
|
+
if (patternFlag) console.log(` pattern: ${patternFlag}`);
|
|
215412
215539
|
}
|
|
215413
215540
|
} catch (e) {
|
|
215414
215541
|
console.error(`Anchor failed: ${formatError(e)}`);
|
|
@@ -215428,21 +215555,59 @@ async function contextCommand(args) {
|
|
|
215428
215555
|
process.exit(1);
|
|
215429
215556
|
}
|
|
215430
215557
|
const missingFiles = files.filter((f) => !(0, import_node_fs4.existsSync)((0, import_node_path4.resolve)(process.cwd(), f)));
|
|
215431
|
-
if (missingFiles.length > 0) {
|
|
215558
|
+
if (missingFiles.length > 0 && !isJSON) {
|
|
215432
215559
|
console.error(`File(s) not found locally: ${missingFiles.join(", ")}. Matching by pattern only.`);
|
|
215433
215560
|
}
|
|
215561
|
+
if (flags["dry-run"]) {
|
|
215562
|
+
try {
|
|
215563
|
+
const results = await api.post(
|
|
215564
|
+
`/workspaces/${workspaceSlug}/watchers/match-files`,
|
|
215565
|
+
{ files }
|
|
215566
|
+
);
|
|
215567
|
+
console.log(`Would match ${results.length} topic${results.length === 1 ? "" : "s"}:`);
|
|
215568
|
+
for (const r of results) {
|
|
215569
|
+
console.log(` ${r.context.topic} via ${r.match_reason}`);
|
|
215570
|
+
}
|
|
215571
|
+
if (missingFiles.length > 0) {
|
|
215572
|
+
console.log(`
|
|
215573
|
+
Warnings:`);
|
|
215574
|
+
for (const f of missingFiles) {
|
|
215575
|
+
console.log(` ${f} does not exist locally \u2014 matched by pattern only`);
|
|
215576
|
+
}
|
|
215577
|
+
}
|
|
215578
|
+
if (!isJSON) {
|
|
215579
|
+
console.log("\n(Dry run \u2014 no context delivered)");
|
|
215580
|
+
}
|
|
215581
|
+
if (isJSON) {
|
|
215582
|
+
emitJSON2({ dry_run: true, matched: results.map((r) => ({ topic: r.context.topic, reason: r.match_reason })), missing_files: missingFiles });
|
|
215583
|
+
}
|
|
215584
|
+
} catch (e) {
|
|
215585
|
+
console.error(`Dry run failed: ${formatError(e)}`);
|
|
215586
|
+
process.exit(1);
|
|
215587
|
+
}
|
|
215588
|
+
process.exit(0);
|
|
215589
|
+
}
|
|
215434
215590
|
try {
|
|
215435
215591
|
const results = await api.post(
|
|
215436
215592
|
`/workspaces/${workspaceSlug}/watchers/match-files`,
|
|
215437
215593
|
{ files }
|
|
215438
215594
|
);
|
|
215439
|
-
if (results.length === 0) {
|
|
215440
|
-
console.
|
|
215595
|
+
if (results.length === 0 && !isJSON) {
|
|
215596
|
+
console.log(`No context topics match these files.`);
|
|
215441
215597
|
}
|
|
215442
|
-
if (
|
|
215443
|
-
|
|
215598
|
+
if (isJSON) {
|
|
215599
|
+
emitJSON2(results);
|
|
215444
215600
|
} else {
|
|
215445
|
-
|
|
215601
|
+
if (results.length > 0) {
|
|
215602
|
+
console.log(`Matched ${results.length} topic${results.length === 1 ? "" : "s"}:`);
|
|
215603
|
+
for (const r of results) {
|
|
215604
|
+
console.log(` ${r.context.topic} via ${r.match_reason}`);
|
|
215605
|
+
}
|
|
215606
|
+
console.log(`
|
|
215607
|
+
Context delivered for ${files.length} file${files.length === 1 ? "" : "s"}.`);
|
|
215608
|
+
} else {
|
|
215609
|
+
console.log(`No context topics match these files. No watcher covers the changed paths.`);
|
|
215610
|
+
}
|
|
215446
215611
|
}
|
|
215447
215612
|
} catch (e) {
|
|
215448
215613
|
console.error(`Push failed: ${formatError(e)}`);
|
|
@@ -215455,9 +215620,284 @@ async function contextCommand(args) {
|
|
|
215455
215620
|
Run 'driftless help context' for full reference.`);
|
|
215456
215621
|
}
|
|
215457
215622
|
|
|
215458
|
-
// src/commands/
|
|
215623
|
+
// src/commands/session.ts
|
|
215624
|
+
init_git();
|
|
215459
215625
|
var import_node_fs5 = require("node:fs");
|
|
215460
215626
|
var import_node_path5 = require("node:path");
|
|
215627
|
+
function parseArgs2(args) {
|
|
215628
|
+
const flags = {};
|
|
215629
|
+
const positional = [];
|
|
215630
|
+
for (let i = 0; i < args.length; i++) {
|
|
215631
|
+
if (args[i].startsWith("--")) {
|
|
215632
|
+
const key = args[i].slice(2);
|
|
215633
|
+
const next = args[i + 1];
|
|
215634
|
+
if (next && !next.startsWith("--")) {
|
|
215635
|
+
flags[key] = next;
|
|
215636
|
+
i++;
|
|
215637
|
+
} else {
|
|
215638
|
+
flags[key] = true;
|
|
215639
|
+
}
|
|
215640
|
+
} else {
|
|
215641
|
+
positional.push(args[i]);
|
|
215642
|
+
}
|
|
215643
|
+
}
|
|
215644
|
+
return { flags, positional };
|
|
215645
|
+
}
|
|
215646
|
+
function emitJSON3(data) {
|
|
215647
|
+
console.log(JSON.stringify(data, null, 2));
|
|
215648
|
+
}
|
|
215649
|
+
async function resolveWorkspaceSlug2() {
|
|
215650
|
+
try {
|
|
215651
|
+
const me = await api.get("/me");
|
|
215652
|
+
if (me?.slug) return me.slug;
|
|
215653
|
+
} catch {
|
|
215654
|
+
}
|
|
215655
|
+
const remote = getGitRemote();
|
|
215656
|
+
if (!remote) {
|
|
215657
|
+
console.error("Error: no git remote found.");
|
|
215658
|
+
process.exit(1);
|
|
215659
|
+
}
|
|
215660
|
+
return remote.org;
|
|
215661
|
+
}
|
|
215662
|
+
async function sessionCommand(args) {
|
|
215663
|
+
if (!isGitRepo()) {
|
|
215664
|
+
console.error("Error: not a git repository.");
|
|
215665
|
+
process.exit(1);
|
|
215666
|
+
}
|
|
215667
|
+
const workspaceSlug = await resolveWorkspaceSlug2();
|
|
215668
|
+
const { flags, positional } = parseArgs2(args);
|
|
215669
|
+
const subCommand = positional[0];
|
|
215670
|
+
const isJSON = !!flags["json"];
|
|
215671
|
+
if (subCommand === "start") {
|
|
215672
|
+
const filesFlag = flags["files"];
|
|
215673
|
+
let files = [];
|
|
215674
|
+
if (filesFlag) {
|
|
215675
|
+
files = filesFlag.split(",").map((f) => f.trim()).filter(Boolean);
|
|
215676
|
+
} else {
|
|
215677
|
+
files = getChangedFilesList();
|
|
215678
|
+
}
|
|
215679
|
+
if (files.length === 0) {
|
|
215680
|
+
if (!isJSON) {
|
|
215681
|
+
console.log("No files specified and no local changes detected.");
|
|
215682
|
+
console.log('Usage: driftless session start --files "src/auth/**"');
|
|
215683
|
+
} else {
|
|
215684
|
+
emitJSON3({ files: [], topics: [], docs: [], rules: [], gotchas: [] });
|
|
215685
|
+
}
|
|
215686
|
+
process.exit(0);
|
|
215687
|
+
}
|
|
215688
|
+
const missingFiles = files.filter((f) => !(0, import_node_fs5.existsSync)((0, import_node_path5.resolve)(process.cwd(), f)));
|
|
215689
|
+
if (missingFiles.length > 0 && !isJSON) {
|
|
215690
|
+
console.error(`Warning: ${missingFiles.length} file(s) not found locally \u2014 matching by pattern only.`);
|
|
215691
|
+
}
|
|
215692
|
+
try {
|
|
215693
|
+
const results = await api.post(
|
|
215694
|
+
`/workspaces/${workspaceSlug}/watchers/match-files`,
|
|
215695
|
+
{ files }
|
|
215696
|
+
);
|
|
215697
|
+
const topics = [];
|
|
215698
|
+
const docs = [];
|
|
215699
|
+
const rules = [];
|
|
215700
|
+
const gotchas = [];
|
|
215701
|
+
const allWhat = [];
|
|
215702
|
+
const allHow = [];
|
|
215703
|
+
for (const r of results) {
|
|
215704
|
+
const ctx = r.context;
|
|
215705
|
+
topics.push(ctx.topic);
|
|
215706
|
+
if (ctx.description.what) allWhat.push(ctx.description.what);
|
|
215707
|
+
if (ctx.description.how) allHow.push(ctx.description.how);
|
|
215708
|
+
if (ctx.description.gotchas) gotchas.push(...ctx.description.gotchas);
|
|
215709
|
+
if (ctx.anchors.docs) {
|
|
215710
|
+
for (const d of ctx.anchors.docs) {
|
|
215711
|
+
if (d.path) docs.push(d.path);
|
|
215712
|
+
}
|
|
215713
|
+
}
|
|
215714
|
+
if (ctx.rules) {
|
|
215715
|
+
for (const rule of ctx.rules) {
|
|
215716
|
+
rules.push(rule.name);
|
|
215717
|
+
}
|
|
215718
|
+
}
|
|
215719
|
+
}
|
|
215720
|
+
if (isJSON) {
|
|
215721
|
+
emitJSON3({
|
|
215722
|
+
files,
|
|
215723
|
+
missing_files: missingFiles,
|
|
215724
|
+
topics,
|
|
215725
|
+
docs: [...new Set(docs)],
|
|
215726
|
+
rules,
|
|
215727
|
+
gotchas,
|
|
215728
|
+
context_summary: {
|
|
215729
|
+
what: allWhat,
|
|
215730
|
+
how: allHow
|
|
215731
|
+
}
|
|
215732
|
+
});
|
|
215733
|
+
} else {
|
|
215734
|
+
console.log(`Session started for ${files.length} file(s):
|
|
215735
|
+
`);
|
|
215736
|
+
for (const f of files) {
|
|
215737
|
+
const exists = (0, import_node_fs5.existsSync)((0, import_node_path5.resolve)(process.cwd(), f));
|
|
215738
|
+
console.log(` ${exists ? "\u2713" : "\u2717"} ${f}`);
|
|
215739
|
+
}
|
|
215740
|
+
if (missingFiles.length > 0) {
|
|
215741
|
+
console.log(`
|
|
215742
|
+
Warning: ${missingFiles.length} file(s) not found locally.`);
|
|
215743
|
+
}
|
|
215744
|
+
if (topics.length > 0) {
|
|
215745
|
+
console.log(`
|
|
215746
|
+
Matched ${topics.length} context topic(s):`);
|
|
215747
|
+
for (const r of results) {
|
|
215748
|
+
console.log(` \u258C ${r.context.topic} (${r.match_reason})`);
|
|
215749
|
+
if (r.context.description.what) {
|
|
215750
|
+
console.log(` ${r.context.description.what}`);
|
|
215751
|
+
}
|
|
215752
|
+
}
|
|
215753
|
+
} else {
|
|
215754
|
+
console.log("\nNo context topics match these files.");
|
|
215755
|
+
}
|
|
215756
|
+
if (docs.length > 0) {
|
|
215757
|
+
console.log(`
|
|
215758
|
+
Anchored docs:`);
|
|
215759
|
+
for (const d of [...new Set(docs)]) {
|
|
215760
|
+
console.log(` \u{1F4C4} ${d}`);
|
|
215761
|
+
}
|
|
215762
|
+
}
|
|
215763
|
+
if (gotchas.length > 0) {
|
|
215764
|
+
console.log(`
|
|
215765
|
+
Gotchas:`);
|
|
215766
|
+
for (const g of gotchas) {
|
|
215767
|
+
console.log(` ! ${g}`);
|
|
215768
|
+
}
|
|
215769
|
+
}
|
|
215770
|
+
if (rules.length > 0) {
|
|
215771
|
+
console.log(`
|
|
215772
|
+
Rules that will be evaluated:`);
|
|
215773
|
+
for (const r of rules) {
|
|
215774
|
+
console.log(` \u2713 ${r}`);
|
|
215775
|
+
}
|
|
215776
|
+
}
|
|
215777
|
+
console.log("\nBefore finishing:");
|
|
215778
|
+
console.log(" driftless scan --diff");
|
|
215779
|
+
console.log(" driftless session finish");
|
|
215780
|
+
}
|
|
215781
|
+
} catch (e) {
|
|
215782
|
+
console.error(`Session start failed: ${formatError(e)}`);
|
|
215783
|
+
process.exit(1);
|
|
215784
|
+
}
|
|
215785
|
+
return;
|
|
215786
|
+
}
|
|
215787
|
+
if (subCommand === "finish") {
|
|
215788
|
+
const files = getChangedFilesList();
|
|
215789
|
+
if (files.length === 0 && !isJSON) {
|
|
215790
|
+
console.log("No local changes detected. Session clean.");
|
|
215791
|
+
process.exit(0);
|
|
215792
|
+
}
|
|
215793
|
+
try {
|
|
215794
|
+
const remote = getGitRemote();
|
|
215795
|
+
if (!remote) {
|
|
215796
|
+
console.error("Error: no git remote found.");
|
|
215797
|
+
process.exit(1);
|
|
215798
|
+
}
|
|
215799
|
+
const me = await api.get("/me");
|
|
215800
|
+
const repos = await api.get(`/workspaces/${me.slug}/repos`);
|
|
215801
|
+
const repo = repos.find((r) => r.github_org === remote.org && r.github_repo === remote.repo);
|
|
215802
|
+
if (!repo) {
|
|
215803
|
+
console.error(`Repo '${remote.repo}' not found. Run 'driftless init' first.`);
|
|
215804
|
+
process.exit(1);
|
|
215805
|
+
}
|
|
215806
|
+
const { getUncommittedDiff: getUncommittedDiff3, getStagedDiff: getStagedDiff2, getLastCommitHash: getLastCommitHash2, getAuthorName: getAuthorName2 } = await Promise.resolve().then(() => (init_git(), git_exports));
|
|
215807
|
+
const staged = getStagedDiff2();
|
|
215808
|
+
const unstaged = getUncommittedDiff3();
|
|
215809
|
+
const diff = [staged, unstaged].filter(Boolean).join("\n");
|
|
215810
|
+
if (!diff && !isJSON) {
|
|
215811
|
+
console.log("No changes to scan. Session clean.");
|
|
215812
|
+
process.exit(0);
|
|
215813
|
+
}
|
|
215814
|
+
const scanResult = await api.post("/scan", {
|
|
215815
|
+
workspace_id: me.workspace_id,
|
|
215816
|
+
repo_id: repo.id,
|
|
215817
|
+
diff,
|
|
215818
|
+
commit_hash: getLastCommitHash2(),
|
|
215819
|
+
author: getAuthorName2()
|
|
215820
|
+
});
|
|
215821
|
+
const rulesEvaluated = scanResult.rules_evaluated || 0;
|
|
215822
|
+
const violations = scanResult.violations || [];
|
|
215823
|
+
const contextResults = files.length > 0 ? await api.post(
|
|
215824
|
+
`/workspaces/${me.slug}/watchers/match-files`,
|
|
215825
|
+
{ files }
|
|
215826
|
+
) : [];
|
|
215827
|
+
const staleTopics = contextResults.filter((r) => r.context.stale?.is_stale);
|
|
215828
|
+
if (isJSON) {
|
|
215829
|
+
emitJSON3({
|
|
215830
|
+
files,
|
|
215831
|
+
rules_evaluated: rulesEvaluated,
|
|
215832
|
+
violations,
|
|
215833
|
+
stale_topics: staleTopics.map((r) => ({ topic: r.context.topic, reason: r.context.stale.reason })),
|
|
215834
|
+
context_matched: contextResults.map((r) => r.context.topic)
|
|
215835
|
+
});
|
|
215836
|
+
} else {
|
|
215837
|
+
console.log(`Session finish \u2014 ${files.length} file(s) changed:
|
|
215838
|
+
`);
|
|
215839
|
+
for (const f of files) {
|
|
215840
|
+
console.log(` \u270E ${f}`);
|
|
215841
|
+
}
|
|
215842
|
+
console.log(`
|
|
215843
|
+
${rulesEvaluated} rule(s) evaluated.`);
|
|
215844
|
+
if (violations.length > 0) {
|
|
215845
|
+
console.log(`
|
|
215846
|
+
${violations.length} violation(s) found:`);
|
|
215847
|
+
for (const v of violations) {
|
|
215848
|
+
console.log(` \u2717 [${v.severity.toUpperCase()}] ${v.rule_name}`);
|
|
215849
|
+
console.log(` ${v.file_path}:${v.line_number} \u2014 ${v.explanation}`);
|
|
215850
|
+
}
|
|
215851
|
+
console.log("\nFix violations before pushing.");
|
|
215852
|
+
} else {
|
|
215853
|
+
console.log("No violations.");
|
|
215854
|
+
}
|
|
215855
|
+
if (staleTopics.length > 0) {
|
|
215856
|
+
console.log(`
|
|
215857
|
+
\u26A0 ${staleTopics.length} stale context topic(s):`);
|
|
215858
|
+
for (const s of staleTopics) {
|
|
215859
|
+
console.log(` ${s.context.topic} \u2014 ${s.context.stale.reason}`);
|
|
215860
|
+
console.log(` \u2192 driftless context update ${s.context.topic} --what "..." --how "..."`);
|
|
215861
|
+
}
|
|
215862
|
+
}
|
|
215863
|
+
if (contextResults.length > 0) {
|
|
215864
|
+
console.log(`
|
|
215865
|
+
Context touched:`);
|
|
215866
|
+
for (const r of contextResults) {
|
|
215867
|
+
console.log(` \u258C ${r.context.topic}`);
|
|
215868
|
+
}
|
|
215869
|
+
}
|
|
215870
|
+
console.log("\nLearned something? Update context:");
|
|
215871
|
+
console.log(' driftless context update <topic> --gotchas "..."');
|
|
215872
|
+
console.log(' driftless context add <new-topic> --what "..." --pattern "..."');
|
|
215873
|
+
}
|
|
215874
|
+
if (violations.length > 0) {
|
|
215875
|
+
process.exit(1);
|
|
215876
|
+
}
|
|
215877
|
+
} catch (e) {
|
|
215878
|
+
console.error(`Session finish failed: ${formatError(e)}`);
|
|
215879
|
+
process.exit(1);
|
|
215880
|
+
}
|
|
215881
|
+
return;
|
|
215882
|
+
}
|
|
215883
|
+
console.log(`Usage: driftless session <start|finish> [args]
|
|
215884
|
+
|
|
215885
|
+
start \u2014 Show relevant context before editing
|
|
215886
|
+
--files "path1,path2" Files to check (default: local changes)
|
|
215887
|
+
--json Output as JSON
|
|
215888
|
+
|
|
215889
|
+
finish \u2014 Scan changes, check violations, suggest context updates
|
|
215890
|
+
--json Output as JSON
|
|
215891
|
+
|
|
215892
|
+
Examples:
|
|
215893
|
+
driftless session start --files "src/auth/**"
|
|
215894
|
+
driftless session start # uses local changes
|
|
215895
|
+
driftless session finish # scan + context report`);
|
|
215896
|
+
}
|
|
215897
|
+
|
|
215898
|
+
// src/commands/install-skill.ts
|
|
215899
|
+
var import_node_fs6 = require("node:fs");
|
|
215900
|
+
var import_node_path6 = require("node:path");
|
|
215461
215901
|
var template = `# Driftless \u2014 Live Repo Context
|
|
215462
215902
|
|
|
215463
215903
|
Driftless Cloud holds the team's living codebase context (topics, anchors, rules, gotchas).
|
|
@@ -215583,29 +216023,29 @@ Context delivery + structural verification only.
|
|
|
215583
216023
|
`;
|
|
215584
216024
|
function installSkillCommand() {
|
|
215585
216025
|
const cwd = process.cwd();
|
|
215586
|
-
const agentsPath = (0,
|
|
215587
|
-
if ((0,
|
|
215588
|
-
const existing = (0,
|
|
216026
|
+
const agentsPath = (0, import_node_path6.resolve)(cwd, "AGENTS.md");
|
|
216027
|
+
if ((0, import_node_fs6.existsSync)(agentsPath)) {
|
|
216028
|
+
const existing = (0, import_node_fs6.readFileSync)(agentsPath, "utf8");
|
|
215589
216029
|
if (existing.includes("# Driftless")) {
|
|
215590
216030
|
console.log("Driftless section already present in AGENTS.md.");
|
|
215591
216031
|
return;
|
|
215592
216032
|
}
|
|
215593
|
-
(0,
|
|
216033
|
+
(0, import_node_fs6.writeFileSync)(agentsPath, existing + "\n---\n\n" + template);
|
|
215594
216034
|
console.log(`Appended Driftless section to ${agentsPath}`);
|
|
215595
216035
|
} else {
|
|
215596
|
-
(0,
|
|
216036
|
+
(0, import_node_fs6.writeFileSync)(agentsPath, template);
|
|
215597
216037
|
console.log(`Driftless skill installed at ${agentsPath}`);
|
|
215598
216038
|
}
|
|
215599
216039
|
}
|
|
215600
216040
|
|
|
215601
216041
|
// src/commands/login.ts
|
|
215602
|
-
var
|
|
215603
|
-
var
|
|
216042
|
+
var import_node_fs7 = require("node:fs");
|
|
216043
|
+
var import_node_path7 = require("node:path");
|
|
215604
216044
|
var import_node_readline = require("node:readline");
|
|
215605
216045
|
var import_node_child_process2 = require("node:child_process");
|
|
215606
216046
|
var import_node_os2 = require("node:os");
|
|
215607
|
-
var CONFIG_DIR = (0,
|
|
215608
|
-
var CONFIG_PATH2 = (0,
|
|
216047
|
+
var CONFIG_DIR = (0, import_node_path7.resolve)((0, import_node_os2.homedir)(), ".driftless");
|
|
216048
|
+
var CONFIG_PATH2 = (0, import_node_path7.resolve)(CONFIG_DIR, "config.json");
|
|
215609
216049
|
function openBrowser(url) {
|
|
215610
216050
|
const cmd = process.platform === "darwin" ? "open" : process.platform === "win32" ? "start" : "xdg-open";
|
|
215611
216051
|
(0, import_node_child_process2.exec)(`${cmd} ${url}`);
|
|
@@ -215634,10 +216074,10 @@ async function loginCommand(args) {
|
|
|
215634
216074
|
input: process.stdin,
|
|
215635
216075
|
output: process.stdout
|
|
215636
216076
|
});
|
|
215637
|
-
const apiKey = await new Promise((
|
|
216077
|
+
const apiKey = await new Promise((resolve9) => {
|
|
215638
216078
|
rl.question("Paste your API key: ", (answer) => {
|
|
215639
216079
|
rl.close();
|
|
215640
|
-
|
|
216080
|
+
resolve9(answer.trim());
|
|
215641
216081
|
});
|
|
215642
216082
|
});
|
|
215643
216083
|
if (!apiKey.startsWith("drift_")) {
|
|
@@ -215650,10 +216090,10 @@ async function loginCommand(args) {
|
|
|
215650
216090
|
function saveConfig(apiKey, apiUrl) {
|
|
215651
216091
|
const url = apiUrl || "https://api.driftless.icu/api/v1";
|
|
215652
216092
|
try {
|
|
215653
|
-
if (!(0,
|
|
215654
|
-
(0,
|
|
216093
|
+
if (!(0, import_node_fs7.existsSync)(CONFIG_DIR)) {
|
|
216094
|
+
(0, import_node_fs7.mkdirSync)(CONFIG_DIR, { recursive: true });
|
|
215655
216095
|
}
|
|
215656
|
-
(0,
|
|
216096
|
+
(0, import_node_fs7.writeFileSync)(
|
|
215657
216097
|
CONFIG_PATH2,
|
|
215658
216098
|
JSON.stringify({ api_key: apiKey, api_url: url }, null, 2) + "\n"
|
|
215659
216099
|
);
|
|
@@ -215669,8 +216109,9 @@ function saveConfig(apiKey, apiUrl) {
|
|
|
215669
216109
|
}
|
|
215670
216110
|
|
|
215671
216111
|
// src/commands/doctor.ts
|
|
215672
|
-
|
|
215673
|
-
var
|
|
216112
|
+
init_git();
|
|
216113
|
+
var import_node_fs8 = require("node:fs");
|
|
216114
|
+
var import_node_path8 = require("node:path");
|
|
215674
216115
|
async function doctorCommand() {
|
|
215675
216116
|
const checks = [];
|
|
215676
216117
|
const apiKey = getApiKey();
|
|
@@ -215756,9 +216197,9 @@ async function doctorCommand() {
|
|
|
215756
216197
|
} else {
|
|
215757
216198
|
checks.push({ name: "Baseline", status: "warn", detail: "Skipped (no git remote)" });
|
|
215758
216199
|
}
|
|
215759
|
-
const agentsPath = (0,
|
|
215760
|
-
if ((0,
|
|
215761
|
-
const content = (0,
|
|
216200
|
+
const agentsPath = (0, import_node_path8.resolve)(process.cwd(), "AGENTS.md");
|
|
216201
|
+
if ((0, import_node_fs8.existsSync)(agentsPath)) {
|
|
216202
|
+
const content = (0, import_node_fs8.readFileSync)(agentsPath, "utf-8");
|
|
215762
216203
|
if (content.includes("driftless")) {
|
|
215763
216204
|
checks.push({ name: "AGENTS.md", status: "ok", detail: "Driftless skill installed" });
|
|
215764
216205
|
} else {
|
|
@@ -215813,31 +216254,33 @@ function pad2(s, n) {
|
|
|
215813
216254
|
}
|
|
215814
216255
|
|
|
215815
216256
|
// src/index.ts
|
|
215816
|
-
var VERSION = "0.1.
|
|
215817
|
-
var HELP_TEXT = `Driftless CLI v${VERSION} \u2014
|
|
216257
|
+
var VERSION = "0.1.23";
|
|
216258
|
+
var HELP_TEXT = `Driftless CLI v${VERSION} \u2014 Living repo context for humans and coding agents
|
|
215818
216259
|
|
|
215819
216260
|
Install: npm install -g @driftless-sh/cli
|
|
215820
216261
|
Docs: https://driftless.icu/docs
|
|
215821
216262
|
API: https://api.driftless.icu/api/v1
|
|
215822
216263
|
|
|
215823
216264
|
Agent loop:
|
|
215824
|
-
driftless
|
|
215825
|
-
driftless
|
|
215826
|
-
driftless context
|
|
215827
|
-
driftless context get
|
|
215828
|
-
driftless context
|
|
215829
|
-
driftless
|
|
216265
|
+
driftless session start Show context before editing
|
|
216266
|
+
driftless session finish Scan changes + context report
|
|
216267
|
+
driftless context list List all context topics
|
|
216268
|
+
driftless context get <topic> Live view of one topic before editing
|
|
216269
|
+
driftless context get --diff What context matters for my local changes?
|
|
216270
|
+
driftless context search "<query>" Discover topics by keyword
|
|
216271
|
+
driftless scan --diff Check changes against active rules
|
|
215830
216272
|
|
|
215831
216273
|
Setup:
|
|
215832
216274
|
driftless login --key <api-key> Authenticate
|
|
215833
|
-
driftless init Scan repo,
|
|
216275
|
+
driftless init Scan repo, bootstrap context, suggest rules
|
|
215834
216276
|
driftless doctor Check environment health
|
|
215835
216277
|
|
|
215836
216278
|
Commands:
|
|
215837
216279
|
login Authenticate with API key
|
|
215838
|
-
init Smart init: scan \u2192 detect patterns \u2192 create
|
|
216280
|
+
init Smart init: scan \u2192 detect patterns \u2192 create topics + rules + anchor docs
|
|
215839
216281
|
scan Evaluate staged + uncommitted changes against rules
|
|
215840
216282
|
scan --diff Evaluate uncommitted changes only
|
|
216283
|
+
session Agent session: start (context) \u2192 finish (scan + report)
|
|
215841
216284
|
context Live repo context (topics, search, anchors)
|
|
215842
216285
|
install-skill Install AGENTS.md into current repo
|
|
215843
216286
|
doctor Check environment health (auth, API, git, workspace, repo, baseline)
|
|
@@ -215859,8 +216302,13 @@ Context subcommands:
|
|
|
215859
216302
|
delete <topic> Delete a topic
|
|
215860
216303
|
push --files "p1,p2" Legacy: match topics by file paths
|
|
215861
216304
|
|
|
216305
|
+
Session subcommands:
|
|
216306
|
+
start [--files "p1,p2"] Show relevant context before editing
|
|
216307
|
+
finish Scan changes, check violations, suggest updates
|
|
216308
|
+
|
|
215862
216309
|
Flags:
|
|
215863
|
-
--
|
|
216310
|
+
--json Output as JSON (default is human-readable)
|
|
216311
|
+
--dry-run Preview changes without writing to Driftless Cloud
|
|
215864
216312
|
|
|
215865
216313
|
Auth priority:
|
|
215866
216314
|
1. DRIFTLESS_API_KEY env var
|
|
@@ -215871,21 +216319,22 @@ Environment:
|
|
|
215871
216319
|
DRIFTLESS_API_URL API server URL (default: http://localhost:3000/api/v1)
|
|
215872
216320
|
|
|
215873
216321
|
Output format:
|
|
215874
|
-
All commands output
|
|
215875
|
-
Use --
|
|
216322
|
+
All commands output human-readable text by default.
|
|
216323
|
+
Use --json flag for machine-readable output (agents, CI).
|
|
215876
216324
|
|
|
215877
216325
|
Examples:
|
|
216326
|
+
driftless session start --files "src/auth/**"
|
|
216327
|
+
driftless session finish
|
|
216328
|
+
|
|
215878
216329
|
driftless context add "b2b-guard" \\
|
|
215879
216330
|
--what "Guard que protege endpoints B2B" \\
|
|
215880
216331
|
--how "Verifica org_id en el token" \\
|
|
215881
|
-
--pattern "src/shared/guards/**"
|
|
215882
|
-
--decisions "Multi-tenant, usamos org_id" \\
|
|
215883
|
-
--gotchas "No funciona con tokens de test" \\
|
|
215884
|
-
--ownership "@team"
|
|
216332
|
+
--pattern "src/shared/guards/**"
|
|
215885
216333
|
|
|
215886
|
-
driftless context get sdk
|
|
216334
|
+
driftless context get sdk
|
|
215887
216335
|
driftless context search "auth"
|
|
215888
216336
|
driftless scan --diff
|
|
216337
|
+
driftless context push --files "src/auth/auth.controller.ts" --dry-run
|
|
215889
216338
|
`;
|
|
215890
216339
|
function showCommandHelp(cmd) {
|
|
215891
216340
|
const help = {
|
|
@@ -215934,7 +216383,7 @@ Example:
|
|
|
215934
216383
|
context: `driftless context <subcommand> [args] [flags]
|
|
215935
216384
|
|
|
215936
216385
|
Live repo context \u2014 the team's shared codebase memory.
|
|
215937
|
-
|
|
216386
|
+
Human-readable by default. Use --json for machine output.
|
|
215938
216387
|
|
|
215939
216388
|
Subcommands:
|
|
215940
216389
|
list [filters] List context topics
|
|
@@ -215956,69 +216405,20 @@ List filters:
|
|
|
215956
216405
|
--manual Only manually-created topics
|
|
215957
216406
|
--repo <id> Only topics scoped to a given repo
|
|
215958
216407
|
|
|
215959
|
-
Canonical 'get' shape (JSON):
|
|
215960
|
-
{
|
|
215961
|
-
"topic": "<slug>",
|
|
215962
|
-
"summary": "...",
|
|
215963
|
-
"description": { "what", "how", "decisions", "gotchas", "ownership" },
|
|
215964
|
-
"anchors": { "files", "patterns", "repos", "docs" },
|
|
215965
|
-
"components": [ ... ],
|
|
215966
|
-
"rules": [],
|
|
215967
|
-
"invariants": ["...", ...],
|
|
215968
|
-
"violations": [],
|
|
215969
|
-
"events": [],
|
|
215970
|
-
"required_checks": ["...", ...],
|
|
215971
|
-
"stale": { "is_stale", "reason" },
|
|
215972
|
-
"metadata": { "created_by", "last_updated", "source" }
|
|
215973
|
-
}
|
|
215974
|
-
|
|
215975
|
-
Match-files response (JSON):
|
|
215976
|
-
[
|
|
215977
|
-
{
|
|
215978
|
-
"context": { ... canonical shape ... },
|
|
215979
|
-
"history": [ ... watcher events ... ],
|
|
215980
|
-
"match_reason": "pattern:src/auth/**"
|
|
215981
|
-
}
|
|
215982
|
-
]
|
|
215983
|
-
|
|
215984
|
-
Create / update options:
|
|
215985
|
-
--what What this piece is
|
|
215986
|
-
--how How it works
|
|
215987
|
-
--pattern Glob (e.g. src/sdk/**) \u2014 resolves to files dynamically
|
|
215988
|
-
--where Explicit file path (alternative to --pattern)
|
|
215989
|
-
--decisions Why it was built this way
|
|
215990
|
-
--gotchas Known traps and edge cases
|
|
215991
|
-
--ownership Who maintains it
|
|
215992
|
-
--file <path> Anchor an existing markdown file as a doc (on add)
|
|
215993
|
-
|
|
215994
|
-
Anchor options:
|
|
215995
|
-
--doc <path> Path to markdown file to anchor as file_content
|
|
215996
|
-
--note "..." Short note appended to decisions
|
|
215997
|
-
--files "..." Comma-separated file paths to anchor
|
|
215998
|
-
--pattern "..." Glob pattern to anchor
|
|
215999
|
-
|
|
216000
|
-
Update append options (PR 3):
|
|
216001
|
-
--gotcha "..." Append a gotcha to existing list
|
|
216002
|
-
--invariant "..." Append an invariant (team rule that must be followed)
|
|
216003
|
-
--check "..." Append a required pre-push check
|
|
216004
|
-
--enforce "..." Create a structural rule from the invariant
|
|
216005
|
-
|
|
216006
216408
|
Flags:
|
|
216007
|
-
--
|
|
216409
|
+
--json Machine-readable JSON output
|
|
216410
|
+
--dry-run Preview changes without writing to Driftless Cloud
|
|
216008
216411
|
|
|
216009
216412
|
Examples:
|
|
216010
|
-
driftless context list
|
|
216413
|
+
driftless context list
|
|
216414
|
+
driftless context list --json
|
|
216011
216415
|
driftless context get auth-boundaries
|
|
216012
|
-
driftless context get
|
|
216013
|
-
driftless context get --diff --human
|
|
216014
|
-
driftless context get --files "src/auth/guard.ts,src/auth/service.ts"
|
|
216416
|
+
driftless context get --diff
|
|
216015
216417
|
driftless context search "auth"
|
|
216016
216418
|
driftless context add "sdk" --pattern "src/sdk/**" --what "Public SDK"
|
|
216017
216419
|
driftless context update sdk --gotchas "Reset token on org switch"
|
|
216018
216420
|
driftless context anchor auth --doc docs/auth.md --files "src/auth/**"
|
|
216019
|
-
driftless context
|
|
216020
|
-
driftless context update auth --invariant "No direct DB from controllers"
|
|
216021
|
-
driftless context update auth --check "Run harness:check before push"
|
|
216421
|
+
driftless context push --files "src/auth/guard.ts" --dry-run
|
|
216022
216422
|
`,
|
|
216023
216423
|
"install-skill": `driftless install-skill
|
|
216024
216424
|
|
|
@@ -216070,6 +216470,9 @@ async function main() {
|
|
|
216070
216470
|
case "context":
|
|
216071
216471
|
await contextCommand(args.slice(1));
|
|
216072
216472
|
break;
|
|
216473
|
+
case "session":
|
|
216474
|
+
await sessionCommand(args.slice(1));
|
|
216475
|
+
break;
|
|
216073
216476
|
case "install-skill":
|
|
216074
216477
|
installSkillCommand();
|
|
216075
216478
|
break;
|