@vreko/cli 3.0.1
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/LICENSE +201 -0
- package/README.md +45 -0
- package/dist/CeremonyView-LQS7FTMK.js +134 -0
- package/dist/CeremonyView-LQS7FTMK.js.map +1 -0
- package/dist/InitApp-7K5DTYSW.js +1479 -0
- package/dist/InitApp-7K5DTYSW.js.map +1 -0
- package/dist/SkippedTestDetector-PJSKSOZR.js +7 -0
- package/dist/SkippedTestDetector-PJSKSOZR.js.map +1 -0
- package/dist/TuiApp-FX23XQBK.js +8 -0
- package/dist/TuiApp-FX23XQBK.js.map +1 -0
- package/dist/analysis-ABEO6RTN.js +8 -0
- package/dist/analysis-ABEO6RTN.js.map +1 -0
- package/dist/auth-XNBEBNPY.js +7669 -0
- package/dist/auth-XNBEBNPY.js.map +1 -0
- package/dist/ceremony-M7CXVBVA.js +45 -0
- package/dist/ceremony-M7CXVBVA.js.map +1 -0
- package/dist/chunk-A3QSZJPD.js +3147 -0
- package/dist/chunk-A3QSZJPD.js.map +1 -0
- package/dist/chunk-ASGZ5B6C.js +3969 -0
- package/dist/chunk-ASGZ5B6C.js.map +1 -0
- package/dist/chunk-DMXC2JTC.js +58 -0
- package/dist/chunk-DMXC2JTC.js.map +1 -0
- package/dist/chunk-EEBSK2IH.js +161 -0
- package/dist/chunk-EEBSK2IH.js.map +1 -0
- package/dist/chunk-EWOJGXRX.js +22 -0
- package/dist/chunk-EWOJGXRX.js.map +1 -0
- package/dist/chunk-F7GEJLP7.js +2389 -0
- package/dist/chunk-F7GEJLP7.js.map +1 -0
- package/dist/chunk-GOYL3F4T.js +605 -0
- package/dist/chunk-GOYL3F4T.js.map +1 -0
- package/dist/chunk-GRMRYWYS.js +17 -0
- package/dist/chunk-GRMRYWYS.js.map +1 -0
- package/dist/chunk-GSUGROXB.js +1951 -0
- package/dist/chunk-GSUGROXB.js.map +1 -0
- package/dist/chunk-H7773ONB.js +50 -0
- package/dist/chunk-H7773ONB.js.map +1 -0
- package/dist/chunk-HFQHU5LC.js +445 -0
- package/dist/chunk-HFQHU5LC.js.map +1 -0
- package/dist/chunk-IVHUBLJD.js +318 -0
- package/dist/chunk-IVHUBLJD.js.map +1 -0
- package/dist/chunk-KJWKY4L4.js +14 -0
- package/dist/chunk-KJWKY4L4.js.map +1 -0
- package/dist/chunk-MJVY2XUN.js +1793 -0
- package/dist/chunk-MJVY2XUN.js.map +1 -0
- package/dist/chunk-QWZVCJII.js +1797 -0
- package/dist/chunk-QWZVCJII.js.map +1 -0
- package/dist/chunk-VTSNRV3V.js +3237 -0
- package/dist/chunk-VTSNRV3V.js.map +1 -0
- package/dist/chunk-W5B4GTXR.js +1466 -0
- package/dist/chunk-W5B4GTXR.js.map +1 -0
- package/dist/chunk-WZEZLVOW.js +4995 -0
- package/dist/chunk-WZEZLVOW.js.map +1 -0
- package/dist/chunk-YPTTIXKC.js +199 -0
- package/dist/chunk-YPTTIXKC.js.map +1 -0
- package/dist/chunk-Z55UGM6X.js +6360 -0
- package/dist/chunk-Z55UGM6X.js.map +1 -0
- package/dist/chunk-ZIIRQODJ.js +110 -0
- package/dist/chunk-ZIIRQODJ.js.map +1 -0
- package/dist/chunk-ZSUQ4FMB.js +77 -0
- package/dist/chunk-ZSUQ4FMB.js.map +1 -0
- package/dist/client-JMTSZS3V.js +10 -0
- package/dist/client-JMTSZS3V.js.map +1 -0
- package/dist/deprecated-snap.js +19 -0
- package/dist/deprecated-snap.js.map +1 -0
- package/dist/dist-2KWBZFLA.js +14 -0
- package/dist/dist-2KWBZFLA.js.map +1 -0
- package/dist/dist-5ZYKNNU3.js +7 -0
- package/dist/dist-5ZYKNNU3.js.map +1 -0
- package/dist/dist-CP3RFHPI.js +11 -0
- package/dist/dist-CP3RFHPI.js.map +1 -0
- package/dist/gecko-53ITAGG6.js +56 -0
- package/dist/gecko-53ITAGG6.js.map +1 -0
- package/dist/guards-QAFC64NO.js +7 -0
- package/dist/guards-QAFC64NO.js.map +1 -0
- package/dist/index.js +57785 -0
- package/dist/index.js.map +1 -0
- package/dist/init-command-246JIVXM.js +7 -0
- package/dist/init-command-246JIVXM.js.map +1 -0
- package/dist/init-core-KAI7LCXZ.js +12 -0
- package/dist/init-core-KAI7LCXZ.js.map +1 -0
- package/dist/init-scan-RZNYDTUV.js +1919 -0
- package/dist/init-scan-RZNYDTUV.js.map +1 -0
- package/dist/local-service-adapter-6KNN6WQL.js +8 -0
- package/dist/local-service-adapter-6KNN6WQL.js.map +1 -0
- package/dist/secure-credentials-JXWAQLS2.js +306 -0
- package/dist/secure-credentials-JXWAQLS2.js.map +1 -0
- package/dist/tui-TPJPUS2R.js +111 -0
- package/dist/tui-TPJPUS2R.js.map +1 -0
- package/dist/vreko-dir-O3RLG7PI.js +8 -0
- package/dist/vreko-dir-O3RLG7PI.js.map +1 -0
- package/package.json +132 -0
- package/scripts/check-banned-words.ts +152 -0
- package/scripts/hooks/posttooluse-file-notify.sh +108 -0
- package/scripts/hooks/pretooluse-fragile-guard.sh +82 -0
- package/scripts/post-install-notice.js +24 -0
- package/scripts/postinstall.mjs +84 -0
- package/scripts/preuninstall.mjs +34 -0
- package/scripts/verify-jsx-transform.mjs +55 -0
|
@@ -0,0 +1,445 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { __name } from './chunk-EWOJGXRX.js';
|
|
3
|
+
import { mkdir, writeFile, access, constants, readFile, appendFile, stat } from 'fs/promises';
|
|
4
|
+
import { homedir } from 'os';
|
|
5
|
+
import { join, dirname } from 'path';
|
|
6
|
+
import { z } from 'zod';
|
|
7
|
+
|
|
8
|
+
process.env.VREKO_CLI='true';process.env.NODE_NO_WARNINGS='1';
|
|
9
|
+
var VREKO_DIR = ".vreko";
|
|
10
|
+
var GLOBAL_VREKO_DIR = ".vreko";
|
|
11
|
+
var WorkspaceConfigSchema = z.object({
|
|
12
|
+
workspaceId: z.string().optional(),
|
|
13
|
+
tier: z.enum([
|
|
14
|
+
"free",
|
|
15
|
+
"pro"
|
|
16
|
+
]).optional(),
|
|
17
|
+
protectionLevel: z.enum([
|
|
18
|
+
"standard",
|
|
19
|
+
"strict"
|
|
20
|
+
]).optional(),
|
|
21
|
+
syncEnabled: z.boolean().optional(),
|
|
22
|
+
createdAt: z.string(),
|
|
23
|
+
updatedAt: z.string()
|
|
24
|
+
});
|
|
25
|
+
var WorkspaceVitalsSchema = z.object({
|
|
26
|
+
framework: z.string().optional(),
|
|
27
|
+
frameworkConfidence: z.number().optional(),
|
|
28
|
+
packageManager: z.enum([
|
|
29
|
+
"npm",
|
|
30
|
+
"pnpm",
|
|
31
|
+
"yarn",
|
|
32
|
+
"bun"
|
|
33
|
+
]).optional(),
|
|
34
|
+
typescript: z.object({
|
|
35
|
+
enabled: z.boolean(),
|
|
36
|
+
strict: z.boolean().optional(),
|
|
37
|
+
version: z.string().optional()
|
|
38
|
+
}).optional(),
|
|
39
|
+
criticalFiles: z.array(z.string()).optional(),
|
|
40
|
+
detectedAt: z.string()
|
|
41
|
+
});
|
|
42
|
+
var ProtectedFileSchema = z.object({
|
|
43
|
+
pattern: z.string(),
|
|
44
|
+
addedAt: z.string(),
|
|
45
|
+
reason: z.string().optional()
|
|
46
|
+
});
|
|
47
|
+
var SessionStateSchema = z.object({
|
|
48
|
+
id: z.string(),
|
|
49
|
+
task: z.string().optional(),
|
|
50
|
+
startedAt: z.string(),
|
|
51
|
+
snapshotCount: z.number(),
|
|
52
|
+
filesModified: z.number().optional(),
|
|
53
|
+
state: z.enum([
|
|
54
|
+
"active",
|
|
55
|
+
"ended"
|
|
56
|
+
]).optional(),
|
|
57
|
+
active: z.boolean().optional()
|
|
58
|
+
});
|
|
59
|
+
var LearningEntrySchema = z.object({
|
|
60
|
+
id: z.string(),
|
|
61
|
+
type: z.enum([
|
|
62
|
+
"pattern",
|
|
63
|
+
"pitfall",
|
|
64
|
+
"efficiency",
|
|
65
|
+
"discovery",
|
|
66
|
+
"workflow"
|
|
67
|
+
]),
|
|
68
|
+
trigger: z.string(),
|
|
69
|
+
action: z.string(),
|
|
70
|
+
source: z.string(),
|
|
71
|
+
createdAt: z.string()
|
|
72
|
+
});
|
|
73
|
+
var ViolationEntrySchema = z.object({
|
|
74
|
+
type: z.string(),
|
|
75
|
+
file: z.string(),
|
|
76
|
+
message: z.string(),
|
|
77
|
+
count: z.number().optional(),
|
|
78
|
+
date: z.string(),
|
|
79
|
+
prevention: z.string().optional()
|
|
80
|
+
});
|
|
81
|
+
var GlobalCredentialsSchema = z.object({
|
|
82
|
+
accessToken: z.string(),
|
|
83
|
+
refreshToken: z.string().optional(),
|
|
84
|
+
email: z.string(),
|
|
85
|
+
tier: z.enum([
|
|
86
|
+
"free",
|
|
87
|
+
"pro"
|
|
88
|
+
]),
|
|
89
|
+
expiresAt: z.string().optional()
|
|
90
|
+
});
|
|
91
|
+
var GlobalConfigSchema = z.object({
|
|
92
|
+
apiUrl: z.string().optional(),
|
|
93
|
+
defaultWorkspace: z.string().optional(),
|
|
94
|
+
analytics: z.boolean().optional()
|
|
95
|
+
});
|
|
96
|
+
function getGlobalDir() {
|
|
97
|
+
return join(homedir(), GLOBAL_VREKO_DIR);
|
|
98
|
+
}
|
|
99
|
+
__name(getGlobalDir, "getGlobalDir");
|
|
100
|
+
function getWorkspaceDir(workspaceRoot) {
|
|
101
|
+
return join(workspaceRoot || process.cwd(), VREKO_DIR);
|
|
102
|
+
}
|
|
103
|
+
__name(getWorkspaceDir, "getWorkspaceDir");
|
|
104
|
+
function getGlobalPath(relativePath) {
|
|
105
|
+
return join(getGlobalDir(), relativePath);
|
|
106
|
+
}
|
|
107
|
+
__name(getGlobalPath, "getGlobalPath");
|
|
108
|
+
function getWorkspacePath(relativePath, workspaceRoot) {
|
|
109
|
+
return join(getWorkspaceDir(workspaceRoot), relativePath);
|
|
110
|
+
}
|
|
111
|
+
__name(getWorkspacePath, "getWorkspacePath");
|
|
112
|
+
async function createVrekoDirectory(workspaceRoot) {
|
|
113
|
+
const baseDir = getWorkspaceDir(workspaceRoot);
|
|
114
|
+
const dirs = [
|
|
115
|
+
"",
|
|
116
|
+
"patterns",
|
|
117
|
+
"learnings",
|
|
118
|
+
"session",
|
|
119
|
+
"snapshots"
|
|
120
|
+
];
|
|
121
|
+
for (const dir of dirs) {
|
|
122
|
+
await mkdir(join(baseDir, dir), {
|
|
123
|
+
recursive: true
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
const gitignore = `# Vreko Directory
|
|
127
|
+
# Ignore snapshot content (large binary data)
|
|
128
|
+
snapshots/
|
|
129
|
+
embeddings.db
|
|
130
|
+
|
|
131
|
+
# Keep these for team sharing
|
|
132
|
+
!patterns/
|
|
133
|
+
!learnings/
|
|
134
|
+
!vitals.json
|
|
135
|
+
!config.json
|
|
136
|
+
!protected.json
|
|
137
|
+
`.trim();
|
|
138
|
+
await writeFile(join(baseDir, ".gitignore"), gitignore);
|
|
139
|
+
}
|
|
140
|
+
__name(createVrekoDirectory, "createVrekoDirectory");
|
|
141
|
+
async function createGlobalDirectory() {
|
|
142
|
+
const baseDir = getGlobalDir();
|
|
143
|
+
const dirs = [
|
|
144
|
+
"",
|
|
145
|
+
"cache",
|
|
146
|
+
"mcp-configs"
|
|
147
|
+
];
|
|
148
|
+
for (const dir of dirs) {
|
|
149
|
+
await mkdir(join(baseDir, dir), {
|
|
150
|
+
recursive: true
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
__name(createGlobalDirectory, "createGlobalDirectory");
|
|
155
|
+
async function isVrekoInitialized(workspaceRoot) {
|
|
156
|
+
try {
|
|
157
|
+
const dirPath = getWorkspaceDir(workspaceRoot);
|
|
158
|
+
await access(dirPath, constants.F_OK);
|
|
159
|
+
return true;
|
|
160
|
+
} catch {
|
|
161
|
+
return false;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
__name(isVrekoInitialized, "isVrekoInitialized");
|
|
165
|
+
async function isLoggedIn() {
|
|
166
|
+
try {
|
|
167
|
+
const credentials = await getCredentials();
|
|
168
|
+
if (!credentials?.accessToken) {
|
|
169
|
+
return false;
|
|
170
|
+
}
|
|
171
|
+
if (credentials.expiresAt) {
|
|
172
|
+
const expiresAt = new Date(credentials.expiresAt);
|
|
173
|
+
if (expiresAt < /* @__PURE__ */ new Date()) {
|
|
174
|
+
return false;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
return true;
|
|
178
|
+
} catch {
|
|
179
|
+
return false;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
__name(isLoggedIn, "isLoggedIn");
|
|
183
|
+
async function readVrekoJson(relativePath, workspaceRoot) {
|
|
184
|
+
try {
|
|
185
|
+
const content = await readFile(getWorkspacePath(relativePath, workspaceRoot), "utf-8");
|
|
186
|
+
return JSON.parse(content);
|
|
187
|
+
} catch {
|
|
188
|
+
return null;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
__name(readVrekoJson, "readVrekoJson");
|
|
192
|
+
async function writeVrekoJson(relativePath, data, workspaceRoot) {
|
|
193
|
+
const fullPath = getWorkspacePath(relativePath, workspaceRoot);
|
|
194
|
+
await mkdir(dirname(fullPath), {
|
|
195
|
+
recursive: true
|
|
196
|
+
});
|
|
197
|
+
await writeFile(fullPath, JSON.stringify(data, null, 2));
|
|
198
|
+
}
|
|
199
|
+
__name(writeVrekoJson, "writeVrekoJson");
|
|
200
|
+
async function appendVrekoJsonl(relativePath, data, workspaceRoot) {
|
|
201
|
+
const fullPath = getWorkspacePath(relativePath, workspaceRoot);
|
|
202
|
+
await mkdir(dirname(fullPath), {
|
|
203
|
+
recursive: true
|
|
204
|
+
});
|
|
205
|
+
await appendFile(fullPath, `${JSON.stringify(data)}
|
|
206
|
+
`);
|
|
207
|
+
}
|
|
208
|
+
__name(appendVrekoJsonl, "appendVrekoJsonl");
|
|
209
|
+
async function loadVrekoJsonl(relativePath, workspaceRoot) {
|
|
210
|
+
try {
|
|
211
|
+
const content = await readFile(getWorkspacePath(relativePath, workspaceRoot), "utf-8");
|
|
212
|
+
return content.split("\n").filter((line) => line.trim()).map((line) => JSON.parse(line));
|
|
213
|
+
} catch {
|
|
214
|
+
return [];
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
__name(loadVrekoJsonl, "loadVrekoJsonl");
|
|
218
|
+
async function readGlobalJson(relativePath) {
|
|
219
|
+
try {
|
|
220
|
+
const content = await readFile(getGlobalPath(relativePath), "utf-8");
|
|
221
|
+
return JSON.parse(content);
|
|
222
|
+
} catch {
|
|
223
|
+
return null;
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
__name(readGlobalJson, "readGlobalJson");
|
|
227
|
+
async function writeGlobalJson(relativePath, data, mode) {
|
|
228
|
+
const fullPath = getGlobalPath(relativePath);
|
|
229
|
+
await mkdir(dirname(fullPath), {
|
|
230
|
+
recursive: true
|
|
231
|
+
});
|
|
232
|
+
await writeFile(fullPath, JSON.stringify(data, null, 2), mode !== void 0 ? {
|
|
233
|
+
mode
|
|
234
|
+
} : void 0);
|
|
235
|
+
}
|
|
236
|
+
__name(writeGlobalJson, "writeGlobalJson");
|
|
237
|
+
async function deleteGlobalJson(relativePath) {
|
|
238
|
+
const fullPath = getGlobalPath(relativePath);
|
|
239
|
+
try {
|
|
240
|
+
const { unlink } = await import('fs/promises');
|
|
241
|
+
await unlink(fullPath);
|
|
242
|
+
} catch {
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
__name(deleteGlobalJson, "deleteGlobalJson");
|
|
246
|
+
async function getWorkspaceConfig(workspaceRoot) {
|
|
247
|
+
const data = await readVrekoJson("config.json", workspaceRoot);
|
|
248
|
+
if (!data) {
|
|
249
|
+
return null;
|
|
250
|
+
}
|
|
251
|
+
const result = WorkspaceConfigSchema.safeParse(data);
|
|
252
|
+
return result.success ? result.data : null;
|
|
253
|
+
}
|
|
254
|
+
__name(getWorkspaceConfig, "getWorkspaceConfig");
|
|
255
|
+
async function saveWorkspaceConfig(config, workspaceRoot) {
|
|
256
|
+
await writeVrekoJson("config.json", config, workspaceRoot);
|
|
257
|
+
}
|
|
258
|
+
__name(saveWorkspaceConfig, "saveWorkspaceConfig");
|
|
259
|
+
async function getWorkspaceVitals(workspaceRoot) {
|
|
260
|
+
const data = await readVrekoJson("vitals.json", workspaceRoot);
|
|
261
|
+
if (!data) {
|
|
262
|
+
return null;
|
|
263
|
+
}
|
|
264
|
+
const result = WorkspaceVitalsSchema.safeParse(data);
|
|
265
|
+
return result.success ? result.data : null;
|
|
266
|
+
}
|
|
267
|
+
__name(getWorkspaceVitals, "getWorkspaceVitals");
|
|
268
|
+
async function saveWorkspaceVitals(vitals, workspaceRoot) {
|
|
269
|
+
await writeVrekoJson("vitals.json", vitals, workspaceRoot);
|
|
270
|
+
}
|
|
271
|
+
__name(saveWorkspaceVitals, "saveWorkspaceVitals");
|
|
272
|
+
async function getProtectedFiles(workspaceRoot) {
|
|
273
|
+
const data = await readVrekoJson("protected.json", workspaceRoot);
|
|
274
|
+
if (!data) {
|
|
275
|
+
return [];
|
|
276
|
+
}
|
|
277
|
+
const result = z.array(ProtectedFileSchema).safeParse(data);
|
|
278
|
+
return result.success ? result.data : [];
|
|
279
|
+
}
|
|
280
|
+
__name(getProtectedFiles, "getProtectedFiles");
|
|
281
|
+
async function saveProtectedFiles(files, workspaceRoot) {
|
|
282
|
+
await writeVrekoJson("protected.json", files, workspaceRoot);
|
|
283
|
+
}
|
|
284
|
+
__name(saveProtectedFiles, "saveProtectedFiles");
|
|
285
|
+
async function getCurrentSession(workspaceRoot) {
|
|
286
|
+
const data = await readVrekoJson("session/current.json", workspaceRoot);
|
|
287
|
+
if (!data) {
|
|
288
|
+
return null;
|
|
289
|
+
}
|
|
290
|
+
const result = SessionStateSchema.safeParse(data);
|
|
291
|
+
return result.success ? result.data : null;
|
|
292
|
+
}
|
|
293
|
+
__name(getCurrentSession, "getCurrentSession");
|
|
294
|
+
async function saveCurrentSession(session, workspaceRoot) {
|
|
295
|
+
await writeVrekoJson("session/current.json", session, workspaceRoot);
|
|
296
|
+
}
|
|
297
|
+
__name(saveCurrentSession, "saveCurrentSession");
|
|
298
|
+
async function endCurrentSession(workspaceRoot) {
|
|
299
|
+
const fullPath = getWorkspacePath("session/current.json", workspaceRoot);
|
|
300
|
+
try {
|
|
301
|
+
const { unlink } = await import('fs/promises');
|
|
302
|
+
await unlink(fullPath);
|
|
303
|
+
} catch {
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
__name(endCurrentSession, "endCurrentSession");
|
|
307
|
+
async function recordLearning(learning, workspaceRoot) {
|
|
308
|
+
await appendVrekoJsonl("learnings/user-learnings.jsonl", learning, workspaceRoot);
|
|
309
|
+
}
|
|
310
|
+
__name(recordLearning, "recordLearning");
|
|
311
|
+
async function getLearnings(workspaceRoot) {
|
|
312
|
+
const data = await loadVrekoJsonl("learnings/user-learnings.jsonl", workspaceRoot);
|
|
313
|
+
return data.filter((item) => LearningEntrySchema.safeParse(item).success);
|
|
314
|
+
}
|
|
315
|
+
__name(getLearnings, "getLearnings");
|
|
316
|
+
async function recordViolation(violation, workspaceRoot) {
|
|
317
|
+
await appendVrekoJsonl("patterns/violations.jsonl", violation, workspaceRoot);
|
|
318
|
+
}
|
|
319
|
+
__name(recordViolation, "recordViolation");
|
|
320
|
+
async function getViolations(workspaceRoot) {
|
|
321
|
+
const data = await loadVrekoJsonl("patterns/violations.jsonl", workspaceRoot);
|
|
322
|
+
return data.filter((item) => ViolationEntrySchema.safeParse(item).success);
|
|
323
|
+
}
|
|
324
|
+
__name(getViolations, "getViolations");
|
|
325
|
+
async function getCredentials() {
|
|
326
|
+
try {
|
|
327
|
+
const { getCredentialsSecure } = await import('./secure-credentials-JXWAQLS2.js');
|
|
328
|
+
return await getCredentialsSecure();
|
|
329
|
+
} catch {
|
|
330
|
+
return readGlobalJson("credentials.json");
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
__name(getCredentials, "getCredentials");
|
|
334
|
+
async function saveCredentials(credentials) {
|
|
335
|
+
try {
|
|
336
|
+
const { saveCredentialsSecure, getSecureCredentials } = await import('./secure-credentials-JXWAQLS2.js');
|
|
337
|
+
await saveCredentialsSecure(credentials);
|
|
338
|
+
const providerName = getSecureCredentials().getProviderName();
|
|
339
|
+
const backend = providerName.includes("keytar") || providerName.includes("keychain") ? "keychain" : "encrypted-file";
|
|
340
|
+
return {
|
|
341
|
+
backend,
|
|
342
|
+
secure: true
|
|
343
|
+
};
|
|
344
|
+
} catch (error) {
|
|
345
|
+
const downgradeReason = error instanceof Error ? error.message : String(error);
|
|
346
|
+
await createGlobalDirectory();
|
|
347
|
+
await writeGlobalJson("credentials.json", credentials, 384);
|
|
348
|
+
return {
|
|
349
|
+
backend: "plaintext-file",
|
|
350
|
+
secure: false,
|
|
351
|
+
downgradeReason
|
|
352
|
+
};
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
__name(saveCredentials, "saveCredentials");
|
|
356
|
+
async function clearCredentials() {
|
|
357
|
+
try {
|
|
358
|
+
const { clearCredentialsSecure } = await import('./secure-credentials-JXWAQLS2.js');
|
|
359
|
+
return await clearCredentialsSecure();
|
|
360
|
+
} catch {
|
|
361
|
+
await deleteGlobalJson("credentials.json");
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
__name(clearCredentials, "clearCredentials");
|
|
365
|
+
async function getGlobalConfig() {
|
|
366
|
+
const data = await readGlobalJson("config.json");
|
|
367
|
+
if (!data) {
|
|
368
|
+
return null;
|
|
369
|
+
}
|
|
370
|
+
const result = GlobalConfigSchema.safeParse(data);
|
|
371
|
+
return result.success ? result.data : null;
|
|
372
|
+
}
|
|
373
|
+
__name(getGlobalConfig, "getGlobalConfig");
|
|
374
|
+
async function saveGlobalConfig(config) {
|
|
375
|
+
await createGlobalDirectory();
|
|
376
|
+
await writeGlobalJson("config.json", config);
|
|
377
|
+
}
|
|
378
|
+
__name(saveGlobalConfig, "saveGlobalConfig");
|
|
379
|
+
async function saveBenchmarkOptIn(optedIn) {
|
|
380
|
+
await createGlobalDirectory();
|
|
381
|
+
let existing = {};
|
|
382
|
+
try {
|
|
383
|
+
const raw = await readGlobalJson("config.json");
|
|
384
|
+
if (raw !== null) {
|
|
385
|
+
existing = raw;
|
|
386
|
+
}
|
|
387
|
+
} catch {
|
|
388
|
+
}
|
|
389
|
+
existing.benchmarks = {
|
|
390
|
+
...existing.benchmarks ?? {},
|
|
391
|
+
optIn: optedIn
|
|
392
|
+
};
|
|
393
|
+
await writeGlobalJson("config.json", existing);
|
|
394
|
+
}
|
|
395
|
+
__name(saveBenchmarkOptIn, "saveBenchmarkOptIn");
|
|
396
|
+
async function findWorkspaceRoot(startDir) {
|
|
397
|
+
let currentDir = startDir || process.cwd();
|
|
398
|
+
const maxDepth = 10;
|
|
399
|
+
let depth = 0;
|
|
400
|
+
while (depth < maxDepth) {
|
|
401
|
+
try {
|
|
402
|
+
await access(join(currentDir, VREKO_DIR), constants.F_OK);
|
|
403
|
+
return currentDir;
|
|
404
|
+
} catch {
|
|
405
|
+
}
|
|
406
|
+
try {
|
|
407
|
+
await access(join(currentDir, "package.json"), constants.F_OK);
|
|
408
|
+
return currentDir;
|
|
409
|
+
} catch {
|
|
410
|
+
}
|
|
411
|
+
const parentDir = dirname(currentDir);
|
|
412
|
+
if (parentDir === currentDir) {
|
|
413
|
+
break;
|
|
414
|
+
}
|
|
415
|
+
currentDir = parentDir;
|
|
416
|
+
depth++;
|
|
417
|
+
}
|
|
418
|
+
return null;
|
|
419
|
+
}
|
|
420
|
+
__name(findWorkspaceRoot, "findWorkspaceRoot");
|
|
421
|
+
async function pathExists(path) {
|
|
422
|
+
try {
|
|
423
|
+
await access(path, constants.F_OK);
|
|
424
|
+
return true;
|
|
425
|
+
} catch {
|
|
426
|
+
return false;
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
__name(pathExists, "pathExists");
|
|
430
|
+
async function getStats(path) {
|
|
431
|
+
try {
|
|
432
|
+
const stats = await stat(path);
|
|
433
|
+
return {
|
|
434
|
+
size: stats.size,
|
|
435
|
+
modifiedAt: stats.mtime
|
|
436
|
+
};
|
|
437
|
+
} catch {
|
|
438
|
+
return null;
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
__name(getStats, "getStats");
|
|
442
|
+
|
|
443
|
+
export { GlobalConfigSchema, GlobalCredentialsSchema, LearningEntrySchema, ProtectedFileSchema, SessionStateSchema, ViolationEntrySchema, WorkspaceConfigSchema, WorkspaceVitalsSchema, appendVrekoJsonl, clearCredentials, createGlobalDirectory, createVrekoDirectory, deleteGlobalJson, endCurrentSession, findWorkspaceRoot, getCredentials, getCurrentSession, getGlobalConfig, getGlobalDir, getGlobalPath, getLearnings, getProtectedFiles, getStats, getViolations, getWorkspaceConfig, getWorkspaceDir, getWorkspacePath, getWorkspaceVitals, isLoggedIn, isVrekoInitialized, loadVrekoJsonl, pathExists, readGlobalJson, readVrekoJson, recordLearning, recordViolation, saveBenchmarkOptIn, saveCredentials, saveCurrentSession, saveGlobalConfig, saveProtectedFiles, saveWorkspaceConfig, saveWorkspaceVitals, writeGlobalJson, writeVrekoJson };
|
|
444
|
+
//# sourceMappingURL=chunk-HFQHU5LC.js.map
|
|
445
|
+
//# sourceMappingURL=chunk-HFQHU5LC.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/services/vreko-dir.ts"],"names":["VREKO_DIR","GLOBAL_VREKO_DIR","WorkspaceConfigSchema","z","object","workspaceId","string","optional","tier","enum","protectionLevel","syncEnabled","boolean","createdAt","updatedAt","WorkspaceVitalsSchema","framework","frameworkConfidence","number","packageManager","typescript","enabled","strict","version","criticalFiles","array","detectedAt","ProtectedFileSchema","pattern","addedAt","reason","SessionStateSchema","id","task","startedAt","snapshotCount","filesModified","state","active","LearningEntrySchema","type","trigger","action","source","ViolationEntrySchema","file","message","count","date","prevention","GlobalCredentialsSchema","accessToken","refreshToken","email","expiresAt","GlobalConfigSchema","apiUrl","defaultWorkspace","analytics","getGlobalDir","join","homedir","getWorkspaceDir","workspaceRoot","process","cwd","getGlobalPath","relativePath","getWorkspacePath","createVrekoDirectory","baseDir","dirs","dir","mkdir","recursive","gitignore","trim","writeFile","createGlobalDirectory","isVrekoInitialized","dirPath","access","constants","F_OK","isLoggedIn","credentials","getCredentials","Date","readVrekoJson","content","readFile","JSON","parse","writeVrekoJson","data","fullPath","dirname","stringify","appendVrekoJsonl","appendFile","loadVrekoJsonl","split","filter","line","map","readGlobalJson","writeGlobalJson","mode","undefined","deleteGlobalJson","unlink","getWorkspaceConfig","result","safeParse","success","saveWorkspaceConfig","config","getWorkspaceVitals","saveWorkspaceVitals","vitals","getProtectedFiles","saveProtectedFiles","files","getCurrentSession","saveCurrentSession","session","endCurrentSession","recordLearning","learning","getLearnings","item","recordViolation","violation","getViolations","getCredentialsSecure","saveCredentials","saveCredentialsSecure","getSecureCredentials","providerName","getProviderName","backend","includes","secure","error","downgradeReason","Error","String","clearCredentials","clearCredentialsSecure","getGlobalConfig","saveGlobalConfig","saveBenchmarkOptIn","optedIn","existing","raw","benchmarks","optIn","findWorkspaceRoot","startDir","currentDir","maxDepth","depth","parentDir","pathExists","path","getStats","stats","stat","size","modifiedAt","mtime"],"mappings":"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","file":"chunk-HFQHU5LC.js","sourcesContent":["/**\n * Vreko Directory Service\n *\n * Manages .vreko/ workspace directory and ~/.vreko/ global directory.\n * This is the foundation for CLI commands that need persistent storage.\n *\n * Storage Architecture:\n * - ~/.vreko/ (GLOBAL) - credentials, user config, MCP configs\n * - .vreko/ (WORKSPACE) - patterns, learnings, session, snapshots\n *\n * @see implementation_plan.md Section 1.3\n */\n\nimport { access, appendFile, constants, mkdir, readFile, stat, writeFile } from \"node:fs/promises\";\nimport { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\nimport { z } from \"zod\";\n\n// =============================================================================\n// CONSTANTS\n// =============================================================================\n\nconst VREKO_DIR = \".vreko\";\nconst GLOBAL_VREKO_DIR = \".vreko\";\n\n// =============================================================================\n// ZOD SCHEMAS (Runtime validation)\n// =============================================================================\n\nexport const WorkspaceConfigSchema = z.object({\n\tworkspaceId: z.string().optional(),\n\ttier: z.enum([\"free\", \"pro\"]).optional(),\n\tprotectionLevel: z.enum([\"standard\", \"strict\"]).optional(),\n\tsyncEnabled: z.boolean().optional(),\n\tcreatedAt: z.string(),\n\tupdatedAt: z.string(),\n});\n\nexport const WorkspaceVitalsSchema = z.object({\n\tframework: z.string().optional(),\n\tframeworkConfidence: z.number().optional(),\n\tpackageManager: z.enum([\"npm\", \"pnpm\", \"yarn\", \"bun\"]).optional(),\n\ttypescript: z\n\t\t.object({\n\t\t\tenabled: z.boolean(),\n\t\t\tstrict: z.boolean().optional(),\n\t\t\tversion: z.string().optional(),\n\t\t})\n\t\t.optional(),\n\tcriticalFiles: z.array(z.string()).optional(),\n\tdetectedAt: z.string(),\n});\n\nexport const ProtectedFileSchema = z.object({\n\tpattern: z.string(),\n\taddedAt: z.string(),\n\treason: z.string().optional(),\n});\n\nexport const SessionStateSchema = z.object({\n\tid: z.string(),\n\ttask: z.string().optional(),\n\tstartedAt: z.string(),\n\tsnapshotCount: z.number(),\n\tfilesModified: z.number().optional(),\n\tstate: z.enum([\"active\", \"ended\"]).optional(),\n\tactive: z.boolean().optional(),\n});\n\nexport const LearningEntrySchema = z.object({\n\tid: z.string(),\n\ttype: z.enum([\"pattern\", \"pitfall\", \"efficiency\", \"discovery\", \"workflow\"]),\n\ttrigger: z.string(),\n\taction: z.string(),\n\tsource: z.string(),\n\tcreatedAt: z.string(),\n});\n\nexport const ViolationEntrySchema = z.object({\n\ttype: z.string(),\n\tfile: z.string(),\n\tmessage: z.string(),\n\tcount: z.number().optional(),\n\tdate: z.string(),\n\tprevention: z.string().optional(),\n});\n\nexport const GlobalCredentialsSchema = z.object({\n\taccessToken: z.string(),\n\trefreshToken: z.string().optional(),\n\temail: z.string(),\n\ttier: z.enum([\"free\", \"pro\"]),\n\texpiresAt: z.string().optional(),\n});\n\nexport const GlobalConfigSchema = z.object({\n\tapiUrl: z.string().optional(),\n\tdefaultWorkspace: z.string().optional(),\n\tanalytics: z.boolean().optional(),\n});\n\n// =============================================================================\n// TYPE DEFINITIONS (derived from schemas)\n// =============================================================================\n\nexport interface WorkspaceConfig {\n\tworkspaceId?: string;\n\ttier?: \"free\" | \"pro\";\n\t/**\n\t * CLI protection preset - user-friendly abstraction layer.\n\t *\n\t * Maps to canonical ProtectionLevel values (@vreko/contracts):\n\t * - \"standard\" → \"watch\" (auto-snapshot, warn on risky changes)\n\t * - \"strict\" → \"block\" (confirmation required, block high-risk)\n\t *\n\t * The CLI uses presets for better UX, while internal operations\n\t * use the canonical \"watch\" | \"warn\" | \"block\" values.\n\t */\n\tprotectionLevel?: \"standard\" | \"strict\";\n\tsyncEnabled?: boolean;\n\tcreatedAt: string;\n\tupdatedAt: string;\n}\n\nexport interface WorkspaceVitals {\n\tframework?: string;\n\tframeworkConfidence?: number;\n\tpackageManager?: \"npm\" | \"pnpm\" | \"yarn\" | \"bun\";\n\ttypescript?: {\n\t\tenabled: boolean;\n\t\tstrict?: boolean;\n\t\tversion?: string;\n\t};\n\tcriticalFiles?: string[];\n\tdetectedAt: string;\n}\n\nexport interface ProtectedFile {\n\tpattern: string;\n\taddedAt: string;\n\treason?: string;\n}\n\nexport interface SessionState {\n\tid: string;\n\ttask?: string;\n\tstartedAt: string;\n\tsnapshotCount: number;\n\tfilesModified?: number;\n\t/** Daemon-compatible state field - written on session start for pulse fallback */\n\tstate?: \"active\" | \"ended\";\n\t/** Legacy boolean alias - written alongside state for isActiveSession() compatibility */\n\tactive?: boolean;\n}\n\nexport interface LearningEntry {\n\tid: string;\n\ttype: \"pattern\" | \"pitfall\" | \"efficiency\" | \"discovery\" | \"workflow\";\n\ttrigger: string;\n\taction: string;\n\tsource: string;\n\tcreatedAt: string;\n}\n\nexport interface ViolationEntry {\n\ttype: string;\n\tfile: string;\n\tmessage: string;\n\tcount?: number;\n\tdate: string;\n\tprevention?: string;\n}\n\nexport interface GlobalCredentials {\n\taccessToken: string;\n\trefreshToken?: string;\n\temail: string;\n\ttier: \"free\" | \"pro\";\n\texpiresAt?: string;\n}\n\nexport interface GlobalConfig {\n\tapiUrl?: string;\n\tdefaultWorkspace?: string;\n\tanalytics?: boolean;\n}\n\n// =============================================================================\n// PATH HELPERS\n// =============================================================================\n\n/**\n * Get global vreko directory path (~/.vreko/)\n */\nexport function getGlobalDir(): string {\n\treturn join(homedir(), GLOBAL_VREKO_DIR);\n}\n\n/**\n * Get workspace vreko directory path\n */\nexport function getWorkspaceDir(workspaceRoot?: string): string {\n\treturn join(workspaceRoot || process.cwd(), VREKO_DIR);\n}\n\n/**\n * Get path to a file in the global directory\n */\nexport function getGlobalPath(relativePath: string): string {\n\treturn join(getGlobalDir(), relativePath);\n}\n\n/**\n * Get path to a file in the workspace directory\n */\nexport function getWorkspacePath(relativePath: string, workspaceRoot?: string): string {\n\treturn join(getWorkspaceDir(workspaceRoot), relativePath);\n}\n\n// =============================================================================\n// DIRECTORY MANAGEMENT\n// =============================================================================\n\n/**\n * Create the .vreko/ directory structure in a workspace\n * Mirrors the structure expected by MCP server (context-tools.ts)\n */\nexport async function createVrekoDirectory(workspaceRoot?: string): Promise<void> {\n\tconst baseDir = getWorkspaceDir(workspaceRoot);\n\n\tconst dirs = [\"\", \"patterns\", \"learnings\", \"session\", \"snapshots\"];\n\n\tfor (const dir of dirs) {\n\t\tawait mkdir(join(baseDir, dir), { recursive: true });\n\t}\n\n\t// Create .gitignore to exclude snapshots but keep patterns\n\tconst gitignore = `# Vreko Directory\n# Ignore snapshot content (large binary data)\nsnapshots/\nembeddings.db\n\n# Keep these for team sharing\n!patterns/\n!learnings/\n!vitals.json\n!config.json\n!protected.json\n`.trim();\n\n\tawait writeFile(join(baseDir, \".gitignore\"), gitignore);\n}\n\n/**\n * Create the global ~/.vreko/ directory structure\n */\nexport async function createGlobalDirectory(): Promise<void> {\n\tconst baseDir = getGlobalDir();\n\n\tconst dirs = [\"\", \"cache\", \"mcp-configs\"];\n\n\tfor (const dir of dirs) {\n\t\tawait mkdir(join(baseDir, dir), { recursive: true });\n\t}\n}\n\n/**\n * Check if .vreko/ directory exists in workspace\n */\nexport async function isVrekoInitialized(workspaceRoot?: string): Promise<boolean> {\n\ttry {\n\t\tconst dirPath = getWorkspaceDir(workspaceRoot);\n\t\tawait access(dirPath, constants.F_OK);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Check if user is logged in (has credentials)\n */\nexport async function isLoggedIn(): Promise<boolean> {\n\ttry {\n\t\tconst credentials = await getCredentials();\n\t\tif (!credentials?.accessToken) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// Check if token is expired\n\t\tif (credentials.expiresAt) {\n\t\t\tconst expiresAt = new Date(credentials.expiresAt);\n\t\t\tif (expiresAt < new Date()) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n// =============================================================================\n// JSON FILE OPERATIONS - WORKSPACE\n// =============================================================================\n\n/**\n * Read JSON file from .vreko/\n */\nexport async function readVrekoJson<T>(relativePath: string, workspaceRoot?: string): Promise<T | null> {\n\ttry {\n\t\tconst content = await readFile(getWorkspacePath(relativePath, workspaceRoot), \"utf-8\");\n\t\treturn JSON.parse(content) as T;\n\t} catch {\n\t\treturn null;\n\t}\n}\n\n/**\n * Write JSON file to .vreko/\n */\nexport async function writeVrekoJson<T>(relativePath: string, data: T, workspaceRoot?: string): Promise<void> {\n\tconst fullPath = getWorkspacePath(relativePath, workspaceRoot);\n\tawait mkdir(dirname(fullPath), { recursive: true });\n\tawait writeFile(fullPath, JSON.stringify(data, null, 2));\n}\n\n/**\n * Append to JSONL file in .vreko/\n */\nexport async function appendVrekoJsonl<T extends object>(\n\trelativePath: string,\n\tdata: T,\n\tworkspaceRoot?: string,\n): Promise<void> {\n\tconst fullPath = getWorkspacePath(relativePath, workspaceRoot);\n\tawait mkdir(dirname(fullPath), { recursive: true });\n\tawait appendFile(fullPath, `${JSON.stringify(data)}\\n`);\n}\n\n/**\n * Load JSONL file from .vreko/\n */\nexport async function loadVrekoJsonl<T>(relativePath: string, workspaceRoot?: string): Promise<T[]> {\n\ttry {\n\t\tconst content = await readFile(getWorkspacePath(relativePath, workspaceRoot), \"utf-8\");\n\t\treturn content\n\t\t\t.split(\"\\n\")\n\t\t\t.filter((line) => line.trim())\n\t\t\t.map((line) => JSON.parse(line) as T);\n\t} catch {\n\t\treturn [];\n\t}\n}\n\n// =============================================================================\n// JSON FILE OPERATIONS - GLOBAL\n// =============================================================================\n\n/**\n * Read JSON file from ~/.vreko/\n */\nexport async function readGlobalJson<T>(relativePath: string): Promise<T | null> {\n\ttry {\n\t\tconst content = await readFile(getGlobalPath(relativePath), \"utf-8\");\n\t\treturn JSON.parse(content) as T;\n\t} catch {\n\t\treturn null;\n\t}\n}\n\n/**\n * Write JSON file to ~/.vreko/\n *\n * @param mode optional file mode. Pass 0o600 for secrets so a plaintext fallback\n * is at least owner-only readable (AUTH-06 / F-8).\n */\nexport async function writeGlobalJson<T>(relativePath: string, data: T, mode?: number): Promise<void> {\n\tconst fullPath = getGlobalPath(relativePath);\n\tawait mkdir(dirname(fullPath), { recursive: true });\n\tawait writeFile(fullPath, JSON.stringify(data, null, 2), mode !== undefined ? { mode } : undefined);\n}\n\n/**\n * Delete JSON file from ~/.vreko/\n */\nexport async function deleteGlobalJson(relativePath: string): Promise<void> {\n\tconst fullPath = getGlobalPath(relativePath);\n\ttry {\n\t\tconst { unlink } = await import(\"node:fs/promises\");\n\t\tawait unlink(fullPath);\n\t} catch {\n\t\t// File doesn't exist, that's fine\n\t}\n}\n\n// =============================================================================\n// TYPED ACCESSORS\n// =============================================================================\n\n/**\n * Get workspace configuration with Zod validation\n */\nexport async function getWorkspaceConfig(workspaceRoot?: string): Promise<WorkspaceConfig | null> {\n\tconst data = await readVrekoJson<unknown>(\"config.json\", workspaceRoot);\n\tif (!data) {\n\t\treturn null;\n\t}\n\tconst result = WorkspaceConfigSchema.safeParse(data);\n\treturn result.success ? result.data : null;\n}\n\n/**\n * Save workspace configuration\n */\nexport async function saveWorkspaceConfig(config: WorkspaceConfig, workspaceRoot?: string): Promise<void> {\n\tawait writeVrekoJson(\"config.json\", config, workspaceRoot);\n}\n\n/**\n * Get workspace vitals with Zod validation\n */\nexport async function getWorkspaceVitals(workspaceRoot?: string): Promise<WorkspaceVitals | null> {\n\tconst data = await readVrekoJson<unknown>(\"vitals.json\", workspaceRoot);\n\tif (!data) {\n\t\treturn null;\n\t}\n\tconst result = WorkspaceVitalsSchema.safeParse(data);\n\treturn result.success ? result.data : null;\n}\n\n/**\n * Save workspace vitals\n */\nexport async function saveWorkspaceVitals(vitals: WorkspaceVitals, workspaceRoot?: string): Promise<void> {\n\tawait writeVrekoJson(\"vitals.json\", vitals, workspaceRoot);\n}\n\n/**\n * Get protected files list with Zod validation\n */\nexport async function getProtectedFiles(workspaceRoot?: string): Promise<ProtectedFile[]> {\n\tconst data = await readVrekoJson<unknown[]>(\"protected.json\", workspaceRoot);\n\tif (!data) {\n\t\treturn [];\n\t}\n\tconst result = z.array(ProtectedFileSchema).safeParse(data);\n\treturn result.success ? result.data : [];\n}\n\n/**\n * Save protected files list\n */\nexport async function saveProtectedFiles(files: ProtectedFile[], workspaceRoot?: string): Promise<void> {\n\tawait writeVrekoJson(\"protected.json\", files, workspaceRoot);\n}\n\n/**\n * Get current session state with Zod validation\n */\nexport async function getCurrentSession(workspaceRoot?: string): Promise<SessionState | null> {\n\tconst data = await readVrekoJson<unknown>(\"session/current.json\", workspaceRoot);\n\tif (!data) {\n\t\treturn null;\n\t}\n\tconst result = SessionStateSchema.safeParse(data);\n\treturn result.success ? result.data : null;\n}\n\n/**\n * Save current session state\n */\nexport async function saveCurrentSession(session: SessionState, workspaceRoot?: string): Promise<void> {\n\tawait writeVrekoJson(\"session/current.json\", session, workspaceRoot);\n}\n\n/**\n * End current session (delete current.json)\n */\nexport async function endCurrentSession(workspaceRoot?: string): Promise<void> {\n\tconst fullPath = getWorkspacePath(\"session/current.json\", workspaceRoot);\n\ttry {\n\t\tconst { unlink } = await import(\"node:fs/promises\");\n\t\tawait unlink(fullPath);\n\t} catch {\n\t\t// File doesn't exist, that's fine\n\t}\n}\n\n/**\n * Record a learning\n */\nexport async function recordLearning(learning: LearningEntry, workspaceRoot?: string): Promise<void> {\n\tawait appendVrekoJsonl(\"learnings/user-learnings.jsonl\", learning, workspaceRoot);\n}\n\n/**\n * Get all learnings with Zod validation\n */\nexport async function getLearnings(workspaceRoot?: string): Promise<LearningEntry[]> {\n\tconst data = await loadVrekoJsonl<unknown>(\"learnings/user-learnings.jsonl\", workspaceRoot);\n\treturn data.filter((item): item is LearningEntry => LearningEntrySchema.safeParse(item).success);\n}\n\n/**\n * Record a violation\n */\nexport async function recordViolation(violation: ViolationEntry, workspaceRoot?: string): Promise<void> {\n\tawait appendVrekoJsonl(\"patterns/violations.jsonl\", violation, workspaceRoot);\n}\n\n/**\n * Get all violations with Zod validation\n */\nexport async function getViolations(workspaceRoot?: string): Promise<ViolationEntry[]> {\n\tconst data = await loadVrekoJsonl<unknown>(\"patterns/violations.jsonl\", workspaceRoot);\n\treturn data.filter((item): item is ViolationEntry => ViolationEntrySchema.safeParse(item).success);\n}\n\n/**\n * Get credentials\n * @deprecated Use getCredentialsSecure from secure-credentials.ts for production\n */\nexport async function getCredentials(): Promise<GlobalCredentials | null> {\n\t// Try secure credentials first, fall back to legacy\n\ttry {\n\t\tconst { getCredentialsSecure } = await import(\"./secure-credentials\");\n\t\treturn await getCredentialsSecure();\n\t} catch {\n\t\t// Fallback to legacy plain text (development mode)\n\t\treturn readGlobalJson<GlobalCredentials>(\"credentials.json\");\n\t}\n}\n\n/**\n * Result of a credential save, describing which backend actually stored the\n * credential. Callers MUST gate any \"stored securely\" messaging on `secure`\n * and surface a downgrade warning when it is false (AUTH-06 / F-7+F-8).\n */\nexport interface CredentialStorageResult {\n\t/** The backend that stored the credential. */\n\tbackend: \"keychain\" | \"encrypted-file\" | \"plaintext-file\";\n\t/** True only for keychain or encrypted-file; false for the plaintext fallback. */\n\tsecure: boolean;\n\t/** Populated when the secure path failed and we fell back to plaintext. */\n\tdowngradeReason?: string;\n}\n\n/**\n * Save credentials\n * @deprecated Use saveCredentialsSecure from secure-credentials.ts for production\n */\nexport async function saveCredentials(credentials: GlobalCredentials): Promise<CredentialStorageResult> {\n\t// Try secure credentials first, fall back to legacy\n\ttry {\n\t\tconst { saveCredentialsSecure, getSecureCredentials } = await import(\"./secure-credentials\");\n\t\tawait saveCredentialsSecure(credentials);\n\t\tconst providerName = getSecureCredentials().getProviderName();\n\t\t// keytar names itself \"keytar\"/keychain; otherwise the encrypted-file backend.\n\t\tconst backend =\n\t\t\tproviderName.includes(\"keytar\") || providerName.includes(\"keychain\") ? \"keychain\" : \"encrypted-file\";\n\t\treturn { backend, secure: true };\n\t} catch (error) {\n\t\t// Secure backends unavailable - downgrade to a restricted-permission (0o600)\n\t\t// plaintext file and report the downgrade honestly so the caller does NOT\n\t\t// claim secure storage (AP-3: never swallow this silently).\n\t\tconst downgradeReason = error instanceof Error ? error.message : String(error);\n\t\tawait createGlobalDirectory();\n\t\tawait writeGlobalJson(\"credentials.json\", credentials, 0o600);\n\t\treturn { backend: \"plaintext-file\", secure: false, downgradeReason };\n\t}\n}\n\n/**\n * Clear credentials (logout)\n * @deprecated Use clearCredentialsSecure from secure-credentials.ts for production\n */\nexport async function clearCredentials(): Promise<void> {\n\t// Try secure credentials first, fall back to legacy\n\ttry {\n\t\tconst { clearCredentialsSecure } = await import(\"./secure-credentials\");\n\t\treturn await clearCredentialsSecure();\n\t} catch {\n\t\t// Fallback to legacy plain text (development mode)\n\t\tawait deleteGlobalJson(\"credentials.json\");\n\t}\n}\n\n/**\n * Get global config with Zod validation\n */\nexport async function getGlobalConfig(): Promise<GlobalConfig | null> {\n\tconst data = await readGlobalJson<unknown>(\"config.json\");\n\tif (!data) {\n\t\treturn null;\n\t}\n\tconst result = GlobalConfigSchema.safeParse(data);\n\treturn result.success ? result.data : null;\n}\n\n/**\n * Save global config\n */\nexport async function saveGlobalConfig(config: GlobalConfig): Promise<void> {\n\tawait createGlobalDirectory();\n\tawait writeGlobalJson(\"config.json\", config);\n}\n\n/**\n * Persist the user's benchmark opt-in decision to ~/.vreko/config.json.\n *\n * Merges into existing config so other keys (e.g. daemon.idleTimeout) are preserved.\n * Creates ~/.vreko/config.json if it does not exist.\n */\nexport async function saveBenchmarkOptIn(optedIn: boolean): Promise<void> {\n\tawait createGlobalDirectory();\n\n\tlet existing: Record<string, unknown> = {};\n\ttry {\n\t\tconst raw = await readGlobalJson<Record<string, unknown>>(\"config.json\");\n\t\tif (raw !== null) {\n\t\t\texisting = raw;\n\t\t}\n\t} catch {\n\t\t// File doesn't exist or is unparseable - start fresh\n\t}\n\n\texisting.benchmarks = {\n\t\t...((existing.benchmarks as Record<string, unknown>) ?? {}),\n\t\toptIn: optedIn,\n\t};\n\n\tawait writeGlobalJson(\"config.json\", existing);\n}\n\n// =============================================================================\n// UTILITY FUNCTIONS\n// =============================================================================\n\n// Re-export generateId from @vreko/contracts for backwards compatibility\nexport { generateId } from \"@vreko/contracts/id-generator\";\n\n/**\n * Get workspace root by searching for .vreko/ or package.json\n */\nexport async function findWorkspaceRoot(startDir?: string): Promise<string | null> {\n\tlet currentDir = startDir || process.cwd();\n\n\t// Limit search depth to prevent infinite loops\n\tconst maxDepth = 10;\n\tlet depth = 0;\n\n\twhile (depth < maxDepth) {\n\t\t// Check for .vreko directory\n\t\ttry {\n\t\t\tawait access(join(currentDir, VREKO_DIR), constants.F_OK);\n\t\t\treturn currentDir;\n\t\t} catch {\n\t\t\t// Not found, continue\n\t\t}\n\n\t\t// Check for package.json (workspace root indicator)\n\t\ttry {\n\t\t\tawait access(join(currentDir, \"package.json\"), constants.F_OK);\n\t\t\treturn currentDir;\n\t\t} catch {\n\t\t\t// Not found, continue\n\t\t}\n\n\t\t// Move up one directory\n\t\tconst parentDir = dirname(currentDir);\n\t\tif (parentDir === currentDir) {\n\t\t\t// Reached root\n\t\t\tbreak;\n\t\t}\n\t\tcurrentDir = parentDir;\n\t\tdepth++;\n\t}\n\n\treturn null;\n}\n\n/**\n * Check if a path exists\n */\nexport async function pathExists(path: string): Promise<boolean> {\n\ttry {\n\t\tawait access(path, constants.F_OK);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Get file stats\n */\nexport async function getStats(path: string): Promise<{ size: number; modifiedAt: Date } | null> {\n\ttry {\n\t\tconst stats = await stat(path);\n\t\treturn {\n\t\t\tsize: stats.size,\n\t\t\tmodifiedAt: stats.mtime,\n\t\t};\n\t} catch {\n\t\treturn null;\n\t}\n}\n"]}
|