@tostudy-ai/cli 0.13.0 → 0.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/tostudy.ts +2 -0
- package/dist/cli.js +1003 -660
- package/dist/cli.js.map +4 -4
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -41,137 +41,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
41
41
|
mod
|
|
42
42
|
));
|
|
43
43
|
|
|
44
|
-
// ../../node_modules/
|
|
45
|
-
var require_picocolors = __commonJS({
|
|
46
|
-
"../../node_modules/picocolors/picocolors.js"(exports, module) {
|
|
47
|
-
var p = process || {};
|
|
48
|
-
var argv = p.argv || [];
|
|
49
|
-
var env = p.env || {};
|
|
50
|
-
var isColorSupported = !(!!env.NO_COLOR || argv.includes("--no-color")) && (!!env.FORCE_COLOR || argv.includes("--color") || p.platform === "win32" || (p.stdout || {}).isTTY && env.TERM !== "dumb" || !!env.CI);
|
|
51
|
-
var formatter = (open, close, replace = open) => (input2) => {
|
|
52
|
-
let string4 = "" + input2, index2 = string4.indexOf(close, open.length);
|
|
53
|
-
return ~index2 ? open + replaceClose(string4, close, replace, index2) + close : open + string4 + close;
|
|
54
|
-
};
|
|
55
|
-
var replaceClose = (string4, close, replace, index2) => {
|
|
56
|
-
let result = "", cursor = 0;
|
|
57
|
-
do {
|
|
58
|
-
result += string4.substring(cursor, index2) + replace;
|
|
59
|
-
cursor = index2 + close.length;
|
|
60
|
-
index2 = string4.indexOf(close, cursor);
|
|
61
|
-
} while (~index2);
|
|
62
|
-
return result + string4.substring(cursor);
|
|
63
|
-
};
|
|
64
|
-
var createColors = (enabled = isColorSupported) => {
|
|
65
|
-
let f = enabled ? formatter : () => String;
|
|
66
|
-
return {
|
|
67
|
-
isColorSupported: enabled,
|
|
68
|
-
reset: f("\x1B[0m", "\x1B[0m"),
|
|
69
|
-
bold: f("\x1B[1m", "\x1B[22m", "\x1B[22m\x1B[1m"),
|
|
70
|
-
dim: f("\x1B[2m", "\x1B[22m", "\x1B[22m\x1B[2m"),
|
|
71
|
-
italic: f("\x1B[3m", "\x1B[23m"),
|
|
72
|
-
underline: f("\x1B[4m", "\x1B[24m"),
|
|
73
|
-
inverse: f("\x1B[7m", "\x1B[27m"),
|
|
74
|
-
hidden: f("\x1B[8m", "\x1B[28m"),
|
|
75
|
-
strikethrough: f("\x1B[9m", "\x1B[29m"),
|
|
76
|
-
black: f("\x1B[30m", "\x1B[39m"),
|
|
77
|
-
red: f("\x1B[31m", "\x1B[39m"),
|
|
78
|
-
green: f("\x1B[32m", "\x1B[39m"),
|
|
79
|
-
yellow: f("\x1B[33m", "\x1B[39m"),
|
|
80
|
-
blue: f("\x1B[34m", "\x1B[39m"),
|
|
81
|
-
magenta: f("\x1B[35m", "\x1B[39m"),
|
|
82
|
-
cyan: f("\x1B[36m", "\x1B[39m"),
|
|
83
|
-
white: f("\x1B[37m", "\x1B[39m"),
|
|
84
|
-
gray: f("\x1B[90m", "\x1B[39m"),
|
|
85
|
-
bgBlack: f("\x1B[40m", "\x1B[49m"),
|
|
86
|
-
bgRed: f("\x1B[41m", "\x1B[49m"),
|
|
87
|
-
bgGreen: f("\x1B[42m", "\x1B[49m"),
|
|
88
|
-
bgYellow: f("\x1B[43m", "\x1B[49m"),
|
|
89
|
-
bgBlue: f("\x1B[44m", "\x1B[49m"),
|
|
90
|
-
bgMagenta: f("\x1B[45m", "\x1B[49m"),
|
|
91
|
-
bgCyan: f("\x1B[46m", "\x1B[49m"),
|
|
92
|
-
bgWhite: f("\x1B[47m", "\x1B[49m"),
|
|
93
|
-
blackBright: f("\x1B[90m", "\x1B[39m"),
|
|
94
|
-
redBright: f("\x1B[91m", "\x1B[39m"),
|
|
95
|
-
greenBright: f("\x1B[92m", "\x1B[39m"),
|
|
96
|
-
yellowBright: f("\x1B[93m", "\x1B[39m"),
|
|
97
|
-
blueBright: f("\x1B[94m", "\x1B[39m"),
|
|
98
|
-
magentaBright: f("\x1B[95m", "\x1B[39m"),
|
|
99
|
-
cyanBright: f("\x1B[96m", "\x1B[39m"),
|
|
100
|
-
whiteBright: f("\x1B[97m", "\x1B[39m"),
|
|
101
|
-
bgBlackBright: f("\x1B[100m", "\x1B[49m"),
|
|
102
|
-
bgRedBright: f("\x1B[101m", "\x1B[49m"),
|
|
103
|
-
bgGreenBright: f("\x1B[102m", "\x1B[49m"),
|
|
104
|
-
bgYellowBright: f("\x1B[103m", "\x1B[49m"),
|
|
105
|
-
bgBlueBright: f("\x1B[104m", "\x1B[49m"),
|
|
106
|
-
bgMagentaBright: f("\x1B[105m", "\x1B[49m"),
|
|
107
|
-
bgCyanBright: f("\x1B[106m", "\x1B[49m"),
|
|
108
|
-
bgWhiteBright: f("\x1B[107m", "\x1B[49m")
|
|
109
|
-
};
|
|
110
|
-
};
|
|
111
|
-
module.exports = createColors();
|
|
112
|
-
module.exports.createColors = createColors;
|
|
113
|
-
}
|
|
114
|
-
});
|
|
115
|
-
|
|
116
|
-
// ../../node_modules/@parisgroup-ai/logger/dist/logger.base-DJVL2Rjl.mjs
|
|
117
|
-
function formatJson(entry) {
|
|
118
|
-
const { timestamp: timestamp2, level, message, service, environment, context, data, error: error49 } = entry;
|
|
119
|
-
const output3 = {
|
|
120
|
-
timestamp: timestamp2,
|
|
121
|
-
level,
|
|
122
|
-
message,
|
|
123
|
-
service,
|
|
124
|
-
environment,
|
|
125
|
-
...context,
|
|
126
|
-
...data
|
|
127
|
-
};
|
|
128
|
-
if (error49) output3.error = error49;
|
|
129
|
-
return JSON.stringify(output3);
|
|
130
|
-
}
|
|
131
|
-
function formatTime(timestamp2) {
|
|
132
|
-
const date6 = new Date(timestamp2);
|
|
133
|
-
return `${String(date6.getUTCHours()).padStart(2, "0")}:${String(date6.getUTCMinutes()).padStart(2, "0")}:${String(date6.getUTCSeconds()).padStart(2, "0")}`;
|
|
134
|
-
}
|
|
135
|
-
function formatLevel(level) {
|
|
136
|
-
const colorFn = LEVEL_COLORS[level];
|
|
137
|
-
return colorFn(level.toUpperCase().padEnd(LEVEL_WIDTH));
|
|
138
|
-
}
|
|
139
|
-
function formatData(data) {
|
|
140
|
-
const entries = Object.entries(data);
|
|
141
|
-
if (entries.length === 0) return "";
|
|
142
|
-
return "\n" + entries.map(([key, value]) => {
|
|
143
|
-
const formatted = typeof value === "object" ? JSON.stringify(value) : String(value);
|
|
144
|
-
return ` ${import_picocolors.default.dim(key + ":")} ${formatted}`;
|
|
145
|
-
}).join("\n");
|
|
146
|
-
}
|
|
147
|
-
function formatPretty(entry) {
|
|
148
|
-
const { timestamp: timestamp2, level, message, service, context, data, error: error49 } = entry;
|
|
149
|
-
const time4 = formatTime(timestamp2);
|
|
150
|
-
const lvl = formatLevel(level);
|
|
151
|
-
const mod = context.module ? import_picocolors.default.dim(`[${context.module}]`) + " " : "";
|
|
152
|
-
const svc = import_picocolors.default.dim(`[${service}]`) + " ";
|
|
153
|
-
let output3 = `${import_picocolors.default.dim(time4)} ${lvl} ${svc}${mod}${message}`;
|
|
154
|
-
const traceInfo = {};
|
|
155
|
-
if (context.traceId) traceInfo.traceId = context.traceId;
|
|
156
|
-
if (context.requestId && context.requestId !== context.traceId) traceInfo.requestId = context.requestId;
|
|
157
|
-
if (context.caller) traceInfo.caller = context.caller;
|
|
158
|
-
if (context.duration !== void 0) traceInfo.duration = `${context.duration}ms`;
|
|
159
|
-
const allData = {
|
|
160
|
-
...traceInfo,
|
|
161
|
-
...data
|
|
162
|
-
};
|
|
163
|
-
if (Object.keys(allData).length > 0) output3 += formatData(allData);
|
|
164
|
-
if (error49) {
|
|
165
|
-
output3 += "\n" + import_picocolors.default.red(` ${error49.name}: ${error49.message}`);
|
|
166
|
-
if (error49.code) output3 += import_picocolors.default.dim(` (${error49.code})`);
|
|
167
|
-
if (error49.stack) {
|
|
168
|
-
const stackLines = error49.stack.split("\n").slice(1, 4);
|
|
169
|
-
output3 += "\n" + stackLines.map((l) => import_picocolors.default.dim(` ${l.trim()}`)).join("\n");
|
|
170
|
-
}
|
|
171
|
-
if (error49.cause) output3 += "\n" + import_picocolors.default.dim(` Caused by: ${error49.cause.name}: ${error49.cause.message}`);
|
|
172
|
-
}
|
|
173
|
-
return output3;
|
|
174
|
-
}
|
|
44
|
+
// ../../node_modules/@parisgroup-ai/logger/dist/sanitize-u1LaSkAO.mjs
|
|
175
45
|
function email(value) {
|
|
176
46
|
if (!value || typeof value !== "string") return "[INVALID_EMAIL]";
|
|
177
47
|
const atIndex = value.indexOf("@");
|
|
@@ -296,42 +166,9 @@ function headers(hdrs) {
|
|
|
296
166
|
for (const key of Object.keys(sanitized)) if (sensitiveHeaders.some((h) => key.toLowerCase() === h)) sanitized[key] = "[REDACTED]";
|
|
297
167
|
return sanitized;
|
|
298
168
|
}
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
message: error49.message
|
|
303
|
-
};
|
|
304
|
-
if (includeStack && error49.stack) info.stack = error49.stack;
|
|
305
|
-
if ("code" in error49 && typeof error49.code === "string") info.code = error49.code;
|
|
306
|
-
visited.add(error49);
|
|
307
|
-
if (error49.cause instanceof Error) if (visited.has(error49.cause)) info.cause = {
|
|
308
|
-
name: error49.cause.name,
|
|
309
|
-
message: "[Circular]"
|
|
310
|
-
};
|
|
311
|
-
else info.cause = extractErrorInfo(error49.cause, includeStack, visited);
|
|
312
|
-
return info;
|
|
313
|
-
}
|
|
314
|
-
var import_picocolors, LOG_LEVELS, LEVEL_COLORS, LEVEL_WIDTH, SENSITIVE_FIELDS, sanitize, BaseLogger;
|
|
315
|
-
var init_logger_base_DJVL2Rjl = __esm({
|
|
316
|
-
"../../node_modules/@parisgroup-ai/logger/dist/logger.base-DJVL2Rjl.mjs"() {
|
|
317
|
-
import_picocolors = __toESM(require_picocolors(), 1);
|
|
318
|
-
LOG_LEVELS = {
|
|
319
|
-
trace: 0,
|
|
320
|
-
debug: 1,
|
|
321
|
-
info: 2,
|
|
322
|
-
warn: 3,
|
|
323
|
-
error: 4,
|
|
324
|
-
fatal: 5
|
|
325
|
-
};
|
|
326
|
-
LEVEL_COLORS = {
|
|
327
|
-
trace: import_picocolors.default.gray,
|
|
328
|
-
debug: import_picocolors.default.cyan,
|
|
329
|
-
info: import_picocolors.default.green,
|
|
330
|
-
warn: import_picocolors.default.yellow,
|
|
331
|
-
error: import_picocolors.default.red,
|
|
332
|
-
fatal: (s) => import_picocolors.default.bgRed(import_picocolors.default.white(s))
|
|
333
|
-
};
|
|
334
|
-
LEVEL_WIDTH = 5;
|
|
169
|
+
var SENSITIVE_FIELDS, sanitize;
|
|
170
|
+
var init_sanitize_u1LaSkAO = __esm({
|
|
171
|
+
"../../node_modules/@parisgroup-ai/logger/dist/sanitize-u1LaSkAO.mjs"() {
|
|
335
172
|
SENSITIVE_FIELDS = [
|
|
336
173
|
"password",
|
|
337
174
|
"senha",
|
|
@@ -398,6 +235,177 @@ var init_logger_base_DJVL2Rjl = __esm({
|
|
|
398
235
|
headers,
|
|
399
236
|
isSensitiveKey
|
|
400
237
|
};
|
|
238
|
+
}
|
|
239
|
+
});
|
|
240
|
+
|
|
241
|
+
// ../../node_modules/picocolors/picocolors.js
|
|
242
|
+
var require_picocolors = __commonJS({
|
|
243
|
+
"../../node_modules/picocolors/picocolors.js"(exports, module) {
|
|
244
|
+
var p = process || {};
|
|
245
|
+
var argv = p.argv || [];
|
|
246
|
+
var env = p.env || {};
|
|
247
|
+
var isColorSupported = !(!!env.NO_COLOR || argv.includes("--no-color")) && (!!env.FORCE_COLOR || argv.includes("--color") || p.platform === "win32" || (p.stdout || {}).isTTY && env.TERM !== "dumb" || !!env.CI);
|
|
248
|
+
var formatter = (open, close, replace = open) => (input2) => {
|
|
249
|
+
let string4 = "" + input2, index2 = string4.indexOf(close, open.length);
|
|
250
|
+
return ~index2 ? open + replaceClose(string4, close, replace, index2) + close : open + string4 + close;
|
|
251
|
+
};
|
|
252
|
+
var replaceClose = (string4, close, replace, index2) => {
|
|
253
|
+
let result = "", cursor = 0;
|
|
254
|
+
do {
|
|
255
|
+
result += string4.substring(cursor, index2) + replace;
|
|
256
|
+
cursor = index2 + close.length;
|
|
257
|
+
index2 = string4.indexOf(close, cursor);
|
|
258
|
+
} while (~index2);
|
|
259
|
+
return result + string4.substring(cursor);
|
|
260
|
+
};
|
|
261
|
+
var createColors = (enabled = isColorSupported) => {
|
|
262
|
+
let f = enabled ? formatter : () => String;
|
|
263
|
+
return {
|
|
264
|
+
isColorSupported: enabled,
|
|
265
|
+
reset: f("\x1B[0m", "\x1B[0m"),
|
|
266
|
+
bold: f("\x1B[1m", "\x1B[22m", "\x1B[22m\x1B[1m"),
|
|
267
|
+
dim: f("\x1B[2m", "\x1B[22m", "\x1B[22m\x1B[2m"),
|
|
268
|
+
italic: f("\x1B[3m", "\x1B[23m"),
|
|
269
|
+
underline: f("\x1B[4m", "\x1B[24m"),
|
|
270
|
+
inverse: f("\x1B[7m", "\x1B[27m"),
|
|
271
|
+
hidden: f("\x1B[8m", "\x1B[28m"),
|
|
272
|
+
strikethrough: f("\x1B[9m", "\x1B[29m"),
|
|
273
|
+
black: f("\x1B[30m", "\x1B[39m"),
|
|
274
|
+
red: f("\x1B[31m", "\x1B[39m"),
|
|
275
|
+
green: f("\x1B[32m", "\x1B[39m"),
|
|
276
|
+
yellow: f("\x1B[33m", "\x1B[39m"),
|
|
277
|
+
blue: f("\x1B[34m", "\x1B[39m"),
|
|
278
|
+
magenta: f("\x1B[35m", "\x1B[39m"),
|
|
279
|
+
cyan: f("\x1B[36m", "\x1B[39m"),
|
|
280
|
+
white: f("\x1B[37m", "\x1B[39m"),
|
|
281
|
+
gray: f("\x1B[90m", "\x1B[39m"),
|
|
282
|
+
bgBlack: f("\x1B[40m", "\x1B[49m"),
|
|
283
|
+
bgRed: f("\x1B[41m", "\x1B[49m"),
|
|
284
|
+
bgGreen: f("\x1B[42m", "\x1B[49m"),
|
|
285
|
+
bgYellow: f("\x1B[43m", "\x1B[49m"),
|
|
286
|
+
bgBlue: f("\x1B[44m", "\x1B[49m"),
|
|
287
|
+
bgMagenta: f("\x1B[45m", "\x1B[49m"),
|
|
288
|
+
bgCyan: f("\x1B[46m", "\x1B[49m"),
|
|
289
|
+
bgWhite: f("\x1B[47m", "\x1B[49m"),
|
|
290
|
+
blackBright: f("\x1B[90m", "\x1B[39m"),
|
|
291
|
+
redBright: f("\x1B[91m", "\x1B[39m"),
|
|
292
|
+
greenBright: f("\x1B[92m", "\x1B[39m"),
|
|
293
|
+
yellowBright: f("\x1B[93m", "\x1B[39m"),
|
|
294
|
+
blueBright: f("\x1B[94m", "\x1B[39m"),
|
|
295
|
+
magentaBright: f("\x1B[95m", "\x1B[39m"),
|
|
296
|
+
cyanBright: f("\x1B[96m", "\x1B[39m"),
|
|
297
|
+
whiteBright: f("\x1B[97m", "\x1B[39m"),
|
|
298
|
+
bgBlackBright: f("\x1B[100m", "\x1B[49m"),
|
|
299
|
+
bgRedBright: f("\x1B[101m", "\x1B[49m"),
|
|
300
|
+
bgGreenBright: f("\x1B[102m", "\x1B[49m"),
|
|
301
|
+
bgYellowBright: f("\x1B[103m", "\x1B[49m"),
|
|
302
|
+
bgBlueBright: f("\x1B[104m", "\x1B[49m"),
|
|
303
|
+
bgMagentaBright: f("\x1B[105m", "\x1B[49m"),
|
|
304
|
+
bgCyanBright: f("\x1B[106m", "\x1B[49m"),
|
|
305
|
+
bgWhiteBright: f("\x1B[107m", "\x1B[49m")
|
|
306
|
+
};
|
|
307
|
+
};
|
|
308
|
+
module.exports = createColors();
|
|
309
|
+
module.exports.createColors = createColors;
|
|
310
|
+
}
|
|
311
|
+
});
|
|
312
|
+
|
|
313
|
+
// ../../node_modules/@parisgroup-ai/logger/dist/logger.base-W8CRO9aE.mjs
|
|
314
|
+
function formatJson(entry) {
|
|
315
|
+
const { timestamp: timestamp2, level, message, service, environment, context, data, error: error49 } = entry;
|
|
316
|
+
const output3 = {
|
|
317
|
+
timestamp: timestamp2,
|
|
318
|
+
level,
|
|
319
|
+
message,
|
|
320
|
+
service,
|
|
321
|
+
environment,
|
|
322
|
+
...context,
|
|
323
|
+
...data
|
|
324
|
+
};
|
|
325
|
+
if (error49) output3.error = error49;
|
|
326
|
+
return JSON.stringify(output3);
|
|
327
|
+
}
|
|
328
|
+
function formatTime(timestamp2) {
|
|
329
|
+
const date6 = new Date(timestamp2);
|
|
330
|
+
return `${String(date6.getUTCHours()).padStart(2, "0")}:${String(date6.getUTCMinutes()).padStart(2, "0")}:${String(date6.getUTCSeconds()).padStart(2, "0")}`;
|
|
331
|
+
}
|
|
332
|
+
function formatLevel(level) {
|
|
333
|
+
const colorFn = LEVEL_COLORS[level];
|
|
334
|
+
return colorFn(level.toUpperCase().padEnd(LEVEL_WIDTH));
|
|
335
|
+
}
|
|
336
|
+
function formatData(data) {
|
|
337
|
+
const entries = Object.entries(data);
|
|
338
|
+
if (entries.length === 0) return "";
|
|
339
|
+
return "\n" + entries.map(([key, value]) => {
|
|
340
|
+
const formatted = typeof value === "object" ? JSON.stringify(value) : String(value);
|
|
341
|
+
return ` ${import_picocolors.default.dim(key + ":")} ${formatted}`;
|
|
342
|
+
}).join("\n");
|
|
343
|
+
}
|
|
344
|
+
function formatPretty(entry) {
|
|
345
|
+
const { timestamp: timestamp2, level, message, service, context, data, error: error49 } = entry;
|
|
346
|
+
const time4 = formatTime(timestamp2);
|
|
347
|
+
const lvl = formatLevel(level);
|
|
348
|
+
const mod = context.module ? import_picocolors.default.dim(`[${context.module}]`) + " " : "";
|
|
349
|
+
const svc = import_picocolors.default.dim(`[${service}]`) + " ";
|
|
350
|
+
let output3 = `${import_picocolors.default.dim(time4)} ${lvl} ${svc}${mod}${message}`;
|
|
351
|
+
const traceInfo = {};
|
|
352
|
+
if (context.traceId) traceInfo.traceId = context.traceId;
|
|
353
|
+
if (context.requestId && context.requestId !== context.traceId) traceInfo.requestId = context.requestId;
|
|
354
|
+
if (context.caller) traceInfo.caller = context.caller;
|
|
355
|
+
if (context.duration !== void 0) traceInfo.duration = `${context.duration}ms`;
|
|
356
|
+
const allData = {
|
|
357
|
+
...traceInfo,
|
|
358
|
+
...data
|
|
359
|
+
};
|
|
360
|
+
if (Object.keys(allData).length > 0) output3 += formatData(allData);
|
|
361
|
+
if (error49) {
|
|
362
|
+
output3 += "\n" + import_picocolors.default.red(` ${error49.name}: ${error49.message}`);
|
|
363
|
+
if (error49.code) output3 += import_picocolors.default.dim(` (${error49.code})`);
|
|
364
|
+
if (error49.stack) {
|
|
365
|
+
const stackLines = error49.stack.split("\n").slice(1, 4);
|
|
366
|
+
output3 += "\n" + stackLines.map((l) => import_picocolors.default.dim(` ${l.trim()}`)).join("\n");
|
|
367
|
+
}
|
|
368
|
+
if (error49.cause) output3 += "\n" + import_picocolors.default.dim(` Caused by: ${error49.cause.name}: ${error49.cause.message}`);
|
|
369
|
+
}
|
|
370
|
+
return output3;
|
|
371
|
+
}
|
|
372
|
+
function extractErrorInfo(error49, includeStack, visited = /* @__PURE__ */ new WeakSet()) {
|
|
373
|
+
const info = {
|
|
374
|
+
name: error49.name,
|
|
375
|
+
message: error49.message
|
|
376
|
+
};
|
|
377
|
+
if (includeStack && error49.stack) info.stack = error49.stack;
|
|
378
|
+
if ("code" in error49 && typeof error49.code === "string") info.code = error49.code;
|
|
379
|
+
visited.add(error49);
|
|
380
|
+
if (error49.cause instanceof Error) if (visited.has(error49.cause)) info.cause = {
|
|
381
|
+
name: error49.cause.name,
|
|
382
|
+
message: "[Circular]"
|
|
383
|
+
};
|
|
384
|
+
else info.cause = extractErrorInfo(error49.cause, includeStack, visited);
|
|
385
|
+
return info;
|
|
386
|
+
}
|
|
387
|
+
var import_picocolors, LOG_LEVELS, LEVEL_COLORS, LEVEL_WIDTH, BaseLogger;
|
|
388
|
+
var init_logger_base_W8CRO9aE = __esm({
|
|
389
|
+
"../../node_modules/@parisgroup-ai/logger/dist/logger.base-W8CRO9aE.mjs"() {
|
|
390
|
+
init_sanitize_u1LaSkAO();
|
|
391
|
+
import_picocolors = __toESM(require_picocolors(), 1);
|
|
392
|
+
LOG_LEVELS = {
|
|
393
|
+
trace: 0,
|
|
394
|
+
debug: 1,
|
|
395
|
+
info: 2,
|
|
396
|
+
warn: 3,
|
|
397
|
+
error: 4,
|
|
398
|
+
fatal: 5
|
|
399
|
+
};
|
|
400
|
+
LEVEL_COLORS = {
|
|
401
|
+
trace: import_picocolors.default.gray,
|
|
402
|
+
debug: import_picocolors.default.cyan,
|
|
403
|
+
info: import_picocolors.default.green,
|
|
404
|
+
warn: import_picocolors.default.yellow,
|
|
405
|
+
error: import_picocolors.default.red,
|
|
406
|
+
fatal: (s) => import_picocolors.default.bgRed(import_picocolors.default.white(s))
|
|
407
|
+
};
|
|
408
|
+
LEVEL_WIDTH = 5;
|
|
401
409
|
BaseLogger = class {
|
|
402
410
|
level;
|
|
403
411
|
format;
|
|
@@ -639,7 +647,8 @@ function createLogger(module, options) {
|
|
|
639
647
|
var asyncLocalStorage, ConsoleTransport, FileTransport, HttpTransport, SINGLETON_KEY, Logger, logger;
|
|
640
648
|
var init_dist = __esm({
|
|
641
649
|
"../../node_modules/@parisgroup-ai/logger/dist/index.mjs"() {
|
|
642
|
-
|
|
650
|
+
init_logger_base_W8CRO9aE();
|
|
651
|
+
init_sanitize_u1LaSkAO();
|
|
643
652
|
asyncLocalStorage = new AsyncLocalStorage();
|
|
644
653
|
ConsoleTransport = class {
|
|
645
654
|
log(entry, formatted) {
|
|
@@ -1575,13 +1584,27 @@ function detectIDEs(home = os3.homedir()) {
|
|
|
1575
1584
|
detected: checkExists(path4.join(home, ".codex")),
|
|
1576
1585
|
configPath: path4.join(home, ".codex", "config.toml")
|
|
1577
1586
|
},
|
|
1578
|
-
// OpenCode: ~/.opencode
|
|
1587
|
+
// OpenCode: ~/.opencode or XDG ~/.config/opencode
|
|
1579
1588
|
{
|
|
1580
1589
|
name: "OpenCode",
|
|
1581
1590
|
id: "opencode",
|
|
1582
|
-
detected: checkExists(path4.join(home, ".opencode")),
|
|
1591
|
+
detected: checkExists(path4.join(home, ".opencode")) || checkExists(path4.join(home, ".config", "opencode")),
|
|
1583
1592
|
configPath: path4.join(home, ".opencode", "opencode.json")
|
|
1584
1593
|
},
|
|
1594
|
+
// Grok CLI: ~/.grok
|
|
1595
|
+
{
|
|
1596
|
+
name: "Grok CLI",
|
|
1597
|
+
id: "grok",
|
|
1598
|
+
detected: checkExists(path4.join(home, ".grok")),
|
|
1599
|
+
configPath: path4.join(home, ".grok", "config.toml")
|
|
1600
|
+
},
|
|
1601
|
+
// Antigravity: ~/.gemini/antigravity-cli
|
|
1602
|
+
{
|
|
1603
|
+
name: "Antigravity",
|
|
1604
|
+
id: "antigravity",
|
|
1605
|
+
detected: checkExists(path4.join(home, ".gemini", "antigravity-cli")),
|
|
1606
|
+
configPath: path4.join(home, ".gemini", "antigravity-cli", "mcp_config.json")
|
|
1607
|
+
},
|
|
1585
1608
|
// Manual (always available as fallback)
|
|
1586
1609
|
{
|
|
1587
1610
|
name: "Manual",
|
|
@@ -1598,6 +1621,19 @@ function detectIDEs(home = os3.homedir()) {
|
|
|
1598
1621
|
} catch {
|
|
1599
1622
|
}
|
|
1600
1623
|
}
|
|
1624
|
+
for (const [id, bin] of [
|
|
1625
|
+
["grok", "grok"],
|
|
1626
|
+
["antigravity", "agy"]
|
|
1627
|
+
]) {
|
|
1628
|
+
const ide = ides.find((i) => i.id === id);
|
|
1629
|
+
if (ide && !ide.detected) {
|
|
1630
|
+
try {
|
|
1631
|
+
execFileSync("which", [bin], { encoding: "utf-8" });
|
|
1632
|
+
ide.detected = true;
|
|
1633
|
+
} catch {
|
|
1634
|
+
}
|
|
1635
|
+
}
|
|
1636
|
+
}
|
|
1601
1637
|
return ides;
|
|
1602
1638
|
}
|
|
1603
1639
|
var init_ide_detector = __esm({
|
|
@@ -1906,64 +1942,51 @@ var init_instruction_template_v3 = __esm({
|
|
|
1906
1942
|
}
|
|
1907
1943
|
});
|
|
1908
1944
|
|
|
1909
|
-
// src/workspace/
|
|
1910
|
-
var
|
|
1911
|
-
__export(
|
|
1912
|
-
|
|
1913
|
-
|
|
1914
|
-
upsertRootAgentsBlock: () => upsertRootAgentsBlock
|
|
1915
|
-
writeInstructionFiles: () => writeInstructionFiles
|
|
1945
|
+
// src/workspace/runtime-registry.ts
|
|
1946
|
+
var runtime_registry_exports = {};
|
|
1947
|
+
__export(runtime_registry_exports, {
|
|
1948
|
+
RUNTIMES: () => RUNTIMES,
|
|
1949
|
+
detectedSlashHints: () => detectedSlashHints,
|
|
1950
|
+
upsertRootAgentsBlock: () => upsertRootAgentsBlock
|
|
1916
1951
|
});
|
|
1952
|
+
import { execFileSync as execFileSync2 } from "node:child_process";
|
|
1917
1953
|
import { existsSync as existsSync2, mkdirSync as mkdirSync2, readFileSync, writeFileSync as writeFileSync2 } from "node:fs";
|
|
1918
|
-
import { homedir } from "node:os";
|
|
1919
1954
|
import { join as join2 } from "node:path";
|
|
1920
|
-
function
|
|
1921
|
-
|
|
1955
|
+
function hasBinary(name) {
|
|
1956
|
+
try {
|
|
1957
|
+
execFileSync2("which", [name], { encoding: "utf-8", stdio: "pipe" });
|
|
1958
|
+
return true;
|
|
1959
|
+
} catch {
|
|
1960
|
+
return false;
|
|
1961
|
+
}
|
|
1922
1962
|
}
|
|
1923
|
-
function
|
|
1924
|
-
|
|
1925
|
-
|
|
1926
|
-
|
|
1927
|
-
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
|
-
const claudeFile = `tostudy-${slug}.md`;
|
|
1931
|
-
writeFileSync2(join2(claudeDir, claudeFile), content);
|
|
1932
|
-
written.push(`.claude/commands/${claudeFile}`);
|
|
1933
|
-
const cursorDir = join2(cwd, ".cursor", "rules");
|
|
1934
|
-
if (existsSync2(join2(cwd, ".cursor")) || existsSync2(cursorDir)) {
|
|
1935
|
-
if (!existsSync2(cursorDir)) {
|
|
1936
|
-
mkdirSync2(cursorDir, { recursive: true });
|
|
1937
|
-
}
|
|
1938
|
-
const mdcContent = `---
|
|
1939
|
-
description: ${ctx.courseTitle} \u2014 ToStudy Course Guide
|
|
1963
|
+
function writeFile2(absDir, fileName, body) {
|
|
1964
|
+
mkdirSync2(absDir, { recursive: true });
|
|
1965
|
+
writeFileSync2(join2(absDir, fileName), body);
|
|
1966
|
+
}
|
|
1967
|
+
function cursorMdc(title, content) {
|
|
1968
|
+
return `---
|
|
1969
|
+
description: ${title} \u2014 ToStudy Course Guide
|
|
1940
1970
|
globs: ["**/*"]
|
|
1941
1971
|
alwaysApply: true
|
|
1942
1972
|
---
|
|
1943
1973
|
|
|
1944
1974
|
${content}`;
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
|
-
|
|
1957
|
-
written.push(rootAgents);
|
|
1958
|
-
}
|
|
1959
|
-
logger2.info("Generated instruction files (v3)", {
|
|
1960
|
-
slug,
|
|
1961
|
-
files: written
|
|
1962
|
-
});
|
|
1963
|
-
return written;
|
|
1975
|
+
}
|
|
1976
|
+
function antigravitySkillMd(name, description, content) {
|
|
1977
|
+
return `---
|
|
1978
|
+
name: ${name}
|
|
1979
|
+
description: >-
|
|
1980
|
+
${description}
|
|
1981
|
+
---
|
|
1982
|
+
|
|
1983
|
+
${content}`;
|
|
1984
|
+
}
|
|
1985
|
+
function detectedSlashHints(slug, home, cwd) {
|
|
1986
|
+
return RUNTIMES.filter((r) => r.slashHint && r.detect(home, cwd)).map((r) => r.slashHint(slug));
|
|
1964
1987
|
}
|
|
1965
1988
|
function upsertRootAgentsBlock(cwd, ctx) {
|
|
1966
|
-
const slug =
|
|
1989
|
+
const slug = slugifyTitle(ctx.courseTitle);
|
|
1967
1990
|
const block = [
|
|
1968
1991
|
"<!-- tostudy:start -->",
|
|
1969
1992
|
"",
|
|
@@ -2007,67 +2030,198 @@ function upsertRootAgentsBlock(cwd, ctx) {
|
|
|
2007
2030
|
return null;
|
|
2008
2031
|
}
|
|
2009
2032
|
}
|
|
2010
|
-
function
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
|
|
2033
|
+
function slugifyTitle(title) {
|
|
2034
|
+
return title.toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g, "").replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "").slice(0, 60);
|
|
2035
|
+
}
|
|
2036
|
+
var logger2, detectOpencode, detectGrok, detectAntigravity, RUNTIMES, TOSTUDY_BLOCK_PATTERN, TOSTUDY_BLOCK_PATTERN_GLOBAL;
|
|
2037
|
+
var init_runtime_registry = __esm({
|
|
2038
|
+
"src/workspace/runtime-registry.ts"() {
|
|
2039
|
+
"use strict";
|
|
2040
|
+
init_dist();
|
|
2041
|
+
logger2 = createLogger("cli:runtime-registry");
|
|
2042
|
+
detectOpencode = (home) => existsSync2(join2(home, ".opencode")) || existsSync2(join2(home, ".config", "opencode"));
|
|
2043
|
+
detectGrok = (home) => existsSync2(join2(home, ".grok")) || hasBinary("grok");
|
|
2044
|
+
detectAntigravity = (home) => existsSync2(join2(home, ".gemini", "antigravity-cli")) || hasBinary("agy");
|
|
2045
|
+
RUNTIMES = [
|
|
2046
|
+
{
|
|
2047
|
+
id: "claude",
|
|
2048
|
+
name: "Claude Code",
|
|
2049
|
+
detect: () => hasBinary("claude"),
|
|
2050
|
+
writePerCourse({ cwd, slug, content }) {
|
|
2051
|
+
writeFile2(join2(cwd, ".claude", "commands"), `tostudy-${slug}.md`, content);
|
|
2052
|
+
return [`.claude/commands/tostudy-${slug}.md`];
|
|
2053
|
+
},
|
|
2054
|
+
writeUniversal({ cwd, content }) {
|
|
2055
|
+
writeFile2(join2(cwd, ".claude", "commands"), "tostudy.md", content);
|
|
2056
|
+
return [".claude/commands/tostudy.md"];
|
|
2057
|
+
},
|
|
2058
|
+
slashHint: (slug) => `No Claude Code, digite: /tostudy-${slug}`
|
|
2059
|
+
},
|
|
2060
|
+
{
|
|
2061
|
+
id: "cursor",
|
|
2062
|
+
name: "Cursor",
|
|
2063
|
+
detect: (home, cwd) => existsSync2(join2(home, ".cursor")) || existsSync2(join2(cwd, ".cursor")),
|
|
2064
|
+
writePerCourse({ cwd, slug, ctx, content, force }) {
|
|
2065
|
+
if (!force && !existsSync2(join2(cwd, ".cursor"))) return [];
|
|
2066
|
+
writeFile2(
|
|
2067
|
+
join2(cwd, ".cursor", "rules"),
|
|
2068
|
+
`tostudy-${slug}.mdc`,
|
|
2069
|
+
cursorMdc(ctx.courseTitle, content)
|
|
2070
|
+
);
|
|
2071
|
+
return [`.cursor/rules/tostudy-${slug}.mdc`];
|
|
2072
|
+
},
|
|
2073
|
+
writeUniversal({ cwd, content }) {
|
|
2074
|
+
writeFile2(join2(cwd, ".cursor", "rules"), "tostudy.mdc", cursorMdc("ToStudy", content));
|
|
2075
|
+
return [".cursor/rules/tostudy.mdc"];
|
|
2076
|
+
}
|
|
2077
|
+
},
|
|
2078
|
+
{
|
|
2079
|
+
id: "codex",
|
|
2080
|
+
name: "Codex",
|
|
2081
|
+
detect: (home) => existsSync2(join2(home, ".codex")),
|
|
2082
|
+
// No writePerCourse: Codex has no project-level command channel — the
|
|
2083
|
+
// root AGENTS.md managed block (generic entry) is its per-course path.
|
|
2084
|
+
writeUniversal({ home, content }) {
|
|
2085
|
+
const file2 = join2(home, ".codex", "prompts", "tostudy.md");
|
|
2086
|
+
writeFile2(join2(home, ".codex", "prompts"), "tostudy.md", content);
|
|
2087
|
+
return [file2];
|
|
2088
|
+
}
|
|
2089
|
+
},
|
|
2090
|
+
{
|
|
2091
|
+
id: "opencode",
|
|
2092
|
+
name: "OpenCode",
|
|
2093
|
+
detect: (home) => detectOpencode(home),
|
|
2094
|
+
writePerCourse({ cwd, home, slug, ctx, content, force }) {
|
|
2095
|
+
if (!force && !detectOpencode(home)) return [];
|
|
2096
|
+
const body = `---
|
|
2097
|
+
description: ${ctx.courseTitle} \u2014 ToStudy Course Guide
|
|
2034
2098
|
---
|
|
2035
2099
|
|
|
2036
|
-
${content}
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
const mdcContent = `---
|
|
2100
|
+
${content}`;
|
|
2101
|
+
writeFile2(join2(cwd, ".opencode", "command"), `tostudy-${slug}.md`, body);
|
|
2102
|
+
return [`.opencode/command/tostudy-${slug}.md`];
|
|
2103
|
+
},
|
|
2104
|
+
writeUniversal({ home, content }) {
|
|
2105
|
+
const dir = join2(home, ".config", "opencode", "command");
|
|
2106
|
+
const body = `---
|
|
2044
2107
|
description: ToStudy \u2014 AI Tutor Guide
|
|
2045
|
-
globs: ["**/*"]
|
|
2046
|
-
alwaysApply: true
|
|
2047
2108
|
---
|
|
2048
2109
|
|
|
2049
2110
|
${content}`;
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
|
|
2111
|
+
writeFile2(dir, "tostudy.md", body);
|
|
2112
|
+
return [join2(dir, "tostudy.md")];
|
|
2113
|
+
},
|
|
2114
|
+
slashHint: (slug) => `No OpenCode, digite: /tostudy-${slug}`
|
|
2115
|
+
},
|
|
2116
|
+
{
|
|
2117
|
+
id: "grok",
|
|
2118
|
+
name: "Grok CLI",
|
|
2119
|
+
detect: (home) => detectGrok(home),
|
|
2120
|
+
writePerCourse({ cwd, home, slug, content, force }) {
|
|
2121
|
+
if (!force && !detectGrok(home)) return [];
|
|
2122
|
+
writeFile2(join2(cwd, ".grok", "commands"), `tostudy-${slug}.md`, content);
|
|
2123
|
+
return [`.grok/commands/tostudy-${slug}.md`];
|
|
2124
|
+
},
|
|
2125
|
+
writeUniversal({ home, content }) {
|
|
2126
|
+
const dir = join2(home, ".grok", "commands");
|
|
2127
|
+
writeFile2(dir, "tostudy.md", content);
|
|
2128
|
+
return [join2(dir, "tostudy.md")];
|
|
2129
|
+
},
|
|
2130
|
+
slashHint: (slug) => `No Grok, digite: /tostudy-${slug}`
|
|
2131
|
+
},
|
|
2132
|
+
{
|
|
2133
|
+
id: "antigravity",
|
|
2134
|
+
name: "Antigravity",
|
|
2135
|
+
detect: (home) => detectAntigravity(home),
|
|
2136
|
+
writePerCourse({ cwd, home, slug, ctx, content, force }) {
|
|
2137
|
+
if (!force && !detectAntigravity(home)) return [];
|
|
2138
|
+
writeFile2(
|
|
2139
|
+
join2(cwd, ".agents", "skills", `tostudy-${slug}`),
|
|
2140
|
+
"SKILL.md",
|
|
2141
|
+
antigravitySkillMd(
|
|
2142
|
+
`tostudy-${slug}`,
|
|
2143
|
+
`${ctx.courseTitle} \u2014 ToStudy Course Guide. Use when the student asks to study, continue the course, or runs tostudy commands.`,
|
|
2144
|
+
content
|
|
2145
|
+
)
|
|
2146
|
+
);
|
|
2147
|
+
return [`.agents/skills/tostudy-${slug}/SKILL.md`];
|
|
2148
|
+
},
|
|
2149
|
+
writeUniversal({ cwd, content }) {
|
|
2150
|
+
writeFile2(
|
|
2151
|
+
join2(cwd, ".agents", "skills", "tostudy"),
|
|
2152
|
+
"SKILL.md",
|
|
2153
|
+
antigravitySkillMd(
|
|
2154
|
+
"tostudy",
|
|
2155
|
+
"ToStudy \u2014 AI Tutor Guide. Use when the student asks to study or runs tostudy commands.",
|
|
2156
|
+
content
|
|
2157
|
+
)
|
|
2158
|
+
);
|
|
2159
|
+
return [".agents/skills/tostudy/SKILL.md"];
|
|
2160
|
+
},
|
|
2161
|
+
slashHint: (slug) => `No Antigravity, a skill tostudy-${slug} ativa automaticamente`
|
|
2162
|
+
},
|
|
2163
|
+
{
|
|
2164
|
+
id: "generic",
|
|
2165
|
+
name: "Generic (AGENTS.md)",
|
|
2166
|
+
// Windsurf is the remaining consumer of the generic universal install.
|
|
2167
|
+
detect: (home) => existsSync2(join2(home, ".codeium", "windsurf")),
|
|
2168
|
+
writePerCourse({ cwd, slug, ctx, content }) {
|
|
2169
|
+
writeFile2(join2(cwd, ".tostudy", "courses", slug), "AGENTS.md", content);
|
|
2170
|
+
const written = [`.tostudy/courses/${slug}/AGENTS.md`];
|
|
2171
|
+
const rootAgents = upsertRootAgentsBlock(cwd, ctx);
|
|
2172
|
+
if (rootAgents) written.push(rootAgents);
|
|
2173
|
+
return written;
|
|
2174
|
+
},
|
|
2175
|
+
writeUniversal({ cwd, content }) {
|
|
2176
|
+
writeFile2(join2(cwd, ".tostudy"), "AGENTS.md", content);
|
|
2177
|
+
return [".tostudy/AGENTS.md"];
|
|
2178
|
+
}
|
|
2179
|
+
}
|
|
2180
|
+
];
|
|
2181
|
+
TOSTUDY_BLOCK_PATTERN = /<!-- tostudy:start -->[\s\S]*?<!-- tostudy:end -->/;
|
|
2182
|
+
TOSTUDY_BLOCK_PATTERN_GLOBAL = /<!-- tostudy:start -->[\s\S]*?<!-- tostudy:end -->/g;
|
|
2058
2183
|
}
|
|
2059
|
-
|
|
2184
|
+
});
|
|
2185
|
+
|
|
2186
|
+
// src/workspace/instruction-files.ts
|
|
2187
|
+
var instruction_files_exports = {};
|
|
2188
|
+
__export(instruction_files_exports, {
|
|
2189
|
+
installUniversalCommand: () => installUniversalCommand,
|
|
2190
|
+
slugify: () => slugify,
|
|
2191
|
+
upsertRootAgentsBlock: () => upsertRootAgentsBlock,
|
|
2192
|
+
writeInstructionFiles: () => writeInstructionFiles
|
|
2193
|
+
});
|
|
2194
|
+
import { homedir } from "node:os";
|
|
2195
|
+
function slugify(title) {
|
|
2196
|
+
return title.toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g, "").replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "").slice(0, 60);
|
|
2197
|
+
}
|
|
2198
|
+
function writeInstructionFiles(cwd, ctx, content, opts = {}) {
|
|
2199
|
+
const home = opts.home ?? homedir();
|
|
2200
|
+
const force = opts.allRuntimes ?? false;
|
|
2201
|
+
const slug = slugify(ctx.courseTitle);
|
|
2202
|
+
const written = RUNTIMES.flatMap(
|
|
2203
|
+
(r) => r.writePerCourse?.({ cwd, home, slug, ctx, content, force }) ?? []
|
|
2204
|
+
);
|
|
2205
|
+
logger3.info("Generated instruction files (v3)", { slug, files: written });
|
|
2206
|
+
return written;
|
|
2207
|
+
}
|
|
2208
|
+
function installUniversalCommand(platform2, cwd = process.cwd(), homeDir = homedir()) {
|
|
2209
|
+
const entry = RUNTIMES.find((r) => r.id === platform2);
|
|
2210
|
+
if (!entry?.writeUniversal) return [];
|
|
2211
|
+
const content = renderUniversalInstruction();
|
|
2212
|
+
const written = entry.writeUniversal({ cwd, home: homeDir, content });
|
|
2213
|
+
logger3.info("Installed universal /tostudy command", { platform: platform2, files: written });
|
|
2060
2214
|
return written;
|
|
2061
2215
|
}
|
|
2062
|
-
var
|
|
2216
|
+
var logger3;
|
|
2063
2217
|
var init_instruction_files = __esm({
|
|
2064
2218
|
"src/workspace/instruction-files.ts"() {
|
|
2065
2219
|
"use strict";
|
|
2066
2220
|
init_dist();
|
|
2067
2221
|
init_instruction_template_v3();
|
|
2068
|
-
|
|
2069
|
-
|
|
2070
|
-
|
|
2222
|
+
init_runtime_registry();
|
|
2223
|
+
init_runtime_registry();
|
|
2224
|
+
logger3 = createLogger("cli:instruction-files");
|
|
2071
2225
|
}
|
|
2072
2226
|
});
|
|
2073
2227
|
|
|
@@ -2140,16 +2294,7 @@ async function loginWithMagicLink(magicLinkUrl, apiUrl) {
|
|
|
2140
2294
|
await persistSession(data, apiUrl);
|
|
2141
2295
|
return data;
|
|
2142
2296
|
}
|
|
2143
|
-
|
|
2144
|
-
const lower = ideName.toLowerCase();
|
|
2145
|
-
if (lower.includes("claude")) return "claude";
|
|
2146
|
-
if (lower.includes("codex")) return "codex";
|
|
2147
|
-
if (lower.includes("cursor")) return "cursor";
|
|
2148
|
-
if (lower.includes("opencode")) return "opencode";
|
|
2149
|
-
if (lower.includes("windsurf") || lower.includes("antigravity")) return "generic";
|
|
2150
|
-
return null;
|
|
2151
|
-
}
|
|
2152
|
-
var logger3, DEFAULT_API_URL, PORT, loginCommand;
|
|
2297
|
+
var logger4, DEFAULT_API_URL, PORT, loginCommand;
|
|
2153
2298
|
var init_login = __esm({
|
|
2154
2299
|
"src/commands/login.ts"() {
|
|
2155
2300
|
"use strict";
|
|
@@ -2159,7 +2304,7 @@ var init_login = __esm({
|
|
|
2159
2304
|
init_oauth_server();
|
|
2160
2305
|
init_session_store();
|
|
2161
2306
|
init_formatter();
|
|
2162
|
-
|
|
2307
|
+
logger4 = createLogger("cli:login");
|
|
2163
2308
|
DEFAULT_API_URL = "https://tostudy.ai";
|
|
2164
2309
|
PORT = 9876;
|
|
2165
2310
|
loginCommand = new Command("login").description("Autentica no ToStudy via browser").option("--manual", "Login manual (sem browser)").option("--code <code>", "Login n\xE3o-interativo via c\xF3digo de autentica\xE7\xE3o").option("--magic-link <url>", "Login via URL de magic-link (recupera\xE7\xE3o)").option("--api-url <url>", "API URL override", DEFAULT_API_URL).action(async (opts) => {
|
|
@@ -2224,6 +2369,8 @@ var init_login = __esm({
|
|
|
2224
2369
|
try {
|
|
2225
2370
|
const { detectIDEs: detectIDEs2 } = await Promise.resolve().then(() => (init_ide_detector(), ide_detector_exports));
|
|
2226
2371
|
const { installUniversalCommand: installUniversalCommand2 } = await Promise.resolve().then(() => (init_instruction_files(), instruction_files_exports));
|
|
2372
|
+
const { RUNTIMES: RUNTIMES2 } = await Promise.resolve().then(() => (init_runtime_registry(), runtime_registry_exports));
|
|
2373
|
+
const { homedir: homedir2 } = await import("node:os");
|
|
2227
2374
|
const ides = detectIDEs2();
|
|
2228
2375
|
const detected = ides.filter((ide) => ide.detected);
|
|
2229
2376
|
if (detected.length > 0) {
|
|
@@ -2231,27 +2378,26 @@ var init_login = __esm({
|
|
|
2231
2378
|
for (const ide of detected) {
|
|
2232
2379
|
console.log(` \u2713 ${ide.name} detectado`);
|
|
2233
2380
|
}
|
|
2234
|
-
|
|
2235
|
-
|
|
2236
|
-
|
|
2237
|
-
|
|
2238
|
-
|
|
2239
|
-
|
|
2240
|
-
|
|
2241
|
-
}
|
|
2381
|
+
}
|
|
2382
|
+
const cwd = process.cwd();
|
|
2383
|
+
const home = homedir2();
|
|
2384
|
+
const installedFiles = [];
|
|
2385
|
+
for (const runtime of RUNTIMES2) {
|
|
2386
|
+
if (runtime.writeUniversal && runtime.detect(home, cwd)) {
|
|
2387
|
+
installedFiles.push(...installUniversalCommand2(runtime.id, cwd));
|
|
2242
2388
|
}
|
|
2243
|
-
|
|
2244
|
-
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
}
|
|
2389
|
+
}
|
|
2390
|
+
if (installedFiles.length > 0) {
|
|
2391
|
+
console.log("");
|
|
2392
|
+
for (const file2 of [...new Set(installedFiles)]) {
|
|
2393
|
+
console.log(` \u2713 Instalado: ${file2}`);
|
|
2248
2394
|
}
|
|
2249
2395
|
}
|
|
2250
2396
|
} catch {
|
|
2251
2397
|
}
|
|
2252
2398
|
try {
|
|
2253
2399
|
const data = createHttpProvider(apiUrl, token2);
|
|
2254
|
-
const courses3 = await listCourses({ userId }, { data, logger:
|
|
2400
|
+
const courses3 = await listCourses({ userId }, { data, logger: logger4 });
|
|
2255
2401
|
if (courses3.length > 0) {
|
|
2256
2402
|
console.log(`
|
|
2257
2403
|
\u2713 ${courses3.length} curso(s) matriculado(s)`);
|
|
@@ -2775,16 +2921,16 @@ var init_setup = __esm({
|
|
|
2775
2921
|
});
|
|
2776
2922
|
|
|
2777
2923
|
// src/installer/node-detector.ts
|
|
2778
|
-
import { execFileSync as
|
|
2924
|
+
import { execFileSync as execFileSync3 } from "node:child_process";
|
|
2779
2925
|
function detectNode() {
|
|
2780
2926
|
try {
|
|
2781
|
-
const version3 =
|
|
2927
|
+
const version3 = execFileSync3("node", ["--version"], {
|
|
2782
2928
|
encoding: "utf-8"
|
|
2783
2929
|
}).trim();
|
|
2784
2930
|
let nodePath = null;
|
|
2785
2931
|
try {
|
|
2786
2932
|
const whichCmd = process.platform === "win32" ? "where" : "which";
|
|
2787
|
-
nodePath =
|
|
2933
|
+
nodePath = execFileSync3(whichCmd, ["node"], { encoding: "utf-8" }).trim();
|
|
2788
2934
|
} catch {
|
|
2789
2935
|
}
|
|
2790
2936
|
const major = parseInt(version3.replace("v", ""), 10);
|
|
@@ -2804,7 +2950,7 @@ var CLI_VERSION;
|
|
|
2804
2950
|
var init_version = __esm({
|
|
2805
2951
|
"src/version.ts"() {
|
|
2806
2952
|
"use strict";
|
|
2807
|
-
CLI_VERSION = true ? "0.
|
|
2953
|
+
CLI_VERSION = true ? "0.15.0" : "0.7.1";
|
|
2808
2954
|
}
|
|
2809
2955
|
});
|
|
2810
2956
|
|
|
@@ -2814,22 +2960,24 @@ __export(update_checker_exports, {
|
|
|
2814
2960
|
checkForUpdates: () => checkForUpdates,
|
|
2815
2961
|
checkVersionSync: () => checkVersionSync,
|
|
2816
2962
|
fetchLatestVersion: () => fetchLatestVersion,
|
|
2817
|
-
isNewerVersion: () => isNewerVersion
|
|
2963
|
+
isNewerVersion: () => isNewerVersion,
|
|
2964
|
+
readCache: () => readCache,
|
|
2965
|
+
writeCache: () => writeCache
|
|
2818
2966
|
});
|
|
2819
2967
|
import fs7 from "node:fs";
|
|
2820
2968
|
import path9 from "node:path";
|
|
2821
|
-
function readCache() {
|
|
2969
|
+
function readCache(configDir) {
|
|
2822
2970
|
try {
|
|
2823
|
-
const p = path9.join(getConfigDir(), CACHE_FILE);
|
|
2971
|
+
const p = path9.join(configDir ?? getConfigDir(), CACHE_FILE);
|
|
2824
2972
|
if (!fs7.existsSync(p)) return null;
|
|
2825
2973
|
return JSON.parse(fs7.readFileSync(p, "utf-8"));
|
|
2826
2974
|
} catch {
|
|
2827
2975
|
return null;
|
|
2828
2976
|
}
|
|
2829
2977
|
}
|
|
2830
|
-
function writeCache(cache) {
|
|
2978
|
+
function writeCache(cache, configDir) {
|
|
2831
2979
|
try {
|
|
2832
|
-
const dir = getConfigDir();
|
|
2980
|
+
const dir = configDir ?? getConfigDir();
|
|
2833
2981
|
fs7.mkdirSync(dir, { recursive: true });
|
|
2834
2982
|
fs7.writeFileSync(path9.join(dir, CACHE_FILE), JSON.stringify(cache));
|
|
2835
2983
|
} catch {
|
|
@@ -2993,14 +3141,14 @@ var init_doctor = __esm({
|
|
|
2993
3141
|
git: null
|
|
2994
3142
|
};
|
|
2995
3143
|
try {
|
|
2996
|
-
const { execFileSync:
|
|
2997
|
-
envChecks["pnpm"] =
|
|
3144
|
+
const { execFileSync: execFileSync4 } = await import("node:child_process");
|
|
3145
|
+
envChecks["pnpm"] = execFileSync4("pnpm", ["--version"], { encoding: "utf-8" }).trim();
|
|
2998
3146
|
} catch {
|
|
2999
3147
|
envChecks["pnpm"] = null;
|
|
3000
3148
|
}
|
|
3001
3149
|
try {
|
|
3002
|
-
const { execFileSync:
|
|
3003
|
-
envChecks["git"] =
|
|
3150
|
+
const { execFileSync: execFileSync4 } = await import("node:child_process");
|
|
3151
|
+
envChecks["git"] = execFileSync4("git", ["--version"], { encoding: "utf-8" }).trim().replace("git version ", "");
|
|
3004
3152
|
} catch {
|
|
3005
3153
|
envChecks["git"] = null;
|
|
3006
3154
|
}
|
|
@@ -3179,7 +3327,7 @@ var init_doctor = __esm({
|
|
|
3179
3327
|
|
|
3180
3328
|
// src/commands/courses.ts
|
|
3181
3329
|
import { Command as Command5 } from "commander";
|
|
3182
|
-
var
|
|
3330
|
+
var logger5, coursesCommand;
|
|
3183
3331
|
var init_courses2 = __esm({
|
|
3184
3332
|
"src/commands/courses.ts"() {
|
|
3185
3333
|
"use strict";
|
|
@@ -3188,12 +3336,12 @@ var init_courses2 = __esm({
|
|
|
3188
3336
|
init_http();
|
|
3189
3337
|
init_guards();
|
|
3190
3338
|
init_formatter();
|
|
3191
|
-
|
|
3339
|
+
logger5 = createLogger("cli:courses");
|
|
3192
3340
|
coursesCommand = new Command5("courses").description("List your enrolled courses with progress").option("--json", "Output structured JSON").option("--mine", "List only your own courses, including drafts").action(async (opts) => {
|
|
3193
3341
|
try {
|
|
3194
3342
|
const session = await requireSession();
|
|
3195
3343
|
const data = createHttpProvider(session.apiUrl, session.token);
|
|
3196
|
-
const deps = { data, logger:
|
|
3344
|
+
const deps = { data, logger: logger5 };
|
|
3197
3345
|
let coursesToList;
|
|
3198
3346
|
if (opts.mine) {
|
|
3199
3347
|
coursesToList = await data.courses.listCreatorCourses({
|
|
@@ -3525,7 +3673,7 @@ async function resolveAndGenerate(input2, options = {}, context) {
|
|
|
3525
3673
|
});
|
|
3526
3674
|
}
|
|
3527
3675
|
} catch (err) {
|
|
3528
|
-
|
|
3676
|
+
logger6.warn("T0 fetch failed \u2014 rendering without persona", { err });
|
|
3529
3677
|
tutorPersona = null;
|
|
3530
3678
|
}
|
|
3531
3679
|
}
|
|
@@ -3549,7 +3697,7 @@ async function resolveAndGenerate(input2, options = {}, context) {
|
|
|
3549
3697
|
fetchedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
3550
3698
|
});
|
|
3551
3699
|
} catch (err) {
|
|
3552
|
-
|
|
3700
|
+
logger6.warn("T1 fetch failed \u2014 rendering without brief", { err });
|
|
3553
3701
|
}
|
|
3554
3702
|
}
|
|
3555
3703
|
if (!studentBrief && options.collectT1Interactive) {
|
|
@@ -3569,7 +3717,7 @@ async function resolveAndGenerate(input2, options = {}, context) {
|
|
|
3569
3717
|
});
|
|
3570
3718
|
bootstrapped = "t1";
|
|
3571
3719
|
} catch (err) {
|
|
3572
|
-
|
|
3720
|
+
logger6.warn("T1 bootstrap failed", { err });
|
|
3573
3721
|
}
|
|
3574
3722
|
}
|
|
3575
3723
|
let enrollmentProfile = null;
|
|
@@ -3583,7 +3731,7 @@ async function resolveAndGenerate(input2, options = {}, context) {
|
|
|
3583
3731
|
enrollmentProfile = onboarding.learnerProfile;
|
|
3584
3732
|
}
|
|
3585
3733
|
} catch (err) {
|
|
3586
|
-
|
|
3734
|
+
logger6.warn("T2 fetch failed \u2014 rendering without enrollment profile", { err });
|
|
3587
3735
|
}
|
|
3588
3736
|
const content = renderCourseInstruction({
|
|
3589
3737
|
course: {
|
|
@@ -3607,7 +3755,7 @@ async function resolveAndGenerate(input2, options = {}, context) {
|
|
|
3607
3755
|
courseTitle: courseMeta.courseTitle
|
|
3608
3756
|
});
|
|
3609
3757
|
} catch (err) {
|
|
3610
|
-
|
|
3758
|
+
logger6.warn("Failed to write workspace marker", { err });
|
|
3611
3759
|
}
|
|
3612
3760
|
if (markerPath) {
|
|
3613
3761
|
try {
|
|
@@ -3617,7 +3765,7 @@ async function resolveAndGenerate(input2, options = {}, context) {
|
|
|
3617
3765
|
lastInitCourseId: input2.courseId
|
|
3618
3766
|
});
|
|
3619
3767
|
} catch (err) {
|
|
3620
|
-
|
|
3768
|
+
logger6.warn("Failed to update workspace state v2 fields", {
|
|
3621
3769
|
error: err instanceof Error ? err.message : String(err)
|
|
3622
3770
|
});
|
|
3623
3771
|
}
|
|
@@ -3632,7 +3780,7 @@ async function resolveAndGenerate(input2, options = {}, context) {
|
|
|
3632
3780
|
renderedInstruction: content
|
|
3633
3781
|
};
|
|
3634
3782
|
}
|
|
3635
|
-
var
|
|
3783
|
+
var logger6, defaultDeps2;
|
|
3636
3784
|
var init_instruction_pipeline = __esm({
|
|
3637
3785
|
"src/instruction-pipeline.ts"() {
|
|
3638
3786
|
"use strict";
|
|
@@ -3647,7 +3795,7 @@ var init_instruction_pipeline = __esm({
|
|
|
3647
3795
|
init_api3();
|
|
3648
3796
|
init_session_store();
|
|
3649
3797
|
init_instruction_template_v3();
|
|
3650
|
-
|
|
3798
|
+
logger6 = createLogger("cli:instruction-pipeline");
|
|
3651
3799
|
defaultDeps2 = {
|
|
3652
3800
|
fetchTutorPersona: fetchTutorPersonality,
|
|
3653
3801
|
fetchLearnerBrief,
|
|
@@ -3670,7 +3818,7 @@ var init_instruction_pipeline = __esm({
|
|
|
3670
3818
|
async function fetchCourseMetaViaHttp(input2) {
|
|
3671
3819
|
const { session, courseId, enrollmentId } = input2;
|
|
3672
3820
|
const data = createHttpProvider(session.apiUrl, session.token);
|
|
3673
|
-
const coreDeps = { data, logger:
|
|
3821
|
+
const coreDeps = { data, logger: logger7 };
|
|
3674
3822
|
const detail = await selectCourse({ userId: session.userId, courseId }, coreDeps);
|
|
3675
3823
|
let currentModuleTitle;
|
|
3676
3824
|
let currentLessonTitle;
|
|
@@ -3679,7 +3827,7 @@ async function fetchCourseMetaViaHttp(input2) {
|
|
|
3679
3827
|
currentModuleTitle = progress3.currentModule?.title;
|
|
3680
3828
|
currentLessonTitle = progress3.currentLesson?.title;
|
|
3681
3829
|
} catch (err) {
|
|
3682
|
-
|
|
3830
|
+
logger7.debug("getProgress failed \u2014 falling back to basic course meta", {
|
|
3683
3831
|
error: err instanceof Error ? err.message : String(err)
|
|
3684
3832
|
});
|
|
3685
3833
|
}
|
|
@@ -3693,7 +3841,7 @@ async function fetchCourseMetaViaHttp(input2) {
|
|
|
3693
3841
|
courseLevel = match.level;
|
|
3694
3842
|
}
|
|
3695
3843
|
} catch (err) {
|
|
3696
|
-
|
|
3844
|
+
logger7.debug("listCourses failed \u2014 skipping tags/level", {
|
|
3697
3845
|
error: err instanceof Error ? err.message : String(err)
|
|
3698
3846
|
});
|
|
3699
3847
|
}
|
|
@@ -3713,7 +3861,7 @@ async function fetchCourseMetaViaHttp(input2) {
|
|
|
3713
3861
|
}
|
|
3714
3862
|
};
|
|
3715
3863
|
}
|
|
3716
|
-
async function writeFilesAdapter(cwd, courseMeta, content) {
|
|
3864
|
+
async function writeFilesAdapter(cwd, courseMeta, content, opts = {}) {
|
|
3717
3865
|
return writeInstructionFiles(
|
|
3718
3866
|
cwd,
|
|
3719
3867
|
{
|
|
@@ -3726,17 +3874,18 @@ async function writeFilesAdapter(cwd, courseMeta, content) {
|
|
|
3726
3874
|
currentLessonTitle: courseMeta.progress.currentLessonTitle,
|
|
3727
3875
|
courseDescription: courseMeta.courseDescription
|
|
3728
3876
|
},
|
|
3729
|
-
content
|
|
3877
|
+
content,
|
|
3878
|
+
{ allRuntimes: opts.allRuntimes }
|
|
3730
3879
|
);
|
|
3731
3880
|
}
|
|
3732
|
-
function buildPipelineDeps() {
|
|
3881
|
+
function buildPipelineDeps(opts = {}) {
|
|
3733
3882
|
return {
|
|
3734
3883
|
...defaultDeps2,
|
|
3735
3884
|
fetchCourseMeta: fetchCourseMetaViaHttp,
|
|
3736
|
-
writeFiles: writeFilesAdapter
|
|
3885
|
+
writeFiles: (cwd, courseMeta, content) => writeFilesAdapter(cwd, courseMeta, content, opts)
|
|
3737
3886
|
};
|
|
3738
3887
|
}
|
|
3739
|
-
var
|
|
3888
|
+
var logger7;
|
|
3740
3889
|
var init_pipeline_deps = __esm({
|
|
3741
3890
|
"src/commands/_shared/pipeline-deps.ts"() {
|
|
3742
3891
|
"use strict";
|
|
@@ -3745,14 +3894,14 @@ var init_pipeline_deps = __esm({
|
|
|
3745
3894
|
init_http();
|
|
3746
3895
|
init_instruction_pipeline();
|
|
3747
3896
|
init_instruction_files();
|
|
3748
|
-
|
|
3897
|
+
logger7 = createLogger("cli:pipeline-deps");
|
|
3749
3898
|
}
|
|
3750
3899
|
});
|
|
3751
3900
|
|
|
3752
3901
|
// src/commands/select.ts
|
|
3753
3902
|
import { Command as Command6 } from "commander";
|
|
3754
3903
|
import os7 from "node:os";
|
|
3755
|
-
var
|
|
3904
|
+
var logger8, selectCommand;
|
|
3756
3905
|
var init_select = __esm({
|
|
3757
3906
|
"src/commands/select.ts"() {
|
|
3758
3907
|
"use strict";
|
|
@@ -3762,17 +3911,18 @@ var init_select = __esm({
|
|
|
3762
3911
|
init_guards();
|
|
3763
3912
|
init_workspace_marker();
|
|
3764
3913
|
init_resolve();
|
|
3914
|
+
init_runtime_registry();
|
|
3765
3915
|
init_formatter();
|
|
3766
3916
|
init_errors();
|
|
3767
3917
|
init_status();
|
|
3768
3918
|
init_instruction_pipeline();
|
|
3769
3919
|
init_pipeline_deps();
|
|
3770
|
-
|
|
3920
|
+
logger8 = createLogger("cli:select");
|
|
3771
3921
|
selectCommand = new Command6("select").description("Activate a course by ID or list index number").argument("<course>", "Course ID (UUID) or index number from `tostudy courses`").option("--json", "Output structured JSON").action(async (course, opts) => {
|
|
3772
3922
|
try {
|
|
3773
3923
|
const session = await requireSession();
|
|
3774
3924
|
const data = createHttpProvider(session.apiUrl, session.token);
|
|
3775
|
-
const deps = { data, logger:
|
|
3925
|
+
const deps = { data, logger: logger8 };
|
|
3776
3926
|
const courses3 = await listCourses({ userId: session.userId }, deps);
|
|
3777
3927
|
let courseId = course;
|
|
3778
3928
|
let enrollmentId = "";
|
|
@@ -3811,7 +3961,7 @@ var init_select = __esm({
|
|
|
3811
3961
|
{ cwd: process.cwd(), deps: buildPipelineDeps() }
|
|
3812
3962
|
);
|
|
3813
3963
|
} catch (err) {
|
|
3814
|
-
|
|
3964
|
+
logger8.warn("Failed to run instruction pipeline", {
|
|
3815
3965
|
error: err instanceof Error ? err.message : String(err)
|
|
3816
3966
|
});
|
|
3817
3967
|
}
|
|
@@ -3862,12 +4012,18 @@ var init_select = __esm({
|
|
|
3862
4012
|
if (pipelineResult && !pipelineResult.usedT1) {
|
|
3863
4013
|
lines.push(" (sem brief base \u2014 rode `tostudy init` para configurar)");
|
|
3864
4014
|
}
|
|
3865
|
-
lines.push(
|
|
3866
|
-
|
|
3867
|
-
|
|
3868
|
-
|
|
3869
|
-
|
|
3870
|
-
|
|
4015
|
+
lines.push("", "\u2192 Abra sua plataforma (claude, codex, cursor...)");
|
|
4016
|
+
if (courseSlug2) {
|
|
4017
|
+
const hints = detectedSlashHints(courseSlug2, home, cwd);
|
|
4018
|
+
if (hints.length > 0) {
|
|
4019
|
+
lines.push(...hints.map((h) => `\u2192 ${h}`));
|
|
4020
|
+
} else {
|
|
4021
|
+
lines.push(`\u2192 No Claude Code, digite: ${slashCmd}`);
|
|
4022
|
+
}
|
|
4023
|
+
} else {
|
|
4024
|
+
lines.push(`\u2192 No Claude Code, digite: ${slashCmd}`);
|
|
4025
|
+
}
|
|
4026
|
+
lines.push("\u2192 Em outras plataformas: tostudy init");
|
|
3871
4027
|
output(lines.join("\n"), { json: false });
|
|
3872
4028
|
}
|
|
3873
4029
|
} catch (err) {
|
|
@@ -3884,7 +4040,7 @@ var init_select = __esm({
|
|
|
3884
4040
|
|
|
3885
4041
|
// src/commands/progress.ts
|
|
3886
4042
|
import { Command as Command7 } from "commander";
|
|
3887
|
-
var
|
|
4043
|
+
var logger9, progressCommand;
|
|
3888
4044
|
var init_progress = __esm({
|
|
3889
4045
|
"src/commands/progress.ts"() {
|
|
3890
4046
|
"use strict";
|
|
@@ -3895,7 +4051,7 @@ var init_progress = __esm({
|
|
|
3895
4051
|
init_course_state();
|
|
3896
4052
|
init_formatter();
|
|
3897
4053
|
init_errors();
|
|
3898
|
-
|
|
4054
|
+
logger9 = createLogger("cli:progress");
|
|
3899
4055
|
progressCommand = new Command7("progress").description("Show your progress in the active course").option("--json", "Output structured JSON").action(async (opts) => {
|
|
3900
4056
|
try {
|
|
3901
4057
|
const session = await requireSession();
|
|
@@ -3903,7 +4059,7 @@ var init_progress = __esm({
|
|
|
3903
4059
|
const driftWarning = await checkCourseDrift();
|
|
3904
4060
|
if (driftWarning) process.stderr.write(driftWarning + "\n");
|
|
3905
4061
|
const data = createHttpProvider(session.apiUrl, session.token);
|
|
3906
|
-
const deps = { data, logger:
|
|
4062
|
+
const deps = { data, logger: logger9 };
|
|
3907
4063
|
const progress3 = await getProgress({ enrollmentId: activeCourse.enrollmentId }, deps);
|
|
3908
4064
|
if (opts.json) {
|
|
3909
4065
|
output(progress3, { json: true });
|
|
@@ -5468,7 +5624,7 @@ var init_query_promise = __esm({
|
|
|
5468
5624
|
function mapResultRow(columns, row, joinsNotNullableMap) {
|
|
5469
5625
|
const nullifyMap = {};
|
|
5470
5626
|
const result = columns.reduce(
|
|
5471
|
-
(result2, { path:
|
|
5627
|
+
(result2, { path: path24, field }, columnIndex) => {
|
|
5472
5628
|
let decoder;
|
|
5473
5629
|
if (is(field, Column)) {
|
|
5474
5630
|
decoder = field;
|
|
@@ -5480,8 +5636,8 @@ function mapResultRow(columns, row, joinsNotNullableMap) {
|
|
|
5480
5636
|
decoder = field.sql.decoder;
|
|
5481
5637
|
}
|
|
5482
5638
|
let node = result2;
|
|
5483
|
-
for (const [pathChunkIndex, pathChunk] of
|
|
5484
|
-
if (pathChunkIndex <
|
|
5639
|
+
for (const [pathChunkIndex, pathChunk] of path24.entries()) {
|
|
5640
|
+
if (pathChunkIndex < path24.length - 1) {
|
|
5485
5641
|
if (!(pathChunk in node)) {
|
|
5486
5642
|
node[pathChunk] = {};
|
|
5487
5643
|
}
|
|
@@ -5489,8 +5645,8 @@ function mapResultRow(columns, row, joinsNotNullableMap) {
|
|
|
5489
5645
|
} else {
|
|
5490
5646
|
const rawValue = row[columnIndex];
|
|
5491
5647
|
const value = node[pathChunk] = rawValue === null ? null : decoder.mapFromDriverValue(rawValue);
|
|
5492
|
-
if (joinsNotNullableMap && is(field, Column) &&
|
|
5493
|
-
const objectName =
|
|
5648
|
+
if (joinsNotNullableMap && is(field, Column) && path24.length === 2) {
|
|
5649
|
+
const objectName = path24[0];
|
|
5494
5650
|
if (!(objectName in nullifyMap)) {
|
|
5495
5651
|
nullifyMap[objectName] = value === null ? getTableName(field.table) : false;
|
|
5496
5652
|
} else if (typeof nullifyMap[objectName] === "string" && nullifyMap[objectName] !== getTableName(field.table)) {
|
|
@@ -9437,13 +9593,13 @@ function Subscribe(postgres2, options) {
|
|
|
9437
9593
|
}
|
|
9438
9594
|
}
|
|
9439
9595
|
function handle(a, b2) {
|
|
9440
|
-
const
|
|
9596
|
+
const path24 = b2.relation.schema + "." + b2.relation.table;
|
|
9441
9597
|
call("*", a, b2);
|
|
9442
|
-
call("*:" +
|
|
9443
|
-
b2.relation.keys.length && call("*:" +
|
|
9598
|
+
call("*:" + path24, a, b2);
|
|
9599
|
+
b2.relation.keys.length && call("*:" + path24 + "=" + b2.relation.keys.map((x2) => a[x2.name]), a, b2);
|
|
9444
9600
|
call(b2.command, a, b2);
|
|
9445
|
-
call(b2.command + ":" +
|
|
9446
|
-
b2.relation.keys.length && call(b2.command + ":" +
|
|
9601
|
+
call(b2.command + ":" + path24, a, b2);
|
|
9602
|
+
b2.relation.keys.length && call(b2.command + ":" + path24 + "=" + b2.relation.keys.map((x2) => a[x2.name]), a, b2);
|
|
9447
9603
|
}
|
|
9448
9604
|
function pong() {
|
|
9449
9605
|
const x2 = Buffer.alloc(34);
|
|
@@ -9556,8 +9712,8 @@ function parseEvent(x) {
|
|
|
9556
9712
|
const xs = x.match(/^(\*|insert|update|delete)?:?([^.]+?\.?[^=]+)?=?(.+)?/i) || [];
|
|
9557
9713
|
if (!xs)
|
|
9558
9714
|
throw new Error("Malformed subscribe pattern: " + x);
|
|
9559
|
-
const [, command,
|
|
9560
|
-
return (command || "*") + (
|
|
9715
|
+
const [, command, path24, key] = xs;
|
|
9716
|
+
return (command || "*") + (path24 ? ":" + (path24.indexOf(".") === -1 ? "public." + path24 : path24) : "") + (key ? "=" + key : "");
|
|
9561
9717
|
}
|
|
9562
9718
|
var noop2;
|
|
9563
9719
|
var init_subscribe = __esm({
|
|
@@ -9695,10 +9851,10 @@ function Postgres(a, b2) {
|
|
|
9695
9851
|
});
|
|
9696
9852
|
return query;
|
|
9697
9853
|
}
|
|
9698
|
-
function file2(
|
|
9854
|
+
function file2(path24, args = [], options2 = {}) {
|
|
9699
9855
|
arguments.length === 2 && !Array.isArray(args) && (options2 = args, args = []);
|
|
9700
9856
|
const query = new Query([], args, (query2) => {
|
|
9701
|
-
fs11.readFile(
|
|
9857
|
+
fs11.readFile(path24, "utf8", (err, string4) => {
|
|
9702
9858
|
if (err)
|
|
9703
9859
|
return query2.reject(err);
|
|
9704
9860
|
query2.strings = [string4];
|
|
@@ -14277,12 +14433,12 @@ var init_session2 = __esm({
|
|
|
14277
14433
|
init_tracing();
|
|
14278
14434
|
init_utils();
|
|
14279
14435
|
PostgresJsPreparedQuery = class extends PgPreparedQuery {
|
|
14280
|
-
constructor(client, queryString, params,
|
|
14436
|
+
constructor(client, queryString, params, logger35, cache, queryMetadata, cacheConfig, fields, _isResponseInArrayMode, customResultMapper) {
|
|
14281
14437
|
super({ sql: queryString, params }, cache, queryMetadata, cacheConfig);
|
|
14282
14438
|
this.client = client;
|
|
14283
14439
|
this.queryString = queryString;
|
|
14284
14440
|
this.params = params;
|
|
14285
|
-
this.logger =
|
|
14441
|
+
this.logger = logger35;
|
|
14286
14442
|
this.fields = fields;
|
|
14287
14443
|
this._isResponseInArrayMode = _isResponseInArrayMode;
|
|
14288
14444
|
this.customResultMapper = customResultMapper;
|
|
@@ -14423,11 +14579,11 @@ function construct(client, config2 = {}) {
|
|
|
14423
14579
|
client.options.serializers["114"] = transparentParser;
|
|
14424
14580
|
client.options.serializers["3802"] = transparentParser;
|
|
14425
14581
|
const dialect = new PgDialect({ casing: config2.casing });
|
|
14426
|
-
let
|
|
14582
|
+
let logger35;
|
|
14427
14583
|
if (config2.logger === true) {
|
|
14428
|
-
|
|
14584
|
+
logger35 = new DefaultLogger();
|
|
14429
14585
|
} else if (config2.logger !== false) {
|
|
14430
|
-
|
|
14586
|
+
logger35 = config2.logger;
|
|
14431
14587
|
}
|
|
14432
14588
|
let schema;
|
|
14433
14589
|
if (config2.schema) {
|
|
@@ -14441,7 +14597,7 @@ function construct(client, config2 = {}) {
|
|
|
14441
14597
|
tableNamesMap: tablesConfig.tableNamesMap
|
|
14442
14598
|
};
|
|
14443
14599
|
}
|
|
14444
|
-
const session = new PostgresJsSession(client, dialect, schema, { logger:
|
|
14600
|
+
const session = new PostgresJsSession(client, dialect, schema, { logger: logger35, cache: config2.cache });
|
|
14445
14601
|
const db2 = new PostgresJsDatabase(dialect, session, schema);
|
|
14446
14602
|
db2.$client = client;
|
|
14447
14603
|
db2.$cache = config2.cache;
|
|
@@ -14756,10 +14912,10 @@ function mergeDefs(...defs) {
|
|
|
14756
14912
|
function cloneDef(schema) {
|
|
14757
14913
|
return mergeDefs(schema._zod.def);
|
|
14758
14914
|
}
|
|
14759
|
-
function getElementAtPath(obj,
|
|
14760
|
-
if (!
|
|
14915
|
+
function getElementAtPath(obj, path24) {
|
|
14916
|
+
if (!path24)
|
|
14761
14917
|
return obj;
|
|
14762
|
-
return
|
|
14918
|
+
return path24.reduce((acc, key) => acc?.[key], obj);
|
|
14763
14919
|
}
|
|
14764
14920
|
function promiseAllObject(promisesObj) {
|
|
14765
14921
|
const keys = Object.keys(promisesObj);
|
|
@@ -15071,11 +15227,11 @@ function aborted(x, startIndex = 0) {
|
|
|
15071
15227
|
}
|
|
15072
15228
|
return false;
|
|
15073
15229
|
}
|
|
15074
|
-
function prefixIssues(
|
|
15230
|
+
function prefixIssues(path24, issues) {
|
|
15075
15231
|
return issues.map((iss) => {
|
|
15076
15232
|
var _a2;
|
|
15077
15233
|
(_a2 = iss).path ?? (_a2.path = []);
|
|
15078
|
-
iss.path.unshift(
|
|
15234
|
+
iss.path.unshift(path24);
|
|
15079
15235
|
return iss;
|
|
15080
15236
|
});
|
|
15081
15237
|
}
|
|
@@ -15317,7 +15473,7 @@ function formatError(error49, mapper = (issue2) => issue2.message) {
|
|
|
15317
15473
|
}
|
|
15318
15474
|
function treeifyError(error49, mapper = (issue2) => issue2.message) {
|
|
15319
15475
|
const result = { errors: [] };
|
|
15320
|
-
const processError = (error50,
|
|
15476
|
+
const processError = (error50, path24 = []) => {
|
|
15321
15477
|
var _a2, _b;
|
|
15322
15478
|
for (const issue2 of error50.issues) {
|
|
15323
15479
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
@@ -15327,7 +15483,7 @@ function treeifyError(error49, mapper = (issue2) => issue2.message) {
|
|
|
15327
15483
|
} else if (issue2.code === "invalid_element") {
|
|
15328
15484
|
processError({ issues: issue2.issues }, issue2.path);
|
|
15329
15485
|
} else {
|
|
15330
|
-
const fullpath = [...
|
|
15486
|
+
const fullpath = [...path24, ...issue2.path];
|
|
15331
15487
|
if (fullpath.length === 0) {
|
|
15332
15488
|
result.errors.push(mapper(issue2));
|
|
15333
15489
|
continue;
|
|
@@ -15359,8 +15515,8 @@ function treeifyError(error49, mapper = (issue2) => issue2.message) {
|
|
|
15359
15515
|
}
|
|
15360
15516
|
function toDotPath(_path) {
|
|
15361
15517
|
const segs = [];
|
|
15362
|
-
const
|
|
15363
|
-
for (const seg of
|
|
15518
|
+
const path24 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
|
|
15519
|
+
for (const seg of path24) {
|
|
15364
15520
|
if (typeof seg === "number")
|
|
15365
15521
|
segs.push(`[${seg}]`);
|
|
15366
15522
|
else if (typeof seg === "symbol")
|
|
@@ -28054,13 +28210,13 @@ function resolveRef(ref, ctx) {
|
|
|
28054
28210
|
if (!ref.startsWith("#")) {
|
|
28055
28211
|
throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
|
|
28056
28212
|
}
|
|
28057
|
-
const
|
|
28058
|
-
if (
|
|
28213
|
+
const path24 = ref.slice(1).split("/").filter(Boolean);
|
|
28214
|
+
if (path24.length === 0) {
|
|
28059
28215
|
return ctx.rootSchema;
|
|
28060
28216
|
}
|
|
28061
28217
|
const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
|
|
28062
|
-
if (
|
|
28063
|
-
const key =
|
|
28218
|
+
if (path24[0] === defsKey) {
|
|
28219
|
+
const key = path24[1];
|
|
28064
28220
|
if (!key || !ctx.defs[key]) {
|
|
28065
28221
|
throw new Error(`Reference not found: ${ref}`);
|
|
28066
28222
|
}
|
|
@@ -29167,7 +29323,7 @@ var init_user_preferences = __esm({
|
|
|
29167
29323
|
});
|
|
29168
29324
|
|
|
29169
29325
|
// ../../packages/database/src/schema/mcp.ts
|
|
29170
|
-
var mcpSessions, syncLogs
|
|
29326
|
+
var mcpSessions, syncLogs;
|
|
29171
29327
|
var init_mcp = __esm({
|
|
29172
29328
|
"../../packages/database/src/schema/mcp.ts"() {
|
|
29173
29329
|
"use strict";
|
|
@@ -29230,11 +29386,6 @@ var init_mcp = __esm({
|
|
|
29230
29386
|
syncedAtIdx: index("idx_sync_logs_synced_at").on(table.syncedAt)
|
|
29231
29387
|
})
|
|
29232
29388
|
);
|
|
29233
|
-
platformConfig = pgTable("platform_config", {
|
|
29234
|
-
key: varchar("key", { length: 50 }).primaryKey(),
|
|
29235
|
-
value: text("value").notNull(),
|
|
29236
|
-
updatedAt: timestamp("updated_at").defaultNow().notNull()
|
|
29237
|
-
});
|
|
29238
29389
|
}
|
|
29239
29390
|
});
|
|
29240
29391
|
|
|
@@ -29568,6 +29719,13 @@ var init_tutor_feedback = __esm({
|
|
|
29568
29719
|
}
|
|
29569
29720
|
});
|
|
29570
29721
|
|
|
29722
|
+
// ../../packages/types/src/lesson-review.ts
|
|
29723
|
+
var init_lesson_review = __esm({
|
|
29724
|
+
"../../packages/types/src/lesson-review.ts"() {
|
|
29725
|
+
"use strict";
|
|
29726
|
+
}
|
|
29727
|
+
});
|
|
29728
|
+
|
|
29571
29729
|
// ../../packages/types/src/errors.ts
|
|
29572
29730
|
var init_errors6 = __esm({
|
|
29573
29731
|
"../../packages/types/src/errors.ts"() {
|
|
@@ -29599,7 +29757,8 @@ var init_credit_payment_enums = __esm({
|
|
|
29599
29757
|
// course_sale_credit (legacy Stripe 20/85) so reconciliation/clawback never
|
|
29600
29758
|
// conflate the two funding models.
|
|
29601
29759
|
"course_enrollment_debit",
|
|
29602
|
-
"course_enrollment_credit"
|
|
29760
|
+
"course_enrollment_credit",
|
|
29761
|
+
"referral_bonus"
|
|
29603
29762
|
];
|
|
29604
29763
|
CREDIT_SUBSCRIPTION_STATUS_VALUES = [
|
|
29605
29764
|
"active",
|
|
@@ -29619,6 +29778,13 @@ var init_credit_payment_enums = __esm({
|
|
|
29619
29778
|
}
|
|
29620
29779
|
});
|
|
29621
29780
|
|
|
29781
|
+
// ../../packages/types/src/referral.ts
|
|
29782
|
+
var init_referral = __esm({
|
|
29783
|
+
"../../packages/types/src/referral.ts"() {
|
|
29784
|
+
"use strict";
|
|
29785
|
+
}
|
|
29786
|
+
});
|
|
29787
|
+
|
|
29622
29788
|
// ../../packages/types/src/index.ts
|
|
29623
29789
|
var init_src2 = __esm({
|
|
29624
29790
|
"../../packages/types/src/index.ts"() {
|
|
@@ -29632,8 +29798,10 @@ var init_src2 = __esm({
|
|
|
29632
29798
|
init_exercise_type();
|
|
29633
29799
|
init_lesson_contract();
|
|
29634
29800
|
init_tutor_feedback();
|
|
29801
|
+
init_lesson_review();
|
|
29635
29802
|
init_errors6();
|
|
29636
29803
|
init_credit_payment_enums();
|
|
29804
|
+
init_referral();
|
|
29637
29805
|
}
|
|
29638
29806
|
});
|
|
29639
29807
|
|
|
@@ -30016,7 +30184,7 @@ var init_llm_analytics = __esm({
|
|
|
30016
30184
|
// Operation type
|
|
30017
30185
|
operationType: varchar("operation_type", { length: 50 }).notNull(),
|
|
30018
30186
|
// Provider (references llm_provider enum from llm-pricing.ts)
|
|
30019
|
-
provider: llmProviderEnum("provider").notNull().default("
|
|
30187
|
+
provider: llmProviderEnum("provider").notNull().default("other"),
|
|
30020
30188
|
// Tracing
|
|
30021
30189
|
correlationId: varchar("correlation_id", { length: 64 }),
|
|
30022
30190
|
// Relationships
|
|
@@ -30036,6 +30204,11 @@ var init_llm_analytics = __esm({
|
|
|
30036
30204
|
responseTokens: integer("response_tokens"),
|
|
30037
30205
|
// Cost & Revenue
|
|
30038
30206
|
costUsd: decimal("cost_usd", { precision: 10, scale: 6 }),
|
|
30207
|
+
// spec 2026-07-10 phase 3.3: where cost_usd came from - 'table' (pricing
|
|
30208
|
+
// table rate), 'gateway' (LiteLLM-reported cost fallback), 'unpriced'
|
|
30209
|
+
// (no rate anywhere: cost_usd=0, alertable). Nullable: rows predating the
|
|
30210
|
+
// marker stay null.
|
|
30211
|
+
costSource: varchar("cost_source", { length: 16 }),
|
|
30039
30212
|
revenueUsd: decimal("revenue_usd", { precision: 10, scale: 6 }).default("0"),
|
|
30040
30213
|
// Cache metrics (prompt caching)
|
|
30041
30214
|
cacheCreationTokens: integer("cache_creation_tokens").default(0),
|
|
@@ -30062,6 +30235,12 @@ var init_llm_analytics = __esm({
|
|
|
30062
30235
|
"llm_interactions_status_check",
|
|
30063
30236
|
sql`${table.status} IN ('pending', 'success', 'error', 'timeout', 'abandoned')`
|
|
30064
30237
|
),
|
|
30238
|
+
// spec 2026-07-10 phase 3.3: cost_source vocabulary — NULL allowed for
|
|
30239
|
+
// rows predating the marker.
|
|
30240
|
+
costSourceVocabularyCheck: check(
|
|
30241
|
+
"llm_interactions_cost_source_check",
|
|
30242
|
+
sql`${table.costSource} IS NULL OR ${table.costSource} IN ('table', 'gateway', 'unpriced')`
|
|
30243
|
+
),
|
|
30065
30244
|
creatorIdx: index("idx_llm_interactions_creator").on(table.creatorId, table.createdAt),
|
|
30066
30245
|
operationIdx: index("idx_llm_interactions_operation").on(table.operationType, table.createdAt),
|
|
30067
30246
|
correlationIdx: index("idx_llm_interactions_correlation").on(table.correlationId),
|
|
@@ -30148,7 +30327,9 @@ var init_credit_wallets = __esm({
|
|
|
30148
30327
|
// Credits-first (WS3/WS4): student debit (-), creator full-price credit (+).
|
|
30149
30328
|
course_enrollment_debit: "negative",
|
|
30150
30329
|
course_enrollment_credit: "positive",
|
|
30151
|
-
adjustment: "either"
|
|
30330
|
+
adjustment: "either",
|
|
30331
|
+
// Referral program (spec 2026-07-17): both-sides fixed grant on first purchase.
|
|
30332
|
+
referral_bonus: "positive"
|
|
30152
30333
|
};
|
|
30153
30334
|
WITHDRAWABLE_LEDGER_TYPES = [
|
|
30154
30335
|
"course_sale_credit",
|
|
@@ -30194,6 +30375,7 @@ var init_credit_wallets = __esm({
|
|
|
30194
30375
|
"subscription",
|
|
30195
30376
|
"package",
|
|
30196
30377
|
"withdrawal",
|
|
30378
|
+
"referral",
|
|
30197
30379
|
"backfill",
|
|
30198
30380
|
"credit_transaction_migration"
|
|
30199
30381
|
];
|
|
@@ -30248,6 +30430,12 @@ var init_credit_wallets = __esm({
|
|
|
30248
30430
|
// the PK). Raw `sql` literal (not eq()) to dodge the drizzle-kit `$N`
|
|
30249
30431
|
// placeholder DDL bug — see packages/database/AGENTS.md.
|
|
30250
30432
|
courseSaleCreditEnrollmentUnique: uniqueIndex("cwt_course_sale_credit_enrollment_unique").on(table.referenceId, table.referenceType, table.type).where(sql`${table.type} = 'course_sale_credit' AND ${table.referenceType} = 'enrollment'`),
|
|
30433
|
+
cwtPurchasePaymentIntentUnique: uniqueIndex("cwt_purchase_payment_intent_unique").on(sql`(${table.metadata}->>'stripe_payment_intent_id')`).where(sql`${table.type} = 'purchase'`),
|
|
30434
|
+
// Idempotency guard for subscription reloads via stripe invoice.
|
|
30435
|
+
// Closes the double-reload window when Stripe invoice webhook fires concurrently
|
|
30436
|
+
// or re-delivers. Raw `sql` literal (not eq()) to dodge the drizzle-kit `$N`
|
|
30437
|
+
// placeholder DDL bug — see packages/database/AGENTS.md.
|
|
30438
|
+
cwtSubscriptionReloadInvoiceUnique: uniqueIndex("cwt_subscription_reload_invoice_unique").on(sql`(${table.metadata}->>'stripe_invoice_id')`).where(sql`${table.type} = 'subscription_reload'`),
|
|
30251
30439
|
// Idempotency guard for the AI-consumption reconciliation sweep (CHORE-credit-recon).
|
|
30252
30440
|
// The sweep must not double-charge a debit the inline path already committed;
|
|
30253
30441
|
// this index makes the DB the final arbiter — a second ai_consumption insert
|
|
@@ -30257,23 +30445,34 @@ var init_credit_wallets = __esm({
|
|
|
30257
30445
|
// Raw `sql` literal (not eq()) to dodge the drizzle-kit `$N` placeholder DDL
|
|
30258
30446
|
// bug (packages/database/AGENTS.md).
|
|
30259
30447
|
aiConsumptionInteractionUniq: uniqueIndex("cwt_ai_consumption_interaction_uniq").on(table.interactionId).where(sql`${table.type} = 'ai_consumption' AND ${table.interactionId} IS NOT NULL`),
|
|
30260
|
-
// Credits-first (
|
|
30261
|
-
//
|
|
30262
|
-
//
|
|
30263
|
-
//
|
|
30264
|
-
//
|
|
30265
|
-
//
|
|
30266
|
-
//
|
|
30267
|
-
//
|
|
30268
|
-
//
|
|
30269
|
-
//
|
|
30270
|
-
//
|
|
30271
|
-
//
|
|
30448
|
+
// Credits-first ramp gate (credits-ssot-ux WS1): partial UNIQUE closes the
|
|
30449
|
+
// double-debit window in EnrollWithCreditsUseCase before the
|
|
30450
|
+
// `feature.credit_debit_enrollment_enabled` ramp. The advisory lock + re-check
|
|
30451
|
+
// covers the double-click case, but the DB is the final arbiter against any
|
|
30452
|
+
// path that bypasses the lock (retry storms, future callers); the use-case
|
|
30453
|
+
// catches 23505 as AlreadyEnrolled. This is the "standalone migration once
|
|
30454
|
+
// these enum values are universally committed" the previous note here
|
|
30455
|
+
// anticipated: the enum values landed in 0044 (13 migrations back, deployed
|
|
30456
|
+
// to prod), and a cold-boot single-transaction `pnpm db:migrate` is safe
|
|
30457
|
+
// because the TYPE itself is created in that same transaction (enum.c's
|
|
30458
|
+
// check_safe_enum_use only restricts values added to a PRE-EXISTING type).
|
|
30459
|
+
// Scoped to type='course_enrollment_debit' AND reference_type='enrollment' —
|
|
30460
|
+
// predicate-disjoint from every other partial index on this table, so the
|
|
30461
|
+
// `undefined`-constraint branches of the sibling 23505 detectors stay safe.
|
|
30462
|
+
// course_enrollment_credit needs no index of its own: it is written in the
|
|
30463
|
+
// SAME transaction as the debit, so the debit index aborts both. Raw `sql`
|
|
30464
|
+
// literal (not eq()) to dodge the drizzle-kit `$N` placeholder DDL bug —
|
|
30465
|
+
// see packages/database/AGENTS.md.
|
|
30466
|
+
courseEnrollmentDebitEnrollmentUnique: uniqueIndex(
|
|
30467
|
+
"cwt_course_enrollment_debit_enrollment_unique"
|
|
30468
|
+
).on(table.referenceId, table.referenceType, table.type).where(
|
|
30469
|
+
sql`${table.type} = 'course_enrollment_debit' AND ${table.referenceType} = 'enrollment'`
|
|
30470
|
+
),
|
|
30272
30471
|
referenceTypeCheck: check(
|
|
30273
30472
|
"cwt_reference_type_check",
|
|
30274
30473
|
sql`${table.referenceType} IS NULL OR ${table.referenceType} IN (
|
|
30275
30474
|
'ai_operation', 'enrollment', 'booking',
|
|
30276
|
-
'subscription', 'package', 'withdrawal',
|
|
30475
|
+
'subscription', 'package', 'withdrawal', 'referral',
|
|
30277
30476
|
'backfill', 'credit_transaction_migration'
|
|
30278
30477
|
)`
|
|
30279
30478
|
)
|
|
@@ -30323,6 +30522,10 @@ var init_credit_packages = __esm({
|
|
|
30323
30522
|
}).notNull(),
|
|
30324
30523
|
isActive: boolean("is_active").notNull().default(true),
|
|
30325
30524
|
includesCatalog: boolean("includes_catalog").notNull().default(true),
|
|
30525
|
+
// Subscription tiers 2026-07-07 spec: % off AI-usage debits (0 = none).
|
|
30526
|
+
consumptionDiscountPercent: integer("consumption_discount_percent").notNull().default(0),
|
|
30527
|
+
// Course enrollments redeemable per billing cycle (0 = none; Pro = 1).
|
|
30528
|
+
courseEnrollmentsPerMonth: integer("course_enrollments_per_month").notNull().default(0),
|
|
30326
30529
|
sortOrder: integer("sort_order").notNull().default(0),
|
|
30327
30530
|
createdAt: timestamp("created_at", { withTimezone: true }).defaultNow().notNull(),
|
|
30328
30531
|
updatedAt: timestamp("updated_at", { withTimezone: true }).defaultNow().notNull()
|
|
@@ -30330,7 +30533,12 @@ var init_credit_packages = __esm({
|
|
|
30330
30533
|
(table) => ({
|
|
30331
30534
|
creditsPositive: check("csp_credits_positive", sql`${table.creditsPerMonth} > 0`),
|
|
30332
30535
|
pricePositive: check("csp_price_positive", sql`${table.priceUsdMonthly} > 0`),
|
|
30333
|
-
nameSlugPattern: check("csp_name_slug_pattern", sql`${table.name} ~ '^[a-z][a-z0-9_]{0,49}$'`)
|
|
30536
|
+
nameSlugPattern: check("csp_name_slug_pattern", sql`${table.name} ~ '^[a-z][a-z0-9_]{0,49}$'`),
|
|
30537
|
+
discountRange: check(
|
|
30538
|
+
"csp_discount_range",
|
|
30539
|
+
sql`${table.consumptionDiscountPercent} >= 0 AND ${table.consumptionDiscountPercent} <= 90`
|
|
30540
|
+
),
|
|
30541
|
+
quotaNonNegative: check("csp_quota_non_negative", sql`${table.courseEnrollmentsPerMonth} >= 0`)
|
|
30334
30542
|
})
|
|
30335
30543
|
);
|
|
30336
30544
|
creditSubscriptions = pgTable(
|
|
@@ -30363,7 +30571,13 @@ var init_credit_packages = __esm({
|
|
|
30363
30571
|
(table) => ({
|
|
30364
30572
|
userIdx: index("cs_user_idx").on(table.userId),
|
|
30365
30573
|
stripeSubIdx: index("cs_stripe_sub_idx").on(table.stripeSubscriptionId),
|
|
30366
|
-
lastInvoiceIdx: index("cs_last_invoice_idx").on(table.lastInvoiceId)
|
|
30574
|
+
lastInvoiceIdx: index("cs_last_invoice_idx").on(table.lastInvoiceId),
|
|
30575
|
+
// #793: one live billable row per user. createSubscription's active/past_due
|
|
30576
|
+
// guard checks-then-inserts without a lock; this closes the double-submit
|
|
30577
|
+
// race (deferred "while latent" in credit-wallet.router.ts — the rm-030
|
|
30578
|
+
// acquisition UI un-latents it). Raw sql in .where() — drizzle-kit
|
|
30579
|
+
// serializes eq() as a $N placeholder in partial-index DDL (42P02).
|
|
30580
|
+
activeUserUnique: uniqueIndex("cs_active_user_unique").on(table.userId).where(sql`status = 'active'`)
|
|
30367
30581
|
})
|
|
30368
30582
|
);
|
|
30369
30583
|
}
|
|
@@ -31026,7 +31240,7 @@ var init_enrollment_channel_changes = __esm({
|
|
|
31026
31240
|
});
|
|
31027
31241
|
|
|
31028
31242
|
// ../../packages/database/migrations/schema.ts
|
|
31029
|
-
var applicableTo, badgeCriteriaType, badgeTier, badgeType, brainstormStatus, cancellationReason, challengeType, communityPostType, courseReviewStatus, courseStatus, discountType, enrollmentStatus, funnelEventType, knowledgeProcessingStatus, knowledgeResourceType, knowledgeUrlMode, marketingContentType, mentorshipCreditStatus, mentorshipTransactionStatus, mentorshipTransactionType, moderationAction, moderationTarget, participantStatus, progressStatus, proposalStatus, refundReason, refundType, reportReason, reportStatus, resourceType, serviceType, sessionCancelledReason, sessionStatus, slaStatus, studentRole, testimonialStatus, threadStatus, transactionType, userRole, userStatus, goalType, skillLevel, pathStatus, milestoneStatus, tsvector, slashCommandAnalytics, notificationLogs, couponUsages, validationAttempts, users2, accounts2,
|
|
31243
|
+
var applicableTo, badgeCriteriaType, badgeTier, badgeType, brainstormStatus, cancellationReason, challengeType, communityPostType, courseReviewStatus, courseStatus, discountType, enrollmentStatus, funnelEventType, knowledgeProcessingStatus, knowledgeResourceType, knowledgeUrlMode, marketingContentType, mentorshipCreditStatus, mentorshipTransactionStatus, mentorshipTransactionType, moderationAction, moderationTarget, participantStatus, progressStatus, proposalStatus, refundReason, refundType, reportReason, reportStatus, resourceType, serviceType, sessionCancelledReason, sessionStatus, slaStatus, studentRole, testimonialStatus, threadStatus, transactionType, userRole, userStatus, goalType, skillLevel, pathStatus, milestoneStatus, tsvector, slashCommandAnalytics, notificationLogs, couponUsages, validationAttempts, users2, accounts2, platformConfig, concepts2, mentorshipMessages, courseReviews2, webhookEvents, sessions2, courses2, badges2, userBadges2, challenges, userChallengeScores, leaderboardPreferences, onboardingAnalytics, creatorApplications, reviews, certificates2, userPreferences2, progress2, mentorshipTemplates, notifications, lessons2, syncLogs2, mentorshipThreads, courseReports2, mcpSessions2, transactions, enrollments2, reviewHelpfulVotes, modules2, coupons, funnelEvents, moderationLog, mentorshipServices, mentorAvailability, mentorAvailabilityExceptions, sessionWaitlist, sessionParticipants, mentorshipTransactions, mentorshipSessions, sessionResources, sessionReviews, mentorshipPackages, mentorshipCredits, refundAuditLog, sessionReviewVotes, communityPosts, communityComments, communityLikes, userFollows, sparkChatSessions, platformSettings, generationState, creatorTestimonials, marketingContent, studentNotes, userCredits, userUsageQuotas, usageTierLimits, brainstormSessions, creditTransactions, courseProposals, brainstormMessages, knowledgeResources, knowledgeChunks, verificationTokens2, studentTutorContext, tutorInteractionHistory, studentLearningPreferences, learningStreaks, dailyGoals, dailyGoalProgress, learningPaths, pathCourses, pathMilestones;
|
|
31030
31244
|
var init_schema2 = __esm({
|
|
31031
31245
|
"../../packages/database/migrations/schema.ts"() {
|
|
31032
31246
|
"use strict";
|
|
@@ -31489,7 +31703,7 @@ var init_schema2 = __esm({
|
|
|
31489
31703
|
}).onDelete("cascade")
|
|
31490
31704
|
]
|
|
31491
31705
|
);
|
|
31492
|
-
|
|
31706
|
+
platformConfig = pgTable("platform_config", {
|
|
31493
31707
|
key: varchar({ length: 50 }).primaryKey().notNull(),
|
|
31494
31708
|
value: text().notNull(),
|
|
31495
31709
|
updatedAt: timestamp("updated_at", { mode: "string" }).defaultNow().notNull()
|
|
@@ -35885,13 +36099,17 @@ var init_mentorship_credits = __esm({
|
|
|
35885
36099
|
// Package lookup
|
|
35886
36100
|
packageIdIdx: index("mentorship_credits_package_id_idx").on(table.packageId),
|
|
35887
36101
|
// Stripe payment intent lookup (for webhook idempotency)
|
|
35888
|
-
|
|
35889
|
-
table.stripePaymentIntentId
|
|
35890
|
-
),
|
|
36102
|
+
stripePaymentIntentIdUnique: uniqueIndex("mentorship_credits_stripe_payment_intent_unique").on(table.stripePaymentIntentId).where(sql`${table.stripePaymentIntentId} IS NOT NULL`),
|
|
35891
36103
|
// ORDER BY purchasedAt DESC (credit transaction history)
|
|
35892
36104
|
purchasedAtIdx: index("mentorship_credits_purchased_at_idx").on(table.purchasedAt),
|
|
35893
36105
|
// FEAT-1288: refund revoke looks up course-granted credits by enrollment
|
|
35894
36106
|
enrollmentIdIdx: index("mentorship_credits_enrollment_id_idx").on(table.enrollmentId),
|
|
36107
|
+
// GH #905 F5: one course-purchase grant per enrollment. The check-then-write
|
|
36108
|
+
// in GrantCourseMentoriaCreditsUseCase races on Stripe webhook re-delivery
|
|
36109
|
+
// (stripe_payment_intent_id is null for these rows, so the existing intent
|
|
36110
|
+
// unique index doesn't cover them). This partial unique index is the DB-side
|
|
36111
|
+
// idempotency guard; the use case catches 23505 as a no-op.
|
|
36112
|
+
courseEnrollmentUnique: uniqueIndex("mentorship_credits_course_enrollment_unique").on(table.enrollmentId).where(sql`${table.origin} = 'course_purchase' AND ${table.enrollmentId} IS NOT NULL`),
|
|
35895
36113
|
// FEAT-1288: each origin carries its tracing FK — package rows keep a
|
|
35896
36114
|
// package_id, course-purchase rows keep an enrollment_id.
|
|
35897
36115
|
originConsistencyCheck: check(
|
|
@@ -35985,6 +36203,7 @@ var init_mentorship_transactions = __esm({
|
|
|
35985
36203
|
"../../packages/database/src/schema/mentorship-transactions.ts"() {
|
|
35986
36204
|
"use strict";
|
|
35987
36205
|
init_pg_core();
|
|
36206
|
+
init_drizzle_orm();
|
|
35988
36207
|
init_users();
|
|
35989
36208
|
init_mentorship_sessions();
|
|
35990
36209
|
init_mentorship_packages();
|
|
@@ -36085,9 +36304,9 @@ var init_mentorship_transactions = __esm({
|
|
|
36085
36304
|
studentIdIdx: index("mentorship_transactions_student_id_idx").on(table.studentId),
|
|
36086
36305
|
mentorIdIdx: index("mentorship_transactions_mentor_id_idx").on(table.mentorId),
|
|
36087
36306
|
statusIdx: index("mentorship_transactions_status_idx").on(table.status),
|
|
36088
|
-
|
|
36089
|
-
|
|
36090
|
-
),
|
|
36307
|
+
stripePaymentIntentIdUnique: uniqueIndex(
|
|
36308
|
+
"mentorship_transactions_stripe_payment_intent_id_unique"
|
|
36309
|
+
).on(table.stripePaymentIntentId).where(sql`${table.stripePaymentIntentId} IS NOT NULL`),
|
|
36091
36310
|
createdAtIdx: index("mentorship_transactions_created_at_idx").on(table.createdAt),
|
|
36092
36311
|
// Story 19.3: Additional indexes for split and aggregation
|
|
36093
36312
|
typeIdx: index("mentorship_transactions_type_idx").on(table.transactionType),
|
|
@@ -37515,6 +37734,7 @@ var init_transactions = __esm({
|
|
|
37515
37734
|
"../../packages/database/src/schema/transactions.ts"() {
|
|
37516
37735
|
"use strict";
|
|
37517
37736
|
init_pg_core();
|
|
37737
|
+
init_drizzle_orm();
|
|
37518
37738
|
init_courses3();
|
|
37519
37739
|
init_users();
|
|
37520
37740
|
init_enrollments();
|
|
@@ -37523,9 +37743,13 @@ var init_transactions = __esm({
|
|
|
37523
37743
|
{
|
|
37524
37744
|
id: uuid("id").defaultRandom().primaryKey(),
|
|
37525
37745
|
// Stripe references
|
|
37526
|
-
stripePaymentIntentId: varchar("stripe_payment_intent_id", { length: 255 }).
|
|
37746
|
+
stripePaymentIntentId: varchar("stripe_payment_intent_id", { length: 255 }).unique(),
|
|
37527
37747
|
stripeTransferId: varchar("stripe_transfer_id", { length: 255 }),
|
|
37528
37748
|
// Stripe Transfer ID (if separate transfer)
|
|
37749
|
+
// spec 2026-07-31-pix-modobank: second inbound provider. 'stripe' rows keep
|
|
37750
|
+
// stripe_payment_intent_id; 'modobank' rows carry the e2eid here instead.
|
|
37751
|
+
provider: varchar("provider", { length: 20 }).notNull().default("stripe"),
|
|
37752
|
+
providerPaymentId: varchar("provider_payment_id", { length: 255 }),
|
|
37529
37753
|
// Foreign keys
|
|
37530
37754
|
courseId: uuid("course_id").notNull().references(() => courses.id, { onDelete: "restrict" }),
|
|
37531
37755
|
creatorId: uuid("creator_id").notNull().references(() => users.id, { onDelete: "restrict" }),
|
|
@@ -37597,6 +37821,56 @@ var init_transactions = __esm({
|
|
|
37597
37821
|
table.studentId,
|
|
37598
37822
|
table.status,
|
|
37599
37823
|
table.createdAt
|
|
37824
|
+
),
|
|
37825
|
+
// spec 2026-07-31-pix-modobank: dedupes per-provider payment refs; NULL
|
|
37826
|
+
// provider_payment_id (legacy Stripe rows, pre-webhook-write) is excluded.
|
|
37827
|
+
providerPaymentIdUnique: uniqueIndex("transactions_provider_payment_id_unique").on(table.provider, table.providerPaymentId).where(sql`${table.providerPaymentId} IS NOT NULL`)
|
|
37828
|
+
})
|
|
37829
|
+
);
|
|
37830
|
+
}
|
|
37831
|
+
});
|
|
37832
|
+
|
|
37833
|
+
// ../../packages/database/src/schema/pix-charges.ts
|
|
37834
|
+
var PIX_CHARGE_STATUSES, PIX_CHARGE_PURPOSES, pixCharges;
|
|
37835
|
+
var init_pix_charges = __esm({
|
|
37836
|
+
"../../packages/database/src/schema/pix-charges.ts"() {
|
|
37837
|
+
"use strict";
|
|
37838
|
+
init_drizzle_orm();
|
|
37839
|
+
init_pg_core();
|
|
37840
|
+
init_users();
|
|
37841
|
+
PIX_CHARGE_STATUSES = ["pending", "paid", "fulfilled", "expired", "refunded"];
|
|
37842
|
+
PIX_CHARGE_PURPOSES = ["course_sale", "credit_topup"];
|
|
37843
|
+
pixCharges = pgTable(
|
|
37844
|
+
"pix_charges",
|
|
37845
|
+
{
|
|
37846
|
+
id: uuid("id").defaultRandom().primaryKey(),
|
|
37847
|
+
txid: varchar("txid", { length: 35 }).notNull(),
|
|
37848
|
+
e2eid: varchar("e2eid", { length: 64 }),
|
|
37849
|
+
status: varchar("status", { length: 20 }).notNull().default("pending"),
|
|
37850
|
+
purpose: varchar("purpose", { length: 20 }).notNull(),
|
|
37851
|
+
userId: uuid("user_id").references(() => users.id, { onDelete: "restrict" }).notNull(),
|
|
37852
|
+
/** courseId (course_sale) or credit package id (credit_topup). */
|
|
37853
|
+
referenceId: uuid("reference_id"),
|
|
37854
|
+
amountBrlCents: integer("amount_brl_cents").notNull(),
|
|
37855
|
+
pixCopiaECola: text("pix_copia_e_cola").notNull(),
|
|
37856
|
+
/** course_sale: money breakdown replayed at fulfillment (creatorId, fees, couponId...). */
|
|
37857
|
+
metadata: jsonb("metadata").notNull().default(sql`'{}'::jsonb`),
|
|
37858
|
+
expiresAt: timestamp("expires_at", { withTimezone: true }).notNull(),
|
|
37859
|
+
paidAt: timestamp("paid_at", { withTimezone: true }),
|
|
37860
|
+
createdAt: timestamp("created_at", { withTimezone: true }).defaultNow().notNull(),
|
|
37861
|
+
updatedAt: timestamp("updated_at", { withTimezone: true }).defaultNow().notNull().$onUpdate(() => /* @__PURE__ */ new Date())
|
|
37862
|
+
},
|
|
37863
|
+
(table) => ({
|
|
37864
|
+
txidUnique: uniqueIndex("pix_charges_txid_unique").on(table.txid),
|
|
37865
|
+
userIdIdx: index("pix_charges_user_id_idx").on(table.userId),
|
|
37866
|
+
sweepIdx: index("pix_charges_sweep_idx").on(table.status, table.expiresAt),
|
|
37867
|
+
statusCheck: check(
|
|
37868
|
+
"pxc_status_check",
|
|
37869
|
+
sql`${table.status} IN ('pending', 'paid', 'fulfilled', 'expired', 'refunded')`
|
|
37870
|
+
),
|
|
37871
|
+
purposeCheck: check(
|
|
37872
|
+
"pxc_purpose_check",
|
|
37873
|
+
sql`${table.purpose} IN ('course_sale', 'credit_topup')`
|
|
37600
37874
|
)
|
|
37601
37875
|
})
|
|
37602
37876
|
);
|
|
@@ -38516,140 +38790,6 @@ var init_study_index = __esm({
|
|
|
38516
38790
|
}
|
|
38517
38791
|
});
|
|
38518
38792
|
|
|
38519
|
-
// ../../packages/database/src/schema/platform-settings.ts
|
|
38520
|
-
function parseSettingValue(value, valueType) {
|
|
38521
|
-
switch (valueType) {
|
|
38522
|
-
case "boolean":
|
|
38523
|
-
return value === "true";
|
|
38524
|
-
case "number":
|
|
38525
|
-
return Number(value);
|
|
38526
|
-
case "json":
|
|
38527
|
-
try {
|
|
38528
|
-
return JSON.parse(value);
|
|
38529
|
-
} catch {
|
|
38530
|
-
return null;
|
|
38531
|
-
}
|
|
38532
|
-
default:
|
|
38533
|
-
return value;
|
|
38534
|
-
}
|
|
38535
|
-
}
|
|
38536
|
-
function stringifySettingValue(value, valueType) {
|
|
38537
|
-
switch (valueType) {
|
|
38538
|
-
case "boolean":
|
|
38539
|
-
return value ? "true" : "false";
|
|
38540
|
-
case "number":
|
|
38541
|
-
return String(value);
|
|
38542
|
-
case "json":
|
|
38543
|
-
return JSON.stringify(value);
|
|
38544
|
-
default:
|
|
38545
|
-
return String(value);
|
|
38546
|
-
}
|
|
38547
|
-
}
|
|
38548
|
-
var settingValueTypes, settingCategories, platformSettings2, insertPlatformSettingSchema, selectPlatformSettingSchema, settingKeys;
|
|
38549
|
-
var init_platform_settings = __esm({
|
|
38550
|
-
"../../packages/database/src/schema/platform-settings.ts"() {
|
|
38551
|
-
"use strict";
|
|
38552
|
-
init_pg_core();
|
|
38553
|
-
init_zod();
|
|
38554
|
-
settingValueTypes = ["string", "boolean", "number", "json"];
|
|
38555
|
-
settingCategories = [
|
|
38556
|
-
"platform",
|
|
38557
|
-
"notifications",
|
|
38558
|
-
"security",
|
|
38559
|
-
"email",
|
|
38560
|
-
"financial"
|
|
38561
|
-
];
|
|
38562
|
-
platformSettings2 = pgTable(
|
|
38563
|
-
"platform_settings",
|
|
38564
|
-
{
|
|
38565
|
-
key: varchar("key", { length: 100 }).primaryKey(),
|
|
38566
|
-
value: text("value").notNull(),
|
|
38567
|
-
valueType: varchar("value_type", { length: 20 }).notNull().default("string"),
|
|
38568
|
-
category: varchar("category", { length: 50 }).notNull().default("general"),
|
|
38569
|
-
description: text("description"),
|
|
38570
|
-
updatedAt: timestamp("updated_at", { withTimezone: true }).defaultNow(),
|
|
38571
|
-
updatedBy: varchar("updated_by", { length: 255 })
|
|
38572
|
-
},
|
|
38573
|
-
(table) => [index("idx_platform_settings_category").on(table.category)]
|
|
38574
|
-
);
|
|
38575
|
-
insertPlatformSettingSchema = external_exports.object({
|
|
38576
|
-
key: external_exports.string().min(1).max(100),
|
|
38577
|
-
value: external_exports.string(),
|
|
38578
|
-
valueType: external_exports.enum(settingValueTypes).default("string"),
|
|
38579
|
-
category: external_exports.enum(settingCategories).default("platform"),
|
|
38580
|
-
description: external_exports.string().nullable().optional(),
|
|
38581
|
-
updatedBy: external_exports.string().nullable().optional()
|
|
38582
|
-
});
|
|
38583
|
-
selectPlatformSettingSchema = external_exports.object({
|
|
38584
|
-
key: external_exports.string(),
|
|
38585
|
-
value: external_exports.string(),
|
|
38586
|
-
valueType: external_exports.string(),
|
|
38587
|
-
category: external_exports.string(),
|
|
38588
|
-
description: external_exports.string().nullable(),
|
|
38589
|
-
updatedAt: external_exports.date().nullable(),
|
|
38590
|
-
updatedBy: external_exports.string().nullable()
|
|
38591
|
-
});
|
|
38592
|
-
settingKeys = {
|
|
38593
|
-
// Platform
|
|
38594
|
-
platformName: "platform_name",
|
|
38595
|
-
platformUrl: "platform_url",
|
|
38596
|
-
platformLogoUrl: "platform_logo_url",
|
|
38597
|
-
platformDescription: "platform_description",
|
|
38598
|
-
maintenanceMode: "maintenance_mode",
|
|
38599
|
-
// Notifications
|
|
38600
|
-
emailWelcome: "email_welcome",
|
|
38601
|
-
emailCourseApproved: "email_course_approved",
|
|
38602
|
-
emailNewEnrollment: "email_new_enrollment",
|
|
38603
|
-
adminSystemAlerts: "admin_system_alerts",
|
|
38604
|
-
// Security
|
|
38605
|
-
mfaRequiredAdmins: "mfa_required_admins",
|
|
38606
|
-
mfaRequiredCreators: "mfa_required_creators",
|
|
38607
|
-
sessionTimeoutMinutes: "session_timeout_minutes",
|
|
38608
|
-
maxLoginAttempts: "max_login_attempts",
|
|
38609
|
-
// Email
|
|
38610
|
-
emailFrom: "email_from",
|
|
38611
|
-
emailFromName: "email_from_name"
|
|
38612
|
-
};
|
|
38613
|
-
}
|
|
38614
|
-
});
|
|
38615
|
-
|
|
38616
|
-
// ../../packages/database/src/schema/admin-settings-audit.ts
|
|
38617
|
-
var adminSettingsAudit, adminSettingsAuditRelations;
|
|
38618
|
-
var init_admin_settings_audit = __esm({
|
|
38619
|
-
"../../packages/database/src/schema/admin-settings-audit.ts"() {
|
|
38620
|
-
"use strict";
|
|
38621
|
-
init_pg_core();
|
|
38622
|
-
init_drizzle_orm();
|
|
38623
|
-
init_users();
|
|
38624
|
-
adminSettingsAudit = pgTable(
|
|
38625
|
-
"admin_settings_audit",
|
|
38626
|
-
{
|
|
38627
|
-
id: uuid("id").defaultRandom().primaryKey(),
|
|
38628
|
-
// What changed
|
|
38629
|
-
settingKey: varchar("setting_key", { length: 100 }).notNull(),
|
|
38630
|
-
previousValue: jsonb("previous_value"),
|
|
38631
|
-
// nullable for new settings
|
|
38632
|
-
newValue: jsonb("new_value").notNull(),
|
|
38633
|
-
// Who changed it
|
|
38634
|
-
adminId: uuid("admin_id").references(() => users.id, { onDelete: "set null" }),
|
|
38635
|
-
// When
|
|
38636
|
-
createdAt: timestamp("created_at").defaultNow().notNull()
|
|
38637
|
-
},
|
|
38638
|
-
(table) => ({
|
|
38639
|
-
settingKeyIdx: index("admin_settings_audit_setting_key_idx").on(table.settingKey),
|
|
38640
|
-
adminIdIdx: index("admin_settings_audit_admin_id_idx").on(table.adminId),
|
|
38641
|
-
createdAtIdx: index("admin_settings_audit_created_at_idx").on(table.createdAt)
|
|
38642
|
-
})
|
|
38643
|
-
);
|
|
38644
|
-
adminSettingsAuditRelations = relations(adminSettingsAudit, ({ one }) => ({
|
|
38645
|
-
admin: one(users, {
|
|
38646
|
-
fields: [adminSettingsAudit.adminId],
|
|
38647
|
-
references: [users.id]
|
|
38648
|
-
})
|
|
38649
|
-
}));
|
|
38650
|
-
}
|
|
38651
|
-
});
|
|
38652
|
-
|
|
38653
38793
|
// ../../packages/database/src/schema/admin-activity-feed.ts
|
|
38654
38794
|
var adminActivityFeed, adminActivityFeedRelations;
|
|
38655
38795
|
var init_admin_activity_feed = __esm({
|
|
@@ -39859,26 +39999,19 @@ var init_system_config = __esm({
|
|
|
39859
39999
|
}));
|
|
39860
40000
|
configKeys = {
|
|
39861
40001
|
// AI - Generation
|
|
39862
|
-
|
|
40002
|
+
// GH #942: ai.*.model keys (generation/chat/study) retired — model comes from
|
|
40003
|
+
// the routing rule + gateway tier (GH #799 2b); DB keeps inference params only.
|
|
39863
40004
|
"ai.generation.max_tokens": "ai.generation.max_tokens",
|
|
39864
40005
|
"ai.generation.temperature": "ai.generation.temperature",
|
|
39865
40006
|
// AI - Chat
|
|
39866
|
-
"ai.chat.model": "ai.chat.model",
|
|
39867
40007
|
"ai.chat.max_tokens": "ai.chat.max_tokens",
|
|
39868
40008
|
"ai.chat.temperature": "ai.chat.temperature",
|
|
39869
40009
|
// AI - Study
|
|
39870
|
-
"ai.study.chat_model": "ai.study.chat_model",
|
|
39871
|
-
"ai.study.hint_model": "ai.study.hint_model",
|
|
39872
40010
|
"ai.study.max_tokens": "ai.study.max_tokens",
|
|
39873
40011
|
"ai.study.temperature": "ai.study.temperature",
|
|
39874
|
-
// AI - Costs
|
|
40012
|
+
// AI - Costs (GH #947: cache_optimization_enabled and ai.context.* purged;
|
|
40013
|
+
// GH #974: requests_per_minute purged — reader never mounted)
|
|
39875
40014
|
"ai.costs.daily_limit_usd": "ai.costs.daily_limit_usd",
|
|
39876
|
-
"ai.costs.requests_per_minute": "ai.costs.requests_per_minute",
|
|
39877
|
-
"ai.costs.cache_optimization_enabled": "ai.costs.cache_optimization_enabled",
|
|
39878
|
-
// AI - Context Window Management
|
|
39879
|
-
"ai.context.window_size": "ai.context.window_size",
|
|
39880
|
-
"ai.context.output_reserve": "ai.context.output_reserve",
|
|
39881
|
-
"ai.context.compression_threshold": "ai.context.compression_threshold",
|
|
39882
40015
|
// Business - Pricing
|
|
39883
40016
|
"business.pricing.min_course_price_brl": "business.pricing.min_course_price_brl",
|
|
39884
40017
|
"business.pricing.course_mentoria_creator_share": "business.pricing.course_mentoria_creator_share",
|
|
@@ -39895,6 +40028,8 @@ var init_system_config = __esm({
|
|
|
39895
40028
|
"business.monitoring.prompt_caching_discount": "business.monitoring.prompt_caching_discount",
|
|
39896
40029
|
"business.monitoring.llm_cost_warning_usd": "business.monitoring.llm_cost_warning_usd",
|
|
39897
40030
|
"business.monitoring.llm_cost_critical_usd": "business.monitoring.llm_cost_critical_usd",
|
|
40031
|
+
// GH #948: margin tolerance for the daily credit-reconciliation job
|
|
40032
|
+
"business.monitoring.margin_tolerance_percent": "business.monitoring.margin_tolerance_percent",
|
|
39898
40033
|
// Business - Limits
|
|
39899
40034
|
"business.limits.max_courses_per_creator": "business.limits.max_courses_per_creator",
|
|
39900
40035
|
"business.limits.max_modules_per_course": "business.limits.max_modules_per_course",
|
|
@@ -39907,21 +40042,11 @@ var init_system_config = __esm({
|
|
|
39907
40042
|
"feature.community_enabled": "feature.community_enabled",
|
|
39908
40043
|
"feature.certificates_enabled": "feature.certificates_enabled",
|
|
39909
40044
|
"feature.maintenance_mode": "feature.maintenance_mode",
|
|
39910
|
-
"feature.new_user_registration": "feature.new_user_registration",
|
|
39911
40045
|
"feature.require_creator_mfa": "feature.require_creator_mfa",
|
|
39912
40046
|
"feature.require_admin_mfa": "feature.require_admin_mfa",
|
|
39913
|
-
|
|
39914
|
-
|
|
39915
|
-
// Platform Identity
|
|
39916
|
-
"platform.identity.name": "platform.identity.name",
|
|
39917
|
-
"platform.identity.url": "platform.identity.url",
|
|
39918
|
-
"platform.identity.logo_url": "platform.identity.logo_url",
|
|
39919
|
-
"platform.identity.description": "platform.identity.description",
|
|
40047
|
+
// GH #947: feature.security.*, platform.identity.* and the four
|
|
40048
|
+
// notification.email.* toggles purged — zero functional readers.
|
|
39920
40049
|
// Notification Settings
|
|
39921
|
-
"notification.email.welcome_enabled": "notification.email.welcome_enabled",
|
|
39922
|
-
"notification.email.course_approved_enabled": "notification.email.course_approved_enabled",
|
|
39923
|
-
"notification.email.new_enrollment_enabled": "notification.email.new_enrollment_enabled",
|
|
39924
|
-
"notification.email.admin_system_alerts": "notification.email.admin_system_alerts",
|
|
39925
40050
|
"notification.sender.from_address": "notification.sender.from_address",
|
|
39926
40051
|
"notification.sender.from_name": "notification.sender.from_name"
|
|
39927
40052
|
};
|
|
@@ -41192,7 +41317,6 @@ var init_relations_auth = __esm({
|
|
|
41192
41317
|
init_user_regional_settings();
|
|
41193
41318
|
init_users();
|
|
41194
41319
|
init_validation_attempts();
|
|
41195
|
-
init_admin_settings_audit();
|
|
41196
41320
|
init_brainstormings();
|
|
41197
41321
|
init_course_review_snapshots();
|
|
41198
41322
|
init_learning_paths();
|
|
@@ -41250,7 +41374,6 @@ var init_relations_auth = __esm({
|
|
|
41250
41374
|
dailyGoal: one(dailyGoals2),
|
|
41251
41375
|
dailyGoalProgress: many(dailyGoalProgress2),
|
|
41252
41376
|
regionalSettings: one(userRegionalSettings),
|
|
41253
|
-
adminSettingsAuditLogs: many(adminSettingsAudit),
|
|
41254
41377
|
creatorAuditLogs: many(creatorAuditLog),
|
|
41255
41378
|
lessonRefinements: many(lessonRefinements),
|
|
41256
41379
|
courseReviewSnapshots: many(courseReviewSnapshots),
|
|
@@ -43035,6 +43158,77 @@ var init_idempotency = __esm({
|
|
|
43035
43158
|
}
|
|
43036
43159
|
});
|
|
43037
43160
|
|
|
43161
|
+
// ../../packages/database/src/schema/referrals.ts
|
|
43162
|
+
var referralCodes, referrals;
|
|
43163
|
+
var init_referrals = __esm({
|
|
43164
|
+
"../../packages/database/src/schema/referrals.ts"() {
|
|
43165
|
+
"use strict";
|
|
43166
|
+
init_pg_core();
|
|
43167
|
+
init_users();
|
|
43168
|
+
referralCodes = pgTable("referral_codes", {
|
|
43169
|
+
userId: uuid("user_id").primaryKey().references(() => users.id, { onDelete: "cascade" }),
|
|
43170
|
+
code: varchar("code", { length: 16 }).notNull().unique(),
|
|
43171
|
+
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow()
|
|
43172
|
+
});
|
|
43173
|
+
referrals = pgTable("referrals", {
|
|
43174
|
+
// PK = one referrer per person, one bonus per person, DB-enforced.
|
|
43175
|
+
referredUserId: uuid("referred_user_id").primaryKey().references(() => users.id, { onDelete: "cascade" }),
|
|
43176
|
+
// null = referrer account deleted; referred keeps their referral record.
|
|
43177
|
+
referrerUserId: uuid("referrer_user_id").references(() => users.id, { onDelete: "set null" }),
|
|
43178
|
+
code: varchar("code", { length: 16 }).notNull(),
|
|
43179
|
+
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
|
|
43180
|
+
// Set exactly once by the bonus claim (UPDATE ... WHERE qualified_at IS NULL).
|
|
43181
|
+
qualifiedAt: timestamp("qualified_at", { withTimezone: true })
|
|
43182
|
+
});
|
|
43183
|
+
}
|
|
43184
|
+
});
|
|
43185
|
+
|
|
43186
|
+
// ../../packages/database/src/schema/user-consents.ts
|
|
43187
|
+
var userConsentDocumentEnum, userConsentSurfaceEnum, userConsents;
|
|
43188
|
+
var init_user_consents = __esm({
|
|
43189
|
+
"../../packages/database/src/schema/user-consents.ts"() {
|
|
43190
|
+
"use strict";
|
|
43191
|
+
init_pg_core();
|
|
43192
|
+
init_users();
|
|
43193
|
+
userConsentDocumentEnum = pgEnum("user_consent_document", ["terms", "privacy"]);
|
|
43194
|
+
userConsentSurfaceEnum = pgEnum("user_consent_surface", [
|
|
43195
|
+
"signup_form",
|
|
43196
|
+
// password signup, /signup
|
|
43197
|
+
"oauth",
|
|
43198
|
+
// provider buttons, on /signup AND on /login
|
|
43199
|
+
"magic_link",
|
|
43200
|
+
// magic-link request form
|
|
43201
|
+
"login_form"
|
|
43202
|
+
// /login, login-time capture for pre-chokepoint accounts (GH #1007)
|
|
43203
|
+
]);
|
|
43204
|
+
userConsents = pgTable(
|
|
43205
|
+
"user_consents",
|
|
43206
|
+
{
|
|
43207
|
+
id: uuid("id").primaryKey().defaultRandom(),
|
|
43208
|
+
userId: uuid("user_id").notNull().references(() => users.id, { onDelete: "cascade" }),
|
|
43209
|
+
document: userConsentDocumentEnum("document").notNull(),
|
|
43210
|
+
// Policy version the person was shown, e.g. "v1.0" or "v1.0-BR". Width matches
|
|
43211
|
+
// countries.terms_version so a per-jurisdiction scheme stays possible later.
|
|
43212
|
+
version: varchar("version", { length: 20 }).notNull(),
|
|
43213
|
+
// Which translation was on screen — 5 locales means 5 different texts.
|
|
43214
|
+
locale: varchar("locale", { length: 10 }).notNull(),
|
|
43215
|
+
surface: userConsentSurfaceEnum("surface").notNull(),
|
|
43216
|
+
acknowledgedAt: timestamp("acknowledged_at", { withTimezone: true }).defaultNow().notNull()
|
|
43217
|
+
},
|
|
43218
|
+
(table) => ({
|
|
43219
|
+
// Idempotency, not just a constraint: the OAuth callback runs on EVERY login,
|
|
43220
|
+
// so the writer must be safe to call repeatedly. The left-hand prefix also
|
|
43221
|
+
// serves every "what has this user acknowledged?" read, so no second index.
|
|
43222
|
+
userDocumentVersionUnique: uniqueIndex("user_consents_user_document_version_unique").on(
|
|
43223
|
+
table.userId,
|
|
43224
|
+
table.document,
|
|
43225
|
+
table.version
|
|
43226
|
+
)
|
|
43227
|
+
})
|
|
43228
|
+
);
|
|
43229
|
+
}
|
|
43230
|
+
});
|
|
43231
|
+
|
|
43038
43232
|
// ../../packages/database/src/schema/user-deletions.ts
|
|
43039
43233
|
var userDeletionStatusEnum, userDeletions;
|
|
43040
43234
|
var init_user_deletions = __esm({
|
|
@@ -43206,6 +43400,87 @@ var init_email_delivery = __esm({
|
|
|
43206
43400
|
}
|
|
43207
43401
|
});
|
|
43208
43402
|
|
|
43403
|
+
// ../../packages/database/src/schema/subscription-redemptions.ts
|
|
43404
|
+
var subscriptionCourseRedemptions;
|
|
43405
|
+
var init_subscription_redemptions = __esm({
|
|
43406
|
+
"../../packages/database/src/schema/subscription-redemptions.ts"() {
|
|
43407
|
+
"use strict";
|
|
43408
|
+
init_pg_core();
|
|
43409
|
+
init_users();
|
|
43410
|
+
init_courses3();
|
|
43411
|
+
init_enrollments();
|
|
43412
|
+
init_credit_packages();
|
|
43413
|
+
subscriptionCourseRedemptions = pgTable(
|
|
43414
|
+
"subscription_course_redemptions",
|
|
43415
|
+
{
|
|
43416
|
+
id: uuid("id").defaultRandom().primaryKey(),
|
|
43417
|
+
subscriptionId: uuid("subscription_id").references(() => creditSubscriptions.id, { onDelete: "restrict" }).notNull(),
|
|
43418
|
+
userId: uuid("user_id").references(() => users.id, { onDelete: "cascade" }).notNull(),
|
|
43419
|
+
courseId: uuid("course_id").references(() => courses.id, { onDelete: "restrict" }).notNull(),
|
|
43420
|
+
enrollmentId: uuid("enrollment_id").references(() => enrollments.id, { onDelete: "restrict" }).notNull(),
|
|
43421
|
+
cycleStart: timestamp("cycle_start", { withTimezone: true }).notNull(),
|
|
43422
|
+
createdAt: timestamp("created_at", { withTimezone: true }).defaultNow().notNull()
|
|
43423
|
+
},
|
|
43424
|
+
(table) => ({
|
|
43425
|
+
oncePerCycle: uniqueIndex("scr_subscription_cycle_uq").on(
|
|
43426
|
+
table.subscriptionId,
|
|
43427
|
+
table.cycleStart
|
|
43428
|
+
),
|
|
43429
|
+
userIdx: index("scr_user_idx").on(table.userId)
|
|
43430
|
+
})
|
|
43431
|
+
);
|
|
43432
|
+
}
|
|
43433
|
+
});
|
|
43434
|
+
|
|
43435
|
+
// ../../packages/database/src/schema/operation-billing-rates.ts
|
|
43436
|
+
var operationBillingRates, operationBillingRatesHistory;
|
|
43437
|
+
var init_operation_billing_rates = __esm({
|
|
43438
|
+
"../../packages/database/src/schema/operation-billing-rates.ts"() {
|
|
43439
|
+
"use strict";
|
|
43440
|
+
init_pg_core();
|
|
43441
|
+
init_users();
|
|
43442
|
+
operationBillingRates = pgTable(
|
|
43443
|
+
"operation_billing_rates",
|
|
43444
|
+
{
|
|
43445
|
+
id: uuid("id").primaryKey().defaultRandom(),
|
|
43446
|
+
operationType: varchar("operation_type", { length: 100 }).notNull().unique(),
|
|
43447
|
+
chargedInputPer1M: decimal("charged_input_per_1m", {
|
|
43448
|
+
precision: 10,
|
|
43449
|
+
scale: 4,
|
|
43450
|
+
mode: "number"
|
|
43451
|
+
}).notNull(),
|
|
43452
|
+
chargedOutputPer1M: decimal("charged_output_per_1m", {
|
|
43453
|
+
precision: 10,
|
|
43454
|
+
scale: 4,
|
|
43455
|
+
mode: "number"
|
|
43456
|
+
}).notNull(),
|
|
43457
|
+
isActive: boolean("is_active").notNull().default(true),
|
|
43458
|
+
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
|
|
43459
|
+
updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow()
|
|
43460
|
+
},
|
|
43461
|
+
(table) => [index("idx_operation_billing_rates_active").on(table.isActive)]
|
|
43462
|
+
);
|
|
43463
|
+
operationBillingRatesHistory = pgTable(
|
|
43464
|
+
"operation_billing_rates_history",
|
|
43465
|
+
{
|
|
43466
|
+
id: uuid("id").primaryKey().defaultRandom(),
|
|
43467
|
+
operationType: varchar("operation_type", { length: 100 }).notNull(),
|
|
43468
|
+
action: varchar("action", { length: 20 }).notNull(),
|
|
43469
|
+
// 'create' | 'update' | 'delete'
|
|
43470
|
+
oldValues: jsonb("old_values"),
|
|
43471
|
+
newValues: jsonb("new_values"),
|
|
43472
|
+
changedBy: uuid("changed_by").notNull().references(() => users.id),
|
|
43473
|
+
changedAt: timestamp("changed_at", { withTimezone: true }).notNull().defaultNow(),
|
|
43474
|
+
reason: varchar("reason", { length: 500 })
|
|
43475
|
+
},
|
|
43476
|
+
(table) => [
|
|
43477
|
+
index("idx_obr_history_operation").on(table.operationType),
|
|
43478
|
+
index("idx_obr_history_date").on(table.changedAt)
|
|
43479
|
+
]
|
|
43480
|
+
);
|
|
43481
|
+
}
|
|
43482
|
+
});
|
|
43483
|
+
|
|
43209
43484
|
// ../../packages/database/src/schema/index.ts
|
|
43210
43485
|
var schema_exports = {};
|
|
43211
43486
|
__export(schema_exports, {
|
|
@@ -43221,6 +43496,8 @@ __export(schema_exports, {
|
|
|
43221
43496
|
PACKAGE_MINIMUM_PRICES: () => PACKAGE_MINIMUM_PRICES,
|
|
43222
43497
|
PACKAGE_SESSION_OPTIONS: () => PACKAGE_SESSION_OPTIONS,
|
|
43223
43498
|
PACKAGE_VALIDITY_OPTIONS: () => PACKAGE_VALIDITY_OPTIONS,
|
|
43499
|
+
PIX_CHARGE_PURPOSES: () => PIX_CHARGE_PURPOSES,
|
|
43500
|
+
PIX_CHARGE_STATUSES: () => PIX_CHARGE_STATUSES,
|
|
43224
43501
|
REVIEW_TAGS: () => REVIEW_TAGS,
|
|
43225
43502
|
SUGGESTED_DISCOUNTS: () => SUGGESTED_DISCOUNTS,
|
|
43226
43503
|
V3_CANCEL_REASON_TTL_SECONDS: () => V3_CANCEL_REASON_TTL_SECONDS,
|
|
@@ -43230,8 +43507,6 @@ __export(schema_exports, {
|
|
|
43230
43507
|
actionTypeEnum: () => actionTypeEnum,
|
|
43231
43508
|
adminActivityFeed: () => adminActivityFeed,
|
|
43232
43509
|
adminActivityFeedRelations: () => adminActivityFeedRelations,
|
|
43233
|
-
adminSettingsAudit: () => adminSettingsAudit,
|
|
43234
|
-
adminSettingsAuditRelations: () => adminSettingsAuditRelations,
|
|
43235
43510
|
announcementTypes: () => announcementTypes,
|
|
43236
43511
|
announcements: () => announcements,
|
|
43237
43512
|
applicableToEnum: () => applicableToEnum,
|
|
@@ -43398,7 +43673,6 @@ __export(schema_exports, {
|
|
|
43398
43673
|
insertCourseMentoriaOfferSchema: () => insertCourseMentoriaOfferSchema,
|
|
43399
43674
|
insertMentorshipCreditSchema: () => insertMentorshipCreditSchema,
|
|
43400
43675
|
insertMentorshipPackageSchema: () => insertMentorshipPackageSchema,
|
|
43401
|
-
insertPlatformSettingSchema: () => insertPlatformSettingSchema,
|
|
43402
43676
|
isAmountSignValid: () => isAmountSignValid,
|
|
43403
43677
|
isCreditUsable: () => isCreditUsable,
|
|
43404
43678
|
isWithdrawableLedgerType: () => isWithdrawableLedgerType,
|
|
@@ -43486,9 +43760,10 @@ __export(schema_exports, {
|
|
|
43486
43760
|
notificationsRelations: () => notificationsRelations2,
|
|
43487
43761
|
onboardingAnalytics: () => onboardingAnalytics2,
|
|
43488
43762
|
onboardingAnalyticsRelations: () => onboardingAnalyticsRelations2,
|
|
43763
|
+
operationBillingRates: () => operationBillingRates,
|
|
43764
|
+
operationBillingRatesHistory: () => operationBillingRatesHistory,
|
|
43489
43765
|
optimizerRoleEnum: () => optimizerRoleEnum,
|
|
43490
43766
|
parisAuthorizedCreators: () => parisAuthorizedCreators,
|
|
43491
|
-
parseSettingValue: () => parseSettingValue,
|
|
43492
43767
|
participantStatusEnum: () => participantStatusEnum,
|
|
43493
43768
|
pathCourses: () => pathCourses2,
|
|
43494
43769
|
pathCoursesRelations: () => pathCoursesRelations2,
|
|
@@ -43502,9 +43777,8 @@ __export(schema_exports, {
|
|
|
43502
43777
|
payoutWithdrawalTransitions: () => payoutWithdrawalTransitions,
|
|
43503
43778
|
payoutWithdrawals: () => payoutWithdrawals,
|
|
43504
43779
|
pgBackendIdempotencyKeys: () => pgBackendIdempotencyKeys,
|
|
43780
|
+
pixCharges: () => pixCharges,
|
|
43505
43781
|
pixKeyTypeEnum: () => pixKeyTypeEnum,
|
|
43506
|
-
platformConfig: () => platformConfig,
|
|
43507
|
-
platformSettings: () => platformSettings2,
|
|
43508
43782
|
playgroundEvalScores: () => playgroundEvalScores,
|
|
43509
43783
|
playgroundEvalScoresRelations: () => playgroundEvalScoresRelations,
|
|
43510
43784
|
playgroundEvaluations: () => playgroundEvaluations,
|
|
@@ -43548,6 +43822,8 @@ __export(schema_exports, {
|
|
|
43548
43822
|
pushTokens: () => pushTokens,
|
|
43549
43823
|
pushTokensRelations: () => pushTokensRelations,
|
|
43550
43824
|
quotaChangeHistory: () => quotaChangeHistory,
|
|
43825
|
+
referralCodes: () => referralCodes,
|
|
43826
|
+
referrals: () => referrals,
|
|
43551
43827
|
refinementStatusEnum: () => refinementStatusEnum,
|
|
43552
43828
|
refundAuditLog: () => refundAuditLog2,
|
|
43553
43829
|
refundAuditLogRelations: () => refundAuditLogRelations2,
|
|
@@ -43570,7 +43846,6 @@ __export(schema_exports, {
|
|
|
43570
43846
|
securityEventCategoryEnum: () => securityEventCategoryEnum,
|
|
43571
43847
|
securityEventResultEnum: () => securityEventResultEnum,
|
|
43572
43848
|
securityEventTypeEnum: () => securityEventTypeEnum,
|
|
43573
|
-
selectPlatformSettingSchema: () => selectPlatformSettingSchema,
|
|
43574
43849
|
serviceTypeEnum: () => serviceTypeEnum,
|
|
43575
43850
|
sessionCancelledReasonEnum: () => sessionCancelledReasonEnum,
|
|
43576
43851
|
sessionParticipants: () => sessionParticipants2,
|
|
@@ -43586,9 +43861,6 @@ __export(schema_exports, {
|
|
|
43586
43861
|
sessionWaitlistRelations: () => sessionWaitlistRelations2,
|
|
43587
43862
|
sessions: () => sessions,
|
|
43588
43863
|
sessionsRelations: () => sessionsRelations2,
|
|
43589
|
-
settingCategories: () => settingCategories,
|
|
43590
|
-
settingKeys: () => settingKeys,
|
|
43591
|
-
settingValueTypes: () => settingValueTypes,
|
|
43592
43864
|
skillLevelEnum: () => skillLevelEnum,
|
|
43593
43865
|
slaStatusEnum: () => slaStatusEnum,
|
|
43594
43866
|
slashCommandAnalytics: () => slashCommandAnalytics2,
|
|
@@ -43598,7 +43870,6 @@ __export(schema_exports, {
|
|
|
43598
43870
|
sparkChatSessions: () => sparkChatSessions2,
|
|
43599
43871
|
sparkChatSessionsRelations: () => sparkChatSessionsRelations2,
|
|
43600
43872
|
sparkPhaseValues: () => sparkPhaseValues,
|
|
43601
|
-
stringifySettingValue: () => stringifySettingValue,
|
|
43602
43873
|
studentCourseMemory: () => studentCourseMemory,
|
|
43603
43874
|
studentCourseMemoryRelations: () => studentCourseMemoryRelations,
|
|
43604
43875
|
studentFeedback: () => studentFeedback,
|
|
@@ -43628,6 +43899,7 @@ __export(schema_exports, {
|
|
|
43628
43899
|
studyModuleSessionsRelations: () => studyModuleSessionsRelations,
|
|
43629
43900
|
studyPhaseV2Values: () => studyPhaseV2Values,
|
|
43630
43901
|
studyPhaseValues: () => studyPhaseValues,
|
|
43902
|
+
subscriptionCourseRedemptions: () => subscriptionCourseRedemptions,
|
|
43631
43903
|
subscriptionPoolStatusEnum: () => subscriptionPoolStatusEnum,
|
|
43632
43904
|
subscriptionSplitStatusEnum: () => subscriptionSplitStatusEnum,
|
|
43633
43905
|
supportedCurrencies: () => supportedCurrencies,
|
|
@@ -43655,6 +43927,9 @@ __export(schema_exports, {
|
|
|
43655
43927
|
userBadgesRelations: () => userBadgesRelations2,
|
|
43656
43928
|
userChallengeScores: () => userChallengeScores,
|
|
43657
43929
|
userChallengeScoresRelations: () => userChallengeScoresRelations,
|
|
43930
|
+
userConsentDocumentEnum: () => userConsentDocumentEnum,
|
|
43931
|
+
userConsentSurfaceEnum: () => userConsentSurfaceEnum,
|
|
43932
|
+
userConsents: () => userConsents,
|
|
43658
43933
|
userDeletionStatusEnum: () => userDeletionStatusEnum,
|
|
43659
43934
|
userDeletions: () => userDeletions,
|
|
43660
43935
|
userFollows: () => userFollows2,
|
|
@@ -43714,6 +43989,7 @@ var init_schema3 = __esm({
|
|
|
43714
43989
|
init_creator_index();
|
|
43715
43990
|
init_webhook_events();
|
|
43716
43991
|
init_transactions();
|
|
43992
|
+
init_pix_charges();
|
|
43717
43993
|
init_coupons();
|
|
43718
43994
|
init_coupon_usages();
|
|
43719
43995
|
init_onboarding_analytics();
|
|
@@ -43726,8 +44002,6 @@ var init_schema3 = __esm({
|
|
|
43726
44002
|
init_user_follows();
|
|
43727
44003
|
init_spark_chat_sessions();
|
|
43728
44004
|
init_study_index();
|
|
43729
|
-
init_platform_settings();
|
|
43730
|
-
init_admin_settings_audit();
|
|
43731
44005
|
init_admin_activity_feed();
|
|
43732
44006
|
init_generation_state();
|
|
43733
44007
|
init_security_audit_log();
|
|
@@ -43775,7 +44049,6 @@ var init_schema3 = __esm({
|
|
|
43775
44049
|
init_relations_community();
|
|
43776
44050
|
init_relations_gamification();
|
|
43777
44051
|
init_moderation_log();
|
|
43778
|
-
init_admin_settings_audit();
|
|
43779
44052
|
init_creator_audit_log();
|
|
43780
44053
|
init_banks();
|
|
43781
44054
|
init_course_qa_reports();
|
|
@@ -43797,10 +44070,14 @@ var init_schema3 = __esm({
|
|
|
43797
44070
|
init_course_visibility();
|
|
43798
44071
|
init_course_allowlist();
|
|
43799
44072
|
init_idempotency();
|
|
44073
|
+
init_referrals();
|
|
44074
|
+
init_user_consents();
|
|
43800
44075
|
init_user_deletions();
|
|
43801
44076
|
init_user_profiles();
|
|
43802
44077
|
init_user_resource_audits();
|
|
43803
44078
|
init_email_delivery();
|
|
44079
|
+
init_subscription_redemptions();
|
|
44080
|
+
init_operation_billing_rates();
|
|
43804
44081
|
}
|
|
43805
44082
|
});
|
|
43806
44083
|
|
|
@@ -43862,7 +44139,6 @@ var init_src3 = __esm({
|
|
|
43862
44139
|
init_user_follows();
|
|
43863
44140
|
init_generation_state();
|
|
43864
44141
|
init_community();
|
|
43865
|
-
init_platform_settings();
|
|
43866
44142
|
init_marketing();
|
|
43867
44143
|
init_security_audit_log();
|
|
43868
44144
|
init_credit_movement_audit_log();
|
|
@@ -44201,7 +44477,7 @@ async function runStart(opts, deps = defaultDeps3) {
|
|
|
44201
44477
|
deps.error(msg);
|
|
44202
44478
|
}
|
|
44203
44479
|
}
|
|
44204
|
-
var
|
|
44480
|
+
var logger10, defaultDeps3, startCommand;
|
|
44205
44481
|
var init_start = __esm({
|
|
44206
44482
|
"src/commands/start.ts"() {
|
|
44207
44483
|
"use strict";
|
|
@@ -44214,7 +44490,7 @@ var init_start = __esm({
|
|
|
44214
44490
|
init_status();
|
|
44215
44491
|
init_formatter();
|
|
44216
44492
|
init_errors();
|
|
44217
|
-
|
|
44493
|
+
logger10 = createLogger("cli:start");
|
|
44218
44494
|
defaultDeps3 = {
|
|
44219
44495
|
requireSession,
|
|
44220
44496
|
requireActiveCourse,
|
|
@@ -44228,7 +44504,7 @@ var init_start = __esm({
|
|
|
44228
44504
|
output,
|
|
44229
44505
|
error,
|
|
44230
44506
|
stderrWrite: (message) => process.stderr.write(message),
|
|
44231
|
-
logger:
|
|
44507
|
+
logger: logger10
|
|
44232
44508
|
};
|
|
44233
44509
|
startCommand = new Command8("start").description("Start (or resume) the current module of the active course").option("--json", "Output structured JSON").action(async (opts) => {
|
|
44234
44510
|
await runStart(opts);
|
|
@@ -44238,7 +44514,7 @@ var init_start = __esm({
|
|
|
44238
44514
|
|
|
44239
44515
|
// src/commands/start-next.ts
|
|
44240
44516
|
import { Command as Command9 } from "commander";
|
|
44241
|
-
var
|
|
44517
|
+
var logger11, startNextCommand;
|
|
44242
44518
|
var init_start_next = __esm({
|
|
44243
44519
|
"src/commands/start-next.ts"() {
|
|
44244
44520
|
"use strict";
|
|
@@ -44250,7 +44526,7 @@ var init_start_next = __esm({
|
|
|
44250
44526
|
init_workspace_state();
|
|
44251
44527
|
init_formatter();
|
|
44252
44528
|
init_errors();
|
|
44253
|
-
|
|
44529
|
+
logger11 = createLogger("cli:start-next");
|
|
44254
44530
|
startNextCommand = new Command9("start-next").description("Transition to the next module after completing the current one").option("--json", "Output structured JSON").action(async (opts) => {
|
|
44255
44531
|
try {
|
|
44256
44532
|
const session = await requireSession();
|
|
@@ -44258,7 +44534,7 @@ var init_start_next = __esm({
|
|
|
44258
44534
|
const driftWarning = await checkCourseDrift();
|
|
44259
44535
|
if (driftWarning) process.stderr.write(driftWarning + "\n");
|
|
44260
44536
|
const data = createHttpProvider(session.apiUrl, session.token);
|
|
44261
|
-
const deps = { data, logger:
|
|
44537
|
+
const deps = { data, logger: logger11 };
|
|
44262
44538
|
const moduleData = await startNextModule({ enrollmentId: activeCourse.enrollmentId }, deps);
|
|
44263
44539
|
const ws = await findWorkspaceState();
|
|
44264
44540
|
if (ws)
|
|
@@ -44295,7 +44571,7 @@ var init_start_next = __esm({
|
|
|
44295
44571
|
|
|
44296
44572
|
// src/commands/next.ts
|
|
44297
44573
|
import { Command as Command10 } from "commander";
|
|
44298
|
-
var
|
|
44574
|
+
var logger12, nextCommand;
|
|
44299
44575
|
var init_next = __esm({
|
|
44300
44576
|
"src/commands/next.ts"() {
|
|
44301
44577
|
"use strict";
|
|
@@ -44307,7 +44583,7 @@ var init_next = __esm({
|
|
|
44307
44583
|
init_workspace_state();
|
|
44308
44584
|
init_formatter();
|
|
44309
44585
|
init_errors();
|
|
44310
|
-
|
|
44586
|
+
logger12 = createLogger("cli:next");
|
|
44311
44587
|
nextCommand = new Command10("next").description("Advance to the next lesson in the active course").option("--json", "Output structured JSON").action(async (opts) => {
|
|
44312
44588
|
try {
|
|
44313
44589
|
const session = await requireSession();
|
|
@@ -44315,7 +44591,7 @@ var init_next = __esm({
|
|
|
44315
44591
|
const driftWarning = await checkCourseDrift();
|
|
44316
44592
|
if (driftWarning) process.stderr.write(driftWarning + "\n");
|
|
44317
44593
|
const data = createHttpProvider(session.apiUrl, session.token);
|
|
44318
|
-
const deps = { data, logger:
|
|
44594
|
+
const deps = { data, logger: logger12 };
|
|
44319
44595
|
const lessonData = await nextLesson(
|
|
44320
44596
|
{ enrollmentId: activeCourse.enrollmentId, userConfirmation: "cli-next" },
|
|
44321
44597
|
deps
|
|
@@ -44388,7 +44664,7 @@ function replacePlaceholders(text2, workspacePath, courseTitle) {
|
|
|
44388
44664
|
const base = path13.basename(workspacePath) === ".tostudy" ? path13.dirname(workspacePath) : workspacePath;
|
|
44389
44665
|
const slug = courseSlug(courseTitle);
|
|
44390
44666
|
const vaultPath = resolveVaultPath(workspacePath, slug);
|
|
44391
|
-
return text2.
|
|
44667
|
+
return text2.replace(/\$WORKSPACE(?![A-Za-z0-9_])/g, () => base).replace(/\$VAULT(?![A-Za-z0-9_])/g, () => vaultPath);
|
|
44392
44668
|
}
|
|
44393
44669
|
function formatLessonContent(data, workspacePath, courseTitle) {
|
|
44394
44670
|
const time4 = adjustTimeEstimate(data.type, data.estimatedTimeMinutes);
|
|
@@ -44429,7 +44705,7 @@ function formatLessonContent(data, workspacePath, courseTitle) {
|
|
|
44429
44705
|
}
|
|
44430
44706
|
return lines.join("\n");
|
|
44431
44707
|
}
|
|
44432
|
-
var
|
|
44708
|
+
var logger13, lessonCommand;
|
|
44433
44709
|
var init_lesson = __esm({
|
|
44434
44710
|
"src/commands/lesson.ts"() {
|
|
44435
44711
|
"use strict";
|
|
@@ -44442,7 +44718,7 @@ var init_lesson = __esm({
|
|
|
44442
44718
|
init_formatter();
|
|
44443
44719
|
init_resolve();
|
|
44444
44720
|
init_errors();
|
|
44445
|
-
|
|
44721
|
+
logger13 = createLogger("cli:lesson");
|
|
44446
44722
|
lessonCommand = new Command11("lesson").description("Show the content of the current lesson").option("--json", "Output structured JSON").option(
|
|
44447
44723
|
"--read <lessonId>",
|
|
44448
44724
|
"Read a specific lesson by id (works on archived / read-only courses)"
|
|
@@ -44453,7 +44729,7 @@ var init_lesson = __esm({
|
|
|
44453
44729
|
const driftWarning = await checkCourseDrift();
|
|
44454
44730
|
if (driftWarning) process.stderr.write(driftWarning + "\n");
|
|
44455
44731
|
const data = createHttpProvider(session.apiUrl, session.token);
|
|
44456
|
-
const deps = { data, logger:
|
|
44732
|
+
const deps = { data, logger: logger13 };
|
|
44457
44733
|
let lessonId = opts.read ?? activeCourse.currentLessonId;
|
|
44458
44734
|
if (!lessonId) {
|
|
44459
44735
|
try {
|
|
@@ -44548,7 +44824,7 @@ function formatKnowledge(data) {
|
|
|
44548
44824
|
});
|
|
44549
44825
|
return lines.join("\n").trimEnd();
|
|
44550
44826
|
}
|
|
44551
|
-
var
|
|
44827
|
+
var logger14, knowledgeCommand;
|
|
44552
44828
|
var init_knowledge2 = __esm({
|
|
44553
44829
|
"src/commands/knowledge.ts"() {
|
|
44554
44830
|
"use strict";
|
|
@@ -44556,7 +44832,7 @@ var init_knowledge2 = __esm({
|
|
|
44556
44832
|
init_http();
|
|
44557
44833
|
init_guards();
|
|
44558
44834
|
init_formatter();
|
|
44559
|
-
|
|
44835
|
+
logger14 = createLogger("cli:knowledge");
|
|
44560
44836
|
knowledgeCommand = new Command12("knowledge").description("Show the active course's knowledge base (base de conhecimento)").option("--json", "Output structured JSON").action(async (opts) => {
|
|
44561
44837
|
try {
|
|
44562
44838
|
const activeCourse = await requireActiveCourse();
|
|
@@ -44580,7 +44856,7 @@ var init_knowledge2 = __esm({
|
|
|
44580
44856
|
else error(msg);
|
|
44581
44857
|
return;
|
|
44582
44858
|
}
|
|
44583
|
-
|
|
44859
|
+
logger14.warn("knowledge failed", { error: msg });
|
|
44584
44860
|
if (opts.json) jsonError(msg);
|
|
44585
44861
|
else error(msg);
|
|
44586
44862
|
}
|
|
@@ -44590,7 +44866,7 @@ var init_knowledge2 = __esm({
|
|
|
44590
44866
|
|
|
44591
44867
|
// src/commands/hint.ts
|
|
44592
44868
|
import { Command as Command13 } from "commander";
|
|
44593
|
-
var
|
|
44869
|
+
var logger15, hintCommand;
|
|
44594
44870
|
var init_hint = __esm({
|
|
44595
44871
|
"src/commands/hint.ts"() {
|
|
44596
44872
|
"use strict";
|
|
@@ -44601,7 +44877,7 @@ var init_hint = __esm({
|
|
|
44601
44877
|
init_course_state();
|
|
44602
44878
|
init_formatter();
|
|
44603
44879
|
init_errors();
|
|
44604
|
-
|
|
44880
|
+
logger15 = createLogger("cli:hint");
|
|
44605
44881
|
hintCommand = new Command13("hint").description("Get a progressive hint for the current exercise").option("--json", "Output structured JSON").action(async (opts) => {
|
|
44606
44882
|
try {
|
|
44607
44883
|
const session = await requireSession();
|
|
@@ -44609,7 +44885,7 @@ var init_hint = __esm({
|
|
|
44609
44885
|
const driftWarning = await checkCourseDrift();
|
|
44610
44886
|
if (driftWarning) process.stderr.write(driftWarning + "\n");
|
|
44611
44887
|
const data = createHttpProvider(session.apiUrl, session.token);
|
|
44612
|
-
const deps = { data, logger:
|
|
44888
|
+
const deps = { data, logger: logger15 };
|
|
44613
44889
|
const hint = await getHint(
|
|
44614
44890
|
{ userId: session.userId, enrollmentId: activeCourse.enrollmentId },
|
|
44615
44891
|
deps
|
|
@@ -44963,7 +45239,7 @@ var init_init_template = __esm({
|
|
|
44963
45239
|
import fs12 from "node:fs";
|
|
44964
45240
|
import path14 from "node:path";
|
|
44965
45241
|
import { Command as Command14 } from "commander";
|
|
44966
|
-
var
|
|
45242
|
+
var logger16, validateCommand;
|
|
44967
45243
|
var init_validate = __esm({
|
|
44968
45244
|
"src/commands/validate.ts"() {
|
|
44969
45245
|
"use strict";
|
|
@@ -44976,7 +45252,7 @@ var init_validate = __esm({
|
|
|
44976
45252
|
init_formatter();
|
|
44977
45253
|
init_init_template();
|
|
44978
45254
|
init_errors();
|
|
44979
|
-
|
|
45255
|
+
logger16 = createLogger("cli:validate");
|
|
44980
45256
|
validateCommand = new Command14("validate").description("Validate your solution for the current exercise").argument("[file]", "Path to the solution file to read").option("--stdin", "Read solution from stdin instead of a file").option("--json", "Output structured JSON").action(async (file2, opts) => {
|
|
44981
45257
|
try {
|
|
44982
45258
|
const session = await requireSession();
|
|
@@ -44984,7 +45260,7 @@ var init_validate = __esm({
|
|
|
44984
45260
|
const driftWarning = await checkCourseDrift();
|
|
44985
45261
|
if (driftWarning) process.stderr.write(driftWarning + "\n");
|
|
44986
45262
|
const data = createHttpProvider(session.apiUrl, session.token);
|
|
44987
|
-
const deps = { data, logger:
|
|
45263
|
+
const deps = { data, logger: logger16 };
|
|
44988
45264
|
let lessonId = activeCourse.currentLessonId;
|
|
44989
45265
|
if (!lessonId) {
|
|
44990
45266
|
try {
|
|
@@ -45433,7 +45709,7 @@ Rode \`tostudy select <n\xFAmero>\` para ativar um curso.`,
|
|
|
45433
45709
|
deps.output(artifacts.learnerBrief, { json: false });
|
|
45434
45710
|
}
|
|
45435
45711
|
}
|
|
45436
|
-
var
|
|
45712
|
+
var logger17, defaultDeps4, initCommand;
|
|
45437
45713
|
var init_init = __esm({
|
|
45438
45714
|
"src/commands/init.ts"() {
|
|
45439
45715
|
"use strict";
|
|
@@ -45449,7 +45725,7 @@ var init_init = __esm({
|
|
|
45449
45725
|
init_api3();
|
|
45450
45726
|
init_instruction_pipeline();
|
|
45451
45727
|
init_pipeline_deps();
|
|
45452
|
-
|
|
45728
|
+
logger17 = createLogger("cli:init");
|
|
45453
45729
|
defaultDeps4 = {
|
|
45454
45730
|
getSession,
|
|
45455
45731
|
findWorkspaceState,
|
|
@@ -45463,7 +45739,7 @@ var init_init = __esm({
|
|
|
45463
45739
|
saveCourseLearnerProfile,
|
|
45464
45740
|
buildInitArtifacts,
|
|
45465
45741
|
output,
|
|
45466
|
-
logger:
|
|
45742
|
+
logger: logger17,
|
|
45467
45743
|
createHttpProvider,
|
|
45468
45744
|
resolveAndGenerate,
|
|
45469
45745
|
buildPipelineDeps
|
|
@@ -45785,7 +46061,7 @@ import { Command as Command17 } from "commander";
|
|
|
45785
46061
|
import path17 from "node:path";
|
|
45786
46062
|
import os9 from "node:os";
|
|
45787
46063
|
import fs15 from "node:fs/promises";
|
|
45788
|
-
var
|
|
46064
|
+
var logger18, workspaceCommand;
|
|
45789
46065
|
var init_workspace2 = __esm({
|
|
45790
46066
|
"src/commands/workspace.ts"() {
|
|
45791
46067
|
"use strict";
|
|
@@ -45795,7 +46071,7 @@ var init_workspace2 = __esm({
|
|
|
45795
46071
|
init_course_state();
|
|
45796
46072
|
init_resolve();
|
|
45797
46073
|
init_errors();
|
|
45798
|
-
|
|
46074
|
+
logger18 = createLogger("cli:workspace");
|
|
45799
46075
|
workspaceCommand = new Command17("workspace").description(
|
|
45800
46076
|
getErrors().workspaceCommandDescription
|
|
45801
46077
|
);
|
|
@@ -45861,7 +46137,7 @@ Pr\xF3ximo passo: tostudy export
|
|
|
45861
46137
|
);
|
|
45862
46138
|
}
|
|
45863
46139
|
} catch (err) {
|
|
45864
|
-
|
|
46140
|
+
logger18.error("workspace setup failed", { error: err });
|
|
45865
46141
|
process.stderr.write(`\u274C ${err instanceof Error ? err.message : String(err)}
|
|
45866
46142
|
`);
|
|
45867
46143
|
process.exit(1);
|
|
@@ -45969,7 +46245,7 @@ import { Command as Command18 } from "commander";
|
|
|
45969
46245
|
import path18 from "node:path";
|
|
45970
46246
|
import os10 from "node:os";
|
|
45971
46247
|
import fs16 from "node:fs/promises";
|
|
45972
|
-
var
|
|
46248
|
+
var logger19, exportCommand;
|
|
45973
46249
|
var init_export = __esm({
|
|
45974
46250
|
"src/commands/export.ts"() {
|
|
45975
46251
|
"use strict";
|
|
@@ -45980,7 +46256,7 @@ var init_export = __esm({
|
|
|
45980
46256
|
init_course_state();
|
|
45981
46257
|
init_resolve();
|
|
45982
46258
|
init_errors();
|
|
45983
|
-
|
|
46259
|
+
logger19 = createLogger("cli:export");
|
|
45984
46260
|
exportCommand = new Command18("export").description("Extrair exerc\xEDcio atual para o workspace local").option("--tier <tier>", "Tier do exerc\xEDcio: guided, semiGuided, challenging", "guided").option("--path <dir>", "Diret\xF3rio base do workspace", path18.join(os10.homedir(), "study")).option("--json", "Output structured JSON").action(async (opts) => {
|
|
45985
46261
|
try {
|
|
45986
46262
|
const session = await requireSession();
|
|
@@ -46008,7 +46284,7 @@ var init_export = __esm({
|
|
|
46008
46284
|
}
|
|
46009
46285
|
if (!hasConfig) {
|
|
46010
46286
|
const slug = courseSlug(activeCourse.courseTitle);
|
|
46011
|
-
|
|
46287
|
+
logger19.info("Auto-initializing workspace", { workspacePath: ws.workspacePath });
|
|
46012
46288
|
await fs16.mkdir(ws.workspacePath, { recursive: true });
|
|
46013
46289
|
for (const dir of ["exercises", "generated", "notes", "diagrams"]) {
|
|
46014
46290
|
await fs16.mkdir(path18.join(ws.workspacePath, dir), { recursive: true });
|
|
@@ -46070,7 +46346,7 @@ ${result.files.map((f) => ` \u{1F4C4} ${f}`).join("\n")}
|
|
|
46070
46346
|
);
|
|
46071
46347
|
}
|
|
46072
46348
|
} catch (err) {
|
|
46073
|
-
|
|
46349
|
+
logger19.error("export failed", { error: err });
|
|
46074
46350
|
process.stderr.write(`\u274C ${err instanceof Error ? err.message : String(err)}
|
|
46075
46351
|
`);
|
|
46076
46352
|
process.exit(1);
|
|
@@ -46084,7 +46360,7 @@ import { Command as Command19 } from "commander";
|
|
|
46084
46360
|
import { execFile as execFile3 } from "node:child_process";
|
|
46085
46361
|
import path19 from "node:path";
|
|
46086
46362
|
import os11 from "node:os";
|
|
46087
|
-
var
|
|
46363
|
+
var logger20, openCommand;
|
|
46088
46364
|
var init_open = __esm({
|
|
46089
46365
|
"src/commands/open.ts"() {
|
|
46090
46366
|
"use strict";
|
|
@@ -46093,7 +46369,7 @@ var init_open = __esm({
|
|
|
46093
46369
|
init_course_state();
|
|
46094
46370
|
init_resolve();
|
|
46095
46371
|
init_errors();
|
|
46096
|
-
|
|
46372
|
+
logger20 = createLogger("cli:open");
|
|
46097
46373
|
openCommand = new Command19("open").description("Abrir workspace do curso na IDE").option("--path <dir>", "Diret\xF3rio base do workspace", path19.join(os11.homedir(), "study")).action(async (opts) => {
|
|
46098
46374
|
try {
|
|
46099
46375
|
const activeCourse = await requireActiveCourse();
|
|
@@ -46111,7 +46387,7 @@ var init_open = __esm({
|
|
|
46111
46387
|
const editor = process.env["EDITOR"] ?? "code";
|
|
46112
46388
|
execFile3(editor, [ws.workspacePath], (err) => {
|
|
46113
46389
|
if (err) {
|
|
46114
|
-
|
|
46390
|
+
logger20.error("open failed", { editor, workspacePath: ws.workspacePath });
|
|
46115
46391
|
process.stderr.write(`\u274C Falha ao abrir: ${err.message}
|
|
46116
46392
|
`);
|
|
46117
46393
|
process.exit(1);
|
|
@@ -46120,7 +46396,7 @@ var init_open = __esm({
|
|
|
46120
46396
|
`);
|
|
46121
46397
|
});
|
|
46122
46398
|
} catch (err) {
|
|
46123
|
-
|
|
46399
|
+
logger20.error("open command failed", { error: err });
|
|
46124
46400
|
process.stderr.write(`\u274C ${err instanceof Error ? err.message : String(err)}
|
|
46125
46401
|
`);
|
|
46126
46402
|
process.exit(1);
|
|
@@ -46192,7 +46468,7 @@ import { Command as Command20 } from "commander";
|
|
|
46192
46468
|
import path21 from "node:path";
|
|
46193
46469
|
import os12 from "node:os";
|
|
46194
46470
|
import fs18 from "node:fs/promises";
|
|
46195
|
-
var
|
|
46471
|
+
var logger21, vaultCommand;
|
|
46196
46472
|
var init_vault2 = __esm({
|
|
46197
46473
|
"src/commands/vault.ts"() {
|
|
46198
46474
|
"use strict";
|
|
@@ -46204,7 +46480,7 @@ var init_vault2 = __esm({
|
|
|
46204
46480
|
init_course_state();
|
|
46205
46481
|
init_resolve();
|
|
46206
46482
|
init_errors();
|
|
46207
|
-
|
|
46483
|
+
logger21 = createLogger("cli:vault");
|
|
46208
46484
|
vaultCommand = new Command20("vault").description("Gerenciar vault Obsidian do curso");
|
|
46209
46485
|
vaultCommand.command("init").description("Gerar vault Obsidian para o curso ativo").option("--path <dir>", "Diret\xF3rio base do workspace", path21.join(os12.homedir(), "study")).option("--json", "Output structured JSON").action(async (opts) => {
|
|
46210
46486
|
try {
|
|
@@ -46249,7 +46525,7 @@ var init_vault2 = __esm({
|
|
|
46249
46525
|
activeCourse.courseId,
|
|
46250
46526
|
slug
|
|
46251
46527
|
);
|
|
46252
|
-
|
|
46528
|
+
logger21.info("Vault generated", {
|
|
46253
46529
|
courseId: activeCourse.courseId,
|
|
46254
46530
|
vaultPath: result.vaultPath,
|
|
46255
46531
|
filesWritten: result.filesWritten
|
|
@@ -46282,7 +46558,7 @@ Para visualizar:
|
|
|
46282
46558
|
);
|
|
46283
46559
|
}
|
|
46284
46560
|
} catch (err) {
|
|
46285
|
-
|
|
46561
|
+
logger21.error("vault init failed", { error: err });
|
|
46286
46562
|
process.stderr.write(`\u274C ${err instanceof Error ? err.message : String(err)}
|
|
46287
46563
|
`);
|
|
46288
46564
|
process.exit(1);
|
|
@@ -46312,7 +46588,7 @@ Para visualizar:
|
|
|
46312
46588
|
process.exit(1);
|
|
46313
46589
|
}
|
|
46314
46590
|
const data = createHttpProvider(session.apiUrl, session.token);
|
|
46315
|
-
const deps = { data, logger:
|
|
46591
|
+
const deps = { data, logger: logger21 };
|
|
46316
46592
|
const progress3 = await getProgress({ enrollmentId: activeCourse.enrollmentId }, deps);
|
|
46317
46593
|
const markerPath = path21.join(vaultPath, ".ana-vault.json");
|
|
46318
46594
|
const markerRaw = await fs18.readFile(markerPath, "utf-8");
|
|
@@ -46366,7 +46642,7 @@ Para visualizar:
|
|
|
46366
46642
|
);
|
|
46367
46643
|
}
|
|
46368
46644
|
} catch (err) {
|
|
46369
|
-
|
|
46645
|
+
logger21.error("vault sync failed", { error: err });
|
|
46370
46646
|
process.stderr.write(`\u274C ${err instanceof Error ? err.message : String(err)}
|
|
46371
46647
|
`);
|
|
46372
46648
|
process.exit(1);
|
|
@@ -46446,7 +46722,7 @@ var init_profile = __esm({
|
|
|
46446
46722
|
|
|
46447
46723
|
// src/commands/sync.ts
|
|
46448
46724
|
import { Command as Command22 } from "commander";
|
|
46449
|
-
var
|
|
46725
|
+
var logger22, syncCommand;
|
|
46450
46726
|
var init_sync = __esm({
|
|
46451
46727
|
"src/commands/sync.ts"() {
|
|
46452
46728
|
"use strict";
|
|
@@ -46455,15 +46731,18 @@ var init_sync = __esm({
|
|
|
46455
46731
|
init_formatter();
|
|
46456
46732
|
init_instruction_pipeline();
|
|
46457
46733
|
init_pipeline_deps();
|
|
46458
|
-
|
|
46459
|
-
syncCommand = new Command22("sync").description("Regenerate instruction files with updated progress").option("--json", "Output structured JSON").
|
|
46734
|
+
logger22 = createLogger("cli:sync");
|
|
46735
|
+
syncCommand = new Command22("sync").description("Regenerate instruction files with updated progress").option("--json", "Output structured JSON").option(
|
|
46736
|
+
"--all-runtimes",
|
|
46737
|
+
"Write instruction files for every supported runtime, even undetected ones"
|
|
46738
|
+
).action(async (opts) => {
|
|
46460
46739
|
try {
|
|
46461
46740
|
await requireSession();
|
|
46462
46741
|
const activeCourse = await requireActiveCourse();
|
|
46463
46742
|
const pipelineResult = await resolveAndGenerate(
|
|
46464
46743
|
{ courseId: activeCourse.courseId, enrollmentId: activeCourse.enrollmentId },
|
|
46465
46744
|
{ forceRefresh: true, collectT1Interactive: false, collectT2Interactive: false },
|
|
46466
|
-
{ cwd: process.cwd(), deps: buildPipelineDeps() }
|
|
46745
|
+
{ cwd: process.cwd(), deps: buildPipelineDeps({ allRuntimes: opts.allRuntimes }) }
|
|
46467
46746
|
);
|
|
46468
46747
|
if (opts.json) {
|
|
46469
46748
|
output(
|
|
@@ -46494,7 +46773,7 @@ var init_sync = __esm({
|
|
|
46494
46773
|
} catch (err) {
|
|
46495
46774
|
const msg = err instanceof Error ? err.message : String(err);
|
|
46496
46775
|
if (msg.includes("process.exit")) return;
|
|
46497
|
-
|
|
46776
|
+
logger22.warn("sync failed", { error: msg });
|
|
46498
46777
|
error(msg);
|
|
46499
46778
|
}
|
|
46500
46779
|
});
|
|
@@ -46503,7 +46782,7 @@ var init_sync = __esm({
|
|
|
46503
46782
|
|
|
46504
46783
|
// src/commands/brief.ts
|
|
46505
46784
|
import { Command as Command23 } from "commander";
|
|
46506
|
-
var
|
|
46785
|
+
var logger23, briefCommand;
|
|
46507
46786
|
var init_brief = __esm({
|
|
46508
46787
|
"src/commands/brief.ts"() {
|
|
46509
46788
|
"use strict";
|
|
@@ -46512,7 +46791,7 @@ var init_brief = __esm({
|
|
|
46512
46791
|
init_cache();
|
|
46513
46792
|
init_api();
|
|
46514
46793
|
init_formatter();
|
|
46515
|
-
|
|
46794
|
+
logger23 = createLogger("cli:brief");
|
|
46516
46795
|
briefCommand = new Command23("brief").description("Show your base learner brief (T1) status and content").option("--json", "Output structured JSON").action(async (opts) => {
|
|
46517
46796
|
try {
|
|
46518
46797
|
const session = await requireSession();
|
|
@@ -46546,7 +46825,7 @@ var init_brief = __esm({
|
|
|
46546
46825
|
}
|
|
46547
46826
|
output(lines.join("\n"), { json: false });
|
|
46548
46827
|
} catch (err) {
|
|
46549
|
-
|
|
46828
|
+
logger23.error("Failed to show brief", { err });
|
|
46550
46829
|
error(`Erro ao buscar brief: ${err instanceof Error ? err.message : String(err)}`);
|
|
46551
46830
|
}
|
|
46552
46831
|
});
|
|
@@ -46555,7 +46834,7 @@ var init_brief = __esm({
|
|
|
46555
46834
|
|
|
46556
46835
|
// src/commands/brief-create.ts
|
|
46557
46836
|
import { Command as Command24 } from "commander";
|
|
46558
|
-
var
|
|
46837
|
+
var logger24, briefCreateCommand;
|
|
46559
46838
|
var init_brief_create = __esm({
|
|
46560
46839
|
"src/commands/brief-create.ts"() {
|
|
46561
46840
|
"use strict";
|
|
@@ -46565,7 +46844,7 @@ var init_brief_create = __esm({
|
|
|
46565
46844
|
init_api();
|
|
46566
46845
|
init_cache();
|
|
46567
46846
|
init_formatter();
|
|
46568
|
-
|
|
46847
|
+
logger24 = createLogger("cli:brief-create");
|
|
46569
46848
|
briefCreateCommand = new Command24("brief-create").description("Create your base learner brief via interactive prompts (T1 bootstrap)").action(async () => {
|
|
46570
46849
|
try {
|
|
46571
46850
|
const session = await requireSession();
|
|
@@ -46590,7 +46869,7 @@ var init_brief_create = __esm({
|
|
|
46590
46869
|
];
|
|
46591
46870
|
output(doneLines.join("\n"), { json: false });
|
|
46592
46871
|
} catch (err) {
|
|
46593
|
-
|
|
46872
|
+
logger24.error("Failed to create brief", { err });
|
|
46594
46873
|
error(`Erro ao criar brief: ${err instanceof Error ? err.message : String(err)}`);
|
|
46595
46874
|
}
|
|
46596
46875
|
});
|
|
@@ -46655,7 +46934,7 @@ async function saveModuleSummary(workspacePath, input2) {
|
|
|
46655
46934
|
""
|
|
46656
46935
|
].join("\n");
|
|
46657
46936
|
fs19.writeFileSync(filePath, header + input2.summary, { mode: 384 });
|
|
46658
|
-
|
|
46937
|
+
logger25.debug("Module summary saved", { moduleId: input2.moduleId, path: filePath });
|
|
46659
46938
|
return filePath;
|
|
46660
46939
|
}
|
|
46661
46940
|
async function loadSessionContext(workspacePath) {
|
|
@@ -46676,19 +46955,19 @@ async function loadSessionContext(workspacePath) {
|
|
|
46676
46955
|
}
|
|
46677
46956
|
return { moduleSummaries: summaries };
|
|
46678
46957
|
}
|
|
46679
|
-
var
|
|
46958
|
+
var logger25;
|
|
46680
46959
|
var init_storage = __esm({
|
|
46681
46960
|
"src/sessions/storage.ts"() {
|
|
46682
46961
|
"use strict";
|
|
46683
46962
|
init_dist();
|
|
46684
|
-
|
|
46963
|
+
logger25 = createLogger("cli:sessions");
|
|
46685
46964
|
}
|
|
46686
46965
|
});
|
|
46687
46966
|
|
|
46688
46967
|
// src/commands/compact.ts
|
|
46689
46968
|
import fs20 from "node:fs";
|
|
46690
46969
|
import { Command as Command26 } from "commander";
|
|
46691
|
-
var
|
|
46970
|
+
var logger26, compactCommand;
|
|
46692
46971
|
var init_compact = __esm({
|
|
46693
46972
|
"src/commands/compact.ts"() {
|
|
46694
46973
|
"use strict";
|
|
@@ -46697,7 +46976,7 @@ var init_compact = __esm({
|
|
|
46697
46976
|
init_workspace_state();
|
|
46698
46977
|
init_storage();
|
|
46699
46978
|
init_formatter();
|
|
46700
|
-
|
|
46979
|
+
logger26 = createLogger("cli:compact");
|
|
46701
46980
|
compactCommand = new Command26("compact").description("Save a module study summary (LLM-generated, from stdin)").option("--module-id <id>", "Module ID").option("--module-title <title>", "Module title").option("--json", "Output structured JSON").action(async (opts) => {
|
|
46702
46981
|
try {
|
|
46703
46982
|
const activeCourse = await requireActiveCourse();
|
|
@@ -46718,7 +46997,7 @@ var init_compact = __esm({
|
|
|
46718
46997
|
moduleTitle,
|
|
46719
46998
|
summary
|
|
46720
46999
|
});
|
|
46721
|
-
|
|
47000
|
+
logger26.debug("Compact summary saved", { moduleId, filePath });
|
|
46722
47001
|
if (opts.json) {
|
|
46723
47002
|
output({ saved: true, path: filePath, moduleId }, { json: true });
|
|
46724
47003
|
} else {
|
|
@@ -46727,7 +47006,7 @@ var init_compact = __esm({
|
|
|
46727
47006
|
} catch (err) {
|
|
46728
47007
|
const msg = err instanceof Error ? err.message : String(err);
|
|
46729
47008
|
if (msg.includes("process.exit")) return;
|
|
46730
|
-
|
|
47009
|
+
logger26.warn("compact failed", { error: msg });
|
|
46731
47010
|
if (opts.json) jsonError(msg);
|
|
46732
47011
|
error(msg);
|
|
46733
47012
|
}
|
|
@@ -46737,7 +47016,7 @@ var init_compact = __esm({
|
|
|
46737
47016
|
|
|
46738
47017
|
// src/commands/context.ts
|
|
46739
47018
|
import { Command as Command27 } from "commander";
|
|
46740
|
-
var
|
|
47019
|
+
var logger27, contextCommand;
|
|
46741
47020
|
var init_context = __esm({
|
|
46742
47021
|
"src/commands/context.ts"() {
|
|
46743
47022
|
"use strict";
|
|
@@ -46745,7 +47024,7 @@ var init_context = __esm({
|
|
|
46745
47024
|
init_workspace_state();
|
|
46746
47025
|
init_storage();
|
|
46747
47026
|
init_formatter();
|
|
46748
|
-
|
|
47027
|
+
logger27 = createLogger("cli:context");
|
|
46749
47028
|
contextCommand = new Command27("context").description("Load session context (workspace state + module summaries) for LLM consumption").option("--json", "Output structured JSON").action(async (opts) => {
|
|
46750
47029
|
try {
|
|
46751
47030
|
const ws = await findWorkspaceState();
|
|
@@ -46773,7 +47052,7 @@ var init_context = __esm({
|
|
|
46773
47052
|
})),
|
|
46774
47053
|
totalModulesCompleted: sessionCtx.moduleSummaries.length
|
|
46775
47054
|
};
|
|
46776
|
-
|
|
47055
|
+
logger27.debug("Context loaded", {
|
|
46777
47056
|
courseId: ws.state.courseId,
|
|
46778
47057
|
moduleSummaries: sessionCtx.moduleSummaries.length
|
|
46779
47058
|
});
|
|
@@ -46787,7 +47066,7 @@ var init_context = __esm({
|
|
|
46787
47066
|
} catch (err) {
|
|
46788
47067
|
const msg = err instanceof Error ? err.message : String(err);
|
|
46789
47068
|
if (msg.includes("process.exit")) return;
|
|
46790
|
-
|
|
47069
|
+
logger27.warn("context failed", { error: msg });
|
|
46791
47070
|
if (opts.json) jsonError(msg);
|
|
46792
47071
|
error(msg);
|
|
46793
47072
|
}
|
|
@@ -46797,7 +47076,7 @@ var init_context = __esm({
|
|
|
46797
47076
|
|
|
46798
47077
|
// src/commands/memory.ts
|
|
46799
47078
|
import { Command as Command28 } from "commander";
|
|
46800
|
-
var
|
|
47079
|
+
var logger28, memoryCommand;
|
|
46801
47080
|
var init_memory = __esm({
|
|
46802
47081
|
"src/commands/memory.ts"() {
|
|
46803
47082
|
"use strict";
|
|
@@ -46806,7 +47085,7 @@ var init_memory = __esm({
|
|
|
46806
47085
|
init_workspace_state();
|
|
46807
47086
|
init_guards();
|
|
46808
47087
|
init_formatter();
|
|
46809
|
-
|
|
47088
|
+
logger28 = createLogger("cli:memory");
|
|
46810
47089
|
memoryCommand = new Command28("memory").description("Load accumulated student memory (learning profile + recent lessons) for the tutor").option("--json", "Output structured JSON").action(async (opts) => {
|
|
46811
47090
|
try {
|
|
46812
47091
|
const ws = await findWorkspaceState();
|
|
@@ -46830,7 +47109,7 @@ var init_memory = __esm({
|
|
|
46830
47109
|
} catch (err) {
|
|
46831
47110
|
const msg = err instanceof Error ? err.message : String(err);
|
|
46832
47111
|
if (msg.includes("process.exit")) return;
|
|
46833
|
-
|
|
47112
|
+
logger28.warn("memory failed", { error: msg });
|
|
46834
47113
|
if (opts.json) jsonError(msg);
|
|
46835
47114
|
else error(msg);
|
|
46836
47115
|
}
|
|
@@ -46840,7 +47119,7 @@ var init_memory = __esm({
|
|
|
46840
47119
|
|
|
46841
47120
|
// src/commands/insight.ts
|
|
46842
47121
|
import { Command as Command29 } from "commander";
|
|
46843
|
-
var
|
|
47122
|
+
var logger29, VALID_TYPES, insightCommand;
|
|
46844
47123
|
var init_insight = __esm({
|
|
46845
47124
|
"src/commands/insight.ts"() {
|
|
46846
47125
|
"use strict";
|
|
@@ -46849,7 +47128,7 @@ var init_insight = __esm({
|
|
|
46849
47128
|
init_workspace_state();
|
|
46850
47129
|
init_guards();
|
|
46851
47130
|
init_formatter();
|
|
46852
|
-
|
|
47131
|
+
logger29 = createLogger("cli:insight");
|
|
46853
47132
|
VALID_TYPES = ["difficulty", "breakthrough", "question"];
|
|
46854
47133
|
insightCommand = new Command29("insight").description(
|
|
46855
47134
|
"Persist a student cognitive insight (difficulty | breakthrough | question) into course memory"
|
|
@@ -46891,7 +47170,7 @@ var init_insight = __esm({
|
|
|
46891
47170
|
} catch (err) {
|
|
46892
47171
|
const msg = err instanceof Error ? err.message : String(err);
|
|
46893
47172
|
if (msg.includes("process.exit")) return;
|
|
46894
|
-
|
|
47173
|
+
logger29.warn("insight failed", { error: msg });
|
|
46895
47174
|
if (opts.json) jsonError(msg);
|
|
46896
47175
|
else error(msg);
|
|
46897
47176
|
}
|
|
@@ -46904,7 +47183,7 @@ import { Command as Command30 } from "commander";
|
|
|
46904
47183
|
function isExerciseLevel2(value) {
|
|
46905
47184
|
return ALL_LEVELS.includes(value);
|
|
46906
47185
|
}
|
|
46907
|
-
var
|
|
47186
|
+
var logger30, ALL_LEVELS, LEVEL_LABELS2, levelCommand;
|
|
46908
47187
|
var init_level = __esm({
|
|
46909
47188
|
"src/commands/level.ts"() {
|
|
46910
47189
|
"use strict";
|
|
@@ -46913,7 +47192,7 @@ var init_level = __esm({
|
|
|
46913
47192
|
init_exercises();
|
|
46914
47193
|
init_guards();
|
|
46915
47194
|
init_formatter();
|
|
46916
|
-
|
|
47195
|
+
logger30 = createLogger("cli:level");
|
|
46917
47196
|
ALL_LEVELS = ["L0", "L1", "L2", "L3", "L4"];
|
|
46918
47197
|
LEVEL_LABELS2 = {
|
|
46919
47198
|
L0: "Pr\xE9-check (perguntas conceituais)",
|
|
@@ -46927,7 +47206,7 @@ var init_level = __esm({
|
|
|
46927
47206
|
const session = await requireSession();
|
|
46928
47207
|
const activeCourse = await requireActiveCourse();
|
|
46929
47208
|
const data = createHttpProvider(session.apiUrl, session.token);
|
|
46930
|
-
const deps = { data, logger:
|
|
47209
|
+
const deps = { data, logger: logger30 };
|
|
46931
47210
|
if (!rawLevel) {
|
|
46932
47211
|
const levels = await getEnrollmentLevels({ enrollmentId: activeCourse.enrollmentId }, deps);
|
|
46933
47212
|
if (opts.json) {
|
|
@@ -46986,7 +47265,7 @@ var init_level = __esm({
|
|
|
46986
47265
|
|
|
46987
47266
|
// src/commands/theory.ts
|
|
46988
47267
|
import { Command as Command31 } from "commander";
|
|
46989
|
-
var
|
|
47268
|
+
var logger31, EXERCISE_LEVELS2, theoryCommand;
|
|
46990
47269
|
var init_theory = __esm({
|
|
46991
47270
|
"src/commands/theory.ts"() {
|
|
46992
47271
|
"use strict";
|
|
@@ -46994,7 +47273,7 @@ var init_theory = __esm({
|
|
|
46994
47273
|
init_guards();
|
|
46995
47274
|
init_formatter();
|
|
46996
47275
|
init_errors();
|
|
46997
|
-
|
|
47276
|
+
logger31 = createLogger("cli:theory");
|
|
46998
47277
|
EXERCISE_LEVELS2 = ["L0", "L1", "L2", "L3", "L4"];
|
|
46999
47278
|
theoryCommand = new Command31("theory").description("Request more theory on the current lesson (escape hatch)").option("--focus <text>", "Optional focus area in PT-BR (max 500 chars)").option("--level <L0|L1|L2|L3|L4>", "Override current exercise level (otherwise auto-detect)").option("--lesson <uuid>", "Override lesson ID (defaults to current workspace lesson)").option("--json", "Output structured JSON").action(async (opts) => {
|
|
47000
47279
|
try {
|
|
@@ -47033,7 +47312,7 @@ var init_theory = __esm({
|
|
|
47033
47312
|
currentLevel = levels.currentLevel;
|
|
47034
47313
|
}
|
|
47035
47314
|
const requestUrl = `${session.apiUrl}/api/cli/exercises/more-theory`;
|
|
47036
|
-
|
|
47315
|
+
logger31.debug("Requesting more theory", { lessonId, currentLevel });
|
|
47037
47316
|
const res = await fetch(requestUrl, {
|
|
47038
47317
|
method: "POST",
|
|
47039
47318
|
headers: {
|
|
@@ -47438,7 +47717,7 @@ async function runExportGrades(opts, deps = defaultDeps5) {
|
|
|
47438
47717
|
if (!rendered.endsWith("\n")) rendered += "\n";
|
|
47439
47718
|
deps.stdoutWrite(rendered);
|
|
47440
47719
|
}
|
|
47441
|
-
var
|
|
47720
|
+
var logger32, SUPPORTED_FORMATS, defaultDeps5, exportGradesCommand;
|
|
47442
47721
|
var init_export_grades = __esm({
|
|
47443
47722
|
"src/commands/export-grades.ts"() {
|
|
47444
47723
|
"use strict";
|
|
@@ -47446,7 +47725,7 @@ var init_export_grades = __esm({
|
|
|
47446
47725
|
init_guards();
|
|
47447
47726
|
init_grades();
|
|
47448
47727
|
init_resolve_enrollment();
|
|
47449
|
-
|
|
47728
|
+
logger32 = createLogger("cli:export-grades");
|
|
47450
47729
|
SUPPORTED_FORMATS = ["json", "csv", "md"];
|
|
47451
47730
|
defaultDeps5 = {
|
|
47452
47731
|
requireSession,
|
|
@@ -47456,7 +47735,7 @@ var init_export_grades = __esm({
|
|
|
47456
47735
|
stderrWrite: (message) => process.stderr.write(message),
|
|
47457
47736
|
// process.exit is typed as `never` — wrap so the cast is local to one line.
|
|
47458
47737
|
exit: (code) => process.exit(code),
|
|
47459
|
-
logger:
|
|
47738
|
+
logger: logger32,
|
|
47460
47739
|
resolveBySlug: resolveEnrollmentBySlug
|
|
47461
47740
|
};
|
|
47462
47741
|
exportGradesCommand = new Command32("export-grades").description("Exporta o hist\xF3rico de valida\xE7\xF5es (notas) do curso ativo").option(
|
|
@@ -47625,7 +47904,7 @@ async function runGrades(opts, deps = defaultDeps6) {
|
|
|
47625
47904
|
);
|
|
47626
47905
|
deps.stdoutWrite(formatGradesAllEnrollmentsTable(summaries) + "\n");
|
|
47627
47906
|
}
|
|
47628
|
-
var
|
|
47907
|
+
var logger33, defaultDeps6, gradesCommand;
|
|
47629
47908
|
var init_grades2 = __esm({
|
|
47630
47909
|
"src/commands/grades.ts"() {
|
|
47631
47910
|
"use strict";
|
|
@@ -47635,14 +47914,14 @@ var init_grades2 = __esm({
|
|
|
47635
47914
|
init_guards();
|
|
47636
47915
|
init_grades();
|
|
47637
47916
|
init_resolve_enrollment();
|
|
47638
|
-
|
|
47917
|
+
logger33 = createLogger("cli:grades");
|
|
47639
47918
|
defaultDeps6 = {
|
|
47640
47919
|
requireSession,
|
|
47641
47920
|
fetch: globalThis.fetch.bind(globalThis),
|
|
47642
47921
|
stdoutWrite: (message) => process.stdout.write(message),
|
|
47643
47922
|
stderrWrite: (message) => process.stderr.write(message),
|
|
47644
47923
|
exit: (code) => process.exit(code),
|
|
47645
|
-
logger:
|
|
47924
|
+
logger: logger33,
|
|
47646
47925
|
resolveBySlug: resolveEnrollmentBySlug,
|
|
47647
47926
|
buildDataProvider: createHttpProvider,
|
|
47648
47927
|
listCoursesFn: listCourses
|
|
@@ -47807,7 +48086,7 @@ async function runReview(slug, opts, deps = defaultDeps7) {
|
|
|
47807
48086
|
}) + "\n"
|
|
47808
48087
|
);
|
|
47809
48088
|
}
|
|
47810
|
-
var
|
|
48089
|
+
var logger34, defaultDeps7, reviewCommand;
|
|
47811
48090
|
var init_review2 = __esm({
|
|
47812
48091
|
"src/commands/review.ts"() {
|
|
47813
48092
|
"use strict";
|
|
@@ -47815,14 +48094,14 @@ var init_review2 = __esm({
|
|
|
47815
48094
|
init_guards();
|
|
47816
48095
|
init_grades();
|
|
47817
48096
|
init_resolve_enrollment();
|
|
47818
|
-
|
|
48097
|
+
logger34 = createLogger("cli:review");
|
|
47819
48098
|
defaultDeps7 = {
|
|
47820
48099
|
requireSession,
|
|
47821
48100
|
fetch: globalThis.fetch.bind(globalThis),
|
|
47822
48101
|
stdoutWrite: (message) => process.stdout.write(message),
|
|
47823
48102
|
stderrWrite: (message) => process.stderr.write(message),
|
|
47824
48103
|
exit: (code) => process.exit(code),
|
|
47825
|
-
logger:
|
|
48104
|
+
logger: logger34,
|
|
47826
48105
|
resolveBySlug: resolveEnrollmentBySlug,
|
|
47827
48106
|
promptLessonChoice: defaultPromptLessonChoice
|
|
47828
48107
|
};
|
|
@@ -47937,13 +48216,77 @@ var init_cli = __esm({
|
|
|
47937
48216
|
}
|
|
47938
48217
|
});
|
|
47939
48218
|
|
|
48219
|
+
// src/auto-updater.ts
|
|
48220
|
+
var auto_updater_exports = {};
|
|
48221
|
+
__export(auto_updater_exports, {
|
|
48222
|
+
detectManager: () => detectManager,
|
|
48223
|
+
maybeAutoUpdate: () => maybeAutoUpdate
|
|
48224
|
+
});
|
|
48225
|
+
import fs21 from "node:fs";
|
|
48226
|
+
import path23 from "node:path";
|
|
48227
|
+
import { spawn as spawn2 } from "node:child_process";
|
|
48228
|
+
function detectManager(entryRealPath) {
|
|
48229
|
+
const p = entryRealPath.split(path23.sep).join("/");
|
|
48230
|
+
if (p.includes("/pnpm/")) return { cmd: "pnpm", args: ["add", "-g", `${PACKAGE_NAME2}@latest`] };
|
|
48231
|
+
if (p.includes("/.bun/")) return { cmd: "bun", args: ["add", "-g", `${PACKAGE_NAME2}@latest`] };
|
|
48232
|
+
if (p.includes(`/node_modules/${PACKAGE_NAME2}/`))
|
|
48233
|
+
return { cmd: "npm", args: ["i", "-g", `${PACKAGE_NAME2}@latest`] };
|
|
48234
|
+
return null;
|
|
48235
|
+
}
|
|
48236
|
+
function installDir(entryRealPath) {
|
|
48237
|
+
const normalized = entryRealPath.split(path23.sep).join("/");
|
|
48238
|
+
const marker = `/node_modules/${PACKAGE_NAME2}/`;
|
|
48239
|
+
const idx = normalized.indexOf(marker);
|
|
48240
|
+
if (idx === -1) return path23.dirname(entryRealPath);
|
|
48241
|
+
return entryRealPath.slice(0, idx + marker.length - 1);
|
|
48242
|
+
}
|
|
48243
|
+
function maybeAutoUpdate(currentVersion, opts = {}) {
|
|
48244
|
+
try {
|
|
48245
|
+
const env = opts.env ?? process.env;
|
|
48246
|
+
const argv = opts.argv ?? process.argv;
|
|
48247
|
+
const isTTY = opts.isTTY ?? process.stderr.isTTY === true;
|
|
48248
|
+
if (env["TOSTUDY_NO_AUTO_UPDATE"]) return;
|
|
48249
|
+
if (env["CI"] || !isTTY || argv.includes("--json")) return;
|
|
48250
|
+
const configDir = opts.configDir ?? getConfigDir();
|
|
48251
|
+
const cache = readCache(configDir);
|
|
48252
|
+
if (!cache || !isNewerVersion(cache.latest, currentVersion)) return;
|
|
48253
|
+
if (cache.attemptedVersion === cache.latest) return;
|
|
48254
|
+
const entryPath = opts.entryPath ?? argv[1];
|
|
48255
|
+
if (!entryPath) return;
|
|
48256
|
+
const real2 = fs21.realpathSync(entryPath);
|
|
48257
|
+
const mgr = detectManager(real2);
|
|
48258
|
+
if (!mgr) return;
|
|
48259
|
+
fs21.accessSync(installDir(real2), fs21.constants.W_OK);
|
|
48260
|
+
writeCache({ ...cache, attemptedVersion: cache.latest }, configDir);
|
|
48261
|
+
process.stderr.write(
|
|
48262
|
+
`
|
|
48263
|
+
Atualizando ${PACKAGE_NAME2} para ${cache.latest} em segundo plano\u2026
|
|
48264
|
+
`
|
|
48265
|
+
);
|
|
48266
|
+
const spawnFn = opts.spawnFn ?? spawn2;
|
|
48267
|
+
spawnFn(mgr.cmd, mgr.args, { detached: true, stdio: "ignore" }).unref();
|
|
48268
|
+
} catch {
|
|
48269
|
+
}
|
|
48270
|
+
}
|
|
48271
|
+
var PACKAGE_NAME2;
|
|
48272
|
+
var init_auto_updater = __esm({
|
|
48273
|
+
"src/auto-updater.ts"() {
|
|
48274
|
+
"use strict";
|
|
48275
|
+
init_config_dir();
|
|
48276
|
+
init_update_checker();
|
|
48277
|
+
PACKAGE_NAME2 = "@tostudy-ai/cli";
|
|
48278
|
+
}
|
|
48279
|
+
});
|
|
48280
|
+
|
|
47940
48281
|
// src/cli-entry.ts
|
|
47941
48282
|
if (!process.env.LOG_LEVEL) {
|
|
47942
48283
|
process.env.LOG_LEVEL = "fatal";
|
|
47943
48284
|
}
|
|
47944
48285
|
var { createProgram: createProgram2, CLI_VERSION: CLI_VERSION2 } = await Promise.resolve().then(() => (init_cli(), cli_exports));
|
|
47945
48286
|
var { checkForUpdates: checkForUpdates2 } = await Promise.resolve().then(() => (init_update_checker(), update_checker_exports));
|
|
48287
|
+
var { maybeAutoUpdate: maybeAutoUpdate2 } = await Promise.resolve().then(() => (init_auto_updater(), auto_updater_exports));
|
|
47946
48288
|
var program = createProgram2();
|
|
47947
48289
|
program.parse();
|
|
47948
48290
|
checkForUpdates2(CLI_VERSION2);
|
|
48291
|
+
maybeAutoUpdate2(CLI_VERSION2);
|
|
47949
48292
|
//# sourceMappingURL=cli.js.map
|